mirror of
https://github.com/Kareadita/Kavita.git
synced 2025-07-09 03:04:19 -04:00
Merged develop into main to fix the issues
This commit is contained in:
commit
642b23ed61
@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"TokenKey": "super secret unguessable key",
|
||||
"Port": 5000,
|
||||
"IpAddresses": "",
|
||||
"BaseUrl": "/joe/"
|
||||
"TokenKey": "super secret unguessable key",
|
||||
"Port": 5000,
|
||||
"IpAddresses": "",
|
||||
"BaseUrl": "/joe/"
|
||||
}
|
||||
|
@ -1,27 +1,27 @@
|
||||
<nav class="navbar navbar-expand-md navbar-dark fixed-top" *ngIf="navService?.navbarVisible$ | async">
|
||||
<div class="container-fluid">
|
||||
<a class="visually-hidden-focusable focus-visible" href="javascript:void(0);" (click)="moveFocus()">Skip to main content</a>
|
||||
<a class="side-nav-toggle" *ngIf="navService?.sideNavVisibility$ | async" (click)="hideSideNav()"><i class="fas fa-bars"></i></a>
|
||||
<a class="navbar-brand dark-exempt" routerLink="/libraries" routerLinkActive="active">
|
||||
<img width="28px" height="28px" class="logo" src="assets/images/logo.png" alt="kavita icon" aria-hidden="true"/>
|
||||
<span class="d-none d-md-inline logo"> Kavita</span>
|
||||
</a>
|
||||
<ul class="navbar-nav col me-auto">
|
||||
<div class="container-fluid">
|
||||
<a class="visually-hidden-focusable focus-visible" href="javascript:void(0);" (click)="moveFocus()">Skip to main content</a>
|
||||
<a class="side-nav-toggle" *ngIf="navService?.sideNavVisibility$ | async" (click)="hideSideNav()"><i class="fas fa-bars"></i></a>
|
||||
<a class="navbar-brand dark-exempt" routerLink="/libraries" routerLinkActive="active">
|
||||
<img width="28px" height="28px" class="logo" src="assets/images/logo.png" alt="kavita icon" aria-hidden="true"/>
|
||||
<span class="d-none d-md-inline logo"> Kavita</span>
|
||||
</a>
|
||||
<ul class="navbar-nav col me-auto">
|
||||
|
||||
<div class="nav-item" *ngIf="(accountService.currentUser$ | async) as user">
|
||||
<label for="nav-search" class="form-label visually-hidden">Search series</label>
|
||||
<div class="ng-autocomplete">
|
||||
<app-grouped-typeahead
|
||||
#search
|
||||
id="nav-search"
|
||||
[minQueryLength]="2"
|
||||
initialValue=""
|
||||
placeholder="Search…"
|
||||
[grouppedData]="searchResults"
|
||||
(inputChanged)="onChangeSearch($event)"
|
||||
(clearField)="clearSearch()"
|
||||
(focusChanged)="focusUpdate($event)"
|
||||
>
|
||||
<div class="nav-item" *ngIf="(accountService.currentUser$ | async) as user">
|
||||
<label for="nav-search" class="form-label visually-hidden">Search series</label>
|
||||
<div class="ng-autocomplete">
|
||||
<app-grouped-typeahead
|
||||
#search
|
||||
id="nav-search"
|
||||
[minQueryLength]="2"
|
||||
initialValue=""
|
||||
placeholder="Search…"
|
||||
[grouppedData]="searchResults"
|
||||
(inputChanged)="onChangeSearch($event)"
|
||||
(clearField)="clearSearch()"
|
||||
(focusChanged)="focusUpdate($event)"
|
||||
>
|
||||
|
||||
<ng-template #libraryTemplate let-item>
|
||||
<div style="display: flex;padding: 5px;" (click)="clickLibraryResult(item)">
|
||||
@ -130,44 +130,43 @@
|
||||
</ng-template>
|
||||
|
||||
</app-grouped-typeahead>
|
||||
</div>
|
||||
</div>
|
||||
</ul>
|
||||
|
||||
<ng-container *ngIf="!searchFocused">
|
||||
<div class="back-to-top" *ngIf="backToTopNeeded">
|
||||
<button class="btn btn-icon scroll-to-top" (click)="scrollToTop()">
|
||||
<i class="fa fa-angle-double-up nav" aria-hidden="true"></i>
|
||||
<span class="visually-hidden">Scroll to Top</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="(accountService.currentUser$ | async) as user">
|
||||
<div class="nav-item">
|
||||
<app-nav-events-toggle [user]="user"></app-nav-events-toggle>
|
||||
</div>
|
||||
<div class="nav-item not-xs-only">
|
||||
<a routerLink="/admin/dashboard" *ngIf="user.roles.includes('Admin')" class="dark-exempt btn btn-icon" title="Server Settings">
|
||||
<i class="fa fa-cogs nav" aria-hidden="true"></i>
|
||||
<span class="visually-hidden">Server Settings</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
<div ngbDropdown class="nav-item dropdown" display="dynamic" placement="bottom-right" *ngIf="(accountService.currentUser$ | async) as user" dropdown>
|
||||
<button class="btn btn-outline-secondary primary-text" ngbDropdownToggle>
|
||||
<i class="fa-solid fa-user-circle align-self-center phone-hidden d-xs-inline-block d-sm-inline-block d-md-none"></i><span class="d-none d-xs-none d-sm-none d-md-inline-block">{{user.username | sentenceCase}}</span>
|
||||
</button>
|
||||
<div ngbDropdownMenu>
|
||||
<a class="xs-only" ngbDropdownItem routerLink="/admin/dashboard" *ngIf="user.roles.includes('Admin')">Server Settings</a>
|
||||
<a ngbDropdownItem routerLink="/preferences/">Settings</a>
|
||||
<a ngbDropdownItem href="https://wiki.kavitareader.com" rel="noopener noreferrer" target="_blank">Help</a>
|
||||
<a ngbDropdownItem routerLink="/announcements/" *ngIf="accountService.hasAdminRole(user)">Announcements</a>
|
||||
<a ngbDropdownItem (click)="logout()">Logout</a>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</div>
|
||||
</nav>
|
||||
</ul>
|
||||
|
||||
<ng-container *ngIf="!searchFocused">
|
||||
<div class="back-to-top" *ngIf="backToTopNeeded">
|
||||
<button class="btn btn-icon scroll-to-top" (click)="scrollToTop()">
|
||||
<i class="fa fa-angle-double-up nav" aria-hidden="true"></i>
|
||||
<span class="visually-hidden">Scroll to Top</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<ng-container *ngIf="(accountService.currentUser$ | async) as user">
|
||||
<div class="nav-item">
|
||||
<app-nav-events-toggle [user]="user"></app-nav-events-toggle>
|
||||
</div>
|
||||
<div class="nav-item not-xs-only">
|
||||
<a routerLink="/admin/dashboard" *ngIf="user.roles.includes('Admin')" class="dark-exempt btn btn-icon" title="Server Settings">
|
||||
<i class="fa fa-cogs nav" aria-hidden="true"></i>
|
||||
<span class="visually-hidden">Server Settings</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
||||
<div ngbDropdown class="nav-item dropdown" display="dynamic" placement="bottom-right" *ngIf="(accountService.currentUser$ | async) as user" dropdown>
|
||||
<button class="btn btn-outline-secondary primary-text" ngbDropdownToggle>
|
||||
<i class="fa-solid fa-user-circle align-self-center phone-hidden d-xs-inline-block d-sm-inline-block d-md-none"></i><span class="d-none d-xs-none d-sm-none d-md-inline-block">{{user.username | sentenceCase}}</span>
|
||||
</button>
|
||||
<div ngbDropdownMenu>
|
||||
<a class="xs-only" ngbDropdownItem routerLink="/admin/dashboard" *ngIf="user.roles.includes('Admin')">Server Settings</a>
|
||||
<a ngbDropdownItem routerLink="/preferences/">Settings</a>
|
||||
<a ngbDropdownItem href="https://wiki.kavitareader.com" rel="noopener noreferrer" target="_blank">Help</a>
|
||||
<a ngbDropdownItem routerLink="/announcements/" *ngIf="accountService.hasAdminRole(user)">Announcements</a>
|
||||
<a ngbDropdownItem (click)="logout()">Logout</a>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</div>
|
||||
</nav>
|
||||
|
@ -1,134 +1,134 @@
|
||||
<app-side-nav-companion-bar [hasExtras]="readingList !== undefined" [extraDrawer]="extrasDrawer">
|
||||
<h2 title>
|
||||
<app-card-actionables (actionHandler)="performAction($event)" [actions]="actions" [attr.labelBy]="readingList?.title" *ngIf="actions.length > 0"></app-card-actionables>
|
||||
{{readingList?.title}}
|
||||
<span *ngIf="readingList?.promoted" class="ms-1">(<i class="fa fa-angle-double-up" aria-hidden="true"></i>)</span>
|
||||
</h2>
|
||||
<h6 subtitle class="subtitle-with-actionables">{{items.length | number}} Items</h6>
|
||||
|
||||
<ng-template #extrasDrawer let-offcanvas>
|
||||
<div style="margin-top: 56px" *ngIf="readingList">
|
||||
<div class="offcanvas-header">
|
||||
<h4 class="offcanvas-title" id="offcanvas-basic-title">Page Settings</h4>
|
||||
<button type="button" class="btn-close" aria-label="Close" (click)="offcanvas.dismiss()"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<div class="row g-0">
|
||||
<div class="col-md-12 col-sm-12 pe-2 mb-3">
|
||||
<button class="btn btn-danger" (click)="removeRead()" [disabled]="readingList.promoted && !this.isAdmin">
|
||||
<span>
|
||||
<i class="fa fa-check"></i>
|
||||
</span>
|
||||
<span class="read-btn--text"> Remove Read</span>
|
||||
</button>
|
||||
|
||||
<div class="col-auto ms-2 mt-2" *ngIf="!(readingList?.promoted && !this.isAdmin)">
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" id="accessibility-mode" [value]="accessibilityMode" (change)="updateAccesibilityMode()">
|
||||
<label class="form-check-label" for="accessibility-mode">Order Numbers</label>
|
||||
</div>
|
||||
<h2 title>
|
||||
<app-card-actionables (actionHandler)="performAction($event)" [actions]="actions" [attr.labelBy]="readingList?.title" *ngIf="actions.length > 0"></app-card-actionables>
|
||||
{{readingList?.title}}
|
||||
<span *ngIf="readingList?.promoted" class="ms-1">(<i class="fa fa-angle-double-up" aria-hidden="true"></i>)</span>
|
||||
</h2>
|
||||
<h6 subtitle class="subtitle-with-actionables">{{items.length | number}} Items</h6>
|
||||
|
||||
<ng-template #extrasDrawer let-offcanvas>
|
||||
<div style="margin-top: 56px" *ngIf="readingList">
|
||||
<div class="offcanvas-header">
|
||||
<h4 class="offcanvas-title" id="offcanvas-basic-title">Page Settings</h4>
|
||||
<button type="button" class="btn-close" aria-label="Close" (click)="offcanvas.dismiss()"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<div class="row g-0">
|
||||
<div class="col-md-12 col-sm-12 pe-2 mb-3">
|
||||
<button class="btn btn-danger" (click)="removeRead()" [disabled]="readingList.promoted && !this.isAdmin">
|
||||
<span>
|
||||
<i class="fa fa-check"></i>
|
||||
</span>
|
||||
<span class="read-btn--text"> Remove Read</span>
|
||||
</button>
|
||||
|
||||
<div class="col-auto ms-2 mt-2" *ngIf="!(readingList?.promoted && !this.isAdmin)">
|
||||
<div class="form-check form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" id="accessibility-mode" [value]="accessibilityMode" (change)="updateAccesibilityMode()">
|
||||
<label class="form-check-label" for="accessibility-mode">Order Numbers</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
</app-side-nav-companion-bar>
|
||||
<div class="container-fluid mt-2" *ngIf="readingList" >
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-2 col-xs-4 col-sm-6 d-none d-sm-block" *ngIf="readingList.coverImage !== '' && readingList.coverImage !== undefined && readingList.coverImage !== null">
|
||||
<app-image maxWidth="300px" maxHeight="400px" [imageUrl]="readingListImage"></app-image>
|
||||
</div>
|
||||
<div class="col-md-10 col-xs-8 col-sm-6 mt-2">
|
||||
<div class="row g-0 mb-3">
|
||||
<div class="col-auto me-2">
|
||||
<!-- Action row-->
|
||||
<div class="btn-group me-3">
|
||||
<button type="button" class="btn btn-primary" (click)="continue()">
|
||||
<span>
|
||||
<i class="fa fa-book-open" aria-hidden="true"></i>
|
||||
<span class="read-btn--text"> Continue</span>
|
||||
</span>
|
||||
</button>
|
||||
<div class="btn-group" ngbDropdown role="group" aria-label="Read options">
|
||||
<button type="button" class="btn btn-primary dropdown-toggle-split" ngbDropdownToggle></button>
|
||||
<div class="dropdown-menu" ngbDropdownMenu>
|
||||
<button ngbDropdownItem (click)="read()">
|
||||
<span>
|
||||
<i class="fa fa-book" aria-hidden="true"></i>
|
||||
<span class="read-btn--text"> Read</span>
|
||||
</span>
|
||||
</button>
|
||||
<button ngbDropdownItem (click)="continue(true)">
|
||||
<span>
|
||||
<i class="fa fa-book-open" aria-hidden="true"></i>
|
||||
<span class="read-btn--text"> Continue</span>
|
||||
(<i class="fa fa-glasses ms-1" aria-hidden="true"></i>)
|
||||
<span class="visually-hidden">(Incognito)</span>
|
||||
</span>
|
||||
</button>
|
||||
<button ngbDropdownItem (click)="read(true)">
|
||||
<span>
|
||||
<i class="fa fa-book" aria-hidden="true"></i>
|
||||
<span class="read-btn--text"> Read</span>
|
||||
(<i class="fa fa-glasses ms-1" aria-hidden="true"></i>)
|
||||
<span class="visually-hidden">(Incognito)</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
</app-side-nav-companion-bar>
|
||||
<div class="container-fluid mt-2" *ngIf="readingList" >
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-2 col-xs-4 col-sm-6 d-none d-sm-block" *ngIf="readingList.coverImage !== '' && readingList.coverImage !== undefined && readingList.coverImage !== null">
|
||||
<app-image maxWidth="300px" maxHeight="400px" [imageUrl]="readingListImage"></app-image>
|
||||
</div>
|
||||
<div class="col-md-10 col-xs-8 col-sm-6 mt-2">
|
||||
<div class="row g-0 mb-3">
|
||||
<div class="col-auto me-2">
|
||||
<!-- Action row-->
|
||||
<div class="btn-group me-3">
|
||||
<button type="button" class="btn btn-primary" (click)="continue()">
|
||||
<span>
|
||||
<i class="fa fa-book-open" aria-hidden="true"></i>
|
||||
<span class="read-btn--text"> Continue</span>
|
||||
</span>
|
||||
</button>
|
||||
<div class="btn-group" ngbDropdown role="group" aria-label="Read options">
|
||||
<button type="button" class="btn btn-primary dropdown-toggle-split" ngbDropdownToggle></button>
|
||||
<div class="dropdown-menu" ngbDropdownMenu>
|
||||
<button ngbDropdownItem (click)="read()">
|
||||
<span>
|
||||
<i class="fa fa-book" aria-hidden="true"></i>
|
||||
<span class="read-btn--text"> Read</span>
|
||||
</span>
|
||||
</button>
|
||||
<button ngbDropdownItem (click)="continue(true)">
|
||||
<span>
|
||||
<i class="fa fa-book-open" aria-hidden="true"></i>
|
||||
<span class="read-btn--text"> Continue</span>
|
||||
(<i class="fa fa-glasses ms-1" aria-hidden="true"></i>)
|
||||
<span class="visually-hidden">(Incognito)</span>
|
||||
</span>
|
||||
</button>
|
||||
<button ngbDropdownItem (click)="read(true)">
|
||||
<span>
|
||||
<i class="fa fa-book" aria-hidden="true"></i>
|
||||
<span class="read-btn--text"> Read</span>
|
||||
(<i class="fa fa-glasses ms-1" aria-hidden="true"></i>)
|
||||
<span class="visually-hidden">(Incognito)</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row g-0 mt-2" *ngIf="readingList.startingYear !== 0">
|
||||
<h4 class="reading-list-years">
|
||||
<ng-container *ngIf="readingList.startingMonth > 0">{{readingList.startingMonth | date:'MMM'}}</ng-container>
|
||||
<ng-container *ngIf="readingList.startingMonth > 0 && readingList.startingYear > 0">, </ng-container>
|
||||
<ng-container *ngIf="readingList.startingYear > 0">{{readingList.startingYear}}</ng-container>
|
||||
—
|
||||
<ng-container *ngIf="readingList.endingYear > 0">
|
||||
<ng-container *ngIf="readingList.endingMonth > 0">{{readingList.endingMonth}}</ng-container>
|
||||
<ng-container *ngIf="readingList.endingMonth > 0 && readingList.endingYear > 0">, </ng-container>
|
||||
<ng-container *ngIf="readingList.endingYear > 0">{{readingList.endingYear}}</ng-container>
|
||||
</ng-container>
|
||||
|
||||
</h4>
|
||||
</div>
|
||||
<!-- Summary row-->
|
||||
<div class="row g-0 mt-2">
|
||||
<app-read-more [text]="readingListSummary" [maxLength]="250"></app-read-more>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row g-0 mt-2" *ngIf="readingList.startingYear !== 0">
|
||||
<h4 class="reading-list-years">
|
||||
<ng-container *ngIf="readingList.startingMonth > 0">{{readingList.startingMonth | date:'MMM'}}</ng-container>
|
||||
<ng-container *ngIf="readingList.startingMonth > 0 && readingList.startingYear > 0">, </ng-container>
|
||||
<ng-container *ngIf="readingList.startingYear > 0">{{readingList.startingYear}}</ng-container>
|
||||
—
|
||||
<ng-container *ngIf="readingList.endingYear > 0">
|
||||
<ng-container *ngIf="readingList.endingMonth > 0">{{readingList.endingMonth}}</ng-container>
|
||||
<ng-container *ngIf="readingList.endingMonth > 0 && readingList.endingYear > 0">, </ng-container>
|
||||
<ng-container *ngIf="readingList.endingYear > 0">{{readingList.endingYear}}</ng-container>
|
||||
</ng-container>
|
||||
|
||||
</h4>
|
||||
</div>
|
||||
<!-- Summary row-->
|
||||
<div class="row g-0 mt-2">
|
||||
<app-read-more [text]="readingListSummary" [maxLength]="250"></app-read-more>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<ng-container *ngIf="characters$ | async as characters">
|
||||
<div class="row" *ngIf="characters && characters.length > 0">
|
||||
<h5>Characters</h5>
|
||||
<app-badge-expander [items]="characters">
|
||||
<ng-template #badgeExpanderItem let-item let-position="idx">
|
||||
<app-person-badge a11y-click="13,32" class="col-auto" [person]="item"></app-person-badge>
|
||||
</ng-template>
|
||||
</app-badge-expander>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3 scroll-container" #scrollingBlock>
|
||||
<div class="mx-auto" style="width: 200px;">
|
||||
<ng-container *ngIf="items.length === 0 && !isLoading">
|
||||
Nothing added
|
||||
</ng-container>
|
||||
<app-loading [loading]="isLoading"></app-loading>
|
||||
</div>
|
||||
|
||||
<app-draggable-ordered-list [items]="items" (orderUpdated)="orderUpdated($event)" [accessibilityMode]="accessibilityMode"
|
||||
[showRemoveButton]="false">
|
||||
<ng-template #draggableItem let-item let-position="idx">
|
||||
<app-reading-list-item [ngClass]="{'content-container': items.length < 100, 'non-virtualized-container': items.length >= 100}" [item]="item" [position]="position" [libraryTypes]="libraryTypes"
|
||||
[promoted]="item.promoted" (read)="readChapter($event)" (remove)="itemRemoved($event, position)"></app-reading-list-item>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<ng-container *ngIf="characters$ | async as characters">
|
||||
<div class="row" *ngIf="characters && characters.length > 0">
|
||||
<h5>Characters</h5>
|
||||
<app-badge-expander [items]="characters">
|
||||
<ng-template #badgeExpanderItem let-item let-position="idx">
|
||||
<app-person-badge a11y-click="13,32" class="col-auto" [person]="item"></app-person-badge>
|
||||
</ng-template>
|
||||
</app-draggable-ordered-list>
|
||||
</app-badge-expander>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3 scroll-container" #scrollingBlock>
|
||||
<div class="mx-auto" style="width: 200px;">
|
||||
<ng-container *ngIf="items.length === 0 && !isLoading">
|
||||
Nothing added
|
||||
</ng-container>
|
||||
<app-loading [loading]="isLoading"></app-loading>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<app-draggable-ordered-list [items]="items" (orderUpdated)="orderUpdated($event)" [accessibilityMode]="accessibilityMode"
|
||||
[showRemoveButton]="false">
|
||||
<ng-template #draggableItem let-item let-position="idx">
|
||||
<app-reading-list-item [ngClass]="{'content-container': items.length < 100, 'non-virtualized-container': items.length >= 100}" [item]="item" [position]="position" [libraryTypes]="libraryTypes"
|
||||
[promoted]="item.promoted" (read)="readChapter($event)" (remove)="itemRemoved($event, position)"></app-reading-list-item>
|
||||
</ng-template>
|
||||
</app-draggable-ordered-list>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -15566,4 +15566,4 @@
|
||||
"description": "Responsible for all things Want To Read"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user