interface: type corrections, part 3

This commit is contained in:
Matilde Park 2021-05-04 18:34:48 -04:00
parent 97288c349b
commit a276d42078
21 changed files with 79 additions and 123 deletions

View File

@ -1,14 +1,13 @@
/* eslint-disable max-lines */
import { useEffect, useState, useCallback, useMemo } from 'react';
import _ from 'lodash';
import { IconRef } from '~/types';
import f, { compose, memoize } from 'lodash/fp';
import bigInt, { BigInteger } from 'big-integer';
import { Association, Contact } from '@urbit/api';
import useLocalState from '../state/local';
import produce, { enableMapSet } from 'immer';
import { enableMapSet } from 'immer';
import useSettingsState from '../state/settings';
import { State, UseStore } from 'zustand';
import { Cage } from '~/types/cage';
import { BaseState } from '../state/base';
import anyAscii from 'any-ascii';
enableMapSet();
@ -24,7 +23,7 @@ export const MOMENT_CALENDAR_DATE = {
sameElse: '~YYYY.M.D'
};
export const getModuleIcon = (mod: string) => {
export const getModuleIcon = (mod: string): IconRef => {
if (mod === 'link') {
return 'Collection';
}
@ -226,11 +225,11 @@ export function writeText(str: string) {
}
// trim patps to match dojo, chat-cli
export function cite(ship: string) {
export function cite(ship: string): string {
let patp = ship,
shortened = '';
if (patp === null || patp === '') {
return null;
return '';
}
if (patp.startsWith('~')) {
patp = patp.substr(1);
@ -425,7 +424,7 @@ export const useHovering = (): useHoveringInterface => {
};
const DM_REGEX = /ship\/~([a-z]|-)*\/dm--/;
export function getItemTitle(association: Association) {
export function getItemTitle(association: Association): string {
if (DM_REGEX.test(association.resource)) {
const [, , ship, name] = association.resource.split('/');
if (ship.slice(1) === window.ship) {
@ -433,6 +432,6 @@ export function getItemTitle(association: Association) {
}
return cite(ship);
}
return association.metadata.title || association.resource;
return association.metadata.title ?? association.resource ?? '';
}

View File

@ -18,10 +18,10 @@ export function getTitleFromWorkspace(
export function getGroupFromWorkspace(
workspace: Workspace
): string | undefined {
): string {
if (workspace.type === 'group') {
return workspace.group;
}
return undefined;
return '';
}

View File

@ -3,7 +3,7 @@ import { Box } from '@tlon/indigo-react';
import { PropFunc } from '~/types/util';
interface ModalOverlayProps {
spacing: PropFunc<typeof Box>['m'];
spacing?: PropFunc<typeof Box>['m'];
dismiss: () => void;
}
type Props = ModalOverlayProps & PropFunc<typeof Box>;

View File

@ -5,7 +5,7 @@ import { LoadingSpinner, Action } from '@tlon/indigo-react';
interface AsyncActionProps {
children: ReactNode;
name: string;
name?: string;
disabled?: boolean;
onClick: (e: React.MouseEvent) => Promise<void>;
}

View File

@ -1,15 +1,15 @@
import React from "react";
import { Post, ReferenceContent } from "@urbit/api";
import { Box } from "@tlon/indigo-react";
import React from 'react';
import { Content, Post, ReferenceContent } from '@urbit/api';
import { Box } from '@tlon/indigo-react';
import GlobalApi from "~/logic/api/global";
import TextContent from "./content/text";
import CodeContent from "./content/code";
import RemoteContent from "~/views/components/RemoteContent";
import { Mention } from "~/views/components/MentionText";
import { PermalinkEmbed } from "~/views/apps/permalinks/embed";
import { referenceToPermalink } from "~/logic/lib/permalinks";
import { PropFunc } from "~/types";
import GlobalApi from '~/logic/api/global';
import TextContent from './content/text';
import CodeContent from './content/code';
import RemoteContent from '~/views/components/RemoteContent';
import { Mention } from '~/views/components/MentionText';
import { PermalinkEmbed } from '~/views/apps/permalinks/embed';
import { referenceToPermalink } from '~/logic/lib/permalinks';
import { PropFunc } from '~/types';
function GraphContentWideInner(
props: {
@ -23,21 +23,21 @@ function GraphContentWideInner(
return (
<Box {...rest}>
{post.contents.map((content, i) => {
{post.contents.map((content: Content, i) => {
switch (Object.keys(content)[0]) {
case "text":
case 'text':
return (
<TextContent
key={i}
api={api}
fontSize={1}
lineHeight={"20px"}
lineHeight={'20px'}
content={content}
/>
);
case "code":
case 'code':
return <CodeContent key={i} content={content} />;
case "reference":
case 'reference':
const { link } = referenceToPermalink(content as ReferenceContent);
return (
<PermalinkEmbed
@ -47,7 +47,7 @@ function GraphContentWideInner(
showOurContact={showOurContact}
/>
);
case "url":
case 'url':
return (
<Box
key={i}
@ -58,15 +58,15 @@ function GraphContentWideInner(
width="fit-content"
maxWidth="min(500px, 100%)"
>
<RemoteContent
<RemoteContent
key={content.url}
url={content.url}
transcluded={transcluded}
/>
</Box>
);
case "mention":
const first = (i) => i === 0;
case 'mention':
const first = i => i === 0;
return (
<Mention
key={i}

View File

@ -1,5 +1,6 @@
import React, { ReactElement, ReactNode, useRef } from 'react';
import { Metadata, PropFunc } from '@urbit/api';
import { Metadata } from '@urbit/api';
import { PropFunc } from '~/types';
import { Col, Row, Text } from '@tlon/indigo-react';
import { MetadataIcon } from './MetadataIcon';
import { useTutorialModal } from '~/views/components/useTutorialModal';

View File

@ -31,7 +31,7 @@ const GroupSwitcherItem = ({ to, children, bottom = false, ...rest }) => (
</Link>
);
function RecentGroups(props: { recent: string[]; associations: Associations }) {
function RecentGroups(props: { recent: string[] }) {
const { recent } = props;
if (recent.length < 2) {
return null;

View File

@ -1,10 +1,9 @@
import React, { useEffect, ReactNode } from 'react';
import React, { useEffect } from 'react';
import {
Switch,
Route,
RouteComponentProps
} from 'react-router-dom';
import { Col, Box, Text } from '@tlon/indigo-react';
import _ from 'lodash';
import Helmet from 'react-helmet';
@ -28,7 +27,6 @@ import { getGroupFromWorkspace } from '~/logic/lib/workspace';
import { GroupHome } from './Home/GroupHome';
import { EmptyGroupHome } from './Home/EmptyGroupHome';
import { Workspace } from '~/types/workspace';
import useContactState from '~/logic/state/contact';
import useGroupState from '~/logic/state/group';
import useHarkState from '~/logic/state/hark';
import useMetadataState from '~/logic/state/metadata';
@ -42,17 +40,12 @@ type GroupsPaneProps = StoreState & {
export function GroupsPane(props: GroupsPaneProps) {
const { baseUrl, api, workspace } = props;
const associations = useMetadataState(state => state.associations);
const contacts = useContactState(state => state.contacts);
const notificationsCount = useHarkState(state => state.notificationsCount);
const relativePath = (path: string) => baseUrl + path;
const groupPath = getGroupFromWorkspace(workspace);
const groups = useGroupState(state => state.groups);
const groupContacts = Object.assign({}, ...Array.from(groups?.[groupPath]?.members ?? []).filter(e => contacts[`~${e}`]).map(e => {
return {[e]: contacts[`~${e}`]};
})) || {};
const rootIdentity = contacts?.["/~/default"]?.[window.ship];
const groupAssociation =
(groupPath && associations.groups[groupPath]) || undefined;
const group = (groupPath && groups[groupPath]) || undefined;
@ -75,8 +68,6 @@ export function GroupsPane(props: GroupsPaneProps) {
const popovers = (routeProps: RouteComponentProps, baseUrl: string) =>
( <>
{groupPath && ( <PopoverRoutes
contacts={groupContacts || {}}
rootIdentity={rootIdentity}
association={groupAssociation!}
group={group!}
api={api}
@ -202,12 +193,13 @@ export function GroupsPane(props: GroupsPaneProps) {
</title>
</Helmet>
<Skeleton
{...props}
mobileHide={shouldHideSidebar}
recentGroups={recentGroups}
baseUrl={baseUrl}
{...props}>
>
{ workspace.type === 'group' ? (
<GroupHome
<GroupHome
api={api}
baseUrl={baseUrl}
groupPath={groupPath}

View File

@ -1,27 +1,24 @@
import React, { useCallback } from "react";
import { ModalOverlay } from "~/views/components/ModalOverlay";
import { Formik, Form, FormikHelpers } from "formik";
import React, { useCallback } from 'react';
import { ModalOverlay } from '~/views/components/ModalOverlay';
import { Formik, Form, FormikHelpers } from 'formik';
import {
GroupFeedPermissions,
GroupFeedPermsInput,
} from "./Post/GroupFeedPerms";
import { Text, Button, Col, Row } from "@tlon/indigo-react";
import { AsyncButton } from "~/views/components/AsyncButton";
import GlobalApi from "~/logic/api/global";
import { resourceFromPath, Tag, resourceAsPath } from "@urbit/api";
import useGroupState, { useGroup } from "~/logic/state/group";
GroupFeedPermsInput
} from './Post/GroupFeedPerms';
import { Text, Button, Col, Row } from '@tlon/indigo-react';
import { AsyncButton } from '~/views/components/AsyncButton';
import GlobalApi from '~/logic/api/global';
import { resourceFromPath, Tag, resourceAsPath } from '@urbit/api';
import { useHistory } from 'react-router-dom';
import useMetadataState from "~/logic/state/metadata";
interface FormSchema {
permissions: GroupFeedPermissions;
permissions: any;
}
export function EnableGroupFeed(props: {
groupPath: string;
dismiss: () => void;
api: GlobalApi;
baseUrl: string;
}) {
const { api, groupPath, baseUrl } = props;
@ -31,9 +28,9 @@ export function EnableGroupFeed(props: {
};
const initialValues: FormSchema = {
permissions: "everyone",
permissions: 'everyone'
};
const onSubmit =
const onSubmit =
async (values: FormSchema, actions: FormikHelpers<FormSchema>) => {
const resource = resourceFromPath(groupPath);
const feed = resourceAsPath(

View File

@ -44,6 +44,7 @@ interface NewChannelProps {
api: GlobalApi;
group?: string;
workspace: Workspace;
baseUrl?: string;
}
export function NewChannel(props: NewChannelProps): ReactElement {
@ -118,7 +119,7 @@ export function NewChannel(props: NewChannelProps): ReactElement {
<Box
pb='3'
display={workspace?.type === 'messages' ? 'none' : ['block', 'none']}
onClick={() => history.push(props.baseUrl)}
onClick={() => history.push(props?.baseUrl ?? '/')}
>
<Text>{'<- Back'}</Text>
</Box>

View File

@ -2,8 +2,6 @@ import React, { useRef, useCallback, ReactElement } from 'react';
import { Route, Switch, RouteComponentProps, Link } from 'react-router-dom';
import { Box, Col, Text } from '@tlon/indigo-react';
import { GroupNotificationsConfig, Associations } from '@urbit/api';
import { Contacts, Contact } from '@urbit/api/contacts';
import { Group } from '@urbit/api/groups';
import { Association } from '@urbit/api/metadata';
@ -15,7 +13,6 @@ import { DeleteGroup } from './DeleteGroup';
import { resourceFromPath } from '~/logic/lib/group';
import { ModalOverlay } from '~/views/components/ModalOverlay';
import { SidebarItem } from '~/views/landscape/components/SidebarItem';
import { StorageState } from '~/types';
export function PopoverRoutes(
props: {
@ -23,8 +20,6 @@ export function PopoverRoutes(
group: Group;
association: Association;
api: GlobalApi;
notificationsGroupConfig: GroupNotificationsConfig;
rootIdentity: Contact;
} & RouteComponentProps
): ReactElement {
const relativeUrl = (url: string) => `${props.baseUrl}/popover${url}`;

View File

@ -15,7 +15,7 @@ import useGroupState from '~/logic/state/group';
import useContactState from '~/logic/state/contact';
import useHarkState from '~/logic/state/hark';
import useMetadataState from '~/logic/state/metadata';
import {Workspace} from '~/types';
import { Workspace } from '~/types';
type ResourceProps = StoreState & {
association: Association;
@ -25,23 +25,20 @@ type ResourceProps = StoreState & {
};
export function Resource(props: ResourceProps): ReactElement {
const { association, api, notificationsGraphConfig } = props;
const { association, api } = props;
const groups = useGroupState(state => state.groups);
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'];
const rid = association.resource;
const selectedGroup = association.group;
const relativePath = (p: string) =>
`${props.baseUrl}/resource/${app}${rid}${p}`;
const { resource: rid, group: selectedGroup } = association;
const relativePath = (p: string) => `${props.baseUrl}/resource/${app}${rid}${p}`;
const skelProps = { api, association, groups, contacts };
let title = props.association.metadata.title;
if ('workspace' in props) {
if ('group' in props.workspace && props.workspace.group in associations.groups) {
if ('group' in props.workspace && props.workspace.group in associations.groups) {
title = `${associations.groups[props.workspace.group].metadata.title} - ${props.association.metadata.title}`;
}
}
return (
<>
<Helmet defer={false}>

View File

@ -47,7 +47,7 @@ export function ResourceSkeleton(props: ResourceSkeletonProps): ReactElement {
? getItemTitle(association)
: association?.metadata?.title;
let recipient = "";
let recipient = '';
const contacts = useContactState(state => state.contacts);

View File

@ -6,13 +6,8 @@ import {
import GlobalApi from '~/logic/api/global';
import { GroupSwitcher } from '../GroupSwitcher';
import {
Associations,
Workspace,
Groups,
Invites,
Rolodex
} from '@urbit/api';
import { Workspace } from '~/types';
import { SidebarListConfig } from './types';
import { SidebarListHeader } from './SidebarListHeader';
import { useLocalStorageState } from '~/logic/lib/useLocalStorageState';
import { getGroupFromWorkspace } from '~/logic/lib/workspace';
@ -21,7 +16,6 @@ import { SidebarList } from './SidebarList';
import { roleForShip } from '~/logic/lib/group';
import { useTutorialModal } from '~/views/components/useTutorialModal';
import useGroupState from '~/logic/state/group';
import useMetadataState from '~/logic/state/metadata';
const ScrollbarLessCol = styled(Col)`
scrollbar-width: none !important;
@ -32,7 +26,6 @@ const ScrollbarLessCol = styled(Col)`
`;
interface SidebarProps {
children: ReactNode;
recentGroups: string[];
api: GlobalApi;
selected?: string;
@ -91,7 +84,6 @@ export function Sidebar(props: SidebarProps): ReactElement | null {
selected={selected || ''}
workspace={workspace}
api={props.api}
history={props.history}
/>
<SidebarList
config={config}

View File

@ -2,36 +2,20 @@ import React, { ReactElement, useRef } from 'react';
import urbitOb from 'urbit-ob';
import { Icon, Row, Box, Text, BaseImage } from '@tlon/indigo-react';
import { Groups, Association, Rolodex } from '@urbit/api';
import { Association } from '@urbit/api';
import { HoverBoxLink } from '~/views/components/HoverBox';
import { Sigil } from '~/logic/lib/sigil';
import { getModuleIcon, getItemTitle, uxToHex } from '~/logic/lib/util';
import { useTutorialModal } from '~/views/components/useTutorialModal';
import { TUTORIAL_HOST, TUTORIAL_GROUP } from '~/logic/lib/tutorialModal';
import { SidebarAppConfigs, SidebarItemStatus } from './types';
import { SidebarAppConfigs } from './types';
import { Workspace } from '~/types/workspace';
import useContactState from '~/logic/state/contact';
import useGroupState from '~/logic/state/group';
import useSettingsState, { selectCalmState } from '~/logic/state/settings';
import Dot from '~/views/components/Dot';
function SidebarItemIndicator(props: { status?: SidebarItemStatus }) {
switch (props.status) {
case 'disconnected':
return <Icon ml={2} fill="red" icon="X" />;
case 'unsubscribed':
return <Icon ml={2} icon="Circle" fill="gray" />;
case 'mention':
return <Icon ml={2} icon="Circle" />;
case 'loading':
return <Icon ml={2} icon="Bullet" />;
default:
return null;
}
}
// eslint-disable-next-line max-lines-per-function
export function SidebarItem(props: {
hideUnjoined: boolean;
@ -99,11 +83,11 @@ export function SidebarItem(props: {
return null;
}
let img = null;
let img: null | JSX.Element = null;
if (urbitOb.isValidPatp(title)) {
if (contacts?.[title]?.avatar && !hideAvatars) {
img = <BaseImage referrerPolicy="no-referrer" src={contacts[title].avatar} width='16px' height='16px' borderRadius={2} />;
img = <BaseImage referrerPolicy="no-referrer" src={contacts?.[title].avatar ?? ''} width='16px' height='16px' borderRadius={2} />;
} else {
img = <Sigil ship={title} color={`#${uxToHex(contacts?.[title]?.color || '0x0')}`} icon padding={2} size={16} />;
}
@ -137,7 +121,7 @@ export function SidebarItem(props: {
<Icon
display="block"
color={isSynced ? 'black' : 'lightGray'}
icon={getModuleIcon(mod) as any}
icon={getModuleIcon(mod)}
/>
)
}

View File

@ -15,7 +15,7 @@ import { Groups, Rolodex, Associations } from '@urbit/api';
import { FormikOnBlur } from '~/views/components/FormikOnBlur';
import { Dropdown } from '~/views/components/Dropdown';
import { SidebarListConfig } from './types';
import { SidebarListConfig } from './types';
import { getGroupFromWorkspace } from '~/logic/lib/workspace';
import { roleForShip } from '~/logic/lib/group';
import { NewChannel } from '~/views/landscape/components/NewChannel';
@ -32,7 +32,7 @@ export function SidebarListHeader(props: {
baseUrl: string;
selected: string;
workspace: Workspace;
handleSubmit: (c: SidebarListConfig) => void;
handleSubmit: (s: any) => void;
}): ReactElement {
const history = useHistory();
const onSubmit = useCallback(
@ -75,7 +75,7 @@ export function SidebarListHeader(props: {
borderBottom={1}
borderColor="lightGray"
backgroundColor={['transparent',
history.location.pathname.includes(`/~landscape${groupPath}/feed`)
history.location.pathname.includes(`/~landscape${groupPath}/feed`)
? (
'washedGray'
) : (

View File

@ -18,5 +18,5 @@ export interface SidebarAppConfig {
}
export type SidebarAppConfigs = {
[a in 'chat' | 'link' | 'publish']: SidebarAppConfig;
graph: SidebarAppConfig;
};

View File

@ -1,4 +1,4 @@
import React from 'react';
import React, { ReactElement } from 'react';
import { Row, Icon, Text } from '@tlon/indigo-react';
import { IconRef, PropFunc } from '~/types/util';

View File

@ -52,8 +52,7 @@ export function Skeleton(props: SkeletonProps): ReactElement {
baseUrl={props.baseUrl}
mobileHide={props.mobileHide}
workspace={props.workspace}
history={props.history}
/>
/>
</ErrorBoundary>
{props.children}
</Body>

View File

@ -43,7 +43,7 @@ export function TutorialModal(props: { api: GlobalApi }) {
const {
title,
description,
arrow,
arrow = 'North',
alignX,
alignY,
offsetX,

View File

@ -1,4 +1,4 @@
import React, { Component, useEffect, useCallback, ReactElement } from 'react';
import React, { useEffect, useCallback, ReactElement } from 'react';
import { Route, Switch, RouteComponentProps } from 'react-router-dom';
import Helmet from 'react-helmet';
@ -18,8 +18,7 @@ import { Loading } from '../components/Loading';
import { Workspace } from '~/types/workspace';
import GlobalSubscription from '~/logic/subscription/global';
import useGraphState from '~/logic/state/graph';
import useHarkState, { withHarkState } from '~/logic/state/hark';
import withState from '~/logic/lib/withState';
import useHarkState from '~/logic/state/hark';
import moment from 'moment';