chore: update app version to 0.5.37 and enhance tool URL handling

- Bump application version to 0.5.37 in index.html and version.json.
- Implement settings change listener in ToolGenerator to refresh template iframes when gemini settings change.
- Update ToolWinBoxManager to process tool URLs dynamically during rendering.
- Refactor ToolboxDrawer to maintain original template URLs for later processing.
This commit is contained in:
liquidliang committed 2026-01-21 17:18:46 +08:00
1 parent a206daa998
commit fba900ce21
6 files changed
+74 -22

No files matched your search

+1 -1
View File
@@ -61,7 +61,7 @@
</script>
<!-- base href 由构建工具处理,CDN 模式下使用相对路径 -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<meta name="app-version" content="0.5.36" />
<meta name="app-version" content="0.5.37" />
<link rel="icon" type="image/svg+xml" sizes="16x16" href="./icons/favicon-16x16.svg" />
<link rel="icon" type="image/svg+xml" sizes="32x32" href="./icons/favicon-32x32.svg" />
+1 -1
View File
@@ -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": []
}
@@ -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<string, ToolLoadState>();
private loadTimeouts = new Map<string, NodeJS.Timeout>();
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) => {
@@ -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 = () => {
</Suspense>
) : tool.url ? (
<iframe
src={tool.url}
src={processToolUrl(tool.url).url}
title={tool.name}
style={{ width: '100%', height: '100%', border: 'none' }}
sandbox={tool.permissions?.join(' ') || 'allow-scripts allow-same-origin'}
@@ -18,7 +18,7 @@ import { DEFAULT_TOOL_CONFIG, TOOL_CATEGORY_LABELS } from '../../constants/built
import { ToolList } from './ToolList';
import { CustomToolDialog } from '../custom-tool-dialog/CustomToolDialog';
import { BaseDrawer } from '../side-drawer';
import { processToolUrl, needsApiKeyConfiguration } from '../../utils/url-template';
import { needsApiKeyConfiguration } from '../../utils/url-template';
import { geminiSettings } from '../../utils/settings-manager';
import './toolbox-drawer.scss';
@@ -110,19 +110,16 @@ export const ToolboxDrawer: React.FC<ToolboxDrawerProps> = ({
const width = tool.defaultWidth || DEFAULT_TOOL_CONFIG.defaultWidth;
const height = tool.defaultHeight || DEFAULT_TOOL_CONFIG.defaultHeight;
// 处理 URL 模板变量替换
let processedUrl = (tool as any).url;
if (processedUrl) {
const { url } = processToolUrl(processedUrl);
processedUrl = url;
}
// 获取工具 URL(保持模板形式,如 ${apiKey})
// 模板变量会在渲染时由 ToolGenerator 动态替换
const toolUrl = (tool as any).url;
// 插入到画布(中心对齐)
if (processedUrl || tool.component) {
if (toolUrl || tool.component) {
ToolTransforms.insertTool(
board,
tool.id,
processedUrl, // 使用替换后的 URL
toolUrl, // 存储原始模板 URL,渲染时再替换
[centerX - width / 2, centerY - height / 2],
{ width, height },
{
@@ -168,15 +165,8 @@ export const ToolboxDrawer: React.FC<ToolboxDrawerProps> = ({
*/
const executeToolOpenWindow = useCallback(
(tool: ToolDefinition) => {
// 处理 URL 模板变量替换
let processedTool = tool;
const toolUrl = (tool as any).url;
if (toolUrl) {
const { url } = processToolUrl(toolUrl);
processedTool = { ...tool, url } as ToolDefinition;
}
toolWindowService.openTool(processedTool);
// 存储原始模板 URL,在渲染时由 ToolWinBoxManager 替换
toolWindowService.openTool(tool);
// 在窗口打开后,可以选择关闭抽屉,也可以保持打开
handleClose();
},
@@ -430,6 +430,14 @@ class SettingsManager {
}
});
}
// 触发全局事件,用于画布中的工具 URL 模板刷新
// 当 gemini 相关设置变化时(如 apiKey、baseUrl)
if (path.startsWith('gemini') && typeof window !== 'undefined') {
window.dispatchEvent(new CustomEvent('gemini-settings-changed', {
detail: { path, newValue, oldValue }
}));
}
}
/**