mirror of
https://github.com/Kareadita/Kavita.git
synced 2025-07-09 03:04:19 -04:00
Polish for Release (#2357)
This commit is contained in:
parent
b0eb60e894
commit
05bcc3e88e
@ -200,6 +200,10 @@ public class MangaParserTests
|
|||||||
[InlineData("Accel World Chapter 001 Volume 002", "Accel World")]
|
[InlineData("Accel World Chapter 001 Volume 002", "Accel World")]
|
||||||
[InlineData("Bleach 001-003", "Bleach")]
|
[InlineData("Bleach 001-003", "Bleach")]
|
||||||
[InlineData("Accel World Volume 2", "Accel World")]
|
[InlineData("Accel World Volume 2", "Accel World")]
|
||||||
|
[InlineData("죠시라쿠! 2년 후 v01", "죠시라쿠! 2년 후")]
|
||||||
|
[InlineData("죠시라쿠! 2년 후 1권", "죠시라쿠! 2년 후")]
|
||||||
|
[InlineData("test 2 years 1권", "test 2 years")]
|
||||||
|
[InlineData("test 2 years 1화", "test 2 years")]
|
||||||
public void ParseSeriesTest(string filename, string expected)
|
public void ParseSeriesTest(string filename, string expected)
|
||||||
{
|
{
|
||||||
Assert.Equal(expected, API.Services.Tasks.Scanner.Parser.Parser.ParseSeries(filename));
|
Assert.Equal(expected, API.Services.Tasks.Scanner.Parser.Parser.ParseSeries(filename));
|
||||||
|
@ -32,14 +32,8 @@ public class AppUserBuilder : IEntityBuilder<AppUser>
|
|||||||
DashboardStreams = new List<AppUserDashboardStream>(),
|
DashboardStreams = new List<AppUserDashboardStream>(),
|
||||||
SideNavStreams = new List<AppUserSideNavStream>()
|
SideNavStreams = new List<AppUserSideNavStream>()
|
||||||
};
|
};
|
||||||
foreach (var s in Seed.DefaultStreams)
|
_appUser.DashboardStreams = Seed.DefaultStreams.ToList();
|
||||||
{
|
_appUser.SideNavStreams = Seed.DefaultSideNavStreams.ToList();
|
||||||
_appUser.DashboardStreams.Add(s);
|
|
||||||
}
|
|
||||||
foreach (var s in Seed.DefaultSideNavStreams)
|
|
||||||
{
|
|
||||||
_appUser.SideNavStreams.Add(s);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public AppUserBuilder WithLibrary(Library library, bool createSideNavStream = false)
|
public AppUserBuilder WithLibrary(Library library, bool createSideNavStream = false)
|
||||||
|
@ -678,6 +678,8 @@ public class SeriesService : ISeriesService
|
|||||||
.OrderBy(c => c.CreatedUtc)
|
.OrderBy(c => c.CreatedUtc)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
|
if (chapters.Count < 3) return _emptyExpectedChapter;
|
||||||
|
|
||||||
// Calculate the time differences between consecutive chapters
|
// Calculate the time differences between consecutive chapters
|
||||||
var timeDifferences = new List<TimeSpan>();
|
var timeDifferences = new List<TimeSpan>();
|
||||||
DateTime? previousChapterTime = null;
|
DateTime? previousChapterTime = null;
|
||||||
|
@ -321,6 +321,10 @@ public static class Parser
|
|||||||
new Regex(
|
new Regex(
|
||||||
@"(?<Series>.*)( ?- ?)Ch\.\d+-?\d*",
|
@"(?<Series>.*)( ?- ?)Ch\.\d+-?\d*",
|
||||||
MatchOptions, RegexTimeout),
|
MatchOptions, RegexTimeout),
|
||||||
|
// Korean catch all for symbols 죠시라쿠! 2년 후 1권
|
||||||
|
new Regex(
|
||||||
|
@"^(?!Vol)(?!Chapter)(?<Series>.+?)(-|_|\s|#)\d+(-\d+)?(권|화|話)",
|
||||||
|
MatchOptions, RegexTimeout),
|
||||||
// [BAA]_Darker_than_Black_Omake-1, Bleach 001-002, Kodoja #001 (March 2016)
|
// [BAA]_Darker_than_Black_Omake-1, Bleach 001-002, Kodoja #001 (March 2016)
|
||||||
new Regex(
|
new Regex(
|
||||||
@"^(?!Vol)(?!Chapter)(?<Series>.+?)(-|_|\s|#)\d+(-\d+)?",
|
@"^(?!Vol)(?!Chapter)(?<Series>.+?)(-|_|\s|#)\d+(-\d+)?",
|
||||||
|
@ -106,16 +106,18 @@ export class ErrorInterceptor implements HttpInterceptor {
|
|||||||
console.error('500 error: ', error);
|
console.error('500 error: ', error);
|
||||||
}
|
}
|
||||||
this.toast(err.message);
|
this.toast(err.message);
|
||||||
} else if (error.hasOwnProperty('message') && error.message.trim() !== '') {
|
return;
|
||||||
|
}
|
||||||
|
if (error.hasOwnProperty('message') && error.message.trim() !== '') {
|
||||||
if (error.message !== 'User is not authenticated' && error.message !== 'errors.user-not-auth') {
|
if (error.message !== 'User is not authenticated' && error.message !== 'errors.user-not-auth') {
|
||||||
console.error('500 error: ', error);
|
console.error('500 error: ', error);
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
this.toast('errors.unknown-crit');
|
this.toast('errors.unknown-crit');
|
||||||
console.error('500 error:', error);
|
console.error('500 error:', error);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private handleAuthError(error: any) {
|
private handleAuthError(error: any) {
|
||||||
// Special hack for register url, to not care about auth
|
// Special hack for register url, to not care about auth
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<button type="button" class="btn-close" [attr.aria-label]="t('close')" (click)="close()"></button>
|
<button type="button" class="btn-close" [attr.aria-label]="t('close')" (click)="close()"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body scrollable-modal">
|
<div class="modal-body scrollable-modal">
|
||||||
<p [innerHTML]="t('description') | safeHtml"></p>
|
<p *ngIf="!invited" [innerHTML]="t('description') | safeHtml"></p>
|
||||||
|
|
||||||
<form [formGroup]="inviteForm" *ngIf="emailLink === ''">
|
<form [formGroup]="inviteForm" *ngIf="emailLink === ''">
|
||||||
<div class="row g-0">
|
<div class="row g-0">
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import {ChangeDetectorRef, Component, inject, OnInit} from '@angular/core';
|
||||||
import { FormControl, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms';
|
import { FormControl, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||||
import { ToastrService } from 'ngx-toastr';
|
import { ToastrService } from 'ngx-toastr';
|
||||||
@ -33,6 +33,9 @@ export class InviteUserComponent implements OnInit {
|
|||||||
selectedLibraries: Array<number> = [];
|
selectedLibraries: Array<number> = [];
|
||||||
selectedRestriction: AgeRestriction = {ageRating: AgeRating.NotApplicable, includeUnknowns: false};
|
selectedRestriction: AgeRestriction = {ageRating: AgeRating.NotApplicable, includeUnknowns: false};
|
||||||
emailLink: string = '';
|
emailLink: string = '';
|
||||||
|
invited: boolean = false;
|
||||||
|
|
||||||
|
private readonly cdRef = inject(ChangeDetectorRef);
|
||||||
|
|
||||||
makeLink: (val: string) => string = (val: string) => {return this.emailLink};
|
makeLink: (val: string) => string = (val: string) => {return this.emailLink};
|
||||||
|
|
||||||
@ -51,7 +54,6 @@ export class InviteUserComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
invite() {
|
invite() {
|
||||||
|
|
||||||
this.isSending = true;
|
this.isSending = true;
|
||||||
const email = this.inviteForm.get('email')?.value.trim();
|
const email = this.inviteForm.get('email')?.value.trim();
|
||||||
this.accountService.inviteUser({
|
this.accountService.inviteUser({
|
||||||
@ -62,10 +64,12 @@ export class InviteUserComponent implements OnInit {
|
|||||||
}).subscribe((data: InviteUserResponse) => {
|
}).subscribe((data: InviteUserResponse) => {
|
||||||
this.emailLink = data.emailLink;
|
this.emailLink = data.emailLink;
|
||||||
this.isSending = false;
|
this.isSending = false;
|
||||||
|
this.invited = true;
|
||||||
if (data.emailSent) {
|
if (data.emailSent) {
|
||||||
this.toastr.info(translate('toasts.email-sent', {email: email}));
|
this.toastr.info(translate('toasts.email-sent', {email: email}));
|
||||||
this.modal.close(true);
|
this.modal.close(true);
|
||||||
}
|
}
|
||||||
|
this.cdRef.markForCheck();
|
||||||
}, err => {
|
}, err => {
|
||||||
this.isSending = false;
|
this.isSending = false;
|
||||||
this.toastr.error(err)
|
this.toastr.error(err)
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row g-0 mb-2">
|
<div class="row g-0 mb-2">
|
||||||
<div class="col-md-8 col-sm-12 pe-2">
|
<div class="col-md-8 col-sm-12 pe-md-2">
|
||||||
<label for="settings-ipaddresses" class="form-label">{{t('ip-address-label')}}</label><i class="fa fa-info-circle ms-1" placement="right" [ngbTooltip]="ipAddressesTooltip" role="button" tabindex="0"></i>
|
<label for="settings-ipaddresses" class="form-label">{{t('ip-address-label')}}</label><i class="fa fa-info-circle ms-1" placement="right" [ngbTooltip]="ipAddressesTooltip" role="button" tabindex="0"></i>
|
||||||
<ng-template #ipAddressesTooltip>{{t('ip-address-tooltip')}}</ng-template>
|
<ng-template #ipAddressesTooltip>{{t('ip-address-tooltip')}}</ng-template>
|
||||||
<span class="visually-hidden" id="settings-ipaddresses-help">
|
<span class="visually-hidden" id="settings-ipaddresses-help">
|
||||||
@ -42,7 +42,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-4 col-sm-12 pe-2">
|
<div class="col-md-4 col-sm-12">
|
||||||
<label for="settings-port" class="form-label">{{t('port-label')}}</label><i class="fa fa-info-circle ms-1" placement="right" [ngbTooltip]="portTooltip" role="button" tabindex="0"></i>
|
<label for="settings-port" class="form-label">{{t('port-label')}}</label><i class="fa fa-info-circle ms-1" placement="right" [ngbTooltip]="portTooltip" role="button" tabindex="0"></i>
|
||||||
<ng-template #portTooltip>{{t('port-tooltip')}}</ng-template>
|
<ng-template #portTooltip>{{t('port-tooltip')}}</ng-template>
|
||||||
<span class="visually-hidden" id="settings-port-help">
|
<span class="visually-hidden" id="settings-port-help">
|
||||||
@ -53,7 +53,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row g-0 mb-2">
|
<div class="row g-0 mb-2">
|
||||||
<div class="col-md-4 col-sm-12 pe-2">
|
<div class="col-md-4 col-sm-12 pe-md-2">
|
||||||
<label for="backup-tasks" class="form-label">{{t('backup-label')}}</label><i class="fa fa-info-circle ms-1" placement="right" [ngbTooltip]="backupTasksTooltip" role="button" tabindex="0"></i>
|
<label for="backup-tasks" class="form-label">{{t('backup-label')}}</label><i class="fa fa-info-circle ms-1" placement="right" [ngbTooltip]="backupTasksTooltip" role="button" tabindex="0"></i>
|
||||||
<ng-template #backupTasksTooltip>{{t('backup-tooltip')}}.</ng-template>
|
<ng-template #backupTasksTooltip>{{t('backup-tooltip')}}.</ng-template>
|
||||||
<span class="visually-hidden" id="backup-tasks-help">
|
<span class="visually-hidden" id="backup-tasks-help">
|
||||||
@ -75,7 +75,7 @@
|
|||||||
</ng-container>
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-4 col-sm-12 pe-2">
|
<div class="col-md-4 col-sm-12 pe-md-2">
|
||||||
<label for="log-tasks" class="form-label">{{t('log-label')}}</label><i class="fa fa-info-circle ms-1" placement="right" [ngbTooltip]="logTasksTooltip" role="button" tabindex="0"></i>
|
<label for="log-tasks" class="form-label">{{t('log-label')}}</label><i class="fa fa-info-circle ms-1" placement="right" [ngbTooltip]="logTasksTooltip" role="button" tabindex="0"></i>
|
||||||
<ng-template #logTasksTooltip>{{t('log-tooltip')}}</ng-template>
|
<ng-template #logTasksTooltip>{{t('log-tooltip')}}</ng-template>
|
||||||
<span class="visually-hidden" id="log-tasks-help">
|
<span class="visually-hidden" id="log-tasks-help">
|
||||||
@ -111,7 +111,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="row g-0 mb-2 mt-3">
|
<div class="row g-0 mb-2 mt-3">
|
||||||
<div class="col-md-4 col-sm-12 pe-2">
|
<div class="col-md-4 col-sm-12 pe-md-2">
|
||||||
<label for="cache-size" class="form-label">{{t('cache-size-label')}}</label><i class="fa fa-info-circle ms-1" placement="right" [ngbTooltip]="cacheSizeTooltip" role="button" tabindex="0"></i>
|
<label for="cache-size" class="form-label">{{t('cache-size-label')}}</label><i class="fa fa-info-circle ms-1" placement="right" [ngbTooltip]="cacheSizeTooltip" role="button" tabindex="0"></i>
|
||||||
<ng-template #cacheSizeTooltip>{{t('cache-size-tooltip')}}</ng-template>
|
<ng-template #cacheSizeTooltip>{{t('cache-size-tooltip')}}</ng-template>
|
||||||
<span class="visually-hidden" id="cache-size-help">
|
<span class="visually-hidden" id="cache-size-help">
|
||||||
@ -129,7 +129,7 @@
|
|||||||
</p>
|
</p>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4 col-sm-12 pe-2">
|
<div class="col-md-4 col-sm-12 pe-md-2">
|
||||||
<label for="on-deck-progress-days" class="form-label">{{t('on-deck-last-progress-label')}}</label><i class="fa fa-info-circle ms-1" placement="right" [ngbTooltip]="onDeckProgressDaysTooltip" role="button" tabindex="0"></i>
|
<label for="on-deck-progress-days" class="form-label">{{t('on-deck-last-progress-label')}}</label><i class="fa fa-info-circle ms-1" placement="right" [ngbTooltip]="onDeckProgressDaysTooltip" role="button" tabindex="0"></i>
|
||||||
<ng-template #onDeckProgressDaysTooltip>{{t('on-deck-last-progress-tooltip')}}</ng-template>
|
<ng-template #onDeckProgressDaysTooltip>{{t('on-deck-last-progress-tooltip')}}</ng-template>
|
||||||
<span class="visually-hidden" id="on-deck-progress-days-help">
|
<span class="visually-hidden" id="on-deck-progress-days-help">
|
||||||
@ -147,7 +147,7 @@
|
|||||||
</p>
|
</p>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4 col-sm-12 pe-2">
|
<div class="col-md-4 col-sm-12">
|
||||||
<label for="on-deck-update-days" class="form-label">{{t('on-deck-last-chapter-add-label')}}</label><i class="fa fa-info-circle ms-1" placement="right" [ngbTooltip]="onDeckUpdateDaysTooltip" role="button" tabindex="0"></i>
|
<label for="on-deck-update-days" class="form-label">{{t('on-deck-last-chapter-add-label')}}</label><i class="fa fa-info-circle ms-1" placement="right" [ngbTooltip]="onDeckUpdateDaysTooltip" role="button" tabindex="0"></i>
|
||||||
<ng-template #onDeckUpdateDaysTooltip>{{t('on-deck-last-chapter-add-tooltip')}}</ng-template>
|
<ng-template #onDeckUpdateDaysTooltip>{{t('on-deck-last-chapter-add-tooltip')}}</ng-template>
|
||||||
<span class="visually-hidden" id="on-deck-update-days-help">
|
<span class="visually-hidden" id="on-deck-update-days-help">
|
||||||
|
@ -93,7 +93,7 @@ export class FilterUtilitiesService {
|
|||||||
|
|
||||||
|
|
||||||
encodeSortOptions(sortOptions: SortOptions) {
|
encodeSortOptions(sortOptions: SortOptions) {
|
||||||
return `sortField=${sortOptions.sortField}&isAscending=${sortOptions.isAscending}`;
|
return `sortField=${sortOptions.sortField},isAscending=${sortOptions.isAscending}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
encodeFilterStatements(statements: Array<FilterStatement>) {
|
encodeFilterStatements(statements: Array<FilterStatement>) {
|
||||||
@ -195,7 +195,7 @@ export class FilterUtilitiesService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
decodeSortOptions(encodedSortOptions: string): SortOptions | null {
|
decodeSortOptions(encodedSortOptions: string): SortOptions | null {
|
||||||
const parts = decodeURIComponent(encodedSortOptions).split('&');
|
const parts = decodeURIComponent(encodedSortOptions).split(',');
|
||||||
const sortFieldPart = parts.find(part => part.startsWith('sortField='));
|
const sortFieldPart = parts.find(part => part.startsWith('sortField='));
|
||||||
const isAscendingPart = parts.find(part => part.startsWith('isAscending='));
|
const isAscendingPart = parts.find(part => part.startsWith('isAscending='));
|
||||||
|
|
||||||
|
@ -546,11 +546,11 @@
|
|||||||
"invite-user": {
|
"invite-user": {
|
||||||
"title": "Invite User",
|
"title": "Invite User",
|
||||||
"close": "{{common.close}}",
|
"close": "{{common.close}}",
|
||||||
"description": "Invite a user to your server. Enter their email in and we will send them an email to create an account. If you do not want to use our email service, you can <a href=\"https://wiki.kavitareader.com/en/guides/misc/email\" rel=\"noopener noreferrer\" target=\"_blank\">host your own</a> email service or use a fake email (Forgot User will not work). A link will be presented regardless and can be used to setup the account manually.",
|
"description": "Invite a user to your server by entering their email. They'll receive an email to create an account. For this to work you must have the Host Name field set in the <a href=\"/admin/dashboard#email\" rel=\"noopener noreferrer\" target=\"_blank\">Email</a> tab or be accessing your instance through it's remote URL. <br/><br/>Alternatively, you can use a username, but note that password resets won't be available for username-based accounts. If you do not want to use our email service, you can host your own email service.",
|
||||||
"email": "{{common.email}}",
|
"email": "{{common.email}}",
|
||||||
"required-field": "{{common.required-field}}",
|
"required-field": "{{common.required-field}}",
|
||||||
"setup-user-title": "User invited",
|
"setup-user-title": "User invited",
|
||||||
"setup-user-description": "You can use the following link below to setup the account for your user or use the copy button. You may need to log out before using the link to register a new user. If your server is externally accessible, an email will have been sent to the user and the links can be used by them to finish setting up their account.",
|
"setup-user-description": "You can use the following link below to setup the account for your user or use the copy button. You may need to log out before using the link to register a new user. If Kavita can determine your server as accessibile externally (or Host Name is set), an email will have been sent to the user and the links can be used by them to finish setting up their account. Otherwise, use the link below or in logs to manually send to them or setup their account.",
|
||||||
"setup-user-account": "Setup user's account",
|
"setup-user-account": "Setup user's account",
|
||||||
"setup-user-account-tooltip": "Copy this and paste in a new tab. You may need to log out.",
|
"setup-user-account-tooltip": "Copy this and paste in a new tab. You may need to log out.",
|
||||||
"invite-url-label": "Invite Url",
|
"invite-url-label": "Invite Url",
|
||||||
|
@ -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.9.3"
|
"version": "0.7.9.4"
|
||||||
},
|
},
|
||||||
"servers": [
|
"servers": [
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user