import { inject, Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { delay, firstValueFrom, map, Observable, of } from 'rxjs'; import { RecipeUploadClientModel } from '../client-models/RecipeUploadClientModel'; import { RecipeUploadStep } from '../client-models/RecipeUploadStep'; import { RecipeDraftViewModel } from '../models/RecipeDraftView.model'; import { EndpointService } from './EndpointService'; import { WithStringDates } from '../util'; import { Recipe } from '../models/Recipe.model'; @Injectable({ providedIn: 'root', }) export class RecipeDraftService { private readonly http = inject(HttpClient); private readonly endpointService = inject(EndpointService); private hydrateView(rawView: WithStringDates): RecipeDraftViewModel { return { ...rawView, created: new Date(rawView.created), modified: rawView.modified ? new Date(rawView.modified) : undefined, lastInference: rawView.lastInference ? { ...rawView.lastInference, inferredAt: new Date(rawView.lastInference.inferredAt), } : undefined, }; } public getInProgressDrafts(): Promise { return firstValueFrom( this.http.get[]>(this.endpointService.getUrl('recipeDrafts')).pipe( map((rawViews) => { return rawViews.map((rawView) => this.hydrateView(rawView)); }), ), ); } public getRecipeUploadClientModel(draftId: string): Observable { return this.http .get>(this.endpointService.getUrl('recipeDrafts', [draftId])) .pipe( map((rawDraft) => { return this.hydrateView(rawDraft); }), map((draft) => { return { draft, inProgressStep: draft.state === 'ENTER_DATA' ? RecipeUploadStep.ENTER_DATA : RecipeUploadStep.INFER, }; }), ); } public createManualDraft(): Promise { return firstValueFrom( this.http .post< WithStringDates >(this.endpointService.getUrl('recipeDrafts', ['manual']), null) .pipe( map((rawDraft) => this.hydrateView(rawDraft)), map((draft) => ({ draft, inProgressStep: RecipeUploadStep.ENTER_DATA, })), ), ); } public updateDraft(id: string, data: { title?: string | null; slug?: string | null; rawText?: string | null; }): Promise { return firstValueFrom( this.http.put>( this.endpointService.getUrl('recipeDrafts', [id]), data ) .pipe( map(rawView => this.hydrateView(rawView)), map(draft => ({ draft, inProgressStep: RecipeUploadStep.ENTER_DATA, })) ) ); } public publish(id: string): Promise { return firstValueFrom( this.http.post( this.endpointService.getUrl('recipeDrafts', [id, 'publish']), null ) ); } public doInference(model: RecipeUploadClientModel): Observable { return of({ inProgressStep: RecipeUploadStep.ENTER_DATA, id: 16, inferredTitle: 'Some recipe', inferredSlug: 'some-recipe', inferredText: 'Some text.', inferredIngredients: [], }).pipe(delay(5_000)); } }