@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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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>
    )
})