import { useEffect, useState } from "react"; import { AdminPanel } from "./components/AdminPanel.js"; import { FreeLabelPage } from "./components/FreeLabelPage.js"; import { FiltersPanel } from "./components/Filters.js"; import { Feed } from "./components/Feed.js"; import { GraphPage } from "./components/GraphPage.js"; import type { FreeLabelSummary, ContributorStats, Filters, LabelStat } from "./lib/api.js"; import { defaultFilters, fetchFreeLabels, fetchContributors, fetchLabels, fetchMe, } from "./lib/api.js"; import type { Route } from "./lib/router.js"; import { navigate, useRoute } from "./lib/router.js"; type AuthState = | { status: "checking" } | { status: "signed-out" } | { status: "signed-in"; username: string; isAdmin: boolean }; type View = "feed" | "install" | "admin"; const INSTALL_COMMAND = 'rm -rf ~/.local/share/xtap-pool-extension && mkdir -p ~/.local/share/xtap-pool-extension && curl -L https://github.com/osolmaz/xtap-pool/archive/refs/heads/main.tar.gz | tar -xz --strip-components=2 -C ~/.local/share/xtap-pool-extension xtap-pool-main/extension && open -a "Google Chrome" "chrome://extensions"'; function InstallExtension(): React.JSX.Element { const [copied, setCopied] = useState(false); const copyCommand = (): void => { void navigator.clipboard.writeText(INSTALL_COMMAND).then( () => { setCopied(true); window.setTimeout(() => { setCopied(false); }, 1500); }, () => undefined, ); }; return (

Install extension

Add the browser extension, connect it to this pool, then browse X normally.

Run this on macOS, enable Developer mode in Chrome, then Load unpacked and choose{" "} ~/.local/share/xtap-pool-extension.

        {INSTALL_COMMAND}
      
Connect
); } function SignIn(): React.JSX.Element { return (

xtap-pool

A private tweet pool for friends. Sign in with your Hugging Face account to explore.

Sign in with Hugging Face
); } type SidebarProps = { username: string; isAdmin: boolean; view: View; onGraphRoute: boolean; filters: Filters; contributors: readonly ContributorStats[]; labels: readonly LabelStat[]; freeLabels: readonly FreeLabelSummary[]; onView: (view: View) => void; onFilters: (filters: Filters) => void; }; /** Left rail: identity, view tabs (including the graph route) and filters. */ function Sidebar({ username, isAdmin, view, onGraphRoute, filters, contributors, labels, freeLabels, onView, onFilters, }: SidebarProps): React.JSX.Element { const tabClass = (active: boolean, tone: "default" | "accent" = "default"): string => [ "rounded-md border px-3 py-1.5 text-sm font-semibold", tone === "accent" ? "border-(--x-accent) text-(--x-accent)" : "border-(--x-border)", active ? (tone === "accent" ? "bg-(--x-accent) text-white" : "bg-(--x-soft-active)") : "", ] .filter(Boolean) .join(" "); const feedActive = !onGraphRoute && view === "feed"; const installActive = !onGraphRoute && view === "install"; const adminActive = !onGraphRoute && view === "admin"; return ( ); } type MainContentProps = { route: Route; view: View; isAdmin: boolean; filters: Filters; }; /** Active main pane: graph routes win over the feed-shell view tabs. */ function MainContent({ route, view, isAdmin, filters }: MainContentProps): React.JSX.Element { if (route.kind === "free-label") return ; if (route.kind === "graph") return ; if (view === "install") return ; if (view === "admin" && isAdmin) return ; return ; } /** Root explorer app: auth gate, routing, filter rail and tweet feed. */ export function App(): React.JSX.Element { const [auth, setAuth] = useState({ status: "checking" }); const [view, setView] = useState("feed"); const [filters, setFilters] = useState(defaultFilters); const [contributors, setContributors] = useState([]); const [labels, setLabels] = useState([]); const [freeLabels, setFreeLabels] = useState([]); const route = useRoute(); useEffect(() => { void (async (): Promise => { try { const me = await fetchMe(); setAuth( me === undefined ? { status: "signed-out" } : { status: "signed-in", username: me.username, isAdmin: me.isAdmin }, ); } catch { setAuth({ status: "signed-out" }); } })(); }, []); useEffect(() => { if (auth.status !== "signed-in") return; void fetchContributors().then(setContributors, () => undefined); void fetchLabels().then(setLabels, () => undefined); void fetchFreeLabels().then(setFreeLabels, () => undefined); }, [auth.status]); if (auth.status === "checking") { return

Loading…

; } if (auth.status === "signed-out") { return ; } const selectView = (next: View): void => { setView(next); if (route.kind !== "home") navigate("/"); }; return (
); }