fix(tealfm): status clearing, expiry, and state detection per review

This commit is contained in:
Jax
2026-05-27 18:04:29 -04:00
parent 925f3b916d
commit 3a96c28b2d
2 changed files with 13 additions and 7 deletions
@@ -124,13 +124,16 @@ export const playToRecord = (play: PlayObject): ScrobbleRecord => {
}
export const playToStatusRecord = (play: PlayObject, notPlaying: boolean, position?: number): StatusRecord => {
const { $type, ...item } = playToRecord(play);
const { $type, ...item } = notPlaying
? { trackName: "", artists: [] }
: playToRecord(play);
return {
$type: "fm.teal.alpha.actor.status",
time: dayjs().toISOString(),
// expiry is 1min ago if paused, (now + duration - position) if position is available, or fallback to (now + 10mins)
// 1min ago if paused -> try now + (duration - position) -> try now + duration -> fallback to now + 10mins
expiry: notPlaying ? dayjs().subtract(1, 'minute').toISOString()
: position !== undefined ? dayjs().add(play.data.duration - position, 'second').toISOString()
: position !== undefined && play.data.duration !== undefined ? dayjs().add(play.data.duration - position, 'second').toISOString()
: play.data.duration !== undefined ? dayjs().add(play.data.duration, 'second').toISOString()
: dayjs().add(10, 'minute').toISOString(),
item
};
+7 -4
View File
@@ -17,7 +17,6 @@ export default class TealScrobbler extends AbstractScrobbleClient {
requiresAuth = true;
requiresAuthInteraction = false;
clearedStatus = false; // tracks if a user's status has been cleared on their repo
declare config: TealClientConfig;
@@ -127,21 +126,25 @@ export default class TealScrobbler extends AbstractScrobbleClient {
const notPlaying = [CALCULATED_PLAYER_STATUSES.stopped, CALCULATED_PLAYER_STATUSES.paused].includes(data.status.calculated as ReportedPlayerStatus);
try {
await this.client.updateStatusRecord(playToStatusRecord(data.play, notPlaying, data.position));
this.clearedStatus = notPlaying;
} catch (e) {
throw e;
}
}
wasLastStatusCleared = () => {
return this.nowPlayingLastPlay !== undefined
&& [CALCULATED_PLAYER_STATUSES.stopped, CALCULATED_PLAYER_STATUSES.paused].includes(this.nowPlayingLastPlay.status.calculated as ReportedPlayerStatus)
}
shouldUpdatePlayingNowPlatformSpecific = async (data: SourcePlayerObj): Promise<[boolean, string?, LogLevel?]> => {
if ([CALCULATED_PLAYER_STATUSES.stopped, CALCULATED_PLAYER_STATUSES.paused].includes(data.status.calculated as ReportedPlayerStatus) && !this.clearedStatus
if ([CALCULATED_PLAYER_STATUSES.stopped, CALCULATED_PLAYER_STATUSES.paused].includes(data.status.calculated as ReportedPlayerStatus) && !this.wasLastStatusCleared()
|| [CALCULATED_PLAYER_STATUSES.playing].includes(data.status.calculated as ReportedPlayerStatus)
|| (data.nowPlayingMode && !CALCULATED_PLAYER_STATUSES.stopped)) {
return [true];
} else {
if(!data.nowPlayingMode && ![CALCULATED_PLAYER_STATUSES.stopped, CALCULATED_PLAYER_STATUSES.paused, CALCULATED_PLAYER_STATUSES.playing].includes(data.status.calculated as ReportedPlayerStatus)) {
return [false,`player is not in state: stopped | paused | playing => Found '${data.status.calculated }'`];
} else if (this.clearedStatus) {
} else if (this.wasLastStatusCleared()) {
return [false, 'teal.fm status has already been set to expired'];
} else if (data.nowPlayingMode && CALCULATED_PLAYER_STATUSES.stopped) {
this.npLogger.trace(`Will not update because now playing player is stopped => Found ${data.status.calculated}`);