feat(ui): dynamically load playlists and artists in library

This commit is contained in:
2025-09-30 20:21:29 -04:00
parent a8f8e4602a
commit b5d14a71d6
5 changed files with 185 additions and 20 deletions

View File

@@ -0,0 +1,72 @@
import { readDir } from '@tauri-apps/plugin-fs';
export interface Artist {
name: string;
path: string;
}
export interface Playlist {
name: string;
path: string;
}
/**
* Scan music folder for artists (each folder is an artist)
*/
export async function scanArtists(musicFolderPath: string): Promise<Artist[]> {
try {
const entries = await readDir(musicFolderPath);
const artists: Artist[] = [];
for (const entry of entries) {
if (entry.isDirectory) {
artists.push({
name: entry.name,
path: `${musicFolderPath}/${entry.name}`
});
}
}
// Sort alphabetically
artists.sort((a, b) => a.name.localeCompare(b.name));
return artists;
} catch (error) {
console.error('Error scanning artists:', error);
return [];
}
}
/**
* Scan playlists folder for m3u/m3u8 files
*/
export async function scanPlaylists(playlistsFolderPath: string): Promise<Playlist[]> {
try {
const entries = await readDir(playlistsFolderPath);
const playlists: Playlist[] = [];
for (const entry of entries) {
if (!entry.isDirectory) {
const isPlaylist = entry.name.endsWith('.m3u') || entry.name.endsWith('.m3u8');
if (isPlaylist) {
// Remove extension for display name
const nameWithoutExt = entry.name.replace(/\.(m3u8?|M3U8?)$/, '');
playlists.push({
name: nameWithoutExt,
path: `${playlistsFolderPath}/${entry.name}`
});
}
}
}
// Sort alphabetically
playlists.sort((a, b) => a.name.localeCompare(b.name));
return playlists;
} catch (error) {
console.error('Error scanning playlists:', error);
return [];
}
}