web/lib/use-app-switcher.tsxblame
View source
10621c51"use client";
10621c52
10621c53import { useState, useEffect, useMemo } from "react";
10621c54import { GroveLogo } from "@/app/components/grove-logo";
10621c55import { CanopyLogo } from "@/app/components/canopy-logo";
10621c56import { RingLogo } from "@/app/components/ring-logo";
10621c57import { CollabLogo } from "@/app/components/collab-logo";
10621c58import type { AppSwitcherItem } from "@/app/components/ui/navbar";
10621c59
10621c510function useSubdomainOrigin(subdomain: string) {
10621c511 const [origin, setOrigin] = useState("");
10621c512 useEffect(() => {
10621c513 const host = window.location.host;
10621c514 // Strip existing subdomain prefix if present (e.g. canopy.grove.host → grove.host)
10621c515 const parts = host.split(".");
10621c516 const base =
10621c517 parts[0] === "canopy" || parts[0] === "ring" || parts[0] === "collab"
10621c518 ? parts.slice(1).join(".")
10621c519 : host;
10621c520 setOrigin(`${window.location.protocol}//${subdomain}.${base}`);
10621c521 }, [subdomain]);
10621c522 return origin;
10621c523}
10621c524
10621c525function useBaseOrigin() {
10621c526 const [origin, setOrigin] = useState("");
10621c527 useEffect(() => {
10621c528 const host = window.location.host;
10621c529 const parts = host.split(".");
10621c530 const base =
10621c531 parts[0] === "canopy" || parts[0] === "ring" || parts[0] === "collab"
10621c532 ? parts.slice(1).join(".")
10621c533 : host;
10621c534 setOrigin(`${window.location.protocol}//${base}`);
10621c535 }, []);
10621c536 return origin;
10621c537}
10621c538
10621c539/**
10621c540 * Returns app switcher items for all apps except the current one.
10621c541 * Pass the current app name (e.g. "grove", "canopy") to exclude it.
10621c542 */
10621c543export function useAppSwitcherItems(
10621c544 currentApp: "grove" | "canopy" | "ring" | "collab",
10621c545 context?: { owner?: string; repo?: string },
10621c546): AppSwitcherItem[] {
10621c547 const groveOrigin = useBaseOrigin();
10621c548 const canopyOrigin = useSubdomainOrigin("canopy");
10621c549 const ringOrigin = useSubdomainOrigin("ring");
10621c550 const collabOrigin = useSubdomainOrigin("collab");
10621c551
10621c552 return useMemo(() => {
10621c553 const repoPath = context?.owner && context?.repo ? `/${context.owner}/${context.repo}` : "";
10621c554 const all: (AppSwitcherItem & { key: string })[] = [
10621c555 { key: "grove", name: "Grove", logo: <GroveLogo size={28} />, href: `${groveOrigin}${repoPath}` },
10621c556 { key: "canopy", name: "Canopy", logo: <CanopyLogo size={28} />, href: `${canopyOrigin}${repoPath}${repoPath ? "/builds" : ""}` },
10621c557 { key: "ring", name: "Ring", logo: <RingLogo size={28} />, href: `${ringOrigin}${repoPath}` },
10621c558 { key: "collab", name: "Collab", logo: <CollabLogo size={28} />, href: `${collabOrigin}${repoPath}` },
10621c559 ];
10621c560 return all.filter((item) => item.key !== currentApp);
10621c561 }, [currentApp, context?.owner, context?.repo, groveOrigin, canopyOrigin, ringOrigin, collabOrigin]);
10621c562}