Skip to content

Commit

Permalink
feat: QR 코드를 생성하고 공유할 수 있음
Browse files Browse the repository at this point in the history
   - 노트를 QR 코드로 공유 (1673beta#45)
   - 사용자를 QR 코드로 공유 (1673beta#46), (1673beta#49)
   - 갤러리를 QR 코드로 공유 (1673beta#51)
   - 페이지를 QR 코드로 공유 (1673beta#53)
  • Loading branch information
noridev committed Oct 3, 2024
1 parent 6b92caf commit 2643170
Show file tree
Hide file tree
Showing 14 changed files with 175 additions and 2 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG_CHERRYPICK.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ Misskey의 전체 변경 사항을 확인하려면, [CHANGELOG.md#2024xx](CHANGE
- 이 변경으로 이미지 뷰어의 파일 이름 영역에는 더 이상 캡션이 아닌 실제 파일 이름이 표시됩니다.
- Feat: 사용자 정의 스플래시 텍스트를 설정할 수 있음 (1673beta/cherrypick#153)
- Feat: 주사위 위젯 (1673beta/cherrypick#73)
- Feat: QR 코드를 생성하고 공유할 수 있음
- 노트를 QR 코드로 공유 (1673beta/cherrypick#45)
- 사용자를 QR 코드로 공유 (1673beta/cherrypick#46), (1673beta/cherrypick#49)
- 갤러리를 QR 코드로 공유 (1673beta/cherrypick#51)
- 페이지를 QR 코드로 공유 (1673beta/cherrypick#53)
- Play를 QR 코드로 공유

### Client
- Enhance: CherryPick 업데이트 페이지를 제어판 목록에 추가함
Expand Down
1 change: 1 addition & 0 deletions locales/en-US.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
_lang_: "English"
getQRCode: "Get QR code"
customSplashText: "Custom splash text"
customSplashTextDescription: "This text will be displayed on the loading page."
showNoAltWarning: "Show caption unset warning"
Expand Down
4 changes: 4 additions & 0 deletions locales/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ export interface Locale extends ILocale {
* 日本語
*/
"_lang_": string;
/**
* QRコードを取得
*/
"getQRCode": string;
/**
* カスタムスプラッシュテキスト
*/
Expand Down
1 change: 1 addition & 0 deletions locales/ja-JP.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
_lang_: "日本語"

getQRCode: "QRコードを取得"
customSplashText: "カスタムスプラッシュテキスト"
customSplashTextDescription: "ロード画面に表示されるテキストを設定します。改行で区切って複数設定できます。"
showNoAltWarning: "キャプション未設定案内を表示"
Expand Down
1 change: 1 addition & 0 deletions locales/ko-KR.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
_lang_: "한국어"
getQRCode: "QR 코드 생성"
customSplashText: "사용자 정의 스플래시 텍스트"
customSplashTextDescription: "스플래시 화면에 표시되는 텍스트를 설정해요. 줄바꿈으로 구분해 설정할 수 있어요."
showNoAltWarning: "캡션 미설정 안내 표시"
Expand Down
3 changes: 3 additions & 0 deletions packages/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@
"photoswipe": "5.4.4",
"prismjs": "1.29.0",
"punycode": "2.3.1",
"qrcode": "^1.5.4",
"qrcode-vue3": "^1.7.1",
"rollup": "4.22.5",
"sanitize-html": "2.13.0",
"sass": "1.79.3",
Expand Down Expand Up @@ -109,6 +111,7 @@
"@types/node": "20.14.12",
"@types/prismjs": "^1.26.0",
"@types/punycode": "2.1.4",
"@types/qrcode": "^1.5.5",
"@types/sanitize-html": "2.13.0",
"@types/seedrandom": "3.0.8",
"@types/throttle-debounce": "5.0.2",
Expand Down
88 changes: 88 additions & 0 deletions packages/frontend/src/components/MkQRCode.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<template>
<MkModal ref="modal" :zPriority="'middle'" @closed="$emit('closed')">
<div :class="$style.root">
<div :class="$style.title">
<QRCodeVue3
:value="qrCode"
:qrOptions="{ errorCorrectionLevel: 'Q' }"
:cornersSquareOptions="{ type: 'square' }"
:cornersDotOptions="{ type: 'square' }"
:dotsOptions="{
type: 'square',
}"
/>
</div>
<div class="_flexList" style="gap: 0.6rem">
<MkButton :class="$style.gotIt" primary full @click="gotIt()">{{ i18n.ts.gotIt }}</MkButton>
<MkButton :class="$style.copyLink" full @click="copyLink()">{{ i18n.ts.copyLink }}</MkButton>
</div>
</div>
</MkModal>
</template>

<script lang="ts" setup>
import { shallowRef } from 'vue';
import QRCodeVue3 from 'qrcode-vue3';
import MkModal from '@/components/MkModal.vue';
import MkButton from '@/components/MkButton.vue';
import { i18n } from '@/i18n.js';
import * as os from '@/os.js';
import { copyToClipboard } from '@/scripts/copy-to-clipboard.js';
const props = defineProps<{
qrCode: string;
}>();
const modal = shallowRef<InstanceType<typeof MkModal>>();
const gotIt = () => {
modal.value?.close();
};
const copyLink = () => {
copyToClipboard(props.qrCode);
os.toast(i18n.ts.copiedContent, 'copied');
};
</script>

<style lang="scss" module>
.root {
margin: auto;
position: relative;
padding: 32px;
min-width: 320px;
max-width: 480px;
box-sizing: border-box;
text-align: center;
background: var(--panel);
border-radius: var(--radius);
}
.title {
font-weight: bold;
> div {
> div {
> img {
max-width: 60%;
}
}
}
> p {
margin: 0;
}
}
.time {
font-size: 0.8rem;
}
.gotIt {
margin: 8px 0 0 0;
}
.copyLink {
margin: 8px 0 0 0;
}
</style>
18 changes: 18 additions & 0 deletions packages/frontend/src/os.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import MkPasswordDialog from '@/components/MkPasswordDialog.vue';
import MkEmojiPickerDialog from '@/components/MkEmojiPickerDialog.vue';
import MkPopupMenu from '@/components/MkPopupMenu.vue';
import MkContextMenu from '@/components/MkContextMenu.vue';
import MkQRcode from '@/components/MkQRcode.vue';
import { copyToClipboard } from '@/scripts/copy-to-clipboard.js';
import { pleaseLogin } from '@/scripts/please-login.js';
import { showMovedDialog } from '@/scripts/show-moved-dialog.js';
Expand Down Expand Up @@ -737,3 +738,20 @@ export function checkExistence(fileData: ArrayBuffer): Promise<any> {
});
});
}*/

export async function displayQRCode(qrCode: string) {
(await new Promise<(() => void ) | undefined>((resolve) => {
let dispose: (() => void ) | undefined;
popup(
MkQRcode,
{ qrCode },
{
closed: () => {
resolve(dispose);
},
},
).then((res) => {
dispose = res.dispose;
});
}))?.();
}
6 changes: 6 additions & 0 deletions packages/frontend/src/pages/flash/flash.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkButton v-if="flash.isLiked" v-tooltip="i18n.ts.unlike" asLike :class="$style.button" class="button" rounded primary @click="unlike()"><i class="ti ti-heart"></i><span v-if="flash?.likedCount && flash.likedCount > 0" style="margin-left: 6px;">{{ flash.likedCount }}</span></MkButton>
<MkButton v-else v-tooltip="i18n.ts.like" asLike :class="$style.button" class="button" rounded @click="like()"><i class="ti ti-heart"></i><span v-if="flash?.likedCount && flash.likedCount > 0" style="margin-left: 6px;">{{ flash.likedCount }}</span></MkButton>
<MkButton v-tooltip="i18n.ts.copyLink" :class="$style.button" class="button" rounded @click="copyLink"><i class="ti ti-link ti-fw"></i></MkButton>
<MkButton v-tooltip="i18n.ts.getQRCode" :class="$style.button" class="_button" rounded @click="shareQRCode"><i class="ti ti-qrcode ti-fw"></i></MkButton>
<MkButton v-tooltip="i18n.ts.share" :class="$style.button" class="button" rounded @click="share"><i class="ti ti-share ti-fw"></i></MkButton>
<MkButton v-if="$i && $i.id !== flash.user.id" :class="$style.button" class="button" rounded @mousedown="showMenu"><i class="ti ti-dots ti-fw"></i></MkButton>
</div>
Expand Down Expand Up @@ -130,6 +131,11 @@ function copyLink() {
os.success();
}
function shareQRCode() {
if (!flash.value) return;
os.displayQRCode(`${url}/play/${flash.value.id}`);
}
function shareWithNavigator() {
if (!flash.value) return;
Expand Down
8 changes: 6 additions & 2 deletions packages/frontend/src/pages/gallery/post.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<button v-if="$i && $i.id === post.user.id" v-tooltip="i18n.ts.edit" v-click-anime class="_button" @click="edit"><i class="ti ti-pencil ti-fw"></i></button>
<button v-tooltip="i18n.ts.shareWithNote" v-click-anime class="_button" @click="shareWithNote"><i class="ti ti-repeat ti-fw"></i></button>
<button v-tooltip="i18n.ts.copyLink" v-click-anime class="_button" @click="copyLink"><i class="ti ti-link ti-fw"></i></button>
<button v-tooltip="i18n.ts.getQRCode" v-click-anime class="_button" @click="shareQRCode"><i class="ti ti-qrcode ti-fw"></i></button>
<button v-if="isSupportShare()" v-tooltip="i18n.ts.share" v-click-anime class="_button" @click="share"><i class="ti ti-share ti-fw"></i></button>
<button v-if="$i && $i.id !== post.user.id" v-click-anime class="_button" @mousedown="showMenu"><i class="ti ti-dots ti-fw"></i></button>
</div>
Expand Down Expand Up @@ -128,6 +129,10 @@ function shareWithNote() {
});
}
function shareQRCode() {
os.displayQRCode(`${url}/gallery/${post.value.id}`);
}
function like() {
os.apiWithDialog('gallery/posts/like', {
postId: props.postId,
Expand Down Expand Up @@ -283,7 +288,7 @@ definePageMetadata(() => ({
> button {
padding: 8px;
margin: 0 8px;
margin: 0 6px;
&:hover {
color: var(--fgHighlighted);
Expand Down Expand Up @@ -324,7 +329,6 @@ definePageMetadata(() => ({
margin: var(--margin);
> .post {
}
}
</style>
6 changes: 6 additions & 0 deletions packages/frontend/src/pages/page.vue
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div :class="$style.other">
<MkA v-if="page.userId === $i?.id" v-tooltip="i18n.ts._pages.editThisPage" :to="`/pages/edit/${page.id}`" class="_button" :class="$style.generalActionButton"><i class="ti ti-pencil ti-fw"></i></MkA>
<button v-tooltip="i18n.ts.copyLink" class="_button" :class="$style.generalActionButton" @click="copyLink"><i class="ti ti-link ti-fw"></i></button>
<button v-tooltip="i18n.ts.getQRCode" class="_button" :class="$style.generalActionButton" @click="shareQRCode"><i class="ti ti-qrcode ti-fw"></i></button>
<button v-tooltip="i18n.ts.share" class="_button" :class="$style.generalActionButton" @click="share"><i class="ti ti-share ti-fw"></i></button>
<button v-if="$i" v-click-anime class="_button" :class="$style.generalActionButton" @mousedown="showMenu"><i class="ti ti-dots ti-fw"></i></button>
</div>
Expand Down Expand Up @@ -191,6 +192,11 @@ function copyLink() {
os.success();
}
function shareQRCode() {
if (!page.value) return;
os.displayQRCode(`${url}/@${page.value.user.username}/pages/${page.value.name}`);
}
function shareWithNote() {
if (!page.value) return;
Expand Down
8 changes: 8 additions & 0 deletions packages/frontend/src/scripts/get-note-menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,14 @@ export function getNoteMenu(props: {

getCopyNoteLinkMenu(appearNote, i18n.ts.copyLink);

menuItems.push({
icon: 'ti ti-qrcode',
text: i18n.ts.getQRCode,
action: () => {
os.displayQRCode(`${url}/notes/${appearNote.id}`);
},
});

menuItems.push({
icon: 'ti ti-copy',
text: i18n.ts.copyContent,
Expand Down
6 changes: 6 additions & 0 deletions packages/frontend/src/scripts/get-user-menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,12 @@ export function getUserMenu(user: Misskey.entities.UserDetailed, router: IRouter
copyToClipboard(`${url}/${canonical}`);
os.toast(i18n.ts.copiedLink, 'copied');
},
}, {
icon: 'ti ti-qrcode',
text: i18n.ts.getQRCode,
action: () => {
os.displayQRCode(`https://${user.host ?? host}/@${user.username}`);
},
});

if ($i) {
Expand Down
21 changes: 21 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 2643170

Please sign in to comment.