new: option to love tracks on last.fm

This commit is contained in:
Julien Maille 2025-12-29 23:14:57 +01:00
parent 14691da826
commit 0185f161a0
6 changed files with 59 additions and 6 deletions

View file

@ -339,6 +339,17 @@
<span class="slider"></span>
</label>
</div>
<div class="setting-item" id="lastfm-love-setting" style="display: none;">
<div class="info">
<span class="label">Love on Like</span>
<span class="description">Automatically 'love' tracks on Last.fm when you like them</span>
</div>
<label class="toggle-switch">
<input type="checkbox" id="lastfm-love-toggle">
<span class="slider"></span>
</label>
</div>
</div>
<div class="settings-group">

View file

@ -196,7 +196,7 @@ document.addEventListener('DOMContentLoaded', async () => {
initializeSettings(scrobbler, player, api, ui);
initializePlayerEvents(player, audioPlayer, scrobbler, ui);
initializeTrackInteractions(player, api, document.querySelector('.main-content'), document.getElementById('context-menu'), lyricsManager, ui);
initializeTrackInteractions(player, api, document.querySelector('.main-content'), document.getElementById('context-menu'), lyricsManager, ui, scrobbler);
initializeUIInteractions(player, api);
initializeKeyboardShortcuts(player, audioPlayer, lyricsPanel);

View file

@ -316,7 +316,7 @@ function initializeSmoothSliders(audioPlayer, player) {
});
}
export async function handleTrackAction(action, item, player, api, lyricsManager, type = 'track', ui = null) {
export async function handleTrackAction(action, item, player, api, lyricsManager, type = 'track', ui = null, scrobbler = null) {
if (!item) return;
if (action === 'add-to-queue') {
@ -357,6 +357,10 @@ export async function handleTrackAction(action, item, player, api, lyricsManager
const added = await db.toggleFavorite(type, item);
syncManager.syncLibraryItem(type, item, added);
if (added && type === 'track' && scrobbler && lastFMStorage.isEnabled() && lastFMStorage.shouldLoveOnLike()) {
scrobbler.loveTrack(item);
}
// Update all instances of this item's like button on the page
const id = type === 'playlist' ? item.uuid : item.id;
const selector = type === 'track'
@ -429,7 +433,7 @@ export async function handleTrackAction(action, item, player, api, lyricsManager
}
}
export function initializeTrackInteractions(player, api, mainContent, contextMenu, lyricsManager, ui) {
export function initializeTrackInteractions(player, api, mainContent, contextMenu, lyricsManager, ui, scrobbler) {
let contextTrack = null;
mainContent.addEventListener('click', async e => {
@ -462,7 +466,7 @@ export function initializeTrackInteractions(player, api, mainContent, contextMen
}
if (item) {
await handleTrackAction(action, item, player, api, lyricsManager, type, ui);
await handleTrackAction(action, item, player, api, lyricsManager, type, ui, scrobbler);
}
return;
}
@ -539,7 +543,7 @@ export function initializeTrackInteractions(player, api, mainContent, contextMen
e.stopPropagation();
const action = e.target.dataset.action;
if (action && contextTrack) {
await handleTrackAction(action, contextTrack, player, api, lyricsManager, 'track', ui);
await handleTrackAction(action, contextTrack, player, api, lyricsManager, 'track', ui, scrobbler);
}
contextMenu.style.display = 'none';
});
@ -575,7 +579,7 @@ export function initializeTrackInteractions(player, api, mainContent, contextMen
nowPlayingLikeBtn.addEventListener('click', async (e) => {
e.stopPropagation();
if (player.currentTrack) {
await handleTrackAction('toggle-like', player.currentTrack, player, api, lyricsManager, 'track', ui);
await handleTrackAction('toggle-like', player.currentTrack, player, api, lyricsManager, 'track', ui, scrobbler);
}
});
}

View file

@ -232,6 +232,22 @@ export class LastFMScrobbler {
}
}
async loveTrack(track) {
if (!this.isAuthenticated()) return;
try {
const params = {
artist: track.artist?.name || 'Unknown Artist',
track: track.title
};
await this.makeRequest('track.love', params, true);
console.log('Loved track on Last.fm:', track.title);
} catch (error) {
console.error('Failed to love track on Last.fm:', error);
}
}
onTrackChange(track) {
if (!this.isAuthenticated()) return;
this.updateNowPlaying(track);

View file

@ -14,6 +14,8 @@ export function initializeSettings(scrobbler, player, api, ui) {
const lastfmStatus = document.getElementById('lastfm-status');
const lastfmToggle = document.getElementById('lastfm-toggle');
const lastfmToggleSetting = document.getElementById('lastfm-toggle-setting');
const lastfmLoveToggle = document.getElementById('lastfm-love-toggle');
const lastfmLoveSetting = document.getElementById('lastfm-love-setting');
function updateLastFMUI() {
if (scrobbler.isAuthenticated()) {
@ -21,12 +23,15 @@ export function initializeSettings(scrobbler, player, api, ui) {
lastfmConnectBtn.textContent = 'Disconnect';
lastfmConnectBtn.classList.add('danger');
lastfmToggleSetting.style.display = 'flex';
lastfmLoveSetting.style.display = 'flex';
lastfmToggle.checked = lastFMStorage.isEnabled();
lastfmLoveToggle.checked = lastFMStorage.shouldLoveOnLike();
} else {
lastfmStatus.textContent = 'Connect your Last.fm account to scrobble tracks';
lastfmConnectBtn.textContent = 'Connect Last.fm';
lastfmConnectBtn.classList.remove('danger');
lastfmToggleSetting.style.display = 'none';
lastfmLoveSetting.style.display = 'none';
}
}
@ -104,6 +109,10 @@ export function initializeSettings(scrobbler, player, api, ui) {
lastFMStorage.setEnabled(e.target.checked);
});
lastfmLoveToggle?.addEventListener('change', (e) => {
lastFMStorage.setLoveOnLike(e.target.checked);
});
// Theme picker
const themePicker = document.getElementById('theme-picker');
const currentTheme = themeManager.getTheme();

View file

@ -293,6 +293,7 @@ export const themeManager = {
export const lastFMStorage = {
STORAGE_KEY: 'lastfm-enabled',
LOVE_ON_LIKE_KEY: 'lastfm-love-on-like',
isEnabled() {
try {
@ -304,6 +305,18 @@ export const lastFMStorage = {
setEnabled(enabled) {
localStorage.setItem(this.STORAGE_KEY, enabled ? 'true' : 'false');
},
shouldLoveOnLike() {
try {
return localStorage.getItem(this.LOVE_ON_LIKE_KEY) === 'true';
} catch (e) {
return false;
}
},
setLoveOnLike(enabled) {
localStorage.setItem(this.LOVE_ON_LIKE_KEY, enabled ? 'true' : 'false');
}
};