Skip to content

Commit 9ca714a

Browse files
committed
Enhance settings modal and chat functionality with new appearance and behavior options
- Added appearance settings for compact density, timestamp visibility, and reduced motion preferences in `settings-modal.html` and `settings-modal.js`. - Implemented behavior settings for auto-scrolling during streaming and default expansion of thinking details. - Updated `style.css` with new styles for the appearance settings and improved UI elements. - Introduced inline help for first-time users in `chat.html`, enhancing user experience. - Added lightweight virtualization for chat history to manage message display efficiently.
1 parent c798cbf commit 9ca714a

File tree

4 files changed

+273
-10
lines changed

4 files changed

+273
-10
lines changed

src/deepseek_wrapper/static/settings-modal.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,11 +168,25 @@ window.saveSettingsModal = async function() {
168168
const extractAnswerOnlyCheckbox = document.getElementById('extract-answer-only');
169169
const extractAnswerOnly = extractAnswerOnlyCheckbox ? extractAnswerOnlyCheckbox.checked : false;
170170

171+
// Appearance
172+
const compact = document.getElementById('appearance-compact-density')?.checked || false;
173+
const timestamps = document.getElementById('appearance-show-timestamps')?.checked || false;
174+
const reducedMotion = document.getElementById('appearance-reduced-motion')?.checked || false;
175+
176+
// Behavior
177+
const autoScroll = document.getElementById('behavior-auto-scroll')?.checked || false;
178+
const detailsDefault = document.getElementById('behavior-details-default')?.checked || false;
179+
171180
// Store in localStorage
172181
localStorage.setItem('ds_username', username);
173182
localStorage.setItem('ds_avatar', avatar);
174183
localStorage.setItem('ds_system_prompt', systemPrompt);
175184
localStorage.setItem('ds_extract_answer_only', extractAnswerOnly);
185+
localStorage.setItem('ds_compact_density', compact);
186+
localStorage.setItem('ds_show_timestamps', timestamps);
187+
localStorage.setItem('ds_reduced_motion', reducedMotion);
188+
localStorage.setItem('ds_auto_scroll', autoScroll);
189+
localStorage.setItem('ds_details_default', detailsDefault);
176190

177191
// Save extract_answer_only setting to config
178192
try {
@@ -210,6 +224,20 @@ function updateUIWithSettings() {
210224
el.textContent = localStorage.getItem('ds_avatar') || 'U';
211225
});
212226

227+
// Apply appearance prefs
228+
const compact = localStorage.getItem('ds_compact_density') === 'true';
229+
document.documentElement.toggleAttribute('data-density-compact', compact);
230+
231+
const showTimestamps = localStorage.getItem('ds_show_timestamps') === 'true';
232+
document.documentElement.toggleAttribute('data-show-timestamps', showTimestamps);
233+
234+
const reducedMotion = localStorage.getItem('ds_reduced_motion') === 'true';
235+
document.documentElement.toggleAttribute('data-reduced-motion', reducedMotion);
236+
237+
// Behavior defaults
238+
const detailsDefault = localStorage.getItem('ds_details_default') === 'true';
239+
if (detailsDefault) sessionStorage.setItem('ds_thinking_expanded','true');
240+
213241
// Update hidden form fields if they exist
214242
const usernameHidden = document.getElementById('user_name_hidden');
215243
const avatarHidden = document.getElementById('user_avatar_hidden');
@@ -238,6 +266,24 @@ function loadSettings() {
238266
if (extractAnswerOnlyCheckbox) {
239267
extractAnswerOnlyCheckbox.checked = extractAnswerOnly;
240268
}
269+
270+
// Appearance + Behavior fields
271+
const compact = localStorage.getItem('ds_compact_density') === 'true';
272+
const timestamps = localStorage.getItem('ds_show_timestamps') === 'true';
273+
const reducedMotion = localStorage.getItem('ds_reduced_motion') === 'true';
274+
const autoScroll = localStorage.getItem('ds_auto_scroll') === 'true';
275+
const detailsDefault = localStorage.getItem('ds_details_default') === 'true';
276+
277+
const compactEl = document.getElementById('appearance-compact-density');
278+
const tsEl = document.getElementById('appearance-show-timestamps');
279+
const rmEl = document.getElementById('appearance-reduced-motion');
280+
const asEl = document.getElementById('behavior-auto-scroll');
281+
const ddEl = document.getElementById('behavior-details-default');
282+
if (compactEl) compactEl.checked = compact;
283+
if (tsEl) tsEl.checked = timestamps;
284+
if (rmEl) rmEl.checked = reducedMotion;
285+
if (asEl) asEl.checked = autoScroll;
286+
if (ddEl) ddEl.checked = detailsDefault;
241287

242288
// Load API key status
243289
fetch('/api/key-status')

src/deepseek_wrapper/static/style.css

Lines changed: 92 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@
1818
--border-color: #DEE2E6; /* Light gray border */
1919
--border-input-focus: var(--primary-light);
2020
--shadow-color: rgba(0, 0, 0, 0.05); /* Softer shadow */
21+
/* Role-based tokens */
22+
--bg-subtle: #F3F4F6;
23+
--bg-hover: #ECEFF3;
24+
--text-muted: #6B7280;
2125

2226
--bubble-user-bg: var(--primary);
2327
--bubble-user-text: var(--text-on-primary);
@@ -37,6 +41,12 @@
3741
--max-width-content: 800px;
3842

3943
--primary-rgb: 0, 122, 255;
44+
45+
/* Spacing tokens */
46+
--space-1: 4px;
47+
--space-2: 8px;
48+
--space-3: 12px;
49+
--space-4: 16px;
4050
}
4151

4252
/* Dark Theme */
@@ -59,6 +69,9 @@
5969
--border-color: #38383A;
6070
--border-input-focus: var(--primary);
6171
--shadow-color: rgba(0, 0, 0, 0.2);
72+
--bg-subtle: #2A2A2C;
73+
--bg-hover: #333336;
74+
--text-muted: #9CA3AF;
6275

6376
--bubble-user-bg: var(--primary);
6477
--bubble-user-text: var(--text-on-primary);
@@ -156,18 +169,18 @@ header.top-bar {
156169
display: flex;
157170
align-items: center;
158171
font-size: 0.85rem;
159-
background-color: color-mix(in srgb, var(--primary) 6%, transparent);
172+
background-color: var(--bg-subtle);
160173
border-radius: 20px;
161174
padding: 0.3rem 0.8rem;
162-
color: var(--text-secondary);
175+
color: var(--text-muted);
163176
margin-left: auto;
164177
margin-right: 1rem;
165178
transition: all 0.2s ease;
166179
position: relative;
167180
}
168181

169182
.model-indicator:hover {
170-
background-color: color-mix(in srgb, var(--primary) 12%, transparent);
183+
background-color: var(--bg-hover);
171184
cursor: pointer;
172185
}
173186

@@ -228,6 +241,23 @@ header.top-bar {
228241
gap: 1em;
229242
}
230243

244+
/* Virtualized history controls */
245+
.load-older {
246+
align-self: center;
247+
display: inline-flex;
248+
align-items: center;
249+
gap: 8px;
250+
font-size: 0.875rem;
251+
color: var(--text-primary);
252+
background: var(--bg-subtle);
253+
border: 1px solid var(--border-color);
254+
border-radius: 999px;
255+
padding: 6px 12px;
256+
cursor: pointer;
257+
}
258+
.load-older:hover { background: var(--bg-hover); }
259+
.load-older svg { opacity: 0.7; }
260+
231261
/* Date separators */
232262
.date-separator {
233263
align-self: center;
@@ -407,6 +437,35 @@ button#send-btn:disabled {
407437
transform: none;
408438
}
409439

440+
/* First-run help */
441+
.first-run-help {
442+
max-width: var(--max-width-content);
443+
width: 100%;
444+
margin: 0 auto;
445+
padding: 0.5rem 1rem 0;
446+
}
447+
.first-run-help .tips {
448+
display: flex;
449+
justify-content: space-between;
450+
align-items: center;
451+
gap: 8px;
452+
font-size: 0.875rem;
453+
color: var(--text-muted);
454+
background: var(--bg-subtle);
455+
border: 1px dashed var(--border-color);
456+
border-radius: 10px;
457+
padding: 8px 12px;
458+
}
459+
.first-run-help .help-dismiss {
460+
background: transparent;
461+
border: none;
462+
color: var(--text-secondary);
463+
width: 28px; height: 28px; border-radius: 6px;
464+
}
465+
.first-run-help .help-dismiss:hover {
466+
background: rgba(0,0,0,0.05);
467+
}
468+
410469
/* File Upload Label - Enhanced */
411470
label[for="file-input"] {
412471
padding: 10px 16px;
@@ -602,6 +661,17 @@ label[for="file-input"]:active {
602661
backdrop-filter: blur(8px);
603662
}
604663

664+
/* Compact density */
665+
[data-density-compact="true"] .bubble {
666+
padding: 0.625rem 0.75rem;
667+
}
668+
[data-density-compact="true"] form#chat-form {
669+
padding: 0.75rem;
670+
}
671+
[data-density-compact="true"] #user_message {
672+
min-height: 38px;
673+
}
674+
605675
.bubble:hover {
606676
transform: translateY(-2px);
607677
box-shadow: 0 4px 12px rgba(0,0,0,0.12), 0 6px 16px rgba(0,0,0,0.06);
@@ -615,9 +685,9 @@ label[for="file-input"]:active {
615685
}
616686

617687
.assistant-msg {
618-
background: rgba(var(--primary-rgb), 0.06);
688+
background: rgba(var(--primary-rgb), 0.05);
619689
color: var(--bubble-assistant-text);
620-
border: 1px solid rgba(var(--primary-rgb), 0.12);
690+
border: 1px solid rgba(var(--primary-rgb), 0.10);
621691
border-bottom-left-radius: 6px;
622692
margin-left: 0.5rem;
623693
backdrop-filter: blur(8px);
@@ -674,6 +744,11 @@ label[for="file-input"]:active {
674744
opacity: 0.7;
675745
}
676746

747+
/* Hide timestamps unless preference enabled */
748+
:root:not([data-show-timestamps="true"]) .timestamp {
749+
display: none;
750+
}
751+
677752
.bubble:hover .timestamp {
678753
opacity: 1;
679754
background-color: rgba(0,0,0,0.05);
@@ -1135,6 +1210,18 @@ label:focus {
11351210
}
11361211
}
11371212

1213+
/* Reduced motion override via preference */
1214+
[data-reduced-motion="true"] *,
1215+
[data-reduced-motion="true"] *::before,
1216+
[data-reduced-motion="true"] *::after {
1217+
animation-duration: 0.01ms !important;
1218+
animation-iteration-count: 1 !important;
1219+
transition-duration: 0.01ms !important;
1220+
}
1221+
[data-reduced-motion="true"] .thinking-bar .progress { animation: none !important; }
1222+
[data-reduced-motion="true"] .bubble:hover { transform: none !important; }
1223+
[data-reduced-motion="true"] .action-btn:hover { transform: none !important; }
1224+
11381225
/* High contrast support */
11391226
@media (prefers-contrast: high) {
11401227
:root {

0 commit comments

Comments
 (0)