summaryrefslogtreecommitdiff
path: root/packages/frontend/src/pages
diff options
context:
space:
mode:
author1STEP621 <86859447+1STEP621@users.noreply.github.com>2023-12-14 13:11:23 +0900
committerGitHub <noreply@github.com>2023-12-14 13:11:23 +0900
commitb33fe530476f89282e1e554aecf0cfe82e6d6edd (patch)
treefcf410283db79cdf3883a43543887a5836ed6f2f /packages/frontend/src/pages
parentrefactor(frontend) $i の型情報にtokenを追加 (#12649) (diff)
downloadmisskey-b33fe530476f89282e1e554aecf0cfe82e6d6edd.tar.gz
misskey-b33fe530476f89282e1e554aecf0cfe82e6d6edd.tar.bz2
misskey-b33fe530476f89282e1e554aecf0cfe82e6d6edd.zip
Enhance(frontend): MFMや絵文字が使える入力ボックスでオートコンプリートを使えるように (#12643)
* 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>
Diffstat (limited to 'packages/frontend/src/pages')
-rw-r--r--packages/frontend/src/pages/admin/announcements.vue4
-rw-r--r--packages/frontend/src/pages/channel-editor.vue4
-rw-r--r--packages/frontend/src/pages/clip.vue1
-rw-r--r--packages/frontend/src/pages/my-clips/index.vue1
-rw-r--r--packages/frontend/src/pages/page-editor/els/page-editor.el.text.vue16
-rw-r--r--packages/frontend/src/pages/settings/profile.vue7
6 files changed, 24 insertions, 9 deletions
diff --git a/packages/frontend/src/pages/admin/announcements.vue b/packages/frontend/src/pages/admin/announcements.vue
index 92070dc6c6..e4bbe15955 100644
--- a/packages/frontend/src/pages/admin/announcements.vue
+++ b/packages/frontend/src/pages/admin/announcements.vue
@@ -25,7 +25,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkInput v-model="announcement.title">
<template #label>{{ i18n.ts.title }}</template>
</MkInput>
- <MkTextarea v-model="announcement.text">
+ <MkTextarea v-model="announcement.text" mfmAutocomplete :mfmPreview="true">
<template #label>{{ i18n.ts.text }}</template>
</MkTextarea>
<MkInput v-model="announcement.imageUrl" type="url">
@@ -75,7 +75,6 @@ import { ref, computed } from 'vue';
import XHeader from './_header_.vue';
import MkButton from '@/components/MkButton.vue';
import MkInput from '@/components/MkInput.vue';
-import MkTextarea from '@/components/MkTextarea.vue';
import MkSwitch from '@/components/MkSwitch.vue';
import MkRadios from '@/components/MkRadios.vue';
import MkInfo from '@/components/MkInfo.vue';
@@ -83,6 +82,7 @@ import * as os from '@/os.js';
import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';
import MkFolder from '@/components/MkFolder.vue';
+import MkTextarea from '@/components/MkTextarea.vue';
const announcements = ref<any[]>([]);
diff --git a/packages/frontend/src/pages/channel-editor.vue b/packages/frontend/src/pages/channel-editor.vue
index af382bb137..f16b8709f3 100644
--- a/packages/frontend/src/pages/channel-editor.vue
+++ b/packages/frontend/src/pages/channel-editor.vue
@@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<template #label>{{ i18n.ts.name }}</template>
</MkInput>
- <MkTextarea v-model="description">
+ <MkTextarea v-model="description" mfmAutocomplete :mfmPreview="true">
<template #label>{{ i18n.ts.description }}</template>
</MkTextarea>
@@ -70,7 +70,6 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { computed, ref, watch, defineAsyncComponent } from 'vue';
-import MkTextarea from '@/components/MkTextarea.vue';
import MkButton from '@/components/MkButton.vue';
import MkInput from '@/components/MkInput.vue';
import MkColorInput from '@/components/MkColorInput.vue';
@@ -81,6 +80,7 @@ import { definePageMetadata } from '@/scripts/page-metadata.js';
import { i18n } from '@/i18n.js';
import MkFolder from '@/components/MkFolder.vue';
import MkSwitch from '@/components/MkSwitch.vue';
+import MkTextarea from '@/components/MkTextarea.vue';
const Sortable = defineAsyncComponent(() => import('vuedraggable').then(x => x.default));
diff --git a/packages/frontend/src/pages/clip.vue b/packages/frontend/src/pages/clip.vue
index 2ea0312c7e..3c94db82d7 100644
--- a/packages/frontend/src/pages/clip.vue
+++ b/packages/frontend/src/pages/clip.vue
@@ -101,6 +101,7 @@ const headerActions = computed(() => clip.value && isOwned.value ? [{
type: 'string',
required: false,
multiline: true,
+ treatAsMfm: true,
label: i18n.ts.description,
default: clip.value.description,
},
diff --git a/packages/frontend/src/pages/my-clips/index.vue b/packages/frontend/src/pages/my-clips/index.vue
index 2390617954..85c016187d 100644
--- a/packages/frontend/src/pages/my-clips/index.vue
+++ b/packages/frontend/src/pages/my-clips/index.vue
@@ -60,6 +60,7 @@ async function create() {
type: 'string',
required: false,
multiline: true,
+ treatAsMfm: true,
label: i18n.ts.description,
},
isPublic: {
diff --git a/packages/frontend/src/pages/page-editor/els/page-editor.el.text.vue b/packages/frontend/src/pages/page-editor/els/page-editor.el.text.vue
index 4f47a77bdd..643e8ecdad 100644
--- a/packages/frontend/src/pages/page-editor/els/page-editor.el.text.vue
+++ b/packages/frontend/src/pages/page-editor/els/page-editor.el.text.vue
@@ -9,16 +9,17 @@ SPDX-License-Identifier: AGPL-3.0-only
<template #header><i class="ti ti-align-left"></i> {{ i18n.ts._pages.blocks.text }}</template>
<section>
- <textarea v-model="text" :class="$style.textarea"></textarea>
+ <textarea ref="inputEl" v-model="text" :class="$style.textarea"></textarea>
</section>
</XContainer>
</template>
<script lang="ts" setup>
/* eslint-disable vue/no-mutating-props */
-import { watch, ref } from 'vue';
+import { watch, ref, shallowRef, onMounted, onUnmounted } from 'vue';
import XContainer from '../page-editor.container.vue';
import { i18n } from '@/i18n.js';
+import { Autocomplete } from '@/scripts/autocomplete.js';
const props = defineProps<{
modelValue: any
@@ -28,7 +29,10 @@ const emit = defineEmits<{
(ev: 'update:modelValue', value: any): void;
}>();
+let autocomplete: Autocomplete;
+
const text = ref(props.modelValue.text ?? '');
+const inputEl = shallowRef<HTMLTextAreaElement | null>(null);
watch(text, () => {
emit('update:modelValue', {
@@ -36,6 +40,14 @@ watch(text, () => {
text: text.value,
});
});
+
+onMounted(() => {
+ autocomplete = new Autocomplete(inputEl.value, text);
+});
+
+onUnmounted(() => {
+ autocomplete.detach();
+});
</script>
<style lang="scss" module>
diff --git a/packages/frontend/src/pages/settings/profile.vue b/packages/frontend/src/pages/settings/profile.vue
index 5f0d1aee51..1381042c39 100644
--- a/packages/frontend/src/pages/settings/profile.vue
+++ b/packages/frontend/src/pages/settings/profile.vue
@@ -13,11 +13,11 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkButton primary rounded :class="$style.bannerEdit" @click="changeBanner">{{ i18n.ts._profile.changeBanner }}</MkButton>
</div>
- <MkInput v-model="profile.name" :max="30" manualSave>
+ <MkInput v-model="profile.name" :max="30" manualSave :mfmAutocomplete="['emoji']">
<template #label>{{ i18n.ts._profile.name }}</template>
</MkInput>
- <MkTextarea v-model="profile.description" :max="500" tall manualSave>
+ <MkTextarea v-model="profile.description" :max="500" tall manualSave mfmAutocomplete :mfmPreview="true" :nyaize="$i?.isCat ? 'respect' : undefined" :author="($i as Misskey.entities.UserLite)">
<template #label>{{ i18n.ts._profile.description }}</template>
<template #caption>{{ i18n.ts._profile.youCanIncludeHashtags }}</template>
</MkTextarea>
@@ -112,10 +112,10 @@ SPDX-License-Identifier: AGPL-3.0-only
<script lang="ts" setup>
import { computed, reactive, ref, watch, defineAsyncComponent } from 'vue';
+import Misskey from 'misskey-js';
import XAvatarDecoration from './profile.avatar-decoration.vue';
import MkButton from '@/components/MkButton.vue';
import MkInput from '@/components/MkInput.vue';
-import MkTextarea from '@/components/MkTextarea.vue';
import MkSwitch from '@/components/MkSwitch.vue';
import MkSelect from '@/components/MkSelect.vue';
import FormSplit from '@/components/form/split.vue';
@@ -130,6 +130,7 @@ import { definePageMetadata } from '@/scripts/page-metadata.js';
import { claimAchievement } from '@/scripts/achievements.js';
import { defaultStore } from '@/store.js';
import MkInfo from '@/components/MkInfo.vue';
+import MkTextarea from '@/components/MkTextarea.vue';
const Sortable = defineAsyncComponent(() => import('vuedraggable').then(x => x.default));