From 018511effb563e3f197b3386810a5dbb1702adee Mon Sep 17 00:00:00 2001 From: Ginger <75683114+gingershaped@users.noreply.github.com> Date: Tue, 18 Mar 2025 09:54:29 -0400 Subject: [PATCH] Show a loading spinner while adding a server --- src/app/pages/client/explore/Explore.tsx | 122 +++++++++++------------ 1 file changed, 59 insertions(+), 63 deletions(-) diff --git a/src/app/pages/client/explore/Explore.tsx b/src/app/pages/client/explore/Explore.tsx index 7d406a2f..db1c00ce 100644 --- a/src/app/pages/client/explore/Explore.tsx +++ b/src/app/pages/client/explore/Explore.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useRef, useState } from 'react'; +import React, { ReactNode, useCallback, useRef, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import FocusTrap from 'focus-trap-react'; import { @@ -21,6 +21,7 @@ import { } from 'folds'; import { useFocusWithin, useHover } from 'react-aria'; import { + NavButton, NavCategory, NavCategoryHeader, NavItem, @@ -42,17 +43,14 @@ import { PageNav, PageNavContent, PageNavHeader } from '../../../components/page import { stopPropagation } from '../../../utils/keyboard'; import { useExploreServers } from '../../../hooks/useExploreServers'; -export function AddExploreServerPrompt() { - const mx = useMatrixClient(); - const navigate = useNavigate(); +type AddExploreServerPromptProps = { + onSubmit: (server: string) => Promise; + children: ReactNode; +}; +export function AddExploreServerPrompt({ onSubmit, children }: AddExploreServerPromptProps) { const [dialog, setDialog] = useState(false); - const [, addServer] = useExploreServers(); const serverInputRef = useRef(null); - const [exploreState] = useAsyncCallback( - useCallback((server: string) => mx.publicRooms({ server, limit: 1 }), [mx]) - ); - const getInputServer = (): string | undefined => { const serverInput = serverInputRef.current; if (!serverInput) return undefined; @@ -60,14 +58,15 @@ export function AddExploreServerPrompt() { return server || undefined; }; - const handleSubmit = useCallback(() => { - const server = getInputServer(); - if (!server) return; + const [submitState, handleSubmit] = useAsyncCallback( + useCallback(async () => { + const server = getInputServer(); + if (!server) return; - setDialog(false); - addServer(server); - navigate(getExploreServerPath(server)); - }, [navigate, addServer]); + await onSubmit(server); + setDialog(false); + }, [onSubmit]) + ); return ( <> @@ -111,27 +110,25 @@ export function AddExploreServerPrompt() { Server Name - {exploreState.status === AsyncStatus.Error && ( + {submitState.status === AsyncStatus.Error && ( Failed to load public rooms. Please try again. )} - {/* */} - - @@ -140,17 +137,11 @@ export function AddExploreServerPrompt() { - + + setDialog(true)}> + {children} + + ); } @@ -224,17 +215,34 @@ export function ExploreServerNavItem({ export function Explore() { const mx = useMatrixClient(); + const navigate = useNavigate(); useNavToActivePathMapper('explore'); const userId = mx.getUserId(); const clientConfig = useClientConfig(); const userServer = userId ? getMxIdServer(userId) : undefined; const featuredServers = clientConfig.featuredCommunities?.servers?.filter((server) => server !== userServer) ?? []; - const [exploreServers, , removeServer] = useExploreServers(); + const [exploreServers, addServer, removeServer] = useExploreServers(); const featuredSelected = useExploreFeaturedSelected(); const selectedServer = useExploreServer(); + const addServerCallback = useCallback( + async (server: string) => { + await addServer(server); + navigate(getExploreServerPath(server)); + }, + [addServer, navigate] + ); + + const removeServerCallback = useCallback( + async (server: string) => { + navigate(getExploreFeaturedPath()); + await removeServer(server); + }, + [removeServer, navigate] + ); + return ( @@ -267,30 +275,7 @@ export function Explore() { {userServer && ( - - - - - - - - - - {userServer} - - - - - - + )} @@ -311,12 +296,23 @@ export function Explore() { key={server} server={server} selected={server === selectedServer} - onRemove={() => removeServer(server)} + onRemove={() => removeServerCallback(server)} /> ))} - + + + + + + + + Add Server + + + +