Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v0.8.3.2 - A Small Hotfix #3194

Merged
merged 27 commits into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
370b412
Fixed a bug where library type wasn't wired up and all chapter cards …
majora2007 Sep 18, 2024
a42ab40
Instead of showing Special on chapter cards that belong to a volume w…
majora2007 Sep 18, 2024
54180c7
more fixes for card title
therobbiedavis Sep 18, 2024
5ec93f0
Fixed a locale string for edit icon
majora2007 Sep 18, 2024
bb087cb
Fixed Cover Artists still showing instead of Artist in search
majora2007 Sep 18, 2024
fe39ee4
Changed how the warning about having real settings before test work
majora2007 Sep 18, 2024
33af893
More localization cache busting techniques
majora2007 Sep 18, 2024
7d91b2f
adding custom card action padding
therobbiedavis Sep 18, 2024
a252dfe
Merge branch 'hotfix/v0.8.3' of https://github.com/Kareadita/Kavita i…
therobbiedavis Sep 18, 2024
08c0c19
Fixed a bug where manage tasks screen wasn't saving
majora2007 Sep 18, 2024
ec68607
Fixed a bug where manage tasks screen wasn't saving
majora2007 Sep 18, 2024
4beb2e7
Don't serialize reading list items over opds when we can avoid it
majora2007 Sep 18, 2024
9bde8e3
Changed edit setting item so that when selection text within the inpu…
majora2007 Sep 19, 2024
717bc6b
Fixed missing validators being updated for 256 character passwords
majora2007 Sep 19, 2024
179a033
[skip ci] Weblate Changes (#3188)
weblate Sep 19, 2024
96ef7b0
Locale fix
majora2007 Sep 19, 2024
49c62ae
Manually patch locale
majora2007 Sep 19, 2024
4868f0b
Fixed alignment on details tab so that Genres/Tags lines up with Writ…
majora2007 Sep 20, 2024
899fe27
Manually patched localization files so that we can release hotfix wit…
majora2007 Sep 20, 2024
ce2fd7b
Some more polish on details tab
majora2007 Sep 20, 2024
ff024a8
Fixed an issue where Cover Image Size wasn't displaying on the UI
majora2007 Sep 20, 2024
7beeab2
Fixed a bug when moving bookmark directory
majora2007 Sep 20, 2024
dc935ba
Better handle special chapters not leaking encoding on chapter detail…
majora2007 Sep 20, 2024
2db6a91
Fixed a bunch of issues around smart filters and base url reverse pro…
majora2007 Sep 20, 2024
2e3995c
[skip ci] Weblate Changes (#3195)
weblate Sep 20, 2024
25b767a
Version bump. I got to fix the GA
majora2007 Sep 20, 2024
91d3e0b
Refactored the code to use routerLink over href when doing internal l…
majora2007 Sep 20, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions API/Controllers/OPDSController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -549,12 +549,15 @@ public async Task<IActionResult> GetReadingLists(string apiKey, [FromQuery] int
Id = readingListDto.Id.ToString(),
Title = readingListDto.Title,
Summary = readingListDto.Summary,
Links = new List<FeedLink>()
{
CreateLink(FeedLinkRelation.SubSection, FeedLinkType.AtomNavigation, $"{prefix}{apiKey}/reading-list/{readingListDto.Id}"),
CreateLink(FeedLinkRelation.Image, FeedLinkType.Image, $"{baseUrl}api/image/readinglist-cover?readingListId={readingListDto.Id}&apiKey={apiKey}"),
CreateLink(FeedLinkRelation.Thumbnail, FeedLinkType.Image, $"{baseUrl}api/image/readinglist-cover?readingListId={readingListDto.Id}&apiKey={apiKey}")
}
Links =
[
CreateLink(FeedLinkRelation.SubSection, FeedLinkType.AtomNavigation,
$"{prefix}{apiKey}/reading-list/{readingListDto.Id}"),
CreateLink(FeedLinkRelation.Image, FeedLinkType.Image,
$"{baseUrl}api/image/readinglist-cover?readingListId={readingListDto.Id}&apiKey={apiKey}"),
CreateLink(FeedLinkRelation.Thumbnail, FeedLinkType.Image,
$"{baseUrl}api/image/readinglist-cover?readingListId={readingListDto.Id}&apiKey={apiKey}")
]
});
}

Expand All @@ -573,7 +576,7 @@ private static UserParams GetUserParams(int pageNumber)

[HttpGet("{apiKey}/reading-list/{readingListId}")]
[Produces("application/xml")]
public async Task<IActionResult> GetReadingListItems(int readingListId, string apiKey)
public async Task<IActionResult> GetReadingListItems(int readingListId, string apiKey, [FromQuery] int pageNumber = 0)
{
var userId = await GetUser(apiKey);
if (!(await _unitOfWork.SettingsRepository.GetSettingsDtoAsync()).EnableOpds)
Expand All @@ -592,7 +595,7 @@ public async Task<IActionResult> GetReadingListItems(int readingListId, string a
var feed = CreateFeed(readingList.Title + " " + await _localizationService.Translate(userId, "reading-list"), $"{apiKey}/reading-list/{readingListId}", apiKey, prefix);
SetFeedId(feed, $"reading-list-{readingListId}");

var items = (await _unitOfWork.ReadingListRepository.GetReadingListItemDtosByIdAsync(readingListId, userId)).ToList();
var items = await _unitOfWork.ReadingListRepository.GetReadingListItemDtosByIdAsync(readingListId, userId);
foreach (var item in items)
{
var chapterDto = await _unitOfWork.ChapterRepository.GetChapterDtoAsync(item.ChapterId);
Expand Down
3 changes: 2 additions & 1 deletion API/Controllers/SettingsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ public async Task<ActionResult<ServerSettingDto>> UpdateSettings(ServerSettingDt

if (updateBookmarks)
{
BackgroundJob.Enqueue(() => UpdateBookmarkDirectory(originalBookmarkDirectory, bookmarkDirectory));
UpdateBookmarkDirectory(originalBookmarkDirectory, bookmarkDirectory);
}

if (updateSettingsDto.EnableFolderWatching)
Expand All @@ -371,6 +371,7 @@ public async Task<ActionResult<ServerSettingDto>> UpdateSettings(ServerSettingDt
return Ok(updateSettingsDto);
}


private void UpdateBookmarkDirectory(string originalBookmarkDirectory, string bookmarkDirectory)
{
_directoryService.ExistOrCreate(bookmarkDirectory);
Expand Down
2 changes: 1 addition & 1 deletion API/DTOs/Account/ConfirmEmailDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public class ConfirmEmailDto
[Required]
public string Token { get; set; } = default!;
[Required]
[StringLength(32, MinimumLength = 6)]
[StringLength(256, MinimumLength = 6)]
public string Password { get; set; } = default!;
[Required]
public string Username { get; set; } = default!;
Expand Down
2 changes: 1 addition & 1 deletion API/DTOs/Account/ConfirmPasswordResetDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ public class ConfirmPasswordResetDto
[Required]
public string Token { get; set; } = default!;
[Required]
[StringLength(32, MinimumLength = 6)]
[StringLength(256, MinimumLength = 6)]
public string Password { get; set; } = default!;
}
2 changes: 1 addition & 1 deletion API/DTOs/Account/ResetPasswordDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class ResetPasswordDto
/// The new password
/// </summary>
[Required]
[StringLength(32, MinimumLength = 6)]
[StringLength(256, MinimumLength = 6)]
public string Password { get; init; } = default!;
/// <summary>
/// The old, existing password. If an admin is performing the change, this is not required. Otherwise, it is.
Expand Down
2 changes: 1 addition & 1 deletion API/DTOs/RegisterDto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ public class RegisterDto
/// </summary>
public string Email { get; init; } = default!;
[Required]
[StringLength(32, MinimumLength = 6)]
[StringLength(256, MinimumLength = 6)]
public string Password { get; set; } = default!;
}
1 change: 1 addition & 0 deletions API/Services/CacheService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ public IEnumerable<FileDimensionDto> GetCachedFileDimensions(string cachePath)
}

_logger.LogDebug("File Dimensions call for {Length} images took {Time}ms", dimensions.Count, sw.ElapsedMilliseconds);

return dimensions;
}

Expand Down
4 changes: 2 additions & 2 deletions Kavita.Common/Kavita.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<TargetFramework>net8.0</TargetFramework>
<Company>kavitareader.com</Company>
<Product>Kavita</Product>
<AssemblyVersion>0.8.3.1</AssemblyVersion>
<AssemblyVersion>0.8.3.2</AssemblyVersion>
<NeutralLanguage>en</NeutralLanguage>
<TieredPGO>true</TieredPGO>
</PropertyGroup>
Expand All @@ -20,4 +20,4 @@
</PackageReference>
<PackageReference Include="xunit.assert" Version="2.9.0" />
</ItemGroup>
</Project>
</Project>
2 changes: 1 addition & 1 deletion UI/Web/src/_card-item-common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ $image-width: 160px;
font-size: 0.8rem;
margin: 0;
text-align: center;
max-width: 110px;
max-width: 98px;

a {
overflow: hidden;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@
padding: var(--bs-dropdown-item-padding-y) 0;
}

.btn {
padding: 5px;
}

// Robbie added this but it broke most of the uses
//.dropdown-toggle {
// padding-top: 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
<ng-container *transloco="let t; read: 'details-tab'">
<div class="details pb-3">
<div class="mb-3">
<div class="mb-3 ms-1">
<h4 class="header">{{t('genres-title')}}</h4>
<app-badge-expander [includeComma]="true" [items]="genres" [itemsTillExpander]="3">
<ng-template #badgeExpanderItem let-item let-position="idx" let-last="last">
<a href="javascript:void(0)" class="dark-exempt btn-icon" (click)="openGeneric(FilterField.Genres, item.id)">{{item.title}}</a>
</ng-template>
</app-badge-expander>
<div class="ms-3">
<app-badge-expander [includeComma]="true" [items]="genres" [itemsTillExpander]="3">
<ng-template #badgeExpanderItem let-item let-position="idx" let-last="last">
<a href="javascript:void(0)" class="dark-exempt btn-icon" (click)="openGeneric(FilterField.Genres, item.id)">{{item.title}}</a>
</ng-template>
</app-badge-expander>
</div>
</div>

<div class="mb-3">
<div class="mb-3 ms-1">
<h4 class="header">{{t('tags-title')}}</h4>
<app-badge-expander [includeComma]="true" [items]="tags" [itemsTillExpander]="3">
<ng-template #badgeExpanderItem let-item let-position="idx" let-last="last">
<a href="javascript:void(0)" class="dark-exempt btn-icon" (click)="openGeneric(FilterField.Tags, item.id)">{{item.title}}</a>
</ng-template>
</app-badge-expander>
<div class="ms-3">
<app-badge-expander [includeComma]="true" [items]="tags" [itemsTillExpander]="3">
<ng-template #badgeExpanderItem let-item let-position="idx" let-last="last">
<a href="javascript:void(0)" class="dark-exempt btn-icon" (click)="openGeneric(FilterField.Tags, item.id)">{{item.title}}</a>
</ng-template>
</app-badge-expander>
</div>
</div>

<div class="mb-3">
Expand All @@ -29,7 +33,7 @@ <h4 class="header">{{t('tags-title')}}</h4>
</app-carousel-reel>
</div>

@if (genres.length > 0 || tags.length > 0) {
@if (genres.length > 0 || tags.length > 0 || webLinks.length > 0) {
<div class="setting-section-break" aria-hidden="true"></div>
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,7 @@
<p>{{t('description')}}</p>

<form [formGroup]="settingsForm">
<p class="alert alert-warning">{{t('setting-description')}}</p>

@if (settingsForm.dirty) {
<div class="alert alert-warning">{{t('test-warning')}}</div>
}
<p class="alert alert-warning">{{t('setting-description')}} {{t('test-warning')}}</p>

<div class="row g-0 mt-2">
@if (settingsForm.get('hostName'); as formControl) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, inject, OnInit} from '@angular/core';
import {FormControl, FormGroup, ReactiveFormsModule, Validators} from '@angular/forms';
import {ToastrService} from 'ngx-toastr';
import {debounceTime, distinctUntilChanged, filter, switchMap, take, tap} from 'rxjs';
import {debounceTime, distinctUntilChanged, filter, map, switchMap, take, tap} from 'rxjs';
import {SettingsService} from '../settings.service';
import {ServerSettings} from '../_models/server-settings';
import {
NgbAlert,
NgbTooltip
} from '@ng-bootstrap/ng-bootstrap';
import {NgIf, NgTemplateOutlet, TitleCasePipe} from '@angular/common';
import {AsyncPipe, NgIf, NgTemplateOutlet, TitleCasePipe} from '@angular/common';
import {translate, TranslocoModule} from "@jsverse/transloco";
import {SafeHtmlPipe} from "../../_pipes/safe-html.pipe";
import {ManageMediaIssuesComponent} from "../manage-media-issues/manage-media-issues.component";
Expand All @@ -25,7 +25,7 @@ import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [NgIf, ReactiveFormsModule, NgbTooltip, NgTemplateOutlet, TranslocoModule, SafeHtmlPipe,
ManageMediaIssuesComponent, TitleCasePipe, NgbAlert, SettingItemComponent, SettingSwitchComponent, DefaultValuePipe, BytesPipe]
ManageMediaIssuesComponent, TitleCasePipe, NgbAlert, SettingItemComponent, SettingSwitchComponent, DefaultValuePipe, BytesPipe, AsyncPipe]
})
export class ManageEmailSettingsComponent implements OnInit {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {allEncodeFormats} from '../_models/encode-format';
import {ManageMediaIssuesComponent} from '../manage-media-issues/manage-media-issues.component';
import {NgFor, NgIf, NgTemplateOutlet} from '@angular/common';
import {translate, TranslocoDirective, TranslocoService} from "@jsverse/transloco";
import {allCoverImageSizes} from '../_models/cover-image-size';
import {allCoverImageSizes, CoverImageSize} from '../_models/cover-image-size';
import {pageLayoutModes} from "../../_models/preferences/preferences";
import {PageLayoutModePipe} from "../../_pipes/page-layout-mode.pipe";
import {SettingItemComponent} from "../../settings/_components/setting-item/setting-item.component";
Expand Down Expand Up @@ -62,7 +62,7 @@ export class ManageMediaSettingsComponent implements OnInit {
this.serverSettings = settings;
this.settingsForm.addControl('encodeMediaAs', new FormControl(this.serverSettings.encodeMediaAs, [Validators.required]));
this.settingsForm.addControl('bookmarksDirectory', new FormControl(this.serverSettings.bookmarksDirectory, [Validators.required]));
this.settingsForm.addControl('coverImageSize', new FormControl(this.serverSettings.coverImageSize, [Validators.required]));
this.settingsForm.addControl('coverImageSize', new FormControl(this.serverSettings.coverImageSize || CoverImageSize.Default, [Validators.required]));

// Automatically save settings as we edit them
this.settingsForm.valueChanges.pipe(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export class ManageTasksSettingsComponent implements OnInit {
},
{
name: 'sync-themes-task',
description: 'sync-themes-desc',
description: 'sync-themes-task-desc',
api: this.serverService.syncThemes(),
successMessage: 'sync-themes-success'
},
Expand Down Expand Up @@ -143,72 +143,20 @@ export class ManageTasksSettingsComponent implements OnInit {
this.logLevels = result.levels;
this.serverSettings = result.settings;

// Create base controls for taskScan, taskBackup, taskCleanup
this.settingsForm.addControl('taskScan', new FormControl(this.serverSettings.taskScan, [Validators.required]));
this.settingsForm.addControl('taskBackup', new FormControl(this.serverSettings.taskBackup, [Validators.required]));
this.settingsForm.addControl('taskCleanup', new FormControl(this.serverSettings.taskCleanup, [Validators.required]));

if (!this.taskFrequencies.includes(this.serverSettings.taskScan)) {
this.settingsForm.get('taskScan')?.setValue(this.customOption);
this.settingsForm.addControl('taskScanCustom', new FormControl(this.serverSettings.taskScan, [Validators.required]));
} else {
this.settingsForm.addControl('taskScanCustom', new FormControl('', [Validators.required]));
}

if (!this.taskFrequencies.includes(this.serverSettings.taskBackup)) {
this.settingsForm.get('taskBackup')?.setValue(this.customOption);
this.settingsForm.addControl('taskBackupCustom', new FormControl(this.serverSettings.taskBackup, [Validators.required]));
} else {
this.settingsForm.addControl('taskBackupCustom', new FormControl('', [Validators.required]));
}

if (!this.taskFrequenciesForCleanup.includes(this.serverSettings.taskCleanup)) {
this.settingsForm.get('taskCleanup')?.setValue(this.customOption);
this.settingsForm.addControl('taskCleanupCustom', new FormControl(this.serverSettings.taskCleanup, [Validators.required]));
} else {
this.settingsForm.addControl('taskCleanupCustom', new FormControl('', [Validators.required]));
}

this.settingsForm.get('taskScanCustom')?.valueChanges.pipe(
debounceTime(100),
switchMap(val => this.settingsService.isValidCronExpression(val)),
tap(isValid => {
if (isValid) {
this.settingsForm.get('taskScanCustom')?.setErrors(null);
} else {
this.settingsForm.get('taskScanCustom')?.setErrors({invalidCron: true})
}
this.cdRef.markForCheck();
}),
takeUntilDestroyed(this.destroyRef)
).subscribe();

this.settingsForm.get('taskBackupCustom')?.valueChanges.pipe(
debounceTime(100),
switchMap(val => this.settingsService.isValidCronExpression(val)),
tap(isValid => {
if (isValid) {
this.settingsForm.get('taskBackupCustom')?.setErrors(null);
} else {
this.settingsForm.get('taskBackupCustom')?.setErrors({invalidCron: true})
}
this.cdRef.markForCheck();
}),
takeUntilDestroyed(this.destroyRef)
).subscribe();
this.updateCustomFields('taskScan', 'taskScanCustom', this.taskFrequencies, this.serverSettings.taskScan);
this.updateCustomFields('taskBackup', 'taskBackupCustom', this.taskFrequencies, this.serverSettings.taskBackup);
this.updateCustomFields('taskCleanup', 'taskCleanupCustom', this.taskFrequenciesForCleanup, this.serverSettings.taskCleanup);

this.settingsForm.get('taskCleanupCustom')?.valueChanges.pipe(
debounceTime(100),
switchMap(val => this.settingsService.isValidCronExpression(val)),
tap(isValid => {
if (isValid) {
this.settingsForm.get('taskCleanupCustom')?.setErrors(null);
} else {
this.settingsForm.get('taskCleanupCustom')?.setErrors({invalidCron: true})
}
this.cdRef.markForCheck();
}),
takeUntilDestroyed(this.destroyRef)
).subscribe();
// Call the validation method for each custom control
this.validateCronExpression('taskScanCustom');
this.validateCronExpression('taskBackupCustom');
this.validateCronExpression('taskCleanupCustom');

// Automatically save settings as we edit them
this.settingsForm.valueChanges.pipe(
Expand All @@ -235,6 +183,35 @@ export class ManageTasksSettingsComponent implements OnInit {
this.cdRef.markForCheck();
}

// Custom logic to dynamically handle custom fields and validators
updateCustomFields(controlName: string, customControlName: string, frequencyList: string[], currentSetting: string) {
if (!frequencyList.includes(currentSetting)) {
// If the setting is not in the predefined list, it's a custom value
this.settingsForm.get(controlName)?.setValue(this.customOption);
this.settingsForm.addControl(customControlName, new FormControl(currentSetting, [Validators.required]));
} else {
// Otherwise, reset the custom control (no need for Validators.required here)
this.settingsForm.addControl(customControlName, new FormControl(''));
}
}

// Validate the custom fields for cron expressions
validateCronExpression(controlName: string) {
this.settingsForm.get(controlName)?.valueChanges.pipe(
debounceTime(100),
switchMap(val => this.settingsService.isValidCronExpression(val)),
tap(isValid => {
if (isValid) {
this.settingsForm.get(controlName)?.setErrors(null);
} else {
this.settingsForm.get(controlName)?.setErrors({ invalidCron: true });
}
this.cdRef.markForCheck();
}),
takeUntilDestroyed(this.destroyRef)
).subscribe();
}


resetForm() {
this.settingsForm.get('taskScan')?.setValue(this.serverSettings.taskScan, {onlySelf: true, emitEvent: false});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ export class AllSeriesComponent implements OnInit {
private readonly cdRef: ChangeDetectorRef) {

this.router.routeReuseStrategy.shouldReuseRoute = () => false;
console.log('url: ', this.route.snapshot);

this.filterUtilityService.filterPresetsFromUrl(this.route.snapshot).subscribe(filter => {
this.filter = filter;
Expand Down
6 changes: 5 additions & 1 deletion UI/Web/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {ServerService} from "./_services/server.service";
import {OutOfDateModalComponent} from "./announcements/_components/out-of-date-modal/out-of-date-modal.component";
import {PreferenceNavComponent} from "./sidenav/preference-nav/preference-nav.component";
import {Breakpoint, UtilityService} from "./shared/_services/utility.service";
import {translate} from "@jsverse/transloco";
import {TranslocoService} from "@jsverse/transloco";

@Component({
selector: 'app-root',
Expand All @@ -47,6 +47,7 @@ export class AppComponent implements OnInit {
private readonly router = inject(Router);
private readonly themeService = inject(ThemeService);
private readonly document = inject(DOCUMENT);
private readonly translocoService = inject(TranslocoService);

protected readonly Breakpoint = Breakpoint;

Expand Down Expand Up @@ -126,6 +127,9 @@ export class AppComponent implements OnInit {
// Bust locale cache
localStorage.removeItem('@transloco/translations/timestamp');
localStorage.removeItem('@transloco/translations');
(this.translocoService as any).cache.delete(localStorage.getItem('kavita-locale') || 'en');
(this.translocoService as any).cache.clear();
localStorage.setItem('kavita--version', version);
location.reload();
}
localStorage.setItem('kavita--version', version);
Expand Down
Loading
Loading