Skip to content

Commit 6fa80bd

Browse files
dashboard: lyrics enhancements (caelestia-dots#1321)
* dual lrc file search strategies, UI adjustments * qml conventions & order * format --------- Co-authored-by: 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>
1 parent 9c34c23 commit 6fa80bd

4 files changed

Lines changed: 255 additions & 118 deletions

File tree

config/Config.qml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,8 @@ Singleton {
363363
smartScheme: services.smartScheme,
364364
defaultPlayer: services.defaultPlayer,
365365
playerAliases: services.playerAliases,
366-
showLyrics: services.showLyrics
366+
showLyrics: services.showLyrics,
367+
lyricsBackend: services.lyricsBackend
367368
};
368369
}
369370

config/ServiceConfig.qml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@ JsonObject {
1919
"to": "YT Music"
2020
}
2121
]
22-
property bool showLyrics: true
22+
property bool showLyrics: false
23+
property string lyricsBackend: "Auto"
2324
}

modules/dashboard/LyricMenu.qml

Lines changed: 174 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ StyledRect {
3232
anchors.margins: Appearance.padding.large
3333
spacing: Appearance.spacing.normal
3434

35-
// Header: icon, backend name, refresh, toggle
35+
// Header: icon, backend selector, refresh, toggle
3636
RowLayout {
3737
Layout.fillWidth: true
3838
spacing: Appearance.padding.small
@@ -44,12 +44,49 @@ StyledRect {
4444
font.pointSize: Appearance.spacing.large
4545
}
4646

47-
StyledText {
47+
Rectangle {
48+
Layout.preferredHeight: 24
49+
Layout.preferredWidth: 80
50+
radius: Appearance.rounding.small
51+
color: Qt.rgba(Colours.palette.m3primary.r, Colours.palette.m3primary.g, Colours.palette.m3primary.b, 0.15)
52+
53+
StyledText {
54+
anchors.centerIn: parent
55+
text: LyricsService.preferredBackend
56+
font.pointSize: Appearance.font.size.small
57+
color: Colours.palette.m3primary
58+
}
59+
60+
MouseArea {
61+
anchors.fill: parent
62+
cursorShape: Qt.PointingHandCursor
63+
onClicked: {
64+
const backends = ["Auto", "Local", "NetEase"];
65+
const currentIndex = backends.indexOf(LyricsService.preferredBackend);
66+
const nextIndex = (currentIndex + 1) % backends.length;
67+
LyricsService.preferredBackend = backends[nextIndex];
68+
LyricsService.loadLyrics();
69+
}
70+
}
71+
}
72+
73+
Rectangle {
74+
Layout.preferredHeight: 24
75+
Layout.preferredWidth: 60
76+
radius: Appearance.rounding.small
77+
visible: LyricsService.preferredBackend === "Auto"
78+
color: LyricsService.backend === "Local" ? Qt.rgba(Colours.palette.m3tertiary.r, Colours.palette.m3tertiary.g, Colours.palette.m3tertiary.b, 0.15) : Qt.rgba(Colours.palette.m3secondary.r, Colours.palette.m3secondary.g, Colours.palette.m3secondary.b, 0.15)
79+
80+
StyledText {
81+
anchors.centerIn: parent
82+
text: LyricsService.backend
83+
font.pointSize: Appearance.font.size.small
84+
color: LyricsService.backend === "Local" ? Colours.palette.m3tertiary : Colours.palette.m3secondary
85+
}
86+
}
87+
88+
Item {
4889
Layout.fillWidth: true
49-
text: LyricsService.backend
50-
font.pointSize: Appearance.font.size.normal
51-
color: Colours.palette.m3secondary
52-
elide: Text.ElideRight
5390
}
5491

5592
IconButton {
@@ -66,117 +103,141 @@ StyledRect {
66103

67104
StyledText {
68105
Layout.fillWidth: true
69-
text: "Fetched Candidates:"
106+
text: LyricsService.preferredBackend === "Local" ? "Loaded File:" : "Fetched Candidates:"
70107
color: Colours.palette.m3outline
71108
font.pointSize: Appearance.font.size.small
72109
elide: Text.ElideRight
110+
visible: LyricsService.preferredBackend === "Local" ? LyricsService.loadedLocalFile.length > 0 : LyricsService.candidatesModel.count > 0
73111
}
74112

75-
// Candidates list
76-
ListView {
77-
id: candidatesView
78-
113+
// Local file info (shown in Local mode)
114+
Rectangle {
79115
Layout.fillWidth: true
80-
Layout.fillHeight: true
116+
Layout.preferredHeight: 48
117+
visible: LyricsService.preferredBackend === "Local" && LyricsService.loadedLocalFile.length > 0
118+
radius: Appearance.rounding.small
119+
color: Qt.rgba(Colours.palette.m3tertiary.r, Colours.palette.m3tertiary.g, Colours.palette.m3tertiary.b, 0.1)
120+
121+
ColumnLayout {
122+
anchors.fill: parent
123+
anchors.margins: Appearance.padding.small
124+
spacing: 0
81125

82-
visible: LyricsService.candidatesModel.count > 0
83-
model: LyricsService.candidatesModel
84-
clip: true
85-
spacing: Appearance.spacing.small
86-
87-
opacity: visible ? 1 : 0
88-
// Behavior on opacity {
89-
// NumberAnimation { duration: Appearance.anim.durations.normal }
90-
// }
91-
92-
delegate: Item {
93-
id: delegateRoot
94-
95-
required property real id
96-
required property string title
97-
required property string artist
98-
property bool hovered: false
99-
property bool pressed: false
100-
101-
width: ListView.view.width * 0.98
102-
height: 70
103-
anchors.horizontalCenter: parent?.horizontalCenter
104-
scale: hovered ? 1.02 : 1.0
105-
106-
Behavior on scale {
107-
NumberAnimation {
108-
duration: Appearance.anim.durations.small
109-
easing.type: Easing.OutCubic
126+
StyledText {
127+
Layout.fillWidth: true
128+
text: {
129+
const path = LyricsService.loadedLocalFile;
130+
const parts = path.split('/');
131+
return parts[parts.length - 1];
110132
}
133+
font.pointSize: Appearance.font.size.small
134+
color: Colours.palette.m3tertiary
135+
elide: Text.ElideMiddle
111136
}
112137

113-
Rectangle {
114-
id: background
138+
StyledText {
139+
Layout.fillWidth: true
140+
text: {
141+
const path = LyricsService.loadedLocalFile;
142+
const parts = path.split('/');
143+
if (parts.length > 2) {
144+
return parts.slice(-3, -1).join('/');
145+
}
146+
return "";
147+
}
148+
font.pointSize: Appearance.font.size.small
149+
color: Colours.palette.m3outline
150+
elide: Text.ElideMiddle
151+
}
152+
}
153+
}
115154

116-
anchors.fill: parent
117-
radius: Appearance.rounding.small
155+
// Candidates list
156+
Loader {
157+
Layout.fillWidth: true
158+
Layout.fillHeight: true
118159

119-
color: delegateRoot.pressed ? Qt.rgba(Colours.palette.m3primary.r, Colours.palette.m3primary.g, Colours.palette.m3primary.b, 0.25) : delegateRoot.hovered ? Qt.rgba(Colours.palette.m3primary.r, Colours.palette.m3primary.g, Colours.palette.m3primary.b, 0.06) : Qt.rgba(Colours.palette.m3primary.r, Colours.palette.m3primary.g, Colours.palette.m3primary.b, 0.03)
160+
active: LyricsService.preferredBackend !== "Local"
120161

121-
border.width: delegateRoot.hovered ? 1 : 0
122-
border.color: Colours.palette.m3primary
162+
sourceComponent: ListView {
163+
id: candidatesView
123164

124-
Behavior on color {
125-
ColorAnimation {
126-
duration: Appearance.anim.durations.small
127-
}
128-
}
129-
Behavior on border.width {
165+
model: LyricsService.candidatesModel
166+
clip: true
167+
spacing: Appearance.spacing.small
168+
visible: LyricsService.candidatesModel.count > 0
169+
opacity: visible ? 1 : 0
170+
171+
delegate: Item {
172+
id: delegateRoot
173+
174+
required property real id
175+
required property string title
176+
required property string artist
177+
178+
property bool hovered: false
179+
property bool pressed: false
180+
181+
width: ListView.view.width * 0.98
182+
height: 70
183+
184+
anchors.horizontalCenter: parent?.horizontalCenter
185+
scale: hovered ? 1.02 : 1.0
186+
187+
Behavior on scale {
130188
NumberAnimation {
131189
duration: Appearance.anim.durations.small
190+
easing.type: Easing.OutCubic
132191
}
133192
}
134-
}
135193

136-
MouseArea {
137-
anchors.fill: parent
138-
hoverEnabled: true
139-
cursorShape: Qt.PointingHandCursor
194+
Rectangle {
195+
id: background
140196

141-
onEntered: delegateRoot.hovered = true
142-
onExited: delegateRoot.hovered = false
143-
onPressed: delegateRoot.pressed = true
144-
onReleased: delegateRoot.pressed = false
145-
onClicked: LyricsService.selectCandidate(delegateRoot.id)
146-
}
197+
anchors.fill: parent
198+
radius: Appearance.rounding.small
147199

148-
Row {
149-
anchors.fill: parent
150-
anchors.margins: Appearance.padding.normal
151-
spacing: Appearance.spacing.small
200+
color: delegateRoot.pressed ? Qt.rgba(Colours.palette.m3primary.r, Colours.palette.m3primary.g, Colours.palette.m3primary.b, 0.25) : delegateRoot.hovered ? Qt.rgba(Colours.palette.m3primary.r, Colours.palette.m3primary.g, Colours.palette.m3primary.b, 0.06) : Qt.rgba(Colours.palette.m3primary.r, Colours.palette.m3primary.g, Colours.palette.m3primary.b, 0.03)
152201

153-
// Active indicator bar
154-
Rectangle {
155-
width: 4
156-
height: parent.height * 0.6
157-
radius: 2
158-
anchors.verticalCenter: parent.verticalCenter
159-
color: LyricsService.currentSongId === delegateRoot.id ? Colours.palette.m3primary : "transparent"
202+
border.width: delegateRoot.hovered ? 1 : 0
203+
border.color: Colours.palette.m3primary
160204

161205
Behavior on color {
162206
ColorAnimation {
163207
duration: Appearance.anim.durations.small
164208
}
165209
}
210+
Behavior on border.width {
211+
NumberAnimation {
212+
duration: Appearance.anim.durations.small
213+
}
214+
}
166215
}
167216

168-
Column {
169-
anchors.verticalCenter: parent.verticalCenter
170-
width: parent.width - 30
171-
spacing: 4
217+
MouseArea {
218+
anchors.fill: parent
219+
hoverEnabled: true
220+
cursorShape: Qt.PointingHandCursor
172221

173-
Text {
174-
text: delegateRoot.title
175-
font.pointSize: Appearance.font.size.normal
176-
font.bold: true
177-
color: delegateRoot.hovered ? Colours.palette.m3primary : Colours.palette.m3onSurface
178-
width: parent.width
179-
elide: Text.ElideRight
222+
onEntered: delegateRoot.hovered = true
223+
onExited: delegateRoot.hovered = false
224+
onPressed: delegateRoot.pressed = true
225+
onReleased: delegateRoot.pressed = false
226+
onClicked: LyricsService.selectCandidate(delegateRoot.id)
227+
}
228+
229+
Row {
230+
anchors.fill: parent
231+
anchors.margins: Appearance.padding.normal
232+
spacing: Appearance.spacing.small
233+
234+
// Active indicator bar
235+
Rectangle {
236+
width: 4
237+
height: parent.height * 0.6
238+
radius: 2
239+
anchors.verticalCenter: parent.verticalCenter
240+
color: LyricsService.currentSongId === delegateRoot.id ? Colours.palette.m3primary : "transparent"
180241

181242
Behavior on color {
182243
ColorAnimation {
@@ -185,11 +246,32 @@ StyledRect {
185246
}
186247
}
187248

188-
Text {
189-
text: delegateRoot.artist
190-
font.pointSize: Appearance.font.size.small
191-
color: Colours.palette.m3onSurfaceVariant
192-
elide: Text.ElideRight
249+
Column {
250+
anchors.verticalCenter: parent.verticalCenter
251+
width: parent.width - 30
252+
spacing: 4
253+
254+
Text {
255+
text: delegateRoot.title
256+
font.pointSize: Appearance.font.size.normal
257+
font.bold: true
258+
color: delegateRoot.hovered ? Colours.palette.m3primary : Colours.palette.m3onSurface
259+
width: parent.width
260+
elide: Text.ElideRight
261+
262+
Behavior on color {
263+
ColorAnimation {
264+
duration: Appearance.anim.durations.small
265+
}
266+
}
267+
}
268+
269+
Text {
270+
text: delegateRoot.artist
271+
font.pointSize: Appearance.font.size.small
272+
color: Colours.palette.m3onSurfaceVariant
273+
elide: Text.ElideRight
274+
}
193275
}
194276
}
195277
}
@@ -198,7 +280,7 @@ StyledRect {
198280

199281
Item {
200282
Layout.fillHeight: true
201-
visible: LyricsService.candidatesModel.count == 0
283+
visible: LyricsService.candidatesModel.count == 0 && LyricsService.preferredBackend !== "Local"
202284
}
203285

204286
// Manual search

0 commit comments

Comments
 (0)