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("Bleach 001-003", "Bleach")]
|
||||
[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)
|
||||
{
|
||||
Assert.Equal(expected, API.Services.Tasks.Scanner.Parser.Parser.ParseSeries(filename));
|
||||
|
@ -32,14 +32,8 @@ public class AppUserBuilder : IEntityBuilder<AppUser>
|
||||
DashboardStreams = new List<AppUserDashboardStream>(),
|
||||
SideNavStreams = new List<AppUserSideNavStream>()
|
||||
};
|
||||
foreach (var s in Seed.DefaultStreams)
|
||||
{
|
||||
_appUser.DashboardStreams.Add(s);
|
||||
}
|
||||
foreach (var s in Seed.DefaultSideNavStreams)
|
||||
{
|
||||
_appUser.SideNavStreams.Add(s);
|
||||
}
|
||||
_appUser.DashboardStreams = Seed.DefaultStreams.ToList();
|
||||
_appUser.SideNavStreams = Seed.DefaultSideNavStreams.ToList();
|
||||
}
|
||||
|
||||
public AppUserBuilder WithLibrary(Library library, bool createSideNavStream = false)
|
||||
|
@ -678,6 +678,8 @@ public class SeriesService : ISeriesService
|
||||
.OrderBy(c => c.CreatedUtc)
|
||||
.ToList();
|
||||
|
||||
if (chapters.Count < 3) return _emptyExpectedChapter;
|
||||
|
||||
// Calculate the time differences between consecutive chapters
|
||||
var timeDifferences = new List<TimeSpan>();
|
||||
DateTime? previousChapterTime = null;
|
||||
|
@ -321,6 +321,10 @@ public static class Parser
|
||||
new Regex(
|
||||
@"(?<Series>.*)( ?- ?)Ch\.\d+-?\d*",
|
||||
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)
|
||||
new Regex(
|
||||
@"^(?!Vol)(?!Chapter)(?<Series>.+?)(-|_|\s|#)\d+(-\d+)?",
|
||||
|
@ -106,15 +106,17 @@ export class ErrorInterceptor implements HttpInterceptor {
|
||||
console.error('500 error: ', error);
|
||||
}
|
||||
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') {
|
||||
console.error('500 error: ', error);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
this.toast('errors.unknown-crit');
|
||||
console.error('500 error:', error);
|
||||
}
|
||||
|
||||
this.toast('errors.unknown-crit');
|
||||
console.error('500 error:', error);
|
||||
}
|
||||
|
||||
private handleAuthError(error: any) {
|
||||
|
@ -5,7 +5,7 @@
|
||||
<button type="button" class="btn-close" [attr.aria-label]="t('close')" (click)="close()"></button>
|
||||
</div>
|
||||
<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 === ''">
|
||||
<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 { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
@ -33,6 +33,9 @@ export class InviteUserComponent implements OnInit {
|
||||
selectedLibraries: Array<number> = [];
|
||||
selectedRestriction: AgeRestriction = {ageRating: AgeRating.NotApplicable, includeUnknowns: false};
|
||||
emailLink: string = '';
|
||||
invited: boolean = false;
|
||||
|
||||
private readonly cdRef = inject(ChangeDetectorRef);
|
||||
|
||||
makeLink: (val: string) => string = (val: string) => {return this.emailLink};
|
||||
|
||||
@ -51,7 +54,6 @@ export class InviteUserComponent implements OnInit {
|
||||
}
|
||||
|
||||
invite() {
|
||||
|
||||
this.isSending = true;
|
||||
const email = this.inviteForm.get('email')?.value.trim();
|
||||
this.accountService.inviteUser({
|
||||
@ -62,10 +64,12 @@ export class InviteUserComponent implements OnInit {
|
||||
}).subscribe((data: InviteUserResponse) => {
|
||||
this.emailLink = data.emailLink;
|
||||
this.isSending = false;
|
||||
this.invited = true;
|
||||
if (data.emailSent) {
|
||||
this.toastr.info(translate('toasts.email-sent', {email: email}));
|
||||
this.modal.close(true);
|
||||
}
|
||||
this.cdRef.markForCheck();
|
||||
}, err => {
|
||||
this.isSending = false;
|
||||
this.toastr.error(err)
|
||||
|
@ -24,7 +24,7 @@
|
||||
</div>
|
||||
|
||||
<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>
|
||||
<ng-template #ipAddressesTooltip>{{t('ip-address-tooltip')}}</ng-template>
|
||||
<span class="visually-hidden" id="settings-ipaddresses-help">
|
||||
@ -42,7 +42,7 @@
|
||||
</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>
|
||||
<ng-template #portTooltip>{{t('port-tooltip')}}</ng-template>
|
||||
<span class="visually-hidden" id="settings-port-help">
|
||||
@ -53,7 +53,7 @@
|
||||
</div>
|
||||
|
||||
<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>
|
||||
<ng-template #backupTasksTooltip>{{t('backup-tooltip')}}.</ng-template>
|
||||
<span class="visually-hidden" id="backup-tasks-help">
|
||||
@ -75,7 +75,7 @@
|
||||
</ng-container>
|
||||
</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>
|
||||
<ng-template #logTasksTooltip>{{t('log-tooltip')}}</ng-template>
|
||||
<span class="visually-hidden" id="log-tasks-help">
|
||||
@ -103,7 +103,7 @@
|
||||
<span class="visually-hidden" id="logging-level-port-help">
|
||||
<ng-container [ngTemplateOutlet]="loggingLevelTooltip"></ng-container>
|
||||
</span>
|
||||
<select id="logging-level-port" aria-describedby="logging-level-port-help" class="form-select" formControlName="loggingLevel"
|
||||
<select id="logging-level-port" aria-describedby="logging-level-port-help" class="form-select" formControlName="loggingLevel"
|
||||
[class.is-invalid]="settingsForm.get('loggingLevel')?.invalid && settingsForm.get('loggingLevel')?.touched">
|
||||
<option *ngFor="let level of logLevels" [value]="level">{{level | titlecase}}</option>
|
||||
</select>
|
||||
@ -111,7 +111,7 @@
|
||||
</div>
|
||||
|
||||
<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>
|
||||
<ng-template #cacheSizeTooltip>{{t('cache-size-tooltip')}}</ng-template>
|
||||
<span class="visually-hidden" id="cache-size-help">
|
||||
@ -129,7 +129,7 @@
|
||||
</p>
|
||||
</ng-container>
|
||||
</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>
|
||||
<ng-template #onDeckProgressDaysTooltip>{{t('on-deck-last-progress-tooltip')}}</ng-template>
|
||||
<span class="visually-hidden" id="on-deck-progress-days-help">
|
||||
@ -147,7 +147,7 @@
|
||||
</p>
|
||||
</ng-container>
|
||||
</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>
|
||||
<ng-template #onDeckUpdateDaysTooltip>{{t('on-deck-last-chapter-add-tooltip')}}</ng-template>
|
||||
<span class="visually-hidden" id="on-deck-update-days-help">
|
||||
|
@ -93,7 +93,7 @@ export class FilterUtilitiesService {
|
||||
|
||||
|
||||
encodeSortOptions(sortOptions: SortOptions) {
|
||||
return `sortField=${sortOptions.sortField}&isAscending=${sortOptions.isAscending}`;
|
||||
return `sortField=${sortOptions.sortField},isAscending=${sortOptions.isAscending}`;
|
||||
}
|
||||
|
||||
encodeFilterStatements(statements: Array<FilterStatement>) {
|
||||
@ -195,7 +195,7 @@ export class FilterUtilitiesService {
|
||||
}
|
||||
|
||||
decodeSortOptions(encodedSortOptions: string): SortOptions | null {
|
||||
const parts = decodeURIComponent(encodedSortOptions).split('&');
|
||||
const parts = decodeURIComponent(encodedSortOptions).split(',');
|
||||
const sortFieldPart = parts.find(part => part.startsWith('sortField='));
|
||||
const isAscendingPart = parts.find(part => part.startsWith('isAscending='));
|
||||
|
||||
|
@ -546,11 +546,11 @@
|
||||
"invite-user": {
|
||||
"title": "Invite User",
|
||||
"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}}",
|
||||
"required-field": "{{common.required-field}}",
|
||||
"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-tooltip": "Copy this and paste in a new tab. You may need to log out.",
|
||||
"invite-url-label": "Invite Url",
|
||||
|
@ -7,7 +7,7 @@
|
||||
"name": "GPL-3.0",
|
||||
"url": "https://github.com/Kareadita/Kavita/blob/develop/LICENSE"
|
||||
},
|
||||
"version": "0.7.9.3"
|
||||
"version": "0.7.9.4"
|
||||
},
|
||||
"servers": [
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user