Release Testing Day 3 (#1946)

* Removed extra trace messages as the people issue might have been resolved.

* When registering, disable button until form is valid. Allow non-email formatted emails, but not blank.

* Fixed opds not having http(s)://

* Added a new API to allow scanning all libraries from end point

* Moved Bookmarks directory to Media tab

* Fixed an edge case for finding next chapter when we had volume 1,2 etc but they had the same chapter number.

* Code cleanup
This commit is contained in:
Joe Milazzo 2023-04-29 07:49:00 -05:00 committed by GitHub
parent 119ea35b62
commit 4e0e3608aa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 253 additions and 141 deletions

View file

@ -27,6 +27,20 @@
</div>
</div>
<div class="row g-0">
<div class="mb-3">
<label for="settings-bookmarksdir" class="form-label">Bookmarks Directory</label>&nbsp;<i class="fa fa-info-circle" placement="right" [ngbTooltip]="bookmarksDirectoryTooltip" role="button" tabindex="0"></i>
<ng-template #bookmarksDirectoryTooltip>Location where bookmarks will be stored. Bookmarks are source files and can be large. Choose a location with adequate storage. Directory is managed; other files within directory will be deleted. If Docker, mount an additional volume and use that.</ng-template>
<span class="visually-hidden" id="settings-bookmarksdir-help"><ng-container [ngTemplateOutlet]="bookmarksDirectoryTooltip"></ng-container></span>
<div class="input-group">
<input readonly id="settings-bookmarksdir" aria-describedby="settings-bookmarksdir-help" class="form-control" formControlName="bookmarksDirectory" type="text" aria-describedby="change-bookmarks-dir">
<button id="change-bookmarks-dir" class="btn btn-primary" (click)="openDirectoryChooser(settingsForm.get('bookmarksDirectory')?.value, 'bookmarksDirectory')">
Change
</button>
</div>
</div>
</div>
<div class="col-auto d-flex d-md-block justify-content-sm-center text-md-end">
<button type="button" class="flex-fill btn btn-secondary me-2" (click)="resetToDefaults()">Reset to Default</button>
<button type="button" class="flex-fill btn btn-secondary me-2" (click)="resetForm()">Reset</button>

View file

@ -4,6 +4,8 @@ import { ToastrService } from 'ngx-toastr';
import { take } from 'rxjs';
import { SettingsService } from '../settings.service';
import { ServerSettings } from '../_models/server-settings';
import { DirectoryPickerComponent, DirectoryPickerResult } from '../_modals/directory-picker/directory-picker.component';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
@Component({
selector: 'app-manage-media-settings',
@ -15,23 +17,25 @@ export class ManageMediaSettingsComponent implements OnInit {
serverSettings!: ServerSettings;
settingsForm: FormGroup = new FormGroup({});
constructor(private settingsService: SettingsService, private toastr: ToastrService) { }
constructor(private settingsService: SettingsService, private toastr: ToastrService, private modalService: NgbModal, ) { }
ngOnInit(): void {
this.settingsService.getServerSettings().pipe(take(1)).subscribe((settings: ServerSettings) => {
this.serverSettings = settings;
this.settingsForm.addControl('convertBookmarkToWebP', new FormControl(this.serverSettings.convertBookmarkToWebP, [Validators.required]));
this.settingsForm.addControl('convertCoverToWebP', new FormControl(this.serverSettings.convertCoverToWebP, [Validators.required]));
this.settingsForm.addControl('bookmarksDirectory', new FormControl(this.serverSettings.bookmarksDirectory, [Validators.required]));
});
}
resetForm() {
this.settingsForm.get('convertBookmarkToWebP')?.setValue(this.serverSettings.convertBookmarkToWebP);
this.settingsForm.get('convertCoverToWebP')?.setValue(this.serverSettings.convertCoverToWebP);
this.settingsForm.get('bookmarksDirectory')?.setValue(this.serverSettings.bookmarksDirectory);
this.settingsForm.markAsPristine();
}
async saveSettings() {
saveSettings() {
const modelSettings = Object.assign({}, this.serverSettings);
modelSettings.convertBookmarkToWebP = this.settingsForm.get('convertBookmarkToWebP')?.value;
modelSettings.convertCoverToWebP = this.settingsForm.get('convertCoverToWebP')?.value;
@ -46,7 +50,7 @@ export class ManageMediaSettingsComponent implements OnInit {
}
resetToDefaults() {
this.settingsService.resetServerSettings().pipe(take(1)).subscribe(async (settings: ServerSettings) => {
this.settingsService.resetServerSettings().pipe(take(1)).subscribe((settings: ServerSettings) => {
this.serverSettings = settings;
this.resetForm();
this.toastr.success('Server settings updated');
@ -54,4 +58,16 @@ export class ManageMediaSettingsComponent implements OnInit {
console.error('error: ', err);
});
}
openDirectoryChooser(existingDirectory: string, formControl: string) {
const modalRef = this.modalService.open(DirectoryPickerComponent, { scrollable: true, size: 'lg' });
modalRef.componentInstance.startingFolder = existingDirectory || '';
modalRef.componentInstance.helpUrl = '';
modalRef.closed.subscribe((closeResult: DirectoryPickerResult) => {
if (closeResult.success && closeResult.folderPath !== '') {
this.settingsForm.get(formControl)?.setValue(closeResult.folderPath);
this.settingsForm.markAsDirty();
}
});
}
}

View file

@ -10,19 +10,6 @@
<input readonly id="settings-cachedir" aria-describedby="settings-cachedir-help" class="form-control" formControlName="cacheDirectory" type="text">
</div> -->
<div class="mb-3">
<label for="settings-bookmarksdir" class="form-label">Bookmarks Directory</label>&nbsp;<i class="fa fa-info-circle" placement="right" [ngbTooltip]="bookmarksDirectoryTooltip" role="button" tabindex="0"></i>
<ng-template #bookmarksDirectoryTooltip>Location where bookmarks will be stored. Bookmarks are source files and can be large. Choose a location with adequate storage. Directory is managed; other files within directory will be deleted. If Docker, mount an additional volume and use that.</ng-template>
<span class="visually-hidden" id="settings-bookmarksdir-help"><ng-container [ngTemplateOutlet]="bookmarksDirectoryTooltip"></ng-container></span>
<div class="input-group">
<input readonly id="settings-bookmarksdir" aria-describedby="settings-bookmarksdir-help" class="form-control" formControlName="bookmarksDirectory" type="text" aria-describedby="change-bookmarks-dir">
<button id="change-bookmarks-dir" class="btn btn-primary" (click)="openDirectoryChooser(settingsForm.get('bookmarksDirectory')?.value, 'bookmarksDirectory')">
Change
</button>
</div>
</div>
<div class="mb-3">
<label for="settings-baseurl" class="form-label">Base Url</label>&nbsp;<i class="fa fa-info-circle" placement="right" [ngbTooltip]="baseUrlTooltip" role="button" tabindex="0"></i>
<ng-template #baseUrlTooltip>Use this if you want to host Kavita on a base url ie) yourdomain.com/kavita. Not supported on Docker using non-root user.</ng-template>

View file

@ -1,12 +1,10 @@
import { Component, OnInit } from '@angular/core';
import { FormGroup, Validators, FormControl } from '@angular/forms';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { ToastrService } from 'ngx-toastr';
import { take } from 'rxjs/operators';
import { TagBadgeCursor } from 'src/app/shared/tag-badge/tag-badge.component';
import { ServerService } from 'src/app/_services/server.service';
import { SettingsService } from '../settings.service';
import { DirectoryPickerComponent, DirectoryPickerResult } from '../_modals/directory-picker/directory-picker.component';
import { ServerSettings } from '../_models/server-settings';
const ValidIpAddress = /^(\s*((([12]?\d{1,2}\.){3}[12]?\d{1,2})|(([\da-f]{0,4}\:){0,7}([\da-f]{0,4})))\s*\,)*\s*((([12]?\d{1,2}\.){3}[12]?\d{1,2})|(([\da-f]{0,4}\:){0,7}([\da-f]{0,4})))\s*$/i;
@ -28,7 +26,7 @@ export class ManageSettingsComponent implements OnInit {
}
constructor(private settingsService: SettingsService, private toastr: ToastrService,
private modalService: NgbModal, private serverService: ServerService) { }
private serverService: ServerService) { }
ngOnInit(): void {
this.settingsService.getTaskFrequencies().pipe(take(1)).subscribe(frequencies => {
@ -40,7 +38,6 @@ export class ManageSettingsComponent implements OnInit {
this.settingsService.getServerSettings().pipe(take(1)).subscribe((settings: ServerSettings) => {
this.serverSettings = settings;
this.settingsForm.addControl('cacheDirectory', new FormControl(this.serverSettings.cacheDirectory, [Validators.required]));
this.settingsForm.addControl('bookmarksDirectory', new FormControl(this.serverSettings.bookmarksDirectory, [Validators.required]));
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('ipAddresses', new FormControl(this.serverSettings.ipAddresses, [Validators.required, Validators.pattern(ValidIpAddress)]));
@ -67,7 +64,6 @@ export class ManageSettingsComponent implements OnInit {
resetForm() {
this.settingsForm.get('cacheDirectory')?.setValue(this.serverSettings.cacheDirectory);
this.settingsForm.get('bookmarksDirectory')?.setValue(this.serverSettings.bookmarksDirectory);
this.settingsForm.get('scanTask')?.setValue(this.serverSettings.taskScan);
this.settingsForm.get('taskBackup')?.setValue(this.serverSettings.taskBackup);
this.settingsForm.get('ipAddresses')?.setValue(this.serverSettings.ipAddresses);
@ -127,15 +123,5 @@ export class ManageSettingsComponent implements OnInit {
});
}
openDirectoryChooser(existingDirectory: string, formControl: string) {
const modalRef = this.modalService.open(DirectoryPickerComponent, { scrollable: true, size: 'lg' });
modalRef.componentInstance.startingFolder = existingDirectory || '';
modalRef.componentInstance.helpUrl = '';
modalRef.closed.subscribe((closeResult: DirectoryPickerResult) => {
if (closeResult.success && closeResult.folderPath !== '') {
this.settingsForm.get(formControl)?.setValue(closeResult.folderPath);
this.settingsForm.markAsDirty();
}
});
}
}

View file

@ -51,7 +51,7 @@
</div>
<div class="float-end">
<button class="btn btn-secondary alt" type="submit">Register</button>
<button class="btn btn-secondary alt" type="submit" [disabled]="!registerForm.valid">Register</button>
</div>
</form>
</ng-container>

View file

@ -18,7 +18,7 @@ import { MemberService } from 'src/app/_services/member.service';
export class RegisterComponent {
registerForm: FormGroup = new FormGroup({
email: new FormControl('', [Validators.email]),
email: new FormControl('', [Validators.required]),
username: new FormControl('', [Validators.required]),
password: new FormControl('', [Validators.required, Validators.maxLength(32), Validators.minLength(6), Validators.pattern("^.{6,32}$")]),
});

View file

@ -257,10 +257,10 @@ export class UserPreferencesComponent implements OnInit, OnDestroy {
transformKeyToOpdsUrl(key: string) {
if (environment.production) {
return `${location.origin}${environment.apiUrl}opds/${key}`.replace('//', '/');
return `${location.origin}` + `${this.baseUrl}${environment.apiUrl}opds/${key}`.replace('//', '/');
}
return `${location.origin}${this.baseUrl}api/opds/${key}`.replace('//', '/');
return `${location.origin}${this.baseUrl.replace('//', '/')}api/opds/${key}`;
}
handleBackgroundColorChange() {