mirror of
				https://github.com/mealie-recipes/mealie.git
				synced 2025-11-03 18:53:17 -05:00 
			
		
		
		
	* add groupSlug to most routes * fixed more routing issues * fixed jank and incorrect routes * remove public explore links * remove unused groupSlug and explore routes * nuked explore pages * fixed public toolstore bug * fixed various routes missing group slug * restored public app header menu * fix janky login redirect * 404 recipe API call returns to login * removed unused explore layout * force redirect when using the wrong group slug * fixed dead admin links * removed unused middleware from earlier attempt * 🧹 * improve cookbooks sidebar fixed sidebar link not working fixed sidebar link target hide cookbooks header when there are none * added group slug to user * fix $auth typehints * vastly simplified groupSlug logic * allow logged-in users to view other groups * fixed some edgecases that bypassed isOwnGroup * fixed static home ref * 🧹 * fixed redirect logic * lint warning * removed group slug from group and user pages refactored all components to use route groupSlug or user group slug moved some group pages to recipe pages * fixed some bad types * 🧹 * moved groupSlug routes under /g/groupSlug * move /recipe/ to /r/ * fix backend url generation and metadata injection * moved shopping lists to root/other route fixes * changed shared from /recipes/ to /r/ * fixed 404 redirect not awaiting * removed unused import * fix doc links * fix public recipe setting not affecting public API * fixed backend tests * fix nuxt-generate command --------- Co-authored-by: Hayden <64056131+hay-kot@users.noreply.github.com>
		
			
				
	
	
		
			163 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			163 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import { computed, ComputedRef, ref, Ref, useContext } from "@nuxtjs/composition-api";
 | 
						|
import { UserOut } from "~/lib/api/types/user";
 | 
						|
 | 
						|
export enum PageMode {
 | 
						|
  EDIT = "EDIT",
 | 
						|
  VIEW = "VIEW",
 | 
						|
  COOK = "COOK",
 | 
						|
}
 | 
						|
 | 
						|
export enum EditorMode {
 | 
						|
  JSON = "JSON",
 | 
						|
  FORM = "FORM",
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * PageState encapsulates the state of the recipe page the can be shared across components.
 | 
						|
 * It allows and facilitates the complex state management of the recipe page where many components
 | 
						|
 * need to share and communicate with each other and guarantee consistency.
 | 
						|
 *
 | 
						|
 * **Page Modes**
 | 
						|
 *
 | 
						|
 * are ComputedRefs so we can use a readonly reactive copy of the state of the page.
 | 
						|
 */
 | 
						|
interface PageState {
 | 
						|
  slug: Ref<string>;
 | 
						|
  imageKey: Ref<number>;
 | 
						|
 | 
						|
  pageMode: ComputedRef<PageMode>;
 | 
						|
  editMode: ComputedRef<EditorMode>;
 | 
						|
 | 
						|
  /**
 | 
						|
   * true is the page is in edit mode and the edit mode is in form mode.
 | 
						|
   */
 | 
						|
  isEditForm: ComputedRef<boolean>;
 | 
						|
  /**
 | 
						|
   * true is the page is in edit mode and the edit mode is in json mode.
 | 
						|
   */
 | 
						|
  isEditJSON: ComputedRef<boolean>;
 | 
						|
  /**
 | 
						|
   * true is the page is in view mode.
 | 
						|
   */
 | 
						|
  isEditMode: ComputedRef<boolean>;
 | 
						|
  /**
 | 
						|
   * true is the page is in cook mode.
 | 
						|
   */
 | 
						|
  isCookMode: ComputedRef<boolean>;
 | 
						|
 | 
						|
  setMode: (v: PageMode) => void;
 | 
						|
  setEditMode: (v: EditorMode) => void;
 | 
						|
  toggleEditMode: () => void;
 | 
						|
  toggleCookMode: () => void;
 | 
						|
}
 | 
						|
 | 
						|
type PageRefs = ReturnType<typeof pageRefs>;
 | 
						|
 | 
						|
const memo: Record<string, PageRefs> = {};
 | 
						|
 | 
						|
function pageRefs(slug: string) {
 | 
						|
  return {
 | 
						|
    slugRef: ref(slug),
 | 
						|
    pageModeRef: ref(PageMode.VIEW),
 | 
						|
    editModeRef: ref(EditorMode.FORM),
 | 
						|
    imageKey: ref(1),
 | 
						|
  };
 | 
						|
}
 | 
						|
 | 
						|
function pageState({ slugRef, pageModeRef, editModeRef, imageKey }: PageRefs): PageState {
 | 
						|
  const toggleEditMode = () => {
 | 
						|
    if (editModeRef.value === EditorMode.FORM) {
 | 
						|
      editModeRef.value = EditorMode.JSON;
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    editModeRef.value = EditorMode.FORM;
 | 
						|
  };
 | 
						|
 | 
						|
  const toggleCookMode = () => {
 | 
						|
    if (pageModeRef.value === PageMode.COOK) {
 | 
						|
      pageModeRef.value = PageMode.VIEW;
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    pageModeRef.value = PageMode.COOK;
 | 
						|
  };
 | 
						|
 | 
						|
  const setEditMode = (v: EditorMode) => {
 | 
						|
    editModeRef.value = v;
 | 
						|
  };
 | 
						|
 | 
						|
  const setMode = (toMode: PageMode) => {
 | 
						|
    const fromMode = pageModeRef.value;
 | 
						|
 | 
						|
    if (fromMode === PageMode.EDIT && toMode === PageMode.VIEW) {
 | 
						|
      setEditMode(EditorMode.FORM);
 | 
						|
    }
 | 
						|
 | 
						|
    pageModeRef.value = toMode;
 | 
						|
  };
 | 
						|
 | 
						|
  return {
 | 
						|
    slug: slugRef,
 | 
						|
    pageMode: computed(() => pageModeRef.value),
 | 
						|
    editMode: computed(() => editModeRef.value),
 | 
						|
    imageKey,
 | 
						|
 | 
						|
    toggleEditMode,
 | 
						|
    setMode,
 | 
						|
    setEditMode,
 | 
						|
    toggleCookMode,
 | 
						|
 | 
						|
    isEditForm: computed(() => {
 | 
						|
      return pageModeRef.value === PageMode.EDIT && editModeRef.value === EditorMode.FORM;
 | 
						|
    }),
 | 
						|
    isEditJSON: computed(() => {
 | 
						|
      return pageModeRef.value === PageMode.EDIT && editModeRef.value === EditorMode.JSON;
 | 
						|
    }),
 | 
						|
    isEditMode: computed(() => {
 | 
						|
      return pageModeRef.value === PageMode.EDIT;
 | 
						|
    }),
 | 
						|
    isCookMode: computed(() => {
 | 
						|
      return pageModeRef.value === PageMode.COOK;
 | 
						|
    }),
 | 
						|
  };
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * usePageState provides a common way to interact with shared state across the
 | 
						|
 * RecipePage component.
 | 
						|
 */
 | 
						|
export function usePageState(slug: string): PageState {
 | 
						|
  if (!memo[slug]) {
 | 
						|
    memo[slug] = pageRefs(slug);
 | 
						|
  }
 | 
						|
 | 
						|
  return pageState(memo[slug]);
 | 
						|
}
 | 
						|
 | 
						|
export function clearPageState(slug: string) {
 | 
						|
  delete memo[slug];
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * usePageUser provides a wrapper around $auth that provides a type-safe way to
 | 
						|
 * access the UserOut type from the context. If no user is logged in then an empty
 | 
						|
 * object with all properties set to their zero value is returned.
 | 
						|
 */
 | 
						|
export function usePageUser(): { user: UserOut } {
 | 
						|
  const { $auth } = useContext();
 | 
						|
 | 
						|
  if (!$auth.user) {
 | 
						|
    return {
 | 
						|
      user: {
 | 
						|
        id: "",
 | 
						|
        group: "",
 | 
						|
        groupId: "",
 | 
						|
        groupSlug: "",
 | 
						|
        cacheKey: "",
 | 
						|
        email: "",
 | 
						|
      },
 | 
						|
    };
 | 
						|
  }
 | 
						|
 | 
						|
  return { user: $auth.user };
 | 
						|
}
 |