1 Commits

Author SHA1 Message Date
jude
4c98265657 Performance improvements 2025-12-03 21:55:35 +00:00
5 changed files with 76 additions and 60 deletions

View File

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

View File

@@ -1,8 +1,8 @@
import { useQuery, useQueryClient } from "react-query";
import { fetchGuildChannels, fetchGuildReminders } from "../../api";
import { fetchGuildChannels, fetchGuildInfo, fetchGuildReminders, fetchUserInfo } from "../../api";
import { EditReminder } from "../Reminder/EditReminder";
import { CreateReminder } from "../Reminder/CreateReminder";
import { useCallback, useState } from "preact/hooks";
import { useCallback, useMemo, useState } from "preact/hooks";
import { Loader } from "../Loader";
import { useGuild } from "../App/useGuild";
@@ -22,6 +22,11 @@ export const GuildReminders = () => {
data: guildReminders,
} = useQuery(fetchGuildReminders(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 [sort, _setSort] = useState(Sort.Time);
@@ -34,9 +39,49 @@ export const GuildReminders = () => {
_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 (
<>
{!isFetched && <Loader />}
{!(userFetched && guildFetched && isFetched) && <Loader />}
<strong>Create Reminder</strong>
<div id={"reminderCreator"}>
@@ -100,44 +145,7 @@ export const GuildReminders = () => {
</div>
<div id={"guildReminders"} className={isFetching ? "loading" : ""}>
{isSuccess &&
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}
/>
</>
);
})}
{isSuccess && sorted}
</div>
</>
);

View File

@@ -1,5 +1,5 @@
import { useRef, useState } from "preact/hooks";
import { useMutation, useQueryClient } from "react-query";
import { useMutation } from "react-query";
import { patchGuildReminder, patchUserReminder } from "../../../api";
import { ICON_FLASH_TIME } from "../../../consts";
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 { EditButtonRow } from "./ButtonRow/EditButtonRow";
import { Message } from "./Message";
@@ -10,9 +10,16 @@ import "./styles.scss";
type Props = {
reminder: Reminder;
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 [reminder, setReminder] = useState(initialReminder);
const [collapsed, setCollapsed] = useState(false);
@@ -39,11 +46,15 @@ export const EditReminder = ({ reminder: initialReminder, globalCollapse }: Prop
setCollapsed(!collapsed);
}}
/>
<div class="columns reminder-settings">
<Message />
<Settings />
</div>
<EditButtonRow />
{!collapsed && (
<>
<div class="columns reminder-settings">
<Message />
<Settings userInfo={userInfo} guildInfo={guildInfo} />
</div>
<EditButtonRow />
</>
)}
</div>
</ReminderContext.Provider>
);

View File

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