Skip to content

絵文字のショートコードのサジェストを実装しました#76

Merged
totegamma merged 2 commits into
mainfrom
emojiPreview
May 12, 2026
Merged

絵文字のショートコードのサジェストを実装しました#76
totegamma merged 2 commits into
mainfrom
emojiPreview

Conversation

@inugamine
Copy link
Copy Markdown
Contributor

概要

投稿作成中に :shortcode を手入力すると絵文字の候補がサジェスト表示され、タップで補完できるようになります。また、手打ちで完全な :shortcode: を入力した場合も、絵文字パッケージから自動で解決してプレビューに反映されます。

変更内容

1. 絵文字サジェスト (EmojiSuggestion.tsx) — 新規

  • テキストエリアのカーソル位置を input / click / keyup イベントで追跡
  • カーソル直前のテキストを /:(\w+)$/ で検査し、:xxx パターンを検出
  • emojiPicker.search() で候補を取得し、水平スクロール可能なストリップとして表示
  • タップすると :shortcode: に補完され、emojiDict にも自動登録
  • onMouseDownpreventDefault() して textarea の blur を防止
  • requestAnimationFrame でカーソル位置を補完後の正しい位置に設定

2. 手打ちショートコードの自動解決 (Composer.tsx) — 変更

  • draft の変更を監視し、:shortcode: パターンを正規表現で検出
  • emojiPicker.packages から完全一致で検索し、見つかった絵文字を emojiDict に追加
  • emojiDictRef を使って emojiDict を deps から外し、無限ループを回避

変更ファイル

ファイル 種別
app/src/components/EmojiSuggestion.tsx 新規
app/src/components/Composer.tsx 変更
web/src/components/EmojiSuggestion.tsx 新規
web/src/components/Composer.tsx 変更

Copy link
Copy Markdown
Member

@totegamma totegamma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ありがとうございます!
現在のconcrnt-worldと一部仕様が違う部分があるので、そこだけ揃えたい感じです!
web側は今のwebみたいに文字入力部分にオーバーレイで絵文字の候補を表示・カーソルで移動できるUIに今後変更したいと思いますが、一旦はこれで大丈夫です!

Comment thread app/src/components/Composer.tsx Outdated
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])

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

enterで確定でいいので、ここはなくてもいいかも?

Comment thread app/src/components/EmojiSuggestion.tsx Outdated

ta.addEventListener('input', updateCursor)
ta.addEventListener('click', updateCursor)
ta.addEventListener('keyup', updateCursor)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keyupで、Enterなら確定というロジックを入れたい
concrnt-worldの対象コード: https://github.com/concrnt/concrnt-world/blob/develop/app/src/components/Editor/EmojiSuggestion.tsx#L61-L81

Copy link
Copy Markdown
Member

@totegamma totegamma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ありがとうございます!!!!!

@totegamma totegamma merged commit a71be43 into main May 12, 2026
1 check passed
@totegamma totegamma deleted the emojiPreview branch May 12, 2026 13:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants