mirror of
https://github.com/urbit/shrub.git
synced 2025-01-07 05:26:56 +03:00
chat-fe: improve render performance
This commit is contained in:
parent
995a35cd76
commit
c00768442a
@ -86,7 +86,7 @@ const ChatResource = (props: ChatResourceProps): ReactElement => {
|
|||||||
);
|
);
|
||||||
return `${url}\n~${msg.author}: `;
|
return `${url}\n~${msg.author}: `;
|
||||||
},
|
},
|
||||||
[association]
|
[association.resource]
|
||||||
);
|
);
|
||||||
|
|
||||||
const isAdmin = useMemo(
|
const isAdmin = useMemo(
|
||||||
@ -107,7 +107,7 @@ const ChatResource = (props: ChatResourceProps): ReactElement => {
|
|||||||
if (newer) {
|
if (newer) {
|
||||||
const index = graph.peekLargest()?.[0];
|
const index = graph.peekLargest()?.[0];
|
||||||
if (!index) {
|
if (!index) {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
await getYoungerSiblings(
|
await getYoungerSiblings(
|
||||||
ship,
|
ship,
|
||||||
@ -119,10 +119,12 @@ const ChatResource = (props: ChatResourceProps): ReactElement => {
|
|||||||
} else {
|
} else {
|
||||||
const index = graph.peekSmallest()?.[0];
|
const index = graph.peekSmallest()?.[0];
|
||||||
if (!index) {
|
if (!index) {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
await getOlderSiblings(ship, name, pageSize, `/${index.toString()}`);
|
await getOlderSiblings(ship, name, pageSize, `/${index.toString()}`);
|
||||||
const done = expectedSize !== getCurrGraphSize(ship.slice(1), name);
|
const currSize = getCurrGraphSize(ship.slice(1), name);
|
||||||
|
console.log(currSize);
|
||||||
|
const done = expectedSize !== currSize;
|
||||||
return done;
|
return done;
|
||||||
}
|
}
|
||||||
}, [graph, resource]);
|
}, [graph, resource]);
|
||||||
@ -144,7 +146,7 @@ const ChatResource = (props: ChatResourceProps): ReactElement => {
|
|||||||
const getPermalink = useCallback(
|
const getPermalink = useCallback(
|
||||||
(index: BigInteger) =>
|
(index: BigInteger) =>
|
||||||
getPermalinkForGraph(association.group, resource, `/${index.toString()}`),
|
getPermalinkForGraph(association.group, resource, `/${index.toString()}`),
|
||||||
[association]
|
[association.resource]
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!graph) {
|
if (!graph) {
|
||||||
|
@ -16,7 +16,7 @@ import {
|
|||||||
cite, daToUnix, useHovering, useShowNickname, uxToHex
|
cite, daToUnix, useHovering, useShowNickname, uxToHex
|
||||||
} from '~/logic/lib/util';
|
} from '~/logic/lib/util';
|
||||||
import { useContact } from '~/logic/state/contact';
|
import { useContact } from '~/logic/state/contact';
|
||||||
import useLocalState from '~/logic/state/local';
|
import { useDark } from '~/logic/state/join';
|
||||||
import useSettingsState, { selectCalmState } from '~/logic/state/settings';
|
import useSettingsState, { selectCalmState } from '~/logic/state/settings';
|
||||||
import { Dropdown } from '~/views/components/Dropdown';
|
import { Dropdown } from '~/views/components/Dropdown';
|
||||||
import ProfileOverlay from '~/views/components/ProfileOverlay';
|
import ProfileOverlay from '~/views/components/ProfileOverlay';
|
||||||
@ -53,16 +53,13 @@ export const DayBreak = ({ when, shimTop = false }: DayBreakProps) => (
|
|||||||
</Row>
|
</Row>
|
||||||
);
|
);
|
||||||
|
|
||||||
export const MessageAuthor = ({
|
export const MessageAuthor = React.memo<any>(({
|
||||||
timestamp,
|
timestamp,
|
||||||
msg,
|
msg,
|
||||||
showOurContact,
|
showOurContact,
|
||||||
...props
|
...props
|
||||||
}) => {
|
}) => {
|
||||||
const osDark = useLocalState(state => state.dark);
|
const dark = useDark();
|
||||||
|
|
||||||
const theme = useSettingsState(s => s.display.theme);
|
|
||||||
const dark = theme === 'dark' || (theme === 'auto' && osDark);
|
|
||||||
let contact: Contact | null = useContact(`~${msg.author}`);
|
let contact: Contact | null = useContact(`~${msg.author}`);
|
||||||
|
|
||||||
const date = daToUnix(bigInt(msg.index.split('/').reverse()[0]));
|
const date = daToUnix(bigInt(msg.index.split('/').reverse()[0]));
|
||||||
@ -177,7 +174,8 @@ export const MessageAuthor = ({
|
|||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
MessageAuthor.displayName = 'MessageAuthor';
|
||||||
|
|
||||||
type MessageProps = { timestamp: string; timestampHover: boolean; }
|
type MessageProps = { timestamp: string; timestampHover: boolean; }
|
||||||
& Pick<ChatMessageProps, 'msg' | 'transcluded' | 'showOurContact'>
|
& Pick<ChatMessageProps, 'msg' | 'transcluded' | 'showOurContact'>
|
||||||
@ -392,6 +390,7 @@ interface ChatMessageProps {
|
|||||||
showOurContact: boolean;
|
showOurContact: boolean;
|
||||||
onDelete?: () => void;
|
onDelete?: () => void;
|
||||||
}
|
}
|
||||||
|
const emptyCallback = () => {};
|
||||||
|
|
||||||
function ChatMessage(props: ChatMessageProps) {
|
function ChatMessage(props: ChatMessageProps) {
|
||||||
let { highlighted } = props;
|
let { highlighted } = props;
|
||||||
@ -416,10 +415,10 @@ function ChatMessage(props: ChatMessageProps) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const onReply = props?.onReply ?? (() => {});
|
const onReply = props?.onReply || emptyCallback;
|
||||||
const onDelete = props?.onDelete ?? (() => {});
|
const onDelete = props?.onDelete || emptyCallback;
|
||||||
const transcluded = props?.transcluded ?? 0;
|
const transcluded = props?.transcluded || 0;
|
||||||
const renderSigil = props.renderSigil ?? (Boolean(nextMsg && msg.author !== nextMsg.author) ||
|
const renderSigil = props.renderSigil || (Boolean(nextMsg && msg.author !== nextMsg.author) ||
|
||||||
!nextMsg
|
!nextMsg
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -509,9 +508,9 @@ function ChatMessage(props: ChatMessageProps) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default React.forwardRef((props: Omit<ChatMessageProps, 'innerRef'>, ref: any) => (
|
export default React.memo(React.forwardRef((props: Omit<ChatMessageProps, 'innerRef'>, ref: any) => (
|
||||||
<ChatMessage {...props} innerRef={ref} />
|
<ChatMessage {...props} innerRef={ref} />
|
||||||
));
|
)));
|
||||||
|
|
||||||
export const MessagePlaceholder = ({
|
export const MessagePlaceholder = ({
|
||||||
height,
|
height,
|
||||||
|
@ -6,7 +6,7 @@ import React, { ReactElement, useCallback, useEffect, useRef, useState } from 'r
|
|||||||
import { useFileDrag } from '~/logic/lib/useDrag';
|
import { useFileDrag } from '~/logic/lib/useDrag';
|
||||||
import { useLocalStorageState } from '~/logic/lib/useLocalStorageState';
|
import { useLocalStorageState } from '~/logic/lib/useLocalStorageState';
|
||||||
import { useOurContact } from '~/logic/state/contact';
|
import { useOurContact } from '~/logic/state/contact';
|
||||||
import useGraphState from '~/logic/state/graph';
|
import { useGraphTimesent } from '~/logic/state/graph';
|
||||||
import ShareProfile from '~/views/apps/chat/components/ShareProfile';
|
import ShareProfile from '~/views/apps/chat/components/ShareProfile';
|
||||||
import { Loading } from '~/views/components/Loading';
|
import { Loading } from '~/views/components/Loading';
|
||||||
import SubmitDragger from '~/views/components/SubmitDragger';
|
import SubmitDragger from '~/views/components/SubmitDragger';
|
||||||
@ -77,7 +77,7 @@ export function ChatPane(props: ChatPaneProps): ReactElement {
|
|||||||
promptShare = [],
|
promptShare = [],
|
||||||
fetchMessages
|
fetchMessages
|
||||||
} = props;
|
} = props;
|
||||||
const graphTimesentMap = useGraphState(state => state.graphTimesentMap);
|
const graphTimesentMap = useGraphTimesent(id);
|
||||||
const ourContact = useOurContact();
|
const ourContact = useOurContact();
|
||||||
const chatInput = useRef<NakedChatInput>();
|
const chatInput = useRef<NakedChatInput>();
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ export function ChatPane(props: ChatPaneProps): ReactElement {
|
|||||||
}
|
}
|
||||||
(chatInput.current as NakedChatInput)?.uploadFiles(files);
|
(chatInput.current as NakedChatInput)?.uploadFiles(files);
|
||||||
},
|
},
|
||||||
[chatInput.current]
|
[chatInput]
|
||||||
);
|
);
|
||||||
|
|
||||||
const { bind, dragging } = useFileDrag(onFileDrag);
|
const { bind, dragging } = useFileDrag(onFileDrag);
|
||||||
@ -147,7 +147,7 @@ export function ChatPane(props: ChatPaneProps): ReactElement {
|
|||||||
graphSize={graph.size}
|
graphSize={graph.size}
|
||||||
unreadCount={unreadCount}
|
unreadCount={unreadCount}
|
||||||
showOurContact={promptShare.length === 0 && !showBanner}
|
showOurContact={promptShare.length === 0 && !showBanner}
|
||||||
pendingSize={Object.keys(graphTimesentMap[id] || {}).length}
|
pendingSize={Object.keys(graphTimesentMap).length}
|
||||||
onReply={onReply}
|
onReply={onReply}
|
||||||
onDelete={onDelete}
|
onDelete={onDelete}
|
||||||
dismissUnread={dismissUnread}
|
dismissUnread={dismissUnread}
|
||||||
@ -170,3 +170,5 @@ export function ChatPane(props: ChatPaneProps): ReactElement {
|
|||||||
</Col>
|
</Col>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ChatPane.whyDidYouRender = true;
|
||||||
|
@ -6,7 +6,7 @@ import {
|
|||||||
import bigInt, { BigInteger } from 'big-integer';
|
import bigInt, { BigInteger } from 'big-integer';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import VirtualScroller from '~/views/components/VirtualScroller';
|
import VirtualScroller from '~/views/components/VirtualScroller';
|
||||||
import ChatMessage, { MessagePlaceholder } from './ChatMessage';
|
import ChatMessage from './ChatMessage';
|
||||||
import UnreadNotice from './UnreadNotice';
|
import UnreadNotice from './UnreadNotice';
|
||||||
|
|
||||||
const IDLE_THRESHOLD = 64;
|
const IDLE_THRESHOLD = 64;
|
||||||
@ -57,7 +57,7 @@ class ChatWindow extends Component<
|
|||||||
this.state = {
|
this.state = {
|
||||||
fetchPending: false,
|
fetchPending: false,
|
||||||
idle: true,
|
idle: true,
|
||||||
initialized: false,
|
initialized: true,
|
||||||
unreadIndex: bigInt.zero
|
unreadIndex: bigInt.zero
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -72,14 +72,10 @@ class ChatWindow extends Component<
|
|||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.calculateUnreadIndex();
|
this.calculateUnreadIndex();
|
||||||
setTimeout(() => {
|
if(this.props.scrollTo) {
|
||||||
this.setState({ initialized: true }, () => {
|
this.virtualList!.scrollLocked = false;
|
||||||
if(this.props.scrollTo) {
|
this.virtualList!.scrollToIndex(this.props.scrollTo);
|
||||||
this.virtualList!.scrollLocked = false;
|
}
|
||||||
this.virtualList!.scrollToIndex(this.props.scrollTo);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, this.INITIALIZATION_MAX_TIME);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
calculateUnreadIndex() {
|
calculateUnreadIndex() {
|
||||||
@ -205,15 +201,6 @@ class ChatWindow extends Component<
|
|||||||
</Text>
|
</Text>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (!this.state.initialized) {
|
|
||||||
return (
|
|
||||||
<MessagePlaceholder
|
|
||||||
key={index.toString()}
|
|
||||||
height='64px'
|
|
||||||
index={index}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
const isPending: boolean = 'pending' in msg && Boolean(msg.pending);
|
const isPending: boolean = 'pending' in msg && Boolean(msg.pending);
|
||||||
const isLastMessage = index.eq(
|
const isLastMessage = index.eq(
|
||||||
graph.peekLargest()?.[0] ?? bigInt.zero
|
graph.peekLargest()?.[0] ?? bigInt.zero
|
||||||
|
Loading…
Reference in New Issue
Block a user