Merge pull request #4859 from urbit/mp/landscape/more-more-types

interface: type fixes, part 4
This commit is contained in:
matildepark 2021-05-05 19:12:54 -04:00 committed by GitHub
commit 824ee134fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 84 additions and 55 deletions

View File

@ -75,7 +75,6 @@ export class HarkApi extends BaseApi<StoreState> {
graph: {
graph: association.resource,
group: association.group,
module: association.metadata.module,
description,
index: parent
} }

View File

@ -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);

View File

@ -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') {

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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} />;
});
};

View File

@ -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}
/>

View File

@ -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>

View File

@ -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 });
};

View File

@ -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 });

View File

@ -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();

View File

@ -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}`);

View File

@ -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 };

View File

@ -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];

View File

@ -19,7 +19,7 @@ export function useGraphModule(
if (
notifications &&
((typeof notifications === 'number' && notifications > 0)
|| notifications.length)
|| typeof notifications === 'object' && notifications.length)
) {
return 'notification';
}

View File

@ -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);

View File

@ -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

View File

@ -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": {

View File

@ -107,7 +107,6 @@ export const markCountAsRead = (
graph: {
graph: association.resource,
group: association.group,
module: association.metadata.module,
description: description,
index: parent
}

View File

@ -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';

View File

@ -14,6 +14,6 @@
"sourceMap": true,
"strict": false,
"noErrorTruncation": true,
"allowJs": true,
"allowJs": true
}
}

View File

@ -14,6 +14,7 @@ const rules = {
}
],
"arrow-spacing": "error",
"ban-ts-comment": "allow-with-description",
"block-spacing": ["error", "always"],
"brace-style": ["error", "1tbs"],
"camelcase": [