Kavita/UI/Web/src/app/_services/action-factory.service.ts
Joseph Milazzo 2725e6042b
WebP Support (#581)
* Added trackby so when series scan event comes through, cards can update too

* Added chapter boundary toasts on book reader

* Handle closing the reader when in a reading list

* Somehow the trackby save didn't happen

* Fixed an issue where after opening a chapter info modal, then trying to open another in specials tab it would fail due to a pass by reference issue with our factory.

* When a series update occurs, if we loose specials tab, but we were on it, reselect volumes/chapters tab

* Fixed an issue where older releases would show as available, even though they were already installed.

* Converted tabs within modals to use vertical orientation (except on mobile)

* Implemented webp support. Only Safari does not support this format natively. MacOS users can use an alternative browser.

* Refactored ScannerService and MetadataService to be fully async
2021-09-15 17:25:18 -07:00

290 lines
7.6 KiB
TypeScript

import { Injectable } from '@angular/core';
import { Chapter } from '../_models/chapter';
import { CollectionTag } from '../_models/collection-tag';
import { Library } from '../_models/library';
import { MangaFormat } from '../_models/manga-format';
import { ReadingList } from '../_models/reading-list';
import { Series } from '../_models/series';
import { Volume } from '../_models/volume';
import { AccountService } from './account.service';
export enum Action {
MarkAsRead = 0,
MarkAsUnread = 1,
ScanLibrary = 2,
Delete = 3,
Edit = 4,
Info = 5,
RefreshMetadata = 6,
Download = 7,
Bookmarks = 8,
IncognitoRead = 9,
AddToReadingList = 10
}
export interface ActionItem<T> {
title: string;
action: Action;
callback: (action: Action, data: T) => void;
requiresAdmin: boolean;
}
@Injectable({
providedIn: 'root'
})
export class ActionFactoryService {
libraryActions: Array<ActionItem<Library>> = [];
seriesActions: Array<ActionItem<Series>> = [];
volumeActions: Array<ActionItem<Volume>> = [];
chapterActions: Array<ActionItem<Chapter>> = [];
collectionTagActions: Array<ActionItem<CollectionTag>> = [];
readingListActions: Array<ActionItem<ReadingList>> = [];
isAdmin = false;
hasDownloadRole = false;
constructor(private accountService: AccountService) {
this.accountService.currentUser$.subscribe(user => {
if (user) {
this.isAdmin = this.accountService.hasAdminRole(user);
this.hasDownloadRole = this.accountService.hasDownloadRole(user);
} else {
this._resetActions();
return; // If user is logged out, we don't need to do anything
}
this._resetActions();
if (this.isAdmin) {
this.collectionTagActions.push({
action: Action.Edit,
title: 'Edit',
callback: this.dummyCallback,
requiresAdmin: true
});
this.seriesActions.push({
action: Action.ScanLibrary,
title: 'Scan Series',
callback: this.dummyCallback,
requiresAdmin: true
});
this.seriesActions.push({
action: Action.RefreshMetadata,
title: 'Refresh Metadata',
callback: this.dummyCallback,
requiresAdmin: true
});
this.seriesActions.push({
action: Action.Delete,
title: 'Delete',
callback: this.dummyCallback,
requiresAdmin: true
});
this.seriesActions.push({
action: Action.Edit,
title: 'Edit',
callback: this.dummyCallback,
requiresAdmin: true
});
this.libraryActions.push({
action: Action.ScanLibrary,
title: 'Scan Library',
callback: this.dummyCallback,
requiresAdmin: true
});
this.libraryActions.push({
action: Action.RefreshMetadata,
title: 'Refresh Metadata',
callback: this.dummyCallback,
requiresAdmin: true
});
this.chapterActions.push({
action: Action.Edit,
title: 'Info',
callback: this.dummyCallback,
requiresAdmin: false
});
}
if (this.hasDownloadRole || this.isAdmin) {
this.volumeActions.push({
action: Action.Download,
title: 'Download',
callback: this.dummyCallback,
requiresAdmin: false
});
this.chapterActions.push({
action: Action.Download,
title: 'Download',
callback: this.dummyCallback,
requiresAdmin: false
});
}
});
}
getLibraryActions(callback: (action: Action, library: Library) => void) {
const actions = this.libraryActions.map(a => {return {...a}});
actions.forEach(action => action.callback = callback);
return actions;
}
getSeriesActions(callback: (action: Action, series: Series) => void) {
const actions = this.seriesActions.map(a => {return {...a}});
actions.forEach(action => action.callback = callback);
return actions;
}
getVolumeActions(callback: (action: Action, volume: Volume) => void) {
const actions = this.volumeActions.map(a => {return {...a}});
actions.forEach(action => action.callback = callback);
return actions;
}
getChapterActions(callback: (action: Action, chapter: Chapter) => void) {
const actions = this.chapterActions.map(a => {return {...a}});
actions.forEach(action => action.callback = callback);
return actions;
}
getCollectionTagActions(callback: (action: Action, collectionTag: CollectionTag) => void) {
const actions = this.collectionTagActions.map(a => {return {...a}});
actions.forEach(action => action.callback = callback);
return actions;
}
getReadingListActions(callback: (action: Action, readingList: ReadingList) => void) {
const actions = this.readingListActions.map(a => {return {...a}});
actions.forEach(action => action.callback = callback);
return actions;
}
filterBookmarksForFormat(action: ActionItem<Series>, series: Series) {
if (action.action === Action.Bookmarks && series?.format === MangaFormat.EPUB) return false;
return true;
}
dummyCallback(action: Action, data: any) {}
_resetActions() {
this.libraryActions = [];
this.collectionTagActions = [];
this.seriesActions = [
{
action: Action.MarkAsRead,
title: 'Mark as Read',
callback: this.dummyCallback,
requiresAdmin: false
},
{
action: Action.MarkAsUnread,
title: 'Mark as Unread',
callback: this.dummyCallback,
requiresAdmin: false
},
{
action: Action.Bookmarks,
title: 'Bookmarks',
callback: this.dummyCallback,
requiresAdmin: false
},
{
action: Action.AddToReadingList,
title: 'Add to Reading List',
callback: this.dummyCallback,
requiresAdmin: false
},
];
this.volumeActions = [
{
action: Action.MarkAsRead,
title: 'Mark as Read',
callback: this.dummyCallback,
requiresAdmin: false
},
{
action: Action.MarkAsUnread,
title: 'Mark as Unread',
callback: this.dummyCallback,
requiresAdmin: false
},
{
action: Action.AddToReadingList,
title: 'Add to Reading List',
callback: this.dummyCallback,
requiresAdmin: false
},
{
action: Action.IncognitoRead,
title: 'Read in Incognito',
callback: this.dummyCallback,
requiresAdmin: false
},
{
action: Action.Edit,
title: 'Info',
callback: this.dummyCallback,
requiresAdmin: false
}
];
this.chapterActions = [
{
action: Action.MarkAsRead,
title: 'Mark as Read',
callback: this.dummyCallback,
requiresAdmin: false
},
{
action: Action.MarkAsUnread,
title: 'Mark as Unread',
callback: this.dummyCallback,
requiresAdmin: false
},
{
action: Action.IncognitoRead,
title: 'Read in Incognito',
callback: this.dummyCallback,
requiresAdmin: false
},
{
action: Action.AddToReadingList,
title: 'Add to Reading List',
callback: this.dummyCallback,
requiresAdmin: false
},
];
this.readingListActions = [
{
action: Action.Edit,
title: 'Edit',
callback: this.dummyCallback,
requiresAdmin: false
},
{
action: Action.Delete,
title: 'Delete',
callback: this.dummyCallback,
requiresAdmin: false
},
];
}
}