UX Pass 5 (#3128)
Co-authored-by: Robbie Davis <robbie@therobbiedavis.com>
This commit is contained in:
parent
dbc4f35107
commit
c93af3e56f
126 changed files with 1989 additions and 2877 deletions
|
@ -1,5 +1,5 @@
|
|||
<ng-container *transloco="let t; read: 'details-tab'">
|
||||
|
||||
<div class="details pb-3">
|
||||
<div class="mb-3">
|
||||
<app-carousel-reel [items]="genres" [title]="t('genres-title')">
|
||||
<ng-template #carouselItem let-item>
|
||||
|
@ -132,4 +132,5 @@
|
|||
</ng-template>
|
||||
</app-carousel-reel>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
|
|
@ -44,7 +44,6 @@ import {SettingButtonComponent} from "../../settings/_components/setting-button/
|
|||
import {CoverImageChooserComponent} from "../../cards/cover-image-chooser/cover-image-chooser.component";
|
||||
import {EditChapterProgressComponent} from "../../cards/edit-chapter-progress/edit-chapter-progress.component";
|
||||
import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
|
||||
import {EntityInfoCardsComponent} from "../../cards/entity-info-cards/entity-info-cards.component";
|
||||
import {CompactNumberPipe} from "../../_pipes/compact-number.pipe";
|
||||
import {IconAndTitleComponent} from "../../shared/icon-and-title/icon-and-title.component";
|
||||
import {MangaFormat} from "../../_models/manga-format";
|
||||
|
@ -56,6 +55,7 @@ import {ImageComponent} from "../../shared/image/image.component";
|
|||
import {SafeHtmlPipe} from "../../_pipes/safe-html.pipe";
|
||||
import {ReadTimePipe} from "../../_pipes/read-time.pipe";
|
||||
import {ChapterService} from "../../_services/chapter.service";
|
||||
import {AgeRating} from "../../_models/metadata/age-rating";
|
||||
|
||||
enum TabID {
|
||||
General = 'general-tab',
|
||||
|
@ -100,7 +100,6 @@ const blackList = [Action.Edit, Action.IncognitoRead, Action.AddToReadingList];
|
|||
CoverImageChooserComponent,
|
||||
EditChapterProgressComponent,
|
||||
NgbInputDatepicker,
|
||||
EntityInfoCardsComponent,
|
||||
CompactNumberPipe,
|
||||
IconAndTitleComponent,
|
||||
DefaultDatePipe,
|
||||
|
@ -120,7 +119,6 @@ const blackList = [Action.Edit, Action.IncognitoRead, Action.AddToReadingList];
|
|||
export class EditChapterModalComponent implements OnInit {
|
||||
|
||||
protected readonly modal = inject(NgbActiveModal);
|
||||
private readonly seriesService = inject(SeriesService);
|
||||
public readonly utilityService = inject(UtilityService);
|
||||
public readonly imageService = inject(ImageService);
|
||||
private readonly uploadService = inject(UploadService);
|
||||
|
@ -183,7 +181,7 @@ export class EditChapterModalComponent implements OnInit {
|
|||
|
||||
this.editForm.addControl('titleName', new FormControl(this.chapter.titleName, []));
|
||||
this.editForm.addControl('sortOrder', new FormControl(this.chapter.sortOrder, [Validators.required, Validators.min(0)]));
|
||||
this.editForm.addControl('summary', new FormControl(this.chapter.summary, []));
|
||||
this.editForm.addControl('summary', new FormControl(this.chapter.summary || '', []));
|
||||
this.editForm.addControl('language', new FormControl(this.chapter.language, []));
|
||||
this.editForm.addControl('isbn', new FormControl(this.chapter.isbn, []));
|
||||
this.editForm.addControl('ageRating', new FormControl(this.chapter.ageRating, []));
|
||||
|
@ -251,6 +249,14 @@ export class EditChapterModalComponent implements OnInit {
|
|||
const selectedIndex = this.editForm.get('coverImageIndex')?.value || 0;
|
||||
|
||||
this.chapter.releaseDate = model.releaseDate;
|
||||
this.chapter.ageRating = model.ageRating as AgeRating;
|
||||
this.chapter.genres = model.genres;
|
||||
this.chapter.tags = model.tags;
|
||||
this.chapter.sortOrder = model.sortOrder;
|
||||
this.chapter.language = model.language;
|
||||
this.chapter.titleName = model.titleName;
|
||||
this.chapter.summary = model.summary;
|
||||
this.chapter.isbn = model.isbn;
|
||||
|
||||
|
||||
const apis = [
|
||||
|
|
|
@ -17,7 +17,6 @@ import {EntityTitleComponent} from "../../cards/entity-title/entity-title.compon
|
|||
import {SettingButtonComponent} from "../../settings/_components/setting-button/setting-button.component";
|
||||
import {CoverImageChooserComponent} from "../../cards/cover-image-chooser/cover-image-chooser.component";
|
||||
import {EditChapterProgressComponent} from "../../cards/edit-chapter-progress/edit-chapter-progress.component";
|
||||
import {EntityInfoCardsComponent} from "../../cards/entity-info-cards/entity-info-cards.component";
|
||||
import {CompactNumberPipe} from "../../_pipes/compact-number.pipe";
|
||||
import {IconAndTitleComponent} from "../../shared/icon-and-title/icon-and-title.component";
|
||||
import {DefaultDatePipe} from "../../_pipes/default-date.pipe";
|
||||
|
@ -83,7 +82,6 @@ const blackList = [Action.Edit, Action.IncognitoRead, Action.AddToReadingList];
|
|||
CoverImageChooserComponent,
|
||||
EditChapterProgressComponent,
|
||||
NgbInputDatepicker,
|
||||
EntityInfoCardsComponent,
|
||||
CompactNumberPipe,
|
||||
IconAndTitleComponent,
|
||||
DefaultDatePipe,
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
<ng-container *transloco="let t; read:'review-card'">
|
||||
<div class="card review-card clickable mb-3" (click)="showModal()">
|
||||
<div class="row g-0">
|
||||
<div class="col-md-2 d-none d-md-block p-2">
|
||||
<div class="col-md-2 col-sm-2 col-2 d-block p-2">
|
||||
@if (isMyReview) {
|
||||
<i class="d-md-none fa-solid fa-star me-2" aria-hidden="true" [title]="t('your-review')"></i>
|
||||
<img class="me-2" [ngSrc]="ScrobbleProvider.Kavita | providerImage" width="40" height="40" alt="">
|
||||
<i class="d-none fa-solid fa-star me-2" aria-hidden="true" [title]="t('your-review')"></i>
|
||||
<img class="me-2" [ngSrc]="ScrobbleProvider.Kavita | providerImage:true" width="40" height="40" alt="">
|
||||
} @else {
|
||||
<img class="me-2" [ngSrc]="review.provider | providerImage" width="40" height="40" alt="">
|
||||
<img class="me-2" [ngSrc]="review.provider | providerImage:true" width="40" height="40" alt="">
|
||||
}
|
||||
</div>
|
||||
<div class="col-md-10">
|
||||
<div class="col-md-10 col-sm-10 col-10">
|
||||
<div class="card-body p-2">
|
||||
<!--
|
||||
<h6 class="card-title">
|
||||
|
|
|
@ -2,22 +2,25 @@
|
|||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title">
|
||||
{{name}}
|
||||
|
||||
</h5>
|
||||
<button type="button" class="btn-close text-reset" [attr.aria-label]="t('common.close')" (click)="close()"></button>
|
||||
</div>
|
||||
|
||||
<div class="offcanvas-body">
|
||||
<ng-container *ngIf="CoverUrl as coverUrl">
|
||||
@if (CoverUrl; as coverUrl) {
|
||||
<div style="width: 160px" class="mx-auto mb-3">
|
||||
<app-image *ngIf="coverUrl" height="232.91px" width="160px" [styles]="{'object-fit': 'contain', 'max-height': '232.91px'}" [imageUrl]="coverUrl"></app-image>
|
||||
@if (coverUrl) {
|
||||
<app-image height="232.91px" width="160px" [styles]="{'object-fit': 'contain', 'max-height': '232.91px'}" [imageUrl]="coverUrl"></app-image>
|
||||
}
|
||||
</div>
|
||||
</ng-container>
|
||||
}
|
||||
|
||||
<ng-container *ngIf="externalSeries; else localSeriesBody">
|
||||
<div *ngIf="(externalSeries.volumeCount || 0) > 0 || (externalSeries.chapterCount || 0) > 0" class="text-muted muted mb-2">
|
||||
{{t('series-preview-drawer.vols-and-chapters', {volCount: externalSeries.volumeCount, chpCount: externalSeries.chapterCount})}}
|
||||
</div>
|
||||
@if (externalSeries) {
|
||||
@if ((externalSeries.volumeCount || 0) > 0 || (externalSeries.chapterCount || 0) > 0) {
|
||||
<div class="text-muted muted mb-2">
|
||||
{{t('series-preview-drawer.vols-and-chapters', {volCount: externalSeries.volumeCount, chpCount: externalSeries.chapterCount})}}
|
||||
</div>
|
||||
}
|
||||
|
||||
@if(isExternalSeries && externalSeries) {
|
||||
<div class="text-muted muted mb-2">
|
||||
|
@ -26,14 +29,20 @@
|
|||
</div>
|
||||
}
|
||||
|
||||
<app-read-more *ngIf="externalSeries.summary" [maxLength]="300" [text]="externalSeries.summary"></app-read-more>
|
||||
@if (externalSeries.summary) {
|
||||
<app-read-more [maxLength]="300" [text]="externalSeries.summary"></app-read-more>
|
||||
}
|
||||
}
|
||||
|
||||
<a class="btn btn-primary col-12 mt-2" [href]="url" target="_blank" rel="noopener noreferrer">
|
||||
{{t('series-preview-drawer.view-series')}}
|
||||
</a>
|
||||
|
||||
@if (externalSeries) {
|
||||
<div class="mt-3">
|
||||
<app-metadata-detail [tags]="externalSeries.genres" [libraryId]="0" [heading]="t('series-preview-drawer.genres-label')">
|
||||
<ng-template #itemTemplate let-item>
|
||||
<app-tag-badge>
|
||||
{{item}}
|
||||
</app-tag-badge>
|
||||
<span class="dark-exempt btn-icon not-clickable">{{item}}</span>
|
||||
</ng-template>
|
||||
</app-metadata-detail>
|
||||
</div>
|
||||
|
@ -41,25 +50,22 @@
|
|||
<div class="mt-3">
|
||||
<app-metadata-detail [tags]="externalSeries.tags" [libraryId]="0" [heading]="t('series-preview-drawer.tags-label')">
|
||||
<ng-template #itemTemplate let-item>
|
||||
<app-tag-badge>
|
||||
{{item.name}}
|
||||
</app-tag-badge>
|
||||
<span class="dark-exempt btn-icon not-clickable">{{item.name}}</span>
|
||||
</ng-template>
|
||||
</app-metadata-detail>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<app-metadata-detail [tags]="externalSeries.staff" [libraryId]="0" [heading]="t('series-preview-drawer.staff-label')">
|
||||
<app-metadata-detail [tags]="externalSeries.staff" [libraryId]="0" [heading]="t('series-preview-drawer.staff-label')" [includeComma]="false">
|
||||
<ng-template #itemTemplate let-item>
|
||||
<div class="card mb-3">
|
||||
<div class="row g-0">
|
||||
<div class="col-md-3">
|
||||
<ng-container *ngIf="item.imageUrl && !item.imageUrl.endsWith('default.jpg'); else localPerson">
|
||||
@if (item.imageUrl && !item.imageUrl.endsWith('default.jpg')) {
|
||||
<app-image height="24px" width="24px" [styles]="{'object-fit': 'contain'}" [imageUrl]="item.imageUrl" classes="person-img"></app-image>
|
||||
</ng-container>
|
||||
<ng-template #localPerson>
|
||||
} @else {
|
||||
<i class="fa fa-user-circle align-self-center person-img" style="font-size: 28px;" aria-hidden="true"></i>
|
||||
</ng-template>
|
||||
}
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
<div class="card-body">
|
||||
|
@ -72,67 +78,56 @@
|
|||
</ng-template>
|
||||
</app-metadata-detail>
|
||||
</div>
|
||||
</ng-container>
|
||||
}
|
||||
@else if(localSeries) {
|
||||
<div class="d-inline-block mb-2 mt-2" style="width: 100%">
|
||||
<span class="text-muted muted">{{localSeries.publicationStatus | publicationStatus}}</span>
|
||||
<button class="btn btn-secondary btn-sm float-end me-3"
|
||||
(click)="toggleWantToRead()"
|
||||
ngbTooltip="{{wantToRead ? t('series-preview-drawer.remove-from-want-to-read') : t('series-preview-drawer.add-to-want-to-read')}}">
|
||||
<i class="{{wantToRead ? 'fa-solid' : 'fa-regular'}} fa-star" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<ng-template #localSeriesBody>
|
||||
<ng-container *ngIf="localSeries">
|
||||
<div class="d-inline-block mb-2" style="width: 100%">
|
||||
<span class="text-muted muted">{{localSeries.publicationStatus | publicationStatus}}</span>
|
||||
<button class="btn btn-secondary btn-sm float-end me-3"
|
||||
(click)="toggleWantToRead()"
|
||||
ngbTooltip="{{wantToRead ? t('series-preview-drawer.remove-from-want-to-read') : t('series-preview-drawer.add-to-want-to-read')}}">
|
||||
<i class="{{wantToRead ? 'fa-solid' : 'fa-regular'}} fa-star" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
<app-read-more [maxLength]="300" [text]="localSeries.summary"></app-read-more>
|
||||
<app-read-more [maxLength]="300" [text]="localSeries.summary"></app-read-more>
|
||||
|
||||
<div class="mt-3">
|
||||
<app-metadata-detail [tags]="localSeries.genres" [libraryId]="0" [heading]="t('series-preview-drawer.genres-label')">
|
||||
<ng-template #itemTemplate let-item>
|
||||
<app-tag-badge>
|
||||
{{item.title}}
|
||||
</app-tag-badge>
|
||||
</ng-template>
|
||||
</app-metadata-detail>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<app-metadata-detail [tags]="localSeries.genres" [libraryId]="0" [heading]="t('series-preview-drawer.genres-label')">
|
||||
<ng-template #itemTemplate let-item>
|
||||
<a class="dark-exempt btn-icon not-clickable">{{item.title}}</a>
|
||||
</ng-template>
|
||||
</app-metadata-detail>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<app-metadata-detail [tags]="localSeries.tags" [libraryId]="0" [heading]="t('series-preview-drawer.tags-label')">
|
||||
<ng-template #itemTemplate let-item>
|
||||
<app-tag-badge>
|
||||
{{item.title}}
|
||||
</app-tag-badge>
|
||||
</ng-template>
|
||||
</app-metadata-detail>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<app-metadata-detail [tags]="localSeries.tags" [libraryId]="0" [heading]="t('series-preview-drawer.tags-label')">
|
||||
<ng-template #itemTemplate let-item>
|
||||
<span class="dark-exempt btn-icon not-clickable">{{item.title}}</span>
|
||||
</ng-template>
|
||||
</app-metadata-detail>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<app-metadata-detail [tags]="localStaff" [libraryId]="0" [heading]="t('series-preview-drawer.staff-label')">
|
||||
<ng-template #itemTemplate let-item>
|
||||
<div class="card mb-3">
|
||||
<div class="row g-0">
|
||||
<div class="col-md-4">
|
||||
<i class="fa fa-user-circle align-self-center" style="font-size: 28px; margin-top: 24px; margin-left: 24px" aria-hidden="true"></i>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title">{{item.name}}</h6>
|
||||
<p class="card-text" style="font-size: 14px"><small class="text-muted">{{item.role}}</small></p>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<app-metadata-detail [tags]="localStaff" [libraryId]="0" [heading]="t('series-preview-drawer.staff-label')" [includeComma]="false">
|
||||
<ng-template #itemTemplate let-item>
|
||||
<div class="card mb-3">
|
||||
<div class="row g-0">
|
||||
<div class="col-md-4">
|
||||
<i class="fa fa-user-circle align-self-center" style="font-size: 28px; margin-top: 24px; margin-left: 24px" aria-hidden="true"></i>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title">{{item.name}}</h6>
|
||||
<p class="card-text" style="font-size: 14px"><small class="text-muted">{{item.role}}</small></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-template>
|
||||
</app-metadata-detail>
|
||||
</div>
|
||||
|
||||
</ng-container>
|
||||
</ng-template>
|
||||
</div>
|
||||
</ng-template>
|
||||
</app-metadata-detail>
|
||||
</div>
|
||||
}
|
||||
|
||||
<app-loading [loading]="isLoading"></app-loading>
|
||||
|
||||
<a class="btn btn-primary col-12 mt-2" [href]="url" target="_blank" rel="noopener noreferrer">
|
||||
{{t('series-preview-drawer.view-series')}}
|
||||
</a>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
|
|
@ -15,4 +15,13 @@
|
|||
|
||||
a.read-more-link {
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.not-clickable {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.offcanvas-body {
|
||||
mask-image: linear-gradient(to bottom, transparent, black 0%, black 95%, transparent 100%);
|
||||
-webkit-mask-image: linear-gradient(to bottom, transparent, black 0%, black 95%, transparent 100%);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, Input, OnInit} from '@angular/core';
|
||||
import {CommonModule, NgOptimizedImage} from '@angular/common';
|
||||
import {NgOptimizedImage} from '@angular/common';
|
||||
import {TranslocoDirective} from "@jsverse/transloco";
|
||||
import {NgbActiveOffcanvas, NgbTooltip} from "@ng-bootstrap/ng-bootstrap";
|
||||
import {ExternalSeriesDetail, SeriesStaff} from "../../_models/series-detail/external-series-detail";
|
||||
|
@ -17,17 +17,26 @@ import {SeriesMetadata} from "../../_models/metadata/series-metadata";
|
|||
import {ReadMoreComponent} from "../../shared/read-more/read-more.component";
|
||||
import {ActionService} from "../../_services/action.service";
|
||||
import {ProviderImagePipe} from "../../_pipes/provider-image.pipe";
|
||||
import {ScrobbleProvider} from "../../_services/scrobbling.service";
|
||||
import {FilterField} from "../../_models/metadata/v2/filter-field";
|
||||
|
||||
@Component({
|
||||
selector: 'app-series-preview-drawer',
|
||||
standalone: true,
|
||||
imports: [CommonModule, TranslocoDirective, ImageComponent, LoadingComponent, SafeHtmlPipe, A11yClickDirective, MetadataDetailComponent, PersonBadgeComponent, TagBadgeComponent, PublicationStatusPipe, ReadMoreComponent, NgbTooltip, NgOptimizedImage, ProviderImagePipe],
|
||||
imports: [TranslocoDirective, ImageComponent, LoadingComponent, SafeHtmlPipe, A11yClickDirective, MetadataDetailComponent, PersonBadgeComponent, TagBadgeComponent, PublicationStatusPipe, ReadMoreComponent, NgbTooltip, NgOptimizedImage, ProviderImagePipe],
|
||||
templateUrl: './series-preview-drawer.component.html',
|
||||
styleUrls: ['./series-preview-drawer.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class SeriesPreviewDrawerComponent implements OnInit {
|
||||
|
||||
private readonly activeOffcanvas = inject(NgbActiveOffcanvas);
|
||||
private readonly seriesService = inject(SeriesService);
|
||||
private readonly imageService = inject(ImageService);
|
||||
private readonly actionService = inject(ActionService);
|
||||
private readonly cdRef = inject(ChangeDetectorRef);
|
||||
|
||||
protected readonly FilterField = FilterField;
|
||||
|
||||
@Input({required: true}) name!: string;
|
||||
@Input() aniListId?: number;
|
||||
@Input() malId?: number;
|
||||
|
@ -42,11 +51,7 @@ export class SeriesPreviewDrawerComponent implements OnInit {
|
|||
url: string = '';
|
||||
wantToRead: boolean = false;
|
||||
|
||||
private readonly activeOffcanvas = inject(NgbActiveOffcanvas);
|
||||
private readonly seriesService = inject(SeriesService);
|
||||
private readonly imageService = inject(ImageService);
|
||||
private readonly actionService = inject(ActionService);
|
||||
private readonly cdRef = inject(ChangeDetectorRef);
|
||||
|
||||
|
||||
get CoverUrl() {
|
||||
if (this.isExternalSeries) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue