The pane was written fast and had drifted both ways: four whole sections were a placeholder reading "not ported to the Qt frontend yet", and what was there carried rows and copy Slint does not have — an invented custom-theme info row, made-up "Restart to apply" descriptions, dividers Integrations never had, and two buttons forked inline instead of using the shared control. Every section is real now, in Slint's order and grouping, with Slint's labels and control types: Audio, Playback, Appearance, Offline, Local Library, Blacklist, Integrations, Developer, and the sandbox section that only appears on a Flatpak or Snap install. Local Library brings the folder table and the Plex panel — 856 lines of Slint with no counterpart here until now — wired to the Plex store that landed earlier this round. Its PIN auth flow is not ported, so the manual server-url and token path is what this exposes. The rule the round was run under: a row whose key is not in settings_qt's dispatch renders and does nothing, so it is either wired or not shipped. "Share logs" was exactly that — present since the port began, inert — and now opens the on-disk log. The directory is per-section files under a thin composition root rather than one growing file, and the sub-nav's bottom spacer stops being arithmetic over a hardcoded row count, which broke the moment anyone added a section. cc
150 lines
5.5 KiB
QML
150 lines
5.5 KiB
QML
// Settings > Flatpak / Snap — the QML port of crates/qbz-ui/ui/settings/
|
|
// SandboxSettings.slint: the one-time permission commands a sandboxed
|
|
// install needs. Shown only when the process IS sandboxed
|
|
// (settings_qt/devtools.rs detects /.flatpak-info and $SNAP, the Slint's
|
|
// SandboxState.install-method).
|
|
//
|
|
// Commands are plain strings (never translated); the copy uses a hidden
|
|
// TextEdit's own clipboard (QML has no clipboard API of its own, and this
|
|
// port has no clipboard invokable to reuse).
|
|
|
|
import QtQuick
|
|
import com.blitzfc.qbz
|
|
import "../controls"
|
|
import "../theme"
|
|
|
|
Column {
|
|
id: root
|
|
|
|
property var doc: ({})
|
|
readonly property string method: (doc.dev || ({})).installMethod || ""
|
|
|
|
QbzTheme { id: theme }
|
|
|
|
spacing: 4
|
|
|
|
component RowTitle: Text {
|
|
width: parent ? parent.width : 0
|
|
color: theme.textPrimary
|
|
font.pixelSize: theme.fontBody
|
|
font.weight: theme.weightMedium
|
|
wrapMode: Text.WordWrap
|
|
}
|
|
component RowNote: Text {
|
|
width: parent ? parent.width : 0
|
|
color: theme.textMuted
|
|
font.pixelSize: theme.fontLegal
|
|
wrapMode: Text.WordWrap
|
|
}
|
|
// A full-width shell-command block with copy feedback. `command` may hold
|
|
// several lines; the whole block copies as one payload.
|
|
component CommandBlock: Rectangle {
|
|
id: block
|
|
property string command: ""
|
|
property bool copied: false
|
|
|
|
width: parent ? parent.width : 0
|
|
height: Math.max(54, cmdText.implicitHeight + 20)
|
|
radius: theme.radiusSm
|
|
border.width: 1
|
|
border.color: theme.borderSubtle
|
|
color: theme.surfaceElevated
|
|
|
|
Text {
|
|
id: cmdText
|
|
anchors.left: parent.left
|
|
anchors.right: copyBtn.left
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
anchors.leftMargin: 10
|
|
anchors.rightMargin: 12
|
|
text: block.command
|
|
color: theme.textPrimary
|
|
font.family: "monospace"
|
|
font.pixelSize: theme.fontLegal
|
|
wrapMode: Text.WrapAnywhere
|
|
}
|
|
// Off-screen carrier: TextEdit.copy() is the only clipboard write QML
|
|
// offers without a C++ seam.
|
|
TextEdit {
|
|
id: carrier
|
|
visible: false
|
|
text: block.command
|
|
}
|
|
SettingsButton {
|
|
id: copyBtn
|
|
anchors.right: parent.right
|
|
anchors.rightMargin: 10
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
text: block.copied ? QbzSession.tr("Copied!", QbzSession.trRev)
|
|
: QbzSession.tr("Copy", QbzSession.trRev)
|
|
onClicked: {
|
|
carrier.selectAll()
|
|
carrier.copy()
|
|
carrier.deselect()
|
|
block.copied = true
|
|
copiedTimer.restart()
|
|
}
|
|
}
|
|
Timer {
|
|
id: copiedTimer
|
|
interval: 1500
|
|
repeat: false
|
|
onTriggered: block.copied = false
|
|
}
|
|
}
|
|
|
|
// ============================== FLATPAK ==============================
|
|
Column {
|
|
visible: root.method === "flatpak"
|
|
width: parent.width
|
|
spacing: 4
|
|
|
|
GroupHeader { text: QbzSession.tr("FLATPAK SANDBOX", QbzSession.trRev) }
|
|
RowNote {
|
|
text: QbzSession.tr("QBZ is running inside a Flatpak sandbox. Some features need one-time permission grants — run the commands in a terminal, then restart QBZ. Grants persist across updates.", QbzSession.trRev)
|
|
}
|
|
Item { width: 1; height: 8 }
|
|
|
|
RowTitle { text: QbzSession.tr("Exclusive DAC access (bit-perfect)", QbzSession.trRev) }
|
|
RowNote {
|
|
text: QbzSession.tr("Recommended for exclusive mode: lets QBZ ask PipeWire to hand over the DAC cleanly (D-Bus device reservation). Without it, PipeWire keeps holding the DAC and other apps keep mixing through it even with ALSA + hw + Exclusive selected.", QbzSession.trRev)
|
|
}
|
|
CommandBlock {
|
|
command: "flatpak override --user --own-name=org.freedesktop.ReserveDevice1.* com.blitzfc.qbz"
|
|
}
|
|
Item { width: 1; height: 8 }
|
|
|
|
RowTitle { text: QbzSession.tr("Music on NAS or external drives", QbzSession.trRev) }
|
|
RowNote {
|
|
text: QbzSession.tr("Grants access to a folder outside the sandbox. Repeat the command for each folder you need.", QbzSession.trRev)
|
|
}
|
|
CommandBlock {
|
|
command: "flatpak override --user --filesystem=/path/to/your/music com.blitzfc.qbz"
|
|
}
|
|
}
|
|
|
|
// ================================ SNAP ===============================
|
|
Column {
|
|
visible: root.method === "snap"
|
|
width: parent.width
|
|
spacing: 4
|
|
|
|
GroupHeader { text: QbzSession.tr("SNAP SANDBOX", QbzSession.trRev) }
|
|
RowNote {
|
|
text: QbzSession.tr("QBZ is running inside a Snap sandbox. Some audio interfaces need one-time connections — run these commands in a terminal, then restart QBZ.", QbzSession.trRev)
|
|
}
|
|
Item { width: 1; height: 8 }
|
|
|
|
RowTitle { text: QbzSession.tr("Required audio connections", QbzSession.trRev) }
|
|
CommandBlock {
|
|
command: "sudo snap connect qbz-player:alsa\nsudo snap connect qbz-player:pulseaudio\nsudo snap connect qbz-player:pipewire\nsudo snap connect qbz-player:mpris"
|
|
}
|
|
Item { width: 1; height: 8 }
|
|
|
|
RowTitle { text: QbzSession.tr("Optional — external drives & NAS", QbzSession.trRev) }
|
|
CommandBlock {
|
|
command: "sudo snap connect qbz-player:removable-media"
|
|
}
|
|
}
|
|
}
|