mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
Signed-off-by: npub1dccv64krpcpse5cmkzfeh998cftungyatw3djt8jwdw6g43f7fyqzzmrf7 <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz> Co-authored-by: npub1dccv64krpcpse5cmkzfeh998cftungyatw3djt8jwdw6g43f7fyqzzmrf7 <6e30cd56c30e030cd31bb0939b94a7c257c9a09d5ba2d92cf2735da45629f248@buzz.block.builderlab.xyz>
102 lines
3.3 KiB
TypeScript
102 lines
3.3 KiB
TypeScript
import { useRouter } from "@tanstack/react-router";
|
|
import * as React from "react";
|
|
|
|
import type { deriveShellRoute } from "@/app/AppShell.helpers";
|
|
import type { useAppNavigation } from "@/app/navigation/useAppNavigation";
|
|
import {
|
|
replaceCommunityDestinationRoute,
|
|
runCommunityViewTransition,
|
|
} from "@/app/communityViewTransition";
|
|
import {
|
|
loadCommunityDestination,
|
|
markPendingCommunityRestore,
|
|
saveCommunityDestination,
|
|
} from "@/features/communities/communityNavigationStorage";
|
|
import type { useCommunities } from "@/features/communities/useCommunities";
|
|
|
|
type Communities = ReturnType<typeof useCommunities>;
|
|
type ShellRoute = ReturnType<typeof deriveShellRoute>;
|
|
type GoHome = ReturnType<typeof useAppNavigation>["goHome"];
|
|
|
|
export function useCommunityNavigationTransitions({
|
|
communities,
|
|
goHome,
|
|
selectedChannelId,
|
|
selectedView,
|
|
}: {
|
|
communities: Communities;
|
|
goHome: GoHome;
|
|
selectedChannelId: ShellRoute["selectedChannelId"];
|
|
selectedView: ShellRoute["selectedView"];
|
|
}) {
|
|
const router = useRouter();
|
|
const saveActiveDestination = React.useCallback(() => {
|
|
const activeCommunityId = communities.activeCommunity?.id;
|
|
if (!activeCommunityId) return;
|
|
saveCommunityDestination(
|
|
activeCommunityId,
|
|
selectedView === "channel" && selectedChannelId
|
|
? { kind: "channel", channelId: selectedChannelId }
|
|
: { kind: "home" },
|
|
);
|
|
}, [communities.activeCommunity?.id, selectedChannelId, selectedView]);
|
|
|
|
// Home is a teardown barrier: the outgoing channel must unmount before the
|
|
// relay changes, or its read effect can advance markers on the wrong relay.
|
|
const switchCommunity = React.useCallback(
|
|
async (id: string) => {
|
|
const activeCommunityId = communities.activeCommunity?.id;
|
|
if (id === activeCommunityId) return;
|
|
if (!activeCommunityId) {
|
|
communities.switchCommunity(id);
|
|
return;
|
|
}
|
|
|
|
await runCommunityViewTransition(async () => {
|
|
saveActiveDestination();
|
|
await goHome({ replace: true });
|
|
markPendingCommunityRestore(id);
|
|
const destination = loadCommunityDestination(id);
|
|
if (destination?.kind === "channel") {
|
|
replaceCommunityDestinationRoute(
|
|
destination.channelId,
|
|
router.history,
|
|
);
|
|
}
|
|
communities.switchCommunity(id);
|
|
});
|
|
},
|
|
[communities, goHome, router.history, saveActiveDestination],
|
|
);
|
|
|
|
const removeCommunity = React.useCallback(
|
|
async (id: string) => {
|
|
if (id !== communities.activeCommunity?.id) {
|
|
communities.removeCommunity(id);
|
|
return;
|
|
}
|
|
const fallback = communities.communities.find(
|
|
(community) => community.id !== id,
|
|
);
|
|
if (!fallback) return;
|
|
|
|
await runCommunityViewTransition(async () => {
|
|
saveActiveDestination();
|
|
await goHome({ replace: true });
|
|
markPendingCommunityRestore(fallback.id);
|
|
const destination = loadCommunityDestination(fallback.id);
|
|
if (destination?.kind === "channel") {
|
|
replaceCommunityDestinationRoute(
|
|
destination.channelId,
|
|
router.history,
|
|
);
|
|
}
|
|
communities.removeCommunity(id);
|
|
});
|
|
},
|
|
[communities, goHome, router.history, saveActiveDestination],
|
|
);
|
|
|
|
return { removeCommunity, switchCommunity };
|
|
}
|