fix(diagnostics): volume %, auto cast scan, snapshot-on-demand track
- Volume: playerStore.getVolume() already returns 0-100, the extra *100 was reporting "10000%". Just Math.round() the stored value. - Cast scan: run automatically the first time the panel is opened so the user doesn't have to press the button. Button now doubles as "re-scan" while disabled during an in-flight scan. A spinner placeholder shows while the initial scan is in progress. - Track info: capture a single snapshot on open/refresh instead of live-subscribing to the player store — live updates were unnecessary for a diagnostic dump and slowed the settings page. Use "Refresh" to take a fresh snapshot. cc
This commit is contained in:
1 file changed
+25
-18
@@ -1,16 +1,15 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount, onDestroy } from 'svelte';
|
import { onDestroy } from 'svelte';
|
||||||
import { invoke } from '@tauri-apps/api/core';
|
import { invoke } from '@tauri-apps/api/core';
|
||||||
import { writeText as copyToClipboard } from '@tauri-apps/plugin-clipboard-manager';
|
import { writeText as copyToClipboard } from '@tauri-apps/plugin-clipboard-manager';
|
||||||
import { t } from '$lib/i18n';
|
import { t } from '$lib/i18n';
|
||||||
import { RefreshCw, Copy, Check, ChevronDown, ChevronRight, Radio } from 'lucide-svelte';
|
import { RefreshCw, Copy, Check, ChevronDown, ChevronRight, Radio, LoaderCircle } from 'lucide-svelte';
|
||||||
import {
|
import {
|
||||||
getCurrentTrack,
|
getCurrentTrack,
|
||||||
getIsPlaying,
|
getIsPlaying,
|
||||||
getCurrentTime,
|
getCurrentTime,
|
||||||
getDuration,
|
getDuration,
|
||||||
getVolume,
|
getVolume
|
||||||
subscribe as subscribeToPlayer
|
|
||||||
} from '$lib/stores/playerStore';
|
} from '$lib/stores/playerStore';
|
||||||
import type { QconnectConnectionStatus, QconnectSessionSnapshot } from '$lib/services/qconnectRuntime';
|
import type { QconnectConnectionStatus, QconnectSessionSnapshot } from '$lib/services/qconnectRuntime';
|
||||||
|
|
||||||
@@ -118,7 +117,6 @@
|
|||||||
let qconnectOpen = $state(true);
|
let qconnectOpen = $state(true);
|
||||||
let castOpen = $state(true);
|
let castOpen = $state(true);
|
||||||
|
|
||||||
let playerUnsubscribe: (() => void) | null = null;
|
|
||||||
const CAST_SCAN_DURATION_MS = 10000;
|
const CAST_SCAN_DURATION_MS = 10000;
|
||||||
|
|
||||||
// Redact things that look like UUIDs / hex IDs / tokens (defensive: keep paste
|
// Redact things that look like UUIDs / hex IDs / tokens (defensive: keep paste
|
||||||
@@ -135,7 +133,7 @@
|
|||||||
const track = getCurrentTrack();
|
const track = getCurrentTrack();
|
||||||
return {
|
return {
|
||||||
isPlaying: getIsPlaying(),
|
isPlaying: getIsPlaying(),
|
||||||
volumePercent: Math.round(getVolume() * 100),
|
volumePercent: Math.round(getVolume()),
|
||||||
positionSecs: Math.round(getCurrentTime()),
|
positionSecs: Math.round(getCurrentTime()),
|
||||||
durationSecs: Math.round(getDuration()),
|
durationSecs: Math.round(getDuration()),
|
||||||
hasTrack: !!track,
|
hasTrack: !!track,
|
||||||
@@ -359,23 +357,17 @@
|
|||||||
panelOpen = !panelOpen;
|
panelOpen = !panelOpen;
|
||||||
if (panelOpen) {
|
if (panelOpen) {
|
||||||
if (!diagnostics) loadDiagnostics();
|
if (!diagnostics) loadDiagnostics();
|
||||||
// Keep playback snapshot refreshed while the panel is open.
|
// Auto-run a cast scan the first time the panel is opened. Don't
|
||||||
if (!playerUnsubscribe) {
|
// block the diagnostics load on it — scan runs concurrently and
|
||||||
playerUnsubscribe = subscribeToPlayer(() => {
|
// fills its own section when done.
|
||||||
playback = snapshotPlayback();
|
if (!castScan && !castScanning) {
|
||||||
});
|
void runCastScan();
|
||||||
}
|
}
|
||||||
} else if (playerUnsubscribe) {
|
|
||||||
playerUnsubscribe();
|
|
||||||
playerUnsubscribe = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
if (playerUnsubscribe) {
|
// (intentional) don't leave any subscriptions behind
|
||||||
playerUnsubscribe();
|
|
||||||
playerUnsubscribe = null;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function playbackRows(p: PlaybackSnapshot): DiagRow[] {
|
function playbackRows(p: PlaybackSnapshot): DiagRow[] {
|
||||||
@@ -528,6 +520,12 @@
|
|||||||
: $t('settings.developer.diagnostics.castScan')}
|
: $t('settings.developer.diagnostics.castScan')}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
{#if castScanning && !castScan}
|
||||||
|
<div class="cast-scan-placeholder">
|
||||||
|
<LoaderCircle size={20} class="spinning" />
|
||||||
|
<span>{$t('settings.developer.diagnostics.castScanning')}</span>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
{#if castScan}
|
{#if castScan}
|
||||||
<table class="diag-table">
|
<table class="diag-table">
|
||||||
<thead>
|
<thead>
|
||||||
@@ -773,6 +771,15 @@
|
|||||||
animation: spin 1s linear infinite;
|
animation: spin 1s linear infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cast-scan-placeholder {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
padding: 10px 12px;
|
||||||
|
color: var(--text-muted);
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes spin {
|
@keyframes spin {
|
||||||
from { transform: rotate(0deg); }
|
from { transform: rotate(0deg); }
|
||||||
to { transform: rotate(360deg); }
|
to { transform: rotate(360deg); }
|
||||||
|
|||||||
Reference in new issue
Block a user