Readable Bookmarks (#1228)

* Moved bookmarks to it's own page on side nav and integrated actions.

* Implemented the ability to read bookmarks in the manga reader.

* Removed old bookmark components that aren't needed any longer.

* Removed recently added component as we use all-series instead now

* Removed bookmark tab from card detail

* Fixed scroll to top not working and being missing

* When opening the side nav on mobile with metadata filter already open, collapse the filter.

* When on mobile viewports, when clicking an item from side nav, collapse it afterwards

* Converted most of series detail to use the card detail layout, except storyline which has custom logic

* Fixed unit test
This commit is contained in:
Joseph Milazzo 2022-04-23 13:58:14 -05:00 committed by GitHub
parent 62715a9977
commit 9d6843614d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
48 changed files with 648 additions and 634 deletions

View file

@ -17,10 +17,17 @@ export enum Action {
Info = 5,
RefreshMetadata = 6,
Download = 7,
/**
* @deprecated This is no longer supported. Use the dedicated page instead
*/
Bookmarks = 8,
IncognitoRead = 9,
AddToReadingList = 10,
AddToCollection = 11
AddToCollection = 11,
/**
* Essentially a download, but handled differently. Needed so card bubbles it up for handling
*/
DownloadBookmark = 12
}
export interface ActionItem<T> {
@ -47,6 +54,8 @@ export class ActionFactoryService {
readingListActions: Array<ActionItem<ReadingList>> = [];
bookmarkActions: Array<ActionItem<Series>> = [];
isAdmin = false;
hasDownloadRole = false;
@ -181,6 +190,12 @@ export class ActionFactoryService {
return actions;
}
getBookmarkActions(callback: (action: Action, series: Series) => void) {
const actions = this.bookmarkActions.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;
@ -206,12 +221,6 @@ export class ActionFactoryService {
callback: this.dummyCallback,
requiresAdmin: false
},
{
action: Action.Bookmarks,
title: 'Bookmarks',
callback: this.dummyCallback,
requiresAdmin: false
},
{
action: Action.AddToReadingList,
title: 'Add to Reading List',
@ -294,5 +303,20 @@ export class ActionFactoryService {
requiresAdmin: false
},
];
this.bookmarkActions = [
{
action: Action.DownloadBookmark,
title: 'Download',
callback: this.dummyCallback,
requiresAdmin: false
},
{
action: Action.Delete,
title: 'Clear',
callback: this.dummyCallback,
requiresAdmin: false
},
]
}
}

View file

@ -3,7 +3,6 @@ import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
import { ToastrService } from 'ngx-toastr';
import { Subject } from 'rxjs';
import { take } from 'rxjs/operators';
import { BookmarksModalComponent } from '../cards/_modals/bookmarks-modal/bookmarks-modal.component';
import { BulkAddToCollectionComponent } from '../cards/_modals/bulk-add-to-collection/bulk-add-to-collection.component';
import { AddToListModalComponent, ADD_FLOW } from '../reading-list/_modals/add-to-list-modal/add-to-list-modal.component';
import { EditReadingListModalComponent } from '../reading-list/_modals/edit-reading-list-modal/edit-reading-list-modal.component';
@ -302,25 +301,6 @@ export class ActionService implements OnDestroy {
});
}
openBookmarkModal(series: Series, callback?: SeriesActionCallback) {
if (this.bookmarkModalRef != null) { return; }
this.bookmarkModalRef = this.modalService.open(BookmarksModalComponent, { scrollable: true, size: 'lg' });
this.bookmarkModalRef.componentInstance.series = series;
this.bookmarkModalRef.closed.pipe(take(1)).subscribe(() => {
this.bookmarkModalRef = null;
if (callback) {
callback(series);
}
});
this.bookmarkModalRef.dismissed.pipe(take(1)).subscribe(() => {
this.bookmarkModalRef = null;
if (callback) {
callback(series);
}
});
}
addMultipleToReadingList(seriesId: number, volumes: Array<Volume>, chapters?: Array<Chapter>, callback?: VoidActionCallback) {
if (this.readingListModalRef != null) { return; }
this.readingListModalRef = this.modalService.open(AddToListModalComponent, { scrollable: true, size: 'md' });

View file

@ -4,6 +4,7 @@ import { environment } from 'src/environments/environment';
import { ChapterInfo } from '../manga-reader/_models/chapter-info';
import { UtilityService } from '../shared/_services/utility.service';
import { Chapter } from '../_models/chapter';
import { BookmarkInfo } from '../_models/manga-reader/bookmark-info';
import { PageBookmark } from '../_models/page-bookmark';
import { ProgressBookmark } from '../_models/progress-bookmark';
import { Volume } from '../_models/volume';
@ -48,6 +49,14 @@ export class ReaderService {
return this.httpClient.post(this.baseUrl + 'reader/remove-bookmarks', {seriesId});
}
/**
* Used exclusively for reading multiple bookmarks from a series
* @param seriesId
*/
getBookmarkInfo(seriesId: number) {
return this.httpClient.get<BookmarkInfo>(this.baseUrl + 'reader/bookmark-info?seriesId=' + seriesId);
}
getProgress(chapterId: number) {
return this.httpClient.get<ProgressBookmark>(this.baseUrl + 'reader/get-progress?chapterId=' + chapterId);
}
@ -56,6 +65,10 @@ export class ReaderService {
return this.baseUrl + 'reader/image?chapterId=' + chapterId + '&page=' + page;
}
getBookmarkPageUrl(seriesId: number, apiKey: string, page: number) {
return this.baseUrl + 'reader/bookmark-image?seriesId=' + seriesId + '&page=' + page + '&apiKey=' + encodeURIComponent(apiKey);
}
getChapterInfo(chapterId: number) {
return this.httpClient.get<ChapterInfo>(this.baseUrl + 'reader/chapter-info?chapterId=' + chapterId);
}