Skip to content

speakブロックに引数を渡し、アバターと名前を表示#8932

Merged
komagata merged 16 commits intomainfrom
feature/add-arguments-to-speak-block
Jul 28, 2025
Merged

speakブロックに引数を渡し、アバターと名前を表示#8932
komagata merged 16 commits intomainfrom
feature/add-arguments-to-speak-block

Conversation

@su-su-su-su
Copy link
Copy Markdown
Contributor

@su-su-su-su su-su-su-su commented Jul 14, 2025

Issue

概要

Markdown内の独自記法のspeakブロック機能を追加しました。
引数として@ユーザー名(名前, 画像URL)名前のみの3パターンに対応するようにしています。
それぞれに適したアバターと名前を表示。
(名前, 画像URL)の画像はランダムです。

変更確認方法

  1. feature/add-arguments-to-speak-blockをローカルに取り込む
  2. foreman start -f Procfile.devでサーバーを立ち上げます。
  3. komagataでログイン
  4. http://localhost:3000/articles/new で記事を作成。本文を以下にする
  5. プレビュー画面がScreenshotの変更後のようになっていることを確認
  6. 公開後画面がScreenshotの変更後のようになっていることを確認
:::speak @machida
@ユーザー名ver
:::

:::speak(ゲスト, https://picsum.photos/150)
(名前, 画像URL)ver
:::

:::speak ゲスト
名前のみver
:::

Screenshot

変更前

プレビュー画面

image

公開後画面

image

変更後

プレビュー画面

image

公開後画面

image

Summary by CodeRabbit

Summary by CodeRabbit

  • 新機能
    • 「speak」コンテナで、話者名やアバター画像URLの指定が可能になり、柔軟な話者ブロック表示に対応しました。
    • ユーザー名に「@」を含む場合はユーザーリンク付きアバター、含まない場合はデフォルトアバターで表示されます。
  • スタイル調整
    • 「speak」話者ブロック内のアンカーとスパン要素に対してフレックスレイアウトを適用し、アイコンやテキストの間隔を改善しました。
    • 話者アバター画像の下マージンを削除し、見た目を整えました。
  • テスト追加
    • 「speak」ブロックの多様な引数形式に対応したレンダリングの動作確認テストを追加しました。

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jul 14, 2025

"""

Walkthrough

「speak」コンテナプラグインにカスタムマーカー「:」とバリデーション関数が追加され、スピーカー名やアバターURLのパースとレンダリングが拡張されました。ユーザーリンクの有無に応じた表示も可能になっています。加えて、スピーカー表示のCSSスタイルがflexレイアウト対応で調整されました。さらに、システムテストに新たな「speak」ブロックのレンダリング検証が追加されました。加えて、DBスキーマの複数テーブルで文字列長制限の削除やカラム追加・削除、インデックス名変更などの変更が含まれています。

Changes

ファイルパス 変更内容概要
app/javascript/markdown-it-container-speak.js 「speak」コンテナにカスタムマーカー「:」とバリデーション関数追加。スピーカー情報のパースとレンダリングを拡張し、アバターURLやユーザーリンク条件を追加
app/javascript/stylesheets/config/mixins/_long-text-style.sass .speak__speakerの子要素(a, span)にflexレイアウト適用、画像のマージン調整を追加
test/system/markdown_test.rb 「speak」ブロックの異なる引数形式に対するレンダリング検証のシステムテストを2件追加
db/schema.rb 複数テーブルの文字列長制限削除、カラム追加・削除・順序変更、インデックス名変更、テーブル削除などのスキーマ変更を実施

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~40 minutes

Possibly related PRs

  • spanタグのタイポ修正 #8907: 「speak」コンテナのレンダリングロジック拡張とリファクタリングに関するPR。spanタグのtypo修正を含み、本PRと直接関連。

Poem

うさぎはMarkdownをぴょんと跳ね、
スピーカーの顔も自由自在。
名前もアイコンも選べるよ、
ユーザーリンクもおまかせさ。
みんなで話す新しい春、
:speak:で輪が広がるね!
(∩・x・)∩
"""

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 RuboCop (1.76.1)
test/system/markdown_test.rb

rubocop-minitest extension supports plugin, specify plugins: rubocop-minitest instead of require: rubocop-minitest in /.rubocop.yml.
For more information, see https://docs.rubocop.org/rubocop/plugin_migration_guide.html.
rubocop-capybara extension supports plugin, specify plugins: rubocop-capybara instead of require: rubocop-capybara in /.rubocop.yml.
For more information, see https://docs.rubocop.org/rubocop/plugin_migration_guide.html.
Unable to find gem rubocop-fjord; is the gem installed? Gem::MissingSpecError
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:309:in rescue in gem_config_path' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:293:in gem_config_path'
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:84:in block (2 levels) in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:82:in reverse_each'
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:82:in block in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:76:in each_pair'
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:76:in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader.rb:66:in load_file'
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_store.rb:29:in options_config=' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/cli.rb:160:in act_on_options'
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/cli.rb:47:in block in run' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/cli.rb:81:in profile_if_needed'
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/cli.rb:43:in run' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/exe/rubocop:19:in <top (required)>'
/usr/local/bin/rubocop:25:in load' /usr/local/bin/rubocop:25:in

'

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1a86535 and e994314.

📒 Files selected for processing (3)
  • app/javascript/markdown-it-container-speak.js (1 hunks)
  • app/javascript/stylesheets/config/mixins/_long-text-style.sass (2 hunks)
  • test/system/markdown_test.rb (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • app/javascript/stylesheets/config/mixins/_long-text-style.sass
  • app/javascript/markdown-it-container-speak.js
  • test/system/markdown_test.rb
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build_and_test
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/add-arguments-to-speak-block

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (1)
app/javascript/markdown-it-container-speak.js (1)

38-58: コード重複の削除を検討

3つの異なる分岐で類似のHTMLテンプレートが生成されています。保守性向上のため、共通のヘルパー関数を作成することを検討してください。

以下のような共通関数を作成できます:

function createSpeakHTML(speakerName, avatarSrc, userLink = null, title = null) {
  const linkAttrs = userLink ? `href="${userLink}"` : ''
  const imgAttrs = title ? `title="${title}"` : `title="${speakerName}"`
  const imgClass = userLink ? 'js-user-icon a-user-emoji' : 'a-user-emoji speak__speaker-avatar'
  const dataUser = userLink ? `data-user="${speakerName}"` : ''
  
  return `<div class="speak">
            <div class="speak__speaker">
              <a ${linkAttrs} class="a-user-emoji-link">
                <img src="${avatarSrc}" alt="${speakerName}" ${imgAttrs} class="${imgClass}" ${dataUser}>
                <span class="speak__speaker-name">${speakerName}</span>
              </a>
            </div>
            <div class="speak__body">`
}
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4a0875c and 5385a90.

📒 Files selected for processing (1)
  • app/javascript/markdown-it-container-speak.js (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.js

Instructions used from:

Sources:
⚙️ CodeRabbit Configuration File

🧠 Learnings (1)
📓 Common learnings
Learnt from: tyrrell-IH
PR: fjordllc/bootcamp#8807
File: app/views/welcome/job_support.html.slim:391-392
Timestamp: 2025-06-21T22:30:20.116Z
Learning: このプロジェクトにはRailsの組み込みmarkdownヘルパが利用できないため、markdownのHTML変換には自前でヘルパを実装する必要がある。
🧬 Code Graph Analysis (1)
app/javascript/markdown-it-container-speak.js (1)
app/javascript/escapeHtml.js (1)
  • escapeHTML (1-8)
🔇 Additional comments (1)
app/javascript/markdown-it-container-speak.js (1)

61-61: 終了タグの処理を確認

終了タグの処理が正しく実装されていることを確認しました。

@machida
Copy link
Copy Markdown
Member

machida commented Jul 17, 2025

@su-su-su-su
このPRにsu-su-su-su さんをアサイン付けておきましたー
自分自身をPRの担当者につけておいていただけると、PRの一覧を見たときにすぐ誰のPRかわかるので助かります🙏

@su-su-su-su
Copy link
Copy Markdown
Contributor Author

@machida
申し訳ございません。
ご対応いただきありがとうございます!
承知いたしました。今後はPR作成時に自分をアサインするようにします🙇‍♂️

@machida
Copy link
Copy Markdown
Member

machida commented Jul 22, 2025

@su-su-su-su すいません、遅くなりました。今 push しました。
a-user-emoji-linka ではなく、span にしてもデザイン崩れがないようにしました。

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 563dfb1 and 8bfb883.

📒 Files selected for processing (1)
  • app/javascript/stylesheets/config/mixins/_long-text-style.sass (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build_and_test

@su-su-su-su su-su-su-su force-pushed the feature/add-arguments-to-speak-block branch from 8bfb883 to 0c0ab2b Compare July 22, 2025 06:39
@su-su-su-su
Copy link
Copy Markdown
Contributor Author

@riq0h
お疲れ様です。
可能でしたらお手隙の際に、こちらのPRのレビューをお願いできますでしょうか?
ご都合が合わない場合はおっしゃってください🙇‍♀️
どうぞよろしくお願いいたします!

@su-su-su-su su-su-su-su requested a review from riq0h July 22, 2025 10:13
@riq0h
Copy link
Copy Markdown
Contributor

riq0h commented Jul 23, 2025

@su-su-su-su お疲れ様です! 個人的にはお受けするのはまったく構わないのですが、僕はすでに修了している身なので必要以上に依頼を受けてしまうと他の方の学習機会を損ねてしまわないか気がかりです🙇 一旦、現役生の中で手が空いている方を探していただいてもよろしいでしょうか🙏

@su-su-su-su
Copy link
Copy Markdown
Contributor Author

@riq0h
返信ありがとうございます!
なるほどですね。承知しました!
ありがとうございました🙏

@su-su-su-su
Copy link
Copy Markdown
Contributor Author

@e-yanagita-gs
お疲れ様です。
可能でしたらお手隙の際に、レビューをお願いできますでしょうか?
ご都合が合わない場合はおっしゃってください🙇‍♀️
よろしくお願いいたします!

@e-yanagita-gs
Copy link
Copy Markdown
Contributor

@su-su-su-su
お疲れ様です。
すみません、私も既に修了しているため、他の方にお願いできますでしょうか💦
せっかくご指名いただいたのに恐縮です🙇‍♀️

@su-su-su-su
Copy link
Copy Markdown
Contributor Author

@e-yanagita-gs
返信ありがとうございます!
なるほどですね。承知しました!
ありがとうございました🙏

@su-su-su-su
Copy link
Copy Markdown
Contributor Author

@tyrrell-IH
お疲れ様です。
可能でしたらお手隙の際に、こちらのPRのレビューをお願いできますでしょうか?
ご都合が合わない場合はおっしゃってください🙇‍♀️
どうぞよろしくお願いいたします!

@su-su-su-su su-su-su-su requested review from tyrrell-IH and removed request for riq0h July 23, 2025 08:58
@tyrrell-IH
Copy link
Copy Markdown
Contributor

@su-su-su-su
お疲れ様ですー
ちょっと時間いただいて、8/1(金)をレビュー期限とさせていただけるならレビューお受けします〜

@su-su-su-su
Copy link
Copy Markdown
Contributor Author

@tyrrell-IH

返信ありがとうございます!
ごめんなさい!今作業しているのがこれだけなので時間が空いてしまいそうなので他の方にお願いしようかと思います。
ありがとうございました🙏

@su-su-su-su su-su-su-su removed the request for review from tyrrell-IH July 23, 2025 13:05
@su-su-su-su
Copy link
Copy Markdown
Contributor Author

@sjabcdefin
お疲れ様です。
可能でしたらお手隙の際に、こちらのPRのレビューをお願いできますでしょうか?
ご都合が合わない場合はおっしゃってください🙇‍♀️
どうぞよろしくお願いいたします!

@sjabcdefin
Copy link
Copy Markdown
Contributor

@su-su-su-su
お疲れ様です!
すみません。まだ最初のイテレーションで難しいIssueのレビューができないので他の方にレビュー依頼お願いできますでしょうか。😵🙏
よろしくお願いいたします。😌

@su-su-su-su
Copy link
Copy Markdown
Contributor Author

@sjabcdefin
返信ありがとうございます!
承知しました!ありがとうございました🙏

@su-su-su-su
Copy link
Copy Markdown
Contributor Author

@smallmonkeykey
お疲れ様です。
可能でしたらお手隙の際に、レビューをお願いできますでしょうか?
ご都合が合わない場合はおっしゃってください🙇‍♀️
よろしくお願いいたします!

@smallmonkeykey
Copy link
Copy Markdown
Contributor

smallmonkeykey commented Jul 23, 2025

@su-su-su-su
承知しました!土曜日までに返信します!

@su-su-su-su
Copy link
Copy Markdown
Contributor Author

@smallmonkeykey
ありがとうございます!
よろしくお願いいたします🙇‍♂️

@smallmonkeykey smallmonkeykey self-requested a review July 25, 2025 08:52
Copy link
Copy Markdown
Contributor

@smallmonkeykey smallmonkeykey left a comment

Choose a reason for hiding this comment

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

@su-su-su-su
全体としては意図が伝わりやすく、読みやすいコードだと思いました!
2点コメントしましたので、ご確認お願いします🙏

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

if の条件分岐が少し多めに見えました👀
ネストも少し深くなっているので、どのパターンでどういう処理が走るのかを把握するのに少し時間がかかるかも?と感じました。

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

ご指摘ありがとうございます!
確かに条件分岐が多く、ネストも深くて理解しにくい状態でした。
早期リターンパターンでリファクタリングし、処理パターンが分かりやすいように修正いたしました。

const speakerName = escapeHTML(parenMatch[1].trim())
const avatarUrl = escapeHTML(parenMatch[2].trim())

if (tokens[idx].nesting === 1) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

tokens[idx].nesting === 1 のような条件は、一見すると何を判定しているのかが少し分かりづらいかもしれません💦
たとえば、以下のように関数として切り出しておくと、より意図が伝わりやすいかなと思います。

function isOpeningTag(token) {
  return token.nesting === 1;
}

こうすることで、他の方が markdown-it のソースコードを毎回見に行かなくても、ある程度意図が伝わるようになってレビューや保守がしやすくなるんじゃないかな〜と思います!

ただ、他のファイルでも tokens[idx].nesting === 1 のまま使われているようだったので、今回もそのままの記述で統一しておくのもありだと思います 🙆‍♀️
もし関数化して明示した方が良さそうであれば、おまかせします〜!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

ご提案ありがとうございます!
なるほどですね!勉強になります🙏
今回は他のmarkdown-it関連ファイルとの統一性を優先し、既存のコードスタイルに合わせました。
このファイルだけ特別にすると混乱を招く可能性があると判断しました🙇‍♂️

@su-su-su-su su-su-su-su force-pushed the feature/add-arguments-to-speak-block branch from 5adfbd6 to e994314 Compare July 26, 2025 13:59
@su-su-su-su
Copy link
Copy Markdown
Contributor Author

@smallmonkeykey
お疲れ様です!
ご確認、コメントありがとうございます🙇‍♂️
ご指摘いただいた点を修正いしました。
お手隙の際にご確認お願いいたします!

Copy link
Copy Markdown
Contributor

@smallmonkeykey smallmonkeykey left a comment

Choose a reason for hiding this comment

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

@su-su-su-su
Approveさせていただきます〜!
正規表現、とても勉強になりました🙏

@su-su-su-su
Copy link
Copy Markdown
Contributor Author

@smallmonkeykey
ありがとうございます!レビューして頂きありがとうございました🙇‍♂️

@su-su-su-su
Copy link
Copy Markdown
Contributor Author

@komagata
メンバーの方からApproveいただきました。

お手すきの際にご確認お願いいたします。

Copy link
Copy Markdown
Member

@komagata komagata left a comment

Choose a reason for hiding this comment

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

確認させて頂きました。OKです〜🙆‍♂️

@komagata komagata merged commit 21ecca8 into main Jul 28, 2025
13 checks passed
@komagata komagata deleted the feature/add-arguments-to-speak-block branch July 28, 2025 18:58
@github-actions github-actions bot mentioned this pull request Jul 28, 2025
87 tasks
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.

8 participants