mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-14 12:30:06 +02:00
add folder browsing support (#315)
This commit is contained in:
@@ -100,6 +100,22 @@ export const contract = c.router({
|
||||
200: ssType._response.getGenres,
|
||||
},
|
||||
},
|
||||
getIndexes: {
|
||||
method: 'GET',
|
||||
path: 'getIndexes.view',
|
||||
query: ssType._parameters.getIndexes,
|
||||
responses: {
|
||||
200: ssType._response.getIndexes,
|
||||
},
|
||||
},
|
||||
getMusicDirectory: {
|
||||
method: 'GET',
|
||||
path: 'getMusicDirectory.view',
|
||||
query: ssType._parameters.getMusicDirectory,
|
||||
responses: {
|
||||
200: ssType._response.getMusicDirectory,
|
||||
},
|
||||
},
|
||||
getMusicFolderList: {
|
||||
method: 'GET',
|
||||
path: 'getMusicFolders.view',
|
||||
|
||||
@@ -21,7 +21,9 @@ import {
|
||||
InternalControllerEndpoint,
|
||||
LibraryItem,
|
||||
PlaylistListSort,
|
||||
ServerType,
|
||||
Song,
|
||||
SongListSort,
|
||||
SortOrder,
|
||||
} from '/@/shared/types/domain-types';
|
||||
import { ServerFeatures } from '/@/shared/types/features-types';
|
||||
@@ -650,6 +652,106 @@ export const SubsonicController: InternalControllerEndpoint = {
|
||||
'&c=Feishin'
|
||||
);
|
||||
},
|
||||
getFolder: async ({ apiClientProps, query }) => {
|
||||
const sortOrder = (query.sortOrder?.toLowerCase() ?? 'asc') as 'asc' | 'desc';
|
||||
|
||||
const isRootFolderId = /^\d+$/.test(query.id);
|
||||
|
||||
if (isRootFolderId) {
|
||||
const res = await ssApiClient(apiClientProps).getIndexes({
|
||||
query: {
|
||||
musicFolderId: getLibraryId(query.musicFolderId),
|
||||
},
|
||||
});
|
||||
|
||||
if (res.status !== 200) {
|
||||
throw new Error(`Failed to get folder list: ${JSON.stringify(res.body)}`);
|
||||
}
|
||||
|
||||
let items =
|
||||
res.body.indexes?.index?.flatMap((idx) =>
|
||||
idx.artist.map((artist) => ({
|
||||
artist: artist.name,
|
||||
id: artist.id.toString(),
|
||||
isDir: true,
|
||||
title: artist.name,
|
||||
})),
|
||||
) || [];
|
||||
|
||||
if (query.searchTerm) {
|
||||
items = filter(items, (item) => {
|
||||
return item.title.toLowerCase().includes(query.searchTerm!.toLowerCase());
|
||||
});
|
||||
}
|
||||
|
||||
let folders = items.map((item) => ssNormalize.folder(item, apiClientProps.server));
|
||||
|
||||
folders = orderBy(folders, [(v) => v.name.toLowerCase()], [sortOrder]);
|
||||
|
||||
return {
|
||||
_itemType: LibraryItem.FOLDER,
|
||||
_serverId: apiClientProps.server?.id || 'unknown',
|
||||
_serverType: ServerType.SUBSONIC,
|
||||
children: {
|
||||
folders,
|
||||
songs: [],
|
||||
},
|
||||
id: query.id,
|
||||
name: '~',
|
||||
parentId: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
const directoryRes = await ssApiClient(apiClientProps).getMusicDirectory({
|
||||
query: {
|
||||
id: query.id,
|
||||
},
|
||||
});
|
||||
|
||||
if (directoryRes.status !== 200) {
|
||||
throw new Error('Failed to get folder');
|
||||
}
|
||||
|
||||
const folder = ssNormalize.folder(directoryRes.body.directory, apiClientProps.server);
|
||||
|
||||
let filteredFolders = folder.children?.folders || [];
|
||||
let filteredSongs = folder.children?.songs || [];
|
||||
|
||||
if (query.searchTerm) {
|
||||
const searchTermLower = query.searchTerm.toLowerCase();
|
||||
filteredFolders = filter(filteredFolders, (f) =>
|
||||
f.name.toLowerCase().includes(searchTermLower),
|
||||
);
|
||||
filteredSongs = filter(filteredSongs, (s) => {
|
||||
const name = s.name?.toLowerCase() || '';
|
||||
const album = s.album?.toLowerCase() || '';
|
||||
const artist = s.artistName?.toLowerCase() || '';
|
||||
return (
|
||||
name.includes(searchTermLower) ||
|
||||
album.includes(searchTermLower) ||
|
||||
artist.includes(searchTermLower)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
filteredFolders = orderBy(filteredFolders, [(v) => v.name.toLowerCase()], [sortOrder]);
|
||||
|
||||
if (filteredSongs.length > 0) {
|
||||
filteredSongs = sortSongList(
|
||||
filteredSongs,
|
||||
query.sortBy || SongListSort.NAME,
|
||||
query.sortOrder || SortOrder.ASC,
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
...folder,
|
||||
children: {
|
||||
folders: filteredFolders,
|
||||
songs: filteredSongs,
|
||||
},
|
||||
};
|
||||
},
|
||||
getGenreList: async ({ apiClientProps, query }) => {
|
||||
const sortOrder = (query.sortOrder?.toLowerCase() ?? 'asc') as 'asc' | 'desc';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user