From b33fe530476f89282e1e554aecf0cfe82e6d6edd Mon Sep 17 00:00:00 2001
From: 1STEP621 <86859447+1STEP621@users.noreply.github.com>
Date: Thu, 14 Dec 2023 13:11:23 +0900
Subject: Enhance(frontend):
 MFMや絵文字が使える入力ボックスでオートコンプリートを使えるように (#12643)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* rich autocomplete for use in profiles, announcements, and channel descriptions

* implementation omissions

* add tab, apply to page editor, and fix something

* componentization

* fix nyaize doesn't working in profile preview

* detach autocomplete instance when unmounted

* fix: mismatched camelCase

* remove unused / unnecessary styles

* update CHANGELOG.md

* fix lint

* remove dump.rdb

* props.richAutocomplete -> autocomplete

* Update packages/frontend/src/scripts/autocomplete.ts

* clarify namings
メンションなども「MFM」に含まれるのか自信がなかったのでrichSyntaxなどとぼかしていましたが、含むようなので変更しました

* tweak

* Update MkFormDialog.vue

* rename

---------

Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
---
 packages/frontend/src/components/MkTextarea.vue | 29 ++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

(limited to 'packages/frontend/src/components/MkTextarea.vue')

diff --git a/packages/frontend/src/components/MkTextarea.vue b/packages/frontend/src/components/MkTextarea.vue
index 7c1ddcbbed..23fdd5bfe1 100644
--- a/packages/frontend/src/components/MkTextarea.vue
+++ b/packages/frontend/src/components/MkTextarea.vue
@@ -26,16 +26,21 @@ SPDX-License-Identifier: AGPL-3.0-only
 		></textarea>
 	</div>
 	<div :class="$style.caption"><slot name="caption"></slot></div>
+	<button style="font-size: 0.85em;" class="_textButton" type="button" @click="preview = !preview">{{ i18n.ts.preview }}</button>
+	<div v-show="preview" v-panel :class="$style.mfmPreview">
+		<Mfm :text="v"/>
+	</div>
 
 	<MkButton v-if="manualSave && changed" primary :class="$style.save" @click="updated"><i class="ti ti-device-floppy"></i> {{ i18n.ts.save }}</MkButton>
 </div>
 </template>
 
 <script lang="ts" setup>
-import { onMounted, nextTick, ref, watch, computed, toRefs, shallowRef } from 'vue';
+import { onMounted, onUnmounted, nextTick, ref, watch, computed, toRefs, shallowRef } from 'vue';
 import { debounce } from 'throttle-debounce';
 import MkButton from '@/components/MkButton.vue';
 import { i18n } from '@/i18n.js';
+import { Autocomplete, SuggestionType } from '@/scripts/autocomplete.js';
 
 const props = defineProps<{
 	modelValue: string | null;
@@ -46,6 +51,8 @@ const props = defineProps<{
 	placeholder?: string;
 	autofocus?: boolean;
 	autocomplete?: string;
+	mfmAutocomplete?: boolean | SuggestionType[],
+	mfmPreview?: boolean;
 	spellcheck?: boolean;
 	debounce?: boolean;
 	manualSave?: boolean;
@@ -68,6 +75,8 @@ const changed = ref(false);
 const invalid = ref(false);
 const filled = computed(() => v.value !== '' && v.value != null);
 const inputEl = shallowRef<HTMLTextAreaElement>();
+const preview = ref(false);
+let autocomplete: Autocomplete;
 
 const focus = () => inputEl.value.focus();
 const onInput = (ev) => {
@@ -113,6 +122,16 @@ onMounted(() => {
 			focus();
 		}
 	});
+
+	if (props.mfmAutocomplete) {
+		autocomplete = new Autocomplete(inputEl.value, v, props.mfmAutocomplete === true ? null : props.mfmAutocomplete);
+	}
+});
+
+onUnmounted(() => {
+	if (autocomplete) {
+		autocomplete.detach();
+	}
 });
 </script>
 
@@ -194,4 +213,12 @@ onMounted(() => {
 .save {
 	margin: 8px 0 0 0;
 }
+
+.mfmPreview {
+  padding: 12px;
+  border-radius: var(--radius);
+  box-sizing: border-box;
+  min-height: 130px;
+	pointer-events: none;
+}
 </style>
-- 
cgit v1.2.3-freya


From c41924399b1c0b06b451159644789fe00a29d7da Mon Sep 17 00:00:00 2001
From: 1STEP621 <86859447+1STEP621@users.noreply.github.com>
Date: Fri, 15 Dec 2023 17:18:31 +0900
Subject: コード入力ボックスでTabを入力できるように (#12671)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 packages/frontend/src/components/MkTextarea.vue         | 10 ++++++++++
 packages/frontend/src/pages/flash/flash-edit.vue        |  2 +-
 packages/frontend/src/pages/registry.value.vue          |  2 +-
 packages/frontend/src/pages/settings/custom-css.vue     |  2 +-
 packages/frontend/src/pages/settings/plugin.install.vue |  2 +-
 packages/frontend/src/pages/settings/theme.install.vue  |  2 +-
 packages/frontend/src/pages/theme-editor.vue            |  2 +-
 7 files changed, 16 insertions(+), 6 deletions(-)

(limited to 'packages/frontend/src/components/MkTextarea.vue')

diff --git a/packages/frontend/src/components/MkTextarea.vue b/packages/frontend/src/components/MkTextarea.vue
index 23fdd5bfe1..696787122e 100644
--- a/packages/frontend/src/components/MkTextarea.vue
+++ b/packages/frontend/src/components/MkTextarea.vue
@@ -91,6 +91,16 @@ const onKeydown = (ev: KeyboardEvent) => {
 	if (ev.code === 'Enter') {
 		emit('enter');
 	}
+
+	if (props.code && ev.key === 'Tab') {
+		const pos = inputEl.value?.selectionStart ?? 0;
+		const posEnd = inputEl.value?.selectionEnd ?? v.value.length;
+		v.value = v.value.slice(0, pos) + '\t' + v.value.slice(posEnd);
+		nextTick(() => {
+			inputEl.value?.setSelectionRange(pos + 1, pos + 1);
+		});
+		ev.preventDefault();
+	}
 };
 
 const updated = () => {
diff --git a/packages/frontend/src/pages/flash/flash-edit.vue b/packages/frontend/src/pages/flash/flash-edit.vue
index cfda4d6556..365b054f7a 100644
--- a/packages/frontend/src/pages/flash/flash-edit.vue
+++ b/packages/frontend/src/pages/flash/flash-edit.vue
@@ -15,7 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				<template #label>{{ i18n.ts._play.summary }}</template>
 			</MkTextarea>
 			<MkButton primary @click="selectPreset">{{ i18n.ts.selectFromPresets }}<i class="ti ti-chevron-down"></i></MkButton>
-			<MkTextarea v-model="script" class="_monospace" tall spellcheck="false">
+			<MkTextarea v-model="script" code tall spellcheck="false">
 				<template #label>{{ i18n.ts._play.script }}</template>
 			</MkTextarea>
 			<div class="_buttons">
diff --git a/packages/frontend/src/pages/registry.value.vue b/packages/frontend/src/pages/registry.value.vue
index 29406ec83c..1b2cf9f237 100644
--- a/packages/frontend/src/pages/registry.value.vue
+++ b/packages/frontend/src/pages/registry.value.vue
@@ -26,7 +26,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 					</MkKeyValue>
 				</FormSplit>
 
-				<MkTextarea v-model="valueForEditor" tall class="_monospace">
+				<MkTextarea v-model="valueForEditor" tall code>
 					<template #label>{{ i18n.ts.value }} (JSON)</template>
 				</MkTextarea>
 
diff --git a/packages/frontend/src/pages/settings/custom-css.vue b/packages/frontend/src/pages/settings/custom-css.vue
index e33e778246..8e52686c12 100644
--- a/packages/frontend/src/pages/settings/custom-css.vue
+++ b/packages/frontend/src/pages/settings/custom-css.vue
@@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <div class="_gaps_m">
 	<FormInfo warn>{{ i18n.ts.customCssWarn }}</FormInfo>
 
-	<MkTextarea v-model="localCustomCss" manualSave tall class="_monospace" style="tab-size: 2;">
+	<MkTextarea v-model="localCustomCss" manualSave tall code style="tab-size: 2;">
 		<template #label>CSS</template>
 	</MkTextarea>
 </div>
diff --git a/packages/frontend/src/pages/settings/plugin.install.vue b/packages/frontend/src/pages/settings/plugin.install.vue
index f304d777a5..44472d47d9 100644
--- a/packages/frontend/src/pages/settings/plugin.install.vue
+++ b/packages/frontend/src/pages/settings/plugin.install.vue
@@ -7,7 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 <div class="_gaps_m">
 	<FormInfo warn>{{ i18n.ts._plugin.installWarn }}</FormInfo>
 
-	<MkTextarea v-model="code" tall>
+	<MkTextarea v-model="code" tall code>
 		<template #label>{{ i18n.ts.code }}</template>
 	</MkTextarea>
 
diff --git a/packages/frontend/src/pages/settings/theme.install.vue b/packages/frontend/src/pages/settings/theme.install.vue
index c2ca53c743..0f3fbad0b7 100644
--- a/packages/frontend/src/pages/settings/theme.install.vue
+++ b/packages/frontend/src/pages/settings/theme.install.vue
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 
 <template>
 <div class="_gaps_m">
-	<MkTextarea v-model="installThemeCode">
+	<MkTextarea v-model="installThemeCode" code>
 		<template #label>{{ i18n.ts._theme.code }}</template>
 	</MkTextarea>
 
diff --git a/packages/frontend/src/pages/theme-editor.vue b/packages/frontend/src/pages/theme-editor.vue
index 0d137137fc..c4138e23de 100644
--- a/packages/frontend/src/pages/theme-editor.vue
+++ b/packages/frontend/src/pages/theme-editor.vue
@@ -51,7 +51,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 				<template #label>{{ i18n.ts.editCode }}</template>
 
 				<div class="_gaps_m">
-					<MkTextarea v-model="themeCode" tall>
+					<MkTextarea v-model="themeCode" tall code>
 						<template #label>{{ i18n.ts._theme.code }}</template>
 					</MkTextarea>
 					<MkButton primary @click="applyThemeCode">{{ i18n.ts.apply }}</MkButton>
-- 
cgit v1.2.3-freya


From 272dc208b4c71ceb0f3d4308460577f3c4d41758 Mon Sep 17 00:00:00 2001
From: 1STEP621 <86859447+1STEP621@users.noreply.github.com>
Date: Fri, 15 Dec 2023 17:57:31 +0900
Subject: Fix(frontend):
 ほとんどのMkTextareaでMFMプレビューが表示されてしまっている問題を修正
 (#12672)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* ほとんどのMkTextareaでMFMのプレビューが表示されてしまっている不具合を修正

* refactor

* そもそも #12130 でプロフィールはnyaizeされない仕様にもどっていたらしいので修正
---
 packages/frontend/src/components/MkTextarea.vue  | 6 +++---
 packages/frontend/src/pages/settings/profile.vue | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

(limited to 'packages/frontend/src/components/MkTextarea.vue')

diff --git a/packages/frontend/src/components/MkTextarea.vue b/packages/frontend/src/components/MkTextarea.vue
index 696787122e..3ee374300a 100644
--- a/packages/frontend/src/components/MkTextarea.vue
+++ b/packages/frontend/src/components/MkTextarea.vue
@@ -17,7 +17,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 			:readonly="readonly"
 			:placeholder="placeholder"
 			:pattern="pattern"
-			:autocomplete="autocomplete"
+			:autocomplete="props.autocomplete"
 			:spellcheck="spellcheck"
 			@focus="focused = true"
 			@blur="focused = false"
@@ -26,8 +26,8 @@ SPDX-License-Identifier: AGPL-3.0-only
 		></textarea>
 	</div>
 	<div :class="$style.caption"><slot name="caption"></slot></div>
-	<button style="font-size: 0.85em;" class="_textButton" type="button" @click="preview = !preview">{{ i18n.ts.preview }}</button>
-	<div v-show="preview" v-panel :class="$style.mfmPreview">
+	<button v-if="mfmPreview" style="font-size: 0.85em;" class="_textButton" type="button" @click="preview = !preview">{{ i18n.ts.preview }}</button>
+	<div v-if="mfmPreview" v-show="preview" v-panel :class="$style.mfmPreview">
 		<Mfm :text="v"/>
 	</div>
 
diff --git a/packages/frontend/src/pages/settings/profile.vue b/packages/frontend/src/pages/settings/profile.vue
index 1381042c39..83cd698e66 100644
--- a/packages/frontend/src/pages/settings/profile.vue
+++ b/packages/frontend/src/pages/settings/profile.vue
@@ -17,7 +17,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 		<template #label>{{ i18n.ts._profile.name }}</template>
 	</MkInput>
 
-	<MkTextarea v-model="profile.description" :max="500" tall manualSave mfmAutocomplete :mfmPreview="true" :nyaize="$i?.isCat ? 'respect' : undefined" :author="($i as Misskey.entities.UserLite)">
+	<MkTextarea v-model="profile.description" :max="500" tall manualSave mfmAutocomplete :mfmPreview="true">
 		<template #label>{{ i18n.ts._profile.description }}</template>
 		<template #caption>{{ i18n.ts._profile.youCanIncludeHashtags }}</template>
 	</MkTextarea>
-- 
cgit v1.2.3-freya

