Refactor display density settings: replace compact mode with display density option and update related UI components

This commit is contained in:
Will Miao
2025-05-20 19:35:41 +08:00
parent 50704bc882
commit 8e1f73a34e
5 changed files with 132 additions and 44 deletions

View File

@@ -86,23 +86,39 @@
min-height: 0; /* Fix for potential flexbox sizing issue in Firefox */ min-height: 0; /* Fix for potential flexbox sizing issue in Firefox */
} }
/* Smaller text for medium density */
.medium-density .model-name {
font-size: 0.95em;
max-height: 2.6em;
}
.medium-density .base-model-label {
font-size: 0.85em;
max-width: 120px;
}
.medium-density .card-actions i {
font-size: 0.98em;
padding: 4px;
}
/* Smaller text for compact mode */ /* Smaller text for compact mode */
.compact-mode .model-name { .compact-density .model-name {
font-size: 0.9em; font-size: 0.9em;
max-height: 2.4em; max-height: 2.4em;
} }
.compact-mode .base-model-label { .compact-density .base-model-label {
font-size: 0.8em; font-size: 0.8em;
max-width: 110px; max-width: 110px;
} }
.compact-mode .card-actions i { .compact-density .card-actions i {
font-size: 0.95em; font-size: 0.95em;
padding: 3px; padding: 3px;
} }
.compact-mode .model-info { .compact-density .model-info {
padding-bottom: 2px; padding-bottom: 2px;
} }

View File

@@ -683,3 +683,14 @@ input:checked + .toggle-slider:before {
[data-theme="dark"] .warning-text { [data-theme="dark"] .warning-text {
color: var(--lora-warning, #f39c12); color: var(--lora-warning, #f39c12);
} }
/* Add styles for density description list */
.density-description {
margin: 8px 0;
padding-left: 20px;
font-size: 0.9em;
}
.density-description li {
margin-bottom: 4px;
}

View File

@@ -31,6 +31,16 @@ export class SettingsManager {
if (state.global.settings.compactMode === undefined) { if (state.global.settings.compactMode === undefined) {
state.global.settings.compactMode = false; state.global.settings.compactMode = false;
} }
// Convert old boolean compactMode to new displayDensity string
if (typeof state.global.settings.displayDensity === 'undefined') {
if (state.global.settings.compactMode === true) {
state.global.settings.displayDensity = 'compact';
} else {
state.global.settings.displayDensity = 'default';
}
// We can delete the old setting, but keeping it for backwards compatibility
}
} }
initialize() { initialize() {
@@ -82,10 +92,10 @@ export class SettingsManager {
autoplayOnHoverCheckbox.checked = state.global.settings.autoplayOnHover || false; autoplayOnHoverCheckbox.checked = state.global.settings.autoplayOnHover || false;
} }
// Set compact mode setting // Set display density setting
const compactModeCheckbox = document.getElementById('compactMode'); const displayDensitySelect = document.getElementById('displayDensity');
if (compactModeCheckbox) { if (displayDensitySelect) {
compactModeCheckbox.checked = state.global.settings.compactMode || false; displayDensitySelect.value = state.global.settings.displayDensity || 'default';
} }
// Load default lora root // Load default lora root
@@ -219,6 +229,11 @@ export class SettingsManager {
// Update frontend state // Update frontend state
if (settingKey === 'default_lora_root') { if (settingKey === 'default_lora_root') {
state.global.settings.default_loras_root = value; state.global.settings.default_loras_root = value;
} else if (settingKey === 'display_density') {
state.global.settings.displayDensity = value;
// Also update compactMode for backwards compatibility
state.global.settings.compactMode = (value !== 'default');
} else { } else {
// For any other settings that might be added in the future // For any other settings that might be added in the future
state.global.settings[settingKey] = value; state.global.settings[settingKey] = value;
@@ -229,22 +244,38 @@ export class SettingsManager {
try { try {
// For backend settings, make API call // For backend settings, make API call
const payload = {}; if (settingKey === 'default_lora_root') {
payload[settingKey] = value; const payload = {};
payload[settingKey] = value;
const response = await fetch('/api/settings', { const response = await fetch('/api/settings', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}, },
body: JSON.stringify(payload) body: JSON.stringify(payload)
}); });
if (!response.ok) { if (!response.ok) {
throw new Error('Failed to save setting'); throw new Error('Failed to save setting');
}
showToast(`Settings updated: ${settingKey.replace(/_/g, ' ')}`, 'success');
} }
showToast(`Settings updated: ${settingKey.replace(/_/g, ' ')}`, 'success'); // Apply frontend settings immediately
this.applyFrontendSettings();
// Recalculate layout when display density changes
if (settingKey === 'display_density' && state.virtualScroller) {
state.virtualScroller.calculateLayout();
let densityName = "Default";
if (value === 'medium') densityName = "Medium";
if (value === 'compact') densityName = "Compact";
showToast(`Display Density set to ${densityName}`, 'success');
}
} catch (error) { } catch (error) {
showToast('Failed to save setting: ' + error.message, 'error'); showToast('Failed to save setting: ' + error.message, 'error');
@@ -419,8 +450,17 @@ export class SettingsManager {
videoParent.replaceChild(videoClone, video); videoParent.replaceChild(videoClone, video);
}); });
// For show_only_sfw, there's no immediate action needed as it affects content loading // Apply display density class to grid
// The setting will take effect on next reload const grid = document.querySelector('.card-grid');
if (grid) {
const density = state.global.settings.displayDensity || 'default';
// Remove all density classes first
grid.classList.remove('default-density', 'medium-density', 'compact-density');
// Add the appropriate density class
grid.classList.add(`${density}-density`);
}
} }
} }

View File

@@ -88,22 +88,40 @@ export class VirtualScroller {
// Calculate available content width (excluding padding) // Calculate available content width (excluding padding)
const availableContentWidth = containerWidth - paddingLeft - paddingRight; const availableContentWidth = containerWidth - paddingLeft - paddingRight;
// Get compact mode setting // Get display density setting
const compactMode = state.global.settings?.compactMode || false; const displayDensity = state.global.settings?.displayDensity || 'default';
// Set exact column counts and grid widths to match CSS container widths // Set exact column counts and grid widths to match CSS container widths
let maxColumns, maxGridWidth; let maxColumns, maxGridWidth;
// Match exact column counts and CSS container width values // Match exact column counts and CSS container width values based on density
if (window.innerWidth >= 3000) { // 4K if (window.innerWidth >= 3000) { // 4K
maxColumns = compactMode ? 10 : 8; if (displayDensity === 'default') {
maxColumns = 8;
} else if (displayDensity === 'medium') {
maxColumns = 9;
} else { // compact
maxColumns = 10;
}
maxGridWidth = 2400; // Match exact CSS container width for 4K maxGridWidth = 2400; // Match exact CSS container width for 4K
} else if (window.innerWidth >= 2000) { // 2K/1440p } else if (window.innerWidth >= 2000) { // 2K/1440p
maxColumns = compactMode ? 8 : 6; if (displayDensity === 'default') {
maxColumns = 6;
} else if (displayDensity === 'medium') {
maxColumns = 7;
} else { // compact
maxColumns = 8;
}
maxGridWidth = 1800; // Match exact CSS container width for 2K maxGridWidth = 1800; // Match exact CSS container width for 2K
} else { } else {
// 1080p // 1080p
maxColumns = compactMode ? 7 : 5; if (displayDensity === 'default') {
maxColumns = 5;
} else if (displayDensity === 'medium') {
maxColumns = 6;
} else { // compact
maxColumns = 7;
}
maxGridWidth = 1400; // Match exact CSS container width for 1080p maxGridWidth = 1400; // Match exact CSS container width for 1080p
} }
@@ -145,7 +163,7 @@ export class VirtualScroller {
leftOffset: this.leftOffset, leftOffset: this.leftOffset,
paddingLeft, paddingLeft,
paddingRight, paddingRight,
compactMode, displayDensity,
maxColumns, maxColumns,
baseCardWidth, baseCardWidth,
rowGap: this.rowGap rowGap: this.rowGap
@@ -154,12 +172,9 @@ export class VirtualScroller {
// Update grid element max-width to match available width // Update grid element max-width to match available width
this.gridElement.style.maxWidth = `${actualGridWidth}px`; this.gridElement.style.maxWidth = `${actualGridWidth}px`;
// Add or remove compact-mode class for style adjustments // Add or remove density classes for style adjustments
if (compactMode) { this.gridElement.classList.remove('default-density', 'medium-density', 'compact-density');
this.gridElement.classList.add('compact-mode'); this.gridElement.classList.add(`${displayDensity}-density`);
} else {
this.gridElement.classList.remove('compact-mode');
}
// Update spacer height // Update spacer height
this.updateSpacerHeight(); this.updateSpacerHeight();

View File

@@ -161,18 +161,24 @@
<div class="setting-item"> <div class="setting-item">
<div class="setting-row"> <div class="setting-row">
<div class="setting-info"> <div class="setting-info">
<label for="compactMode">Compact Mode</label> <label for="displayDensity">Display Density</label>
</div> </div>
<div class="setting-control"> <div class="setting-control select-control">
<label class="toggle-switch"> <select id="displayDensity" onchange="settingsManager.saveSelectSetting('displayDensity', 'display_density')">
<input type="checkbox" id="compactMode" <option value="default">Default</option>
onchange="settingsManager.saveToggleSetting('compactMode', 'compact_mode')"> <option value="medium">Medium</option>
<span class="toggle-slider"></span> <option value="compact">Compact</option>
</label> </select>
</div> </div>
</div> </div>
<div class="input-help"> <div class="input-help">
Display more cards per row (7 on 1080p, 8 on 2K, 10 on 4K). <span class="warning-text">Warning: May cause performance issues (lag and lower FPS) on systems with limited resources.</span> Choose how many cards to display per row:
<ul class="density-description">
<li><strong>Default:</strong> 5 (1080p), 6 (2K), 8 (4K)</li>
<li><strong>Medium:</strong> 6 (1080p), 7 (2K), 9 (4K)</li>
<li><strong>Compact:</strong> 7 (1080p), 8 (2K), 10 (4K)</li>
</ul>
<span class="warning-text">Warning: Higher densities may cause performance issues on systems with limited resources.</span>
</div> </div>
</div> </div>
</div> </div>