refactor: 模块化架构重构

将单文件巨型 IIFE (1608行) 拆分为 14 个 ES Module:

核心层:
- js/state.js          - 轻量级响应式状态管理 (发布-订阅)
- js/utils.js          - 通用工具函数
- js/sanitizer.js      - HTML XSS 净化器
- js/marked-config.js  - Markdown 渲染器配置

组件层:
- js/components/chat-area.js      - 消息渲染/流式更新/导出
- js/components/input-area.js     - 文本输入/图片上传/发送
- js/components/history-modal.js  - 历史记录面板/搜索/分页
- js/components/settings-modal.js - 设置面板/数据管理
- js/components/header.js         - 顶部导航/连接状态
- js/components/model-bar.js      - 模型选择栏
- js/components/toast.js          - Toast 通知
- js/components/lightbox.js       - 图片预览

入口层:
- js/app.js            - 主入口/初始化协调

index.html: 1608行 → 204行纯模板
This commit is contained in:
thzxx
2026-04-03 11:34:24 +08:00
parent 41128d1937
commit 38edaee0f0
14 changed files with 1628 additions and 1409 deletions
+30
View File
@@ -0,0 +1,30 @@
/**
* Toast - 通知组件
*/
let toastContainer = null;
export function initToast() {
toastContainer = document.querySelector('#toastContainer');
}
/**
* 显示 Toast 通知
* @param {string} text - 通知文本
* @param {'info'|'success'|'warning'|'error'} type - 通知类型
* @param {number} duration - 显示时长 (ms)
*/
export function showToast(text, type = 'info', duration = 3000) {
if (!toastContainer) return;
const iconMap = { success: '✓', error: '✗', warning: '⚠', info: '' };
const toast = document.createElement('div');
toast.className = `toast ${type}`;
toast.innerHTML = `<span class="toast-icon">${iconMap[type] || ''}</span><span>${text}</span>`;
toastContainer.appendChild(toast);
setTimeout(() => {
toast.classList.add('removing');
toast.addEventListener('animationend', () => toast.remove());
}, duration);
}