83 lines
2.3 KiB
TypeScript
83 lines
2.3 KiB
TypeScript
import { useState, useMemo, useEffect } from "react";
|
|
import { Identity } from "spacetimedb";
|
|
import * as Types from "../../../module_bindings/types";
|
|
|
|
export const useNavigation = (
|
|
identity: Identity | null,
|
|
servers: readonly Types.Server[],
|
|
channels: readonly Types.Channel[],
|
|
serverMembers: readonly Types.ServerMember[],
|
|
) => {
|
|
const [activeServerId, setActiveServerId] = useState<bigint | null>(null);
|
|
const [activeChannelId, setActiveChannelId] = useState<bigint | null>(null);
|
|
const [activeThreadId, setActiveThreadId] = useState<bigint | null>(null);
|
|
|
|
const joinedServerIds = useMemo(() => {
|
|
if (!identity) return new Set<bigint>();
|
|
return new Set(
|
|
serverMembers
|
|
.filter((m) => m.identity.isEqual(identity))
|
|
.map((m) => m.serverId),
|
|
);
|
|
}, [serverMembers, identity]);
|
|
|
|
const joinedServers = useMemo(() => {
|
|
return servers.filter((s) => joinedServerIds.has(s.id));
|
|
}, [servers, joinedServerIds]);
|
|
|
|
const availableServers = useMemo(() => {
|
|
return servers.filter((s) => !joinedServerIds.has(s.id));
|
|
}, [servers, joinedServerIds]);
|
|
|
|
// Initial server selection
|
|
useEffect(() => {
|
|
if (!activeServerId && joinedServers.length > 0) {
|
|
setActiveServerId(joinedServers[0].id);
|
|
}
|
|
}, [joinedServers, activeServerId]);
|
|
|
|
// Initial channel selection when server changes
|
|
useEffect(() => {
|
|
if (activeServerId) {
|
|
const serverChannels = channels.filter(
|
|
(c) => c.serverId === activeServerId && c.kind.tag === "Text",
|
|
);
|
|
if (serverChannels.length > 0) {
|
|
if (
|
|
!activeChannelId ||
|
|
!channels.some(
|
|
(c) => c.id === activeChannelId && c.serverId === activeServerId,
|
|
)
|
|
) {
|
|
setActiveChannelId(serverChannels[0].id);
|
|
}
|
|
} else {
|
|
setActiveChannelId(null);
|
|
}
|
|
}
|
|
}, [activeServerId, channels, activeChannelId]);
|
|
|
|
const activeServer = useMemo(
|
|
() => servers.find((s) => s.id === activeServerId),
|
|
[servers, activeServerId],
|
|
);
|
|
|
|
const activeChannel = useMemo(
|
|
() => channels.find((c) => c.id === activeChannelId),
|
|
[channels, activeChannelId],
|
|
);
|
|
|
|
return {
|
|
activeServerId,
|
|
setActiveServerId,
|
|
activeChannelId,
|
|
setActiveChannelId,
|
|
activeThreadId,
|
|
setActiveThreadId,
|
|
activeServer,
|
|
activeChannel,
|
|
joinedServers,
|
|
availableServers,
|
|
};
|
|
};
|