Reading List Detail Overhaul + More Bugfixes and Polish (#3687)
Co-authored-by: Yongun Seong <yseong.p@gmail.com>
This commit is contained in:
parent
b2ee651fb8
commit
dad212bfb9
71 changed files with 5056 additions and 729 deletions
|
|
@ -1,10 +1,7 @@
|
|||
using System.Collections;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using API.DTOs;
|
||||
using API.Entities;
|
||||
using API.Entities.Enums;
|
||||
using API.Entities.Person;
|
||||
using API.Extensions;
|
||||
|
|
@ -31,15 +28,13 @@ public interface IPersonRepository
|
|||
Task<IList<PersonDto>> GetAllPersonDtosByRoleAsync(int userId, PersonRole role);
|
||||
Task RemoveAllPeopleNoLongerAssociated();
|
||||
Task<IList<PersonDto>> GetAllPeopleDtosForLibrariesAsync(int userId, List<int>? libraryIds = null);
|
||||
Task<int> GetCountAsync();
|
||||
|
||||
Task<string> GetCoverImageAsync(int personId);
|
||||
Task<string?> GetCoverImageAsync(int personId);
|
||||
Task<string?> GetCoverImageByNameAsync(string name);
|
||||
Task<IEnumerable<PersonRole>> GetRolesForPersonByName(int personId, int userId);
|
||||
Task<PagedList<BrowsePersonDto>> GetAllWritersAndSeriesCount(int userId, UserParams userParams);
|
||||
Task<Person?> GetPersonById(int personId);
|
||||
Task<PersonDto?> GetPersonDtoByName(string name, int userId);
|
||||
Task<Person> GetPersonByName(string name);
|
||||
Task<bool> IsNameUnique(string name);
|
||||
|
||||
Task<IEnumerable<SeriesDto>> GetSeriesKnownFor(int personId);
|
||||
|
|
@ -126,12 +121,8 @@ public class PersonRepository : IPersonRepository
|
|||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<int> GetCountAsync()
|
||||
{
|
||||
return await _context.Person.CountAsync();
|
||||
}
|
||||
|
||||
public async Task<string> GetCoverImageAsync(int personId)
|
||||
public async Task<string?> GetCoverImageAsync(int personId)
|
||||
{
|
||||
return await _context.Person
|
||||
.Where(c => c.Id == personId)
|
||||
|
|
@ -139,7 +130,7 @@ public class PersonRepository : IPersonRepository
|
|||
.SingleOrDefaultAsync();
|
||||
}
|
||||
|
||||
public async Task<string> GetCoverImageByNameAsync(string name)
|
||||
public async Task<string?> GetCoverImageByNameAsync(string name)
|
||||
{
|
||||
var normalized = name.ToNormalized();
|
||||
return await _context.Person
|
||||
|
|
@ -208,7 +199,7 @@ public class PersonRepository : IPersonRepository
|
|||
.FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
public async Task<PersonDto> GetPersonDtoByName(string name, int userId)
|
||||
public async Task<PersonDto?> GetPersonDtoByName(string name, int userId)
|
||||
{
|
||||
var normalized = name.ToNormalized();
|
||||
var ageRating = await _context.AppUser.GetUserAgeRestriction(userId);
|
||||
|
|
@ -220,11 +211,6 @@ public class PersonRepository : IPersonRepository
|
|||
.FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
public async Task<Person> GetPersonByName(string name)
|
||||
{
|
||||
return await _context.Person.FirstOrDefaultAsync(p => p.NormalizedName == name.ToNormalized());
|
||||
}
|
||||
|
||||
public async Task<bool> IsNameUnique(string name)
|
||||
{
|
||||
return !(await _context.Person.AnyAsync(p => p.Name == name));
|
||||
|
|
|
|||
|
|
@ -49,12 +49,14 @@ public interface IReadingListRepository
|
|||
Task<IList<string>> GetRandomCoverImagesAsync(int readingListId);
|
||||
Task<IList<string>> GetAllCoverImagesAsync();
|
||||
Task<bool> ReadingListExists(string name);
|
||||
IEnumerable<PersonDto> GetReadingListCharactersAsync(int readingListId);
|
||||
IEnumerable<PersonDto> GetReadingListPeopleAsync(int readingListId, PersonRole role);
|
||||
Task<ReadingListCast> GetReadingListAllPeopleAsync(int readingListId);
|
||||
Task<IList<ReadingList>> GetAllWithCoversInDifferentEncoding(EncodeFormat encodeFormat);
|
||||
Task<int> RemoveReadingListsWithoutSeries();
|
||||
Task<ReadingList?> GetReadingListByTitleAsync(string name, int userId, ReadingListIncludes includes = ReadingListIncludes.Items);
|
||||
Task<IEnumerable<ReadingList>> GetReadingListsByIds(IList<int> ids, ReadingListIncludes includes = ReadingListIncludes.Items);
|
||||
Task<IEnumerable<ReadingList>> GetReadingListsBySeriesId(int seriesId, ReadingListIncludes includes = ReadingListIncludes.Items);
|
||||
Task<ReadingListInfoDto?> GetReadingListInfoAsync(int readingListId);
|
||||
}
|
||||
|
||||
public class ReadingListRepository : IReadingListRepository
|
||||
|
|
@ -121,12 +123,12 @@ public class ReadingListRepository : IReadingListRepository
|
|||
.AnyAsync(x => x.NormalizedTitle != null && x.NormalizedTitle.Equals(normalized));
|
||||
}
|
||||
|
||||
public IEnumerable<PersonDto> GetReadingListCharactersAsync(int readingListId)
|
||||
public IEnumerable<PersonDto> GetReadingListPeopleAsync(int readingListId, PersonRole role)
|
||||
{
|
||||
return _context.ReadingListItem
|
||||
.Where(item => item.ReadingListId == readingListId)
|
||||
.SelectMany(item => item.Chapter.People)
|
||||
.Where(p => p.Role == PersonRole.Character)
|
||||
.Where(p => p.Role == role)
|
||||
.OrderBy(p => p.Person.NormalizedName)
|
||||
.Select(p => p.Person)
|
||||
.Distinct()
|
||||
|
|
@ -134,6 +136,77 @@ public class ReadingListRepository : IReadingListRepository
|
|||
.AsEnumerable();
|
||||
}
|
||||
|
||||
public async Task<ReadingListCast> GetReadingListAllPeopleAsync(int readingListId)
|
||||
{
|
||||
var allPeople = await _context.ReadingListItem
|
||||
.Where(item => item.ReadingListId == readingListId)
|
||||
.SelectMany(item => item.Chapter.People)
|
||||
.OrderBy(p => p.Person.NormalizedName)
|
||||
.Select(p => new
|
||||
{
|
||||
Role = p.Role,
|
||||
Person = _mapper.Map<PersonDto>(p.Person)
|
||||
})
|
||||
.Distinct()
|
||||
.ToListAsync();
|
||||
|
||||
// Create the ReadingListCast object
|
||||
var cast = new ReadingListCast();
|
||||
|
||||
// Group people by role and populate the appropriate collections
|
||||
foreach (var personGroup in allPeople.GroupBy(p => p.Role))
|
||||
{
|
||||
var people = personGroup.Select(pg => pg.Person).ToList();
|
||||
|
||||
switch (personGroup.Key)
|
||||
{
|
||||
case PersonRole.Writer:
|
||||
cast.Writers = people;
|
||||
break;
|
||||
case PersonRole.CoverArtist:
|
||||
cast.CoverArtists = people;
|
||||
break;
|
||||
case PersonRole.Publisher:
|
||||
cast.Publishers = people;
|
||||
break;
|
||||
case PersonRole.Character:
|
||||
cast.Characters = people;
|
||||
break;
|
||||
case PersonRole.Penciller:
|
||||
cast.Pencillers = people;
|
||||
break;
|
||||
case PersonRole.Inker:
|
||||
cast.Inkers = people;
|
||||
break;
|
||||
case PersonRole.Imprint:
|
||||
cast.Imprints = people;
|
||||
break;
|
||||
case PersonRole.Colorist:
|
||||
cast.Colorists = people;
|
||||
break;
|
||||
case PersonRole.Letterer:
|
||||
cast.Letterers = people;
|
||||
break;
|
||||
case PersonRole.Editor:
|
||||
cast.Editors = people;
|
||||
break;
|
||||
case PersonRole.Translator:
|
||||
cast.Translators = people;
|
||||
break;
|
||||
case PersonRole.Team:
|
||||
cast.Teams = people;
|
||||
break;
|
||||
case PersonRole.Location:
|
||||
cast.Locations = people;
|
||||
break;
|
||||
case PersonRole.Other:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return cast;
|
||||
}
|
||||
|
||||
public async Task<IList<ReadingList>> GetAllWithCoversInDifferentEncoding(EncodeFormat encodeFormat)
|
||||
{
|
||||
var extension = encodeFormat.GetExtension();
|
||||
|
|
@ -181,6 +254,33 @@ public class ReadingListRepository : IReadingListRepository
|
|||
.ToListAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a Partial ReadingListInfoDto. The HourEstimate needs to be calculated outside the repo
|
||||
/// </summary>
|
||||
/// <param name="readingListId"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ReadingListInfoDto?> GetReadingListInfoAsync(int readingListId)
|
||||
{
|
||||
// Get sum of these across all ReadingListItems: long wordCount, int pageCount, bool isEpub (assume false if any ReadingListeItem.Series.Format is non-epub)
|
||||
var readingList = await _context.ReadingList
|
||||
.Where(rl => rl.Id == readingListId)
|
||||
.Include(rl => rl.Items)
|
||||
.ThenInclude(item => item.Series)
|
||||
.Include(rl => rl.Items)
|
||||
.ThenInclude(item => item.Volume)
|
||||
.Include(rl => rl.Items)
|
||||
.ThenInclude(item => item.Chapter)
|
||||
.Select(rl => new ReadingListInfoDto()
|
||||
{
|
||||
WordCount = rl.Items.Sum(item => item.Chapter.WordCount),
|
||||
Pages = rl.Items.Sum(item => item.Chapter.Pages),
|
||||
IsAllEpub = rl.Items.All(item => item.Series.Format == MangaFormat.Epub),
|
||||
})
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
return readingList;
|
||||
}
|
||||
|
||||
|
||||
public void Remove(ReadingListItem item)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -167,11 +167,11 @@ public class ScrobbleRepository : IScrobbleRepository
|
|||
var query = _context.ScrobbleEvent
|
||||
.Where(e => e.AppUserId == userId)
|
||||
.Include(e => e.Series)
|
||||
.SortBy(filter.Field, filter.IsDescending)
|
||||
.WhereIf(!string.IsNullOrEmpty(filter.Query), s =>
|
||||
EF.Functions.Like(s.Series.Name, $"%{filter.Query}%")
|
||||
)
|
||||
.WhereIf(!filter.IncludeReviews, e => e.ScrobbleEventType != ScrobbleEventType.Review)
|
||||
.SortBy(filter.Field, filter.IsDescending)
|
||||
.AsSplitQuery()
|
||||
.ProjectTo<ScrobbleEventDto>(_mapper.ConfigurationProvider);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue