From dfc98de0771037dd0381b1b95fb202dcf5187dce Mon Sep 17 00:00:00 2001 From: Sebastian Palencsar Date: Sat, 20 Jun 2026 14:24:25 +0200 Subject: [PATCH] refactor(qml): extract dialogs and loading overlay from Main.qml Add AddStationDialog, EditStationDialog, and LoadingOverlay components. Main.qml shrinks to ~325 lines; dialog IDs and app.editDialog API unchanged. --- src/qml.qrc | 3 + src/qml/Main.qml | 105 ++--------------------- src/qml/components/AddStationDialog.qml | 36 ++++++++ src/qml/components/EditStationDialog.qml | 54 ++++++++++++ src/qml/components/LoadingOverlay.qml | 45 ++++++++++ src/qml/components/qmldir | 5 +- 6 files changed, 150 insertions(+), 98 deletions(-) create mode 100644 src/qml/components/AddStationDialog.qml create mode 100644 src/qml/components/EditStationDialog.qml create mode 100644 src/qml/components/LoadingOverlay.qml diff --git a/src/qml.qrc b/src/qml.qrc index bdcaac2..822f7c5 100644 --- a/src/qml.qrc +++ b/src/qml.qrc @@ -12,6 +12,9 @@ qml/components/WorldCategories.qml qml/components/PlayerBar.qml qml/components/AboutDialog.qml + qml/components/AddStationDialog.qml + qml/components/EditStationDialog.qml + qml/components/LoadingOverlay.qml qml/utils/FlagUtils.js diff --git a/src/qml/Main.qml b/src/qml/Main.qml index 0ccddbf..750906c 100644 --- a/src/qml/Main.qml +++ b/src/qml/Main.qml @@ -248,38 +248,8 @@ ApplicationWindow { } } - Rectangle { - visible: backend && backend.loading - anchors.fill: parent - color: "#7f0b121a" - z: 20 - - Rectangle { - anchors.centerIn: parent - width: 210 - height: 110 - radius: 12 - color: BearTheme.panel - border.color: BearTheme.cardBorder - - Column { - anchors.centerIn: parent - spacing: 10 - - BusyIndicator { - running: true - width: 36 - height: 36 - anchors.horizontalCenter: parent.horizontalCenter - } - - Label { - text: qsTr("Loading stations...") - color: BearTheme.textMain - anchors.horizontalCenter: parent.horizontalCenter - } - } - } + LoadingOverlay { + app: root } Component.onCompleted: { @@ -288,75 +258,16 @@ ApplicationWindow { } } - Dialog { + AddStationDialog { id: addDialog - title: qsTr("Add station manually") - modal: true - anchors.centerIn: parent - width: compactMode ? 320 : 420 - standardButtons: Dialog.Ok | Dialog.Cancel - - contentItem: ColumnLayout { - spacing: 8 - TextField { id: manualName; Layout.fillWidth: true; placeholderText: qsTr("Name") } - TextField { id: manualUrl; Layout.fillWidth: true; placeholderText: qsTr("Stream URL (http/https)") } - TextField { id: manualCountry; Layout.fillWidth: true; placeholderText: qsTr("Country (optional)") } - } - - onAccepted: { - if (backend) { - backend.addManualStation(manualName.text, manualUrl.text, manualCountry.text) - toast(qsTr("Station added")) - } - manualName.text = "" - manualUrl.text = "" - manualCountry.text = "" - } + app: root + compactMode: root.compactMode } - Dialog { + EditStationDialog { id: editDialog - title: qsTr("Edit station") - modal: true - anchors.centerIn: parent - width: compactMode ? 320 : 420 - standardButtons: Dialog.Ok | Dialog.Cancel - - property var stationObject: null - - contentItem: ColumnLayout { - spacing: 8 - TextField { id: editName; Layout.fillWidth: true; placeholderText: qsTr("Name") } - TextField { id: editUrl; Layout.fillWidth: true; placeholderText: qsTr("Stream URL (http/https)") } - TextField { id: editCountry; Layout.fillWidth: true; placeholderText: qsTr("Country (optional)") } - } - - function setupAndOpen() { - if (stationObject) { - editName.text = stationObject.name || "" - editUrl.text = stationObject.url || "" - editCountry.text = (stationObject.country === qsTr("Manual") ? "" : (stationObject.country || "")) - open() - } - } - - onAccepted: { - if (backend && stationObject) { - backend.editManualStation(stationObject, editName.text, editUrl.text, editCountry.text) - toast(qsTr("Station updated")) - } - stationObject = null - editName.text = "" - editUrl.text = "" - editCountry.text = "" - } - - onRejected: { - stationObject = null - editName.text = "" - editUrl.text = "" - editCountry.text = "" - } + app: root + compactMode: root.compactMode } AboutDialog { diff --git a/src/qml/components/AddStationDialog.qml b/src/qml/components/AddStationDialog.qml new file mode 100644 index 0000000..c639cbc --- /dev/null +++ b/src/qml/components/AddStationDialog.qml @@ -0,0 +1,36 @@ +// Copyright (c) 2026 Sebastian Palencsar +// SPDX-License-Identifier: GPL-3.0-or-later + +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 + +Dialog { + id: root + + required property var app + required property bool compactMode + + title: qsTr("Add station manually") + modal: true + anchors.centerIn: parent + width: compactMode ? 320 : 420 + standardButtons: Dialog.Ok | Dialog.Cancel + + contentItem: ColumnLayout { + spacing: 8 + TextField { id: manualName; Layout.fillWidth: true; placeholderText: qsTr("Name") } + TextField { id: manualUrl; Layout.fillWidth: true; placeholderText: qsTr("Stream URL (http/https)") } + TextField { id: manualCountry; Layout.fillWidth: true; placeholderText: qsTr("Country (optional)") } + } + + onAccepted: { + if (app.backend) { + app.backend.addManualStation(manualName.text, manualUrl.text, manualCountry.text) + app.toast(qsTr("Station added")) + } + manualName.text = "" + manualUrl.text = "" + manualCountry.text = "" + } +} \ No newline at end of file diff --git a/src/qml/components/EditStationDialog.qml b/src/qml/components/EditStationDialog.qml new file mode 100644 index 0000000..6b4e704 --- /dev/null +++ b/src/qml/components/EditStationDialog.qml @@ -0,0 +1,54 @@ +// Copyright (c) 2026 Sebastian Palencsar +// SPDX-License-Identifier: GPL-3.0-or-later + +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 + +Dialog { + id: root + + required property var app + required property bool compactMode + + property var stationObject: null + + title: qsTr("Edit station") + modal: true + anchors.centerIn: parent + width: compactMode ? 320 : 420 + standardButtons: Dialog.Ok | Dialog.Cancel + + contentItem: ColumnLayout { + spacing: 8 + TextField { id: editName; Layout.fillWidth: true; placeholderText: qsTr("Name") } + TextField { id: editUrl; Layout.fillWidth: true; placeholderText: qsTr("Stream URL (http/https)") } + TextField { id: editCountry; Layout.fillWidth: true; placeholderText: qsTr("Country (optional)") } + } + + function setupAndOpen() { + if (stationObject) { + editName.text = stationObject.name || "" + editUrl.text = stationObject.url || "" + editCountry.text = (stationObject.country === qsTr("Manual") ? "" : (stationObject.country || "")) + open() + } + } + + function clearFields() { + stationObject = null + editName.text = "" + editUrl.text = "" + editCountry.text = "" + } + + onAccepted: { + if (app.backend && stationObject) { + app.backend.editManualStation(stationObject, editName.text, editUrl.text, editCountry.text) + app.toast(qsTr("Station updated")) + } + clearFields() + } + + onRejected: clearFields() +} \ No newline at end of file diff --git a/src/qml/components/LoadingOverlay.qml b/src/qml/components/LoadingOverlay.qml new file mode 100644 index 0000000..2201cee --- /dev/null +++ b/src/qml/components/LoadingOverlay.qml @@ -0,0 +1,45 @@ +// Copyright (c) 2026 Sebastian Palencsar +// SPDX-License-Identifier: GPL-3.0-or-later + +import QtQuick 2.15 +import QtQuick.Controls 2.15 + +import theme 1.0 + +Rectangle { + id: root + + required property var app + + visible: app.backend && app.backend.loading + anchors.fill: parent + color: "#7f0b121a" + z: 20 + + Rectangle { + anchors.centerIn: parent + width: 210 + height: 110 + radius: 12 + color: BearTheme.panel + border.color: BearTheme.cardBorder + + Column { + anchors.centerIn: parent + spacing: 10 + + BusyIndicator { + running: true + width: 36 + height: 36 + anchors.horizontalCenter: parent.horizontalCenter + } + + Label { + text: qsTr("Loading stations...") + color: BearTheme.textMain + anchors.horizontalCenter: parent.horizontalCenter + } + } + } +} \ No newline at end of file diff --git a/src/qml/components/qmldir b/src/qml/components/qmldir index 0cee098..0c07e64 100644 --- a/src/qml/components/qmldir +++ b/src/qml/components/qmldir @@ -5,4 +5,7 @@ StationCard 1.0 StationCard.qml WorldCategoryHeader 1.0 WorldCategoryHeader.qml WorldCategories 1.0 WorldCategories.qml PlayerBar 1.0 PlayerBar.qml -AboutDialog 1.0 AboutDialog.qml \ No newline at end of file +AboutDialog 1.0 AboutDialog.qml +AddStationDialog 1.0 AddStationDialog.qml +EditStationDialog 1.0 EditStationDialog.qml +LoadingOverlay 1.0 LoadingOverlay.qml \ No newline at end of file