From 7cc2ab50224e8ae42501f4cd68c8d5638c650240 Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Thu, 21 Oct 2021 15:23:08 -0500 Subject: [PATCH 1/6] docket: +add-fact after %site install The fact used to be generated before we updated the state to reflect the new status of the charge. Moves fact creation after the state is updated, ensuring that %site desks will install properly inside the web interface --- pkg/garden/app/docket.hoon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/garden/app/docket.hoon b/pkg/garden/app/docket.hoon index 386c05ca49..7321694b8d 100644 --- a/pkg/garden/app/docket.hoon +++ b/pkg/garden/app/docket.hoon @@ -232,8 +232,8 @@ :: if the new chad is a site, we're instantly done :: ?: ?=(%site -.href.docket) - :- ~[add-fact:cha] =. charges (new-chad:cha %site ~) + :- ~[add-fact:cha] state :: =. by-base (~(put by by-base) base.href.docket desk) From 494793ba3cdad5c7c4135c6280438e5c07687cb5 Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Thu, 21 Oct 2021 15:38:52 -0500 Subject: [PATCH 2/6] interface: fix reactivity in SidebarList Fixes urbit/landscape#1262 --- .../views/landscape/components/Sidebar/SidebarList.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/interface/src/views/landscape/components/Sidebar/SidebarList.tsx b/pkg/interface/src/views/landscape/components/Sidebar/SidebarList.tsx index 3763fdcf20..ce9b24345b 100644 --- a/pkg/interface/src/views/landscape/components/Sidebar/SidebarList.tsx +++ b/pkg/interface/src/views/landscape/components/Sidebar/SidebarList.tsx @@ -1,5 +1,5 @@ import React, { ReactElement, useCallback } from 'react'; -import { Associations, Graph } from '@urbit/api'; +import { Associations, Graph, Unreads } from '@urbit/api'; import { patp, patp2dec } from 'urbit-ob'; import _ from 'lodash'; @@ -13,9 +13,8 @@ import useMetadataState from '~/logic/state/metadata'; import { useHistory } from 'react-router'; import { useShortcut } from '~/logic/state/settings'; -function sidebarSort(pending: Set): Record number> { +function sidebarSort(unreads: Unreads, pending: Set): Record number> { const { associations } = useMetadataState.getState(); - const { unreads } = useHarkState.getState(); const alphabetical = (a: string, b: string) => { const aAssoc = associations[a]; const bAssoc = associations[b]; @@ -102,9 +101,10 @@ export function SidebarList(props: { const inbox = useInbox(); const graphKeys = useGraphState(s => s.graphKeys); const pending = useGraphState(s => s.pendingDms); + const unreads = useHarkState(s => s.unreads); const ordered = getItems(associations, workspace, inbox, pending) - .sort(sidebarSort(pending)[config.sortBy]); + .sort(sidebarSort(unreads, pending)[config.sortBy]); const history = useHistory(); From 5fc81149bf2152930bab365091c0135aa820b09d Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Thu, 21 Oct 2021 15:57:09 -0500 Subject: [PATCH 3/6] grid: always show treaty info if we have it Fixes urbit/landscape#1259 --- pkg/grid/src/components/AppInfo.tsx | 9 ++++++--- pkg/grid/src/components/VatMeta.tsx | 7 +------ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/pkg/grid/src/components/AppInfo.tsx b/pkg/grid/src/components/AppInfo.tsx index 2bd227699f..c68d5191ac 100644 --- a/pkg/grid/src/components/AppInfo.tsx +++ b/pkg/grid/src/components/AppInfo.tsx @@ -8,7 +8,7 @@ import { Dialog, DialogClose, DialogContent, DialogTrigger } from './Dialog'; import { DocketHeader } from './DocketHeader'; import { Spinner } from './Spinner'; import { VatMeta } from './VatMeta'; -import useDocketState, { ChargeWithDesk } from '../state/docket'; +import useDocketState, { ChargeWithDesk, useTreaty } from '../state/docket'; import { getAppHref } from '../state/util'; import { addRecentApp } from '../nav/search/Home'; import { TreatyMeta } from './TreatyMeta'; @@ -52,6 +52,7 @@ export const AppInfo: FC = ({ docket, vat, className }) => { const [ship, desk] = getRemoteDesk(docket, vat); const publisher = vat?.arak?.rail?.publisher ?? ship; const [copied, setCopied] = useState(false); + const treaty = useTreaty(ship, desk); const installApp = async () => { if (installStatus === 'installed') { @@ -135,18 +136,20 @@ export const AppInfo: FC = ({ docket, vat, className }) => { +
{vat ? ( <>
) : null} - {'chad' in docket ? null : ( + {!treaty ? null : ( <>
- + )}
+ ); }; diff --git a/pkg/grid/src/components/VatMeta.tsx b/pkg/grid/src/components/VatMeta.tsx index 16de34dd70..a3f92a6147 100644 --- a/pkg/grid/src/components/VatMeta.tsx +++ b/pkg/grid/src/components/VatMeta.tsx @@ -10,14 +10,9 @@ export function VatMeta(props: { vat: Vat }) { const { desk: foreignDesk, ship, next } = arak.rail || {}; const pluralUpdates = next?.length !== 1; + console.log(cass); return (
- - {ship}/{foreignDesk} - - - {moment(cass.da).format('YYYY.MM.DD')} - {hash} From c147bbad1f08459b1d10c8c5102d87f7013fba7b Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Mon, 25 Oct 2021 11:41:55 -0500 Subject: [PATCH 4/6] interface: fixup dead code, typecheck --- pkg/interface/src/logic/lib/hark.ts | 97 ------ pkg/interface/src/logic/lib/notification.ts | 21 -- pkg/interface/src/logic/state/hark.ts | 2 +- .../src/views/apps/notifications/graph.tsx | 302 ------------------ .../src/views/apps/notifications/group.tsx | 61 ---- pkg/interface/src/views/components/Author.tsx | 2 +- .../src/views/components/Comments.tsx | 5 +- .../src/views/components/Invite/Group.tsx | 5 +- .../landscape/components/Sidebar/Apps.tsx | 51 --- 9 files changed, 7 insertions(+), 539 deletions(-) delete mode 100644 pkg/interface/src/logic/lib/notification.ts delete mode 100644 pkg/interface/src/views/apps/notifications/graph.tsx delete mode 100644 pkg/interface/src/views/apps/notifications/group.tsx delete mode 100644 pkg/interface/src/views/landscape/components/Sidebar/Apps.tsx diff --git a/pkg/interface/src/logic/lib/hark.ts b/pkg/interface/src/logic/lib/hark.ts index 5bc73e4397..6e10ec2794 100644 --- a/pkg/interface/src/logic/lib/hark.ts +++ b/pkg/interface/src/logic/lib/hark.ts @@ -1,18 +1,12 @@ import { cite, - GraphNotifIndex, - GroupNotifIndex, - IndexedNotification, NotificationGraphConfig, Post, Unreads } from '@urbit/api'; -import { patp } from 'urbit-ob'; import bigInt, { BigInteger } from 'big-integer'; import _ from 'lodash'; import f from 'lodash/fp'; -import { pluralize } from './util'; -import useMetadataState from '../state/metadata'; import { emptyHarkStats } from '../state/hark'; export function getLastSeen( @@ -60,94 +54,3 @@ export function isWatching( ); } -export function getNotificationKey( - time: BigInteger, - notification: IndexedNotification -): string { - const base = time.toString(); - if ('graph' in notification.index) { - const { graph, index, description } = notification.index.graph; - return `${base}-${graph}-${index}-${description}`; - } else if ('group' in notification.index) { - const { group } = notification.index.group; - return `${base}-${group}`; - } - return `${base}-unknown`; -} - -export function notificationReferent(not: IndexedNotification) { - if ('graph' in not.index) { - return not.index.graph.graph; - } else { - return not.index.group.group; - } -} -export function describeNotification(notification: IndexedNotification) { - function group(idx: GroupNotifIndex) { - switch (idx.description) { - case 'add-members': - return 'joined'; - case 'remove-members': - return 'left'; - default: - return idx.description; - } - } - function graph(idx: GraphNotifIndex, plural: boolean, singleAuthor: boolean) { - const isDm = idx.graph === `/ship/~${window.ship}/dm-inbox`; - if (isDm) { - return 'New DM from '; - } - switch (idx.description) { - case 'post': - return 'Your post received replies in'; - case 'link': - return `New link${plural ? 's' : ''} in`; - case 'comment': - return `New comment${plural ? 's' : ''} on`; - case 'note': - return `New Note${plural ? 's' : ''} in`; - // @ts-ignore need better types - case 'edit-note': - return `updated ${pluralize('note', plural)} in`; - case 'mention': - return 'You were mentioned in'; - case 'message': - if (isDm) { - return 'messaged you'; - } - return `New message${plural ? 's' : ''} in`; - default: return idx.description; - } - } - if ('group' in notification.index) { - return group(notification.index.group); - } else if ('graph' in notification.index) { - // @ts-ignore needs better type guard - const contents = notification.notification?.contents?.graph ?? ([] as Post[]); - return graph( - notification.index.graph, - contents.length > 1, - _.uniq(_.map(contents, 'author')).length === 1 - ); - } -} - -export function getReferent(notification: IndexedNotification) { - const meta = useMetadataState.getState(); - if ('graph' in notification.index) { - if (notification.index.graph.graph === `/ship/~${window.ship}/dm-inbox`) { - const [, ship] = notification.index.graph.index.split('/'); - return cite(patp(ship)); - } - return ( - meta.associations.graph[notification.index.graph.graph]?.metadata - ?.title ?? notification.index.graph - ); - } else if ('group' in notification.index) { - return ( - meta.associations.groups[notification.index.group.group]?.metadata?.title ?? - notification.index.group.group - ); - } -} diff --git a/pkg/interface/src/logic/lib/notification.ts b/pkg/interface/src/logic/lib/notification.ts deleted file mode 100644 index 7514d1e0c7..0000000000 --- a/pkg/interface/src/logic/lib/notification.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { GraphNotificationContents, GraphNotifIndex } from '@urbit/api'; - -export function getParentIndex( - idx: GraphNotifIndex, - contents: GraphNotificationContents -) { - const origIndex = contents[0].index.slice(1).split('/'); - const ret = (i: string[]) => `/${i.join('/')}`; - switch (idx.description) { - case 'link': - return '/'; - case 'comment': - return ret(origIndex.slice(0, 1)); - case 'note': - return '/'; - case 'mention': - return undefined; - default: - return undefined; - } -} diff --git a/pkg/interface/src/logic/state/hark.ts b/pkg/interface/src/logic/state/hark.ts index beafa14535..d3e276a9e8 100644 --- a/pkg/interface/src/logic/state/hark.ts +++ b/pkg/interface/src/logic/state/hark.ts @@ -42,6 +42,7 @@ export interface HarkState { notificationsGroupConfig: string[]; unreads: Unreads; archiveNote: (bin: HarkBin, lid: HarkLid) => Promise; + readCount: (path: string) => Promise; } const useHarkState = createState( @@ -171,5 +172,4 @@ export function useHarkGraphIndex(graph: string, index: string) { ); } -window.hark = useHarkState.getState; export default useHarkState; diff --git a/pkg/interface/src/views/apps/notifications/graph.tsx b/pkg/interface/src/views/apps/notifications/graph.tsx deleted file mode 100644 index 4822df165b..0000000000 --- a/pkg/interface/src/views/apps/notifications/graph.tsx +++ /dev/null @@ -1,302 +0,0 @@ -import { Box, Col, Icon, Row, Text } from '@tlon/indigo-react'; -import { Association, GraphNotificationContents, GraphNotifIndex, Post } from '@urbit/api'; -import { BigInteger } from 'big-integer'; -import { patp } from 'urbit-ob'; -import _ from 'lodash'; -import React, { useCallback } from 'react'; -import { Link, useHistory } from 'react-router-dom'; -import styled from 'styled-components'; -import { pluralize } from '~/logic/lib/util'; -import useGroupState from '~/logic/state/group'; -import { - useAssocForGraph, - useAssocForGroup -} from '~/logic/state/metadata'; -import Author from '~/views/components/Author'; -import { GraphContent } from '~/views/landscape/components/Graph/GraphContent'; -import { Header } from './header'; - -const TruncBox = styled(Box)<{ truncate?: number }>` - -webkit-line-clamp: ${p => p.truncate ?? 'unset'}; - display: -webkit-box; - overflow: hidden; - -webkit-box-orient: vertical; - color: ${p => p.theme.colors.black}; -`; - -function describeNotification( - description: string, - plural: boolean, - isDm: boolean, - singleAuthor: boolean -): string { - switch (description) { - case 'post': - return singleAuthor ? 'replied to you' : 'Your post received replies'; - case 'link': - return `New link${plural ? 's' : ''} in`; - case 'comment': - return `New comment${plural ? 's' : ''} on`; - case 'note': - return `New Note${plural ? 's' : ''} in`; - case 'edit-note': - return `updated ${pluralize('note', plural)} in`; - case 'mention': - return singleAuthor ? 'mentioned you in' : 'You were mentioned in'; - case 'message': - if (isDm) { - return 'messaged you'; - } - return `New message${plural ? 's' : ''} in`; - default: - return description; - } -} - -function ContentSummary({ icon, name, author, to }) { - return ( - - - - - - {name} - - - - - by - - - - - - ); -} - -export const GraphNodeContent = ({ post, mod, index, hidden, association }) => { - const { contents } = post; - const idx = index.slice(1).split('/'); - const url = getNodeUrl(mod, hidden, association?.group, association?.resource, index); - if (mod === 'graph-validator-link' && idx.length === 1) { - const [{ text: title }] = contents; - return ( - - ); - } - if (mod === 'graph-validator-publish' && idx[1] === '1') { - const [{ text: title }] = contents; - return ( - - ); - } - return ( - - - - ); -}; - -function getNodeUrl( - mod: string, - hidden: boolean, - groupPath: string, - graph: string, - index: string -) { - const graphValidator = 'graph-validator-'; - const rmValidator = mod.slice(graphValidator.length); - if (hidden && mod === 'graph-validator-chat') { - groupPath = '/messages'; - } else if (hidden) { - groupPath = '/home'; - } - const graphUrl = `/~landscape${groupPath}/resource/${rmValidator}${graph}`; - const idx = index.slice(1).split('/'); - if (mod === 'graph-validator-publish') { - const [noteId, kind, commId] = idx; - const selected = kind === '2' ? `?selected=${commId}` : ''; - return `${graphUrl}/note/${noteId}${selected}`; - } else if (mod === 'graph-validator-link') { - const [linkId, commId] = idx; - return `${graphUrl}/index/${linkId}${commId ? `?selected=${commId}` : ''}`; - } else if (mod === 'graph-validator-chat') { - if (idx.length > 0) { - return `${graphUrl}?msg=${idx[0]}`; - } - return graphUrl; - } else if (mod === 'graph-validator-post') { - return `/~landscape${groupPath}/feed/thread${index}`; - } else if (mod === 'graph-validator-dm') { - return `/~landscape${groupPath}/dm/${patp(idx[0])}`; - } - return ''; -} - -interface PostsByAuthor { - author: string; - posts: Post[]; -} -const GraphNodes = (props: { - posts: Post[]; - hideAuthors?: boolean; - index: string; - mod: string; - association: Association; - hidden: boolean; -}) => { - const { - posts, - mod, - hidden, - index, - hideAuthors = false, - association - } = props; - - const postsByConsecAuthor = _.reduce( - posts, - (acc: PostsByAuthor[], val: Post, key: number) => { - const lent = acc.length; - if (lent > 0 && acc?.[lent - 1]?.author === val.author) { - const last = acc[lent - 1]; - const rest = acc.slice(0, -1); - return [...rest, { ...last, posts: [...last.posts, val] }]; - } - return [...acc, { author: val.author, posts: [val] }]; - }, - [] - ); - - return ( - <> - {_.map(postsByConsecAuthor, ({ posts, author }, idx) => { - const time = posts[0]?.['time-sent']; - return ( - - {!hideAuthors && ( - - )} - - {_.map(posts, post => ( -