From a172e62ef979ffc372770ddec3e9af106aa342fd Mon Sep 17 00:00:00 2001 From: Sebastian Palencsar Date: Wed, 20 May 2026 19:27:43 +0200 Subject: [PATCH] Polish beta release UI and branding --- README.md | 2 + assets/app/bearwave_line.png | Bin 0 -> 31356 bytes src/qml.qrc | 1 + src/qml/Main.qml | 339 +++++++++++++++++++++++++++++++++-- 4 files changed, 328 insertions(+), 14 deletions(-) create mode 100755 assets/app/bearwave_line.png diff --git a/README.md b/README.md index 022404d..da2dd01 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,8 @@ BearWave intentionally does not aim to be: BearWave is an early public, source-first desktop project. +BearWave is currently in public beta and is best supported on Arch Linux and KDE Plasma. + It is already usable, but it should currently be treated as software for testers, contributors, and technically comfortable Linux users rather than a polished end-user release. Current priorities: diff --git a/assets/app/bearwave_line.png b/assets/app/bearwave_line.png new file mode 100755 index 0000000000000000000000000000000000000000..cb4f9617da3128765600a52c6c1a6190674bd2e4 GIT binary patch literal 31356 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

4=|0{)vEWL<<~s;XCpanW;%``~HiKCau7 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 qml/Main.qml ../assets/app/bearwave.png + ../assets/app/bearwave_line.png ../assets/ui/globe.svg ../assets/ui/github.svg ../assets/ui/linkedin.svg diff --git a/src/qml/Main.qml b/src/qml/Main.qml index 1e491e4..cdde6cf 100644 --- a/src/qml/Main.qml +++ b/src/qml/Main.qml @@ -127,24 +127,26 @@ ApplicationWindow { Rectangle { Layout.fillWidth: true - Layout.preferredHeight: compactMode ? 208 : 176 + Layout.preferredHeight: compactMode ? (headerContent.implicitHeight + 20) : 176 radius: 12 color: panel border.color: cardBorder ColumnLayout { + id: headerContent anchors.fill: parent anchors.margins: 10 spacing: 8 RowLayout { + visible: !compactMode Layout.fillWidth: true spacing: 8 Image { - Layout.preferredWidth: compactMode ? 88 : 112 - Layout.preferredHeight: compactMode ? 32 : 40 - source: "qrc:/assets/app/bearwave.png" + Layout.preferredWidth: 112 + Layout.preferredHeight: 40 + source: "qrc:/assets/app/bearwave_line.png" fillMode: Image.PreserveAspectFit smooth: true mipmap: true @@ -222,7 +224,98 @@ ApplicationWindow { } } + ColumnLayout { + visible: compactMode + Layout.fillWidth: true + spacing: 8 + + RowLayout { + Layout.fillWidth: true + spacing: 8 + + Image { + Layout.preferredWidth: 96 + Layout.preferredHeight: 34 + source: "qrc:/assets/app/bearwave_line.png" + fillMode: Image.PreserveAspectFit + smooth: true + mipmap: true + } + + Item { Layout.fillWidth: true } + + Button { + text: "+" + onClicked: addDialog.open() + } + + Button { + text: qsTr("About") + onClicked: aboutDialog.open() + } + + Button { + visible: backend && backend.canResumeLastStation + text: "↺" + onClicked: { + if (backend) { + backend.resumeLastStation() + } + } + } + } + + Flow { + Layout.fillWidth: true + width: parent.width + spacing: 8 + + Button { + text: qsTr("Top") + highlighted: currentPage === "top" + onClicked: { + if (!backend) return + currentPage = "top" + activeQuickFilter = "" + backend.loadTopStations() + } + } + + Button { + text: qsTr("DE") + highlighted: currentPage === "german" + onClicked: { + if (!backend) return + currentPage = "german" + activeQuickFilter = "" + backend.loadGermanStations() + } + } + + Button { + text: qsTr("NL") + highlighted: currentPage === "dutch" + onClicked: { + if (!backend) return + currentPage = "dutch" + activeQuickFilter = "" + backend.loadDutchStations() + } + } + + Button { + text: qsTr("Favorites") + highlighted: currentPage === "favorites" + onClicked: { + currentPage = "favorites" + activeQuickFilter = "" + } + } + } + } + RowLayout { + visible: !compactMode Layout.fillWidth: true spacing: 8 @@ -280,15 +373,93 @@ ApplicationWindow { } } + ColumnLayout { + visible: compactMode + Layout.fillWidth: true + spacing: 8 + + TextField { + id: compactSearchField + Layout.fillWidth: true + placeholderText: qsTr("Search stations (name, genre, country)") + text: searchField.text + onTextChanged: { + if (searchField.text !== text) { + searchField.text = text + } + if (backend) { + backend.filterQuery = text + } + } + onAccepted: { + if (text.length < 2 || !backend) return + currentPage = "search" + backend.searchStations(text) + } + } + + RowLayout { + Layout.fillWidth: true + spacing: 8 + + Item { Layout.fillWidth: true } + + Button { + text: qsTr("Search") + highlighted: true + onClicked: { + if (compactSearchField.text.length < 2 || !backend) return + currentPage = "search" + backend.searchStations(compactSearchField.text) + } + } + } + + Flow { + Layout.fillWidth: true + width: parent.width + spacing: 8 + + Button { + text: "A-Z" + onClicked: { + if (backend && currentPage !== "favorites") { + backend.sortStations("name") + } + } + } + + Button { + text: "kb" + onClicked: { + if (backend && currentPage !== "favorites") { + backend.sortStations("bitrate") + } + } + } + + Button { + text: "❤" + onClicked: { + if (backend && currentPage !== "favorites") { + backend.sortStations("votes") + } + } + } + } + } + Label { Layout.fillWidth: true text: qsTr("Tip: you are not limited to DE/NL. Search worldwide by country, genre, or station name.") color: textMuted font.pixelSize: 11 - elide: Text.ElideRight + wrapMode: compactMode ? Text.WordWrap : Text.NoWrap + elide: compactMode ? Text.ElideNone : Text.ElideRight } RowLayout { + visible: !compactMode Layout.fillWidth: true spacing: 6 @@ -386,6 +557,117 @@ ApplicationWindow { Item { Layout.fillWidth: true } } + ColumnLayout { + visible: compactMode + Layout.fillWidth: true + spacing: 8 + + Flow { + Layout.fillWidth: true + width: parent.width + spacing: 8 + + Label { + text: qsTr("Genre:") + color: textMuted + font.pixelSize: 11 + verticalAlignment: Text.AlignVCenter + padding: 8 + } + + Button { + text: qsTr("Rock") + highlighted: activeQuickFilter === "tag:rock" + onClicked: { + if (!backend) return + currentPage = "genre-rock" + activeQuickFilter = "tag:rock" + backend.loadByTag("rock") + } + } + + Button { + text: qsTr("News") + highlighted: activeQuickFilter === "tag:news" + onClicked: { + if (!backend) return + currentPage = "genre-news" + activeQuickFilter = "tag:news" + backend.loadByTag("news") + } + } + + Button { + text: qsTr("Jazz") + highlighted: activeQuickFilter === "tag:jazz" + onClicked: { + if (!backend) return + currentPage = "genre-jazz" + activeQuickFilter = "tag:jazz" + backend.loadByTag("jazz") + } + } + } + + Flow { + Layout.fillWidth: true + width: parent.width + spacing: 8 + + Label { + text: qsTr("Country:") + color: textMuted + font.pixelSize: 11 + verticalAlignment: Text.AlignVCenter + padding: 8 + } + + Button { + text: qsTr("US") + highlighted: activeQuickFilter === "cc:US" + onClicked: { + if (!backend) return + currentPage = "country-us" + activeQuickFilter = "cc:US" + backend.loadByCountryCode("US") + } + } + + Button { + text: qsTr("UK") + highlighted: activeQuickFilter === "cc:GB" + onClicked: { + if (!backend) return + currentPage = "country-gb" + activeQuickFilter = "cc:GB" + backend.loadByCountryCode("GB") + } + } + + Button { + text: qsTr("FR") + highlighted: activeQuickFilter === "cc:FR" + onClicked: { + if (!backend) return + currentPage = "country-fr" + activeQuickFilter = "cc:FR" + backend.loadByCountryCode("FR") + } + } + + Button { + text: qsTr("WORLD") + highlighted: activeQuickFilter === "world" + onClicked: { + if (!backend) return + currentPage = "world" + activeQuickFilter = "world" + backend.loadWorldStations() + } + } + } + } + Label { Layout.fillWidth: true visible: backend && backend.lastError.length > 0 @@ -782,6 +1064,14 @@ ApplicationWindow { color: textMuted font.pixelSize: 14 } + + Label { + Layout.alignment: Qt.AlignHCenter + text: qsTr("Public beta") + color: accent + font.pixelSize: 12 + font.bold: true + } } // --- CREDITS & LINKS --- @@ -806,12 +1096,19 @@ ApplicationWindow { ToolButton { Layout.preferredWidth: 40 Layout.preferredHeight: 40 - icon.source: "qrc:/assets/ui/globe.svg" - icon.width: 19 - icon.height: 19 onClicked: Qt.openUrlExternally("https://palencsar.pro") ToolTip.visible: hovered ToolTip.text: qsTr("Open website") + contentItem: Item { + Image { + anchors.centerIn: parent + width: 19 + height: 19 + source: "qrc:/assets/ui/globe.svg" + fillMode: Image.PreserveAspectFit + smooth: true + } + } background: Rectangle { radius: 20 color: parent.hovered ? "#274261" : "#1f3147" @@ -823,12 +1120,19 @@ ApplicationWindow { ToolButton { Layout.preferredWidth: 40 Layout.preferredHeight: 40 - icon.source: "qrc:/assets/ui/github.svg" - icon.width: 19 - icon.height: 19 onClicked: Qt.openUrlExternally("https://github.com/spalencsar") ToolTip.visible: hovered ToolTip.text: qsTr("Open GitHub") + contentItem: Item { + Image { + anchors.centerIn: parent + width: 19 + height: 19 + source: "qrc:/assets/ui/github.svg" + fillMode: Image.PreserveAspectFit + smooth: true + } + } background: Rectangle { radius: 20 color: parent.hovered ? "#274261" : "#1f3147" @@ -840,12 +1144,19 @@ ApplicationWindow { ToolButton { Layout.preferredWidth: 40 Layout.preferredHeight: 40 - icon.source: "qrc:/assets/ui/linkedin.svg" - icon.width: 19 - icon.height: 19 onClicked: Qt.openUrlExternally("https://www.linkedin.com/in/spalencsar/") ToolTip.visible: hovered ToolTip.text: qsTr("Open LinkedIn") + contentItem: Item { + Image { + anchors.centerIn: parent + width: 19 + height: 19 + source: "qrc:/assets/ui/linkedin.svg" + fillMode: Image.PreserveAspectFit + smooth: true + } + } background: Rectangle { radius: 20 color: parent.hovered ? "#274261" : "#1f3147"