Page MenuHomePhabricator

[native] Navigate to the image / video modal when a user clicks on a media item
ClosedPublic

Authored by rohan on Feb 13 2023, 8:40 AM.
Tags
None
Referenced Files
F1441412: D6718.id23118.diff
Fri, Mar 29, 2:35 AM
F1441411: D6718.id23077.diff
Fri, Mar 29, 2:35 AM
F1441410: D6718.id23004.diff
Fri, Mar 29, 2:35 AM
F1441409: D6718.id22951.diff
Fri, Mar 29, 2:34 AM
F1441408: D6718.id22757.diff
Fri, Mar 29, 2:34 AM
F1441407: D6718.id22754.diff
Fri, Mar 29, 2:34 AM
F1441406: D6718.id22748.diff
Fri, Mar 29, 2:34 AM
F1441405: D6718.id22746.diff
Fri, Mar 29, 2:34 AM
Subscribers

Details

Summary

We want to allow users to click on a media item in the gallery and navigate to either the VideoPlaybackModal or the ImageModal. The key parameter for the navigation is similar to the getMediaKey method (https://github.com/CommE2E/comm/blob/dc2f711faf30930a7c9f7f906a2a2b9f28d38bb0/native/chat/multimedia-message-utils.js#L129-L134). Here, for the thread media gallery, the key multimedia|${threadID}|${mediaInfo.index} is unique per media so when the key is pushed to the StackNavigator, there will be no existing duplicate key. We calculate the corners by checking the index of the media item relative to the gallery and the length of mediaInfos.

https://linear.app/comm/issue/ENG-2990/navigate-to-the-image-video-modal-when-a-user-clicks-on-a-media-item

Depends on D6660

Test Plan

Checked that the navigation works on both iOS and Android.

Diff Detail

Repository
rCOMM Comm
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

rohan edited the test plan for this revision. (Show Details)
rohan edited the summary of this revision. (Show Details)
Harbormaster returned this revision to the author for changes because remote builds failed.Feb 13 2023, 9:33 AM
Harbormaster failed remote builds in B16438: Diff 22475!
ashoat requested changes to this revision.Feb 13 2023, 3:48 PM
ashoat added inline comments.
native/chat/settings/thread-settings-media-gallery.react.js
88–89 ↗(On Diff #22475)

What are these coordinates of? Please describe exactly what it corresponds to on iOS and Android

101 ↗(On Diff #22475)

I thought the plan was to introduce a new type for this? Do VideoPlaybackModal and ImageModal actually need corners? We shouldn't be constructing useless data structures

This revision now requires changes to proceed.Feb 13 2023, 3:48 PM
native/chat/settings/thread-settings-media-gallery.react.js
88–89 ↗(On Diff #22475)

So from the touch event, React Native provides a few useful properties that would be good for determining where the event occurred relative to the viewport. There were two main options here:

locationX and locationY - these coordinates tell you, relative to the top left corner of the touchable space, where the touch event happened.

pageX and pageY - these coordinates will tell us, relative to the viewport, where the touch event happened (so relative to the top left of the screen).

Here's a demo where I log pageX, pageY and you can see how the Y coordinate jumps when the image is at the bottom of the screen as opposed to closer to the top.

Meanwhile, when logging locationX, locationY, you can see how the coordinates are contained within each TouchableOpacity, and won't really be useful in determining for the animation where the touch event occurred.

101 ↗(On Diff #22475)

You're right, I took a look originally and mistakingly saw corners calculated in InnerMultimediaMessage and assumed it was used as a prop, so I looked at how the corners were calculated and emulated the behavior. Taking another look at it, it seems like it is mainly used to determine the style for the media grid when images/videos are sent in chat (so what media should have rounded corners as opposed to normal edges). It's passed down as a property from here, but I don't see it used anywhere down the component tree.

I think the best thing to do would be to refactor MediaInfo to simply not require corners, remove it from being passed in as a prop in inner-multimedia-message, and after that update this diff to remove the corners object.

I suggest this as an alternative to introducing a new type simply without corners because I don't really see a place where the corners prop is used / extracted. It'll also be a lot cleaner than replacing every instance of MediaInfo with a new type. I tried this locally and running flow gave me no errors and media worked as expected in both chat and the thread gallery.

Open to creating a new type and replacing instances of MediaInfo if you think this won't be a good idea though

native/chat/settings/thread-settings-media-gallery.react.js
88–89 ↗(On Diff #22475)

I think these are the wrong coordinates – you're capturing the coordinates at which the touch event happened, but initialCoordinates is supposed to represent where the image was on the screen when the touch event happened

You'll need to do the onLayout / .measure approach we discussed in our 1:1

101 ↗(On Diff #22475)

Good catch!! I was able to remove corners from MediaInfo entirely without triggering any Flow errors, so I agree this is safe.

native/chat/settings/thread-settings-media-gallery.react.js
88–89 ↗(On Diff #22475)

Alright, sounds good. Since I can't call useRef inside useCallback(), I think I may have to extract the component rendering into a separate component, like GalleryItem, and there I can attach a ref and onLayout to each individual item.

I'm under the impression that measuring the entire FlatList won't get me what I need since I'm more interested in the position of the actual item inside the list, not the FlatList container, and the item's position changes as we scroll.

101 ↗(On Diff #22475)

corners will be removed in D6659 since we're passing in a mediaInfo into Multimedia there

Use onLayout and .measure to determine item position for initial coordinates. I still need to figure out the $FlowFixMe before landing, but I didn't want to block review otherwise

native/chat/settings/thread-settings-media-gallery.react.js
181–184 ↗(On Diff #22699)

I need to figure this out before landing, but I didn't want to block code review for addressing feedback

native/chat/settings/thread-settings-media-gallery.react.js
116–120 ↗(On Diff #22699)

Curious if there is a better type for this, typeof unboundStyles won't work since I'm passing in memoizedStyles here as opposed to the unbound styles. I feel like the easy solution is to accept a type Object (any), but I know we generally want to avoid that

Run yarn cleaninstall after rebase

Rerun Prettier on the commit

Try yarn eslint:fix on the stack

ashoat requested changes to this revision.Feb 20 2023, 6:54 PM

Memoization

This revision now requires changes to proceed.Feb 20 2023, 6:54 PM

Memoization (mediaInfo and navigateToMedia)

ashoat requested changes to this revision.Feb 22 2023, 4:27 PM

Memoization is perfect! Almost done here, just an issue with the index

native/chat/settings/thread-settings-media-gallery.react.js
88–98 ↗(On Diff #22951)
132–137 ↗(On Diff #22951)
153 ↗(On Diff #22951)

This actually isn't safe in the same way that getMediaKey is, since mediaInfo.index isn't a stable index here.

As new media messages are sent, the index values change for existing media. And so multimedia|123|0 can mean one thing at one time, and another thing at another time.

(In contrast, the media's index within a message is stable and will never change.)

You can imagine subtle ways this will break the system... for instance, if you open index 0, then a new image comes in, and then you quickly dismiss the old image and open the new image (before the old one finishes dismissing), React Navigation will actually just bring back the old image since it thinks you're trying to reopen the existing route with the same key.

This revision now requires changes to proceed.Feb 22 2023, 4:27 PM
native/chat/settings/thread-settings-media-gallery.react.js
153 ↗(On Diff #22951)

Fair point. Since we need a unique key for the navigation, would it be safe to say that generating a key as:

multimedia|${threadID}|${mediaInfo.id}

works instead? Each Media item should have a unique ID that wouldn't change when a new media is uploaded, and so that should (?) make the key unique per media item and avoid the situation you proposed

native/chat/settings/thread-settings-media-gallery.react.js
153 ↗(On Diff #22951)

Yeah that sounds perfect!

Syntax and change navigation key to use mediaInfo.id

native/chat/settings/thread-settings-media-gallery.react.js
135 ↗(On Diff #23004)

Prettier seems to force this here to a new line when the pre commit hooks run. Tried fixing it locally and it got corrected back to this

ashoat added inline comments.
native/chat/settings/thread-settings-media-gallery.react.js
135 ↗(On Diff #23004)

No problem

This revision is now accepted and ready to land.Feb 23 2023, 11:58 AM