Refactored the way cover images are updated from SignalR to use an explicit event that is sent at a granular level for a given type of entity. (#1046)

Fixed a bad event listener for RefreshMetadata (now removed) to update metadata on Series Detail. Now uses ScanService, which indicates a series has completed a scan.
This commit is contained in:
Joseph Milazzo 2022-02-07 17:44:06 -08:00 committed by GitHub
parent c448a3e493
commit 67ba5e302f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 108 additions and 117 deletions

View file

@ -0,0 +1,7 @@
/**
* Represents a generic cover update event. Id is used based on entityType
*/
export interface CoverUpdateEvent {
id: number;
entityType: 'series' | 'chapter' | 'volume' | 'collection';
}

View file

@ -79,7 +79,7 @@ export class ImageService implements OnDestroy {
* @returns Url with a random parameter attached
*/
randomize(url: string) {
const r = Math.random() * 100 + 1;
const r = Math.round(Math.random() * 100 + 1);
if (url.indexOf('&random') >= 0) {
return url + 1;
}

View file

@ -15,7 +15,6 @@ import { User } from '../_models/user';
export enum EVENTS {
UpdateAvailable = 'UpdateAvailable',
ScanSeries = 'ScanSeries',
RefreshMetadata = 'RefreshMetadata',
RefreshMetadataProgress = 'RefreshMetadataProgress',
SeriesAdded = 'SeriesAdded',
SeriesRemoved = 'SeriesRemoved',
@ -25,7 +24,11 @@ export enum EVENTS {
ScanLibraryError = 'ScanLibraryError',
BackupDatabaseProgress = 'BackupDatabaseProgress',
CleanupProgress = 'CleanupProgress',
DownloadProgress = 'DownloadProgress'
DownloadProgress = 'DownloadProgress',
/**
* A cover is updated
*/
CoverUpdate = 'CoverUpdate'
}
export interface Message<T> {
@ -49,7 +52,6 @@ export class MessageHubService {
public scanSeries: EventEmitter<ScanSeriesEvent> = new EventEmitter<ScanSeriesEvent>();
public scanLibrary: EventEmitter<ProgressEvent> = new EventEmitter<ProgressEvent>(); // TODO: Refactor this name to be generic
public seriesAdded: EventEmitter<SeriesAddedEvent> = new EventEmitter<SeriesAddedEvent>();
public refreshMetadata: EventEmitter<RefreshMetadataEvent> = new EventEmitter<RefreshMetadataEvent>();
isAdmin: boolean = false;
@ -152,12 +154,19 @@ export class MessageHubService {
});
});
this.hubConnection.on(EVENTS.RefreshMetadata, resp => {
// this.hubConnection.on(EVENTS.RefreshMetadata, resp => {
// this.messagesSource.next({
// event: EVENTS.RefreshMetadata,
// payload: resp.body
// });
// this.refreshMetadata.emit(resp.body); // TODO: Remove this
// });
this.hubConnection.on(EVENTS.CoverUpdate, resp => {
this.messagesSource.next({
event: EVENTS.RefreshMetadata,
event: EVENTS.CoverUpdate,
payload: resp.body
});
this.refreshMetadata.emit(resp.body);
});
this.hubConnection.on(EVENTS.UpdateAvailable, resp => {

View file

@ -61,13 +61,7 @@ export class SeriesCardComponent implements OnInit, OnChanges, OnDestroy {
ngOnInit(): void {
if (this.data) {
this.imageUrl = this.imageService.randomize(this.imageService.getSeriesCoverImage(this.data.id));
this.hubService.refreshMetadata.pipe(takeWhile(event => event.libraryId === this.libraryId), takeUntil(this.onDestroy)).subscribe((event: RefreshMetadataEvent) => {
if (this.data.id === event.seriesId) {
this.imageUrl = this.imageService.randomize(this.imageService.getSeriesCoverImage(this.data.id));
}
});
this.imageUrl = this.imageService.getSeriesCoverImage(this.data.id);
}
}

View file

@ -3,6 +3,7 @@ import { Title } from '@angular/platform-browser';
import { Router } from '@angular/router';
import { Subject } from 'rxjs';
import { take, takeUntil } from 'rxjs/operators';
import { RefreshMetadataEvent } from '../_models/events/refresh-metadata-event';
import { SeriesAddedEvent } from '../_models/events/series-added-event';
import { SeriesRemovedEvent } from '../_models/events/series-removed-event';
import { Library } from '../_models/library';

View file

@ -200,13 +200,14 @@ export class SeriesDetailComponent implements OnInit, OnDestroy {
this.toastr.info('This series no longer exists');
this.router.navigateByUrl('/libraries');
}
} else if (event.event === EVENTS.RefreshMetadata) {
const seriesRemovedEvent = event.payload as RefreshMetadataEvent;
if (seriesRemovedEvent.seriesId === this.series.id) {
} else if (event.event === EVENTS.ScanSeries) {
const seriesCoverUpdatedEvent = event.payload as ScanSeriesEvent;
if (seriesCoverUpdatedEvent.seriesId === this.series.id) {
console.log('ScanSeries called')
this.seriesService.getMetadata(this.series.id).pipe(take(1)).subscribe(metadata => {
this.seriesMetadata = metadata;
this.createHTML();
})
});
}
}
});

View file

@ -1,5 +1,8 @@
import { Component, ElementRef, Input, OnChanges, OnInit, Renderer2, SimpleChanges, ViewChild } from '@angular/core';
import { Component, ElementRef, Input, OnChanges, OnDestroy, OnInit, Renderer2, SimpleChanges, ViewChild } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { ImageService } from 'src/app/_services/image.service';
import { EVENTS, MessageHubService } from 'src/app/_services/message-hub.service';
/**
* This is used for images with placeholder fallback.
@ -9,7 +12,7 @@ import { ImageService } from 'src/app/_services/image.service';
templateUrl: './image.component.html',
styleUrls: ['./image.component.scss']
})
export class ImageComponent implements OnChanges {
export class ImageComponent implements OnChanges, OnDestroy {
/**
* Source url to load image
@ -38,7 +41,15 @@ export class ImageComponent implements OnChanges {
@ViewChild('img', {static: true}) imgElem!: ElementRef<HTMLImageElement>;
constructor(public imageService: ImageService, private renderer: Renderer2) { }
private readonly onDestroy = new Subject<void>();
constructor(public imageService: ImageService, private renderer: Renderer2, private hubService: MessageHubService) {
this.hubService.messages$.pipe(takeUntil(this.onDestroy)).subscribe(res => {
if (res.event === EVENTS.CoverUpdate) {
this.imageUrl = this.imageService.randomize(this.imageUrl);
}
});
}
ngOnChanges(changes: SimpleChanges): void {
if (this.width != '') {
@ -60,7 +71,11 @@ export class ImageComponent implements OnChanges {
if (this.borderRadius != '') {
this.renderer.setStyle(this.imgElem.nativeElement, 'border-radius', this.borderRadius);
}
}
ngOnDestroy() {
this.onDestroy.next();
this.onDestroy.complete();
}
}