-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
uncaught exception error when uploading a video #38720 #40132
Conversation
CLA Assistant Lite bot All contributors have signed the CLA ✍️ ✅ |
I have read the CLA Document and I hereby sign the CLA |
@@ -172,12 +176,23 @@ function BaseVideoPlayer({ | |||
}); | |||
}, [currentVideoPlayerRef, handleFullscreenUpdate, handlePlaybackStatusUpdate]); | |||
|
|||
useLayoutEffect(() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use useEffect
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we use useEffect
, we can't get the value of videoPlayerRef
because it is called after unmount.
So I used useLayoutEffect
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see why the ref wouldn't be available. Looks we are missing something here. Checking the rest of the refs all are available e.g. videoPlayerElementParentRef
and videoPlayerElementRef
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found that other refs are available in useEffect
.
Only video ref is null.
I thought there is code part to reset videoPlayerRef
, but I couldn't find it.
I've test with other ref videoPlayerRef1
, but couldn't get value in useEffect
either.
It seems it is relative with Video component.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I forgot to reply here. Can you please add a comment explaining that (why we can't use useEffect) and also complete the checklist (screenshots)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please check this?
facebook/react#20875
I think this github issue gives us an answer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense but I meant to write a code comment, add the blog link for future ref https://legacy.reactjs.org/blog/2020/08/10/react-v17-rc.html#effect-cleanup-timing
if(!shouldUseSharedVideoElement && (isUploading || videoPlayerRef.current === currentVideoPlayerRef.current)) { | ||
currentVideoPlayerRef.current = null; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer early return. Please run npm run lint
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, thank you.
@@ -172,12 +176,23 @@ function BaseVideoPlayer({ | |||
}); | |||
}, [currentVideoPlayerRef, handleFullscreenUpdate, handlePlaybackStatusUpdate]); | |||
|
|||
useLayoutEffect(() => { | |||
return () => { | |||
if(!shouldUseSharedVideoElement && (isUploading || videoPlayerRef.current === currentVideoPlayerRef.current)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What case is the isUploading check needed for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isUploading check is not needed. Thank you.
if(currentVideoPlayerRef.current) { | ||
pauseVideo(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is that needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently, previous playing video is paused when playing new video.
When playing new video, below two functions are called in order and playing video is paused.
- pause video
App/src/components/VideoPlayerContexts/PlaybackContext.tsx
Lines 41 to 49 in c7d6926
const updateCurrentlyPlayingURL = useCallback( (url: string | null) => { if (currentlyPlayingURL && url !== currentlyPlayingURL) { pauseVideo(); } setCurrentlyPlayingURL(url); }, [currentlyPlayingURL, pauseVideo], ); - update current ref
App/src/components/VideoPlayerContexts/PlaybackContext.tsx
Lines 51 to 62 in c7d6926
const shareVideoPlayerElements = useCallback( (ref: VideoWithOnFullScreenUpdate | null, parent: View | HTMLDivElement | null, child: View | HTMLDivElement | null, isUploading: boolean) => { currentVideoPlayerRef.current = ref; setOriginalParent(parent); setSharedElement(child); // Prevents autoplay when uploading the attachment if (!isUploading) { playVideo(); } }, [playVideo], );
But when uploading, first function is called after current ref is updated because we set it below.
App/src/components/VideoPlayer/BaseVideoPlayer.tsx
Lines 180 to 181 in c7d6926
// If we are uploading a new video, we want to immediately set the video player ref. | |
currentVideoPlayerRef.current = videoPlayerRef.current; |
And previous video is not paused. So I paused it before setting current ref.
videoPlayerRef.current?.getStatusAsync().then((status) => { | ||
if('rate' in status && status.rate) { | ||
updatePlaybackSpeed(status.rate as PlaybackSpeed); | ||
} | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same, what case is this fixing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assuming this test case.
- Play
Video1
. - Then change playback speed to 0.25
- Play
Video2
. - Then play
Video1
again. - Check playback speed (three dot menu -> playback speed).
Before fix, Video1
is played in speed 0.25 but in menu it is set as 1(default value).
Pressing the three dots button should not play the video Screen.Recording.2024-04-12.at.8.02.04.AM.mov |
@KMichel1030 Please go over the checklist (missing tests, screenshots, etc.) |
I'm working on this. Is it ok to add screenshots after fix? |
|
||
// update shared video elements | ||
useEffect(() => { | ||
if (shouldUseSharedVideoElement || url !== currentlyPlayingURL || isFullScreenRef.current) { | ||
if (shouldUseSharedVideoElement || url !== currentlyPlayingURL) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@s77rt
Let's check this test case.
- play
video1
. - play
video2
. - press fullscreen mode button of
video1
. - exit fullscreen mode with pressing esc key. (don't play video)
- press play button of
video1
.
Before fix:
video2
is played.
This error is occurred because currentVideoPlayerRef
is not set when enter fullscreen mode.
So I've deleted above condition.
Please let me know your suggestion.
return; | ||
} | ||
shareVideoPlayerElements(videoPlayerRef.current, videoPlayerElementParentRef.current, videoPlayerElementRef.current, isUploading); | ||
}, [currentlyPlayingURL, shouldUseSharedVideoElement, shareVideoPlayerElements, url, isUploading, isFullScreenRef]); | ||
shareVideoPlayerElements(videoPlayerRef.current, videoPlayerElementParentRef.current, videoPlayerElementRef.current, isUploading || isPopoverVisible); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In shareVideoPlayerElements
function, video is not played if last parameter is true.
So I added isPopoverVisible
to prevent auto play.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you please revert all the changes that are not related to fixing the console error. The solutions for other problems feel like band-aid and I'd prefer to handle them separately
6e7b491
to
5431131
Compare
Let's investigate this one #40132 (comment) |
@KMichel1030 Please add clear testing steps (the current steps are not enough to reproduce the bug) |
Also please add missing screenshots. |
Can you also run |
Reviewer Checklist
Screenshots/VideosMacOS: Chrome / Safariweb.movMacOS: Desktopdesktop.mov |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! Thank you @KMichel1030 for contributing!
@KMichel1030 one note: in the future preferably don't force-push your changes. I tried to look at the commit history to better understand this comment and couldn't because that history had been overwritten. Please let me know what other issues you found and I can make issues for them for you to fix 🙂 |
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
🚀 Deployed to production by https://github.com/mountiny in version: 1.4.64-6 🚀
|
Details
Fix console error after closing attachment modal and fix error on downloading and changing playback speed.
Fixed Issues
$ #38720
PROPOSAL: #38720 (comment)
Tests
.Offline tests
QA Steps
PR Author Checklist
### Fixed Issues
section aboveTests
sectionOffline steps
sectionQA steps
sectiontoggleReport
and notonIconClick
)myBool && <MyComponent />
.src/languages/*
files and using the translation methodSTYLE.md
) were followedAvatar
, I verified the components usingAvatar
are working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG)
)Avatar
is modified, I verified thatAvatar
is working as expected in all cases)Design
label and/or tagged@Expensify/design
so the design team can review the changes.ScrollView
component to make it scrollable when more elements are added to the page.main
branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTest
steps.Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari
macos.chrome.mp4
MacOS: Desktop
macos.desktop.mp4