Skip to content

Added last.fm plugin#4106

Closed
mosshaven wants to merge 1 commit into
pear-devs:masterfrom
mosshaven:master
Closed

Added last.fm plugin#4106
mosshaven wants to merge 1 commit into
pear-devs:masterfrom
mosshaven:master

Conversation

@mosshaven

Copy link
Copy Markdown

(IT'S VIBECODE PLUGIN!)

i tested first version, and it seems working. ai refactored it, and i don't tested it. merge with caution, ig???
(idk why ai put api keys, bc last.fm requesting to log in if plugin started)

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remaining comments which cannot be posted as a review comment to avoid GitHub Rate Limit

eslint

๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท

label: 'API Secret',


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท

value: config.secret,


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยทยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยทยทยทยทยทยทยทยทยท

...promptOptions(),


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยทยทยท

setConfig({ apiKey: output[0] });


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยทยทยท

setConfig({ secret: output[1] });


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท


๐Ÿšซ [eslint] <importPlugin/order> reported by reviewdog ๐Ÿถ
There should be at least one empty line between import groups

import { BrowserWindow, net } from 'electron';


๐Ÿšซ [eslint] <importPlugin/order> reported by reviewdog ๐Ÿถ
node:crypto import should occur before import of electron

import crypto from 'node:crypto';


๐Ÿšซ [eslint] <@typescript-eslint/consistent-type-imports> reported by reviewdog ๐Ÿถ
Imports "SongInfo" are only used as type.

import {
registerCallback,
SongInfo,
SongInfoEvent,
} from '@/providers/song-info';


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยท with ยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

api_sig?: string;


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยท with ยทยท

Object.entries(params)


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

.sort(([a], [b]) => a.localeCompare(b))


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

.forEach(([key, value]) => {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

// 'format' and 'callback' are not included in the signature


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยท

if (key === 'format' || key === 'callback') return;


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

sig += key + String(value);


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

return crypto.createHash('md5').update(sig, 'utf-8').digest('hex');


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยท with ยทยท

params: Record<string, unknown>,


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

apiSignature: string,


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

const queryParams = { ...params, api_sig: apiSignature };


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

const queryData = Object.entries(queryParams).map(


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยท with ยทยทยทยท

([key, value]) =>


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`,


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยท with ยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

return '?' + queryData.join('&');


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

const formData = new URLSearchParams();


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

for (const key in params) {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

if (params[key] !== undefined) {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

formData.append(key, String(params[key]));


๐Ÿšซ [eslint] <@typescript-eslint/no-base-to-string> reported by reviewdog ๐Ÿถ
'params[key]' may use Object's default stringification format ('[object Object]') when stringified.

formData.append(key, String(params[key]));


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยท with ยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยท with ยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

config?: LastFmConfig;


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

window?: BrowserWindow;


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

scrobbleTimer?: NodeJS.Timeout;


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยท with ยทยท

startAuth(config: LastFmConfig): Promise<void>;


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

createSession(config: LastFmConfig): Promise<void>;


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยท with ยทยท

scrobble(songInfo: SongInfo, config: LastFmConfig): Promise<void>;


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

updateNowPlaying(songInfo: SongInfo, config: LastFmConfig): Promise<void>;


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

async start({ getConfig, setConfig, window }) {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

this.config = await getConfig();


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

this.window = window;


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

// If enabled but no session key, start the authentication flow


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยท with ยทยทยทยท

if (this.config.enabled && !this.config.sessionKey) {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

await this.startAuth(this.config);


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

await setConfig(this.config);


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยท with ยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

// Register a callback to listen for song changes


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

registerCallback((songInfo: SongInfo, event) => {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

// Ignore time updates, we only care about track changes or pause/play


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยท

if (event === SongInfoEvent.TimeChanged) return;


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

// Clear any pending scrobble timer to prevent duplicate scrobbles


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

clearTimeout(this.scrobbleTimer);


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยทยทยท

!songInfo.isPaused &&


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยท

this.config?.enabled &&


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยทยทยท

this.config.sessionKey


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยท

// 1. Update "Now Playing" status on Last.fm


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยท

this.updateNowPlaying(songInfo, this.config);


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยท

// 2. Schedule the Scrobble


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยทยทยท

// Rule: Scrobble at 33% of the song duration OR 4 minutes, whichever comes first.


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยท

const scrobbleThreshold = Math.min(


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยท

Math.ceil(songInfo.songDuration * 0.33),


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยท

4 * 60, // 4 minutes in seconds


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยท

const elapsed = songInfo.elapsedSeconds ?? 0;


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยทยทยท

if (scrobbleThreshold > elapsed) {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยท

const timeToWait = (scrobbleThreshold - elapsed) * 1000;


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยทยทยทยทยท

this.scrobbleTimer = setTimeout(() => {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยท

if (this.config) {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยทยทยทยทยทยทยทยทยท

this.scrobble(songInfo, this.config);


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

async onConfigChange(newConfig) {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

this.config = newConfig;


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

// Re-authenticate if the plugin is enabled but lacks a session key


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยท with ยทยทยทยท

if (this.config.enabled && !this.config.sessionKey) {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

await this.startAuth(this.config);


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยท with ยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยท with ยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยท with ยทยทยท

* Starts the Last.fm authentication process.


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

* 1. Fetches a request token.


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

* 2. Opens a browser window for the user to approve the application.


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

* 3. Creates a session after approval.


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

async startAuth(config: LastFmConfig) {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

// Step 1: Get a Request Token


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยท with ยทยทยทยท

const tokenParams = {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

method: 'auth.gettoken',


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยท

api_key: config.apiKey,


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

const tokenSig = createApiSig(tokenParams, config.secret);


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

const tokenRes = await net.fetch(


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยท

`${config.apiRoot}${createQueryString(tokenParams, tokenSig)}`,


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

const tokenJson = (await tokenRes.json()) as { token?: string };


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

if (!tokenJson.token) {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยท

console.error('Last.fm: Failed to get authentication token.');


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยท with ยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

config.token = tokenJson.token;


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยท with ยทยทยทยท

// Step 2: Request User Approval via Browser Window


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

const authUrl = `https://www.last.fm/api/auth/?api_key=${config.apiKey}&token=${config.token}`;


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

const authWindow = new BrowserWindow({


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

parent: this.window,


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

autoHideMenuBar: true,


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

authWindow.loadURL(authUrl);


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยท with ยทยทยทยท

authWindow.show();


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

// Wait for the user to approve the app in the opened window


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยท with ยทยทยทยท

return new Promise<void>((resolve) => {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

authWindow.webContents.on('did-navigate', async (_, newUrl) => {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยท

const url = new URL(newUrl);


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยทยทยท

// Last.fm redirects to this URL after approval


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยท

if (url.hostname.endsWith('last.fm') && url.pathname === '/api/auth') {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยทยทยทยทยท

// Check if the approval was successful by looking for the confirmation element


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยท

// This is a heuristic; ideally we'd use a callback URL but this is a desktop app


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทconstยทisApproveScreenยท= with constยทisApproveScreenยท=โŽยทยทยทยทยทยทยทยทยทยทยท

const isApproveScreen = await authWindow.webContents.executeJavaScript(


๐Ÿšซ [eslint] <@typescript-eslint/no-unsafe-assignment> reported by reviewdog ๐Ÿถ
Unsafe assignment of an any value.

const isApproveScreen = await authWindow.webContents.executeJavaScript(
"!!document.getElementsByName('confirm').length",
);


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยทยทยท

"!!document.getElementsByName('confirm').length",


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยท

// If we are past the confirmation screen (or it didn't show), assume success


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยทยทยทยทยท

if (!isApproveScreen) {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยท

authWindow.close();


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยท

await this.createSession(config);


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

// Handle window close by user (cancellation)


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

authWindow.on('closed', () => {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยท with ยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยท with ยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยท with ยทยทยท

* Exchanges the request token for a session key.


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

async createSession(config: LastFmConfig) {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

if (!config.token) return;


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

const params = {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยท

api_key: config.apiKey,


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยท

method: 'auth.getsession',


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยท

token: config.token,


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

const sig = createApiSig(params, config.secret);


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

const res = await net.fetch(


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยท

`${config.apiRoot}${createQueryString(params, sig)}`,


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

const json = (await res.json()) as { session?: { key: string } };


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

if (json.session) {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยท

config.sessionKey = json.session.key;


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

console.log('Last.fm: Session created successfully.');


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยท with ยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

console.error('Last.fm: Failed to create session.', json);


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยท with ยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

* Updates the "Now Playing" track on Last.fm.


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

async updateNowPlaying(songInfo: SongInfo, config: LastFmConfig) {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

if (!config.sessionKey) return;


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยท with ยทยทยทยท

const params: LastFmApiParams = {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

method: 'track.updateNowPlaying',


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

track: songInfo.title,


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยท

artist: songInfo.artist,


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

duration: songInfo.songDuration,


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

api_key: config.apiKey,


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยท

sk: config.sessionKey,


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

if (songInfo.album) {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยท

params.album = songInfo.album;


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

const sig = createApiSig(params, config.secret);


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

const formData = createFormData({ ...params, api_sig: sig });


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยท with ยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

await net.fetch(config.apiRoot, {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

} catch (error) {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยท

console.error('Last.fm: Failed to update Now Playing.', error);


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยท with ยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

* Scrobbles a track to Last.fm.


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยท with ยทยท

async scrobble(songInfo: SongInfo, config: LastFmConfig) {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

if (!config.sessionKey) return;


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

const params: LastFmApiParams = {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

method: 'track.scrobble',


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยท

track: songInfo.title,


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

artist: songInfo.artist,


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

timestamp: Math.floor(Date.now() / 1000),


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยท

api_key: config.apiKey,


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

sk: config.sessionKey,


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยท with ยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

if (songInfo.album) {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยท

params.album = songInfo.album;


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยท with ยทยทยทยท

const sig = createApiSig(params, config.secret);


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท

const formData = createFormData({ ...params, api_sig: sig });


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

await net.fetch(config.apiRoot, {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทconsole.log(Last.fm:ยทScrobbleยทsuccessfulยทforยท${songInfo.artist}ยท-ยท${songInfo.title}); with ยทยทยทยทยทยทconsole.log(โŽยทยทยทยทยทยทยทยทLast.fm:ยทScrobbleยทsuccessfulยทforยท${songInfo.artist}ยท-ยท${songInfo.title},

console.log(`Last.fm: Scrobble successful for ${songInfo.artist} - ${songInfo.title}`);


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Insert ยทยท);โŽ

} catch (error) {


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยทยทยท

console.error('Last.fm: Failed to scrobble.', error);


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยทยทยท


๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

* Configuration interface for the Last.fm plugin.
*/
export interface LastFmConfig {
enabled: boolean;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

Suggested change
enabled: boolean;
enabled: boolean;

*/
export interface LastFmConfig {
enabled: boolean;
token?: string; // Request token for authentication

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

Suggested change
token?: string; // Request token for authentication
token?: string; // Request token for authentication

export interface LastFmConfig {
enabled: boolean;
token?: string; // Request token for authentication
sessionKey?: string; // Session key obtained after user approval

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยท with ยทยท

Suggested change
sessionKey?: string; // Session key obtained after user approval
sessionKey?: string; // Session key obtained after user approval

enabled: boolean;
token?: string; // Request token for authentication
sessionKey?: string; // Session key obtained after user approval
apiRoot: string; // Base URL for Last.fm API

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

Suggested change
apiRoot: string; // Base URL for Last.fm API
apiRoot: string; // Base URL for Last.fm API

token?: string; // Request token for authentication
sessionKey?: string; // Session key obtained after user approval
apiRoot: string; // Base URL for Last.fm API
apiKey: string; // Application API Key

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Delete ยทยท

Suggested change
apiKey: string; // Application API Key
apiKey: string; // Application API Key

title: 'Last.fm API Settings',
label: 'Configure API Key and Secret',
type: 'multiInput',
multiInputOptions: [

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยทยทยท

Suggested change
multiInputOptions: [
multiInputOptions: [

label: 'Configure API Key and Secret',
type: 'multiInput',
multiInputOptions: [
{

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท

Suggested change
{
{

type: 'multiInput',
multiInputOptions: [
{
label: 'API Key',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท

Suggested change
label: 'API Key',
label: 'API Key',

multiInputOptions: [
{
label: 'API Key',
value: config.apiKey,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท

Suggested change
value: config.apiKey,
value: config.apiKey,

{
label: 'API Key',
value: config.apiKey,
inputAttrs: {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

๐Ÿšซ [eslint] <prettier/prettier> reported by reviewdog ๐Ÿถ
Replace ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท with ยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยทยท

Suggested change
inputAttrs: {
inputAttrs: {

@JellyBrick JellyBrick added the invalid This doesn't seem right label Dec 19, 2025
@JellyBrick

Copy link
Copy Markdown
Member

We already have last.fm plugin....

@JellyBrick JellyBrick closed this Dec 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

invalid This doesn't seem right

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants