Performance improvements

This commit is contained in:
jude
2025-12-03 21:55:35 +00:00
parent b0c6eedba9
commit 4c98265657
5 changed files with 76 additions and 60 deletions

View File

@@ -6,7 +6,7 @@ enum ColorScheme {
Light = "light", Light = "light",
} }
type UserInfo = { export type UserInfo = {
name: string; name: string;
patreon: boolean; patreon: boolean;
preferences: { preferences: {

View File

@@ -1,8 +1,8 @@
import { useQuery, useQueryClient } from "react-query"; import { useQuery, useQueryClient } from "react-query";
import { fetchGuildChannels, fetchGuildReminders } from "../../api"; import { fetchGuildChannels, fetchGuildInfo, fetchGuildReminders, fetchUserInfo } from "../../api";
import { EditReminder } from "../Reminder/EditReminder"; import { EditReminder } from "../Reminder/EditReminder";
import { CreateReminder } from "../Reminder/CreateReminder"; import { CreateReminder } from "../Reminder/CreateReminder";
import { useCallback, useState } from "preact/hooks"; import { useCallback, useMemo, useState } from "preact/hooks";
import { Loader } from "../Loader"; import { Loader } from "../Loader";
import { useGuild } from "../App/useGuild"; import { useGuild } from "../App/useGuild";
@@ -22,6 +22,11 @@ export const GuildReminders = () => {
data: guildReminders, data: guildReminders,
} = useQuery(fetchGuildReminders(guild)); } = useQuery(fetchGuildReminders(guild));
const { data: channels } = useQuery(fetchGuildChannels(guild)); const { data: channels } = useQuery(fetchGuildChannels(guild));
const channelNames = useMemo(() => {
return new Map(channels.map((ch) => [ch.id, ch.name]));
}, [channels]);
const { isSuccess: guildFetched, data: guildInfo } = useQuery({ ...fetchGuildInfo(guild) });
const { isSuccess: userFetched, data: userInfo } = useQuery({ ...fetchUserInfo() });
const [collapsed, setCollapsed] = useState(false); const [collapsed, setCollapsed] = useState(false);
const [sort, _setSort] = useState(Sort.Time); const [sort, _setSort] = useState(Sort.Time);
@@ -34,9 +39,49 @@ export const GuildReminders = () => {
_setSort(sort); _setSort(sort);
}, []); }, []);
const sorted = useMemo(
() =>
[...guildReminders]
.sort((r1, r2) => {
if (sort === Sort.Time) {
return r1.utc_time > r2.utc_time ? 1 : -1;
} else if (sort === Sort.Name) {
return r1.name > r2.name ? 1 : -1;
} else {
return r1.channel > r2.channel ? 1 : -1;
}
})
.map((reminder) => {
let breaker = <></>;
if (sort === Sort.Channel && channels) {
if (prevReminder === null || prevReminder.channel !== reminder.channel) {
breaker = (
<div class={"channel-tag"}>#{channelNames[reminder.channel]}</div>
);
}
}
prevReminder = reminder;
return (
<>
{breaker}
<EditReminder
key={reminder.uid}
reminder={reminder}
guildInfo={guildInfo}
userInfo={userInfo}
globalCollapse={collapsed}
/>
</>
);
}),
[guildReminders, sort, channelNames, collapsed],
);
return ( return (
<> <>
{!isFetched && <Loader />} {!(userFetched && guildFetched && isFetched) && <Loader />}
<strong>Create Reminder</strong> <strong>Create Reminder</strong>
<div id={"reminderCreator"}> <div id={"reminderCreator"}>
@@ -100,44 +145,7 @@ export const GuildReminders = () => {
</div> </div>
<div id={"guildReminders"} className={isFetching ? "loading" : ""}> <div id={"guildReminders"} className={isFetching ? "loading" : ""}>
{isSuccess && {isSuccess && sorted}
guildReminders
.sort((r1, r2) => {
if (sort === Sort.Time) {
return r1.utc_time > r2.utc_time ? 1 : -1;
} else if (sort === Sort.Name) {
return r1.name > r2.name ? 1 : -1;
} else {
return r1.channel > r2.channel ? 1 : -1;
}
})
.map((reminder) => {
let breaker = <></>;
if (sort === Sort.Channel && channels) {
if (
prevReminder === null ||
prevReminder.channel !== reminder.channel
) {
const channel = channels.find(
(ch) => ch.id === reminder.channel,
);
breaker = <div class={"channel-tag"}>#{channel.name}</div>;
}
}
prevReminder = reminder;
return (
<>
{breaker}
<EditReminder
key={reminder.uid}
reminder={reminder}
globalCollapse={collapsed}
/>
</>
);
})}
</div> </div>
</> </>
); );

View File

@@ -1,5 +1,5 @@
import { useRef, useState } from "preact/hooks"; import { useRef, useState } from "preact/hooks";
import { useMutation, useQueryClient } from "react-query"; import { useMutation } from "react-query";
import { patchGuildReminder, patchUserReminder } from "../../../api"; import { patchGuildReminder, patchUserReminder } from "../../../api";
import { ICON_FLASH_TIME } from "../../../consts"; import { ICON_FLASH_TIME } from "../../../consts";
import { DeleteButton } from "./DeleteButton"; import { DeleteButton } from "./DeleteButton";

View File

@@ -1,4 +1,4 @@
import { Reminder } from "../../api"; import { Reminder, UserInfo, GuildInfo } from "../../api";
import { useEffect, useState } from "preact/hooks"; import { useEffect, useState } from "preact/hooks";
import { EditButtonRow } from "./ButtonRow/EditButtonRow"; import { EditButtonRow } from "./ButtonRow/EditButtonRow";
import { Message } from "./Message"; import { Message } from "./Message";
@@ -10,9 +10,16 @@ import "./styles.scss";
type Props = { type Props = {
reminder: Reminder; reminder: Reminder;
globalCollapse: boolean; globalCollapse: boolean;
userInfo: UserInfo;
guildInfo: GuildInfo;
}; };
export const EditReminder = ({ reminder: initialReminder, globalCollapse }: Props) => { export const EditReminder = ({
reminder: initialReminder,
globalCollapse,
userInfo,
guildInfo,
}: Props) => {
const [propReminder, setPropReminder] = useState(initialReminder); const [propReminder, setPropReminder] = useState(initialReminder);
const [reminder, setReminder] = useState(initialReminder); const [reminder, setReminder] = useState(initialReminder);
const [collapsed, setCollapsed] = useState(false); const [collapsed, setCollapsed] = useState(false);
@@ -39,11 +46,15 @@ export const EditReminder = ({ reminder: initialReminder, globalCollapse }: Prop
setCollapsed(!collapsed); setCollapsed(!collapsed);
}} }}
/> />
<div class="columns reminder-settings"> {!collapsed && (
<Message /> <>
<Settings /> <div class="columns reminder-settings">
</div> <Message />
<EditButtonRow /> <Settings userInfo={userInfo} guildInfo={guildInfo} />
</div>
<EditButtonRow />
</>
)}
</div> </div>
</ReminderContext.Provider> </ReminderContext.Provider>
); );

View File

@@ -1,24 +1,21 @@
import { ChannelSelector } from "./ChannelSelector"; import { ChannelSelector } from "./ChannelSelector";
import { IntervalSelector } from "./IntervalSelector"; import { IntervalSelector } from "./IntervalSelector";
import { useQuery } from "react-query";
import { fetchGuildInfo, fetchUserInfo } from "../../api";
import { useReminder } from "./ReminderContext"; import { useReminder } from "./ReminderContext";
import { Attachment } from "./Attachment"; import { Attachment } from "./Attachment";
import { TTS } from "./TTS"; import { TTS } from "./TTS";
import { TimeInput } from "./TimeInput"; import { TimeInput } from "./TimeInput";
import { useGuild } from "../App/useGuild"; import { useGuild } from "../App/useGuild";
import { GuildInfo, UserInfo } from "../../api";
export const Settings = () => { type Props = {
userInfo: UserInfo;
guildInfo: GuildInfo;
};
export const Settings = ({ guildInfo, userInfo }: Props) => {
const guild = useGuild(); const guild = useGuild();
const { isSuccess: userFetched, data: userInfo } = useQuery({ ...fetchUserInfo() });
const { isSuccess: guildFetched, data: guildInfo } = useQuery({ ...fetchGuildInfo(guild) });
const [reminder, setReminder] = useReminder(); const [reminder, setReminder] = useReminder();
if (!userFetched || !guildFetched) {
return <></>;
}
return ( return (
<div class="column settings"> <div class="column settings">
{guild && ( {guild && (