Prevent the reading of video react native - react-native

I am currently developing an application that enables the user to view sports videos and I would like to implement the following feature :
The user is presented with a list of videos but can only see the next ones if he first views the first ones. At the moment I have simply added a lock on the thumbnail of the videos that should be blocked but the user can still click a bit aside and play the video. I have look through all the props of the package react-native-video but didn't see any that would fit my need. At
Would you have ideas ?
Here is also a sample of the code :
<View style={styles.videoRow}>
<View>
<Video
style={styles.image}
source={{uri: 'https://firebasestorage.googleapis.com/v0/b/roundpower-88ef9.appspot.com/o/BootyAbsPower%2FTuto%2013.mp4?alt=media&token=da011245-fce2-4796-a78b-3abc518c73ef'}}
useNativeControls
resizeMode="contain"
isLooping
onPlaybackStatusUpdate={(playbackStatus) => onPlaybackStatusUpdate3(playbackStatus)}
/>
{!debloque3 ? <View>
<FontAwesome5 name="lock" size={40} color="white" style={styles.icon}/>
</View> : <Text>''</Text>}
</View>
<View>
<Video
style={styles.image}
source={{uri: 'https://firebasestorage.googleapis.com/v0/b/roundpower-88ef9.appspot.com/o/BootyAbsPower%2FTuto%2014.mp4?alt=media&token=cd3d12be-05fd-4fc4-91d9-cd518faf14ce'}}
useNativeControls
resizeMode="contain"
isLooping
onPlaybackStatusUpdate={(playbackStatus) => onPlaybackStatusUpdate4(playbackStatus)}
/>
{!debloque4 ? <View>
<FontAwesome5 name="lock" size={40} color="white" style={styles.icon}/>
</View> : <Text>''</Text>}
</View>
</View>

Yeah, a really easy way you can do this is just prevent the thing you don't want to the user to tap on from receiving any pointerEvents (i.e. touch events).
A really simple quick-and-dirty way of doing this like so:
import * as React from 'react';
import {TouchableOpacity, StyleSheet, View} from 'react-native';
const onPress = () => console.error("I don't want this to happen.");
export default () => (
<View style={[StyleSheet.absoluteFill, styles.center]}>
{/* red box in the middle */}
<View style={{width: 50, height: 50, backgroundColor: 'red'}}>
<TouchableOpacity
onPress={onPress}
style={StyleSheet.absoluteFill}
/>
{/* Obscure the TouchableOpacity with a View which completely covers it */}
{shouldPreventTouches && <View style={StyleSheet.absoluteFill} />}
</View>
</View>
);
Alternatively, you could also just wrap the <Video /> component within a <View /> and useState to toggle between pointerEvents="none" and pointerEvents="auto". Both have the same effect of preventing touch information from being passed to children:
import * as React from 'react';
import {TouchableOpacity, StyleSheet, View} from 'react-native';
const onPress = () => console.error("I don't want this to happen.");
export default () => (
<View style={[StyleSheet.absoluteFill, styles.center]}>
{/* red box in the middle */}
<View
pointerEvents={shouldPreventTouches ? 'none' : 'auto'}
style={{width: 50, height: 50, backgroundColor: 'red'}}>
<TouchableOpacity
onPress={onPress}
style={StyleSheet.absoluteFill}
/>
</View>
</View>
);
Depends what you prefer.

You could reuse the logic you have for showing the lock or not on the video element, and render the video only if it is unlocked.
<View>
{
debloque ? <Video/> : <FontAwesome5 name="lock" size={40} color="white" style={styles.icon} />
}
</View>
Alternatively you could set the source of the video to null until it is unlocked, to initialize the player but prevent anything to be played, according to the docs.

Related

React Native TextInput keeps unfocusing and refreshi8ng the whole page after I type one character

return(
<View style={styles.container}>
<View style={styles.searchbarContainer}>
<TouchableOpacity style={styles.ThreeLineButton} onPress={returnHome}>
<Text style={{color: 'white', fontSize: 20,}}>Done</Text>
</TouchableOpacity>
{/* <Text style={{color: 'white', fontSize: 50, marginLeft: 50}}>UStudy</Text> */}
{/* <TextInput style={styles.searchbarStyle} placeholder="Search Ustudy" placeholderTextColor='#FFF' onChangeText={setSearchText} value={searchText} onChange={refreshSearch} /> */}
</View>
<ScrollView
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={onRefresh}
/>
}
>
<FlatList
ref={(ref) => { this.commentListRef = ref; }}
data={allComments}
renderItem={({item}) => <CommentCard item={item} />}
keyExtractor={item=>item.docID}
showsVerticalScrollIndicator={false}
style={{
width: '110%',
}}
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={onRefresh}
/>
}
/>
</ScrollView>
</View>
);
};
export default DynamicPostScreen
here is the code of my UI and how the TextInput is embeded. Whenever I type a character in my TextInput it refreshes the whole page and unfocuses from the TextInput. How do I stop this from happening?
Unfortunately, you didn't provide the full code of the component. I recommend you refactor the component and give it proper formatting, especially the indentation.
Also, you usually don't want a FlatList inside a ScrollView, there is probably an issue there.
About the question itself, I can't be 100% sure without the full code.
But it's possible that your setSearchText is triggering a useState change and therefore rerendering the component (that's what a state does).
This is a state management problem and you could move the TextInput to a separate component and manage the state from there so the parent component won't rerender.
Another possibility is that by using onChangeText and onChange you are triggering the render, probably with the refreshSearch function.
If this didn't help, please follow my instructions at the beginning and I'm happy to look at it again.

react native TouchableOpacity onpress problem

i'm using TabView and in every tab i use flatList. every list item has phone and email button. But TouchableOpacity onpress not working so i use onPressOut. onPressOut working but it works when i touched in not when touched out. you guys have any ideas why this is happennig
<View style={styles.ButtonGroup}>
<TouchableOpacity
style={[styles.ButtonCont, {backgroundColor: '#BEF7D1'}]}
onPressOut={() => {
Linking.openURL(`tel:+90${data.item.kiraci_gsm1}`);
}}>
<Icon
name={'phone'}
type="font-awesome-5"
size={24}
color="#036122"
/>
</TouchableOpacity>
<TouchableOpacity
style={[styles.ButtonCont, {backgroundColor: '#C6E1FF'}]}
onPressOut={() => {
Linking.openURL(`mailto:${data.item.kiraci_eposta1}`);
}}>
<Icon
name={'envelope'}
type="font-awesome"
size={24}
color="#0050AC"
/>
</TouchableOpacity>
</View>
Pay attention from where import your "TouchableOpacity". When I changed "TouchableOpacity" from "react-native-gesture-handler" to "react-native" for Android platform.

React Navigation Top Bar Getting Same Height (NOT) dependent on its own components

Looking at this example from React Navigation website, between Chat and Contacts, the heights are independent of each other. However, When I tried to implement a top bar, the heights are the same. It takes the height of which ever tab has the most content in it.
But in the example, you can see in Contacts that there may be more contacts where you can scroll, and in Chat, the input field is at the bottom, making it look like that's where it stops.
Here's a screen shot from the example:
Chat tab
Contacts tab
Here's some of my code and what I'm experiencing:
<View style={{backgroundColor: 'orange'}}>
{!loading &&
!loadingProfileInfo &&
typeof data.infoByUser !== 'undefined' && (
<FlatList
data={data.infoByUser}
ListHeaderComponent={
<View>
<UserInfo />
<Tab.Navigator>
<Tab.Screen
name="Test"
component={TestComponent} />
<Tab.Screen
name="New Tab"
component={NewTabComponent}
/>
</Tab.Navigator>
</View>
}
numColumns={2}
renderItem={({item}) => (
<View>
// ...
</View>
)}
keyExtractor={item => item._id}
/>
)}
</View>
TestComponent
<View style={{backgroundColor: 'grey'}}>
<View>
<Text>Test Test</Text>
</View>
<View>
<Text>Test Test</Text>
</View>
<View>
<Text>Test Test</Text>
</View>
<View>
<Text>Test Test</Text>
</View>
<View>
<Text>Test Test</Text>
</View>
</View>
NewTabComponent
<View style={{backgroundColor: 'red'}}>
<Text>new tab</Text>
</View>
Notice how the New Tab has a big gap between the red and the orange, that's from the Test tab's height.
You are rendering your entire navigator as the FlatList 'header'. You shouldn't even use Flatlist in this component. Each screen has a different number of items, and should have its own Flatlist.
To fix this:
Remove the FlatList from your main component (with backgroundColor: 'orange'), and just render the Tab Navigator in that render function.
Inside of TestComponent and NewTabComponent, render a ScrollView (or FlatList) if you need it.
All screens (TestComponent and NewTabComponent) should have a height: '100%' or flex: 1 if you want all screens to take all up all the space of the screen, even when its real height is less than the screen height.
To have heights according to the content inside the particular tab, use Scrollview inside each tab screen. Thank me later if this works perfectly. :)
import * as React from "react";
import { ScrollView, Text, View } from "react-native";
import { createMaterialTopTabNavigator } from "#react-navigation/material-top-tabs";
function Screen1() {
return (
<ScrollView>
<View style={{ flex: 1, alignItems: "center" }}>
<Text style={{ padding: 10 }}>Screen1 </Text>
</View>
</ScrollView>
);
}
function Screen2() {
return (
<ScrollView>
<View style={{ flex: 1, alignItems: "center" }}>
<Text style={{ padding: 10 }}>Screen2</Text>
</View>
</ScrollView>
);
}
function Screen3() {
return (
<ScrollView>
<View style={{ flex: 1, alignItems: "center" }}>
<Text style={{ padding: 10 }}>Screen3 </Text>
</View>
</ScrollView>
);
}
const Tab = createMaterialTopTabNavigator();
export default function TopBarNavigator() {
return (
<Tab.Navigator>
<Tab.Screen name="Screen1" component={Screen1} />
<Tab.Screen name="Screen2" component={Screen2} />
<Tab.Screen name="Screen3" component={Screen3} />
</Tab.Navigator>
);
}
I'm having no idea why you're rendering it inside FlatList as it also inherits props from Scroll View.
<View style={{backgroundColor: 'orange'}}>
<Tab.Navigator>
<Tab.Screen
name="Test"
component={TestComponent} />
<Tab.Screen
name="New Tab"
component={NewTabComponent}
/>
</Tab.Navigator>
</View>
and move the FlatList and other business logics inside the TestComponent or the NewTabComponent.
The point is don't render Tabs inside ScrollView or FlatList or SectionList as they both inherit the props of ScrollView.
After a long research I found out that your problem is because react-native-tab-view (which is used by material-tob-tabs), has this code :
_defineProperty(this, "handleLayout", e => {
const {
height,
width
} = e.nativeEvent.layout;
if (this.state.layout.width === width && this.state.layout.height === height) {
return;
}
this.setState({
layout: {
height,
width
}
});
With option lazy={true} , and using the "New Tab" component on first tab and "Test" on second, you get the right height until you change the tab. When you press on "Test" the layout changes so the height is bigger. After changing tab the height does't change anymore because the layout stays the same ("New Tab" fits perfectly in the bigger height) and doesn't trigger handleLayout from react-native-tab-view.
Hope you can find a way to change the layout again when you change tabs.

ScrollView does not show all content in react native

I have a page with some Components. I am using scrollview to scroll through the page but some content does not show. Here is my code:
render() {
const screenHeight = Dimensions.get('window').height
const {currentItem,callsData}=this.state;
return (
<SafeAreaView style={CustomStyles.container}>
<View style={{flexDirection:'row-reverse',padding:10}}>
<View style={{flex:1,justifyContent:'center',flexDirection:'row'}}>
<CustomText style={[CustomStyles.titleWhite]}>Sponsers</CustomText></View>
<TouchableWithoutFeedback onPress={()=>this.props.navigation.goBack()} style={{marginLeft:20,padding:10,}}>
<Icon name='md-arrow-round-back' color={'white'} size={32} />
</TouchableWithoutFeedback>
</View>
<ScrollView contentContainerStyle={{flexGrow:1,height:screenHeight}}>
<View>
{(this.state.done===1)?
<View >
<CustomText style={[CustomStyles.titleWhite,{alignSelf: 'center',}]}> {currentItem.title} </CustomText>
<Image style={{width:'100%',height:'30%',resizeMode:'contain'}} source={{uri:Strings.imageUrl+ currentItem.image1}}/>
<CustomText style={[{color:'white',lineHeight:24}]}>{currentItem.body}</CustomText>
<Video source={{uri:currentItem.videoLink}} // Can be a URL or a local file.
controls={true} // Store reference
onBuffer={this.onBuffer} // Callback when remote video is buffering
onError={this.videoError} // Callback when video cannot be loaded
paused={true}
style={{width:'100%',height:screenHeight/4,}} />
<View style={{flexDirection:'row-reverse'}}>
<Icon />
</View>
<View style={{flexDirection:'row-reverse'}}>
<CustomText style={CustomStyles.whiteTxt}>website: </CustomText>
<CustomText style={{color:Colors.yellow,marginRight: 3}}>{currentItem.website}</CustomText>
</View>
<View style={{flexDirection:'row-reverse'}}>
<CustomText style={CustomStyles.whiteTxt}>Address: </CustomText>
<CustomText style={{color:Colors.yellow,marginRight: 3,}}>{currentItem.address}</CustomText>
</View>
<View style={{flexDirection:'row-reverse'}}>
<CustomText style={[CustomStyles.whiteTxt,]}>Calls: </CustomText>
<FlatList
data={callsData}
contentContainerStyle={{alignItems:'flex-end',marginRight:4}}
keyExtractor={(index)=>index}
renderItem={({item,index})=>
<TouchableOpacity onPress={()=>this.renderCall(index)}>
<CustomText style={{color:Colors.yellow}}>{item}</CustomText></TouchableOpacity>}
/>
<View style={{flex:1}}/>
</View>
</View>
:
<ActivityIndicator/>}</View>
</ScrollView>
</SafeAreaView>
);
}
EDIT: Here is CustomStyles.js, Colors file is just containing color codes:
import { StyleSheet } from 'react-native';
import Colors from '../Values/Colors'
export default StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'black',
},
titleWhite:{
color:'white',
fontSize:18,margin:5
},
})
I also tried to use View instead of SafeAreaView but the problem did not solved. the bottom component does not show.
help me please
I think the problem is in Image component height property. I change it from "percent" to number like this From:
height:'30%'
to
height:.3*screenHeight
And now the ScrollView work fine

How can I achieve this modal design with react native

I am trying design like below image with react native.If anyone have worked like this modal design over the toolbar then please help me.
1
You will need a Modal with a embedded TouchableOpacity combined with some styling for positioning.
Please refer this
https://snack.expo.io/SJrDAC8Qr
render() {
return (
<>
<View>
<Appbar.Header>
<Appbar.Content title="Title" subtitle="Subtitle" />
<Appbar.Action icon="search" onPress={() => this.setState({displayModal: true})} />
</Appbar.Header>
<View>
<Text>Main content!</Text>
</View>
</View>
{/*Modal code*/}
<Modal transparent={true} visible={this.state.displayModal}>
{/*Container .. clicking this closes the modal*/}
<TouchableOpacity style={{flex:1}} onPress={() => this.setState({displayModal:false})}>
<View style={{backgroundColor:'blue', position:'absolute', right:0, width:200, height: 200}}>
<Text style={{color:'#ffffff'}}>Hello World!</Text>
</View>
</TouchableOpacity>
</Modal>
</>
);
}
Not very nicely styled but I guess it does what you want