MME-34 Remove tanstack from recipe service and toggle star mutation.
This commit is contained in:
parent
b7c9e06d05
commit
4a271ecd10
@ -5,11 +5,22 @@
|
||||
<h1>{{ recipe.title }}</h1>
|
||||
<div class="recipe-actions">
|
||||
@if (isLoggedIn()) {
|
||||
<button id="star" matButton="filled" (click)="starMutation.mutate()">
|
||||
<button
|
||||
id="star"
|
||||
[matButton]="recipeView().isStarred ? 'filled' : 'outlined'"
|
||||
(click)="onToggleStar()"
|
||||
>
|
||||
<div id="star-label">
|
||||
<fa-icon [icon]="faStar" />
|
||||
@if (recipeView().isStarred) {
|
||||
<span>Starred</span>
|
||||
} @else {
|
||||
<span>Star</span>
|
||||
}
|
||||
<span id="star-count">{{ recipe.starCount }}</span>
|
||||
@if (togglingStar()) {
|
||||
<app-spinner size="12px"></app-spinner>
|
||||
}
|
||||
</div>
|
||||
</button>
|
||||
} @else {
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { Component, computed, inject, input, OnInit, signal } from '@angular/core';
|
||||
import { Component, computed, inject, input, OnInit, output, signal } from '@angular/core';
|
||||
import { FullRecipeViewWrapper } from '../../../shared/models/Recipe.model';
|
||||
import { injectMutation } from '@tanstack/angular-query-experimental';
|
||||
import { ImageService } from '../../../shared/services/ImageService';
|
||||
import { faEllipsis, faGlobe, faLock, faStar, faUser } from '@fortawesome/free-solid-svg-icons';
|
||||
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
|
||||
@ -23,7 +22,8 @@ import { ToastrService } from 'ngx-toastr';
|
||||
styleUrl: './recipe-page-content.css',
|
||||
})
|
||||
export class RecipePageContent implements OnInit {
|
||||
public recipeView = input.required<FullRecipeViewWrapper>();
|
||||
public readonly recipeView = input.required<FullRecipeViewWrapper>();
|
||||
public readonly requireHotReload = output<void>();
|
||||
|
||||
private readonly imageService = inject(ImageService);
|
||||
private readonly recipeService = inject(RecipeService);
|
||||
@ -42,6 +42,8 @@ export class RecipePageContent implements OnInit {
|
||||
return !!recipe.preparationTime || !!recipe.cookingTime || !!recipe.totalTime;
|
||||
});
|
||||
|
||||
protected readonly togglingStar = signal(false);
|
||||
|
||||
public ngOnInit(): void {
|
||||
const recipe = this.recipeView().recipe;
|
||||
if (recipe.mainImage) {
|
||||
@ -60,10 +62,6 @@ export class RecipePageContent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
protected readonly starMutation = injectMutation(() => ({
|
||||
mutationFn: () => this.recipeService.toggleStar(this.recipeView()),
|
||||
}));
|
||||
|
||||
private readonly dialog = inject(MatDialog);
|
||||
private readonly toastrService = inject(ToastrService);
|
||||
|
||||
@ -90,6 +88,22 @@ export class RecipePageContent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
protected onToggleStar(): void {
|
||||
this.togglingStar.set(true);
|
||||
const recipe = this.recipeView().recipe;
|
||||
this.recipeService.toggleStar(recipe.owner.username, recipe.slug).subscribe({
|
||||
next: () => {
|
||||
this.togglingStar.set(false);
|
||||
this.requireHotReload.emit();
|
||||
},
|
||||
error: (e) => {
|
||||
this.togglingStar.set(false);
|
||||
this.toastrService.error('There was an error toggling the star');
|
||||
console.error(e);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
protected readonly faStar = faStar;
|
||||
protected readonly faUser = faUser;
|
||||
protected readonly faGlobe = faGlobe;
|
||||
|
||||
@ -3,5 +3,5 @@
|
||||
} @else if (loadRecipeError()) {
|
||||
<p>There was an error loading the recipe.</p>
|
||||
} @else if (recipe(); as recipe) {
|
||||
<app-recipe-page-content [recipeView]="recipe"></app-recipe-page-content>
|
||||
<app-recipe-page-content [recipeView]="recipe" (requireHotReload)="onRequireHotReload()"></app-recipe-page-content>
|
||||
}
|
||||
|
||||
@ -35,4 +35,16 @@ export class RecipePage implements OnInit {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
protected onRequireHotReload(): void {
|
||||
this.recipeService.getRecipeView(this.username, this.slug).subscribe({
|
||||
next: (recipe) => {
|
||||
this.recipe.set(recipe);
|
||||
},
|
||||
error: (e) => {
|
||||
this.loadRecipeError.set(e);
|
||||
console.error(e);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
import { inject, Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { lastValueFrom, map, Observable } from 'rxjs';
|
||||
import { map, Observable } from 'rxjs';
|
||||
import { FullRecipeView, FullRecipeViewWrapper, RecipeInfoView } from '../models/Recipe.model';
|
||||
import { AuthService } from './AuthService';
|
||||
import { QueryClient } from '@tanstack/angular-query-experimental';
|
||||
import { RecipeComment } from '../models/RecipeComment.model';
|
||||
import { QueryParams } from '../models/Query.model';
|
||||
import { EndpointService } from './EndpointService';
|
||||
@ -30,8 +28,6 @@ export class RecipeService {
|
||||
public static readonly RecipeCommentProperties = ['id', 'created', 'modified'] as const;
|
||||
|
||||
private readonly http = inject(HttpClient);
|
||||
private readonly authService = inject(AuthService);
|
||||
private readonly queryClient = inject(QueryClient);
|
||||
private readonly endpointService = inject(EndpointService);
|
||||
private readonly imageService = inject(ImageService);
|
||||
|
||||
@ -106,23 +102,8 @@ export class RecipeService {
|
||||
.pipe(map((raw) => this.hydrateFullRecipeViewWrapper(raw)));
|
||||
}
|
||||
|
||||
private getRecipeBaseUrl(recipeView: FullRecipeViewWrapper): string {
|
||||
return this.endpointService.getUrl('recipes', [recipeView.recipe.owner.username, recipeView.recipe.slug]);
|
||||
}
|
||||
|
||||
public async toggleStar(recipeView: FullRecipeViewWrapper): Promise<void> {
|
||||
if (this.authService.accessToken()) {
|
||||
if (recipeView.isStarred) {
|
||||
await lastValueFrom(this.http.delete(this.getRecipeBaseUrl(recipeView) + '/star'));
|
||||
} else {
|
||||
await lastValueFrom(this.http.post(this.getRecipeBaseUrl(recipeView) + '/star', null));
|
||||
}
|
||||
await this.queryClient.invalidateQueries({
|
||||
queryKey: ['recipe', recipeView.recipe.owner.username, recipeView.recipe.slug],
|
||||
});
|
||||
} else {
|
||||
throw new Error('Cannot star a recipe when not logged in.');
|
||||
}
|
||||
public toggleStar(username: string, slug: string): Observable<void> {
|
||||
return this.http.post<void>(this.endpointService.getUrl('recipes', [username, slug, 'star', 'toggle']), null);
|
||||
}
|
||||
|
||||
public getComments(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user