Unify ChapterRating with Rating

This commit is contained in:
Amelia 2025-04-26 20:20:14 +02:00
parent a9e2937651
commit f29c63c6c4
No known key found for this signature in database
GPG key ID: D6D0ECE365407EAA
34 changed files with 266 additions and 679 deletions

View file

@ -35,20 +35,4 @@ export class ChapterService {
return this.httpClient.get<Array<UserReview>>(this.baseUrl + 'chapter/review?chapterId='+chapterId);
}
updateChapterReview(seriesId: number, chapterId: number, body: string, rating: number) {
return this.httpClient.post<UserReview>(this.baseUrl + 'review/chapter/'+chapterId, {seriesId, rating, body});
}
deleteChapterReview(chapterId: number) {
return this.httpClient.delete(this.baseUrl + 'review/chapter/'+chapterId);
}
overallRating(chapterId: number) {
return this.httpClient.get<Rating>(this.baseUrl + 'rating/overall?chapterId='+chapterId);
}
updateRating(chapterId: number, rating: number) {
return this.httpClient.post(this.baseUrl + 'chapter/update-rating', {chapterId, rating});
}
}

View file

@ -0,0 +1,56 @@
import { Injectable } from '@angular/core';
import {UserReview} from "../_single-module/review-card/user-review";
import {environment} from "../../environments/environment";
import {HttpClient} from "@angular/common/http";
import {Rating} from "../_models/rating";
@Injectable({
providedIn: 'root'
})
export class ReviewService {
private baseUrl = environment.apiUrl;
constructor(private httpClient: HttpClient) { }
getReviews(seriesId: number, chapterId?: number) {
if (chapterId) {
return this.httpClient.get<UserReview[]>(this.baseUrl + `review?chapterId=${chapterId}&seriesId=${seriesId}`);
}
return this.httpClient.get<UserReview[]>(this.baseUrl + 'review?seriesId=' + seriesId);
}
deleteReview(seriesId: number, chapterId?: number) {
if (chapterId) {
return this.httpClient.delete(this.baseUrl + `review?chapterId=${chapterId}&seriesId=${seriesId}`);
}
return this.httpClient.delete(this.baseUrl + 'review?seriesId=' + seriesId);
}
updateReview(seriesId: number, body: string, rating: number, chapterId?: number) {
if (chapterId) {
return this.httpClient.post<UserReview>(this.baseUrl + `review?chapterId=${chapterId}&seriesId=${seriesId}`, {
rating, body
});
}
return this.httpClient.post<UserReview>(this.baseUrl + 'review', {
seriesId, rating, body
});
}
updateRating(seriesId: number, userRating: number, chapterId?: number) {
return this.httpClient.post(this.baseUrl + 'rating', {
seriesId, chapterId, userRating
})
}
overallRating(seriesId: number, chapterId?: number) {
if (chapterId) {
return this.httpClient.get<Rating>(this.baseUrl + `rating/overall?chapterId=${chapterId}&seriesId=${seriesId}`);
}
return this.httpClient.get<Rating>(this.baseUrl + 'rating/overall?seriesId=' + seriesId);
}
}

View file

@ -203,27 +203,9 @@ export class SeriesService {
return this.httpClient.get<SeriesDetail>(this.baseUrl + 'series/series-detail?seriesId=' + seriesId);
}
deleteReview(seriesId: number) {
return this.httpClient.delete(this.baseUrl + 'review?seriesId=' + seriesId);
}
updateReview(seriesId: number, body: string, rating: number) {
return this.httpClient.post<UserReview>(this.baseUrl + 'review', {
seriesId, rating, body
});
}
getReviews(seriesId: number) {
return this.httpClient.get<Array<UserReview>>(this.baseUrl + 'review?seriesId=' + seriesId);
}
getRatings(seriesId: number) {
return this.httpClient.get<Array<Rating>>(this.baseUrl + 'rating?seriesId=' + seriesId);
}
getOverallRating(seriesId: number) {
return this.httpClient.get<Rating>(this.baseUrl + 'rating/overall?seriesId=' + seriesId);
}
removeFromOnDeck(seriesId: number) {
return this.httpClient.post(this.baseUrl + 'series/remove-from-on-deck?seriesId=' + seriesId, {});

View file

@ -10,6 +10,7 @@ import {ChapterService} from "../../_services/chapter.service";
import {of} from "rxjs";
import {NgxStarsModule} from "ngx-stars";
import {ThemeService} from "../../_services/theme.service";
import {ReviewService} from "../../_services/review.service";
export enum ReviewModalCloseAction {
Create,
@ -33,8 +34,8 @@ export interface ReviewModalCloseEvent {
export class ReviewModalComponent implements OnInit {
protected readonly modal = inject(NgbActiveModal);
private readonly reviewService = inject(ReviewService);
private readonly seriesService = inject(SeriesService);
private readonly chapterService = inject(ChapterService);
private readonly cdRef = inject(ChangeDetectorRef);
private readonly confirmService = inject(ConfirmService);
private readonly toastr = inject(ToastrService);
@ -66,14 +67,7 @@ export class ReviewModalComponent implements OnInit {
async delete() {
if (!await this.confirmService.confirm(translate('toasts.delete-review'))) return;
let obs;
if (!this.review.chapterId) {
obs = this.seriesService.deleteReview(this.review.seriesId);
} else {
obs = this.chapterService.deleteChapterReview(this.review.chapterId)
}
obs?.subscribe(() => {
this.reviewService.deleteReview(this.review.seriesId, this.review.chapterId).subscribe(() => {
this.toastr.success(translate('toasts.review-deleted'));
this.modal.close({success: true, review: this.review, action: ReviewModalCloseAction.Delete});
});
@ -85,14 +79,7 @@ export class ReviewModalComponent implements OnInit {
return;
}
let obs;
if (!this.review.chapterId) {
obs = this.seriesService.updateReview(this.review.seriesId, model.reviewBody, this.rating);
} else {
obs = this.chapterService.updateChapterReview(this.review.seriesId, this.review.chapterId, model.reviewBody, this.rating);
}
obs?.subscribe(review => {
this.reviewService.updateReview(this.review.seriesId, model.reviewBody, this.rating, this.review.chapterId).subscribe(review => {
this.modal.close({success: true, review: review, action: ReviewModalCloseAction.Edit});
});

View file

@ -25,6 +25,7 @@ import {AsyncPipe, NgOptimizedImage, NgTemplateOutlet} from "@angular/common";
import {RatingModalComponent} from "../rating-modal/rating-modal.component";
import {ScrobbleProviderNamePipe} from "../../../_pipes/scrobble-provider-name.pipe";
import {ChapterService} from "../../../_services/chapter.service";
import {ReviewService} from "../../../_services/review.service";
@Component({
selector: 'app-external-rating',
@ -38,8 +39,7 @@ import {ChapterService} from "../../../_services/chapter.service";
export class ExternalRatingComponent implements OnInit {
private readonly cdRef = inject(ChangeDetectorRef);
private readonly seriesService = inject(SeriesService);
private readonly chapterService = inject(ChapterService);
private readonly reviewService = inject(ReviewService);
private readonly themeService = inject(ThemeService);
public readonly utilityService = inject(UtilityService);
public readonly destroyRef = inject(DestroyRef);
@ -61,24 +61,13 @@ export class ExternalRatingComponent implements OnInit {
starColor = this.themeService.getCssVariable('--rating-star-color');
ngOnInit() {
let obs;
if (this.chapterId) {
obs = this.chapterService.overallRating(this.chapterId);
} else {
obs = this.seriesService.getOverallRating(this.seriesId);
}
obs?.subscribe(r => this.overallRating = r.averageScore);
this.reviewService.overallRating(this.seriesId, this.chapterId).subscribe(r => {
this.overallRating = r.averageScore;
});
}
updateRating(rating: number) {
let obs;
if (this.chapterId) {
obs = this.chapterService.updateRating(this.chapterId, rating);
} else {
obs = this.seriesService.updateRating(this.seriesId, rating);
}
obs?.subscribe(() => {
this.reviewService.updateRating(this.seriesId, rating, this.chapterId).subscribe(() => {
this.userRating = rating;
this.hasUserRated = true;
this.cdRef.markForCheck();

View file

@ -82,6 +82,7 @@ import {UserReview} from "../_single-module/review-card/user-review";
import {ReviewsComponent} from "../_single-module/reviews/reviews.component";
import {ExternalRatingComponent} from "../series-detail/_components/external-rating/external-rating.component";
import {User} from "../_models/user";
import {ReviewService} from "../_services/review.service";
enum TabID {
@ -182,6 +183,7 @@ export class VolumeDetailComponent implements OnInit {
private readonly readingListService = inject(ReadingListService);
private readonly messageHub = inject(MessageHubService);
private readonly location = inject(Location);
private readonly reviewService = inject(ReviewService);
protected readonly AgeRating = AgeRating;
@ -391,7 +393,6 @@ export class VolumeDetailComponent implements OnInit {
series: this.seriesService.getSeries(this.seriesId),
volume: this.volumeService.getVolumeMetadata(this.volumeId),
libraryType: this.libraryService.getLibraryType(this.libraryId),
reviews: this.volumeService.volumeReviews(this.volumeId),
}).subscribe(results => {
if (results.volume === null) {
@ -402,8 +403,13 @@ export class VolumeDetailComponent implements OnInit {
this.series = results.series;
this.volume = results.volume;
this.libraryType = results.libraryType;
this.userReviews = results.reviews.filter(r => !r.isExternal);
this.plusReviews = results.reviews.filter(r => r.isExternal);
if (this.volume.chapters.length === 1) {
this.reviewService.getReviews(this.seriesId, this.volume.chapters[0].id).subscribe(reviews => {
this.userReviews = reviews.filter(r => !r.isExternal);
this.plusReviews = reviews.filter(r => r.isExternal);
});
}
this.themeService.setColorScape(this.volume!.primaryColor, this.volume!.secondaryColor);