mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-12-14 08:34:25 +03:00
notifications: surface pending DMs
This commit is contained in:
parent
bdf40b9deb
commit
c21151bde7
57
pkg/interface/src/views/apps/notifications/PendingDm.tsx
Normal file
57
pkg/interface/src/views/apps/notifications/PendingDm.tsx
Normal file
@ -0,0 +1,57 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import { Box, Col, Row, Text } from '@tlon/indigo-react';
|
||||
import { StatelessAsyncAction } from '~/views/components/StatelessAsyncAction';
|
||||
import Author from '~/views/components/Author';
|
||||
import GlobalApi from '~/logic/api/global';
|
||||
import { useHistory } from 'react-router';
|
||||
|
||||
export function PendingDm(props: { ship: string; api: GlobalApi }) {
|
||||
const { ship, api } = props;
|
||||
const { push } = useHistory();
|
||||
const onAccept = useCallback(async () => {
|
||||
await api.graph.acceptDm(ship);
|
||||
push(`/~landscape/messages/dm/${ship}`);
|
||||
}, [ship, push, api]);
|
||||
|
||||
const onDecline = useCallback(async () => {
|
||||
await api.graph.declineDm(ship);
|
||||
}, [ship, api]);
|
||||
|
||||
return (
|
||||
<Box
|
||||
display="grid"
|
||||
bg="washedGray"
|
||||
borderRadius="2"
|
||||
gridTemplateColumns={['1fr 24px', '1fr 200px']}
|
||||
gridTemplateRows="auto"
|
||||
gridTemplateAreas="'header actions' 'main main'"
|
||||
p={2}
|
||||
m={2}
|
||||
>
|
||||
<Row alignItems="center" gridArea="header">
|
||||
<Author ship={ship} />
|
||||
<Text ml="1" lineHeight="tall">
|
||||
invited you to a DM
|
||||
</Text>
|
||||
</Row>
|
||||
<Row
|
||||
alignItems="center"
|
||||
gapX="2"
|
||||
gridArea="actions"
|
||||
justifyContent="flex-end"
|
||||
>
|
||||
<StatelessAsyncAction height="auto" primary p="1" onClick={onAccept}>
|
||||
Accept
|
||||
</StatelessAsyncAction>
|
||||
<StatelessAsyncAction
|
||||
height="auto"
|
||||
destructive
|
||||
p="1"
|
||||
onClick={onDecline}
|
||||
>
|
||||
Decline
|
||||
</StatelessAsyncAction>
|
||||
</Row>
|
||||
</Box>
|
||||
);
|
||||
}
|
@ -286,19 +286,22 @@ export function GraphNotification(props: {
|
||||
|
||||
const authors = _.uniq(_.map(contents, "author"));
|
||||
const singleAuthor = authors.length === 1;
|
||||
const { graph, group } = index;
|
||||
const association = useAssocForGraph(graph)!;
|
||||
const dm = isDm(graph);
|
||||
const { graph, mark } = index;
|
||||
const association = useAssocForGraph(graph);
|
||||
const dm = mark === 'graph-validator-dm';
|
||||
const desc = describeNotification(
|
||||
index.description,
|
||||
contents.length !== 1,
|
||||
dm,
|
||||
singleAuthor
|
||||
);
|
||||
const groupAssociation = useAssocForGroup(association?.group);
|
||||
const groupAssociation = useAssocForGroup(association?.group ?? "");
|
||||
const groups = useGroupState((state) => state.groups);
|
||||
|
||||
const onClick = useCallback(() => {
|
||||
if(!association) {
|
||||
history.push(`/~landscape/messages/dm/~${authors[0]}`);
|
||||
}
|
||||
if (
|
||||
!(
|
||||
(index.description === "note" || index.description === "link") &&
|
||||
@ -343,7 +346,7 @@ export function GraphNotification(props: {
|
||||
<GraphNodes
|
||||
hideAuthors={hideAuthors}
|
||||
posts={contents.slice(0, 4)}
|
||||
mod={index.module}
|
||||
mod={index.mark}
|
||||
description={index.description}
|
||||
index={contents?.[0].index}
|
||||
association={association}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { ReactElement, ReactNode } from 'react';
|
||||
import _ from 'lodash';
|
||||
|
||||
import { Col, Box, Text } from '@tlon/indigo-react';
|
||||
import { Col, Box, Text, Row } from '@tlon/indigo-react';
|
||||
import {
|
||||
Invites as IInvites,
|
||||
Associations,
|
||||
@ -11,7 +11,7 @@ import {
|
||||
Contacts,
|
||||
AppInvites,
|
||||
JoinProgress,
|
||||
JoinRequest
|
||||
JoinRequest,
|
||||
} from '@urbit/api';
|
||||
|
||||
import GlobalApi from '~/logic/api/global';
|
||||
@ -19,6 +19,8 @@ import { resourceAsPath, alphabeticalOrder } from '~/logic/lib/util';
|
||||
import InviteItem from '~/views/components/Invite';
|
||||
import useInviteState from '~/logic/state/invite';
|
||||
import useGroupState from '~/logic/state/group';
|
||||
import useGraphState from '~/logic/state/graph';
|
||||
import {PendingDm} from './PendingDm';
|
||||
|
||||
interface InvitesProps {
|
||||
api: GlobalApi;
|
||||
@ -33,7 +35,9 @@ interface InviteRef {
|
||||
|
||||
export function Invites(props: InvitesProps): ReactElement {
|
||||
const { api } = props;
|
||||
const invites = useInviteState(state => state.invites);
|
||||
const invites = useInviteState((state) => state.invites);
|
||||
|
||||
const pendingDms = useGraphState((s) => s.pendingDms);
|
||||
|
||||
const inviteArr: InviteRef[] = _.reduce(
|
||||
invites,
|
||||
@ -54,24 +58,27 @@ export function Invites(props: InvitesProps): ReactElement {
|
||||
|
||||
const invitesAndStatus: { [rid: string]: JoinRequest | InviteRef } = {
|
||||
..._.keyBy(inviteArr, ({ invite }) => resourceAsPath(invite.resource)),
|
||||
...pendingJoin
|
||||
...pendingJoin,
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
{[...pendingDms].map((ship) => (
|
||||
<PendingDm key={ship} api={api} ship={`~${ship}`} />
|
||||
))}
|
||||
{Object.keys(invitesAndStatus)
|
||||
.sort(alphabeticalOrder)
|
||||
.map((resource) => {
|
||||
const inviteOrStatus = invitesAndStatus[resource];
|
||||
const join = pendingJoin[resource];
|
||||
if ('progress' in inviteOrStatus) {
|
||||
return (
|
||||
<InviteItem
|
||||
key={resource}
|
||||
resource={resource}
|
||||
api={api}
|
||||
pendingJoin={join}
|
||||
/>
|
||||
return (
|
||||
<InviteItem
|
||||
key={resource}
|
||||
resource={resource}
|
||||
api={api}
|
||||
pendingJoin={join}
|
||||
/>
|
||||
);
|
||||
} else {
|
||||
const { app, uid, invite } = inviteOrStatus;
|
||||
@ -86,8 +93,7 @@ export function Invites(props: InvitesProps): ReactElement {
|
||||
/>
|
||||
);
|
||||
}
|
||||
})
|
||||
}
|
||||
})}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import { LoadingSpinner, Action } from '@tlon/indigo-react';
|
||||
|
||||
interface AsyncActionProps {
|
||||
children: ReactNode;
|
||||
name: string;
|
||||
name?: string;
|
||||
disabled?: boolean;
|
||||
onClick: (e: React.MouseEvent) => Promise<void>;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user