fix all errors/warnings during linting
This commit is contained in:
parent
18b82e793e
commit
50834a48e0
13 changed files with 50 additions and 73 deletions
|
|
@ -171,7 +171,9 @@ class AudioContextManager {
|
||||||
// Fallback: direct connection
|
// Fallback: direct connection
|
||||||
try {
|
try {
|
||||||
this.source.connect(this.audioContext.destination);
|
this.source.connect(this.audioContext.destination);
|
||||||
} catch {}
|
} catch {
|
||||||
|
/* ignore */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
2
js/db.js
2
js/db.js
|
|
@ -111,7 +111,7 @@ export class MusicDatabase {
|
||||||
store.put(entry);
|
store.put(entry);
|
||||||
};
|
};
|
||||||
|
|
||||||
cursorReq.onerror = (e) => {
|
cursorReq.onerror = (_e) => {
|
||||||
// If cursor fails, just try to put (fallback)
|
// If cursor fails, just try to put (fallback)
|
||||||
store.put(entry);
|
store.put(entry);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,7 @@ export class Equalizer {
|
||||||
* Calculate Q factor for each band
|
* Calculate Q factor for each band
|
||||||
* Using constant-Q design for consistent bandwidth
|
* Using constant-Q design for consistent bandwidth
|
||||||
*/
|
*/
|
||||||
_calculateQ(index) {
|
_calculateQ(_index) {
|
||||||
// For 16-band 1/2 octave spacing, Q ≈ 2.87
|
// For 16-band 1/2 octave spacing, Q ≈ 2.87
|
||||||
// Slightly lower Q for smoother response
|
// Slightly lower Q for smoother response
|
||||||
return 2.5;
|
return 2.5;
|
||||||
|
|
@ -354,15 +354,21 @@ export class Equalizer {
|
||||||
this.filters.forEach((filter) => {
|
this.filters.forEach((filter) => {
|
||||||
try {
|
try {
|
||||||
filter.disconnect();
|
filter.disconnect();
|
||||||
} catch {}
|
} catch {
|
||||||
|
/* ignore */
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.inputNode?.disconnect();
|
this.inputNode?.disconnect();
|
||||||
} catch {}
|
} catch {
|
||||||
|
/* ignore */
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
this.outputNode?.disconnect();
|
this.outputNode?.disconnect();
|
||||||
} catch {}
|
} catch {
|
||||||
|
/* ignore */
|
||||||
|
}
|
||||||
|
|
||||||
this.filters = [];
|
this.filters = [];
|
||||||
this.inputNode = null;
|
this.inputNode = null;
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ const DEFAULT_ALBUM = 'Unknown Album';
|
||||||
* @param {string} quality - Audio quality
|
* @param {string} quality - Audio quality
|
||||||
* @returns {Promise<Blob>} - Audio blob with embedded metadata
|
* @returns {Promise<Blob>} - Audio blob with embedded metadata
|
||||||
*/
|
*/
|
||||||
export async function addMetadataToAudio(audioBlob, track, api, quality) {
|
export async function addMetadataToAudio(audioBlob, track, api, _quality) {
|
||||||
// Always check actual file signature, not just quality setting
|
// Always check actual file signature, not just quality setting
|
||||||
// DASH Hi-Res streams may return fragmented MP4 instead of raw FLAC
|
// DASH Hi-Res streams may return fragmented MP4 instead of raw FLAC
|
||||||
const buffer = await audioBlob.slice(0, 12).arrayBuffer();
|
const buffer = await audioBlob.slice(0, 12).arrayBuffer();
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { sanitizeForFilename, formatTemplate } from './utils.js';
|
import { sanitizeForFilename } from './utils.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates M3U playlist content
|
* Generates M3U playlist content
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,9 @@ export function initializeSettings(scrobbler, player, api, ui) {
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await authManager.sendPasswordReset(email);
|
await authManager.sendPasswordReset(email);
|
||||||
} catch {}
|
} catch {
|
||||||
|
/* ignore */
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -784,7 +784,9 @@ export const equalizerSettings = {
|
||||||
return gains;
|
return gains;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch {}
|
} catch {
|
||||||
|
/* ignore */
|
||||||
|
}
|
||||||
// Return flat EQ (all zeros) by default
|
// Return flat EQ (all zeros) by default
|
||||||
return new Array(16).fill(0);
|
return new Array(16).fill(0);
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
//js/tracker.js
|
//js/tracker.js
|
||||||
import { escapeHtml, SVG_DOWNLOAD, SVG_MENU, SVG_PLAY, trackDataStore, formatTime, SVG_HEART } from './utils.js';
|
import { escapeHtml, SVG_MENU, SVG_PLAY, trackDataStore, formatTime, SVG_HEART } from './utils.js';
|
||||||
import { navigate } from './router.js';
|
import { navigate } from './router.js';
|
||||||
|
|
||||||
let artistsData = [];
|
let artistsData = [];
|
||||||
|
|
@ -22,8 +22,8 @@ function cleanSongTitle(title) {
|
||||||
if (!title) return '';
|
if (!title) return '';
|
||||||
// Remove (prod. ...), (produced by ...), [prod. ...], etc.
|
// Remove (prod. ...), (produced by ...), [prod. ...], etc.
|
||||||
return title
|
return title
|
||||||
.replace(/\s*[\(\[]\s*prod\.?\s+[^\)\]]+[\)\]]/gi, '')
|
.replace(/\s*[([]\s*prod\.?\s+[^)\]]+[)\]]/gi, '')
|
||||||
.replace(/\s*[\(\[]\s*produced\s+by\s+[^\)\]]+[\)\]]/gi, '')
|
.replace(/\s*[([]\s*produced\s+by\s+[^)\]]+[)\]]/gi, '')
|
||||||
.replace(/\s+/g, ' ')
|
.replace(/\s+/g, ' ')
|
||||||
.trim();
|
.trim();
|
||||||
}
|
}
|
||||||
|
|
@ -134,7 +134,7 @@ function getDirectUrl(rawUrl) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert tracker song to standard track format
|
// Convert tracker song to standard track format
|
||||||
function createTrackFromSong(song, era, artistName, index, sheetId = '') {
|
export function createTrackFromSong(song, era, artistName, index, sheetId = '') {
|
||||||
const isValidUrl = (u) => u && typeof u === 'string' && u.trim().length > 0;
|
const isValidUrl = (u) => u && typeof u === 'string' && u.trim().length > 0;
|
||||||
const rawUrl = (isValidUrl(song.url) ? song.url : null) || (song.urls ? song.urls.find(isValidUrl) : null);
|
const rawUrl = (isValidUrl(song.url) ? song.url : null) || (song.urls ? song.urls.find(isValidUrl) : null);
|
||||||
const directUrl = getDirectUrl(rawUrl);
|
const directUrl = getDirectUrl(rawUrl);
|
||||||
|
|
@ -325,7 +325,7 @@ export async function renderTrackerArtistPage(sheetId, container) {
|
||||||
if (era.data) {
|
if (era.data) {
|
||||||
Object.values(era.data).forEach((songs) => {
|
Object.values(era.data).forEach((songs) => {
|
||||||
if (songs && songs.length) {
|
if (songs && songs.length) {
|
||||||
songs.forEach((song, index) => {
|
songs.forEach((song) => {
|
||||||
const track = createTrackFromSong(song, era, artist.name, allTracks.length, sheetId);
|
const track = createTrackFromSong(song, era, artist.name, allTracks.length, sheetId);
|
||||||
allTracks.push(track);
|
allTracks.push(track);
|
||||||
});
|
});
|
||||||
|
|
@ -406,7 +406,7 @@ export async function renderTrackerArtistPage(sheetId, container) {
|
||||||
if (era.data) {
|
if (era.data) {
|
||||||
Object.values(era.data).forEach((songs) => {
|
Object.values(era.data).forEach((songs) => {
|
||||||
if (songs && songs.length) {
|
if (songs && songs.length) {
|
||||||
songs.forEach((song, index) => {
|
songs.forEach((song) => {
|
||||||
const track = createTrackFromSong(song, era, artist.name, eraTracks.length, sheetId);
|
const track = createTrackFromSong(song, era, artist.name, eraTracks.length, sheetId);
|
||||||
eraTracks.push(track);
|
eraTracks.push(track);
|
||||||
});
|
});
|
||||||
|
|
@ -498,7 +498,7 @@ export async function renderTrackerArtistPage(sheetId, container) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render individual tracker project page
|
// Render individual tracker project page
|
||||||
export async function renderTrackerProjectPage(sheetId, projectName, container, ui) {
|
export async function renderTrackerProjectPage(sheetId, projectName, container, _ui) {
|
||||||
if (!artistsData.length) {
|
if (!artistsData.length) {
|
||||||
await loadArtistsData();
|
await loadArtistsData();
|
||||||
}
|
}
|
||||||
|
|
@ -526,7 +526,7 @@ export async function renderTrackerProjectPage(sheetId, projectName, container,
|
||||||
if (era.data) {
|
if (era.data) {
|
||||||
Object.values(era.data).forEach((songs) => {
|
Object.values(era.data).forEach((songs) => {
|
||||||
if (songs && songs.length) {
|
if (songs && songs.length) {
|
||||||
songs.forEach((song, index) => {
|
songs.forEach((song) => {
|
||||||
const track = createTrackFromSong(song, era, artist.name, eraTracks.length, sheetId);
|
const track = createTrackFromSong(song, era, artist.name, eraTracks.length, sheetId);
|
||||||
eraTracks.push(track);
|
eraTracks.push(track);
|
||||||
});
|
});
|
||||||
|
|
@ -645,13 +645,6 @@ export async function renderTrackerProjectPage(sheetId, projectName, container,
|
||||||
const era = trackerData.eras[eraName];
|
const era = trackerData.eras[eraName];
|
||||||
if (!era) return;
|
if (!era) return;
|
||||||
|
|
||||||
let trackCount = 0;
|
|
||||||
if (era.data) {
|
|
||||||
Object.values(era.data).forEach((songs) => {
|
|
||||||
if (songs && songs.length) trackCount += songs.length;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
card.onclick = (e) => {
|
card.onclick = (e) => {
|
||||||
if (e.target.closest('.card-play-btn')) {
|
if (e.target.closest('.card-play-btn')) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
@ -659,7 +652,7 @@ export async function renderTrackerProjectPage(sheetId, projectName, container,
|
||||||
if (era.data) {
|
if (era.data) {
|
||||||
Object.values(era.data).forEach((songs) => {
|
Object.values(era.data).forEach((songs) => {
|
||||||
if (songs && songs.length) {
|
if (songs && songs.length) {
|
||||||
songs.forEach((song, index) => {
|
songs.forEach((song) => {
|
||||||
const track = createTrackFromSong(
|
const track = createTrackFromSong(
|
||||||
song,
|
song,
|
||||||
era,
|
era,
|
||||||
|
|
@ -797,7 +790,7 @@ export async function renderUnreleasedPage(container) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render track page for unreleased songs
|
// Render track page for unreleased songs
|
||||||
export async function renderTrackerTrackPage(trackId, container, ui) {
|
export async function renderTrackerTrackPage(trackId, container, _ui) {
|
||||||
// Parse track ID: tracker-{sheetId}-{eraName}-{index}
|
// Parse track ID: tracker-{sheetId}-{eraName}-{index}
|
||||||
const parts = trackId.split('-');
|
const parts = trackId.split('-');
|
||||||
if (parts.length < 4) {
|
if (parts.length < 4) {
|
||||||
|
|
@ -834,17 +827,15 @@ export async function renderTrackerTrackPage(trackId, container, ui) {
|
||||||
|
|
||||||
// Find the specific track
|
// Find the specific track
|
||||||
let currentTrack = null;
|
let currentTrack = null;
|
||||||
let currentIndex = 0;
|
|
||||||
let allTracks = [];
|
let allTracks = [];
|
||||||
|
|
||||||
Object.values(era.data).forEach((songs) => {
|
Object.values(era.data).forEach((songs) => {
|
||||||
if (songs && songs.length) {
|
if (songs && songs.length) {
|
||||||
songs.forEach((song, idx) => {
|
songs.forEach((song) => {
|
||||||
const track = createTrackFromSong(song, era, artist.name, allTracks.length, sheetId);
|
const track = createTrackFromSong(song, era, artist.name, allTracks.length, sheetId);
|
||||||
allTracks.push(track);
|
allTracks.push(track);
|
||||||
if (allTracks.length - 1 === trackIndex) {
|
if (allTracks.length - 1 === trackIndex) {
|
||||||
currentTrack = track;
|
currentTrack = track;
|
||||||
currentIndex = allTracks.length - 1;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
8
js/ui.js
8
js/ui.js
|
|
@ -33,6 +33,7 @@ import {
|
||||||
findTrackerArtistByName,
|
findTrackerArtistByName,
|
||||||
getArtistUnreleasedProjects,
|
getArtistUnreleasedProjects,
|
||||||
createProjectCardHTML,
|
createProjectCardHTML,
|
||||||
|
createTrackFromSong,
|
||||||
} from './tracker.js';
|
} from './tracker.js';
|
||||||
|
|
||||||
export class UIRenderer {
|
export class UIRenderer {
|
||||||
|
|
@ -2448,6 +2449,7 @@ export class UIRenderer {
|
||||||
loadUnreleasedBtn.style.display = 'none';
|
loadUnreleasedBtn.style.display = 'none';
|
||||||
|
|
||||||
// Add click handlers
|
// Add click handlers
|
||||||
|
const player = this.player;
|
||||||
unreleasedContainer.querySelectorAll('.card').forEach((card) => {
|
unreleasedContainer.querySelectorAll('.card').forEach((card) => {
|
||||||
const eraName = decodeURIComponent(card.dataset.trackerProjectId);
|
const eraName = decodeURIComponent(card.dataset.trackerProjectId);
|
||||||
const era = eras.find((e) => e.name === eraName);
|
const era = eras.find((e) => e.name === eraName);
|
||||||
|
|
@ -2460,7 +2462,7 @@ export class UIRenderer {
|
||||||
if (era.data) {
|
if (era.data) {
|
||||||
Object.values(era.data).forEach((songs) => {
|
Object.values(era.data).forEach((songs) => {
|
||||||
if (songs && songs.length) {
|
if (songs && songs.length) {
|
||||||
songs.forEach((song, index) => {
|
songs.forEach((song) => {
|
||||||
const track = createTrackFromSong(
|
const track = createTrackFromSong(
|
||||||
song,
|
song,
|
||||||
era,
|
era,
|
||||||
|
|
@ -2475,8 +2477,8 @@ export class UIRenderer {
|
||||||
}
|
}
|
||||||
const availableTracks = eraTracks.filter((t) => !t.unavailable);
|
const availableTracks = eraTracks.filter((t) => !t.unavailable);
|
||||||
if (availableTracks.length > 0) {
|
if (availableTracks.length > 0) {
|
||||||
globalPlayer.setQueue(availableTracks, 0);
|
player.setQueue(availableTracks, 0);
|
||||||
globalPlayer.playTrackFromQueue();
|
player.playTrackFromQueue();
|
||||||
}
|
}
|
||||||
} else if (e.target.closest('.card-menu-btn')) {
|
} else if (e.target.closest('.card-menu-btn')) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@ export const buildTrackFilename = (track, quality, extension = null) => {
|
||||||
album: track.album?.title,
|
album: track.album?.title,
|
||||||
};
|
};
|
||||||
|
|
||||||
return formatTemplate(template, data) + '.' + extension;
|
return formatTemplate(template, data) + '.' + ext;
|
||||||
};
|
};
|
||||||
|
|
||||||
const sanitizeToken = (value) => {
|
const sanitizeToken = (value) => {
|
||||||
|
|
|
||||||
|
|
@ -187,7 +187,7 @@ export class LCDPreset {
|
||||||
|
|
||||||
draw(ctx, canvas, analyser, dataArray, params) {
|
draw(ctx, canvas, analyser, dataArray, params) {
|
||||||
const { width, height } = canvas;
|
const { width, height } = canvas;
|
||||||
const { kick, intensity, primaryColor, mode } = params;
|
const { kick, primaryColor, mode } = params;
|
||||||
|
|
||||||
this.primaryColor = primaryColor;
|
this.primaryColor = primaryColor;
|
||||||
const isDark = document.documentElement.getAttribute('data-theme') !== 'light';
|
const isDark = document.documentElement.getAttribute('data-theme') !== 'light';
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ export class ParticlesPreset {
|
||||||
this.particleCount = 180;
|
this.particleCount = 180;
|
||||||
}
|
}
|
||||||
|
|
||||||
resize(width, height) {
|
resize(_width, _height) {
|
||||||
// Particles don't need explicit resize logic unless we want to respawn them,
|
// Particles don't need explicit resize logic unless we want to respawn them,
|
||||||
// but current logic handles boundaries in draw loop.
|
// but current logic handles boundaries in draw loop.
|
||||||
}
|
}
|
||||||
|
|
|
||||||
46
styles.css
46
styles.css
|
|
@ -363,17 +363,6 @@ kbd {
|
||||||
padding-bottom: 160px !important;
|
padding-bottom: 160px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure content sits on top of background */
|
|
||||||
.main-header {
|
|
||||||
position: relative;
|
|
||||||
z-index: 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page {
|
|
||||||
position: relative;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#page-background {
|
#page-background {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
|
@ -704,6 +693,8 @@ input[type='search']::-webkit-search-cancel-button {
|
||||||
|
|
||||||
.page {
|
.page {
|
||||||
display: none;
|
display: none;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.page.active {
|
.page.active {
|
||||||
|
|
@ -1103,6 +1094,8 @@ input[type='search']::-webkit-search-cancel-button {
|
||||||
.heart-icon.filled {
|
.heart-icon.filled {
|
||||||
color: #ef4444;
|
color: #ef4444;
|
||||||
fill: #ef4444;
|
fill: #ef4444;
|
||||||
|
stroke: #ef4444;
|
||||||
|
animation: heart-beat 0.4s var(--ease-elastic);
|
||||||
}
|
}
|
||||||
|
|
||||||
.track-item:hover .like-btn {
|
.track-item:hover .like-btn {
|
||||||
|
|
@ -1878,8 +1871,8 @@ input:checked + .slider::before {
|
||||||
|
|
||||||
.player-controls .buttons button:active {
|
.player-controls .buttons button:active {
|
||||||
transform: scale(0.9);
|
transform: scale(0.9);
|
||||||
|
color: var(--foreground);
|
||||||
/* Press effect */
|
background-color: var(--secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (hover: hover) {
|
@media (hover: hover) {
|
||||||
|
|
@ -1889,11 +1882,6 @@ input:checked + .slider::before {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.player-controls .buttons button:active {
|
|
||||||
color: var(--foreground);
|
|
||||||
background-color: var(--secondary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.player-controls .buttons button.active {
|
.player-controls .buttons button.active {
|
||||||
color: var(--active-highlight);
|
color: var(--active-highlight);
|
||||||
}
|
}
|
||||||
|
|
@ -3614,6 +3602,9 @@ img[src=''] {
|
||||||
|
|
||||||
.modal.active {
|
.modal.active {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
backdrop-filter: blur(4px);
|
||||||
|
background: rgb(0, 0, 0, 0.6);
|
||||||
|
transition: opacity var(--transition-normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-overlay {
|
.modal-overlay {
|
||||||
|
|
@ -5002,9 +4993,6 @@ body:has(#side-panel.active) .fullscreen-main-view {
|
||||||
flex 0.3s ease,
|
flex 0.3s ease,
|
||||||
padding-right 0.3s ease,
|
padding-right 0.3s ease,
|
||||||
margin-right 0.3s ease;
|
margin-right 0.3s ease;
|
||||||
}
|
|
||||||
|
|
||||||
body:has(#side-panel.active) .fullscreen-main-view {
|
|
||||||
padding-right: 600px;
|
padding-right: 600px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5103,13 +5091,6 @@ textarea:focus {
|
||||||
box-shadow: 0 0 0 3px rgb(var(--highlight-rgb), 0.2);
|
box-shadow: 0 0 0 3px rgb(var(--highlight-rgb), 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Modals */
|
|
||||||
.modal.active {
|
|
||||||
backdrop-filter: blur(4px);
|
|
||||||
background: rgb(0, 0, 0, 0.6);
|
|
||||||
transition: opacity var(--transition-normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal.active .modal-content {
|
.modal.active .modal-content {
|
||||||
animation: pop-in var(--transition-normal) var(--ease-out-back);
|
animation: pop-in var(--transition-normal) var(--ease-out-back);
|
||||||
box-shadow: var(--shadow-2xl);
|
box-shadow: var(--shadow-2xl);
|
||||||
|
|
@ -5126,15 +5107,6 @@ textarea:focus {
|
||||||
transform: scale(0.97);
|
transform: scale(0.97);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Heart Icon Animation */
|
|
||||||
.heart-icon.filled {
|
|
||||||
animation: heart-beat 0.4s var(--ease-elastic);
|
|
||||||
fill: #ef4444;
|
|
||||||
|
|
||||||
/* Standardize heart red */
|
|
||||||
stroke: #ef4444;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* =========================================
|
/* =========================================
|
||||||
16-Band Equalizer
|
16-Band Equalizer
|
||||||
========================================= */
|
========================================= */
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue