Disable Animations + Lots of bugfixes and Polish (#1561)
* Fixed inputs not showing inline validation due to a missing class * Fixed some checks * Increased the button size on manga reader (develop) * Migrated a type cast to a pure pipe * Sped up the check for if SendTo should render on the menu * Don't allow user to bookmark in bookmark mode * Fixed a bug where Scan Series would skip over Specials due to how new scan loop works. * Fixed scroll to top button persisting when navigating between pages * Edit Series modal now doesn't have a lock field for Series, which can't be locked as it is inheritently locked. Added some validation to ensure Name and SortName are required. * Fixed up some spacing * Fixed actionable menu not opening submenu on mobile * Cleaned up the layout of cover image on series detail * Show all volume or chapters (if only one volume) for cover selection on series * Don't open submenu to right if there is no space * Fixed up cover image not allowing custom saves of existing series/chapter/volume images. Fixed up logging so console output matches log file. * Implemented the ability to turn off css transitions in the UI. * Updated a note internally * Code smells * Added InstallId when pinging the email service to allow throughput tracking
This commit is contained in:
parent
ee7d109170
commit
28ab34c66d
59 changed files with 2103 additions and 444 deletions
|
|
@ -4,6 +4,7 @@ import { Chapter } from '../_models/chapter';
|
|||
import { CollectionTag } from '../_models/collection-tag';
|
||||
import { Device } from '../_models/device/device';
|
||||
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';
|
||||
|
|
@ -92,6 +93,10 @@ export interface ActionItem<T> {
|
|||
callback: (action: ActionItem<T>, data: T) => void;
|
||||
requiresAdmin: boolean;
|
||||
children: Array<ActionItem<T>>;
|
||||
/**
|
||||
* An optional class which applies to an item. ie) danger on a delete action
|
||||
*/
|
||||
class?: string;
|
||||
/**
|
||||
* Indicates that there exists a separate list will be loaded from an API.
|
||||
* Rule: If using this, only one child should exist in children with the Action for dynamicList.
|
||||
|
|
@ -168,7 +173,15 @@ export class ActionFactoryService {
|
|||
|
||||
dummyCallback(action: ActionItem<any>, data: any) {}
|
||||
|
||||
_resetActions() {
|
||||
filterSendToAction(actions: Array<ActionItem<Chapter>>, chapter: Chapter) {
|
||||
if (chapter.files.filter(f => f.format === MangaFormat.EPUB || f.format === MangaFormat.PDF).length !== chapter.files.length) {
|
||||
// Remove Send To as it doesn't apply
|
||||
return actions.filter(item => item.title !== 'Send To');
|
||||
}
|
||||
return actions;
|
||||
}
|
||||
|
||||
private _resetActions() {
|
||||
this.libraryActions = [
|
||||
{
|
||||
action: Action.Scan,
|
||||
|
|
@ -226,6 +239,13 @@ export class ActionFactoryService {
|
|||
requiresAdmin: false,
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
action: Action.Scan,
|
||||
title: 'Scan Series',
|
||||
callback: this.dummyCallback,
|
||||
requiresAdmin: false,
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
action: Action.Submenu,
|
||||
title: 'Add to',
|
||||
|
|
@ -263,18 +283,22 @@ export class ActionFactoryService {
|
|||
],
|
||||
},
|
||||
{
|
||||
action: Action.Scan,
|
||||
title: 'Scan Series',
|
||||
action: Action.Submenu,
|
||||
title: 'Send To',
|
||||
callback: this.dummyCallback,
|
||||
requiresAdmin: false,
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
action: Action.Edit,
|
||||
title: 'Edit',
|
||||
callback: this.dummyCallback,
|
||||
requiresAdmin: true,
|
||||
children: [],
|
||||
children: [
|
||||
{
|
||||
action: Action.SendTo,
|
||||
title: '',
|
||||
callback: this.dummyCallback,
|
||||
requiresAdmin: false,
|
||||
dynamicList: this.deviceService.devices$.pipe(map((devices: Array<Device>) => devices.map(d => {
|
||||
return {'title': d.name, 'data': d};
|
||||
}), shareReplay())),
|
||||
children: []
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
action: Action.Submenu,
|
||||
|
|
@ -301,10 +325,25 @@ export class ActionFactoryService {
|
|||
title: 'Delete',
|
||||
callback: this.dummyCallback,
|
||||
requiresAdmin: true,
|
||||
class: 'danger',
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
action: Action.Download,
|
||||
title: 'Download',
|
||||
callback: this.dummyCallback,
|
||||
requiresAdmin: false,
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
action: Action.Edit,
|
||||
title: 'Edit',
|
||||
callback: this.dummyCallback,
|
||||
requiresAdmin: true,
|
||||
children: [],
|
||||
},
|
||||
];
|
||||
|
||||
this.volumeActions = [
|
||||
|
|
@ -345,15 +384,15 @@ export class ActionFactoryService {
|
|||
]
|
||||
},
|
||||
{
|
||||
action: Action.Edit,
|
||||
title: 'Details',
|
||||
action: Action.Download,
|
||||
title: 'Download',
|
||||
callback: this.dummyCallback,
|
||||
requiresAdmin: false,
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
action: Action.Download,
|
||||
title: 'Download',
|
||||
action: Action.Edit,
|
||||
title: 'Details',
|
||||
callback: this.dummyCallback,
|
||||
requiresAdmin: false,
|
||||
children: [],
|
||||
|
|
@ -397,29 +436,11 @@ export class ActionFactoryService {
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
action: Action.Edit,
|
||||
title: 'Details',
|
||||
callback: this.dummyCallback,
|
||||
requiresAdmin: false,
|
||||
children: [],
|
||||
},
|
||||
// RBS will handle rendering this, so non-admins with download are appicable
|
||||
{
|
||||
action: Action.Download,
|
||||
title: 'Download',
|
||||
callback: this.dummyCallback,
|
||||
requiresAdmin: false,
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
action: Action.Submenu,
|
||||
title: 'Send To',
|
||||
callback: this.dummyCallback,
|
||||
requiresAdmin: false,
|
||||
// dynamicList: this.deviceService.devices$.pipe(map((devices: Array<Device>) => devices.map(d => {
|
||||
// return {'title': d.name, 'data': d};
|
||||
// }), shareReplay())),
|
||||
children: [
|
||||
{
|
||||
action: Action.SendTo,
|
||||
|
|
@ -433,6 +454,21 @@ export class ActionFactoryService {
|
|||
}
|
||||
],
|
||||
},
|
||||
// RBS will handle rendering this, so non-admins with download are appicable
|
||||
{
|
||||
action: Action.Download,
|
||||
title: 'Download',
|
||||
callback: this.dummyCallback,
|
||||
requiresAdmin: false,
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
action: Action.Edit,
|
||||
title: 'Details',
|
||||
callback: this.dummyCallback,
|
||||
requiresAdmin: false,
|
||||
children: [],
|
||||
},
|
||||
];
|
||||
|
||||
this.readingListActions = [
|
||||
|
|
@ -448,6 +484,7 @@ export class ActionFactoryService {
|
|||
title: 'Delete',
|
||||
callback: this.dummyCallback,
|
||||
requiresAdmin: false,
|
||||
class: 'danger',
|
||||
children: [],
|
||||
},
|
||||
];
|
||||
|
|
@ -471,6 +508,7 @@ export class ActionFactoryService {
|
|||
action: Action.Delete,
|
||||
title: 'Clear',
|
||||
callback: this.dummyCallback,
|
||||
class: 'danger',
|
||||
requiresAdmin: false,
|
||||
children: [],
|
||||
},
|
||||
|
|
@ -494,4 +532,5 @@ export class ActionFactoryService {
|
|||
actions.forEach((action) => this.applyCallback(action, callback));
|
||||
return actions;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,11 +3,12 @@ import { HttpClient } from '@angular/common/http';
|
|||
import { Inject, Injectable, OnDestroy, Renderer2, RendererFactory2, SecurityContext } from '@angular/core';
|
||||
import { DomSanitizer } from '@angular/platform-browser';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
import { map, ReplaySubject, Subject, takeUntil, take } from 'rxjs';
|
||||
import { map, ReplaySubject, Subject, takeUntil, take, distinctUntilChanged, Observable } from 'rxjs';
|
||||
import { environment } from 'src/environments/environment';
|
||||
import { ConfirmService } from '../shared/confirm.service';
|
||||
import { NotificationProgressEvent } from '../_models/events/notification-progress-event';
|
||||
import { SiteTheme, ThemeProvider } from '../_models/preferences/site-theme';
|
||||
import { AccountService } from './account.service';
|
||||
import { EVENTS, MessageHubService } from './message-hub.service';
|
||||
|
||||
|
||||
|
|
@ -24,7 +25,7 @@ export class ThemeService implements OnDestroy {
|
|||
|
||||
private themesSource = new ReplaySubject<SiteTheme[]>(1);
|
||||
public themes$ = this.themesSource.asObservable();
|
||||
|
||||
|
||||
/**
|
||||
* Maintain a cache of themes. SignalR will inform us if we need to refresh cache
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue