diff --git a/apps/web/index.html b/apps/web/index.html index 8d9b2cbf..e9d21245 100644 --- a/apps/web/index.html +++ b/apps/web/index.html @@ -61,7 +61,7 @@ - + diff --git a/apps/web/public/version.json b/apps/web/public/version.json index 2e1791f6..61098e74 100644 --- a/apps/web/public/version.json +++ b/apps/web/public/version.json @@ -1,6 +1,6 @@ { "version": "0.5.37", - "buildTime": "2026-01-21T08:48:22.382Z", + "buildTime": "2026-01-21T08:48:23.142Z", "gitCommit": "unknown", "changelog": [] } \ No newline at end of file diff --git a/packages/drawnix/src/components/tool-element/tool.generator.ts b/packages/drawnix/src/components/tool-element/tool.generator.ts index 96879a95..905b5591 100644 --- a/packages/drawnix/src/components/tool-element/tool.generator.ts +++ b/packages/drawnix/src/components/tool-element/tool.generator.ts @@ -15,6 +15,8 @@ import { ToolProviderWrapper } from '../toolbox-drawer/ToolProviderWrapper'; import { ToolTransforms } from '../../plugins/with-tool'; import { toolWindowService } from '../../services/tool-window-service'; import { BUILT_IN_TOOLS } from '../../constants/built-in-tools'; +import { processToolUrl, hasTemplateVariables } from '../../utils/url-template'; +import { geminiSettings } from '../../utils/settings-manager'; /** * 工具元素渲染生成器 @@ -26,6 +28,7 @@ export class ToolGenerator { private loadStates = new Map(); private loadTimeouts = new Map(); private canvasClickHandler: ((e: MouseEvent) => void) | null = null; + private settingsChangeHandler: (() => void) | null = null; // 加载超时时间(毫秒) private static readonly LOAD_TIMEOUT = 10000; // 10 秒 @@ -35,6 +38,40 @@ export class ToolGenerator { // 监听画布点击事件,恢复所有 iframe 蒙层 this.setupCanvasClickHandler(); + + // 监听设置变化,刷新包含模板变量的 iframe + this.setupSettingsChangeHandler(); + } + + /** + * 设置设置变化监听器 + * 当 apiKey 等配置变化时,刷新包含模板变量的 iframe + */ + private setupSettingsChangeHandler(): void { + this.settingsChangeHandler = () => { + this.refreshTemplateIframes(); + }; + + // 监听设置变化事件 + window.addEventListener('gemini-settings-changed', this.settingsChangeHandler); + } + + /** + * 刷新所有包含模板变量的 iframe + */ + private refreshTemplateIframes(): void { + this.iframeCache.forEach((iframe, elementId) => { + const templateUrl = (iframe as any).__templateUrl; + if (templateUrl && hasTemplateVariables(templateUrl)) { + // 重新处理模板变量 + const { url: processedUrl } = processToolUrl(templateUrl); + const url = new URL(processedUrl, window.location.origin); + url.searchParams.set('toolId', elementId); + + // 更新 iframe src + iframe.src = url.toString(); + } + }); } /** @@ -526,10 +563,20 @@ export class ToolGenerator { // 设置超时检测 this.setupLoadTimeout(element.id); + // 处理模板变量(如 ${apiKey}),在渲染时动态替换 + const { url: processedUrl, missingVariables } = processToolUrl(element.url); + + if (missingVariables.length > 0) { + console.warn(`[ToolGenerator] URL contains missing variables: ${missingVariables.join(', ')}`); + } + // 设置 iframe URL,添加 toolId 参数用于通信 - const url = new URL(element.url, window.location.origin); + const url = new URL(processedUrl, window.location.origin); url.searchParams.set('toolId', element.id); iframe.src = url.toString(); + + // 保存原始模板 URL,用于设置变化时重新替换 + (iframe as any).__templateUrl = element.url; // 关键修改:默认启用 iframe 的鼠标事件,因为拖动只在标题栏上 // 这样 iframe 内的页面可以正常点击和滚动 @@ -822,6 +869,12 @@ export class ToolGenerator { document.removeEventListener('click', this.canvasClickHandler); this.canvasClickHandler = null; } + + // 移除设置变化监听器 + if (this.settingsChangeHandler) { + window.removeEventListener('gemini-settings-changed', this.settingsChangeHandler); + this.settingsChangeHandler = null; + } // 清理所有超时定时器 this.loadTimeouts.forEach((timeoutId) => { diff --git a/packages/drawnix/src/components/toolbox-drawer/ToolWinBoxManager.tsx b/packages/drawnix/src/components/toolbox-drawer/ToolWinBoxManager.tsx index b7897de7..0883b7f8 100644 --- a/packages/drawnix/src/components/toolbox-drawer/ToolWinBoxManager.tsx +++ b/packages/drawnix/src/components/toolbox-drawer/ToolWinBoxManager.tsx @@ -14,6 +14,7 @@ import { InternalToolComponents } from './InternalToolComponents'; import { useDrawnix } from '../../hooks/use-drawnix'; import { ToolTransforms } from '../../plugins/with-tool'; import { DEFAULT_TOOL_CONFIG } from '../../constants/built-in-tools'; +import { processToolUrl } from '../../utils/url-template'; /** * 工具弹窗管理器组件 @@ -123,7 +124,7 @@ export const ToolWinBoxManager: React.FC = () => { ) : tool.url ? (