Skip to content

Conversation

@tanflem
Copy link
Contributor

@tanflem tanflem commented Dec 30, 2025

Summary by CodeRabbit

  • New Features

    • Per-video background poller for upload processing with completion, timeout and error handlers.
  • Bug Fixes

    • Improved cancellation of in-flight uploads and clearer timeout/error notifications.
  • Tests

    • Added tests for the new poller lifecycle; updated cancellation tests and removed obsolete polling tests.
  • Chores / Refactor

    • Replaced interval-based polling and legacy polling utilities with a poller-driven model and simplified internal polling surface.

✏️ Tip: You can customize this high-level summary in your review settings.

mikeallisonJS and others added 5 commits December 20, 2025 00:16
…ndency

- Updated build scripts to use Bun for cross-platform builds.
- Added bun-types to package.json and pnpm-lock.yaml.
- Refactored video-importer to utilize Bun for executing scripts and managing dependencies.
- Removed sea-config.json as it is no longer needed.
- Enhanced error handling for environment variables in Firebase and R2 services.
- Updated E2E tests to run with Bun instead of npx.
…te TypeScript configuration

- Added module and moduleResolution options in tsconfig.json for improved module handling.
- Replaced direct process.env usage with a centralized env import for environment variables across multiple files.
- Removed dotenv/config import statements as environment variables are now managed through the env module.
- Deleted unused envVarTest.ts file to clean up the codebase.
…min-sometimes-leading-to' of https://github.com/JesusFilm/core into tannerfleming/eng-3559-mux-video-uploads-on-journeys-admin-sometimes-leading-to
@tanflem tanflem self-assigned this Dec 30, 2025
@linear
Copy link

linear bot commented Dec 30, 2025

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 30, 2025

Walkthrough

Replaced interval-based polling with a per-video VideoPoller component; moved polling lifecycle and notifications into MuxVideoUploadProvider, introduced stopPollingFnsRef for cancellation, removed several polling utilities and tests, and added VideoPoller unit tests.

Changes

Cohort / File(s) Summary
VideoPoller – New component
apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx, apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.spec.tsx, apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/index.ts
New invisible React component that encapsulates per-video polling via Apollo useLazyQuery. Handles completion, error, timeout, registers/unregisters external stop functions. Includes unit tests for lifecycle, success, error, timeout, and registration.
MuxVideoUploadProvider – Core refactor
apps/journeys-admin/src/components/MuxVideoUploadProvider/MuxVideoUploadProvider.tsx
Removed interval-based polling loop and lazy query usage; added stopPollingFnsRef, per-video start notification, new lifecycle handlers (complete/error/timeout) wired to VideoPoller, and rendering of VideoPoller components for active tasks.
Polling utilities – Removed or reworked
apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/startPolling/*, .../handlePollingComplete/*, .../handlePollingError/*, .../clearPollingInterval/*
Deleted startPolling, handlePollingComplete, handlePollingError, and clearPollingInterval modules and many of their tests; responsibilities moved into MuxVideoUploadProvider and VideoPoller.
cancelUploadForBlock – Updated
apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/cancelUploadForBlock.ts, .../cancelUploadForBlock.spec.ts
Replaced pollingIntervalsRef: Map<string, Timeout> with stopPollingFnsRef: Map<string, () => void>. Cancellation now invokes and unregisters stored stop functions; tests updated accordingly.
clearPollingInterval tests removed
apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/clearPollingInterval/*
Removed utility and its tests; re-export deleted.
handlePollingComplete / handlePollingError tests removed
apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/handlePollingComplete/*, .../handlePollingError/*
Removed modules and test suites for previous polling-complete/error helpers; logic consolidated into provider/poller.
startPolling tests removed
apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/startPolling/*
Removed startPolling utility and its tests; start-notification logic moved into provider.
Translations
libs/locales/en/apps-journeys-admin.json
Reordered placement of "Video processing timed out" key without changing content.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Provider as MuxVideoUploadProvider
  participant Poller as VideoPoller
  participant GraphQL as Apollo/GetMyMuxVideo
  participant UI as Snackbar

  Provider->>Poller: render(videoId,startTime,callbacks,register/unregister)
  Poller->>GraphQL: start polling (useLazyQuery, POLL_INTERVAL)
  GraphQL-->>Poller: response (ready or not) / error
  alt readyToStream
    Poller->>Provider: onComplete()
    Provider->>UI: show success snackbar
    Poller->>Provider: unregisterStopPolling(videoId)
  else error
    Poller->>Provider: onError(error)
    Provider->>UI: show error snackbar
    Poller->>Provider: unregisterStopPolling(videoId)
  else timeout
    Poller->>Provider: onTimeout()
    Provider->>UI: show timeout snackbar
    Poller->>Provider: unregisterStopPolling(videoId)
  end
  note right of Provider: External cancel invokes stop function from stopPollingFnsRef
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • jaco-brink
  • mikeallisonJS
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main fix: addressing blank video issues in Mux video uploads on the journeys admin component, which aligns with the comprehensive refactoring of the polling system.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch tannerfleming/eng-3559-mux-video-uploads-on-journeys-admin-leading-to-blank-video

📜 Recent review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 59b864b and 5c98662.

📒 Files selected for processing (1)
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/cancelUploadForBlock.spec.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/cancelUploadForBlock.spec.ts
⏰ 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). (6)
  • GitHub Check: test (22, 3/3)
  • GitHub Check: test (22, 2/3)
  • GitHub Check: build (22)
  • GitHub Check: test (22, 1/3)
  • GitHub Check: lint (22)
  • GitHub Check: Analyze (javascript)

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Contributor

github-actions bot commented Dec 30, 2025

Warnings
⚠️ ❗ Big PR (1475 changes)

(change count - 1475): Pull Request size seems relatively large. If Pull Request contains multiple changes, split each into separate PR will helps faster, easier review.

Generated by 🚫 dangerJS against 5c98662

@nx-cloud
Copy link

nx-cloud bot commented Dec 30, 2025

View your CI Pipeline Execution ↗ for commit 5c98662

Command Status Duration Result
nx run resources-e2e:e2e ✅ Succeeded 13s View ↗
nx run watch-modern-e2e:e2e ✅ Succeeded 4s View ↗
nx run watch-e2e:e2e ✅ Succeeded 23s View ↗
nx run journeys-admin-e2e:e2e ✅ Succeeded 1m 22s View ↗
nx run journeys-e2e:e2e ✅ Succeeded 25s View ↗
nx run videos-admin-e2e:e2e ✅ Succeeded 4s View ↗
nx run player-e2e:e2e ✅ Succeeded 3s View ↗
nx run-many --target=vercel-alias --projects=jo... ✅ Succeeded 2s View ↗
Additional runs (20) ✅ Succeeded ... View ↗

☁️ Nx Cloud last updated this comment at 2026-01-08 17:08:13 UTC

@github-actions github-actions bot requested a deployment to Preview - journeys-admin December 30, 2025 17:57 Pending
Copy link
Contributor

@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)
apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.spec.tsx (1)

49-55: Unused helper function.

The wrapper helper is defined but never used—each test creates its own MockedProvider inline. Consider removing it to reduce dead code, or refactor tests to use it for consistency.

🔎 Proposed fix
-  const wrapper = (mocks: MockedResponse[]) => {
-    return ({ children }: { children: ReactNode }) => (
-      <MockedProvider mocks={mocks} addTypename={false}>
-        {children}
-      </MockedProvider>
-    )
-  }
-
apps/journeys-admin/src/components/MuxVideoUploadProvider/MuxVideoUploadProvider.tsx (1)

114-147: Potential stale closure with pollingTasks dependency.

handlePollingComplete reads from pollingTasks (line 117) and has it in the dependency array (line 146). However, since this is a Map reference that changes on every setPollingTasks call, the closure may not have the latest task data when the callback fires.

Consider using the functional update pattern to access the current state:

🔎 Proposed fix
  const handlePollingComplete = useCallback(
    (videoId: string) => {
-     const task = pollingTasks.get(videoId)
-     if (task == null) return
-
-     setPollingTasks((prev) => {
-       const next = new Map(prev)
-       next.set(videoId, { ...task, status: 'completed' })
-       return next
-     })
-
-     showSnackbar(t('Video upload completed'), 'success', {
-       autoHideDuration: 4000,
-       preventDuplicate: true,
-       persist: false
-     })
-
-     // Call the completion callback
-     if (task.onComplete != null) {
-       task.onComplete()
-     }
+     setPollingTasks((prev) => {
+       const task = prev.get(videoId)
+       if (task == null) return prev
+       
+       const next = new Map(prev)
+       next.set(videoId, { ...task, status: 'completed' })
+       
+       // Call the completion callback
+       if (task.onComplete != null) {
+         task.onComplete()
+       }
+       
+       return next
+     })
+
+     showSnackbar(t('Video upload completed'), 'success', {
+       autoHideDuration: 4000,
+       preventDuplicate: true,
+       persist: false
+     })

      // Remove from state after notification
      setTimeout(() => {
        setPollingTasks((prev) => {
          const next = new Map(prev)
          next.delete(videoId)
          return next
        })
      }, TASK_CLEANUP_DELAY)
    },
-   [pollingTasks, showSnackbar, t]
+   [showSnackbar, t]
  )
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between bf22ace and d49b66c.

📒 Files selected for processing (19)
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/MuxVideoUploadProvider.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.spec.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/index.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/cancelUploadForBlock.spec.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/cancelUploadForBlock.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/index.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/clearPollingInterval/clearPollingInterval.spec.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/clearPollingInterval/clearPollingInterval.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/clearPollingInterval/index.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/handlePollingComplete/handlePollingComplete.spec.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/handlePollingComplete/handlePollingComplete.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/handlePollingComplete/index.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/handlePollingError/handlePollingError.spec.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/handlePollingError/handlePollingError.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/handlePollingError/index.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/startPolling/index.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/startPolling/startPolling.spec.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/startPolling/startPolling.ts
💤 Files with no reviewable changes (12)
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/clearPollingInterval/clearPollingInterval.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/handlePollingComplete/index.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/clearPollingInterval/index.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/clearPollingInterval/clearPollingInterval.spec.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/handlePollingError/handlePollingError.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/handlePollingError/handlePollingError.spec.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/handlePollingError/index.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/handlePollingComplete/handlePollingComplete.spec.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/startPolling/index.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/handlePollingComplete/handlePollingComplete.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/startPolling/startPolling.spec.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/startPolling/startPolling.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/base.mdc)

**/*.{ts,tsx,js,jsx}: Use early returns whenever possible to make the code more readable.
Use descriptive variable and function/const names.
Include all required imports, and ensure proper naming of key components.

Files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/index.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/cancelUploadForBlock.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.spec.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/index.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/MuxVideoUploadProvider.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/cancelUploadForBlock.spec.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/base.mdc)

Define a type if possible.

Files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/index.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/cancelUploadForBlock.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.spec.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/index.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/MuxVideoUploadProvider.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/cancelUploadForBlock.spec.ts
apps/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/apps.mdc)

apps/**/*.{js,jsx,ts,tsx}: Always use MUI over HTML elements; avoid using CSS or tags.
Use descriptive variable and function/const names. Also, event functions should be named with a “handle” prefix, like “handleClick” for onClick and “handleKeyDown” for onKeyDown.
Implement accessibility features on elements. For example, a tag should have a tabindex=“0”, aria-label, on:click, and on:keydown, and similar attributes.

Files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/index.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/cancelUploadForBlock.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.spec.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/index.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/MuxVideoUploadProvider.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/cancelUploadForBlock.spec.ts
🧠 Learnings (18)
📓 Common learnings
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-19T19:18:43.790Z
Learning: Components like `VideoContentHero` depend on the full provider stack plus video.js and mux metadata; preserve the existing contracts so autoplay, subtitles, and analytics remain intact
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/src/**/*.{ts,tsx} : Preserve existing contracts in components like `VideoBlock` which depend on the full provider stack, video.js, and mux metadata so autoplay, subtitles, and analytics remain intact.
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/src/**/*.{ts,tsx} : Preserve existing contracts in components like `VideoBlock` which depend on the full provider stack, video.js, and mux metadata so autoplay, subtitles, and analytics remain intact.

Applied to files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/index.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/cancelUploadForBlock.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.spec.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/index.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/MuxVideoUploadProvider.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/cancelUploadForBlock.spec.ts
📚 Learning: 2025-11-16T21:30:53.412Z
Learnt from: Kneesal
Repo: JesusFilm/core PR: 8309
File: apps/journeys-admin/setupTests.tsx:47-51
Timestamp: 2025-11-16T21:30:53.412Z
Learning: In apps/journeys-admin/setupTests.tsx, the `document.clearImmediate` mock is required for tests involving the mux upload provider, as an underlying library uses clearImmediate for timeout management to prevent race conditions and unnecessary polling calls.

Applied to files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/index.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/cancelUploadForBlock.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.spec.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/index.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/MuxVideoUploadProvider.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/cancelUploadForBlock.spec.ts
📚 Learning: 2025-12-19T19:18:43.790Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-19T19:18:43.790Z
Learning: Applies to apps/resources/**/*.spec.ts?(x) : Wrap component specs with `MockedProvider`, `VideoProvider`, and `WatchProvider` when the unit touches those contexts—`NewVideoContentPage.spec.tsx` shows the expected harness

Applied to files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.spec.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/index.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/cancelUploadForBlock.spec.ts
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/src/**/*.spec.{ts,tsx} : Co-locate React Testing Library specs under `*.spec.ts(x)` and mock network traffic with MSW handlers in `apps/watch/test`.

Applied to files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.spec.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/cancelUploadForBlock.spec.ts
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/src/**/*.spec.{ts,tsx} : Use the shared Jest setup in `apps/watch/setupTests.tsx` which already boots MSW, Next router mock, and has a longer async timeout.

Applied to files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.spec.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/cancelUploadForBlock.spec.ts
📚 Learning: 2025-12-19T19:18:43.790Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-19T19:18:43.790Z
Learning: Components like `VideoContentHero` depend on the full provider stack plus video.js and mux metadata; preserve the existing contracts so autoplay, subtitles, and analytics remain intact

Applied to files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.spec.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/index.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/MuxVideoUploadProvider.tsx
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/src/**/*.spec.{ts,tsx} : Enclose SWR-based hooks in `TestSWRConfig` (`apps/watch/test/TestSWRConfig.tsx`) to isolate cache state between assertions in tests.

Applied to files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.spec.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/cancelUploadForBlock.spec.ts
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/src/**/*.{ts,tsx} : UI flows must sit inside `VideoProvider`, `WatchProvider`, and `PlayerProvider`. Mirror that wiring when composing features and when writing tests.

Applied to files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.spec.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/index.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/MuxVideoUploadProvider.tsx
📚 Learning: 2025-04-08T07:57:39.246Z
Learnt from: Kneesal
Repo: JesusFilm/core PR: 6209
File: apps/watch/src/components/CollectionsPage/ContainerHeroVideo/ContainerHeroVideo.tsx:60-63
Timestamp: 2025-04-08T07:57:39.246Z
Learning: When adding new method calls to code that uses video.js player (or any external library), the corresponding test mocks must be updated to include those methods. In this specific case, adding `player.src()` to production code required adding a mock implementation of the `src` method in test files to prevent "TypeError: player.src is not a function" errors.

Applied to files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.spec.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/cancelUploadForBlock.spec.ts
📚 Learning: 2025-12-19T19:18:43.790Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-19T19:18:43.790Z
Learning: Applies to apps/resources/**/*.spec.ts?(x) : Co-locate React Testing Library specs under `*.spec.ts(x)` and mock network traffic with MSW handlers in `apps/resources/test`

Applied to files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.spec.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/cancelUploadForBlock.spec.ts
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/src/**/*.{ts,tsx} : `usePlayer` handles playback state (mute, fullscreen, current time). Keep reducer updates idempotent and avoid mixing DOM mutations with state—hero playback relies on these flags.

Applied to files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/MuxVideoUploadProvider.tsx
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/src/**/*.{ts,tsx} : Export all components through index.ts files.

Applied to files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/index.ts
📚 Learning: 2025-12-19T19:18:43.790Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-19T19:18:43.790Z
Learning: Applies to apps/resources/**/index.ts : Export all components through index.ts files

Applied to files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/index.ts
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/src/**/*.{ts,tsx} : Do not introduce new MUI usage; migrate existing MUI to shadcn/Tailwind. New shadcn work should coexist with core shells/wrappers still using MUI until explicit migration tasks retire them.

Applied to files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/MuxVideoUploadProvider.tsx
📚 Learning: 2025-05-22T02:57:46.179Z
Learnt from: Kneesal
Repo: JesusFilm/core PR: 6734
File: apps/journeys-admin/src/components/TermsAndConditions/TermsAndConditions.tsx:58-71
Timestamp: 2025-05-22T02:57:46.179Z
Learning: The team prefers to avoid try/catch blocks when working with Apollo Client mutations in favor of Apollo's built-in error handling mechanisms (checking the returned errors property).

Applied to files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/MuxVideoUploadProvider.tsx
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/src/**/*.{ts,tsx} : Apollo hooks should use generated types alongside colocated documents. Reference the pattern of `useVideoChildren` (`apps/watch/src/libs/useVideoChildren/useVideoChildren.ts`) for data fetching.

Applied to files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/MuxVideoUploadProvider.tsx
📚 Learning: 2025-12-19T19:18:43.790Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-19T19:18:43.790Z
Learning: `usePlayer` handles playback state (mute, fullscreen, current time). Keep reducer updates idempotent and avoid mixing DOM mutations with state—hero playback relies on these flags

Applied to files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/MuxVideoUploadProvider.tsx
🧬 Code graph analysis (4)
apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.spec.tsx (2)
apps/journeys-admin/src/components/MuxVideoUploadProvider/MuxVideoUploadProvider.tsx (1)
  • GET_MY_MUX_VIDEO_QUERY (27-36)
apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx (1)
  • VideoPoller (23-102)
apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx (2)
apps/journeys-admin/src/components/MuxVideoUploadProvider/MuxVideoUploadProvider.tsx (1)
  • GET_MY_MUX_VIDEO_QUERY (27-36)
apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/constants.ts (2)
  • POLL_INTERVAL (1-1)
  • MAX_POLL_TIME (2-2)
apps/journeys-admin/src/components/MuxVideoUploadProvider/MuxVideoUploadProvider.tsx (2)
apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/constants.ts (1)
  • TASK_CLEANUP_DELAY (3-3)
apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx (1)
  • VideoPoller (23-102)
apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/cancelUploadForBlock.spec.ts (2)
apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/types.ts (1)
  • UploadTask (9-19)
apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/cancelUploadForBlock.ts (1)
  • cancelUploadForBlock (16-60)
⏰ 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). (7)
  • GitHub Check: Deploy Preview (journeys-admin, 8556/merge, pull_request, 22)
  • GitHub Check: test (22, 2/3)
  • GitHub Check: test (22, 3/3)
  • GitHub Check: test (22, 1/3)
  • GitHub Check: build (22)
  • GitHub Check: lint (22)
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (18)
apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx (4)

1-16: LGTM! Well-structured imports and interface.

The VideoPollerProps interface clearly defines the component contract with all necessary callbacks for lifecycle management (complete, error, timeout) and external cancellation control (register/unregister).


34-74: Consider memoizing or stabilizing dependencies to prevent potential re-registration issues.

The stopPolling function returned by useLazyQuery may have unstable reference identity across renders. Since stopPolling is in the useEffect dependency array (line 95), this could cause the effect to re-run on every poll response, leading to repeated registration calls.

In practice, Apollo's stopPolling tends to be stable, but verify this doesn't cause issues in testing. If it does, consider wrapping with useCallback or removing from deps with an eslint-disable comment if the behavior is intentional.


40-65: Good use of hasCompletedRef to prevent race conditions.

The guard against duplicate completions is essential since polling callbacks can fire multiple times. The early returns at lines 42 and 67 correctly prevent duplicate processing.


76-98: Clean lifecycle management with proper cleanup.

The effect correctly:

  1. Registers the stop function for external cancellation
  2. Starts the initial query
  3. Cleans up on unmount by stopping polling and unregistering

This pattern ensures no leaked polling intervals.

apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/index.ts (1)

1-2: No functional changes.

This is just a barrel export file with a trailing newline added.

apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/index.ts (1)

1-2: Follows project conventions for barrel exports.

Clean re-export pattern consistent with the codebase structure.

apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/cancelUploadForBlock.ts (1)

39-52: Clean migration to callback-based cancellation.

The new approach properly:

  1. Retrieves and invokes the stop function if registered
  2. Removes the entry from the ref map
  3. Updates polling tasks state
  4. Clears the notification tracking

The null check on stopFn (line 42) ensures graceful handling when no stop function is registered.

apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.spec.tsx (3)

16-25: Good test structure with clear default props.

The defaultProps object provides sensible defaults and jest mocks for all callbacks, making individual tests clean and focused.


61-173: Comprehensive test coverage for VideoPoller lifecycle.

Tests properly cover:

  • Registration of stopPolling on mount
  • onComplete when video is ready
  • onError on query failure
  • onTimeout when MAX_POLL_TIME exceeded
  • Not calling onComplete when video is not ready

The timeout test (line 134) correctly sets startTime in the past to trigger the timeout condition.


175-208: LGTM! Cleanup and render tests are solid.

The unmount test verifies proper cleanup, and the render test confirms the component is invisible as intended.

apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/cancelUploadForBlock.spec.ts (3)

60-87: Good refactor with helper function.

The createVideoBlock helper reduces boilerplate and makes tests more readable. It properly sets all required VideoBlock fields with sensible defaults.


114-137: Test correctly verifies new stopPolling callback mechanism.

The test properly:

  1. Registers a mock stopPolling function
  2. Calls cancelUploadForBlock
  3. Verifies the stop function was invoked
  4. Confirms the function was unregistered from the map

186-206: Good edge case coverage.

This test ensures the code handles the case where a task has a videoId but no stopPolling function is registered—important for robustness during race conditions or unexpected states.

apps/journeys-admin/src/components/MuxVideoUploadProvider/MuxVideoUploadProvider.tsx (5)

25-25: Good architectural decision using VideoPoller component.

Moving polling logic to a dedicated component simplifies the provider and leverages Apollo's built-in polling capabilities rather than manual setInterval management.


84-89: Clean ref-based storage for cancellation callbacks.

Using a ref for stopPollingFnsRef is appropriate since these functions don't need to trigger re-renders when they change.


149-176: handlePollingError uses functional update correctly.

Unlike handlePollingComplete, this handler properly accesses the task via the functional update pattern (prev.get(videoId)), avoiding stale closure issues.


186-213: Clean startPolling implementation.

The function now only creates the task entry and shows the notification—actual polling is delegated to VideoPoller. The hasShownStartNotification guard prevents duplicate snackbars.


278-304: Elegant pattern: rendering VideoPoller components for each processing task.

This approach cleanly separates concerns:

  • Provider manages task state
  • VideoPoller handles individual polling lifecycle
  • React handles component mounting/unmounting as tasks change

The key={videoId} ensures proper component identity.

@github-actions github-actions bot temporarily deployed to Preview - resources December 30, 2025 18:01 Inactive
@github-actions github-actions bot temporarily deployed to Preview - watch-modern December 30, 2025 18:01 Inactive
@github-actions github-actions bot temporarily deployed to Preview - journeys-admin December 30, 2025 18:01 Inactive
@github-actions github-actions bot temporarily deployed to Preview - videos-admin December 30, 2025 18:01 Inactive
@github-actions github-actions bot temporarily deployed to Preview - journeys December 30, 2025 18:01 Inactive
@github-actions
Copy link
Contributor

github-actions bot commented Dec 30, 2025

The latest updates on your projects.

Name Status Preview Updated (UTC)
watch-modern ✅ Ready watch-modern preview Fri Jan 9 06:00:13 NZDT 2026

@github-actions
Copy link
Contributor

github-actions bot commented Dec 30, 2025

The latest updates on your projects.

Name Status Preview Updated (UTC)
player ✅ Ready player preview Fri Jan 9 05:59:45 NZDT 2026

@github-actions
Copy link
Contributor

github-actions bot commented Dec 30, 2025

The latest updates on your projects.

Name Status Preview Updated (UTC)
journeys ✅ Ready journeys preview Fri Jan 9 06:00:05 NZDT 2026

@github-actions
Copy link
Contributor

github-actions bot commented Dec 30, 2025

The latest updates on your projects.

Name Status Preview Updated (UTC)
videos-admin ✅ Ready videos-admin preview Fri Jan 9 06:00:54 NZDT 2026

@github-actions
Copy link
Contributor

github-actions bot commented Dec 30, 2025

The latest updates on your projects.

Name Status Preview Updated (UTC)
resources ✅ Ready resources preview Fri Jan 9 06:00:56 NZDT 2026

@github-actions
Copy link
Contributor

github-actions bot commented Dec 30, 2025

The latest updates on your projects.

Name Status Preview Updated (UTC)
watch ✅ Ready watch preview Fri Jan 9 06:01:48 NZDT 2026

Copy link
Contributor

@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

🧹 Nitpick comments (1)
apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx (1)

45-48: Consider extracting the readiness check for reusability.

The video readiness logic could be extracted into a helper function for clarity and potential reuse.

🔎 Proposed refactor to extract readiness check

Create a helper function in apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/:

// utils/videoReadiness.ts
export function isVideoReady(video: { 
  readyToStream?: boolean | null
  assetId?: string | null
  playbackId?: string | null
} | null | undefined): boolean {
  return video?.readyToStream === true && 
         video?.assetId != null && 
         video?.playbackId != null
}

Then update this file:

+import { isVideoReady } from '../utils/videoReadiness'

 onCompleted: (data) => {
   if (hasCompletedRef.current) return
   
   const video = data?.getMyMuxVideo
-  const isVideoReady =
-    video?.readyToStream === true &&
-    video?.assetId != null &&
-    video?.playbackId != null
   
-  if (isVideoReady) {
+  if (isVideoReady(video)) {
     hasCompletedRef.current = true
     stopPolling()
     unregisterStopPolling(videoId)
     onComplete()
     return
   }
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between d49b66c and efd1b06.

📒 Files selected for processing (5)
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.spec.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/index.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/cancelUploadForBlock.ts
  • libs/locales/en/apps-journeys-admin.json
✅ Files skipped from review due to trivial changes (1)
  • libs/locales/en/apps-journeys-admin.json
🚧 Files skipped from review as they are similar to previous changes (3)
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/index.ts
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.spec.tsx
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/cancelUploadForBlock/cancelUploadForBlock.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/base.mdc)

**/*.{ts,tsx,js,jsx}: Use early returns whenever possible to make the code more readable.
Use descriptive variable and function/const names.
Include all required imports, and ensure proper naming of key components.

Files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/base.mdc)

Define a type if possible.

Files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx
apps/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/apps.mdc)

apps/**/*.{js,jsx,ts,tsx}: Always use MUI over HTML elements; avoid using CSS or tags.
Use descriptive variable and function/const names. Also, event functions should be named with a “handle” prefix, like “handleClick” for onClick and “handleKeyDown” for onKeyDown.
Implement accessibility features on elements. For example, a tag should have a tabindex=“0”, aria-label, on:click, and on:keydown, and similar attributes.

Files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx
🧠 Learnings (6)
📓 Common learnings
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-19T19:18:43.790Z
Learning: Components like `VideoContentHero` depend on the full provider stack plus video.js and mux metadata; preserve the existing contracts so autoplay, subtitles, and analytics remain intact
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/src/**/*.{ts,tsx} : Preserve existing contracts in components like `VideoBlock` which depend on the full provider stack, video.js, and mux metadata so autoplay, subtitles, and analytics remain intact.
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/src/**/*.{ts,tsx} : Preserve existing contracts in components like `VideoBlock` which depend on the full provider stack, video.js, and mux metadata so autoplay, subtitles, and analytics remain intact.

Applied to files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx
📚 Learning: 2025-12-19T19:18:43.790Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-19T19:18:43.790Z
Learning: Components like `VideoContentHero` depend on the full provider stack plus video.js and mux metadata; preserve the existing contracts so autoplay, subtitles, and analytics remain intact

Applied to files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/src/**/*.{ts,tsx} : `usePlayer` handles playback state (mute, fullscreen, current time). Keep reducer updates idempotent and avoid mixing DOM mutations with state—hero playback relies on these flags.

Applied to files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx
📚 Learning: 2025-11-16T21:30:53.412Z
Learnt from: Kneesal
Repo: JesusFilm/core PR: 8309
File: apps/journeys-admin/setupTests.tsx:47-51
Timestamp: 2025-11-16T21:30:53.412Z
Learning: In apps/journeys-admin/setupTests.tsx, the `document.clearImmediate` mock is required for tests involving the mux upload provider, as an underlying library uses clearImmediate for timeout management to prevent race conditions and unnecessary polling calls.

Applied to files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/src/**/*.{ts,tsx} : UI flows must sit inside `VideoProvider`, `WatchProvider`, and `PlayerProvider`. Mirror that wiring when composing features and when writing tests.

Applied to files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx
🧬 Code graph analysis (1)
apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx (2)
apps/journeys-admin/src/components/MuxVideoUploadProvider/MuxVideoUploadProvider.tsx (1)
  • GET_MY_MUX_VIDEO_QUERY (27-36)
apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/constants.ts (2)
  • POLL_INTERVAL (1-1)
  • MAX_POLL_TIME (2-2)
⏰ 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). (12)
  • GitHub Check: Deploy Preview (watch, 8556/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (watch-modern, 8556/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (journeys, 8556/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (videos-admin, 8556/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (resources, 8556/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (journeys-admin, 8556/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (player, 8556/merge, pull_request, 22)
  • GitHub Check: test (22, 3/3)
  • GitHub Check: test (22, 1/3)
  • GitHub Check: test (22, 2/3)
  • GitHub Check: build (22)
  • GitHub Check: lint (22)
🔇 Additional comments (1)
apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx (1)

34-74: Well-designed polling mechanism using Apollo's built-in capabilities.

The use of Apollo's pollInterval with guards via hasCompletedRef is a significant improvement over manual interval management. The readiness, timeout, and error paths are clearly separated and properly handle cleanup.

@github-actions
Copy link
Contributor

github-actions bot commented Dec 30, 2025

The latest updates on your projects.

Name Status Preview Updated (UTC)
journeys-admin ✅ Ready journeys-admin preview Fri Jan 9 06:02:03 NZDT 2026

@github-actions github-actions bot temporarily deployed to Preview - resources January 6, 2026 20:05 Inactive
@github-actions github-actions bot temporarily deployed to Preview - watch-modern January 6, 2026 20:05 Inactive
@github-actions github-actions bot temporarily deployed to Preview - videos-admin January 6, 2026 20:05 Inactive
@github-actions github-actions bot temporarily deployed to Preview - journeys January 6, 2026 20:05 Inactive
@github-actions github-actions bot temporarily deployed to Preview - journeys-admin January 6, 2026 20:05 Inactive
@github-actions github-actions bot temporarily deployed to Preview - player January 6, 2026 20:05 Inactive
Copy link
Contributor

@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 (1)
apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx (1)

58-64: Consider adding explicit return after timeout for clarity.

After invoking onTimeout() on line 63, there's no explicit return statement. While this is functionally correct (the hasCompletedRef.current = true on line 60 ensures subsequent polls will early-return at line 42), adding a return statement would make the control flow more explicit.

🔎 Proposed refactor for clarity
       // Check for timeout
       if (Date.now() - startTime > MAX_POLL_TIME) {
         hasCompletedRef.current = true
         stopPolling()
         unregisterStopPolling(videoId)
         onTimeout()
+        return
       }
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between efd1b06 and 59b864b.

📒 Files selected for processing (1)
  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/base.mdc)

**/*.{ts,tsx,js,jsx}: Use early returns whenever possible to make the code more readable.
Use descriptive variable and function/const names.
Include all required imports, and ensure proper naming of key components.

Files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/base.mdc)

Define a type if possible.

Files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx
apps/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/apps.mdc)

apps/**/*.{js,jsx,ts,tsx}: Always use MUI over HTML elements; avoid using CSS or tags.
Use descriptive variable and function/const names. Also, event functions should be named with a “handle” prefix, like “handleClick” for onClick and “handleKeyDown” for onKeyDown.
Implement accessibility features on elements. For example, a tag should have a tabindex=“0”, aria-label, on:click, and on:keydown, and similar attributes.

Files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx
🧠 Learnings (6)
📓 Common learnings
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-19T19:18:43.790Z
Learning: Components like `VideoContentHero` depend on the full provider stack plus video.js and mux metadata; preserve the existing contracts so autoplay, subtitles, and analytics remain intact
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/src/**/*.{ts,tsx} : Preserve existing contracts in components like `VideoBlock` which depend on the full provider stack, video.js, and mux metadata so autoplay, subtitles, and analytics remain intact.
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/src/**/*.{ts,tsx} : Preserve existing contracts in components like `VideoBlock` which depend on the full provider stack, video.js, and mux metadata so autoplay, subtitles, and analytics remain intact.

Applied to files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx
📚 Learning: 2025-12-19T19:18:43.790Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/resources/AGENTS.md:0-0
Timestamp: 2025-12-19T19:18:43.790Z
Learning: Components like `VideoContentHero` depend on the full provider stack plus video.js and mux metadata; preserve the existing contracts so autoplay, subtitles, and analytics remain intact

Applied to files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/src/**/*.{ts,tsx} : `usePlayer` handles playback state (mute, fullscreen, current time). Keep reducer updates idempotent and avoid mixing DOM mutations with state—hero playback relies on these flags.

Applied to files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx
📚 Learning: 2025-11-16T21:30:53.412Z
Learnt from: Kneesal
Repo: JesusFilm/core PR: 8309
File: apps/journeys-admin/setupTests.tsx:47-51
Timestamp: 2025-11-16T21:30:53.412Z
Learning: In apps/journeys-admin/setupTests.tsx, the `document.clearImmediate` mock is required for tests involving the mux upload provider, as an underlying library uses clearImmediate for timeout management to prevent race conditions and unnecessary polling calls.

Applied to files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx
📚 Learning: 2025-12-19T04:58:24.460Z
Learnt from: CR
Repo: JesusFilm/core PR: 0
File: apps/watch/AGENTS.md:0-0
Timestamp: 2025-12-19T04:58:24.460Z
Learning: Applies to apps/watch/src/**/*.{ts,tsx} : UI flows must sit inside `VideoProvider`, `WatchProvider`, and `PlayerProvider`. Mirror that wiring when composing features and when writing tests.

Applied to files:

  • apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx
🧬 Code graph analysis (1)
apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx (2)
apps/journeys-admin/src/components/MuxVideoUploadProvider/MuxVideoUploadProvider.tsx (1)
  • GET_MY_MUX_VIDEO_QUERY (27-36)
apps/journeys-admin/src/components/MuxVideoUploadProvider/utils/constants.ts (2)
  • POLL_INTERVAL (1-1)
  • MAX_POLL_TIME (2-2)
⏰ 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). (8)
  • GitHub Check: Deploy Preview (journeys-admin, 8556/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (videos-admin, 8556/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (player, 8556/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (watch, 8556/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (journeys, 8556/merge, pull_request, 22)
  • GitHub Check: Deploy Preview (resources, 8556/merge, pull_request, 22)
  • GitHub Check: build (22)
  • GitHub Check: lint (22)
🔇 Additional comments (3)
apps/journeys-admin/src/components/MuxVideoUploadProvider/VideoPoller/VideoPoller.tsx (3)

1-16: LGTM! Well-structured imports and interface.

The imports are clean and the VideoPollerProps interface clearly defines all required callbacks and registry functions with proper TypeScript types.


18-74: Excellent polling implementation with proper guards.

The useLazyQuery setup correctly uses:

  • network-only fetch policy for fresh data
  • hasCompletedRef guards in both onCompleted and onError to prevent race conditions
  • Proper cleanup sequence (set flag, stop polling, unregister, invoke callback)

The timeout check and ready-state validation are well-implemented.


77-92: No action needed; the asymmetry is intentional and safe.

The registered stop function (lines 79-82) intentionally does not call unregisterStopPolling(videoId) because it's designed as a soft stop for external callers. Full cleanup (including unregistration) is guaranteed through one of three paths:

  1. Natural polling completion (success on line 53, timeout on line 62): unregisterStopPolling called in callbacks
  2. Polling error (line 70): unregisterStopPolling called in error handler
  3. Component unmount (line 91): unregisterStopPolling called in cleanup function

This design prevents memory leaks because at least one of these paths will always execute and clean up the registration.

…9-mux-video-uploads-on-journeys-admin-leading-to-blank-video
@github-actions github-actions bot temporarily deployed to Preview - journeys-admin January 8, 2026 16:57 Inactive
@github-actions github-actions bot temporarily deployed to Preview - journeys January 8, 2026 16:57 Inactive
@github-actions github-actions bot temporarily deployed to Preview - resources January 8, 2026 16:57 Inactive
@github-actions github-actions bot temporarily deployed to Preview - player January 8, 2026 16:57 Inactive
@github-actions github-actions bot temporarily deployed to Preview - videos-admin January 8, 2026 16:57 Inactive
@github-actions github-actions bot temporarily deployed to Preview - watch-modern January 8, 2026 16:57 Inactive
@stage-branch-merger
Copy link

I see you added the "on stage" label, I'll get this merged to the stage branch!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants