diff --git a/public/_locales/en/messages.json b/public/_locales/en/messages.json index 20e0f02..cf53287 100644 --- a/public/_locales/en/messages.json +++ b/public/_locales/en/messages.json @@ -98,5 +98,17 @@ "clear_all_data": { "message": "Clear All Data", "description": "Clear all data button" + }, + "popup_title": { + "message": "SearchSyntax Pro", + "description": "Popup window title" + }, + "detached_title": { + "message": "SearchSyntax Pro - Detached Window", + "description": "Detached window title" + }, + "options_title": { + "message": "SearchSyntax Pro - Settings", + "description": "Options page title" } } \ No newline at end of file diff --git a/public/_locales/zh_CN/messages.json b/public/_locales/zh_CN/messages.json index 2fef2c2..53d9d78 100644 --- a/public/_locales/zh_CN/messages.json +++ b/public/_locales/zh_CN/messages.json @@ -1,7 +1,7 @@ { "app_name": { - "message": "搜索语法大师", - "description": "搜索语法大师 - SearchSyntax Pro" + "message": "SearchSyntax Pro", + "description": "SearchSyntax Pro - Advanced Search Syntax Tool" }, "app_description": { "message": "搜索语法可视化工具,降低高级搜索语法使用门槛", @@ -98,5 +98,17 @@ "clear_all_data": { "message": "清除所有数据", "description": "清除所有数据按钮" + }, + "popup_title": { + "message": "SearchSyntax Pro", + "description": "Popup window title" + }, + "detached_title": { + "message": "SearchSyntax Pro - 独立窗口", + "description": "Detached window title" + }, + "options_title": { + "message": "SearchSyntax Pro - 设置", + "description": "Options page title" } } \ No newline at end of file diff --git a/public/manifest.json b/public/manifest.json index b7444ad..9c90244 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -66,7 +66,7 @@ "web_accessible_resources": [ { - "resources": ["icons/*"], + "resources": ["icons/*", "src/detached/index.html"], "matches": [""] } ], diff --git a/src/components/PopoutButton.tsx b/src/components/PopoutButton.tsx new file mode 100644 index 0000000..81bf524 --- /dev/null +++ b/src/components/PopoutButton.tsx @@ -0,0 +1,93 @@ +import { useState } from 'react' +import { WindowManager } from '@/services/window-manager' +import { useTranslation } from '@/i18n' + +interface PopoutButtonProps { + className?: string +} + +/** + * Popout Button Component + * + * 在 popup 窗口中显示的"弹出到新窗口"按钮 + * 点击后将当前 popup 内容在独立窗口中打开 + */ +export function PopoutButton({ className = '' }: PopoutButtonProps) { + const { t } = useTranslation() + const [isLoading, setIsLoading] = useState(false) + + // 只在 popup 模式下显示此按钮 + if (WindowManager.isDetachedWindow()) { + return null + } + + const handlePopout = async () => { + try { + setIsLoading(true) + await WindowManager.popoutToDetachedWindow() + } catch (error) { + console.error('弹出窗口失败:', error) + setIsLoading(false) + alert('打开独立窗口失败,请重试') + } + } + + return ( + + ) +} diff --git a/src/detached/index.html b/src/detached/index.html new file mode 100644 index 0000000..43fcd02 --- /dev/null +++ b/src/detached/index.html @@ -0,0 +1,18 @@ + + + + + + SearchSyntax Pro - Detached Window + + + + +
+ +
+ + + diff --git a/src/detached/main.tsx b/src/detached/main.tsx new file mode 100644 index 0000000..8fd6695 --- /dev/null +++ b/src/detached/main.tsx @@ -0,0 +1,24 @@ +import React from 'react' +import ReactDOM from 'react-dom/client' +import App from '../popup/App' +import '../styles/globals.css' + +/** + * Detached Window Entry Point + * + * 这是独立窗口的入口文件,完全复用 popup/App.tsx 组件 + * 通过 window 对象标记当前运行环境为 detached 模式 + */ + +// 标记当前窗口为 detached 模式,供组件内部判断使用 +;(window as any).__SSP_WINDOW_MODE__ = 'detached' + +// 设置国际化标题 +document.title = chrome.i18n.getMessage('detached_title') + +// 渲染应用 +ReactDOM.createRoot(document.getElementById('app')!).render( + + + , +) diff --git a/src/i18n/translations.ts b/src/i18n/translations.ts index 3b72312..f49350c 100644 --- a/src/i18n/translations.ts +++ b/src/i18n/translations.ts @@ -35,9 +35,11 @@ const translations: Record> = { 'copyButton.tooltipCopy': '复制', 'copyButton.tooltipCopied': '已复制!', 'copyButton.copyError': '复制失败', - 'popup.headerTitle': '搜索语法大师', + 'popup.headerTitle': 'SearchSyntax Pro', 'popup.footer.currentEngine': '当前引擎: {engine}', 'popup.settingsButtonTitle': '设置', + 'popup.popoutButtonTitle': '弹出到新窗口', + 'popup.popoutButtonTooltip': '在独立窗口中使用,不会因浏览器操作而关闭', 'searchForm.keywordLabel': '搜索关键词', 'searchForm.keywordPlaceholder': '输入要搜索的关键词...', 'searchForm.engineLabel': '搜索引擎', @@ -70,7 +72,7 @@ const translations: Record> = { 'searchHistory.viewAllHint': '或前往设置页面查看完整历史记录', 'searchHistory.viewAllInSettings': '查看全部 {total} 条记录,请前往设置页面', 'searchHistory.goToSettings': '打开设置页面', - 'options.header.title': '搜索语法大师 - 设置', + 'options.header.title': 'SearchSyntax Pro - 设置', 'options.header.subtitle': '设置和配置', 'options.tabs.settings': '设置', 'options.tabs.shortcuts': '快捷键', @@ -406,6 +408,8 @@ const translations: Record> = { 'popup.headerTitle': 'SearchSyntax Pro', 'popup.footer.currentEngine': 'Current engine: {engine}', 'popup.settingsButtonTitle': 'Settings', + 'popup.popoutButtonTitle': 'Pop out to new window', + 'popup.popoutButtonTooltip': 'Use in a standalone window that won\'t close with browser actions', 'searchForm.keywordLabel': 'Search keywords', 'searchForm.keywordPlaceholder': 'Enter the keywords you want to search...', 'searchForm.engineLabel': 'Search engine', diff --git a/src/options/index.html b/src/options/index.html index 888cef6..506b557 100644 --- a/src/options/index.html +++ b/src/options/index.html @@ -3,7 +3,7 @@ - SSP智能搜索插件 - 设置 + SearchSyntax Pro - Settings