Polish Part 3 (#2424)

This commit is contained in:
Joe Milazzo 2023-11-10 07:56:30 -06:00 committed by GitHub
parent a018d6828e
commit 944830ca73
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
62 changed files with 518 additions and 493 deletions

View file

@ -1,7 +1,3 @@
.clickable {
cursor: pointer;
}
.clickable:hover, .clickable:focus {
background-color: lightgreen;
}

View file

@ -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>

View file

@ -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;
}

View file

@ -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();

View file

@ -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>

View file

@ -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;
}
}
}

View file

@ -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>

View file

@ -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;
}

View file

@ -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',

View file

@ -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>

View file

@ -0,0 +1,11 @@
::ng-deep .extreme-blur {
filter: brightness(50%) blur(4px)
}
.overlay-information {
background-color: transparent;
}
.card-title {
width: 146px;
}

View file

@ -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();
}
}