diff --git a/desktop/src/api/local/local.controller.ts b/desktop/src/api/local/local.controller.ts index 032d58f..96a62d7 100644 --- a/desktop/src/api/local/local.controller.ts +++ b/desktop/src/api/local/local.controller.ts @@ -91,8 +91,7 @@ export async function scanLibrary(request: FastifyRequest<{ Querystring: ScanQue export async function listEntries(request: FastifyRequest<{ Params: Params }>, reply: FastifyReply) { try { const { type } = request.params; - const entries = await service.getEntriesByType(type); - return entries; + return await service.getEntriesByType(type); } catch { return reply.status(500).send({ error: 'FAILED_TO_LIST_ENTRIES' }); } diff --git a/desktop/src/api/local/local.service.ts b/desktop/src/api/local/local.service.ts index 4384b21..bd44928 100644 --- a/desktop/src/api/local/local.service.ts +++ b/desktop/src/api/local/local.service.ts @@ -186,8 +186,22 @@ export async function performLibraryScan(mode: 'full' | 'incremental' = 'increme } export async function getEntriesByType(type: string) { - const entries = await queryAll(`SELECT * FROM local_entries WHERE type = ?`, [type], 'local_library'); - return await Promise.all(entries.map((entry: any) => resolveEntryMetadata(entry, type))); + const sql = ` + SELECT local_entries.*, COUNT(local_files.id) as file_count + FROM local_entries + LEFT JOIN local_files ON local_entries.id = local_files.entry_id + WHERE local_entries.type = ? + GROUP BY local_entries.id + `; + const entries = await queryAll(sql, [type], 'local_library'); + return await Promise.all(entries.map(async (entry: any) => { + const metadata = await resolveEntryMetadata(entry, type); + return { + ...metadata, + path: entry.path, + files: entry.file_count + }; + })); } export async function getEntryDetails(type: string, id: string) { diff --git a/desktop/src/scripts/profile.js b/desktop/src/scripts/profile.js index 8d3c445..417210e 100644 --- a/desktop/src/scripts/profile.js +++ b/desktop/src/scripts/profile.js @@ -387,6 +387,7 @@ const DashboardApp = { }, Library: { + tempMatchContext: null, loadStats: async function() { const types = ['anime', 'manga', 'novels']; const elements = { 'anime': 'local-anime-count', 'manga': 'local-manga-count', 'novels': 'local-novel-count' }; @@ -446,7 +447,7 @@ const DashboardApp = { const meta = entry.metadata || {}; let poster = meta.coverImage?.large || '/public/assets/placeholder.svg'; - let title = isMatched ? (meta.title?.english || meta.title?.romaji) : entry.folder_name; + let title = isMatched ? (meta.title?.english || meta.title?.romaji) : entry.path; if (!isMatched) title = title.replace(/\[.*?\]|\(.*?\)|\.mkv|\.mp4/g, '').trim(); const url = isMatched ? (type === 'anime' ? `/anime/${meta.id}` : `/book/${meta.id}`) : '#'; @@ -459,12 +460,12 @@ const DashboardApp = { ${!isMatched ? `
UNMATCHED
` : ''}
-

${title}

+

${title}

- ${entry.files ? entry.files.length : 0} FILES + ${entry.files} FILES ${isMatched ? 'MATCHED' : ''}
-
${entry.folder_name}
+
${entry.path}
+ + + + + +
-

${title}

+

${title}

- ${entry.files ? entry.files.length : 0} FILES + ${entry.files} FILES ${isMatched ? 'MATCHED' : ''}
-
${entry.folder_name}
+
${entry.path}
+ + + + + +