Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

omnibus: scroller perf, devex enhancements #1197

Merged
merged 12 commits into from
Nov 21, 2022
Merged
3 changes: 1 addition & 2 deletions desk/app/chat.hoon
Original file line number Diff line number Diff line change
Expand Up @@ -1134,8 +1134,6 @@
(put:log-on:c log.chat time d)
=. ca-core
(ca-give-updates time d)
=. cor
(give-brief flag/flag ca-brief)
?- -.d
%add-sects
=* p perm.chat
Expand All @@ -1153,6 +1151,7 @@
::
%writs
=. pact.chat (reduce:ca-pact time p.d)
=. cor (give-brief flag/flag ca-brief)
?- -.q.p.d
?(%del %add-feel %del-feel) ca-core
%add
Expand Down
1 change: 1 addition & 0 deletions desk/app/diary.hoon
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,7 @@
?- -.dif
%notes
=. notes.diary (reduce:di-notes time p.dif)
=. cor (give-brief flag di-brief)
=/ cons=(list (list content:ha))
(hark:di-notes our.bowl p.dif)
=. cor
Expand Down
1 change: 1 addition & 0 deletions desk/app/heap.hoon
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,7 @@
?- -.d
%curios
=. curios.heap (reduce:he-curios time q.p.d)
=. cor (give-brief flag he-brief)
?- -.q.p.d
?(%edit %del %add-feel %del-feel) he-core
%add
Expand Down
14 changes: 7 additions & 7 deletions ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@
"react-router": "^6.3.0",
"react-router-dom": "^6.3.0",
"react-select": "^5.3.2",
"react-virtuoso": "^2.19.0",
"react-virtuoso": "^3.1.4",
"refractor": "^4.8.0",
"tailwindcss-scoped-groups": "^2.0.0",
"tippy.js": "^6.3.7",
Expand Down
17 changes: 7 additions & 10 deletions ui/src/chat/ChatChannel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,21 @@ import {
GROUP_ADMIN,
} from '@/state/groups/groups';
import ChannelHeader from '@/channels/ChannelHeader';
import { canReadChannel, createStorageKey } from '@/logic/utils';
import { useLocalStorage } from 'usehooks-ts';
import useRecentChannel from '@/logic/useRecentChannel';
import { canReadChannel } from '@/logic/utils';

function ChatChannel({ title }: ViewProps) {
const navigate = useNavigate();
const { chShip, chName } = useParams();
const chFlag = `${chShip}/${chName}`;
const nest = `chat/${chFlag}`;
const groupFlag = useRouteGroup();
const [, setRecent] = useLocalStorage(
createStorageKey(`recent-chan:${groupFlag}`),
''
);
const { setRecentChannel } = useRecentChannel(groupFlag);

useEffect(() => {
useChatState.getState().initialize(chFlag);
setRecent(nest);
}, [chFlag, nest, setRecent]);
setRecentChannel(nest);
}, [chFlag, nest, setRecentChannel]);

const messages = useMessagesForChat(chFlag);
const perms = useChatPerms(chFlag);
Expand All @@ -50,9 +47,9 @@ function ChatChannel({ title }: ViewProps) {
useEffect(() => {
if (channel && !canReadChannel(channel, vessel)) {
navigate('../../activity');
setRecent('');
setRecentChannel('');
}
}, [channel, vessel, navigate, setRecent]);
}, [channel, vessel, navigate, setRecentChannel]);

return (
<Layout
Expand Down
11 changes: 7 additions & 4 deletions ui/src/chat/ChatScroller/ChatScroller.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ import {
useGetFirstUnreadID,
useLoadedWrits,
} from '@/state/chat/chat';
import { MESSAGE_FETCH_PAGE_SIZE } from '@/constants';
import {
INITIAL_MESSAGE_FETCH_PAGE_SIZE,
STANDARD_MESSAGE_FETCH_PAGE_SIZE,
} from '@/constants';
import { ChatBrief, ChatWrit } from '@/types/chat';
import { useIsMobile } from '@/logic/useMedia';
import { IChatScroller } from './IChatScroller';
Expand Down Expand Up @@ -182,7 +185,7 @@ export default function ChatScroller({
);

const fetchMessages = useCallback(
async (newer: boolean, pageSize = MESSAGE_FETCH_PAGE_SIZE) => {
async (newer: boolean, pageSize = STANDARD_MESSAGE_FETCH_PAGE_SIZE) => {
const newest = messages.peekLargest();
const seenNewest = newer && newest && loaded.newest.geq(newest[0]);
const oldest = messages.peekSmallest();
Expand Down Expand Up @@ -242,15 +245,15 @@ export default function ChatScroller({
}, [scrollTo, virtuoso]);

/**
* By default, 100 messages are fetched on initial load. If there are more
* By default, 50 messages are fetched on initial load. If there are more
* unreads per the brief, fetch those as well. That way, the user can click
* the unread banner and see the unread messages.
*/
useEffect(() => {
if (
fetching === 'initial' &&
brief &&
brief.count > MESSAGE_FETCH_PAGE_SIZE &&
brief.count > INITIAL_MESSAGE_FETCH_PAGE_SIZE &&
firstUnreadID &&
!keys.includes(firstUnreadID)
) {
Expand Down
38 changes: 16 additions & 22 deletions ui/src/chat/ChatUnreadAlerts.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React, { useCallback } from 'react';
import { format, isToday } from 'date-fns';
import { useLocation, useNavigate } from 'react-router';
import { daToUnix, udToDec } from '@urbit/api';
import bigInt from 'big-integer';
import XIcon from '@/components/icons/XIcon';
import { ChatBrief } from '@/types/chat';
import { pluralize } from '../logic/utils';
import { useChatKeys, useChatState } from '../state/chat';
import { pluralize } from '@/logic/utils';
import { useChatState, useGetFirstUnreadID } from '@/state/chat';
import { useChatInfo } from './useChatStore';

interface ChatUnreadAlertsProps {
Expand All @@ -21,30 +21,24 @@ export default function ChatUnreadAlerts({ whom }: ChatUnreadAlertsProps) {
const navigate = useNavigate();
const location = useLocation();
// TODO: how to handle replies?
const chatKeys = useChatKeys({ replying: false });
const goToFirstUnread = useCallback(
(b: ChatBrief) => {
const { 'read-id': lastRead } = b;
if (!lastRead) {
return;
}
// lastRead is formatted like: ~zod/123.456.789...
const lastReadBN = bigInt(lastRead.split('/')[1].replaceAll('.', ''));
const firstUnread = chatKeys.find((key) => key.gt(lastReadBN));
if (!firstUnread) {
return;
}
navigate(`${location.pathname}?msg=${firstUnread.toString()}`);
},
[chatKeys, location.pathname, navigate]
);
const firstUnreadID = useGetFirstUnreadID(whom);
const goToFirstUnread = useCallback(() => {
if (!firstUnreadID) {
return;
}
navigate(`${location.pathname}?msg=${firstUnreadID.toString()}`);
}, [firstUnreadID, location.pathname, navigate]);

if (!chatInfo.unread || chatInfo.unread.seen) {
return null;
}

const { brief } = chatInfo.unread;
const date = brief ? new Date(brief.last) : new Date();
const readId = brief['read-id'];
const udTime = readId
? daToUnix(bigInt(udToDec(readId.split('/')[1])))
: null;
const date = udTime ? new Date(udTime) : new Date();
const since = isToday(date)
? `${format(date, 'HH:mm')} today`
: format(date, 'LLLL d');
Expand All @@ -62,7 +56,7 @@ export default function ChatUnreadAlerts({ whom }: ChatUnreadAlertsProps) {
<div className="absolute top-2 left-1/2 z-20 flex w-full -translate-x-1/2 flex-wrap items-center justify-center gap-2">
<button
className="button whitespace-nowrap bg-blue-soft text-sm text-blue dark:bg-blue-900 lg:text-base"
onClick={() => goToFirstUnread(brief)}
onClick={goToFirstUnread}
>
<span className="whitespace-nowrap font-normal">
{unreadMessage}&nbsp;&mdash;&nbsp;Click to View
Expand Down
6 changes: 5 additions & 1 deletion ui/src/components/ButterBar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from 'react';
import { useLocalStorage } from 'usehooks-ts';
import { createStorageKey } from '@/logic/utils';
import AsteriskIcon from './icons/Asterisk16Icon';

interface ButterBarProps {
Expand All @@ -8,7 +9,10 @@ interface ButterBarProps {
}

function ButterBar({ dismissKey, message }: ButterBarProps) {
const [isDismissed, setIsDismissed] = useLocalStorage(dismissKey, false);
const [isDismissed, setIsDismissed] = useLocalStorage(
createStorageKey(dismissKey),
false
);

function onClick() {
setIsDismissed(true);
Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/PrereleaseNotice.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default function PrereleaseNotice() {

return (
<ButterBar
dismissKey={`${app}-prerelease-notice-dismissed`}
dismissKey={`prerelease-notice-dismissed`}
message={`Reminder: you are using a Beta version of ${app}. Everything you write or create, including groups and messages, will be deleted prior to official launch.`}
/>
);
Expand Down
5 changes: 4 additions & 1 deletion ui/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
// eslint-disable-next-line import/prefer-default-export
export const MESSAGE_FETCH_PAGE_SIZE = 100;
export const INITIAL_MESSAGE_FETCH_PAGE_SIZE = 50;
export const STANDARD_MESSAGE_FETCH_PAGE_SIZE = 100;
export const LARGE_MESSAGE_FETCH_PAGE_SIZE = 200;
export const FETCH_BATCH_SIZE = 3;
export const MAX_DISPLAYED_OPTIONS = 40;

export const AUTHORS = [
Expand Down
15 changes: 6 additions & 9 deletions ui/src/diary/DiaryChannel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ import useDismissChannelNotifications from '@/logic/useDismissChannelNotificatio
import { DiaryDisplayMode } from '@/types/diary';
import DiaryGridView from '@/diary/DiaryList/DiaryGridView';
import { Link } from 'react-router-dom';
import { useLocalStorage } from 'usehooks-ts';
import * as Toast from '@radix-ui/react-toast';
import useRecentChannel from '@/logic/useRecentChannel';
import { canReadChannel, createStorageKey } from '@/logic/utils';
import DiaryListItem from './DiaryList/DiaryListItem';
import useDiaryActions from './useDiaryActions';
Expand All @@ -42,18 +42,15 @@ function DiaryChannel() {
const letters = useNotesForDiary(chFlag);
const location = useLocation();
const navigate = useNavigate();
const [, setRecent] = useLocalStorage(
createStorageKey(`recent-chan:${flag}`),
''
);
const { setRecentChannel } = useRecentChannel(flag);
const channel = useChannel(flag, nest);

useEffect(() => {
if (channel && !canReadChannel(channel, vessel)) {
navigate('../../activity');
setRecent('');
setRecentChannel('');
}
}, [channel, vessel, navigate, setRecent]);
}, [channel, vessel, navigate, setRecentChannel]);

const newNote = new URLSearchParams(location.search).get('new');
const [showToast, setShowToast] = useState(false);
Expand Down Expand Up @@ -93,8 +90,8 @@ function DiaryChannel() {

useEffect(() => {
useDiaryState.getState().initialize(chFlag);
setRecent(nest);
}, [chFlag, nest, setRecent]);
setRecentChannel(nest);
}, [chFlag, nest, setRecentChannel]);

useEffect(() => {
let timeout: any;
Expand Down
2 changes: 0 additions & 2 deletions ui/src/groups/GroupSidebar/ChannelList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,6 @@ export default function ChannelList({ flag, className }: ChannelListProps) {
const { isChannelUnread } = useIsChannelUnread();
const vessel = useVessel(flag, window.our);

usePrefetchChannels(flag);

if (!group) {
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ exports[`ChannelList > renders as expected 1`] = `
<span
class="mr-2 pl-1"
>
Sort: A → Z
Sort: Arranged
</span>
</span>
<svg
Expand All @@ -55,7 +55,11 @@ exports[`ChannelList > renders as expected 1`] = `
</div>
<ul
class="space-y-1"
/>
>
<div
class="space-y-1"
/>
</ul>
</div>
</DocumentFragment>
`;
8 changes: 2 additions & 6 deletions ui/src/groups/Groups.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ import api from '@/api';
import { useChatState } from '@/state/chat';
import { useHeapState } from '@/state/heap/heap';
import { useDiaryState } from '@/state/diary';
import { createStorageKey, nestToFlag } from '@/logic/utils';
import { useLocalStorage } from 'usehooks-ts';
import { useIsMobile } from '@/logic/useMedia';
import useRecentChannel from '@/logic/useRecentChannel';
import _ from 'lodash';

function Groups() {
Expand All @@ -27,10 +26,7 @@ function Groups() {
path: '/groups/:ship/:name',
end: true,
});
const [recentChannel] = useLocalStorage(
createStorageKey(`recent-chan:${flag}`),
''
);
const { recentChannel } = useRecentChannel(flag);

useEffect(() => {
if (initialized && !group && !gang) {
Expand Down
Loading