| import { Icon as IconV2 } from "@opencode-ai/ui/v2/icon" |
| import { IconButtonV2 } from "@opencode-ai/ui/v2/icon-button-v2" |
| import { isRTL } from "@kobalte/core/i18n" |
| import { createSignal, Show } from "solid-js" |
| import { Drawer, DrawerClose, DrawerContent } from "@/components/ui/drawer" |
| import { usePlatform } from "@/context/platform" |
| import { useSettings } from "@/context/settings" |
| import { useLanguage } from "@/context/language" |
| import introducingTabsVideo from "@/assets/help/introducing-tabs.mp4" |
| import homeImage from "@/assets/help/home.png" |
| import tabsImage from "@/assets/help/tabs.png" |
|
|
| |
| const showPopover = () => true |
|
|
| |
| export function TabsInfoPopup() { |
| const settings = useSettings() |
| const platform = usePlatform() |
| const language = useLanguage() |
| const [drawerOpen, setDrawerOpen] = createSignal(false) |
| const windows = () => platform.platform === "desktop" && platform.os === "windows" |
| const rtl = () => isRTL(language.intl()) |
|
|
| return ( |
| <Drawer open={drawerOpen()} onOpenChange={setDrawerOpen} side={rtl() ? "left" : "right"}> |
| <Show when={settings.general.shouldDisplayTabsToast()}> |
| <div |
| class="fixed bottom-5 end-5 z-50 h-[240px] w-[192px] rounded-[8px] bg-v2-background-bg-base p-1 shadow-[var(--v2-elevation-floating)]" |
| aria-label={language.t("help.tabs.toast.ariaLabel")} |
| > |
| <button |
| type="button" |
| aria-label={language.t("help.tabs.toast.dismiss")} |
| class="absolute top-3 end-3 z-10 size-5 flex items-center justify-center rounded-[4px] bg-[rgba(0,0,0,0.4)]" |
| onClick={settings.general.dismissTabsToast} |
| > |
| <svg |
| width="16" |
| height="16" |
| viewBox="0 0 16 16" |
| fill="none" |
| xmlns="http://www.w3.org/2000/svg" |
| aria-hidden="true" |
| > |
| <path d="M4.25 11.75L11.75 4.25M11.75 11.75L4.25 4.25" stroke="white" /> |
| </svg> |
| </button> |
| <button |
| type="button" |
| class="relative block h-[232px] w-[184px] cursor-pointer overflow-hidden rounded-[4px] text-start" |
| onClick={() => { |
| settings.general.dismissTabsToast() |
| setDrawerOpen(true) |
| }} |
| > |
| <video |
| src={introducingTabsVideo} |
| class="absolute inset-0 h-full w-full object-cover" |
| loop |
| muted |
| autoplay |
| playsinline |
| aria-hidden="true" |
| onContextMenu={(event) => event.preventDefault()} |
| /> |
| <div class="absolute inset-x-0 bottom-0 flex w-full flex-col items-start gap-1.5 bg-[linear-gradient(180deg,rgba(0,0,0,0)_0%,#000000_100%)] px-3 py-5"> |
| <p class="w-full select-none text-[13px] font-[530] leading-none tracking-[-0.04px] text-[#FFFFFF]"> |
| {language.t("help.tabs.title")} |
| </p> |
| <p class="w-full select-none text-[13px] font-[440] leading-[140%] tracking-[-0.04px] text-[#808080]"> |
| {language.t("help.tabs.description")} |
| </p> |
| </div> |
| </button> |
| </div> |
| </Show> |
| <DrawerContent |
| style={ |
| windows() |
| ? { |
| top: "0", |
| bottom: "0", |
| "inset-inline-end": "0", |
| "inset-inline-start": "auto", |
| "max-height": "100vh", |
| "max-width": "100vw", |
| "border-radius": "0", |
| } |
| : undefined |
| } |
| > |
| <Show when={windows()}> |
| <DrawerClose |
| as={IconButtonV2} |
| type="button" |
| size="small" |
| variant="neutral" |
| aria-label={language.t("common.close")} |
| icon={<IconV2 name="xmark-small" />} |
| class="absolute top-[10px] start-[-36px]" |
| /> |
| </Show> |
| <div |
| class="flex w-full shrink-0 items-center gap-4 self-stretch border-b border-v2-border-border-muted" |
| classList={{ |
| "h-[40px] px-4": windows(), |
| "h-[52px] p-4": !windows(), |
| }} |
| > |
| <p class="min-h-0 min-w-0 flex-1 text-[13px] font-[530] leading-5 tracking-[-0.04px] tabular-nums text-v2-text-text-muted"> |
| {language.t("help.tabs.date")} |
| </p> |
| <Show when={!windows()}> |
| <DrawerClose |
| as={IconButtonV2} |
| type="button" |
| size="small" |
| variant="ghost-muted" |
| aria-label={language.t("common.close")} |
| icon={<IconV2 name="xmark-small" />} |
| /> |
| </Show> |
| </div> |
| <div class="relative flex min-h-0 w-full flex-1 flex-col items-start gap-6 overflow-y-auto p-8"> |
| <p class="w-full shrink-0 self-stretch text-[21px] font-[610] leading-6 tracking-[-0.37px] tabular-nums text-v2-text-text-base"> |
| {language.t("help.tabs.title")} |
| </p> |
| <div class="flex w-full flex-1 flex-col gap-4 text-[13px] font-[440] leading-5 tracking-[-0.04px] text-v2-text-text-base"> |
| <p>{language.t("help.tabs.introduction")}</p> |
| <img src={tabsImage} alt="" class="aspect-video w-full rounded-[6px] object-cover" /> |
| <p>{language.t("help.tabs.sessions")}</p> |
| <p>{language.t("help.tabs.organize")}</p> |
| <p>{language.t("help.tabs.home")}</p> |
| <img src={homeImage} alt="" class="aspect-video w-full rounded-[6px] object-cover" /> |
| <p>{language.t("help.tabs.persistence")}</p> |
| <p>{language.t("help.tabs.worktrees")}</p> |
| </div> |
| </div> |
| </DrawerContent> |
| </Drawer> |
| ) |
| } |
|
|