Kavita+ Overhaul & New Changelog (#3507)
This commit is contained in:
parent
d880c1690c
commit
a5707617f2
249 changed files with 14775 additions and 2300 deletions
|
|
@ -1,7 +1,7 @@
|
|||
import {
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component, inject,
|
||||
Component, DestroyRef, inject,
|
||||
OnInit
|
||||
} from '@angular/core';
|
||||
import { FormControl, FormGroup, Validators, ReactiveFormsModule } from "@angular/forms";
|
||||
|
|
@ -13,8 +13,15 @@ import { NgbTooltip } from '@ng-bootstrap/ng-bootstrap';
|
|||
import {environment} from "../../../environments/environment";
|
||||
import {translate, TranslocoDirective} from "@jsverse/transloco";
|
||||
import {WikiLink} from "../../_models/wiki";
|
||||
import {RouterLink} from "@angular/router";
|
||||
import {SettingItemComponent} from "../../settings/_components/setting-item/setting-item.component";
|
||||
import {DecimalPipe} from "@angular/common";
|
||||
import {DefaultValuePipe} from "../../_pipes/default-value.pipe";
|
||||
import {switchMap} from "rxjs";
|
||||
import {LicenseInfo} from "../../_models/kavitaplus/license-info";
|
||||
import {UtcToLocalTimePipe} from "../../_pipes/utc-to-local-time.pipe";
|
||||
import {filter, tap} from "rxjs/operators";
|
||||
import {SettingButtonComponent} from "../../settings/_components/setting-button/setting-button.component";
|
||||
import {LicenseService} from "../../_services/license.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-license',
|
||||
|
|
@ -22,50 +29,66 @@ import {SettingItemComponent} from "../../settings/_components/setting-item/sett
|
|||
styleUrls: ['./license.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
imports: [NgbTooltip, LoadingComponent, ReactiveFormsModule, TranslocoDirective, RouterLink, SettingItemComponent]
|
||||
imports: [NgbTooltip, LoadingComponent, ReactiveFormsModule, TranslocoDirective, SettingItemComponent,
|
||||
DefaultValuePipe, UtcToLocalTimePipe, SettingButtonComponent, DecimalPipe]
|
||||
})
|
||||
export class LicenseComponent implements OnInit {
|
||||
|
||||
private readonly cdRef = inject(ChangeDetectorRef);
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
private readonly toastr = inject(ToastrService);
|
||||
private readonly confirmService = inject(ConfirmService);
|
||||
protected readonly accountService = inject(AccountService);
|
||||
protected readonly licenseService = inject(LicenseService);
|
||||
protected readonly WikiLink = WikiLink;
|
||||
|
||||
formGroup: FormGroup = new FormGroup({});
|
||||
isViewMode: boolean = true;
|
||||
|
||||
hasValidLicense: boolean = false;
|
||||
hasLicense: boolean = false;
|
||||
isChecking: boolean = true;
|
||||
isSaving: boolean = false;
|
||||
|
||||
|
||||
|
||||
hasLicense: boolean = false;
|
||||
licenseInfo: LicenseInfo | null = null;
|
||||
showEmail: boolean = false;
|
||||
|
||||
buyLink = environment.buyLink;
|
||||
manageLink = environment.manageLink;
|
||||
|
||||
|
||||
|
||||
|
||||
ngOnInit(): void {
|
||||
this.formGroup.addControl('licenseKey', new FormControl('', [Validators.required]));
|
||||
this.formGroup.addControl('email', new FormControl('', [Validators.required]));
|
||||
this.formGroup.addControl('discordId', new FormControl('', [Validators.pattern(/\d+/)]));
|
||||
|
||||
this.loadLicenseInfo().subscribe();
|
||||
|
||||
}
|
||||
|
||||
loadLicenseInfo(forceCheck = false) {
|
||||
this.isChecking = true;
|
||||
this.cdRef.markForCheck();
|
||||
|
||||
this.accountService.hasAnyLicense().subscribe(res => {
|
||||
this.hasLicense = res;
|
||||
this.cdRef.markForCheck();
|
||||
|
||||
if (this.hasLicense) {
|
||||
this.accountService.hasValidLicense().subscribe(res => {
|
||||
this.hasValidLicense = res;
|
||||
return this.licenseService.hasAnyLicense()
|
||||
.pipe(
|
||||
tap(res => {
|
||||
this.hasLicense = res;
|
||||
this.isChecking = false;
|
||||
this.cdRef.markForCheck();
|
||||
});
|
||||
}
|
||||
});
|
||||
}),
|
||||
filter(hasLicense => hasLicense),
|
||||
tap(_ => {
|
||||
this.isChecking = true;
|
||||
this.cdRef.markForCheck();
|
||||
}),
|
||||
switchMap(_ => this.licenseService.licenseInfo(forceCheck)),
|
||||
tap(licenseInfo => {
|
||||
this.licenseInfo = licenseInfo;
|
||||
this.isChecking = false;
|
||||
this.cdRef.markForCheck();
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -79,30 +102,75 @@ export class LicenseComponent implements OnInit {
|
|||
saveForm() {
|
||||
this.isSaving = true;
|
||||
this.cdRef.markForCheck();
|
||||
this.accountService.updateUserLicense(this.formGroup.get('licenseKey')!.value.trim(), this.formGroup.get('email')!.value.trim(), this.formGroup.get('discordId')!.value.trim())
|
||||
const hadActiveLicenseBefore = this.licenseInfo?.isActive;
|
||||
this.licenseService.updateUserLicense(this.formGroup.get('licenseKey')!.value.trim(), this.formGroup.get('email')!.value.trim(), this.formGroup.get('discordId')!.value.trim())
|
||||
.subscribe(() => {
|
||||
this.accountService.hasValidLicense(true).subscribe(isValid => {
|
||||
this.hasValidLicense = isValid;
|
||||
if (!this.hasValidLicense) {
|
||||
this.toastr.info(translate('toasts.k+-license-saved'));
|
||||
} else {
|
||||
this.toastr.success(translate('toasts.k+-unlocked'));
|
||||
}
|
||||
this.hasLicense = this.formGroup.get('licenseKey')!.value.length > 0;
|
||||
|
||||
this.resetForm();
|
||||
this.isViewMode = true;
|
||||
this.isSaving = false;
|
||||
this.cdRef.markForCheck();
|
||||
this.loadLicenseInfo().subscribe(async (info) => {
|
||||
if (info?.isActive && !hadActiveLicenseBefore) {
|
||||
await this.confirmService.info(translate('license.k+-unlocked-description'), translate('license.k+-unlocked'));
|
||||
} else {
|
||||
this.toastr.info(translate('toasts.k+-license-saved'));
|
||||
}
|
||||
});
|
||||
}, async (err) => {
|
||||
await this.handleError(err);
|
||||
});
|
||||
}, err => {
|
||||
this.isSaving = false;
|
||||
this.cdRef.markForCheck();
|
||||
if (err.hasOwnProperty('error')) {
|
||||
this.toastr.error(JSON.parse(err['error']));
|
||||
}
|
||||
|
||||
private async handleError(err: any) {
|
||||
this.isSaving = false;
|
||||
this.cdRef.markForCheck();
|
||||
|
||||
if (err.hasOwnProperty('error')) {
|
||||
if (err['error'][0] === '{') {
|
||||
this.toastr.error(JSON.parse(err['error']));
|
||||
} else {
|
||||
// Prompt user if they want to override their instance. This will call the rest flow then the register flow
|
||||
if (err['error'] === 'Kavita instance already registered with another license') {
|
||||
const answer = await this.confirmService.confirm(translate('license.k+-license-overwrite'), {
|
||||
_type: 'confirm',
|
||||
content: translate('license.k+-license-overwrite'),
|
||||
disableEscape: false,
|
||||
header: translate('license.k+-already-registered-header'),
|
||||
buttons: [
|
||||
{
|
||||
text: translate('license.overwrite'),
|
||||
type: 'primary'
|
||||
},
|
||||
{
|
||||
text: translate('license.cancel'),
|
||||
type: 'secondary'
|
||||
},
|
||||
]
|
||||
});
|
||||
if (answer) {
|
||||
this.forceSave();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
this.toastr.error(translate('toasts.k+-error'));
|
||||
|
||||
}
|
||||
});
|
||||
this.toastr.error(err['error']);
|
||||
}
|
||||
} else {
|
||||
this.toastr.error(translate('toasts.k+-error'));
|
||||
}
|
||||
}
|
||||
|
||||
forceSave() {
|
||||
this.isSaving = false;
|
||||
this.cdRef.markForCheck();
|
||||
|
||||
this.licenseService.resetLicense(this.formGroup.get('licenseKey')!.value.trim(), this.formGroup.get('email')!.value.trim())
|
||||
.subscribe(_ => {
|
||||
this.saveForm();
|
||||
});
|
||||
}
|
||||
|
||||
async deleteLicense() {
|
||||
|
|
@ -110,10 +178,13 @@ export class LicenseComponent implements OnInit {
|
|||
return;
|
||||
}
|
||||
|
||||
this.accountService.deleteLicense().subscribe(() => {
|
||||
this.licenseService.deleteLicense().subscribe(() => {
|
||||
this.resetForm();
|
||||
this.toggleViewMode();
|
||||
this.validateLicense();
|
||||
this.isViewMode = true;
|
||||
this.licenseInfo = null;
|
||||
this.hasLicense = false;
|
||||
//this.hasValidLicense = false;
|
||||
this.cdRef.markForCheck();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -122,28 +193,44 @@ export class LicenseComponent implements OnInit {
|
|||
return;
|
||||
}
|
||||
|
||||
this.accountService.resetLicense(this.formGroup.get('licenseKey')!.value.trim(), this.formGroup.get('email')!.value.trim()).subscribe(() => {
|
||||
this.licenseService.resetLicense(this.formGroup.get('licenseKey')!.value.trim(), this.formGroup.get('email')!.value.trim()).subscribe(() => {
|
||||
this.toastr.success(translate('toasts.k+-reset-key-success'));
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
// validateLicense(forceCheck = false) {
|
||||
// return of().pipe(
|
||||
// startWith(null),
|
||||
// tap(_ => {
|
||||
// this.isChecking = true;
|
||||
// this.cdRef.markForCheck();
|
||||
// }),
|
||||
// switchMap(_ => this.licenseService.licenseInfo(forceCheck)),
|
||||
// tap(licenseInfo => {
|
||||
// this.licenseInfo = licenseInfo;
|
||||
// //this.hasValidLicense = licenseInfo?.isActive || false;
|
||||
// this.isChecking = false;
|
||||
// this.cdRef.markForCheck();
|
||||
// })
|
||||
// )
|
||||
//
|
||||
// }
|
||||
|
||||
updateEditMode(mode: boolean) {
|
||||
this.isViewMode = !mode;
|
||||
this.cdRef.markForCheck();
|
||||
}
|
||||
|
||||
toggleViewMode() {
|
||||
this.isViewMode = !this.isViewMode;
|
||||
console.log('edit mode: ', !this.isViewMode)
|
||||
this.cdRef.markForCheck();
|
||||
this.resetForm();
|
||||
}
|
||||
|
||||
validateLicense() {
|
||||
this.isChecking = true;
|
||||
this.accountService.hasValidLicense(true).subscribe(res => {
|
||||
this.hasValidLicense = res;
|
||||
this.isChecking = false;
|
||||
this.cdRef.markForCheck();
|
||||
});
|
||||
}
|
||||
|
||||
updateEditMode(mode: boolean) {
|
||||
this.isViewMode = mode;
|
||||
toggleEmailShow() {
|
||||
this.showEmail = !this.showEmail;
|
||||
this.cdRef.markForCheck();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue