Merge pull request #5080 from urbit/lf/invite-flow

Invites: fix dismissal, style pass
This commit is contained in:
matildepark 2021-07-06 21:35:24 -04:00 committed by GitHub
commit 26e8a55b8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 136 additions and 43 deletions

View File

@ -127,8 +127,13 @@
++ hide ++ hide
|= rid=resource |= rid=resource
^- (quip card _state) ^- (quip card _state)
=/ =request:view (~(got by joining) rid)
?: ?=(final:view progress.request)
=. joining (~(del by joining) rid)
:_ state
(fact:io group-view-update+!>(`update:view`[%initial joining]) /all ~)^~
:- (fact:io group-view-update+!>([%hide rid]) /all ~)^~ :- (fact:io group-view-update+!>([%hide rid]) /all ~)^~
state(joining (~(jab by joining) rid |=(request:view +<(hidden %.y)))) state(joining (~(put by joining) rid request(hidden %.y)))
:: ::
++ has-joined ++ has-joined
|= rid=resource |= rid=resource
@ -160,7 +165,7 @@
++ tx-progress ++ tx-progress
|= =progress:view |= =progress:view
=. joining =. joining
(~(jab by joining) rid |=(request:view +<(progress progress))) (~(jab by joining) rid |=(req=request:view req(progress progress)))
=; =cage =; =cage
(emit (fact:io cage /all tx+(en-path:resource rid) ~)) (emit (fact:io cage /all tx+(en-path:resource rid) ~))
group-view-update+!>([%progress rid progress]) group-view-update+!>([%progress rid progress])
@ -217,10 +222,11 @@
?> ?=(%poke-ack -.sign) ?> ?=(%poke-ack -.sign)
?^ p.sign ?^ p.sign
(cleanup %no-perms) (cleanup %no-perms)
=> %- emit =. jn-core
%+ poke-our:(jn-pass-io /pull-groups) %group-pull-hook (tx-progress %added)
pull-hook-action+!>([%add ship rid]) %- emit
(tx-progress %added) %+ poke-our:(jn-pass-io /pull-groups) %group-pull-hook
pull-hook-action+!>([%add ship rid])
:: ::
%pull-groups %pull-groups
?> ?=(%poke-ack -.sign) ?> ?=(%poke-ack -.sign)
@ -324,7 +330,6 @@
|= =progress:view |= =progress:view
=. jn-core =. jn-core
(tx-progress progress) (tx-progress progress)
=. joining (~(del by joining) rid)
=. jn-core =. jn-core
(emit (leave-our:(jn-pass-io /groups) %group-store)) (emit (leave-our:(jn-pass-io /groups) %group-store))
(emit (leave-our:(jn-pass-io /md) %metadata-store)) (emit (leave-our:(jn-pass-io /md) %metadata-store))

View File

@ -51,7 +51,7 @@ export const decorators = [
color: '0x26.3e0f', color: '0x26.3e0f',
groups: [], groups: [],
}, },
'~sampel-palnet': { '~sampel-palnet': {
status: 'A test status', status: 'A test status',
'last-updated': 1616609090555, 'last-updated': 1616609090555,
avatar: null, avatar: null,
@ -60,7 +60,7 @@ export const decorators = [
nickname: 'You', nickname: 'You',
color: '0x26.3e0f', color: '0x26.3e0f',
groups: [], groups: [],
} },
}, },
}); });
@ -133,6 +133,47 @@ export const decorators = [
}, },
}, },
}, },
previews: {
'/ship/~bollug-worlus/urbit-index': {
group: '/ship/~bollug-worlus/urbit-index',
channels: {
'/ship/~darrux-landes/index-weekly': {
metadata: {
preview: false,
vip: '',
title: 'Index Weekly',
description: '',
creator: '~bollug-worlus',
picture: '',
hidden: false,
config: {
graph: 'publish',
},
'date-created': '~2020.4.6..21.53.30..dc68',
color: '0x0',
},
'app-name': 'graph',
resource: '/ship/~bollug-worlus/index-weekly',
group: '/ship/~bollug-worlus/urbit-index',
},
},
members: 1237,
metadata: {
preview: false,
vip: '',
title: 'Urbit Index',
description: '',
creator: '~bollug-worlus',
picture: '',
hidden: false,
config: {
group: null,
},
'date-created': '~2020.4.6..21.53.30..dc68',
color: '0x0',
},
},
},
}); });
useContactState.setState({ useContactState.setState({

View File

@ -0,0 +1,42 @@
import React from 'react';
import { Meta, Story } from '@storybook/react';
import { Box } from '@tlon/indigo-react';
import { InviteItem, InviteItemProps } from '~/views/components/Invite';
import { JoinProgress } from '@urbit/api/groups';
export default {
title: 'Notifications/Invite',
component: InviteItem
} as Meta;
const Template: Story<InviteItemProps> = args => (
<Box backgroundColor="white" p="0" maxWidth="90%" width="fit-content">
<InviteItem {...args} />
</Box>
);
const pendingJoin = (progress: JoinProgress) => ({
hidden: false,
started: Date.now() - 3600,
ship: '~haddef-sigwen',
progress
});
export const Pending = Template.bind({});
Pending.args = {
pendingJoin: pendingJoin('start'),
resource: '/ship/~bollug-worlus/urbit-index'
};
export const Errored = Template.bind({});
Errored.args = {
pendingJoin: pendingJoin('no-perms'),
resource: '/ship/~bollug-worlus/urbit-index'
};
export const Done = Template.bind({});
Done.args = {
pendingJoin: pendingJoin('done'),
resource: '/ship/~bollug-worlus/urbit-index'
};

View File

@ -1,16 +1,16 @@
import { css } from '@styled-system/css'; import { css } from '@styled-system/css';
import { import { Box, Icon, LoadingSpinner, Row, Text } from '@tlon/indigo-react';
Box,
Icon,
LoadingSpinner, Row, Text
} from '@tlon/indigo-react';
import { import {
accept, accept,
decline, decline,
hideGroup, hideGroup,
Invite, join, joinProgress, Invite,
join,
joinProgress,
joinResult,
JoinRequest, JoinRequest,
Metadata, MetadataUpdatePreview, Metadata,
MetadataUpdatePreview,
resourceFromPath resourceFromPath
} from '@urbit/api'; } from '@urbit/api';
import { GraphConfig } from '@urbit/api'; import { GraphConfig } from '@urbit/api';
@ -81,9 +81,13 @@ function inviteUrl(hidden: boolean, resource: string, metadata?: Metadata) {
} }
if ((metadata?.config as GraphConfig).graph === 'chat') { if ((metadata?.config as GraphConfig).graph === 'chat') {
return `/~landscape/messages/resource/${(metadata?.config as GraphConfig)?.graph}${resource}`; return `/~landscape/messages/resource/${
(metadata?.config as GraphConfig)?.graph
}${resource}`;
} else { } else {
return `/~landscape/home/resource/${(metadata?.config as GraphConfig)?.graph}${resource}`; return `/~landscape/home/resource/${
(metadata?.config as GraphConfig)?.graph
}${resource}`;
} }
} }
function InviteMetadata(props: { function InviteMetadata(props: {
@ -136,18 +140,20 @@ function InviteStatus(props: { status?: JoinRequest }) {
const current = status && joinProgress.indexOf(status.progress); const current = status && joinProgress.indexOf(status.progress);
const desc = _.isNumber(current) && description[current]; const desc = _.isNumber(current) && description[current];
return ( return (
<Row gapX={1} alignItems="center" height={4}> <Row gapX={2} alignItems="center" minHeight={4}>
{ status.progress === 'done' ? <Icon icon="Checkmark" /> : <LoadingSpinner dark /> } <Row alignItems="center" flexShrink={0}>
{joinResult.includes(status?.progress as any) ? (
<Icon icon={status?.progress === 'done' ? 'Checkmark' : 'X'} />
) : (
<LoadingSpinner dark />
)}
</Row>
<Text gray>{desc}</Text> <Text gray>{desc}</Text>
</Row> </Row>
); );
} }
export function useInviteAccept( export function useInviteAccept(resource: string, app?: string, uid?: string) {
resource: string,
app?: string,
uid?: string
) {
const { ship, name } = resourceFromPath(resource); const { ship, name } = resourceFromPath(resource);
const history = useHistory(); const history = useHistory();
const associations = useMetadataState(s => s.associations); const associations = useMetadataState(s => s.associations);
@ -205,7 +211,6 @@ function InviteActions(props: {
}) { }) {
const { status, resource, app, uid } = props; const { status, resource, app, uid } = props;
const inviteAccept = useInviteAccept(resource, app, uid); const inviteAccept = useInviteAccept(resource, app, uid);
const set = useGroupState(s => s.set);
const inviteDecline = useCallback(async () => { const inviteDecline = useCallback(async () => {
if (!(app && uid)) { if (!(app && uid)) {
@ -214,17 +219,9 @@ function InviteActions(props: {
await airlock.poke(decline(app, uid)); await airlock.poke(decline(app, uid));
}, [app, uid]); }, [app, uid]);
const hideJoin = useCallback(async (e) => { const hideJoin = useCallback(async () => {
if(status?.progress === 'done') {
set((s) => {
// @ts-ignore investigate zustand types
delete s.pendingJoin[resource];
});
e.stopPropagation();
return;
}
await airlock.poke(hideGroup(resource)); await airlock.poke(hideGroup(resource));
}, [resource, status]); }, [resource]);
if (status) { if (status) {
return ( return (
@ -234,7 +231,9 @@ function InviteActions(props: {
backgroundColor="white" backgroundColor="white"
onClick={hideJoin} onClick={hideJoin}
> >
{status?.progress === 'done' ? 'Dismiss' : 'Cancel'} {[...joinResult].includes(status?.progress as any)
? 'Dismiss'
: 'Cancel'}
</StatelessAsyncButton> </StatelessAsyncButton>
</Row> </Row>
); );
@ -288,9 +287,10 @@ export function GroupInvite(props: GroupInviteProps): ReactElement {
: { description: `invited you to a ${invitedTo}`, authors: [invite!.ship] }; : { description: `invited you to a ${invitedTo}`, authors: [invite!.ship] };
const onClick = () => { const onClick = () => {
if(status?.progress === 'done') { if (status?.progress === 'done') {
const redir = inviteUrl(app !== 'groups', resource, graphAssoc?.metadata); const redir = inviteUrl(app !== 'groups', resource, graphAssoc?.metadata);
if(redir) { if (redir) {
airlock.poke(hideGroup(resource));
history.push(redir); history.push(redir);
} }
} }
@ -299,10 +299,15 @@ export function GroupInvite(props: GroupInviteProps): ReactElement {
return ( return (
<NotificationWrapper> <NotificationWrapper>
<Header content {...headerProps} /> <Header content {...headerProps} />
<Row onClick={onClick} height={[null, 4]} alignItems="flex-start" gridArea="main"> <Row
<Elbow mx={2} /> onClick={onClick}
height={[null, 4]}
alignItems="flex-start"
gridArea="main"
>
<Elbow display={['none', 'block']} mx={2} />
<ResponsiveRow <ResponsiveRow
gapXY={[1, 2]} gapXY={2}
height={[null, 4]} height={[null, 4]}
alignItems={['flex-start', 'center']} alignItems={['flex-start', 'center']}
> >

View File

@ -4,7 +4,7 @@ import React from 'react';
import { usePreview } from '~/logic/state/metadata'; import { usePreview } from '~/logic/state/metadata';
import { GroupInvite } from './Group'; import { GroupInvite } from './Group';
interface InviteItemProps { export interface InviteItemProps {
invite?: Invite; invite?: Invite;
resource: string; resource: string;
pendingJoin?: JoinRequest; pendingJoin?: JoinRequest;