2025-06-03 06:50:19 +08:00
|
|
|
|
<!DOCTYPE html>
|
|
|
|
|
<html lang="zh-TW" id="html-root">
|
|
|
|
|
<head>
|
|
|
|
|
<meta charset="UTF-8">
|
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
|
|
|
<title>{{ title }}</title>
|
|
|
|
|
<link rel="stylesheet" href="/static/css/styles.css">
|
2025-06-13 05:48:08 +08:00
|
|
|
|
<link rel="stylesheet" href="/static/css/session-management.css">
|
2025-06-13 13:43:27 +08:00
|
|
|
|
<link rel="stylesheet" href="/static/css/prompt-management.css">
|
2025-06-14 06:02:38 +08:00
|
|
|
|
<link rel="stylesheet" href="/static/css/audio-management.css">
|
2025-06-03 06:50:19 +08:00
|
|
|
|
<style>
|
2025-06-06 17:56:31 +08:00
|
|
|
|
/* 僅保留必要的頁面特定樣式和響應式調整 */
|
2025-06-05 01:59:56 +08:00
|
|
|
|
|
|
|
|
|
/* 響應式調整 */
|
|
|
|
|
@media (max-width: 768px) {
|
|
|
|
|
.timeout-controls {
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
align-items: flex-start;
|
|
|
|
|
gap: 12px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.timeout-separator {
|
|
|
|
|
display: none;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-06 17:56:31 +08:00
|
|
|
|
/* 頁面特定的佈局模式樣式 */
|
2025-06-03 15:09:08 +08:00
|
|
|
|
|
2025-06-07 04:22:24 +08:00
|
|
|
|
/* 佈局模式樣式 - 工作區模式 */
|
|
|
|
|
/* 工作區模式 - 顯示工作區頁籤,隱藏回饋和AI摘要頁籤 */
|
2025-06-06 16:44:24 +08:00
|
|
|
|
body.layout-combined-vertical .tab-button[data-tab="combined"],
|
|
|
|
|
body.layout-combined-horizontal .tab-button[data-tab="combined"] {
|
|
|
|
|
display: inline-block;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
body.layout-combined-vertical .tab-button[data-tab="feedback"],
|
|
|
|
|
body.layout-combined-vertical .tab-button[data-tab="summary"],
|
|
|
|
|
body.layout-combined-horizontal .tab-button[data-tab="feedback"],
|
|
|
|
|
body.layout-combined-horizontal .tab-button[data-tab="summary"] {
|
|
|
|
|
display: none;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-06 17:56:31 +08:00
|
|
|
|
/* 響應式設計 */
|
|
|
|
|
@media (max-width: 768px) {
|
|
|
|
|
.timeout-controls {
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
align-items: flex-start;
|
|
|
|
|
gap: 12px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.timeout-separator {
|
|
|
|
|
display: none;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-06 16:44:24 +08:00
|
|
|
|
|
|
|
|
|
|
2025-06-07 04:22:24 +08:00
|
|
|
|
/* 工作區分頁的水平佈局樣式 */
|
2025-06-03 15:09:08 +08:00
|
|
|
|
#tab-combined.active.combined-horizontal .combined-content {
|
|
|
|
|
display: flex !important;
|
|
|
|
|
flex-direction: row !important;
|
|
|
|
|
gap: 16px;
|
|
|
|
|
height: calc(100% - 60px); /* 減去描述區塊的高度 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#tab-combined.active.combined-horizontal .combined-section:first-child {
|
|
|
|
|
flex: 1 !important;
|
|
|
|
|
min-width: 300px;
|
|
|
|
|
max-width: 50%;
|
2025-06-14 10:54:51 +08:00
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
2025-06-03 15:09:08 +08:00
|
|
|
|
overflow: hidden; /* 確保容器不超出範圍 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#tab-combined.active.combined-horizontal .combined-section:last-child {
|
|
|
|
|
flex: 1 !important;
|
|
|
|
|
min-width: 400px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#tab-combined.active.combined-horizontal .combined-summary {
|
2025-06-14 10:54:51 +08:00
|
|
|
|
flex: 1; /* 讓摘要區域自動填滿剩餘空間 */
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
2025-06-03 15:09:08 +08:00
|
|
|
|
overflow: hidden; /* 確保摘要容器不超出範圍 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#tab-combined.active.combined-horizontal #combinedSummaryContent {
|
2025-06-14 10:54:51 +08:00
|
|
|
|
flex: 1; /* 讓內容區域自動填滿摘要容器 */
|
|
|
|
|
min-height: 200px; /* 降低最小高度 */
|
2025-06-03 15:09:08 +08:00
|
|
|
|
overflow-y: auto; /* 添加垂直滾動條 */
|
|
|
|
|
overflow-x: hidden; /* 隱藏水平滾動條 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#tab-combined.active.combined-horizontal .text-input {
|
|
|
|
|
min-height: 200px;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-07 04:22:24 +08:00
|
|
|
|
/* 工作區分頁的垂直佈局樣式 */
|
2025-06-03 15:09:08 +08:00
|
|
|
|
#tab-combined.active.combined-vertical .combined-content {
|
|
|
|
|
display: flex !important;
|
|
|
|
|
flex-direction: column !important;
|
|
|
|
|
gap: 16px;
|
|
|
|
|
height: calc(100% - 60px); /* 減去描述區塊的高度 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#tab-combined.active.combined-vertical .combined-section:first-child {
|
|
|
|
|
flex: 1 !important;
|
|
|
|
|
min-height: 200px;
|
2025-06-14 10:54:51 +08:00
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
2025-06-03 15:09:08 +08:00
|
|
|
|
overflow: hidden; /* 確保容器不超出範圍 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#tab-combined.active.combined-vertical .combined-section:last-child {
|
|
|
|
|
flex: 2 !important;
|
|
|
|
|
min-height: 300px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#tab-combined.active.combined-vertical .combined-summary {
|
2025-06-14 10:54:51 +08:00
|
|
|
|
flex: 1; /* 讓摘要區域自動填滿剩餘空間 */
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
2025-06-03 15:09:08 +08:00
|
|
|
|
overflow: hidden; /* 確保摘要容器不超出範圍 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#tab-combined.active.combined-vertical #combinedSummaryContent {
|
2025-06-14 10:54:51 +08:00
|
|
|
|
flex: 1; /* 讓內容區域自動填滿摘要容器 */
|
|
|
|
|
min-height: 150px; /* 降低最小高度 */
|
2025-06-03 15:09:08 +08:00
|
|
|
|
overflow-y: auto; /* 添加垂直滾動條 */
|
|
|
|
|
overflow-x: hidden; /* 隱藏水平滾動條 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#tab-combined.active.combined-vertical .text-input {
|
|
|
|
|
min-height: 200px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 預設的合併內容布局 */
|
|
|
|
|
.combined-content {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
gap: 16px;
|
|
|
|
|
flex: 1;
|
2025-06-14 10:54:51 +08:00
|
|
|
|
height: 100%; /* 確保充滿父容器 */
|
2025-06-03 15:09:08 +08:00
|
|
|
|
}
|
2025-06-04 21:34:45 +08:00
|
|
|
|
|
2025-06-07 04:22:24 +08:00
|
|
|
|
/* 工作區基礎樣式 */
|
2025-06-06 18:49:53 +08:00
|
|
|
|
.combined-section {
|
|
|
|
|
background: var(--bg-tertiary);
|
|
|
|
|
border: 1px solid var(--border-color);
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
padding: 16px;
|
|
|
|
|
margin-bottom: 16px;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-14 10:54:51 +08:00
|
|
|
|
/* 確保 AI 摘要區域能夠自動擴展 */
|
|
|
|
|
.combined-section .section-header {
|
|
|
|
|
flex-shrink: 0; /* 標題區域不收縮 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.combined-summary {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-direction: column;
|
|
|
|
|
flex: 1; /* 讓摘要容器自動填滿剩餘空間 */
|
|
|
|
|
min-height: 0; /* 允許收縮 */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#combinedSummaryContent {
|
|
|
|
|
flex: 1; /* 讓內容區域自動填滿摘要容器 */
|
|
|
|
|
min-height: 150px; /* 設定合理的最小高度 */
|
|
|
|
|
overflow-y: auto;
|
|
|
|
|
overflow-x: hidden;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-06 18:49:53 +08:00
|
|
|
|
.combined-section-title {
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
font-weight: 600;
|
|
|
|
|
color: var(--text-primary);
|
|
|
|
|
margin: 0 0 12px 0;
|
|
|
|
|
padding-bottom: 8px;
|
|
|
|
|
border-bottom: 1px solid var(--border-color);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.combined-summary {
|
|
|
|
|
background: var(--bg-secondary);
|
|
|
|
|
border: 1px solid var(--border-color);
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
padding: 0;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#combinedSummaryContent {
|
|
|
|
|
padding: 12px !important;
|
|
|
|
|
line-height: 1.6 !important;
|
|
|
|
|
font-family: inherit !important;
|
|
|
|
|
color: var(--text-primary) !important;
|
|
|
|
|
background: transparent !important;
|
|
|
|
|
border: none !important;
|
|
|
|
|
resize: none !important;
|
|
|
|
|
white-space: pre-wrap !important;
|
|
|
|
|
word-wrap: break-word !important;
|
|
|
|
|
overflow-wrap: break-word !important;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#summaryContent {
|
|
|
|
|
padding: 12px !important;
|
|
|
|
|
line-height: 1.6 !important;
|
|
|
|
|
font-family: inherit !important;
|
|
|
|
|
color: var(--text-primary) !important;
|
|
|
|
|
white-space: pre-wrap !important;
|
|
|
|
|
word-wrap: break-word !important;
|
|
|
|
|
overflow-wrap: break-word !important;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-04 21:34:45 +08:00
|
|
|
|
/* 圖片設定樣式 */
|
|
|
|
|
.image-settings-details {
|
|
|
|
|
border: 1px solid var(--border-color);
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
background: var(--bg-tertiary);
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.image-settings-summary {
|
|
|
|
|
padding: 8px 12px;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
color: var(--text-secondary);
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
user-select: none;
|
|
|
|
|
transition: color 0.3s ease;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.image-settings-summary:hover {
|
|
|
|
|
color: var(--text-primary);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.image-settings-content {
|
|
|
|
|
padding: 12px;
|
|
|
|
|
border-top: 1px solid var(--border-color);
|
|
|
|
|
background: var(--bg-secondary);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.image-setting-row {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
justify-content: space-between;
|
|
|
|
|
margin-bottom: 12px;
|
|
|
|
|
gap: 12px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.image-setting-row:last-of-type {
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.image-setting-label {
|
|
|
|
|
color: var(--text-primary);
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.image-setting-select {
|
|
|
|
|
background: var(--bg-primary);
|
|
|
|
|
color: var(--text-primary);
|
|
|
|
|
border: 1px solid var(--border-color);
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
padding: 4px 8px;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
min-width: 80px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.image-setting-checkbox-container {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 8px;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.image-setting-checkbox {
|
|
|
|
|
width: 16px;
|
|
|
|
|
height: 16px;
|
|
|
|
|
accent-color: var(--accent-color);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.image-setting-help {
|
|
|
|
|
color: var(--warning-color);
|
|
|
|
|
font-size: 11px;
|
|
|
|
|
margin-left: auto;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.image-setting-help-text {
|
|
|
|
|
color: var(--text-secondary);
|
|
|
|
|
font-size: 11px;
|
|
|
|
|
line-height: 1.4;
|
|
|
|
|
margin-top: 4px;
|
|
|
|
|
padding: 8px;
|
|
|
|
|
background: var(--bg-primary);
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
border: 1px solid var(--border-color);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 相容性提示樣式 */
|
|
|
|
|
.compatibility-hint {
|
|
|
|
|
background: rgba(33, 150, 243, 0.1);
|
|
|
|
|
border: 1px solid var(--info-color);
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
padding: 8px 12px;
|
|
|
|
|
margin-bottom: 8px;
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
gap: 12px;
|
|
|
|
|
font-size: 13px;
|
|
|
|
|
color: var(--info-color);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.compatibility-hint-btn {
|
|
|
|
|
background: var(--info-color);
|
|
|
|
|
color: white;
|
|
|
|
|
border: none;
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
padding: 4px 8px;
|
|
|
|
|
font-size: 11px;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
transition: background 0.3s ease;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.compatibility-hint-btn:hover {
|
|
|
|
|
background: #1976d2;
|
|
|
|
|
}
|
2025-06-06 16:44:24 +08:00
|
|
|
|
|
|
|
|
|
/* 回饋狀態指示器樣式 */
|
|
|
|
|
.feedback-status-indicator {
|
|
|
|
|
padding: 12px 16px;
|
|
|
|
|
margin: 16px 0;
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
border: 1px solid;
|
2025-06-06 21:09:45 +08:00
|
|
|
|
background: var(--bg-secondary);
|
2025-06-06 16:44:24 +08:00
|
|
|
|
transition: all 0.3s ease;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.feedback-status-indicator .status-text {
|
2025-06-06 21:09:45 +08:00
|
|
|
|
width: 100%;
|
2025-06-06 16:44:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-06-06 21:09:45 +08:00
|
|
|
|
.feedback-status-indicator .status-text strong,
|
|
|
|
|
.feedback-status-indicator .status-title {
|
2025-06-06 16:44:24 +08:00
|
|
|
|
display: block;
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
margin-bottom: 4px;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-06 21:09:45 +08:00
|
|
|
|
.feedback-status-indicator .status-text span,
|
|
|
|
|
.feedback-status-indicator .status-message {
|
2025-06-06 16:44:24 +08:00
|
|
|
|
font-size: 14px;
|
|
|
|
|
opacity: 0.8;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.feedback-status-indicator.status-waiting {
|
|
|
|
|
border-color: var(--accent-color);
|
|
|
|
|
background: rgba(74, 144, 226, 0.1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.feedback-status-indicator.status-processing {
|
|
|
|
|
border-color: #ffa500;
|
|
|
|
|
background: rgba(255, 165, 0, 0.1);
|
|
|
|
|
animation: pulse 2s infinite;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.feedback-status-indicator.status-submitted {
|
|
|
|
|
border-color: var(--success-color);
|
|
|
|
|
background: rgba(40, 167, 69, 0.1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@keyframes pulse {
|
|
|
|
|
0% { opacity: 1; }
|
|
|
|
|
50% { opacity: 0.7; }
|
|
|
|
|
100% { opacity: 1; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 禁用狀態的樣式 */
|
|
|
|
|
.image-upload-area.disabled {
|
|
|
|
|
opacity: 0.5;
|
|
|
|
|
pointer-events: none;
|
|
|
|
|
cursor: not-allowed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.text-input:disabled {
|
|
|
|
|
opacity: 0.6;
|
|
|
|
|
cursor: not-allowed;
|
|
|
|
|
}
|
2025-06-03 06:50:19 +08:00
|
|
|
|
</style>
|
|
|
|
|
</head>
|
2025-06-06 19:55:37 +08:00
|
|
|
|
<body class="layout-{{ layout_mode }}">
|
2025-06-13 05:48:08 +08:00
|
|
|
|
<!-- ===== 頂部連線監控狀態列 ===== -->
|
|
|
|
|
<div class="connection-monitor-bar">
|
|
|
|
|
<!-- 左側:應用標題和專案資訊 -->
|
|
|
|
|
<div class="app-info-section">
|
|
|
|
|
<div class="app-title">
|
|
|
|
|
<h1 data-i18n="app.title">MCP Feedback Enhanced</h1>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="project-info">
|
2025-06-14 11:38:14 +08:00
|
|
|
|
📂 <span data-i18n="app.projectDirectory">專案目錄</span>:
|
|
|
|
|
<span id="projectPathDisplay" class="project-path-display"
|
|
|
|
|
data-full-path="{{ project_directory }}"
|
|
|
|
|
data-i18n-title="app.clickToCopyPath"
|
|
|
|
|
title="點擊複製完整路徑">{{ project_directory }}</span>
|
2025-06-13 05:48:08 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 中間:連線狀態資訊 -->
|
|
|
|
|
<div class="connection-status-group">
|
2025-06-14 11:38:14 +08:00
|
|
|
|
<!-- 左側:會話狀態資訊 -->
|
|
|
|
|
<div class="session-status-info">
|
|
|
|
|
<div class="current-session-info">
|
|
|
|
|
<span class="session-indicator">
|
|
|
|
|
📋 <span data-i18n="sessionManagement.currentSession">當前會話</span>:
|
|
|
|
|
<span id="currentSessionId" class="session-id-display"
|
|
|
|
|
data-full-id="{{ session_id if session_id else 'loading' }}"
|
|
|
|
|
data-i18n-title="app.clickToCopySessionId"
|
|
|
|
|
title="點擊複製完整會話ID">{{ session_id[:8] if session_id else 'loading' }}...</span>
|
|
|
|
|
</span>
|
|
|
|
|
<span class="session-age">
|
|
|
|
|
<span data-i18n="sessionManagement.activeTime">活躍時間</span>: <span id="sessionAge">--</span>
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-06-13 17:57:34 +08:00
|
|
|
|
<!-- 倒數計時器顯示 -->
|
|
|
|
|
<div id="countdownDisplay" class="countdown-display" style="display: none;">
|
|
|
|
|
<span class="countdown-label" data-i18n="autoSubmit.countdownLabel">提交倒數</span>
|
|
|
|
|
<span id="countdownTimer" class="countdown-timer">--:--</span>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-06-13 05:48:08 +08:00
|
|
|
|
<!-- 主要連線狀態 -->
|
|
|
|
|
<div class="connection-indicator connecting" id="mainConnectionStatus">
|
|
|
|
|
<div class="status-icon pulse"></div>
|
2025-06-13 10:33:24 +08:00
|
|
|
|
<span class="status-text" data-i18n="connectionMonitor.connecting">連接中...</span>
|
2025-06-13 05:48:08 +08:00
|
|
|
|
<div class="connection-quality">
|
2025-06-13 10:33:24 +08:00
|
|
|
|
<div class="latency-indicator"><span data-i18n="connectionMonitor.latency">延遲</span>: --ms</div>
|
2025-06-13 05:48:08 +08:00
|
|
|
|
<div class="signal-strength">
|
|
|
|
|
<div class="signal-bar"></div>
|
|
|
|
|
<div class="signal-bar"></div>
|
|
|
|
|
<div class="signal-bar"></div>
|
2025-06-05 01:59:56 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-06-13 05:48:08 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
2025-06-14 11:38:14 +08:00
|
|
|
|
<!-- 連線和狀態資訊組合 -->
|
|
|
|
|
<div class="connection-status-combined">
|
|
|
|
|
<!-- 連線詳細資訊 -->
|
|
|
|
|
<div class="connection-details">
|
|
|
|
|
<span class="connection-time"><span data-i18n="connectionMonitor.connectionTime">連線時間</span>: --:--</span>
|
|
|
|
|
<span class="reconnect-count"><span data-i18n="connectionMonitor.reconnectCount">重連</span>: 0 <span data-i18n="connectionMonitor.times">次</span></span>
|
2025-06-13 05:48:08 +08:00
|
|
|
|
</div>
|
2025-06-14 11:38:14 +08:00
|
|
|
|
|
|
|
|
|
<!-- 詳細狀態資訊 -->
|
|
|
|
|
<div class="detailed-status-info">
|
|
|
|
|
<div class="websocket-metrics">
|
|
|
|
|
<span class="metric"><span data-i18n="connectionMonitor.metrics.messages">訊息</span>: <span id="messageCount">0</span></span>
|
|
|
|
|
<span class="metric"><span data-i18n="connectionMonitor.metrics.latencyMs">延遲</span>: <span id="latencyDisplay">--ms</span></span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="session-metrics">
|
|
|
|
|
<span class="metric"><span data-i18n="connectionMonitor.metrics.sessions">會話</span>: <span id="sessionCount">1</span></span>
|
|
|
|
|
<span class="metric"><span data-i18n="connectionMonitor.statusText">狀態</span>: <span id="sessionStatusText" data-i18n="connectionMonitor.waiting">等待中</span></span>
|
|
|
|
|
</div>
|
2025-06-03 06:50:19 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-06-13 05:48:08 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
2025-06-13 17:57:34 +08:00
|
|
|
|
<!-- 右側:快速操作 -->
|
2025-06-13 05:48:08 +08:00
|
|
|
|
<div class="quick-actions">
|
2025-06-13 17:57:34 +08:00
|
|
|
|
<!-- 保留空間以保持佈局平衡 -->
|
2025-06-13 05:48:08 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="container">
|
|
|
|
|
|
2025-06-03 06:50:19 +08:00
|
|
|
|
|
2025-06-06 17:56:31 +08:00
|
|
|
|
<!-- ===== 主內容區域 ===== -->
|
2025-06-14 18:38:42 +08:00
|
|
|
|
<main class="main-content">
|
|
|
|
|
<!-- ===== 主要內容區域 ===== -->
|
|
|
|
|
<div class="main-content-area">
|
2025-06-13 05:48:08 +08:00
|
|
|
|
|
|
|
|
|
<!-- 分頁導航 -->
|
|
|
|
|
<div class="tabs">
|
2025-06-03 06:50:19 +08:00
|
|
|
|
<div class="tab-buttons">
|
2025-06-16 14:53:52 +08:00
|
|
|
|
<!-- 工作區分頁 - 主要分頁 -->
|
|
|
|
|
<button class="tab-button active" data-tab="combined" data-i18n="tabs.combined">
|
2025-06-07 04:22:24 +08:00
|
|
|
|
📝 工作區
|
2025-06-03 06:50:19 +08:00
|
|
|
|
</button>
|
|
|
|
|
<button class="tab-button" data-tab="summary" data-i18n="tabs.summary">
|
|
|
|
|
📋 AI 摘要
|
|
|
|
|
</button>
|
|
|
|
|
<button class="tab-button" data-tab="command" data-i18n="tabs.command">
|
|
|
|
|
⚡ 命令
|
|
|
|
|
</button>
|
2025-06-14 18:38:42 +08:00
|
|
|
|
<button class="tab-button" data-tab="sessions" data-i18n="tabs.sessions">
|
|
|
|
|
📋 會話管理
|
|
|
|
|
</button>
|
2025-06-03 06:50:19 +08:00
|
|
|
|
<button class="tab-button" data-tab="settings" data-i18n="tabs.settings">
|
|
|
|
|
⚙️ 設定
|
|
|
|
|
</button>
|
2025-06-03 07:50:54 +08:00
|
|
|
|
<button class="tab-button" data-tab="about" data-i18n="tabs.about">
|
|
|
|
|
ℹ️ 關於
|
|
|
|
|
</button>
|
2025-06-03 06:50:19 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-06-06 16:44:24 +08:00
|
|
|
|
|
|
|
|
|
|
2025-06-06 21:09:45 +08:00
|
|
|
|
|
2025-06-03 06:50:19 +08:00
|
|
|
|
|
2025-06-06 17:56:31 +08:00
|
|
|
|
<!-- ===== AI 摘要分頁 ===== -->
|
2025-06-03 06:50:19 +08:00
|
|
|
|
<div id="tab-summary" class="tab-content">
|
|
|
|
|
<div class="section-description" data-i18n="summary.description">
|
|
|
|
|
以下是 AI 助手完成的工作摘要,請仔細查看並提供您的回饋意見。
|
|
|
|
|
</div>
|
2025-06-11 03:25:08 +08:00
|
|
|
|
|
2025-06-03 06:50:19 +08:00
|
|
|
|
<div class="input-group">
|
2025-06-15 17:29:39 +08:00
|
|
|
|
<div id="summaryContent" class="text-input" style="min-height: 300px; cursor: text; padding: 12px; line-height: 1.6; word-wrap: break-word; overflow-wrap: break-word;" data-dynamic-content="aiSummary">
|
2025-06-03 06:50:19 +08:00
|
|
|
|
{{ summary }}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 命令分頁 -->
|
|
|
|
|
<div id="tab-command" class="tab-content">
|
|
|
|
|
<!-- 命令輸出區域 - 放在上面 -->
|
|
|
|
|
<div class="input-group">
|
|
|
|
|
<div id="commandOutput" class="command-output"></div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 命令輸入區域 - 放在下面 -->
|
|
|
|
|
<div class="input-group" style="margin-bottom: 0;">
|
|
|
|
|
<label class="input-label" data-i18n="command.inputLabel">命令輸入</label>
|
|
|
|
|
<div style="display: flex; gap: 10px; align-items: flex-start;">
|
|
|
|
|
<div style="flex: 1; display: flex; align-items: center; gap: 8px;">
|
|
|
|
|
<span style="color: var(--accent-color); font-family: 'Consolas', 'Monaco', 'Courier New', monospace; font-weight: bold;">$</span>
|
2025-06-11 03:25:08 +08:00
|
|
|
|
<input
|
2025-06-03 06:50:19 +08:00
|
|
|
|
type="text"
|
2025-06-11 03:25:08 +08:00
|
|
|
|
id="commandInput"
|
|
|
|
|
class="command-input-line"
|
2025-06-03 06:50:19 +08:00
|
|
|
|
data-i18n-placeholder="command.placeholder"
|
|
|
|
|
placeholder="輸入要執行的命令..."
|
|
|
|
|
style="flex: 1; background: var(--bg-primary); border: 1px solid var(--border-color); border-radius: 4px; padding: 8px 12px; color: var(--text-primary); font-family: 'Consolas', 'Monaco', 'Courier New', monospace; font-size: 14px;"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<button id="runCommandBtn" class="btn btn-primary" data-i18n="command.runButton" style="white-space: nowrap;">
|
|
|
|
|
▶️ 執行
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-06-16 14:53:52 +08:00
|
|
|
|
<!-- 工作區分頁 - 主要分頁 -->
|
|
|
|
|
<div id="tab-combined" class="tab-content active">
|
2025-06-03 15:09:08 +08:00
|
|
|
|
<div class="combined-content">
|
|
|
|
|
<!-- AI 摘要區域 -->
|
|
|
|
|
<div class="combined-section">
|
2025-06-13 06:04:16 +08:00
|
|
|
|
<div class="section-header">
|
2025-06-07 04:22:24 +08:00
|
|
|
|
<h3 class="combined-section-title" data-i18n="combined.summaryTitle">📋 AI 工作摘要</h3>
|
|
|
|
|
</div>
|
2025-06-03 15:09:08 +08:00
|
|
|
|
<div class="combined-summary">
|
2025-06-15 17:29:39 +08:00
|
|
|
|
<div id="combinedSummaryContent" class="text-input" style="min-height: 200px; cursor: text; padding: 12px; line-height: 1.6; word-wrap: break-word; overflow-wrap: break-word;" data-dynamic-content="aiSummary">{{ summary }}</div>
|
2025-06-03 15:09:08 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 回饋輸入區域 -->
|
|
|
|
|
<div class="combined-section">
|
2025-06-14 18:18:10 +08:00
|
|
|
|
<div class="feedback-title-container">
|
|
|
|
|
<h3 class="combined-section-title" data-i18n="combined.feedbackTitle">💬 提供回饋</h3>
|
|
|
|
|
<button id="submitBtn" class="btn btn-success combined-submit-btn" data-i18n="buttons.submit">
|
|
|
|
|
✅ 提交回饋
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
2025-06-06 16:44:24 +08:00
|
|
|
|
|
|
|
|
|
<!-- 等待回饋狀態指示器 -->
|
2025-06-06 17:56:31 +08:00
|
|
|
|
{% set id = "combinedFeedbackStatusIndicator" %}
|
|
|
|
|
{% set status = "waiting" %}
|
|
|
|
|
{% set icon = "⏳" %}
|
2025-06-06 21:09:45 +08:00
|
|
|
|
{% set title = "等待回饋" %}
|
|
|
|
|
{% set message = "請提供您的回饋意見" %}
|
2025-06-06 17:56:31 +08:00
|
|
|
|
{% include 'components/status-indicator.html' %}
|
2025-06-06 16:44:24 +08:00
|
|
|
|
|
2025-06-03 15:09:08 +08:00
|
|
|
|
<div class="input-group">
|
2025-06-13 17:57:34 +08:00
|
|
|
|
<label class="input-label" data-i18n="feedback.textLabel">文字回饋</label>
|
|
|
|
|
|
|
|
|
|
<!-- 提示詞按鈕 -->
|
|
|
|
|
<div class="prompt-input-buttons" id="combinedPromptButtons">
|
|
|
|
|
<button type="button" class="prompt-input-btn select-prompt-btn" data-container-index="1">
|
|
|
|
|
<span>📝</span>
|
|
|
|
|
<span class="button-text" data-i18n="prompts.buttons.selectPrompt">Templates</span>
|
|
|
|
|
</button>
|
|
|
|
|
<button type="button" class="prompt-input-btn last-prompt-btn" data-container-index="1">
|
|
|
|
|
<span>🔄</span>
|
|
|
|
|
<span class="button-text" data-i18n="prompts.buttons.useLastPrompt">Last Used</span>
|
|
|
|
|
</button>
|
2025-06-13 16:45:13 +08:00
|
|
|
|
</div>
|
2025-06-13 17:57:34 +08:00
|
|
|
|
|
2025-06-06 16:44:24 +08:00
|
|
|
|
<textarea
|
|
|
|
|
id="combinedFeedbackText"
|
|
|
|
|
class="text-input"
|
2025-06-03 15:09:08 +08:00
|
|
|
|
data-i18n-placeholder="feedback.detailedPlaceholder"
|
2025-06-06 16:44:24 +08:00
|
|
|
|
placeholder="請在這裡輸入您的回饋...
|
|
|
|
|
|
|
|
|
|
💡 小提示:
|
|
|
|
|
• 按 Ctrl+Enter/Cmd+Enter (支援數字鍵盤) 可快速提交
|
|
|
|
|
• 按 Ctrl+V/Cmd+V 可直接貼上剪貼板圖片"
|
2025-06-03 15:09:08 +08:00
|
|
|
|
style="min-height: 150px;"
|
|
|
|
|
></textarea>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-06-06 17:56:31 +08:00
|
|
|
|
<!-- 圖片上傳組件 -->
|
|
|
|
|
{% set id_prefix = "combined" %}
|
|
|
|
|
{% set min_height = "100px" %}
|
|
|
|
|
{% include 'components/image-upload.html' %}
|
2025-06-03 15:09:08 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-06-14 18:38:42 +08:00
|
|
|
|
<!-- ===== 會話管理分頁 ===== -->
|
|
|
|
|
<div id="tab-sessions" class="tab-content">
|
|
|
|
|
<div class="section-description" data-i18n="sessionManagement.description">
|
|
|
|
|
管理當前會話和歷史會話記錄,查看會話統計資訊。
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 面板標題和控制 -->
|
|
|
|
|
<div class="session-panel-header">
|
|
|
|
|
<h3 data-i18n="sessionManagement.title">會話管理</h3>
|
|
|
|
|
<div class="panel-controls">
|
|
|
|
|
<button class="btn-icon" id="refreshSessions" data-i18n-title="sessionManagement.refresh" title="重新整理">
|
|
|
|
|
🔄
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="session-panel-content">
|
|
|
|
|
<!-- 當前活躍會話 -->
|
|
|
|
|
<div class="current-session-section">
|
|
|
|
|
<h4 data-i18n="sessionManagement.currentSession">當前會話</h4>
|
|
|
|
|
<div class="session-card active" id="currentSessionCard">
|
|
|
|
|
<div class="session-header">
|
|
|
|
|
<div class="session-id"><span data-i18n="sessionManagement.sessionId">會話 ID</span>: {{ session_id[:8] if session_id else 'loading' }}...</div>
|
|
|
|
|
<div class="session-status">
|
|
|
|
|
<span class="status-badge waiting" data-i18n="connectionMonitor.waiting">等待中</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="session-info">
|
|
|
|
|
<div class="session-time"><span data-i18n="sessionManagement.createdTime">建立時間</span>: --:--:--</div>
|
|
|
|
|
<div class="session-project"><span data-i18n="sessionManagement.project">專案</span>: {{ project_directory }}</div>
|
|
|
|
|
<div class="session-summary"><span data-i18n="sessionManagement.aiSummary">AI 摘要</span>: <span data-i18n="sessionManagement.loading">載入中...</span></div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="session-actions">
|
|
|
|
|
<button class="btn-small" id="viewSessionDetails" data-i18n="sessionManagement.viewDetails">詳細資訊</button>
|
2025-06-25 15:38:17 +08:00
|
|
|
|
<button class="btn-small btn-primary" id="copyCurrentSessionContent" title="复制当前会话内容">📋 复制会话内容</button>
|
|
|
|
|
<button class="btn-small btn-secondary" id="copyCurrentUserContent" title="复制当前用户发送的内容">📝 复制用户内容</button>
|
2025-06-14 18:38:42 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 會話歷史記錄 -->
|
|
|
|
|
<div class="session-history-section">
|
|
|
|
|
<h4 data-i18n="sessionManagement.sessionHistory">會話歷史</h4>
|
|
|
|
|
<div class="session-list" id="sessionHistoryList">
|
|
|
|
|
<div class="no-sessions" data-i18n="sessionManagement.noHistory">暫無歷史會話</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 會話統計 -->
|
|
|
|
|
<div class="session-stats-section">
|
|
|
|
|
<h4 data-i18n="sessionManagement.statistics">統計資訊</h4>
|
|
|
|
|
<div class="stats-grid">
|
|
|
|
|
<div class="stat-item">
|
|
|
|
|
<div class="stat-value stat-today-count">0</div>
|
|
|
|
|
<div class="stat-label" data-i18n="sessionManagement.todaySessions">今日會話</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="stat-item">
|
|
|
|
|
<div class="stat-value stat-average-duration">--</div>
|
|
|
|
|
<div class="stat-label" data-i18n="sessionManagement.todayAverageDuration">今日平均時長</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-06-03 06:50:19 +08:00
|
|
|
|
<!-- 設定分頁 -->
|
|
|
|
|
<div id="tab-settings" class="tab-content">
|
|
|
|
|
<!-- 介面設定卡片 -->
|
|
|
|
|
<div class="settings-card">
|
|
|
|
|
<div class="settings-card-header">
|
|
|
|
|
<h3 class="settings-card-title" data-i18n="settings.interface">🎨 介面設定</h3>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="settings-card-body">
|
|
|
|
|
<div class="setting-item">
|
|
|
|
|
<div class="setting-info">
|
2025-06-03 15:09:08 +08:00
|
|
|
|
<div class="setting-label" data-i18n="settings.layoutMode">界面佈局模式</div>
|
|
|
|
|
<div class="setting-description" data-i18n="settings.layoutModeDesc">
|
|
|
|
|
選擇 AI 摘要和回饋輸入的顯示方式
|
2025-06-03 06:50:19 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-06-03 15:09:08 +08:00
|
|
|
|
<div class="layout-mode-selector">
|
|
|
|
|
<div class="layout-option">
|
2025-06-07 04:22:24 +08:00
|
|
|
|
<input type="radio" id="combinedVertical" name="layoutMode" value="combined-vertical" checked>
|
2025-06-03 15:09:08 +08:00
|
|
|
|
<label for="combinedVertical">
|
2025-06-07 04:22:24 +08:00
|
|
|
|
<div class="layout-option-title" data-i18n="settings.combinedVertical">垂直布局</div>
|
2025-06-03 15:09:08 +08:00
|
|
|
|
<div class="layout-option-desc" data-i18n="settings.combinedVerticalDesc">AI 摘要在上,回饋輸入在下,摘要和回饋在同一頁面</div>
|
|
|
|
|
</label>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="layout-option">
|
|
|
|
|
<input type="radio" id="combinedHorizontal" name="layoutMode" value="combined-horizontal">
|
|
|
|
|
<label for="combinedHorizontal">
|
2025-06-07 04:22:24 +08:00
|
|
|
|
<div class="layout-option-title" data-i18n="settings.combinedHorizontal">水平布局</div>
|
2025-06-03 15:09:08 +08:00
|
|
|
|
<div class="layout-option-desc" data-i18n="settings.combinedHorizontalDesc">AI 摘要在左,回饋輸入在右,增大摘要可視區域</div>
|
|
|
|
|
</label>
|
|
|
|
|
</div>
|
2025-06-03 06:50:19 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-06-05 01:59:56 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-06-06 17:56:31 +08:00
|
|
|
|
|
|
|
|
|
|
2025-06-03 06:50:19 +08:00
|
|
|
|
<!-- 語言設定卡片 -->
|
|
|
|
|
<div class="settings-card">
|
|
|
|
|
<div class="settings-card-header">
|
2025-06-22 02:38:51 +08:00
|
|
|
|
<h3 class="settings-card-title" data-i18n="settings.language">🌍 語言設定</h3>
|
2025-06-03 06:50:19 +08:00
|
|
|
|
</div>
|
|
|
|
|
<div class="settings-card-body">
|
|
|
|
|
<div class="setting-item">
|
|
|
|
|
<div class="setting-info">
|
|
|
|
|
<div class="setting-label" data-i18n="settings.currentLanguage">當前語言</div>
|
|
|
|
|
<div class="setting-description" data-i18n="settings.languageDesc">
|
|
|
|
|
選擇界面顯示語言
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-06-13 14:32:45 +08:00
|
|
|
|
<div class="language-selector-dropdown">
|
|
|
|
|
<select id="settingsLanguageSelect" class="language-setting-select">
|
|
|
|
|
<option value="zh-TW" data-i18n="languages.zh-TW">繁體中文</option>
|
|
|
|
|
<option value="zh-CN" data-i18n="languages.zh-CN">简体中文</option>
|
|
|
|
|
<option value="en" data-i18n="languages.en">English</option>
|
|
|
|
|
</select>
|
2025-06-03 06:50:19 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-06-13 15:20:26 +08:00
|
|
|
|
<!-- 圖片設定卡片 -->
|
|
|
|
|
<div class="settings-card">
|
|
|
|
|
<div class="settings-card-header">
|
|
|
|
|
<h3 class="settings-card-title" data-i18n="images.settings.title">🖼️ 圖片設定</h3>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="settings-card-body">
|
|
|
|
|
<div class="setting-item">
|
|
|
|
|
<div class="setting-info">
|
|
|
|
|
<div class="setting-label" data-i18n="images.settings.sizeLimit">圖片大小限制</div>
|
|
|
|
|
<div class="setting-description" data-i18n="images.settings.sizeLimitDesc">
|
|
|
|
|
設定上傳圖片的最大檔案大小限制
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="image-size-limit-selector">
|
|
|
|
|
<select id="settingsImageSizeLimit" class="image-size-limit-select">
|
|
|
|
|
<option value="0" data-i18n="images.settings.sizeLimitOptions.unlimited">無限制</option>
|
|
|
|
|
<option value="1048576" data-i18n="images.settings.sizeLimitOptions.1mb">1MB</option>
|
|
|
|
|
<option value="3145728" data-i18n="images.settings.sizeLimitOptions.3mb">3MB</option>
|
|
|
|
|
<option value="5242880" data-i18n="images.settings.sizeLimitOptions.5mb">5MB</option>
|
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="setting-item">
|
|
|
|
|
<div class="setting-info">
|
|
|
|
|
<div class="setting-label" data-i18n="images.settings.base64Detail">Base64 相容模式</div>
|
|
|
|
|
<div class="setting-description" data-i18n="images.settings.base64DetailHelp">
|
|
|
|
|
啟用後會在文字中包含完整的 Base64 圖片資料,提升與某些 AI 模型的相容性
|
|
|
|
|
</div>
|
|
|
|
|
<div class="setting-warning" data-i18n="images.settings.base64Warning">⚠️ 會增加傳輸量</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="base64-toggle-container">
|
|
|
|
|
<label class="toggle-switch">
|
|
|
|
|
<input type="checkbox" id="settingsEnableBase64Detail" class="toggle-input">
|
|
|
|
|
<span class="toggle-slider"></span>
|
|
|
|
|
</label>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-06-13 16:45:13 +08:00
|
|
|
|
<!-- 自動定時提交設定卡片 -->
|
|
|
|
|
<div class="settings-card">
|
|
|
|
|
<div class="settings-card-header">
|
|
|
|
|
<h3 class="settings-card-title" data-i18n="autoSubmit.title">⏰ 自動定時提交</h3>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="settings-card-body">
|
|
|
|
|
<div class="setting-item">
|
|
|
|
|
<div class="setting-info">
|
|
|
|
|
<div class="setting-label" data-i18n="autoSubmit.enable">啟用自動提交</div>
|
|
|
|
|
<div class="setting-description" data-i18n="autoSubmit.enableDesc">
|
|
|
|
|
啟用後將在指定時間自動提交選定的提示詞內容
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="setting-control">
|
|
|
|
|
<button type="button" id="autoSubmitToggle" class="toggle-btn" aria-label="切換自動提交">
|
|
|
|
|
<span class="toggle-slider"></span>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="setting-item">
|
|
|
|
|
<div class="setting-info">
|
|
|
|
|
<div class="setting-label" data-i18n="autoSubmit.timeout">倒數時間(秒)</div>
|
|
|
|
|
<div class="setting-description" data-i18n="autoSubmit.timeoutDesc">
|
|
|
|
|
設定自動提交的倒數時間,範圍:1-86400 秒
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="setting-control">
|
|
|
|
|
<input type="number" id="autoSubmitTimeout" min="1" max="86400" value="30"
|
|
|
|
|
class="form-input" style="width: 120px;">
|
|
|
|
|
<span class="input-suffix" data-i18n="autoSubmit.seconds">秒</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="setting-item">
|
|
|
|
|
<div class="setting-info">
|
|
|
|
|
<div class="setting-label" data-i18n="autoSubmit.prompt">自動提交提示詞</div>
|
|
|
|
|
<div class="setting-description" data-i18n="autoSubmit.promptDesc">
|
|
|
|
|
選擇要自動提交的提示詞內容
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="setting-control">
|
|
|
|
|
<select id="autoSubmitPromptSelect" class="form-select" style="width: 200px;">
|
|
|
|
|
<option value="" data-i18n="autoSubmit.selectPrompt">請選擇提示詞</option>
|
|
|
|
|
<!-- 提示詞選項將動態載入 -->
|
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="setting-item">
|
|
|
|
|
<div class="setting-info">
|
|
|
|
|
<div class="setting-label" data-i18n="autoSubmit.status">目前狀態</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="setting-control">
|
|
|
|
|
<button type="button" id="autoSubmitStatus" class="auto-submit-status-btn" disabled>
|
|
|
|
|
<span>⏸️</span>
|
|
|
|
|
<span class="button-text" data-i18n="autoSubmit.disabled">已停用</span>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-06-14 06:02:38 +08:00
|
|
|
|
<!-- 音效通知設定卡片 -->
|
|
|
|
|
<div class="settings-card">
|
|
|
|
|
<div class="settings-card-header">
|
|
|
|
|
<h3 class="settings-card-title" data-i18n="audio.notification.title">🔊 音效通知設定</h3>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="settings-card-body" id="audioManagementContainer">
|
|
|
|
|
<!-- 音效管理 UI 將在這裡動態生成 -->
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-06-14 09:29:03 +08:00
|
|
|
|
<!-- 會話歷史管理卡片 -->
|
|
|
|
|
<div class="settings-card">
|
|
|
|
|
<div class="settings-card-header">
|
|
|
|
|
<h3 class="settings-card-title" data-i18n="sessionHistory.management.title">📚 會話歷史管理</h3>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="settings-card-body">
|
|
|
|
|
<div class="setting-item">
|
|
|
|
|
<div class="setting-info">
|
|
|
|
|
<div class="setting-label" data-i18n="sessionHistory.management.retentionPeriod">保存期限</div>
|
|
|
|
|
<div class="setting-description" data-i18n="sessionHistory.management.description">
|
|
|
|
|
管理本地儲存的會話歷史記錄,包括保存期限設定和資料匯出功能
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="setting-control">
|
|
|
|
|
<select id="sessionHistoryRetentionHours" class="form-select" style="width: 150px;">
|
|
|
|
|
<option value="24" data-i18n="sessionHistory.retention.24hours">24 小時</option>
|
|
|
|
|
<option value="72" data-i18n="sessionHistory.retention.72hours">72 小時</option>
|
|
|
|
|
<option value="168" data-i18n="sessionHistory.retention.168hours">7 天</option>
|
|
|
|
|
<option value="720" data-i18n="sessionHistory.retention.720hours">30 天</option>
|
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-06-14 09:59:42 +08:00
|
|
|
|
<div class="setting-item">
|
|
|
|
|
<div class="setting-info">
|
|
|
|
|
<div class="setting-label" data-i18n="sessionHistory.userMessages.title">用戶訊息記錄</div>
|
|
|
|
|
<div class="setting-description" data-i18n="sessionHistory.userMessages.description">
|
|
|
|
|
控制是否記錄用戶提交的回饋訊息到會話歷史中
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="setting-control">
|
|
|
|
|
<div class="toggle-container">
|
|
|
|
|
<label class="toggle-switch">
|
|
|
|
|
<input type="checkbox" id="userMessageRecordingToggle" class="toggle-input">
|
|
|
|
|
<span class="toggle-slider"></span>
|
|
|
|
|
</label>
|
|
|
|
|
<span class="toggle-label" data-i18n="sessionHistory.userMessages.recordingEnabled">啟用訊息記錄</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="setting-item">
|
|
|
|
|
<div class="setting-info">
|
|
|
|
|
<div class="setting-label" data-i18n="sessionHistory.userMessages.privacyLevel">隱私等級</div>
|
|
|
|
|
<div class="setting-description" id="userMessagePrivacyDescription" data-i18n="sessionHistory.userMessages.privacyDescription.full">
|
|
|
|
|
記錄完整的訊息內容和圖片資訊
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="setting-control">
|
|
|
|
|
<select id="userMessagePrivacyLevel" class="form-select" style="width: 150px;">
|
|
|
|
|
<option value="full" data-i18n="sessionHistory.userMessages.privacyLevels.full">完整記錄</option>
|
|
|
|
|
<option value="basic" data-i18n="sessionHistory.userMessages.privacyLevels.basic">基本統計</option>
|
|
|
|
|
<option value="disabled" data-i18n="sessionHistory.userMessages.privacyLevels.disabled">停用記錄</option>
|
|
|
|
|
</select>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-06-14 09:29:03 +08:00
|
|
|
|
<div class="setting-item" style="border-bottom: none;">
|
|
|
|
|
<div class="setting-info">
|
|
|
|
|
<div class="setting-label" data-i18n="sessionHistory.management.export">資料管理</div>
|
2025-06-14 09:59:42 +08:00
|
|
|
|
<div class="setting-description" data-i18n="sessionHistory.management.exportDescription">
|
2025-06-14 09:29:03 +08:00
|
|
|
|
匯出或清空本地儲存的會話歷史記錄
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-06-14 09:59:42 +08:00
|
|
|
|
<div class="setting-control" style="display: flex; gap: 8px; flex-wrap: wrap;">
|
2025-06-14 09:29:03 +08:00
|
|
|
|
<button id="exportSessionHistoryBtn" class="btn btn-secondary" style="font-size: 12px; padding: 6px 12px;">
|
|
|
|
|
<span data-i18n="sessionHistory.management.exportAll">匯出全部</span>
|
|
|
|
|
</button>
|
2025-06-14 09:59:42 +08:00
|
|
|
|
<button id="clearUserMessagesBtn" class="btn btn-secondary" style="font-size: 12px; padding: 6px 12px; color: var(--warning-color); border-color: var(--warning-color);">
|
|
|
|
|
<span data-i18n="sessionHistory.userMessages.clearAll">清空訊息記錄</span>
|
|
|
|
|
</button>
|
2025-06-14 09:29:03 +08:00
|
|
|
|
<button id="clearSessionHistoryBtn" class="btn btn-secondary" style="font-size: 12px; padding: 6px 12px; color: var(--error-color); border-color: var(--error-color);">
|
|
|
|
|
<span data-i18n="sessionHistory.management.clear">清空</span>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-06-13 13:43:27 +08:00
|
|
|
|
<!-- 提示詞管理卡片 -->
|
|
|
|
|
<div class="settings-card">
|
|
|
|
|
<div class="settings-card-header">
|
|
|
|
|
<h3 class="settings-card-title" data-i18n="prompts.management.title">📝 常用提示詞管理</h3>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="settings-card-body" id="promptManagementContainer">
|
|
|
|
|
<!-- 提示詞管理 UI 將在這裡動態生成 -->
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
2025-06-03 15:09:08 +08:00
|
|
|
|
<!-- 重置設定卡片 -->
|
|
|
|
|
<div class="settings-card">
|
|
|
|
|
<div class="settings-card-header">
|
|
|
|
|
<h3 class="settings-card-title" data-i18n="settings.advanced">🔧 進階設定</h3>
|
2025-06-03 06:50:19 +08:00
|
|
|
|
</div>
|
2025-06-03 15:09:08 +08:00
|
|
|
|
<div class="settings-card-body">
|
|
|
|
|
<div class="setting-item" style="border-bottom: none;">
|
|
|
|
|
<div class="setting-info">
|
|
|
|
|
<div class="setting-label" data-i18n="settings.reset">重置設定</div>
|
|
|
|
|
<div class="setting-description" data-i18n="settings.resetDesc">
|
|
|
|
|
清除所有已保存的設定,恢復到預設狀態
|
|
|
|
|
</div>
|
2025-06-03 06:50:19 +08:00
|
|
|
|
</div>
|
2025-06-03 15:09:08 +08:00
|
|
|
|
<button id="resetSettingsBtn" class="btn btn-secondary" style="font-size: 12px; padding: 6px 16px;">
|
|
|
|
|
<span data-i18n="settings.reset">重置設定</span>
|
|
|
|
|
</button>
|
2025-06-03 06:50:19 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-06-03 07:50:54 +08:00
|
|
|
|
|
|
|
|
|
<!-- 關於分頁 -->
|
|
|
|
|
<div id="tab-about" class="tab-content">
|
|
|
|
|
<!-- 主要資訊卡片 -->
|
|
|
|
|
<div class="settings-card">
|
|
|
|
|
<div class="settings-card-header">
|
|
|
|
|
<div style="display: flex; justify-content: space-between; align-items: center; width: 100%;">
|
|
|
|
|
<h3 class="settings-card-title" style="margin: 0;">MCP Feedback Enhanced</h3>
|
|
|
|
|
<span style="color: var(--accent-color); font-weight: bold; font-size: 16px;">v{{ version }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="settings-card-body">
|
|
|
|
|
<!-- 應用程式描述 -->
|
|
|
|
|
<div class="setting-item" style="border-bottom: none; padding-bottom: 16px;">
|
|
|
|
|
<div class="setting-info">
|
|
|
|
|
<div class="setting-description" data-i18n="about.description" style="color: var(--text-secondary); font-size: 13px; line-height: 1.5;">
|
2025-06-10 05:43:49 +08:00
|
|
|
|
一個強大的 MCP 伺服器,為 AI 輔助開發工具提供人在回路的互動回饋功能。支援 Web UI 介面,並具備圖片上傳、命令執行、多語言等豐富功能。
|
2025-06-03 07:50:54 +08:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 分隔線 -->
|
|
|
|
|
<div style="height: 1px; background: var(--border-color); margin: 16px 0;"></div>
|
|
|
|
|
|
|
|
|
|
<!-- GitHub 專案 -->
|
|
|
|
|
<div class="setting-item" style="border-bottom: none; padding-bottom: 12px;">
|
|
|
|
|
<div class="setting-info">
|
|
|
|
|
<div class="setting-label">📂 <span data-i18n="about.githubProject">GitHub 專案</span></div>
|
|
|
|
|
<div class="setting-description" style="color: var(--text-secondary); font-size: 11px; margin-left: 24px;">
|
|
|
|
|
https://github.com/Minidoracat/mcp-feedback-enhanced
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<button class="btn btn-primary" onclick="window.open('https://github.com/Minidoracat/mcp-feedback-enhanced', '_blank')" style="font-size: 12px; padding: 6px 16px;">
|
|
|
|
|
<span data-i18n="about.visitGithub">訪問 GitHub</span>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 分隔線 -->
|
|
|
|
|
<div style="height: 1px; background: var(--border-color); margin: 16px 0;"></div>
|
|
|
|
|
|
|
|
|
|
<!-- Discord 支援 -->
|
|
|
|
|
<div class="setting-item" style="border-bottom: none; padding-bottom: 12px;">
|
|
|
|
|
<div class="setting-info">
|
|
|
|
|
<div class="setting-label">💬 <span data-i18n="about.discordSupport">Discord 支援</span></div>
|
|
|
|
|
<div class="setting-description" style="color: var(--text-secondary); font-size: 11px; margin-left: 24px;">
|
|
|
|
|
https://discord.gg/ACjf9Q58
|
|
|
|
|
</div>
|
|
|
|
|
<div class="setting-description" data-i18n="about.contactDescription" style="color: var(--text-secondary); font-size: 12px; margin-left: 24px; margin-top: 8px;">
|
|
|
|
|
如需技術支援、問題回報或功能建議,歡迎透過 Discord 社群或 GitHub Issues 與我們聯繫。
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<button class="btn" onclick="window.open('https://discord.gg/ACjf9Q58', '_blank')" style="background: #5865F2; color: white; font-size: 12px; padding: 6px 16px; border: none;">
|
|
|
|
|
<span data-i18n="about.joinDiscord">加入 Discord</span>
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- 致謝與貢獻卡片 -->
|
|
|
|
|
<div class="settings-card">
|
|
|
|
|
<div class="settings-card-header">
|
|
|
|
|
<h3 class="settings-card-title" data-i18n="about.thanks">🙏 致謝與貢獻</h3>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="settings-card-body">
|
|
|
|
|
<div class="setting-item" style="border-bottom: none;">
|
|
|
|
|
<div class="setting-info">
|
|
|
|
|
<div class="text-input" data-i18n="about.thanksText" style="background: var(--bg-primary); border: 1px solid var(--border-color); border-radius: 4px; padding: 12px; color: var(--text-primary); font-size: 12px; line-height: 1.5; min-height: 140px; max-height: 200px; overflow-y: auto; white-space: pre-wrap;">感謝原作者 Fábio Ferreira (@fabiomlferreira) 創建了原始的 interactive-feedback-mcp 專案。
|
|
|
|
|
|
2025-06-10 05:43:49 +08:00
|
|
|
|
本增強版本由 Minidoracat 開發和維護,大幅擴展了專案功能,新增了 Web UI 介面、圖片支援、多語言能力以及許多其他改進功能。
|
2025-06-03 07:50:54 +08:00
|
|
|
|
|
|
|
|
|
同時感謝 sanshao85 的 mcp-feedback-collector 專案提供的 UI 設計靈感。
|
|
|
|
|
|
|
|
|
|
開源協作讓技術變得更美好!</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-06-13 05:48:08 +08:00
|
|
|
|
</div> <!-- 關閉 main-content-area -->
|
2025-06-03 06:50:19 +08:00
|
|
|
|
</main>
|
|
|
|
|
|
2025-06-14 10:37:25 +08:00
|
|
|
|
|
2025-06-03 06:50:19 +08:00
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<!-- WebSocket 和 JavaScript -->
|
2025-06-15 17:29:39 +08:00
|
|
|
|
<!-- Markdown 支援庫 -->
|
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/marked@14.1.3/marked.min.js"></script>
|
|
|
|
|
<script src="https://cdn.jsdelivr.net/npm/dompurify@3.2.2/dist/purify.min.js"></script>
|
2025-06-06 16:44:24 +08:00
|
|
|
|
<script src="/static/js/i18n.js?v=2025010510"></script>
|
2025-06-10 07:19:47 +08:00
|
|
|
|
<!-- 載入所有模組 -->
|
2025-06-15 14:51:36 +08:00
|
|
|
|
<!-- 核心模組(最先載入) -->
|
|
|
|
|
<script src="/static/js/modules/logger.js?v=2025010510"></script>
|
|
|
|
|
|
2025-06-13 05:48:08 +08:00
|
|
|
|
<!-- 工具模組 -->
|
|
|
|
|
<script src="/static/js/modules/utils/dom-utils.js?v=2025010510"></script>
|
|
|
|
|
<script src="/static/js/modules/utils/time-utils.js?v=2025010510"></script>
|
|
|
|
|
<script src="/static/js/modules/utils/status-utils.js?v=2025010510"></script>
|
|
|
|
|
|
|
|
|
|
<!-- 會話管理模組 -->
|
|
|
|
|
<script src="/static/js/modules/session/session-data-manager.js?v=2025010510"></script>
|
|
|
|
|
<script src="/static/js/modules/session/session-ui-renderer.js?v=2025010510"></script>
|
|
|
|
|
<script src="/static/js/modules/session/session-details-modal.js?v=2025010510"></script>
|
|
|
|
|
|
2025-06-13 13:43:27 +08:00
|
|
|
|
<!-- 提示詞管理模組 -->
|
|
|
|
|
<script src="/static/js/modules/prompt/prompt-manager.js?v=2025010510"></script>
|
|
|
|
|
<script src="/static/js/modules/prompt/prompt-modal.js?v=2025010510"></script>
|
|
|
|
|
<script src="/static/js/modules/prompt/prompt-settings-ui.js?v=2025010510"></script>
|
|
|
|
|
<script src="/static/js/modules/prompt/prompt-input-buttons.js?v=2025010510"></script>
|
|
|
|
|
|
2025-06-14 06:02:38 +08:00
|
|
|
|
<!-- 音效管理模組 -->
|
|
|
|
|
<script src="/static/js/modules/audio/audio-manager.js?v=2025010510"></script>
|
|
|
|
|
<script src="/static/js/modules/audio/audio-settings-ui.js?v=2025010510"></script>
|
|
|
|
|
|
2025-06-13 05:48:08 +08:00
|
|
|
|
<!-- 其他模組 -->
|
2025-06-10 07:19:47 +08:00
|
|
|
|
<script src="/static/js/modules/utils.js?v=2025010510"></script>
|
|
|
|
|
<script src="/static/js/modules/tab-manager.js?v=2025010510"></script>
|
|
|
|
|
<script src="/static/js/modules/websocket-manager.js?v=2025010510"></script>
|
2025-06-13 05:48:08 +08:00
|
|
|
|
<script src="/static/js/modules/connection-monitor.js?v=2025010510"></script>
|
|
|
|
|
<script src="/static/js/modules/session-manager.js?v=2025010510"></script>
|
2025-06-13 15:20:26 +08:00
|
|
|
|
<script src="/static/js/modules/file-upload-manager.js?v=2025010510"></script>
|
2025-06-10 07:19:47 +08:00
|
|
|
|
<script src="/static/js/modules/image-handler.js?v=2025010510"></script>
|
|
|
|
|
<script src="/static/js/modules/settings-manager.js?v=2025010510"></script>
|
|
|
|
|
<script src="/static/js/modules/ui-manager.js?v=2025010510"></script>
|
2025-06-14 12:01:24 +08:00
|
|
|
|
<script src="/static/js/modules/textarea-height-manager.js?v=2025010510"></script>
|
2025-06-13 06:04:16 +08:00
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
<!-- 主應用程式 -->
|
2025-06-06 16:44:24 +08:00
|
|
|
|
<script src="/static/js/app.js?v=2025010510"></script>
|
2025-06-03 06:50:19 +08:00
|
|
|
|
<script>
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 等待所有模組載入完成後再初始化 FeedbackApp
|
2025-06-05 01:59:56 +08:00
|
|
|
|
async function initializeApp() {
|
|
|
|
|
const sessionId = '{{ session_id }}';
|
|
|
|
|
|
2025-06-15 17:29:39 +08:00
|
|
|
|
// 檢查 Markdown 依賴庫
|
|
|
|
|
if (typeof window.marked === 'undefined' || typeof window.DOMPurify === 'undefined') {
|
|
|
|
|
const logger = window.MCPFeedback?.logger || console;
|
|
|
|
|
logger.warn('Markdown 依賴庫尚未載入,等待中...');
|
|
|
|
|
setTimeout(initializeApp, 100);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-15 14:51:36 +08:00
|
|
|
|
// 檢查核心依賴
|
|
|
|
|
const requiredModules = [
|
|
|
|
|
'MCPFeedback',
|
|
|
|
|
'MCPFeedback.Logger',
|
|
|
|
|
'MCPFeedback.Utils',
|
|
|
|
|
'MCPFeedback.DOMUtils',
|
|
|
|
|
'MCPFeedback.TimeUtils',
|
|
|
|
|
'MCPFeedback.StatusUtils',
|
|
|
|
|
'MCPFeedback.ConnectionMonitor',
|
|
|
|
|
'MCPFeedback.SessionManager',
|
|
|
|
|
'MCPFeedback.FeedbackApp'
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
const missingModules = requiredModules.filter(modulePath => {
|
|
|
|
|
const parts = modulePath.split('.');
|
|
|
|
|
let current = window;
|
|
|
|
|
for (const part of parts) {
|
|
|
|
|
if (!current[part]) return true;
|
|
|
|
|
current = current[part];
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (missingModules.length > 0) {
|
|
|
|
|
const logger = window.MCPFeedback?.logger || console;
|
|
|
|
|
logger.warn('模組載入不完整,缺少:', missingModules.join(', '));
|
2025-06-10 07:19:47 +08:00
|
|
|
|
setTimeout(initializeApp, 100);
|
|
|
|
|
return;
|
2025-06-05 01:59:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
try {
|
2025-06-15 14:51:36 +08:00
|
|
|
|
const logger = window.MCPFeedback.logger;
|
|
|
|
|
logger.info('開始初始化應用程式...');
|
|
|
|
|
|
2025-06-10 07:19:47 +08:00
|
|
|
|
// 確保 I18nManager 已經初始化
|
|
|
|
|
if (window.i18nManager) {
|
2025-06-15 14:51:36 +08:00
|
|
|
|
logger.debug('初始化國際化管理器...');
|
2025-06-10 07:19:47 +08:00
|
|
|
|
await window.i18nManager.init();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 初始化 FeedbackApp(使用新的命名空間)
|
2025-06-15 14:51:36 +08:00
|
|
|
|
logger.debug('創建 FeedbackApp 實例...');
|
2025-06-10 07:19:47 +08:00
|
|
|
|
window.feedbackApp = new window.MCPFeedback.FeedbackApp(sessionId);
|
|
|
|
|
|
|
|
|
|
// 初始化應用程式
|
2025-06-15 14:51:36 +08:00
|
|
|
|
logger.debug('初始化 FeedbackApp...');
|
2025-06-10 07:19:47 +08:00
|
|
|
|
await window.feedbackApp.init();
|
|
|
|
|
|
2025-06-13 05:48:08 +08:00
|
|
|
|
// 設置全域引用,讓 SessionManager 可以被 HTML 中的 onclick 調用
|
|
|
|
|
if (window.feedbackApp.sessionManager) {
|
|
|
|
|
window.MCPFeedback.app = window.feedbackApp;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-15 17:29:39 +08:00
|
|
|
|
// 初始化完成後,立即渲染現有的 AI 摘要內容為 Markdown
|
|
|
|
|
setTimeout(function() {
|
|
|
|
|
if (window.feedbackApp && window.feedbackApp.uiManager) {
|
|
|
|
|
// 獲取當前的摘要內容
|
|
|
|
|
const summaryElement = document.querySelector('#combinedSummaryContent');
|
|
|
|
|
const summaryTabElement = document.querySelector('#summaryContent');
|
|
|
|
|
|
|
|
|
|
if (summaryElement && summaryElement.textContent) {
|
|
|
|
|
console.log('🔧 初始化時渲染 Markdown 內容...');
|
|
|
|
|
window.feedbackApp.uiManager.updateAISummaryContent(summaryElement.textContent);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}, 100);
|
|
|
|
|
|
2025-06-15 14:51:36 +08:00
|
|
|
|
logger.info('應用程式初始化完成');
|
2025-06-10 07:19:47 +08:00
|
|
|
|
} catch (error) {
|
2025-06-15 14:51:36 +08:00
|
|
|
|
const logger = window.MCPFeedback?.logger || console;
|
|
|
|
|
logger.error('應用程式初始化失敗:', error);
|
2025-06-10 07:19:47 +08:00
|
|
|
|
}
|
2025-06-05 01:59:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 頁面載入完成後初始化
|
|
|
|
|
if (document.readyState === 'loading') {
|
|
|
|
|
document.addEventListener('DOMContentLoaded', initializeApp);
|
|
|
|
|
} else {
|
|
|
|
|
initializeApp();
|
|
|
|
|
}
|
2025-06-03 06:50:19 +08:00
|
|
|
|
</script>
|
|
|
|
|
</body>
|
2025-06-11 03:25:08 +08:00
|
|
|
|
</html>
|