136 lines
5.1 KiB
TypeScript
136 lines
5.1 KiB
TypeScript
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';
|
|
import { ImageView } from '../models/ImageView.model';
|
|
import { SetImageBody } from '../models/SetImageBody';
|
|
import { ImageService } from './ImageService';
|
|
|
|
@Injectable({
|
|
providedIn: 'root',
|
|
})
|
|
export class RecipeDraftService {
|
|
private readonly http = inject(HttpClient);
|
|
private readonly endpointService = inject(EndpointService);
|
|
private readonly imageService = inject(ImageService);
|
|
|
|
private hydrateView(rawView: WithStringDates<RecipeDraftViewModel>): RecipeDraftViewModel {
|
|
return {
|
|
...rawView,
|
|
created: new Date(rawView.created),
|
|
modified: rawView.modified ? new Date(rawView.modified) : undefined,
|
|
mainImage: rawView.mainImage ? this.imageService.hydrateImageView(rawView.mainImage) : undefined,
|
|
lastInference: rawView.lastInference
|
|
? {
|
|
...rawView.lastInference,
|
|
inferredAt: new Date(rawView.lastInference.inferredAt),
|
|
}
|
|
: undefined,
|
|
};
|
|
}
|
|
|
|
public getInProgressDrafts(): Promise<RecipeDraftViewModel[]> {
|
|
return firstValueFrom(
|
|
this.http.get<WithStringDates<RecipeDraftViewModel>[]>(this.endpointService.getUrl('recipeDrafts')).pipe(
|
|
map((rawViews) => {
|
|
return rawViews.map((rawView) => this.hydrateView(rawView));
|
|
}),
|
|
),
|
|
);
|
|
}
|
|
|
|
public getRecipeUploadClientModel(draftId: string): Observable<RecipeUploadClientModel> {
|
|
return this.http
|
|
.get<WithStringDates<RecipeDraftViewModel>>(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<RecipeUploadClientModel> {
|
|
return firstValueFrom(
|
|
this.http
|
|
.post<
|
|
WithStringDates<RecipeDraftViewModel>
|
|
>(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;
|
|
ingredients?: Array<{
|
|
amount?: string | null;
|
|
name: string;
|
|
notes?: string | null;
|
|
}>;
|
|
mainImage?: ImageView | null;
|
|
rawText?: string | null;
|
|
},
|
|
): Promise<RecipeUploadClientModel> {
|
|
return firstValueFrom(
|
|
this.http
|
|
.put<WithStringDates<RecipeDraftViewModel>>(this.endpointService.getUrl('recipeDrafts', [id]), {
|
|
...data,
|
|
mainImage: data.mainImage
|
|
? ({
|
|
username: data.mainImage.owner.username,
|
|
userFilename: data.mainImage.filename,
|
|
} satisfies SetImageBody)
|
|
: undefined,
|
|
})
|
|
.pipe(
|
|
map((rawView) => this.hydrateView(rawView)),
|
|
map((draft) => ({
|
|
draft,
|
|
inProgressStep: RecipeUploadStep.ENTER_DATA,
|
|
})),
|
|
),
|
|
);
|
|
}
|
|
|
|
public publish(id: string): Promise<Recipe> {
|
|
return firstValueFrom(
|
|
this.http.post<Recipe>(this.endpointService.getUrl('recipeDrafts', [id, 'publish']), null),
|
|
);
|
|
}
|
|
|
|
public deleteDraft(id: string): Promise<void> {
|
|
return firstValueFrom(this.http.delete<void>(this.endpointService.getUrl('recipeDrafts', [id])));
|
|
}
|
|
|
|
public doInference(model: RecipeUploadClientModel): Observable<RecipeUploadClientModel> {
|
|
return of({
|
|
inProgressStep: RecipeUploadStep.ENTER_DATA,
|
|
id: 16,
|
|
inferredTitle: 'Some recipe',
|
|
inferredSlug: 'some-recipe',
|
|
inferredText: 'Some text.',
|
|
inferredIngredients: [],
|
|
}).pipe(delay(5_000));
|
|
}
|
|
}
|