mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-11-28 19:55:53 +03:00
interface: dismiss join on view
This commit is contained in:
parent
fd64a627c3
commit
c91784d3bf
@ -1,9 +1,9 @@
|
||||
import { Col, Row, Text, Icon } from '@tlon/indigo-react';
|
||||
import { Metadata } from '@urbit/api';
|
||||
import React, { ReactElement, ReactNode } from 'react';
|
||||
import { PropFunc, IconRef } from '~/types';
|
||||
import { MetadataIcon } from './MetadataIcon';
|
||||
import { useCopy } from '~/logic/lib/useCopy';
|
||||
import { Col, Row, Text, Icon } from "@tlon/indigo-react";
|
||||
import { Metadata } from "@urbit/api";
|
||||
import React, { ReactElement, ReactNode } from "react";
|
||||
import { PropFunc, IconRef } from "~/types";
|
||||
import { MetadataIcon } from "./MetadataIcon";
|
||||
import { useCopy } from "~/logic/lib/useCopy";
|
||||
interface GroupSummaryProps {
|
||||
metadata: Metadata;
|
||||
memberCount: number;
|
||||
@ -28,11 +28,12 @@ export function GroupSummary(
|
||||
} = props;
|
||||
const { doCopy, copyDisplay } = useCopy(
|
||||
`web+urbitgraph://group${resource?.slice(5)}`,
|
||||
'Copy',
|
||||
'Checkmark'
|
||||
"Copy",
|
||||
"Checkmark"
|
||||
);
|
||||
|
||||
return (
|
||||
<Col {...rest} gapY={4} maxWidth={['100%', '288px']}>
|
||||
<Col {...rest} gapY={4} maxWidth={["100%", "288px"]}>
|
||||
<Row gapX={2} width="100%">
|
||||
<MetadataIcon
|
||||
width="40px"
|
||||
@ -53,9 +54,9 @@ export function GroupSummary(
|
||||
{props?.AllowCopy && (
|
||||
<Icon
|
||||
color="gray"
|
||||
icon={props?.locked ? 'Locked' : (copyDisplay as IconRef)}
|
||||
icon={props?.locked ? "Locked" : (copyDisplay as IconRef)}
|
||||
onClick={!props?.locked ? doCopy : null}
|
||||
cursor={props?.locked ? 'default' : 'pointer'}
|
||||
cursor={props?.locked ? "default" : "pointer"}
|
||||
/>
|
||||
)}
|
||||
</Row>
|
||||
@ -69,8 +70,8 @@ export function GroupSummary(
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row width="100%">
|
||||
{metadata.description && (
|
||||
{metadata.description.length > 0 && (
|
||||
<Row width="100%">
|
||||
<Text
|
||||
gray
|
||||
width="100%"
|
||||
@ -80,8 +81,8 @@ export function GroupSummary(
|
||||
>
|
||||
{metadata.description}
|
||||
</Text>
|
||||
)}
|
||||
</Row>
|
||||
</Row>
|
||||
)}
|
||||
{children}
|
||||
</Col>
|
||||
);
|
||||
|
@ -2,6 +2,7 @@ import { readGroup } from '@urbit/api';
|
||||
import _ from 'lodash';
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
import Helmet from 'react-helmet';
|
||||
import { Box } from '@tlon/indigo-react';
|
||||
import {
|
||||
Route,
|
||||
RouteComponentProps, Switch
|
||||
@ -26,6 +27,7 @@ import { PopoverRoutes } from './PopoverRoutes';
|
||||
import { Resource } from './Resource';
|
||||
import { Skeleton } from './Skeleton';
|
||||
import airlock from '~/logic/api';
|
||||
import {Join, JoinRoute} from './Join';
|
||||
|
||||
interface GroupsPaneProps {
|
||||
baseUrl: string;
|
||||
@ -59,6 +61,13 @@ export function GroupsPane(props: GroupsPaneProps) {
|
||||
if (workspace.type !== 'group') {
|
||||
return;
|
||||
}
|
||||
const { pendingJoin, doneJoin } = useGroupState.getState();
|
||||
const group = getGroupFromWorkspace(workspace)!;
|
||||
if(group in pendingJoin) {
|
||||
doneJoin(group);
|
||||
}
|
||||
|
||||
|
||||
return () => {
|
||||
setRecentGroups(gs => _.uniq([workspace.group, ...gs]));
|
||||
};
|
||||
@ -175,7 +184,31 @@ export function GroupsPane(props: GroupsPaneProps) {
|
||||
</>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
/>
|
||||
<Route
|
||||
path={relativePath('/pending/:ship/:name')}
|
||||
render={(routeProps) => {
|
||||
const { ship, name } = routeProps.match.params as Record<string, string>;
|
||||
const desc = {
|
||||
group: `/ship/${ship}/${name}`,
|
||||
kind: 'graph' as const
|
||||
};
|
||||
return (<Skeleton
|
||||
mobileHide
|
||||
recentGroups={recentGroups}
|
||||
{...props}
|
||||
baseUrl={baseUrl}
|
||||
>
|
||||
<Box width="100%">
|
||||
<Join desc={desc} />
|
||||
</Box>
|
||||
</Skeleton>
|
||||
)
|
||||
|
||||
|
||||
}}
|
||||
>
|
||||
</Route>
|
||||
<Route
|
||||
path={relativePath('/new')}
|
||||
render={(routeProps) => {
|
||||
|
@ -13,11 +13,12 @@ import Dot from '~/views/components/Dot';
|
||||
import { useHarkDm, useHarkStat } from '~/logic/state/hark';
|
||||
import useSettingsState from '~/logic/state/settings';
|
||||
import useGraphState from '~/logic/state/graph';
|
||||
import {usePreview} from '~/logic/state/metadata';
|
||||
|
||||
function useAssociationStatus(resource: string) {
|
||||
const [, , ship, name] = resource.split('/');
|
||||
const [, , ship, name] = resource.split("/");
|
||||
const graphKey = `${deSig(ship)}/${name}`;
|
||||
const isSubscribed = useGraphState(s => s.graphKeys.has(graphKey));
|
||||
const isSubscribed = useGraphState((s) => s.graphKeys.has(graphKey));
|
||||
const stats = useHarkStat(`/graph/~${graphKey}`);
|
||||
const { count, each } = stats;
|
||||
const hasNotifications = false;
|
||||
@ -43,6 +44,7 @@ function SidebarItemBase(props: {
|
||||
title: string | ReactNode;
|
||||
mono?: boolean;
|
||||
pending?: boolean;
|
||||
onClick?: () => void;
|
||||
}) {
|
||||
const {
|
||||
title,
|
||||
@ -53,22 +55,24 @@ function SidebarItemBase(props: {
|
||||
hasUnread,
|
||||
isSynced = false,
|
||||
mono = false,
|
||||
pending = false
|
||||
pending = false,
|
||||
onClick
|
||||
} = props;
|
||||
const color = isSynced
|
||||
? hasUnread || hasNotification
|
||||
? 'black'
|
||||
: 'gray'
|
||||
: 'lightGray';
|
||||
? "black"
|
||||
: "gray"
|
||||
: "lightGray";
|
||||
|
||||
const fontWeight = hasUnread || hasNotification ? '500' : 'normal';
|
||||
const fontWeight = hasUnread || hasNotification ? "500" : "normal";
|
||||
|
||||
return (
|
||||
<HoverBoxLink
|
||||
// ref={anchorRef}
|
||||
to={to}
|
||||
bg={pending ? 'lightBlue' : 'white'}
|
||||
bgActive={pending ? 'washedBlue' : 'washedGray'}
|
||||
onClick={onClick}
|
||||
bg={pending ? "lightBlue" : "white"}
|
||||
bgActive={pending ? "washedBlue" : "washedGray"}
|
||||
width="100%"
|
||||
display="flex"
|
||||
justifyContent="space-between"
|
||||
@ -108,7 +112,7 @@ function SidebarItemBase(props: {
|
||||
mono={mono}
|
||||
color={color}
|
||||
fontWeight={fontWeight}
|
||||
style={{ textOverflow: 'ellipsis', whiteSpace: 'pre' }}
|
||||
style={{ textOverflow: "ellipsis", whiteSpace: "pre" }}
|
||||
>
|
||||
{title}
|
||||
</Text>
|
||||
@ -118,156 +122,201 @@ function SidebarItemBase(props: {
|
||||
);
|
||||
}
|
||||
|
||||
export const SidebarDmItem = React.memo((props: {
|
||||
ship: string;
|
||||
selected?: boolean;
|
||||
workspace: Workspace;
|
||||
pending?: boolean;
|
||||
}) => {
|
||||
const { ship, selected = false, pending = false } = props;
|
||||
const contact = useContact(ship);
|
||||
const { hideAvatars, hideNicknames } = useSettingsState(s => s.calm);
|
||||
const title =
|
||||
!hideNicknames && contact?.nickname
|
||||
? contact?.nickname
|
||||
: cite(ship) ?? ship;
|
||||
const { count, each } = useHarkDm(ship);
|
||||
const unreads = count + each.length;
|
||||
const img =
|
||||
contact?.avatar && !hideAvatars ? (
|
||||
<BaseImage
|
||||
referrerPolicy="no-referrer"
|
||||
src={contact.avatar}
|
||||
width="16px"
|
||||
height="16px"
|
||||
borderRadius={2}
|
||||
/>
|
||||
) : (
|
||||
<Sigil
|
||||
ship={ship}
|
||||
color={`#${uxToHex(contact?.color || '0x0')}`}
|
||||
icon
|
||||
padding={2}
|
||||
size={16}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<SidebarItemBase
|
||||
selected={selected}
|
||||
hasNotification={false}
|
||||
hasUnread={(unreads as number) > 0}
|
||||
to={`/~landscape/messages/dm/${ship}`}
|
||||
title={title}
|
||||
mono={hideAvatars || !contact?.nickname}
|
||||
isSynced
|
||||
pending={pending}
|
||||
>
|
||||
{img}
|
||||
</SidebarItemBase>
|
||||
);
|
||||
});
|
||||
// eslint-disable-next-line max-lines-per-function
|
||||
export const SidebarAssociationItem = React.memo((props: {
|
||||
hideUnjoined: boolean;
|
||||
association: Association;
|
||||
export const SidebarPendingItem = (props: {
|
||||
path: string;
|
||||
selected: boolean;
|
||||
workspace: Workspace;
|
||||
}) => {
|
||||
const { association, selected } = props;
|
||||
const title = getItemTitle(association) || '';
|
||||
const appName = association?.['app-name'];
|
||||
let mod: string = appName;
|
||||
if (association?.metadata?.config && 'graph' in association.metadata.config) {
|
||||
mod = association.metadata.config.graph ;
|
||||
}
|
||||
const rid = association?.resource;
|
||||
const groupPath = association?.group;
|
||||
const group = useGroupState(state => state.groups[groupPath]);
|
||||
const { hideNicknames } = useSettingsState(s => s.calm);
|
||||
const contacts = useContactState(s => s.contacts);
|
||||
const isUnmanaged = group?.hidden || false;
|
||||
const DM = isUnmanaged && props.workspace?.type === 'messages';
|
||||
const itemStatus = useAssociationStatus(rid);
|
||||
const hasNotification = itemStatus === 'notification';
|
||||
const hasUnread = itemStatus === 'unread';
|
||||
const isSynced = itemStatus !== 'unsubscribed';
|
||||
let baseUrl = `/~landscape${groupPath}`;
|
||||
|
||||
if (DM) {
|
||||
baseUrl = '/~landscape/messages';
|
||||
} else if (isUnmanaged) {
|
||||
baseUrl = '/~landscape/home';
|
||||
}
|
||||
|
||||
const to = isSynced
|
||||
? `${baseUrl}/resource/${mod}${rid}`
|
||||
: `${baseUrl}/join/${mod}${rid}`;
|
||||
|
||||
if (props.hideUnjoined && !isSynced) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const participantNames = (str: string) => {
|
||||
const color = isSynced
|
||||
? hasUnread || hasNotification
|
||||
? 'black'
|
||||
: 'gray'
|
||||
: 'lightGray';
|
||||
if (_.includes(str, ',') && _.startsWith(str, '~')) {
|
||||
const names = _.split(str, ', ');
|
||||
return names.map((name, idx) => {
|
||||
if (urbitOb.isValidPatp(name)) {
|
||||
if (contacts[name]?.nickname && !hideNicknames)
|
||||
return (
|
||||
<Text key={name} bold={hasUnread} color={color}>
|
||||
{contacts[name]?.nickname}
|
||||
{idx + 1 != names.length ? ', ' : null}
|
||||
</Text>
|
||||
);
|
||||
return (
|
||||
<Text key={name} mono bold={hasUnread} color={color}>
|
||||
{name}
|
||||
<Text color={color}>{idx + 1 != names.length ? ', ' : null}</Text>
|
||||
</Text>
|
||||
);
|
||||
} else {
|
||||
return name;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return str;
|
||||
}
|
||||
};
|
||||
|
||||
const { path, selected } = props;
|
||||
const { preview, error } = usePreview(path);
|
||||
const color = `#${uxToHex(preview?.metadata?.color || "0x0")}`;
|
||||
const title = preview?.metadata?.title || path;
|
||||
const to = `/~landscape/messages/pending/${path.slice(6)}`;
|
||||
return (
|
||||
<SidebarItemBase
|
||||
to={to}
|
||||
title={title}
|
||||
selected={selected}
|
||||
hasUnread={hasUnread}
|
||||
isSynced={isSynced}
|
||||
title={
|
||||
DM && !urbitOb.isValidPatp(title) ? participantNames(title) : title
|
||||
}
|
||||
hasNotification={hasNotification}
|
||||
hasNotification={false}
|
||||
hasUnread={false}
|
||||
pending
|
||||
>
|
||||
{DM ? (
|
||||
<Box
|
||||
flexShrink={0}
|
||||
height={16}
|
||||
width={16}
|
||||
borderRadius={2}
|
||||
backgroundColor={
|
||||
`#${uxToHex(props?.association?.metadata?.color)}` || '#000000'
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<Icon
|
||||
display="block"
|
||||
color={isSynced ? 'black' : 'lightGray'}
|
||||
icon={getModuleIcon(mod as any)}
|
||||
/>
|
||||
)}
|
||||
<Box
|
||||
flexShrink={0}
|
||||
height={16}
|
||||
width={16}
|
||||
borderRadius={2}
|
||||
backgroundColor={color}
|
||||
/>
|
||||
</SidebarItemBase>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export const SidebarDmItem = React.memo(
|
||||
(props: {
|
||||
ship: string;
|
||||
selected?: boolean;
|
||||
workspace: Workspace;
|
||||
pending?: boolean;
|
||||
}) => {
|
||||
const { ship, selected = false, pending = false } = props;
|
||||
const contact = useContact(ship);
|
||||
const { hideAvatars, hideNicknames } = useSettingsState((s) => s.calm);
|
||||
const title =
|
||||
!hideNicknames && contact?.nickname
|
||||
? contact?.nickname
|
||||
: cite(ship) ?? ship;
|
||||
const { count, each } = useHarkDm(ship);
|
||||
const unreads = count + each.length;
|
||||
const img =
|
||||
contact?.avatar && !hideAvatars ? (
|
||||
<BaseImage
|
||||
referrerPolicy="no-referrer"
|
||||
src={contact.avatar}
|
||||
width="16px"
|
||||
height="16px"
|
||||
borderRadius={2}
|
||||
/>
|
||||
) : (
|
||||
<Sigil
|
||||
ship={ship}
|
||||
color={`#${uxToHex(contact?.color || "0x0")}`}
|
||||
icon
|
||||
padding={2}
|
||||
size={16}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<SidebarItemBase
|
||||
selected={selected}
|
||||
hasNotification={false}
|
||||
hasUnread={(unreads as number) > 0}
|
||||
to={`/~landscape/messages/dm/${ship}`}
|
||||
title={title}
|
||||
mono={hideAvatars || !contact?.nickname}
|
||||
isSynced
|
||||
pending={pending}
|
||||
>
|
||||
{img}
|
||||
</SidebarItemBase>
|
||||
);
|
||||
}
|
||||
);
|
||||
// eslint-disable-next-line max-lines-per-function
|
||||
export const SidebarAssociationItem = React.memo(
|
||||
(props: {
|
||||
hideUnjoined: boolean;
|
||||
association: Association;
|
||||
selected: boolean;
|
||||
workspace: Workspace;
|
||||
}) => {
|
||||
const { association, selected } = props;
|
||||
const title = association ? getItemTitle(association) || "" : "";
|
||||
const appName = association?.["app-name"];
|
||||
let mod: string = appName;
|
||||
if (
|
||||
association?.metadata?.config &&
|
||||
"graph" in association.metadata.config
|
||||
) {
|
||||
mod = association.metadata.config.graph;
|
||||
}
|
||||
const pending = useGroupState(s => association.group in s.pendingJoin);
|
||||
console.log(pending);
|
||||
const rid = association?.resource;
|
||||
const { hideNicknames } = useSettingsState((s) => s.calm);
|
||||
const contacts = useContactState((s) => s.contacts);
|
||||
const group = useGroupState(s => association ? s.groups[association.group] : undefined);
|
||||
const isUnmanaged = group?.hidden || false;
|
||||
const DM = isUnmanaged && props.workspace?.type === "messages";
|
||||
const itemStatus = useAssociationStatus(rid);
|
||||
const hasNotification = itemStatus === "notification";
|
||||
const hasUnread = itemStatus === "unread";
|
||||
const isSynced = itemStatus !== "unsubscribed";
|
||||
let baseUrl = `/~landscape${association.group}`;
|
||||
|
||||
if (DM) {
|
||||
baseUrl = "/~landscape/messages";
|
||||
} else if (isUnmanaged) {
|
||||
baseUrl = "/~landscape/home";
|
||||
}
|
||||
|
||||
const to = isSynced
|
||||
? `${baseUrl}/resource/${mod}${rid}`
|
||||
: `${baseUrl}/join/${mod}${rid}`;
|
||||
|
||||
const onClick = pending ? () => {
|
||||
useGroupState.getState().doneJoin(rid);
|
||||
} : undefined;
|
||||
|
||||
if (props.hideUnjoined && !isSynced) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const participantNames = (str: string) => {
|
||||
const color = isSynced
|
||||
? hasUnread || hasNotification
|
||||
? "black"
|
||||
: "gray"
|
||||
: "lightGray";
|
||||
if (_.includes(str, ",") && _.startsWith(str, "~")) {
|
||||
const names = _.split(str, ", ");
|
||||
return names.map((name, idx) => {
|
||||
if (urbitOb.isValidPatp(name)) {
|
||||
if (contacts[name]?.nickname && !hideNicknames)
|
||||
return (
|
||||
<Text key={name} bold={hasUnread} color={color}>
|
||||
{contacts[name]?.nickname}
|
||||
{idx + 1 != names.length ? ", " : null}
|
||||
</Text>
|
||||
);
|
||||
return (
|
||||
<Text key={name} mono bold={hasUnread} color={color}>
|
||||
{name}
|
||||
<Text color={color}>
|
||||
{idx + 1 != names.length ? ", " : null}
|
||||
</Text>
|
||||
</Text>
|
||||
);
|
||||
} else {
|
||||
return name;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return str;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<SidebarItemBase
|
||||
to={to}
|
||||
selected={selected}
|
||||
hasUnread={hasUnread}
|
||||
isSynced={isSynced}
|
||||
title={
|
||||
DM && !urbitOb.isValidPatp(title) ? participantNames(title) : title
|
||||
}
|
||||
hasNotification={hasNotification}
|
||||
pending={pending}
|
||||
onClick={onClick}
|
||||
>
|
||||
{DM ? (
|
||||
<Box
|
||||
flexShrink={0}
|
||||
height={16}
|
||||
width={16}
|
||||
borderRadius={2}
|
||||
backgroundColor={
|
||||
`#${uxToHex(props?.association?.metadata?.color)}` || "#000000"
|
||||
}
|
||||
/>
|
||||
) : (
|
||||
<Icon
|
||||
display="block"
|
||||
color={isSynced ? "black" : "lightGray"}
|
||||
icon={getModuleIcon(mod as any)}
|
||||
/>
|
||||
)}
|
||||
</SidebarItemBase>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
@ -3,7 +3,7 @@ import { Associations, Graph, Unreads } from '@urbit/api';
|
||||
import { patp, patp2dec } from 'urbit-ob';
|
||||
import _ from 'lodash';
|
||||
|
||||
import { SidebarAssociationItem, SidebarDmItem } from './SidebarItem';
|
||||
import { SidebarAssociationItem, SidebarDmItem, SidebarPendingItem } from './SidebarItem';
|
||||
import useGraphState, { useInbox } from '~/logic/state/graph';
|
||||
import useHarkState from '~/logic/state/hark';
|
||||
import { alphabeticalOrder, getResourcePath, modulo } from '~/logic/lib/util';
|
||||
@ -12,8 +12,10 @@ import { Workspace } from '~/types/workspace';
|
||||
import useMetadataState from '~/logic/state/metadata';
|
||||
import { useHistory } from 'react-router';
|
||||
import { useShortcut } from '~/logic/state/settings';
|
||||
import useGroupState from '~/logic/state/group';
|
||||
import useInviteState from '~/logic/state/invite';
|
||||
|
||||
function sidebarSort(unreads: Unreads, pending: Set<string>): Record<SidebarSort, (a: string, b: string) => number> {
|
||||
function sidebarSort(unreads: Unreads, pending: string[]): Record<SidebarSort, (a: string, b: string) => number> {
|
||||
const { associations } = useMetadataState.getState();
|
||||
const alphabetical = (a: string, b: string) => {
|
||||
const aAssoc = associations[a];
|
||||
@ -25,8 +27,8 @@ function sidebarSort(unreads: Unreads, pending: Set<string>): Record<SidebarSort
|
||||
};
|
||||
|
||||
const lastUpdated = (a: string, b: string) => {
|
||||
const aPend = pending.has(a.slice(1));
|
||||
const bPend = pending.has(b.slice(1));
|
||||
const aPend = pending.includes(a);
|
||||
const bPend = pending.includes(b);
|
||||
if(aPend && !bPend) {
|
||||
return -1;
|
||||
}
|
||||
@ -50,7 +52,7 @@ function sidebarSort(unreads: Unreads, pending: Set<string>): Record<SidebarSort
|
||||
};
|
||||
}
|
||||
|
||||
function getItems(associations: Associations, workspace: Workspace, inbox: Graph, pending: Set<string>) {
|
||||
function getItems(associations: Associations, workspace: Workspace, inbox: Graph, pending: string[]) {
|
||||
const filtered = Object.keys(associations.graph).filter((a) => {
|
||||
const assoc = associations.graph[a];
|
||||
if(!('graph' in assoc.metadata.config)) {
|
||||
@ -84,9 +86,9 @@ function getItems(associations: Associations, workspace: Workspace, inbox: Graph
|
||||
: inbox.keys().map(x => patp(x.toString()));
|
||||
const pend = workspace.type !== 'messages'
|
||||
? []
|
||||
: Array.from(pending).map(s => `~${s}`);
|
||||
: pending
|
||||
|
||||
return [...filtered, ..._.union(direct, pend)];
|
||||
return _.union(direct, pend, filtered);
|
||||
}
|
||||
|
||||
export function SidebarList(props: {
|
||||
@ -98,9 +100,18 @@ export function SidebarList(props: {
|
||||
}): ReactElement {
|
||||
const { selected, config, workspace } = props;
|
||||
const associations = useMetadataState(state => state.associations);
|
||||
const groups = useGroupState(s => s.groups);
|
||||
const inbox = useInbox();
|
||||
const graphKeys = useGraphState(s => s.graphKeys);
|
||||
const pending = useGraphState(s => s.pendingDms);
|
||||
const pendingDms = useGraphState(s => [...s.pendingDms].map(s => `~${s}`));
|
||||
const pendingGroupChats = useGroupState(s => _.pickBy(s.pendingJoin, (req, rid) => !(rid in groups) && req.app === 'graph'));
|
||||
const inviteGroupChats = useInviteState(
|
||||
s => Object.values(s.invites?.['graph'] || {})
|
||||
.map(inv => {
|
||||
return `/ship/~${inv.resource.ship}/${inv.resource.name}`
|
||||
})
|
||||
);
|
||||
const pending = [...pendingDms, ...Object.keys(pendingGroupChats), ...inviteGroupChats];
|
||||
const unreads = useHarkState(s => s.unreads);
|
||||
|
||||
const ordered = getItems(associations, workspace, inbox, pending)
|
||||
@ -118,10 +129,16 @@ export function SidebarList(props: {
|
||||
if(newChannel.startsWith('~')) {
|
||||
path = `/~landscape/messages/dm/${newChannel}`;
|
||||
} else {
|
||||
const { metadata, resource } = associations.graph[ordered[newIdx]];
|
||||
const joined = graphKeys.has(resource.slice(7));
|
||||
if ('graph' in metadata.config) {
|
||||
path = getResourcePath(workspace, resource, joined, metadata.config.graph);
|
||||
const association = associations.graph[ordered[newIdx]];
|
||||
if(!association) {
|
||||
path = `/~landscape/messages`
|
||||
return;
|
||||
} else {
|
||||
const { metadata, resource } = association;
|
||||
const joined = graphKeys.has(resource.slice(7));
|
||||
if ('graph' in metadata.config) {
|
||||
path = getResourcePath(workspace, resource, joined, metadata.config.graph);
|
||||
}
|
||||
}
|
||||
}
|
||||
history.push(path);
|
||||
@ -140,7 +157,22 @@ export function SidebarList(props: {
|
||||
return (
|
||||
<>
|
||||
{ordered.map((pathOrShip) => {
|
||||
return pathOrShip.startsWith('/') ? (
|
||||
return pathOrShip.startsWith('~') ? (
|
||||
<SidebarDmItem
|
||||
key={pathOrShip}
|
||||
ship={pathOrShip}
|
||||
workspace={workspace}
|
||||
selected={pathOrShip === selected}
|
||||
pending={pending.includes(pathOrShip)}
|
||||
/>
|
||||
|
||||
) : pending.includes(pathOrShip) ? (
|
||||
<SidebarPendingItem
|
||||
key={pathOrShip}
|
||||
path={pathOrShip}
|
||||
selected={pathOrShip === selected}
|
||||
/>
|
||||
) : (
|
||||
<SidebarAssociationItem
|
||||
key={pathOrShip}
|
||||
selected={pathOrShip === selected}
|
||||
@ -148,16 +180,7 @@ export function SidebarList(props: {
|
||||
hideUnjoined={config.hideUnjoined}
|
||||
workspace={workspace}
|
||||
/>
|
||||
) : (
|
||||
<SidebarDmItem
|
||||
key={pathOrShip}
|
||||
ship={pathOrShip}
|
||||
workspace={workspace}
|
||||
selected={pathOrShip === selected}
|
||||
pending={pending.has(pathOrShip.slice(1))}
|
||||
/>
|
||||
|
||||
);
|
||||
) ;
|
||||
})}
|
||||
</>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user