96 lines
3.3 KiB
TypeScript
96 lines
3.3 KiB
TypeScript
import { inject, Injectable } from '@angular/core';
|
|
import { HttpClient } from '@angular/common/http';
|
|
import { firstValueFrom, lastValueFrom, map } from 'rxjs';
|
|
import { Recipe, RecipeInfoViews, RecipeView } from '../models/Recipe.model';
|
|
import { AuthService } from './AuthService';
|
|
import { QueryClient } from '@tanstack/angular-query-experimental';
|
|
import { RecipeComment, RecipeComments } from '../models/RecipeComment.model';
|
|
import { QueryParams } from '../models/Query.model';
|
|
import { EndpointService } from './EndpointService';
|
|
|
|
@Injectable({
|
|
providedIn: 'root',
|
|
})
|
|
export class RecipeService {
|
|
private readonly http = inject(HttpClient);
|
|
private readonly authService = inject(AuthService);
|
|
private readonly queryClient = inject(QueryClient);
|
|
private readonly endpointService = inject(EndpointService);
|
|
|
|
public getRecipes(): Promise<Recipe[]> {
|
|
return firstValueFrom(
|
|
this.http
|
|
.get<RecipeInfoViews>('http://localhost:8080/recipes')
|
|
.pipe(map((res) => res.content)),
|
|
);
|
|
}
|
|
|
|
public getRecipeView(username: string, slug: string): Promise<RecipeView> {
|
|
return firstValueFrom(
|
|
this.http.get<RecipeView>(`http://localhost:8080/recipes/${username}/${slug}`),
|
|
);
|
|
}
|
|
|
|
private getRecipeUrl(recipeView: RecipeView): string {
|
|
return `http://localhost:8080/recipes/${recipeView.recipe.owner.username}/${recipeView.recipe.slug}`;
|
|
}
|
|
|
|
public async toggleStar(recipeView: RecipeView): Promise<void> {
|
|
if (this.authService.accessToken()) {
|
|
if (recipeView.isStarred) {
|
|
await lastValueFrom(this.http.delete(this.getRecipeUrl(recipeView) + '/star'));
|
|
} else {
|
|
await lastValueFrom(this.http.post(this.getRecipeUrl(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 getComments(
|
|
username: string,
|
|
slug: string,
|
|
queryParams?: QueryParams,
|
|
): Promise<RecipeComments> {
|
|
return firstValueFrom(
|
|
this.http.get<RecipeComments>(
|
|
this.endpointService.getUrl('recipes', [username, slug, 'comments'], queryParams),
|
|
),
|
|
);
|
|
}
|
|
|
|
public async addComment(
|
|
username: string,
|
|
slug: string,
|
|
commentText: string,
|
|
): Promise<RecipeComment> {
|
|
const comment = await firstValueFrom(
|
|
this.http.post<RecipeComment>(
|
|
`http://localhost:8080/recipes/${username}/${slug}/comments`,
|
|
{
|
|
text: commentText,
|
|
},
|
|
),
|
|
);
|
|
await this.queryClient.invalidateQueries({
|
|
queryKey: ['recipeComments', username, slug],
|
|
});
|
|
return comment;
|
|
}
|
|
|
|
public async aiSearch(prompt: string): Promise<Recipe[]> {
|
|
const recipeInfoViews = await firstValueFrom(
|
|
this.http.post<{ results: Recipe[] }>(this.endpointService.getUrl('recipes'), {
|
|
type: 'AI_PROMPT',
|
|
data: {
|
|
prompt,
|
|
},
|
|
}),
|
|
);
|
|
return recipeInfoViews.results;
|
|
}
|
|
}
|