The six local SecondaryButton/ManageButton copies in the settings panels and the two inline AudioSettings buttons had fixed widths sized for English; Spanish/French/German labels overflowed the borders. Width is now Math.max(label preferred-width + padding, old floor), so short labels keep the 160/170/200px right-edge grid and long translations grow leftward instead of overflowing. cc
192 lines
6.7 KiB
Plaintext
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 offline cache");
|
|
description: @tr("Remove every downloaded track. This cannot be undone.");
|
|
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();
|
|
}
|
|
}
|
|
}
|
|
}
|