mirror of
https://github.com/Kareadita/Kavita.git
synced 2026-01-14 16:10:22 -05:00
Co-authored-by: Amelia <77553571+Fesaa@users.noreply.github.com> Co-authored-by: Weblate (bot) <hosted@weblate.org> Co-authored-by: Adam Havránek <adamhavra@seznam.cz> Co-authored-by: Aindriú Mac Giolla Eoin <aindriu80@gmail.com> Co-authored-by: Dark77 <Dark77@pobox.sk> Co-authored-by: Frozehunter <frozehunter@me.com> Co-authored-by: Havokdan <havokdan@yahoo.com.br> Co-authored-by: Igor Dobrača <igor.dobraca@gmail.com> Co-authored-by: Karl B <karl.owl@proton.me> Co-authored-by: Morhain Olivier <sesram@users.noreply.hosted.weblate.org> Co-authored-by: daydreamrabbit <devrabbit90@gmail.com> Co-authored-by: karigane <169052233+karigane-cha@users.noreply.github.com> Co-authored-by: oxygen44k <iiccpp@outlook.com> Co-authored-by: Максим Горпиніч <gorpinicmaksim0@gmail.com> Co-authored-by: 無情天 <kofzhanganguo@126.com> Co-authored-by: 안세훈 <on9686@gmail.com>
85 lines
2.9 KiB
C#
85 lines
2.9 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using API.DTOs.Progress;
|
|
using AutoMapper;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace API.Data.Repositories;
|
|
|
|
public interface IReadingSessionRepository
|
|
{
|
|
Task<IList<ReadingSessionDto>> GetAllReadingSessionAsync(bool isActiveOnly = true);
|
|
}
|
|
|
|
|
|
public class ReadingSessionRepository(DataContext context, IMapper mapper) : IReadingSessionRepository
|
|
{
|
|
public async Task<IList<ReadingSessionDto>> GetAllReadingSessionAsync(bool isActiveOnly = true)
|
|
{
|
|
var query = context.AppUserReadingSession
|
|
.Where(s => !isActiveOnly || s.IsActive);
|
|
|
|
var sessions = await query
|
|
.Include(s => s.ActivityData)
|
|
.Include(s => s.AppUser)
|
|
.ToListAsync();
|
|
|
|
if (sessions.Count == 0) return [];
|
|
|
|
// Gather all unique IDs across ALL sessions
|
|
var allActivityData = sessions
|
|
.Where(s => s.ActivityData != null)
|
|
.SelectMany(s => s.ActivityData)
|
|
.ToList();
|
|
|
|
var libraryIds = allActivityData.Select(a => a.LibraryId).Distinct().ToList();
|
|
var seriesIds = allActivityData.Select(a => a.SeriesId).Distinct().ToList();
|
|
var chapterIds = allActivityData.Select(a => a.ChapterId).Distinct().ToList();
|
|
|
|
// Fetch all lookups in parallel - single query per table
|
|
var libraryLookupTask = context.Library
|
|
.Where(l => libraryIds.Contains(l.Id))
|
|
.ToDictionaryAsync(l => l.Id, l => l.Name);
|
|
|
|
var seriesLookupTask = context.Series
|
|
.Where(s => seriesIds.Contains(s.Id))
|
|
.ToDictionaryAsync(s => s.Id, s => s.Name);
|
|
|
|
var chapterLookupTask = context.Chapter
|
|
.Where(c => chapterIds.Contains(c.Id))
|
|
.ToDictionaryAsync(c => c.Id, c => c.TitleName);
|
|
|
|
await Task.WhenAll(libraryLookupTask, seriesLookupTask, chapterLookupTask);
|
|
|
|
var libraryLookup = libraryLookupTask.Result;
|
|
var seriesLookup = seriesLookupTask.Result;
|
|
var chapterLookup = chapterLookupTask.Result;
|
|
|
|
// Map all sessions with AutoMapper
|
|
var dtos = mapper.Map<List<ReadingSessionDto>>(sessions);
|
|
|
|
// Enrich all activity data with names
|
|
foreach (var dto in dtos)
|
|
{
|
|
if (dto.ActivityData == null) continue;
|
|
|
|
// Sort by most recent first
|
|
dto.ActivityData = dto.ActivityData
|
|
.OrderByDescending(a => a.EndTimeUtc)
|
|
.ToList();
|
|
|
|
|
|
// First activity data will be the most recent
|
|
foreach (var activity in dto.ActivityData)
|
|
{
|
|
activity.LibraryName = libraryLookup.GetValueOrDefault(activity.LibraryId, string.Empty);
|
|
activity.SeriesName = seriesLookup.GetValueOrDefault(activity.SeriesId, string.Empty);
|
|
activity.ChapterTitle = chapterLookup.GetValueOrDefault(activity.ChapterId, string.Empty);
|
|
}
|
|
}
|
|
|
|
return dtos;
|
|
}
|
|
}
|