Skip to content

fix: video editor stuck on loading skeleton after popstate#1917

Open
kishan-gondaliya-7270 wants to merge 1 commit into
developfrom
fix/video-editor-popstate-stuck-skeleton
Open

fix: video editor stuck on loading skeleton after popstate#1917
kishan-gondaliya-7270 wants to merge 1 commit into
developfrom
fix/video-editor-popstate-stuck-skeleton

Conversation

@kishan-gondaliya-7270

Copy link
Copy Markdown
Collaborator

Description

Fixes #1916.

The Video Editor (admin.php?page=rtgodam_video_editor&id=<id>) becomes permanently stuck on its loading skeleton when a popstate event fires while the editor is open.

pages/video-editor/App.js's popstate handler unconditionally calls resetStore()attachmentAPI.util.resetApiState(), which clears the getAttachmentMeta cache. When the popstate does not change the attachment id, setAttachmentID(newId) sets the same value, so <VideoEditor key={ attachmentID } /> does not remount and the mounted useGetAttachmentMetaQuery hook does not re-fetch. isAttachmentConfigLoading stays true forever → the loading skeleton is shown permanently.

Fix

Guard handlePopState so it is a no-op when the attachment id is unchanged. It still resets the store and re-initialises when the attachment actually changes (back to the picker, or to a different video). A useRef mirrors the current attachmentID so the handler can compare without re-subscribing the listener on every render.

const handlePopState = () => {
  const newId = new URLSearchParams( window.location.search ).get( 'id' );
  const normalizedId = newId && ! isNaN( newId ) ? newId : null;
  if ( String( normalizedId ) === String( attachmentIDRef.current ) ) {
    return; // no-op: don't wipe the RTK cache without a refetch
  }
  resetStore();
  setRawID( normalizedId );
  setAttachmentID( normalizedId );
};

Evidence

On a fully-loaded editor, dispatching a single popstate:

window.dispatchEvent( new PopStateEvent( 'popstate' ) );

…reverts the editor to the loading skeleton (.loading-skeleton count 0 → 2, the Preview/Copy Block buttons disappear) and it never recovers (still skeleton after 6s). The attachment-meta request itself is healthy throughout — an in-page fetch('/wp-json/wp/v2/media/<id>', { headers: { 'X-WP-Nonce': … } }) returns 200 with a valid body in ~630ms — confirming it is the RTK cache being wiped without a refetch, not a network/auth issue.

How to test

  1. Open the Video Editor for a video — confirm it loads.
  2. Run window.dispatchEvent( new PopStateEvent('popstate') ) in the console.
  3. Before: editor reverts to the skeleton and stays there. After: editor remains rendered (no-op).
  4. Genuine back/forward (editor ↔ attachment picker, or switching videos) still resets/reloads correctly.

Notes

  • Surfaced via E2E automation: reaching the editor through the Media Library attachment modal (which uses history.pushState('?item=…')) triggers a popstate on the editor and bricks it.
  • Attribute/markup-only React change; no behavioural change for genuine navigation.

🤖 Generated with Claude Code

…ton)

handlePopState unconditionally called resetStore() (attachmentAPI.util.resetApiState),
which clears the getAttachmentMeta cache. When the popstate does not change the
attachment id, <VideoEditor key={ attachmentID } /> does not remount and the
already-mounted useGetAttachmentMetaQuery hook does not refetch, leaving the
editor permanently on its loading skeleton. Guard handlePopState to no-op when
the attachment id is unchanged; only reset + reinitialise on an actual change.

Fixes #1916

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 3, 2026 08:09

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes the Video Editor getting stuck on its loading skeleton after a popstate event by preventing unnecessary RTK Query cache resets when the attachment id hasn’t actually changed.

Changes:

  • Adds a useRef mirror of attachmentID to allow popstate handling without re-binding listeners on every render.
  • Guards the popstate handler to early-return (no-op) when the attachment id is unchanged, avoiding a resetStore() that would clear RTK Query cache without triggering a refetch.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pages/video-editor/App.js
Comment on lines 108 to +112
const newParams = new URLSearchParams( window.location.search );
const newId = newParams.get( 'id' );

if ( newId && ! isNaN( newId ) ) {
setRawID( newId );
setAttachmentID( newId );
} else {
setRawID( null );
setAttachmentID( null );
const normalizedId = newId && ! isNaN( newId ) ? newId : null;

// A popstate that does NOT change the current attachment must be a
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