diff --git a/API.Benchmark/ParserBenchmarks.cs b/API.Benchmark/ParserBenchmarks.cs index 493af5e4d..98e83eb00 100644 --- a/API.Benchmark/ParserBenchmarks.cs +++ b/API.Benchmark/ParserBenchmarks.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Text.RegularExpressions; using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Order; diff --git a/API.Tests/Services/BookmarkServiceTests.cs b/API.Tests/Services/BookmarkServiceTests.cs index f83fb55ed..5f862d35f 100644 --- a/API.Tests/Services/BookmarkServiceTests.cs +++ b/API.Tests/Services/BookmarkServiceTests.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Data.Common; using System.IO; using System.IO.Abstractions.TestingHelpers; @@ -10,15 +11,11 @@ using API.DTOs.Reader; using API.Entities; using API.Entities.Enums; using API.Services; -using API.Services.Tasks; -using API.SignalR; using AutoMapper; -using Microsoft.AspNetCore.SignalR; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.Extensions.Logging; -using NetVips; using NSubstitute; using Xunit; @@ -26,10 +23,7 @@ namespace API.Tests.Services; public class BookmarkServiceTests { - private readonly ILogger _logger = Substitute.For>(); private readonly IUnitOfWork _unitOfWork; - private readonly IHubContext _messageHub = Substitute.For>(); - private readonly DbConnection _connection; private readonly DataContext _context; @@ -63,8 +57,6 @@ public class BookmarkServiceTests return connection; } - public void Dispose() => _connection.Dispose(); - private async Task SeedDb() { await _context.Database.MigrateAsync(); diff --git a/API.Tests/Services/CleanupServiceTests.cs b/API.Tests/Services/CleanupServiceTests.cs index 77984a10c..44cba64a4 100644 --- a/API.Tests/Services/CleanupServiceTests.cs +++ b/API.Tests/Services/CleanupServiceTests.cs @@ -61,8 +61,6 @@ public class CleanupServiceTests return connection; } - public void Dispose() => _connection.Dispose(); - private async Task SeedDb() { await _context.Database.MigrateAsync(); diff --git a/API.Tests/Services/ParseScannedFilesTests.cs b/API.Tests/Services/ParseScannedFilesTests.cs index bd1174416..e3b0b498f 100644 --- a/API.Tests/Services/ParseScannedFilesTests.cs +++ b/API.Tests/Services/ParseScannedFilesTests.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Data.Common; using System.IO.Abstractions.TestingHelpers; using System.Linq; @@ -95,8 +96,6 @@ public class ParseScannedFilesTests return connection; } - public void Dispose() => _connection.Dispose(); - private async Task SeedDb() { await _context.Database.MigrateAsync(); diff --git a/API.Tests/Services/ReaderServiceTests.cs b/API.Tests/Services/ReaderServiceTests.cs index 2356eaef7..05d076b3f 100644 --- a/API.Tests/Services/ReaderServiceTests.cs +++ b/API.Tests/Services/ReaderServiceTests.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Data.Common; using System.IO.Abstractions.TestingHelpers; using System.Linq; @@ -10,10 +11,8 @@ using API.Entities; using API.Entities.Enums; using API.Helpers; using API.Services; -using API.SignalR; using API.Tests.Helpers; using AutoMapper; -using Microsoft.AspNetCore.SignalR; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; @@ -25,9 +24,8 @@ namespace API.Tests.Services; public class ReaderServiceTests { - private readonly ILogger _logger = Substitute.For>(); + private readonly IUnitOfWork _unitOfWork; - private readonly IHubContext _messageHub = Substitute.For>(); private readonly DbConnection _connection; private readonly DataContext _context; @@ -61,8 +59,6 @@ public class ReaderServiceTests return connection; } - public void Dispose() => _connection.Dispose(); - private async Task SeedDb() { await _context.Database.MigrateAsync(); @@ -902,6 +898,81 @@ public class ReaderServiceTests Assert.Equal(-1, prevChapter); } + [Fact] + public async Task GetPrevChapterIdAsync_ShouldFindNoPrevChapterFromVolumeWithZeroChapter() + { + await ResetDB(); + + _context.Series.Add(new Series() + { + Name = "Test", + Library = new Library() { + Name = "Test LIb", + Type = LibraryType.Manga, + }, + Volumes = new List() + { + EntityFactory.CreateVolume("1", new List() + { + EntityFactory.CreateChapter("0", false, new List()), + }), + } + }); + + _context.AppUser.Add(new AppUser() + { + UserName = "majora2007" + }); + + await _context.SaveChangesAsync(); + + var readerService = new ReaderService(_unitOfWork, Substitute.For>()); + + + var prevChapter = await readerService.GetPrevChapterIdAsync(1, 1, 1, 1); + Assert.Equal(-1, prevChapter); + } + + [Fact] + public async Task GetPrevChapterIdAsync_ShouldFindNoPrevChapterFromVolumeWithZeroChapterAndHasNormalChapters() + { + await ResetDB(); + + _context.Series.Add(new Series() + { + Name = "Test", + Library = new Library() { + Name = "Test LIb", + Type = LibraryType.Manga, + }, + Volumes = new List() + { + EntityFactory.CreateVolume("0", new List() + { + EntityFactory.CreateChapter("1", false, new List()), + EntityFactory.CreateChapter("2", false, new List()), + }), + EntityFactory.CreateVolume("1", new List() + { + EntityFactory.CreateChapter("0", false, new List()), + }), + } + }); + + _context.AppUser.Add(new AppUser() + { + UserName = "majora2007" + }); + + await _context.SaveChangesAsync(); + + var readerService = new ReaderService(_unitOfWork, Substitute.For>()); + + + var prevChapter = await readerService.GetPrevChapterIdAsync(1, 1, 1, 1); + Assert.Equal(-1, prevChapter); + } + [Fact] public async Task GetPrevChapterIdAsync_ShouldFindNoPrevChapterFromChapter() { diff --git a/API/Constants/PolicyConstants.cs b/API/Constants/PolicyConstants.cs index baf18b55e..8e8a2bc5d 100644 --- a/API/Constants/PolicyConstants.cs +++ b/API/Constants/PolicyConstants.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Collections.Immutable; +using System.Collections.Immutable; namespace API.Constants { diff --git a/API/Controllers/BookController.cs b/API/Controllers/BookController.cs index 4e55aeef1..89b2d3de4 100644 --- a/API/Controllers/BookController.cs +++ b/API/Controllers/BookController.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using API.Data; -using API.DTOs; using API.DTOs.Reader; using API.Entities.Enums; using API.Extensions; diff --git a/API/Controllers/CollectionController.cs b/API/Controllers/CollectionController.cs index 0c8738229..89921d5f2 100644 --- a/API/Controllers/CollectionController.cs +++ b/API/Controllers/CollectionController.cs @@ -156,7 +156,7 @@ namespace API.Controllers { tag.CoverImageLocked = false; tag.CoverImage = string.Empty; - await _messageHub.Clients.All.SendAsync(SignalREvents.CoverUpdate, MessageFactory.CoverUpdateEvent(tag.Id, "collection")); + await _messageHub.Clients.All.SendAsync(SignalREvents.CoverUpdate, MessageFactory.CoverUpdateEvent(tag.Id, "collectionTag")); _unitOfWork.CollectionTagRepository.Update(tag); } diff --git a/API/Controllers/ReaderController.cs b/API/Controllers/ReaderController.cs index 909fabd87..a71d73e42 100644 --- a/API/Controllers/ReaderController.cs +++ b/API/Controllers/ReaderController.cs @@ -8,7 +8,6 @@ using API.Data.Repositories; using API.DTOs; using API.DTOs.Reader; using API.Entities; -using API.Entities.Enums; using API.Extensions; using API.Services; using API.Services.Tasks; diff --git a/API/Controllers/ServerController.cs b/API/Controllers/ServerController.cs index 8b5cc80c8..7f5c16b0b 100644 --- a/API/Controllers/ServerController.cs +++ b/API/Controllers/ServerController.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Net.NetworkInformation; using System.Threading.Tasks; using API.DTOs.Stats; using API.DTOs.Update; diff --git a/API/DTOs/Account/MigrateUserEmailDto.cs b/API/DTOs/Account/MigrateUserEmailDto.cs index ec684a9be..aa947d5d1 100644 --- a/API/DTOs/Account/MigrateUserEmailDto.cs +++ b/API/DTOs/Account/MigrateUserEmailDto.cs @@ -1,6 +1,4 @@ -using System.ComponentModel.DataAnnotations; - -namespace API.DTOs.Account; +namespace API.DTOs.Account; public class MigrateUserEmailDto { diff --git a/API/DTOs/Search/SearchResultGroupDto.cs b/API/DTOs/Search/SearchResultGroupDto.cs index 109b078ff..2e802df6f 100644 --- a/API/DTOs/Search/SearchResultGroupDto.cs +++ b/API/DTOs/Search/SearchResultGroupDto.cs @@ -2,7 +2,6 @@ using API.DTOs.CollectionTags; using API.DTOs.Metadata; using API.DTOs.ReadingLists; -using API.Entities; namespace API.DTOs.Search; diff --git a/API/Data/Repositories/LibraryRepository.cs b/API/Data/Repositories/LibraryRepository.cs index a97826c75..4a3681de3 100644 --- a/API/Data/Repositories/LibraryRepository.cs +++ b/API/Data/Repositories/LibraryRepository.cs @@ -1,5 +1,4 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; diff --git a/API/Data/Repositories/SeriesRepository.cs b/API/Data/Repositories/SeriesRepository.cs index 67238efb7..eda93ad3a 100644 --- a/API/Data/Repositories/SeriesRepository.cs +++ b/API/Data/Repositories/SeriesRepository.cs @@ -636,7 +636,7 @@ public class SeriesRepository : ISeriesRepository && (!hasPeopleFilter || s.Metadata.People.Any(p => allPeopleIds.Contains(p.Id))) && (!hasCollectionTagFilter || s.Metadata.CollectionTags.Any(t => filter.CollectionTags.Contains(t.Id))) - && (!hasRatingFilter || s.Ratings.Any(r => r.Rating >= filter.Rating)) + && (!hasRatingFilter || s.Ratings.Any(r => r.Rating >= filter.Rating && r.AppUserId == userId)) && (!hasProgressFilter || seriesIds.Contains(s.Id)) && (!hasAgeRating || filter.AgeRating.Contains(s.Metadata.AgeRating)) && (!hasTagsFilter || s.Metadata.Tags.Any(t => filter.Tags.Contains(t.Id))) diff --git a/API/Helpers/AutoMapperProfiles.cs b/API/Helpers/AutoMapperProfiles.cs index e1cdce7ad..6ac4aeee5 100644 --- a/API/Helpers/AutoMapperProfiles.cs +++ b/API/Helpers/AutoMapperProfiles.cs @@ -2,7 +2,6 @@ using System.Linq; using API.DTOs; using API.DTOs.CollectionTags; -using API.DTOs.Email; using API.DTOs.Metadata; using API.DTOs.Reader; using API.DTOs.ReadingLists; diff --git a/API/Services/BookService.cs b/API/Services/BookService.cs index 0b59e109d..9531aa785 100644 --- a/API/Services/BookService.cs +++ b/API/Services/BookService.cs @@ -388,6 +388,7 @@ namespace API.Services Year = !string.IsNullOrEmpty(publicationDate) ? DateTime.Parse(publicationDate).Year : 0, Title = epubBook.Title, Genre = string.Join(",", epubBook.Schema.Package.Metadata.Subjects.Select(s => s.ToLower().Trim())), + LanguageISO = epubBook.Schema.Package.Metadata.Languages.FirstOrDefault() ?? string.Empty }; // Parse tags not exposed via Library diff --git a/API/Services/BookmarkService.cs b/API/Services/BookmarkService.cs index baf304bd3..7acea6ad8 100644 --- a/API/Services/BookmarkService.cs +++ b/API/Services/BookmarkService.cs @@ -4,7 +4,6 @@ using System.IO; using System.Linq; using System.Threading.Tasks; using API.Data; -using API.Data.Repositories; using API.DTOs.Reader; using API.Entities; using API.Entities.Enums; diff --git a/API/Services/DirectoryService.cs b/API/Services/DirectoryService.cs index 24286c22d..0edf51ffc 100644 --- a/API/Services/DirectoryService.cs +++ b/API/Services/DirectoryService.cs @@ -1,5 +1,4 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Collections.Immutable; using System.IO; @@ -7,7 +6,6 @@ using System.IO.Abstractions; using System.Linq; using System.Text.RegularExpressions; using System.Threading.Tasks; -using API.Comparators; using API.Extensions; using Microsoft.Extensions.Logging; diff --git a/API/Services/MetadataService.cs b/API/Services/MetadataService.cs index fa650b7fc..75513193d 100644 --- a/API/Services/MetadataService.cs +++ b/API/Services/MetadataService.cs @@ -6,7 +6,6 @@ using System.Threading.Tasks; using API.Comparators; using API.Data; using API.Data.Repositories; -using API.Data.Scanner; using API.Entities; using API.Extensions; using API.Helpers; diff --git a/API/Services/Tasks/CleanupService.cs b/API/Services/Tasks/CleanupService.cs index 0e66a3860..fbb87ecd5 100644 --- a/API/Services/Tasks/CleanupService.cs +++ b/API/Services/Tasks/CleanupService.cs @@ -1,5 +1,4 @@ using System; -using System.IO; using System.Linq; using System.Threading.Tasks; using API.Data; diff --git a/API/SignalR/MessageFactory.cs b/API/SignalR/MessageFactory.cs index 385f42437..bf7c649bf 100644 --- a/API/SignalR/MessageFactory.cs +++ b/API/SignalR/MessageFactory.cs @@ -1,5 +1,4 @@ using System; -using System.Threading; using API.DTOs.Update; namespace API.SignalR diff --git a/UI/Web/src/app/_models/events/cover-update-event.ts b/UI/Web/src/app/_models/events/cover-update-event.ts index d15fab1a1..54d55049f 100644 --- a/UI/Web/src/app/_models/events/cover-update-event.ts +++ b/UI/Web/src/app/_models/events/cover-update-event.ts @@ -3,5 +3,5 @@ */ export interface CoverUpdateEvent { id: number; - entityType: 'series' | 'chapter' | 'volume' | 'collection'; + entityType: 'series' | 'chapter' | 'volume' | 'collectionTag'; } \ No newline at end of file diff --git a/UI/Web/src/app/cards/chapter-metadata-detail/chapter-metadata-detail.component.html b/UI/Web/src/app/cards/chapter-metadata-detail/chapter-metadata-detail.component.html index 8c6172824..064225057 100644 --- a/UI/Web/src/app/cards/chapter-metadata-detail/chapter-metadata-detail.component.html +++ b/UI/Web/src/app/cards/chapter-metadata-detail/chapter-metadata-detail.component.html @@ -4,7 +4,11 @@ - +
+
+ Id: {{chapter.id}} +
+
diff --git a/UI/Web/src/app/series-detail/series-detail.component.ts b/UI/Web/src/app/series-detail/series-detail.component.ts index d9020995b..d28acde9e 100644 --- a/UI/Web/src/app/series-detail/series-detail.component.ts +++ b/UI/Web/src/app/series-detail/series-detail.component.ts @@ -203,10 +203,7 @@ export class SeriesDetailComponent implements OnInit, OnDestroy { } else if (event.event === EVENTS.ScanSeries) { const seriesCoverUpdatedEvent = event.payload as ScanSeriesEvent; if (seriesCoverUpdatedEvent.seriesId === this.series.id) { - this.seriesService.getMetadata(this.series.id).pipe(take(1)).subscribe(metadata => { - this.seriesMetadata = metadata; - this.createHTML(); - }); + this.loadSeries(seriesId); } } }); diff --git a/UI/Web/src/app/shared/image/image.component.ts b/UI/Web/src/app/shared/image/image.component.ts index f2cc07347..f8ed4363c 100644 --- a/UI/Web/src/app/shared/image/image.component.ts +++ b/UI/Web/src/app/shared/image/image.component.ts @@ -1,6 +1,7 @@ import { Component, ElementRef, Input, OnChanges, OnDestroy, OnInit, Renderer2, SimpleChanges, ViewChild } from '@angular/core'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; +import { CoverUpdateEvent } from 'src/app/_models/events/cover-update-event'; import { ImageService } from 'src/app/_services/image.service'; import { EVENTS, MessageHubService } from 'src/app/_services/message-hub.service'; @@ -46,7 +47,13 @@ export class ImageComponent implements OnChanges, OnDestroy { constructor(public imageService: ImageService, private renderer: Renderer2, private hubService: MessageHubService) { this.hubService.messages$.pipe(takeUntil(this.onDestroy)).subscribe(res => { if (res.event === EVENTS.CoverUpdate) { - this.imageUrl = this.imageService.randomize(this.imageUrl); + const updateEvent = res.payload as CoverUpdateEvent; + if (this.imageUrl === undefined || this.imageUrl === null || this.imageUrl === '') return; + + const tokens = this.imageUrl.split(updateEvent.entityType + 'Id='); + if (tokens.length > 1 && tokens[1] === (updateEvent.id + '')) { + this.imageUrl = this.imageService.randomize(this.imageUrl); + } } }); }