@talk2view/sdk 0.3.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client.d.ts +1 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +4 -4
- package/dist/client.js.map +1 -1
- package/dist/event-emitter.d.ts +7 -0
- package/dist/event-emitter.d.ts.map +1 -0
- package/dist/event-emitter.js +23 -0
- package/dist/event-emitter.js.map +1 -0
- package/dist/index.d.ts +78 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +312 -6
- package/dist/index.js.map +1 -1
- package/dist/react/T2VProvider.js +1 -1
- package/dist/react/T2VProvider.js.map +1 -1
- package/dist/react/index.d.ts +2 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/useT2VChat.d.ts +6 -22
- package/dist/react/useT2VChat.d.ts.map +1 -1
- package/dist/react/useT2VChat.js +34 -218
- package/dist/react/useT2VChat.js.map +1 -1
- package/dist/sessions.d.ts.map +1 -1
- package/dist/sessions.js +3 -0
- package/dist/sessions.js.map +1 -1
- package/dist/tools.d.ts +5 -0
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +16 -2
- package/dist/tools.js.map +1 -1
- package/dist/types.d.ts +45 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/components/ApprovalCard.d.ts +10 -0
- package/dist/ui/components/ApprovalCard.d.ts.map +1 -0
- package/dist/ui/components/ApprovalCard.js +60 -0
- package/dist/ui/components/ApprovalCard.js.map +1 -0
- package/dist/ui/components/{T2VChatHeader.d.ts → ChatHeader.d.ts} +4 -4
- package/dist/ui/components/ChatHeader.d.ts.map +1 -0
- package/dist/ui/components/ChatHeader.js +126 -0
- package/dist/ui/components/ChatHeader.js.map +1 -0
- package/dist/ui/components/ChatPanel.d.ts +9 -0
- package/dist/ui/components/ChatPanel.d.ts.map +1 -0
- package/dist/ui/components/ChatPanel.js +37 -0
- package/dist/ui/components/ChatPanel.js.map +1 -0
- package/dist/ui/components/ChatWidget.d.ts +5 -0
- package/dist/ui/components/ChatWidget.d.ts.map +1 -0
- package/dist/ui/components/ChatWidget.js +27 -0
- package/dist/ui/components/ChatWidget.js.map +1 -0
- package/dist/ui/components/CodeBlock.d.ts +6 -0
- package/dist/ui/components/CodeBlock.d.ts.map +1 -0
- package/dist/ui/components/CodeBlock.js +79 -0
- package/dist/ui/components/CodeBlock.js.map +1 -0
- package/dist/ui/components/Composer.d.ts +14 -0
- package/dist/ui/components/Composer.d.ts.map +1 -0
- package/dist/ui/components/Composer.js +172 -0
- package/dist/ui/components/Composer.js.map +1 -0
- package/dist/ui/components/LoginForm.d.ts +5 -0
- package/dist/ui/components/LoginForm.d.ts.map +1 -0
- package/dist/ui/components/LoginForm.js +37 -0
- package/dist/ui/components/LoginForm.js.map +1 -0
- package/dist/ui/components/MarkdownRenderer.d.ts +5 -0
- package/dist/ui/components/MarkdownRenderer.d.ts.map +1 -0
- package/dist/ui/components/MarkdownRenderer.js +28 -0
- package/dist/ui/components/MarkdownRenderer.js.map +1 -0
- package/dist/ui/components/MessageActions.d.ts +6 -0
- package/dist/ui/components/MessageActions.d.ts.map +1 -0
- package/dist/ui/components/MessageActions.js +43 -0
- package/dist/ui/components/MessageActions.js.map +1 -0
- package/dist/ui/components/MessageBubble.d.ts +16 -0
- package/dist/ui/components/MessageBubble.d.ts.map +1 -0
- package/dist/ui/components/MessageBubble.js +71 -0
- package/dist/ui/components/MessageBubble.js.map +1 -0
- package/dist/ui/components/MessageList.d.ts +10 -0
- package/dist/ui/components/MessageList.d.ts.map +1 -0
- package/dist/ui/components/MessageList.js +69 -0
- package/dist/ui/components/MessageList.js.map +1 -0
- package/dist/ui/components/SettingsPanel.d.ts +11 -0
- package/dist/ui/components/SettingsPanel.d.ts.map +1 -0
- package/dist/ui/components/{SettingsView.js → SettingsPanel.js} +27 -27
- package/dist/ui/components/SettingsPanel.js.map +1 -0
- package/dist/ui/components/Shimmer.d.ts +2 -0
- package/dist/ui/components/Shimmer.d.ts.map +1 -0
- package/dist/ui/components/Shimmer.js +10 -0
- package/dist/ui/components/Shimmer.js.map +1 -0
- package/dist/ui/components/Talk2View.d.ts +21 -0
- package/dist/ui/components/Talk2View.d.ts.map +1 -0
- package/dist/ui/components/Talk2View.js +79 -0
- package/dist/ui/components/Talk2View.js.map +1 -0
- package/dist/ui/components/ThinkingBlock.d.ts +7 -0
- package/dist/ui/components/ThinkingBlock.d.ts.map +1 -0
- package/dist/ui/components/ThinkingBlock.js +64 -0
- package/dist/ui/components/ThinkingBlock.js.map +1 -0
- package/dist/ui/components/ToolDisplay.d.ts +28 -0
- package/dist/ui/components/ToolDisplay.d.ts.map +1 -0
- package/dist/ui/components/ToolDisplay.js +123 -0
- package/dist/ui/components/ToolDisplay.js.map +1 -0
- package/dist/ui/components/WelcomeScreen.d.ts +6 -0
- package/dist/ui/components/WelcomeScreen.d.ts.map +1 -0
- package/dist/ui/components/WelcomeScreen.js +18 -0
- package/dist/ui/components/WelcomeScreen.js.map +1 -0
- package/dist/ui/context.d.ts +29 -0
- package/dist/ui/context.d.ts.map +1 -0
- package/dist/ui/context.js +16 -0
- package/dist/ui/context.js.map +1 -0
- package/dist/ui/index.d.ts +24 -37
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +23 -35
- package/dist/ui/index.js.map +1 -1
- package/dist/ui/styles.d.ts +2 -0
- package/dist/ui/styles.d.ts.map +1 -0
- package/dist/ui/styles.js +91 -0
- package/dist/ui/styles.js.map +1 -0
- package/dist/ui/theme.d.ts +11 -0
- package/dist/ui/theme.d.ts.map +1 -0
- package/dist/ui/theme.js +70 -0
- package/dist/ui/theme.js.map +1 -0
- package/package.json +5 -10
- package/dist/ui/components/LoginModal.d.ts +0 -10
- package/dist/ui/components/LoginModal.d.ts.map +0 -1
- package/dist/ui/components/LoginModal.js +0 -138
- package/dist/ui/components/LoginModal.js.map +0 -1
- package/dist/ui/components/SettingsView.d.ts +0 -11
- package/dist/ui/components/SettingsView.d.ts.map +0 -1
- package/dist/ui/components/SettingsView.js.map +0 -1
- package/dist/ui/components/T2VAssistantModal.d.ts +0 -31
- package/dist/ui/components/T2VAssistantModal.d.ts.map +0 -1
- package/dist/ui/components/T2VAssistantModal.js +0 -151
- package/dist/ui/components/T2VAssistantModal.js.map +0 -1
- package/dist/ui/components/T2VAssistantProvider.d.ts +0 -42
- package/dist/ui/components/T2VAssistantProvider.d.ts.map +0 -1
- package/dist/ui/components/T2VAssistantProvider.js +0 -66
- package/dist/ui/components/T2VAssistantProvider.js.map +0 -1
- package/dist/ui/components/T2VChatHeader.d.ts.map +0 -1
- package/dist/ui/components/T2VChatHeader.js +0 -112
- package/dist/ui/components/T2VChatHeader.js.map +0 -1
- package/dist/ui/components/T2VComposer.d.ts +0 -11
- package/dist/ui/components/T2VComposer.d.ts.map +0 -1
- package/dist/ui/components/T2VComposer.js +0 -124
- package/dist/ui/components/T2VComposer.js.map +0 -1
- package/dist/ui/components/T2VDictationAdapter.d.ts +0 -18
- package/dist/ui/components/T2VDictationAdapter.d.ts.map +0 -1
- package/dist/ui/components/T2VDictationAdapter.js +0 -126
- package/dist/ui/components/T2VDictationAdapter.js.map +0 -1
- package/dist/ui/components/T2VLoginGate.d.ts +0 -23
- package/dist/ui/components/T2VLoginGate.d.ts.map +0 -1
- package/dist/ui/components/T2VLoginGate.js +0 -11
- package/dist/ui/components/T2VLoginGate.js.map +0 -1
- package/dist/ui/components/T2VThread.d.ts +0 -25
- package/dist/ui/components/T2VThread.d.ts.map +0 -1
- package/dist/ui/components/T2VThread.js +0 -66
- package/dist/ui/components/T2VThread.js.map +0 -1
- package/dist/ui/components/T2VToolFallback.d.ts +0 -11
- package/dist/ui/components/T2VToolFallback.d.ts.map +0 -1
- package/dist/ui/components/T2VToolFallback.js +0 -209
- package/dist/ui/components/T2VToolFallback.js.map +0 -1
- package/dist/ui/runtime/convertMessage.d.ts +0 -17
- package/dist/ui/runtime/convertMessage.d.ts.map +0 -1
- package/dist/ui/runtime/convertMessage.js +0 -77
- package/dist/ui/runtime/convertMessage.js.map +0 -1
- package/dist/ui/runtime/useT2VRuntime.d.ts +0 -42
- package/dist/ui/runtime/useT2VRuntime.d.ts.map +0 -1
- package/dist/ui/runtime/useT2VRuntime.js +0 -62
- package/dist/ui/runtime/useT2VRuntime.js.map +0 -1
- package/dist/ui/themes/tailwind-preset.d.ts +0 -43
- package/dist/ui/themes/tailwind-preset.d.ts.map +0 -1
- package/dist/ui/themes/tailwind-preset.js +0 -43
- package/dist/ui/themes/tailwind-preset.js.map +0 -1
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Composer — text input + mic button for sending messages.
|
|
4
|
+
*
|
|
5
|
+
* - Auto-resizing textarea (min 1 row, max ~120px).
|
|
6
|
+
* - Send on Enter, Shift+Enter inserts newline.
|
|
7
|
+
* - Disabled while loading.
|
|
8
|
+
* - Mic button records audio via MediaRecorder, sends to t2v.transcribe(),
|
|
9
|
+
* and inserts the transcript into the textarea.
|
|
10
|
+
* - Prefers audio/webm;codecs=opus, falls back to audio/webm.
|
|
11
|
+
* - STT model/language from useUserPreferences + usePartnerConfig.
|
|
12
|
+
* - Send button uses accent color when text is present, border color when empty.
|
|
13
|
+
*/
|
|
14
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
15
|
+
import { Mic, Send, Square, Loader2 } from 'lucide-react';
|
|
16
|
+
import { useChat } from '../context';
|
|
17
|
+
import { useTalk2View } from '../context';
|
|
18
|
+
import { useUserPreferences } from '../../react/useUserPreferences';
|
|
19
|
+
import { usePartnerConfig } from '../../react/usePartnerConfig';
|
|
20
|
+
export function Composer() {
|
|
21
|
+
const { sendMessage, isLoading } = useChat();
|
|
22
|
+
const { t2v } = useTalk2View();
|
|
23
|
+
const { preferences } = useUserPreferences();
|
|
24
|
+
const { config: partnerConfig } = usePartnerConfig();
|
|
25
|
+
const [text, setText] = useState('');
|
|
26
|
+
const [isRecording, setIsRecording] = useState(false);
|
|
27
|
+
const [isTranscribing, setIsTranscribing] = useState(false);
|
|
28
|
+
const textareaRef = useRef(null);
|
|
29
|
+
const mediaRecorderRef = useRef(null);
|
|
30
|
+
const chunksRef = useRef([]);
|
|
31
|
+
// Auto-resize textarea
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
const el = textareaRef.current;
|
|
34
|
+
if (!el)
|
|
35
|
+
return;
|
|
36
|
+
el.style.height = 'auto';
|
|
37
|
+
el.style.height = `${Math.min(el.scrollHeight, 120)}px`;
|
|
38
|
+
}, [text]);
|
|
39
|
+
const handleSend = useCallback(() => {
|
|
40
|
+
const trimmed = text.trim();
|
|
41
|
+
if (!trimmed || isLoading)
|
|
42
|
+
return;
|
|
43
|
+
setText('');
|
|
44
|
+
sendMessage(trimmed).catch(console.error);
|
|
45
|
+
}, [text, isLoading, sendMessage]);
|
|
46
|
+
const handleKeyDown = useCallback((e) => {
|
|
47
|
+
if (e.key === 'Enter' && !e.shiftKey) {
|
|
48
|
+
e.preventDefault();
|
|
49
|
+
handleSend();
|
|
50
|
+
}
|
|
51
|
+
}, [handleSend]);
|
|
52
|
+
const handleMic = useCallback(async () => {
|
|
53
|
+
if (isRecording) {
|
|
54
|
+
if (mediaRecorderRef.current?.state === 'recording') {
|
|
55
|
+
mediaRecorderRef.current.stop();
|
|
56
|
+
}
|
|
57
|
+
setIsRecording(false);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
62
|
+
const mimeType = MediaRecorder.isTypeSupported('audio/webm;codecs=opus')
|
|
63
|
+
? 'audio/webm;codecs=opus'
|
|
64
|
+
: 'audio/webm';
|
|
65
|
+
const recorder = new MediaRecorder(stream, { mimeType });
|
|
66
|
+
mediaRecorderRef.current = recorder;
|
|
67
|
+
chunksRef.current = [];
|
|
68
|
+
recorder.ondataavailable = (e) => {
|
|
69
|
+
if (e.data.size > 0)
|
|
70
|
+
chunksRef.current.push(e.data);
|
|
71
|
+
};
|
|
72
|
+
recorder.onstop = async () => {
|
|
73
|
+
stream.getTracks().forEach((t) => t.stop());
|
|
74
|
+
const chunks = chunksRef.current;
|
|
75
|
+
if (chunks.length === 0)
|
|
76
|
+
return;
|
|
77
|
+
setIsTranscribing(true);
|
|
78
|
+
try {
|
|
79
|
+
const blob = new Blob(chunks, { type: mimeType });
|
|
80
|
+
const formData = new FormData();
|
|
81
|
+
formData.append('file', blob, 'recording.webm');
|
|
82
|
+
const sttModel = preferences.sttModel ||
|
|
83
|
+
partnerConfig?.default_stt_model ||
|
|
84
|
+
'faster-whisper-base';
|
|
85
|
+
const sttLanguage = preferences.sttLanguage;
|
|
86
|
+
formData.append('model', sttModel);
|
|
87
|
+
if (sttLanguage)
|
|
88
|
+
formData.append('language', sttLanguage);
|
|
89
|
+
const result = await t2v.transcribe(formData);
|
|
90
|
+
const transcript = result.text.trim();
|
|
91
|
+
if (transcript) {
|
|
92
|
+
setText((prev) => (prev ? `${prev} ${transcript}` : transcript));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch (err) {
|
|
96
|
+
console.error('Transcription failed:', err);
|
|
97
|
+
}
|
|
98
|
+
finally {
|
|
99
|
+
setIsTranscribing(false);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
recorder.start();
|
|
103
|
+
setIsRecording(true);
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
console.error('Microphone access denied:', err);
|
|
107
|
+
}
|
|
108
|
+
}, [isRecording, t2v, preferences.sttModel, preferences.sttLanguage, partnerConfig?.default_stt_model]);
|
|
109
|
+
const hasText = text.trim().length > 0;
|
|
110
|
+
return (_jsxs("div", { style: {
|
|
111
|
+
display: 'flex',
|
|
112
|
+
alignItems: 'flex-end',
|
|
113
|
+
gap: '6px',
|
|
114
|
+
padding: '10px 12px',
|
|
115
|
+
borderTop: '1px solid var(--t2v-border)',
|
|
116
|
+
background: 'var(--t2v-bg)',
|
|
117
|
+
fontFamily: 'var(--t2v-font)',
|
|
118
|
+
}, children: [_jsx("textarea", { ref: textareaRef, value: text, onChange: (e) => setText(e.target.value), onKeyDown: handleKeyDown, disabled: isLoading, placeholder: "Type a message\u2026", rows: 1, style: {
|
|
119
|
+
flex: 1,
|
|
120
|
+
resize: 'none',
|
|
121
|
+
border: '1px solid var(--t2v-border)',
|
|
122
|
+
borderRadius: 'calc(var(--t2v-radius) * 0.75px)',
|
|
123
|
+
padding: '8px 10px',
|
|
124
|
+
fontSize: '14px',
|
|
125
|
+
lineHeight: 1.5,
|
|
126
|
+
fontFamily: 'var(--t2v-font)',
|
|
127
|
+
color: 'var(--t2v-foreground)',
|
|
128
|
+
background: 'var(--t2v-bg)',
|
|
129
|
+
outline: 'none',
|
|
130
|
+
minHeight: '36px',
|
|
131
|
+
maxHeight: '120px',
|
|
132
|
+
overflowY: 'auto',
|
|
133
|
+
transition: 'border-color 0.15s',
|
|
134
|
+
}, onFocus: (e) => {
|
|
135
|
+
e.currentTarget.style.borderColor = 'var(--t2v-accent)';
|
|
136
|
+
}, onBlur: (e) => {
|
|
137
|
+
e.currentTarget.style.borderColor = 'var(--t2v-border)';
|
|
138
|
+
} }), _jsx("button", { type: "button", onClick: () => { handleMic().catch(console.error); }, disabled: isTranscribing, "aria-label": isTranscribing
|
|
139
|
+
? 'Transcribing…'
|
|
140
|
+
: isRecording
|
|
141
|
+
? 'Stop recording'
|
|
142
|
+
: 'Voice input', style: {
|
|
143
|
+
width: '36px',
|
|
144
|
+
height: '36px',
|
|
145
|
+
flexShrink: 0,
|
|
146
|
+
borderRadius: 'calc(var(--t2v-radius) * 0.75px)',
|
|
147
|
+
border: 'none',
|
|
148
|
+
background: isRecording ? 'var(--t2v-error)' : 'var(--t2v-accent)',
|
|
149
|
+
color: 'var(--t2v-accent-foreground)',
|
|
150
|
+
cursor: isTranscribing ? 'wait' : 'pointer',
|
|
151
|
+
opacity: isTranscribing ? 0.6 : 1,
|
|
152
|
+
transition: 'background 0.15s, opacity 0.15s',
|
|
153
|
+
display: 'flex',
|
|
154
|
+
alignItems: 'center',
|
|
155
|
+
justifyContent: 'center',
|
|
156
|
+
}, children: isTranscribing ? _jsx(Loader2, { size: 16, style: { animation: 't2v-spin 0.8s linear infinite' } }) : isRecording ? _jsx(Square, { size: 16 }) : _jsx(Mic, { size: 16 }) }), _jsx("button", { type: "button", onClick: handleSend, disabled: isLoading || !hasText, "aria-label": "Send message", style: {
|
|
157
|
+
width: '36px',
|
|
158
|
+
height: '36px',
|
|
159
|
+
flexShrink: 0,
|
|
160
|
+
borderRadius: 'calc(var(--t2v-radius) * 0.75px)',
|
|
161
|
+
border: hasText ? 'none' : '1px solid var(--t2v-border)',
|
|
162
|
+
background: hasText ? 'var(--t2v-accent)' : 'transparent',
|
|
163
|
+
color: hasText ? 'var(--t2v-accent-foreground)' : 'var(--t2v-muted)',
|
|
164
|
+
cursor: hasText && !isLoading ? 'pointer' : 'default',
|
|
165
|
+
opacity: isLoading ? 0.5 : 1,
|
|
166
|
+
transition: 'background 0.15s, border 0.15s, color 0.15s, opacity 0.15s',
|
|
167
|
+
display: 'flex',
|
|
168
|
+
alignItems: 'center',
|
|
169
|
+
justifyContent: 'center',
|
|
170
|
+
}, children: _jsx(Send, { size: 16 }) })] }));
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=Composer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Composer.js","sourceRoot":"","sources":["../../../src/ui/components/Composer.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LoginForm.d.ts","sourceRoot":"","sources":["../../../src/ui/components/LoginForm.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,SAAS,CAAC,EAAE,SAAS,EAAE,EAAE,cAAc,2CAgEtD"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { useT2VAuth } from '../../react/useT2VAuth';
|
|
4
|
+
import { LOGOS } from '../theme';
|
|
5
|
+
export function LoginForm({ signupUrl }) {
|
|
6
|
+
const { login, isLoading, error, clearError } = useT2VAuth();
|
|
7
|
+
const [email, setEmail] = useState('');
|
|
8
|
+
const [password, setPassword] = useState('');
|
|
9
|
+
const handleSubmit = async (e) => {
|
|
10
|
+
e.preventDefault();
|
|
11
|
+
if (!email || !password || isLoading)
|
|
12
|
+
return;
|
|
13
|
+
try {
|
|
14
|
+
await login(email, password);
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
// useT2VAuth already surfaces the message via the `error` state; swallow
|
|
18
|
+
// the rejection here so the dev overlay doesn't flag it as uncaught.
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const inputStyle = {
|
|
22
|
+
width: '100%', padding: '10px 12px',
|
|
23
|
+
border: '1.5px solid var(--t2v-border)', borderRadius: 'calc(var(--t2v-radius) * 0.5px)',
|
|
24
|
+
fontFamily: 'var(--t2v-font)', fontSize: '14px',
|
|
25
|
+
background: 'var(--t2v-bg)', color: 'var(--t2v-foreground)',
|
|
26
|
+
outline: 'none', transition: 'border-color 0.15s',
|
|
27
|
+
boxSizing: 'border-box',
|
|
28
|
+
};
|
|
29
|
+
return (_jsxs("div", { style: { flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', padding: '32px 24px', gap: '20px' }, children: [_jsx("img", { src: LOGOS.icon, alt: "Talk2View", style: { width: 36, height: 36 } }), _jsxs("div", { style: { textAlign: 'center' }, children: [_jsx("h2", { style: { margin: 0, fontSize: '16px', fontWeight: 600, fontFamily: 'var(--t2v-font)' }, children: "Sign in to Talk2View" }), _jsx("p", { style: { margin: '4px 0 0', fontSize: '13px', color: 'var(--t2v-muted)' }, children: "Enter your credentials to continue" })] }), error && (_jsx("div", { style: { width: '100%', maxWidth: '280px', padding: '8px 12px', background: 'rgba(220,38,38,0.06)', border: '1px solid rgba(220,38,38,0.15)', borderRadius: '6px', fontSize: '12px', color: 'var(--t2v-error)' }, children: error })), _jsxs("form", { onSubmit: handleSubmit, style: { width: '100%', maxWidth: '280px', display: 'flex', flexDirection: 'column', gap: '10px' }, children: [_jsxs("label", { style: { display: 'flex', flexDirection: 'column', gap: '4px' }, children: [_jsx("span", { style: { fontSize: '12px', fontWeight: 500, fontFamily: 'var(--t2v-font)', color: 'var(--t2v-foreground)' }, children: "Email" }), _jsx("input", { id: "t2v-email", type: "email", placeholder: "Email", value: email, onChange: (e) => { setEmail(e.target.value); clearError(); }, className: "t2v-focusable", style: inputStyle })] }), _jsxs("label", { style: { display: 'flex', flexDirection: 'column', gap: '4px' }, children: [_jsx("span", { style: { fontSize: '12px', fontWeight: 500, fontFamily: 'var(--t2v-font)', color: 'var(--t2v-foreground)' }, children: "Password" }), _jsx("input", { id: "t2v-password", type: "password", placeholder: "Password", value: password, onChange: (e) => { setPassword(e.target.value); clearError(); }, className: "t2v-focusable", style: inputStyle })] }), _jsx("button", { type: "submit", disabled: !email || !password || isLoading, className: "t2v-btn", style: {
|
|
30
|
+
width: '100%', padding: '10px', border: 'none', borderRadius: 'calc(var(--t2v-radius) * 0.5px)',
|
|
31
|
+
background: 'var(--t2v-accent)', color: 'var(--t2v-accent-foreground)',
|
|
32
|
+
fontFamily: 'var(--t2v-font)', fontSize: '14px', fontWeight: 500,
|
|
33
|
+
cursor: isLoading ? 'wait' : 'pointer', opacity: (!email || !password || isLoading) ? 0.6 : 1,
|
|
34
|
+
transition: 'opacity 0.15s',
|
|
35
|
+
}, children: isLoading ? 'Signing in...' : 'Sign in' })] }), signupUrl && (_jsxs("p", { style: { fontSize: '12px', color: 'var(--t2v-muted)' }, children: ["Don't have an account?", ' ', _jsx("a", { href: signupUrl, target: "_blank", rel: "noopener noreferrer", style: { color: 'var(--t2v-accent)', textDecoration: 'underline' }, children: "Sign up" })] }))] }));
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=LoginForm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LoginForm.js","sourceRoot":"","sources":["../../../src/ui/components/LoginForm.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MarkdownRenderer.d.ts","sourceRoot":"","sources":["../../../src/ui/components/MarkdownRenderer.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;CACjB;AAQD,wBAAgB,gBAAgB,CAAC,EAAE,OAAO,EAAE,EAAE,qBAAqB,2CA0BlE"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo, useState, useEffect } from 'react';
|
|
3
|
+
import { Marked } from 'marked';
|
|
4
|
+
// Private instance avoids mutating the global marked singleton
|
|
5
|
+
const parser = new Marked({ gfm: true, breaks: true });
|
|
6
|
+
// Module-level cache for the DOMPurify instance (browser only)
|
|
7
|
+
let purifyInstance = null;
|
|
8
|
+
export function MarkdownRenderer({ content }) {
|
|
9
|
+
// Track whether DOMPurify has been loaded so useMemo re-runs after load
|
|
10
|
+
const [purifyReady, setPurifyReady] = useState(() => purifyInstance !== null);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (typeof window === 'undefined' || purifyInstance !== null)
|
|
13
|
+
return;
|
|
14
|
+
import('dompurify').then((mod) => {
|
|
15
|
+
purifyInstance = mod.default;
|
|
16
|
+
setPurifyReady(true);
|
|
17
|
+
}).catch(() => { });
|
|
18
|
+
}, []);
|
|
19
|
+
const html = useMemo(() => {
|
|
20
|
+
if (typeof window === 'undefined' || !purifyInstance)
|
|
21
|
+
return '';
|
|
22
|
+
const raw = parser.parse(content);
|
|
23
|
+
return purifyInstance.sanitize(raw, { ADD_ATTR: ['target'] });
|
|
24
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
25
|
+
}, [content, purifyReady]);
|
|
26
|
+
return (_jsx("div", { className: "t2v-md", dangerouslySetInnerHTML: { __html: html }, style: { fontSize: 'inherit', lineHeight: 1.55, wordBreak: 'break-word' } }));
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=MarkdownRenderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MarkdownRenderer.js","sourceRoot":"","sources":["../../../src/ui/components/MarkdownRenderer.tsx"],"names":[],"mappings":";AAAA,OAAc,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAOhC,+DAA+D;AAC/D,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;AAEvD,+DAA+D;AAC/D,IAAI,cAAc,GAAgC,IAAI,CAAC;AAEvD,MAAM,UAAU,gBAAgB,CAAC,EAAE,OAAO,EAAyB;IACjE,wEAAwE;IACxE,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,cAAc,KAAK,IAAI,CAAC,CAAC;IAE9E,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,cAAc,KAAK,IAAI;YAAE,OAAO;QACrE,MAAM,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE;YAC/B,cAAc,GAAG,GAAG,CAAC,OAAO,CAAC;YAC7B,cAAc,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACrB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE;QACxB,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,CAAC,cAAc;YAAE,OAAO,EAAE,CAAC;QAChE,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAW,CAAC;QAC5C,OAAO,cAAc,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;QAChE,uDAAuD;IACvD,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC;IAE3B,OAAO,CACL,cACE,SAAS,EAAC,QAAQ,EAClB,uBAAuB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EACzC,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,GACzE,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageActions.d.ts","sourceRoot":"","sources":["../../../src/ui/components/MessageActions.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,wBAAgB,cAAc,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,mBAAmB,2CA6DtE"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useEffect, useRef } from 'react';
|
|
3
|
+
import { Copy, Check, RefreshCw } from 'lucide-react';
|
|
4
|
+
import { useChat } from '../context';
|
|
5
|
+
export function MessageActions({ content, isLast }) {
|
|
6
|
+
const { retryLastMessage } = useChat();
|
|
7
|
+
const [copied, setCopied] = useState(false);
|
|
8
|
+
const timerRef = useRef(undefined);
|
|
9
|
+
// Clear timeout on unmount to prevent memory leak
|
|
10
|
+
useEffect(() => () => { clearTimeout(timerRef.current); }, []);
|
|
11
|
+
const handleCopy = () => {
|
|
12
|
+
navigator.clipboard.writeText(content).then(() => {
|
|
13
|
+
clearTimeout(timerRef.current);
|
|
14
|
+
setCopied(true);
|
|
15
|
+
timerRef.current = setTimeout(() => setCopied(false), 2000);
|
|
16
|
+
}).catch(() => {
|
|
17
|
+
// Fallback for insecure contexts (HTTP)
|
|
18
|
+
try {
|
|
19
|
+
const textarea = document.createElement('textarea');
|
|
20
|
+
textarea.value = content;
|
|
21
|
+
textarea.style.position = 'fixed';
|
|
22
|
+
textarea.style.opacity = '0';
|
|
23
|
+
document.body.appendChild(textarea);
|
|
24
|
+
textarea.select();
|
|
25
|
+
document.execCommand('copy');
|
|
26
|
+
document.body.removeChild(textarea);
|
|
27
|
+
clearTimeout(timerRef.current);
|
|
28
|
+
setCopied(true);
|
|
29
|
+
timerRef.current = setTimeout(() => setCopied(false), 2000);
|
|
30
|
+
}
|
|
31
|
+
catch { /* ignore */ }
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
const btnStyle = {
|
|
35
|
+
display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
|
|
36
|
+
width: 28, height: 28, borderRadius: '6px',
|
|
37
|
+
border: 'none', background: 'transparent', cursor: 'pointer',
|
|
38
|
+
color: 'var(--t2v-muted)', fontSize: '14px',
|
|
39
|
+
transition: 'background 0.15s, color 0.15s',
|
|
40
|
+
};
|
|
41
|
+
return (_jsxs("div", { style: { display: 'flex', gap: '2px', marginTop: '4px', opacity: 0.6, transition: 'opacity 0.15s' }, onMouseEnter: (e) => { e.currentTarget.style.opacity = '1'; }, onMouseLeave: (e) => { e.currentTarget.style.opacity = '0.6'; }, children: [_jsx("button", { onClick: handleCopy, title: copied ? 'Copied!' : 'Copy message', style: { ...btnStyle, color: copied ? 'var(--t2v-accent)' : 'var(--t2v-muted)' }, onMouseEnter: (e) => { e.currentTarget.style.background = 'var(--t2v-surface-hover)'; }, onMouseLeave: (e) => { e.currentTarget.style.background = 'transparent'; }, children: copied ? _jsx(Check, { size: 14 }) : _jsx(Copy, { size: 14 }) }), isLast && (_jsx("button", { onClick: () => { retryLastMessage().catch(() => { }); }, title: "Regenerate response", style: btnStyle, onMouseEnter: (e) => { e.currentTarget.style.background = 'var(--t2v-surface-hover)'; }, onMouseLeave: (e) => { e.currentTarget.style.background = 'transparent'; }, children: _jsx(RefreshCw, { size: 14 }) }))] }));
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=MessageActions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageActions.js","sourceRoot":"","sources":["../../../src/ui/components/MessageActions.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MessageBubble — renders a single chat message.
|
|
3
|
+
*
|
|
4
|
+
* User messages: right-aligned dark bubble, plain text.
|
|
5
|
+
* Assistant messages: left-aligned with Talk2View logo avatar, renders
|
|
6
|
+
* ThinkingBlock (if plan exists), ToolDisplay (if steps exist),
|
|
7
|
+
* ApprovalCard (if pendingApproval and isStreaming), MarkdownRenderer
|
|
8
|
+
* (for content), and a blinking streaming cursor.
|
|
9
|
+
*/
|
|
10
|
+
import type { DisplayMessage } from '../../types';
|
|
11
|
+
export interface MessageBubbleProps {
|
|
12
|
+
message: DisplayMessage;
|
|
13
|
+
isLast?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export declare function MessageBubble({ message, isLast }: MessageBubbleProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
//# sourceMappingURL=MessageBubble.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageBubble.d.ts","sourceRoot":"","sources":["../../../src/ui/components/MessageBubble.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAUlD,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,aAAa,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,kBAAkB,2CAmIpE"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useChat } from '../context';
|
|
3
|
+
import { LOGOS } from '../theme';
|
|
4
|
+
import { MarkdownRenderer } from './MarkdownRenderer';
|
|
5
|
+
import { ThinkingBlock } from './ThinkingBlock';
|
|
6
|
+
import { ToolStepGroup } from './ToolDisplay';
|
|
7
|
+
import { ApprovalCard } from './ApprovalCard';
|
|
8
|
+
import { MessageActions } from './MessageActions';
|
|
9
|
+
import { Shimmer } from './Shimmer';
|
|
10
|
+
export function MessageBubble({ message, isLast }) {
|
|
11
|
+
const { pendingApproval, approveToolCall } = useChat();
|
|
12
|
+
const isUser = message.role === 'user';
|
|
13
|
+
if (isUser) {
|
|
14
|
+
return (_jsx("div", { style: {
|
|
15
|
+
display: 'flex',
|
|
16
|
+
justifyContent: 'flex-end',
|
|
17
|
+
marginBottom: '12px',
|
|
18
|
+
animation: 't2v-fade-in 0.2s ease-out',
|
|
19
|
+
}, children: _jsx("div", { style: {
|
|
20
|
+
maxWidth: '75%',
|
|
21
|
+
padding: '10px 14px',
|
|
22
|
+
borderRadius: 'calc(var(--t2v-radius) * 1px)',
|
|
23
|
+
borderBottomRightRadius: '4px',
|
|
24
|
+
background: 'var(--t2v-user-bubble)',
|
|
25
|
+
color: 'var(--t2v-user-foreground)',
|
|
26
|
+
fontSize: '14px',
|
|
27
|
+
lineHeight: 1.5,
|
|
28
|
+
fontFamily: 'var(--t2v-font)',
|
|
29
|
+
whiteSpace: 'pre-wrap',
|
|
30
|
+
wordBreak: 'break-word',
|
|
31
|
+
}, children: message.content }) }));
|
|
32
|
+
}
|
|
33
|
+
// Assistant message
|
|
34
|
+
const showApproval = message.isStreaming &&
|
|
35
|
+
pendingApproval !== null;
|
|
36
|
+
return (_jsxs("div", { style: {
|
|
37
|
+
display: 'flex',
|
|
38
|
+
alignItems: 'flex-start',
|
|
39
|
+
gap: '8px',
|
|
40
|
+
marginBottom: '12px',
|
|
41
|
+
animation: 't2v-fade-in 0.2s ease-out',
|
|
42
|
+
}, children: [_jsx("img", { src: LOGOS.icon, alt: "Talk2View", style: {
|
|
43
|
+
width: '24px',
|
|
44
|
+
height: '24px',
|
|
45
|
+
borderRadius: '50%',
|
|
46
|
+
flexShrink: 0,
|
|
47
|
+
marginTop: '2px',
|
|
48
|
+
objectFit: 'contain',
|
|
49
|
+
background: 'var(--t2v-bg)',
|
|
50
|
+
border: '1px solid var(--t2v-border)',
|
|
51
|
+
} }), _jsxs("div", { style: {
|
|
52
|
+
flex: 1,
|
|
53
|
+
minWidth: 0,
|
|
54
|
+
fontSize: '14px',
|
|
55
|
+
lineHeight: 1.55,
|
|
56
|
+
color: 'var(--t2v-foreground)',
|
|
57
|
+
fontFamily: 'var(--t2v-font)',
|
|
58
|
+
background: 'var(--t2v-surface)',
|
|
59
|
+
borderRadius: '8px',
|
|
60
|
+
padding: '10px 12px',
|
|
61
|
+
}, children: [message.plan && _jsx(ThinkingBlock, { content: message.plan }), message.steps && message.steps.length > 0 && (_jsx("div", { style: { marginBottom: message.content ? '8px' : '0' }, children: _jsx(ToolStepGroup, { steps: message.steps, isStreaming: message.isStreaming }) })), showApproval && pendingApproval && (_jsx(ApprovalCard, { toolName: pendingApproval.toolName, toolCallId: pendingApproval.toolCallId, args: pendingApproval.arguments, description: pendingApproval.description, onDecision: approveToolCall })), message.isStreaming && !message.content && !message.plan && !pendingApproval && (_jsx(Shimmer, {})), message.content && _jsx(MarkdownRenderer, { content: message.content }), message.isStreaming && message.content && !pendingApproval && !message.plan && (_jsx("span", { style: {
|
|
62
|
+
display: 'inline-block',
|
|
63
|
+
width: '2px',
|
|
64
|
+
height: '1em',
|
|
65
|
+
background: 'var(--t2v-accent)',
|
|
66
|
+
marginLeft: '2px',
|
|
67
|
+
verticalAlign: 'text-bottom',
|
|
68
|
+
animation: 't2v-blink 1s step-start infinite',
|
|
69
|
+
} })), !message.isStreaming && message.content && (_jsx(MessageActions, { content: message.content, isLast: isLast ?? false }))] })] }));
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=MessageBubble.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageBubble.js","sourceRoot":"","sources":["../../../src/ui/components/MessageBubble.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MessageList — scrollable list of chat messages.
|
|
3
|
+
*
|
|
4
|
+
* - Auto-scrolls to bottom when messages change (only if already near bottom).
|
|
5
|
+
* - Shows a scroll-to-bottom button when scrolled up more than 150px.
|
|
6
|
+
* - Shows a Shimmer typing indicator when isLoading and last message has no content.
|
|
7
|
+
* - Renders a MessageBubble for each message.
|
|
8
|
+
*/
|
|
9
|
+
export declare function MessageList(): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
//# sourceMappingURL=MessageList.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/ui/components/MessageList.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,wBAAgB,WAAW,4CAwF1B"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* MessageList — scrollable list of chat messages.
|
|
4
|
+
*
|
|
5
|
+
* - Auto-scrolls to bottom when messages change (only if already near bottom).
|
|
6
|
+
* - Shows a scroll-to-bottom button when scrolled up more than 150px.
|
|
7
|
+
* - Shows a Shimmer typing indicator when isLoading and last message has no content.
|
|
8
|
+
* - Renders a MessageBubble for each message.
|
|
9
|
+
*/
|
|
10
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
11
|
+
import { ArrowDown } from 'lucide-react';
|
|
12
|
+
import { useChat } from '../context';
|
|
13
|
+
import { MessageBubble } from './MessageBubble';
|
|
14
|
+
export function MessageList() {
|
|
15
|
+
const { messages, isLoading } = useChat();
|
|
16
|
+
const containerRef = useRef(null);
|
|
17
|
+
const [showScrollBtn, setShowScrollBtn] = useState(false);
|
|
18
|
+
const isNearBottom = useCallback(() => {
|
|
19
|
+
const el = containerRef.current;
|
|
20
|
+
if (!el)
|
|
21
|
+
return true;
|
|
22
|
+
return el.scrollHeight - el.scrollTop - el.clientHeight < 150;
|
|
23
|
+
}, []);
|
|
24
|
+
const scrollToBottom = useCallback((behavior = 'smooth') => {
|
|
25
|
+
const el = containerRef.current;
|
|
26
|
+
if (!el)
|
|
27
|
+
return;
|
|
28
|
+
el.scrollTo({ top: el.scrollHeight, behavior });
|
|
29
|
+
}, []);
|
|
30
|
+
// Auto-scroll when messages change (only if already near bottom)
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
if (isNearBottom()) {
|
|
33
|
+
scrollToBottom('smooth');
|
|
34
|
+
}
|
|
35
|
+
}, [messages, isNearBottom, scrollToBottom]);
|
|
36
|
+
// Track scroll position to show/hide scroll-to-bottom button
|
|
37
|
+
const handleScroll = useCallback(() => {
|
|
38
|
+
const el = containerRef.current;
|
|
39
|
+
if (!el)
|
|
40
|
+
return;
|
|
41
|
+
const distanceFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight;
|
|
42
|
+
setShowScrollBtn(distanceFromBottom > 150);
|
|
43
|
+
}, []);
|
|
44
|
+
return (_jsxs("div", { style: { position: 'relative', flex: 1, minHeight: 0 }, children: [_jsxs("div", { ref: containerRef, role: "log", "aria-live": "polite", className: "t2v-scrollable", onScroll: handleScroll, style: {
|
|
45
|
+
height: '100%',
|
|
46
|
+
overflowY: 'auto',
|
|
47
|
+
padding: '16px',
|
|
48
|
+
boxSizing: 'border-box',
|
|
49
|
+
}, children: [messages.map((msg, i) => (_jsx(MessageBubble, { message: msg, isLast: i === messages.length - 1 }, msg.id))), _jsx("div", { style: { height: showScrollBtn ? '40px' : '0' } })] }), showScrollBtn && (_jsxs("button", { onClick: () => scrollToBottom('smooth'), "aria-label": "Scroll to bottom", style: {
|
|
50
|
+
position: 'absolute',
|
|
51
|
+
bottom: '16px',
|
|
52
|
+
left: '50%',
|
|
53
|
+
transform: 'translateX(-50%)',
|
|
54
|
+
display: 'flex',
|
|
55
|
+
alignItems: 'center',
|
|
56
|
+
gap: '4px',
|
|
57
|
+
padding: '6px 12px',
|
|
58
|
+
background: 'var(--t2v-bg)',
|
|
59
|
+
border: '1px solid var(--t2v-border)',
|
|
60
|
+
borderRadius: '16px',
|
|
61
|
+
cursor: 'pointer',
|
|
62
|
+
fontSize: '12px',
|
|
63
|
+
fontFamily: 'var(--t2v-font)',
|
|
64
|
+
color: 'var(--t2v-muted)',
|
|
65
|
+
boxShadow: '0 2px 8px rgba(0,0,0,0.08)',
|
|
66
|
+
zIndex: 1,
|
|
67
|
+
}, children: [_jsx(ArrowDown, { size: 14 }), "Scroll to bottom"] }))] }));
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=MessageList.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageList.js","sourceRoot":"","sources":["../../../src/ui/components/MessageList.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SettingsPanel — full-panel settings page for user preferences.
|
|
3
|
+
*/
|
|
4
|
+
export interface SettingsPanelProps {
|
|
5
|
+
onBack?: () => void;
|
|
6
|
+
onModelChange?: (model: string) => void;
|
|
7
|
+
/** Hide the built-in header (use when embedding in a container with its own header). */
|
|
8
|
+
hideHeader?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function SettingsPanel({ onBack, onModelChange, hideHeader }: SettingsPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
//# sourceMappingURL=SettingsPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SettingsPanel.d.ts","sourceRoot":"","sources":["../../../src/ui/components/SettingsPanel.tsx"],"names":[],"mappings":"AAAA;;GAEG;AASH,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,wFAAwF;IACxF,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAuDD,wBAAgB,aAAa,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,UAAU,EAAE,EAAE,kBAAkB,2CAyPtF"}
|