diff --git a/README.md b/README.md
index 7e29c02..39663b8 100644
--- a/README.md
+++ b/README.md
@@ -13,6 +13,12 @@
本项目初衷是方便特殊时期隔离在家而材料有限的小伙伴,因此菜谱材料会尽量限制在特定范围内。
+更多可参见 [来做菜 | 关于](https://cook.yunyoujun.cn/about)。
+
+### Features
+
+本项目支持 PWA,使用浏览器打开时,可将其添加到主屏幕以获得近原生 APP 的体验。
+
## 开发
```bash
diff --git a/index.html b/index.html
index 8c77653..dba0e0e 100644
--- a/index.html
+++ b/index.html
@@ -7,7 +7,6 @@
-
隔离食用手册
diff --git a/src/components.d.ts b/src/components.d.ts
index 3bfe0ae..5232b92 100644
--- a/src/components.d.ts
+++ b/src/components.d.ts
@@ -17,6 +17,7 @@ declare module '@vue/runtime-core' {
RouterView: typeof import('vue-router')['RouterView']
StapleTag: typeof import('./components/tags/StapleTag.vue')['default']
Switch: typeof import('./components/Switch.vue')['default']
+ ToggleMode: typeof import('./components/ToggleMode.vue')['default']
ToolTag: typeof import('./components/tags/ToolTag.vue')['default']
VegetableTag: typeof import('./components/tags/VegetableTag.vue')['default']
}
diff --git a/src/components/AboutMe.vue b/src/components/AboutMe.vue
index 8058568..4fb256f 100644
--- a/src/components/AboutMe.vue
+++ b/src/components/AboutMe.vue
@@ -11,8 +11,47 @@ const copyright = {
author: '云游君',
authorUrl: 'https://www.yunyoujun.cn',
}
+
+const links = [
+ {
+ type: 'github',
+ label: 'GitHub: YunYouJun',
+ href: 'https://github.com/YunYouJun',
+ },
+ {
+ type: 'telegram',
+ label: 'Telegram Channel',
+ href: 'https://t.me/elpsycn',
+ },
+ {
+ type: 'weibo',
+ label: '微博:机智的云游君',
+ href: 'http://weibo.com/jizhideyunyoujun',
+ },
+ {
+ type: 'twitter',
+ label: 'Twitter: YunYouJun',
+ href: 'https://twitter.com/YunYouJun',
+ },
+ {
+ type: 'wechat',
+ label: '微信公众号:云游君',
+ href: '/wechat',
+ target: '_self',
+ },
+ {
+ type: 'bilibili',
+ label: '云游君Official',
+ href: 'https://space.bilibili.com/1579790',
+ },
+ {
+ type: 'blog',
+ label: '博客:yunyoujun.cn',
+ href: 'http://www.yunyoujun.cn',
+ },
+]
-
+
diff --git a/src/components/ChooseFood.vue b/src/components/ChooseFood.vue
index 0efffb8..2ba9440 100644
--- a/src/components/ChooseFood.vue
+++ b/src/components/ChooseFood.vue
@@ -1,8 +1,6 @@
-
+
模糊匹配
-
+
精准匹配
diff --git a/src/components/ToggleMode.vue b/src/components/ToggleMode.vue
new file mode 100644
index 0000000..82fd8e9
--- /dev/null
+++ b/src/components/ToggleMode.vue
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
diff --git a/src/composables/animation.ts b/src/composables/animation.ts
new file mode 100644
index 0000000..24d8448
--- /dev/null
+++ b/src/composables/animation.ts
@@ -0,0 +1,42 @@
+import { isClient } from '@vueuse/core'
+import type { Ref } from 'vue'
+
+export function useEmojiAnimation(recipeBtn: Ref) {
+ const { x, y } = usePointer()
+ const { top, left } = useElementBounding(recipeBtn)
+
+ const playAnimation = (emoji: string) => {
+ if (!isClient)
+ return
+
+ // 单个 Vue 组件实现不适合创建多个元素和清除动画
+ const emojiEl = document.createElement('span')
+ emojiEl.style.position = 'fixed'
+ emojiEl.style.left = `${x.value}px`
+ emojiEl.style.top = `${y.value}px`
+ emojiEl.style.zIndex = '10'
+ emojiEl.style.transition = 'left .4s linear, top .4s cubic-bezier(0.5, -0.5, 1, 1)'
+ emojiEl.textContent = emoji
+ document.body.appendChild(emojiEl)
+
+ setTimeout(() => {
+ // 以防万一,按钮位置没检测出来,就不播放动画了
+ if (!top.value || !left.value) {
+ emojiEl.style.top = `${x.value}px`
+ emojiEl.style.left = `${y.value}px`
+ }
+ else {
+ emojiEl.style.top = `${top.value}px`
+ emojiEl.style.left = `${left.value + 12}px`
+ }
+ }, 1)
+
+ emojiEl.ontransitionend = () => {
+ emojiEl.remove()
+ }
+ }
+
+ return {
+ playAnimation,
+ }
+}
diff --git a/src/data/food.ts b/src/data/food.ts
index d8d6030..a5b47f0 100644
--- a/src/data/food.ts
+++ b/src/data/food.ts
@@ -179,7 +179,7 @@ export const tools: StuffItem[] = [
icon: 'i-gg-smart-home-cooker',
},
{
- label: '一口啥都能煮的大锅',
+ label: '一口能炒又能煮的大锅',
name: '一口大锅',
emoji: '',
icon: 'i-mdi-pot-steam-outline',
diff --git a/src/main.ts b/src/main.ts
index 0584e73..74a38b4 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -4,7 +4,6 @@ import { setupLayouts } from 'virtual:generated-layouts'
import App from './App.vue'
import '@unocss/reset/tailwind.css'
-import './styles/main.css'
import './styles/css-vars.scss'
import './styles/index.scss'
import 'uno.css'
diff --git a/src/modules/pwa.ts b/src/modules/pwa.ts
index 319d9fd..c0c9f82 100644
--- a/src/modules/pwa.ts
+++ b/src/modules/pwa.ts
@@ -5,7 +5,7 @@ export const install: UserModule = ({ isClient, router }) => {
if (!isClient)
return
- router.isReady().then(async() => {
+ router.isReady().then(async () => {
const { registerSW } = await import('virtual:pwa-register')
registerSW({ immediate: true })
})
diff --git a/src/modules/toast.ts b/src/modules/toast.ts
new file mode 100644
index 0000000..921c276
--- /dev/null
+++ b/src/modules/toast.ts
@@ -0,0 +1,9 @@
+import Toast from 'vue-toastification'
+import type { UserModule } from '~/types'
+
+import 'vue-toastification/dist/index.css'
+
+export const install: UserModule = ({ app }) => {
+ // add google tag manager, and add GA4 in gtag
+ app.use(Toast)
+}
diff --git a/src/pages/about.md b/src/pages/about.md
index d66a680..15edc62 100644
--- a/src/pages/about.md
+++ b/src/pages/about.md
@@ -11,7 +11,7 @@ title: 关于
> 希望大家吃的开心!
@@ -25,9 +25,6 @@ title: 关于
-- 如果您发现了任何「故障」或希望有某个「新功能」,可前往 [Issues](https://github.com/YunYouJun/cook/issues)。
-- 如果您有任何想要交流的内容,包括但不局限于建议/反馈/分享等,可前往 [Discussions](https://github.com/YunYouJun/cook/issues)。
-
## **致谢**
感谢以下小伙伴为本项目提供的数据支持和 QA !
@@ -39,8 +36,31 @@ title: 关于
- 晴方啾
- 课代表阿伟
-## **友情提示**
+## **关于我**
-点击首页最上方的大锅图标,可以清空所选食材和工具。(本来想当作彩蛋,但是感觉还挺实用的。)
+Hello,我是云游君。
+
+很高兴能在这里与你相遇,也很希望这个网站可以真的帮助到你。
+
+同时,我也以我或许不值一提的脸面保证它会以免费开源的形式维护运营下去。
+
+此外,我也会继续尝试做一些有趣或有用的东西,并分享给大家。
+你也可以在这些地方找到我。
+
+对了,给微信公众号「云游君」发送「做菜」也可以快速找到这个网址。
+
+## [**赞助者**](https://sponsors.yunyoujun.cn)
+
+也非常感谢至今以来的所有赞助者们!
+
+如果觉得我的[小项目们](https://sponsors.yunyoujun.cn/projects)还算有趣的话,要不要考虑[赞助](https://sponsors.yunyoujun.cn/)我?
+
+我会将其公开在[账簿](https://sponsors.yunyoujun.cn/account)中,并投入在周边的服务器、域名、CDN 等费用上。
+
+
+
+
+
+
diff --git a/src/pages/help.md b/src/pages/help.md
new file mode 100644
index 0000000..940cd00
--- /dev/null
+++ b/src/pages/help.md
@@ -0,0 +1,23 @@
+---
+title: 帮助
+---
+
+
+使用帮助
+
+
+- 故障/新功能反馈:[Issues](https://github.com/YunYouJun/cook/issues)
+- 交流/建议/分享:[Discussions](https://github.com/YunYouJun/cook/issues)
+
+## **模式说明**
+
+- 模糊匹配:展示所有含当前选中任意食材的菜谱
+- 精准匹配:展示所有含当前选中所有食材的菜谱
+- 生存模式:展示当前选中食材可制作的所有菜谱
+
+## **友情提示**
+
+- 点击首页最上方的大锅图标,可清空所选食材和工具。
+- 本项目支持 PWA,使用浏览器打开时,可将其添加到主屏幕以获得近原生 APP 的体验。
+
+
diff --git a/src/stores/recipe.ts b/src/stores/recipe.ts
index 94eaa60..bcf743e 100644
--- a/src/stores/recipe.ts
+++ b/src/stores/recipe.ts
@@ -2,9 +2,14 @@ import { acceptHMRUpdate, defineStore } from 'pinia'
const namespace = 'cook'
-export const useRecipeStore = defineStore('recipe', () => {
- const strict = useStorage(`${namespace}:strict`, false)
+/**
+ * survival: 生存模式
+ * strict: 严格
+ * loose: 模糊
+ */
+export type SearchMode = 'survival' | 'loose' | 'strict'
+export const useRecipeStore = defineStore('recipe', () => {
const curStuff = useStorage(`${namespace}:stuff`, new Set())
// const curTools = ref(new Set())
const curTool = useStorage(`${namespace}:tool`, '')
@@ -13,6 +18,8 @@ export const useRecipeStore = defineStore('recipe', () => {
// const selectedTools = computed(() => Array.from(curTools.value))
// const selectedTools = ref('')
+ const curMode = useStorage(`${namespace}:mode`, 'loose')
+
function toggleStuff(name: string) {
if (!curStuff)
return
@@ -33,6 +40,10 @@ export const useRecipeStore = defineStore('recipe', () => {
// curTools.value.add(name)
}
+ function setMode(mode: SearchMode) {
+ curMode.value = mode
+ }
+
/**
* 重置
*/
@@ -43,12 +54,14 @@ export const useRecipeStore = defineStore('recipe', () => {
}
return {
- strict,
curTool,
+ curMode,
selectedStuff,
+
toggleStuff,
toggleTools,
reset,
+ setMode,
}
})
diff --git a/src/styles/animation.scss b/src/styles/animation.scss
new file mode 100644
index 0000000..a3cae15
--- /dev/null
+++ b/src/styles/animation.scss
@@ -0,0 +1,38 @@
+/* we will explain what these classes do next! */
+.v-enter-active,
+.v-leave-active {
+ transition: opacity 0.3s ease;
+}
+
+.v-enter-from,
+.v-leave-to {
+ opacity: 0;
+}
+
+// scrollbar
+::-webkit-scrollbar {
+ width: 8px;
+ height: 8px;
+}
+
+::-webkit-scrollbar-track {
+ border-radius: 2px;
+ background-color: rgba(255, 255, 255, 0.1);
+}
+
+::-webkit-scrollbar-thumb {
+ border-radius: 2px;
+ background-color: rgba(122, 122, 122, 0.3);
+
+ &:window-inactive {
+ background-color: rgba(122, 122, 122, 0.3);
+ }
+
+ &:hover {
+ background-color: rgba(122, 122, 122, 0.7);
+ }
+
+ &:active {
+ background-color: rgba(122, 122, 122, 0.9);
+ }
+}
diff --git a/src/styles/index.scss b/src/styles/index.scss
index 58cc45c..208f00d 100644
--- a/src/styles/index.scss
+++ b/src/styles/index.scss
@@ -1,5 +1,33 @@
+@import './animation.scss';
@import './markdown.scss';
+html,
+body,
+#app {
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+html.dark {
+ background: #121212;
+}
+
+#nprogress {
+ pointer-events: none;
+}
+
+#nprogress .bar {
+ background: rgb(13,148,136);
+ opacity: 0.75;
+ position: fixed;
+ z-index: 1031;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 2px;
+}
+
html {
color: var(--c-text);
background-color: var(--c-bg);
@@ -23,47 +51,11 @@ button {
}
}
+hr {opacity: 0.1;}
+
.tag {
margin: 4px;
padding: 2px 4px;
// border: 1px solid var(--c-text);
}
-/* we will explain what these classes do next! */
-.v-enter-active,
-.v-leave-active {
- transition: opacity 0.3s ease;
-}
-
-.v-enter-from,
-.v-leave-to {
- opacity: 0;
-}
-
-// scrollbar
-::-webkit-scrollbar {
- width: 8px;
- height: 8px;
-}
-
-::-webkit-scrollbar-track {
- border-radius: 2px;
- background-color: rgba(255, 255, 255, 0.1);
-}
-
-::-webkit-scrollbar-thumb {
- border-radius: 2px;
- background-color: rgba(122, 122, 122, 0.3);
-
- &:window-inactive {
- background-color: rgba(122, 122, 122, 0.3);
- }
-
- &:hover {
- background-color: rgba(122, 122, 122, 0.7);
- }
-
- &:active {
- background-color: rgba(122, 122, 122, 0.9);
- }
-}
diff --git a/src/styles/main.css b/src/styles/main.css
deleted file mode 100755
index e5059e3..0000000
--- a/src/styles/main.css
+++ /dev/null
@@ -1,26 +0,0 @@
-html,
-body,
-#app {
- height: 100%;
- margin: 0;
- padding: 0;
-}
-
-html.dark {
- background: #121212;
-}
-
-#nprogress {
- pointer-events: none;
-}
-
-#nprogress .bar {
- background: rgb(13,148,136);
- opacity: 0.75;
- position: fixed;
- z-index: 1031;
- top: 0;
- left: 0;
- width: 100%;
- height: 2px;
-}
diff --git a/vercel.json b/vercel.json
new file mode 100644
index 0000000..448dc52
--- /dev/null
+++ b/vercel.json
@@ -0,0 +1,7 @@
+{
+ "rewrites": [
+ { "source": "/about", "destination": "/index.html" },
+ { "source": "/help", "destination": "/index.html" },
+ { "source": "/wechat", "destination": "/index.html" }
+ ]
+}