Last Polish before Stable (#3167)

Co-authored-by: Robbie Davis <robbie@therobbiedavis.com>
This commit is contained in:
Joe Milazzo 2024-09-15 12:15:39 -05:00 committed by GitHub
parent f17ecbf305
commit cabb27fb74
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 64 additions and 34 deletions

View File

@ -28,7 +28,7 @@ body:
label: Kavita Version Number - If you don not see your version number listed, please update Kavita and see if your issue still persists. label: Kavita Version Number - If you don not see your version number listed, please update Kavita and see if your issue still persists.
multiple: false multiple: false
options: options:
- 0.8.2 - Stable - 0.8.3 - Stable
- Nightly Testing Branch - Nightly Testing Branch
validations: validations:
required: true required: true

View File

@ -773,6 +773,7 @@ public class AccountController : BaseApiController
{ {
validationErrors.AddRange(await _accountService.ValidateUsername(dto.Username)); validationErrors.AddRange(await _accountService.ValidateUsername(dto.Username));
} }
validationErrors.AddRange(await _accountService.ValidatePassword(user, dto.Password)); validationErrors.AddRange(await _accountService.ValidatePassword(user, dto.Password));
if (validationErrors.Any()) if (validationErrors.Any())

View File

@ -1,9 +1,9 @@
# [<img src="/Logo/kavita.svg" width="32" alt="">]() Kavita # [<img src="/Logo/kavita.svg" width="32" alt="">]() Kavita
<div align="center"> <div align="center">
![new_github_preview_stills](https://user-images.githubusercontent.com/735851/169657008-37812c18-5490-4e2a-9dcb-4806f8c87c69.gif) ![new_github_preview_stills](https://github.com/user-attachments/assets/f016b34f-3c4c-4f07-8e72-12cd6f4e71ea)
Kavita is a fast, feature rich, cross platform reading server. Built with a focus for being a full solution for all your reading needs. Setup your own server and share Kavita is a fast, feature rich, cross-platform reading server. Built with a focus for being a full solution for all your reading needs. Set up your own server and share
your reading collection with your friends and family! your reading collection with your friends and family!
[![Release](https://img.shields.io/github/release/Kareadita/Kavita.svg?style=flat&maxAge=3600)](https://github.com/Kareadita/Kavita/releases) [![Release](https://img.shields.io/github/release/Kareadita/Kavita.svg?style=flat&maxAge=3600)](https://github.com/Kareadita/Kavita/releases)
@ -24,14 +24,14 @@ your reading collection with your friends and family!
## What Kavita Provides ## What Kavita Provides
- Serve up Manga/Webtoons/Comics (cbr, cbz, zip/rar/rar5, 7zip, raw images) and Books (epub, pdf) - Serve up Manga/Webtoons/Comics (cbr, cbz, zip/rar/rar5, 7zip, raw images) and Books (epub, pdf)
- First class responsive readers that work great on any device (phone, tablet, desktop) - First class responsive readers that work great on any device (phone, tablet, desktop)
- Dark mode and customizable theming support - Customizable theming support: [Theme Repo](https://github.com/Kareadita/Themes) and [Documentation](https://wiki.kavitareader.com/guides/themes)
- External metadata integration and scrobbling for read status, ratings, and reviews (available via Kavita+) - External metadata integration and scrobbling for read status, ratings, and reviews (available via [Kavita+](https://wiki.kavitareader.com/kavita+))
- Rich Metadata support with filtering and searching - Rich Metadata support with filtering and searching
- Ways to group reading material: Collections, Reading Lists (CBL Import), Want to Read - Ways to group reading material: Collections, Reading Lists (CBL Import), Want to Read
- Ability to manage users with rich Role-based management for age restrictions, abilities within the app, etc - Ability to manage users with rich Role-based management for age restrictions, abilities within the app, etc
- Rich web readers supporting webtoon, continuous reading mode (continue without leaving the reader), virtual pages (epub), etc - Rich web readers supporting webtoon, continuous reading mode (continue without leaving the reader), virtual pages (epub), etc
- Ability to customize your dashboard and side nav with smart filters, custom order and visibility toggles
- Full Localization Support - Full Localization Support
- Ability to customize your dashboard and side nav with smart filters, custom order and visibility toggles.
## Support ## Support
@ -52,7 +52,7 @@ install methods and platforms.
[https://wiki.kavitareader.com/installation/getting-started](https://wiki.kavitareader.com/installation/getting-started) [https://wiki.kavitareader.com/installation/getting-started](https://wiki.kavitareader.com/installation/getting-started)
## Feature Requests ## Feature Requests
Got a great idea? Throw it up on [Discussions](https://github.com/Kareadita/Kavita/discussions/2529) or vote on another idea. Please check the [Project Board](https://github.com/Kareadita/Kavita/projects?type=classic) first for a list of planned features before you submit an idea. Got a great idea? Throw it up on [Discussions](https://github.com/Kareadita/Kavita/discussions/2529) or vote on another idea. Many great features in Kavita are driven by our community.
## Notice ## Notice
Kavita is being actively developed and should be considered beta software until the 1.0 release. Kavita is being actively developed and should be considered beta software until the 1.0 release.
@ -62,7 +62,7 @@ vision. You may lose data and have to restart. The Kavita team strives to avoid
## Donate ## Donate
If you like Kavita, have gotten good use out of it, or feel like you want to say thanks with a few bucks, feel free to donate. Money will go towards If you like Kavita, have gotten good use out of it, or feel like you want to say thanks with a few bucks, feel free to donate. Money will go towards
expenses related to Kavita. Back us through [OpenCollective](https://opencollective.com/Kavita#backer). You can also use [Paypal](https://www.paypal.com/paypalme/majora2007?locale.x=en_US), however your name will not show below. Kavita+ is also an expenses related to Kavita. Back us through [OpenCollective](https://opencollective.com/Kavita#backer). You can also use [Paypal](https://www.paypal.com/paypalme/majora2007?locale.x=en_US), however your name will not show below. Kavita+ is also an
option which provides funding and you get a benefit. option which provides funding, and you get a benefit.
## Kavita+ ## Kavita+
[Kavita+](https://wiki.kavitareader.com/kavita+) is a paid subscription that offers premium features that otherwise wouldn't be feasible to include in Kavita. It is ran and operated by majora2007, the creator and developer of Kavita. [Kavita+](https://wiki.kavitareader.com/kavita+) is a paid subscription that offers premium features that otherwise wouldn't be feasible to include in Kavita. It is ran and operated by majora2007, the creator and developer of Kavita.
@ -72,7 +72,7 @@ If you are interested, you can use the promo code `FIRSTTIME` for your initial s
**If you already contribute via OpenCollective, please reach out to majora2007 for a provisioned license.** **If you already contribute via OpenCollective, please reach out to majora2007 for a provisioned license.**
## Localization ## Localization
Thank you to [Weblate](https://hosted.weblate.org/engage/kavita/) who hosts our localization infrastructure pro-bono. If you want to see Kavita in your language, please help us localize. Thank you to [Weblate](https://hosted.weblate.org/engage/kavita/) who hosts our localization infrastructure pro bono. If you want to see Kavita in your language, please help us localize.
<a href="https://hosted.weblate.org/engage/kavita/"> <a href="https://hosted.weblate.org/engage/kavita/">
<img src="https://hosted.weblate.org/widget/kavita/horizontal-auto.svg" alt="Translation status" /> <img src="https://hosted.weblate.org/widget/kavita/horizontal-auto.svg" alt="Translation status" />

View File

@ -160,16 +160,15 @@ $image-width: 160px;
.card-title-container { .card-title-container {
display: flex; display: flex;
justify-content: end; justify-content: space-between;
align-items: center; align-items: center;
padding: 0 5px; padding: 0 5px;
.card-title { .card-title {
font-size: 0.8rem; font-size: 0.8rem;
margin: 0; margin: 0;
padding: 10px 0;
text-align: center; text-align: center;
max-width: 120px; max-width: 110px;
a { a {
overflow: hidden; overflow: hidden;
@ -178,14 +177,28 @@ $image-width: 160px;
} }
} }
.card-actions {
min-width: 15.82px;
}
.card-format {
min-width: 22px;
}
::ng-deep app-card-actionables .dropdown .dropdown-toggle { ::ng-deep app-card-actionables .dropdown .dropdown-toggle {
padding: 0 5px; padding: 0 5px;
} }
.meta-title {
.card-title {
max-width: unset;
}
}
.card-title { .card-title {
font-size: 0.8rem; font-size: 0.8rem;
margin: 0; margin: 0;
padding: 10px; padding: 10px 0;
text-align: center; text-align: center;
max-width: 120px; max-width: 120px;
@ -208,6 +221,9 @@ $image-width: 160px;
.overlay-information { .overlay-information {
visibility: hidden; visibility: hidden;
display: none; display: none;
.card-title {
padding: 10px;
}
} }
.chapter, .chapter,

View File

@ -73,9 +73,11 @@
</div> </div>
@if (title.length > 0 || actions.length > 0) { @if (title.length > 0 || actions.length > 0) {
<div class="card-title-container"> <div class="card-title-container">
@if (showFormat) { <span class="card-format">
<app-series-format [format]="format"></app-series-format> @if (showFormat) {
} <app-series-format [format]="format"></app-series-format>
}
</span>
<span class="card-title" placement="top" id="{{title}}_{{entity.id}}" [ngbTooltip]="tooltipTitle" (click)="handleClick($event)" tabindex="0"> <span class="card-title" placement="top" id="{{title}}_{{entity.id}}" [ngbTooltip]="tooltipTitle" (click)="handleClick($event)" tabindex="0">
@if (isPromoted(); as isPromoted) { @if (isPromoted(); as isPromoted) {
@ -87,14 +89,13 @@
{{title}} {{title}}
} }
</span> </span>
<span class="card-actions">
@if (actions && actions.length > 0) { @if (actions && actions.length > 0) {
<span class="card-actions">
<app-card-actionables (actionHandler)="performAction($event)" [actions]="actions" [labelBy]="title"></app-card-actionables>
</span>
} @else {
}
<app-card-actionables (actionHandler)="performAction($event)" [actions]="actions" [labelBy]="title"></app-card-actionables>
}
</span>
</div> </div>
} }
</div> </div>

View File

@ -1,5 +1 @@
@use '../../../card-item-common'; @use '../../../card-item-common';
.card-title-container {
justify-content: center;
}

View File

@ -73,6 +73,8 @@
<div class="card-title-container"> <div class="card-title-container">
<span class="card-format">
</span>
<span class="card-title" id="{{chapter.id}}" tabindex="0" [ngbTooltip]="chapter.isSpecial ? (chapter.title || chapter.range) : null"> <span class="card-title" id="{{chapter.id}}" tabindex="0" [ngbTooltip]="chapter.isSpecial ? (chapter.title || chapter.range) : null">
<a class="dark-exempt btn-icon" routerLink="/library/{{libraryId}}/series/{{seriesId}}/chapter/{{chapter.id}}"> <a class="dark-exempt btn-icon" routerLink="/library/{{libraryId}}/series/{{seriesId}}/chapter/{{chapter.id}}">
@if (chapter.isSpecial) { @if (chapter.isSpecial) {
@ -82,12 +84,11 @@
} }
</a> </a>
</span> </span>
<span class="card-actions">
@if (actions && actions.length > 0) { @if (actions && actions.length > 0) {
<span class="card-actions">
<app-card-actionables (actionHandler)="performAction($event)" [actions]="actions" [labelBy]="chapter.titleName"></app-card-actionables> <app-card-actionables (actionHandler)="performAction($event)" [actions]="actions" [labelBy]="chapter.titleName"></app-card-actionables>
</span>
} }
</span>
</div> </div>
</div> </div>

View File

@ -19,14 +19,16 @@
<div class="card-title-container"> <div class="card-title-container">
@if (data.name.length > 0) { @if (data.name.length > 0) {
<img class="me-1" [ngSrc]="data.provider | providerImage" width="20" height="20" alt="">
<a #link class="card-title" [href]="data.url" target="_blank" rel="noreferrer nofollow"> <a #link class="card-title" [href]="data.url" target="_blank" rel="noreferrer nofollow">
<span class="card-title" placement="top" id="{{data.name}}" [ngbTooltip]="data.name" (click)="handleClick()" tabindex="0"> <span class="card-title" placement="top" id="{{data.name}}" [ngbTooltip]="data.name" (click)="handleClick()" tabindex="0">
<img class="me-1" [ngSrc]="data.provider | providerImage" width="20" height="20" alt="">
{{data.name}} {{data.name}}
</span> </span>
</a> </a>
}
}
<span class="card-actions">
</span>
</div> </div>
</div> </div>

View File

@ -9,6 +9,6 @@ a {
} }
.card-title { .card-title {
padding: 5px; padding: 5px 0;
max-width: unset; max-width: unset;
} }

View File

@ -52,13 +52,23 @@
@if (libraryType === LibraryType.LightNovel || libraryType === LibraryType.Book) { @if (libraryType === LibraryType.LightNovel || libraryType === LibraryType.Book) {
<div class="card-body meta-title"> <div class="card-body meta-title">
<span class="card-format">
</span>
<div class="card-content d-flex justify-content-center align-items-center text-center" style="width:100%;min-height:58px;"> <div class="card-content d-flex justify-content-center align-items-center text-center" style="width:100%;min-height:58px;">
{{volume.name}} {{volume.name}}
</div> </div>
@if (actions && actions.length > 0) {
<span class="card-actions">
<app-card-actionables (actionHandler)="performAction($event)" [actions]="actions" [labelBy]="volume.name"></app-card-actionables>
</span>
}
</div> </div>
} }
<div class="card-title-container"> <div class="card-title-container">
<span class="card-format">
</span>
<span class="card-title" id="{{volume.id}}" tabindex="0"> <span class="card-title" id="{{volume.id}}" tabindex="0">
<a class="dark-exempt btn-icon" routerLink="/library/{{libraryId}}/series/{{seriesId}}/volume/{{volume.id}}"> <a class="dark-exempt btn-icon" routerLink="/library/{{libraryId}}/series/{{seriesId}}/volume/{{volume.id}}">
{{volume.name}} {{volume.name}}

View File

@ -10,6 +10,7 @@
@case (Step.Import) { @case (Step.Import) {
<div class="row g-0"> <div class="row g-0">
<p>{{t('import-description')}}</p> <p>{{t('import-description')}}</p>
<p>{{t('cbl-repo') | safeHtml}}</p>
<form [formGroup]="uploadForm" enctype="multipart/form-data"> <form [formGroup]="uploadForm" enctype="multipart/form-data">
<file-upload formControlName="files"></file-upload> <file-upload formControlName="files"></file-upload>
</form> </form>

View File

@ -740,7 +740,8 @@
"required-field": "{{common.required-field}}", "required-field": "{{common.required-field}}",
"valid-email": "{{common.valid-email}}", "valid-email": "{{common.valid-email}}",
"password-validation": "{{validation.password-validation}}", "password-validation": "{{validation.password-validation}}",
"register": "Register" "register": "Register",
"error-label": "Error:"
}, },
"confirm-email-change": { "confirm-email-change": {
@ -1461,6 +1462,7 @@
"theme": "Theme", "theme": "Theme",
"customize": "Customize", "customize": "Customize",
"cbl-import": "CBL Reading List", "cbl-import": "CBL Reading List",
"cbl-repo": "You can find many reading lists in the community <a href='https://github.com/DieselTech/CBL-ReadingLists' target='_blank' rel='noopener noreferrer'>repo</a>.",
"mal-stack-import": "MAL Stack" "mal-stack-import": "MAL Stack"
}, },

View File

@ -2,7 +2,7 @@
"openapi": "3.0.1", "openapi": "3.0.1",
"info": { "info": {
"title": "Kavita", "title": "Kavita",
"description": "Kavita provides a set of APIs that are authenticated by JWT. JWT token can be copied from local storage. Assume all fields of a payload are required. Built against v0.8.2.9", "description": "Kavita provides a set of APIs that are authenticated by JWT. JWT token can be copied from local storage. Assume all fields of a payload are required. Built against v0.8.2.10",
"license": { "license": {
"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"