mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-12-01 03:23:09 +03:00
Merge pull request #5080 from urbit/lf/invite-flow
Invites: fix dismissal, style pass
This commit is contained in:
commit
26e8a55b8c
@ -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))
|
||||||
|
@ -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({
|
||||||
|
42
pkg/interface/src/stories/Invite.stories.tsx
Normal file
42
pkg/interface/src/stories/Invite.stories.tsx
Normal 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'
|
||||||
|
};
|
@ -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']}
|
||||||
>
|
>
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user