mirror of
https://github.com/urbit/shrub.git
synced 2024-12-22 18:31:44 +03:00
DM: lazy loading, status bar
This commit is contained in:
parent
772a134108
commit
5b317e8af1
@ -69,6 +69,17 @@ export class HarkApi extends BaseApi<StoreState> {
|
|||||||
return this.actOnNotification('unread-note', time, index);
|
return this.actOnNotification('unread-note', time, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dismissReadCount(graph: string, index: string) {
|
||||||
|
return this.harkAction({
|
||||||
|
'read-count': {
|
||||||
|
graph: {
|
||||||
|
graph,
|
||||||
|
index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
markCountAsRead(association: Association, parent: string, description: GraphNotifDescription) {
|
markCountAsRead(association: Association, parent: string, description: GraphNotifDescription) {
|
||||||
return this.harkAction(
|
return this.harkAction(
|
||||||
{ 'read-count': {
|
{ 'read-count': {
|
||||||
|
@ -98,7 +98,7 @@ class App extends React.Component {
|
|||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.subscription.start();
|
this.subscription.start();
|
||||||
this.api.graph.getGraph(`~${window.ship}`, 'inbox');
|
this.api.graph.getShallowChildren(`~${window.ship}`, 'inbox');
|
||||||
this.themeWatcher = window.matchMedia('(prefers-color-scheme: dark)');
|
this.themeWatcher = window.matchMedia('(prefers-color-scheme: dark)');
|
||||||
this.themeWatcher.onchange = this.updateTheme;
|
this.themeWatcher.onchange = this.updateTheme;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
@ -1,20 +1,81 @@
|
|||||||
import { Content, createPost } from '@urbit/api';
|
import { cite, Content, createPost } from '@urbit/api';
|
||||||
import React, { useCallback } from 'react';
|
import React, { useCallback, useEffect } from 'react';
|
||||||
|
import bigInt from 'big-integer';
|
||||||
|
import { Box, Row, Col, Text } from '@tlon/indigo-react';
|
||||||
import { patp2dec } from 'urbit-ob';
|
import { patp2dec } from 'urbit-ob';
|
||||||
import GlobalApi from '~/logic/api/global';
|
import GlobalApi from '~/logic/api/global';
|
||||||
import { useDM } from '~/logic/state/graph';
|
import { useContact } from '~/logic/state/contact';
|
||||||
|
import useGraphState, { useDM } from '~/logic/state/graph';
|
||||||
import useHarkState, { useHarkDm } from '~/logic/state/hark';
|
import useHarkState, { useHarkDm } from '~/logic/state/hark';
|
||||||
|
import useSettingsState, { selectCalmState } from '~/logic/state/settings';
|
||||||
import { ChatPane } from './components/ChatPane';
|
import { ChatPane } from './components/ChatPane';
|
||||||
|
|
||||||
interface DmResourceProps {
|
interface DmResourceProps {
|
||||||
ship: string;
|
ship: string;
|
||||||
api: GlobalApi;
|
api: GlobalApi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getCurrDmSize = (ship: string) => {
|
||||||
|
const { graphs } = useGraphState.getState();
|
||||||
|
const graph = graphs[`${window.ship}/inbox`];
|
||||||
|
if (!graph) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
const shipGraph = graph.get(bigInt(patp2dec(ship)));
|
||||||
|
return shipGraph?.children?.size ?? 0;
|
||||||
|
};
|
||||||
|
|
||||||
export function DmResource(props: DmResourceProps) {
|
export function DmResource(props: DmResourceProps) {
|
||||||
const { ship, api } = props;
|
const { ship, api } = props;
|
||||||
const dm = useDM(ship);
|
const dm = useDM(ship);
|
||||||
const hark = useHarkDm(ship);
|
const hark = useHarkDm(ship);
|
||||||
const unreadCount = (hark?.unreads as number) ?? 0;
|
const unreadCount = (hark?.unreads as number) ?? 0;
|
||||||
|
const contact = useContact(ship);
|
||||||
|
const { hideNicknames } = useSettingsState(selectCalmState);
|
||||||
|
const showNickname = !hideNicknames && !!contact;
|
||||||
|
const nickname = showNickname ? contact!.nickname : cite(ship) ?? ship;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
api.graph.getNewest(`~${window.ship}`, 'inbox', 100, `/${patp2dec(ship)}`);
|
||||||
|
}, [ship]);
|
||||||
|
|
||||||
|
const fetchMessages = useCallback(
|
||||||
|
async (newer: boolean) => {
|
||||||
|
const pageSize = 100;
|
||||||
|
const expectedSize = dm.size + pageSize;
|
||||||
|
if (newer) {
|
||||||
|
const index = dm.peekLargest()?.[0];
|
||||||
|
if (!index) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
await api.graph.getYoungerSiblings(
|
||||||
|
`~${window.ship}`,
|
||||||
|
'inbox',
|
||||||
|
pageSize,
|
||||||
|
`/${patp2dec(ship)}/${index.toString()}`
|
||||||
|
);
|
||||||
|
return expectedSize !== getCurrDmSize(ship);
|
||||||
|
} else {
|
||||||
|
const index = dm.peekSmallest()?.[0];
|
||||||
|
if (!index) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
await api.graph.getOlderSiblings(
|
||||||
|
`~${window.ship}`,
|
||||||
|
'inbox',
|
||||||
|
pageSize,
|
||||||
|
`/${patp2dec(ship)}/${index.toString()}`
|
||||||
|
);
|
||||||
|
return expectedSize !== getCurrDmSize(ship);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[ship, dm, api]
|
||||||
|
);
|
||||||
|
|
||||||
|
const dismissUnread = useCallback(() => {
|
||||||
|
api.hark.dismissReadCount(`/ship/~${window.ship}/inbox`, `/${patp2dec(ship)}`);
|
||||||
|
}, [ship]);
|
||||||
|
|
||||||
|
|
||||||
const onSubmit = useCallback(
|
const onSubmit = useCallback(
|
||||||
(contents: Content[]) => {
|
(contents: Content[]) => {
|
||||||
@ -24,18 +85,44 @@ export function DmResource(props: DmResourceProps) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ChatPane
|
<Col width="100%" height="100%" overflow="hidden">
|
||||||
api={api}
|
<Row
|
||||||
canWrite
|
px="3"
|
||||||
id={ship}
|
gapX="3"
|
||||||
graph={dm}
|
flexShrink={0}
|
||||||
unreadCount={unreadCount}
|
alignItems="center"
|
||||||
onReply={() => ''}
|
height="6"
|
||||||
fetchMessages={async () => true}
|
borderBottom="1"
|
||||||
dismissUnread={() => {}}
|
borderBottomColor="lightGray"
|
||||||
getPermalink={() => ''}
|
>
|
||||||
isAdmin
|
<Row gapX="2" alignItems="baseline">
|
||||||
onSubmit={onSubmit}
|
{showNickname && (
|
||||||
/>
|
<Box>
|
||||||
|
<Text fontWeight="medium" fontSize={2} mono={!showNickname}>
|
||||||
|
{nickname}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
<Box>
|
||||||
|
<Text gray={showNickname} mono>
|
||||||
|
{cite(ship)}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
</Row>
|
||||||
|
</Row>
|
||||||
|
<ChatPane
|
||||||
|
api={api}
|
||||||
|
canWrite
|
||||||
|
id={ship}
|
||||||
|
graph={dm}
|
||||||
|
unreadCount={unreadCount}
|
||||||
|
onReply={() => ''}
|
||||||
|
fetchMessages={fetchMessages}
|
||||||
|
dismissUnread={dismissUnread}
|
||||||
|
getPermalink={() => ''}
|
||||||
|
isAdmin
|
||||||
|
onSubmit={onSubmit}
|
||||||
|
/>
|
||||||
|
</Col>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -111,7 +111,7 @@ export function SidebarDmItem(props: {
|
|||||||
const img = (contact?.avatar && !hideAvatars) ? (
|
const img = (contact?.avatar && !hideAvatars) ? (
|
||||||
<BaseImage referrerPolicy="no-referrer" src={contact.avatar} width='16px' height='16px' borderRadius={2} />
|
<BaseImage referrerPolicy="no-referrer" src={contact.avatar} width='16px' height='16px' borderRadius={2} />
|
||||||
) : (
|
) : (
|
||||||
<Sigil ship={title} color={`#${uxToHex(contact?.color || '0x0')}`} icon padding={2} size={16} />
|
<Sigil ship={ship} color={`#${uxToHex(contact?.color || '0x0')}`} icon padding={2} size={16} />
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
Loading…
Reference in New Issue
Block a user