feat(web): add markdown syntax highlighting, slash commands, stop button, quote/reply

- PromptEditor with Prism.js syntax highlighting
- Slash commands (/run, /status, /images, /list, /help) in chat input
- Stop button to cancel ongoing generation
- Quote/reply and regenerate/continue actions in chat
- MiddlePanel with conversation timestamps and preview
- Pipeline progress in chat view
- Fix all remaining dark theme classes

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-07 04:09:00 +08:00
parent f43a640e64
commit e850613972
12 changed files with 375 additions and 213 deletions

View File

@@ -9,21 +9,11 @@ class ChatSocket {
const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
const url = `${protocol}//${location.host}/ws`;
this.ws = new WebSocket(url);
this.ws.onopen = () => {
this.emit('connected', {});
};
this.ws.onopen = () => { this.emit('connected', {}); };
this.ws.onmessage = (event) => {
try {
const { type, data } = JSON.parse(event.data);
this.emit(type, data);
} catch {}
};
this.ws.onclose = () => {
this.reconnectTimer = setTimeout(() => this.connect(), 3000);
try { const { type, data } = JSON.parse(event.data); this.emit(type, data); } catch {}
};
this.ws.onclose = () => { this.reconnectTimer = setTimeout(() => this.connect(), 3000); };
}
on(type: string, handler: MessageHandler) {
@@ -42,6 +32,8 @@ class ChatSocket {
}
}
stop() { this.send('stop'); }
private emit(type: string, data: Record<string, unknown>) {
(this.handlers.get(type) || []).forEach((h) => h(data));
}