Skip to content

Conversation

@ochisamu
Copy link
Contributor

@ochisamu ochisamu commented Apr 9, 2025

@tegnike
プロダクトのコンセプトに沿っていそうでしたら取り込みご検討いただけますでしょうか...?

関連するイシュー

  • なし

やったこと

  • Web上でスライドモードのセリフを編集できる機能を追加

できるようになること(ユーザ目線)

  • メニューのスライド設定内にセリフ編集ボタンが追加
    image

  • ボタンを押すと選択中のスライドのセリフ編集画面が別タブで表示

    • scripts.jsonおよびsupplement.txtの編集が画面上で可能
    • スライド下のボタンもしくは矢印キーの左右でスライドページ移動
    • 画面下部の保存ボタンもしくはCtrl+Sでファイル上書き
      image

動作確認

  • demoスライドが編集可能なことを確認
  • 動作確認環境: Windows11 MS Edge

Summary by CodeRabbit

  • 新機能

    • 新しいスライドエディター画面を追加し、スライドの内容、脚本、補足情報の編集が可能になりました。
    • 編集用のリンクボタンを導入し、選択中のスライドへの直接アクセスが実現しました。
    • 再生ボタンの表示設定が追加され、操作性が向上しました。
    • 日本語のローカライズを強化し、「セリフ編集」のラベルが追加されました。
  • 改善

    • スライド関連APIの入力検証とエラーハンドリングを強化し、セキュリティと信頼性を向上しました。
    • スライドフォルダ一覧表示で、必要なファイルが揃ったフォルダのみを対象とするように改善しました。
    • メッセージ送信設定画面の外部リンクを新しいタブで開くようにし、視認性とアクセシビリティを向上しました。
    • 送信メッセージ画面の背景を単色に変更し、デザインを調整しました。

@vercel
Copy link

vercel bot commented Apr 9, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
aituber-kit ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 23, 2025 6:23pm

@coderabbitai
Copy link

coderabbitai bot commented Apr 9, 2025

ウォークスルー

このPRは、スライド編集機能に関連する複数の変更を含みます。日本語ローカライズに新規エントリを追加し、設定コンポーネントには選択中のスライドの編集ページへ遷移するリンクボタンが実装されました。また、SlideControlsに表示制御用のオプションが導入され、APIエンドポイントでは入力サニタイズやバリデーション、エラーハンドリングの改善が行われました。さらに、新規スライドエディタページが追加され、データの取得、編集、保存、リバートが可能になっています。

変更点

ファイル 変更内容
locales/ja/translation.json 新規エントリ "EditSlideScripts": "セリフ編集""PleaseSelectSlide": "スライドを選択してください" を追加
src/components/settings/slide.tsx スライド選択ドロップダウンに空の選択肢を追加し、選択中のスライド編集ページへ遷移するリンクボタン(next/link利用)を追加。Flexコンテナで水平配置。useEffectによる初期選択設定を削除
src/components/slideControls.tsx SlideControlsPropsshowPlayButton オプションを追加。showPlayButtontrue の場合のみ再生中のスライド切替ボタンを無効化。Tailwind CSSのレイアウト調整を実施
src/pages/api/getSupplement.ts
src/pages/api/updateSlideData.ts
GETエンドポイントでメソッドチェックの簡略化、入力サニタイズ、ResponseData型の導入、エラーハンドリングを改善。
新規POSTエンドポイントでは、スライドデータ更新用のバリデーション、パスサニタイズ、ファイル書き込み処理を追加
src/pages/slide-editor/[slideName].tsx スライドエディタページを新規実装。APIからのスライドHTML/CSS、スクリプト、補足情報の取得、編集、保存、リバート機能およびキーボードショートカットの実装を含む。レスポンシブ対応とIME入力対応も実装
src/components/settings/messageReceiver.tsx /send-messageへのリンクをNext.jsのLinkコンポーネントに置換し、新規タブで開くように変更。アイコン画像を追加し、スタイルを強化
src/pages/api/getSlideFolders.ts スライドフォルダ一覧取得APIで、slides.mdscripts.jsonの両方を含むフォルダのみ返すようフィルタリングを追加
src/pages/send-message.tsx 背景グラデーションを単色の紫系背景に変更

シーケンス図

sequenceDiagram
    participant U as ユーザー
    participant SE as スライドエディタページ
    participant GS as GET /api/getSupplement
    participant US as POST /api/updateSlideData

    U->>SE: ページ読み込み(スライド名取得)
    SE->>GS: 補足情報リクエスト送信
    GS-->>SE: データレスポンス受信
    U->>SE: スライド内容を編集
    U->>SE: 保存操作を実施
    SE->>US: 更新データ送信
    US-->>SE: 保存完了レスポンス受信
Loading
sequenceDiagram
    participant U as ユーザー
    participant SC as Slideコンポーネント
    participant E as エディタページ

    U->>SC: スライド選択・編集リンクをクリック
    SC->>E: 新規タブでエディタページをオープン
Loading

関連するPR

  • 本番リリース #146: 日本語翻訳ファイルに新規エントリを追加しており、ローカライズ改善の面で今回の変更と共通の文脈を持つ

🪧 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @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 generate unit testing code.
    • @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.

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 sequence diagram to generate a sequence diagram of the changes in 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.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

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

@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: 0

🧹 Nitpick comments (2)
src/components/settings/slide.tsx (1)

96-142: セリフ編集機能へのリンクボタンが追加されています

スライド選択プルダウンと編集ボタンを横並びにするレイアウトが実装され、機能的にも優れています。条件付きレンダリングにより、スライドが選択されている場合のみ編集ボタンが表示される仕組みは適切です。

一点注意点として、Next.jsのLinkコンポーネントでlegacyBehaviorpassHrefを併用していますが、将来的なNext.jsのバージョンアップで非推奨になる可能性があります。

将来的なメンテナンス性を考慮すると、以下のような最新のNext.js Linkの使い方に更新することを検討してください:

-              <Link
-                href={`/slide-editor/${selectedSlideDocs}`}
-                passHref
-                legacyBehavior
-              >
-                <a
-                  target="_blank" // 新しいタブで開く
-                  rel="noopener noreferrer"
-                  className="inline-flex items-center px-3 py-2 text-sm bg-primary hover:bg-primary-hover rounded-3xl text-white font-bold transition-colors duration-200 whitespace-nowrap"
-                >
-                  {t('EditSlideScripts')}
-                  {/* 外部リンクアイコンを追加しても良いかも */}
-                  <svg
-                    xmlns="http://www.w3.org/2000/svg"
-                    className="h-4 w-4 ml-1"
-                    fill="none"
-                    viewBox="0 0 24 24"
-                    stroke="currentColor"
-                    strokeWidth={2}
-                  >
-                    <path
-                      strokeLinecap="round"
-                      strokeLinejoin="round"
-                      d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
-                    />
-                  </svg>
-                </a>
+              <Link
+                href={`/slide-editor/${selectedSlideDocs}`}
+                target="_blank"
+                rel="noopener noreferrer"
+                className="inline-flex items-center px-3 py-2 text-sm bg-primary hover:bg-primary-hover rounded-3xl text-white font-bold transition-colors duration-200 whitespace-nowrap"
+              >
+                {t('EditSlideScripts')}
+                <svg
+                  xmlns="http://www.w3.org/2000/svg"
+                  className="h-4 w-4 ml-1"
+                  fill="none"
+                  viewBox="0 0 24 24"
+                  stroke="currentColor"
+                  strokeWidth={2}
+                >
+                  <path
+                    strokeLinecap="round"
+                    strokeLinejoin="round"
+                    d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
+                  />
+                </svg>
-              </Link>
+              </Link>
src/pages/slide-editor/[slideName].tsx (1)

321-558: 変更の元に戻す処理やキーボード操作に対応したUI設計がユーザーフレンドリーです。

  • もう一度編集前の状態に戻すCtrl+S・左右矢印キー対応が直感的で使いやすいです。
  • バックエンドと連携した保存結果も含め、UI全体の完成度が高いです。

もし将来的にスライド数が多い場合、ページ一覧をモーダルで表示してジャンプできる機能があると利便性がさらに向上しそうです。必要であれば実装を検討してみてください。

🧰 Tools
🪛 Biome (1.9.4)

[error] 348-349: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8ace4a9 and 6a92c90.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (6)
  • locales/ja/translation.json (1 hunks)
  • src/components/settings/slide.tsx (2 hunks)
  • src/components/slideControls.tsx (2 hunks)
  • src/pages/api/getSupplement.ts (1 hunks)
  • src/pages/api/updateSlideData.ts (1 hunks)
  • src/pages/slide-editor/[slideName].tsx (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (4)
src/components/settings/slide.tsx (1)
src/components/link.tsx (1)
  • Link (1-12)
src/pages/api/updateSlideData.ts (1)
src/pages/api/getSupplement.ts (1)
  • handler (11-64)
src/pages/api/getSupplement.ts (1)
src/pages/api/updateSlideData.ts (1)
  • handler (22-107)
src/components/slideControls.tsx (1)
src/components/iconButton.tsx (1)
  • IconButton (14-51)
🪛 Biome (1.9.4)
src/pages/slide-editor/[slideName].tsx

[error] 224-224: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 348-349: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (27)
locales/ja/translation.json (1)

158-158: 新しい翻訳キーが適切に追加されています

スライドのセリフ編集機能に対応する翻訳キー「EditSlideScripts」が適切に追加されています。この追加により、新機能のUIが日本語環境で正しく表示されるようになります。

src/components/settings/slide.tsx (1)

4-4: Next.jsのLinkコンポーネントが適切にインポートされています

next/linkからのインポートが適切に行われています。コメントも明確に記述されており、コードの理解を助けています。

src/components/slideControls.tsx (3)

11-11: プロパティの追加が適切に行われています

showPlayButtonというオプショナルプロパティが適切に追加されています。コメントも明確で、この変更の目的がわかりやすく記述されています。


21-21: デフォルト値の設定が適切です

showPlayButtonのデフォルト値がtrueに設定されており、既存のユースケースとの互換性が維持されています。コメントも適切です。


24-51: レイアウトとボタンの条件付き表示が改善されています

スライドコントロールのレイアウトが改善され、Tailwind CSSを使用して適切にスタイリングされています。mx-16を削除し、親要素にgap-8を追加することで、より柔軟なレイアウトになっています。

また、showPlayButtonプロパティに基づく条件付きレンダリングと、ボタンの無効化ロジックが適切に実装されています。各ボタンのdisabled属性の条件分岐が明確に記述されており、可読性が高いです。

src/pages/api/updateSlideData.ts (5)

1-21: APIエンドポイントの型定義が適切です

スライドデータ更新のためのAPIエンドポイントの型定義が適切に実装されています。ScriptEntryインターフェース、リクエストボディの型、レスポンスの型が明確に定義されており、型安全性が確保されています。


22-52: バリデーションとサニタイゼーションが適切に実装されています

リクエストメソッドの検証、必須パラメータのチェック、そしてスライド名のサニタイゼーションが適切に実装されています。特にパストラバーサル攻撃を防止するための対策が講じられており、セキュリティ面でも配慮されています。

エラーレスポンスも適切なHTTPステータスコードと明確なメッセージが返されるようになっています。


53-67: ディレクトリとファイルパスの処理が適切です

ファイルパスの構築が適切に行われており、ターゲットディレクトリの存在確認も実装されています。存在しないディレクトリに対するエラーハンドリングも適切です。


68-90: 入力データの検証が詳細に実装されています

scripts配列の形式検証とsupplementContentの検証が適切に実装されています。型チェックだけでなく、配列の各要素の構造も確認されており、不正なデータを早期に検出できるようになっています。


91-107: ファイル書き込み処理とエラーハンドリングが適切です

Promise.allを使用して両方のファイルを並行して書き込む実装は効率的です。エラーハンドリングも適切に行われており、エラーメッセージが詳細に記録されるようになっています。

成功時と失敗時のレスポンスの形式も一貫しており、クライアント側での処理がしやすい設計になっています。

src/pages/api/getSupplement.ts (10)

1-9: レスポンスデータ型を導入している点が良いですね。
ResponseData 型でレスポンスの構造を明示しているため、クライアント側との連携が分かりやすく保守性も高いです。


13-14: ジェネリック型パラメータでのレスポンス型指定が適切です。
NextApiResponse<ResponseData> により、API レスポンス内容が明瞭化され、開発者体験が向上します。


15-17: GET以外のリクエストを早期に 405 返す実装は明確で良いです。
REST 原則にも合致しており、エラー処理が分かりやすくなります。


19-20: クエリパラメータから slideName を取得する処理は問題ありません。
特にエラー処理も混乱なく実装されており、読みやすいです。


21-25: slideName の妥当性チェックが適切です。
空文字や文字列以外を 400 エラーで早期に弾くため、想定外のバグを防げます。


27-39: path の正規化と無効文字・パストラバーサル対策がしっかりしています。
安全なファイルアクセスのために欠かせない実装で、セキュリティ面が大きく向上します。


41-47: OS依存しないパス作成ができており、可読性も高いです。
path.join の利用で誤ったパス指定のリスクを減らせています。


49-51: ファイルの読み込みに成功した場合に content を返す設計が分かりやすいです。
レスポンス内容もシンプルで、クライアント側で処理しやすいと思われます。


53-56: ENOENT 時に空文字列を返す方針は、利用者にとって便利ですが想定動作を要確認です。
ファイルが存在しないケースでも例外ではなく正常系となるため、フロント側の処理が簡易化されますが、期待どおりかどうか要再確認すると良いでしょう。


57-61: ファイル読み込み以外のエラーはログ出力の上で 500 を返しており、運用時のトラブルシュートもしやすいです。

src/pages/slide-editor/[slideName].tsx (7)

1-14: import と goToSlide の定義が分かりやすいです。
goToSlide 関数が単独でエクスポートされているため、再利用やテストがしやすくなっています。


15-114: コンポーネントの基本的な状態管理とマークダウン変換ロジックがよく整理されています。

  • useEffect でスライドデータを非同期取得し、エラー時やローディング時の状態を適切に制御しています。
  • スタイル要素を DOM に追加・削除するライフサイクル管理も正しく行われており、メモリリークを防げています。

114-123: スライドの表示切り替えが適切です。
currentSlide の変更をフックにして SVG を切り替えるシンプルな実装となっており、分かりやすいです。


124-174: scripts.json を取得する処理が堅牢です。

  • 404 時に空スクリプトとして扱うなど、想定外エラーにも柔軟に対応しています。
  • スクリプトフォーマットのバリデーションで、型が厳密に保証されている点も安心です。

176-206: supplement.txt の読み込みも同様に分かりやすい設計です。
404 はエラー扱いにせず、空文字列にして取り込む方針が統一されており、フロント処理の簡易化が図れます。


208-226: currentSlide に応じて現在のセリフや追加情報をセットするフローが読みやすいです。
nextSlide / prevSlideslideCount をもとに安全に境界処理をしており、意図しないインデックスエラーを避けられます。

🧰 Tools
🪛 Biome (1.9.4)

[error] 224-224: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


228-319: scripts ステート更新関数や保存処理がしっかり設計されています。

  • updateScriptsState による差分更新で複雑度が低く、拡張が容易です。
  • handleSave では POST リクエストをまとめて実行し、エラー時に警告を出す実装が妥当です。
  • 静的解析の指摘があった行(224, 348 付近)については、state.currentSlideinitialScripts は配列として初期化されるため、オプショナルチェーンは不要と考えられます。

@tegnike tegnike changed the base branch from main to develop April 13, 2025 21:38
Copy link

@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: 0

🧹 Nitpick comments (6)
src/pages/api/getSlideFolders.ts (1)

9-19: 同期 I/O の多用はレスポンス遅延の原因になります

readdirSyncexistsSync をループ内で呼び出すと、CPU バウンドではなく I/O バウンドの待ちが連続し、API がブロッキングされます。非同期 API (fs.promises) を使い、Promise.all で並列判定に切り替えるとスケールしやすくなります。

-const folders = fs
-  .readdirSync(slidesDir, { withFileTypes: true })
+const dirents = await fs.promises.readdir(slidesDir, { withFileTypes: true })
+
+const folders = await Promise.all(
+  dirents
     .filter((dirent) => dirent.isDirectory())
-    .filter((dirent) => {
-      const folderPath = path.join(slidesDir, dirent.name)
-      const hasSlidesFile = fs.existsSync(path.join(folderPath, 'slides.md'))
-      const hasScriptsFile = fs.existsSync(path.join(folderPath, 'scripts.json'))
-      return hasSlidesFile && hasScriptsFile
-    })
-  .map((dirent) => dirent.name)
+    .filter(async (dirent) => {
+      const folderPath = path.join(slidesDir, dirent.name)
+      const [slides, scripts] = await Promise.all([
+        fs.promises
+          .stat(path.join(folderPath, 'slides.md'))
+          .then(() => true)
+          .catch(() => false),
+        fs.promises
+          .stat(path.join(folderPath, 'scripts.json'))
+          .then(() => true)
+          .catch(() => false),
+      ])
+      return slides && scripts
+    })
+)
src/pages/slide-editor/[slideName].tsx (5)

1-1: 未使用の KeyboardEvent インポートを削除してください

globalThis.KeyboardEvent を直接使用しており、ここでインポートした型は参照されていません。ビルド時の不要コード削減のためにも除去しましょう。


4-4: homeStore が未使用です

現状このファイル内で homeStore は参照されておらず、Linter で警告対象になります。削除か使用の検討をお願いします。


8-13: goToSlide の重複定義とコメントの残骸を整理してください

  • 既に別ファイルで定義済みなら再利用して DRY 原則を保ちましょう。
  • 「slides.tsxからインポートするか…」というコメントはレビュー用メモに見えるため、マージ前に削除を推奨します。

226-229: optional chaining で可読性&安全性を向上

三項演算子よりも script?.line ?? '' などの記法が簡潔です。静的解析でも指摘されています。

-setCurrentScript(script ? script.line : '')
-setCurrentNotes(script && script.notes ? script.notes : '')
+setCurrentScript(script?.line ?? '')
+setCurrentNotes(script?.notes ?? '')

371-383: isDirty 判定のパフォーマンスを改善可能

JSON.stringify とソートは O(n log n) + シリアライズのコストがあり、スクリプト数が多いと再計算が重くなります。変更フラグを handleScriptChange / handleNotesChange / handleSupplementChange 内で都度立てる方式へ切り替えると、不要な比較を避けられます。

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro (Legacy)

📥 Commits

Reviewing files that changed from the base of the PR and between e8f7d7a and 8fb73e4.

⛔ Files ignored due to path filters (1)
  • public/images/icons/external-link.svg is excluded by !**/*.svg
📒 Files selected for processing (6)
  • locales/ja/translation.json (1 hunks)
  • src/components/settings/messageReceiver.tsx (2 hunks)
  • src/components/settings/slide.tsx (2 hunks)
  • src/pages/api/getSlideFolders.ts (1 hunks)
  • src/pages/send-message.tsx (1 hunks)
  • src/pages/slide-editor/[slideName].tsx (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • src/pages/send-message.tsx
  • locales/ja/translation.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/settings/slide.tsx
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/components/settings/messageReceiver.tsx (1)
src/components/link.tsx (1)
  • Link (1-12)
🪛 Biome (1.9.4)
src/pages/slide-editor/[slideName].tsx

[error] 240-241: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 367-369: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (4)
src/components/settings/messageReceiver.tsx (3)

3-3: 適切なNext.jsコンポーネントのインポートが追加されています。

ImageLinkコンポーネントの追加は、Webアプリケーションのパフォーマンスと開発体験の向上に貢献します。Next.jsの組み込みコンポーネントを使用することで、画像の最適化やルーティングの取り扱いが改善されます。

Also applies to: 7-7


50-65: リンク実装の改善が適切に行われています。

従来のシンプルなアンカータグから、Next.jsのLinkコンポーネントへの変更は以下の点で優れています:

  • legacyBehaviorpassHrefを正しく使用し、子要素のアンカータグにhref属性を渡しています
  • 新しいタブでの開き方が実装され、適切なセキュリティ属性(rel="noopener noreferrer")が設定されています
  • Tailwind CSSを活用した視覚的に魅力的なスタイリングが適用されています
  • 外部リンクであることを示すアイコンが追加され、ユーザーエクスペリエンスが向上しています

スタイリングのクラス名も適切で、他のUIコンポーネントとの一貫性を保っています。


57-63: 適切な画像コンポーネントの実装です。

Next.jsのImageコンポーネントの使用は以下の点で適切です:

  • 必要なwidthheight属性が指定されています
  • 適切な代替テキストが翻訳関数を通して提供されています
  • アイコンと周囲の要素との間隔が適切に設定されています

画像の最適化により、ページのパフォーマンスが向上し、ユーザーエクスペリエンスが改善されます。

src/pages/api/getSlideFolders.ts (1)

12-19: 👍 必要ファイルの存在チェックが追加されました

slides.mdscripts.json の双方を確認してからリストに載せるロジックは要件を満たしており、意図したフォルダのみを UI に露出させられます。

@tegnike tegnike merged commit 60906b8 into tegnike:develop Apr 23, 2025
5 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Apr 25, 2025
terisuke pushed a commit to terisuke/aituber-kit that referenced this pull request Dec 5, 2025
スライドのセリフ編集機能を追加
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