diff --git a/locales/en-US.yml b/locales/en-US.yml index 7ccda1426c..cb96caa823 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -1157,6 +1157,7 @@ addRe: "Add \"re:\" at the beginning of comment in reply to a post with a conten confirm: "Confirm" importZip: "Import ZIP" exportZip: "Export ZIP" +getQrCode: "Get QR code" emojiPackCreator: "Emoji pack creator" indexable: "Indexable" indexableDescription: "Allow built-in search to show your public posts" diff --git a/locales/fr-FR.yml b/locales/fr-FR.yml index 6367dda9f4..5d7a1ecef8 100644 --- a/locales/fr-FR.yml +++ b/locales/fr-FR.yml @@ -928,6 +928,8 @@ colored: "Coloré" label: "Étiquette" localOnly: "Local seulement" account: "Comptes" +getQrCode: "Obtenir le code QR" + _emailUnavailable: used: "Adresse non disponible" format: "Le format de cette adresse de courriel est invalide" diff --git a/packages/client/package.json b/packages/client/package.json index 97a5f83ef7..8b9184ad38 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -28,6 +28,7 @@ "@types/matter-js": "0.19.6", "@types/prismjs": "^1.26.3", "@types/punycode": "2.1.4", + "@types/qrcode": "1.5.1", "@types/seedrandom": "3.0.8", "@types/textarea-caret": "^3.0.3", "@types/throttle-debounce": "5.0.2", @@ -60,13 +61,17 @@ "insert-text-at-cursor": "0.3.0", "json5": "2.2.3", "katex": "0.16.10", + "long": "^5.2.3", "libopenmpt-wasm": "github:TheEssem/libopenmpt-packaging#build", "matter-js": "0.19.0", "mfm-js": "0.24.0", + "multer": "1.4.4-lts.1", "moment": "2.30.1", "photoswipe": "5.4.3", "prismjs": "1.29.0", "punycode": "2.3.1", + "qrcode": "1.5.3", + "qrcode-vue3": "^1.6.8", "rollup": "4.14.2", "s-age": "1.1.2", "sass": "1.75.0", diff --git a/packages/client/src/components/FfQrCode.vue b/packages/client/src/components/FfQrCode.vue new file mode 100644 index 0000000000..9dca107406 --- /dev/null +++ b/packages/client/src/components/FfQrCode.vue @@ -0,0 +1,70 @@ + + + + + diff --git a/packages/client/src/os.ts b/packages/client/src/os.ts index c7c62852de..61629863ba 100644 --- a/packages/client/src/os.ts +++ b/packages/client/src/os.ts @@ -7,6 +7,7 @@ import type { Component, MaybeRef, Ref } from "vue"; import { defineAsyncComponent, markRaw, ref } from "vue"; import { i18n } from "./i18n"; import MkDialog from "@/components/MkDialog.vue"; +import FfQrCode from "@/components/FfQrCode.vue"; import MkPostFormDialog from "@/components/MkPostFormDialog.vue"; import MkToast from "@/components/MkToast.vue"; import MkWaitingDialog from "@/components/MkWaitingDialog.vue"; @@ -1003,6 +1004,19 @@ export function post( }); } +export async function displayQrCode(qrCode: string) { + (await new Promise<(() => void) | undefined>((resolve) => { + let dispose: (() => void) | undefined; + popup(FfQrCode, { qrCode }, { + closed: () => { + resolve(dispose); + } + }).then((res) => { + dispose = res.dispose + }) + }))?.(); +} + export const deckGlobalEvents = new EventEmitter(); /* diff --git a/packages/client/src/scripts/get-user-menu.ts b/packages/client/src/scripts/get-user-menu.ts index 880ce481c7..713023eada 100644 --- a/packages/client/src/scripts/get-user-menu.ts +++ b/packages/client/src/scripts/get-user-menu.ts @@ -290,6 +290,13 @@ export function getUserMenu(user, router: Router = mainRouter) { os.post({ specified: user }); }, }, + { + icon: "ph-qr-code ph-bold ph-lg", + text: i18n.ts.getQrCode, + action: () => { + os.displayQrCode(window.location.href) + } + }, isSignedIn(me) && me.id !== user.id ? { type: "link",