Skip to content

Conversation

@tegnike
Copy link
Owner

@tegnike tegnike commented May 31, 2025

Summary by CodeRabbit

  • 新機能

    • ドラッグ可能なUI要素を実現するカスタムフックと、リサイズ可能なUI要素を実現するカスタムフックを追加しました。
    • ドラッグ&リサイズ対応の新しいビデオ表示コンポーネントを追加しました。
  • リファクタ

    • キャプチャとWebカメラ機能のUIおよびロジックを簡素化し、背景動画や画像キャプチャ機能を削除しました。
    • ビデオ表示と操作を新しいコンポーネントに集約しました。

claude bot and others added 8 commits May 30, 2025 09:43
…lity

- Create useDraggable hook with mobile detection
- Enable mouse dragging for camera and screen sharing modals on desktop only
- Add expand icon to toggle background video mode instead of manual setting
- Remove useVideoAsBackground setting from advanced settings
- Change modal positioning from absolute to fixed for proper drag behavior

Co-authored-by: tegnike <tegnike@users.noreply.github.com>
@vercel
Copy link

vercel bot commented May 31, 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 Jun 1, 2025 7:44pm

@coderabbitai
Copy link

coderabbitai bot commented May 31, 2025

Walkthrough

この変更では、Capture および Webcam コンポーネントからシャッターキャプチャ機能や背景動画のロジックが削除され、新たに VideoDisplay コンポーネントが導入されました。また、ドラッグやリサイズを可能にするカスタムフック useDraggableuseResizable が追加されています。

Changes

ファイル/グループ 変更内容概要
src/components/capture.tsx シャッターキャプチャ・背景動画関連ロジックを削除し、VideoDisplay のみを表示するようリファクタリング。
src/components/webcam.tsx シャッターキャプチャ・背景動画関連ロジックを削除し、VideoDisplay にUIと操作を委譲。
src/components/common/VideoDisplay.tsx 新規: ドラッグ・リサイズ可能な動画表示コンポーネントを追加。キャプチャやトグルUIを内包。
src/hooks/useDraggable.ts 新規: 要素のドラッグ移動を可能にするカスタムフックを追加。
src/hooks/useResizable.ts 新規: 要素のリサイズを可能にするカスタムフックを追加。

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Webcam
    participant VideoDisplay

    User->>Webcam: ページ表示/デバイス選択
    Webcam->>VideoDisplay: videoRef, mediaStream, トグルコールバック等を渡す
    User->>VideoDisplay: トグルボタン操作
    VideoDisplay-->>Webcam: onToggleSource コールバック呼び出し
Loading

Possibly related PRs

  • tegnike/aituber-kit#101: Webcam コンポーネントにシャッターキャプチャや画像処理機能を追加しており、本PRでの削除・リファクタと直接関連。
  • tegnike/aituber-kit#157: Capture コンポーネントの初期実装でキャプチャ・画面共有機能を導入しており、本PRのリファクタ・機能削除と密接に関連。

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.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

npm error Exit handler never called!
npm error This is an error with npm itself. Please report this error at:
npm error https://github.com/npm/cli/issues
npm error A complete log of this run can be found in: /.npm/_logs/2025-06-01T19_44_43_260Z-debug-0.log


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 7bc2b36 and 2d5ff0c.

📒 Files selected for processing (2)
  • .claude/settings.local.json (1 hunks)
  • src/components/common/VideoDisplay.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • .claude/settings.local.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/common/VideoDisplay.tsx
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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 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: 2

🧹 Nitpick comments (7)
src/hooks/useDraggable.ts (1)

21-22: ユーザーエージェント検出の信頼性について検討してください

現在のユーザーエージェント検出パターンは一般的なものですが、将来的により堅牢な検出方法(例:タッチイベントの存在確認など)の採用も検討することをお勧めします。

setIsMobile(
  window.innerWidth <= 768 ||
-    /Mobi|Android|iPhone|iPad|iPod/i.test(navigator.userAgent)
+    /Mobi|Android|iPhone|iPad|iPod/i.test(navigator.userAgent) ||
+    ('ontouchstart' in window)
)
src/hooks/useResizable.ts (1)

15-16: ウィンドウサイズ変更時の最大サイズ更新について検討してください

デフォルトの最大サイズがウィンドウサイズに基づいて設定されていますが、ウィンドウがリサイズされた場合に更新されません。これにより、小さなウィンドウでページを開いた後に拡張した場合、制約が厳しすぎる可能性があります。

ウィンドウリサイズイベントを監視して最大サイズを動的に更新することを検討してください:

+useEffect(() => {
+  const handleResize = () => {
+    setMaxConstraints({
+      maxWidth: window.innerWidth * 0.8,
+      maxHeight: window.innerHeight * 0.8
+    })
+  }
+  window.addEventListener('resize', handleResize)
+  return () => window.removeEventListener('resize', handleResize)
+}, [])
src/components/common/VideoDisplay.tsx (5)

39-51: 状態管理とhooksの使用方法を改善できます。

useDraggableとuseResizableの戻り値の構造化代入は適切ですが、カスタムhooksの初期位置設定に関して改善の余地があります。

    const {
      isMobile,
      handleMouseDown,
      resetPosition,
      style: dragStyle,
-   } = useDraggable()
+   } = useDraggable({ x: 0, y: 0 })

初期位置を明示的に設定することで、予期しない配置を防げます。


54-64: 背景ビデオの同期ロジックを確認してください。

背景ビデオの同期処理は正しく実装されていますが、エラーハンドリングを追加することを推奨します。

    useEffect(() => {
      if (useVideoAsBackground && videoRef.current?.srcObject) {
        if (backgroundVideoRef.current) {
          backgroundVideoRef.current.srcObject = videoRef.current.srcObject
+         backgroundVideoRef.current.play().catch(console.error)
        }
      } else if (!useVideoAsBackground) {
        if (backgroundVideoRef.current) {
          backgroundVideoRef.current.srcObject = null
        }
      }
    }, [useVideoAsBackground, videoRef])

74-97: キャプチャ機能の実装は適切ですが、エラーハンドリングを強化してください。

キャプチャロジックは正常に動作しますが、より堅牢なエラーハンドリングを追加することを推奨します。

    const handleCapture = useCallback(() => {
      if (!videoRef.current) return

+     try {
        const canvas = document.createElement('canvas')
        canvas.width = videoRef.current.videoWidth
        canvas.height = videoRef.current.videoHeight
        const ctx = canvas.getContext('2d')
        if (!ctx) return

        ctx.drawImage(videoRef.current, 0, 0)
        const data = canvas.toDataURL('image/png')

        if (data !== '') {
          console.log('capture')
          homeStore.setState({
            modalImage: data,
            triggerShutter: false,
          })
        } else {
          homeStore.setState({ modalImage: '' })
        }

        onCapture?.()
+     } catch (error) {
+       console.error('Capture failed:', error)
+       homeStore.setState({ modalImage: '' })
+     }
    }, [videoRef, onCapture])

150-187: リサイズハンドルの実装は良好ですが、アクセシビリティを向上できます。

リサイズハンドルの配置と機能は適切ですが、視覚的なフィードバックを改善できます。

                <div
-                 className="absolute top-0 left-0 w-3 h-3 cursor-nwse-resize"
+                 className="absolute top-0 left-0 w-3 h-3 cursor-nwse-resize bg-transparent hover:bg-blue-500 hover:opacity-50 transition-colors"
                  onMouseDown={(e) => handleResizeStart(e, 'top-left')}
                />

各リサイズハンドルにホバー効果を追加することで、ユーザビリティが向上します。


126-133: 動的スタイル設定でパフォーマンスの問題を確認してください。

インラインスタイルオブジェクトがrenderごとに再作成される可能性があります。useMemoを使用してパフォーマンスを改善することを検討してください。

+         const containerStyle = useMemo(() => ({
+           ...dragStyle,
+           width: isExpanded ? 'auto' : `${size.width}px`,
+           height: isExpanded ? 'auto' : `${size.height}px`,
+           maxWidth: isExpanded ? '70%' : 'none',
+           maxHeight: isExpanded ? '40vh' : 'none',
+         }), [dragStyle, isExpanded, size.width, size.height])

          style={{
-           ...dragStyle,
-           width: isExpanded ? 'auto' : `${size.width}px`,
-           height: isExpanded ? 'auto' : `${size.height}px`,
-           maxWidth: isExpanded ? '70%' : 'none',
-           maxHeight: isExpanded ? '40vh' : 'none',
+           ...containerStyle,
          }}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 1fbff63 and 3e252d1.

📒 Files selected for processing (5)
  • src/components/capture.tsx (3 hunks)
  • src/components/common/VideoDisplay.tsx (1 hunks)
  • src/components/webcam.tsx (3 hunks)
  • src/hooks/useDraggable.ts (1 hunks)
  • src/hooks/useResizable.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/components/webcam.tsx (1)
src/components/common/VideoDisplay.tsx (1)
  • VideoDisplay (25-216)
src/components/common/VideoDisplay.tsx (3)
src/hooks/useDraggable.ts (1)
  • useDraggable (8-92)
src/hooks/useResizable.ts (1)
  • useResizable (11-133)
src/components/iconButton.tsx (1)
  • IconButton (14-51)
🔇 Additional comments (10)
src/hooks/useDraggable.ts (1)

1-92: 実装は全体的に良好です

このドラッグ機能フックの実装は適切に設計されており、以下の点で優れています:

  • 適切なイベントリスナーの管理(useEffectでの追加/削除)
  • モバイル端末での無効化
  • ドラッグ中のテキスト選択防止
  • 適切な依存関係の管理
src/components/webcam.tsx (3)

4-4: VideoDisplayコンポーネントの統合が適切です

新しいVideoDisplayコンポーネントの導入により、コードの責任分離が改善されています。


55-55: 依存関係の更新が正しく行われています

useVideoAsBackgroundへの依存関係が削除されたのは正しい変更です。このロジックがVideoDisplayコンポーネントに移動されたためです。


77-84: VideoDisplayとの統合が適切に実装されています

プロパティの渡し方とコールバックの設定が適切で、カメラローテーション機能も正しく統合されています。

src/components/capture.tsx (3)

3-3: VideoDisplayコンポーネントの統合により、アーキテクチャが改善されています

キャプチャコンポーネントの責任が適切に分離され、VideoDisplayに表示ロジックが委譲されています。


17-26: ストリーム設定関数が適切に更新されています

新しいアーキテクチャに合わせてストリーム設定ロジックが適切に調整されており、VideoDisplayコンポーネントとの連携が正しく実装されています。


96-103: VideoDisplayとの統合が正しく実装されています

mediaStreamの渡し方、toggleソースの接続、アイコンの設定などが適切に行われており、画面キャプチャ機能が正しく統合されています。

src/components/common/VideoDisplay.tsx (3)

1-12: インポート文の構成は適切です。

React hooksとカスタムhooksが適切にインポートされており、モジュール構成も明確で理解しやすいです。


14-23: インターフェース設計が良好です。

VideoDisplayPropsの型定義は明確で、オプショナルプロパティも適切に設定されています。各プロパティの意図が理解しやすく、再利用性を考慮した設計になっています。


218-218: displayNameの設定は適切です。

forwardRefを使用したコンポーネントにdisplayNameを設定することで、デバッグ時の識別が容易になります。

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

♻️ Duplicate comments (1)
src/components/common/VideoDisplay.tsx (1)

112-116: 過去に指摘された問題が適切に修正されています。

handleExpand関数からuseVideoAsBackgroundの状態変更が削除され、展開状態の管理のみに集中するように改善されました。

🧹 Nitpick comments (4)
src/components/common/VideoDisplay.tsx (4)

94-94: 本番環境用にコンソールログを削除することを推奨します。

デバッグ用のログが残っているようです。本番環境では削除するか、適切なロガーを使用することを検討してください。

-        console.log('capture')

145-150: パフォーマンス最適化のためにuseMemoの使用を検討してください。

videoBounds状態の更新で新しいオブジェクトを毎回生成すると、不要な再レンダリングが発生する可能性があります。値が実際に変更された場合のみ更新するようにすることを推奨します。

+import { useMemo } from 'react'

+    const newVideoBounds = useMemo(() => ({
+      x: offsetX,
+      y: offsetY,
+      width: actualWidth,
+      height: actualHeight,
+    }), [offsetX, offsetY, actualWidth, actualHeight])
+
-      setVideoBounds({
-        x: offsetX,
-        y: offsetY,
-        width: actualWidth,
-        height: actualHeight,
-      })
+      setVideoBounds(prev => {
+        if (prev.x === offsetX && prev.y === offsetY && 
+            prev.width === actualWidth && prev.height === actualHeight) {
+          return prev
+        }
+        return newVideoBounds
+      })

217-285: マジックナンバーを定数として定義することを推奨します。

リサイズハンドルの位置計算で使用されている数値(12、8など)を定数として定義すると、コードの可読性と保守性が向上します。

コンポーネントの上部に定数を追加:

+const HANDLE_SIZE = 12
+const EDGE_HANDLE_SIZE = 8
+const EDGE_HANDLE_THICKNESS = 2

// 使用例:
-                    left: `${videoBounds.x + videoBounds.width - 12}px`,
+                    left: `${videoBounds.x + videoBounds.width - HANDLE_SIZE}px`,

25-316: コンポーネントの分割を検討することを推奨します。

VideoDisplayコンポーネントは複数の責任(ドラッグ、リサイズ、キャプチャ、背景動画管理)を持っています。将来的な保守性向上のため、以下の分割を検討してください:

  • VideoContainer: 基本的な動画表示
  • ResizableVideo: リサイズ機能
  • VideoControls: コントロールボタン群
  • BackgroundVideoManager: 背景動画管理

これにより、各コンポーネントの責任が明確になり、テストやデバッグが容易になります。

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 3e252d1 and 7bc2b36.

📒 Files selected for processing (2)
  • src/components/common/VideoDisplay.tsx (1 hunks)
  • src/hooks/useResizable.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/hooks/useResizable.ts
🔇 Additional comments (2)
src/components/common/VideoDisplay.tsx (2)

14-23: Props定義が適切に設計されています。

型安全性が確保され、オプショナルプロパティも適切に定義されています。


177-185: 背景動画の条件付きレンダリングが適切に実装されています。

useVideoAsBackground設定に基づく条件付きレンダリングが正しく実装されており、対応するエフェクトでも適切なnullチェックが行われています。

@tegnike tegnike merged commit 0ab129f into develop Jun 1, 2025
5 checks passed
@tegnike tegnike deleted the claude/issue-405-20250530_094000 branch June 1, 2025 21:16
terisuke pushed a commit to terisuke/aituber-kit that referenced this pull request Dec 5, 2025
…_094000

Claude/issue 405 20250530 094000
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