Co-authored-by: Robbie Davis <robbie@therobbiedavis.com>
This commit is contained in:
Joe Milazzo 2024-08-29 08:46:17 -05:00 committed by GitHub
parent 5bf5558212
commit 79eb98a3bb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
67 changed files with 1398 additions and 1006 deletions

View file

@ -1,109 +1,104 @@
<div class="main-container">
<app-side-nav-companion-bar></app-side-nav-companion-bar>
<ng-container *transloco="let t; read: 'dashboard'">
@if (libraries$ | async; as libraries) {
@if (libraries.length === 0) {
@if (accountService.isAdmin$ | async; as isAdmin) {
<div class="mt-3">
@if (isAdmin) {
<div class="d-flex justify-content-center">
<p>{{t('no-libraries')}} <a routerLink="/settings" [fragment]="SettingsTabId.Libraries">{{t('server-settings-link')}}</a>.</p>
</div>
} @else {
<div class="d-flex justify-content-center">
<p>{{t('not-granted')}}</p>
</div>
}
</div>
}
}
}
@for(stream of streams; track stream.id) {
@switch (stream.streamType) {
@case (StreamType.OnDeck) {
<ng-container [ngTemplateOutlet]="onDeck" [ngTemplateOutletContext]="{ stream: stream }"></ng-container>
}
@case (StreamType.RecentlyUpdated) {
<ng-container [ngTemplateOutlet]="recentlyUpdated" [ngTemplateOutletContext]="{ stream: stream }"></ng-container>
}
@case (StreamType.NewlyAdded) {
<ng-container [ngTemplateOutlet]="newlyUpdated" [ngTemplateOutletContext]="{ stream: stream }"></ng-container>
}
@case (StreamType.SmartFilter) {
<ng-container [ngTemplateOutlet]="smartFilter" [ngTemplateOutletContext]="{ stream: stream }"></ng-container>
}
@case (StreamType.MoreInGenre) {
<ng-container [ngTemplateOutlet]="moreInGenre" [ngTemplateOutletContext]="{ stream: stream }"></ng-container>
<ng-container *transloco="let t; read: 'dashboard'">
@if (libraries$ | async; as libraries) {
@if (libraries.length === 0) {
@if (accountService.isAdmin$ | async; as isAdmin) {
<div class="mt-3">
@if (isAdmin) {
<div class="d-flex justify-content-center">
<p>{{t('no-libraries')}} <a routerLink="/settings" [fragment]="SettingsTabId.Libraries">{{t('server-settings-link')}}</a>.</p>
</div>
} @else {
<div class="d-flex justify-content-center">
<p>{{t('not-granted')}}</p>
</div>
}
</div>
}
}
}
<ng-template #smartFilter let-stream: DashboardStream>
@if(stream.api | async; as data) {
<app-carousel-reel [items]="data" [title]="stream.name" (sectionClick)="handleFilterSectionClick(stream)">
<ng-template #carouselItem let-item>
<app-series-card [series]="item" [libraryId]="item.libraryId"
(reload)="reloadStream(item.id)" (dataChanged)="reloadStream(item.id)"></app-series-card>
</ng-template>
</app-carousel-reel>
@for(stream of streams; track stream.id) {
@switch (stream.streamType) {
@case (StreamType.OnDeck) {
<ng-container [ngTemplateOutlet]="onDeck" [ngTemplateOutletContext]="{ stream: stream }"></ng-container>
}
@case (StreamType.RecentlyUpdated) {
<ng-container [ngTemplateOutlet]="recentlyUpdated" [ngTemplateOutletContext]="{ stream: stream }"></ng-container>
}
@case (StreamType.NewlyAdded) {
<ng-container [ngTemplateOutlet]="newlyUpdated" [ngTemplateOutletContext]="{ stream: stream }"></ng-container>
}
@case (StreamType.SmartFilter) {
<ng-container [ngTemplateOutlet]="smartFilter" [ngTemplateOutletContext]="{ stream: stream }"></ng-container>
}
@case (StreamType.MoreInGenre) {
<ng-container [ngTemplateOutlet]="moreInGenre" [ngTemplateOutletContext]="{ stream: stream }"></ng-container>
}
}
</ng-template>
<ng-template #onDeck let-stream: DashboardStream>
@if(stream.api | async; as data) {
<app-carousel-reel [items]="data" [title]="t('on-deck-title')" (sectionClick)="handleSectionClick(StreamId.OnDeck)">
<ng-template #carouselItem let-item>
<app-series-card [series]="item" [libraryId]="item.libraryId" [isOnDeck]="true"
(reload)="reloadStream(stream.id, true)" (dataChanged)="reloadStream(stream.id)"></app-series-card>
</ng-template>
</app-carousel-reel>
}
</ng-template>
<ng-template #recentlyUpdated let-stream: DashboardStream>
@if(stream.api | async; as data) {
<app-carousel-reel [items]="data" [title]="t('recently-updated-title')" (sectionClick)="handleSectionClick(StreamId.RecentlyUpdatedSeries)">
<ng-template #carouselItem let-item>
<app-card-item [entity]="item" [title]="item.seriesName" [imageUrl]="imageService.getSeriesCoverImage(item.seriesId)"
[suppressArchiveWarning]="true" (clicked)="handleRecentlyAddedChapterClick(item)" [count]="item.count"
[showReadButton]="true" (readClicked)="handleRecentlyAddedChapterRead(item)">
<ng-template #smartFilter let-stream: DashboardStream>
@if(stream.api | async; as data) {
<app-carousel-reel [items]="data" [title]="stream.name" (sectionClick)="handleFilterSectionClick(stream)">
<ng-template #carouselItem let-item>
<app-series-card [series]="item" [libraryId]="item.libraryId"
(reload)="reloadStream(item.id)" (dataChanged)="reloadStream(item.id)"></app-series-card>
</ng-template>
</app-carousel-reel>
}
</ng-template>
</app-card-item>
</ng-template>
</app-carousel-reel>
<ng-template #onDeck let-stream: DashboardStream>
@if(stream.api | async; as data) {
<app-carousel-reel [items]="data" [title]="t('on-deck-title')" (sectionClick)="handleSectionClick(StreamId.OnDeck)">
<ng-template #carouselItem let-item>
<app-series-card [series]="item" [libraryId]="item.libraryId" [isOnDeck]="true"
(reload)="reloadStream(stream.id, true)" (dataChanged)="reloadStream(stream.id)"></app-series-card>
</ng-template>
</app-carousel-reel>
}
</ng-template>
<ng-template #itemOverlay let-item="item">
<span (click)="handleRecentlyAddedChapterClick(item)">
<div>
<i class="fa-solid fa-book" aria-hidden="true"></i>
</div>
</span>
</ng-template>
}
</ng-template>
<ng-template #recentlyUpdated let-stream: DashboardStream>
@if(stream.api | async; as data) {
<app-carousel-reel [items]="data" [title]="t('recently-updated-title')" (sectionClick)="handleSectionClick(StreamId.RecentlyUpdatedSeries)">
<ng-template #carouselItem let-item>
<app-card-item [entity]="item" [title]="item.seriesName" [imageUrl]="imageService.getSeriesCoverImage(item.seriesId)"
[suppressArchiveWarning]="true" [count]="item.count" (clicked)="handleRecentlyAddedChapterClick(item)"
[showReadButton]="true" (readClicked)="handleRecentlyAddedChapterRead(item)"
[linkUrl]="'/library/' + item.libraryId + '/series/' + item.seriesId">
<ng-template #newlyUpdated let-stream: DashboardStream>
@if(stream.api | async; as data) {
<app-carousel-reel [items]="data" [title]="t('recently-added-title')" (sectionClick)="handleSectionClick(StreamId.NewlyAddedSeries)">
<ng-template #carouselItem let-item>
<app-series-card [series]="item" [libraryId]="item.libraryId" (dataChanged)="reloadStream(stream.id)"></app-series-card>
</ng-template>
</app-carousel-reel>
}
</ng-template>
</app-card-item>
</ng-template>
</app-carousel-reel>
}
</ng-template>
<ng-template #moreInGenre let-stream: DashboardStream>
@if(stream.api | async; as data) {
<app-carousel-reel [items]="data" [title]="t('more-in-genre-title', {genre: genre?.title})" (sectionClick)="handleSectionClick(StreamId.MoreInGenre)">
<ng-template #carouselItem let-item>
<app-series-card [series]="item" [libraryId]="item.libraryId" (dataChanged)="reloadStream(stream.id)"></app-series-card>
</ng-template>
</app-carousel-reel>
}
</ng-template>
}
<ng-template #newlyUpdated let-stream: DashboardStream>
@if(stream.api | async; as data) {
<app-carousel-reel [items]="data" [title]="t('recently-added-title')" (sectionClick)="handleSectionClick(StreamId.NewlyAddedSeries)">
<ng-template #carouselItem let-item>
<app-series-card [series]="item" [libraryId]="item.libraryId" (dataChanged)="reloadStream(stream.id)"></app-series-card>
</ng-template>
</app-carousel-reel>
}
</ng-template>
<app-loading [loading]="isLoadingDashboard || (streamCount !== streamsLoaded)"></app-loading>
</ng-container>
<ng-template #moreInGenre let-stream: DashboardStream>
@if(stream.api | async; as data) {
<app-carousel-reel [items]="data" [title]="t('more-in-genre-title', {genre: genre?.title})" (sectionClick)="handleSectionClick(StreamId.MoreInGenre)">
<ng-template #carouselItem let-item>
<app-series-card [series]="item" [libraryId]="item.libraryId" (dataChanged)="reloadStream(stream.id)"></app-series-card>
</ng-template>
</app-carousel-reel>
}
</ng-template>
}
<app-loading [loading]="isLoadingDashboard || (streamCount !== streamsLoaded)"></app-loading>
</ng-container>
</div>

View file

@ -0,0 +1,4 @@
.main-container {
margin-top: 10px;
padding: 0 0 0 10px;
}

View file

@ -1,7 +1,7 @@
import {ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, inject, OnInit} from '@angular/core';
import {Title} from '@angular/platform-browser';
import {Router, RouterLink} from '@angular/router';
import {Observable, of, ReplaySubject, Subject, switchMap} from 'rxjs';
import {Observable, ReplaySubject, Subject, switchMap} from 'rxjs';
import {debounceTime, map, shareReplay, take, tap, throttleTime} from 'rxjs/operators';
import {FilterUtilitiesService} from 'src/app/shared/_services/filter-utilities.service';
import {Library} from 'src/app/_models/library/library';
@ -32,7 +32,6 @@ import {StreamType} from "../../_models/dashboard/stream-type.enum";
import {LoadingComponent} from "../../shared/loading/loading.component";
import {ScrobbleProvider, ScrobblingService} from "../../_services/scrobbling.service";
import {ToastrService} from "ngx-toastr";
import {ServerService} from "../../_services/server.service";
import {SettingsTabId} from "../../sidenav/preference-nav/preference-nav.component";
import {ReaderService} from "../../_services/reader.service";