mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-11-06 15:30:27 +03:00
Show a loading spinner while adding a server
This commit is contained in:
parent
4c126e47b6
commit
018511effb
1 changed files with 59 additions and 63 deletions
|
|
@ -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 { useNavigate } from 'react-router-dom';
|
||||||
import FocusTrap from 'focus-trap-react';
|
import FocusTrap from 'focus-trap-react';
|
||||||
import {
|
import {
|
||||||
|
|
@ -21,6 +21,7 @@ import {
|
||||||
} from 'folds';
|
} from 'folds';
|
||||||
import { useFocusWithin, useHover } from 'react-aria';
|
import { useFocusWithin, useHover } from 'react-aria';
|
||||||
import {
|
import {
|
||||||
|
NavButton,
|
||||||
NavCategory,
|
NavCategory,
|
||||||
NavCategoryHeader,
|
NavCategoryHeader,
|
||||||
NavItem,
|
NavItem,
|
||||||
|
|
@ -42,17 +43,14 @@ import { PageNav, PageNavContent, PageNavHeader } from '../../../components/page
|
||||||
import { stopPropagation } from '../../../utils/keyboard';
|
import { stopPropagation } from '../../../utils/keyboard';
|
||||||
import { useExploreServers } from '../../../hooks/useExploreServers';
|
import { useExploreServers } from '../../../hooks/useExploreServers';
|
||||||
|
|
||||||
export function AddExploreServerPrompt() {
|
type AddExploreServerPromptProps = {
|
||||||
const mx = useMatrixClient();
|
onSubmit: (server: string) => Promise<void>;
|
||||||
const navigate = useNavigate();
|
children: ReactNode;
|
||||||
|
};
|
||||||
|
export function AddExploreServerPrompt({ onSubmit, children }: AddExploreServerPromptProps) {
|
||||||
const [dialog, setDialog] = useState(false);
|
const [dialog, setDialog] = useState(false);
|
||||||
const [, addServer] = useExploreServers();
|
|
||||||
const serverInputRef = useRef<HTMLInputElement>(null);
|
const serverInputRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
const [exploreState] = useAsyncCallback(
|
|
||||||
useCallback((server: string) => mx.publicRooms({ server, limit: 1 }), [mx])
|
|
||||||
);
|
|
||||||
|
|
||||||
const getInputServer = (): string | undefined => {
|
const getInputServer = (): string | undefined => {
|
||||||
const serverInput = serverInputRef.current;
|
const serverInput = serverInputRef.current;
|
||||||
if (!serverInput) return undefined;
|
if (!serverInput) return undefined;
|
||||||
|
|
@ -60,14 +58,15 @@ export function AddExploreServerPrompt() {
|
||||||
return server || undefined;
|
return server || undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = useCallback(() => {
|
const [submitState, handleSubmit] = useAsyncCallback(
|
||||||
|
useCallback(async () => {
|
||||||
const server = getInputServer();
|
const server = getInputServer();
|
||||||
if (!server) return;
|
if (!server) return;
|
||||||
|
|
||||||
|
await onSubmit(server);
|
||||||
setDialog(false);
|
setDialog(false);
|
||||||
addServer(server);
|
}, [onSubmit])
|
||||||
navigate(getExploreServerPath(server));
|
);
|
||||||
}, [navigate, addServer]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
@ -111,27 +110,25 @@ export function AddExploreServerPrompt() {
|
||||||
<Box direction="Column" gap="100">
|
<Box direction="Column" gap="100">
|
||||||
<Text size="L400">Server Name</Text>
|
<Text size="L400">Server Name</Text>
|
||||||
<Input ref={serverInputRef} name="serverInput" variant="Background" required />
|
<Input ref={serverInputRef} name="serverInput" variant="Background" required />
|
||||||
{exploreState.status === AsyncStatus.Error && (
|
{submitState.status === AsyncStatus.Error && (
|
||||||
<Text style={{ color: color.Critical.Main }} size="T300">
|
<Text style={{ color: color.Critical.Main }} size="T300">
|
||||||
Failed to load public rooms. Please try again.
|
Failed to load public rooms. Please try again.
|
||||||
</Text>
|
</Text>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
<Box direction="Column" gap="200">
|
<Box direction="Column" gap="200">
|
||||||
{/* <Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
|
onClick={handleSubmit}
|
||||||
variant="Secondary"
|
variant="Secondary"
|
||||||
|
fill="Soft"
|
||||||
before={
|
before={
|
||||||
exploreState.status === AsyncStatus.Loading ? (
|
submitState.status === AsyncStatus.Loading && (
|
||||||
<Spinner fill="Solid" variant="Secondary" size="200" />
|
<Spinner fill="Solid" variant="Secondary" size="200" />
|
||||||
) : undefined
|
)
|
||||||
}
|
}
|
||||||
aria-disabled={exploreState.status === AsyncStatus.Loading}
|
disabled={submitState.status === AsyncStatus.Loading}
|
||||||
>
|
>
|
||||||
<Text size="B400">Save</Text>
|
|
||||||
</Button> */}
|
|
||||||
|
|
||||||
<Button type="submit" onClick={handleSubmit} variant="Secondary" fill="Soft">
|
|
||||||
<Text size="B400">View</Text>
|
<Text size="B400">View</Text>
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
@ -140,17 +137,11 @@ export function AddExploreServerPrompt() {
|
||||||
</FocusTrap>
|
</FocusTrap>
|
||||||
</OverlayCenter>
|
</OverlayCenter>
|
||||||
</Overlay>
|
</Overlay>
|
||||||
<Button
|
<NavItem variant="Secondary">
|
||||||
variant="Secondary"
|
<NavButton onClick={() => setDialog(true)}>
|
||||||
fill="Soft"
|
<NavItemContent>{children}</NavItemContent>
|
||||||
size="300"
|
</NavButton>
|
||||||
before={<Icon size="100" src={Icons.Plus} />}
|
</NavItem>
|
||||||
onClick={() => setDialog(true)}
|
|
||||||
>
|
|
||||||
<Text size="B300" truncate>
|
|
||||||
Add Server
|
|
||||||
</Text>
|
|
||||||
</Button>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -224,17 +215,34 @@ export function ExploreServerNavItem({
|
||||||
|
|
||||||
export function Explore() {
|
export function Explore() {
|
||||||
const mx = useMatrixClient();
|
const mx = useMatrixClient();
|
||||||
|
const navigate = useNavigate();
|
||||||
useNavToActivePathMapper('explore');
|
useNavToActivePathMapper('explore');
|
||||||
const userId = mx.getUserId();
|
const userId = mx.getUserId();
|
||||||
const clientConfig = useClientConfig();
|
const clientConfig = useClientConfig();
|
||||||
const userServer = userId ? getMxIdServer(userId) : undefined;
|
const userServer = userId ? getMxIdServer(userId) : undefined;
|
||||||
const featuredServers =
|
const featuredServers =
|
||||||
clientConfig.featuredCommunities?.servers?.filter((server) => server !== userServer) ?? [];
|
clientConfig.featuredCommunities?.servers?.filter((server) => server !== userServer) ?? [];
|
||||||
const [exploreServers, , removeServer] = useExploreServers();
|
const [exploreServers, addServer, removeServer] = useExploreServers();
|
||||||
|
|
||||||
const featuredSelected = useExploreFeaturedSelected();
|
const featuredSelected = useExploreFeaturedSelected();
|
||||||
const selectedServer = useExploreServer();
|
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 (
|
return (
|
||||||
<PageNav>
|
<PageNav>
|
||||||
<PageNavHeader>
|
<PageNavHeader>
|
||||||
|
|
@ -267,30 +275,7 @@ export function Explore() {
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</NavItem>
|
</NavItem>
|
||||||
{userServer && (
|
{userServer && (
|
||||||
<NavItem
|
<ExploreServerNavItem server={userServer} selected={userServer === selectedServer} />
|
||||||
variant="Background"
|
|
||||||
radii="400"
|
|
||||||
aria-selected={selectedServer === userServer}
|
|
||||||
>
|
|
||||||
<NavLink to={getExploreServerPath(userServer)}>
|
|
||||||
<NavItemContent>
|
|
||||||
<Box as="span" grow="Yes" alignItems="Center" gap="200">
|
|
||||||
<Avatar size="200" radii="400">
|
|
||||||
<Icon
|
|
||||||
src={Icons.Category}
|
|
||||||
size="100"
|
|
||||||
filled={selectedServer === userServer}
|
|
||||||
/>
|
|
||||||
</Avatar>
|
|
||||||
<Box as="span" grow="Yes">
|
|
||||||
<Text as="span" size="Inherit" truncate>
|
|
||||||
{userServer}
|
|
||||||
</Text>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
</NavItemContent>
|
|
||||||
</NavLink>
|
|
||||||
</NavItem>
|
|
||||||
)}
|
)}
|
||||||
</NavCategory>
|
</NavCategory>
|
||||||
<NavCategory>
|
<NavCategory>
|
||||||
|
|
@ -311,12 +296,23 @@ export function Explore() {
|
||||||
key={server}
|
key={server}
|
||||||
server={server}
|
server={server}
|
||||||
selected={server === selectedServer}
|
selected={server === selectedServer}
|
||||||
onRemove={() => removeServer(server)}
|
onRemove={() => removeServerCallback(server)}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</NavCategory>
|
</NavCategory>
|
||||||
<Box direction="Column">
|
<Box direction="Column">
|
||||||
<AddExploreServerPrompt />
|
<AddExploreServerPrompt onSubmit={addServerCallback}>
|
||||||
|
<Box as="span" grow="Yes" alignItems="Center" gap="200">
|
||||||
|
<Avatar size="200" radii="400">
|
||||||
|
<Icon src={Icons.Plus} size="100" />
|
||||||
|
</Avatar>
|
||||||
|
<Box as="span" grow="Yes">
|
||||||
|
<Text as="span" size="Inherit" truncate>
|
||||||
|
Add Server
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
</AddExploreServerPrompt>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</PageNavContent>
|
</PageNavContent>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue