Polish beta release UI and branding

This commit is contained in:
Sebastian Palencsar
2026-05-20 19:27:43 +02:00
parent 0c717742c8
commit a172e62ef9
4 changed files with 328 additions and 14 deletions

View File

@@ -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:

BIN
assets/app/bearwave_line.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@@ -2,6 +2,7 @@
<qresource prefix="/">
<file alias="Main.qml">qml/Main.qml</file>
<file alias="assets/app/bearwave.png">../assets/app/bearwave.png</file>
<file alias="assets/app/bearwave_line.png">../assets/app/bearwave_line.png</file>
<file alias="assets/ui/globe.svg">../assets/ui/globe.svg</file>
<file alias="assets/ui/github.svg">../assets/ui/github.svg</file>
<file alias="assets/ui/linkedin.svg">../assets/ui/linkedin.svg</file>

View File

@@ -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"