Files
qbz/crates/qbz-ui/ui/settings/OfflineSettings.slint
T
vicrodh 8c50c16faa fix(offline): clarify that Clear cache keeps downloaded albums
After #606 the offline Clear-cache purges only the transient cache dirs (tracks/tracks-cmaf/artwork), never the organized downloaded albums — those are removed per-item from the offline manager. The old copy ('Remove every downloaded track. This cannot be undone.') was misleading. Relabels the row 'Clear cache', rewrites the description to say downloads are kept and point to the manager, and softens the toasts to 'Cache cleared' / 'Couldn't clear the cache'. 8 locales.

cc
2026-07-13 21:01:48 -06:00

192 lines
6.7 KiB
Plaintext

// Settings > Offline — two explicitly-titled groups (the Tauri tab hid
// this boundary; the owner endorsed the split):
//
// - OFFLINE MODE — the app operating without Qobuz: tri-state status row
// (online / no connection / induced) with an honest "Check now"
// re-probe, the persisted Enable Offline Mode toggle (#279 stream-first
// snapshot handled by the shared engine), and the network-folders
// policy toggle (mounted only while induced is on, Tauri parity).
// - OFFLINE CACHE — downloads: manager launch + open-folder / clear-all.
// The Local-Library rows (show-in-library, repair) arrive with the
// Local Library port.
//
// Same structure as the other settings panels (GroupHeader + SettingRow +
// SecondaryButton). Toggle changes bubble through settings-bool; the
// status row reads the live OfflineState global; the panel's init
// re-seeds the toggle states from the engine store (OfflineModeActions).
import { Theme } from "../foundation/semantic-colors.slint";
import { Palette } from "../foundation/palette.slint";
import { Typography } from "../foundation/typography.slint";
import { Radius } from "../foundation/radius.slint";
import { LyricsState, OfflineManagerActions, OfflineModeActions, OfflineState, SettingsState } from "../state.slint";
import { QbzToggle } from "../primitives/QbzToggle.slint";
import { SettingRow } from "SettingRow.slint";
component GroupHeader inherits Text {
color: Theme.text-muted;
font-size: 11px;
letter-spacing: 1.5px;
font-weight: Typography.semibold;
}
component Divider inherits Rectangle {
height: 1px;
background: Theme.border-subtle;
}
// Matches AudioSettings/AppearanceSettings' SecondaryButton.
component SecondaryButton inherits Rectangle {
in property <string> label;
in property <bool> danger: false;
in property <bool> enabled: true;
callback clicked();
// 160px floor keeps the settings right-edge grid; longer translations grow.
width: Math.max(label-txt.preferred-width + 32px, 160px);
height: 34px;
border-radius: Radius.sm;
border-width: 1px;
border-color: root.danger ? #e0564f : Theme.border-subtle;
background: ta.has-hover && root.enabled ? Theme.surface-hover : Theme.surface-elevated;
opacity: root.enabled ? 1.0 : 0.4;
label-txt := Text {
width: 100%;
height: 100%;
text: root.label;
color: root.danger ? #e0564f : Theme.text-secondary;
font-size: Typography.body;
font-weight: Typography.medium;
horizontal-alignment: center;
vertical-alignment: center;
}
ta := TouchArea {
mouse-cursor: root.enabled ? pointer : default;
clicked => {
if (root.enabled) {
root.clicked();
}
}
}
}
export component OfflineSettings inherits VerticalLayout {
callback settings-bool(string, bool);
spacing: 4px;
// Re-seed the toggle states from the engine store on every mount of
// this section (same lazy-load hook LocalLibrarySettings uses); also
// refresh the lyrics-cache stats for the LYRICS group below.
init => {
OfflineModeActions.load();
LyricsState.cache-refresh();
}
GroupHeader { text: @tr("OFFLINE MODE"); }
SettingRow {
label: @tr("Status");
description: OfflineState.captive-portal
? @tr("Captive portal detected — sign in to the network to get online.")
: "";
HorizontalLayout {
spacing: 16px;
VerticalLayout {
alignment: center;
// Tri-state: online green / real-offline amber / induced accent.
Text {
text: OfflineState.mode == 2 ? @tr("Offline mode enabled")
: OfflineState.mode == 1 ? @tr("No connection")
: @tr("Online");
color: OfflineState.mode == 2 ? Theme.accent
: OfflineState.mode == 1 ? Palette.warning
: #3fae6a;
font-size: Typography.body;
font-weight: Typography.medium;
}
}
SecondaryButton {
label: SettingsState.offline-checking ? @tr("Checking...") : @tr("Check now");
enabled: !SettingsState.offline-checking;
clicked => {
if (!SettingsState.offline-checking) {
OfflineModeActions.check-now();
}
}
}
}
}
SettingRow {
label: @tr("Enable Offline Mode");
description: @tr("Manually switch to offline mode even with internet.");
QbzToggle {
checked: SettingsState.offline-mode-enabled;
toggled(v) => {
SettingsState.offline-mode-enabled = v;
root.settings-bool("offline-mode-enabled", v);
}
}
}
Rectangle { height: 12px; }
Divider { }
Rectangle { height: 12px; }
GroupHeader { text: @tr("OFFLINE CACHE"); }
SettingRow {
label: @tr("Manage offline cache");
description: @tr("Browse and manage your downloaded tracks and albums.");
SecondaryButton {
label: @tr("Open manager");
clicked => {
OfflineManagerActions.open();
}
}
}
SettingRow {
label: @tr("Cache folder");
description: @tr("Open the folder where offline tracks are stored on disk.");
SecondaryButton {
label: @tr("Open folder");
clicked => {
OfflineManagerActions.open-folder();
}
}
}
SettingRow {
label: @tr("Clear cache");
description: @tr("Frees up cached data. Your downloaded albums are kept — remove those from the offline manager above.");
SecondaryButton {
label: @tr("Clear all");
danger: true;
clicked => {
OfflineManagerActions.clear-all();
}
}
}
Rectangle { height: 12px; }
Divider { }
Rectangle { height: 12px; }
// Lyrics cache (Tauri Settings > Storage row, SettingsView.svelte:6539-
// 6562). Stats come from the REAL per-user lyrics.db via qbz_lyrics
// cache_stats — fix-forward F1 (Tauri measured a stale global path).
GroupHeader { text: @tr("LYRICS"); }
SettingRow {
label: @tr("Clear lyrics cache");
description: LyricsState.cache-loaded
? @tr("{} entries using {}", LyricsState.cache-entries-text, LyricsState.cache-size)
: "";
SecondaryButton {
label: @tr("Clear");
danger: true;
clicked => {
LyricsState.cache-clear();
}
}
}
}