From abd7e7f85390f0271ff087b446c5eb3a37d0b17e Mon Sep 17 00:00:00 2001 From: Patrick O'Sullivan Date: Tue, 22 Mar 2022 15:16:16 -0500 Subject: [PATCH 1/3] groups: Handle notifs received without links (like group updates) --- .../src/logic/lib/notificationRedirects.ts | 56 +++++++++++++------ pkg/interface/src/logic/state/metadata.ts | 4 +- .../views/apps/notifications/notification.tsx | 30 ++++++---- .../views/landscape/components/Content.tsx | 4 +- 4 files changed, 62 insertions(+), 32 deletions(-) diff --git a/pkg/interface/src/logic/lib/notificationRedirects.ts b/pkg/interface/src/logic/lib/notificationRedirects.ts index dbd3fb469..a63319f86 100644 --- a/pkg/interface/src/logic/lib/notificationRedirects.ts +++ b/pkg/interface/src/logic/lib/notificationRedirects.ts @@ -1,27 +1,33 @@ import useMetadataState from '../state/metadata'; import ob from 'urbit-ob'; import useInviteState from '../state/invite'; -import { deSig, resourceAsPath } from '@urbit/api'; +import { deSig, Notification, resourceAsPath } from '@urbit/api'; import { createJoinParams } from '~/views/landscape/components/Join/Join'; function getGroupResourceRedirect(key: string) { const graphs = useMetadataState.getState().associations.graph; const association = graphs[`/ship/${key}`]; - if(!association || !('graph' in association.metadata.config)) { + if (!association || !('graph' in association.metadata.config)) { return ''; } - const section = association.group === association.resource ? '/messages' : association.group; + const section = + association.group === association.resource + ? '/messages' + : association.group; return `/~landscape${section}/resource/${association.metadata.config.graph}${association.resource}`; } function getPostRedirect(key: string, segs: string[]) { - const association = useMetadataState.getState().associations.graph[`/ship/${key}`]; + const association = + useMetadataState.getState().associations.graph[`/ship/${key}`]; const { metadata } = association; - if(!association || !('graph' in metadata.config)) { + if (!association || !('graph' in metadata.config)) { return ''; } - return `/~landscape${association.group}/feed/thread/${segs.slice(0, -1).join('/')}`; + return `/~landscape${association.group}/feed/thread/${segs + .slice(0, -1) + .join('/')}`; } function getChatRedirect(chat: string, segs: string[]) { @@ -31,7 +37,7 @@ function getChatRedirect(chat: string, segs: string[]) { function getPublishRedirect(graphKey: string, segs: string[]) { const base = getGroupResourceRedirect(graphKey); - if(segs.length === 3) { + if (segs.length === 3) { return `${base}/note/${segs[0]}`; } else if (segs.length === 4) { return `${base}/note/${segs[0]}?selected=${segs[2]}`; @@ -41,7 +47,7 @@ function getPublishRedirect(graphKey: string, segs: string[]) { function getLinkRedirect(graphKey: string, segs: string[]) { const base = getGroupResourceRedirect(graphKey); - if(segs.length === 1) { + if (segs.length === 1) { return `${base}/index/${segs[0]}`; } else if (segs.length === 3) { return `${base}/index/${segs[0]}?selected=${segs[1]}`; @@ -50,9 +56,9 @@ function getLinkRedirect(graphKey: string, segs: string[]) { } function getGraphRedirect(link: string) { - const [,mark, ship, name, ...rest] = link.split('/'); + const [, mark, ship, name, ...rest] = link.split('/'); const graphKey = `${ship}/${name}`; - switch(mark) { + switch (mark) { case 'graph-validator-dm': return `/~landscape/messages/dm/${ob.patp(rest[0])}`; case 'graph-validator-chat': @@ -60,18 +66,18 @@ function getGraphRedirect(link: string) { case 'graph-validator-publish': return getPublishRedirect(graphKey, rest); case 'graph-validator-link': - return getLinkRedirect(graphKey, rest); + return getLinkRedirect(graphKey, rest); case 'graph-validator-post': return getPostRedirect(graphKey, rest); default: - return''; + return ''; } } function getInviteRedirect(link: string) { - const [,,app,uid] = link.split('/'); + const [, , app, uid] = link.split('/'); const invite = useInviteState.getState().invites[app][uid]; - if(!invite || (app !== 'groups' && app !== 'graph')) { + if (!invite || (app !== 'groups' && app !== 'graph')) { return ''; } @@ -86,16 +92,16 @@ function getInviteRedirect(link: string) { } function getDmRedirect(link: string) { - const [,,ship] = link.split('/'); + const [, , ship] = link.split('/'); return `/~landscape/messages/dm/${ship}`; } function getGroupRedirect(link: string) { - const [,,ship,name] = link.split('/'); + const [, , ship, name] = link.split('/'); return `/~landscape/ship/${ship}/${name}`; } -export function getNotificationRedirect(link: string) { - if(link.startsWith('/graph-validator')) { +export function getNotificationRedirectFromLink(link: string) { + if (link.startsWith('/graph-validator')) { return getGraphRedirect(link); } else if (link.startsWith('/invite')) { return getInviteRedirect(link); @@ -105,3 +111,17 @@ export function getNotificationRedirect(link: string) { return getGroupRedirect(link); } } + +export function getNotificationRedirectFromPlacePath( + notification: Notification +) { + const placePath = notification.bin.place.path; + switch (notification.bin.path) { + case '/add-members': + return `/~landscape/ship${placePath}`; + case '/remove-members': + return `/~landscape/ship${placePath}`; + default: + return undefined; + } +} diff --git a/pkg/interface/src/logic/state/metadata.ts b/pkg/interface/src/logic/state/metadata.ts index 59a144d26..67d9b2926 100644 --- a/pkg/interface/src/logic/state/metadata.ts +++ b/pkg/interface/src/logic/state/metadata.ts @@ -9,7 +9,7 @@ import { import airlock from '~/logic/api'; import history from '~/logic/lib/history'; import { reduce } from '../reducers/metadata-update'; -import { getNotificationRedirect } from '../lib/notificationRedirects'; +import { getNotificationRedirectFromLink } from '../lib/notificationRedirects'; export const METADATA_MAX_PREVIEW_WAIT = 150000; @@ -127,7 +127,7 @@ function handleGridRedirect() { const query = new URLSearchParams(window.location.search); if(query.has('grid-note')) { - history.push(getNotificationRedirect(query.get('grid-note'))); + history.push(getNotificationRedirectFromLink(query.get('grid-note'))); } else if(query.has('grid-link')) { const link = decodeURIComponent(query.get('grid-link')!); history.push(`/perma${link}`); diff --git a/pkg/interface/src/views/apps/notifications/notification.tsx b/pkg/interface/src/views/apps/notifications/notification.tsx index d55895e90..065caa83e 100644 --- a/pkg/interface/src/views/apps/notifications/notification.tsx +++ b/pkg/interface/src/views/apps/notifications/notification.tsx @@ -17,7 +17,10 @@ import { map, take, uniqBy } from 'lodash'; import { Mention } from '~/views/components/MentionText'; import { PropFunc } from '~/types'; import { useHistory } from 'react-router-dom'; -import { getNotificationRedirect } from '~/logic/lib/notificationRedirects'; +import { + getNotificationRedirectFromLink, + getNotificationRedirectFromPlacePath +} from '~/logic/lib/notificationRedirects'; export interface NotificationProps { notification: INotification; @@ -44,7 +47,11 @@ const NotificationText = ({ contents, ...rest }: NotificationTextProps) => { /> ); } - return {content.text}; + return ( + + {content.text} + + ); })} ); @@ -59,7 +66,7 @@ export function Notification(props: { const key = `${harkLidToId(lid)}-${harkBinToId(notification.bin)}`; const history = useHistory(); - const isMobile = useLocalState(s => s.mobile); + const isMobile = useLocalState((s) => s.mobile); const onArchive = useCallback( async (e) => { @@ -73,10 +80,8 @@ export function Notification(props: { ); const { hovering, bind } = useHovering(); - const dedupedBody = uniqBy(notification.body, item => item.link); - const contents = map(dedupedBody, 'content').filter( - c => c.length > 0 - ); + const dedupedBody = uniqBy(notification.body, (item) => item.link); + const contents = map(dedupedBody, 'content').filter((c) => c.length > 0); const first = notification.body[0]; if (!first) { // should be unreachable @@ -84,9 +89,14 @@ export function Notification(props: { } const onClick = (e: any) => { - const redirect = getNotificationRedirect(first.link); - if(redirect) { - history.push(redirect); + console.log({ notification }); + const redirectFromLink = getNotificationRedirectFromLink(first.link); + const redirectFromPlacePath = + getNotificationRedirectFromPlacePath(notification); + if (redirectFromLink) { + history.push(redirectFromLink); + } else if (redirectFromPlacePath) { + history.push(redirectFromPlacePath); } else { console.log('no redirect'); } diff --git a/pkg/interface/src/views/landscape/components/Content.tsx b/pkg/interface/src/views/landscape/components/Content.tsx index 5cad1730a..1bb93f2ea 100644 --- a/pkg/interface/src/views/landscape/components/Content.tsx +++ b/pkg/interface/src/views/landscape/components/Content.tsx @@ -8,7 +8,7 @@ import { useShortcut } from '~/logic/state/settings'; import { Loading } from '~/views/components/Loading'; import LaunchApp from '~/views/apps/launch/App'; -import { getNotificationRedirect } from '~/logic/lib/notificationRedirects'; +import { getNotificationRedirectFromLink } from '~/logic/lib/notificationRedirects'; import { JoinRoute } from './Join/Join'; import useInviteState from '~/logic/state/invite'; import useMetadataState from '~/logic/state/metadata'; @@ -38,7 +38,7 @@ export const Content = () => { return; } if(query.has('grid-note')) { - history.push(getNotificationRedirect(query.get('grid-note')!)); + history.push(getNotificationRedirectFromLink(query.get('grid-note')!)); } else if(query.has('grid-link')) { const link = decodeURIComponent(query.get('grid-link')!); history.push(`/perma${link}`); From 0a62aa8f22791a0e413bffe113e309f610e37a1c Mon Sep 17 00:00:00 2001 From: Patrick O'Sullivan Date: Tue, 22 Mar 2022 15:17:29 -0500 Subject: [PATCH 2/3] groups: Fix left notifications --- pkg/landscape/app/hark-group-hook.hoon | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/landscape/app/hark-group-hook.hoon b/pkg/landscape/app/hark-group-hook.hoon index 5b0f3912f..04dfcd31b 100644 --- a/pkg/landscape/app/hark-group-hook.hoon +++ b/pkg/landscape/app/hark-group-hook.hoon @@ -44,7 +44,7 @@ ^- (quip card _this) `this(state !<(state-0 old)) :: -++ on-watch +++ on-watch |= =path ?. ?=([%updates ~] path) (on-watch:def path) @@ -148,7 +148,7 @@ :: ++ add-unread |= [=bin:store =body:store] - ^- card + ^- card =- [%pass / %agent [our.bowl %hark-store] %poke -] :- %hark-action !> ^- action:store @@ -188,7 +188,7 @@ :: %remove-members :- ~ - :* (snoc ships text+(rap 3 ' joined ' title.u.meta ~)) + :* (snoc ships text+(rap 3 ' left ' title.u.meta ~)) ~ now.bowl / From dfcc0bf7c3ab70c970d1a8ec074a5d6103a29dc2 Mon Sep 17 00:00:00 2001 From: Patrick O'Sullivan Date: Tue, 22 Mar 2022 15:20:16 -0500 Subject: [PATCH 3/3] groups: remove debug statement --- pkg/interface/src/views/apps/notifications/notification.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/interface/src/views/apps/notifications/notification.tsx b/pkg/interface/src/views/apps/notifications/notification.tsx index 065caa83e..bde0c00de 100644 --- a/pkg/interface/src/views/apps/notifications/notification.tsx +++ b/pkg/interface/src/views/apps/notifications/notification.tsx @@ -89,7 +89,6 @@ export function Notification(props: { } const onClick = (e: any) => { - console.log({ notification }); const redirectFromLink = getNotificationRedirectFromLink(first.link); const redirectFromPlacePath = getNotificationRedirectFromPlacePath(notification);