diff --git a/src/qml.qrc b/src/qml.qrc index 822f7c5..39c8ee5 100644 --- a/src/qml.qrc +++ b/src/qml.qrc @@ -15,6 +15,8 @@ qml/components/AddStationDialog.qml qml/components/EditStationDialog.qml qml/components/LoadingOverlay.qml + qml/components/ToastPopup.qml + qml/components/StationListPanel.qml qml/utils/FlagUtils.js diff --git a/src/qml/Main.qml b/src/qml/Main.qml index 750906c..a592ed5 100644 --- a/src/qml/Main.qml +++ b/src/qml/Main.qml @@ -31,10 +31,10 @@ ApplicationWindow { property string selectedWorldType: "" property string countrySearchText: "" property alias searchField: searchToolbar.searchField + property alias stationList: stationPanel.stationList function toast(message) { - toastLabel.text = message - toastPopup.open() + toastPopup.show(message) } function resetSearchFilter() { @@ -192,27 +192,11 @@ ApplicationWindow { app: root } - ScrollView { - id: stationScrollView + StationListPanel { + id: stationPanel Layout.fillWidth: true Layout.fillHeight: true - visible: !(currentPage === "world" && selectedWorldCategory === "") - clip: true - ScrollBar.vertical.policy: ScrollBar.AlwaysOn - - ListView { - id: stationList - width: stationScrollView.availableWidth - spacing: 8 - model: activeModel() - visible: count > 0 - - delegate: StationCard { - app: root - compactMode: root.compactMode - listWidth: stationScrollView.availableWidth - } - } + app: root } WorldCategories { @@ -223,23 +207,6 @@ ApplicationWindow { compactMode: root.compactMode } } - - Column { - anchors.centerIn: parent - spacing: 8 - visible: stationList.count === 0 && !(currentPage === "world" && selectedWorldCategory === "") - - Label { - text: currentPage === "history" ? qsTr("No playback history") : qsTr("No stations loaded yet") - color: BearTheme.textMain - font.bold: true - } - - Label { - text: currentPage === "history" ? qsTr("Play some stations to build history") : qsTr("Load DE/NL stations or use search") - color: BearTheme.textMuted - } - } } PlayerBar { @@ -275,30 +242,9 @@ ApplicationWindow { compactMode: root.compactMode } - Popup { + ToastPopup { id: toastPopup - x: (root.width - width) / 2 - y: root.height - height - 20 - padding: 10 - closePolicy: Popup.NoAutoClose - background: Rectangle { - radius: 10 - color: "#24364e" - border.color: BearTheme.accent - } - - contentItem: Label { - id: toastLabel - color: BearTheme.textMain - font.pixelSize: 12 - } - - Timer { - interval: 1400 - running: toastPopup.visible - repeat: false - onTriggered: toastPopup.close() - } + window: root } Timer { diff --git a/src/qml/components/StationListPanel.qml b/src/qml/components/StationListPanel.qml new file mode 100644 index 0000000..5ae17d1 --- /dev/null +++ b/src/qml/components/StationListPanel.qml @@ -0,0 +1,59 @@ +// 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 + +Item { + id: root + + required property var app + + property alias stationList: stationList + + readonly property bool showEmptyState: stationList.count === 0 + && !(app.currentPage === "world" && app.selectedWorldCategory === "") + + ScrollView { + id: stationScrollView + anchors.fill: parent + visible: !(app.currentPage === "world" && app.selectedWorldCategory === "") + clip: true + ScrollBar.vertical.policy: ScrollBar.AlwaysOn + + ListView { + id: stationList + width: stationScrollView.availableWidth + spacing: 8 + model: app.activeModel() + visible: count > 0 + + delegate: StationCard { + app: root.app + compactMode: root.app.compactMode + listWidth: stationScrollView.availableWidth + } + } + } + + Column { + anchors.centerIn: parent + spacing: 8 + visible: root.showEmptyState + + Label { + text: app.currentPage === "history" ? qsTr("No playback history") : qsTr("No stations loaded yet") + color: BearTheme.textMain + font.bold: true + } + + Label { + text: app.currentPage === "history" + ? qsTr("Play some stations to build history") + : qsTr("Load DE/NL stations or use search") + color: BearTheme.textMuted + } + } +} \ No newline at end of file diff --git a/src/qml/components/ToastPopup.qml b/src/qml/components/ToastPopup.qml new file mode 100644 index 0000000..26653b9 --- /dev/null +++ b/src/qml/components/ToastPopup.qml @@ -0,0 +1,42 @@ +// 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 + +Popup { + id: root + + required property var window + + padding: 10 + closePolicy: Popup.NoAutoClose + x: (window.width - width) / 2 + y: window.height - height - 20 + + function show(message) { + toastLabel.text = message + open() + } + + background: Rectangle { + radius: 10 + color: "#24364e" + border.color: BearTheme.accent + } + + contentItem: Label { + id: toastLabel + color: BearTheme.textMain + font.pixelSize: 12 + } + + Timer { + interval: 1400 + running: root.visible + repeat: false + onTriggered: root.close() + } +} \ No newline at end of file diff --git a/src/qml/components/qmldir b/src/qml/components/qmldir index 0c07e64..70e0b82 100644 --- a/src/qml/components/qmldir +++ b/src/qml/components/qmldir @@ -8,4 +8,6 @@ PlayerBar 1.0 PlayerBar.qml 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 +LoadingOverlay 1.0 LoadingOverlay.qml +ToastPopup 1.0 ToastPopup.qml +StationListPanel 1.0 StationListPanel.qml \ No newline at end of file