emojiAutoSpacing

This commit is contained in:
fly_mc 2024-11-15 13:29:09 +08:00
parent fdd190ec75
commit 3aa0a5ea9b
2 changed files with 65 additions and 42 deletions

View file

@ -996,49 +996,54 @@ function insertMention() {
}
async function insertEmoji(ev: MouseEvent) {
textAreaReadOnly.value = true;
const target = ev.currentTarget ?? ev.target;
if (target == null) return;
textAreaReadOnly.value = true;
const target = ev.currentTarget ?? ev.target;
if (target == null) return;
// emojiPickertextarea
// focustrapinsertTextAtCursor
// 稿
// See: https://github.com/misskey-dev/misskey/pull/14282
// https://github.com/misskey-dev/misskey/issues/14274
// emojiPickertextarea
// focustrapinsertTextAtCursor
// 稿
// See: https://github.com/misskey-dev/misskey/pull/14282
// https://github.com/misskey-dev/misskey/issues/14274
let pos = textareaEl.value?.selectionStart ?? 0;
let posEnd = textareaEl.value?.selectionEnd ?? text.value.length;
let pos = textareaEl.value?.selectionStart ?? 0;
let posEnd = textareaEl.value?.selectionEnd ?? text.value.length;
const addSpacing = (before: string, emoji: string) => {
let result = emoji;
const needSpaceBefore = before.length > 0 && !before.endsWith(' ');
const addSpacing = (before: string, after: string, emoji: string) => {
let result = emoji;
const needSpaceBefore = before.length > 0 && !before.endsWith(' ');
const needSpaceAfter = !after.startsWith(' ');
if (needSpaceBefore) result = ' ' + result;
result = result + ' ';
if (needSpaceBefore) result = ' ' + result;
if (needSpaceAfter) result = result + ' ';
return result;
return {
text: result,
addedSpaces: (needSpaceBefore ? 1 : 0) + (needSpaceAfter ? 1 : 0),
};
};
emojiPicker.show(
target as HTMLElement,
emoji => {
const textBefore = text.value.substring(0, pos);
const textAfter = text.value.substring(posEnd);
emojiPicker.show(
target as HTMLElement,
(emoji) => {
const textBefore = text.value.substring(0, pos);
const textAfter = text.value.substring(posEnd);
const processedEmoji = defaultStore.state.emojiAutoSpacing
? addSpacing(textBefore, emoji)
: emoji + ' ';
const processed = defaultStore.state.emojiAutoSpacing
? addSpacing(textBefore, textAfter, emoji)
: { text: emoji + ' ', addedSpaces: 1 };
text.value = textBefore + processedEmoji + textAfter;
text.value = textBefore + processed.text + textAfter;
pos += processedEmoji.length;
posEnd += processedEmoji.length;
},
() => {
textAreaReadOnly.value = false;
nextTick(() => focus());
},
);
const newPos = pos + emoji.length + processed.addedSpaces;
pos = newPos;
posEnd = newPos;
},
() => {
textAreaReadOnly.value = false;
nextTick(() => focus());
},
);
}
async function insertMfmFunction(ev: MouseEvent) {

View file

@ -7,6 +7,7 @@ import { nextTick, Ref, ref, defineAsyncComponent } from 'vue';
import getCaretCoordinates from 'textarea-caret';
import { toASCII } from 'punycode/';
import { popup } from '@/os.js';
import { defaultStore } from '@/store.js';
export type SuggestionType = 'user' | 'hashtag' | 'emoji' | 'mfmTag' | 'mfmParam';
@ -265,20 +266,37 @@ export class Autocomplete {
});
} else if (type === 'emoji') {
const source = this.text;
const before = source.substring(0, caret);
const trimmedBefore = before.substring(0, before.lastIndexOf(':'));
const after = source.substring(caret);
// 挿入
this.text = trimmedBefore + value + after;
if (defaultStore.state.emojiAutoSpacing) {
const needSpaceBefore = trimmedBefore.length > 0 && !trimmedBefore.endsWith(' ');
const needSpaceAfter = !after.startsWith(' ');
// キャレットを戻す
nextTick(() => {
this.textarea.focus();
const pos = trimmedBefore.length + value.length;
this.textarea.setSelectionRange(pos, pos);
});
this.text = trimmedBefore +
(needSpaceBefore ? ' ' : '') +
value +
(needSpaceAfter ? ' ' : '') +
after;
nextTick(() => {
this.textarea.focus();
const pos = trimmedBefore.length +
(needSpaceBefore ? 1 : 0) +
value.length +
(needSpaceAfter ? 1 : 0);
this.textarea.setSelectionRange(pos, pos);
});
} else {
this.text = trimmedBefore + value + after;
nextTick(() => {
this.textarea.focus();
const pos = trimmedBefore.length + value.length;
this.textarea.setSelectionRange(pos, pos);
});
}
} else if (type === 'mfmTag') {
const source = this.text;