mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-11-05 23:10:28 +03:00
Show a loading spinner while removing a server
This commit is contained in:
parent
a374a5fb94
commit
4c126e47b6
2 changed files with 61 additions and 35 deletions
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { useCallback, useMemo } from 'react';
|
||||||
import { AccountDataEvent } from '../../types/matrix/accountData';
|
import { AccountDataEvent } from '../../types/matrix/accountData';
|
||||||
import { useAccountData } from './useAccountData';
|
import { useAccountData } from './useAccountData';
|
||||||
import { useMatrixClient } from './useMatrixClient';
|
import { useMatrixClient } from './useMatrixClient';
|
||||||
|
|
@ -6,33 +7,37 @@ export type InCinnyExploreServersContent = {
|
||||||
servers?: string[];
|
servers?: string[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ExploreServerListAction =
|
export const useExploreServers = (): [
|
||||||
| {
|
string[],
|
||||||
type: 'APPEND';
|
(server: string) => Promise<void>,
|
||||||
server: string;
|
(server: string) => Promise<void>
|
||||||
}
|
] => {
|
||||||
| {
|
|
||||||
type: 'DELETE';
|
|
||||||
server: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useExploreServers = (): [string[], (action: ExploreServerListAction) => void] => {
|
|
||||||
const mx = useMatrixClient();
|
const mx = useMatrixClient();
|
||||||
const userAddedServers =
|
const accountData = useAccountData(AccountDataEvent.CinnyExploreServers);
|
||||||
useAccountData(AccountDataEvent.CinnyExploreServers)?.getContent<InCinnyExploreServersContent>()
|
const userAddedServers = useMemo(
|
||||||
?.servers ?? [];
|
() => accountData?.getContent<InCinnyExploreServersContent>()?.servers ?? [],
|
||||||
|
[accountData]
|
||||||
|
);
|
||||||
|
|
||||||
const setUserAddedServers = (action: ExploreServerListAction) => {
|
const addServer = useCallback(
|
||||||
if (action.type === 'APPEND') {
|
async (server: string) => {
|
||||||
mx.setAccountData(AccountDataEvent.CinnyExploreServers, {
|
if (userAddedServers.indexOf(server) === -1) {
|
||||||
servers: [...userAddedServers, action.server],
|
await mx.setAccountData(AccountDataEvent.CinnyExploreServers, {
|
||||||
});
|
servers: [...userAddedServers, server],
|
||||||
} else if (action.type === 'DELETE') {
|
});
|
||||||
mx.setAccountData(AccountDataEvent.CinnyExploreServers, {
|
}
|
||||||
servers: userAddedServers.filter((server) => server !== action.server),
|
},
|
||||||
});
|
[mx, userAddedServers]
|
||||||
}
|
);
|
||||||
};
|
|
||||||
|
|
||||||
return [userAddedServers, setUserAddedServers];
|
const removeServer = useCallback(
|
||||||
|
async (server: string) => {
|
||||||
|
await mx.setAccountData(AccountDataEvent.CinnyExploreServers, {
|
||||||
|
servers: userAddedServers.filter((addedServer) => server !== addedServer),
|
||||||
|
});
|
||||||
|
},
|
||||||
|
[mx, userAddedServers]
|
||||||
|
);
|
||||||
|
|
||||||
|
return [userAddedServers, addServer, removeServer];
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import {
|
||||||
Overlay,
|
Overlay,
|
||||||
OverlayBackdrop,
|
OverlayBackdrop,
|
||||||
OverlayCenter,
|
OverlayCenter,
|
||||||
|
Spinner,
|
||||||
Text,
|
Text,
|
||||||
color,
|
color,
|
||||||
config,
|
config,
|
||||||
|
|
@ -45,7 +46,7 @@ export function AddExploreServerPrompt() {
|
||||||
const mx = useMatrixClient();
|
const mx = useMatrixClient();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [dialog, setDialog] = useState(false);
|
const [dialog, setDialog] = useState(false);
|
||||||
const [, setExploreServers] = useExploreServers();
|
const [, addServer] = useExploreServers();
|
||||||
const serverInputRef = useRef<HTMLInputElement>(null);
|
const serverInputRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
const [exploreState] = useAsyncCallback(
|
const [exploreState] = useAsyncCallback(
|
||||||
|
|
@ -64,9 +65,9 @@ export function AddExploreServerPrompt() {
|
||||||
if (!server) return;
|
if (!server) return;
|
||||||
|
|
||||||
setDialog(false);
|
setDialog(false);
|
||||||
setExploreServers({ type: 'APPEND', server });
|
addServer(server);
|
||||||
navigate(getExploreServerPath(server));
|
navigate(getExploreServerPath(server));
|
||||||
}, [navigate, setExploreServers]);
|
}, [navigate, addServer]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
@ -157,7 +158,7 @@ export function AddExploreServerPrompt() {
|
||||||
type ExploreServerNavItemProps = {
|
type ExploreServerNavItemProps = {
|
||||||
server: string;
|
server: string;
|
||||||
selected: boolean;
|
selected: boolean;
|
||||||
onRemove?: (() => void) | null;
|
onRemove?: (() => Promise<void>) | null;
|
||||||
};
|
};
|
||||||
export function ExploreServerNavItem({
|
export function ExploreServerNavItem({
|
||||||
server,
|
server,
|
||||||
|
|
@ -167,6 +168,15 @@ export function ExploreServerNavItem({
|
||||||
const [hover, setHover] = useState(false);
|
const [hover, setHover] = useState(false);
|
||||||
const { hoverProps } = useHover({ onHoverChange: setHover });
|
const { hoverProps } = useHover({ onHoverChange: setHover });
|
||||||
const { focusWithinProps } = useFocusWithin({ onFocusWithinChange: setHover });
|
const { focusWithinProps } = useFocusWithin({ onFocusWithinChange: setHover });
|
||||||
|
const [removeState, removeCallback] = useAsyncCallback(
|
||||||
|
useCallback(async () => {
|
||||||
|
if (onRemove !== null) {
|
||||||
|
await onRemove();
|
||||||
|
}
|
||||||
|
}, [onRemove])
|
||||||
|
);
|
||||||
|
const removeInProgress =
|
||||||
|
removeState.status === AsyncStatus.Loading || removeState.status === AsyncStatus.Success;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NavItem
|
<NavItem
|
||||||
|
|
@ -190,10 +200,21 @@ export function ExploreServerNavItem({
|
||||||
</Box>
|
</Box>
|
||||||
</NavItemContent>
|
</NavItemContent>
|
||||||
</NavLink>
|
</NavLink>
|
||||||
{onRemove !== null && hover && (
|
{onRemove !== null && (hover || removeInProgress) && (
|
||||||
<NavItemOptions>
|
<NavItemOptions>
|
||||||
<IconButton onClick={onRemove} variant="Background" fill="None" size="300" radii="300">
|
<IconButton
|
||||||
<Icon size="50" src={Icons.Minus} />
|
onClick={removeCallback}
|
||||||
|
variant="Background"
|
||||||
|
fill="None"
|
||||||
|
size="300"
|
||||||
|
radii="300"
|
||||||
|
disabled={removeInProgress}
|
||||||
|
>
|
||||||
|
{removeInProgress ? (
|
||||||
|
<Spinner variant="Secondary" fill="Solid" size="200" />
|
||||||
|
) : (
|
||||||
|
<Icon size="50" src={Icons.Minus} />
|
||||||
|
)}
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</NavItemOptions>
|
</NavItemOptions>
|
||||||
)}
|
)}
|
||||||
|
|
@ -209,7 +230,7 @@ export function Explore() {
|
||||||
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, setExploreServers] = useExploreServers();
|
const [exploreServers, , removeServer] = useExploreServers();
|
||||||
|
|
||||||
const featuredSelected = useExploreFeaturedSelected();
|
const featuredSelected = useExploreFeaturedSelected();
|
||||||
const selectedServer = useExploreServer();
|
const selectedServer = useExploreServer();
|
||||||
|
|
@ -290,7 +311,7 @@ export function Explore() {
|
||||||
key={server}
|
key={server}
|
||||||
server={server}
|
server={server}
|
||||||
selected={server === selectedServer}
|
selected={server === selectedServer}
|
||||||
onRemove={() => setExploreServers({ type: 'DELETE', server })}
|
onRemove={() => removeServer(server)}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</NavCategory>
|
</NavCategory>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue