import { appPath } from "@agent-native/core/client/api-path"; import { useT } from "@agent-native/core/client/i18n"; import { IconBrandApple, IconBrandChrome, IconBrandWindows, IconChevronDown, IconDeviceDesktop, IconExternalLink, } from "@tabler/icons-react"; import { type ReactNode, useSyncExternalStore } from "react"; import { Button, type ButtonProps } from "@/components/ui/button"; import { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover"; import { attemptOpenDesktopApp, clipsChromeExtensionUrl, hasDownloadedDesktopApp, subscribeDownloaded, useClipsChromeExtensionEnabled, } from "@/lib/capture-install-options"; import { cn } from "@/lib/utils"; // SSR snapshot is always false; same-tab markDesktopAppDownloaded() notifies // subscribers so mounted CTAs flip to "Open" without a reload. function useHasDownloadedDesktopApp(): boolean { return useSyncExternalStore( subscribeDownloaded, hasDownloadedDesktopApp, () => false, ); } type PopoverPlacement = { align?: "start" | "center" | "end"; side?: "top" | "right" | "bottom" | "left"; }; type CaptureInstallButtonProps = Omit & PopoverPlacement & { children: ReactNode; /** Label shown once the desktop app has been downloaded. */ downloadedChildren?: ReactNode; desktopHref?: string; }; type CaptureInstallInlineLinkProps = PopoverPlacement & { children: ReactNode; /** Label shown once the desktop app has been downloaded. */ downloadedChildren?: ReactNode; className?: string; desktopHref?: string; }; /** * The desktop-app tile shows the icon for the visitor's current OS — Apple on * macOS, Windows on Windows — and falls back to a neutral desktop glyph on other * platforms or during SSR. The Chrome tile always uses the Chrome brand icon. */ function desktopOsIcon(): typeof IconDeviceDesktop { if (typeof navigator === "undefined") return IconDeviceDesktop; const ua = navigator.userAgent; if (/Windows/i.test(ua)) return IconBrandWindows; if (/Mac|iPhone|iPad/i.test(ua)) return IconBrandApple; return IconDeviceDesktop; } function InstallOptionsContent({ desktopHref = "/download" }) { const t = useT(); const chromeAvailable = Boolean(clipsChromeExtensionUrl); const DesktopIcon = desktopOsIcon(); return (
{chromeAvailable ? ( {t("captureInstall.chromeTitle")} {t("captureInstall.chromeDescription")} ) : (
{t("captureInstall.chromeTitle")} {t("captureInstall.chromePendingDescription")}
)} {t("captureInstall.desktopTitle")} {t("captureInstall.desktopDescription")}
); } export function CaptureInstallButton({ children, downloadedChildren, className, desktopHref = "/download", align = "end", side = "bottom", ...buttonProps }: CaptureInstallButtonProps) { const downloaded = useHasDownloadedDesktopApp(); const chromeExtensionEnabled = useClipsChromeExtensionEnabled(); const label = downloaded ? (downloadedChildren ?? children) : children; if (downloaded) { const { onClick, ...restButtonProps } = buttonProps; return ( ); } if (!chromeExtensionEnabled) { return ( ); } return ( ); } export function CaptureInstallInlineLink({ children, downloadedChildren, className, desktopHref = "/download", align = "start", side = "bottom", }: CaptureInstallInlineLinkProps) { const downloaded = useHasDownloadedDesktopApp(); const chromeExtensionEnabled = useClipsChromeExtensionEnabled(); const label = downloaded ? (downloadedChildren ?? children) : children; if (downloaded) { return ( ); } if (!chromeExtensionEnabled) { return ( {label} ); } return ( ); }