mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-12-14 17:41:33 +03:00
Merge pull request #4859 from urbit/mp/landscape/more-more-types
interface: type fixes, part 4
This commit is contained in:
commit
824ee134fe
@ -75,7 +75,6 @@ export class HarkApi extends BaseApi<StoreState> {
|
||||
graph: {
|
||||
graph: association.resource,
|
||||
group: association.group,
|
||||
module: association.metadata.module,
|
||||
description,
|
||||
index: parent
|
||||
} }
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
import { writeText } from './util';
|
||||
|
||||
export function useCopy(copied: string, display: string) {
|
||||
export function useCopy(copied: string, display?: string) {
|
||||
const [didCopy, setDidCopy] = useState(false);
|
||||
const doCopy = useCallback(() => {
|
||||
writeText(copied);
|
||||
|
@ -22,7 +22,7 @@ export const MOMENT_CALENDAR_DATE = {
|
||||
sameElse: '~YYYY.M.D'
|
||||
};
|
||||
|
||||
type GraphModule = 'link' | 'post' | 'chat' | 'publish';
|
||||
export type GraphModule = 'link' | 'post' | 'chat' | 'publish';
|
||||
|
||||
export const getModuleIcon = (mod: GraphModule): IconRef => {
|
||||
if (mod === 'link') {
|
||||
|
@ -38,7 +38,7 @@ function decodePolicy(policy: Enc<GroupPolicy>): GroupPolicy {
|
||||
function decodeTags(tags: Enc<Tags>): Tags {
|
||||
return _.reduce(
|
||||
tags,
|
||||
(acc, ships, key): Tags => {
|
||||
(acc, ships: any, key): Tags => {
|
||||
if (key.search(/\\/) === -1) {
|
||||
acc.role[key] = new Set(ships);
|
||||
return acc;
|
||||
|
@ -1,30 +1,29 @@
|
||||
import {
|
||||
BaseImage, Box,
|
||||
|
||||
BoxProps,
|
||||
|
||||
Center, Col,
|
||||
|
||||
Icon, Row,
|
||||
|
||||
Text
|
||||
} from '@tlon/indigo-react';
|
||||
import { uxToHex } from '@urbit/api';
|
||||
import React, { useCallback, useEffect, useRef, useState, useMemo, ReactNode } from 'react';
|
||||
import { uxToHex, cite } from '@urbit/api';
|
||||
import { useShowNickname } from '~/logic/lib/util';
|
||||
import _ from 'lodash';
|
||||
import React, { ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import VisibilitySensor from 'react-visibility-sensor';
|
||||
import styled from 'styled-components';
|
||||
import { getRelativePosition } from '~/logic/lib/relativePosition';
|
||||
import { Sigil } from '~/logic/lib/sigil';
|
||||
import { useCopy } from '~/logic/lib/useCopy';
|
||||
import { useOutsideClick } from '~/logic/lib/useOutsideClick';
|
||||
import { cite, useShowNickname } from '~/logic/lib/util';
|
||||
import { useContact } from '~/logic/state/contact';
|
||||
import useSettingsState from '~/logic/state/settings';
|
||||
import { Portal } from './Portal';
|
||||
import { ProfileStatus } from './ProfileStatus';
|
||||
import {
|
||||
Box,
|
||||
Row,
|
||||
Col,
|
||||
Text,
|
||||
BaseImage,
|
||||
Icon,
|
||||
BoxProps,
|
||||
Center
|
||||
} from '@tlon/indigo-react';
|
||||
import RichText from './RichText';
|
||||
import { ProfileStatus } from './ProfileStatus';
|
||||
import useSettingsState from '~/logic/state/settings';
|
||||
import { useOutsideClick } from '~/logic/lib/useOutsideClick';
|
||||
import { useCopy } from '~/logic/lib/useCopy';
|
||||
import { useContact } from '~/logic/state/contact';
|
||||
import { Portal } from './Portal';
|
||||
|
||||
export const OVERLAY_HEIGHT = 250;
|
||||
const FixedOverlay = styled(Col)`
|
||||
@ -39,12 +38,12 @@ type ProfileOverlayProps = BoxProps & {
|
||||
ship: string;
|
||||
api: any;
|
||||
children: ReactNode;
|
||||
color?: string;
|
||||
};
|
||||
|
||||
const ProfileOverlay = (props: ProfileOverlayProps) => {
|
||||
const {
|
||||
ship,
|
||||
api,
|
||||
children,
|
||||
...rest
|
||||
} = props;
|
||||
|
@ -13,19 +13,21 @@ type RemoteContentProps = VirtualContextProps & {
|
||||
text?: string;
|
||||
unfold?: boolean;
|
||||
renderUrl?: boolean;
|
||||
remoteContentPolicy: RemoteContentPolicy;
|
||||
remoteContentPolicy?: RemoteContentPolicy;
|
||||
imageProps?: any;
|
||||
audioProps?: any;
|
||||
videoProps?: any;
|
||||
oembedProps?: any;
|
||||
textProps?: any;
|
||||
style?: any;
|
||||
transcluded?: any;
|
||||
}
|
||||
|
||||
interface RemoteContentState {
|
||||
unfold: boolean;
|
||||
embed: any | undefined;
|
||||
noCors: boolean;
|
||||
showArrow: boolean;
|
||||
}
|
||||
|
||||
const IMAGE_REGEX = new RegExp(/(jpg|img|png|gif|tiff|jpeg|webp|webm|svg)$/i);
|
||||
|
@ -13,6 +13,7 @@ export type TimestampProps = BoxProps & {
|
||||
relative?: boolean;
|
||||
dateNotRelative?: boolean;
|
||||
height?: string;
|
||||
color?: string;
|
||||
};
|
||||
|
||||
const Timestamp = (props: TimestampProps): ReactElement | null => {
|
||||
@ -22,7 +23,7 @@ const Timestamp = (props: TimestampProps): ReactElement | null => {
|
||||
time,
|
||||
color,
|
||||
relative,
|
||||
dateNotRelative,
|
||||
dateNotRelative = false,
|
||||
fontSize,
|
||||
lineHeight,
|
||||
...rest
|
||||
|
@ -199,7 +199,7 @@ export default class VirtualScroller<T> extends Component<VirtualScrollerProps<T
|
||||
}, 50);
|
||||
|
||||
componentDidUpdate(prevProps: VirtualScrollerProps<T>, _prevState: VirtualScrollerState<T>) {
|
||||
const { id, size, data, offset, pendingSize } = this.props;
|
||||
const { size, data, offset, pendingSize } = this.props;
|
||||
|
||||
if(size !== prevProps.size || pendingSize !== prevProps.pendingSize) {
|
||||
if((this.window?.scrollTop ?? 0) < ZONE_SIZE) {
|
||||
@ -245,7 +245,7 @@ export default class VirtualScroller<T> extends Component<VirtualScrollerProps<T
|
||||
}
|
||||
log('reflow', `from: ${this.startOffset()} to: ${newOffset}`);
|
||||
|
||||
const { data, onCalculateVisibleItems } = this.props;
|
||||
const { data } = this.props;
|
||||
const visibleItems = data.keys().slice(newOffset, newOffset + this.pageSize);
|
||||
|
||||
this.save();
|
||||
@ -346,7 +346,7 @@ export default class VirtualScroller<T> extends Component<VirtualScrollerProps<T
|
||||
}
|
||||
};
|
||||
|
||||
onScroll(event: SyntheticEvent<HTMLElement, ScrollEvent>) {
|
||||
onScroll(event: SyntheticEvent<HTMLElement>) {
|
||||
this.updateScroll();
|
||||
if(!this.window) {
|
||||
// bail if we're going to adjust scroll anyway
|
||||
@ -522,8 +522,6 @@ export default class VirtualScroller<T> extends Component<VirtualScrollerProps<T
|
||||
|
||||
render() {
|
||||
const {
|
||||
startgap,
|
||||
endgap,
|
||||
visibleItems
|
||||
} = this.state;
|
||||
|
||||
|
@ -7,7 +7,7 @@ const withStorage = <P, C extends React.ComponentType<P & IuseStorage>>(
|
||||
) => {
|
||||
return React.forwardRef<C, Omit<C, keyof IuseStorage>>((props, ref) => {
|
||||
const storage = useStorage(params);
|
||||
|
||||
// @ts-ignore Error is based on React component attrs?
|
||||
return <Component ref={ref} {...storage} {...props} />;
|
||||
});
|
||||
};
|
||||
|
@ -58,6 +58,7 @@ function GraphContentWideInner(
|
||||
>
|
||||
<RemoteContent
|
||||
key={content.url}
|
||||
// @ts-ignore Invalid prop detection due to double with() export
|
||||
url={content.url}
|
||||
transcluded={transcluded}
|
||||
/>
|
||||
|
@ -3,7 +3,7 @@ import { Association, Group } from '@urbit/api';
|
||||
import React, { useCallback } from 'react';
|
||||
import GlobalApi from '~/logic/api/global';
|
||||
import { resourceFromPath, roleForShip } from '~/logic/lib/group';
|
||||
import { getModuleIcon } from '~/logic/lib/util';
|
||||
import { getModuleIcon, GraphModule } from '~/logic/lib/util';
|
||||
import useMetadataState from '~/logic/state/metadata';
|
||||
import { Dropdown } from '~/views/components/Dropdown';
|
||||
import { StatelessAsyncAction } from '~/views/components/StatelessAsyncAction';
|
||||
@ -38,7 +38,6 @@ export function GroupChannelSettings(props: GroupChannelSettingsProps) {
|
||||
const disabled =
|
||||
resourceFromPath(association.group).ship.slice(1) !== window.ship &&
|
||||
roleForShip(group, window.ship) !== 'admin';
|
||||
|
||||
return (
|
||||
<Col maxWidth="384px" width="100%">
|
||||
<Text p="4" id="channels" fontWeight="600" fontSize="2">
|
||||
@ -49,7 +48,12 @@ export function GroupChannelSettings(props: GroupChannelSettingsProps) {
|
||||
{channels.filter(({ metadata }) => !metadata.hidden).map(({ resource, metadata }) => (
|
||||
<Row justifyContent="space-between" width="100%" key={resource}>
|
||||
<Row gapX="2">
|
||||
<Icon icon={getModuleIcon(metadata?.config?.graph)} />
|
||||
<Icon
|
||||
icon={getModuleIcon(
|
||||
'graph' in metadata?.config
|
||||
? metadata?.config?.graph as GraphModule
|
||||
: 'post')}
|
||||
/>
|
||||
<Text>{metadata.title}</Text>
|
||||
{metadata.preview && <Text gray>Pinned</Text>}
|
||||
</Row>
|
||||
|
@ -19,9 +19,17 @@ export function GroupFeedSettings(props: {
|
||||
group: Group;
|
||||
api: GlobalApi;
|
||||
}) {
|
||||
const { association, group, api } = props;
|
||||
const { association, api } = props;
|
||||
const resource = resourceFromPath(association.group);
|
||||
const feedResource = association?.metadata.config?.group?.resource;
|
||||
let feedResource = '';
|
||||
if (
|
||||
association?.metadata?.config &&
|
||||
'group' in association.metadata.config &&
|
||||
association.metadata.config.group !== null &&
|
||||
'resource' in association.metadata.config.group
|
||||
) {
|
||||
feedResource = association.metadata.config.group.resource ?? '';
|
||||
}
|
||||
const feedAssoc = useMetadataState(s => s.associations.graph[feedResource]);
|
||||
const isEnabled = Boolean(feedResource);
|
||||
|
||||
@ -44,7 +52,7 @@ export function GroupFeedSettings(props: {
|
||||
values: FormSchema,
|
||||
actions: FormikHelpers<FormSchema>
|
||||
) => {
|
||||
await api.metadata.update(feedAssoc, { vip: values.permissions.trim() });
|
||||
await api.metadata.update(feedAssoc, { vip: values.permissions.trim() as PermVariation });
|
||||
|
||||
actions.setStatus({ success: null });
|
||||
};
|
||||
|
@ -37,7 +37,10 @@ export function GroupifyForm(props: GroupifyFormProps) {
|
||||
name,
|
||||
values.group?.toString() || undefined
|
||||
);
|
||||
const mod = association.metadata?.config?.graph || association['app-name'];
|
||||
let mod = association['app-name'];
|
||||
if (association?.metadata?.config && 'graph' in association.metadata.config) {
|
||||
mod = association.metadata.config.graph;
|
||||
}
|
||||
const newGroup = values.group || association.group;
|
||||
history.push(`/~landscape${newGroup}/resource/${mod}${rid}`);
|
||||
actions.setStatus({ success: null });
|
||||
|
@ -42,7 +42,7 @@ export function InvitePopover(props: InvitePopoverProps) {
|
||||
const { baseUrl, api, association } = props;
|
||||
|
||||
const relativePath = (p: string) => baseUrl + p;
|
||||
const { title } = association?.metadata || '';
|
||||
const { title } = association?.metadata || { title: '' };
|
||||
const innerRef = useRef(null);
|
||||
const history = useHistory();
|
||||
|
||||
|
@ -98,7 +98,9 @@ export function JoinGroup(props: JoinGroupProps): ReactElement {
|
||||
|
||||
if(groups?.[group]?.hidden) {
|
||||
const { metadata } = associations.graph[group];
|
||||
history.push(`/~landscape/home/resource/${metadata.config.graph}${group}`);
|
||||
if (metadata?.config && 'graph' in metadata.config) {
|
||||
history.push(`/~landscape/home/resource/${metadata.config.graph}${group}`);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
history.push(`/~landscape${group}`);
|
||||
|
@ -28,7 +28,10 @@ export function Resource(props: ResourceProps): ReactElement {
|
||||
const notificationsCount = useHarkState(state => state.notificationsCount);
|
||||
const associations = useMetadataState(state => state.associations);
|
||||
const contacts = useContactState(state => state.contacts);
|
||||
const app = association.metadata?.config?.graph || association['app-name'];
|
||||
let app = association['app-name'];
|
||||
if (association?.metadata?.config && 'graph' in association.metadata.config) {
|
||||
app = association.metadata.config.graph;
|
||||
}
|
||||
const { resource: rid, group: selectedGroup } = association;
|
||||
const relativePath = (p: string) => `${props.baseUrl}/resource/${app}${rid}${p}`;
|
||||
const skelProps = { api, association, groups, contacts };
|
||||
|
@ -28,7 +28,10 @@ type ResourceSkeletonProps = {
|
||||
|
||||
export function ResourceSkeleton(props: ResourceSkeletonProps): ReactElement {
|
||||
const { association, baseUrl, children } = props;
|
||||
const app = association?.metadata?.config?.graph || association['app-name'];
|
||||
let app = association['app-name'];
|
||||
if (association?.metadata?.config && 'graph' in association.metadata.config) {
|
||||
app = association.metadata.config.graph;
|
||||
}
|
||||
const rid = association.resource;
|
||||
const groups = useGroupState(state => state.groups);
|
||||
const group = groups[association.group];
|
||||
|
@ -19,7 +19,7 @@ export function useGraphModule(
|
||||
if (
|
||||
notifications &&
|
||||
((typeof notifications === 'number' && notifications > 0)
|
||||
|| notifications.length)
|
||||
|| typeof notifications === 'object' && notifications.length)
|
||||
) {
|
||||
return 'notification';
|
||||
}
|
||||
|
@ -26,7 +26,10 @@ export function SidebarItem(props: {
|
||||
const { association, path, selected, apps } = props;
|
||||
let title = getItemTitle(association) || '';
|
||||
const appName = association?.['app-name'];
|
||||
const mod = association?.metadata?.config?.graph || appName;
|
||||
let mod = appName;
|
||||
if (association?.metadata?.config && 'graph' in association.metadata.config) {
|
||||
mod = association.metadata.config.graph;
|
||||
}
|
||||
const rid = association?.resource;
|
||||
const groupPath = association?.group;
|
||||
const groups = useGroupState(state => state.groups);
|
||||
|
@ -52,7 +52,10 @@ export function SidebarListHeader(props: {
|
||||
|
||||
const noun = (props.workspace?.type === 'messages') ? 'Messages' : 'Channels';
|
||||
|
||||
const feedPath = metadata?.config?.group?.resource;
|
||||
let feedPath: any = '';
|
||||
if (metadata?.config && 'group' in metadata.config) {
|
||||
feedPath = metadata.config.group ?? '';
|
||||
}
|
||||
|
||||
const unreadCount = useHarkState(
|
||||
s => s.unreads?.graph?.[feedPath ?? '']?.['/']?.unreads as number ?? 0
|
||||
|
@ -3,15 +3,15 @@
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUnusedParameters": false,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitReturns": false,
|
||||
"moduleResolution": "node",
|
||||
"esModuleInterop": true,
|
||||
"noUnusedLocals": false,
|
||||
"noImplicitAny": false,
|
||||
"noEmit": true,
|
||||
"target": "es2015",
|
||||
"module": "es2015",
|
||||
"strict": true,
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"strict": false,
|
||||
"jsx": "react",
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
|
@ -107,7 +107,6 @@ export const markCountAsRead = (
|
||||
graph: {
|
||||
graph: association.resource,
|
||||
group: association.group,
|
||||
module: association.metadata.module,
|
||||
description: description,
|
||||
index: parent
|
||||
}
|
||||
|
@ -76,10 +76,10 @@ export interface Metadata {
|
||||
type MetadataConfig = GroupConfig | GraphConfig;
|
||||
|
||||
interface GroupConfig {
|
||||
group: null | {} | Resource;
|
||||
group: null | Record<string, string> | Resource;
|
||||
}
|
||||
interface GraphConfig {
|
||||
graph: string;
|
||||
}
|
||||
|
||||
export type PermVariation = '' | 'reader-comments' | 'member-metadata' | 'host-feed' | 'admin-feed';
|
||||
export type PermVariation = '' | ' ' | 'reader-comments' | 'member-metadata' | 'host-feed' | 'admin-feed';
|
||||
|
@ -14,6 +14,6 @@
|
||||
"sourceMap": true,
|
||||
"strict": false,
|
||||
"noErrorTruncation": true,
|
||||
"allowJs": true,
|
||||
"allowJs": true
|
||||
}
|
||||
}
|
@ -14,6 +14,7 @@ const rules = {
|
||||
}
|
||||
],
|
||||
"arrow-spacing": "error",
|
||||
"ban-ts-comment": "allow-with-description",
|
||||
"block-spacing": ["error", "always"],
|
||||
"brace-style": ["error", "1tbs"],
|
||||
"camelcase": [
|
||||
|
Loading…
Reference in New Issue
Block a user