diff --git a/packages/client/src/components/MkNote.vue b/packages/client/src/components/MkNote.vue index 5e4fe316f..2e7fd98f3 100644 --- a/packages/client/src/components/MkNote.vue +++ b/packages/client/src/components/MkNote.vue @@ -239,6 +239,8 @@ import XStarButtonNoEmoji from "@/components/MkStarButtonNoEmoji.vue"; import XQuoteButton from "@/components/MkQuoteButton.vue"; import MkUrlPreview from "@/components/MkUrlPreview.vue"; import MkVisibility from "@/components/MkVisibility.vue"; +import copyToClipboard from "@/scripts/copy-to-clipboard"; +import { url } from "@/config"; import { pleaseLogin } from "@/scripts/please-login"; import { focusPrev, focusNext } from "@/scripts/focus"; import { getWordSoftMute } from "@/scripts/check-word-mute"; @@ -254,6 +256,7 @@ import { useNoteCapture } from "@/scripts/use-note-capture"; import { notePage } from "@/filters/note"; import { deepClone } from "@/scripts/clone"; + const router = useRouter(); const props = defineProps<{ @@ -386,16 +389,43 @@ function onContextmenu(ev: MouseEvent): void { react(); } else { os.contextMenu( - getNoteMenu({ - note: note, - translating, - translation, - menuButton, - isDeleted, - currentClipPage, - }), + [ + { + type: "label", + text: notePage(appearNote), + }, + { + icon: "ph-browser ph-bold ph-lg", + text: i18n.ts.openInWindow, + action: () => { + os.pageWindow(notePage(appearNote)); + }, + }, + { + icon: "ph-arrows-out-simple ph-bold ph-lg", + text: i18n.ts.showInPage, + action: () => { + router.push(notePage(appearNote), "forcePage"); + }, + }, + null, + { + icon: "ph-arrow-square-out ph-bold ph-lg", + text: i18n.ts.openInNewTab, + action: () => { + window.open(notePage(appearNote), "_blank"); + }, + }, + { + icon: "ph-link-simple ph-bold ph-lg", + text: i18n.ts.copyLink, + action: () => { + copyToClipboard(`${url}${notePage(appearNote)}`); + }, + }, + ], ev - ).then(focus); + ); } } @@ -596,6 +626,7 @@ defineExpose({ margin-right: 14px; margin-top: 0; flex-grow: 0; + pointer-events: none; } > div > i { diff --git a/packages/client/src/components/MkNoteSub.vue b/packages/client/src/components/MkNoteSub.vue index af2dba490..77046dcba 100644 --- a/packages/client/src/components/MkNoteSub.vue +++ b/packages/client/src/components/MkNoteSub.vue @@ -11,6 +11,7 @@ singleStart: replies.length == 1, firstColumn: depth == 1 && conversation, }" + @contextmenu.stop="onContextmenu" >
@@ -180,6 +181,8 @@ import XStarButton from "@/components/MkStarButton.vue"; import XStarButtonNoEmoji from "@/components/MkStarButtonNoEmoji.vue"; import XRenoteButton from "@/components/MkRenoteButton.vue"; import XQuoteButton from "@/components/MkQuoteButton.vue"; +import copyToClipboard from "@/scripts/copy-to-clipboard"; +import { url } from "@/config"; import { pleaseLogin } from "@/scripts/please-login"; import { getNoteMenu } from "@/scripts/get-note-menu"; import { getWordSoftMute } from "@/scripts/check-word-mute"; @@ -318,6 +321,61 @@ function menu(viaKeyboard = false): void { ).then(focus); } +function onContextmenu(ev: MouseEvent): void { + const isLink = (el: HTMLElement) => { + if (el.tagName === "A") return true; + if (el.parentElement) { + return isLink(el.parentElement); + } + }; + if (isLink(ev.target)) return; + if (window.getSelection().toString() !== "") return; + + if (defaultStore.state.useReactionPickerForContextMenu) { + ev.preventDefault(); + react(); + } else { + os.contextMenu( + [ + { + type: "label", + text: notePage(appearNote), + }, + { + icon: "ph-browser ph-bold ph-lg", + text: i18n.ts.openInWindow, + action: () => { + os.pageWindow(notePage(appearNote)); + }, + }, + { + icon: "ph-arrows-out-simple ph-bold ph-lg", + text: i18n.ts.showInPage, + action: () => { + router.push(notePage(appearNote), "forcePage"); + }, + }, + null, + { + icon: "ph-arrow-square-out ph-bold ph-lg", + text: i18n.ts.openInNewTab, + action: () => { + window.open(notePage(appearNote), "_blank"); + }, + }, + { + icon: "ph-link-simple ph-bold ph-lg", + text: i18n.ts.copyLink, + action: () => { + copyToClipboard(`${url}${notePage(appearNote)}`); + }, + }, + ], + ev + ); + } +} + function focus() { el.value.focus(); } @@ -562,6 +620,7 @@ function noteClick(e) { display: flex; flex-grow: 1; margin-bottom: -10px; + pointer-events: none; &::before { content: ""; position: absolute;