CORE: Added Last.FM scrobbling
Build and Publish / Build and Publish Docker Image (push) Successful in 2m50s

This commit is contained in:
Ultradesu
2026-05-27 16:52:36 +03:00
parent 5600a8065d
commit 59910bc34e
2 changed files with 26 additions and 5 deletions
Generated
+1 -1
View File
@@ -1418,7 +1418,7 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
[[package]]
name = "furumusic"
version = "0.1.20"
version = "0.1.21"
dependencies = [
"anyhow",
"async-trait",
+25 -4
View File
@@ -373,6 +373,8 @@ document.addEventListener('alpine:init', () => {
});
audio.addEventListener('ended', () => {
this._trackListenedDelta();
this._maybeScrobble(true);
this._recordHistory(true);
this.next();
});
@@ -677,6 +679,23 @@ document.addEventListener('alpine:init', () => {
this._lastAudioTime = current;
},
_trackDuration() {
const candidates = [
this.currentTrack?.duration_seconds,
this.duration,
audio.duration,
];
for (const value of candidates) {
const duration = Number(value || 0);
if (Number.isFinite(duration) && duration > 0) return duration;
}
return 0;
},
_scrobbleThreshold(duration) {
return Math.min(duration / 2, 240);
},
_sendNowPlaying() {
if (this._nowPlayingSent || !this.currentTrack) return;
const lastfm = Alpine.store('user')?.lastfm;
@@ -689,14 +708,16 @@ document.addEventListener('alpine:init', () => {
}).catch(() => {});
},
_maybeScrobble() {
_maybeScrobble(force = false) {
if (this._scrobbleSent || !this.currentTrack) return;
const lastfm = Alpine.store('user')?.lastfm;
if (!lastfm?.configured || !lastfm?.connected || lastfm?.reauth_required) return;
const duration = Number(this.duration || audio.duration || this.currentTrack.duration_seconds || 0);
const duration = this._trackDuration();
if (!duration || duration <= 30) return;
const threshold = Math.min(duration / 2, 240);
if (this._listenedSeconds < threshold) return;
const threshold = this._scrobbleThreshold(duration);
const listened = force ? this._listenedSeconds + 1 : this._listenedSeconds;
if (listened < threshold) return;
this._listenedSeconds = Math.max(this._listenedSeconds, listened);
this._sendScrobble();
},