Merge branch 'main' into sdfs
This commit is contained in:
commit
5a4dbf1300
8 changed files with 293 additions and 119 deletions
|
|
@ -363,7 +363,8 @@ Singleton {
|
|||
smartScheme: services.smartScheme,
|
||||
defaultPlayer: services.defaultPlayer,
|
||||
playerAliases: services.playerAliases,
|
||||
showLyrics: services.showLyrics
|
||||
showLyrics: services.showLyrics,
|
||||
lyricsBackend: services.lyricsBackend
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,5 +19,6 @@ JsonObject {
|
|||
"to": "YT Music"
|
||||
}
|
||||
]
|
||||
property bool showLyrics: true
|
||||
property bool showLyrics: false
|
||||
property string lyricsBackend: "Auto"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -280,6 +280,11 @@ ColumnLayout {
|
|||
forceActiveFocus();
|
||||
}
|
||||
|
||||
if (event.key === Qt.Key_Escape) {
|
||||
event.accepted = false;
|
||||
closeDialog();
|
||||
}
|
||||
|
||||
// Clear error when user starts typing
|
||||
if (connectButton.hasError && event.text && event.text.length > 0) {
|
||||
connectButton.hasError = false;
|
||||
|
|
@ -298,6 +303,10 @@ ColumnLayout {
|
|||
}
|
||||
event.accepted = true;
|
||||
} else if (event.text && event.text.length > 0) {
|
||||
if (event.key === Qt.Key_Tab) {
|
||||
event.accepted = false;
|
||||
return;
|
||||
}
|
||||
passwordBuffer += event.text;
|
||||
event.accepted = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -202,6 +202,11 @@ Item {
|
|||
forceActiveFocus();
|
||||
}
|
||||
|
||||
if (event.key === Qt.Key_Escape) {
|
||||
event.accepted = false;
|
||||
closeDialog();
|
||||
}
|
||||
|
||||
if (connectButton.hasError && event.text && event.text.length > 0) {
|
||||
connectButton.hasError = false;
|
||||
}
|
||||
|
|
@ -219,6 +224,10 @@ Item {
|
|||
}
|
||||
event.accepted = true;
|
||||
} else if (event.text && event.text.length > 0) {
|
||||
if (event.key === Qt.Key_Tab) {
|
||||
event.accepted = false;
|
||||
return;
|
||||
}
|
||||
passwordBuffer += event.text;
|
||||
event.accepted = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ StyledRect {
|
|||
anchors.margins: Appearance.padding.large
|
||||
spacing: Appearance.spacing.normal
|
||||
|
||||
// Header: icon, backend name, refresh, toggle
|
||||
// Header: icon, backend selector, refresh, toggle
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Appearance.padding.small
|
||||
|
|
@ -44,12 +44,49 @@ StyledRect {
|
|||
font.pointSize: Appearance.spacing.large
|
||||
}
|
||||
|
||||
StyledText {
|
||||
Rectangle {
|
||||
Layout.preferredHeight: 24
|
||||
Layout.preferredWidth: 80
|
||||
radius: Appearance.rounding.small
|
||||
color: Qt.rgba(Colours.palette.m3primary.r, Colours.palette.m3primary.g, Colours.palette.m3primary.b, 0.15)
|
||||
|
||||
StyledText {
|
||||
anchors.centerIn: parent
|
||||
text: LyricsService.preferredBackend
|
||||
font.pointSize: Appearance.font.size.small
|
||||
color: Colours.palette.m3primary
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
const backends = ["Auto", "Local", "NetEase"];
|
||||
const currentIndex = backends.indexOf(LyricsService.preferredBackend);
|
||||
const nextIndex = (currentIndex + 1) % backends.length;
|
||||
LyricsService.preferredBackend = backends[nextIndex];
|
||||
LyricsService.loadLyrics();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.preferredHeight: 24
|
||||
Layout.preferredWidth: 60
|
||||
radius: Appearance.rounding.small
|
||||
visible: LyricsService.preferredBackend === "Auto"
|
||||
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)
|
||||
|
||||
StyledText {
|
||||
anchors.centerIn: parent
|
||||
text: LyricsService.backend
|
||||
font.pointSize: Appearance.font.size.small
|
||||
color: LyricsService.backend === "Local" ? Colours.palette.m3tertiary : Colours.palette.m3secondary
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
text: LyricsService.backend
|
||||
font.pointSize: Appearance.font.size.normal
|
||||
color: Colours.palette.m3secondary
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
IconButton {
|
||||
|
|
@ -66,117 +103,141 @@ StyledRect {
|
|||
|
||||
StyledText {
|
||||
Layout.fillWidth: true
|
||||
text: "Fetched Candidates:"
|
||||
text: LyricsService.preferredBackend === "Local" ? "Loaded File:" : "Fetched Candidates:"
|
||||
color: Colours.palette.m3outline
|
||||
font.pointSize: Appearance.font.size.small
|
||||
elide: Text.ElideRight
|
||||
visible: LyricsService.preferredBackend === "Local" ? LyricsService.loadedLocalFile.length > 0 : LyricsService.candidatesModel.count > 0
|
||||
}
|
||||
|
||||
// Local file info (shown in Local mode)
|
||||
Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 48
|
||||
visible: LyricsService.preferredBackend === "Local" && LyricsService.loadedLocalFile.length > 0
|
||||
radius: Appearance.rounding.small
|
||||
color: Qt.rgba(Colours.palette.m3tertiary.r, Colours.palette.m3tertiary.g, Colours.palette.m3tertiary.b, 0.1)
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Appearance.padding.small
|
||||
spacing: 0
|
||||
|
||||
StyledText {
|
||||
Layout.fillWidth: true
|
||||
text: {
|
||||
const path = LyricsService.loadedLocalFile;
|
||||
const parts = path.split('/');
|
||||
return parts[parts.length - 1];
|
||||
}
|
||||
font.pointSize: Appearance.font.size.small
|
||||
color: Colours.palette.m3tertiary
|
||||
elide: Text.ElideMiddle
|
||||
}
|
||||
|
||||
StyledText {
|
||||
Layout.fillWidth: true
|
||||
text: {
|
||||
const path = LyricsService.loadedLocalFile;
|
||||
const parts = path.split('/');
|
||||
if (parts.length > 2) {
|
||||
return parts.slice(-3, -1).join('/');
|
||||
}
|
||||
return "";
|
||||
}
|
||||
font.pointSize: Appearance.font.size.small
|
||||
color: Colours.palette.m3outline
|
||||
elide: Text.ElideMiddle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Candidates list
|
||||
ListView {
|
||||
id: candidatesView
|
||||
|
||||
Loader {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
visible: LyricsService.candidatesModel.count > 0
|
||||
model: LyricsService.candidatesModel
|
||||
clip: true
|
||||
spacing: Appearance.spacing.small
|
||||
active: LyricsService.preferredBackend !== "Local"
|
||||
|
||||
opacity: visible ? 1 : 0
|
||||
// Behavior on opacity {
|
||||
// NumberAnimation { duration: Appearance.anim.durations.normal }
|
||||
// }
|
||||
sourceComponent: ListView {
|
||||
id: candidatesView
|
||||
|
||||
delegate: Item {
|
||||
id: delegateRoot
|
||||
model: LyricsService.candidatesModel
|
||||
clip: true
|
||||
spacing: Appearance.spacing.small
|
||||
visible: LyricsService.candidatesModel.count > 0
|
||||
opacity: visible ? 1 : 0
|
||||
|
||||
required property real id
|
||||
required property string title
|
||||
required property string artist
|
||||
property bool hovered: false
|
||||
property bool pressed: false
|
||||
delegate: Item {
|
||||
id: delegateRoot
|
||||
|
||||
width: ListView.view.width * 0.98
|
||||
height: 70
|
||||
anchors.horizontalCenter: parent?.horizontalCenter
|
||||
scale: hovered ? 1.02 : 1.0
|
||||
required property real id
|
||||
required property string title
|
||||
required property string artist
|
||||
|
||||
Behavior on scale {
|
||||
NumberAnimation {
|
||||
duration: Appearance.anim.durations.small
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
property bool hovered: false
|
||||
property bool pressed: false
|
||||
|
||||
Rectangle {
|
||||
id: background
|
||||
width: ListView.view.width * 0.98
|
||||
height: 70
|
||||
|
||||
anchors.fill: parent
|
||||
radius: Appearance.rounding.small
|
||||
anchors.horizontalCenter: parent?.horizontalCenter
|
||||
scale: hovered ? 1.02 : 1.0
|
||||
|
||||
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)
|
||||
|
||||
border.width: delegateRoot.hovered ? 1 : 0
|
||||
border.color: Colours.palette.m3primary
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Appearance.anim.durations.small
|
||||
}
|
||||
}
|
||||
Behavior on border.width {
|
||||
Behavior on scale {
|
||||
NumberAnimation {
|
||||
duration: Appearance.anim.durations.small
|
||||
easing.type: Easing.OutCubic
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
|
||||
onEntered: delegateRoot.hovered = true
|
||||
onExited: delegateRoot.hovered = false
|
||||
onPressed: delegateRoot.pressed = true
|
||||
onReleased: delegateRoot.pressed = false
|
||||
onClicked: LyricsService.selectCandidate(delegateRoot.id)
|
||||
}
|
||||
|
||||
Row {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Appearance.padding.normal
|
||||
spacing: Appearance.spacing.small
|
||||
|
||||
// Active indicator bar
|
||||
Rectangle {
|
||||
width: 4
|
||||
height: parent.height * 0.6
|
||||
radius: 2
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: LyricsService.currentSongId === delegateRoot.id ? Colours.palette.m3primary : "transparent"
|
||||
id: background
|
||||
|
||||
anchors.fill: parent
|
||||
radius: Appearance.rounding.small
|
||||
|
||||
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)
|
||||
|
||||
border.width: delegateRoot.hovered ? 1 : 0
|
||||
border.color: Colours.palette.m3primary
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Appearance.anim.durations.small
|
||||
}
|
||||
}
|
||||
Behavior on border.width {
|
||||
NumberAnimation {
|
||||
duration: Appearance.anim.durations.small
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: parent.width - 30
|
||||
spacing: 4
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
|
||||
Text {
|
||||
text: delegateRoot.title
|
||||
font.pointSize: Appearance.font.size.normal
|
||||
font.bold: true
|
||||
color: delegateRoot.hovered ? Colours.palette.m3primary : Colours.palette.m3onSurface
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
onEntered: delegateRoot.hovered = true
|
||||
onExited: delegateRoot.hovered = false
|
||||
onPressed: delegateRoot.pressed = true
|
||||
onReleased: delegateRoot.pressed = false
|
||||
onClicked: LyricsService.selectCandidate(delegateRoot.id)
|
||||
}
|
||||
|
||||
Row {
|
||||
anchors.fill: parent
|
||||
anchors.margins: Appearance.padding.normal
|
||||
spacing: Appearance.spacing.small
|
||||
|
||||
// Active indicator bar
|
||||
Rectangle {
|
||||
width: 4
|
||||
height: parent.height * 0.6
|
||||
radius: 2
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
color: LyricsService.currentSongId === delegateRoot.id ? Colours.palette.m3primary : "transparent"
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
|
|
@ -185,11 +246,32 @@ StyledRect {
|
|||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
text: delegateRoot.artist
|
||||
font.pointSize: Appearance.font.size.small
|
||||
color: Colours.palette.m3onSurfaceVariant
|
||||
elide: Text.ElideRight
|
||||
Column {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: parent.width - 30
|
||||
spacing: 4
|
||||
|
||||
Text {
|
||||
text: delegateRoot.title
|
||||
font.pointSize: Appearance.font.size.normal
|
||||
font.bold: true
|
||||
color: delegateRoot.hovered ? Colours.palette.m3primary : Colours.palette.m3onSurface
|
||||
width: parent.width
|
||||
elide: Text.ElideRight
|
||||
|
||||
Behavior on color {
|
||||
ColorAnimation {
|
||||
duration: Appearance.anim.durations.small
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
text: delegateRoot.artist
|
||||
font.pointSize: Appearance.font.size.small
|
||||
color: Colours.palette.m3onSurfaceVariant
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -198,7 +280,7 @@ StyledRect {
|
|||
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
visible: LyricsService.candidatesModel.count == 0
|
||||
visible: LyricsService.candidatesModel.count == 0 && LyricsService.preferredBackend !== "Local"
|
||||
}
|
||||
|
||||
// Manual search
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ pragma Singleton
|
|||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Services.Pipewire
|
||||
import Caelestia
|
||||
import Caelestia.Services
|
||||
|
|
@ -67,6 +68,15 @@ Singleton {
|
|||
Pipewire.preferredDefaultAudioSource = newSource;
|
||||
}
|
||||
|
||||
function cycleNextAudioOutput(): void {
|
||||
if (sinks.length === 0)
|
||||
return;
|
||||
|
||||
const currentIndex = sinks.findIndex(s => s === sink);
|
||||
const nextIndex = (currentIndex + 1) % sinks.length;
|
||||
setAudioSink(sinks[nextIndex]);
|
||||
}
|
||||
|
||||
function setStreamVolume(stream: PwNode, newVolume: real): void {
|
||||
if (stream?.ready && stream?.audio) {
|
||||
stream.audio.muted = false;
|
||||
|
|
@ -162,4 +172,12 @@ Singleton {
|
|||
BeatTracker {
|
||||
id: beatTracker
|
||||
}
|
||||
|
||||
IpcHandler {
|
||||
function cycleOutput(): void {
|
||||
root.cycleNextAudioOutput();
|
||||
}
|
||||
|
||||
target: "audio"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,22 +17,17 @@ Singleton {
|
|||
property bool isManualSeeking: false
|
||||
property bool lyricsVisible: Config.services.showLyrics
|
||||
property string backend: "Local"
|
||||
property string preferredBackend: Config.services.lyricsBackend
|
||||
property real currentSongId: 0
|
||||
|
||||
property string loadedLocalFile: ""
|
||||
property real offset
|
||||
property int currentRequestId: 0
|
||||
property var lyricsMap: ({})
|
||||
|
||||
readonly property string lyricsDir: Paths.absolutePath(Config.paths.lyricsDir)
|
||||
readonly property string lyricsMapFile: Paths.absolutePath(Config.paths.lyricsDir) + "/lyrics_map.json"
|
||||
|
||||
property int currentRequestId: 0
|
||||
|
||||
// The data source for the UI
|
||||
readonly property alias model: lyricsModel
|
||||
readonly property alias candidatesModel: fetchedCandidatesModel
|
||||
|
||||
property var lyricsMap: ({})
|
||||
|
||||
// shared headers for all NetEase requests
|
||||
readonly property var _netEaseHeaders: ({
|
||||
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:120.0) Gecko/20100101 Firefox/120.0",
|
||||
"Referer": "https://music.163.com/"
|
||||
|
|
@ -90,7 +85,6 @@ Singleton {
|
|||
lyricsModel.clear();
|
||||
currentIndex = -1;
|
||||
root.currentSongId = 0;
|
||||
root.backend = "Local";
|
||||
|
||||
root.currentRequestId++;
|
||||
let requestId = root.currentRequestId;
|
||||
|
|
@ -99,29 +93,47 @@ Singleton {
|
|||
let saved = root.lyricsMap[key];
|
||||
root.offset = saved?.offset ?? 0.0;
|
||||
|
||||
if (saved?.neteaseId && saved?.backend === "NetEase") {
|
||||
if (root.preferredBackend === "NetEase") {
|
||||
root.backend = "NetEase";
|
||||
root.currentSongId = saved.neteaseId;
|
||||
fetchNetEaseLyrics(saved.neteaseId, requestId);
|
||||
fetchNetEaseCandidates(meta.title, meta.artist, requestId);
|
||||
fetchNetEase(meta.title, meta.artist, requestId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (saved?.backend === "NetEase") {
|
||||
fallbackTimer.restart();
|
||||
if (root.preferredBackend === "Local") {
|
||||
root.backend = "Local";
|
||||
let cleanDir = lyricsDir.replace(/\/$/, "");
|
||||
let flatPath = `${cleanDir}/${meta.artist} - ${meta.title}.lrc`;
|
||||
|
||||
// Search for files matching "Artist - Title.lrc" pattern
|
||||
const artistStr = Array.isArray(meta.artist) ? meta.artist.join(", ") : String(meta.artist || "");
|
||||
const titleStr = Array.isArray(meta.title) ? meta.title.join(", ") : String(meta.title || "");
|
||||
const escapedTitle = titleStr.replace(/'/g, "'\\''");
|
||||
const escapedArtist = artistStr.replace(/'/g, "'\\''");
|
||||
findLyricsInSubdirs.command = ["sh", "-c", `find "${cleanDir}" -type f -iname "*${escapedArtist}*${escapedTitle}*.lrc" | head -n 1`];
|
||||
findLyricsInSubdirs.requestId = requestId;
|
||||
findLyricsInSubdirs.running = true;
|
||||
|
||||
lrcFile.path = "";
|
||||
lrcFile.path = flatPath;
|
||||
return;
|
||||
}
|
||||
|
||||
// Auto mode: try local first
|
||||
root.backend = "Local";
|
||||
let cleanDir = lyricsDir.replace(/\/$/, "");
|
||||
let fullPath = `${cleanDir}/${meta.artist} - ${meta.title}.lrc`;
|
||||
let flatPath = `${cleanDir}/${meta.artist} - ${meta.title}.lrc`;
|
||||
|
||||
const artistStr = Array.isArray(meta.artist) ? meta.artist.join(", ") : String(meta.artist || "");
|
||||
const titleStr = Array.isArray(meta.title) ? meta.title.join(", ") : String(meta.title || "");
|
||||
const escapedTitle = titleStr.replace(/'/g, "'\\''");
|
||||
const escapedArtist = artistStr.replace(/'/g, "'\\''");
|
||||
findLyricsInSubdirs.command = ["sh", "-c", `find "${cleanDir}" -type f -iname "*${escapedArtist}*${escapedTitle}*.lrc" | head -n 1`];
|
||||
findLyricsInSubdirs.requestId = requestId;
|
||||
findLyricsInSubdirs.running = true;
|
||||
|
||||
lrcFile.path = "";
|
||||
lrcFile.path = fullPath;
|
||||
fetchNetEaseCandidates(meta.title, meta.artist, requestId); //to populate the list regardless
|
||||
|
||||
// if the file is missing, FileView will not fire onLoaded, so we arm the fallback timer here as a safety net. It is cancelled in onLoaded if the file loads successfully.
|
||||
if (saved?.backend !== "Local")
|
||||
fallbackTimer.restart();
|
||||
lrcFile.path = flatPath;
|
||||
fetchNetEaseCandidates(meta.title, meta.artist, requestId);
|
||||
}
|
||||
|
||||
function updateModel(parsedArray) {
|
||||
|
|
@ -256,6 +268,13 @@ Singleton {
|
|||
seekTimer.restart();
|
||||
}
|
||||
|
||||
onPreferredBackendChanged: {
|
||||
if (Config.services.lyricsBackend !== preferredBackend) {
|
||||
Config.services.lyricsBackend = preferredBackend;
|
||||
Config.save();
|
||||
}
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: lyricsModel
|
||||
}
|
||||
|
|
@ -314,12 +333,15 @@ Singleton {
|
|||
let parsed = Lrc.parseLrc(text());
|
||||
if (parsed.length > 0) {
|
||||
root.backend = "Local";
|
||||
root.loadedLocalFile = path;
|
||||
updateModel(parsed);
|
||||
loading = false;
|
||||
} else {
|
||||
} else if (root.preferredBackend === "Local") {
|
||||
// Local mode only - fail immediately
|
||||
root.backend = "NetEase";
|
||||
fallbackToOnline();
|
||||
}
|
||||
// In Auto mode, let the Process onExited handle fallback
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -346,4 +368,35 @@ Singleton {
|
|||
|
||||
command: ["sh", "-c", `mkdir -p "${root.lyricsDir}" && echo '${JSON.stringify(root.lyricsMap)}' > "${root.lyricsMapFile}"`]
|
||||
}
|
||||
|
||||
Process {
|
||||
id: findLyricsInSubdirs
|
||||
|
||||
property int requestId: -1
|
||||
property bool foundFile: false
|
||||
|
||||
stdout: SplitParser {
|
||||
onRead: data => {
|
||||
if (findLyricsInSubdirs.requestId === root.currentRequestId) {
|
||||
const foundPath = data.trim();
|
||||
if (foundPath && foundPath.length > 0) {
|
||||
findLyricsInSubdirs.foundFile = true;
|
||||
fallbackTimer.stop();
|
||||
root.loadedLocalFile = foundPath;
|
||||
lrcFile.path = "";
|
||||
lrcFile.path = foundPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onExited: (exitCode, exitStatus) => { // qmllint disable signal-handler-parameters
|
||||
if (requestId === root.currentRequestId && !foundFile && root.preferredBackend === "Auto") {
|
||||
if (lyricsModel.count === 0) {
|
||||
fallbackTimer.restart();
|
||||
}
|
||||
}
|
||||
foundFile = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ Singleton {
|
|||
const forecastList = [];
|
||||
for (let i = 0; i < json.daily.time.length; i++)
|
||||
forecastList.push({
|
||||
date: json.daily.time[i],
|
||||
date: json.daily.time[i].replace(/-/g, "/"),
|
||||
maxTempC: Math.round(json.daily.temperature_2m_max[i]),
|
||||
maxTempF: Math.round(toFahrenheit(json.daily.temperature_2m_max[i])),
|
||||
minTempC: Math.round(json.daily.temperature_2m_min[i]),
|
||||
|
|
@ -141,7 +141,8 @@ Singleton {
|
|||
const hourlyList = [];
|
||||
const now = new Date();
|
||||
for (let i = 0; i < json.hourly.time.length; i++) {
|
||||
const time = new Date(json.hourly.time[i]);
|
||||
const time = new Date(json.hourly.time[i].replace("T", " "));
|
||||
|
||||
if (time < now)
|
||||
continue;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue