From 81353e33589faabcf1d6f46d292d74833b3ecbb9 Mon Sep 17 00:00:00 2001 From: YunYouJun Date: Tue, 7 Oct 2025 20:08:49 +0800 Subject: [PATCH] feat: add custom favourite & search --- Dockerfile | 2 +- app/components/tags/DishLabel.vue | 20 ++-- app/composables/store/favorite.ts | 68 +++++++++++++ app/pages/changelog.vue | 40 ++++++++ app/pages/recipes/collect.vue | 12 --- app/pages/recipes/favorites.vue | 143 ++++++++++++++++++++++++++ app/pages/tabs.vue | 5 + app/pages/tabs/home/index.vue | 6 ++ app/pages/tabs/library/index.vue | 160 ++++++++++++++++++++++++++++++ app/pages/tabs/my/index.vue | 6 +- edgeone.json | 2 +- nuxt.config.ts | 2 +- package.json | 2 +- 13 files changed, 443 insertions(+), 25 deletions(-) create mode 100644 app/composables/store/favorite.ts create mode 100644 app/pages/changelog.vue delete mode 100644 app/pages/recipes/collect.vue create mode 100644 app/pages/recipes/favorites.vue create mode 100644 app/pages/tabs/library/index.vue diff --git a/Dockerfile b/Dockerfile index 16cec99..b28b866 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,5 +9,5 @@ COPY . . RUN pnpm install && pnpm run build FROM nginx:stable-alpine -COPY --from=builder /app/.output/public /usr/share/nginx/html +COPY --from=builder /app/dist /usr/share/nginx/html EXPOSE 80 diff --git a/app/components/tags/DishLabel.vue b/app/components/tags/DishLabel.vue index 9d8aa47..ba2c7c3 100644 --- a/app/components/tags/DishLabel.vue +++ b/app/components/tags/DishLabel.vue @@ -8,18 +8,26 @@ const props = defineProps<{ dish: RecipeItem | DbRecipeItem }>() -const dishLabel = computed(() => { - const emojis = getEmojisFromStuff(props.dish.stuff) - return `${props.dish.tags?.includes('杂烩') ? '🍲' : emojis.join(' ')} ${props.dish.name}` +const dishEmojis = computed(() => { + return getEmojisFromStuff(props.dish.stuff) }) diff --git a/app/composables/store/favorite.ts b/app/composables/store/favorite.ts new file mode 100644 index 0000000..f1bc495 --- /dev/null +++ b/app/composables/store/favorite.ts @@ -0,0 +1,68 @@ +import type { RecipeItem } from '~/types' +import type { DbRecipeItem } from '~/utils/db' +import { useStorage } from '@vueuse/core' +import { namespace } from '~/constants' + +export interface FavoriteEntry { id: number, time: number } + +// Store favorite entries with timestamp in localStorage +const rawFavorites = useStorage(`${namespace}:favorites`, [] as any) + +// Migration: if old format number[] exists, convert to FavoriteEntry[] with current time +function ensureFavoriteEntries(): FavoriteEntry[] { + const now = Date.now() + const v = rawFavorites.value + if (Array.isArray(v)) { + if (v.length === 0) + return [] + // old format: array of numbers + if (typeof v[0] === 'number') { + const migrated: FavoriteEntry[] = (v as number[]).map(id => ({ id, time: now })) + rawFavorites.value = migrated + return migrated + } + // new format + if (typeof v[0] === 'object' && v[0] && 'id' in v[0]) + return v as FavoriteEntry[] + } + // fallback + rawFavorites.value = [] + return [] +} + +export const favoriteEntries = computed(() => ensureFavoriteEntries()) +export const favoriteRecipeIds = computed(() => favoriteEntries.value.map(e => e.id)) + +function getId(item: RecipeItem | DbRecipeItem): number | null { + // Only support DbRecipeItem with numeric id for now + return typeof (item as DbRecipeItem).id === 'number' ? (item as DbRecipeItem).id! : null +} + +export function isFavorited(item: RecipeItem | DbRecipeItem) { + const id = getId(item) + if (id == null) + return false + return favoriteRecipeIds.value.includes(id) +} + +export function toggleFavorite(item: RecipeItem | DbRecipeItem) { + const id = getId(item) + if (id == null) + return + const list = ensureFavoriteEntries() + const idx = list.findIndex(e => e.id === id) + if (idx >= 0) + list.splice(idx, 1) + else + list.push({ id, time: Date.now() }) + rawFavorites.value = list +} + +export function getFavoriteTime(item: RecipeItem | DbRecipeItem): number | null { + const id = getId(item) + if (id == null) + return null + const list = ensureFavoriteEntries() + const entry = list.find(e => e.id === id) + return entry?.time ?? null +} diff --git a/app/pages/changelog.vue b/app/pages/changelog.vue new file mode 100644 index 0000000..61c1945 --- /dev/null +++ b/app/pages/changelog.vue @@ -0,0 +1,40 @@ + + + diff --git a/app/pages/recipes/collect.vue b/app/pages/recipes/collect.vue deleted file mode 100644 index a8f2edd..0000000 --- a/app/pages/recipes/collect.vue +++ /dev/null @@ -1,12 +0,0 @@ - - - diff --git a/app/pages/recipes/favorites.vue b/app/pages/recipes/favorites.vue new file mode 100644 index 0000000..248a8bf --- /dev/null +++ b/app/pages/recipes/favorites.vue @@ -0,0 +1,143 @@ + + + diff --git a/app/pages/tabs.vue b/app/pages/tabs.vue index da9eebd..f752cfe 100644 --- a/app/pages/tabs.vue +++ b/app/pages/tabs.vue @@ -42,6 +42,11 @@ onMounted(() => { 做菜 + + + 菜谱 + + 吃什么 diff --git a/app/pages/tabs/home/index.vue b/app/pages/tabs/home/index.vue index 45ac90b..917f875 100644 --- a/app/pages/tabs/home/index.vue +++ b/app/pages/tabs/home/index.vue @@ -30,6 +30,12 @@ const rStore = useRecipeStore() + + + + + + diff --git a/app/pages/tabs/library/index.vue b/app/pages/tabs/library/index.vue new file mode 100644 index 0000000..f218902 --- /dev/null +++ b/app/pages/tabs/library/index.vue @@ -0,0 +1,160 @@ + + + diff --git a/app/pages/tabs/my/index.vue b/app/pages/tabs/my/index.vue index ccec03d..acf06b1 100644 --- a/app/pages/tabs/my/index.vue +++ b/app/pages/tabs/my/index.vue @@ -21,11 +21,11 @@ definePageMeta({ 历史记录 - @@ -47,7 +47,7 @@ definePageMeta({ - + 更新日志 diff --git a/edgeone.json b/edgeone.json index 2d641e5..f620ef1 100644 --- a/edgeone.json +++ b/edgeone.json @@ -1,6 +1,6 @@ { "installCommand": "corepack enable && pnpm install", "buildCommand": "pnpm build", - "outputDirectory": ".output/public", + "outputDirectory": "dist", "nodeVersion": "22.20.0" } diff --git a/nuxt.config.ts b/nuxt.config.ts index f65e038..c528da0 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -125,7 +125,7 @@ export default defineNuxtConfig({ css: { core: true, basic: true, - // utilities: true, + utilities: true, }, config: { mode: 'ios', diff --git a/package.json b/package.json index 43a5cf3..0d9ca58 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "open:android": "cap open android", "docs:dev": "pnpm -C docs run docs:dev", "generate": "nuxt generate", - "start:generate": "npx serve .output/public", + "start:generate": "npx serve dist", "start": "node .output/server/index.mjs", "lint": "eslint .", "postinstall": "nuxt prepare",