65 lines
2.0 KiB
JavaScript
65 lines
2.0 KiB
JavaScript
export function formatDuration(seconds) {
|
|
if (!Number.isFinite(seconds) || seconds < 0) return '0:00';
|
|
const m = Math.floor(seconds / 60);
|
|
const s = Math.floor(seconds % 60);
|
|
return `${m}:${String(s).padStart(2, '0')}`;
|
|
}
|
|
|
|
export function formatDate(dateStr) {
|
|
if (!dateStr) return '';
|
|
const date = new Date(dateStr);
|
|
if (Number.isNaN(date.getTime())) return '';
|
|
return date.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' });
|
|
}
|
|
|
|
export function formatYear(dateStr) {
|
|
if (!dateStr) return '';
|
|
const date = new Date(dateStr);
|
|
if (Number.isNaN(date.getTime())) return '';
|
|
return String(date.getFullYear());
|
|
}
|
|
|
|
export function escapeHtml(value) {
|
|
return String(value)
|
|
.replace(/&/g, '\u0026amp;')
|
|
.replace(/</g, '\u0026lt;')
|
|
.replace(/>/g, '\u0026gt;')
|
|
.replace(/"/g, '\u0026quot;')
|
|
.replace(/\u0027/g, '\u0026#39;');
|
|
}
|
|
|
|
export function getTrackArtists(track) {
|
|
if (!track || typeof track !== 'object') return 'Unknown artist';
|
|
if (track.artist?.name) return track.artist.name;
|
|
if (Array.isArray(track.artists) && track.artists.length > 0) {
|
|
return track.artists.map((a) => a?.name).filter(Boolean).join(', ') || 'Unknown artist';
|
|
}
|
|
if (typeof track.artist === 'string' && track.artist.trim()) return track.artist;
|
|
return 'Unknown artist';
|
|
}
|
|
|
|
export function getTrackTitle(track) {
|
|
return track?.title || 'Unknown title';
|
|
}
|
|
|
|
export function sanitizeForFilename(str) {
|
|
return String(str || '')
|
|
.replace(/[\\/:*?"<>|]/g, '_')
|
|
.replace(/\s+/g, ' ')
|
|
.trim();
|
|
}
|
|
|
|
export function buildTrackFilename(track, extension = 'flac') {
|
|
const artists = sanitizeForFilename(getTrackArtists(track));
|
|
const title = sanitizeForFilename(getTrackTitle(track));
|
|
return `${artists} - ${title}.${extension}`;
|
|
}
|
|
|
|
export function debounce(fn, wait = 250) {
|
|
let t = null;
|
|
return (...args) => {
|
|
if (t) clearTimeout(t);
|
|
t = setTimeout(() => fn(...args), wait);
|
|
};
|
|
}
|