diff --git a/src/app/hooks/useExploreServers.ts b/src/app/hooks/useExploreServers.ts index cc27baec..9e60eda9 100644 --- a/src/app/hooks/useExploreServers.ts +++ b/src/app/hooks/useExploreServers.ts @@ -7,16 +7,17 @@ export type InCinnyExploreServersContent = { servers?: string[]; }; -export const useExploreServers = (): [ - string[], - (server: string) => Promise, - (server: string) => Promise -] => { +export const useExploreServers = ( + exclude?: string[] +): [string[], (server: string) => Promise, (server: string) => Promise] => { const mx = useMatrixClient(); const accountData = useAccountData(AccountDataEvent.CinnyExplore); const userAddedServers = useMemo( - () => accountData?.getContent()?.servers ?? [], - [accountData] + () => + accountData + ?.getContent() + ?.servers?.filter((server) => !exclude?.includes(server)) ?? [], + [exclude, accountData] ); const addServer = useCallback( diff --git a/src/app/pages/client/explore/Explore.tsx b/src/app/pages/client/explore/Explore.tsx index e3a99c68..bec600eb 100644 --- a/src/app/pages/client/explore/Explore.tsx +++ b/src/app/pages/client/explore/Explore.tsx @@ -31,7 +31,6 @@ import { NavLink, } from '../../../components/nav'; import { getExploreFeaturedPath, getExploreServerPath } from '../../pathUtils'; -import { useClientConfig } from '../../../hooks/useClientConfig'; import { useExploreFeaturedRooms, useExploreServer, @@ -44,9 +43,10 @@ import { PageNav, PageNavContent, PageNavHeader } from '../../../components/page import { stopPropagation } from '../../../utils/keyboard'; import { useExploreServers } from '../../../hooks/useExploreServers'; import { useAlive } from '../../../hooks/useAlive'; +import { useClientConfig } from '../../../hooks/useClientConfig'; type AddExploreServerPromptProps = { - onSubmit: (server: string) => Promise; + onSubmit: (server: string, save: boolean) => Promise; header: ReactNode; children: ReactNode; selected?: boolean; @@ -69,19 +69,25 @@ export function AddExploreServerPrompt({ return server || undefined; }; - const [submitState, handleSubmit] = useAsyncCallback( - useCallback(async () => { + const submit = useCallback( + async (save: boolean) => { const server = getInputServer(); if (!server) return; await mx.publicRooms({ server, limit: 1 }); - await onSubmit(server); + await onSubmit(server, save); if (alive()) { setDialog(false); } - }, [alive, onSubmit, mx]) + }, + [alive, onSubmit, mx] ); + const [viewState, handleView] = useAsyncCallback(() => submit(false)); + const [saveViewState, handleSaveView] = useAsyncCallback(() => submit(true)); + const busy = + viewState.status === AsyncStatus.Loading || saveViewState.status === AsyncStatus.Loading; + return ( <> }> @@ -108,21 +114,12 @@ export function AddExploreServerPrompt({ - { - evt.preventDefault(); - handleSubmit(); - }} - style={{ padding: config.space.S400 }} - direction="Column" - gap="400" - > + Add server name to explore public communities. Server Name - {submitState.status === AsyncStatus.Error && ( + {viewState.status === AsyncStatus.Error && ( Failed to load public rooms. Please try again. @@ -131,18 +128,32 @@ export function AddExploreServerPrompt({ + @@ -158,30 +169,33 @@ export function AddExploreServerPrompt({ ); } +type ExploreServerNavItemAction = { + onClick: () => Promise; + icon: IconSrc; + alwaysVisible: boolean; +}; type ExploreServerNavItemProps = { server: string; selected: boolean; icon: IconSrc; - onRemove?: (() => Promise) | null; + action?: ExploreServerNavItemAction; }; export function ExploreServerNavItem({ server, selected, icon, - onRemove = null, + action, }: ExploreServerNavItemProps) { const [hover, setHover] = useState(false); const { hoverProps } = useHover({ onHoverChange: setHover }); const { focusWithinProps } = useFocusWithin({ onFocusWithinChange: setHover }); - const [removeState, removeCallback] = useAsyncCallback( + const [actionState, actionCallback] = useAsyncCallback( useCallback(async () => { - if (onRemove !== null) { - await onRemove(); - } - }, [onRemove]) + await action?.onClick(); + }, [action]) ); - const removeInProgress = - removeState.status === AsyncStatus.Loading || removeState.status === AsyncStatus.Success; + const actionInProgress = + actionState.status === AsyncStatus.Loading || actionState.status === AsyncStatus.Success; return ( - {onRemove !== null && (hover || removeInProgress) && ( + {action !== undefined && (hover || actionInProgress || action.alwaysVisible) && ( - {removeInProgress ? ( + {actionInProgress ? ( ) : ( - + )} @@ -239,7 +253,7 @@ export function Explore() { clientConfig.featuredCommunities?.servers?.filter((server) => server !== userServer) ?? [], [clientConfig, userServer] ); - const [exploreServers, addServer, removeServer] = useExploreServers(); + const [exploreServers, addServer, removeServer] = useExploreServers(featuredServers); const selectedServer = useExploreServer(); const exploringFeaturedRooms = useExploreFeaturedRooms(); @@ -251,12 +265,12 @@ export function Explore() { featuredServers.includes(selectedServer) || exploreServers.includes(selectedServer) ), - [exploreServers, featuredServers, selectedServer, userServer] + [exploreServers, selectedServer, userServer, featuredServers] ); const addServerCallback = useCallback( - async (server: string) => { - if (server !== userServer && selectedServer && !featuredServers.includes(selectedServer)) { + async (server: string, save: boolean) => { + if (save && server !== userServer && !featuredServers.includes(server) && selectedServer) { await addServer(server); } navigate(getExploreServerPath(server)); @@ -271,13 +285,6 @@ export function Explore() { [removeServer] ); - const exploreUnlistedServerCallback = useCallback( - async (server: string) => { - navigate(getExploreServerPath(server)); - }, - [navigate] - ); - return ( @@ -293,29 +300,6 @@ export function Explore() { - View Server} - selected={exploringUnlistedServer} - > - - - - - - - Explore with Address - - - - - - - - - Featured - - @@ -325,7 +309,7 @@ export function Explore() { - Featured Rooms + Featured @@ -339,6 +323,25 @@ export function Explore() { icon={Icons.Home} /> )} + {exploringUnlistedServer && selectedServer !== undefined && ( + addServerCallback(selectedServer, true), + }} + /> + )} + + + + + Servers + + {featuredServers.map((server) => ( ))} - - - - - Servers - - {exploreServers.map((server) => ( removeServerCallback(server)} icon={Icons.Server} + action={{ + alwaysVisible: false, + icon: Icons.Minus, + onClick: () => removeServerCallback(server), + }} /> ))}