Polish Part 3 (#2424)
This commit is contained in:
parent
a018d6828e
commit
944830ca73
62 changed files with 518 additions and 493 deletions
|
|
@ -1,7 +1,3 @@
|
|||
.clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.clickable:hover, .clickable:focus {
|
||||
background-color: lightgreen;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<ng-container *transloco="let t; read: 'card-item'">
|
||||
<div class="card {{selected ? 'selected-highlight' : ''}}">
|
||||
<div class="card-item-container card {{selected ? 'selected-highlight' : ''}}">
|
||||
<div class="overlay" (click)="handleClick($event)">
|
||||
<ng-container *ngIf="total > 0 || suppressArchiveWarning">
|
||||
<app-image borderRadius=".25rem .25rem 0 0" height="230px" width="158px" [imageUrl]="imageUrl"></app-image>
|
||||
<app-image borderRadius=".25rem .25rem 0 0" height="230px" width="158px" [imageUrl]="imageUrl"></app-image>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="total === 0 && !suppressArchiveWarning">
|
||||
<app-image borderRadius=".25rem .25rem 0 0" height="230px" width="158px" [imageUrl]="imageService.errorImage"></app-image>
|
||||
|
|
@ -34,11 +34,14 @@
|
|||
<span class="badge bg-primary">{{count}}</span>
|
||||
</div>
|
||||
<div class="card-overlay"></div>
|
||||
<div class="overlay-information {{centerOverlay ? 'overlay-information--centered' : ''}}" *ngIf="overlayInformation !== '' || overlayInformation !== undefined">
|
||||
<div class="position-relative">
|
||||
<span class="card-title library mx-auto" style="width: auto;" [ngbTooltip]="overlayInformation" placement="top">{{overlayInformation}}</span>
|
||||
<ng-container *ngIf="overlayInformation | safeHtml as info">
|
||||
<div class="overlay-information {{centerOverlay ? 'overlay-information--centered' : ''}}" *ngIf="info !== '' || info !== undefined">
|
||||
<div class="position-relative">
|
||||
<span class="card-title library mx-auto" style="width: auto;" [ngbTooltip]="info" placement="top" [innerHTML]="info"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="card-body" *ngIf="title.length > 0 || actions.length > 0">
|
||||
|
|
@ -54,7 +57,7 @@
|
|||
</ng-container>
|
||||
{{title}}
|
||||
</span>
|
||||
<span class="card-actions float-end">
|
||||
<span class="card-actions float-end" *ngIf="actions && actions.length > 0">
|
||||
<app-card-actionables (actionHandler)="performAction($event)" [actions]="actions" [labelBy]="title"></app-card-actionables>
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -17,39 +17,11 @@ $image-width: 160px;
|
|||
right: 0px;
|
||||
}
|
||||
|
||||
.card {
|
||||
max-width: $image-width;
|
||||
cursor: pointer;
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
color: var(--card-text-color);
|
||||
border: 1px var(--card-border-color);
|
||||
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 13px;
|
||||
width: 130px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
margin-top: 2px;
|
||||
margin-bottom: 0px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.selected-highlight {
|
||||
outline: 2px solid var(--primary-color);
|
||||
}
|
||||
|
||||
|
||||
.img-top {
|
||||
height: $image-height;
|
||||
}
|
||||
|
||||
.progress-banner {
|
||||
width: $image-width;
|
||||
height: 5px;
|
||||
|
|
@ -78,7 +50,6 @@ $image-width: 160px;
|
|||
position: absolute;
|
||||
top: 0;
|
||||
width: 158px;
|
||||
|
||||
}
|
||||
|
||||
.not-read-badge {
|
||||
|
|
@ -113,46 +84,14 @@ $image-width: 160px;
|
|||
}
|
||||
|
||||
|
||||
|
||||
.overlay-information {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: 5px;
|
||||
border-radius: 15px;
|
||||
padding: 0 10px;
|
||||
background-color: var(--card-bg-color);
|
||||
|
||||
&.overlay-information--centered {
|
||||
top: 95px;
|
||||
left: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
.overlay {
|
||||
height: $image-height;
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
|
||||
&:hover {
|
||||
visibility: visible;
|
||||
|
||||
.bulk-mode {
|
||||
visibility: visible;
|
||||
z-index: 110;
|
||||
}
|
||||
|
||||
.overlay-item {
|
||||
visibility: visible;
|
||||
z-index: 100;
|
||||
}
|
||||
}
|
||||
|
||||
.overlay-item {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
z-index: 10;
|
||||
|
||||
.count {
|
||||
top: 5px;
|
||||
right: 10px;
|
||||
|
|
@ -167,29 +106,8 @@ $image-width: 160px;
|
|||
width: 20px;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 5px !important;
|
||||
background-color: var(--card-bg-color);
|
||||
border-width: var(--card-border-width);
|
||||
border-style: var(--card-border-style);
|
||||
border-color: var(--card-border-color);
|
||||
border-radius: 0.25em;
|
||||
}
|
||||
|
||||
.library {
|
||||
font-size: 13px;
|
||||
text-decoration: none;
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.card-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: $image-height;
|
||||
z-index: 10;
|
||||
transition: all 0.2s;
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import {
|
|||
EventEmitter,
|
||||
HostListener,
|
||||
inject,
|
||||
Input, NgZone,
|
||||
Input,
|
||||
OnInit,
|
||||
Output
|
||||
} from '@angular/core';
|
||||
|
|
@ -39,11 +39,11 @@ import {MangaFormatIconPipe} from "../../_pipes/manga-format-icon.pipe";
|
|||
import {SentenceCasePipe} from "../../_pipes/sentence-case.pipe";
|
||||
import {CommonModule} from "@angular/common";
|
||||
import {RouterLink} from "@angular/router";
|
||||
import {translate, TranslocoModule, TranslocoService} from "@ngneat/transloco";
|
||||
import {TranslocoModule} from "@ngneat/transloco";
|
||||
import {CardActionablesComponent} from "../../_single-module/card-actionables/card-actionables.component";
|
||||
import {NextExpectedChapter} from "../../_models/series-detail/next-expected-chapter";
|
||||
import {UtcToLocalTimePipe} from "../../_pipes/utc-to-local-time.pipe";
|
||||
import {TimeAgoPipe} from "../../_pipes/time-ago.pipe";
|
||||
import {SafeHtmlPipe} from "../../_pipes/safe-html.pipe";
|
||||
|
||||
@Component({
|
||||
selector: 'app-card-item',
|
||||
|
|
@ -60,7 +60,8 @@ import {TimeAgoPipe} from "../../_pipes/time-ago.pipe";
|
|||
CardActionablesComponent,
|
||||
SentenceCasePipe,
|
||||
RouterLink,
|
||||
TranslocoModule
|
||||
TranslocoModule,
|
||||
SafeHtmlPipe
|
||||
],
|
||||
templateUrl: './card-item.component.html',
|
||||
styleUrls: ['./card-item.component.scss'],
|
||||
|
|
@ -68,6 +69,19 @@ import {TimeAgoPipe} from "../../_pipes/time-ago.pipe";
|
|||
})
|
||||
export class CardItemComponent implements OnInit {
|
||||
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
public readonly imageService = inject(ImageService);
|
||||
public readonly bulkSelectionService = inject(BulkSelectionService);
|
||||
private readonly libraryService = inject(LibraryService);
|
||||
private readonly downloadService = inject(DownloadService);
|
||||
private readonly utilityService = inject(UtilityService);
|
||||
private readonly messageHub = inject(MessageHubService);
|
||||
private readonly accountService = inject(AccountService);
|
||||
private readonly scrollService = inject(ScrollService);
|
||||
private readonly cdRef = inject(ChangeDetectorRef);
|
||||
private readonly actionFactoryService = inject(ActionFactoryService);
|
||||
protected readonly MangaFormat = MangaFormat;
|
||||
|
||||
/**
|
||||
* Card item url. Will internally handle error and missing covers
|
||||
*/
|
||||
|
|
@ -109,7 +123,7 @@ export class CardItemComponent implements OnInit {
|
|||
*/
|
||||
@Input() allowSelection: boolean = false;
|
||||
/**
|
||||
* This will suppress the cannot read archive warning when total pages is 0
|
||||
* This will suppress the "cannot read archive warning" when total pages is 0
|
||||
*/
|
||||
@Input() suppressArchiveWarning: boolean = false;
|
||||
/**
|
||||
|
|
@ -159,21 +173,6 @@ export class CardItemComponent implements OnInit {
|
|||
selectionInProgress: boolean = false;
|
||||
|
||||
private user: User | undefined;
|
||||
private readonly destroyRef = inject(DestroyRef);
|
||||
private readonly ngZone = inject(NgZone);
|
||||
private readonly translocoService = inject(TranslocoService);
|
||||
|
||||
get MangaFormat(): typeof MangaFormat {
|
||||
return MangaFormat;
|
||||
}
|
||||
|
||||
|
||||
constructor(public imageService: ImageService, private libraryService: LibraryService,
|
||||
public utilityService: UtilityService, private downloadService: DownloadService,
|
||||
public bulkSelectionService: BulkSelectionService,
|
||||
private messageHub: MessageHubService, private accountService: AccountService,
|
||||
private scrollService: ScrollService, private readonly cdRef: ChangeDetectorRef,
|
||||
private actionFactoryService: ActionFactoryService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
||||
|
|
@ -224,12 +223,15 @@ export class CardItemComponent implements OnInit {
|
|||
this.imageUrl = '';
|
||||
const nextDate = (this.entity as NextExpectedChapter);
|
||||
|
||||
this.overlayInformation = nextDate.title;
|
||||
const tokens = nextDate.title.split(':');
|
||||
this.overlayInformation = `
|
||||
<i class="fa-regular fa-clock mb-2" style="font-size: 26px" aria-hidden="true"></i>
|
||||
<div>${tokens[0]}</div><div>${tokens[1]}</div>`;
|
||||
this.centerOverlay = true;
|
||||
|
||||
if (nextDate.expectedDate) {
|
||||
const utcPipe = new UtcToLocalTimePipe();
|
||||
this.title = utcPipe.transform(nextDate.expectedDate, 'shortDate');
|
||||
this.title = '~ ' + utcPipe.transform(nextDate.expectedDate, 'shortDate');
|
||||
}
|
||||
|
||||
this.cdRef.markForCheck();
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
</form>
|
||||
|
||||
<div class="row g-0 chooser" style="padding-top: 10px">
|
||||
<div class="image-card col-auto"
|
||||
<div class="clickable col-auto"
|
||||
*ngIf="showReset" tabindex="0" (click)="reset()"
|
||||
[ngClass]="{'selected': !showApplyButton && selectedIndex === -1}">
|
||||
<app-image class="card-img-top" [title]="t('reset-cover-tooltip')" height="230px" width="158px" [imageUrl]="imageService.resetCoverImage"></app-image>
|
||||
|
|
@ -62,7 +62,7 @@
|
|||
</ng-container>
|
||||
|
||||
</div>
|
||||
<div class="image-card col-auto"
|
||||
<div class="clickable col-auto"
|
||||
*ngFor="let url of imageUrls; let idx = index;" tabindex="0" [attr.aria-label]="t('image-num', {num: idx + 1})" (click)="selectImage(idx)"
|
||||
[ngClass]="{'selected': !showApplyButton && selectedIndex === idx}">
|
||||
<app-image class="card-img-top" height="230px" width="158px" [imageUrl]="url" [processEvents]="idx > 0"></app-image>
|
||||
|
|
|
|||
|
|
@ -7,9 +7,6 @@ $image-width: 160px;
|
|||
max-height: $image-height;
|
||||
}
|
||||
|
||||
.image-card {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.selected {
|
||||
outline: 5px solid var(--primary-color);
|
||||
|
|
@ -38,4 +35,4 @@ ngx-file-drop ::ng-deep > div {
|
|||
display: inline-block;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<ng-container *transloco="let t; read: 'external-series-card'">
|
||||
<ng-container *ngIf="data !== undefined">
|
||||
<div class="card">
|
||||
<div class="card-item-container card clickable">
|
||||
<div class="overlay" (click)="handleClick()">
|
||||
<ng-container>
|
||||
<app-image borderRadius=".25rem .25rem 0 0" height="230px" width="158px" [imageUrl]="data.coverUrl"></app-image>
|
||||
|
|
|
|||
|
|
@ -1,126 +0,0 @@
|
|||
|
||||
|
||||
$image-height: 230px;
|
||||
$image-width: 160px;
|
||||
|
||||
|
||||
.card {
|
||||
max-width: $image-width;
|
||||
cursor: pointer;
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
color: var(--card-text-color);
|
||||
border: 1px var(--card-border-color);
|
||||
}
|
||||
|
||||
.card-actions {
|
||||
position: absolute;
|
||||
top: 236px;
|
||||
right: 0px;
|
||||
width: 20px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.library {
|
||||
font-size: 13px;
|
||||
text-decoration: none;
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 13px;
|
||||
width: 131px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
margin-top: 2px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
|
||||
.img-top {
|
||||
height: $image-height;
|
||||
}
|
||||
|
||||
|
||||
.badge-container {
|
||||
border-radius: 4px;
|
||||
display: block;
|
||||
height: $image-height;
|
||||
left: 0;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 158px;
|
||||
|
||||
}
|
||||
|
||||
.not-read-badge {
|
||||
position: absolute;
|
||||
top: calc(-1 * (var(--card-progress-triangle-size) / 2));
|
||||
right: -14px;
|
||||
z-index: 1000;
|
||||
height: var(--card-progress-triangle-size);
|
||||
width: var(--card-progress-triangle-size);
|
||||
background-color: var(--primary-color);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
|
||||
.overlay {
|
||||
height: $image-height;
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
|
||||
&:hover {
|
||||
visibility: visible;
|
||||
|
||||
.bulk-mode {
|
||||
visibility: visible;
|
||||
z-index: 110;
|
||||
}
|
||||
|
||||
.overlay-item {
|
||||
visibility: visible;
|
||||
z-index: 100;
|
||||
}
|
||||
}
|
||||
|
||||
.overlay-item {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
z-index: 10;
|
||||
|
||||
.count {
|
||||
top: 5px;
|
||||
right: 10px;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.card-body {
|
||||
padding: 5px !important;
|
||||
background-color: var(--card-bg-color);
|
||||
border-width: var(--card-border-width);
|
||||
border-style: var(--card-border-style);
|
||||
border-color: var(--card-border-color);
|
||||
border-radius: 0.25em;
|
||||
}
|
||||
|
||||
.card-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: $image-height;
|
||||
z-index: 10;
|
||||
transition: all 0.2s;
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
|
|
@ -9,11 +9,10 @@ import {CommonModule} from '@angular/common';
|
|||
import {ExternalSeries} from "../../_models/series-detail/external-series";
|
||||
import {RouterLinkActive} from "@angular/router";
|
||||
import {ImageComponent} from "../../shared/image/image.component";
|
||||
import {NgbActiveOffcanvas, NgbOffcanvas, NgbProgressbar, NgbTooltip} from "@ng-bootstrap/ng-bootstrap";
|
||||
import {NgbOffcanvas, NgbProgressbar, NgbTooltip} from "@ng-bootstrap/ng-bootstrap";
|
||||
import {ReactiveFormsModule} from "@angular/forms";
|
||||
import {TranslocoDirective} from "@ngneat/transloco";
|
||||
import {SeriesPreviewDrawerComponent} from "../../_single-module/series-preview-drawer/series-preview-drawer.component";
|
||||
import {SeriesService} from "../../_services/series.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-external-series-card',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
<div class="card-item-container card">
|
||||
<div class="overlay">
|
||||
<app-image borderRadius=".25rem .25rem 0 0" height="230px" width="158px" classes="extreme-blur" [imageUrl]="imageUrl"></app-image>
|
||||
|
||||
<div class="card-overlay"></div>
|
||||
<ng-container *ngIf="overlayInformation | safeHtml as info">
|
||||
<div class="overlay-information overlay-information--centered" *ngIf="info !== '' || info !== undefined">
|
||||
<div class="position-relative">
|
||||
<span class="card-title library mx-auto" style="width: auto;">
|
||||
<i class="fa-regular fa-clock mb-2" style="font-size: 26px" aria-hidden="true"></i>
|
||||
<span [innerHTML]="info"></span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="card-body">
|
||||
<span class="card-title" tabindex="0">{{title}}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
::ng-deep .extreme-blur {
|
||||
filter: brightness(50%) blur(4px)
|
||||
}
|
||||
|
||||
.overlay-information {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
width: 146px;
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, Input} from '@angular/core';
|
||||
import {CommonModule} from '@angular/common';
|
||||
import {ImageComponent} from "../../shared/image/image.component";
|
||||
import {NextExpectedChapter} from "../../_models/series-detail/next-expected-chapter";
|
||||
import {UtcToLocalTimePipe} from "../../_pipes/utc-to-local-time.pipe";
|
||||
import {SafeHtmlPipe} from "../../_pipes/safe-html.pipe";
|
||||
|
||||
@Component({
|
||||
selector: 'app-next-expected-card',
|
||||
standalone: true,
|
||||
imports: [CommonModule, ImageComponent, SafeHtmlPipe],
|
||||
templateUrl: './next-expected-card.component.html',
|
||||
styleUrl: './next-expected-card.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class NextExpectedCardComponent {
|
||||
private readonly cdRef = inject(ChangeDetectorRef);
|
||||
|
||||
/**
|
||||
* Card item url. Will internally handle error and missing covers
|
||||
*/
|
||||
@Input() imageUrl = '';
|
||||
/**
|
||||
* This is the entity we are representing. It will be returned if an action is executed.
|
||||
*/
|
||||
@Input({required: true}) entity!: NextExpectedChapter;
|
||||
|
||||
/**
|
||||
* Additional information to show on the overlay area. Will always render.
|
||||
*/
|
||||
@Input() overlayInformation: string = '';
|
||||
title: string = '';
|
||||
|
||||
|
||||
|
||||
ngOnInit(): void {
|
||||
const tokens = this.entity.title.split(':');
|
||||
this.overlayInformation = `<div>${tokens[0]}</div><div>${tokens[1]}</div>`;
|
||||
|
||||
if (this.entity.expectedDate) {
|
||||
const utcPipe = new UtcToLocalTimePipe();
|
||||
this.title = '~ ' + utcPipe.transform(this.entity.expectedDate, 'shortDate');
|
||||
}
|
||||
this.cdRef.markForCheck();
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue