new: option to love tracks on last.fm
This commit is contained in:
parent
14691da826
commit
0185f161a0
6 changed files with 59 additions and 6 deletions
11
index.html
11
index.html
|
|
@ -339,6 +339,17 @@
|
||||||
<span class="slider"></span>
|
<span class="slider"></span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</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>
|
||||||
|
|
||||||
<div class="settings-group">
|
<div class="settings-group">
|
||||||
|
|
|
||||||
|
|
@ -196,7 +196,7 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||||
|
|
||||||
initializeSettings(scrobbler, player, api, ui);
|
initializeSettings(scrobbler, player, api, ui);
|
||||||
initializePlayerEvents(player, audioPlayer, scrobbler, 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);
|
initializeUIInteractions(player, api);
|
||||||
initializeKeyboardShortcuts(player, audioPlayer, lyricsPanel);
|
initializeKeyboardShortcuts(player, audioPlayer, lyricsPanel);
|
||||||
|
|
||||||
|
|
|
||||||
14
js/events.js
14
js/events.js
|
|
@ -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 (!item) return;
|
||||||
|
|
||||||
if (action === 'add-to-queue') {
|
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);
|
const added = await db.toggleFavorite(type, item);
|
||||||
syncManager.syncLibraryItem(type, item, added);
|
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
|
// Update all instances of this item's like button on the page
|
||||||
const id = type === 'playlist' ? item.uuid : item.id;
|
const id = type === 'playlist' ? item.uuid : item.id;
|
||||||
const selector = type === 'track'
|
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;
|
let contextTrack = null;
|
||||||
|
|
||||||
mainContent.addEventListener('click', async e => {
|
mainContent.addEventListener('click', async e => {
|
||||||
|
|
@ -462,7 +466,7 @@ export function initializeTrackInteractions(player, api, mainContent, contextMen
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item) {
|
if (item) {
|
||||||
await handleTrackAction(action, item, player, api, lyricsManager, type, ui);
|
await handleTrackAction(action, item, player, api, lyricsManager, type, ui, scrobbler);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -539,7 +543,7 @@ export function initializeTrackInteractions(player, api, mainContent, contextMen
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
const action = e.target.dataset.action;
|
const action = e.target.dataset.action;
|
||||||
if (action && contextTrack) {
|
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';
|
contextMenu.style.display = 'none';
|
||||||
});
|
});
|
||||||
|
|
@ -575,7 +579,7 @@ export function initializeTrackInteractions(player, api, mainContent, contextMen
|
||||||
nowPlayingLikeBtn.addEventListener('click', async (e) => {
|
nowPlayingLikeBtn.addEventListener('click', async (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (player.currentTrack) {
|
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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
16
js/lastfm.js
16
js/lastfm.js
|
|
@ -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) {
|
onTrackChange(track) {
|
||||||
if (!this.isAuthenticated()) return;
|
if (!this.isAuthenticated()) return;
|
||||||
this.updateNowPlaying(track);
|
this.updateNowPlaying(track);
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ export function initializeSettings(scrobbler, player, api, ui) {
|
||||||
const lastfmStatus = document.getElementById('lastfm-status');
|
const lastfmStatus = document.getElementById('lastfm-status');
|
||||||
const lastfmToggle = document.getElementById('lastfm-toggle');
|
const lastfmToggle = document.getElementById('lastfm-toggle');
|
||||||
const lastfmToggleSetting = document.getElementById('lastfm-toggle-setting');
|
const lastfmToggleSetting = document.getElementById('lastfm-toggle-setting');
|
||||||
|
const lastfmLoveToggle = document.getElementById('lastfm-love-toggle');
|
||||||
|
const lastfmLoveSetting = document.getElementById('lastfm-love-setting');
|
||||||
|
|
||||||
function updateLastFMUI() {
|
function updateLastFMUI() {
|
||||||
if (scrobbler.isAuthenticated()) {
|
if (scrobbler.isAuthenticated()) {
|
||||||
|
|
@ -21,12 +23,15 @@ export function initializeSettings(scrobbler, player, api, ui) {
|
||||||
lastfmConnectBtn.textContent = 'Disconnect';
|
lastfmConnectBtn.textContent = 'Disconnect';
|
||||||
lastfmConnectBtn.classList.add('danger');
|
lastfmConnectBtn.classList.add('danger');
|
||||||
lastfmToggleSetting.style.display = 'flex';
|
lastfmToggleSetting.style.display = 'flex';
|
||||||
|
lastfmLoveSetting.style.display = 'flex';
|
||||||
lastfmToggle.checked = lastFMStorage.isEnabled();
|
lastfmToggle.checked = lastFMStorage.isEnabled();
|
||||||
|
lastfmLoveToggle.checked = lastFMStorage.shouldLoveOnLike();
|
||||||
} else {
|
} else {
|
||||||
lastfmStatus.textContent = 'Connect your Last.fm account to scrobble tracks';
|
lastfmStatus.textContent = 'Connect your Last.fm account to scrobble tracks';
|
||||||
lastfmConnectBtn.textContent = 'Connect Last.fm';
|
lastfmConnectBtn.textContent = 'Connect Last.fm';
|
||||||
lastfmConnectBtn.classList.remove('danger');
|
lastfmConnectBtn.classList.remove('danger');
|
||||||
lastfmToggleSetting.style.display = 'none';
|
lastfmToggleSetting.style.display = 'none';
|
||||||
|
lastfmLoveSetting.style.display = 'none';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -104,6 +109,10 @@ export function initializeSettings(scrobbler, player, api, ui) {
|
||||||
lastFMStorage.setEnabled(e.target.checked);
|
lastFMStorage.setEnabled(e.target.checked);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
lastfmLoveToggle?.addEventListener('change', (e) => {
|
||||||
|
lastFMStorage.setLoveOnLike(e.target.checked);
|
||||||
|
});
|
||||||
|
|
||||||
// Theme picker
|
// Theme picker
|
||||||
const themePicker = document.getElementById('theme-picker');
|
const themePicker = document.getElementById('theme-picker');
|
||||||
const currentTheme = themeManager.getTheme();
|
const currentTheme = themeManager.getTheme();
|
||||||
|
|
|
||||||
|
|
@ -293,6 +293,7 @@ export const themeManager = {
|
||||||
|
|
||||||
export const lastFMStorage = {
|
export const lastFMStorage = {
|
||||||
STORAGE_KEY: 'lastfm-enabled',
|
STORAGE_KEY: 'lastfm-enabled',
|
||||||
|
LOVE_ON_LIKE_KEY: 'lastfm-love-on-like',
|
||||||
|
|
||||||
isEnabled() {
|
isEnabled() {
|
||||||
try {
|
try {
|
||||||
|
|
@ -304,6 +305,18 @@ export const lastFMStorage = {
|
||||||
|
|
||||||
setEnabled(enabled) {
|
setEnabled(enabled) {
|
||||||
localStorage.setItem(this.STORAGE_KEY, enabled ? 'true' : 'false');
|
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');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue