New OfflinePlaceholder (mode-aware copy + Open Settings shortcut for induced mode) mounted at the AppShell routing seam over the 12 Qobuz-only content views; the matching nav rows (sidebar, header tabs, compact rail) render disabled while offline instead of hiding (layout stability). Playback gains the offline playable rule (local always, plex only under induced, qobuz only when cached and within the subscription grace): explicit plays fast-fail with an honest toast (distinct copy when the grace expired), manual and auto advance skip unavailable tracks bounded by 5 consecutive (gapless target structurally exempt), gapless prefetch skips unplayable successors, and the network prefetch warmer pauses offline. cc
67 lines
2.5 KiB
Plaintext
67 lines
2.5 KiB
Plaintext
// Offline placeholder — mounted INSTEAD of the Qobuz-only content views
|
|
// while the app is offline (ADR-010 conditional mount at the AppShell
|
|
// routing seam, broader than Tauri's three gated view families). The body
|
|
// copy distinguishes real offline (no connectivity) from induced offline
|
|
// (the Settings toggle); induced adds an "Open Settings" shortcut straight
|
|
// to Settings > Offline so the user can flip the mode back off.
|
|
|
|
import { Theme } from "../foundation/semantic-colors.slint";
|
|
import { Typography } from "../foundation/typography.slint";
|
|
import { QbzIcon } from "../primitives/QbzIcon.slint";
|
|
import { SecondaryButton } from "../primitives/SecondaryButton.slint";
|
|
import { OfflineState, NavState, SettingsState } from "../state.slint";
|
|
|
|
export component OfflinePlaceholder inherits Rectangle {
|
|
background: Theme.surface-main;
|
|
|
|
// 2 = induced offline (OfflineState.mode semantics: 0 online / 1 real / 2 induced).
|
|
property <bool> induced: OfflineState.mode == 2;
|
|
|
|
VerticalLayout {
|
|
alignment: center;
|
|
HorizontalLayout {
|
|
alignment: center;
|
|
QbzIcon {
|
|
source: @image-url("../assets/icons/cloud-off.svg");
|
|
width: 56px;
|
|
height: 56px;
|
|
tint: Theme.text-muted;
|
|
}
|
|
}
|
|
Rectangle { height: 18px; }
|
|
Text {
|
|
text: @tr("You're offline");
|
|
color: Theme.text-primary;
|
|
font-size: Typography.heading;
|
|
font-weight: Typography.semibold;
|
|
horizontal-alignment: center;
|
|
}
|
|
Rectangle { height: 8px; }
|
|
HorizontalLayout {
|
|
alignment: center;
|
|
Text {
|
|
max-width: 420px;
|
|
text: root.induced
|
|
? @tr("Offline mode is enabled. Disable it in Settings to use Qobuz.")
|
|
: @tr("No internet connection. Your local library and downloads keep working.");
|
|
color: Theme.text-secondary;
|
|
font-size: Typography.body;
|
|
horizontal-alignment: center;
|
|
wrap: word-wrap;
|
|
}
|
|
}
|
|
if root.induced: Rectangle { height: 20px; }
|
|
if root.induced: HorizontalLayout {
|
|
alignment: center;
|
|
SecondaryButton {
|
|
label: @tr("Open Settings");
|
|
clicked => {
|
|
// Settings > Offline is section index 3 (SettingsView nav).
|
|
SettingsState.section = 3;
|
|
NavState.request-settings();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|