diff --git a/src/app/pages/recipe-page/recipe-page-content/recipe-page-content.html b/src/app/pages/recipe-page/recipe-page-content/recipe-page-content.html index 25400ec..8531ecb 100644 --- a/src/app/pages/recipe-page/recipe-page-content/recipe-page-content.html +++ b/src/app/pages/recipe-page/recipe-page-content/recipe-page-content.html @@ -5,11 +5,22 @@

{{ recipe.title }}

@if (isLoggedIn()) { - } @else { diff --git a/src/app/pages/recipe-page/recipe-page-content/recipe-page-content.ts b/src/app/pages/recipe-page/recipe-page-content/recipe-page-content.ts index c8a3279..c4840a7 100644 --- a/src/app/pages/recipe-page/recipe-page-content/recipe-page-content.ts +++ b/src/app/pages/recipe-page/recipe-page-content/recipe-page-content.ts @@ -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(); + public readonly recipeView = input.required(); + public readonly requireHotReload = output(); 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; diff --git a/src/app/pages/recipe-page/recipe-page.html b/src/app/pages/recipe-page/recipe-page.html index c647f72..49de88b 100644 --- a/src/app/pages/recipe-page/recipe-page.html +++ b/src/app/pages/recipe-page/recipe-page.html @@ -3,5 +3,5 @@ } @else if (loadRecipeError()) {

There was an error loading the recipe.

} @else if (recipe(); as recipe) { - + } diff --git a/src/app/pages/recipe-page/recipe-page.ts b/src/app/pages/recipe-page/recipe-page.ts index 42572a1..58b03a1 100644 --- a/src/app/pages/recipe-page/recipe-page.ts +++ b/src/app/pages/recipe-page/recipe-page.ts @@ -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); + }, + }); + } } diff --git a/src/app/shared/services/RecipeService.ts b/src/app/shared/services/RecipeService.ts index 5e1b633..b4963b9 100644 --- a/src/app/shared/services/RecipeService.ts +++ b/src/app/shared/services/RecipeService.ts @@ -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 { - 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 { + return this.http.post(this.endpointService.getUrl('recipes', [username, slug, 'star', 'toggle']), null); } public getComments(