feat(content-preview): defer loading indicator to avoid brief flicker#4437
feat(content-preview): defer loading indicator to avoid brief flicker#4437sanilsalvi wants to merge 2 commits intobox:masterfrom
Conversation
WalkthroughContentPreview gains a deferred loading spinner controlled by Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant ContentPreview
participant PreviewMask
participant PreviewInstance
Client->>ContentPreview: mount / open file (with loadingIndicatorDelayMs>0)
ContentPreview-->>ContentPreview: set isDeferringLoading=true, start timeout
ContentPreview->>PreviewInstance: init (include delay)
Note over ContentPreview,PreviewMask: while deferring, isLoading=false
alt timeout fires
ContentPreview-->>ContentPreview: clear timeout, set isDeferringLoading=false, set isLoading=true
ContentPreview->>PreviewMask: render loading
PreviewMask->>Client: show spinner
else file loads quickly / error occurs before timeout
ContentPreview-->>ContentPreview: clear timeout, endLoadingSession()
ContentPreview->>PreviewMask: render error or no-loading
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
No actionable comments were generated in the recent review. 🎉 🧹 Recent nitpick comments
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/elements/content-preview/ContentPreview.js (1)
306-329: 🛠️ Refactor suggestion | 🟠 MajorUndeclared instance properties and redundant defer-state setup in constructor.
Two observations:
loadingIndicatorShownThisSessionandloadingIndicatorDelayTimeoutIdare used as instance properties throughout the class but are never declared in the class body (unlikepreview,api,fetchFileEndTime, etc.). Declare them for consistency and Flow typing.The constructor (Line 325) and
componentDidMount(Lines 416–422) both set{ isLoading: false, isDeferringLoading: true }whendelayMs > 0. The constructor state is immediately overwritten bycomponentDidMount, making the constructor spread redundant. Consider removing the defer logic from the constructor and keeping it only incomponentDidMount, which is where the timeout actually starts.Proposed class-body declarations
previewLibraryLoaded: boolean = false; updateVersionToCurrent: ?() => void; dynamicOnPreviewLoadAction: ?() => void; + + loadingIndicatorShownThisSession: boolean = false; + + loadingIndicatorDelayTimeoutId: ?TimeoutID;
🤖 Fix all issues with AI agents
In `@src/elements/content-preview/ContentPreview.js`:
- Around line 457-472: When handling a file-change in componentDidUpdate, avoid
starting the deferred loading timeout when there is no new file to load: before
creating loadingIndicatorDelayTimeoutId or calling setTimeout in the
hasFileIdChanged branch, check that currentFileId is truthy (or alternatively
call endLoadingSession immediately when fetchFile would short-circuit); update
componentDidUpdate to either guard the timeout setup with a currentFileId
truthiness check or to call endLoadingSession/destroyPreview to clear any
pending timeout if fetchFile returns early, ensuring
loadingIndicatorShownThisSession and isLoading are not toggled for an absent
file.
- Line 152: Remove the development-only inline comment on the isDeferringLoading
prop in the ContentPreview component: locate the prop declaration
(isDeferringLoading?: boolean) in ContentPreview (ContentPreview.js) and delete
the trailing "// DEMO: deferred spinner cues – remove for production" comment so
the prop line contains only the type/signature.
🧹 Nitpick comments (1)
src/elements/content-preview/__tests__/ContentPreview.test.js (1)
888-904: Consider adding tests for core defer/timeout behavior.The new tests cover error and session-flag scenarios well, but there's no test coverage for:
componentDidMountsetting up the defer timer whenloadingIndicatorDelayMs > 0- The timeout firing and transitioning from
isDeferringLoading: true→isLoading: trueendLoadingSessionclearing the timeout before it fires (fast-load scenario)getLoadingIndicatorDelayMshandling negative or non-numeric valuesThese would strengthen confidence in the timer lifecycle, especially around edge cases. You can use
jest.useFakeTimers()/jest.advanceTimersByTime()to test timeout behavior deterministically.Also applies to: 664-675
Description:
Summary by CodeRabbit
New Features
Bug Fixes
Tests