@react-navigation/native#CommonActions JavaScript Examples
The following examples show how to use
@react-navigation/native#CommonActions.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Profile.js From id.co.moonlay-eworkplace-mobile with MIT License | 6 votes |
async LogOut(){
const value = await AsyncStorage.getItem('state');
if(value === '1'){
alert('You must clock out before log out!')
}
else if(value === '0'){
this.deleteJWT();
this.props.delete();
await AsyncStorage.removeItem('user_permission');
await AsyncStorage.removeItem('username');
await AsyncStorage.removeItem('name');
await AsyncStorage.removeItem('firstname');
await AsyncStorage.removeItem('division');
await AsyncStorage.removeItem('job_title');
await AsyncStorage.removeItem('location');
await AsyncStorage.removeItem('clockinHour');
await AsyncStorage.removeItem('clockinMinute');
await AsyncStorage.removeItem('id_user');
this.props.navigation.dispatch(
CommonActions.navigate({
name: 'Login',
})
);
}
}
Example #2
Source File: consts.js From guardioes-app with Apache License 2.0 | 6 votes |
showSurveillanceInvite = (
name,
{ status, body },
func,
navigation
) => {
const title = translate('surveillance.titleMessage')
const message = `${getNameParts(name)}, ${translate(
'surveillance.message'
)}`
Alert.alert(title, message, [
{
text: translate('surveillance.cancelButton'),
onPress: () => {
func(status, body)
},
},
{
text: translate('surveillance.redirectButton'),
onPress: () => {
navigation.dispatch(
CommonActions.reset({
index: 1,
routes: [
{ name: 'HomeDrawer' },
{ name: 'Vigilancia' },
],
})
)
},
},
])
}
Example #3
Source File: index.js From atendimento-e-agilidade-medica-AAMed with MIT License | 6 votes |
Header = ({ flag, navigation, label }) => {
return (
<Container>
{flag ? (
<>
<ButtonLeft onPress={() => navigation.toggleDrawer()}>
<Ionicons name="md-menu" size={35} color="#fff" />
</ButtonLeft>
<ImgCenter source={require('../../assets/icon_.png')} />
<ButtonRight onPress={() => navigation.navigate('Help')}>
<Feather name="help-circle" size={35} color="#fff" />
</ButtonRight>
</>
) : (
<>
<ButtonLeft
onPress={() => navigation.dispatch(CommonActions.goBack())}
>
<Ionicons name="md-arrow-back" size={30} color="#fff" />
</ButtonLeft>
<Label>{label}</Label>
<ImgLeft source={require('../../assets/icon_.png')} />
</>
)}
</Container>
);
}
Example #4
Source File: ModalListener.js From actual with MIT License | 6 votes |
function ModalListener({ modalStack, navigatorRef, popModal }) {
useLayoutEffect(() => {
if (modalStack.length > 0) {
let last = modalStack[modalStack.length - 1];
let { name, options = {} } = last;
switch (name) {
case 'create-encryption-key':
navigatorRef.current.dispatch(
CommonActions.navigate('CreateEncryptionKeyModal', options)
);
popModal();
break;
case 'fix-encryption-key':
navigatorRef.current.dispatch(
CommonActions.navigate('FixEncryptionKeyModal', options)
);
popModal();
break;
case 'settings':
navigatorRef.current.dispatch(
CommonActions.navigate('Settings', options)
);
popModal();
break;
default:
}
}
}, [modalStack]);
return null;
}
Example #5
Source File: navigation.js From stayaway-app with European Union Public License 1.2 | 5 votes |
function goBack(...args) {
if (navigationRef.current) {
navigationRef.current.dispatch(CommonActions.goBack(...args));
}
}
Example #6
Source File: navigation-service.js From React-Native-Boilerplate with MIT License | 5 votes |
function goBack(key) {
_navigator.dispatch(
CommonActions.back({
key: key,
}),
);
}
Example #7
Source File: versionCheck.js From filen-mobile with GNU Affero General Public License v3.0 | 5 votes |
checkAppVersion = async ({ navigation }) => {
if(typeof navigation !== "undefined"){
if(typeof navigation.current !== "undefined"){
if(typeof navigation.current.routes !== "undefined"){
if(navigation.current.getState().routes.filter(route => route.name == "UpdateScreen").length !== 0){
return false
}
}
}
}
const netInfo = useStore.getState().netInfo
if(!netInfo.isConnected || !netInfo.isInternetReachable){
return false
}
if((storage.getNumber("lastAppVersionCheck") + CHECK_TIMEOUT) > Math.floor(+new Date() / 1000)){
return false
}
storage.set("lastAppVersionCheck", Math.floor(+new Date() / 1000))
try{
var latestVersion = await getLatestVersion()
var currentVersion = DeviceInfo.getVersion()
var needsUpdate = compareVersions(currentVersion, latestVersion) == "update"
}
catch(e){
return console.log(e)
}
if(!needsUpdate.isNeeded){
return false
}
navigationAnimation({ enable: true }).then(() => {
navigation.current.dispatch(CommonActions.reset({
index: 0,
routes: [
{
name: "UpdateScreen"
}
]
}))
})
return true
}
Example #8
Source File: UserButton.js From actual with MIT License | 5 votes |
function UserButton({
navigation,
userData,
error,
keyId,
showActionSheetWithOptions,
onLogOut
}) {
function onPress() {
if (userData || error) {
let options = ['Log out', 'Cancel'];
showActionSheetWithOptions(
{
options,
cancelButtonIndex: 1,
title: error
? 'The current logged in user could not be authenticated. This usually means you are offline.'
: userData.email
},
idx => {
switch (idx) {
case 0:
onLogOut();
break;
}
}
);
} else {
navigation.dispatch(CommonActions.navigate({ routeName: 'Login' }));
}
}
if (userData) {
if (userData.offline) {
return (
<View
style={{
alignSelf: 'center',
justifySelf: 'center',
padding: 5,
top: -5
}}
>
<Text style={{ fontSize: 15, color: 'white' }}>Offline</Text>
</View>
);
}
return (
<Button
bare
style={{
backgroundColor: 'transparent',
borderRadius: 4,
fontSize: 15,
padding: 5,
paddingVertical: 10,
top: -5
}}
textStyle={{ color: colors.n8, fontSize: 13 }}
onPress={onPress}
>
{keyId && (
<Key
style={{ width: 12, height: 12, color: 'white', marginRight: 7 }}
/>
)}
<Text style={{ fontSize: 15, color: 'white' }}>{userData.email}</Text>
</Button>
);
}
return null;
}
Example #9
Source File: navigation-service.js From React-Native-Boilerplate with MIT License | 5 votes |
function navigate(routeName, params) {
_navigator.dispatch(
CommonActions.navigate({
name: routeName,
params: params,
}),
);
}
Example #10
Source File: OrderConfirmed.js From salyd with GNU General Public License v3.0 | 5 votes |
OrderConfirmed = ({ navigation }) => {
const goToHome = () => {
navigation.dispatch(
CommonActions.reset({
index: 0,
routes: [
{
name: 'HomeMain',
},
],
})
);
}
return (
<View style={{
height: Dimensions.get("window").height,
backgroundColor: colors.back,
justifyContent: "center",
alignItems: "center"
}}>
<Icon name="checkbox-marked-circle-outline" size={100} color={colors.accentPrimary}></Icon>
<Text style={{
fontSize: 17, color: colors.accentPrimary, marginTop: 10,
}}>Your Order Is Confirmed</Text>
<Button
icon="home"
color={colors.accentPrimary}
style={{
marginTop: 20
}}
dark
mode="contained"
size={20}
onPress={() => goToHome()}
>Home</Button>
</View>
)
}
Example #11
Source File: Login.js From salyd with GNU General Public License v3.0 | 4 votes |
Login = ({ navigation }) => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [submitting, isSubmitting] = useState(false);
const { updateUser, user, token, updateToken } = useContext(GlobalContext);
const signin = () => {
isSubmitting(true)
Axios.post(`${apiUrl}/signin`, {
"email": email,
"password": password
})
.then(async (res) => {
updateToken(res.data.token)
updateUser(res.data.user)
//Updating asyncstorage for persistence
await AsyncStorage.setItem('token', res.data.token);
await AsyncStorage.setItem('user', JSON.stringify(res.data.user));
isSubmitting(false)
navigation.dispatch(
CommonActions.reset({
index: 0,
routes: [
{
name: 'MainApp',
},
],
})
);
})
.catch(err => { isSubmitting(false); console.log(err) })
}
const signUpRedirect = () => {
navigation.navigate("SignUp");
}
const forgotPass = () => {
navigation.navigate("ForgotPassword")
}
return (
<View style={{ ...styles.container, height: Dimensions.get("screen").height }}>
<KeyboardAvoidingView behavior="position">
<Header isBack navigation={navigation}>Sign In</Header>
<TextInput
label="Email"
value={email}
underlineColor="transparent"
theme={{ roundness: 20, colors: { primary: colors.accentPrimary } }}
style={styles.inputbox}
onChangeText={(text) => setEmail(text)}
/>
<TextInput
label="Password"
value={password}
secureTextEntry={true}
underlineColor="transparent"
theme={{ roundness: 20, colors: { primary: colors.accentPrimary } }}
style={styles.inputbox}
onChangeText={(text) => setPassword(text)}
/>
<View style={{
alignItems: "center",
marginTop: 20,
}}>
{
submitting ? < ActivityIndicator color={colors.accentPrimary} /> : (
<Button onPressFunction={() => signin()}>Logout</Button>
)
}
</View>
<TouchableOpacity onPress={() => signUpRedirect()}>
<Text style={{
marginHorizontal: 25,
marginTop: 25,
fontSize: 16,
paddingLeft: 10,
borderRadius: 20,
fontFamily: "ProductSans"
}} >
Dont Have an account ? SignUp
</Text>
</TouchableOpacity>
<TouchableOpacity onPress={() => forgotPass()}>
<Text style={{
marginHorizontal: 25,
marginTop: 25,
fontSize: 16,
paddingLeft: 10,
borderRadius: 20,
color: colors.accentPrimary,
fontFamily: "ProductSans"
}} >
Forgot Password
</Text>
</TouchableOpacity>
</KeyboardAvoidingView>
</View>
)
}
Example #12
Source File: sick.js From id.co.moonlay-eworkplace-mobile with MIT License | 4 votes |
async submitAll(){
const value = await AsyncStorage.getItem('clockin_state2');
const location = await AsyncStorage.getItem('location');
const sickValue = await AsyncStorage.getItem('sick_submit');
if(this.props.clockin_status === true || value === 'clockin'){
Alert.alert(
"You can't submit!",'You have clocked in today, your next submit will be start tomorrow at 07.00 AM',
[
{ text: "OK", onPress: () => console.log('OK'), style: "cancel"},
],
{ cancelable: false },
);
this.props.addLoad(false)
return true;
}
else if(this.state.headDivision === '' || this.state.projectName === '' || this.state.message === ''){
alert('All form must be filled!');
}
else if(sickValue === '1'){
Alert.alert(
"You can't submit!",'You have submitted sick form today. Your next submit will be start tomorrow at 07.00 AM',
[
{ text: "OK", onPress: () => console.log('OK'), style: "cancel"},
],
{ cancelable: false },
);
this.props.addLoad(false)
return true;
}
else if(location === null || location === ''){
Alert.alert(
'Location is nowhere','You must enable your location before clock in!',
[
{ text: "OK", onPress: () => console.log('OK'), style: "cancel"},
],
{ cancelable: false },
);
this.props.addLoad(false)
return true;
}
else if(this.state.headDivision !== '' && this.state.projectName !== '' && this.props.clockin_status === false && this.state.message !== ''){
axios({
method: 'POST',
url: Url_Clockin,
headers: {
'accept': 'application/json',
'Authorization': 'Bearer ' + this.props.tokenJWT
},
data: {
Username: this.state.username,
Name: this.state.fullname,
CheckIn: new Date(),
State: this.state.status,
Location : this.state.Location,
Approval : 'Pending',
ApprovalByAdmin : 'Pending',
HeadDivision: this.state.headDivision,
ProjectName: this.state.projectName,
Note: this.state.message
}
}).then((response) => {
console.log('Success: Submit sick data')
this.props.addClockin(false, ' ', this.state.idUser, this.state.status);
this.setState({
idUser: response.data.Id,
});
deviceStorage.saveItem("sick_submit", "1");
deviceStorage.saveItem("sick_submit_day", moment().format('dddd'));
this.props.addLoad(true)
if(this.state.permission === 1){
this.props.navigation.dispatch(
CommonActions.reset({
index: 1,
routes: [
{ name: 'HomeHD' },
],
})
)
}
else if(this.state.permission === 2){
this.props.navigation.dispatch(
CommonActions.reset({
index: 1,
routes: [
{ name: 'Home' },
],
})
)
}
ToastAndroid.showWithGravity(
'Submit success!',
ToastAndroid.SHORT,
ToastAndroid.BOTTOM,
);
})
.catch((errorr) => {
console.log('Error: Submit sick data')
ToastAndroid.showWithGravity(
'Submit fail!',
ToastAndroid.SHORT,
ToastAndroid.BOTTOM,
);
});
}
}
Example #13
Source File: WorkHome.js From id.co.moonlay-eworkplace-mobile with MIT License | 4 votes |
async submitAll(){
if(this.props.announcement !== ''){
Alert.alert(
"You can't clock in!",this.props.announcement,
[
{ text: "OK", onPress: () => console.log('OK'), style: "cancel"},
],
{ cancelable: false },
);
return true;
}
else{
const value = await AsyncStorage.getItem('clockin_state2');
const location = await AsyncStorage.getItem('location');
const sickValue = await AsyncStorage.getItem('sick_submit');
//Get Hour
const hour = new Date().getHours();
console.log('Time right now: '+hour)
if(this.props.clockin_status === true || value === 'clockin'){
Alert.alert(
'You have clocked in today!','Your next clock in will be start tomorrow at 07.00 AM',
[
{ text: "OK", onPress: () => console.log('OK'), style: "cancel"},
],
{ cancelable: false },
);
this.props.addLoad(false)
return true;
}
else if(hour <= 6){
Alert.alert(
"You can't clock in!",'Clock in time only available at 7 AM - 24 PM',
[
{ text: "OK", onPress: () => console.log('OK'), style: "cancel"},
],
{ cancelable: false },
);
this.props.addLoad(false)
return true;
}
else if(this.state.headDivision === '' || this.state.urlphoto === '' || this.state.projectName === '' || this.state.message === ''){
alert('All form must be filled!');
}
else if(sickValue === '1'){
Alert.alert(
"You can't clock in!",'You have submitted sick form today. Your next clock in will be start tomorrow at 07.00 AM',
[
{ text: "OK", onPress: () => console.log('OK'), style: "cancel"},
],
{ cancelable: false },
);
this.props.addLoad(false)
return true;
}
else if(location === null || location === ''){
Alert.alert(
'Location is nowhere','You must enable your location before clock in!',
[
{ text: "OK", onPress: () => console.log('OK'), style: "cancel"},
],
{ cancelable: false },
);
this.props.addLoad(false)
return true;
}
else if(this.state.headDivision !== '' && this.state.urlphoto !== '' && this.state.projectName !== '' && this.props.clockin_status === false && this.state.message !== '' && hour > 6){
const clockintime = new Date();
axios({
method: 'POST',
url: Url_Clockin,
headers: {
'accept': 'application/json',
'Authorization': 'Bearer ' + this.props.tokenJWT
},
data: {
Username: this.state.username,
Name: this.state.fullname,
CheckIn: clockintime,
State: this.state.status,
Photo : this.state.urlphoto,
Location : this.state.Location,
Note : this.state.message,
ProjectName : this.state.projectName,
Approval : 'Pending',
ApprovalByAdmin : 'Pending',
HeadDivision : this.state.headDivision
}
}).then((response) => {
console.log('Success: Clock in work from home')
this.setState({
statusCheckIn: ' ',
idUser: response.data.Id,
clockInstatus: true,
});
deviceStorage.saveItem("clockin_state", "clockin");
deviceStorage.saveItem("state", '1');
deviceStorage.saveItem("clockinHour", new Date().getHours().toString());
deviceStorage.saveItem("clockinMinute", new Date().getMinutes().toString());
deviceStorage.saveItem("id_user", JSON.stringify(this.state.idUser));
this.props.addClockin(this.state.clockInstatus, this.state.statusCheckInn, this.state.idUser, this.state.status)
this.props.addLoad(true)
ToastAndroid.showWithGravity(
'Clock in success!',
ToastAndroid.SHORT,
ToastAndroid.BOTTOM,
);
if(this.state.permission === 1){
this.props.navigation.dispatch(
CommonActions.reset({
index: 1,
routes: [
{ name: 'HomeHD' },
],
})
)
}
else if(this.state.permission === 2){
this.props.navigation.dispatch(
CommonActions.reset({
index: 1,
routes: [
{ name: 'Home' },
],
})
)
}
})
.catch((errorr) => {
console.log('Error: Clock in work from home')
ToastAndroid.showWithGravity(
'Clock in fail!',
ToastAndroid.SHORT,
ToastAndroid.BOTTOM,
);
});
}
}
}
Example #14
Source File: WorkClient.js From id.co.moonlay-eworkplace-mobile with MIT License | 4 votes |
async submitAll(){
if(this.props.announcement !== ''){
Alert.alert(
"You can't clock in!",this.props.announcement,
[
{ text: "OK", onPress: () => console.log('OK'), style: "cancel"},
],
{ cancelable: false },
);
return true;
}
else{
const value = await AsyncStorage.getItem('clockin_state2');
const location = await AsyncStorage.getItem('location');
const sickValue = await AsyncStorage.getItem('sick_submit');
//Get Hour
const hour = new Date().getHours();
console.log('Time right now: '+hour)
if(this.props.clockin_status === true || value === 'clockin'){
Alert.alert(
'You have clocked in today!','Your next clock in will be start tomorrow at 07.00 AM',
[
{ text: "OK", onPress: () => console.log('OK'), style: "cancel"},
],
{ cancelable: false },
);
this.props.addLoad(false)
return true;
}
else if(hour <= 6){
Alert.alert(
"You can't clock in!",'Clock in time only available at 7 AM - 24 PM',
[
{ text: "OK", onPress: () => console.log('OK'), style: "cancel"},
],
{ cancelable: false },
);
this.props.addLoad(false)
return true;
}
else if(this.state.headDivision === '' || this.state.urlphoto === '' || this.state.projectName === '' || this.state.client === '' || this.state.clientCompany === ''){
alert('All form must be filled!');
}
else if(sickValue === '1'){
Alert.alert(
"You can't clock in!",'You have submitted sick form today. Your next clock in will be start tomorrow at 07.00 AM',
[
{ text: "OK", onPress: () => console.log('OK'), style: "cancel"},
],
{ cancelable: false },
);
this.props.addLoad(false)
return true;
}
else if(location === null || location === ''){
Alert.alert(
'Location is nowhere','You must enable your location before clock in!',
[
{ text: "OK", onPress: () => console.log('OK'), style: "cancel"},
],
{ cancelable: false },
);
this.props.addLoad(false)
return true;
}
else if(this.state.headDivision !== '' && this.state.urlphoto !== '' && this.state.projectName !== ''
&& this.state.client !== '' && this.state.clientCompany !== '' && this.props.clockin_status === false && hour > 6){
const clockintime = new Date();
axios({
method: 'POST',
url: Url_Clockin,
headers: {
'accept': 'application/json',
'Authorization': 'Bearer ' + this.props.tokenJWT
},
data: {
Username: this.state.username,
Name: this.state.fullname,
CheckIn: clockintime,
State: this.state.status,
Location : this.state.Location,
Approval : 'Pending',
ApprovalByAdmin : 'Pending',
Photo: this.state.urlphoto,
CompanyName: this.state.clientCompany,
ClientName: this.state.client,
ProjectName: this.state.projectName,
HeadDivision: this.state.headDivision
}
}).then((response) => {
console.log('Success: Clock in at client office')
this.setState({
statusCheckIn: ' ',
clockInstatus: true,
idUser: response.data.Id,
});
deviceStorage.saveItem("clockin_state", "clockin");
deviceStorage.saveItem("state", '1');
deviceStorage.saveItem("clockinHour", new Date().getHours().toString());
deviceStorage.saveItem("clockinMinute", new Date().getMinutes().toString());
deviceStorage.saveItem("id_user", JSON.stringify(this.state.idUser));
this.props.addClockin(this.state.clockInstatus, this.state.statusCheckInn, this.state.idUser, this.state.status)
this.props.addLoad(true)
ToastAndroid.showWithGravity(
'Clock in success!',
ToastAndroid.SHORT,
ToastAndroid.BOTTOM,
);
if(this.state.permission === 1){
this.props.navigation.dispatch(
CommonActions.reset({
index: 1,
routes: [
{ name: 'HomeHD' },
],
})
)
}
else if(this.state.permission === 2){
this.props.navigation.dispatch(
CommonActions.reset({
index: 1,
routes: [
{ name: 'Home' },
],
})
)
}
})
.catch((errorr) => {
console.log('Error: Clock in at client office')
ToastAndroid.showWithGravity(
'Clock in fail!',
ToastAndroid.SHORT,
ToastAndroid.BOTTOM,
);
});
}
}
}
Example #15
Source File: Table.js From salyd with GNU General Public License v3.0 | 4 votes |
Table = ({ navigation }) => {
const [selectedValue, setSelectedValue] = useState("view");
const [restro, setRestro] = useState({});
const [submitting, isSubmitting] = useState(false);
const { token, globalRoomId, updateTable, updateRoom, globalTableId, updateRestro } = useContext(GlobalContext);
useEffect(() => {
Axios({
url: `${apiUrl}/getrestro`,
method: 'post',
headers: {
"Content-Type": "application/json"
},
data: { "tableId": globalTableId }
}).then((res) => {
console.log(res.data);
setRestro(res.data.tableOf);
//Updating the restro in global state
updateRestro(res.data.tableOf);
}).catch((err) => {
res.status(422).json(err);
})
}, [])
const onSubmit = () => {
isSubmitting(true)
Axios({
url: `${apiUrl}/permission/grant`,
method: 'post',
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`
},
data: { "permission": selectedValue }
})
.then((res) => {
console.log(res.data)
isSubmitting(false)
navigation.dispatch(
CommonActions.reset({
index: 0,
routes: [
{
name: 'Menu',
},
],
})
);
}).catch((err) => {
isSubmitting(false)
console.log(err);
})
}
const exitTable = async () => {
updateRoom(null)
updateTable(null)
const tableid = await AsyncStorage.removeItem('tableId')
navigation.navigate('HomeMain')
}
console.log()
return (
<View>
<Header navigation={navigation} isBack>Your Table</Header>
<View style={styles.container}>
<View style={{
marginTop: 30,
marginBottom: 50,
flexDirection: "row",
justifyContent: "space-around",
alignItems: "center"
}}>
<View style={{
flex: 2,
alignItems: "center"
}}>
<Text style={{
color: "black",
fontSize: 50,
textAlign: "center",
color: colors.accentPrimary,
fontFamily: "ProductSansBold",
}}>{globalRoomId}</Text>
<View style={{
alignItems: "center",
flexDirection: "row"
}} >
<View style={{
backgroundColor: colors.accentPrimary,
height: 3,
width: 100,
borderRadius: 20
}} />
<View style={{
backgroundColor: colors.accentPrimary,
height: 3,
marginLeft: 5,
width: 15,
borderRadius: 20
}} />
</View>
</View>
<View style={{
flex: 3,
}}>
<Image style={{
marginLeft: 40,
width: 152,
height: 174
}} source={require("../../../assets/share_Image.png")} />
</View>
</View>
{/* SHARE ID */}
<View style={{
flexDirection: "row",
backgroundColor: "#d8ffcf",
borderRadius: 10,
padding: 20,
alignItems: "center"
}}>
<FontAwesome5 style={{
marginRight: 20
}} name="lightbulb" size={24} color="black" />
<Text style={{
fontFamily: "ProductSans",
marginRight: 30
}}>Share this Room Id with your colleagues to let them join the table</Text>
</View>
{/* GRANT PERMISSION */}
<View style={{
marginTop: 40
}}>
<Text style={{
fontSize: 20,
textAlign: "center",
fontFamily: "ProductSans"
}}> Grant permission to the members</Text>
<View style={{
margin: 0,
padding: 0,
height: 70,
alignItems: "center",
flexDirection: 'row',
justifyContent: "center"
}}>
<Button
colorBack={selectedValue === "view" ? colors.accentPrimary : "#d8ffcf"}
colorText={selectedValue === "view" ? colors.back : colors.accentPrimary}
mystyle={{
borderTopRightRadius: 0,
borderBottomRightRadius: 0
}}
onPressFunction={() => setSelectedValue("view")}
>
View
</Button>
<Button
colorBack={selectedValue === "edit" ? colors.accentPrimary : "#d8ffcf"}
colorText={selectedValue === "edit" ? colors.back : colors.accentPrimary}
mystyle={{
borderTopLeftRadius: 0,
borderBottomLeftRadius: 0
}}
onPressFunction={() => setSelectedValue("edit")}
>
Edit
</Button>
</View>
<View style={{
alignItems: "center",
}}>
{
submitting ?
<View style={{
marginTop: 15
}}>
<ActivityIndicator color={colors.accentPrimary} />
</View> :
<Button
mode="contained"
onPressFunction={() => onSubmit()}
>Proceed</Button>
}
</View>
</View>
{/* EXIT TABLE */}
<View style={{
marginTop: 40
}}>
<Text style={{
fontSize: 20,
textAlign: "center",
fontFamily: "ProductSans"
}}> Exit Table</Text>
<View style={{
alignItems: "center",
marginTop: 15
}}>
<Button
colorBack="#ff6257"
onPressFunction={() => exitTable()}
>
Exit Table
</Button>
</View>
</View>
</View>
</View>
)
}
Example #16
Source File: JoinTable.js From salyd with GNU General Public License v3.0 | 4 votes |
JoinTable = (props) => {
const [localRoomId, setLocalRoomID] = useState(null);
const [name, setName] = useState(null);
const { token, updateRoom } = useContext(GlobalContext)
const enterId = async () => {
//If user has token(logged in) then let him/her enter only the roomId
if (token) {
fetch(`${apiUrl}/addmember`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + token
},
body: JSON.stringify({
"roomId": localRoomId
})
}).then((res) => res.json())
.then(async (data) => {
if (data.error) {
Alert.alert("Wrong roomId");
}
else {
//Storing the roomId
updateRoom(data.roomId)
Alert.alert("Successfully added to the table");
props.navigation.dispatch(
CommonActions.reset({
index: 0,
routes: [
{
name: 'Menu',
},
],
})
);
}
})
}
else {
//If user not logged in then make him/her enter the roomId and name(for unique identity)
fetch(`${apiUrl}/registerandaddmember`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
"name": name,
"roomId": localRoomId
})
}).then((res) => res.json())
.then(async (data) => {
console.log(data.id);
if (data.error) {
Alert.alert("Wrong roomId");
}
else {
updateRoom(data.result.roomId)
await AsyncStorage.setItem("userId", (data.id).toString());
Alert.alert("Successfully added to the table");
props.navigation.dispatch(
CommonActions.reset({
index: 0,
routes: [
{
name: 'Menu',
},
],
})
);
}
})
}
}
return (
<View>
<Header navigation={props.navigation} isBack >Join Table</Header>
{token ? (
<View style={styles.container}>
<View style={{
margin: 40, alignItems: "center"
}}>
<Image source={require("../../../assets/code.png")} />
</View>
{/* SHARE ID */}
<View style={{
flexDirection: "row",
backgroundColor: "#d8ffcf",
borderRadius: 10,
padding: 20,
alignItems: "center",
marginBottom: 20
}}>
<FontAwesome5 style={{
marginRight: 20
}} name="lightbulb" size={24} color="black" />
<Text style={{
fontFamily: "ProductSans",
marginRight: 30
}}>Enter the Room Id you got from your colleagues to join the table</Text>
</View>
<TextInput
label="Room Id"
value={localRoomId}
keyboardType="number-pad"
underlineColor="transparent"
theme={{ roundness: 20, colors: { primary: colors.accentPrimary } }}
style={styles.inputbox}
onChangeText={(text) => setLocalRoomID(text)}
/>
<View style={{
marginTop: 20,
alignItems: "center"
}}>
<Button onPressFunction={() => enterId()}>Join Room</Button>
</View>
</View>)
:
(<View style={styles.container}>
<View style={{
margin: 40, alignItems: "center"
}}>
<Image source={require("../../../assets/code.png")} />
</View>
{/* SHARE ID */}
<View style={{
flexDirection: "row",
backgroundColor: "#d8ffcf",
borderRadius: 10,
padding: 20,
alignItems: "center",
marginBottom: 20
}}>
<FontAwesome5 style={{
marginRight: 20
}} name="lightbulb" size={24} color="black" />
<Text style={{
fontFamily: "ProductSans",
marginRight: 30
}}>Enter the Room Id you got from your colleagues to join the table</Text>
</View>
<TextInput
label="Room Id"
value={localRoomId}
keyboardType="number-pad"
underlineColor="transparent"
theme={{ roundness: 20, colors: { primary: colors.accentPrimary } }}
style={styles.inputbox}
onChangeText={(text) => setLocalRoomID(text)}
/>
<TextInput
label="Name"
value={name}
underlineColor="transparent"
theme={{ roundness: 20, colors: { primary: colors.accentPrimary } }}
style={{ ...styles.inputbox, marginTop: 20 }}
onChangeText={(text) => setName(text)}
/>
<View style={{
marginTop: 20,
alignItems: "center"
}}>
<Button onPressFunction={() => enterId()}>Join Room</Button>
</View>
</View>)
}
</View>
)
}
Example #17
Source File: HomeMain.js From salyd with GNU General Public License v3.0 | 4 votes |
HomeMain = (props) => {
const [tableId, setTableId] = useState(null);
const [localRoomId, setLocalRoomID] = useState(null);
const [submitting, isSubmitting] = useState(false);
const { user, token, globalTableId, updateTable, updateRoom } = useContext(GlobalContext);
const [hasPermission, setHasPermission] = useState(null);
const [scanned, setScanned] = useState(true);
useEffect(() => {
(async () => {
const { status } = await BarCodeScanner.requestPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
const handleBarCodeScanned = ({ data }) => {
console.log("SCANEED : >>>>>> ", scanned)
setScanned(true);
console.log("SCANEED : >>>>>> ", scanned)
setTableId(data.toString());
// newTable()
};
useEffect(() => {
if (globalTableId)
props.navigation.dispatch(
CommonActions.reset({
index: 0,
routes: [
{
name: 'Table'
},
],
})
);
}, [globalTableId])
const newTable = async () => {
isSubmitting(true)
Axios({
url: `${apiUrl}/newtable`,
method: 'post',
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${token}`
},
data: { tableId }
})
.then(async res => {
if (res.data.error) {
Alert.alert("Sorry, Incorrect Table Id");
}
else {
updateTable(res.data._id);
updateRoom(res.data.roomId);
console.log(res.data.roomId)
await AsyncStorage.setItem('tableId', res.data._id.toString());
await AsyncStorage.setItem('roomId', res.data.roomId.toString());
isSubmitting(false)
props.navigation.dispatch(
CommonActions.reset({
index: 0,
routes: [
{
name: 'Table',
//TODO: remove this
params: { roomId: res.data.roomId }
},
],
})
);
}
}).catch(err => {
isSubmitting(false);
console.log(err)
})
}
if (hasPermission === null) {
return <Text>Requesting for camera permission</Text>;
}
if (hasPermission === false) {
return <Text>No access to camera</Text>;
}
return (
<React.Fragment>
<Header isUser navigation={props.navigation}>Home</Header>
<View style={styles.container}>
<ScrollView>
<KeyboardAvoidingView
behavior={Platform.OS == "ios" ? "padding" : "position"}
>
{/* <MaskedView
style={{ height: 100, backgroundColor: "#eee" }}
maskElement={
<Image source={require('../../../assets/Untitled.png')} style={{ height: 100, width: 100 }} />
}
>
<View style={{ flex: 1 ,backgroundColor: "cyan"}}>
<BarCodeScanner
onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
style={{ height: 340, width: 340 }}
>
</BarCodeScanner>
</View>
</MaskedView> */}
{/* <View style={styles.qrBox} />
{scanned && <Button color={colors.accentPrimary} onPress={() => setScanned(false)}>Tap to Scan Again</Button>}
<Text style={{
textAlign: "center",
fontWeight: "bold",
margin: 10
}}> OR</Text> */}
<View style={{
marginBottom: 10
}}>
<Text style={{
fontFamily: "ProductSansBold",
fontSize: 20
}}> Hi {user && user.name && user.name}</Text>
<Text style={{
color: "#333",
fontFamily: "ProductSans"
}}> Welcome Back</Text>
</View>
<Text style={{
fontFamily: "ProductSansBold",
fontSize: 20,
color: "#009c0a"
}}> Scan QR Code on Table</Text>
<View style={{
marginTop: 0,
margin: 20
}}>
<View style={{
alignItems: "center",
marginTop: 20,
justifyContent: "center"
}}>
<View style={{
height: 330,
width: 330,
borderRadius: 20,
backgroundColor: "#5effa7"
}} />
</View>
<TextInput
label="Table ID"
value={tableId}
underlineColor="transparent"
theme={{ roundness: 20, colors: { primary: colors.accentPrimary } }}
style={styles.inputbox}
onChangeText={(text) => setTableId(text)}
/>
{
submitting ?
<View style={{
marginTop : 20,alignItems: "flex-start",marginLeft: 10,marginBottom: 15
}}>
<ActivityIndicator color={colors.accentPrimary} />
</View> :
<Button mystyle={{ marginTop: 20 }} onPressFunction={newTable} >Proceed </Button>
}
</View>
<Text style={{
fontFamily: "ProductSansBold",
fontSize: 20,
color: "#009c0a"
}}> Join a Table</Text>
<Text style={{
fontFamily: "ProductSans",
marginLeft: 20,
marginTop: 20,
}}> You can just enter a code generated by someone else</Text>
<Button mystyle={{ marginLeft: 20, marginTop: 10 }} onPressFunction={() => props.navigation.navigate('JoinTable')}>Join Table</Button>
</KeyboardAvoidingView >
</ScrollView>
</View>
</React.Fragment>
)
}
Example #18
Source File: Checkout.js From salyd with GNU General Public License v3.0 | 4 votes |
Checkout = ({ navigation }) => {
const [visible, setVisible] = React.useState(false);
const [orderId, setOrderId] = React.useState(Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5));
const [content, setContent] = React.useState(true)
const [processing, setProcessing] = React.useState(false)
const { order, globalTableId, user, restro, token } = React.useContext(GlobalContext)
const OfflineContent = {
title: "Offline",
content: ['Step 1 : Lorem ipsum dolor sit amet ', 'Step 2 : Lorem ipsum dolor sit amet ', 'Step 3 : Lorem ipsum dolor sit amet ']
}
const OnlineContent = {
title: "Online",
content: ['Step 1 : Lorem ipsum dolor sit amet ', 'Step 2 : Lorem ipsum dolor sit amet ', 'Step 3 : Lorem ipsum dolor sit amet ']
}
const checkIfPaid = () => {
setProcessing(true)
const newDate = new Date();
fetch(`${apiUrl}/orderplace`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer " + token
},
body: JSON.stringify({
"tableId": globalTableId,
"orderId": orderId,
"menu": order.menu,
"name": restro.name,
"address": restro.address,
"date": newDate
})
}).then((res) => res.json())
.then((data) => {
if (data.error) {
Alert.alert("Sorry, something went wrong");
}
else {
socket.emit("orderPlaced", { globalTableId, "menu": order.menu, "username": user.name, orderId, "restroId": restro._id });
socket.on("paid", (oID) => {
if (oID === orderId) {
navigation.dispatch(
CommonActions.reset({
index: 0,
routes: [
{
name: 'OrderConfirmed',
},
],
})
);
}
})
}
})
}
return (
<View style={styles.container}>
<Modal
animationType="fade"
transparent
statusBarTranslucent
visible={visible}
onRequestClose={() => setVisible(!visible)}
>
<View style={styles.centeredView}>
<View style={styles.modalView}>
<Text style={{
fontSize: 20
}}>Instuctions for {content ? OfflineContent.title : OnlineContent.title} Payment</Text>
<View style={{
margin: 10
}}>
<Text style={{ margin: 5, fontSize: 15 }}>Step 2 : Lorem ipsum dolor sit amet </Text>
<Divider />
<Text style={{ margin: 5, fontSize: 15 }}>Step 3 : Lorem ipsum dolor sit amet </Text>
<Divider />
</View>
<Button
onPressFunction={() => {
setVisible(!visible);
}}
>
Close
</Button>
</View>
</View>
</Modal>
<Header navigation={navigation} isBack>Checkout</Header>
<View style={{ margin: 20, marginTop: 15 }}>
<View style={{
backgroundColor: "white",
borderRadius: 20,
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.8,
shadowRadius: 2,
elevation: 5
}}>
<View style={{ padding: 20, paddingBottom: 15 }}>
<Text style={{
fontSize: 20,
marginBottom: 10,
fontFamily: "ProductSansBold",
}}>Order</Text>
<View style={{
maxHeight: 300,
}}>
<View style={{ marginVertical: 10, flexDirection: "row", justifyContent: "space-between", alignItems: "center" }}>
<Text style={{ flex: 1, color: "#00821a", fontFamily: "ProductSansBold" }}>Name</Text>
<Text style={{ flex: 1, color: "#00821a", fontFamily: "ProductSansBold" }}>Quantity</Text>
<Text style={{ flex: 1, color: "#00821a", fontFamily: "ProductSansBold" }}>Price</Text>
<Text style={{ flex: 1, color: "#00821a", fontFamily: "ProductSansBold" }}>Total Price</Text>
</View>
<FlatList
data={order.menu}
renderItem={({ item }) => (
item.count ?
<View style={{ marginVertical: 10, flexDirection: "row", justifyContent: "space-between", alignItems: "center" }}>
<Text style={{ flex: 1, fontFamily: "ProductSans" }}>{item.item}</Text>
<Text style={{ flex: 1, fontFamily: "ProductSans" }}>{item.count}</Text>
<Text style={{ flex: 1, fontFamily: "ProductSans" }}>₹{item.price}</Text>
<Text style={{ flex: 1, fontFamily: "ProductSans" }}>₹{item.price * item.count}</Text>
</View> : null
)}
/>
</View>
</View>
<View style={{
height: 50,
borderBottomEndRadius: 20,
borderBottomLeftRadius: 20,
backgroundColor: "#2ce66d",
alignItems: "center",
flexDirection: "row",
justifyContent: "space-around"
}}>
<Text style={{
fontFamily: "ProductSansBold",
color: "#fff",
fontSize: 22
}}>Total</Text>
<Text style={{
fontSize: 22,
textAlign: "right",
color: "#fff",
marginLeft: 10,
fontFamily: "ProductSansBold"
}}>₹ 300</Text>
</View>
</View>
<View style={{
backgroundColor: "white",
padding: 20,
borderRadius: 20,
marginTop: 20,
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.8,
shadowRadius: 2,
elevation: 5
}}>
<Text style={{ fontSize: 20, fontFamily: "ProductSansBold", marginBottom: 15 }}>Pay for your Order</Text>
<Text style={{ color: "#555", fontFamily: "ProductSans" }}>Pay your Bill using one of the preffered methods</Text>
<View style={{
marginTop: 10, flexDirection: "row", justifyContent: "space-around", alignItems: "center"
}}>
<Button colorBack="#54cfff" onPressFunction={() => { setContent(true); setVisible(true) }}> Pay Offline</Button>
<Button colorBack="#ffaa54" onPressFunction={() => { setContent(false); setVisible(true) }}> Pay Online</Button>
</View>
</View>
<View style={{
backgroundColor: "white",
padding: 20,
marginTop: 20,
borderRadius: 20,
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.8,
shadowRadius: 2,
elevation: 5
}}>
<Text style={{ fontSize: 20, fontFamily: "ProductSansBold", marginBottom: 15 }}>Confirm Order</Text>
<Text style={{ color: "#555", fontFamily: "ProductSans", marginBottom: 10 }}>Pay your Bill using one of the preffered methods</Text>
{
processing ?
<View style={{ marginTop: 15, flexDirection: "row", alignItems: "center", justifyContent: "center" }}>
<Text style={{ color: colors.accentPrimary, marginRight: 10, fontFamily: "ProductSans" }} >Processing</Text>
<ActivityIndicator animating={true} color={colors.accentPrimary} />
</View> :
<Button
onPressFunction={() => checkIfPaid()}
>
Confirm
</Button>
}
</View>
</View>
</View >
)
}
Example #19
Source File: App.js From filen-mobile with GNU Affero General Public License v3.0 | 4 votes |
App = memo(() => {
const [isLoggedIn, setIsLoggedIn] = useMMKVBoolean("isLoggedIn", storage)
const setDimensions = useStore(useCallback(state => state.setDimensions))
const [darkMode, setDarkMode] = useMMKVBoolean("darkMode", storage)
const [setupDone, setSetupDone] = useState(false)
const [currentScreenName, setCurrentScreenName] = useState("MainScreen")
const setCurrentRoutes = useStore(useCallback(state => state.setCurrentRoutes))
const toastBottomOffset = useStore(useCallback(state => state.toastBottomOffset))
const toastTopOffset = useStore(useCallback(state => state.toastTopOffset))
const setNetInfo = useStore(useCallback(state => state.setNetInfo))
const showNavigationAnimation = useStore(useCallback(state => state.showNavigationAnimation))
const [userId, setUserId] = useMMKVNumber("userId", storage)
const [cameraUploadEnabled, setCameraUploadEnabled] = useMMKVBoolean("cameraUploadEnabled:" + userId, storage)
const setBiometricAuthScreenState = useStore(useCallback(state => state.setBiometricAuthScreenState))
const setCurrentShareItems = useStore(useCallback(state => state.setCurrentShareItems))
const setAppState = useStore(useCallback(state => state.setAppState))
const [lang, setLang] = useMMKVString("lang", storage)
const [nodeJSAlive, setNodeJSAlive] = useState(true)
const setContentHeight = useStore(useCallback(state => state.setContentHeight))
const isDeviceReady = useStore(useCallback(state => state.isDeviceReady))
const [startOnCloudScreen, setStartOnCloudScreen] = useMMKVBoolean("startOnCloudScreen:" + userId, storage)
const [userSelectedTheme, setUserSelectedTheme] = useMMKVString("userSelectedTheme", storage)
const [currentDimensions, setCurrentDimensions] = useState({ window: Dimensions.get("window"), screen: Dimensions.get("screen") })
const handleShare = useCallback(async (items) => {
if(!items){
return false
}
if(typeof items !== "undefined"){
if(typeof items.data !== "undefined"){
if(items.data !== null){
if(items.data.length > 0){
await new Promise((resolve) => {
const wait = BackgroundTimer.setInterval(() => {
if(typeof navigationRef !== "undefined"){
const navState = navigationRef.getState()
if(typeof navState !== "undefined"){
if(typeof navState.routes !== "undefined"){
if(navState.routes.filter(route => route.name == "SetupScreen" || route.name == "BiometricAuthScreen" || route.name == "LoginScreen").length == 0){
if(storage.getBoolean("isLoggedIn")){
BackgroundTimer.clearInterval(wait)
return resolve()
}
}
}
}
}
}, 250)
})
let containsValidItems = true
if(Platform.OS == "android"){
if(Array.isArray(items.data)){
for(let i = 0; i < items.data.length; i++){
if(items.data[i].indexOf("file://") == -1 && items.data[i].indexOf("content://") == -1){
containsValidItems = false
}
}
}
else{
if(items.data.indexOf("file://") == -1 && items.data.indexOf("content://") == -1){
containsValidItems = false
}
}
}
else{
for(let i = 0; i < items.data.length; i++){
if(items.data[i].data.indexOf("file://") == -1 && items.data[i].data.indexOf("content://") == -1){
containsValidItems = false
}
}
}
if(containsValidItems){
setCurrentShareItems(items)
showToast({ type: "upload" })
}
else{
showToast({ message: i18n(lang, "shareMenuInvalidType") })
}
}
}
}
}
})
const initBackgroundFetch = useCallback(() => {
BackgroundFetch.configure({
minimumFetchInterval: 15,
requiredNetworkType: BackgroundFetch.NETWORK_TYPE_ANY,
stopOnTerminate: false,
startOnBoot: true,
enableHeadless: false
}, (taskId) => {
console.log("[" + Platform.OS + "] BG fetch running:", taskId)
const waitForInit = (callback) => {
const timeout = (+new Date() + 15000)
const wait = BackgroundTimer.setInterval(() => {
if(timeout > (+new Date())){
if(isLoggedIn && cameraUploadEnabled && setupDone && isDeviceReady){
BackgroundTimer.clearInterval(wait)
return callback(false)
}
}
else{
BackgroundTimer.clearInterval(wait)
return callback(true)
}
}, 10)
}
waitForInit((timedOut) => {
if(timedOut){
console.log("[" + Platform.OS + "] BG fetch timed out:", taskId)
BackgroundFetch.finish(taskId)
}
else{
runCameraUpload({
runOnce: true,
maxQueue: 1,
callback: () => {
console.log("[" + Platform.OS + "] BG fetch done:", taskId)
BackgroundFetch.finish(taskId)
}
})
}
})
}, (taskId) => {
console.log("[" + Platform.OS + "] BG fetch timeout:", taskId)
BackgroundFetch.finish(taskId)
}).then((status) => {
console.log("[" + Platform.OS + "] BG fetch init status:", status)
}).catch((err) => {
console.log("[" + Platform.OS + "] BG fetch init error:", err)
})
})
const setAppearance = useCallback(() => {
BackgroundTimer.setTimeout(() => {
if(typeof userSelectedTheme == "string" && userSelectedTheme.length > 1){
if(userSelectedTheme == "dark"){
setDarkMode(true)
setStatusBarStyle(true)
}
else{
setDarkMode(false)
setStatusBarStyle(false)
}
}
else{
if(Appearance.getColorScheme() == "dark"){
setDarkMode(true)
setStatusBarStyle(true)
}
else{
setDarkMode(false)
setStatusBarStyle(false)
}
}
}, 1000) // We use a timeout due to the RN appearance event listener firing both "dark" and "light" on app resume which causes the screen to flash for a second
})
useEffect(() => {
if(isLoggedIn && cameraUploadEnabled && setupDone){
runCameraUpload({
maxQueue: 10,
runOnce: false,
callback: undefined
})
}
}, [isLoggedIn, cameraUploadEnabled, setupDone])
useEffect(() => {
initBackgroundFetch()
//global.nodeThread.pingPong(() => {
// setNodeJSAlive(false)
//})
NetInfo.fetch().then((state) => {
setNetInfo(state)
}).catch((err) => {
console.log(err)
})
//BackgroundTimer.start()
const appStateListener = AppState.addEventListener("change", (nextAppState) => {
setAppState(nextAppState)
if(nextAppState == "background"){
if(Math.floor(+new Date()) > storage.getNumber("biometricPinAuthTimeout:" + userId) && storage.getBoolean("biometricPinAuth:" + userId)){
setBiometricAuthScreenState("auth")
storage.set("biometricPinAuthTimeout:" + userId, (Math.floor(+new Date()) + 500000))
navigationRef.current.dispatch(StackActions.push("BiometricAuthScreen"))
}
}
if(nextAppState == "active"){
checkAppVersion({ navigation: navigationRef })
}
})
const netInfoListener = NetInfo.addEventListener((state) => {
setNetInfo(state)
})
const dimensionsListener = Dimensions.addEventListener("change", ({ window, screen }) => {
setDimensions({ window, screen })
setCurrentDimensions({ window, screen })
})
const navigationRefListener = navigationRef.addListener("state", (event) => {
if(typeof event.data !== "undefined"){
if(typeof event.data.state !== "undefined"){
if(typeof event.data.state.routes !== "undefined"){
//console.log("Current Screen:", event.data.state.routes[event.data.state.routes.length - 1].name, event.data.state.routes[event.data.state.routes.length - 1].params)
setCurrentScreenName(event.data.state.routes[event.data.state.routes.length - 1].name)
setCurrentRoutes(event.data.state.routes)
}
}
}
})
ShareMenu.getInitialShare(handleShare)
const shareMenuListener = ShareMenu.addNewShareListener(handleShare)
setAppearance()
const appearanceListener = Appearance.addChangeListener(() => {
setAppearance()
})
if(isLoggedIn && !setupDone){
setup({ navigation: navigationRef }).then(() => {
setSetupDone(true)
if(storage.getBoolean("biometricPinAuth:" + userId)){
setBiometricAuthScreenState("auth")
storage.set("biometricPinAuthTimeout:" + userId, (Math.floor(+new Date()) + 500000))
navigationRef.current.dispatch(StackActions.push("BiometricAuthScreen"))
}
else{
navigationRef.current.dispatch(CommonActions.reset({
index: 0,
routes: [
{
name: "MainScreen",
params: {
parent: startOnCloudScreen ? (storage.getBoolean("defaultDriveOnly:" + userId) ? storage.getString("defaultDriveUUID:" + userId) : "base") : "recents"
}
}
]
}))
}
}).catch((err) => {
console.log(err)
if(typeof storage.getString("masterKeys") == "string" && typeof storage.getString("apiKey") == "string" && typeof storage.getString("privateKey") == "string" && typeof storage.getString("publicKey") == "string" && typeof storage.getNumber("userId") == "number"){
if(storage.getString("masterKeys").length > 16 && storage.getString("apiKey").length > 16 && storage.getString("privateKey").length > 16 && storage.getString("publicKey").length > 16 && storage.getNumber("userId") !== 0){
setSetupDone(true)
if(storage.getBoolean("biometricPinAuth:" + userId)){
setBiometricAuthScreenState("auth")
storage.set("biometricPinAuthTimeout:" + userId, (Math.floor(+new Date()) + 500000))
navigationRef.current.dispatch(StackActions.push("BiometricAuthScreen"))
}
else{
navigationRef.current.dispatch(CommonActions.reset({
index: 0,
routes: [
{
name: "MainScreen",
params: {
parent: startOnCloudScreen ? (storage.getBoolean("defaultDriveOnly:" + userId) ? storage.getString("defaultDriveUUID:" + userId) : "base") : "recents"
}
}
]
}))
}
}
else{
setSetupDone(false)
showToast({ message: i18n(lang, "appSetupNotPossible") })
}
}
else{
setSetupDone(false)
showToast({ message: i18n(lang, "appSetupNotPossible") })
}
})
}
// Reset on app launch
storage.set("cameraUploadRunning", false)
return () => {
dimensionsListener.remove()
shareMenuListener.remove()
navigationRef.removeListener(navigationRefListener)
navigationRefListener()
appearanceListener.remove()
netInfoListener()
appStateListener.remove()
}
}, [])
return (
<>
<NavigationContainer ref={navigationRef}>
<Fragment>
<SafeAreaProvider style={{
backgroundColor: darkMode ? "black" : "white",
}}>
<SafeAreaView mode="padding" style={{
backgroundColor: currentScreenName == "ImageViewerScreen" ? "black" : (darkMode ? "black" : "white"),
paddingTop: Platform.OS == "android" ? 5 : 5,
height: "100%",
width: "100%"
}}>
<View style={{
width: currentScreenName == "ImageViewerScreen" ? currentDimensions.screen.width : "100%",
height: currentScreenName == "ImageViewerScreen" ? currentDimensions.screen.height : "100%",
backgroundColor: darkMode ? "black" : "white"
}} onLayout={(e) => setContentHeight(e.nativeEvent.layout.height)}>
{
nodeJSAlive ? (
<>
<Stack.Navigator initialRouteName={isLoggedIn ? (setupDone ? "MainScreen" : "SetupScreen") : "LoginScreen"} screenOptions={{
contentStyle: {
backgroundColor: darkMode ? "black" : "white"
},
headerStyle: {
backgroundColor: darkMode ? "black" : "white"
},
headerShown: false,
animation: showNavigationAnimation ? "default" : "none"
}}>
<Stack.Screen name="SetupScreen" component={SetupScreen} options={{
title: "SetupScreen"
}}></Stack.Screen>
<Stack.Screen name="LoginScreen" options={{
title: "LoginScreen"
}}>{(props) => <LoginScreen {...props} setSetupDone={setSetupDone} />}</Stack.Screen>
<Stack.Screen name="RegisterScreen" component={RegisterScreen} options={{
title: "RegisterScreen"
}}></Stack.Screen>
<Stack.Screen name="ForgotPasswordScreen" component={ForgotPasswordScreen} options={{
title: "ForgotPasswordScreen"
}}></Stack.Screen>
<Stack.Screen name="ResendConfirmationScreen" component={ResendConfirmationScreen} options={{
title: "ResendConfirmationScreen"
}}></Stack.Screen>
<Stack.Screen name="MainScreen" initialParams={{ parent: startOnCloudScreen ? (storage.getBoolean("defaultDriveOnly:" + userId) ? storage.getString("defaultDriveUUID:" + userId) : "base") : "recents" }} component={MainScreen} options={{
title: "MainScreen"
}}></Stack.Screen>
<Stack.Screen name="SettingsScreen" component={SettingsScreen} options={{
title: "SettingsScreen"
}}></Stack.Screen>
<Stack.Screen name="TransfersScreen" component={TransfersScreen} options={{
title: "TransfersScreen"
}}></Stack.Screen>
<Stack.Screen name="CameraUploadScreen" component={CameraUploadScreen} options={{
title: "CameraUploadScreen"
}}></Stack.Screen>
<Stack.Screen name="BiometricAuthScreen" component={BiometricAuthScreen} options={{
title: "BiometricAuthScreen"
}}></Stack.Screen>
<Stack.Screen name="LanguageScreen" component={LanguageScreen} options={{
title: "LanguageScreen"
}}></Stack.Screen>
<Stack.Screen name="SettingsAdvancedScreen" component={SettingsAdvancedScreen} options={{
title: "SettingsAdvancedScreen"
}}></Stack.Screen>
<Stack.Screen name="SettingsAccountScreen" component={SettingsAccountScreen} options={{
title: "SettingsAccountScreen"
}}></Stack.Screen>
<Stack.Screen name="EventsScreen" component={EventsScreen} options={{
title: "EventsScreen"
}}></Stack.Screen>
<Stack.Screen name="EventsInfoScreen" component={EventsInfoScreen} options={{
title: "EventsInfoScreen"
}}></Stack.Screen>
<Stack.Screen name="GDPRScreen" component={GDPRScreen} options={{
title: "GDPRScreen"
}}></Stack.Screen>
<Stack.Screen name="InviteScreen" component={InviteScreen} options={{
title: "InviteScreen"
}}></Stack.Screen>
<Stack.Screen name="TwoFactorScreen" component={TwoFactorScreen} options={{
title: "TwoFactorScreen"
}}></Stack.Screen>
<Stack.Screen name="ChangeEmailPasswordScreen" component={ChangeEmailPasswordScreen} options={{
title: "ChangeEmailPasswordScreen"
}}></Stack.Screen>
<Stack.Screen name="TextEditorScreen" component={TextEditorScreen} options={{
title: "TextEditorScreen"
}}></Stack.Screen>
<Stack.Screen name="UpdateScreen" component={UpdateScreen} options={{
title: "UpdateScreen"
}}></Stack.Screen>
<Stack.Screen name="ImageViewerScreen" component={ImageViewerScreen} options={{
title: "ImageViewerScreen",
presentation: "fullScreenModal"
}}></Stack.Screen>
</Stack.Navigator>
<>
{
setupDone && isLoggedIn && ["MainScreen", "SettingsScreen", "TransfersScreen", "CameraUploadScreen", "EventsScreen", "EventsInfoScreen", "SettingsAdvancedScreen", "SettingsAccountScreen", "LanguageScreen", "GDPRScreen", "InviteScreen", "TwoFactorScreen", "ChangeEmailPasswordScreen"].includes(currentScreenName) && (
<View style={{
position: "relative",
width: "100%",
bottom: 0,
height: 50
}}>
<BottomBar navigation={navigationRef} currentScreenName={currentScreenName} />
</View>
)
}
</>
</>
) : (
<View style={{
width: "100%",
height: "100%",
justifyContent: "center",
alignItems: "center"
}}>
<Ionicon name="information-circle-outline" size={70} color={darkMode ? "white" : "black"} />
<Text style={{
color: darkMode ? "white" : "black",
marginTop: 5,
width: "70%",
textAlign: "center"
}}>
{i18n(lang, "nodeJSProcessDied")}
</Text>
</View>
)
}
{
nodeJSAlive && (
<>
<TransfersIndicator navigation={navigationRef} />
<TopBarActionSheet navigation={navigationRef} />
<BottomBarAddActionSheet navigation={navigationRef} />
<ItemActionSheet navigation={navigationRef} />
<FolderColorActionSheet navigation={navigationRef} />
<PublicLinkActionSheet navigation={navigationRef} />
<ShareActionSheet navigation={navigationRef} />
<FileVersionsActionSheet navigation={navigationRef} />
<ProfilePictureActionSheet navigation={navigationRef} />
<SortByActionSheet navigation={navigationRef} />
</>
)
}
</View>
</SafeAreaView>
</SafeAreaProvider>
{
nodeJSAlive && (
<>
<Disable2FATwoFactorDialog navigation={navigationRef} />
<DeleteAccountTwoFactorDialog navigation={navigationRef} />
<RedeemCodeDialog navigation={navigationRef} />
<ConfirmStopSharingDialog navigation={navigationRef} />
<ConfirmRemoveFromSharedInDialog navigation={navigationRef} />
<ConfirmPermanentDeleteDialog navigation={navigationRef} />
<RenameDialog navigation={navigationRef} />
<CreateFolderDialog navigation={navigationRef} />
<CreateTextFileDialog navigation={navigationRef} />
<BulkShareDialog navigation={navigationRef} />
<FullscreenLoadingModal navigation={navigationRef} />
</>
)
}
</Fragment>
</NavigationContainer>
<Toast
ref={(ref) => global.toast = ref}
offsetBottom={toastBottomOffset}
offsetTop={toastTopOffset}
pointerEvents="box-none"
style={{
zIndex: 99999
}}
/>
</>
)
})
Example #20
Source File: TwoFactorScreen.js From filen-mobile with GNU Affero General Public License v3.0 | 4 votes |
TwoFactorScreen = memo(({ navigation, route }) => {
const [darkMode, setDarkMode] = useMMKVBoolean("darkMode", storage)
const [lang, setLang] = useMMKVString("lang", storage)
const [enabled, setEnabled] = useState(route.params.accountSettings.twoFactorEnabled == 1 ? true : false)
const [accountSettings, setAccountSettings] = useState(route.params.accountSettings)
const dimensions = useStore(useCallback(state => state.dimensions))
const [twoFactorKey, setTwoFactorKey] = useState("")
const setDisable2FATwoFactorDialogVisible = useStore(useCallback(state => state.setDisable2FATwoFactorDialogVisible))
console.log(route.params)
return (
<KeyboardAvoidingView behavior="position">
<View style={{
flexDirection: "row",
justifyContent: "flex-start",
backgroundColor: darkMode ? "black" : "white"
}}>
<TouchableOpacity style={{
marginTop: Platform.OS == "ios" ? 17 : 4,
marginLeft: 15,
}} onPress={() => navigation.goBack()}>
<Ionicon name="chevron-back" size={24} color={darkMode ? "white" : "black"}></Ionicon>
</TouchableOpacity>
<Text style={{
color: darkMode ? "white" : "black",
fontWeight: "bold",
fontSize: 24,
marginLeft: 10,
marginTop: Platform.OS == "ios" ? 15 : 0
}}>
{i18n(lang, "twoFactorAuthentication")}
</Text>
</View>
<View style={{
height: "100%",
width: "100%",
backgroundColor: darkMode ? "black" : "white"
}}>
{
enabled ? (
<>
<SettingsGroup>
<SettingsButtonLinkHighlight onPress={() => {
Alert.alert(i18n(lang, "disable2FA"), i18n(lang, "disable2FAInfo"), [
{
text: i18n(lang, "cancel"),
onPress: () => {
return false
},
style: "cancel"
},
{
text: i18n(lang, "ok"),
onPress: () => {
Alert.alert(i18n(lang, "disable2FA"), i18n(lang, "areYouReallySure"), [
{
text: i18n(lang, "cancel"),
onPress: () => {
return false
},
style: "cancel"
},
{
text: i18n(lang, "ok"),
onPress: () => {
setDisable2FATwoFactorDialogVisible(true)
},
style: "default"
}
], {
cancelable: true
})
},
style: "default"
}
], {
cancelable: true
})
}} title={i18n(lang, "disable2FA")} />
</SettingsGroup>
<View style={{
width: "100%",
height: "auto",
paddingLeft: 8,
paddingRight: 8,
marginTop: 5
}}>
<View style={{
width: "100%",
height: "auto",
flexDirection: "row",
justifyContent: "space-between",
paddingLeft: 10,
paddingRight: 10,
paddingTop: 10,
paddingBottom: 10
}}>
<View>
<Text style={{
color: "gray",
fontSize: 11
}}>
{i18n(lang, "disable2FAInfo")}
</Text>
</View>
</View>
</View>
</>
) : (
<>
<View style={{
backgroundColor: "white",
width: "100%",
height: dimensions.screen.width,
justifyContent: "center",
alignItems: "center",
marginTop: 10
}}>
<QRCode
value={"otpauth://totp/" + encodeURIComponent("Filen") + ":" + encodeURIComponent(accountSettings.email) + "?secret=" + encodeURIComponent(accountSettings.twoFactorKey) + "&issuer=" + encodeURIComponent("Filen") + "&digits=6&period=30"}
size={dimensions.screen.width - 60}
backgroundColor="white"
/>
</View>
<SettingsGroup>
<Pressable style={{
width: "100%",
height: "auto"
}}>
<View style={{
width: "100%",
height: "auto",
flexDirection: "row",
justifyContent: "space-between",
paddingLeft: 10,
paddingRight: 10,
paddingTop: 10,
paddingBottom: 10
}}>
<Text style={{
color: darkMode ? "white" : "black",
width: "70%"
}} numberOfLines={1}>
{accountSettings.twoFactorKey}
</Text>
<TouchableOpacity onPress={() => {
Clipboard.setString(accountSettings.twoFactorKey)
showToast({ message: i18n(lang, "copiedToClipboard") })
}}>
<Text style={{
color: "#0A84FF"
}}>
{i18n(lang, "copy")}
</Text>
</TouchableOpacity>
</View>
</Pressable>
</SettingsGroup>
<SettingsGroup>
<Pressable style={{
width: "100%",
height: "auto"
}}>
<View style={{
width: "100%",
height: "auto",
flexDirection: "row",
justifyContent: "space-between",
paddingLeft: 10,
paddingRight: 10,
paddingTop: 10,
paddingBottom: 10
}}>
<TextInput
onChangeText={setTwoFactorKey}
value={twoFactorKey}
placeholder={i18n(lang, "twoFactorPlaceholder")}
placeholderTextColor={"gray"}
autoCapitalize="none"
autoComplete="off"
returnKeyType="done"
autoCorrect={false}
style={{
height: 35,
width: "80%",
maxWidth: "80%",
padding: 5,
backgroundColor: darkMode ? "#222222" : "lightgray",
color: "gray",
borderRadius: 10,
paddingLeft: 10,
paddingRight: 10
}}
/>
<TouchableOpacity onPress={() => {
const code = twoFactorKey.trim()
if(code.length == 0){
return false
}
useStore.setState({ fullscreenLoadingModalVisible: true })
Keyboard.dismiss()
enable2FA({ code }).then(() => {
useStore.setState({ fullscreenLoadingModalVisible: false })
showToast({ message: i18n(lang, "twoFactorEnabledSuccess") })
navigationAnimation({ enable: false }).then(() => {
navigation.dispatch(CommonActions.reset({
index: 1,
routes: [
{
name: "SettingsScreen"
},
{
name: "SettingsAccountScreen"
}
]
}))
})
}).catch((err) => {
console.log(err)
useStore.setState({ fullscreenLoadingModalVisible: false })
showToast({ message: err.toString() })
})
}}>
<Text style={{
color: "#0A84FF",
paddingTop: 7
}}>
{i18n(lang, "enable")}
</Text>
</TouchableOpacity>
</View>
</Pressable>
</SettingsGroup>
</>
)
}
</View>
</KeyboardAvoidingView>
)
})
Example #21
Source File: TopBar.js From filen-mobile with GNU Affero General Public License v3.0 | 4 votes |
TopBar = memo(({ navigation, route, setLoadDone, searchTerm, setSearchTerm }) => {
const getTopBarTitle = useCallback(({ route, lang = "en" }) => {
let title = "Cloud"
const parent = getParent(route)
const routeURL = getRouteURL(route)
const isMainScreen = (route.name == "MainScreen")
const isTransfersScreen = (route.name == "TransfersScreen")
const isSettingsScreen = (route.name == "SettingsScreen")
const isBaseScreen = (parent.indexOf("base") !== -1)
const isRecentsScreen = (parent.indexOf("recents") !== -1)
const isTrashScreen = (parent.indexOf("trash") !== -1)
const isSharedInScreen = (parent.indexOf("shared-in") !== -1)
const isSharedOutScreen = (parent.indexOf("shared-out") !== -1)
const isPublicLinksScreen = (parent.indexOf("links") !== -1)
const isOfflineScreen = (parent.indexOf("offline") !== -1)
const isFavoritesScreen = (parent.indexOf("favorites") !== -1)
const isPhotosScreen = (parent.indexOf("photos") !== -1)
if(isTransfersScreen){
title = i18n(lang, "transfers")
}
else if(isSettingsScreen){
title = i18n(lang, "settings")
}
else if(isRecentsScreen){
title = i18n(lang, "home")
}
else if(isTrashScreen){
title = i18n(lang, "trash")
}
else if(isSharedInScreen){
title = i18n(lang, "home")
}
else if(isSharedOutScreen){
title = i18n(lang, "home")
}
else if(isPublicLinksScreen){
title = i18n(lang, "home")
}
else if(isFavoritesScreen){
title = i18n(lang, "home")
}
else if(isOfflineScreen){
title = i18n(lang, "home")
}
else if(isPhotosScreen){
title = i18n(lang, "photos")
}
else{
if(parent == "base"){
title = i18n(lang, "cloud")
}
else{
if((routeURL.split("/").length - 1) > 0){
try{
var folderCache = JSON.parse(storage.getString("itemCache:folder:" + parent))
}
catch(e){
//console.log(e)
}
if(typeof folderCache == "object"){
title = folderCache.name
}
else{
title = i18n(lang, "cloud")
}
}
else{
title = i18n(lang, "cloud")
}
}
}
return title
})
const [darkMode, setDarkMode] = useMMKVBoolean("darkMode", storage)
const itemsSelectedCount = useStore(useCallback(state => state.itemsSelectedCount))
const [lang, setLang] = useMMKVString("lang", storage)
const [showTextClearButton, setShowTextClearButton] = useState(false)
const [title, setTitle] = useState(getTopBarTitle({ route, lang }))
const setTopBarHeight = useStore(useCallback(state => state.setTopBarHeight))
const [publicKey, setPublicKey] = useMMKVString("publicKey", storage)
const [privateKey, setPrivateKey] = useMMKVString("privateKey", storage)
const parent = getParent(route)
const routeURL = getRouteURL(route)
const isMainScreen = (route.name == "MainScreen")
const isTransfersScreen = (route.name == "TransfersScreen")
const isSettingsScreen = (route.name == "SettingsScreen")
const isBaseScreen = (parent.indexOf("base") !== -1)
const isRecentsScreen = (parent.indexOf("recents") !== -1)
const isTrashScreen = (parent.indexOf("trash") !== -1)
const isSharedInScreen = (parent.indexOf("shared-in") !== -1)
const isSharedOutScreen = (parent.indexOf("shared-out") !== -1)
const isPublicLinksScreen = (parent.indexOf("links") !== -1)
const isOfflineScreen = (parent.indexOf("offline") !== -1)
const isFavoritesScreen = (parent.indexOf("favorites") !== -1)
const isPhotosScreen = (parent.indexOf("photos") !== -1)
const showHomeTabBar = (["shared-in", "shared-out", "links", "recents", "offline", "favorites"].includes(parent))
let showBackButton = (typeof route.params !== "undefined" && !isBaseScreen && !isRecentsScreen && !isSharedInScreen && !isSharedOutScreen && !isPublicLinksScreen && !isFavoritesScreen && !isOfflineScreen && !isPhotosScreen)
if(isTransfersScreen && !showBackButton){
showBackButton = true
}
if(isMainScreen && (routeURL.split("/").length - 1) == 0){
showBackButton = false
}
useEffect(() => {
setTitle(getTopBarTitle({ route, lang }))
}, [])
const goBack = useCallback(() => {
if(typeof setLoadDone !== "undefined"){
setLoadDone(false)
}
navigation.goBack()
})
return (
<View onLayout={(e) => setTopBarHeight(e.nativeEvent.layout.height)}>
<View style={{
height: showHomeTabBar ? 75 : isMainScreen && !isPhotosScreen ? 80 : 35,
borderBottomColor: getColor(darkMode, "primaryBorder"),
borderBottomWidth: 0, //showHomeTabBar || routeURL.indexOf("photos") !== -1 ? 0 : 1
marginTop: Platform.OS == "ios" ? 10 : 0
}}>
<View style={{
justifyContent: "space-between",
flexDirection: "row",
paddingLeft: 15,
paddingRight: 15
}}>
{
itemsSelectedCount > 0 && isMainScreen ? (
<TouchableOpacity style={{
marginTop: Platform.OS == "android" ? 1 : 0
}} onPress={() => {
DeviceEventEmitter.emit("event", {
type: "unselect-all-items"
})
}}>
<Ionicon name="chevron-back" size={24} color={darkMode ? "white" : "black"}></Ionicon>
</TouchableOpacity>
) : (
showBackButton && (
<TouchableOpacity style={{
marginTop: Platform.OS == "android" ? 1 : 0
}} onPress={() => goBack()}>
<Ionicon name="chevron-back" size={24} color={darkMode ? "white" : "black"}></Ionicon>
</TouchableOpacity>
)
)
}
<View style={{
marginLeft: showBackButton ? 5 : 0,
width: showBackButton ? "80%" : "85%"
}}>
<Text style={{
fontSize: 20,
color: darkMode ? "white" : "black",
fontWeight: "bold"
}} numberOfLines={1}>{itemsSelectedCount > 0 && isMainScreen ? itemsSelectedCount + " " + i18n(lang, "items", false) : title}</Text>
</View>
<TouchableOpacity hitSlop={{
top: 10,
right: 10,
left: 10,
bottom: 10
}} style={{
alignItems: "flex-end",
flexDirection: "row",
backgroundColor: "transparent",
height: "100%",
paddingLeft: 0
}} onPress={() => SheetManager.show("TopBarActionSheet")}>
{
!isSettingsScreen && (
<View>
<Ionicon name="ellipsis-horizontal-sharp" size={24} color={darkMode ? "white" : "black"}></Ionicon>
</View>
)
}
</TouchableOpacity>
</View>
{
isMainScreen && !isPhotosScreen && (
<View style={{
paddingLeft: 15,
paddingRight: 15
}}>
<Ionicon name="search-outline" size={18} color="gray" style={{
position: "absolute",
zIndex: 2,
marginTop: 17,
marginLeft: 23
}} />
<TouchableOpacity hitSlop={{
top: 10,
left: 10,
right: 10,
bottom: 10
}} style={{
position: "absolute",
zIndex: 2,
right: 0,
marginTop: 17,
display: showTextClearButton ? "flex" : "none",
width: 43,
height: 30
}} onPress={() => {
setSearchTerm("")
Keyboard.dismiss()
setShowTextClearButton(false)
}}>
<Ionicon name="close-circle" size={18} color="gray" />
</TouchableOpacity>
<TextInput onChangeText={(val) => {
if(val.length > 0){
setShowTextClearButton(true)
}
else{
setShowTextClearButton(false)
}
setSearchTerm(val)
}} value={searchTerm} placeholder={i18n(lang, "searchInThisFolder")} placeholderTextColor={"gray"} autoCapitalize="none" autoComplete="off" style={{
height: 32,
marginTop: 10,
zIndex: 1,
padding: 5,
backgroundColor: darkMode ? "#171717" : "lightgray",
color: "gray",
borderRadius: 10,
paddingLeft: 35,
paddingRight: 40
}} />
</View>
)
}
</View>
{
showHomeTabBar && (
<View style={{
paddingTop: 4,
height: 40,
flexDirection: "row",
paddingLeft: 15,
paddingRight: 15,
borderBottomWidth: 0,
borderBottomColor: getColor(darkMode, "primaryBorder"),
justifyContent: "space-between"
}}>
<TouchableOpacity style={{
borderBottomWidth: isRecentsScreen ? Platform.OS == "ios" ? 1.5 : 2 : 0,
borderBottomColor: isRecentsScreen ? "#0A84FF" : "#171717",
height: 27
}} onPress={() => {
navigationAnimation({ enable: false }).then(() => {
navigation.dispatch(CommonActions.reset({
index: 0,
routes: [
{
name: "MainScreen",
params: {
parent: "recents"
}
}
]
}))
})
}}>
<Text style={{
color: isRecentsScreen ? "#0A84FF" : "gray",
fontWeight: "bold",
fontSize: 13,
paddingTop: 3
}}>
{i18n(lang, "recents")}
</Text>
</TouchableOpacity>
{
typeof privateKey == "string" && typeof publicKey == "string" && privateKey.length > 16 && publicKey.length > 16 && (
<>
<TouchableOpacity style={{
borderBottomWidth: isSharedInScreen ? Platform.OS == "ios" ? 1.5 : 2 : 0,
borderBottomColor: isSharedInScreen ? "#0A84FF" : "#171717",
height: 27
}} onPress={() => {
navigationAnimation({ enable: false }).then(() => {
navigation.dispatch(CommonActions.reset({
index: 0,
routes: [
{
name: "MainScreen",
params: {
parent: "shared-in"
}
}
]
}))
})
}}>
<Text style={{
color: isSharedInScreen ? "#0A84FF" : "gray",
fontWeight: "bold",
fontSize: 13,
paddingTop: 3
}}>
{i18n(lang, "sharedIn")}
</Text>
</TouchableOpacity>
<TouchableOpacity style={{
borderBottomWidth: isSharedOutScreen ? Platform.OS == "ios" ? 1.5 : 2 : 0,
borderBottomColor: isSharedOutScreen ? "#0A84FF" : "#171717",
height: 27
}} onPress={() => {
navigationAnimation({ enable: false }).then(() => {
navigation.dispatch(CommonActions.reset({
index: 0,
routes: [
{
name: "MainScreen",
params: {
parent: "shared-out"
}
}
]
}))
})
}}>
<Text style={{
color: isSharedOutScreen ? "#0A84FF" : "gray",
fontWeight: "bold",
fontSize: 13,
paddingTop: 3
}}>
{i18n(lang, "sharedOut")}
</Text>
</TouchableOpacity>
</>
)
}
<TouchableOpacity style={{
borderBottomWidth: isPublicLinksScreen ? Platform.OS == "ios" ? 1.5 : 2 : 0,
borderBottomColor: isPublicLinksScreen ? "#0A84FF" : "#171717",
height: 27
}} onPress={() => {
navigationAnimation({ enable: false }).then(() => {
navigation.dispatch(CommonActions.reset({
index: 0,
routes: [
{
name: "MainScreen",
params: {
parent: "links"
}
}
]
}))
})
}}>
<Text style={{
color: isPublicLinksScreen ? "#0A84FF" : "gray",
fontWeight: "bold",
fontSize: 13,
paddingTop: 3
}}>
{i18n(lang, "publicLinks")}
</Text>
</TouchableOpacity>
<TouchableOpacity style={{
borderBottomWidth: isFavoritesScreen ? Platform.OS == "ios" ? 1.5 : 2 : 0,
borderBottomColor: isFavoritesScreen ? "#0A84FF" : "#171717",
height: 27
}} onPress={() => {
navigationAnimation({ enable: false }).then(() => {
navigation.dispatch(CommonActions.reset({
index: 0,
routes: [
{
name: "MainScreen",
params: {
parent: "favorites"
}
}
]
}))
})
}}>
<Text style={{
color: isFavoritesScreen ? "#0A84FF" : "gray",
fontWeight: "bold",
fontSize: 13,
paddingTop: 3
}}>
{i18n(lang, "favorites")}
</Text>
</TouchableOpacity>
<TouchableOpacity style={{
borderBottomWidth: isOfflineScreen ? Platform.OS == "ios" ? 1.5 : 2 : 0,
borderBottomColor: isOfflineScreen ? "#0A84FF" : "#171717",
height: 27
}} onPress={() => {
navigationAnimation({ enable: false }).then(() => {
navigation.dispatch(CommonActions.reset({
index: 0,
routes: [
{
name: "MainScreen",
params: {
parent: "offline"
}
}
]
}))
})
}}>
<Text style={{
color: isOfflineScreen ? "#0A84FF" : "gray",
fontWeight: "bold",
fontSize: 13,
paddingTop: 3
}}>
{i18n(lang, "offlineFiles")}
</Text>
</TouchableOpacity>
</View>
)
}
</View>
)
})
Example #22
Source File: Toasts.js From filen-mobile with GNU Affero General Public License v3.0 | 4 votes |
CameraUploadChooseFolderToast = memo(({ message, navigation }) => {
const [darkMode, setDarkMode] = useMMKVBoolean("darkMode", storage)
const [lang, setLang] = useMMKVString("lang", storage)
const currentRoutes = useStore(useCallback(state => state.currentRoutes))
const [currentParent, setCurrentParent] = useState("")
const [currentRouteURL, setCurrentRouteURL] = useState("")
useEffect(() => {
if(Array.isArray(currentRoutes)){
const parent = getParent(currentRoutes[currentRoutes.length - 1])
if(typeof parent == "string" && parent.length > 0){
setCurrentParent(parent)
setCurrentRouteURL(getRouteURL(currentRoutes[currentRoutes.length - 1]))
}
}
}, [currentRoutes])
return (
<View style={{
flexDirection: "row",
justifyContent: "space-between",
width: "100%",
height: "100%",
zIndex: 99999
}}>
<View>
<Text style={{
color: darkMode ? "white" : "black"
}}>
{message}
</Text>
</View>
<View style={{
flexDirection: "row"
}}>
<TouchableOpacity underlayColor={"transparent"} hitSlop={{
right: 20,
left: 20,
top: 10,
bottom: 10
}} style={{
width: "auto",
height: "auto",
paddingLeft: 10,
paddingRight: 10
}} onPress={() => {
hideAllToasts()
navigationAnimation({ enable: false }).then(() => {
navigation.dispatch(CommonActions.reset({
index: 1,
routes: [
{
name: "SettingsScreen"
},
{
name: "CameraUploadScreen"
}
]
}))
})
}}>
<Text style={{
color: darkMode ? "white" : "black"
}}>
{i18n(lang, "cancel")}
</Text>
</TouchableOpacity>
<TouchableOpacity underlayColor={"transparent"} hitSlop={{
right: 20,
left: 20,
top: 10,
bottom: 10
}} style={{
marginLeft: 20
}} onPress={() => {
if(
currentRouteURL.indexOf("shared-in") !== -1 ||
currentRouteURL.indexOf("shared-out") !== -1 ||
currentRouteURL.indexOf("recents") !== -1 ||
currentRouteURL.indexOf("trash") !== -1 ||
currentRouteURL.indexOf("photos") !== -1 ||
currentRouteURL.indexOf("offline") !== -1 ||
currentRouteURL.split("/").length < 2
){
return false
}
const parent = getParent()
let folderName = undefined
if(parent.length < 32){
return false
}
try{
var folderCache = JSON.parse(storage.getString("itemCache:folder:" + parent))
}
catch(e){
console.log(e)
console.log(currentRouteURL)
return false
}
if(typeof folderCache == "object"){
folderName = folderCache.name
}
if(typeof folderName == "undefined"){
return false
}
try{
storage.set("cameraUploadFolderUUID:" + storage.getNumber("userId"), parent)
storage.set("cameraUploadFolderName:" + storage.getNumber("userId"), folderName)
//storage.set("cameraUploadUploadedIds:" + storage.getNumber("userId"), "{}")
//storage.set("cameraUploadFetchNewAssetsTimeout", 0)
//storage.set("cachedCameraUploadAssets:" + storage.getNumber("userId"), "[]")
//storage.set("cameraUploadEnabled:" + storage.getNumber("userId"), true)
}
catch(e){
console.log(e)
return false
}
hideAllToasts()
navigationAnimation({ enable: false }).then(() => {
navigation.dispatch(CommonActions.reset({
index: 1,
routes: [
{
name: "SettingsScreen"
},
{
name: "CameraUploadScreen"
}
]
}))
})
}}>
<Text style={{
color: (currentRouteURL.indexOf("shared-in") == -1 && currentRouteURL.indexOf("recents") == -1 && currentRouteURL.indexOf("trash") == -1 && currentRouteURL.indexOf("photos") == -1 && currentRouteURL.indexOf("offline") == -1 && currentParent.length > 32 && currentRouteURL.split("/").length >= 2) ? darkMode ? "white" : "black" : "gray"
}}>
{i18n(lang, "choose")}
</Text>
</TouchableOpacity>
</View>
</View>
)
})
Example #23
Source File: Dialogs.js From filen-mobile with GNU Affero General Public License v3.0 | 4 votes |
Disable2FATwoFactorDialog = memo(({ navigation }) => {
const [darkMode, setDarkMode] = useMMKVBoolean("darkMode", storage)
const disable2FATwoFactorDialogVisible = useStore(useCallback(state => state.disable2FATwoFactorDialogVisible))
const setDisable2FATwoFactorDialogVisible = useStore(useCallback(state => state.setDisable2FATwoFactorDialogVisible))
const [value, setValue] = useState("")
const inputRef = useRef()
const [buttonsDisabled, setButtonsDisabled] = useState(false)
const [lang, setLang] = useMMKVString("lang", storage)
useEffect(() => {
setButtonsDisabled(false)
if(!disable2FATwoFactorDialogVisible){
setTimeout(() => {
setValue("")
}, 250)
}
if(disable2FATwoFactorDialogVisible){
setTimeout(() => {
inputRef.current.focus()
}, 250)
}
}, [disable2FATwoFactorDialogVisible])
return (
<Dialog.Container
visible={disable2FATwoFactorDialogVisible}
useNativeDriver={false}
onRequestClose={() => setDisable2FATwoFactorDialogVisible(false)}
onBackdropPress={() => {
if(!buttonsDisabled){
setDisable2FATwoFactorDialogVisible(false)
}
}}
>
<Dialog.Title>{i18n(lang, "disable2FA")}</Dialog.Title>
<Dialog.Input placeholder={i18n(lang, "code")} value={value} autoFocus={true} onChangeText={(val) => setValue(val)} textInputRef={inputRef} />
<Dialog.Button label={i18n(lang, "cancel")} disabled={buttonsDisabled} onPress={() => setDisable2FATwoFactorDialogVisible(false)} />
<Dialog.Button label={i18n(lang, "disable")} disabled={buttonsDisabled} onPress={() => {
setButtonsDisabled(true)
setDisable2FATwoFactorDialogVisible(false)
Keyboard.dismiss()
useStore.setState({ fullscreenLoadingModalVisible: true })
const code = value.trim()
if(code.length == 0){
return false
}
disable2FA({ code }).then(() => {
setButtonsDisabled(false)
useStore.setState({ fullscreenLoadingModalVisible: false })
showToast({ message: i18n(lang, "twoFactorDisabledSuccess") })
navigationAnimation({ enable: false }).then(() => {
navigation.dispatch(CommonActions.reset({
index: 1,
routes: [
{
name: "SettingsScreen"
},
{
name: "SettingsAccountScreen"
}
]
}))
})
}).catch((err) => {
setButtonsDisabled(false)
useStore.setState({ fullscreenLoadingModalVisible: false })
showToast({ message: err.toString() })
})
}} />
</Dialog.Container>
)
})
Example #24
Source File: BottomBar.js From filen-mobile with GNU Affero General Public License v3.0 | 4 votes |
BottomBar = memo(({ navigation, route }) => {
const [darkMode, setDarkMode] = useMMKVBoolean("darkMode", storage)
const currentRoutes = useStore(useCallback(state => state.currentRoutes))
const [lang, setLang] = useMMKVString("lang", storage)
const netInfo = useStore(useCallback(state => state.netInfo))
const setBottomBarHeight = useStore(useCallback(state => state.setBottomBarHeight))
const [userId, setUserId] = useMMKVNumber("userId", storage)
const [defaultDriveOnly, setDefaultDriveOnly] = useMMKVBoolean("defaultDriveOnly:" + userId, storage)
const [defaultDriveUUID, setDefaultDriveUUID] = useMMKVString("defaultDriveUUID:" + userId, storage)
const parent = getParent(route)
const routeURL = getRouteURL(route)
const baseName = defaultDriveOnly ? defaultDriveUUID : "base"
let currentScreenName = "MainScreen"
let isRecentsScreen = false
let isTrashScreen = false
let isSharedScreen = false
let isPhotosScreen = false
let isFavoritesScreen = false
let isBaseScreen = false
let isOfflineScreen = false
if(typeof currentRoutes == "object"){
if(currentRoutes.length > 0){
const currentRoute = currentRoutes[currentRoutes.length - 1]
currentScreenName = currentRoute.name
isRecentsScreen = (routeURL.indexOf("recents") !== -1)
isTrashScreen = (routeURL.indexOf("trash") !== -1)
isPhotosScreen = (routeURL.indexOf("photos") !== -1)
isFavoritesScreen = (routeURL.indexOf("favorites") !== -1)
isSharedScreen = ((routeURL.indexOf("shared-in") !== -1) || (routeURL.indexOf("shared-out") !== -1) || (routeURL.indexOf("links") !== -1))
isBaseScreen = (routeURL.indexOf(baseName) !== -1)
isOfflineScreen = (routeURL.indexOf("offline") !== -1)
}
}
const canOpenBottomAddActionSheet = currentScreenName == "MainScreen"
&& !isOfflineScreen
&& !isTrashScreen
&& !isFavoritesScreen
&& !isPhotosScreen
&& !isRecentsScreen
&& routeURL.indexOf("shared-in") == -1
&& parent !== "shared-out"
&& parent !== "links"
const showCloud = isBaseScreen
&& !isRecentsScreen
&& !isTrashScreen
&& !isSharedScreen
&& currentScreenName !== "SettingsAccountScreen"
&& currentScreenName !== "LanguageScreen"
&& currentScreenName !== "SettingsAdvancedScreen"
&& currentScreenName !== "CameraUploadScreen"
&& currentScreenName !== "SettingsScreen"
&& currentScreenName !== "TransfersScreen"
&& currentScreenName !== "EventsScreen"
&& currentScreenName !== "EventsInfoScreen"
&& currentScreenName !== "GDPRScreen"
&& currentScreenName !== "InviteScreen"
&& currentScreenName !== "TwoFactorScreen"
&& currentScreenName !== "ChangeEmailPasswordScreen"
const showSettings = currentScreenName == "SettingsScreen"
|| currentScreenName == "LanguageScreen"
|| currentScreenName == "SettingsAccountScreen"
|| currentScreenName == "SettingsAdvancedScreen"
|| currentScreenName == "CameraUploadScreen"
|| currentScreenName == "EventsScreen"
|| currentScreenName == "EventsInfoScreen"
|| isTrashScreen
|| currentScreenName == "GDPRScreen"
|| currentScreenName == "InviteScreen"
|| currentScreenName == "TwoFactorScreen"
|| currentScreenName == "ChangeEmailPasswordScreen"
const showHome = isSharedScreen
|| isRecentsScreen
|| isFavoritesScreen
|| isOfflineScreen
return (
<View style={{
paddingTop: 6,
height: 80,
flexDirection: "row",
justifyContent: "space-between",
borderTopColor: getColor(darkMode, "primaryBorder"),
borderTopWidth: 1
}} onLayout={(e) => setBottomBarHeight(e.nativeEvent.layout.height)}>
<Pressable style={{
alignItems: "center",
width: "20%",
}} onPress={() => {
navigationAnimation({ enable: false }).then(() => {
navigation.current.dispatch(CommonActions.reset({
index: 0,
routes: [
{
name: "MainScreen",
params: {
parent: "recents"
}
}
]
}))
})
}}>
<Ionicon name={showHome ? "home" : "home-outline"} size={22} color={showHome ? "#0A84FF" : (darkMode ? "gray" : "gray")} />
<Text style={{
color: showHome ? "#0A84FF" : (darkMode ? "gray" : "gray"),
fontSize: 10,
marginTop: 3
}}>{i18n(lang, "home")}</Text>
</Pressable>
<Pressable style={{
alignItems: "center",
width: "20%",
}} onPress={() => {
navigationAnimation({ enable: false }).then(() => {
navigation.current.dispatch(CommonActions.reset({
index: 0,
routes: [
{
name: "MainScreen",
params: {
parent: (defaultDriveOnly ? defaultDriveUUID : "base")
}
}
]
}))
})
}}>
<Ionicon name={showCloud ? "cloud" : "cloud-outline"} size={22} color={showCloud ? "#0A84FF" : (darkMode ? "gray" : "gray")} />
<Text style={{
color: showCloud ? "#0A84FF" : (darkMode ? "gray" : "gray"),
fontSize: 10,
marginTop: 3
}}>{i18n(lang, "cloud")}</Text>
</Pressable>
<Pressable style={{
alignItems: "center",
width: "20%",
paddingTop: 2
}} onPress={() => {
if(canOpenBottomAddActionSheet && netInfo.isConnected && netInfo.isInternetReachable){
SheetManager.show("BottomBarAddActionSheet")
}
}}>
<Ionicon name={netInfo.isConnected && netInfo.isInternetReachable ? (canOpenBottomAddActionSheet ? "add-circle-outline" : "close-circle-outline") : "cloud-offline-outline"} size={30} color={netInfo.isConnected && netInfo.isInternetReachable && canOpenBottomAddActionSheet ? darkMode ? "white" : "gray" : darkMode ? "gray" : "lightgray"} />
</Pressable>
<Pressable style={{
alignItems: "center",
width: "20%"
}} onPress={() => {
navigationAnimation({ enable: false }).then(() => {
navigation.current.dispatch(CommonActions.reset({
index: 0,
routes: [
{
name: "MainScreen",
params: {
parent: "photos"
}
}
]
}))
})
}}>
<Ionicon name={isPhotosScreen ? "image" : "image-outline"} size={22} color={isPhotosScreen ? "#0A84FF" : (darkMode ? "gray" : "gray")} />
<Text style={{
color: isPhotosScreen ? "#0A84FF" : (darkMode ? "gray" : "gray"),
fontSize: 10,
marginTop: 3
}}>{i18n(lang, "photos")}</Text>
</Pressable>
<Pressable style={{
alignItems: "center",
width: "20%",
}} onPress={() => {
navigationAnimation({ enable: false }).then(() => {
navigation.current.dispatch(CommonActions.reset({
index: 0,
routes: [
{
name: "SettingsScreen"
}
]
}))
})
}}>
<Ionicon name={showSettings ? "settings" : "settings-outline"} size={22} color={showSettings ? "#0A84FF" : (darkMode ? "gray" : "gray")} />
<Text style={{
color: showSettings ? "#0A84FF" : (darkMode ? "gray" : "gray"),
fontSize: 10,
marginTop: 3
}}>{i18n(lang, "settings")}</Text>
</Pressable>
</View>
)
})
Example #25
Source File: BiometricAuthScreen.js From filen-mobile with GNU Affero General Public License v3.0 | 4 votes |
BiometricAuthScreen = memo(({ navigation, route }) => {
const [darkMode, setDarkMode] = useMMKVBoolean("darkMode", storage)
const [lang, setLang] = useMMKVString("lang", storage)
const [userId, setUserId] = useMMKVNumber("userId", storage)
const biometricAuthScreenState = useStore(useCallback(state => state.biometricAuthScreenState))
const [pinCode, setPinCode] = useState("")
const [confirmPinCode, setConfirmPinCode] = useState("")
const [confirmPinCodeVisible, setConfirmPinCodeVisible] = useState(false)
const headerTextColor = darkMode ? "white" : "gray"
const [dotColor, setDotColor] = useState(headerTextColor)
const [showingBiometrics, setShowingBiometrics] = useState(false)
const [shakeAnimation, setShakeAnimation] = useState(new Animated.Value(0))
const setIsAuthing = useStore(useCallback(state => state.setIsAuthing))
const appState = useRef(AppState.currentState)
const setBiometricAuthScreenVisible = useStore(useCallback(state => state.setBiometricAuthScreenVisible))
const [startOnCloudScreen, setStartOnCloudScreen] = useMMKVBoolean("startOnCloudScreen:" + userId, storage)
const startShake = useCallback(() => {
Animated.sequence([
Animated.timing(shakeAnimation, { toValue: 10, duration: 100, useNativeDriver: true }),
Animated.timing(shakeAnimation, { toValue: -10, duration: 100, useNativeDriver: true }),
Animated.timing(shakeAnimation, { toValue: 10, duration: 100, useNativeDriver: true }),
Animated.timing(shakeAnimation, { toValue: -10, duration: 100, useNativeDriver: true }),
Animated.timing(shakeAnimation, { toValue: 10, duration: 100, useNativeDriver: true }),
Animated.timing(shakeAnimation, { toValue: 0, duration: 100, useNativeDriver: true })
]).start()
BackgroundTimer.setTimeout(() => {
setDotColor(headerTextColor)
}, 700)
})
const authed = useCallback(() => {
setConfirmPinCode("")
setPinCode("")
setConfirmPinCodeVisible(false)
setShowingBiometrics(false)
canGoBack = true
navigationAnimation({ enable: false }).then(() => {
let wasSetupScreen = false
const routes = navigation.getState().routes
for(let i = 0; i < routes.length; i++){
if(routes[i].name == "SetupScreen"){
wasSetupScreen = true
}
}
setIsAuthing(false)
if(wasSetupScreen){
navigationAnimation({ enable: true }).then(() => {
navigation.dispatch(CommonActions.reset({
index: 0,
routes: [
{
name: "MainScreen",
params: {
parent: startOnCloudScreen ? (storage.getBoolean("defaultDriveOnly:" + userId) ? storage.getString("defaultDriveUUID:" + userId) : "base") : "recents"
}
}
]
}))
})
}
else{
navigation.goBack()
}
})
})
const updatePinCode = useCallback((num) => {
setDotColor(headerTextColor)
if(num == -1){
if(pinCode.length > 0){
return setPinCode(code => code.substring(0, (code.length - 1)))
}
else{
return false
}
}
const newCode = pinCode + "" + num.toString()
if(newCode.length <= 4){
setPinCode(newCode)
}
if(newCode.length >= 4){
if(confirmPinCodeVisible){
if(newCode == confirmPinCode){
try{
storage.set("pinCode:" + userId, confirmPinCode)
storage.set("biometricPinAuth:" + userId, true)
}
catch(e){
console.log(e)
}
authed()
}
else{
startShake()
setDotColor("red")
setConfirmPinCode("")
setPinCode("")
setConfirmPinCodeVisible(false)
}
}
else{
if(biometricAuthScreenState == "setup"){
setConfirmPinCode(newCode)
setPinCode("")
setConfirmPinCodeVisible(true)
}
else{
try{
var storedPinCode = storage.getString("pinCode:" + userId) || "1234567890"
}
catch(e){
console.log(e)
}
if(newCode == storedPinCode){
authed()
}
else{
setPinCode("")
setDotColor("red")
startShake()
}
}
}
}
})
const promptBiometrics = useCallback(async () => {
if(biometricAuthScreenState == "setup"){
return false
}
if(showingBiometrics){
return false
}
await new Promise((resolve) => {
const wait = BackgroundTimer.setInterval(() => {
if(appState.current == "active"){
BackgroundTimer.clearInterval(wait)
return resolve()
}
}, 100)
})
ReactNativeBiometrics.isSensorAvailable().then((result) => {
const { available } = result
if(available){
setShowingBiometrics(true)
ReactNativeBiometrics.simplePrompt({
promptMessage: i18n(lang, "biometricAuthPrompt"),
cancelButtonText: i18n(lang, "cancel")
}).then((res) => {
const { success } = res
setShowingBiometrics(false)
if(success){
authed()
}
else{
console.log('user cancelled biometric prompt')
}
}).catch((err) => {
setShowingBiometrics(false)
console.log(err)
})
}
else{
console.log("Biometrics not available")
}
}).catch((err) => {
console.log(err)
})
})
useEffect(() => {
setIsAuthing(true)
setBiometricAuthScreenVisible(true)
canGoBack = false
SheetManager.hideAll()
useStore.setState({
renameDialogVisible: false,
createFolderDialogVisible: false,
confirmPermanentDeleteDialogVisible: false,
removeFromSharedInDialogVisible: false,
stopSharingDialogVisible: false,
createTextFileDialogVisible: false,
redeemCodeDialogVisible: false,
deleteAccountTwoFactorDialogVisible: false,
disable2FATwoFactorDialogVisible: false,
bulkShareDialogVisible: false
})
const removeListener = navigation.addListener("beforeRemove", (e) => {
if(!canGoBack){
e.preventDefault()
}
return false
})
const appStateListener = AppState.addEventListener("change", (nextAppState) => {
appState.current = nextAppState
})
BackgroundTimer.setTimeout(promptBiometrics, 100)
return () => {
removeListener()
appStateListener.remove()
setBiometricAuthScreenVisible(false)
}
}, [])
return (
<View style={{
height: window.height,
width: "100%",
backgroundColor: darkMode ? "black" : "white",
justifyContent: "center",
alignItems: "center"
}}>
<View style={{
marginBottom: 100
}}>
{
biometricAuthScreenState == "setup" ? (
<Text style={{
color: headerTextColor,
fontSize: 19
}}>
{confirmPinCodeVisible ? i18n(lang, "confirmPinCode") : i18n(lang, "setupPinCode")}
</Text>
) : (
<Text style={{
color: headerTextColor,
fontSize: 19
}}>
{i18n(lang, "enterPinCode")}
</Text>
)
}
<Animated.View style={{
flexDirection: "row",
justifyContent: "center",
marginTop: 35,
transform: [
{
translateX: shakeAnimation
}
]
}}>
{
Array.from(Array(4).keys()).map((key) => {
return (
<Ionicon key={key} name={pinCode.charAt(key).length > 0 ? "radio-button-on-outline" : "radio-button-off-outline"} size={22} color={dotColor} style={{
marginLeft: 5
}} />
)
})
}
</Animated.View>
</View>
<PINCodeRow numbers={[1, 2, 3]} updatePinCode={updatePinCode} promptBiometrics={promptBiometrics} />
<PINCodeRow numbers={[4, 5, 6]} updatePinCode={updatePinCode} promptBiometrics={promptBiometrics} />
<PINCodeRow numbers={[7, 8, 9]} updatePinCode={updatePinCode} promptBiometrics={promptBiometrics} />
<PINCodeRow updatePinCode={updatePinCode} promptBiometrics={promptBiometrics} />
</View>
)
})