絵文字のショートコードのサジェストを実装しました#76
Merged
Merged
Conversation
totegamma
requested changes
May 12, 2026
Member
totegamma
left a comment
There was a problem hiding this comment.
ありがとうございます!
現在のconcrnt-worldと一部仕様が違う部分があるので、そこだけ揃えたい感じです!
web側は今のwebみたいに文字入力部分にオーバーレイで絵文字の候補を表示・カーソルで移動できるUIに今後変更したいと思いますが、一旦はこれで大丈夫です!
Comment on lines
+50
to
+77
| // 手打ちショートコードの自動解決(emojiDictRefで無限ループ回避) | ||
| const emojiDictRef = useRef(emojiDict) | ||
| emojiDictRef.current = emojiDict | ||
|
|
||
| useEffect(() => { | ||
| const shortcodeRegex = /:([\w+-]+):/g | ||
| const matches = [...draft.matchAll(shortcodeRegex)] | ||
| if (matches.length === 0) return | ||
|
|
||
| const currentDict = emojiDictRef.current | ||
| const newEntries: Record<string, { imageURL: string }> = {} | ||
| for (const match of matches) { | ||
| const code = match[1] | ||
| if (currentDict[code]) continue | ||
| for (const pkg of emojiPicker.packages) { | ||
| const found = pkg.emojis.find((e) => e.shortcode === code) | ||
| if (found) { | ||
| newEntries[code] = { imageURL: found.imageURL } | ||
| break | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (Object.keys(newEntries).length > 0) { | ||
| setEmojiDict((prev) => ({ ...prev, ...newEntries })) | ||
| } | ||
| }, [draft, emojiPicker.packages]) | ||
|
|
|
|
||
| ta.addEventListener('input', updateCursor) | ||
| ta.addEventListener('click', updateCursor) | ||
| ta.addEventListener('keyup', updateCursor) |
Member
There was a problem hiding this comment.
keyupで、Enterなら確定というロジックを入れたい
concrnt-worldの対象コード: https://github.com/concrnt/concrnt-world/blob/develop/app/src/components/Editor/EmojiSuggestion.tsx#L61-L81
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
投稿作成中に
:shortcodeを手入力すると絵文字の候補がサジェスト表示され、タップで補完できるようになります。また、手打ちで完全な:shortcode:を入力した場合も、絵文字パッケージから自動で解決してプレビューに反映されます。変更内容
1. 絵文字サジェスト (
EmojiSuggestion.tsx) — 新規input/click/keyupイベントで追跡/:(\w+)$/で検査し、:xxxパターンを検出emojiPicker.search()で候補を取得し、水平スクロール可能なストリップとして表示:shortcode:に補完され、emojiDictにも自動登録onMouseDownでpreventDefault()して textarea の blur を防止requestAnimationFrameでカーソル位置を補完後の正しい位置に設定2. 手打ちショートコードの自動解決 (
Composer.tsx) — 変更draftの変更を監視し、:shortcode:パターンを正規表現で検出emojiPicker.packagesから完全一致で検索し、見つかった絵文字をemojiDictに追加emojiDictRefを使ってemojiDictを deps から外し、無限ループを回避変更ファイル
app/src/components/EmojiSuggestion.tsxapp/src/components/Composer.tsxweb/src/components/EmojiSuggestion.tsxweb/src/components/Composer.tsx