From b0274c39d45f982c441c4d270806f5089c073ace Mon Sep 17 00:00:00 2001 From: vicrodh <103399283+vicrodh@users.noreply.github.com> Date: Wed, 3 Jun 2026 00:36:59 -0600 Subject: [PATCH] feat(qbz-slint): move QConnect diagnostics to Settings > Developer Relocate the QConnect diagnostics launcher out of the now-playing bar flyout into a new opt-in Settings > Developer section (the modal + DEV log/status code is unchanged). Also make the status block selectable (read-only TextEdit) so session_uuid etc. can be copied, and relabel the event log. cc --- .../ui/settings/DeveloperSettings.slint | 61 +++++++++++++++++++ .../qbz-slint/ui/settings/SettingsView.slint | 10 +++ crates/qbz-slint/ui/shell/PlayerBar.slint | 18 +----- .../qbz-slint/ui/shell/QconnectDevModal.slint | 23 +++---- 4 files changed, 84 insertions(+), 28 deletions(-) create mode 100644 crates/qbz-slint/ui/settings/DeveloperSettings.slint diff --git a/crates/qbz-slint/ui/settings/DeveloperSettings.slint b/crates/qbz-slint/ui/settings/DeveloperSettings.slint new file mode 100644 index 000000000..8e82365bd --- /dev/null +++ b/crates/qbz-slint/ui/settings/DeveloperSettings.slint @@ -0,0 +1,61 @@ +// Settings > Developer — opt-in home for developer/diagnostic tools. Same +// structure as the other settings panels (GroupHeader + SettingRow + a +// SecondaryButton). Currently launches the Qobuz Connect diagnostics modal +// (live session topology + rolling event log); more dev tools can land here. + +import { Theme } from "../foundation/semantic-colors.slint"; +import { Typography } from "../foundation/typography.slint"; +import { Radius } from "../foundation/radius.slint"; +import { QconnectDevState } from "../state.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 SecondaryButton inherits Rectangle { + in property label; + callback clicked(); + width: 160px; + height: 34px; + border-radius: Radius.sm; + border-width: 1px; + border-color: Theme.border-subtle; + background: ta.has-hover ? Theme.surface-hover : Theme.surface-elevated; + Text { + width: 100%; + height: 100%; + text: root.label; + color: Theme.text-secondary; + font-size: Typography.body; + font-weight: Typography.medium; + horizontal-alignment: center; + vertical-alignment: center; + } + ta := TouchArea { + mouse-cursor: pointer; + clicked => { + root.clicked(); + } + } +} + +export component DeveloperSettings inherits VerticalLayout { + spacing: 4px; + + GroupHeader { text: @tr("QOBUZ CONNECT"); } + + SettingRow { + label: @tr("Connect diagnostics"); + description: @tr("Live session topology and a rolling event log for debugging Qobuz Connect at runtime."); + SecondaryButton { + label: @tr("Open diagnostics"); + clicked => { + QconnectDevState.open = true; + } + } + } +} diff --git a/crates/qbz-slint/ui/settings/SettingsView.slint b/crates/qbz-slint/ui/settings/SettingsView.slint index 1ea406104..421c19fbd 100644 --- a/crates/qbz-slint/ui/settings/SettingsView.slint +++ b/crates/qbz-slint/ui/settings/SettingsView.slint @@ -16,6 +16,7 @@ import { PlaybackSettings } from "PlaybackSettings.slint"; import { AppearanceSettings } from "AppearanceSettings.slint"; import { OfflineSettings } from "OfflineSettings.slint"; import { LocalLibrarySettings } from "LocalLibrarySettings.slint"; +import { DeveloperSettings } from "DeveloperSettings.slint"; import { ScrollView } from "std-widgets.slint"; component SubNavItem inherits Rectangle { @@ -149,6 +150,14 @@ export component SettingsView inherits Rectangle { SettingsState.section = 4; } } + SubNavItem { + icon: @image-url("../assets/icons/bug.svg"); + label: @tr("Developer"); + active: SettingsState.section == 5; + clicked => { + SettingsState.section = 5; + } + } } } @@ -200,6 +209,7 @@ export component SettingsView inherits Rectangle { if !SettingsState.loading && SettingsState.section == 2: AppearanceSettings { } if !SettingsState.loading && SettingsState.section == 3: OfflineSettings { } if !SettingsState.loading && SettingsState.section == 4: LocalLibrarySettings { } + if !SettingsState.loading && SettingsState.section == 5: DeveloperSettings { } } } } diff --git a/crates/qbz-slint/ui/shell/PlayerBar.slint b/crates/qbz-slint/ui/shell/PlayerBar.slint index c0565e66e..ee2731865 100644 --- a/crates/qbz-slint/ui/shell/PlayerBar.slint +++ b/crates/qbz-slint/ui/shell/PlayerBar.slint @@ -19,7 +19,7 @@ import { IconButton, PlayButton } from "../primitives/BarControls.slint"; import { SeekBar } from "SeekBar.slint"; import { SongCard } from "SongCard.slint"; import { TransportControls } from "TransportControls.slint"; -import { NowPlayingState, ShellState, AppearanceState, SettingsState, TooltipState, QconnectDevState } from "../state.slint"; +import { NowPlayingState, ShellState, AppearanceState, SettingsState, TooltipState } from "../state.slint"; // IconButton + PlayButton now live in primitives/BarControls.slint (shared // with TransportControls). ConnectButton + ToggleRow stay local (bar-only). @@ -412,22 +412,6 @@ export component PlayerBar inherits Rectangle { vertical-alignment: center; } } - // DEV: open the QConnect diagnostics modal. - diag-ta := TouchArea { - height: 22px; - mouse-cursor: pointer; - clicked => { - QconnectDevState.open = true; - qconnect-menu.close(); - } - Text { - text: "Diagnostics"; - color: diag-ta.has-hover ? Theme.text-secondary : Theme.text-muted; - font-size: 11px; - horizontal-alignment: center; - vertical-alignment: center; - } - } } } } diff --git a/crates/qbz-slint/ui/shell/QconnectDevModal.slint b/crates/qbz-slint/ui/shell/QconnectDevModal.slint index 038c0249c..e8cd67048 100644 --- a/crates/qbz-slint/ui/shell/QconnectDevModal.slint +++ b/crates/qbz-slint/ui/shell/QconnectDevModal.slint @@ -74,23 +74,24 @@ export component QconnectDevModal inherits Rectangle { Rectangle { background: Theme.surface-elevated; border-radius: Radius.sm; - VerticalLayout { - padding: 12px; - Text { - text: QconnectDevState.status == "" - ? "Not connected." - : QconnectDevState.status; - color: Theme.text-secondary; - font-size: 12px; - wrap: word-wrap; - } + height: 140px; + clip: true; + TextEdit { + width: 100%; + height: 100%; + read-only: true; + wrap: word-wrap; + font-size: 12px; + text: QconnectDevState.status == "" + ? "Not connected." + : QconnectDevState.status; } } // Event-log header + clear. HorizontalLayout { Text { - text: "Event log"; + text: "Event log (newest first)"; color: Theme.text-primary; font-size: Typography.body; font-weight: Typography.semibold;