From ff04fea0fd45c46998923a7c44928bb2a25578df Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 10 May 2026 09:26:46 +0000 Subject: [PATCH 1/4] Initial plan From ae062bc7729f279e51d9be2e03905cd29e86b35f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 10 May 2026 09:35:49 +0000 Subject: [PATCH 2/4] Add Hub login session sync and display login status in options page Agent-Logs-Url: https://github.com/ujiro99/selection-command/sessions/d9e4cdb0-f494-4fc4-bbc3-84c6acc0a049 Co-authored-by: ujiro99 <677231+ujiro99@users.noreply.github.com> --- .../public/_locales/de/messages.json | 3 + .../public/_locales/en/messages.json | 3 + .../public/_locales/es/messages.json | 3 + .../public/_locales/fr/messages.json | 3 + .../public/_locales/hi/messages.json | 3 + .../public/_locales/id/messages.json | 3 + .../public/_locales/it/messages.json | 3 + .../public/_locales/ja/messages.json | 3 + .../public/_locales/ko/messages.json | 3 + .../public/_locales/ms/messages.json | 3 + .../public/_locales/pt_BR/messages.json | 3 + .../public/_locales/pt_PT/messages.json | 3 + .../public/_locales/ru/messages.json | 3 + .../public/_locales/zh_CN/messages.json | 3 + .../components/option/HubBanner.module.css | 14 +++ .../src/components/option/HubBanner.tsx | 48 +++++++- .../src/services/hub/background.test.ts | 114 +++++++++++++++++- .../extension/src/services/hub/background.ts | 31 ++++- .../extension/src/services/storage/const.ts | 1 + .../extension/src/services/storage/index.ts | 1 + packages/extension/src/types/index.ts | 5 + 21 files changed, 248 insertions(+), 8 deletions(-) diff --git a/packages/extension/public/_locales/de/messages.json b/packages/extension/public/_locales/de/messages.json index 9f7c9a61..727739f1 100644 --- a/packages/extension/public/_locales/de/messages.json +++ b/packages/extension/public/_locales/de/messages.json @@ -1247,5 +1247,8 @@ }, "Menu_disabled_urlNotMatch": { "message": "Kann auf dieser Seite nicht ausgeführt werden (Seiten-URL stimmt nicht überein)" + }, + "hub_login": { + "message": "Beim Hub anmelden" } } diff --git a/packages/extension/public/_locales/en/messages.json b/packages/extension/public/_locales/en/messages.json index b6a0352f..e5fe3576 100644 --- a/packages/extension/public/_locales/en/messages.json +++ b/packages/extension/public/_locales/en/messages.json @@ -1253,5 +1253,8 @@ }, "Menu_disabled_urlNotMatch": { "message": "Cannot run on this page (page URL does not match)" + }, + "hub_login": { + "message": "Login to Hub" } } diff --git a/packages/extension/public/_locales/es/messages.json b/packages/extension/public/_locales/es/messages.json index 7aadf686..a260159f 100644 --- a/packages/extension/public/_locales/es/messages.json +++ b/packages/extension/public/_locales/es/messages.json @@ -1247,5 +1247,8 @@ }, "Menu_disabled_urlNotMatch": { "message": "No se puede ejecutar en esta página (la URL de la página no coincide)" + }, + "hub_login": { + "message": "Iniciar sesión en Hub" } } diff --git a/packages/extension/public/_locales/fr/messages.json b/packages/extension/public/_locales/fr/messages.json index ca4c32f1..aa7ef4ca 100644 --- a/packages/extension/public/_locales/fr/messages.json +++ b/packages/extension/public/_locales/fr/messages.json @@ -1247,5 +1247,8 @@ }, "Menu_disabled_urlNotMatch": { "message": "Impossible d'exécuter sur cette page (l'URL de la page ne correspond pas)" + }, + "hub_login": { + "message": "Se connecter au Hub" } } diff --git a/packages/extension/public/_locales/hi/messages.json b/packages/extension/public/_locales/hi/messages.json index abd92477..fa850923 100644 --- a/packages/extension/public/_locales/hi/messages.json +++ b/packages/extension/public/_locales/hi/messages.json @@ -1247,5 +1247,8 @@ }, "Menu_disabled_urlNotMatch": { "message": "इस पेज पर नहीं चला सकते (पृष्ठ URL मेल नहीं खाता)" + }, + "hub_login": { + "message": "Hub में लॉगिन करें" } } diff --git a/packages/extension/public/_locales/id/messages.json b/packages/extension/public/_locales/id/messages.json index effb3a26..cb7470f0 100644 --- a/packages/extension/public/_locales/id/messages.json +++ b/packages/extension/public/_locales/id/messages.json @@ -1250,5 +1250,8 @@ }, "Menu_disabled_urlNotMatch": { "message": "Tidak dapat dijalankan di halaman ini (URL Halaman tidak cocok)" + }, + "hub_login": { + "message": "Masuk ke Hub" } } diff --git a/packages/extension/public/_locales/it/messages.json b/packages/extension/public/_locales/it/messages.json index ca533b2a..0761f14e 100644 --- a/packages/extension/public/_locales/it/messages.json +++ b/packages/extension/public/_locales/it/messages.json @@ -1247,5 +1247,8 @@ }, "Menu_disabled_urlNotMatch": { "message": "Impossibile eseguire su questa pagina (l'URL della pagina non corrisponde)" + }, + "hub_login": { + "message": "Accedi all'Hub" } } diff --git a/packages/extension/public/_locales/ja/messages.json b/packages/extension/public/_locales/ja/messages.json index 3ac84d7e..aa6b5fec 100644 --- a/packages/extension/public/_locales/ja/messages.json +++ b/packages/extension/public/_locales/ja/messages.json @@ -1244,5 +1244,8 @@ }, "Menu_disabled_urlNotMatch": { "message": "このページでは実行できません(ページURLが一致しません)" + }, + "hub_login": { + "message": "Hubにログイン" } } diff --git a/packages/extension/public/_locales/ko/messages.json b/packages/extension/public/_locales/ko/messages.json index 75c61c9f..4506ca8f 100644 --- a/packages/extension/public/_locales/ko/messages.json +++ b/packages/extension/public/_locales/ko/messages.json @@ -1247,5 +1247,8 @@ }, "Menu_disabled_urlNotMatch": { "message": "이 페이지에서 실행할 수 없습니다 (페이지 URL이 일치하지 않습니다)" + }, + "hub_login": { + "message": "Hub에 로그인" } } diff --git a/packages/extension/public/_locales/ms/messages.json b/packages/extension/public/_locales/ms/messages.json index dcaefb80..f63a4191 100644 --- a/packages/extension/public/_locales/ms/messages.json +++ b/packages/extension/public/_locales/ms/messages.json @@ -1250,5 +1250,8 @@ }, "Menu_disabled_urlNotMatch": { "message": "Tidak boleh dijalankan pada halaman ini (URL Halaman tidak sepadan)" + }, + "hub_login": { + "message": "Log masuk ke Hub" } } diff --git a/packages/extension/public/_locales/pt_BR/messages.json b/packages/extension/public/_locales/pt_BR/messages.json index 63f2af3b..64886c1e 100644 --- a/packages/extension/public/_locales/pt_BR/messages.json +++ b/packages/extension/public/_locales/pt_BR/messages.json @@ -1250,5 +1250,8 @@ }, "Menu_disabled_urlNotMatch": { "message": "Não é possível executar nesta página (URL da página não corresponde)" + }, + "hub_login": { + "message": "Entrar no Hub" } } diff --git a/packages/extension/public/_locales/pt_PT/messages.json b/packages/extension/public/_locales/pt_PT/messages.json index 419f1a3e..c9b6c219 100644 --- a/packages/extension/public/_locales/pt_PT/messages.json +++ b/packages/extension/public/_locales/pt_PT/messages.json @@ -1250,5 +1250,8 @@ }, "Menu_disabled_urlNotMatch": { "message": "Não é possível executar nesta página (URL da página não corresponde)" + }, + "hub_login": { + "message": "Iniciar sessão no Hub" } } diff --git a/packages/extension/public/_locales/ru/messages.json b/packages/extension/public/_locales/ru/messages.json index 31c98caa..4ddd1c5d 100644 --- a/packages/extension/public/_locales/ru/messages.json +++ b/packages/extension/public/_locales/ru/messages.json @@ -1247,5 +1247,8 @@ }, "Menu_disabled_urlNotMatch": { "message": "Невозможно выполнить на этой странице (URL страницы не совпадает)" + }, + "hub_login": { + "message": "Войти в Hub" } } diff --git a/packages/extension/public/_locales/zh_CN/messages.json b/packages/extension/public/_locales/zh_CN/messages.json index 8adb75f2..f3c365c9 100644 --- a/packages/extension/public/_locales/zh_CN/messages.json +++ b/packages/extension/public/_locales/zh_CN/messages.json @@ -1247,5 +1247,8 @@ }, "Menu_disabled_urlNotMatch": { "message": "无法在此页面运行(页面URL不匹配)" + }, + "hub_login": { + "message": "登录 Hub" } } diff --git a/packages/extension/src/components/option/HubBanner.module.css b/packages/extension/src/components/option/HubBanner.module.css index 7f1c8da0..7b7ed397 100644 --- a/packages/extension/src/components/option/HubBanner.module.css +++ b/packages/extension/src/components/option/HubBanner.module.css @@ -19,3 +19,17 @@ font-size: 0.8rem; padding-left: 4px; } + +.userInfo { + @apply flex items-center gap-2; +} + +.userAvatar { + @apply rounded-full; + object-fit: cover; +} + +.userName { + @apply font-mono text-gray-700; + font-size: 0.85rem; +} diff --git a/packages/extension/src/components/option/HubBanner.tsx b/packages/extension/src/components/option/HubBanner.tsx index 334ea70f..e02b7867 100644 --- a/packages/extension/src/components/option/HubBanner.tsx +++ b/packages/extension/src/components/option/HubBanner.tsx @@ -1,19 +1,35 @@ +import { useState, useEffect } from "react" +import { LogIn } from "lucide-react" import css from "./Option.module.css" import css2 from "./HubBanner.module.css" import { t } from "@/services/i18n" import { cn } from "@/lib/utils" -import { HUB_URL } from "@/const" +import { HUB_URL, NEW_HUB_URL } from "@/const" +import { Storage, LOCAL_STORAGE_KEY } from "@/services/storage" +import type { HubUser } from "@/types" + +const HUB_BANNER_LINK = `${HUB_URL}?utm_source=optionPage&utm_medium=banner` +const HUB_LOGIN_LINK = `${NEW_HUB_URL}/auth/signin?utm_source=extension&utm_medium=optionPage` export function HubBanner() { + const [hubUser, setHubUser] = useState(null) + + useEffect(() => { + Storage.get(LOCAL_STORAGE_KEY.HUB_USER).then(setHubUser) + + const unsubscribe = Storage.addListener( + LOCAL_STORAGE_KEY.HUB_USER, + (newVal) => setHubUser(newVal), + ) + return unsubscribe + }, []) + return (

Sharing Commands

- + {t("commandHub_description")}

+ {hubUser ? ( +
+ {hubUser.name} + {hubUser.name} +
+ ) : ( +
+ + {t("hub_login")} + + )}
) } diff --git a/packages/extension/src/services/hub/background.test.ts b/packages/extension/src/services/hub/background.test.ts index 403c965e..06391e31 100644 --- a/packages/extension/src/services/hub/background.test.ts +++ b/packages/extension/src/services/hub/background.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect, vi, beforeEach } from "vitest" import { shareCommandToHub, initHubExternalListener } from "./background" import { Ipc, BgCommand } from "@/services/ipc" -import { Storage } from "@/services/storage" +import { Storage, LOCAL_STORAGE_KEY } from "@/services/storage" vi.mock("@/services/ipc", () => ({ Ipc: { callListener: vi.fn() }, @@ -9,7 +9,8 @@ vi.mock("@/services/ipc", () => ({ })) vi.mock("@/services/storage", () => ({ - Storage: { getCommands: vi.fn() }, + Storage: { getCommands: vi.fn(), set: vi.fn() }, + LOCAL_STORAGE_KEY: { HUB_USER: "hubUser" }, })) vi.mock("@/const", () => ({ @@ -246,6 +247,115 @@ describe("onMessageExternal - RequestInstalledCommand", () => { }) }) +// --------------------------------------------------------------------------- +// onMessageExternal — SetSession +// --------------------------------------------------------------------------- + +describe("onMessageExternal - SetSession", () => { + it("SS-01: stores session data and calls sendResponse with result:true", async () => { + vi.mocked(Storage.set).mockResolvedValue(true) + const listener = getRegisteredListener() + const sendResponse = vi.fn() + const session = { name: "Test User", image: "https://example.com/avatar.png" } + const result = listener( + { action: "SetSession", session }, + { origin: HUB_ORIGIN }, + sendResponse, + ) + expect(result).toBe(true) + await vi.waitFor(() => { + expect(Storage.set).toHaveBeenCalledWith( + LOCAL_STORAGE_KEY.HUB_USER, + session, + ) + expect(sendResponse).toHaveBeenCalledWith({ result: true }) + }) + }) + + it("SS-02: calls sendResponse with result:false when Storage.set rejects", async () => { + vi.mocked(Storage.set).mockRejectedValue(new Error("storage error")) + const listener = getRegisteredListener() + const sendResponse = vi.fn() + listener( + { + action: "SetSession", + session: { name: "Test User", image: "https://example.com/avatar.png" }, + }, + { origin: HUB_ORIGIN }, + sendResponse, + ) + await vi.waitFor(() => + expect(sendResponse).toHaveBeenCalledWith({ + result: false, + error: "storage error", + }), + ) + }) + + it("SS-03: returns false when session is missing required fields", () => { + const listener = getRegisteredListener() + const sendResponse = vi.fn() + const result = listener( + { action: "SetSession", session: { name: "Test User" } }, + { origin: HUB_ORIGIN }, + sendResponse, + ) + expect(result).toBe(false) + expect(Storage.set).not.toHaveBeenCalled() + }) + + it("SS-04: returns false when session is not provided", () => { + const listener = getRegisteredListener() + const sendResponse = vi.fn() + const result = listener( + { action: "SetSession" }, + { origin: HUB_ORIGIN }, + sendResponse, + ) + expect(result).toBe(false) + expect(Storage.set).not.toHaveBeenCalled() + }) +}) + +// --------------------------------------------------------------------------- +// onMessageExternal — ClearSession +// --------------------------------------------------------------------------- + +describe("onMessageExternal - ClearSession", () => { + it("CS-01: clears session data and calls sendResponse with result:true", async () => { + vi.mocked(Storage.set).mockResolvedValue(true) + const listener = getRegisteredListener() + const sendResponse = vi.fn() + const result = listener( + { action: "ClearSession" }, + { origin: HUB_ORIGIN }, + sendResponse, + ) + expect(result).toBe(true) + await vi.waitFor(() => { + expect(Storage.set).toHaveBeenCalledWith(LOCAL_STORAGE_KEY.HUB_USER, null) + expect(sendResponse).toHaveBeenCalledWith({ result: true }) + }) + }) + + it("CS-02: calls sendResponse with result:false when Storage.set rejects", async () => { + vi.mocked(Storage.set).mockRejectedValue(new Error("storage error")) + const listener = getRegisteredListener() + const sendResponse = vi.fn() + listener( + { action: "ClearSession" }, + { origin: HUB_ORIGIN }, + sendResponse, + ) + await vi.waitFor(() => + expect(sendResponse).toHaveBeenCalledWith({ + result: false, + error: "storage error", + }), + ) + }) +}) + // --------------------------------------------------------------------------- // shareCommandToHub // --------------------------------------------------------------------------- diff --git a/packages/extension/src/services/hub/background.ts b/packages/extension/src/services/hub/background.ts index 65c25372..e99b88a9 100644 --- a/packages/extension/src/services/hub/background.ts +++ b/packages/extension/src/services/hub/background.ts @@ -1,8 +1,9 @@ import { NEW_HUB_URL } from "@/const" import { Ipc, BgCommand } from "@/services/ipc" import type { Sender } from "@/services/ipc" -import { Storage } from "@/services/storage" +import { Storage, LOCAL_STORAGE_KEY } from "@/services/storage" import type { SubmitCommandInput } from "@/services/hubShare" +import type { HubUser } from "@/types" const RETRY_INTERVAL_MS = 100 const MAX_RETRIES = 20 // 2 seconds @@ -139,6 +140,34 @@ function onMessageExternal( return true } + if (action === "SetSession") { + const session = message.session as HubUser | undefined + if ( + session && + typeof session.name === "string" && + typeof session.image === "string" + ) { + Storage.set(LOCAL_STORAGE_KEY.HUB_USER, session) + .then(() => sendResponse({ result: true })) + .catch((err) => { + console.error("[onMessageExternal] SetSession failed:", err) + sendResponse({ result: false, error: err?.message ?? "Unknown error" }) + }) + return true + } + return false + } + + if (action === "ClearSession") { + Storage.set(LOCAL_STORAGE_KEY.HUB_USER, null) + .then(() => sendResponse({ result: true })) + .catch((err) => { + console.error("[onMessageExternal] ClearSession failed:", err) + sendResponse({ result: false, error: err?.message ?? "Unknown error" }) + }) + return true + } + return false } diff --git a/packages/extension/src/services/storage/const.ts b/packages/extension/src/services/storage/const.ts index 6f78c9cc..767326e2 100644 --- a/packages/extension/src/services/storage/const.ts +++ b/packages/extension/src/services/storage/const.ts @@ -16,6 +16,7 @@ export enum LOCAL_STORAGE_KEY { COMMANDS_BACKUP = "commandsBackup", DAILY_COMMANDS_BACKUP = "dailyCommandsBackup", WEEKLY_COMMANDS_BACKUP = "weeklyCommandsBackup", + HUB_USER = "hubUser", } export enum SESSION_STORAGE_KEY { diff --git a/packages/extension/src/services/storage/index.ts b/packages/extension/src/services/storage/index.ts index 9a151a00..0b24e70d 100644 --- a/packages/extension/src/services/storage/index.ts +++ b/packages/extension/src/services/storage/index.ts @@ -73,6 +73,7 @@ const DEFAULTS = { [LOCAL_STORAGE_KEY.WEEKLY_COMMANDS_BACKUP]: null, [LOCAL_STORAGE_KEY.LOCAL_COMMAND_METADATA]: null, [LOCAL_STORAGE_KEY.GLOBAL_COMMAND_METADATA]: null, + [LOCAL_STORAGE_KEY.HUB_USER]: null, [SESSION_STORAGE_KEY.BG]: {}, [SESSION_STORAGE_KEY.SESSION_DATA]: null, [SESSION_STORAGE_KEY.MESSAGE_QUEUE]: [], diff --git a/packages/extension/src/types/index.ts b/packages/extension/src/types/index.ts index 5ab3e91a..ca9c378b 100644 --- a/packages/extension/src/types/index.ts +++ b/packages/extension/src/types/index.ts @@ -207,6 +207,11 @@ export type SessionData = { timestamp: number } +export type HubUser = { + name: string + image: string +} + export type ExecuteCommandParams = { command: Command | SelectionCommand position: { x: number; y: number } | null From 5a607231ca4a90e74faf986c78487939bed9059e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 10 May 2026 09:37:52 +0000 Subject: [PATCH 3/4] Fix: add avatar image error fallback in HubBanner Agent-Logs-Url: https://github.com/ujiro99/selection-command/sessions/d9e4cdb0-f494-4fc4-bbc3-84c6acc0a049 Co-authored-by: ujiro99 <677231+ujiro99@users.noreply.github.com> --- packages/extension/src/components/option/HubBanner.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/extension/src/components/option/HubBanner.tsx b/packages/extension/src/components/option/HubBanner.tsx index e02b7867..08f409ae 100644 --- a/packages/extension/src/components/option/HubBanner.tsx +++ b/packages/extension/src/components/option/HubBanner.tsx @@ -48,6 +48,9 @@ export function HubBanner() { alt={hubUser.name} width="24" height="24" + onError={(e) => { + e.currentTarget.style.display = "none" + }} /> {hubUser.name} From 907dc59e36709a96a15827401eca70004aaa5041 Mon Sep 17 00:00:00 2001 From: ujiro99 Date: Sun, 10 May 2026 22:23:17 +0900 Subject: [PATCH 4/4] Update: Display login information in the top-right of the settings page header bar. --- packages/extension/package.json | 1 + .../public/_locales/ja/messages.json | 2 +- .../src/components/option/HubBanner.tsx | 44 +--------- .../src/components/option/HubUserInfo.tsx | 52 ++++++++++++ .../src/components/option/Option.tsx | 4 + .../src/services/hub/background.test.ts | 77 +++++++++++------ .../extension/src/services/hub/background.ts | 82 +++++++++++++++---- yarn.lock | 60 +++++++++++++- 8 files changed, 236 insertions(+), 86 deletions(-) create mode 100644 packages/extension/src/components/option/HubUserInfo.tsx diff --git a/packages/extension/package.json b/packages/extension/package.json index e4435c65..f5b271cb 100644 --- a/packages/extension/package.json +++ b/packages/extension/package.json @@ -39,6 +39,7 @@ "@radix-ui/react-toggle-group": "^1.1.7", "@sentry/react": "^9.42.0", "@sentry/vite-plugin": "^4.0.1", + "@supabase/supabase-js": "^2.105.4", "@testing-library/user-event": "^14.6.0", "bowser": "^2.14.1", "class-variance-authority": "^0.7.0", diff --git a/packages/extension/public/_locales/ja/messages.json b/packages/extension/public/_locales/ja/messages.json index aa6b5fec..0a6d9b0d 100644 --- a/packages/extension/public/_locales/ja/messages.json +++ b/packages/extension/public/_locales/ja/messages.json @@ -1246,6 +1246,6 @@ "message": "このページでは実行できません(ページURLが一致しません)" }, "hub_login": { - "message": "Hubにログイン" + "message": "Hubへログイン" } } diff --git a/packages/extension/src/components/option/HubBanner.tsx b/packages/extension/src/components/option/HubBanner.tsx index 08f409ae..53b33948 100644 --- a/packages/extension/src/components/option/HubBanner.tsx +++ b/packages/extension/src/components/option/HubBanner.tsx @@ -1,29 +1,12 @@ -import { useState, useEffect } from "react" -import { LogIn } from "lucide-react" import css from "./Option.module.css" import css2 from "./HubBanner.module.css" import { t } from "@/services/i18n" import { cn } from "@/lib/utils" -import { HUB_URL, NEW_HUB_URL } from "@/const" -import { Storage, LOCAL_STORAGE_KEY } from "@/services/storage" -import type { HubUser } from "@/types" +import { HUB_URL } from "@/const" const HUB_BANNER_LINK = `${HUB_URL}?utm_source=optionPage&utm_medium=banner` -const HUB_LOGIN_LINK = `${NEW_HUB_URL}/auth/signin?utm_source=extension&utm_medium=optionPage` export function HubBanner() { - const [hubUser, setHubUser] = useState(null) - - useEffect(() => { - Storage.get(LOCAL_STORAGE_KEY.HUB_USER).then(setHubUser) - - const unsubscribe = Storage.addListener( - LOCAL_STORAGE_KEY.HUB_USER, - (newVal) => setHubUser(newVal), - ) - return unsubscribe - }, []) - return (

@@ -40,31 +23,6 @@ export function HubBanner() {

{t("commandHub_description")}

- {hubUser ? ( -
- {hubUser.name} { - e.currentTarget.style.display = "none" - }} - /> - {hubUser.name} -
- ) : ( - - - {t("hub_login")} - - )}
) } diff --git a/packages/extension/src/components/option/HubUserInfo.tsx b/packages/extension/src/components/option/HubUserInfo.tsx new file mode 100644 index 00000000..742871c5 --- /dev/null +++ b/packages/extension/src/components/option/HubUserInfo.tsx @@ -0,0 +1,52 @@ +import { useState, useEffect } from "react" +import { LogIn } from "lucide-react" +import { t } from "@/services/i18n" +import { NEW_HUB_URL } from "@/const" +import { Storage, LOCAL_STORAGE_KEY } from "@/services/storage" +import type { HubUser } from "@/types" + +const HUB_LOGIN_LINK = `${NEW_HUB_URL}/auth/login?utm_source=extension&utm_medium=optionPage` + +export function HubUserInfo() { + const [hubUser, setHubUser] = useState(null) + + useEffect(() => { + Storage.get(LOCAL_STORAGE_KEY.HUB_USER).then(setHubUser) + + const unsubscribe = Storage.addListener( + LOCAL_STORAGE_KEY.HUB_USER, + (newVal) => setHubUser(newVal), + ) + return unsubscribe + }, []) + + if (hubUser) { + return ( +
+ {hubUser.name} { + e.currentTarget.style.display = "none" + }} + /> + {hubUser.name} +
+ ) + } + + return ( + + + {t("hub_login")} + + ) +} diff --git a/packages/extension/src/components/option/Option.tsx b/packages/extension/src/components/option/Option.tsx index be47f1a5..c2388f9a 100644 --- a/packages/extension/src/components/option/Option.tsx +++ b/packages/extension/src/components/option/Option.tsx @@ -10,6 +10,7 @@ import { ImportExport } from "@/components/option/ImportExport" import { UserSupport } from "@/components/option/UserSupport" import { DeveloperSupport } from "@/components/option/DeveloperSupport" import { HubBanner } from "@/components/option/HubBanner" +import { HubUserInfo } from "@/components/option/HubUserInfo" import { SettingForm } from "@/components/option/SettingForm" import StorageUsage from "@/components/option/StorageUsage" import { PromptHistoryBanner } from "@/components/option/PromptHistoryBanner" @@ -59,6 +60,9 @@ export function Option() { })} Version: {VERSION} +
+ +