From 15fb3dc4c8206e197a974becd7bb546a75f34403 Mon Sep 17 00:00:00 2001 From: Rizumu Ayaka Date: Mon, 14 Oct 2024 15:20:59 +0800 Subject: [PATCH 1/4] feat(i18n): share via QR --- app/app.css | 36 +++++++++++++++++ app/components/{atomic => qifi}/QifiCode.vue | 42 ++++++++++++-------- app/components/qifi/QifiHowToScan.en.md | 11 +++++ app/components/qifi/QifiHowToScan.zh-Hans.md | 11 +++++ app/components/qifi/QifiHowToScan.zh-Hant.md | 11 +++++ app/locales/en.json | 6 +++ app/locales/zh-Hans.json | 6 +++ app/locales/zh-Hant.json | 6 +++ app/shims.d.ts | 6 +++ nuxt.config.ts | 11 +++++ package.json | 1 + pnpm-lock.yaml | 10 +++++ 12 files changed, 140 insertions(+), 17 deletions(-) rename app/components/{atomic => qifi}/QifiCode.vue (68%) create mode 100644 app/components/qifi/QifiHowToScan.en.md create mode 100644 app/components/qifi/QifiHowToScan.zh-Hans.md create mode 100644 app/components/qifi/QifiHowToScan.zh-Hant.md create mode 100644 app/shims.d.ts diff --git a/app/app.css b/app/app.css index 65fb8613..e5e8411e 100644 --- a/app/app.css +++ b/app/app.css @@ -100,3 +100,39 @@ html.dark { width: 0 !important; height: 0 !important; } + +.markdown-magic-link { + display: inline-flex; + align-items: center; + background: rgb(156 163 175 / 0.3) ; + transform: translateY(3px); + line-height: 100%; + color: var(--fg-light) !important; + --uno: gap-1 transition rounded px1.5 py1 important-border-0 font-condensed; +} + +.markdown-magic-link:hover { + background: rgb(156 163 175 / 0.4); + color: var(--fg) !important; +} + +.markdown-magic-link-image { + display: inline-block; + height: 1.1em; + width: 1.1em; + background-size: cover; + background-repeat: no-repeat; + background-position: center; + border-radius: 2px; +} + +.markdown-magic-link.markdown-magic-link-github-at { + transform: translateY(6px); + --uno: pl-0 py-0 pr2 text-sm gap-1.2 rounded-full; +} + +.markdown-magic-link.markdown-magic-link-github-at .markdown-magic-link-image { + height: 1.6em; + width: 1.6em; + border-radius: 50%; +} diff --git a/app/components/atomic/QifiCode.vue b/app/components/qifi/QifiCode.vue similarity index 68% rename from app/components/atomic/QifiCode.vue rename to app/components/qifi/QifiCode.vue index fcb11ca5..1ff06fea 100644 --- a/app/components/atomic/QifiCode.vue +++ b/app/components/qifi/QifiCode.vue @@ -1,5 +1,9 @@ diff --git a/app/components/qifi/QifiHowToScan.en.md b/app/components/qifi/QifiHowToScan.en.md new file mode 100644 index 00000000..c21a47b8 --- /dev/null +++ b/app/components/qifi/QifiHowToScan.en.md @@ -0,0 +1,11 @@ +
+ +Due to the transfer size limitation of a single QR Code, we use a dynamic QR Code called {QiFi}. + +After scanning with a camera app, it will direct you to the QRS scanner page to continue scanning the remaining information. You may need camera permissions during this process; rest assured, the webpage code is open source and does not save camera footage. Once data reception is complete, it will automatically return to maru to open the corresponding song. + +Some camera apps may not scan dynamic QR codes properly. You can click , which will help you scan. + +You can also manually enter the scanning webpage address: qrss.netlify.app + +
diff --git a/app/components/qifi/QifiHowToScan.zh-Hans.md b/app/components/qifi/QifiHowToScan.zh-Hans.md new file mode 100644 index 00000000..b707e8f7 --- /dev/null +++ b/app/components/qifi/QifiHowToScan.zh-Hans.md @@ -0,0 +1,11 @@ +
+ +由于单个 QR Code 的传输大小限制,我们采用了一种名为 {QiFi} 的 动态 QR Code。 + +使用相机 App 扫描后,将导向 QRS 扫描器页面,继续扫描传输剩余信息。过程中可能会需要相机权限,请放心,网页代码开源且不保存相机画面。数据接收完成后,会自动返回 maru 打开对应歌曲。 + +部分相机 APP 会因为动态变化的二维码而无法正常扫描,您可以点击 ,这会有助于您扫描。 + +您也可以手动输入扫描网页的地址:qrss.netlify.app + +
diff --git a/app/components/qifi/QifiHowToScan.zh-Hant.md b/app/components/qifi/QifiHowToScan.zh-Hant.md new file mode 100644 index 00000000..b633f484 --- /dev/null +++ b/app/components/qifi/QifiHowToScan.zh-Hant.md @@ -0,0 +1,11 @@ +
+ +由於單個 QR Code 的傳輸大小限制,我們採用了名為 {QiFi} 的 動態 QR Code。 + +使用相機 App 掃描後,將導向 QRS 掃描器頁面,繼續掃描傳輸剩餘信息。過程中可能會需要相機權限,請放心,網頁代碼開源且不保存相機畫面。數據接收完成後,會自動回到 maru 打開對應歌曲。 + +部分相機 APP 會因為動態變化的二維碼而無法正常掃描,也你可以點擊 ,這會有助於你掃描。 + +你也可以手動輸入掃描網頁的地址:qrss.netlify.app + +
diff --git a/app/locales/en.json b/app/locales/en.json index b89400f1..e684417d 100644 --- a/app/locales/en.json +++ b/app/locales/en.json @@ -167,5 +167,11 @@ "space": "Space", "up": "Up", "table": "Shortcut Table" + }, + "share": { + "qifi": { + "pausePlayback": "Pause 3s", + "close": "Close" + } } } diff --git a/app/locales/zh-Hans.json b/app/locales/zh-Hans.json index 3ae9edf1..3a77652a 100644 --- a/app/locales/zh-Hans.json +++ b/app/locales/zh-Hans.json @@ -167,5 +167,11 @@ "space": "空白键", "up": "上", "table": "快捷键列表" + }, + "share": { + "qifi": { + "pausePlayback": "暂停 3 秒", + "close": "关闭" + } } } diff --git a/app/locales/zh-Hant.json b/app/locales/zh-Hant.json index 9e4637e0..592b3a82 100644 --- a/app/locales/zh-Hant.json +++ b/app/locales/zh-Hant.json @@ -168,5 +168,11 @@ "right": "右", "down": "下", "table": "快捷鍵列表" + }, + "share": { + "qifi": { + "pausePlayback": "暫停 3 秒", + "close": "關閉" + } } } diff --git a/app/shims.d.ts b/app/shims.d.ts new file mode 100644 index 00000000..a6311ec3 --- /dev/null +++ b/app/shims.d.ts @@ -0,0 +1,6 @@ +declare module '*.md' { + import type { DefineComponent } from 'vue' + + const component: DefineComponent + export default component +} diff --git a/nuxt.config.ts b/nuxt.config.ts index c4dd33ae..ec83c31a 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -1,5 +1,6 @@ import { fileURLToPath } from 'node:url' import { execaSync } from 'execa' +import MarkdownItMagicLink from 'markdown-it-magic-link' import { appDescription, appName } from './app/constants' import { dependencies } from './package.json' @@ -24,6 +25,16 @@ export default defineNuxtConfig({ dark: 'vitesse-dark', }, }, + markdownItSetup(md) { + md.use(MarkdownItMagicLink, { + linksMap: { + QiFi: 'https://github.com/qifi-dev/qrs', + }, + imageOverrides: [ + ['https://github.com/qifi-dev/qrs', 'https://cdn.jsdelivr.net/gh/qifi-dev/qrs/public/logo.svg'], + ], + }) + }, }, runtimeConfig: { diff --git a/package.json b/package.json index e868db8b..b4d14681 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,7 @@ "esno": "^4.8.0", "execa": "^9.4.0", "fast-glob": "^3.3.2", + "markdown-it-magic-link": "^0.1.4", "nuxt": "^3.13.2", "nuxt-compile-markdown": "^0.1.1", "shiki": "^1.22.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4385540b..cdaf294e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -132,6 +132,9 @@ importers: fast-glob: specifier: ^3.3.2 version: 3.3.2 + markdown-it-magic-link: + specifier: ^0.1.4 + version: 0.1.4 nuxt: specifier: ^3.13.2 version: 3.13.2(@parcel/watcher@2.4.1)(@types/node@22.5.0)(encoding@0.1.13)(eslint@9.12.0(jiti@2.0.0))(idb-keyval@6.2.1)(ioredis@5.4.1)(magicast@0.3.5)(optionator@0.9.4)(rollup@3.29.5)(terser@5.31.6)(typescript@5.6.3)(vite@5.4.6(@types/node@22.5.0)(terser@5.31.6))(vue-tsc@2.1.6(typescript@5.6.3))(webpack-sources@3.2.3) @@ -3779,6 +3782,9 @@ packages: resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} engines: {node: '>=8'} + markdown-it-magic-link@0.1.4: + resolution: {integrity: sha512-Y0CgJVtqdGGeWJ+8bN+eBEr2q2ugmf5AMJWSbxBpmGcqARbKBB62biB7LwkoxtbddlmVkACYBFyjlMP/SzYlzg==} + markdown-it-mdc@0.2.5: resolution: {integrity: sha512-7nj5/efQlZX+OAVw5nAYEH6kXtiNmRoMf5i7WDCeFRLXl5POFQCb+9s6qIsaBHnDLVWpZC3UTIPoVStbR9+24A==} peerDependencies: @@ -9923,6 +9929,10 @@ snapshots: dependencies: semver: 6.3.1 + markdown-it-magic-link@0.1.4: + dependencies: + markdown-it: 14.1.0 + markdown-it-mdc@0.2.5(@types/markdown-it@14.1.2)(markdown-it@14.1.0): dependencies: '@types/markdown-it': 14.1.2 From 6ec07a8ffcff488ba145f7d715ba20d1f5ed7579 Mon Sep 17 00:00:00 2001 From: Rizumu Ayaka Date: Mon, 14 Oct 2024 15:24:12 +0800 Subject: [PATCH 2/4] chore: fix lint --- app/app.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/app.css b/app/app.css index e5e8411e..b491caf0 100644 --- a/app/app.css +++ b/app/app.css @@ -104,7 +104,7 @@ html.dark { .markdown-magic-link { display: inline-flex; align-items: center; - background: rgb(156 163 175 / 0.3) ; + background: rgb(156 163 175 / 0.3); transform: translateY(3px); line-height: 100%; color: var(--fg-light) !important; From 1926c47b49e6d7196890d65c880804e9825baa2c Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Mon, 14 Oct 2024 18:30:54 +0800 Subject: [PATCH 3/4] chore: update i18n --- app/components/qifi/QifiCode.vue | 4 ++-- app/locales/en.json | 10 +++------- app/locales/zh-Hans.json | 10 +++------- app/locales/zh-Hant.json | 10 +++------- 4 files changed, 11 insertions(+), 23 deletions(-) diff --git a/app/components/qifi/QifiCode.vue b/app/components/qifi/QifiCode.vue index 1ff06fea..b857c934 100644 --- a/app/components/qifi/QifiCode.vue +++ b/app/components/qifi/QifiCode.vue @@ -102,10 +102,10 @@ const { t } = useI18n({ />
- {{ $t('share.qifi.pausePlayback') }} + {{ $t('actions.pauseQifi', 3) }} - {{ $t('share.qifi.close') }} + {{ $t('actions.close') }}
diff --git a/app/locales/en.json b/app/locales/en.json index e684417d..5574546e 100644 --- a/app/locales/en.json +++ b/app/locales/en.json @@ -128,7 +128,9 @@ "downloadAllLyrics": "Download All Lyrics", "exportSelected": "Export Selected", "removeSelected": "Remove Selected", - "shareViaQR": "Share via QR Code" + "shareViaQR": "Share via QR Code", + "close": "Close", + "pauseQifi": "Pause {0}s" }, "messages": { "wip": "The website is under development, and many features are not yet complete. Welcome to report issues via Discord", @@ -167,11 +169,5 @@ "space": "Space", "up": "Up", "table": "Shortcut Table" - }, - "share": { - "qifi": { - "pausePlayback": "Pause 3s", - "close": "Close" - } } } diff --git a/app/locales/zh-Hans.json b/app/locales/zh-Hans.json index 3a77652a..eaf5c613 100644 --- a/app/locales/zh-Hans.json +++ b/app/locales/zh-Hans.json @@ -128,7 +128,9 @@ "downloadAllLyrics": "下载所有歌词文件", "exportSelected": "导出所选", "removeSelected": "删除所选", - "shareViaQR": "二维码分享" + "shareViaQR": "二维码分享", + "close": "关闭", + "pauseQifi": "暂停 {0} 秒" }, "messages": { "wip": "网站开发中、许多功能尚未完善。欢迎通过 Discord 回报问题", @@ -167,11 +169,5 @@ "space": "空白键", "up": "上", "table": "快捷键列表" - }, - "share": { - "qifi": { - "pausePlayback": "暂停 3 秒", - "close": "关闭" - } } } diff --git a/app/locales/zh-Hant.json b/app/locales/zh-Hant.json index 592b3a82..aba575ce 100644 --- a/app/locales/zh-Hant.json +++ b/app/locales/zh-Hant.json @@ -134,7 +134,9 @@ "downloadAllLyrics": "下載所有歌詞檔案", "exportSelected": "匯出所選", "removeSelected": "刪除所選", - "shareViaQR": "QR 分享" + "shareViaQR": "QR 分享", + "close": "關閉", + "pauseQifi": "暫停 {0} 秒" }, "appname": "二重丸", "errors": { @@ -168,11 +170,5 @@ "right": "右", "down": "下", "table": "快捷鍵列表" - }, - "share": { - "qifi": { - "pausePlayback": "暫停 3 秒", - "close": "關閉" - } } } From 28d3b2944843b2bc6f2a2bd3e528cd403bb8bedd Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Mon, 14 Oct 2024 18:51:41 +0800 Subject: [PATCH 4/4] feat: improve i18n handling --- app/app.css | 38 ++++++++++++++++++++ app/components/qifi/QifiCode.vue | 28 +++------------ app/components/qifi/QifiHowToScan.en.md | 8 ++--- app/components/qifi/QifiHowToScan.ts | 22 ++++++++++++ app/components/qifi/QifiHowToScan.zh-Hans.md | 10 ++---- app/components/qifi/QifiHowToScan.zh-Hant.md | 8 ++--- app/layouts/content.vue | 38 -------------------- 7 files changed, 72 insertions(+), 80 deletions(-) create mode 100644 app/components/qifi/QifiHowToScan.ts diff --git a/app/app.css b/app/app.css index b491caf0..641de3be 100644 --- a/app/app.css +++ b/app/app.css @@ -101,6 +101,44 @@ html.dark { height: 0 !important; } +/* Markdown */ + +.markdown-content a { + --uno: 'op75 hover:op100 hover:underline'; +} + +.markdown-content h1 { + --uno: font-bold text-2xl mb5; +} + +.markdown-content h2 { + --uno: text-xl mb5 op75 border-b border-base py2; +} + +.markdown-content p { + --uno: mb5; +} + +.markdown-content pre { + --uno: mb5; +} + +.markdown-content pre { + --uno: px3 py2 bg-gray-100 rounded max-w-200 of-auto text-sm; +} + +.markdown-content .shiki { + background: #f7f7f7 !important; +} + +.dark .markdown-content .shiki { + background: var(--shiki-dark-bg) !important; +} + +.dark .markdown-content .shiki span { + color: var(--shiki-dark) !important; +} + .markdown-magic-link { display: inline-flex; align-items: center; diff --git a/app/components/qifi/QifiCode.vue b/app/components/qifi/QifiCode.vue index b857c934..6329d174 100644 --- a/app/components/qifi/QifiCode.vue +++ b/app/components/qifi/QifiCode.vue @@ -1,9 +1,6 @@ diff --git a/app/components/qifi/QifiHowToScan.en.md b/app/components/qifi/QifiHowToScan.en.md index c21a47b8..a726b06e 100644 --- a/app/components/qifi/QifiHowToScan.en.md +++ b/app/components/qifi/QifiHowToScan.en.md @@ -1,11 +1,7 @@ -
- Due to the transfer size limitation of a single QR Code, we use a dynamic QR Code called {QiFi}. After scanning with a camera app, it will direct you to the QRS scanner page to continue scanning the remaining information. You may need camera permissions during this process; rest assured, the webpage code is open source and does not save camera footage. Once data reception is complete, it will automatically return to maru to open the corresponding song. -Some camera apps may not scan dynamic QR codes properly. You can click , which will help you scan. - -You can also manually enter the scanning webpage address: qrss.netlify.app +Some camera apps may not scan dynamic QR codes properly. You can click to pause, which might help you scan. -
+You can also manually enter the scanning webpage address: [qrss.netlify.app](https://qrss.netlify.app) diff --git a/app/components/qifi/QifiHowToScan.ts b/app/components/qifi/QifiHowToScan.ts new file mode 100644 index 00000000..2764c8b7 --- /dev/null +++ b/app/components/qifi/QifiHowToScan.ts @@ -0,0 +1,22 @@ +export default defineComponent({ + setup() { + const { locale } = useI18n() + const components = Object.fromEntries( + Array.from(Object.entries(import.meta.glob('./QifiHowToScan.*.md')) + .map(([key, value]) => [key.match(/\.([\w\-]+)\.\w+$/)![1], value]), + ), + ) + + // const usingFallback = computed(() => !components[locale.value]) + const component = shallowRef() + + watch(locale, async () => { + const mod = await (components[locale.value] || components['zh-Hant'])() + component.value = mod.default + }, { + immediate: true, + }) + + return () => component.value ? h(component.value) : null + }, +}) diff --git a/app/components/qifi/QifiHowToScan.zh-Hans.md b/app/components/qifi/QifiHowToScan.zh-Hans.md index b707e8f7..3e835f45 100644 --- a/app/components/qifi/QifiHowToScan.zh-Hans.md +++ b/app/components/qifi/QifiHowToScan.zh-Hans.md @@ -1,11 +1,7 @@ -
- -由于单个 QR Code 的传输大小限制,我们采用了一种名为 {QiFi} 的 动态 QR Code。 +由于单个二维码的传输大小限制,我们采用了一种名为 {QiFi} 的 动态二维码。 使用相机 App 扫描后,将导向 QRS 扫描器页面,继续扫描传输剩余信息。过程中可能会需要相机权限,请放心,网页代码开源且不保存相机画面。数据接收完成后,会自动返回 maru 打开对应歌曲。 -部分相机 APP 会因为动态变化的二维码而无法正常扫描,您可以点击 ,这会有助于您扫描。 - -您也可以手动输入扫描网页的地址:qrss.netlify.app +部分相机 APP 会因为动态变化的二维码而无法正常扫描,您可以点击 暫停,这会有助于您扫描。 -
+您也可以手动输入扫描网页的地址: [qrss.netlify.app](https://qrss.netlify.app) diff --git a/app/components/qifi/QifiHowToScan.zh-Hant.md b/app/components/qifi/QifiHowToScan.zh-Hant.md index b633f484..b8c0ce00 100644 --- a/app/components/qifi/QifiHowToScan.zh-Hant.md +++ b/app/components/qifi/QifiHowToScan.zh-Hant.md @@ -1,11 +1,7 @@ -
- 由於單個 QR Code 的傳輸大小限制,我們採用了名為 {QiFi} 的 動態 QR Code。 使用相機 App 掃描後,將導向 QRS 掃描器頁面,繼續掃描傳輸剩餘信息。過程中可能會需要相機權限,請放心,網頁代碼開源且不保存相機畫面。數據接收完成後,會自動回到 maru 打開對應歌曲。 -部分相機 APP 會因為動態變化的二維碼而無法正常掃描,也你可以點擊 ,這會有助於你掃描。 - -你也可以手動輸入掃描網頁的地址:qrss.netlify.app +部分相機 APP 會因為動態變化的二維碼而無法正常掃描,也你可以點擊 暫停,這會有助於你掃描。 -
+你也可以手動輸入掃描網頁的地址: [qrss.netlify.app](https://qrss.netlify.app) diff --git a/app/layouts/content.vue b/app/layouts/content.vue index 3327537a..e7d91bf7 100644 --- a/app/layouts/content.vue +++ b/app/layouts/content.vue @@ -17,41 +17,3 @@ const isMatchedLocale = computed(() => locale.value === route.meta.locale) - -