feat: Upgraded Ingredient Parsing Workflow (#6151)

This commit is contained in:
Michael Genson
2025-09-20 23:37:14 -05:00
committed by GitHub
parent 9e5a54477f
commit c929a03b57
15 changed files with 758 additions and 547 deletions

View File

@@ -44,11 +44,16 @@ interface PageState {
* true is the page is in cook mode.
*/
isCookMode: ComputedRef<boolean>;
/**
* true if the recipe is currently being parsed.
*/
isParsing: ComputedRef<boolean>;
setMode: (v: PageMode) => void;
setEditMode: (v: EditorMode) => void;
toggleEditMode: () => void;
toggleCookMode: () => void;
toggleIsParsing: (v?: boolean) => void;
}
type PageRefs = ReturnType<typeof pageRefs>;
@@ -60,11 +65,12 @@ function pageRefs(slug: string) {
slugRef: ref(slug),
pageModeRef: ref(PageMode.VIEW),
editModeRef: ref(EditorMode.FORM),
isParsingRef: ref(false),
imageKey: ref(1),
};
}
function pageState({ slugRef, pageModeRef, editModeRef, imageKey }: PageRefs): PageState {
function pageState({ slugRef, pageModeRef, editModeRef, isParsingRef, imageKey }: PageRefs): PageState {
const { activateNavigationWarning, deactivateNavigationWarning } = useNavigationWarning();
const toggleEditMode = () => {
@@ -83,6 +89,14 @@ function pageState({ slugRef, pageModeRef, editModeRef, imageKey }: PageRefs): P
pageModeRef.value = PageMode.COOK;
};
const toggleIsParsing = (v: boolean | null = null) => {
if (v === null) {
v = !isParsingRef.value;
}
isParsingRef.value = v;
};
const setEditMode = (v: EditorMode) => {
editModeRef.value = v;
};
@@ -113,6 +127,7 @@ function pageState({ slugRef, pageModeRef, editModeRef, imageKey }: PageRefs): P
setMode,
setEditMode,
toggleCookMode,
toggleIsParsing,
isEditForm: computed(() => {
return pageModeRef.value === PageMode.EDIT && editModeRef.value === EditorMode.FORM;
@@ -126,6 +141,9 @@ function pageState({ slugRef, pageModeRef, editModeRef, imageKey }: PageRefs): P
isCookMode: computed(() => {
return pageModeRef.value === PageMode.COOK;
}),
isParsing: computed(() => {
return isParsingRef.value;
}),
};
}

View File

@@ -0,0 +1,85 @@
import { useRecipeCreatePreferences } from "~/composables/use-users/preferences";
export interface UseNewRecipeOptionsProps {
enableImportKeywords?: boolean;
enableStayInEditMode?: boolean;
enableParseRecipe?: boolean;
}
export function useNewRecipeOptions(props: UseNewRecipeOptionsProps = {}) {
const {
enableImportKeywords = true,
enableStayInEditMode = true,
enableParseRecipe = true,
} = props;
const router = useRouter();
const recipeCreatePreferences = useRecipeCreatePreferences();
const importKeywordsAsTags = computed({
get() {
if (!enableImportKeywords) return false;
return recipeCreatePreferences.value.importKeywordsAsTags;
},
set(v: boolean) {
if (!enableImportKeywords) return;
recipeCreatePreferences.value.importKeywordsAsTags = v;
},
});
const stayInEditMode = computed({
get() {
if (!enableStayInEditMode) return false;
return recipeCreatePreferences.value.stayInEditMode;
},
set(v: boolean) {
if (!enableStayInEditMode) return;
recipeCreatePreferences.value.stayInEditMode = v;
},
});
const parseRecipe = computed({
get() {
if (!enableParseRecipe) return false;
return recipeCreatePreferences.value.parseRecipe;
},
set(v: boolean) {
if (!enableParseRecipe) return;
recipeCreatePreferences.value.parseRecipe = v;
},
});
function navigateToRecipe(recipeSlug: string, groupSlug: string, createPagePath: string) {
const editParam = enableStayInEditMode ? stayInEditMode.value : false;
const parseParam = enableParseRecipe ? parseRecipe.value : false;
const queryParams = new URLSearchParams();
if (editParam) {
queryParams.set("edit", "true");
}
if (parseParam) {
queryParams.set("parse", "true");
}
const queryString = queryParams.toString();
const recipeUrl = `/g/${groupSlug}/r/${recipeSlug}${queryString ? `?${queryString}` : ""}`;
// Replace current entry to prevent re-import on back navigation
router.replace(createPagePath).then(() => router.push(recipeUrl));
}
return {
// Computed properties for the checkboxes
importKeywordsAsTags,
stayInEditMode,
parseRecipe,
// Helper functions
navigateToRecipe,
// Props for conditional rendering
enableImportKeywords,
enableStayInEditMode,
enableParseRecipe,
};
}

View File

@@ -59,6 +59,12 @@ export interface UserRecipeFinderPreferences {
includeToolsOnHand: boolean;
}
export interface UserRecipeCreatePreferences {
importKeywordsAsTags: boolean;
stayInEditMode: boolean;
parseRecipe: boolean;
}
export function useUserMealPlanPreferences(): Ref<UserMealPlanPreferences> {
const fromStorage = useLocalStorage(
"meal-planner-preferences",
@@ -200,3 +206,19 @@ export function useRecipeFinderPreferences(): Ref<UserRecipeFinderPreferences> {
return fromStorage;
}
export function useRecipeCreatePreferences(): Ref<UserRecipeCreatePreferences> {
const fromStorage = useLocalStorage(
"recipe-create-preferences",
{
importKeywordsAsTags: false,
stayInEditMode: false,
parseRecipe: true,
},
{ mergeDefaults: true },
// we cast to a Ref because by default it will return an optional type ref
// but since we pass defaults we know all properties are set.
) as unknown as Ref<UserRecipeCreatePreferences>;
return fromStorage;
}