Reduce visualizer latency, tighten UI paddings, fix mobile browser toolbar

- Visualizer: FPS 25→30, chunk_size 2048→1024, smoothing 0.65→0.15
- Beat effect: scale 0.03→0.04, glow range 0.5-0.8→0.4-0.8
- UI: reduce container/section paddings from 2rem to 1rem
- Source name: add ellipsis overflow for long names
- Mobile browser toolbar: use flex-wrap instead of column stack,
  hide "Items per page" label text on small screens

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-01 12:35:23 +03:00
parent 3846610042
commit 652f10fc4c
4 changed files with 33 additions and 17 deletions

View File

@@ -118,7 +118,7 @@ class Settings(BaseSettings):
description="Enable audio spectrum visualizer (requires soundcard + numpy)", description="Enable audio spectrum visualizer (requires soundcard + numpy)",
) )
visualizer_fps: int = Field( visualizer_fps: int = Field(
default=25, default=30,
description="Visualizer update rate in frames per second", description="Visualizer update rate in frames per second",
ge=10, ge=10,
le=60, le=60,

View File

@@ -40,8 +40,8 @@ class AudioAnalyzer:
self, self,
num_bins: int = 32, num_bins: int = 32,
sample_rate: int = 44100, sample_rate: int = 44100,
chunk_size: int = 2048, chunk_size: int = 1024,
target_fps: int = 25, target_fps: int = 30,
device_name: str | None = None, device_name: str | None = None,
): ):
self.num_bins = num_bins self.num_bins = num_bins

View File

@@ -144,7 +144,7 @@ body.dialog-open {
.container { .container {
max-width: 800px; max-width: 800px;
margin: 0 auto; margin: 0 auto;
padding: 2rem 2rem 0.5rem; padding: 0.75rem 0.75rem 0.5rem;
} }
header { header {
@@ -498,7 +498,7 @@ h1 {
.player-container { .player-container {
background: var(--bg-secondary); background: var(--bg-secondary);
border-radius: 12px; border-radius: 12px;
padding: 2rem; padding: 1rem;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5); box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
} }
@@ -936,12 +936,18 @@ button:disabled {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
gap: 0.75rem; gap: 0.75rem;
min-width: 0;
} }
.source-label { .source-label {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
gap: 0.35rem; gap: 0.35rem;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 200px;
} }
.source-icon { .source-icon {
@@ -998,7 +1004,7 @@ button:disabled {
.scripts-container { .scripts-container {
background: var(--bg-secondary); background: var(--bg-secondary);
border-radius: 12px; border-radius: 12px;
padding: 2rem; padding: 1rem;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5); box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
} }
@@ -1131,7 +1137,7 @@ button:disabled {
} }
.settings-section summary { .settings-section summary {
padding: 1rem 1.5rem; padding: 1rem;
font-size: 1rem; font-size: 1rem;
font-weight: 600; font-weight: 600;
color: var(--text-primary); color: var(--text-primary);
@@ -1169,7 +1175,7 @@ button:disabled {
} }
.settings-section-content { .settings-section-content {
padding: 0 1.5rem 1.5rem; padding: 0 1rem 1rem;
overflow-x: auto; overflow-x: auto;
} }
@@ -1282,7 +1288,7 @@ button:disabled {
.display-container { .display-container {
background: var(--bg-secondary); background: var(--bg-secondary);
border-radius: 12px; border-radius: 12px;
padding: 2rem; padding: 1rem;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5); box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
} }
@@ -2218,7 +2224,7 @@ button.primary svg {
@media (max-width: 600px) { @media (max-width: 600px) {
.container { .container {
padding: 1rem; padding: 0.5rem;
} }
#album-art { #album-art {
@@ -2289,7 +2295,7 @@ footer .separator {
.browser-container { .browser-container {
background: var(--bg-secondary); background: var(--bg-secondary);
border-radius: 12px; border-radius: 12px;
padding: 2rem; padding: 1rem;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5); box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
} }
@@ -3006,16 +3012,26 @@ footer .separator {
} }
.browser-toolbar { .browser-toolbar {
flex-direction: column; flex-wrap: wrap;
align-items: stretch; gap: 0.5rem;
}
.browser-toolbar-left {
gap: 0.35rem;
} }
.browser-search-wrapper { .browser-search-wrapper {
max-width: none; max-width: none;
flex-basis: 100%;
order: 10;
} }
.browser-toolbar-right { .browser-toolbar-right {
justify-content: flex-end; margin-left: auto;
}
.items-per-page-label span {
display: none;
} }
.browser-list-item { .browser-list-item {

View File

@@ -258,7 +258,7 @@ let visualizerCtx = null;
let visualizerAnimFrame = null; let visualizerAnimFrame = null;
let frequencyData = null; let frequencyData = null;
let smoothedFrequencies = null; let smoothedFrequencies = null;
const VISUALIZER_SMOOTHING = 0.65; const VISUALIZER_SMOOTHING = 0.15;
async function checkVisualizerAvailability() { async function checkVisualizerAvailability() {
try { try {
@@ -386,7 +386,7 @@ function renderVisualizerFrame() {
} }
const bass = frequencyData.bass || 0; const bass = frequencyData.bass || 0;
const scale = 1 + bass * 0.03; const scale = 1 + bass * 0.04;
const art = document.getElementById('album-art'); const art = document.getElementById('album-art');
if (art) { if (art) {
if (vinylMode) { if (vinylMode) {
@@ -397,7 +397,7 @@ function renderVisualizerFrame() {
} }
const glow = document.getElementById('album-art-glow'); const glow = document.getElementById('album-art-glow');
if (glow) { if (glow) {
glow.style.opacity = (0.5 + bass * 0.3).toFixed(2); glow.style.opacity = (0.4 + bass * 0.4).toFixed(2);
} }
} }