mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-11-06 23:30:28 +03:00
Hide bookmark entries for featured servers
This commit is contained in:
parent
be51dc5f12
commit
2f42ca99fc
2 changed files with 85 additions and 84 deletions
|
|
@ -7,16 +7,17 @@ export type InCinnyExploreServersContent = {
|
|||
servers?: string[];
|
||||
};
|
||||
|
||||
export const useExploreServers = (): [
|
||||
string[],
|
||||
(server: string) => Promise<void>,
|
||||
(server: string) => Promise<void>
|
||||
] => {
|
||||
export const useExploreServers = (
|
||||
exclude?: string[]
|
||||
): [string[], (server: string) => Promise<void>, (server: string) => Promise<void>] => {
|
||||
const mx = useMatrixClient();
|
||||
const accountData = useAccountData(AccountDataEvent.CinnyExplore);
|
||||
const userAddedServers = useMemo(
|
||||
() => accountData?.getContent<InCinnyExploreServersContent>()?.servers ?? [],
|
||||
[accountData]
|
||||
() =>
|
||||
accountData
|
||||
?.getContent<InCinnyExploreServersContent>()
|
||||
?.servers?.filter((server) => !exclude?.includes(server)) ?? [],
|
||||
[exclude, accountData]
|
||||
);
|
||||
|
||||
const addServer = useCallback(
|
||||
|
|
|
|||
|
|
@ -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<void>;
|
||||
onSubmit: (server: string, save: boolean) => Promise<void>;
|
||||
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 (
|
||||
<>
|
||||
<Overlay open={dialog} backdrop={<OverlayBackdrop />}>
|
||||
|
|
@ -108,21 +114,12 @@ export function AddExploreServerPrompt({
|
|||
<Icon src={Icons.Cross} />
|
||||
</IconButton>
|
||||
</Header>
|
||||
<Box
|
||||
as="form"
|
||||
onSubmit={(evt) => {
|
||||
evt.preventDefault();
|
||||
handleSubmit();
|
||||
}}
|
||||
style={{ padding: config.space.S400 }}
|
||||
direction="Column"
|
||||
gap="400"
|
||||
>
|
||||
<Box style={{ padding: config.space.S400 }} direction="Column" gap="400">
|
||||
<Text priority="400">Add server name to explore public communities.</Text>
|
||||
<Box direction="Column" gap="100">
|
||||
<Text size="L400">Server Name</Text>
|
||||
<Input ref={serverInputRef} name="serverInput" variant="Background" required />
|
||||
{submitState.status === AsyncStatus.Error && (
|
||||
{viewState.status === AsyncStatus.Error && (
|
||||
<Text style={{ color: color.Critical.Main }} size="T300">
|
||||
Failed to load public rooms. Please try again.
|
||||
</Text>
|
||||
|
|
@ -131,18 +128,32 @@ export function AddExploreServerPrompt({
|
|||
<Box direction="Column" gap="200">
|
||||
<Button
|
||||
type="submit"
|
||||
onClick={handleSubmit}
|
||||
onClick={handleView}
|
||||
variant="Secondary"
|
||||
fill="Soft"
|
||||
before={
|
||||
submitState.status === AsyncStatus.Loading && (
|
||||
viewState.status === AsyncStatus.Loading && (
|
||||
<Spinner fill="Solid" variant="Secondary" size="200" />
|
||||
)
|
||||
}
|
||||
disabled={submitState.status === AsyncStatus.Loading}
|
||||
disabled={busy}
|
||||
>
|
||||
<Text size="B400">View</Text>
|
||||
</Button>
|
||||
<Button
|
||||
type="submit"
|
||||
onClick={handleSaveView}
|
||||
variant="Primary"
|
||||
fill="Soft"
|
||||
before={
|
||||
saveViewState.status === AsyncStatus.Loading && (
|
||||
<Spinner fill="Solid" variant="Secondary" size="200" />
|
||||
)
|
||||
}
|
||||
disabled={busy}
|
||||
>
|
||||
<Text size="B400">Save & View</Text>
|
||||
</Button>
|
||||
</Box>
|
||||
</Box>
|
||||
</Dialog>
|
||||
|
|
@ -158,30 +169,33 @@ export function AddExploreServerPrompt({
|
|||
);
|
||||
}
|
||||
|
||||
type ExploreServerNavItemAction = {
|
||||
onClick: () => Promise<void>;
|
||||
icon: IconSrc;
|
||||
alwaysVisible: boolean;
|
||||
};
|
||||
type ExploreServerNavItemProps = {
|
||||
server: string;
|
||||
selected: boolean;
|
||||
icon: IconSrc;
|
||||
onRemove?: (() => Promise<void>) | 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 (
|
||||
<NavItem
|
||||
|
|
@ -205,20 +219,20 @@ export function ExploreServerNavItem({
|
|||
</Box>
|
||||
</NavItemContent>
|
||||
</NavLink>
|
||||
{onRemove !== null && (hover || removeInProgress) && (
|
||||
{action !== undefined && (hover || actionInProgress || action.alwaysVisible) && (
|
||||
<NavItemOptions>
|
||||
<IconButton
|
||||
onClick={removeCallback}
|
||||
onClick={actionCallback}
|
||||
variant="Background"
|
||||
fill="None"
|
||||
size="300"
|
||||
radii="300"
|
||||
disabled={removeInProgress}
|
||||
disabled={actionInProgress}
|
||||
>
|
||||
{removeInProgress ? (
|
||||
{actionInProgress ? (
|
||||
<Spinner variant="Secondary" fill="Solid" size="200" />
|
||||
) : (
|
||||
<Icon size="50" src={Icons.Minus} />
|
||||
<Icon size="50" src={action.icon} />
|
||||
)}
|
||||
</IconButton>
|
||||
</NavItemOptions>
|
||||
|
|
@ -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 (
|
||||
<PageNav>
|
||||
<PageNavHeader>
|
||||
|
|
@ -293,29 +300,6 @@ export function Explore() {
|
|||
<PageNavContent>
|
||||
<Box direction="Column" gap="300">
|
||||
<NavCategory>
|
||||
<AddExploreServerPrompt
|
||||
onSubmit={exploreUnlistedServerCallback}
|
||||
header={<Text size="H4">View Server</Text>}
|
||||
selected={exploringUnlistedServer}
|
||||
>
|
||||
<Box as="span" grow="Yes" alignItems="Center" gap="200">
|
||||
<Avatar size="200" radii="400">
|
||||
<Icon src={Icons.Link} size="100" />
|
||||
</Avatar>
|
||||
<Box as="span" grow="Yes">
|
||||
<Text as="span" size="Inherit" truncate>
|
||||
Explore with Address
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
</AddExploreServerPrompt>
|
||||
</NavCategory>
|
||||
<NavCategory>
|
||||
<NavCategoryHeader>
|
||||
<Text size="O400" style={{ paddingLeft: config.space.S200 }}>
|
||||
Featured
|
||||
</Text>
|
||||
</NavCategoryHeader>
|
||||
<NavItem variant="Background" radii="400" aria-selected={exploringFeaturedRooms}>
|
||||
<NavLink to={getExploreFeaturedPath()}>
|
||||
<NavItemContent>
|
||||
|
|
@ -325,7 +309,7 @@ export function Explore() {
|
|||
</Avatar>
|
||||
<Box as="span" grow="Yes">
|
||||
<Text as="span" size="Inherit" truncate>
|
||||
Featured Rooms
|
||||
Featured
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
|
|
@ -339,6 +323,25 @@ export function Explore() {
|
|||
icon={Icons.Home}
|
||||
/>
|
||||
)}
|
||||
{exploringUnlistedServer && selectedServer !== undefined && (
|
||||
<ExploreServerNavItem
|
||||
server={selectedServer}
|
||||
selected
|
||||
icon={Icons.Server}
|
||||
action={{
|
||||
alwaysVisible: true,
|
||||
icon: Icons.Plus,
|
||||
onClick: () => addServerCallback(selectedServer, true),
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</NavCategory>
|
||||
<NavCategory>
|
||||
<NavCategoryHeader>
|
||||
<Text size="O400" style={{ paddingLeft: config.space.S200 }}>
|
||||
Servers
|
||||
</Text>
|
||||
</NavCategoryHeader>
|
||||
{featuredServers.map((server) => (
|
||||
<ExploreServerNavItem
|
||||
key={server}
|
||||
|
|
@ -347,20 +350,17 @@ export function Explore() {
|
|||
icon={Icons.Server}
|
||||
/>
|
||||
))}
|
||||
</NavCategory>
|
||||
<NavCategory>
|
||||
<NavCategoryHeader>
|
||||
<Text size="O400" style={{ paddingLeft: config.space.S200 }}>
|
||||
Servers
|
||||
</Text>
|
||||
</NavCategoryHeader>
|
||||
{exploreServers.map((server) => (
|
||||
<ExploreServerNavItem
|
||||
key={server}
|
||||
server={server}
|
||||
selected={server === selectedServer}
|
||||
onRemove={() => removeServerCallback(server)}
|
||||
icon={Icons.Server}
|
||||
action={{
|
||||
alwaysVisible: false,
|
||||
icon: Icons.Minus,
|
||||
onClick: () => removeServerCallback(server),
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
<AddExploreServerPrompt
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue