Want to Read List (#1392)

* Implemented a Want To Read list of series for all users, as a way to keep track of what you want to read.

When canceling a bulk action, like Add to Reading list, the selected cards wont de-select.

* Hooked up Remove from Want to Read

* When making bulk selection, allow the user to click on anywhere on the card

* Added no series messaging

* Code cleanup
This commit is contained in:
Joseph Milazzo 2022-07-28 17:18:35 -05:00 committed by GitHub
parent 495c986000
commit f130440bd0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
36 changed files with 2209 additions and 48 deletions

View file

@ -69,6 +69,14 @@ export enum Action {
* Open the reader for entity
*/
Read = 14,
/**
* Add to user's Want to Read List
*/
AddToWantToReadList = 15,
/**
* Remove from user's Want to Read List
*/
RemoveFromWantToReadList = 16,
}
export interface ActionItem<T> {
@ -276,6 +284,12 @@ export class ActionFactoryService {
title: 'Add to Reading List',
callback: this.dummyCallback,
requiresAdmin: false
},
{
action: Action.AddToWantToReadList,
title: 'Add to Want To Read',
callback: this.dummyCallback,
requiresAdmin: false
}
];

View file

@ -13,6 +13,7 @@ import { ReadingList } from '../_models/reading-list';
import { Series } from '../_models/series';
import { Volume } from '../_models/volume';
import { LibraryService } from './library.service';
import { MemberService } from './member.service';
import { ReaderService } from './reader.service';
import { SeriesService } from './series.service';
@ -33,13 +34,12 @@ export type BooleanActionCallback = (result: boolean) => void;
export class ActionService implements OnDestroy {
private readonly onDestroy = new Subject<void>();
private bookmarkModalRef: NgbModalRef | null = null;
private readingListModalRef: NgbModalRef | null = null;
private collectionModalRef: NgbModalRef | null = null;
constructor(private libraryService: LibraryService, private seriesService: SeriesService,
private readerService: ReaderService, private toastr: ToastrService, private modalService: NgbModal,
private confirmService: ConfirmService) { }
private confirmService: ConfirmService, private memberService: MemberService) { }
ngOnDestroy() {
this.onDestroy.next();
@ -342,7 +342,7 @@ export class ActionService implements OnDestroy {
});
}
addMultipleToReadingList(seriesId: number, volumes: Array<Volume>, chapters?: Array<Chapter>, callback?: VoidActionCallback) {
addMultipleToReadingList(seriesId: number, volumes: Array<Volume>, chapters?: Array<Chapter>, callback?: BooleanActionCallback) {
if (this.readingListModalRef != null) { return; }
this.readingListModalRef = this.modalService.open(AddToListModalComponent, { scrollable: true, size: 'md' });
this.readingListModalRef.componentInstance.seriesId = seriesId;
@ -355,18 +355,36 @@ export class ActionService implements OnDestroy {
this.readingListModalRef.closed.pipe(take(1)).subscribe(() => {
this.readingListModalRef = null;
if (callback) {
callback();
callback(true);
}
});
this.readingListModalRef.dismissed.pipe(take(1)).subscribe(() => {
this.readingListModalRef = null;
if (callback) {
callback();
callback(false);
}
});
}
addMultipleSeriesToReadingList(series: Array<Series>, callback?: VoidActionCallback) {
addMultipleSeriesToWantToReadList(seriesIds: Array<number>, callback?: VoidActionCallback) {
this.memberService.addSeriesToWantToRead(seriesIds).subscribe(() => {
this.toastr.success('Series added to Want to Read list');
if (callback) {
callback();
}
});
}
removeMultipleSeriesFromWantToReadList(seriesIds: Array<number>, callback?: VoidActionCallback) {
this.memberService.removeSeriesToWantToRead(seriesIds).subscribe(() => {
this.toastr.success('Series removed from Want to Read list');
if (callback) {
callback();
}
});
}
addMultipleSeriesToReadingList(series: Array<Series>, callback?: BooleanActionCallback) {
if (this.readingListModalRef != null) { return; }
this.readingListModalRef = this.modalService.open(AddToListModalComponent, { scrollable: true, size: 'md' });
this.readingListModalRef.componentInstance.seriesIds = series.map(v => v.id);
@ -377,13 +395,13 @@ export class ActionService implements OnDestroy {
this.readingListModalRef.closed.pipe(take(1)).subscribe(() => {
this.readingListModalRef = null;
if (callback) {
callback();
callback(true);
}
});
this.readingListModalRef.dismissed.pipe(take(1)).subscribe(() => {
this.readingListModalRef = null;
if (callback) {
callback();
callback(false);
}
});
}
@ -394,7 +412,7 @@ export class ActionService implements OnDestroy {
* @param callback
* @returns
*/
addMultipleSeriesToCollectionTag(series: Array<Series>, callback?: VoidActionCallback) {
addMultipleSeriesToCollectionTag(series: Array<Series>, callback?: BooleanActionCallback) {
if (this.collectionModalRef != null) { return; }
this.collectionModalRef = this.modalService.open(BulkAddToCollectionComponent, { scrollable: true, size: 'md', windowClass: 'collection' });
this.collectionModalRef.componentInstance.seriesIds = series.map(v => v.id);
@ -403,13 +421,13 @@ export class ActionService implements OnDestroy {
this.collectionModalRef.closed.pipe(take(1)).subscribe(() => {
this.collectionModalRef = null;
if (callback) {
callback();
callback(true);
}
});
this.collectionModalRef.dismissed.pipe(take(1)).subscribe(() => {
this.collectionModalRef = null;
if (callback) {
callback();
callback(false);
}
});
}

View file

@ -36,8 +36,16 @@ export class MemberService {
return this.httpClient.get<boolean>(this.baseUrl + 'users/has-reading-progress?libraryId=' + librayId);
}
getPendingInvites() {
return this.httpClient.get<Array<Member>>(this.baseUrl + 'users/pending');
}
addSeriesToWantToRead(seriesIds: Array<number>) {
return this.httpClient.post<Array<Member>>(this.baseUrl + 'want-to-read/add-series', {seriesIds});
}
removeSeriesToWantToRead(seriesIds: Array<number>) {
return this.httpClient.post<Array<Member>>(this.baseUrl + 'want-to-read/remove-series', {seriesIds});
}
}

View file

@ -1,6 +1,6 @@
import { HttpClient, HttpParams } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { of } from 'rxjs';
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { environment } from 'src/environments/environment';
import { UtilityService } from '../shared/_services/utility.service';
@ -124,6 +124,18 @@ export class SeriesService {
return this.httpClient.post<SeriesGroup[]>(this.baseUrl + 'series/recently-updated-series', {});
}
getWantToRead(pageNum?: number, itemsPerPage?: number, filter?: SeriesFilter): Observable<PaginatedResult<Series[]>> {
const data = this.createSeriesFilter(filter);
let params = new HttpParams();
params = this.utilityService.addPaginationIfExists(params, pageNum, itemsPerPage);
return this.httpClient.post<Series[]>(this.baseUrl + 'want-to-read/', data, {observe: 'response', params}).pipe(
map(response => {
return this.utilityService.createPaginatedResult(response, new PaginatedResult<Series[]>());
}));
}
getOnDeck(libraryId: number = 0, pageNum?: number, itemsPerPage?: number, filter?: SeriesFilter) {
const data = this.createSeriesFilter(filter);