From 654560f289c0c68b782bfe69636fcc6407b2217b Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 18 Jul 2026 09:52:34 +0100 Subject: [PATCH] feat(ui): add Apps & extensions page to the Control UI (#110563) * feat(ui): add Apps & extensions page * feat(ui): add per-theme app-art card illustrations * docs: describe the Apps and extensions page in control-ui * fix(ui): keep icons.ts under max-lines, drop unused export, regen docs map --- docs/docs_map.md | 1 + docs/web/control-ui.md | 12 + ui/public/app-art/android-dark.webp | Bin 0 -> 3630 bytes ui/public/app-art/android.webp | Bin 0 -> 4074 bytes ui/public/app-art/apple-watch-dark.webp | Bin 0 -> 5620 bytes ui/public/app-art/apple-watch.webp | Bin 0 -> 5540 bytes ui/public/app-art/chrome-extension-dark.webp | Bin 0 -> 4954 bytes ui/public/app-art/chrome-extension.webp | Bin 0 -> 5366 bytes ui/public/app-art/ios-dark.webp | Bin 0 -> 4030 bytes ui/public/app-art/ios.webp | Bin 0 -> 4612 bytes ui/public/app-art/linux-dark.webp | Bin 0 -> 5202 bytes ui/public/app-art/linux.webp | Bin 0 -> 5250 bytes ui/public/app-art/macos-dark.webp | Bin 0 -> 5382 bytes ui/public/app-art/macos.webp | Bin 0 -> 5256 bytes ui/public/app-art/plugins-dark.webp | Bin 0 -> 6690 bytes ui/public/app-art/plugins.webp | Bin 0 -> 7054 bytes ui/public/app-art/wear-os-dark.webp | Bin 0 -> 3912 bytes ui/public/app-art/wear-os.webp | Bin 0 -> 3944 bytes ui/public/app-art/windows-dark.webp | Bin 0 -> 4678 bytes ui/public/app-art/windows.webp | Bin 0 -> 4992 bytes ui/src/app-navigation-groups.test.ts | 8 + ui/src/app-navigation.test.ts | 5 + ui/src/app-navigation.ts | 3 + ui/src/app-route-paths.ts | 1 + ui/src/app-routes.ts | 2 + ui/src/app/public-assets.ts | 3 +- ui/src/components/app-sidebar-agent-menu.ts | 7 + ui/src/components/command-palette.ts | 7 + ui/src/i18n/locales/en-agents.ts | 1 + ui/src/i18n/locales/en.ts | 62 ++++ ui/src/pages/apps/apps-page.ts | 31 ++ ui/src/pages/apps/brand-icons.ts | 52 ++++ ui/src/pages/apps/route.ts | 12 + ui/src/pages/apps/view.test.ts | 110 +++++++ ui/src/pages/apps/view.ts | 302 +++++++++++++++++++ ui/src/styles/apps.css | 266 ++++++++++++++++ 36 files changed, 884 insertions(+), 1 deletion(-) create mode 100644 ui/public/app-art/android-dark.webp create mode 100644 ui/public/app-art/android.webp create mode 100644 ui/public/app-art/apple-watch-dark.webp create mode 100644 ui/public/app-art/apple-watch.webp create mode 100644 ui/public/app-art/chrome-extension-dark.webp create mode 100644 ui/public/app-art/chrome-extension.webp create mode 100644 ui/public/app-art/ios-dark.webp create mode 100644 ui/public/app-art/ios.webp create mode 100644 ui/public/app-art/linux-dark.webp create mode 100644 ui/public/app-art/linux.webp create mode 100644 ui/public/app-art/macos-dark.webp create mode 100644 ui/public/app-art/macos.webp create mode 100644 ui/public/app-art/plugins-dark.webp create mode 100644 ui/public/app-art/plugins.webp create mode 100644 ui/public/app-art/wear-os-dark.webp create mode 100644 ui/public/app-art/wear-os.webp create mode 100644 ui/public/app-art/windows-dark.webp create mode 100644 ui/public/app-art/windows.webp create mode 100644 ui/src/pages/apps/apps-page.ts create mode 100644 ui/src/pages/apps/brand-icons.ts create mode 100644 ui/src/pages/apps/route.ts create mode 100644 ui/src/pages/apps/view.test.ts create mode 100644 ui/src/pages/apps/view.ts create mode 100644 ui/src/styles/apps.css diff --git a/docs/docs_map.md b/docs/docs_map.md index f9a51459930..d2aa5612e7b 100644 --- a/docs/docs_map.md +++ b/docs/docs_map.md @@ -10519,6 +10519,7 @@ Do not edit it by hand; run `pnpm docs:map:gen`. - H2: Language support - H2: Appearance themes - H2: Manage plugins + - H2: Apps and extensions - H2: Sidebar navigation - H2: New session page - H2: What it can do (today) diff --git a/docs/web/control-ui.md b/docs/web/control-ui.md index bd2cacdaaf0..ea1876bccaa 100644 --- a/docs/web/control-ui.md +++ b/docs/web/control-ui.md @@ -173,6 +173,18 @@ The page intentionally focuses on inventory, discovery, install, enablement, and removal. Use [`openclaw plugins`](/cli/plugins) for arbitrary npm, git, or local-path sources, updates, and advanced plugin configuration. +## Apps and extensions + +Open **Apps** from the sidebar **More** menu, the command palette, or the +sidebar agent menu (**Get the apps**), or use `/apps` relative to the +configured Control UI base path. The page collects install links for every +OpenClaw companion surface: the [iOS](/platforms/ios) and +[Android](/platforms/android) apps, the Apple Watch and Wear OS companions +bundled with them, the [macOS](/platforms/macos), [Windows](/platforms/windows), +and [Linux](/platforms/linux) desktop apps, the +[Chrome extension](/tools/chrome-extension), the in-app Plugins hub with +[ClawHub](https://clawhub.ai), and the Discord community and docs. + ## Sidebar navigation The sidebar pins navigation above a scrollable session list. In multi-agent setups every agent appears as a collapsible top-level section; expanding an agent browses its sessions without navigating away from the open chat, and collapsed agents show an unread indicator. Within an agent the list splits into **Pinned**, one built-in section per connected channel (Telegram, Slack, WhatsApp, ...), a built-in **Work** section for sessions bound to a managed worktree or exec node (rows show a `repo ⎇ branch` line plus the node host), custom groups (the session `category`), and **Chats** for the rest. Channel and Work sections classify rows automatically; assigning a session to a custom group always wins. Opening a session moves the selection highlight without reordering the rows. Parent sessions with recent child runs show a disclosure and child count; expand it to inspect nested child sessions, live or terminal status, and runtime without leaving the sidebar. Selecting a child opens its chat and automatically reveals its ancestor path. Child rows stay outside root grouping, pinning, dragging, multi-select, and pagination. Sessions with new activity since they were last read show an unread dot, and opening one marks it read. Cloud-worker lifecycle states use a globe badge; local and reclaimed sessions omit a placement badge because local execution is the default. Each root session row has a context menu (kebab button or right-click) with Pin/Unpin, Mark as unread/read, Rename, Fork, Move to group (including New group and Remove from group), Archive, and Delete; touch layouts keep the direct pin and menu controls visible. Cmd/Ctrl-click toggles root rows into a multi-select and Shift-click extends it across the visible order; opening the menu on a selected row then offers batch actions (Mark N as unread/read, Move N to group, Archive N, Delete N) that apply to every selected session, with a single confirmation for batch delete. Drag a root session onto **Pinned** to pin it, or onto a custom group or **Chats** to move it. Custom group headers can be collapsed, expanded, or dragged to reorder them; group names and their order live in the gateway (`sessions.groups.*`), so they follow you across browsers, while the collapsed state stays in the browser profile. Group headers also have a menu (kebab button or right-click) with Rename group, New group, and Delete group; renaming or deleting a group updates every member session server-side, including archived ones, and deleting a group keeps its sessions and moves them back to Chats. The single **+** in the session-list header opens the New session page (see below). The sort control also has a Group by toggle: Grouped (default) or None for one flat list (Pinned stays separate); the choice is stored in the current browser profile. **Usage**, **Automations**, and **Plugins** are pinned by default; the **More** row opens a menu with every other destination, including plugin-provided tabs. Select **Edit pinned items** in that menu, or right-click the navigation area, to pin or unpin destinations and restore the defaults. The pinned set is stored in the current browser profile and survives reloads. diff --git a/ui/public/app-art/android-dark.webp b/ui/public/app-art/android-dark.webp new file mode 100644 index 0000000000000000000000000000000000000000..6fa54b55a98b74f70d8f04c787a164626feba399 GIT binary patch literal 3630 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 O8geTqYa8D20002u!2*r| literal 0 HcmV?d00001 diff --git a/ui/public/app-art/apple-watch.webp b/ui/public/app-art/apple-watch.webp new file mode 100644 index 0000000000000000000000000000000000000000..eac98218c9b2830948171b8326cdeecd62789c91 GIT binary patch literal 5540 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 literal 0 HcmV?d00001 diff --git a/ui/public/app-art/chrome-extension-dark.webp b/ui/public/app-art/chrome-extension-dark.webp new file mode 100644 index 0000000000000000000000000000000000000000..184820aff5bd17164efc4053bafa65a321d2c2f8 GIT binary patch literal 4954 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 uU^CzH+yW2-)53c4j9)@^zb9zcdH(iT`uT)}nnf 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 M-C?ilgAM=y0PyJp&;S4c literal 0 HcmV?d00001 diff --git a/ui/public/app-art/linux.webp b/ui/public/app-art/linux.webp new file mode 100644 index 0000000000000000000000000000000000000000..c27457b29fa66cf27432672269531ca744928c6f GIT binary patch literal 5250 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 Ir)yvU01}8jSO5S3 literal 0 HcmV?d00001 diff --git a/ui/public/app-art/macos-dark.webp b/ui/public/app-art/macos-dark.webp new file mode 100644 index 0000000000000000000000000000000000000000..a47654c77ce5c2aa1e61e966e20ed42251d5c660 GIT binary patch literal 5382 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 literal 0 HcmV?d00001 diff --git a/ui/public/app-art/macos.webp b/ui/public/app-art/macos.webp new file mode 100644 index 0000000000000000000000000000000000000000..08535f0e169268f488f37090f9e92445cc30a5a5 GIT binary patch literal 5256 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 literal 0 HcmV?d00001 diff --git a/ui/public/app-art/plugins-dark.webp b/ui/public/app-art/plugins-dark.webp new file mode 100644 index 0000000000000000000000000000000000000000..e14a3f44d5efc2f8aa4f3f915e37b4f6bb6ad3f7 GIT binary patch literal 6690 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 literal 0 HcmV?d00001 diff --git a/ui/public/app-art/plugins.webp b/ui/public/app-art/plugins.webp new file mode 100644 index 0000000000000000000000000000000000000000..8098a4622a443af7bd37bf3c0603107b1bc97219 GIT binary patch literal 7054 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 WfM-8zqiDi_4$XjUdeq?n0002ddb2P9 literal 0 HcmV?d00001 diff --git a/ui/public/app-art/wear-os.webp b/ui/public/app-art/wear-os.webp new file mode 100644 index 0000000000000000000000000000000000000000..966ffe84c09bb35dc8dedd519d6017c85e413a6e GIT binary patch literal 3944 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 C|CuBJ literal 0 HcmV?d00001 diff --git a/ui/public/app-art/windows-dark.webp b/ui/public/app-art/windows-dark.webp new file mode 100644 index 0000000000000000000000000000000000000000..97dbc571c8f412f3e294ebb6aed039107eaf4bcd GIT binary patch literal 4678 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 literal 0 HcmV?d00001 diff --git a/ui/public/app-art/windows.webp b/ui/public/app-art/windows.webp new file mode 100644 index 0000000000000000000000000000000000000000..137393213a1697d335c3bd5eff8b22b61256548c GIT binary patch literal 4992 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 { expect(normalizeSidebarPinnedRoutes(["nodes", "usage"])).toEqual(["usage"]); }); + it("keeps the apps promo page unpinned by default but customizable", () => { + expect(SIDEBAR_NAV_ROUTES).toContain("apps"); + expect(DEFAULT_SIDEBAR_PINNED_ROUTES).not.toContain("apps"); + expect(sidebarMoreRoutes(DEFAULT_SIDEBAR_PINNED_ROUTES)).toContain("apps"); + expect(settingsRoutes).not.toContain("apps"); + expect(isSettingsNavigationRoute("apps")).toBe(false); + }); + it("keeps the plugin manager in customizable workspace routes", () => { expect(normalizeSidebarPinnedRoutes(["plugins", "usage", "plugins"])).toEqual([ "plugins", diff --git a/ui/src/app-navigation.test.ts b/ui/src/app-navigation.test.ts index 16724cd8c56..779a893ff86 100644 --- a/ui/src/app-navigation.test.ts +++ b/ui/src/app-navigation.test.ts @@ -84,6 +84,7 @@ describe("navigationIconForRoute", () => { chat: "messageSquare", custodian: "lobster", activity: "activity", + apps: "smartphone", approvals: "shieldCheck", workboard: "kanban", worktrees: "folder", @@ -141,6 +142,7 @@ describe("titleForRoute", () => { chat: "Chat", custodian: "OpenClaw", activity: "Activity", + apps: "Apps", approvals: "Approvals", workboard: "Workboard", worktrees: "Worktrees", @@ -184,6 +186,7 @@ describe("subtitleForRoute", () => { chat: "Gateway chat for quick interventions.", custodian: "System setup and care.", activity: "Browser-local tool activity summaries.", + apps: "Companion apps for phone, watch, desktop, and browser.", approvals: "Recent exec, plugin, and system-agent approvals.", workboard: "Agent work queue and session handoff.", worktrees: "Isolated agent task checkouts and recovery snapshots.", @@ -222,6 +225,7 @@ describe("subtitleForRoute", () => { describe("pathForRoute", () => { it("returns correct path without base", () => { expect(pathForRoute("chat")).toBe("/chat"); + expect(pathForRoute("apps")).toBe("/apps"); expect(pathForRoute("custodian")).toBe("/custodian"); expect(pathForRoute("connection")).toBe("/settings/connection"); expect(pathForRoute("debug")).toBe("/debug"); @@ -256,6 +260,7 @@ describe("routeIdFromPath", () => { expect(routeIdFromPath("/settings/connection")).toBe("connection"); expect(routeIdFromPath("/connection")).toBeNull(); expect(routeIdFromPath("/activity")).toBe("activity"); + expect(routeIdFromPath("/apps")).toBe("apps"); expect(routeIdFromPath("/sessions")).toBe("sessions"); expect(routeIdFromPath("/debug")).toBe("debug"); expect(routeIdFromPath("/logs")).toBe("logs"); diff --git a/ui/src/app-navigation.ts b/ui/src/app-navigation.ts index 89d805c7629..2d83f84ae32 100644 --- a/ui/src/app-navigation.ts +++ b/ui/src/app-navigation.ts @@ -24,6 +24,7 @@ export const SIDEBAR_NAV_ROUTES = [ "sessions", "activity", "plugins", + "apps", ] as const satisfies readonly NavigationRouteId[]; // Routes presented as tabs of the Plugins hub. The sidebar highlights the @@ -174,6 +175,7 @@ const SETTINGS_TAKEOVER_ROUTES = SETTINGS_NAVIGATION_ROUTES.filter( const NAVIGATION_ICONS: NavigationItem = { agents: "bot", activity: "activity", + apps: "smartphone", approvals: "shieldCheck", workboard: "kanban", worktrees: "folder", @@ -269,6 +271,7 @@ export function cancelRoutePreload( const NAVIGATION_COPY: Record = { agents: { titleKey: "tabs.agents", subtitleKey: "subtitles.agents" }, activity: { titleKey: "tabs.activity", subtitleKey: "subtitles.activity" }, + apps: { titleKey: "tabs.apps", subtitleKey: "subtitles.apps" }, approvals: { titleKey: "tabs.approvals", subtitleKey: "subtitles.approvals" }, workboard: { titleKey: "tabs.workboard", subtitleKey: "subtitles.workboard" }, worktrees: { titleKey: "tabs.worktrees", subtitleKey: "subtitles.worktrees" }, diff --git a/ui/src/app-route-paths.ts b/ui/src/app-route-paths.ts index 4ebcaad5def..bc5e59b8baa 100644 --- a/ui/src/app-route-paths.ts +++ b/ui/src/app-route-paths.ts @@ -6,6 +6,7 @@ const APP_ROUTE_DEFINITIONS = { custodian: { path: "/custodian" }, "new-session": { path: "/new" }, activity: { path: "/activity" }, + apps: { path: "/apps" }, agents: { path: "/settings/agents", aliases: ["/agents"] }, channels: { path: "/settings/channels", aliases: ["/channels"] }, connection: { path: "/settings/connection" }, diff --git a/ui/src/app-routes.ts b/ui/src/app-routes.ts index a432bc2c682..370238d44a2 100644 --- a/ui/src/app-routes.ts +++ b/ui/src/app-routes.ts @@ -6,6 +6,7 @@ import { page as aboutPage } from "./pages/about/route.ts"; import { page as activityPage } from "./pages/activity/route.ts"; import { page as agentsPage } from "./pages/agents/route.ts"; import { page as approvalsPage } from "./pages/approvals/route.ts"; +import { page as appsPage } from "./pages/apps/route.ts"; import { page as channelsPage } from "./pages/channels/route.ts"; import { page as chatPage } from "./pages/chat/route.ts"; import { pages as configPages } from "./pages/config/route.ts"; @@ -47,6 +48,7 @@ const APP_ROUTE_TREE = [ custodianPage, newSessionPage, activityPage, + appsPage, agentsPage, approvalsPage, channelsPage, diff --git a/ui/src/app/public-assets.ts b/ui/src/app/public-assets.ts index 04decdfafb6..6effa67020a 100644 --- a/ui/src/app/public-assets.ts +++ b/ui/src/app/public-assets.ts @@ -10,7 +10,8 @@ type ControlUiPublicAsset = | "manifest.webmanifest" | "sw.js" | `provider-icons/ProviderIcon-${string}.svg` - | `plugin-art/${string}.webp`; + | `plugin-art/${string}.webp` + | `app-art/${string}.webp`; export function controlUiPublicAssetPath( asset: ControlUiPublicAsset, diff --git a/ui/src/components/app-sidebar-agent-menu.ts b/ui/src/components/app-sidebar-agent-menu.ts index c1d0264fa50..974a32c506f 100644 --- a/ui/src/components/app-sidebar-agent-menu.ts +++ b/ui/src/components/app-sidebar-agent-menu.ts @@ -230,6 +230,9 @@ export function renderSidebarAgentMenu(params: SidebarAgentMenuParams) { case `${COMMAND_VALUE_PREFIX}pair-mobile`: params.onPairMobile(); break; + case `${COMMAND_VALUE_PREFIX}apps`: + params.onNavigate("apps"); + break; } }} @wa-after-show=${(event: Event) => { @@ -331,6 +334,10 @@ export function renderSidebarAgentMenu(params: SidebarAgentMenuParams) { ${t("nodes.pairing.button")} + + + ${t("agentChip.getApps")} + this.context.navigate(routeId), + }); + return html` +
+
+
${titleForRoute("apps")}
+
+
+ ${renderSettingsWorkspace(body)} + `; + } +} + +if (!customElements.get("openclaw-apps-page")) { + customElements.define("openclaw-apps-page", AppsPage); +} diff --git a/ui/src/pages/apps/brand-icons.ts b/ui/src/pages/apps/brand-icons.ts new file mode 100644 index 00000000000..7831cfafef2 --- /dev/null +++ b/ui/src/pages/apps/brand-icons.ts @@ -0,0 +1,52 @@ +import { html } from "lit"; + +// Platform marks for the Apps page cards. Kept local (not in the shared +// lucide `icons` set) so the page owns its one-off glyphs and the shared +// icon file stays under its size cap; apps.css targets .icon--filled to +// render solid fills while unclassed glyphs stay stroked. +export const appsBrandIcons = { + watch: html` + + + + + + + `, + apple: html` + + + + `, + android: html` + + + + `, + windows: html` + + + + `, + linux: html` + + + + `, + chrome: html` + + + + `, +} as const; diff --git a/ui/src/pages/apps/route.ts b/ui/src/pages/apps/route.ts new file mode 100644 index 00000000000..7d9a1fcec4b --- /dev/null +++ b/ui/src/pages/apps/route.ts @@ -0,0 +1,12 @@ +import { definePage } from "@openclaw/uirouter"; +import { html } from "lit"; + +export const page = definePage({ + id: "apps", + path: "/apps", + component: () => + import("./apps-page.ts").then(() => ({ + header: true, + render: () => html``, + })), +}); diff --git a/ui/src/pages/apps/view.test.ts b/ui/src/pages/apps/view.test.ts new file mode 100644 index 00000000000..d215e94565d --- /dev/null +++ b/ui/src/pages/apps/view.test.ts @@ -0,0 +1,110 @@ +/* @vitest-environment jsdom */ + +import { render } from "lit"; +import { beforeEach, describe, expect, it, vi } from "vitest"; +import { i18n } from "../../i18n/index.ts"; +import { renderApps } from "./view.ts"; + +const EXPECTED_EXTERNAL_HREFS = [ + "https://apps.apple.com/app/openclaw-ai-that-does-things/id6780396132", + "https://docs.openclaw.ai/platforms/ios", + "https://play.google.com/store/apps/details?id=ai.openclaw.app", + "https://docs.openclaw.ai/platforms/android", + "https://docs.openclaw.ai/platforms/ios", + "https://docs.openclaw.ai/platforms/android", + "https://github.com/openclaw/openclaw/releases", + "https://docs.openclaw.ai/platforms/macos", + "https://github.com/openclaw/openclaw-windows-node/releases/latest", + "https://docs.openclaw.ai/platforms/windows", + "https://github.com/openclaw/openclaw/releases", + "https://docs.openclaw.ai/platforms/linux", + "https://docs.openclaw.ai/tools/chrome-extension", + "https://clawhub.ai", + "https://discord.gg/clawd", + "https://docs.openclaw.ai", +]; + +describe("renderApps", () => { + beforeEach(async () => { + document.body.innerHTML = ""; + await i18n.setLocale("en"); + }); + + function renderIntoContainer(onNavigate = vi.fn()) { + const container = document.createElement("div"); + render(renderApps({ onNavigate }), container); + return container; + } + + it("renders the hero and one heading per section", () => { + const container = renderIntoContainer(); + expect(container.querySelector(".apps-hero__title")?.textContent).toBe( + "Take OpenClaw everywhere", + ); + expect(container.querySelector(".apps-hero__tagline")?.textContent).toContain( + "Companion apps for your phone", + ); + const headings = Array.from(container.querySelectorAll(".apps-section__heading")).map( + (heading) => heading.textContent, + ); + expect(headings).toEqual([ + "On your phone", + "On your wrist", + "On your desktop", + "In your browser", + "Community", + ]); + }); + + it("renders every external link in order with safe target and rel", () => { + const container = renderIntoContainer(); + const anchors = Array.from(container.querySelectorAll("a[href]")); + expect(anchors.map((anchor) => anchor.getAttribute("href"))).toEqual(EXPECTED_EXTERNAL_HREFS); + for (const anchor of anchors) { + expect(anchor.getAttribute("target")).toBe("_blank"); + expect(anchor.getAttribute("rel")).toContain("noopener"); + expect(anchor.getAttribute("rel")).toContain("noreferrer"); + } + }); + + it("navigates to the in-app Plugins hub from the plugins card", () => { + const onNavigate = vi.fn(); + const container = renderIntoContainer(onNavigate); + const buttons = Array.from( + container.querySelectorAll("button.apps-card__cta"), + ); + expect(buttons).toHaveLength(1); + expect(buttons[0]?.textContent).toContain("Open Plugins"); + buttons[0]?.click(); + expect(onNavigate).toHaveBeenCalledExactlyOnceWith("plugins"); + }); + + it("badges the watch apps as bundled with their phone apps", () => { + const container = renderIntoContainer(); + const badges = Array.from(container.querySelectorAll(".apps-card__badge")).map( + (badge) => badge.textContent?.trim(), + ); + expect(badges).toEqual(["Included with the iOS app", "Included with the Android app"]); + }); + + it("renders decorative lazy card art with a per-theme variant for every card", () => { + const container = renderIntoContainer(); + const images = Array.from(container.querySelectorAll(".apps-card__art img")); + expect(images).toHaveLength(18); + for (const image of images) { + expect(image.getAttribute("alt")).toBe(""); + expect(image.getAttribute("loading")).toBe("lazy"); + } + const lightSrcs = images + .filter((image) => image.classList.contains("apps-card__art-img--light")) + .map((image) => image.getAttribute("src")); + const darkSrcs = images + .filter((image) => image.classList.contains("apps-card__art-img--dark")) + .map((image) => image.getAttribute("src")); + expect(lightSrcs).toHaveLength(9); + for (const src of lightSrcs) { + expect(src).toMatch(/^\/app-art\/[a-z-]+\.webp$/); + } + expect(darkSrcs).toEqual(lightSrcs.map((src) => src?.replace(/\.webp$/, "-dark.webp"))); + }); +}); diff --git a/ui/src/pages/apps/view.ts b/ui/src/pages/apps/view.ts new file mode 100644 index 00000000000..d6f884d7ad2 --- /dev/null +++ b/ui/src/pages/apps/view.ts @@ -0,0 +1,302 @@ +// Control UI view renders the Apps & extensions promo page. +import { html, nothing, type TemplateResult } from "lit"; +import type { RouteId } from "../../app-route-paths.ts"; +import { inferControlUiPublicAssetPath } from "../../app/public-assets.ts"; +import { icons } from "../../components/icons.ts"; +import { t } from "../../i18n/index.ts"; +import { buildExternalLinkRel, EXTERNAL_LINK_TARGET } from "../../lib/external-link.ts"; +import "../../styles/apps.css"; +import { brandIcons } from "../about/brand-icons.ts"; +import { appsBrandIcons } from "./brand-icons.ts"; + +type AppsProps = { + onNavigate: (routeId: RouteId) => void; +}; + +type AppCardCta = + | { kind: "external"; href: string; label: () => string } + | { kind: "internal"; routeId: RouteId; label: () => string }; + +type AppCard = { + id: string; + /** Two-stop gradient behind the card art; also covers image load latency. */ + gradient: readonly [string, string]; + icon: TemplateResult; + title: () => string; + desc: () => string; + badge?: () => string; + ctas: readonly AppCardCta[]; +}; + +type AppSection = { + id: string; + label: () => string; + cards: readonly AppCard[]; +}; + +const docsCta = (path: string): AppCardCta => ({ + kind: "external", + href: `https://docs.openclaw.ai${path}`, + label: () => t("appsPage.ctaDocs"), +}); + +const APP_SECTIONS: readonly AppSection[] = [ + { + id: "mobile", + label: () => t("appsPage.sectionMobile"), + cards: [ + { + id: "ios", + gradient: ["#38bdf8", "#1d4ed8"], + icon: appsBrandIcons.apple, + title: () => t("appsPage.cards.ios.title"), + desc: () => t("appsPage.cards.ios.desc"), + ctas: [ + { + kind: "external", + href: "https://apps.apple.com/app/openclaw-ai-that-does-things/id6780396132", + label: () => t("appsPage.ctaAppStore"), + }, + docsCta("/platforms/ios"), + ], + }, + { + id: "android", + gradient: ["#34d399", "#047857"], + icon: appsBrandIcons.android, + title: () => t("appsPage.cards.android.title"), + desc: () => t("appsPage.cards.android.desc"), + ctas: [ + { + kind: "external", + href: "https://play.google.com/store/apps/details?id=ai.openclaw.app", + label: () => t("appsPage.ctaPlayStore"), + }, + docsCta("/platforms/android"), + ], + }, + ], + }, + { + id: "watch", + label: () => t("appsPage.sectionWatch"), + cards: [ + { + id: "apple-watch", + gradient: ["#f472b6", "#be185d"], + icon: appsBrandIcons.watch, + title: () => t("appsPage.cards.appleWatch.title"), + desc: () => t("appsPage.cards.appleWatch.desc"), + badge: () => t("appsPage.badgeBundledIos"), + ctas: [docsCta("/platforms/ios")], + }, + { + id: "wear-os", + gradient: ["#22d3ee", "#0e7490"], + icon: appsBrandIcons.watch, + title: () => t("appsPage.cards.wearOs.title"), + desc: () => t("appsPage.cards.wearOs.desc"), + badge: () => t("appsPage.badgeBundledAndroid"), + ctas: [docsCta("/platforms/android")], + }, + ], + }, + { + id: "desktop", + label: () => t("appsPage.sectionDesktop"), + cards: [ + { + id: "macos", + gradient: ["#a855f7", "#6b21a8"], + icon: appsBrandIcons.apple, + title: () => t("appsPage.cards.macos.title"), + desc: () => t("appsPage.cards.macos.desc"), + ctas: [ + { + kind: "external", + href: "https://github.com/openclaw/openclaw/releases", + label: () => t("appsPage.ctaDownload"), + }, + docsCta("/platforms/macos"), + ], + }, + { + id: "windows", + gradient: ["#818cf8", "#4338ca"], + icon: appsBrandIcons.windows, + title: () => t("appsPage.cards.windows.title"), + desc: () => t("appsPage.cards.windows.desc"), + ctas: [ + { + kind: "external", + href: "https://github.com/openclaw/openclaw-windows-node/releases/latest", + label: () => t("appsPage.ctaDownload"), + }, + docsCta("/platforms/windows"), + ], + }, + { + id: "linux", + gradient: ["#fbbf24", "#b45309"], + icon: appsBrandIcons.linux, + title: () => t("appsPage.cards.linux.title"), + desc: () => t("appsPage.cards.linux.desc"), + ctas: [ + { + kind: "external", + href: "https://github.com/openclaw/openclaw/releases", + label: () => t("appsPage.ctaDownload"), + }, + docsCta("/platforms/linux"), + ], + }, + ], + }, + { + id: "browser", + label: () => t("appsPage.sectionBrowser"), + cards: [ + { + id: "chrome-extension", + gradient: ["#f59e0b", "#ea580c"], + icon: appsBrandIcons.chrome, + title: () => t("appsPage.cards.chrome.title"), + desc: () => t("appsPage.cards.chrome.desc"), + // Installs unpacked via `openclaw browser extension path`; there is no + // Chrome Web Store listing, so the only CTA is the setup guide. + ctas: [ + { + kind: "external", + href: "https://docs.openclaw.ai/tools/chrome-extension", + label: () => t("appsPage.ctaSetupGuide"), + }, + ], + }, + { + id: "plugins", + gradient: ["#fb7185", "#9f1239"], + icon: icons.puzzle, + title: () => t("appsPage.cards.plugins.title"), + desc: () => t("appsPage.cards.plugins.desc"), + ctas: [ + { kind: "internal", routeId: "plugins", label: () => t("appsPage.ctaOpenPlugins") }, + { + kind: "external", + href: "https://clawhub.ai", + label: () => t("appsPage.ctaBrowseClawHub"), + }, + ], + }, + ], + }, +]; + +const COMMUNITY_LINKS: ReadonlyArray<{ href: string; icon: TemplateResult; label: () => string }> = + [ + { + href: "https://discord.gg/clawd", + icon: brandIcons.discord, + label: () => t("appsPage.linkDiscord"), + }, + { href: "https://docs.openclaw.ai", icon: icons.book, label: () => t("appsPage.linkDocs") }, + ]; + +function renderCta(cta: AppCardCta, index: number, props: AppsProps) { + const className = index === 0 ? "apps-card__cta apps-card__cta--primary" : "apps-card__cta"; + if (cta.kind === "internal") { + return html` + + `; + } + return html` + + ${cta.label()} + + `; +} + +function renderAppCard(card: AppCard, props: AppsProps) { + const [from, to] = card.gradient; + return html` +
+
+ + +
+
+
+ +

${card.title()}

+ ${card.badge ? html`${card.badge()}` : nothing} +
+

${card.desc()}

+
+ ${card.ctas.map((cta, index) => renderCta(cta, index, props))} +
+
+
+ `; +} + +function renderSection(section: AppSection, props: AppsProps) { + return html` +
+

${section.label()}

+
${section.cards.map((card) => renderAppCard(card, props))}
+
+ `; +} + +function renderCommunity() { + return html` +
+

${t("appsPage.sectionCommunity")}

+ +
+ `; +} + +export function renderApps(props: AppsProps) { + return html` +
+
+

${t("appsPage.heroTitle")}

+

${t("appsPage.heroTagline")}

+
+ ${APP_SECTIONS.map((section) => renderSection(section, props))} ${renderCommunity()} +
+ `; +} diff --git a/ui/src/styles/apps.css b/ui/src/styles/apps.css new file mode 100644 index 00000000000..295df1dab3c --- /dev/null +++ b/ui/src/styles/apps.css @@ -0,0 +1,266 @@ +/* Apps & extensions promo page — hero, card grid, and community pills. */ + +.apps-hero { + display: flex; + flex-direction: column; + align-items: center; + padding: 18px 16px 10px; + text-align: center; +} + +.apps-hero__title { + margin: 0; + color: var(--text-strong); + font-size: 30px; + font-weight: 700; + letter-spacing: -0.02em; + line-height: 1.15; +} + +.apps-hero__tagline { + max-width: 460px; + margin: 6px 0 0; + color: var(--muted); + font-size: var(--control-ui-text-sm); + line-height: 1.45; +} + +.apps-section { + margin-top: 26px; +} + +/* Mirrors .settings-section__heading typography; cards intentionally do not + sit inside a .settings-group surface (one level of elevation only). */ +.apps-section__heading { + margin: 0 0 10px 2px; + color: var(--muted); + font-size: var(--control-ui-text-xs); + font-weight: 600; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.apps-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); + gap: var(--space-4, 16px); +} + +.apps-card { + display: flex; + flex-direction: column; + overflow: hidden; + border: 1px solid var(--border); + border-radius: var(--radius-lg); + background: var(--card); + transition: + transform 140ms ease, + border-color 140ms ease; +} + +.apps-card:hover { + transform: translateY(-1px); + border-color: color-mix(in srgb, var(--border) 55%, var(--text) 45%); +} + +.apps-card__art { + aspect-ratio: 16 / 9; + background: linear-gradient( + 135deg, + color-mix(in srgb, var(--apps-art-a) 70%, var(--card)), + color-mix(in srgb, var(--apps-art-b) 70%, var(--card)) + ); +} + +.apps-card__art img { + display: block; + width: 100%; + height: 100%; + object-fit: cover; +} + +/* Per-theme art variants; the app root always carries data-theme-mode + (bootstrap.ts), dark stays the fallback to match the dark-default tokens. */ +.apps-card__art .apps-card__art-img--light { + display: none; +} + +:root[data-theme-mode="light"] .apps-card__art .apps-card__art-img--light { + display: block; +} + +:root[data-theme-mode="light"] .apps-card__art .apps-card__art-img--dark { + display: none; +} + +.apps-card__body { + display: flex; + flex: 1; + flex-direction: column; + gap: 8px; + padding: 14px; +} + +.apps-card__title-row { + display: flex; + align-items: center; + gap: 8px; + min-width: 0; +} + +.apps-card__icon { + display: inline-flex; + color: var(--text); +} + +.apps-card__title { + margin: 0; + color: var(--text-strong); + font-size: var(--control-ui-text-md, 15px); + font-weight: 600; +} + +.apps-card__badge { + margin-inline-start: auto; + padding: 2px 9px; + border: 1px solid var(--border); + border-radius: 999px; + background: color-mix(in srgb, var(--bg-elevated) 55%, var(--card) 45%); + color: var(--muted); + font-size: var(--control-ui-text-xs); + white-space: nowrap; +} + +.apps-card__desc { + margin: 0; + color: var(--muted); + font-size: var(--control-ui-text-sm); + line-height: 1.45; +} + +.apps-card__ctas { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin-top: auto; + padding-top: 6px; +} + +.apps-card__cta { + display: inline-flex; + align-items: center; + padding: 6px 13px; + border: 1px solid var(--border); + border-radius: 999px; + background: var(--card); + color: var(--text); + font: inherit; + font-size: var(--control-ui-text-sm); + font-weight: 550; + text-decoration: none; + cursor: pointer; + transition: + transform 140ms ease, + background 140ms ease, + border-color 140ms ease; +} + +.apps-card__cta--primary { + border-color: color-mix(in srgb, var(--border) 30%, var(--text) 70%); + background: var(--text-strong); + color: var(--bg); +} + +.apps-card__cta:hover { + transform: translateY(-1px); + border-color: color-mix(in srgb, var(--border) 40%, var(--text) 60%); + background: var(--bg-hover); + text-decoration: none; +} + +.apps-card__cta--primary:hover { + background: var(--text); + color: var(--bg); +} + +.apps-card__cta:focus-visible { + outline: none; + box-shadow: var(--focus-ring); +} + +.apps-community { + display: flex; + flex-wrap: wrap; + gap: 10px; +} + +.apps-pill { + display: inline-flex; + align-items: center; + gap: 8px; + padding: 8px 15px; + border: 1px solid var(--border); + border-radius: 999px; + background: var(--card); + color: var(--text); + font-size: var(--control-ui-text-sm); + font-weight: 550; + text-decoration: none; + transition: + transform 140ms ease, + background 140ms ease, + border-color 140ms ease; +} + +.apps-pill:hover { + transform: translateY(-1px); + border-color: color-mix(in srgb, var(--border) 40%, var(--text) 60%); + background: var(--bg-hover); + text-decoration: none; +} + +.apps-pill:focus-visible { + outline: none; + box-shadow: var(--focus-ring); +} + +.apps-pill__icon { + display: inline-flex; +} + +.apps-card__icon svg, +.apps-pill svg { + width: 16px; + height: 16px; + fill: none; + stroke: currentColor; + stroke-linecap: round; + stroke-linejoin: round; + stroke-width: 1.8; +} + +.apps-card__icon svg.icon--filled, +.apps-pill svg.icon--filled { + fill: currentColor; + stroke: none; +} + +@media (prefers-reduced-motion: reduce) { + .apps-card, + .apps-card__cta, + .apps-pill { + transition: none; + } + + .apps-card:hover, + .apps-card__cta:hover, + .apps-pill:hover { + transform: none; + } +} + +@media (max-width: 560px) { + .apps-hero__title { + font-size: 25px; + } +}