diff --git a/packages/api/src/routes/guilds/guild.ts b/packages/api/src/routes/guilds/guild.ts index 7e805cf..7301683 100644 --- a/packages/api/src/routes/guilds/guild.ts +++ b/packages/api/src/routes/guilds/guild.ts @@ -12,7 +12,7 @@ export const guildsGuild: RoleypolyHandler = async ( request: Request, context: Context ) => { - const { noCache } = getQuery(request); + const { __no_cache: noCache } = getQuery(request); const guild = await getGuild(context.config, context.params!.guildId!, !!noCache); if (!guild) { diff --git a/packages/design-system/organisms/editor-shell/EditorShell.tsx b/packages/design-system/organisms/editor-shell/EditorShell.tsx index 18d0f07..bcbefa7 100644 --- a/packages/design-system/organisms/editor-shell/EditorShell.tsx +++ b/packages/design-system/organisms/editor-shell/EditorShell.tsx @@ -15,6 +15,7 @@ export type EditorShellProps = { onGuildChange?: (guild: PresentableGuild) => void; onCategoryChange?: (category: Category) => void; onMessageChange?: (message: PresentableGuild['data']['message']) => void; + onRefreshCache?: () => void; }; export const EditorShell = (props: EditorShellProps) => { @@ -69,7 +70,11 @@ export const EditorShell = (props: EditorShellProps) => { guild={guild.guild} /> - + diff --git a/packages/design-system/organisms/server-category-editor/ServerCategoryEditor.tsx b/packages/design-system/organisms/server-category-editor/ServerCategoryEditor.tsx index 69da61b..239a6ad 100644 --- a/packages/design-system/organisms/server-category-editor/ServerCategoryEditor.tsx +++ b/packages/design-system/organisms/server-category-editor/ServerCategoryEditor.tsx @@ -15,7 +15,14 @@ import { flatten, sortBy } from 'lodash'; import React from 'react'; import { DragDropContext, Draggable, Droppable, DropResult } from 'react-beautiful-dnd'; import { CgReorder } from 'react-icons/cg'; -import { GoArrowDown, GoArrowUp, GoCheck, GoGrabber, GoPlus } from 'react-icons/go'; +import { + GoArrowDown, + GoArrowUp, + GoCheck, + GoGrabber, + GoPlus, + GoSync, +} from 'react-icons/go'; import { ulid } from 'ulidx'; import { CategoryActions, @@ -26,6 +33,7 @@ import { type Props = { guild: PresentableGuild; onChange: (categories: PresentableGuild['data']['categories']) => void; + onRefreshCache?: () => void; }; const resetOrder = (categories: Category[]) => @@ -126,6 +134,9 @@ export const ServerCategoryEditor = (props: Props) => { + {props.guild.data.categories.length > 0 ? ( sortBy(props.guild.data.categories, ['position', 'id']).map((category, idx) => ( diff --git a/packages/design-system/templates/editor/Editor.tsx b/packages/design-system/templates/editor/Editor.tsx index 6e6169c..0273a2a 100644 --- a/packages/design-system/templates/editor/Editor.tsx +++ b/packages/design-system/templates/editor/Editor.tsx @@ -7,11 +7,21 @@ import { export const EditorTemplate = ( props: EditorShellProps & Omit ) => { - const { guild, onCategoryChange, onMessageChange, onGuildChange, ...appShellProps } = - props; + const { + guild, + onCategoryChange, + onMessageChange, + onGuildChange, + onRefreshCache, + ...appShellProps + } = props; return ( - + ); }; diff --git a/packages/web/src/contexts/guild/GuildContext.tsx b/packages/web/src/contexts/guild/GuildContext.tsx index 7bc01fb..7b6c340 100644 --- a/packages/web/src/contexts/guild/GuildContext.tsx +++ b/packages/web/src/contexts/guild/GuildContext.tsx @@ -19,12 +19,14 @@ type GuildContextT = { ) => Promise; getGuildSlug: (id: string) => Promise; uncacheGuild: (id: string) => void; + uncacheRemoteGuild: (id: string) => Promise; }; export const GuildContext = React.createContext({ getFullGuild: (id: string) => Promise.reject(new Error('Not implemented')), getGuildSlug: (id: string) => Promise.reject(new Error('Not implemented')), - uncacheGuild: (id: string) => {}, + uncacheGuild: (id: string) => void 0, + uncacheRemoteGuild: (id: string) => Promise.resolve(void 0), }); export const useGuildContext = () => React.useContext(GuildContext); @@ -108,6 +110,9 @@ export const GuildProvider = (props: { children: React.ReactNode }) => { uncacheGuild: (id: string) => { sessionStorage.removeItem(`guild-${id}`); }, + uncacheRemoteGuild: async (id: string) => { + await authedFetch(`/guilds/${id}/cache`, { method: 'DELETE' }); + }, }; return ( diff --git a/packages/web/src/pages/editor.tsx b/packages/web/src/pages/editor.tsx index c8aad3a..fd521ed 100644 --- a/packages/web/src/pages/editor.tsx +++ b/packages/web/src/pages/editor.tsx @@ -25,7 +25,7 @@ const Editor = (props: EditorProps) => { const { authedFetch } = useAuthedFetch(); const { pushRecentGuild } = useRecentGuilds(); const appShellProps = useAppShellProps(); - const { getFullGuild, uncacheGuild } = useGuildContext(); + const { getFullGuild, uncacheGuild, uncacheRemoteGuild } = useGuildContext(); const [guild, setGuild] = React.useState(null); const [pending, setPending] = React.useState(false); @@ -52,8 +52,10 @@ const Editor = (props: EditorProps) => { setGuild(guild); }; - fetchGuild(); - }, [serverID, getFullGuild]); + if (guild === null) { + fetchGuild(); + } + }, [serverID, getFullGuild, guild]); React.useCallback((serverID) => pushRecentGuild(serverID), [pushRecentGuild])(serverID); @@ -105,10 +107,32 @@ const Editor = (props: EditorProps) => { setPending(false); }; + const onRefreshCache = async () => { + if ( + Number(sessionStorage.getItem('rp_editor_last_refresh')) > + Date.now() - 1000 * 60 * 2 + ) { + console.error('Slow down there partner!'); + return; + } + + console.log('Refreshing cache'); + uncacheGuild(serverID); + await uncacheRemoteGuild(serverID); + sessionStorage.setItem('rp_editor_last_pull', String(Date.now())); + sessionStorage.setItem('rp_editor_last_refresh', String(Date.now())); + setGuild(null); + }; + return ( <> - <EditorTemplate {...appShellProps} guild={guild} onGuildChange={onGuildChange} /> + <EditorTemplate + {...appShellProps} + guild={guild} + onGuildChange={onGuildChange} + onRefreshCache={onRefreshCache} + /> </> ); };