Merge pull request #5655 from urbit/po/fix-user-joined-group-notification

Po/fix user joined group notification
This commit is contained in:
Patrick O'Sullivan 2022-03-23 09:10:01 -05:00 committed by GitHub
commit dbf89717af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 64 additions and 35 deletions

View File

@ -1,27 +1,33 @@
import useMetadataState from '../state/metadata'; import useMetadataState from '../state/metadata';
import ob from 'urbit-ob'; import ob from 'urbit-ob';
import useInviteState from '../state/invite'; 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'; import { createJoinParams } from '~/views/landscape/components/Join/Join';
function getGroupResourceRedirect(key: string) { function getGroupResourceRedirect(key: string) {
const graphs = useMetadataState.getState().associations.graph; const graphs = useMetadataState.getState().associations.graph;
const association = graphs[`/ship/${key}`]; const association = graphs[`/ship/${key}`];
if(!association || !('graph' in association.metadata.config)) { if (!association || !('graph' in association.metadata.config)) {
return ''; 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}`; return `/~landscape${section}/resource/${association.metadata.config.graph}${association.resource}`;
} }
function getPostRedirect(key: string, segs: string[]) { 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; const { metadata } = association;
if(!association || !('graph' in metadata.config)) { if (!association || !('graph' in metadata.config)) {
return ''; 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[]) { function getChatRedirect(chat: string, segs: string[]) {
@ -31,7 +37,7 @@ function getChatRedirect(chat: string, segs: string[]) {
function getPublishRedirect(graphKey: string, segs: string[]) { function getPublishRedirect(graphKey: string, segs: string[]) {
const base = getGroupResourceRedirect(graphKey); const base = getGroupResourceRedirect(graphKey);
if(segs.length === 3) { if (segs.length === 3) {
return `${base}/note/${segs[0]}`; return `${base}/note/${segs[0]}`;
} else if (segs.length === 4) { } else if (segs.length === 4) {
return `${base}/note/${segs[0]}?selected=${segs[2]}`; return `${base}/note/${segs[0]}?selected=${segs[2]}`;
@ -41,7 +47,7 @@ function getPublishRedirect(graphKey: string, segs: string[]) {
function getLinkRedirect(graphKey: string, segs: string[]) { function getLinkRedirect(graphKey: string, segs: string[]) {
const base = getGroupResourceRedirect(graphKey); const base = getGroupResourceRedirect(graphKey);
if(segs.length === 1) { if (segs.length === 1) {
return `${base}/index/${segs[0]}`; return `${base}/index/${segs[0]}`;
} else if (segs.length === 3) { } else if (segs.length === 3) {
return `${base}/index/${segs[0]}?selected=${segs[1]}`; return `${base}/index/${segs[0]}?selected=${segs[1]}`;
@ -50,9 +56,9 @@ function getLinkRedirect(graphKey: string, segs: string[]) {
} }
function getGraphRedirect(link: string) { function getGraphRedirect(link: string) {
const [,mark, ship, name, ...rest] = link.split('/'); const [, mark, ship, name, ...rest] = link.split('/');
const graphKey = `${ship}/${name}`; const graphKey = `${ship}/${name}`;
switch(mark) { switch (mark) {
case 'graph-validator-dm': case 'graph-validator-dm':
return `/~landscape/messages/dm/${ob.patp(rest[0])}`; return `/~landscape/messages/dm/${ob.patp(rest[0])}`;
case 'graph-validator-chat': case 'graph-validator-chat':
@ -60,18 +66,18 @@ function getGraphRedirect(link: string) {
case 'graph-validator-publish': case 'graph-validator-publish':
return getPublishRedirect(graphKey, rest); return getPublishRedirect(graphKey, rest);
case 'graph-validator-link': case 'graph-validator-link':
return getLinkRedirect(graphKey, rest); return getLinkRedirect(graphKey, rest);
case 'graph-validator-post': case 'graph-validator-post':
return getPostRedirect(graphKey, rest); return getPostRedirect(graphKey, rest);
default: default:
return''; return '';
} }
} }
function getInviteRedirect(link: string) { function getInviteRedirect(link: string) {
const [,,app,uid] = link.split('/'); const [, , app, uid] = link.split('/');
const invite = useInviteState.getState().invites[app][uid]; const invite = useInviteState.getState().invites[app][uid];
if(!invite || (app !== 'groups' && app !== 'graph')) { if (!invite || (app !== 'groups' && app !== 'graph')) {
return ''; return '';
} }
@ -86,16 +92,16 @@ function getInviteRedirect(link: string) {
} }
function getDmRedirect(link: string) { function getDmRedirect(link: string) {
const [,,ship] = link.split('/'); const [, , ship] = link.split('/');
return `/~landscape/messages/dm/${ship}`; return `/~landscape/messages/dm/${ship}`;
} }
function getGroupRedirect(link: string) { function getGroupRedirect(link: string) {
const [,,ship,name] = link.split('/'); const [, , ship, name] = link.split('/');
return `/~landscape/ship/${ship}/${name}`; return `/~landscape/ship/${ship}/${name}`;
} }
export function getNotificationRedirect(link: string) { export function getNotificationRedirectFromLink(link: string) {
if(link.startsWith('/graph-validator')) { if (link.startsWith('/graph-validator')) {
return getGraphRedirect(link); return getGraphRedirect(link);
} else if (link.startsWith('/invite')) { } else if (link.startsWith('/invite')) {
return getInviteRedirect(link); return getInviteRedirect(link);
@ -105,3 +111,17 @@ export function getNotificationRedirect(link: string) {
return getGroupRedirect(link); 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;
}
}

View File

@ -9,7 +9,7 @@ import {
import airlock from '~/logic/api'; import airlock from '~/logic/api';
import history from '~/logic/lib/history'; import history from '~/logic/lib/history';
import { reduce } from '../reducers/metadata-update'; import { reduce } from '../reducers/metadata-update';
import { getNotificationRedirect } from '../lib/notificationRedirects'; import { getNotificationRedirectFromLink } from '../lib/notificationRedirects';
export const METADATA_MAX_PREVIEW_WAIT = 150000; export const METADATA_MAX_PREVIEW_WAIT = 150000;
@ -127,7 +127,7 @@ function handleGridRedirect() {
const query = new URLSearchParams(window.location.search); const query = new URLSearchParams(window.location.search);
if(query.has('grid-note')) { 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')) { } else if(query.has('grid-link')) {
const link = decodeURIComponent(query.get('grid-link')!); const link = decodeURIComponent(query.get('grid-link')!);
history.push(`/perma${link}`); history.push(`/perma${link}`);

View File

@ -17,7 +17,10 @@ import { map, take, uniqBy } from 'lodash';
import { Mention } from '~/views/components/MentionText'; import { Mention } from '~/views/components/MentionText';
import { PropFunc } from '~/types'; import { PropFunc } from '~/types';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { getNotificationRedirect } from '~/logic/lib/notificationRedirects'; import {
getNotificationRedirectFromLink,
getNotificationRedirectFromPlacePath
} from '~/logic/lib/notificationRedirects';
export interface NotificationProps { export interface NotificationProps {
notification: INotification; notification: INotification;
@ -44,7 +47,11 @@ const NotificationText = ({ contents, ...rest }: NotificationTextProps) => {
/> />
); );
} }
return <Text key={idx} {...rest}>{content.text}</Text>; return (
<Text key={idx} {...rest}>
{content.text}
</Text>
);
})} })}
</> </>
); );
@ -59,7 +66,7 @@ export function Notification(props: {
const key = `${harkLidToId(lid)}-${harkBinToId(notification.bin)}`; const key = `${harkLidToId(lid)}-${harkBinToId(notification.bin)}`;
const history = useHistory(); const history = useHistory();
const isMobile = useLocalState(s => s.mobile); const isMobile = useLocalState((s) => s.mobile);
const onArchive = useCallback( const onArchive = useCallback(
async (e) => { async (e) => {
@ -73,10 +80,8 @@ export function Notification(props: {
); );
const { hovering, bind } = useHovering(); const { hovering, bind } = useHovering();
const dedupedBody = uniqBy(notification.body, item => item.link); const dedupedBody = uniqBy(notification.body, (item) => item.link);
const contents = map(dedupedBody, 'content').filter( const contents = map(dedupedBody, 'content').filter((c) => c.length > 0);
c => c.length > 0
);
const first = notification.body[0]; const first = notification.body[0];
if (!first) { if (!first) {
// should be unreachable // should be unreachable
@ -84,9 +89,13 @@ export function Notification(props: {
} }
const onClick = (e: any) => { const onClick = (e: any) => {
const redirect = getNotificationRedirect(first.link); const redirectFromLink = getNotificationRedirectFromLink(first.link);
if(redirect) { const redirectFromPlacePath =
history.push(redirect); getNotificationRedirectFromPlacePath(notification);
if (redirectFromLink) {
history.push(redirectFromLink);
} else if (redirectFromPlacePath) {
history.push(redirectFromPlacePath);
} else { } else {
console.log('no redirect'); console.log('no redirect');
} }

View File

@ -8,7 +8,7 @@ import { useShortcut } from '~/logic/state/settings';
import { Loading } from '~/views/components/Loading'; import { Loading } from '~/views/components/Loading';
import LaunchApp from '~/views/apps/launch/App'; 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 { JoinRoute } from './Join/Join';
import useInviteState from '~/logic/state/invite'; import useInviteState from '~/logic/state/invite';
import useMetadataState from '~/logic/state/metadata'; import useMetadataState from '~/logic/state/metadata';
@ -38,7 +38,7 @@ export const Content = () => {
return; return;
} }
if(query.has('grid-note')) { 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')) { } else if(query.has('grid-link')) {
const link = decodeURIComponent(query.get('grid-link')!); const link = decodeURIComponent(query.get('grid-link')!);
history.push(`/perma${link}`); history.push(`/perma${link}`);

View File

@ -44,7 +44,7 @@
^- (quip card _this) ^- (quip card _this)
`this(state !<(state-0 old)) `this(state !<(state-0 old))
:: ::
++ on-watch ++ on-watch
|= =path |= =path
?. ?=([%updates ~] path) ?. ?=([%updates ~] path)
(on-watch:def path) (on-watch:def path)
@ -148,7 +148,7 @@
:: ::
++ add-unread ++ add-unread
|= [=bin:store =body:store] |= [=bin:store =body:store]
^- card ^- card
=- [%pass / %agent [our.bowl %hark-store] %poke -] =- [%pass / %agent [our.bowl %hark-store] %poke -]
:- %hark-action :- %hark-action
!> ^- action:store !> ^- action:store
@ -188,7 +188,7 @@
:: ::
%remove-members %remove-members
:- ~ :- ~
:* (snoc ships text+(rap 3 ' joined ' title.u.meta ~)) :* (snoc ships text+(rap 3 ' left ' title.u.meta ~))
~ ~
now.bowl now.bowl
/ /