I have developed react-native cli, react-native-video (Currently, tried to expo-video).
In a screen, there are one flatList, it has a renderItem(column2). In a renderItem renders image or video thumbnail. Like shopping app UI AMAZON.
The problem is videos. It will stops automatically by user's swipe down to phone's view. Simultaneously, below stopped video, other video player will stops. This video is in exactly middle of user's phone view!
How can i solve this?
const [videoPlayback, setVideoPlayback] = useState(false);
const viewabilityConfig = {
itemVisiblePercentThreshold: 80,
};
const _onViewableItemsChanged = useCallback((props) => {
const changed = props.changed;
changed.forEach((item) => {
if (item.item.vimeoId) {
if (item.isViewable) {
setVideoPlayback((prev) => true);
} else {
setVideoPlayback((prev) => false);
}
}
});
}, []);
...
<FlatList
ref={ref}
numColumns={2}
data={posts}
keyExtractor={(item: any) => `${item.postId}`}
viewabilityConfig={viewabilityConfig}
onViewableItemsChanged={_onViewableItemsChanged}
renderItem={({ item, index }) => (
<PostContainer item={item} videoPlayback={videoPlayback} navigation={navigation} index={index} />
)}
const PostContainer = ({ item, videoPlayback }) => {
const videoPlayer = useRef(null);
useFocusEffect(
React.useCallback(() => {
videoPlayer?.current?.seek(0);
if (videoPlayer && !videoPlayback) {
videoPlayer?.current?.seek(0);
}
}, [fadeAnim, videoPlayback]),
);
return (
<View>
{ // This place that image component rendered}
{item.vimeoId && (
<StyledVideo
ref={videoPlayer}
paused={!videoPlayback}
repeat={true}
resizeMode={"cover"}
volume={0}
source={{
uri: item.vimeoThumbnail,
}}
/>
)}
</View>
);
};
I solved my problem. There are no fault in my logic. the important thing is 'What videos are current playing?'
const _onViewableItemsChanged = useCallback(
(props) => {
const changed = props.changed;
changed.forEach((item) => {
if (item.item.vimeoId) {
const tempId = item.item.vimeoId;
if (item.isViewable) {
if (readVideosVar.list.indexOf(tempId) === -1) {
dispatch(postSlice.actions.addId(tempId));
}
} else {
dispatch(postSlice.actions.deleteId(tempId));
}
}
});
},
[dispatch],
);
addId: (state, action) => {
if (state.list.indexOf(action.payload) !== -1) {
return;
} else {
let tempA = [];
tempA.push(action.payload);
state.list = state.list.concat(tempA);
}
},
deleteId: (state, action) => {
if (state.list.indexOf(action.payload) === -1) {
return;
} else {
let stand = state.list;
let findIdx = stand.indexOf(action.payload);
let leftA = stand.slice(0, findIdx);
let rightA = stand.slice(findIdx + 1);
state.list = leftA.concat(rightA);
}
},
Compared to the existing code, I had added 'redux-toolkit'. In dispatch logic, "onViewalbeItems" had tracked chagend viewable items by real-time.
And then, I also added,
export const viewabilityConfig = {
minimumViewTime: 1000,
viewAreaCoveragePercentThreshold: 0,
};
This is just sugar.
I solved it like this !