From 5220d2b30093d088c941f27a4cdca92e4430686f Mon Sep 17 00:00:00 2001 From: ThePromidius Date: Fri, 18 Mar 2022 02:14:27 +0100 Subject: [PATCH] Fixed loose chapters marked as read for Tachiyomi (#1158) * Tachiyomi-related fixes * Created unit test for MarkAsReadAnythingUntil * Applied the requested changes. --- API.Tests/Services/ReaderServiceTests.cs | 72 ++++++++++++++++++++++++ API/Controllers/ReaderController.cs | 4 ++ API/Services/ReaderService.cs | 2 +- 3 files changed, 77 insertions(+), 1 deletion(-) diff --git a/API.Tests/Services/ReaderServiceTests.cs b/API.Tests/Services/ReaderServiceTests.cs index a66863487..402f136c3 100644 --- a/API.Tests/Services/ReaderServiceTests.cs +++ b/API.Tests/Services/ReaderServiceTests.cs @@ -1780,6 +1780,78 @@ public class ReaderServiceTests Assert.True(await _unitOfWork.AppUserProgressRepository.UserHasProgress(LibraryType.Manga, 1)); } + [Fact] + public async Task MarkChaptersUntilAsRead_ShouldMarkAsReadAnythingUntil() + { + 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("45", false, new List(), 5), + + EntityFactory.CreateChapter("46", false, new List(), 46), + EntityFactory.CreateChapter("47", false, new List(), 47), + EntityFactory.CreateChapter("48", false, new List(), 48), + EntityFactory.CreateChapter("49", false, new List(), 49), + EntityFactory.CreateChapter("50", false, new List(), 50), + EntityFactory.CreateChapter("Some Special Title", true, new List(), 10), + }), + EntityFactory.CreateVolume("1", new List() + { + EntityFactory.CreateChapter("0", false, new List(), 6), + }), + EntityFactory.CreateVolume("2", new List() + { + EntityFactory.CreateChapter("0", false, new List(), 7), + }), + EntityFactory.CreateVolume("3", new List() + { + EntityFactory.CreateChapter("12", false, new List(), 5), + EntityFactory.CreateChapter("13", false, new List(), 5), + EntityFactory.CreateChapter("14", false, new List(), 5), + }), + } + }); + + _context.AppUser.Add(new AppUser() + { + UserName = "majora2007" + }); + + await _context.SaveChangesAsync(); + + var readerService = new ReaderService(_unitOfWork, Substitute.For>()); + + var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007", AppUserIncludes.Progress); + const int markReadUntilNumber = 47; + + await readerService.MarkChaptersUntilAsRead(user, 1, markReadUntilNumber); + await _context.SaveChangesAsync(); + + var volumes = await _unitOfWork.VolumeRepository.GetVolumesDtoAsync(1, 1); + Assert.True(volumes.SelectMany(v => v.Chapters).All(c => + { + // Specials are ignored. + var notReadChapterRanges = new[] {"Some Special Title", "48", "49", "50"}; + if (notReadChapterRanges.Contains(c.Range)) + { + return c.PagesRead == 0; + } + // Pages read and total pages must match -> chapter fully read + return c.Pages == c.PagesRead; + + })); + } + #endregion diff --git a/API/Controllers/ReaderController.cs b/API/Controllers/ReaderController.cs index a8a34bdfd..9bcce9591 100644 --- a/API/Controllers/ReaderController.cs +++ b/API/Controllers/ReaderController.cs @@ -394,6 +394,10 @@ namespace API.Controllers var user = await _unitOfWork.UserRepository.GetUserByUsernameAsync(User.GetUsername(), AppUserIncludes.Progress); user.Progresses ??= new List(); + // Tachiyomi sends chapter 0.0f when there's no chapters read. + // Due to the encoding for volumes this marks all chapters in volume 0 (loose chapters) as read so we ignore it + if (chapterNumber == 0.0f) return true; + if (chapterNumber < 1.0f) { // This is a hack to track volume number. We need to map it back by x100 diff --git a/API/Services/ReaderService.cs b/API/Services/ReaderService.cs index ee8647187..f5437e7bc 100644 --- a/API/Services/ReaderService.cs +++ b/API/Services/ReaderService.cs @@ -443,7 +443,7 @@ public class ReaderService : IReaderService public async Task MarkVolumesUntilAsRead(AppUser user, int seriesId, int volumeNumber) { var volumes = await _unitOfWork.VolumeRepository.GetVolumesForSeriesAsync(new List() { seriesId }, true); - foreach (var volume in volumes.OrderBy(v => v.Number).Where(v => v.Number <= volumeNumber)) + foreach (var volume in volumes.OrderBy(v => v.Number).Where(v => v.Number <= volumeNumber && v.Number > 0)) { MarkChaptersAsRead(user, volume.SeriesId, volume.Chapters); }