mirror of
https://github.com/Kareadita/Kavita.git
synced 2025-06-04 22:25:36 -04:00
Few More Fixes (#2032)
* Fixed spreads stretching on PC * Fixed a bug where reading list dates couldn't be cleared out. * Reading list page refreshes after updating info in the modal * Fixed an issue where create library wouldn't take into account advanced settings. * Fixed an issue where selection of the first chapter of a series to pull series-level metadata could fail in cases where you had Volume 2 and Chapter 1, Volume 2 would be selected.
This commit is contained in:
parent
cb3c021573
commit
061be58496
@ -343,7 +343,7 @@ public class SeriesServiceTests : AbstractDbTest
|
|||||||
|
|
||||||
Assert.True(result);
|
Assert.True(result);
|
||||||
|
|
||||||
var ratings = (await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007", AppUserIncludes.Ratings))
|
var ratings = (await _unitOfWork.UserRepository.GetUserByUsernameAsync("majora2007", AppUserIncludes.Ratings))!
|
||||||
.Ratings;
|
.Ratings;
|
||||||
Assert.NotEmpty(ratings);
|
Assert.NotEmpty(ratings);
|
||||||
Assert.Equal(3, ratings.First().Rating);
|
Assert.Equal(3, ratings.First().Rating);
|
||||||
@ -780,7 +780,7 @@ public class SeriesServiceTests : AbstractDbTest
|
|||||||
{
|
{
|
||||||
var series = CreateSeriesMock();
|
var series = CreateSeriesMock();
|
||||||
|
|
||||||
var firstChapter = SeriesService.GetFirstChapterForMetadata(series, true);
|
var firstChapter = SeriesService.GetFirstChapterForMetadata(series);
|
||||||
Assert.Same("1", firstChapter.Range);
|
Assert.Same("1", firstChapter.Range);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -789,7 +789,7 @@ public class SeriesServiceTests : AbstractDbTest
|
|||||||
{
|
{
|
||||||
var series = CreateSeriesMock();
|
var series = CreateSeriesMock();
|
||||||
|
|
||||||
var firstChapter = SeriesService.GetFirstChapterForMetadata(series, false);
|
var firstChapter = SeriesService.GetFirstChapterForMetadata(series);
|
||||||
Assert.Same("1", firstChapter.Range);
|
Assert.Same("1", firstChapter.Range);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -808,10 +808,35 @@ public class SeriesServiceTests : AbstractDbTest
|
|||||||
new ChapterBuilder("1.2").WithFiles(files).WithPages(1).Build(),
|
new ChapterBuilder("1.2").WithFiles(files).WithPages(1).Build(),
|
||||||
};
|
};
|
||||||
|
|
||||||
var firstChapter = SeriesService.GetFirstChapterForMetadata(series, false);
|
var firstChapter = SeriesService.GetFirstChapterForMetadata(series);
|
||||||
Assert.Same("1.1", firstChapter.Range);
|
Assert.Same("1.1", firstChapter.Range);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetFirstChapterForMetadata_NonBook_ShouldReturnChapter1_WhenFirstVolumeIs3()
|
||||||
|
{
|
||||||
|
var file = new MangaFileBuilder("Test.cbz", MangaFormat.Archive, 1).Build();
|
||||||
|
|
||||||
|
var series = new SeriesBuilder("Test")
|
||||||
|
.WithVolume(new VolumeBuilder("0")
|
||||||
|
.WithChapter(new ChapterBuilder("1").WithPages(1).WithFile(file).Build())
|
||||||
|
.WithChapter(new ChapterBuilder("2").WithPages(1).WithFile(file).Build())
|
||||||
|
.Build())
|
||||||
|
.WithVolume(new VolumeBuilder("2")
|
||||||
|
.WithChapter(new ChapterBuilder("21").WithPages(1).WithFile(file).Build())
|
||||||
|
.WithChapter(new ChapterBuilder("22").WithPages(1).WithFile(file).Build())
|
||||||
|
.Build())
|
||||||
|
.WithVolume(new VolumeBuilder("3")
|
||||||
|
.WithChapter(new ChapterBuilder("31").WithPages(1).WithFile(file).Build())
|
||||||
|
.WithChapter(new ChapterBuilder("32").WithPages(1).WithFile(file).Build())
|
||||||
|
.Build())
|
||||||
|
.Build();
|
||||||
|
series.Library = new LibraryBuilder("Test LIb", LibraryType.Book).Build();
|
||||||
|
|
||||||
|
var firstChapter = SeriesService.GetFirstChapterForMetadata(series);
|
||||||
|
Assert.Same("1", firstChapter.Range);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region SeriesRelation
|
#region SeriesRelation
|
||||||
|
@ -50,22 +50,28 @@ public class LibraryController : BaseApiController
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new Library. Upon library creation, adds new library to all Admin accounts.
|
/// Creates a new Library. Upon library creation, adds new library to all Admin accounts.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="createLibraryDto"></param>
|
/// <param name="dto"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[Authorize(Policy = "RequireAdminRole")]
|
[Authorize(Policy = "RequireAdminRole")]
|
||||||
[HttpPost("create")]
|
[HttpPost("create")]
|
||||||
public async Task<ActionResult> AddLibrary(CreateLibraryDto createLibraryDto)
|
public async Task<ActionResult> AddLibrary(UpdateLibraryDto dto)
|
||||||
{
|
{
|
||||||
if (await _unitOfWork.LibraryRepository.LibraryExists(createLibraryDto.Name))
|
if (await _unitOfWork.LibraryRepository.LibraryExists(dto.Name))
|
||||||
{
|
{
|
||||||
return BadRequest("Library name already exists. Please choose a unique name to the server.");
|
return BadRequest("Library name already exists. Please choose a unique name to the server.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var library = new Library
|
var library = new Library
|
||||||
{
|
{
|
||||||
Name = createLibraryDto.Name,
|
Name = dto.Name,
|
||||||
Type = createLibraryDto.Type,
|
Type = dto.Type,
|
||||||
Folders = createLibraryDto.Folders.Select(x => new FolderPath {Path = x}).ToList()
|
Folders = dto.Folders.Select(x => new FolderPath {Path = x}).Distinct().ToList(),
|
||||||
|
FolderWatching = dto.FolderWatching,
|
||||||
|
IncludeInDashboard = dto.IncludeInDashboard,
|
||||||
|
IncludeInRecommended = dto.IncludeInRecommended,
|
||||||
|
IncludeInSearch = dto.IncludeInSearch,
|
||||||
|
ManageCollections = dto.ManageCollections,
|
||||||
|
ManageReadingLists = dto.ManageReadingLists,
|
||||||
};
|
};
|
||||||
|
|
||||||
_unitOfWork.LibraryRepository.Add(library);
|
_unitOfWork.LibraryRepository.Add(library);
|
||||||
@ -359,7 +365,7 @@ public class LibraryController : BaseApiController
|
|||||||
var originalFolders = library.Folders.Select(x => x.Path).ToList();
|
var originalFolders = library.Folders.Select(x => x.Path).ToList();
|
||||||
|
|
||||||
library.Name = newName;
|
library.Name = newName;
|
||||||
library.Folders = dto.Folders.Select(s => new FolderPath() {Path = s}).ToList();
|
library.Folders = dto.Folders.Select(s => new FolderPath() {Path = s}).Distinct().ToList();
|
||||||
|
|
||||||
var typeUpdate = library.Type != dto.Type;
|
var typeUpdate = library.Type != dto.Type;
|
||||||
var folderWatchingUpdate = library.FolderWatching != dto.FolderWatching;
|
var folderWatchingUpdate = library.FolderWatching != dto.FolderWatching;
|
||||||
|
@ -157,19 +157,19 @@ public class ReadingListService : IReadingListService
|
|||||||
readingList.CoverImageLocked = dto.CoverImageLocked;
|
readingList.CoverImageLocked = dto.CoverImageLocked;
|
||||||
|
|
||||||
|
|
||||||
if (NumberHelper.IsValidMonth(dto.StartingMonth))
|
if (NumberHelper.IsValidMonth(dto.StartingMonth) || dto.StartingMonth == 0)
|
||||||
{
|
{
|
||||||
readingList.StartingMonth = dto.StartingMonth;
|
readingList.StartingMonth = dto.StartingMonth;
|
||||||
}
|
}
|
||||||
if (NumberHelper.IsValidYear(dto.StartingYear))
|
if (NumberHelper.IsValidYear(dto.StartingYear) || dto.StartingYear == 0)
|
||||||
{
|
{
|
||||||
readingList.StartingYear = dto.StartingYear;
|
readingList.StartingYear = dto.StartingYear;
|
||||||
}
|
}
|
||||||
if (NumberHelper.IsValidMonth(dto.EndingMonth))
|
if (NumberHelper.IsValidMonth(dto.EndingMonth) || dto.EndingMonth == 0)
|
||||||
{
|
{
|
||||||
readingList.EndingMonth = dto.EndingMonth;
|
readingList.EndingMonth = dto.EndingMonth;
|
||||||
}
|
}
|
||||||
if (NumberHelper.IsValidYear(dto.EndingYear))
|
if (NumberHelper.IsValidYear(dto.EndingYear) || dto.EndingYear == 0)
|
||||||
{
|
{
|
||||||
readingList.EndingYear = dto.EndingYear;
|
readingList.EndingYear = dto.EndingYear;
|
||||||
}
|
}
|
||||||
|
@ -48,14 +48,25 @@ public class SeriesService : ISeriesService
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the first chapter for a series to extract metadata from (ie Summary, etc)
|
/// Returns the first chapter for a series to extract metadata from (ie Summary, etc)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="series"></param>
|
/// <param name="series">The full series with all volumes and chapters on it</param>
|
||||||
/// <param name="isBookLibrary"></param>
|
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static Chapter? GetFirstChapterForMetadata(Series series, bool isBookLibrary)
|
public static Chapter? GetFirstChapterForMetadata(Series series)
|
||||||
{
|
{
|
||||||
return series.Volumes.OrderBy(v => v.Number, ChapterSortComparer.Default)
|
var sortedVolumes = series.Volumes.OrderBy(v => v.Number, ChapterSortComparer.Default);
|
||||||
|
var minVolumeNumber = sortedVolumes
|
||||||
|
.Where(v => v.Number != 0)
|
||||||
|
.MinBy(v => v.Number);
|
||||||
|
|
||||||
|
var minChapter = series.Volumes
|
||||||
.SelectMany(v => v.Chapters.OrderBy(c => float.Parse(c.Number), ChapterSortComparer.Default))
|
.SelectMany(v => v.Chapters.OrderBy(c => float.Parse(c.Number), ChapterSortComparer.Default))
|
||||||
.FirstOrDefault();
|
.FirstOrDefault();
|
||||||
|
|
||||||
|
if (minVolumeNumber != null && minChapter != null && float.Parse(minChapter.Number) > minVolumeNumber.Number)
|
||||||
|
{
|
||||||
|
return minVolumeNumber.Chapters.MinBy(c => float.Parse(c.Number), ChapterSortComparer.Default);
|
||||||
|
}
|
||||||
|
|
||||||
|
return minChapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<bool> UpdateSeriesMetadata(UpdateSeriesMetadataDto updateSeriesMetadataDto)
|
public async Task<bool> UpdateSeriesMetadata(UpdateSeriesMetadataDto updateSeriesMetadataDto)
|
||||||
|
@ -266,8 +266,7 @@ public class ProcessSeries : IProcessSeries
|
|||||||
public void UpdateSeriesMetadata(Series series, Library library)
|
public void UpdateSeriesMetadata(Series series, Library library)
|
||||||
{
|
{
|
||||||
series.Metadata ??= new SeriesMetadataBuilder().Build();
|
series.Metadata ??= new SeriesMetadataBuilder().Build();
|
||||||
var isBook = library.Type == LibraryType.Book;
|
var firstChapter = SeriesService.GetFirstChapterForMetadata(series);
|
||||||
var firstChapter = SeriesService.GetFirstChapterForMetadata(series, isBook);
|
|
||||||
|
|
||||||
var firstFile = firstChapter?.Files.FirstOrDefault();
|
var firstFile = firstChapter?.Files.FirstOrDefault();
|
||||||
if (firstFile == null) return;
|
if (firstFile == null) return;
|
||||||
|
@ -42,13 +42,13 @@ img {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.full-width {
|
.full-width {
|
||||||
width: 100%;
|
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
max-width: fit-content;
|
max-width: fit-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fit-to-screen.full-width {
|
.fit-to-screen.full-width {
|
||||||
|
width: 100%;
|
||||||
max-height: calc(var(--vh)*100);
|
max-height: calc(var(--vh)*100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,18 +123,20 @@ export class ReadingListDetailComponent implements OnInit {
|
|||||||
this.router.navigate(this.readerService.getNavigationArray(item.libraryId, item.seriesId, item.chapterId, item.seriesFormat), {queryParams: params});
|
this.router.navigate(this.readerService.getNavigationArray(item.libraryId, item.seriesId, item.chapterId, item.seriesFormat), {queryParams: params});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleReadingListActionCallback(action: ActionItem<ReadingList>, readingList: ReadingList) {
|
async handleReadingListActionCallback(action: ActionItem<ReadingList>, readingList: ReadingList) {
|
||||||
switch(action.action) {
|
switch(action.action) {
|
||||||
case Action.Delete:
|
case Action.Delete:
|
||||||
this.deleteList(readingList);
|
await this.deleteList(readingList);
|
||||||
break;
|
break;
|
||||||
case Action.Edit:
|
case Action.Edit:
|
||||||
this.actionService.editReadingList(readingList, (readingList: ReadingList) => {
|
this.actionService.editReadingList(readingList, (readingList: ReadingList) => {
|
||||||
// Reload information around list
|
// Reload information around list
|
||||||
this.readingList = readingList;
|
this.readingListService.getReadingList(this.listId).subscribe(rl => {
|
||||||
|
this.readingList = rl;
|
||||||
this.readingListSummary = (this.readingList.summary === null ? '' : this.readingList.summary).replace(/\n/g, '<br>');
|
this.readingListSummary = (this.readingList.summary === null ? '' : this.readingList.summary).replace(/\n/g, '<br>');
|
||||||
this.readingListImage = this.imageService.randomize(this.imageService.getReadingListCoverImage(this.listId));
|
this.readingListImage = this.imageService.randomize(this.imageService.getReadingListCoverImage(this.listId));
|
||||||
this.cdRef.markForCheck();
|
this.cdRef.markForCheck();
|
||||||
|
})
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
33
openapi.json
33
openapi.json
@ -7,7 +7,7 @@
|
|||||||
"name": "GPL-3.0",
|
"name": "GPL-3.0",
|
||||||
"url": "https://github.com/Kareadita/Kavita/blob/develop/LICENSE"
|
"url": "https://github.com/Kareadita/Kavita/blob/develop/LICENSE"
|
||||||
},
|
},
|
||||||
"version": "0.7.2.26"
|
"version": "0.7.2.28"
|
||||||
},
|
},
|
||||||
"servers": [
|
"servers": [
|
||||||
{
|
{
|
||||||
@ -2129,17 +2129,17 @@
|
|||||||
"content": {
|
"content": {
|
||||||
"application/json": {
|
"application/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/components/schemas/CreateLibraryDto"
|
"$ref": "#/components/schemas/UpdateLibraryDto"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"text/json": {
|
"text/json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/components/schemas/CreateLibraryDto"
|
"$ref": "#/components/schemas/UpdateLibraryDto"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"application/*+json": {
|
"application/*+json": {
|
||||||
"schema": {
|
"schema": {
|
||||||
"$ref": "#/components/schemas/CreateLibraryDto"
|
"$ref": "#/components/schemas/UpdateLibraryDto"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -11191,31 +11191,6 @@
|
|||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
},
|
},
|
||||||
"CreateLibraryDto": {
|
|
||||||
"required": [
|
|
||||||
"folders",
|
|
||||||
"name",
|
|
||||||
"type"
|
|
||||||
],
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"name": {
|
|
||||||
"minLength": 1,
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"$ref": "#/components/schemas/LibraryType"
|
|
||||||
},
|
|
||||||
"folders": {
|
|
||||||
"minItems": 1,
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"additionalProperties": false
|
|
||||||
},
|
|
||||||
"CreateReadingListDto": {
|
"CreateReadingListDto": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user