From 0df67c27867ef2fcb1bdd329b796b9aab48c3bfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=82=8A=E3=81=99?= Date: Thu, 21 Mar 2024 14:58:10 +0900 Subject: [PATCH 1/2] =?UTF-8?q?Fix:=20=E3=83=81=E3=83=A3=E3=83=83=E3=83=88?= =?UTF-8?q?=E3=81=A7=E7=B5=B5=E6=96=87=E5=AD=97=E3=83=94=E3=83=83=E3=82=AB?= =?UTF-8?q?=E3=83=BC=E3=82=92=E9=96=8B=E3=81=91=E3=81=AA=E3=81=8F=E3=81=AA?= =?UTF-8?q?=E3=82=8B=E5=95=8F=E9=A1=8C=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/frontend/src/os.ts | 56 +++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/packages/frontend/src/os.ts b/packages/frontend/src/os.ts index 189730330a..7a4c6605bb 100644 --- a/packages/frontend/src/os.ts +++ b/packages/frontend/src/os.ts @@ -7,6 +7,7 @@ import { Component, markRaw, Ref, ref, defineAsyncComponent } from 'vue'; import { EventEmitter } from 'eventemitter3'; +import insertTextAtCursor from 'insert-text-at-cursor'; import * as Misskey from 'cherrypick-js'; import type { ComponentProps as CP } from 'vue-component-type-helpers'; import type { Form, GetFormResultType } from '@/scripts/form.js'; @@ -20,6 +21,7 @@ import MkWelcomeToast from '@/components/MkWelcomeToast.vue'; import MkDialog from '@/components/MkDialog.vue'; import MkPasswordDialog from '@/components/MkPasswordDialog.vue'; import MkEmojiPickerDialog from '@/components/MkEmojiPickerDialog.vue'; +import MkEmojiPickerWindow from '@/components/MkEmojiPickerWindow.vue'; import MkPopupMenu from '@/components/MkPopupMenu.vue'; import MkContextMenu from '@/components/MkContextMenu.vue'; import { MenuItem } from '@/types/menu.js'; @@ -610,6 +612,60 @@ export async function cropImage(image: Misskey.entities.DriveFile, options: { }); } +type AwaitType = + T extends Promise ? U : + T extends (...args: any[]) => Promise ? V : + T; +let openingEmojiPicker: AwaitType> | null = null; +let activeTextarea: HTMLTextAreaElement | HTMLInputElement | null = null; +export async function openEmojiPicker(src?: HTMLElement, opts, initialTextarea: typeof activeTextarea) { + if (openingEmojiPicker) return; + + activeTextarea = initialTextarea; + + const textareas = document.querySelectorAll('textarea, input'); + for (const textarea of Array.from(textareas)) { + textarea.addEventListener('focus', () => { + activeTextarea = textarea; + }); + } + + const observer = new MutationObserver(records => { + for (const record of records) { + for (const node of Array.from(record.addedNodes).filter(node => node instanceof HTMLElement) as HTMLElement[]) { + const textareas = node.querySelectorAll('textarea, input') as NodeListOf>; + for (const textarea of Array.from(textareas).filter(textarea => textarea.dataset.preventEmojiInsert == null)) { + if (document.activeElement === textarea) activeTextarea = textarea; + textarea.addEventListener('focus', () => { + activeTextarea = textarea; + }); + } + } + } + }); + + observer.observe(document.body, { + childList: true, + subtree: true, + attributes: false, + characterData: false, + }); + + openingEmojiPicker = await popup(MkEmojiPickerWindow, { + src, + ...opts, + }, { + chosen: emoji => { + insertTextAtCursor(activeTextarea, emoji); + }, + closed: () => { + openingEmojiPicker!.dispose(); + openingEmojiPicker = null; + observer.disconnect(); + }, + }); +} + export function popupMenu(items: MenuItem[], src?: HTMLElement | EventTarget | null, options?: { align?: string; width?: number; From ffae6d43440730d722c6b36e5c51014b8c8824e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=82=E3=82=8A=E3=81=99?= Date: Thu, 21 Mar 2024 15:09:06 +0900 Subject: [PATCH 2/2] Fix: Emoji --- .../src/components/MkEmojiPickerWindow.vue | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 packages/frontend/src/components/MkEmojiPickerWindow.vue diff --git a/packages/frontend/src/components/MkEmojiPickerWindow.vue b/packages/frontend/src/components/MkEmojiPickerWindow.vue new file mode 100644 index 0000000000..0bcc7066c9 --- /dev/null +++ b/packages/frontend/src/components/MkEmojiPickerWindow.vue @@ -0,0 +1,49 @@ + + + + + + + \ No newline at end of file