Co-authored-by: Andre Smith <Hobogrammer@users.noreply.github.com>
This commit is contained in:
Joe Milazzo 2023-11-28 16:00:04 -06:00 committed by GitHub
parent 565a93f2d2
commit 915bf13a7c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 606 additions and 342 deletions

View file

@ -160,7 +160,7 @@
<button class="btn btn-secondary col-2 col-xs-1" (click)="closeReader()"><i class="fa fa-times-circle" aria-hidden="true"></i></button>
<button class="btn btn-outline-secondary btn-icon col-2 col-xs-1"
[disabled]="readingDirection === ReadingDirection.LeftToRight ? IsNextDisabled : IsPrevDisabled"
(click)="movePage(readingDirection === ReadingDirection.LeftToRight ? PAGING_DIRECTION.FORWARD : PAGING_DIRECTION.BACKWARDS)" title="{{readingDirection === ReadingDirection.LeftToRight ? t('next') : t('previous')}} Page">
title="{{readingDirection === ReadingDirection.LeftToRight ? t('next') : t('previous')}} Page">
<i class="fa {{(readingDirection === ReadingDirection.LeftToRight ? IsNextChapter : IsPrevChapter) ? 'fa-angle-double-right' : 'fa-angle-right'}} {{readingDirection === ReadingDirection.LeftToRight ? 'next-page-highlight' : ''}}" aria-hidden="true"></i>
</button>
</div>

View file

@ -102,10 +102,29 @@ const elementLevelStyles = ['line-height', 'font-family'];
])
],
standalone: true,
imports: [NgTemplateOutlet, DrawerComponent, NgIf, NgbProgressbar, NgbNav, NgbNavItem, NgbNavItemRole, NgbNavLink, NgbNavContent, ReaderSettingsComponent, TableOfContentsComponent, NgbNavOutlet, NgStyle, NgClass, NgbTooltip, BookLineOverlayComponent, PersonalTableOfContentsComponent, TranslocoDirective]
imports: [NgTemplateOutlet, DrawerComponent, NgIf, NgbProgressbar, NgbNav, NgbNavItem, NgbNavItemRole, NgbNavLink,
NgbNavContent, ReaderSettingsComponent, TableOfContentsComponent, NgbNavOutlet, NgStyle, NgClass, NgbTooltip,
BookLineOverlayComponent, PersonalTableOfContentsComponent, TranslocoDirective]
})
export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy {
private readonly route = inject(ActivatedRoute);
private readonly router = inject(Router);
private readonly accountService = inject(AccountService);
private readonly seriesService = inject(SeriesService);
private readonly readerService = inject(ReaderService);
private readonly renderer = inject(Renderer2);
private readonly navService = inject(NavService);
private readonly toastr = inject(ToastrService);
private readonly domSanitizer = inject(DomSanitizer);
private readonly bookService = inject(BookService);
private readonly memberService = inject(MemberService);
private readonly scrollService = inject(ScrollService);
private readonly utilityService = inject(UtilityService);
private readonly libraryService = inject(LibraryService);
private readonly themeService = inject(ThemeService);
private readonly cdRef = inject(ChangeDetectorRef);
libraryId!: number;
seriesId!: number;
volumeId!: number;
@ -194,11 +213,11 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy {
*/
page: SafeHtml | undefined = undefined;
/**
* Next Chapter Id. This is not garunteed to be a valid ChapterId. Prefetched on page load (non-blocking).
* Next Chapter Id. This is not guaranteed to be a valid ChapterId. Prefetched on page load (non-blocking).
*/
nextChapterId: number = CHAPTER_ID_NOT_FETCHED;
/**
* Previous Chapter Id. This is not garunteed to be a valid ChapterId. Prefetched on page load (non-blocking).
* Previous Chapter Id. This is not guaranteed to be a valid ChapterId. Prefetched on page load (non-blocking).
*/
prevChapterId: number = CHAPTER_ID_NOT_FETCHED;
/**
@ -480,13 +499,7 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy {
return (this.windowHeight) - (this.topOffset * 2) + 'px';
}
constructor(private route: ActivatedRoute, private router: Router, private accountService: AccountService,
private seriesService: SeriesService, private readerService: ReaderService, private location: Location,
private renderer: Renderer2, private navService: NavService, private toastr: ToastrService,
private domSanitizer: DomSanitizer, private bookService: BookService, private memberService: MemberService,
private scrollService: ScrollService, private utilityService: UtilityService, private libraryService: LibraryService,
@Inject(DOCUMENT) private document: Document, private themeService: ThemeService, private readonly cdRef: ChangeDetectorRef) {
constructor(@Inject(DOCUMENT) private document: Document) {
this.navService.hideNavBar();
this.themeService.clearThemes();
this.navService.hideSideNav();
@ -1620,7 +1633,7 @@ export class BookReaderComponent implements OnInit, AfterViewInit, OnDestroy {
// Responsible for handling pagination only
handleContainerClick(event: MouseEvent) {
if (this.drawerOpen || ['action-bar'].some(className => (event.target as Element).classList.contains(className))) {
if (this.drawerOpen || ['action-bar', 'offcanvas-backdrop'].some(className => (event.target as Element).classList.contains(className))) {
return;
}

View file

@ -3,11 +3,12 @@
<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">
<ng-container *ngIf="entity.title | safeHtml as info">
<div class="overlay-information overlay-information--centered" *ngIf="info !== ''">
<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>
<div class="upcoming-header">Upcoming</div>
<span [innerHTML]="info"></span>
</span>
</div>

View file

@ -6,6 +6,10 @@
background-color: transparent;
}
.upcoming-header {
font-size: 16px;
}
.card-title {
width: 146px;
}

View file

@ -1,4 +1,4 @@
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, Input} from '@angular/core';
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, Input, OnInit} from '@angular/core';
import {CommonModule} from '@angular/common';
import {ImageComponent} from "../../shared/image/image.component";
import {NextExpectedChapter} from "../../_models/series-detail/next-expected-chapter";
@ -14,7 +14,7 @@ import {translate} from "@ngneat/transloco";
styleUrl: './next-expected-card.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class NextExpectedCardComponent {
export class NextExpectedCardComponent implements OnInit {
private readonly cdRef = inject(ChangeDetectorRef);
/**
@ -25,19 +25,9 @@ export class NextExpectedCardComponent {
* 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 = translate('next-expected-card.title', {date: utcPipe.transform(this.entity.expectedDate, 'shortDate')});

View file

@ -67,7 +67,7 @@ import { FittingIconPipe } from '../../../_pipes/fitting-icon.pipe';
import { InfiniteScrollerComponent } from '../infinite-scroller/infinite-scroller.component';
import { SwipeDirective } from '../../../ng-swipe/ng-swipe.directive';
import { LoadingComponent } from '../../../shared/loading/loading.component';
import {translate, TranslocoDirective, TranslocoService} from "@ngneat/transloco";
import {translate, TranslocoDirective} from "@ngneat/transloco";
const PREFETCH_PAGES = 10;

View file

@ -22,39 +22,41 @@
<p>{{t('validate-description')}}</p>
<div class="row g-0">
<ngb-accordion #a="ngbAccordion">
<ngb-panel *ngFor="let fileToProcess of filesToProcess">
<ng-container *ngIf="fileToProcess.validateSummary as summary">
<ng-template ngbPanelTitle>
<ng-container [ngTemplateOutlet]="heading" [ngTemplateOutletContext]="{ summary: summary, filename: fileToProcess.fileName }"></ng-container>
</ng-template>
<ng-template ngbPanelContent>
<ng-container *ngIf="summary.results.length > 0; else noValidateIssues">
<h5>{{t('validate-warning')}}</h5>
<ol class="list-group list-group-numbered list-group-flush" >
<li class="list-group-item no-hover" *ngFor="let result of summary.results"
[innerHTML]="result | cblConflictReason | safeHtml">
</li>
</ol>
</ng-container>
<ng-template #noValidateIssues>
<div class="justify-content-center col">
<div class="d-flex align-items-center">
<div class="flex-shrink-0">
<i class="fa-solid fa-circle-check" style="font-size: 24px" aria-hidden="true"></i>
</div>
<div class="flex-grow-1 ms-3">
{{t('validate-no-issue')}}
<div ngbAccordion #accordion="ngbAccordion">
@for(fileToProcess of filesToProcess; track fileToProcess.fileName) {
<div ngbAccordionItem *ngIf="fileToProcess.validateSummary as summary">
<h5 ngbAccordionHeader>
<button ngbAccordionButton>
<ng-container [ngTemplateOutlet]="heading" [ngTemplateOutletContext]="{ summary: summary, filename: fileToProcess.fileName }"></ng-container>
</button>
</h5>
<div ngbAccordionCollapse>
<div ngbAccordionBody>
@if(summary.results.length > 0) {
<h5>{{t('validate-warning')}}</h5>
<ol class="list-group list-group-numbered list-group-flush" >
<li class="list-group-item no-hover" *ngFor="let result of summary.results"
[innerHTML]="result | cblConflictReason | safeHtml">
</li>
</ol>
} @else {
<div class="justify-content-center col">
<div class="d-flex align-items-center">
<div class="flex-shrink-0">
<i class="fa-solid fa-circle-check" style="font-size: 24px" aria-hidden="true"></i>
</div>
<div class="flex-grow-1 ms-3">
{{t('validate-no-issue')}}
</div>
</div>
{{t('validate-no-issue-description')}}
</div>
{{t('validate-no-issue-description')}}
</div>
</ng-template>
</ng-template>
</ng-container>
</ngb-panel>
</ngb-accordion>
}
</div>
</div>
</div>
}
</div>
</div>
</ng-container>
@ -62,57 +64,65 @@
<div class="row g-0">
<p>{{t('dry-run-description')}}</p>
<ngb-accordion #a="ngbAccordion">
<ngb-panel *ngFor="let fileToProcess of filesToProcess">
<ng-container *ngIf="fileToProcess.dryRunSummary as summary">
<ng-template ngbPanelTitle>
<ng-container [ngTemplateOutlet]="heading" [ngTemplateOutletContext]="{ summary: summary, filename: fileToProcess.fileName }"></ng-container>
</ng-template>
<ng-template ngbPanelContent>
<ng-container [ngTemplateOutlet]="resultsList" [ngTemplateOutletContext]="{ summary: summary }"></ng-container>
</ng-template>
</ng-container>
</ngb-panel>
</ngb-accordion>
<div ngbAccordion #a="ngbAccordion">
@for(fileToProcess of filesToProcess; track fileToProcess.fileName) {
<div ngbAccordionItem *ngIf="fileToProcess.dryRunSummary as summary">
<h5 ngbAccordionHeader>
<button ngbAccordionButton>
<ng-container [ngTemplateOutlet]="heading" [ngTemplateOutletContext]="{ summary: summary, filename: fileToProcess.fileName }"></ng-container>
</button>
</h5>
<div ngbAccordionCollapse>
<div ngbAccordionBody>
<ng-container [ngTemplateOutlet]="resultsList" [ngTemplateOutletContext]="{ summary: summary }"></ng-container>
</div>
</div>
</div>
}
</div>
</div>
</ng-container>
<ng-container *ngIf="currentStepIndex === Step.Finalize">
<div class="row g-0">
<ngb-accordion #a="ngbAccordion">
<ngb-panel *ngFor="let fileToProcess of filesToProcess">
<ng-container *ngIf="fileToProcess.finalizeSummary as summary">
<ng-template ngbPanelTitle>
<ng-container [ngTemplateOutlet]="heading" [ngTemplateOutletContext]="{ summary: summary, filename: fileToProcess.fileName }"></ng-container>
</ng-template>
<ng-template ngbPanelContent>
<ng-container [ngTemplateOutlet]="resultsList" [ngTemplateOutletContext]="{ summary: summary }"></ng-container>
</ng-template>
</ng-container>
</ngb-panel>
</ngb-accordion>
<div ngbAccordion #a="ngbAccordion">
@for(fileToProcess of filesToProcess; track fileToProcess.fileName) {
<div ngbAccordionItem *ngIf="fileToProcess.finalizeSummary as summary">
<h5 ngbAccordionHeader>
<button ngbAccordionButton>
<ng-container [ngTemplateOutlet]="heading" [ngTemplateOutletContext]="{ summary: summary, filename: fileToProcess.fileName }"></ng-container>
</button>
</h5>
<div ngbAccordionCollapse>
<div ngbAccordionBody>
<ng-container [ngTemplateOutlet]="resultsList" [ngTemplateOutletContext]="{ summary: summary }"></ng-container>
</div>
</div>
</div>
}
</div>
</div>
</ng-container>
</div>
<ng-template #resultsList let-summary="summary">
<ul class="list-group list-group-flush">
<li class="list-group-item no-hover" *ngFor="let result of summary.results"
innerHTML="{{result.order + 1}}. {{result | cblConflictReason | safeHtml}}"></li>
@for(result of summary.results; track result.order) {
<li class="list-group-item no-hover"
innerHTML="{{result.order + 1}}. {{result | cblConflictReason | safeHtml}}"></li>
}
</ul>
</ng-template>
<ng-template #heading let-filename="filename" let-summary="summary">
<ng-container *ngIf="summary.success | cblImportResult as success">
<ng-container [ngSwitch]="summary.success">
<span *ngSwitchCase="CblImportResult.Success" class="badge bg-primary me-1">{{success}}</span>
<span *ngSwitchCase="CblImportResult.Fail" class="badge bg-danger me-1">{{success}}</span>
<span *ngSwitchCase="CblImportResult.Partial" class="badge bg-warning me-1">{{success}}</span>
<ng-container *ngIf="summary.success | cblImportResult as success">
<ng-container [ngSwitch]="summary.success">
<span *ngSwitchCase="CblImportResult.Success" class="badge bg-primary me-1">{{success}}</span>
<span *ngSwitchCase="CblImportResult.Fail" class="badge bg-danger me-1">{{success}}</span>
<span *ngSwitchCase="CblImportResult.Partial" class="badge bg-warning me-1">{{success}}</span>
</ng-container>
</ng-container>
</ng-container>
<span>{{filename}}<span *ngIf="summary.cblName">: ({{summary.cblName}})</span></span>
<span>{{filename}}<span *ngIf="summary.cblName">: ({{summary.cblName}})</span></span>
</ng-template>

View file

@ -16,7 +16,7 @@ import {CommonModule} from "@angular/common";
import {SafeHtmlPipe} from "../../../_pipes/safe-html.pipe";
import {CblConflictReasonPipe} from "../../../_pipes/cbl-conflict-reason.pipe";
import {CblImportResultPipe} from "../../../_pipes/cbl-import-result.pipe";
import {TranslocoDirective, TranslocoService} from "@ngneat/transloco";
import {translate, TranslocoDirective, TranslocoService} from "@ngneat/transloco";
interface FileStep {
fileName: string;
@ -48,8 +48,6 @@ export class ImportCblModalComponent {
@ViewChild('fileUpload') fileUpload!: ElementRef<HTMLInputElement>;
translocoService = inject(TranslocoService);
fileUploadControl = new FormControl<undefined | Array<File>>(undefined, [
FileUploadValidators.accept(['.cbl']),
]);
@ -61,10 +59,10 @@ export class ImportCblModalComponent {
isLoading: boolean = false;
steps: Array<TimelineStep> = [
{title: this.translocoService.translate('import-cbl-modal.import-step'), index: Step.Import, active: true, icon: 'fa-solid fa-file-arrow-up'},
{title: this.translocoService.translate('import-cbl-modal.validate-cbl-step'), index: Step.Validate, active: false, icon: 'fa-solid fa-spell-check'},
{title: this.translocoService.translate('import-cbl-modal.dry-run-step'), index: Step.DryRun, active: false, icon: 'fa-solid fa-gears'},
{title: this.translocoService.translate('import-cbl-modal.final-import-step'), index: Step.Finalize, active: false, icon: 'fa-solid fa-floppy-disk'},
{title: translate('import-cbl-modal.import-step'), index: Step.Import, active: true, icon: 'fa-solid fa-file-arrow-up'},
{title: translate('import-cbl-modal.validate-cbl-step'), index: Step.Validate, active: false, icon: 'fa-solid fa-spell-check'},
{title: translate('import-cbl-modal.dry-run-step'), index: Step.DryRun, active: false, icon: 'fa-solid fa-gears'},
{title: translate('import-cbl-modal.final-import-step'), index: Step.Finalize, active: false, icon: 'fa-solid fa-floppy-disk'},
];
currentStepIndex = this.steps[0].index;
@ -103,7 +101,7 @@ export class ImportCblModalComponent {
case Step.Import:
const files = this.uploadForm.get('files')?.value;
if (!files) {
this.toastr.error(this.translocoService.translate('toasts.select-files-warning'));
this.toastr.error(translate('toasts.select-files-warning'));
return;
}
// Load each file into filesToProcess and group their data
@ -236,7 +234,7 @@ export class ImportCblModalComponent {
this.isLoading = false;
this.currentStepIndex++;
this.toastr.success(this.translocoService.translate('toasts.reading-list-imported'));
this.toastr.success(translate('toasts.reading-list-imported'));
this.cdRef.markForCheck();
});
}

View file

@ -5,7 +5,7 @@
<div class="col-lg-10 col-md-12 pe-2">
<div class="mb-3">
<label for="item--{{i}}" class="visually-hidden">{{label}}</label>
<input type="text" class="form-control" formControlName="link{{i}}" attr.id="item--{{i}}">
<input type="text" class="form-control" formControlName="link{{i}}" id="item--{{i}}">
</div>
</div>
<div class="col-lg-2">

View file

@ -27,7 +27,8 @@ enum TabID {
selector: 'app-customize-dashboard-modal',
standalone: true,
imports: [CommonModule, SafeHtmlPipe, TranslocoDirective, DraggableOrderedListComponent, ReadingListItemComponent, DashboardStreamListItemComponent,
NgbNav, NgbNavContent, NgbNavLink, NgbNavItem, NgbNavOutlet, CustomizeDashboardStreamsComponent, CustomizeSidenavStreamsComponent, ManageExternalSourcesComponent, ManageSmartFiltersComponent],
NgbNav, NgbNavContent, NgbNavLink, NgbNavItem, NgbNavOutlet, CustomizeDashboardStreamsComponent, CustomizeSidenavStreamsComponent,
ManageExternalSourcesComponent, ManageSmartFiltersComponent],
templateUrl: './customize-dashboard-modal.component.html',
styleUrls: ['./customize-dashboard-modal.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush

View file

@ -13,6 +13,7 @@ import {forkJoin} from "rxjs";
import {TranslocoDirective} from "@ngneat/transloco";
import {FormControl, FormGroup, ReactiveFormsModule} from "@angular/forms";
import {FilterPipe} from "../../../_pipes/filter.pipe";
import {Breakpoint, UtilityService} from "../../../shared/_services/utility.service";
@Component({
selector: 'app-customize-dashboard-streams',
@ -31,6 +32,7 @@ export class CustomizeDashboardStreamsComponent {
private readonly dashboardService = inject(DashboardService);
private readonly filterService = inject(FilterService);
private readonly cdRef = inject(ChangeDetectorRef);
private readonly utilityService = inject(UtilityService);
listForm: FormGroup = new FormGroup({
'filterQuery': new FormControl('', [])
@ -50,7 +52,7 @@ export class CustomizeDashboardStreamsComponent {
this.items = results[0];
// After 100 items, drag and drop is disabled to use virtualization
if (this.items.length > 100) {
if (this.items.length > 100 || this.utilityService.getActiveBreakpoint() <= Breakpoint.Tablet) {
this.accessibilityMode = true;
}

View file

@ -2,7 +2,7 @@ import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
DestroyRef, EventEmitter,
DestroyRef,
HostListener,
inject,
OnDestroy
@ -29,9 +29,9 @@ import {FilterPipe} from "../../../_pipes/filter.pipe";
import {BulkOperationsComponent} from "../../../cards/bulk-operations/bulk-operations.component";
import {Action, ActionItem} from "../../../_services/action-factory.service";
import {BulkSelectionService} from "../../../cards/bulk-selection.service";
import {filter, tap} from "rxjs/operators";
import {tap} from "rxjs/operators";
import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
import {KEY_CODES} from "../../../shared/_services/utility.service";
import {Breakpoint, KEY_CODES, UtilityService} from "../../../shared/_services/utility.service";
@Component({
selector: 'app-customize-sidenav-streams',
@ -43,7 +43,6 @@ import {KEY_CODES} from "../../../shared/_services/utility.service";
})
export class CustomizeSidenavStreamsComponent implements OnDestroy {
//@Input({required: true}) parentScrollElem!: Element | Window;
items: SideNavStream[] = [];
smartFilters: SmartFilter[] = [];
externalSources: ExternalSource[] = [];
@ -108,6 +107,7 @@ export class CustomizeSidenavStreamsComponent implements OnDestroy {
private readonly cdRef = inject(ChangeDetectorRef);
private readonly destroyRef = inject(DestroyRef);
public readonly bulkSelectionService = inject(BulkSelectionService);
public readonly utilityService = inject(UtilityService);
@HostListener('document:keydown.shift', ['$event'])
handleKeypress(event: KeyboardEvent) {
@ -172,7 +172,7 @@ export class CustomizeSidenavStreamsComponent implements OnDestroy {
this.items = results[0];
// After X items, drag and drop is disabled to use virtualization
if (this.items.length > this.virtualizeAfter) {
if (this.items.length > this.virtualizeAfter || this.utilityService.getActiveBreakpoint() <= Breakpoint.Tablet) {
this.pageOperationsForm.get('accessibilityMode')?.setValue(true);
}

View file

@ -66,10 +66,10 @@
</button>
</div>
<div class="row mt-2">
<p>{{t('help-us-part-1')}}<a href="https://wiki.kavitareader.com/en/guides/managing-your-files" rel="noopener noreferrer" target="_blank" referrerpolicy="no-refer">{{t('help-us-part-2')}}</a> {{t('help-us-part-3')}}</p>
<p>{{t('help-us-part-1')}}<a href="https://wiki.kavitareader.com/en/guides/managing-your-files" rel="noopener noreferrer" target="_blank" referrerpolicy="no-referrer">{{t('help-us-part-2')}}</a> {{t('help-us-part-3')}}</p>
</div>
<div class="row mt-2">
<p>{{t('naming-conventions-part-1')}}<a href="https://wiki.kavitareader.com/en/guides/managing-your-files/scanner#introduction" rel="noopener noreferrer" target="_blank" referrerpolicy="no-refer">{{t('naming-conventions-part-2')}}</a> {{t('naming-conventions-part-3')}}</p>
<p>{{t('naming-conventions-part-1')}}<a href="https://wiki.kavitareader.com/en/guides/managing-your-files/scanner#introduction" rel="noopener noreferrer" target="_blank" referrerpolicy="no-referrer">{{t('naming-conventions-part-2')}}</a> {{t('naming-conventions-part-3')}}</p>
</div>
</ng-template>
</li>

View file

@ -11,7 +11,6 @@ import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
import { LineChartModule } from '@swimlane/ngx-charts';
import { NgIf, NgFor, AsyncPipe } from '@angular/common';
import {TranslocoDirective, TranslocoService} from "@ngneat/transloco";
import {UtcToLocalTimePipe} from "../../../_pipes/utc-to-local-time.pipe";
const options: Intl.DateTimeFormatOptions = { month: "short", day: "numeric" };
@ -32,10 +31,10 @@ export class ReadingActivityComponent implements OnInit {
@Input() isAdmin: boolean = true;
@Input() individualUserMode: boolean = false;
private readonly utcDatePipe = new UtcToLocalTimePipe();
private readonly destroyRef = inject(DestroyRef);
private readonly translocoService = inject(TranslocoService);
private readonly cdRef = inject(ChangeDetectorRef);
//private readonly translocoService = inject(TranslocoService);
private readonly statService = inject(StatisticsService);
private readonly memberService = inject(MemberService);
view: [number, number] = [0, 400];
formGroup: FormGroup = new FormGroup({
@ -45,14 +44,14 @@ export class ReadingActivityComponent implements OnInit {
users$: Observable<Member[]> | undefined;
data$: Observable<Array<PieDataItem>>;
timePeriods = TimePeriods;
mangaFormatPipe = new MangaFormatPipe(this.translocoService);
//mangaFormatPipe = new MangaFormatPipe(this.translocoService);
constructor(private statService: StatisticsService, private memberService: MemberService) {
constructor() {
this.data$ = this.formGroup.valueChanges.pipe(
switchMap(_ => this.statService.getReadCountByDay(this.formGroup.get('users')!.value, this.formGroup.get('days')!.value)),
map(data => {
const gList = data.reduce((formats, entry) => {
const formatTranslated = this.mangaFormatPipe.transform(entry.format);
const formatTranslated = this.statService.mangaFormatPipe.transform(entry.format);
if (!formats[formatTranslated]) {
formats[formatTranslated] = {
name: formatTranslated,
@ -76,7 +75,10 @@ export class ReadingActivityComponent implements OnInit {
}
ngOnInit(): void {
this.users$ = (this.isAdmin ? this.memberService.getMembers() : of([])).pipe(filter(_ => this.isAdmin), takeUntilDestroyed(this.destroyRef), shareReplay());
this.users$ = (this.isAdmin ? this.memberService.getMembers() : of([])).pipe(
filter(_ => this.isAdmin),
takeUntilDestroyed(this.destroyRef),
shareReplay());
this.formGroup.get('users')?.setValue(this.userId, {emitValue: true});
if (!this.isAdmin) {