mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-12 02:51:46 +00:00
78 lines
2.7 KiB
TypeScript
78 lines
2.7 KiB
TypeScript
import registerCallback, { type SongInfo } from '@/providers/song-info';
|
|
import { createBackend } from '@/utils';
|
|
|
|
import { ScrobblerPluginConfig } from './index';
|
|
import { LastFmScrobbler } from './services/lastfm';
|
|
import { ListenbrainzScrobbler } from './services/listenbrainz';
|
|
import { ScrobblerBase } from './services/base';
|
|
|
|
export type SetConfType = (
|
|
conf: Partial<Omit<ScrobblerPluginConfig, 'enabled'>>,
|
|
) => void | Promise<void>;
|
|
|
|
export const backend = createBackend<{
|
|
config?: ScrobblerPluginConfig;
|
|
enabledScrobblers: Map<string, ScrobblerBase>;
|
|
toggleScrobblers(config: ScrobblerPluginConfig): void;
|
|
}, ScrobblerPluginConfig>({
|
|
enabledScrobblers: new Map(),
|
|
|
|
toggleScrobblers(config: ScrobblerPluginConfig) {
|
|
if (config.scrobblers.lastfm && config.scrobblers.lastfm.enabled) {
|
|
this.enabledScrobblers.set('lastfm', new LastFmScrobbler());
|
|
} else {
|
|
this.enabledScrobblers.delete('lastfm');
|
|
}
|
|
|
|
if (config.scrobblers.listenbrainz && config.scrobblers.listenbrainz.enabled) {
|
|
this.enabledScrobblers.set('listenbrainz', new ListenbrainzScrobbler());
|
|
} else {
|
|
this.enabledScrobblers.delete('listenbrainz');
|
|
}
|
|
},
|
|
|
|
async start({
|
|
getConfig,
|
|
setConfig,
|
|
}) {
|
|
const config = this.config = await getConfig();
|
|
// This will store the timeout that will trigger addScrobble
|
|
let scrobbleTimer: NodeJS.Timeout | undefined;
|
|
|
|
this.toggleScrobblers(config);
|
|
for (const [, scrobbler] of this.enabledScrobblers) {
|
|
if (!scrobbler.isSessionCreated(config)) {
|
|
await scrobbler.createSession(config, setConfig);
|
|
}
|
|
}
|
|
|
|
registerCallback((songInfo: SongInfo) => {
|
|
// Set remove the old scrobble timer
|
|
clearTimeout(scrobbleTimer);
|
|
if (!songInfo.isPaused) {
|
|
const configNonnull = this.config!;
|
|
// Scrobble when the song is halfway through, or has passed the 4-minute mark
|
|
const scrobbleTime = Math.min(Math.ceil(songInfo.songDuration / 2), 4 * 60);
|
|
if (scrobbleTime > (songInfo.elapsedSeconds ?? 0)) {
|
|
// Scrobble still needs to happen
|
|
const timeToWait = (scrobbleTime - (songInfo.elapsedSeconds ?? 0)) * 1000;
|
|
scrobbleTimer = setTimeout((info, config) => {
|
|
this.enabledScrobblers.forEach((scrobbler) => scrobbler.addScrobble(info, config, setConfig));
|
|
}, timeToWait, songInfo, configNonnull);
|
|
}
|
|
|
|
this.enabledScrobblers.forEach((scrobbler) => scrobbler.setNowPlaying(songInfo, configNonnull, setConfig));
|
|
}
|
|
});
|
|
},
|
|
|
|
onConfigChange(newConfig: ScrobblerPluginConfig) {
|
|
this.enabledScrobblers.clear();
|
|
|
|
this.config = newConfig;
|
|
|
|
this.toggleScrobblers(this.config);
|
|
}
|
|
});
|
|
|