From be7e3b9a0cb81b78a744993fef2fa2fd2833fa9c Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Sun, 9 Mar 2025 14:28:01 +0900 Subject: refactor(frontend): scripts -> utility --- packages/frontend/src/utility/get-embed-code.ts | 87 +++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 packages/frontend/src/utility/get-embed-code.ts (limited to 'packages/frontend/src/utility/get-embed-code.ts') diff --git a/packages/frontend/src/utility/get-embed-code.ts b/packages/frontend/src/utility/get-embed-code.ts new file mode 100644 index 0000000000..9021520da8 --- /dev/null +++ b/packages/frontend/src/utility/get-embed-code.ts @@ -0,0 +1,87 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ +import { defineAsyncComponent } from 'vue'; +import { v4 as uuid } from 'uuid'; +import type { EmbedParams, EmbeddableEntity } from '@@/js/embed-page.js'; +import { url } from '@@/js/config.js'; +import * as os from '@/os.js'; +import { copyToClipboard } from '@/utility/copy-to-clipboard.js'; +import { defaultEmbedParams, embedRouteWithScrollbar } from '@@/js/embed-page.js'; + +const MOBILE_THRESHOLD = 500; + +/** + * パラメータを正規化する(埋め込みコード作成用) + * @param params パラメータ + * @returns 正規化されたパラメータ + */ +export function normalizeEmbedParams(params: EmbedParams): Record { + // paramsのvalueをすべてstringに変換。undefinedやnullはプロパティごと消す + const normalizedParams: Record = {}; + for (const key in params) { + // デフォルトの値と同じならparamsに含めない + if (params[key] == null || params[key] === defaultEmbedParams[key]) { + continue; + } + switch (typeof params[key]) { + case 'number': + normalizedParams[key] = params[key].toString(); + break; + case 'boolean': + normalizedParams[key] = params[key] ? 'true' : 'false'; + break; + default: + normalizedParams[key] = params[key]; + break; + } + } + return normalizedParams; +} + +/** + * 埋め込みコードを生成(iframe IDの発番もやる) + */ +export function getEmbedCode(path: string, params?: EmbedParams): string { + const iframeId = 'v1_' + uuid(); // 将来embed.jsのバージョンが上がったとき用にv1_を付けておく + + let paramString = ''; + if (params) { + const searchParams = new URLSearchParams(normalizeEmbedParams(params)); + paramString = searchParams.toString() === '' ? '' : '?' + searchParams.toString(); + } + + const iframeCode = [ + ``, + ``, + ]; + return iframeCode.join('\n'); +} + +/** + * 埋め込みコードを生成してコピーする(カスタマイズ機能つき) + * + * カスタマイズ機能がいらない場合(事前にパラメータを指定する場合)は getEmbedCode を直接使ってください + */ +export function genEmbedCode(entity: EmbeddableEntity, id: string, params?: EmbedParams) { + const _params = { ...params }; + + if (embedRouteWithScrollbar.includes(entity) && _params.maxHeight == null) { + _params.maxHeight = 700; + } + + // PCじゃない場合はコードカスタマイズ画面を出さずにそのままコピー + if (window.innerWidth < MOBILE_THRESHOLD) { + copyToClipboard(getEmbedCode(`/embed/${entity}/${id}`, _params)); + os.success(); + } else { + const { dispose } = os.popup(defineAsyncComponent(() => import('@/components/MkEmbedCodeGenDialog.vue')), { + entity, + id, + params: _params, + }, { + closed: () => dispose(), + }); + } +} -- cgit v1.2.3-freya From 81a0cbd294bd6485fc47200b1bf63dbf2cbc8507 Mon Sep 17 00:00:00 2001 From: syuilo <4439005+syuilo@users.noreply.github.com> Date: Sun, 16 Mar 2025 15:04:38 +0900 Subject: chore(frontend): use toast to show message when call copyToClipboard --- locales/index.d.ts | 4 ++++ locales/ja-JP.yml | 1 + packages/frontend/src/components/MkCode.vue | 1 - packages/frontend/src/components/MkEmbedCodeGenDialog.vue | 1 - packages/frontend/src/components/MkInviteCode.vue | 1 - packages/frontend/src/components/MkKeyValue.vue | 1 - packages/frontend/src/components/global/MkCustomEmoji.vue | 1 - packages/frontend/src/components/global/MkEmoji.vue | 1 - packages/frontend/src/os.ts | 1 - packages/frontend/src/pages/channel.vue | 1 - packages/frontend/src/pages/clip.vue | 1 - packages/frontend/src/pages/drop-and-fusion.game.vue | 1 - packages/frontend/src/pages/emojis.emoji.vue | 3 +-- packages/frontend/src/pages/flash/flash.vue | 1 - packages/frontend/src/pages/gallery/post.vue | 1 - packages/frontend/src/pages/page.vue | 1 - packages/frontend/src/pages/settings/theme.manage.vue | 3 +-- packages/frontend/src/utility/copy-to-clipboard.ts | 8 +++++++- packages/frontend/src/utility/get-drive-file-menu.ts | 1 - packages/frontend/src/utility/get-embed-code.ts | 5 ++--- packages/frontend/src/utility/get-note-menu.ts | 5 ----- 21 files changed, 16 insertions(+), 27 deletions(-) (limited to 'packages/frontend/src/utility/get-embed-code.ts') diff --git a/locales/index.d.ts b/locales/index.d.ts index 3b56563149..0c6e73aac4 100644 --- a/locales/index.d.ts +++ b/locales/index.d.ts @@ -2810,6 +2810,10 @@ export interface Locale extends ILocale { * コピー */ "copy": string; + /** + * クリップボードにコピーされました + */ + "copiedToClipboard": string; /** * メトリクス */ diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index ad96549160..d6af72ab57 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -698,6 +698,7 @@ userSaysSomethingAbout: "{name}が「{word}」について何かを言いまし makeActive: "アクティブにする" display: "表示" copy: "コピー" +copiedToClipboard: "クリップボードにコピーされました" metrics: "メトリクス" overview: "概要" logs: "ログ" diff --git a/packages/frontend/src/components/MkCode.vue b/packages/frontend/src/components/MkCode.vue index 9708b78a30..d2d9f320ee 100644 --- a/packages/frontend/src/components/MkCode.vue +++ b/packages/frontend/src/components/MkCode.vue @@ -48,7 +48,6 @@ const XCode = defineAsyncComponent(() => import('@/components/MkCode.core.vue')) function copy() { copyToClipboard(props.code); - os.success(); } diff --git a/packages/frontend/src/components/MkEmbedCodeGenDialog.vue b/packages/frontend/src/components/MkEmbedCodeGenDialog.vue index a53c9c7904..e038b84ba7 100644 --- a/packages/frontend/src/components/MkEmbedCodeGenDialog.vue +++ b/packages/frontend/src/components/MkEmbedCodeGenDialog.vue @@ -194,7 +194,6 @@ function generate() { function doCopy() { copyToClipboard(result.value); - os.success(); } //#endregion diff --git a/packages/frontend/src/components/MkInviteCode.vue b/packages/frontend/src/components/MkInviteCode.vue index 0f53d1573d..ab797459cc 100644 --- a/packages/frontend/src/components/MkInviteCode.vue +++ b/packages/frontend/src/components/MkInviteCode.vue @@ -90,7 +90,6 @@ function deleteCode() { function copyInviteCode() { copyToClipboard(props.invite.code); - os.success(); } diff --git a/packages/frontend/src/components/MkKeyValue.vue b/packages/frontend/src/components/MkKeyValue.vue index 275b153e4a..b4185d2d0a 100644 --- a/packages/frontend/src/components/MkKeyValue.vue +++ b/packages/frontend/src/components/MkKeyValue.vue @@ -31,7 +31,6 @@ const props = withDefaults(defineProps<{ const copy_ = () => { copyToClipboard(props.copy); - os.success(); }; diff --git a/packages/frontend/src/components/global/MkCustomEmoji.vue b/packages/frontend/src/components/global/MkCustomEmoji.vue index 65d6e9a3f6..af8f1d035e 100644 --- a/packages/frontend/src/components/global/MkCustomEmoji.vue +++ b/packages/frontend/src/components/global/MkCustomEmoji.vue @@ -100,7 +100,6 @@ function onClick(ev: MouseEvent) { icon: 'ti ti-copy', action: () => { copyToClipboard(`:${props.name}:`); - os.success(); }, }); diff --git a/packages/frontend/src/components/global/MkEmoji.vue b/packages/frontend/src/components/global/MkEmoji.vue index 37df945233..ca67a28b70 100644 --- a/packages/frontend/src/components/global/MkEmoji.vue +++ b/packages/frontend/src/components/global/MkEmoji.vue @@ -50,7 +50,6 @@ function onClick(ev: MouseEvent) { icon: 'ti ti-copy', action: () => { copyToClipboard(props.emoji); - os.success(); }, }); diff --git a/packages/frontend/src/os.ts b/packages/frontend/src/os.ts index a009a3f3d1..8e4c97e59f 100644 --- a/packages/frontend/src/os.ts +++ b/packages/frontend/src/os.ts @@ -63,7 +63,6 @@ export const apiWithDialog = ( { return; } copyToClipboard(`${url}/channels/${channel.value.id}`); - os.success(); }, }); diff --git a/packages/frontend/src/pages/clip.vue b/packages/frontend/src/pages/clip.vue index 590a506a55..772ed6bd11 100644 --- a/packages/frontend/src/pages/clip.vue +++ b/packages/frontend/src/pages/clip.vue @@ -148,7 +148,6 @@ const headerActions = computed(() => clip.value && isOwned.value ? [{ text: i18n.ts.copyUrl, action: () => { copyToClipboard(`${url}/clips/${clip.value!.id}`); - os.success(); }, }, { icon: 'ti ti-code', diff --git a/packages/frontend/src/pages/drop-and-fusion.game.vue b/packages/frontend/src/pages/drop-and-fusion.game.vue index 364006e9ad..e30e381ce1 100644 --- a/packages/frontend/src/pages/drop-and-fusion.game.vue +++ b/packages/frontend/src/pages/drop-and-fusion.game.vue @@ -849,7 +849,6 @@ function exportLog() { l: DropAndFusionGame.serializeLogs(logs), }); copyToClipboard(data); - os.success(); } function updateSettings< diff --git a/packages/frontend/src/pages/emojis.emoji.vue b/packages/frontend/src/pages/emojis.emoji.vue index bedb0b64f9..d5570eb20a 100644 --- a/packages/frontend/src/pages/emojis.emoji.vue +++ b/packages/frontend/src/pages/emojis.emoji.vue @@ -25,7 +25,7 @@ import MkCustomEmojiDetailedDialog from '@/components/MkCustomEmojiDetailedDialo import { $i } from '@/i.js'; const props = defineProps<{ - emoji: Misskey.entities.EmojiSimple; + emoji: Misskey.entities.EmojiSimple; }>(); function menu(ev) { @@ -38,7 +38,6 @@ function menu(ev) { icon: 'ti ti-copy', action: () => { copyToClipboard(`:${props.emoji.name}:`); - os.success(); }, }, { text: i18n.ts.info, diff --git a/packages/frontend/src/pages/flash/flash.vue b/packages/frontend/src/pages/flash/flash.vue index 08ac913958..96e43b0205 100644 --- a/packages/frontend/src/pages/flash/flash.vue +++ b/packages/frontend/src/pages/flash/flash.vue @@ -129,7 +129,6 @@ function copyLink() { if (!flash.value) return; copyToClipboard(`${url}/play/${flash.value.id}`); - os.success(); } function shareWithNavigator() { diff --git a/packages/frontend/src/pages/gallery/post.vue b/packages/frontend/src/pages/gallery/post.vue index eb01aadbcc..6a9737e30f 100644 --- a/packages/frontend/src/pages/gallery/post.vue +++ b/packages/frontend/src/pages/gallery/post.vue @@ -111,7 +111,6 @@ function fetchPost() { function copyLink() { copyToClipboard(`${url}/gallery/${post.value.id}`); - os.success(); } function share() { diff --git a/packages/frontend/src/pages/page.vue b/packages/frontend/src/pages/page.vue index 00c664d2a0..523d443359 100644 --- a/packages/frontend/src/pages/page.vue +++ b/packages/frontend/src/pages/page.vue @@ -190,7 +190,6 @@ function copyLink() { if (!page.value) return; copyToClipboard(`${url}/@${page.value.user.username}/pages/${page.value.name}`); - os.success(); } function shareWithNote() { diff --git a/packages/frontend/src/pages/settings/theme.manage.vue b/packages/frontend/src/pages/settings/theme.manage.vue index e2b48ea232..c68c04bb44 100644 --- a/packages/frontend/src/pages/settings/theme.manage.vue +++ b/packages/frontend/src/pages/settings/theme.manage.vue @@ -33,12 +33,12 @@ SPDX-License-Identifier: AGPL-3.0-only