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
@@ -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
@@ -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
1 change: 1 addition & 0 deletions desk/app/diary.hoon
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions desk/app/heap.hoon
Original file line number Diff line number Diff line change
@@ -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
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
@@ -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",
17 changes: 7 additions & 10 deletions ui/src/chat/ChatChannel.tsx
Original file line number Diff line number Diff line change
@@ -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);
@@ -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
11 changes: 7 additions & 4 deletions ui/src/chat/ChatScroller/ChatScroller.tsx
Original file line number Diff line number Diff line change
@@ -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';
@@ -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();
@@ -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)
) {
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 {
@@ -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');
@@ -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
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 {
@@ -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);
2 changes: 1 addition & 1 deletion ui/src/components/PrereleaseNotice.tsx
Original file line number Diff line number Diff line change
@@ -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.`}
/>
);
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 = [
15 changes: 6 additions & 9 deletions ui/src/diary/DiaryChannel.tsx
Original file line number Diff line number Diff line change
@@ -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';
@@ -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);
@@ -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;
2 changes: 0 additions & 2 deletions ui/src/groups/GroupSidebar/ChannelList.tsx
Original file line number Diff line number Diff line change
@@ -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;
}
Original file line number Diff line number Diff line change
@@ -34,7 +34,7 @@ exports[`ChannelList > renders as expected 1`] = `
<span
class="mr-2 pl-1"
>
Sort: A → Z
Sort: Arranged
</span>
</span>
<svg
@@ -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
@@ -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() {
@@ -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) {
Loading