-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
207 lines (193 loc) · 13.6 KB
/
Copy pathindex.html
File metadata and controls
207 lines (193 loc) · 13.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
<!DOCTYPE html>
<html lang="zh-CN" class="h-full">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" href="https://github.githubassets.com/favicons/favicon.svg">
<title data-i18n="title">Opencode Chat WebUI</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
<style>
body { font-family: "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; }
.glass { backdrop-filter: blur(10px); background: rgba(255,255,255,0.7); }
.card { border: 1px solid rgba(0,0,0,0.06); box-shadow: 0 10px 35px rgba(15,23,42,0.08); }
.scrollbar-thin::-webkit-scrollbar { width: 6px; }
.scrollbar-thin::-webkit-scrollbar-thumb { background: rgba(100,116,139,0.6); border-radius: 999px; }
.avatar { width: 40px; height: 40px; border-radius: 9999px; display: inline-flex; align-items: center; justify-content: center; font-weight: 600; color: white; overflow: hidden; background-size: cover; background-position: center; flex-shrink: 0; }
.avatar img { width: 100%; height: 100%; object-fit: cover; }
.prose p { margin-bottom: 0.5em; }
.prose p:last-child { margin-bottom: 0; }
.prose pre { background: #1e293b; color: #e2e8f0; padding: 0.75rem; border-radius: 0.5rem; overflow-x: auto; margin: 0.5rem 0; }
.prose code { font-family: monospace; background: rgba(0,0,0,0.05); padding: 0.1em 0.3em; border-radius: 0.25em; font-size: 0.9em; }
.prose pre code { background: transparent; padding: 0; color: inherit; font-size: 0.85em; }
.prose ul { list-style-type: disc; padding-left: 1.2em; margin-bottom: 0.5em; }
.prose ol { list-style-type: decimal; padding-left: 1.2em; margin-bottom: 0.5em; }
.prose a { color: #2563eb; text-decoration: underline; }
.prose blockquote { border-left: 3px solid #cbd5e1; padding-left: 1em; color: #64748b; font-style: italic; }
.prose h1, .prose h2, .prose h3 { font-weight: 600; margin-top: 1em; margin-bottom: 0.5em; color: #1e293b; }
.prose h1 { font-size: 1.25em; }
.prose h2 { font-size: 1.1em; }
</style>
</head>
<body class="h-screen flex flex-col bg-gradient-to-br from-slate-50 via-white to-slate-100 text-slate-900 overflow-hidden">
<div class="h-full flex flex-col">
<header class="flex-none px-6 py-4 flex items-center justify-between glass z-20 shadow-sm">
<a href="https://github.com/Darkstarrd-dev" target="_blank" class="flex items-center gap-3 hover:opacity-80 transition-opacity text-inherit no-underline">
<div class="w-10 h-10 rounded-2xl bg-slate-900 text-white flex items-center justify-center font-semibold shadow-lg">OC</div>
<div>
<div class="text-xl font-semibold" data-i18n="title">Opencode Chat WebUI</div>
<div class="text-sm text-slate-500" data-i18n="subtitle">by darkstarrd</div>
</div>
</a>
<div class="flex items-center gap-3 text-sm text-slate-600 flex-wrap justify-end">
<input id="baseUrlInput" class="px-2 py-1 rounded-lg bg-white border border-slate-200 w-48" value="http://127.0.0.1:4096" placeholder="Server URL" />
<button id="helpBtn" class="px-3 py-2 rounded-lg bg-slate-100 text-slate-700 text-sm font-medium hover:bg-slate-200" data-i18n="help">说明</button>
<button id="toggleDebugBtn" class="px-3 py-2 rounded-lg bg-slate-100 text-slate-700 text-sm font-medium hover:bg-slate-200" data-i18n="debug">调试</button>
<select id="langSelect" class="px-2 py-1 rounded-lg bg-white border border-slate-200 text-xs cursor-pointer focus:outline-none focus:ring-1 focus:ring-slate-300">
<option value="zh">中文</option>
<option value="en">English</option>
<option value="ja">日本語</option>
</select>
<button id="connectBtn" class="px-3 py-2 rounded-lg bg-slate-900 text-white text-sm font-medium shadow hover:bg-slate-800" data-i18n="connect">连接</button>
<div class="hidden md:flex items-center gap-2 px-3 py-2 rounded-full bg-white/70 card">
<span class="h-2 w-2 rounded-full bg-amber-500 animate-pulse" id="statusDot"></span>
<span id="statusText" data-i18n="status_disconnected">未接后端 · 演示模式</span>
</div>
</div>
</header>
<main class="flex-1 flex flex-col gap-4 px-6 pb-6 min-h-0">
<section class="flex-1 min-h-0 card bg-white rounded-2xl p-4 grid grid-cols-1 lg:grid-cols-[280px_1fr] gap-4 overflow-hidden">
<div class="flex flex-col gap-3 h-full overflow-hidden">
<div class="flex-none flex items-center justify-between">
<div class="font-semibold" data-i18n="userList">用户/Agent 列表</div>
</div>
<div id="userList" class="flex-1 overflow-y-auto scrollbar-thin space-y-2 pr-1"></div>
<div class="flex-none pt-2 border-t border-slate-200 flex flex-col gap-2">
<div id="settingsPanel" class="flex flex-col gap-2">
<div class="flex items-center justify-between">
<div class="font-semibold text-sm" data-i18n="autoControl">自动对话控制</div>
<select id="loopMode" class="text-xs bg-slate-100 border-none rounded px-1 py-0.5 outline-none focus:ring-1 focus:ring-slate-300">
<option value="count" data-i18n="mode_count">按次数</option>
<option value="time" data-i18n="mode_time">按时间</option>
</select>
</div>
<div class="flex items-center gap-2 text-xs text-slate-500" id="controlInputs">
<div class="flex items-center gap-1 flex-1">
<label id="inputLabelA" data-i18n="label_count">次数</label>
<input id="loopValue" class="w-full px-2 py-1 rounded-lg border border-slate-200 text-center" value="4" />
</div>
<div class="flex items-center gap-1 flex-1" id="varianceContainer">
<label data-i18n="variance">±波动</label>
<input id="loopVariance" class="w-full px-2 py-1 rounded-lg border border-slate-200 text-center" value="1" />
</div>
</div>
<div class="flex items-center gap-2 text-xs text-slate-500 mt-1">
<div class="flex items-center gap-1 flex-1">
<label data-i18n="cooldown">冷却(s)</label>
<input id="coolDownBase" class="w-full px-2 py-1 rounded-lg border border-slate-200 text-center" value="2" />
</div>
<div class="flex items-center gap-1 flex-1">
<label data-i18n="variance">±波动</label>
<input id="coolDownVar" class="w-full px-2 py-1 rounded-lg border border-slate-200 text-center" value="1" />
</div>
</div>
<div class="flex gap-2 mt-1">
<input id="agentAddInput" class="flex-1 px-2 py-1 rounded-lg border border-slate-200 text-sm" placeholder="新增 User/Agent" data-i18n-placeholder="add_placeholder" />
<button id="agentAddBtn" class="px-3 py-1 rounded-lg bg-slate-900 text-white text-xs" data-i18n="btn_add">添加</button>
</div>
<button id="resetBtn" class="w-full px-3 py-2 rounded-lg border border-rose-200 text-sm text-rose-600 hover:bg-rose-50 mt-2" data-i18n="btn_reset">重置会话</button>
<button id="exportBtn" class="w-full px-3 py-2 rounded-lg border border-indigo-200 text-sm text-indigo-600 hover:bg-indigo-50 mt-2" data-i18n="btn_export">导出对话</button>
</div>
<button id="stopBtn" class="hidden w-full px-3 py-3 rounded-lg bg-rose-500 text-white text-sm font-medium shadow-md hover:bg-rose-600 transition-colors" data-i18n="btn_stop">停止聊天</button>
</div>
</div>
<div class="flex flex-col h-full min-h-0 overflow-hidden">
<div class="flex-none flex items-center justify-between mb-3" id="chatHeaderControls">
<div>
<div class="text-lg font-semibold" id="chatTitle" data-i18n="chatTitle">共享对话</div>
<div class="text-xs text-slate-500" data-i18n="chatSubtitle">所有用户共享同一条对话流;各自输入框独立</div>
</div>
<div class="flex gap-2 text-sm flex-wrap items-center">
<select id="agentSelect" class="px-2 py-1 rounded-lg bg-slate-100 min-w-[140px]">
<option value="build">build</option>
<option value="general">general</option>
<option value="plan">plan</option>
<option value="custom">custom</option>
</select>
<select id="modelSelect" class="px-2 py-1 rounded-lg bg-slate-100 min-w-[200px]">
<option value="opencode/default">opencode/default</option>
</select>
<button id="favAddBtn" class="px-2 py-1 rounded-lg border border-slate-200 text-slate-700 hover:border-slate-400" data-i18n="fav_current">⭐ 收藏当前</button>
<select id="favSelect" class="px-2 py-1 rounded-lg bg-slate-100 min-w-[180px]">
<option value="" data-i18n="fav_select">选择收藏</option>
</select>
</div>
</div>
<div id="messages" class="flex-1 bg-slate-50 rounded-xl p-4 overflow-y-auto scrollbar-thin space-y-4 text-sm mb-3">
<div class="text-slate-400" data-i18n="msg_demo">演示消息:未连接后端。</div>
</div>
<div class="flex-none flex gap-2">
<input id="chatInput" class="flex-1 px-3 py-2 rounded-xl border border-slate-200 focus:outline-none focus:ring-2 focus:ring-slate-300" placeholder="输入消息(占位,不会发送)" data-i18n-placeholder="input_placeholder" />
<button id="sendBtn" class="px-4 py-2 rounded-xl bg-slate-900 text-white text-sm font-medium" data-i18n="btn_send">发送</button>
</div>
</div>
</section>
</main>
</div>
<div id="debugPanel" class="fixed bottom-0 left-0 right-0 h-64 bg-white border-t border-slate-200 shadow-[0_-4px_20px_rgba(0,0,0,0.1)] transition-transform duration-300 transform translate-y-full z-30 flex flex-col">
<div class="flex-none flex items-center justify-between px-4 py-2 bg-slate-50 border-b border-slate-200">
<div class="font-semibold text-sm flex items-center gap-2">
<span class="w-2 h-2 rounded-full bg-emerald-500"></span>
<span data-i18n="debug_title">调试 & 事件面板</span>
</div>
<div class="flex gap-3">
<button id="clearLog" class="text-xs text-slate-500 hover:text-slate-800 px-2 py-1 rounded hover:bg-slate-200 transition-colors" data-i18n="btn_clear">清空日志</button>
<button id="closeDebugBtn" class="text-slate-400 hover:text-slate-800 text-lg leading-none">×</button>
</div>
</div>
<div id="log" class="flex-1 overflow-y-auto scrollbar-thin text-xs text-slate-600 p-3 font-mono space-y-1 bg-white"></div>
</div>
<div id="editModal" class="fixed inset-0 z-50 hidden flex items-center justify-center bg-black/50 backdrop-blur-sm">
<div class="bg-white rounded-2xl p-6 w-full max-w-md shadow-2xl">
<h3 class="text-lg font-bold mb-4" data-i18n="edit_title">编辑信息</h3>
<div class="space-y-4">
<div>
<label class="block text-xs text-slate-500 mb-1" data-i18n="label_name">名称</label>
<input id="editNameInput" class="w-full px-3 py-2 rounded-lg border border-slate-200" />
</div>
<div>
<label class="block text-xs text-slate-500 mb-1" data-i18n="label_avatar">头像</label>
<div class="flex items-center gap-4">
<div id="editAvatarPreview" class="avatar w-16 h-16 text-2xl"></div>
<label class="px-3 py-2 rounded-lg bg-slate-100 text-slate-600 text-sm cursor-pointer hover:bg-slate-200" data-i18n="btn_upload">
上传图片
<input type="file" id="editAvatarFile" class="hidden" accept="image/*" />
</label>
<button id="editAvatarClear" class="text-xs text-red-500 hover:underline" data-i18n="btn_clear_img">清除</button>
</div>
</div>
</div>
<div class="mt-6 flex justify-end gap-2">
<button id="editCancelBtn" class="px-4 py-2 rounded-lg border border-slate-200 text-slate-600 hover:bg-slate-50" data-i18n="btn_cancel">取消</button>
<button id="editSaveBtn" class="px-4 py-2 rounded-lg bg-slate-900 text-white font-medium hover:bg-slate-800" data-i18n="btn_save">保存</button>
</div>
</div>
</div>
<div id="helpModal" class="fixed inset-0 z-50 hidden flex items-center justify-center bg-black/50 backdrop-blur-sm">
<div class="bg-white rounded-2xl p-6 w-full max-w-2xl shadow-2xl max-h-[90vh] overflow-y-auto">
<div class="flex justify-between items-center mb-4">
<h3 class="text-xl font-bold" data-i18n="help_title">使用说明</h3>
<button id="helpCloseBtn" class="text-slate-400 hover:text-slate-600 text-2xl">×</button>
</div>
<div id="helpContent" class="prose prose-sm max-w-none text-slate-600">
</div>
<div class="mt-6 flex justify-end">
<button id="helpOkBtn" class="px-6 py-2 rounded-lg bg-slate-900 text-white font-medium hover:bg-slate-800" data-i18n="help_ok">明白了</button>
</div>
</div>
</div>
<script type="module" src="src/app.js"></script>
</body>
</html>