@react-navigation/native#StackActions JavaScript Examples

The following examples show how to use @react-navigation/native#StackActions. 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: logout.js    From filen-mobile with GNU Affero General Public License v3.0 6 votes vote down vote up
logout = ({ navigation }) => {
    try{
        storage.delete("apiKey")
        storage.delete("userId")
        storage.delete("email"),
        storage.delete("masterKeys")
        storage.delete("authVersion")
        storage.set("isLoggedIn", false)

        storage.getAllKeys().forEach((key) => {
            if(key.indexOf("loadItemsCache:") !== -1){
                storage.delete(key)
            }
        })
    }
    catch(e){
        return console.log(e)
    }

    if(typeof navigation.replace !== "undefined"){
        navigation.replace("LoginScreen")
    }
    else{
        navigation.current.dispatch(StackActions.replace("LoginScreen"))
    }
}
Example #2
Source File: refNavigation.js    From rn-animation with MIT License 5 votes vote down vote up
function push (name, params) {
  navigationRef.current?.dispatch(StackActions.push(name, params));
}
Example #3
Source File: helperFunctions.js    From WhatsApp-Clone with MIT License 5 votes vote down vote up
export async function logoutUser(navigation) {
  await clearLocalData();
  navigation.dispatch(StackActions.replace(NAV_TYPES.LOGIN));
  // navigation.navigate(NAV_TYPES.LOGIN);
}
Example #4
Source File: QrCodeAppScanner.js    From WhatsApp-Clone with MIT License 5 votes vote down vote up
QrCodeAppScanner = ({navigation}) => {
  var [state, dispatch] = useReducer(statusReducer, statusState);
  var {loading, isFlashEnabled, isFrontCam} = state;

  var cameraRef = useRef('');

  async function onScanQrCode(data) {
    let user = await getUserDetails();
    // alert(isValid);
    socket.emit(constants.SCAN_QR_CODE, user);
    try {
      if (isValid) {
        isValid = false;
        navigation.dispatch(StackActions.replace(NAV_TYPES.HOME_SCREEN));
      }
      setTimeout(function() {
        isValid = true;
      }, 1500);
    } catch (error) {
      console.log(error);
    }
  }

  return (
    <Root>
      <SafeAreaView style={styles.container}>
        {/* <TouchableOpacity onPress={() => onScanQrCode()}>
          <Text>CONNECT</Text>
        </TouchableOpacity>  */}
        <View style={styles.container}>
          <CameraView
            navigation={navigation}
            onScanQrCode={onScanQrCode}
            isScanCode
          />
        </View>
      </SafeAreaView>
    </Root>
  );
}
Example #5
Source File: navigation.js    From stayaway-app with European Union Public License 1.2 5 votes vote down vote up
function popToTop(...args) {
  if (navigationRef.current) {
    navigationRef.current.dispatch(StackActions.popToTop(...args));
  }
}
Example #6
Source File: navigation.js    From stayaway-app with European Union Public License 1.2 5 votes vote down vote up
function reset(...args) {
  if (navigationRef.current) {
    navigationRef.current.dispatch(StackActions.reset(...args));
  }
}
Example #7
Source File: navigation.js    From stayaway-app with European Union Public License 1.2 5 votes vote down vote up
function pop(...args) {
  if (navigationRef.current) {
    navigationRef.current.dispatch(StackActions.pop(...args));
  }
}
Example #8
Source File: navigation.js    From stayaway-app with European Union Public License 1.2 5 votes vote down vote up
function push(...args) {
  if (navigationRef.current) {
    navigationRef.current.dispatch(StackActions.push(...args));
  }
}
Example #9
Source File: refNavigation.js    From rn-animation with MIT License 5 votes vote down vote up
function replace (name, params) {
  navigationRef.current?.dispatch(StackActions.replace(name, params));
}
Example #10
Source File: refNavigation.js    From rn-animation with MIT License 5 votes vote down vote up
function popToTop () {
  navigationRef.current?.dispatch(StackActions.popToTop());
}
Example #11
Source File: EventsScreen.js    From filen-mobile with GNU Affero General Public License v3.0 5 votes vote down vote up
render(){
        const { item, index, darkMode, lang, navigation } = this.props

        return (
            <View key={index} style={{
                height: 35,
                width: "100%",
                paddingLeft: 15,
                paddingRight: 15,
                marginBottom: 10
            }}>
                <View style={{
                    height: "auto",
                    width: "100%",
                    backgroundColor: darkMode ? "#171717" : "lightgray",
                    borderRadius: 10
                }}>
                    <TouchableHighlight underlayColor={"gray"} style={{
                        width: "100%",
                        height: "auto",
                        borderRadius: 10
                    }} onPress={() => {
                        navigationAnimation({ enable: true }).then(() => {
                            navigation.dispatch(StackActions.push("EventsInfoScreen", {
                                uuid: item.uuid
                            }))
                        })
                    }}>
                        <View style={{
                            width: "100%",
                            height: "auto",
                            flexDirection: "row",
                            justifyContent: "space-between",
                            paddingLeft: 10,
                            paddingRight: 10,
                            paddingTop: 9,
                            paddingBottom: 10
                        }}>
                            <Text style={{
                                color: darkMode ? "white" : "black",
                                fontSize: 13,
                                width: "45%"
                            }} numberOfLines={1}>
                                {this.state.eventText}
                            </Text>
                            <View style={{
                                flexDirection: "row",
                                paddingTop: 2
                            }}>
                                <Text style={{
                                    color: "gray",
                                    paddingRight: 10,
                                    fontSize: 12
                                }}>
                                    {new Date(item.timestamp * 1000).toLocaleDateString()} {new Date(item.timestamp * 1000).toLocaleTimeString()}
                                </Text>
                                <Ionicon name="chevron-forward-outline" size={15} color="gray" style={{
                                    marginTop: 0
                                }} />
                            </View>
                        </View>
                    </TouchableHighlight>
                </View>
            </View>
        )
    }
Example #12
Source File: Dialogs.js    From filen-mobile with GNU Affero General Public License v3.0 5 votes vote down vote up
CreateTextFileDialog = memo(({ navigation }) => {
    const [darkMode, setDarkMode] = useMMKVBoolean("darkMode", storage)
    const createTextFileDialogVisible = useStore(useCallback(state => state.createTextFileDialogVisible))
    const setCreateTextFileDialogVisible = useStore(useCallback(state => state.setCreateTextFileDialogVisible))
    const [value, setValue] = useState(".txt")
    const inputRef = useRef()
    const [lang, setLang] = useMMKVString("lang", storage)
	const setTextEditorState = useStore(useCallback(state => state.setTextEditorState))
	const setTextEditorText = useStore(useCallback(state => state.setTextEditorText))
    const setCreateTextFileDialogName = useStore(useCallback(state => state.setCreateTextFileDialogName))
    const setTextEditorParent = useStore(useCallback(state => state.setTextEditorParent))

    useEffect(() => {
        if(!createTextFileDialogVisible){
            setTimeout(() => {
                setValue(".txt")
            }, 250)
        }

        if(createTextFileDialogVisible){
            setTimeout(() => {
                inputRef.current.focus()
                //inputRef.current.setNativeProps({ selection: { start: 0, end: 0 } })
            }, 250)
        }
    }, [createTextFileDialogVisible])

    return (
        <Dialog.Container
            visible={createTextFileDialogVisible}
            useNativeDriver={false}
            onRequestClose={() => setCreateTextFileDialogVisible(false)}
            onBackdropPress={() => {
                setCreateTextFileDialogVisible(false)
            }}
        >
            <Dialog.Title>{i18n(lang, "createTextFile")}</Dialog.Title>
            <Dialog.Input placeholder={i18n(lang, "fileName")} value={value} autoFocus={true} onChangeText={(val) => setValue(val)} textInputRef={inputRef} />
            <Dialog.Button label={i18n(lang, "cancel")} onPress={() => setCreateTextFileDialogVisible(false)} />
            <Dialog.Button label={i18n(lang, "create")} onPress={() => {
                if(value.length == 0){
                    return false
                }

                setCreateTextFileDialogVisible(false)
                setCreateTextFileDialogName(value)
                setTextEditorText("")
                setTextEditorParent(getParent())
                setTextEditorState("edit")
                                                    
                navigationAnimation({ enable: true }).then(() => {
                    navigation.dispatch(StackActions.push("TextEditorScreen"))
                })
            }} />
        </Dialog.Container>
    )
})
Example #13
Source File: TransfersIndicator.js    From filen-mobile with GNU Affero General Public License v3.0 4 votes vote down vote up
TransfersIndicator = memo(({ navigation }) => {
    const [darkMode, setDarkMode] = useMMKVBoolean("darkMode", storage)
    const uploadsCount = useStore(useCallback(state => Object.keys(state.uploads).length))
    const downloadsCount = useStore(useCallback(state => Object.keys(state.downloads).length))
    const [visible, setVisible] = useState(false)
    const uploads = useStore(useCallback(state => state.uploads), (current, next) => !isEqual(current, next))
    const downloads = useStore(useCallback(state => state.downloads), (current, next) => !isEqual(current, next))
    const [progress, setProgress] = useState(0)
    const currentRoutes = useStore(useCallback(state => state.currentRoutes))
    const [currentRouteName, setCurrentRouteName] = useState("")
    const biometricAuthScreenVisible = useStore(useCallback(state => state.biometricAuthScreenVisible))

    useEffect(() => {
        if((uploadsCount + downloadsCount) > 0 && currentRouteName !== "TransfersScreen" && !biometricAuthScreenVisible){
            setVisible(true)
        }
        else{
            setVisible(false)
        }
    }, [uploadsCount, downloadsCount, currentRouteName, biometricAuthScreenVisible])

    useEffect(() => {
        if(typeof currentRoutes !== "undefined"){
			if(typeof currentRoutes[currentRoutes.length - 1] !== "undefined"){
                setCurrentRouteName(currentRoutes[currentRoutes.length - 1].name)
			}
		}
    }, [currentRoutes])

    useEffect(() => {
        if((uploadsCount + downloadsCount) > 0){
            const transfers = memoryCache.get("transfers") || {}
            
            let chunks = 0
            let chunksDone = 0

            for(let prop in uploads){
                if(typeof transfers['upload:' + uploads[prop].id] == "undefined"){
                    transfers['upload:' + uploads[prop].id] = uploads[prop]
                }
            }

            for(let prop in downloads){
                if(typeof transfers['download:' + downloads[prop].id] == "undefined"){
                    transfers['download:' + downloads[prop].id] = downloads[prop]
                }
            }

            memoryCache.set("transfers", transfers)

            for(let prop in transfers){
                const transferDone = transfers[prop].chunksDone >= transfers[prop].file.chunks ? 1 : 0

                if(!transferDone){
                    chunks = chunks + transfers[prop].file.chunks
                    chunksDone = chunksDone + transfers[prop].chunksDone
                }
            }

            let prog = Math.round((chunksDone / chunks) * 100)

            if(isNaN(prog)){
                prog = 0
            }

            if(prog >= 100){
                prog = 100
            }

            setProgress(prog)
        }
        else{
            setProgress(0)
        }
    }, [JSON.stringify(uploads), JSON.stringify(downloads), uploadsCount, downloadsCount])

    useEffect(() => {
        if((uploadsCount + downloadsCount) <= 0){
            const transfers = memoryCache.get("transfers") || {}
            
            for(let prop in transfers){
                transfers[prop].chunksDone = transfers[prop].file.chunks
            }

            memoryCache.set("transfers", transfers)
        }
    }, [uploadsCount, downloadsCount])

    return (
        <TouchableOpacity style={{
            width: 50,
            height: 50,
            borderRadius: 50,
            backgroundColor: darkMode ? "#171717" : "lightgray",
            position: "absolute",
            bottom: 60,
            right: 10,
            zIndex: 999999,
            display: visible ? "flex" : "none"
        }} onPress={() => {
            if(currentRouteName == "TransfersScreen"){
                return false
            }

            navigationAnimation({ enable: true }).then(() => {
                navigation.current.dispatch(StackActions.push("TransfersScreen"))
            })
        }}>
            <View style={{
                justifyContent: "center",
                alignContent: "center",
                transform: [
                    {
                        rotate: "270deg"
                    }
                ]
            }}>
                {/*color={progress > 0 ? "#0A84FF" : darkMode ? "#171717" : "lightgray"}
                    progress={progress}
                    backgroundColor={darkMode ? "#171717" : "lightgray"}
                    containerColor={darkMode ? "#171717" : "lightgray"}*/}
                <AnimatedProgressWheel
                    size={50} 
                    width={4}
                    color="transparent"
                    progress={progress}
                    backgroundColor="transparent"
                    containerColor="transparent"
                />
                <ActivityIndicator size={"small"} color={darkMode ? "white" : "black"} style={{
                    position: "absolute",
                    marginLeft: 15
                }} />
            </View>
        </TouchableOpacity>
    )
})
Example #14
Source File: items.js    From filen-mobile with GNU Affero General Public License v3.0 4 votes vote down vote up
previewItem = async ({ item, setCurrentActionSheetItem = true, navigation }) => {
    if(item.size >= 134217728){
        return DeviceEventEmitter.emit("event", {
            type: "open-item-actionsheet",
            data: item
        })
    }

    const previewType = getFilePreviewType(getFileExt(item.name))
    const canThumbnail = canCompressThumbnail(getFileExt(item.name))

    if(!["image", "video", "text", "code", "pdf", "doc", "audio"].includes(previewType)){
        DeviceEventEmitter.emit("event", {
            type: "open-item-actionsheet",
            data: item
        })

        return false
    }

    if(previewType == "image"){
        if(!canThumbnail){
            DeviceEventEmitter.emit("event", {
                type: "open-item-actionsheet",
                data: item
            })
    
            return false
        }

        if(typeof item.thumbnail !== "string"){
            return false
        }
        
        return setImmediate(() => {
            const currentItems = useStore.getState().currentItems

            if(!Array.isArray(currentItems)){
                return false
            }

            const currentImages = []
            let currentIndex = 0
            const addedImages = {}
            let index = 0
            let imgFound = false

            for(let i = 0; i < currentItems.length; i++){
                const ext = getFileExt(currentItems[i].name)

                if(getFilePreviewType(ext) == "image" && canCompressThumbnail(ext) && !addedImages[currentItems[i].uuid]){
                    addedImages[currentItems[i].uuid] = true

                    if(currentItems[i].uuid == item.uuid){
                        currentIndex = index
                        imgFound = true
                    }
                    
                    currentImages.push({
                        uri: undefined,
                        name: currentItems[i].name,
                        index,
                        uuid: currentItems[i].uuid,
                        thumbnail: currentItems[i].thumbnail,
                        file: currentItems[i]
                    })

                    index += 1
                }
            }

            if(imgFound){
                navigationAnimation({ enable: true }).then(() => {
                    navigation.dispatch(StackActions.push("ImageViewerScreen", {
                        items: currentImages,
                        index: currentIndex
                    }))
                })
            }
        })
    }

    let existsOffline = false
    let offlinePath = ""

    try{
        offlinePath = getItemOfflinePath(await getDownloadPath({ type: "offline" }), item)

        if((await RNFS.exists(offlinePath))){
            existsOffline = true
        }
    }
    catch(e){
        //console.log(e)
    }

    const open = (path, offlineMode = false) => {
        setTimeout(() => {
            useStore.setState({ fullscreenLoadingModalVisible: false })

            if(offlineMode){
                return FileViewer.open(path, {
                    displayName: item.name,
                    showOpenWithDialog: false
                }).then(() => {
                    //console.log(path)
                }).catch((err) => {
                    console.log(err)

                    showToast({ message: i18n(storage.getString("lang"), "couldNotOpenFileLocally", true, ["__NAME__"], [item.name]) })
                })
            }

            if(previewType == "video"){
                FileViewer.open(path, {
                    displayName: item.name,
                    showOpenWithDialog: false
                }).then(() => {
                    //console.log(path)
                }).catch((err) => {
                    console.log(err)

                    showToast({ message: i18n(storage.getString("lang"), "couldNotOpenFileLocally", true, ["__NAME__"], [item.name]) })
                })
            }
            else if(previewType == "pdf" || previewType == "doc"){
                FileViewer.open(path, {
                    displayName: item.name,
                    showOpenWithDialog: false
                }).then(() => {
                    //console.log(path)
                }).catch((err) => {
                    console.log(err)

                    showToast({ message: i18n(storage.getString("lang"), "couldNotOpenFileLocally", true, ["__NAME__"], [item.name]) })
                })
            }
            else if(previewType == "text" || previewType == "code"){
                RNFS.readFile(path, "utf8").then((content) => {
                    if(setCurrentActionSheetItem){
                        useStore.setState({ currentActionSheetItem: item })
                    }

                    useStore.setState({
                        textEditorState: "view",
                        textEditorParent: item.parent,
                        createTextFileDialogName: item.name,
                        textEditorText: content
                    })
														
					navigationAnimation({ enable: true }).then(() => {
                        navigation.dispatch(StackActions.push("TextEditorScreen"))
                    })
                }).catch((err) => {
                    console.log(err)
                })
            }
        }, existsOffline ? 1 : 100)
    }

    if(existsOffline){
        return open(offlinePath, true)
    }

    const netInfo = useStore.getState().netInfo

    if(!netInfo.isConnected || !netInfo.isInternetReachable){
        return showToast({ message: i18n(storage.getString("lang"), "deviceOffline") })
    }

    try{
        if(storage.getBoolean("onlyWifiDownloads:" + storage.getNumber("userId")) && netInfo.type !== "wifi"){
            return showToast({ message: i18n(storage.getString("lang"), "onlyWifiDownloads") })
        }
    }
    catch(e){
        console.log(e)

        showToast({ message: e.toString() })
    }

    useStore.setState({ fullscreenLoadingModalVisible: true, fullscreenLoadingModalDismissable: true })

    queueFileDownload({
        file: item,
        optionalCallback: (err, path) => {
            useStore.setState({ fullscreenLoadingModalVisible: false })

            if(err){
                console.log(err)

                return showToast({ message: err.toString() })
            }

            return open(path)
        },
        isPreview: true
    })
}
Example #15
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 #16
Source File: SettingsScreen.js    From filen-mobile with GNU Affero General Public License v3.0 4 votes vote down vote up
SettingsScreen = memo(({ navigation, route }) => {
    const [darkMode, setDarkMode] = useMMKVBoolean("darkMode", storage)
    const [lang, setLang] = useMMKVString("lang", storage)
    const [userId, setUserId] = useMMKVNumber("userId", storage)
    const [onlyWifiUploads, setOnlyWifiUploads] = useMMKVBoolean("onlyWifiUploads:" + userId, storage)
    const [onlyWifiDownloads, setOnlyWifiDownloads] = useMMKVBoolean("onlyWifiDownloads:" + userId, storage)
    const [hideThumbnails, setHideThumbnails] = useMMKVBoolean("hideThumbnails:" + userId, storage)
    const [hideFileNames, setHideFileNames] = useMMKVBoolean("hideFileNames:" + userId, storage)
    const [hideSizes, setHideSizes] = useMMKVBoolean("hideSizes:" + userId, storage)
    const [biometricPinAuth, setBiometricPinAuth] = useMMKVBoolean("biometricPinAuth:" + userId, storage)
    const netInfo = useStore(useCallback(state => state.netInfo))
    const [startOnCloudScreen, setStartOnCloudScreen] = useMMKVBoolean("startOnCloudScreen:" + userId, storage)
    const [userSelectedTheme, setUserSelectedTheme] = useMMKVString("userSelectedTheme", storage)

    return (
        <ScrollView style={{
            height: "100%",
            width: "100%",
            backgroundColor: darkMode ? "black" : "white"
        }}>
            <Text style={{
                color: darkMode ? "white" : "black",
                fontWeight: "bold",
                fontSize: 24,
                marginLeft: 15,
                marginTop: Platform.OS == "ios" ? 20 : 0
            }}>
                {i18n(lang, "settings")}
            </Text>
            <SettingsGroup marginTop={15}>
                <SettingsHeader navigation={navigation} route={route} />
            </SettingsGroup>
            {
                __DEV__ && (
                    <SettingsGroup>
                        <SettingsButtonLinkHighlight title={"Clear loadItemsCache"} onPress={() => {
                            const keys = storage.getAllKeys()

                            keys.forEach(key => {
                                if(key.indexOf("loadItemsCache:") !== -1 || key.indexOf("folderSize:") !== -1){
                                    storage.delete(key)
                                }
                            })

                            showToast({ message: "Cleared" })
                        }} />
                    </SettingsGroup>
                )
            }
            <SettingsGroup>
                <SettingsButtonLinkHighlight onPress={() => {
                    if(!netInfo.isConnected || !netInfo.isInternetReachable){
                        return showToast({ message: i18n(lang, "deviceOffline") })
                    }

                    navigationAnimation({ enable: true }).then(() => {
                        navigation.dispatch(StackActions.push("MainScreen", {
                            parent: "trash"
                        }))
                    })
                }} title={i18n(lang, "trash")} />
                <SettingsButtonLinkHighlight onPress={() => {
                    if(!netInfo.isConnected || !netInfo.isInternetReachable){
                        return showToast({ message: i18n(lang, "deviceOffline") })
                    }

                    navigationAnimation({ enable: true }).then(() => {
                        navigation.dispatch(StackActions.push("TransfersScreen"))
                    })
                }} title={i18n(lang, "transfers")} />
                <SettingsButtonLinkHighlight onPress={() => {
                    if(!netInfo.isConnected || !netInfo.isInternetReachable){
                        return showToast({ message: i18n(lang, "deviceOffline") })
                    }
                    
                    navigationAnimation({ enable: true }).then(() => {
                        navigation.dispatch(StackActions.push("EventsScreen"))
                    })
                }} title={i18n(lang, "events")} />
            </SettingsGroup>
            <SettingsGroup>
                <SettingsButtonLinkHighlight onPress={() => {
                    if(!netInfo.isConnected || !netInfo.isInternetReachable){
                        return showToast({ message: i18n(lang, "deviceOffline") })
                    }

                    navigationAnimation({ enable: true }).then(() => {
                        navigation.dispatch(StackActions.push("CameraUploadScreen"))
                    })
                }} title={i18n(lang, "cameraUpload")} />
            </SettingsGroup>
            <SettingsGroup>
                <SettingsButton title={i18n(lang, "darkMode")} rightComponent={
                    <Switch
                        trackColor={getColor(darkMode, "switchTrackColor")}
                        thumbColor={userSelectedTheme == "dark" ? getColor(darkMode, "switchThumbColorEnabled") : getColor(darkMode, "switchThumbColorDisabled")}
                        ios_backgroundColor={getColor(darkMode, "switchIOSBackgroundColor")}
                        onValueChange={(value) => {
                            if(value){
                                setUserSelectedTheme("dark")
                                setDarkMode(true)
                                setStatusBarStyle(true)
                            }
                            else{
                                setUserSelectedTheme("light")
                                setDarkMode(false)
                                setStatusBarStyle(false)
                            }
                        }}
                        value={typeof userSelectedTheme == "string" && userSelectedTheme.length > 1 ? userSelectedTheme == "dark" : darkMode}
                    />
                } />
                <SettingsButton title={i18n(lang, "startOnCloudScreen")} rightComponent={
                    <Switch
                        trackColor={getColor(darkMode, "switchTrackColor")}
                        thumbColor={startOnCloudScreen ? getColor(darkMode, "switchThumbColorEnabled") : getColor(darkMode, "switchThumbColorDisabled")}
                        ios_backgroundColor={getColor(darkMode, "switchIOSBackgroundColor")}
                        onValueChange={() => setStartOnCloudScreen(!startOnCloudScreen)}
                        value={startOnCloudScreen}
                    />
                } />
                <SettingsButton title={i18n(lang, "onlyWifiUploads")} rightComponent={
                    <Switch
                        trackColor={getColor(darkMode, "switchTrackColor")}
                        thumbColor={onlyWifiUploads ? getColor(darkMode, "switchThumbColorEnabled") : getColor(darkMode, "switchThumbColorDisabled")}
                        ios_backgroundColor={getColor(darkMode, "switchIOSBackgroundColor")}
                        onValueChange={() => setOnlyWifiUploads(!onlyWifiUploads)}
                        value={onlyWifiUploads}
                    />
                } />
                <SettingsButton title={i18n(lang, "onlyWifiDownloads")} rightComponent={
                    <Switch
                        trackColor={getColor(darkMode, "switchTrackColor")}
                        thumbColor={onlyWifiDownloads ? getColor(darkMode, "switchThumbColorEnabled") : getColor(darkMode, "switchThumbColorDisabled")}
                        ios_backgroundColor={getColor(darkMode, "switchIOSBackgroundColor")}
                        onValueChange={() => setOnlyWifiDownloads(!onlyWifiDownloads)}
                        value={onlyWifiDownloads}
                    />
                } />
                <SettingsButton title={i18n(lang, "hideThumbnails")} rightComponent={
                    <Switch
                        trackColor={getColor(darkMode, "switchTrackColor")}
                        thumbColor={hideThumbnails ? getColor(darkMode, "switchThumbColorEnabled") : getColor(darkMode, "switchThumbColorDisabled")}
                        ios_backgroundColor={getColor(darkMode, "switchIOSBackgroundColor")}
                        onValueChange={() => setHideThumbnails(!hideThumbnails)}
                        value={hideThumbnails}
                    />
                } />
                <SettingsButton title={i18n(lang, "hideFileNames")} rightComponent={
                    <Switch
                        trackColor={getColor(darkMode, "switchTrackColor")}
                        thumbColor={hideFileNames ? getColor(darkMode, "switchThumbColorEnabled") : getColor(darkMode, "switchThumbColorDisabled")}
                        ios_backgroundColor={getColor(darkMode, "switchIOSBackgroundColor")}
                        onValueChange={() => setHideFileNames(!hideFileNames)}
                        value={hideFileNames}
                    />
                } />
                <SettingsButton title={i18n(lang, "hideFileFolderSize")} rightComponent={
                    <Switch
                        trackColor={getColor(darkMode, "switchTrackColor")}
                        thumbColor={hideSizes ? getColor(darkMode, "switchThumbColorEnabled") : getColor(darkMode, "switchThumbColorDisabled")}
                        ios_backgroundColor={getColor(darkMode, "switchIOSBackgroundColor")}
                        onValueChange={() => setHideSizes(!hideSizes)}
                        value={hideSizes}
                    />
                } />
                <SettingsButton title={i18n(lang, "biometricPinAuth")} rightComponent={
                    <Switch
                        trackColor={getColor(darkMode, "switchTrackColor")}
                        thumbColor={biometricPinAuth ? getColor(darkMode, "switchThumbColorEnabled") : getColor(darkMode, "switchThumbColorDisabled")}
                        ios_backgroundColor={getColor(darkMode, "switchIOSBackgroundColor")}
                        onValueChange={() => {
                            if(biometricPinAuth){
                                return Alert.alert(i18n(lang, "disableBiometricPinAuth"), i18n(lang, "disableBiometricPinAuthWarning"), [
                                    {
                                        text: i18n(lang, "cancel"),
                                        onPress: () => {
                                            setBiometricPinAuth(true)

                                            return false
                                        },
                                        style: "cancel"
                                    },
                                    {
                                        text: i18n(lang, "ok"),
                                        onPress: () => {
                                            Alert.alert(i18n(lang, "disableBiometricPinAuth"), i18n(lang, "areYouReallySure"), [
                                                {
                                                    text: i18n(lang, "cancel"),
                                                    onPress: () => {
                                                        setBiometricPinAuth(true)

                                                        return false
                                                    },
                                                    style: "cancel"
                                                },
                                                {
                                                    text: i18n(lang, "ok"),
                                                    onPress: () => {
                                                        setBiometricPinAuth(false)

                                                        storage.delete("pinCode:" + userId)
                                                    },
                                                    style: "default"
                                                }
                                            ], {
                                                cancelable: true
                                            })
                                        },
                                        style: "default"
                                    }
                                ], {
                                    cancelable: true
                                })
                            }

                            waitForStateUpdate("biometricAuthScreenState", "setup").then(() => {
                                navigationAnimation({ enable: true }).then(() => {
                                    navigation.dispatch(StackActions.push("BiometricAuthScreen"))
                                })
                            })
                        }}
                        value={biometricPinAuth}
                    />
                } />
                <SettingsButtonLinkHighlight onPress={() => {
                    navigationAnimation({ enable: true }).then(() => {
                        navigation.dispatch(StackActions.push("LanguageScreen"))
                    })
                }} title={i18n(lang, "language")} />
            </SettingsGroup>
            <SettingsGroup>
                <SettingsButtonLinkHighlight onPress={() => {
                    navigationAnimation({ enable: true }).then(() => {
                        navigation.dispatch(StackActions.push("SettingsAdvancedScreen"))
                    })
                }} title={i18n(lang, "advanced")} />
            </SettingsGroup>
            <View style={{ height: 25 }}></View>
        </ScrollView>
    )
})
Example #17
Source File: SettingsScreen.js    From filen-mobile with GNU Affero General Public License v3.0 4 votes vote down vote up
SettingsHeader = memo(({ navigation, route, navigationEnabled = true }) => {
    const [darkMode, setDarkMode] = useMMKVBoolean("darkMode", storage)
    const [userId, setUserId] = useMMKVNumber("userId", storage)
    const [email, setEmail] = useMMKVString("email", storage)
    const [lang, setLang] = useMMKVString("lang", storage)
    const netInfo = useStore(useCallback(state => state.netInfo))
    const [userInfo, setUserInfo] = useMMKVObject("userInfo:" + userId, storage)
    const [userAvatarCached, setUserAvatarCached] = useMMKVString("userAvatarCached:" + userId, storage)

    const cacheUserAvatar = useCallback(() => {
        if(typeof userInfo !== "undefined"){
            if(userInfo.avatarURL.indexOf("https://down.") !== -1){
                const avatarName = getFilenameFromPath(userInfo.avatarURL)

                if(userAvatarCached !== avatarName){
                    hasStoragePermissions().then(() => {
                        getDownloadPath({ type: "misc" }).then(async (path) => {
                            const avatarPath = path + avatarName
        
                            try{
                                if((await RNFS.exists(avatarPath))){
                                    await RNFS.unlink(avatarPath)
                                }
                            }
                            catch(e){
                                //console.log(e)
                            }
        
                            RNFS.downloadFile({
                                fromUrl: userInfo.avatarURL,
                                toFile: avatarPath
                            }).promise.then(async () => {
                                try{
                                    if(typeof userAvatarCached == "string"){
                                        if(userAvatarCached.length > 4){
                                            if((await RNFS.exists(MISC_BASE_PATH + userAvatarCached))){
                                                await RNFS.unlink(MISC_BASE_PATH + userAvatarCached)
                                            }
                                        }
                                    }
                                }
                                catch(e){
                                    //console.log(e)
                                }

                                setUserAvatarCached(avatarName)
                            }).catch((err) => {
                                console.log(err)
                            })
                        }).catch((err) => {
                            console.log(err)
                        })
                    }).catch((err) => {
                        console.log(err)
                    })
                }
                else{
                    if(typeof userAvatarCached == "string"){
                        if(userAvatarCached.length > 4){
                            getDownloadPath({ type: "misc" }).then((path) => {
                                const avatarPath = path + userAvatarCached
            
                                RNFS.exists(avatarPath).then((exists) => {
                                    if(!exists){
                                        setUserAvatarCached("")
        
                                        setTimeout(() => {
                                            cacheUserAvatar()
                                        }, 500)
                                    }
                                }).catch((err) => {
                                    console.log(err)
                                })
                            }).catch((err) => {
                                console.log(err)
                            })
                        }
                    }
                }
            }
        }
    })

    useEffect(() => {
        updateUserInfo()
    }, [])

    useEffect(() => {
        cacheUserAvatar()
    }, [userInfo])

    return (
        <Pressable style={{
            width: "100%",
            height: "auto",
            flexDirection: "row",
            justifyContent: "space-between",
            paddingLeft: 10,
            paddingRight: 10,
            paddingBottom: 10,
            paddingTop: 10,
            alignItems: "center"
        }} onPress={() => {
            if(!navigationEnabled){
                return false
            }

            if(!netInfo.isConnected || !netInfo.isInternetReachable){
                return showToast({ message: i18n(lang, "deviceOffline") })
            }

            navigationAnimation({ enable: true }).then(() => {
                navigation.dispatch(StackActions.push("SettingsAccountScreen"))
            })
        }}>
            <TouchableOpacity onPress={() => {
                if(Platform.OS == "android"){ // @TODO fix android avatar upload
                    return false
                }

                if(!netInfo.isConnected || !netInfo.isInternetReachable){
                    return showToast({ message: i18n(lang, "deviceOffline") })
                }
                
                SheetManager.show("ProfilePictureActionSheet")
            }}>
                <FastImage source={typeof userAvatarCached == "string" && userAvatarCached.length > 4 ? ({ uri: "file://" + MISC_BASE_PATH + userAvatarCached }) : (typeof userInfo !== "undefined" && userInfo.avatarURL.indexOf("https://down.") !== -1 ? { uri: userInfo.avatarURL } : require("../assets/images/appstore.png"))} style={{
                    width: 50,
                    height: 50,
                    borderRadius: 50
                }} />
            </TouchableOpacity>
            <View style={{
                width: "79%",
                paddingLeft: 15
            }}>
                <Text style={{
                    color: darkMode ? "white" : "black",
                    fontWeight: "bold",
                    fontSize: 19
                }} numberOfLines={1}>
                    {email}
                </Text>
                <Text style={{
                    color: "gray",
                    fontSize: 12,
                    marginTop: 1
                }} numberOfLines={1}>
                    {
                        typeof userInfo !== "undefined" ?
                            i18n(lang, "settingsHeaderUsage", true, ["__USAGE__", "__MAX__", "__PERCENT__"], [formatBytes(userInfo.storageUsed), formatBytes(userInfo.maxStorage), (isNaN((userInfo.storageUsed / userInfo.maxStorage * 100)) ? 0 : ((userInfo.storageUsed / userInfo.maxStorage * 100) >= 100) ? 100 : (userInfo.storageUsed / userInfo.maxStorage * 100).toFixed(2))])
                        :
                            i18n(lang, "settingsHeaderUsage", true, ["__USAGE__", "__MAX__", "__PERCENT__"], [formatBytes(0), formatBytes(0), 0])
                    }
                </Text>
            </View>
            <Ionicon name="chevron-forward-outline" size={22} color={navigationEnabled ? "gray" : "transparent"} />
        </Pressable>
    )
})
Example #18
Source File: LoginScreen.js    From app with GNU General Public License v3.0 4 votes vote down vote up
LoginScreen = ({navigation}) => {

  const [color,setColor] = useState("");
  const {updateUser,updateIsAuthenticated,updateToken} = useContext(GlobalContext);

	useEffect(() => {
		const getDominantColors = async () => {
			const colors = await ImageColors.getColors(BG, {
				fallback: '#7f8c8d',
			});
			if (colors.platform === 'android') {
				averageColor = colors.average;
				setColor(averageColor);
			} else {
				const backgroundColor = colors.background;
				setColor(backgroundColor);
			}
			return averageColor;
		};
		getDominantColors();
	}, []);

    useEffect(() => {
      GoogleSignin.configure({
        webClientId
      });

      const subscriber = auth().onAuthStateChanged(async(user) => {
        if (user) {
          console.log(user,"user");
          axios.post(`${userApiUrl}/user/signup`,{
            name:user.displayName,
            email:user.email,
            photo:user.photoURL
          }).then(async (result) => {
            console.log(result.data,"data");
            
            updateUser(result.data.user);
            await AsyncStorage.setItem('user', JSON.stringify(result.data.user));  
            
            updateToken(result.data.token);     
            await AsyncStorage.setItem('token',JSON.stringify(result.data.token));
            
            updateIsAuthenticated(true);
            await AsyncStorage.setItem('isAuthenticated',JSON.stringify(true));

            if (Platform.OS === 'android') {
              ToastAndroid.show('Login Successful', ToastAndroid.SHORT);
            }

            //If username present
            if(result.data.user.username) {
              navigation.dispatch(StackActions.replace('MainApp'));
            }
            else{
              navigation.navigate("UsernameScreen");
            }
          
          }).catch((err) => {
            console.log(err);
            
            if (Platform.OS === 'android') {
              ToastAndroid.show('Network Error', ToastAndroid.SHORT);
            }
          })
        }
    });
    return subscriber;
    }, []);

    async function onGoogleButtonPress() {
    // Get the users ID token
        const { idToken } = await GoogleSignin.signIn();

        // Create a Google credential with the token
        const googleCredential = auth.GoogleAuthProvider.credential(idToken);

        // Sign-in the user with the credential
        return auth().signInWithCredential(googleCredential);
    }


    return (

      <LinearGradientComp
			  bgcolors={{
				  colorOne: "#2d3436",
				  colorTwo: "#000000",
			}}>

      {/* <KeyboardAvoidingView
        keyboardVerticalOffset={-height / 2}
        style={{flex: 1, alignItems: 'center'}}
        behavior="position"> */}
        

        {/* <View style={{backgroundColor:"white", paddingHorizontal: 10}}> */}
          <View
            style={{
              flex: 0.4,
              justifyContent: 'center',
              marginTop:height/5,
              margin:30,
              minHeight: height / 10,
              maxHeight: height / 2.5,
            }}>
            <View
              style={{flexDirection: 'column',marginBottom:50, alignItems:"center"}}> 
              <Image
                source={LOGO}
                style={{height:height/4, width: width/2, marginBottom: 50}}
              />
              <Text style={{
                  color:"white",
                  fontSize:26,
                  // marginRight: "5%",
                  letterSpacing:1,
                  marginBottom:20,
                  alignContent: "center",
                  fontWeight:"bold"
                }}>{"Welcome Aboard!"}</Text>
            </View>
            <View style={{
              justifyContent:"center",
              alignItems:'center'
            }}>
              <GoogleSigninButton
              style={{ width: 192, height: 48 }}
              size={GoogleSigninButton.Size.Wide}
              color={GoogleSigninButton.Color.Dark}
              onPress={onGoogleButtonPress} 
              />

            </View>
          </View>
      </LinearGradientComp>
  );
}
Example #19
Source File: UsernameScreen.js    From app with GNU General Public License v3.0 4 votes vote down vote up
UsernameScreen = ({navigation}) => {
  const [username,setUsername] = useState('');
  const [submitting, isSubmitting] = useState(false);
  const [color,setColor] = useState("");

  const {user,updateUser,token} = useContext(GlobalContext);

  const handleUsernameChange= (text) => setUsername(text);

	useEffect(() => {
		const getDominantColors = async () => {
			const colors = await ImageColors.getColors(BG, {
				fallback: '#7f8c8d',
			});
			if (colors.platform === 'android') {
				averageColor = colors.average;
				setColor(averageColor);
			} else {
				const backgroundColor = colors.background;
				setColor(backgroundColor);
			}
			return averageColor;
		};
		getDominantColors();
	}, []);

  const handleUpdateUsername = () => {
    isSubmitting(true);
    axios.post(`${userApiUrl}/user/updateUsername`,{
        username,
        email:user.email,
      },{
        headers: {
					Authorization: "Bearer " + token,
				},
      }).then(async (result) => {
        console.log(result.data,"data");
        isSubmitting(false);
        updateUser(result.data.user);
        await AsyncStorage.setItem('user', JSON.stringify(result.data.user));  
        if (Platform.OS === 'android') {
          ToastAndroid.show('Username added successfully', ToastAndroid.SHORT);
        }
        navigation.dispatch(StackActions.replace('MainApp'));   
      }).catch((err) => {
        console.log(err.response.data.message,"error");
        isSubmitting(false);
        if (Platform.OS === 'android') {
          ToastAndroid.show(err?.response?.data?.message, ToastAndroid.SHORT);
        }
      })        
  };

  return (

      <LinearGradientComp
			  bgcolors={{
          colorOne: "#2d3436",
				  colorTwo: "#000000",
			}}>

      {/* <KeyboardAvoidingView
        keyboardVerticalOffset={-height / 2}
        style={{flex: 1, alignItems: 'center'}}
        behavior="position"> */}
        

        {/* <View style={{backgroundColor:"white", paddingHorizontal: 10}}> */}
          <View
            style={{
              flex: 0.5,
              justifyContent: 'center',
              marginTop:height/3,
              margin:30,
              minHeight: height / 10,
              maxHeight: height / 2.5,
            }}>
            <View
              style={{flexDirection: 'column',marginBottom:60, alignItems:"center"}}> 
              <Image
                source={LOGO}
                style={{height:height/4, width: width/2}}
              />
              <Text style={{
                  color:"white",
                  fontSize:26,
                  // marginRight: "5%",
                  letterSpacing:1,
                  marginBottom:5,
                  alignContent: "center",
                  fontWeight:"bold"
                }}>{"Pick a username"}</Text>
            </View>
            <InputBox
              style={{
                backgroundColor: "transparent",
                color: "white",
                fontSize: 16,
                borderLeftWidth:0,
                borderRightWidth:0,
                borderTopWidth:0,
                borderWidth: 1,
              }}
              label="Username"
              value={username}
              onChangeText={handleUsernameChange}
              autoCapitalize={'none'}
              autoCompleteType={'username'}
            />

            <View style={{
              flexDirection:"row",
              justifyContent:"center",
              marginTop:50
            }}>
              <Btn
                style={{
                  width:width/3,
                  color: "black",
                  backgroundColor:"rgb(243, 244, 246)"
                }}
                title={"Let's Go!"}
                loading={submitting}
                loadingText={"Loading"}
                onPress={handleUpdateUsername}
              />

            </View>
          </View>
      </LinearGradientComp>
  );
}
Example #20
Source File: SettingsAccountScreen.js    From filen-mobile with GNU Affero General Public License v3.0 4 votes vote down vote up
SettingsAccountScreen = memo(({ navigation, route }) => {
    const [darkMode, setDarkMode] = useMMKVBoolean("darkMode", storage)
    const [lang, setLang] = useMMKVString("lang", storage)
    const setRedeemCodeDialogVisible = useStore(useCallback(state => state.setRedeemCodeDialogVisible))
    const setDeleteAccountTwoFactorDialogVisible = useStore(useCallback(state => state.setDeleteAccountTwoFactorDialogVisible))
    const [accountSettings, setAccountSettings] = useState({})
    const [isLoading, setIsLoading] = useState(true)
    const isMounted = useMountedState()

    useEffect(() => {
        getSettings().then((settings) => {
            if(isMounted()){
                setAccountSettings(settings)
                setIsLoading(false)
            }
        }).catch((err) => {
            console.log(err)

            showToast({ message: err.toString() })
        })
    }, [])

    return (
        <>
            <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, "accountSettings")}
                </Text>
            </View>
            <ScrollView style={{
                height: "100%",
                width: "100%",
                backgroundColor: darkMode ? "black" : "white"
            }}>
                {
                    isLoading ? (
                        <ActivityIndicator size={"small"} color={darkMode ? "white" : "black"} style={{
                            marginTop: "70%"
                        }} />
                    ) : (
                        <>
                            <SettingsGroup marginTop={15}>
                                <SettingsButtonLinkHighlight onPress={() => {
                                    navigationAnimation({ enable: true }).then(() => {
                                        navigation.dispatch(StackActions.push("ChangeEmailPasswordScreen"))
                                    })
                                }} title={i18n(lang, "changeEmailPassword")} />
                                <SettingsButtonLinkHighlight onPress={() => {
                                    navigationAnimation({ enable: true }).then(() => {
                                        navigation.dispatch(StackActions.push("TwoFactorScreen", {
                                            accountSettings
                                        }))
                                    })
                                }} title={i18n(lang, accountSettings.twoFactorEnabled ? "disable2FA" : "enable2FA")} />
                                <SettingsButtonLinkHighlight onPress={() => {
                                    navigationAnimation({ enable: true }).then(() => {
                                        navigation.dispatch(StackActions.push("GDPRScreen"))
                                    })
                                }} title={i18n(lang, "showGDPR")} />
                            </SettingsGroup>
                            <SettingsGroup>
                                <SettingsButtonLinkHighlight rightText={formatBytes(accountSettings.storageUsed)} onPress={() => {
                                    Alert.alert(i18n(lang, "deleteAllFiles"), i18n(lang, "deleteAllFilesInfo"), [
                                        {
                                            text: i18n(lang, "cancel"),
                                            onPress: () => {
                                                return false
                                            },
                                            style: "cancel"
                                        },
                                        {
                                            text: i18n(lang, "ok"),
                                            onPress: () => {
                                                Alert.alert(i18n(lang, "deleteAllFiles"), i18n(lang, "areYouReallySure"), [
                                                    {
                                                        text: i18n(lang, "cancel"),
                                                        onPress: () => {
                                                            return false
                                                        },
                                                        style: "cancel"
                                                    },
                                                    {
                                                        text: i18n(lang, "ok"),
                                                        onPress: () => {
                                                            useStore.setState({ fullscreenLoadingModalVisible: true })

                                                            deleteAllFilesAndFolders().then(() => {
                                                                useStore.setState({ fullscreenLoadingModalVisible: false })

                                                                showToast({ message: i18n(lang, "deleteAllFilesSuccess") })

                                                                setAccountSettings(prev => ({ ...prev, storageUsed: 0  }))
                                                            }).catch((err) => {
                                                                console.log(err)

                                                                useStore.setState({ fullscreenLoadingModalVisible: false })

                                                                showToast({ message: err.toString() })
                                                            })
                                                        },
                                                        style: "default"
                                                    }
                                                ], {
                                                    cancelable: true
                                                })
                                            },
                                            style: "default"
                                        }
                                    ], {
                                        cancelable: true
                                    })
                                }} title={i18n(lang, "deleteAllFiles")} />
                                <SettingsButtonLinkHighlight rightText={formatBytes(accountSettings.versionedStorage)} onPress={() => {
                                    Alert.alert(i18n(lang, "deleteAllVersionedFiles"), i18n(lang, "deleteAllVersionedFilesInfo"), [
                                        {
                                            text: i18n(lang, "cancel"),
                                            onPress: () => {
                                                return false
                                            },
                                            style: "cancel"
                                        },
                                        {
                                            text: i18n(lang, "ok"),
                                            onPress: () => {
                                                Alert.alert(i18n(lang, "deleteAllVersionedFiles"), i18n(lang, "areYouReallySure"), [
                                                    {
                                                        text: i18n(lang, "cancel"),
                                                        onPress: () => {
                                                            return false
                                                        },
                                                        style: "cancel"
                                                    },
                                                    {
                                                        text: i18n(lang, "ok"),
                                                        onPress: () => {
                                                            useStore.setState({ fullscreenLoadingModalVisible: true })

                                                            deleteAllVersionedFiles().then(() => {
                                                                useStore.setState({ fullscreenLoadingModalVisible: false })

                                                                showToast({ message: i18n(lang, "deleteAllVersionedFilesSuccess") })

                                                                setAccountSettings(prev => ({ ...prev, storageUsed: (prev.storageUsed - prev.versionedStorage) }))
                                                                setAccountSettings(prev => ({ ...prev, versionedStorage: 0  }))
                                                            }).catch((err) => {
                                                                console.log(err)

                                                                useStore.setState({ fullscreenLoadingModalVisible: false })

                                                                showToast({ message: err.toString() })
                                                            })
                                                        },
                                                        style: "default"
                                                    }
                                                ], {
                                                    cancelable: true
                                                })
                                            },
                                            style: "default"
                                        }
                                    ], {
                                        cancelable: true
                                    })
                                }} title={i18n(lang, "deleteAllVersionedFiles")} />
                            </SettingsGroup>
                            <SettingsGroup>
                                <SettingsButtonLinkHighlight onPress={() => setRedeemCodeDialogVisible(true)} title={i18n(lang, "redeemACode")} />
                                <SettingsButtonLinkHighlight onPress={() => {
                                    navigationAnimation({ enable: true }).then(() => {
                                        navigation.dispatch(StackActions.push("InviteScreen"))
                                    })
                                }} title={i18n(lang, "invite")} />
                            </SettingsGroup>
                            <SettingsGroup>
                                <SettingsButtonLinkHighlight onPress={() => {
                                    Alert.alert(i18n(lang, "logout"), i18n(lang, "areYouReallySure"), [
                                        {
                                            text: i18n(lang, "cancel"),
                                            onPress: () => {
                                                return false
                                            },
                                            style: "cancel"
                                        },
                                        {
                                            text: i18n(lang, "ok"),
                                            onPress: () => logout({ navigation }),
                                            style: "default"
                                        }
                                    ], {
                                        cancelable: true
                                    })
                                }} title={i18n(lang, "logout")} />
                            </SettingsGroup>
                            <SettingsGroup>
                                <SettingsButtonLinkHighlight onPress={() => {
                                    Alert.alert(i18n(lang, "deleteAccount"), i18n(lang, "deleteAccountInfo"), [
                                        {
                                            text: i18n(lang, "cancel"),
                                            onPress: () => {
                                                return false
                                            },
                                            style: "cancel"
                                        },
                                        {
                                            text: i18n(lang, "ok"),
                                            onPress: () => {
                                                Alert.alert(i18n(lang, "deleteAccount"), i18n(lang, "areYouReallySure"), [
                                                    {
                                                        text: i18n(lang, "cancel"),
                                                        onPress: () => {
                                                            return false
                                                        },
                                                        style: "cancel"
                                                    },
                                                    {
                                                        text: i18n(lang, "ok"),
                                                        onPress: () => {
                                                            useStore.setState({ fullscreenLoadingModalVisible: true })

                                                            getSettings().then((settings) => {
                                                                if(settings.twoFactorEnabled){
                                                                    useStore.setState({ fullscreenLoadingModalVisible: false })

                                                                    return setDeleteAccountTwoFactorDialogVisible(true)
                                                                }

                                                                deleteAccount({ twoFactorKey: "XXXXXX" }).then(() => {
                                                                    useStore.setState({ fullscreenLoadingModalVisible: false })

                                                                    logout({ navigation })
                                                                }).catch((err) => {
                                                                    console.log(err)

                                                                    useStore.setState({ fullscreenLoadingModalVisible: false })

                                                                    showToast({ message: err.toString() })
                                                                })
                                                            }).catch((err) => {
                                                                console.log(err)

                                                                useStore.setState({ fullscreenLoadingModalVisible: false })

                                                                showToast({ message: err.toString() })
                                                            })
                                                        },
                                                        style: "default"
                                                    }
                                                ], {
                                                    cancelable: true
                                                })
                                            },
                                            style: "default"
                                        }
                                    ], {
                                        cancelable: true
                                    })
                                }} title={i18n(lang, "deleteAccount")} />
                            </SettingsGroup>
                            <View style={{ height: 25 }}></View>
                        </>
                    )
                }
            </ScrollView>
        </>
    )
})
Example #21
Source File: MainScreen.js    From filen-mobile with GNU Affero General Public License v3.0 4 votes vote down vote up
MainScreen = memo(({ navigation, route }) => {
    const [darkMode, setDarkMode] = useMMKVBoolean("darkMode", storage)
    const [userId, setUserId] = useMMKVNumber("userId", storage)
    const [routeURL, setRouteURL] = useState(useCallback(getRouteURL(route)))
    const cachedItemsRef = useRef(storage.getString("loadItemsCache:" + routeURL)).current
    const cachedItemsParsed = useRef(typeof cachedItemsRef == "string" ? JSON.parse(cachedItemsRef) : []).current
    const [items, setItems] = useState(Array.isArray(cachedItemsParsed) ? cachedItemsParsed.filter(item => item !== null && typeof item.uuid == "string") : [])
    const [searchTerm, setSearchTerm] = useState("")
    const [loadDone, setLoadDone] = useState(typeof cachedItemsRef !== "undefined" ? true : false)
    const setNavigation = useStore(useCallback(state => state.setNavigation))
    const setRoute = useStore(useCallback(state => state.setRoute))
    const [masterKeys, setMasterKeys] = useState(useCallback(getMasterKeys()))
    const isMounted = useMountedState()
    const setCurrentActionSheetItem = useStore(useCallback(state => state.setCurrentActionSheetItem))
    const setCurrentItems = useStore(useCallback(state => state.setCurrentItems))
    const itemsRef = useRef([])
    const setItemsSelectedCount = useStore(useCallback(state => state.setItemsSelectedCount))
    const setInsets = useStore(useCallback(state => state.setInsets))
    const insets = useSafeAreaInsets()
    const [progress, setProgress] = useState({ itemsDone: 0, totalItems: 1 })
    const selectedCountRef = useRef(0)
    const setIsDeviceReady = useStore(useCallback(state => state.setIsDeviceReady))
    const [itemsBeforeSearch, setItemsBeforeSearch] = useState([])
    const [photosGridSize, setPhotosGridSize] = useMMKVNumber("photosGridSize", storage)
    const bottomBarHeight = useStore(useCallback(state => state.bottomBarHeight))
    const topBarHeight = useStore(useCallback(state => state.topBarHeight))
    const contentHeight = useStore(useCallback(state => state.contentHeight))
    const [photosRange, setPhotosRange] = useMMKVString("photosRange:" + userId, storage)
    const netInfo = useStore(useCallback(state => state.netInfo))
    const itemsSortBy = useStore(useCallback(state => state.itemsSortBy))
    const [initialized, setInitialized] = useState(false)
    const isFocused = useIsFocused()

    const updateItemThumbnail = useCallback((item, path) => {
        if(typeof path !== "string"){
            return false
        }

        if(path.length < 4){
            return false
        }
    
        if(isMounted()){
            setItems(items => items.map(mapItem => mapItem.uuid == item.uuid && typeof mapItem.thumbnail == "undefined" ? {...mapItem, thumbnail: item.uuid + ".jpg" } : mapItem))
        }
    })
    
    const selectItem = useCallback((item) => {
        if(getRouteURL(route).indexOf("photos") !== -1){
            if(calcPhotosGridSize(photosGridSize) >= 6){
                return false
            }
        }

        if(isMounted()){
            setItems(items => items.map(mapItem => mapItem.uuid == item.uuid ? {...mapItem, selected: true} : mapItem))
        }
    })
    
    const unselectItem = useCallback((item) => {
        if(isMounted()){
            setItems(items => items.map(mapItem => mapItem.uuid == item.uuid ? {...mapItem, selected: false} : mapItem))
        }
    })

    const unselectAllItems = useCallback(() => {
        if(isMounted()){
            setItems(items => items.map(mapItem => mapItem.selected ? {...mapItem, selected: false} : mapItem))
        }
    })

    const selectAllItems = useCallback(() => {
        if(getRouteURL(route).indexOf("photos") !== -1){
            if(calcPhotosGridSize(photosGridSize) >= 6){
                return false
            }
        }

        if(isMounted()){
            setItems(items => items.map(mapItem => !mapItem.selected ? {...mapItem, selected: true} : mapItem))
        }
    })

    const removeItem = useCallback((uuid) => {
        if(isMounted()){
            setItems(items => items.filter(mapItem => mapItem.uuid !== uuid && mapItem))
        }
    })

    const markOffline = useCallback((uuid, value) => {
        if(isMounted()){
            setItems(items => items.map(mapItem => mapItem.uuid == uuid ? {...mapItem, offline: value} : mapItem))
        }
    })

    const markFavorite = useCallback((uuid, value) => {
        if(isMounted()){
            setItems(items => items.map(mapItem => mapItem.uuid == uuid ? {...mapItem, favorited: value} : mapItem))
        }
    })

    const changeFolderColor = useCallback((uuid, color) => {
        if(isMounted()){
            setItems(items => items.map(mapItem => mapItem.uuid == uuid && mapItem.type == "folder" ? {...mapItem, color} : mapItem))
        }
    })

    const changeItemName = useCallback((uuid, name) => {
        if(isMounted()){
            setItems(items => items.map(mapItem => mapItem.uuid == uuid ? {...mapItem, name} : mapItem))
        }
    })

    const addItem = useCallback((item, parent) => {
        const currentParent = getParent(route)

        if(isMounted() && (currentParent == parent || (item.offline && parent == "offline"))){
            setItems(items => sortItems({ items: [...items, item], passedRoute: route }))
        }
    })

    const changeWholeItem = useCallback((item, uuid) => {
        if(isMounted()){
            setItems(items => items.map(mapItem => mapItem.uuid == uuid ? item : mapItem))
        }
    })

    const reloadList = useCallback((parent) => {
        const currentParent = getParent(route)

        if(isMounted() && currentParent == parent){
            fetchItemList({ bypassCache: true, callStack: 1 })
        }
    })

    const updateFolderSize = useCallback((uuid, size) => {
        if(isMounted()){
            setItems(items => items.map(mapItem => mapItem.uuid == uuid && mapItem.type == "folder" ? {...mapItem, size} : mapItem))
        }
    })

    useEffect(() => {
        if(isMounted() && initialized){
            if(searchTerm.length == 0){
                if(itemsBeforeSearch.length > 0){
                    setItems(itemsBeforeSearch)
                    setItemsBeforeSearch([])
                }
            }
            else{
                if(itemsBeforeSearch.length == 0){
                    setItemsBeforeSearch(items)
    
                    var filtered = items.filter(item => item.name.toLowerCase().trim().indexOf(searchTerm.toLowerCase().trim()) !== -1 && item)
                }
                else{
                    var filtered = itemsBeforeSearch.filter(item => item.name.toLowerCase().trim().indexOf(searchTerm.toLowerCase().trim()) !== -1 && item)
                }
    
                setItems(filtered)
            }
        }
    }, [searchTerm])

    useEffect(() => {
        if(isMounted() && initialized){
            const sorted = sortItems({ items, passedRoute: route })

            setItems(sorted)
        }
    }, [itemsSortBy])

    useEffect(() => {
        if(isFocused){
            if(Array.isArray(items) && items.length > 0){
                setCurrentItems(items)

                itemsRef.current = items
                global.items = items

                const selected = items.filter(item => item.selected).length

                selectedCountRef.current = selected

                setItemsSelectedCount(selectedCountRef.current)
            }
            else{
                setCurrentItems([])
    
                itemsRef.current = []
                global.items = []
    
                setItemsSelectedCount(0)
            }

            global.setItems = setItems
        }
    }, [items, isFocused])

    const fetchItemList = useCallback(({ bypassCache = false, callStack = 0, loadFolderSizes = false }) => {
        return new Promise((resolve, reject) => {
            loadItems({
                parent: getParent(route),
                setItems,
                masterKeys,
                setLoadDone,
                navigation,
                isMounted,
                bypassCache,
                route,
                setProgress,
                callStack,
                loadFolderSizes
            }).then(resolve).catch(reject)
        })
    })

    useEffect(() => {
        setNavigation(navigation)
        setRoute(route)
        setInsets(insets)
        
        fetchItemList({ bypassCache: false, callStack: 0, loadFolderSizes: false }).catch((err) => console.log(err))

        global.fetchItemList = fetchItemList

        const deviceListener = DeviceEventEmitter.addListener("event", (data) => {
            const navigationRoutes = navigation.getState().routes
            const isListenerActive = typeof navigationRoutes == "object" ? (navigationRoutes[navigationRoutes.length - 1].key == route.key) : false

            if(data.type == "thumbnail-generated"){
                updateItemThumbnail(data.data, data.data.path)
            }
            else if(data.type == "item-onpress" && isListenerActive){
                if(data.data.selected){
                    unselectItem(data.data)
                }
                else{
                    if(selectedCountRef.current > 0){
                        selectItem(data.data)
                    }
                    else{
                        global.currentReceiverId = data.data.receiverId

                        try{
                            const currentRouteURL = getRouteURL(route)

                            if(typeof currentRouteURL == "string"){
                                if(data.data.type == "folder" && currentRouteURL.indexOf("trash") == -1){
                                    navigationAnimation({ enable: true }).then(() => {
                                        navigation.dispatch(StackActions.push("MainScreen", {
                                            parent: currentRouteURL + "/" + data.data.uuid
                                        }))
                                    })
                                }
                                else{
                                    previewItem({ item: data.data, navigation })
                                }
                            }
                            else{
                                console.log("route url !== string: ", currentRouteURL)
                            }
                        }
                        catch(e){
                            console.log(e)
                        }
                    }
                }
            }
            else if(data.type == "item-onlongpress" && isListenerActive){
                selectItem(data.data)
            }
            else if(data.type == "open-item-actionsheet" && isListenerActive){
                setCurrentActionSheetItem(data.data)
    
                SheetManager.show("ItemActionSheet")
            }
            else if(data.type == "unselect-all-items" && isListenerActive){
                unselectAllItems()
            }
            else if(data.type == "select-all-items" && isListenerActive){
                selectAllItems()
            }
            else if(data.type == "select-item" && isListenerActive){
                selectItem(data.data)
            }
            else if(data.type == "unselect-item" && isListenerActive){
                unselectItem(data.data)
            }
            else if(data.type == "remove-item"){
                removeItem(data.data.uuid)
            }
            else if(data.type == "add-item"){
                addItem(data.data.item, data.data.parent)
            }
            else if(data.type == "mark-item-offline"){
                if(!data.data.value && getRouteURL(route).indexOf("offline") !== -1){
                    removeItem(data.data.uuid)
                }
                else{
                    markOffline(data.data.uuid, data.data.value)
                }
            }
            else if(data.type == "mark-item-favorite"){
                if(!data.data.value && getRouteURL(route).indexOf("favorites") !== -1){
                    removeItem(data.data.uuid)
                }
                else{
                    markFavorite(data.data.uuid, data.data.value)
                }
            }
            else if(data.type == "change-folder-color"){
                changeFolderColor(data.data.uuid, data.data.color)
            }
            else if(data.type == "change-item-name"){
                changeItemName(data.data.uuid, data.data.name)
            }
            else if(data.type == "change-whole-item"){
                changeWholeItem(data.data.item, data.data.uuid)
            }
            else if(data.type == "reload-list"){
                reloadList(data.data.parent)
            }
            else if(data.type == "remove-public-link"){
                if(getRouteURL(route).indexOf("links") !== -1){
                    removeItem(data.data.uuid)
                }
            }
            else if(data.type == "folder-size"){
                updateFolderSize(data.data.uuid, data.data.size)
            }
        })

        setIsDeviceReady(true)
        setInitialized(true)

        return () => {
            deviceListener.remove()
            
            setPhotosRange("all")
        }
    }, [])

    return (
        <View style={{
            height: "100%",
            width: "100%",
            backgroundColor: darkMode ? "black" : "white"
        }}>
            <TopBar navigation={navigation} route={route} setLoadDone={setLoadDone} searchTerm={searchTerm} setSearchTerm={setSearchTerm} />
            <View style={{
                height: routeURL.indexOf("photos") !== -1 ? (contentHeight - 40 - bottomBarHeight + (Platform.OS == "android" ? 35 : 26)) : (contentHeight - topBarHeight - bottomBarHeight + 30)
            }}>
                <ItemList navigation={navigation} route={route} items={items} setItems={setItems} showLoader={!loadDone} loadDone={loadDone} searchTerm={searchTerm} isMounted={isMounted} fetchItemList={fetchItemList} progress={progress} setProgress={setProgress} />
            </View>
        </View>
    )
})
Example #22
Source File: ItemList.js    From filen-mobile with GNU Affero General Public License v3.0 4 votes vote down vote up
ItemList = memo(({ navigation, route, items, showLoader, setItems, searchTerm, isMounted, fetchItemList, progress, setProgress, loadDone }) => {
    const [darkMode, setDarkMode] = useMMKVBoolean("darkMode", storage)
    const [refreshing, setRefreshing] = useState(false)
    const [itemViewMode, setItemViewMode] = useMMKVString("itemViewMode", storage)
    const dimensions = { window: Dimensions.get("window"), screen: Dimensions.get("screen") }
    const [lang, setLang] = useMMKVString("lang", storage)
    const cameraUploadTotal = useStore(useCallback(state => state.cameraUploadTotal))
    const cameraUploadUploaded = useStore(useCallback(state => state.cameraUploadUploaded))
    const [userId, setUserId] = useMMKVNumber("userId", storage)
    const [cameraUploadEnabled, setCameraUploadEnabled] = useMMKVBoolean("cameraUploadEnabled:" + userId, storage)
    const [scrollDate, setScrollDate] = useState(Array.isArray(items) && items.length > 0 ? calcCameraUploadCurrentDate(items[0].lastModified, items[items.length - 1].lastModified, lang) : "")
    const [photosGridSize, setPhotosGridSize] = useMMKVNumber("photosGridSize", storage)
    const [hideThumbnails, setHideThumbnails] = useMMKVBoolean("hideThumbnails:" + userId, storage)
    const [hideFileNames, setHideFileNames] = useMMKVBoolean("hideFileNames:" + userId, storage)
    const [hideSizes, setHideSizes] = useMMKVBoolean("hideSizes:" + userId, storage)
    const [photosRange, setPhotosRange] = useMMKVString("photosRange:" + userId, storage)
    const itemListRef = useRef()
    const [routeURL, setRouteURL] = useState(useCallback(getRouteURL(route)))
    const netInfo = useStore(useCallback(state => state.netInfo))
    const [scrollIndex, setScrollIndex] = useState(0)
    const [currentItems, setCurrentItems] = useState([])
    const insets = useSafeAreaInsets()
    const [onlyWifiUploads, setOnlyWifiUploads] = useMMKVBoolean("onlyWifiUploads:" + userId, storage)

    const generateItemsForItemList = useCallback((items, range, lang = "en") => {
        range = normalizePhotosRange(range)
    
        if(range == "all"){
            return items
        }
    
        let sortedItems = []
    
        if(range == "years"){
            const occupied = {}
    
            for(let i = 0; i < items.length; i++){
                const itemDate = new Date(items[i].lastModified * 1000)
                const itemYear = itemDate.getFullYear()
                const occKey = itemYear
    
                if(typeof occupied[occKey] == "undefined"){
                    occupied[occKey] = {
                        ...items[i],
                        title: itemYear,
                        remainingItems: 0,
                        including: []
                    }
                }
    
                occupied[occKey].remainingItems = occupied[occKey].remainingItems + 1
                occupied[occKey].including.push(items[i].uuid)
            }
    
            for(let prop in occupied){
                sortedItems.push(occupied[prop])
            }
    
            sortedItems = sortedItems.reverse()
        }
        else if(range == "months"){
            const occupied = {}
    
            for(let i = 0; i < items.length; i++){
                const itemDate = new Date(items[i].lastModified * 1000)
                const itemYear = itemDate.getFullYear()
                const itemMonth = itemDate.getMonth()
                const occKey = itemYear + ":" + itemMonth
    
                if(typeof occupied[occKey] == "undefined"){
                    occupied[occKey] = {
                        ...items[i],
                        title: i18n(lang, "month_" + itemMonth) + " " + itemYear,
                        remainingItems: 0,
                        including: []
                    }
                }
    
                occupied[occKey].remainingItems = occupied[occKey].remainingItems + 1
                occupied[occKey].including.push(items[i].uuid)
            }
    
            for(let prop in occupied){
                sortedItems.push(occupied[prop])
            }
        }
        else if(range == "days"){
            const occupied = {}
    
            for(let i = 0; i < items.length; i++){
                const itemDate = new Date(items[i].lastModified * 1000)
                const itemYear = itemDate.getFullYear()
                const itemMonth = itemDate.getMonth()
                const itemDay = itemDate.getDate()
                const occKey = itemYear + ":" + itemMonth + ":" + itemDay
    
                if(typeof occupied[occKey] == "undefined"){
                    occupied[occKey] = {
                        ...items[i],
                        title: itemDay + ". " + i18n(lang, "monthShort_" + itemMonth) + " " + itemYear,
                        remainingItems: 0,
                        including: []
                    }
                }
    
                occupied[occKey].remainingItems = occupied[occKey].remainingItems + 1
                occupied[occKey].including.push(items[i].uuid)
            }
    
            for(let prop in occupied){
                sortedItems.push(occupied[prop])
            }
        }
        
        return sortedItems
    }, [items, photosRange, lang])

    const getThumbnail = useCallback(({ item }) => {
        if(item.type == "file"){
            if(canCompressThumbnail(getFileExt(item.name))){
                if(typeof item.thumbnail !== "string"){
                    DeviceEventEmitter.emit("event", {
                        type: "generate-thumbnail",
                        item
                    })
                }
                else{
                    //DeviceEventEmitter.emit("event", {
                    //    type: "check-thumbnail",
                    //    item
                    //})
                }
            }
        }
    })

    const onViewableItemsChangedRef = useRef(useCallback(({ viewableItems }) => {
        if(typeof viewableItems[0] == "object"){
            if(typeof viewableItems[0].index == "number"){
                setScrollIndex(viewableItems[0].index >= 0 ? viewableItems[0].index : 0)
            }
        }

        const visible = {}

        for(let i = 0; i < viewableItems.length; i++){
            let item = viewableItems[i].item

            visible[item.uuid] = true
            global.visibleItems[item.uuid] = true

            getThumbnail({ item })
        }

        if(typeof viewableItems[0] == "object" && typeof viewableItems[viewableItems.length - 1] == "object" && routeURL.indexOf("photos") !== -1){
            setScrollDate(calcCameraUploadCurrentDate(viewableItems[0].item.lastModified, viewableItems[viewableItems.length - 1].item.lastModified, lang))
        }

        for(let prop in global.visibleItems){
            if(typeof visible[prop] !== "undefined"){
                global.visibleItems[prop] = true
            }
            else{
                delete global.visibleItems[prop]
            }
        }
    }))

    const viewabilityConfigRef = useRef({
        minimumViewTime: 0,
        viewAreaCoveragePercentThreshold: 0
    })

    const photosRangeItemClick = useCallback((item) => {
        const currentRangeSelection = normalizePhotosRange(photosRange)
        let nextRangeSelection = "all"

        if(currentRangeSelection == "years"){
            nextRangeSelection = "months"
        }
        else if(currentRangeSelection == "months"){
            nextRangeSelection = "days"
        }
        else if(currentRangeSelection == "days"){
            nextRangeSelection = "all"
        }
        else{
            nextRangeSelection = "all"
        }

        const itemsForIndexLoop = generateItemsForItemList(items, nextRangeSelection, lang)
        let scrollToIndex = 0

        for(let i = 0; i < itemsForIndexLoop.length; i++){
            if(nextRangeSelection == "all"){
                if(itemsForIndexLoop[i].uuid == item.uuid){
                    scrollToIndex = i
                }
            }
            else{
                if(itemsForIndexLoop[i].including.includes(item.uuid)){
                    scrollToIndex = i
                }
            }
        }

        setScrollIndex(scrollToIndex >= 0 && scrollToIndex <= itemsForIndexLoop.length ? scrollToIndex : 0)
        setPhotosRange(nextRangeSelection)
    })

    const getInitialScrollIndex = useCallback(() => {
        const range = normalizePhotosRange(photosRange)
        const gridSize = calcPhotosGridSize(photosGridSize)
        const viewMode = routeURL.indexOf("photos") !== -1 ? "photos" : itemViewMode
        const itemsLength = currentItems.length > 0 ? currentItems.length : items.length

        if(viewMode == "list"){
            return scrollIndex >= 0 && scrollIndex <= itemsLength ? scrollIndex : 0
        }

        if(range == "all"){
            const calcedIndex = Math.floor(scrollIndex / gridSize)

            return calcedIndex >= 0 && calcedIndex <= itemsLength ? calcedIndex : 0
        }
        else{
            return scrollIndex >= 0 && scrollIndex <= itemsLength ? scrollIndex : 0
        }
    })

    const renderItem = useCallback(({ item, index, viewMode }) => {
        if(viewMode == "photos"){
            if(normalizePhotosRange(photosRange) !== "all"){
                return (
                    <PhotosRangeItem item={item} index={index} darkMode={darkMode} selected={item.selected} thumbnail={item.thumbnail} name={item.name} size={item.size} color={item.color} favorited={item.favorited} offline={item.offline} photosGridSize={photosGridSize} hideFileNames={hideFileNames} hideThumbnails={hideThumbnails} lang={lang} dimensions={dimensions} hideSizes={hideSizes} photosRange={normalizePhotosRange(photosRange)} photosRangeItemClick={photosRangeItemClick} insets={insets} />
                )
            }

            return (
                <PhotosItem item={item} index={index} darkMode={darkMode} selected={item.selected} thumbnail={item.thumbnail} name={item.name} size={item.size} color={item.color} favorited={item.favorited} offline={item.offline} photosGridSize={photosGridSize} hideFileNames={hideFileNames} hideThumbnails={hideThumbnails} lang={lang} dimensions={dimensions} hideSizes={hideSizes} insets={insets} />
            )
        }

        if(viewMode == "grid"){
            return (
                <GridItem item={item} index={index} darkMode={darkMode} selected={item.selected} thumbnail={item.thumbnail} name={item.name} size={item.size} color={item.color} favorited={item.favorited} offline={item.offline} hideFileNames={hideFileNames} hideThumbnails={hideThumbnails} lang={lang} dimensions={dimensions} hideSizes={hideSizes} insets={insets} />
            )
        }

        return (
            <ListItem item={item} index={index} darkMode={darkMode} selected={item.selected} thumbnail={item.thumbnail} name={item.name} size={item.size} color={item.color} favorited={item.favorited} offline={item.offline} hideFileNames={hideFileNames} hideThumbnails={hideThumbnails} lang={lang} dimensions={dimensions} hideSizes={hideSizes} insets={insets} />
        )
    })

    useEffect(() => {
        setCurrentItems(generateItemsForItemList(items, normalizePhotosRange(photosRange), lang))
    }, [items, photosRange, lang])

    useEffect(() => {
        if(items.length > 0){
            const max = 32

            for(let i = 0; i < items.length; i++){
                if(i < max){
                    global.visibleItems[items[i].uuid] = true

                    getThumbnail({ item: items[i] })
                }
            }
        }
    }, [items, itemViewMode])

    useEffect(() => {
        if(calcPhotosGridSize(photosGridSize) >= 6){
            DeviceEventEmitter.emit("event", {
                type: "unselect-all-items"
            })
        }
    }, [photosGridSize])

    useEffect(() => {
        items.forEach(item => {
            if(item.type == "folder"){
                getFolderSizeFromCache({ folder: item, routeURL, load: true })
            }
        })
    }, [items])

    return (
        <View style={{
            width: "100%",
            height: "100%",
            paddingLeft: itemViewMode == "grid" && routeURL.indexOf("photos") == -1 ? 15 : 0,
            paddingRight: itemViewMode == "grid" && routeURL.indexOf("photos") == -1 ? 15 : 0
        }}>
            {
                routeURL.indexOf("photos") !== -1 && (
                    <>
                        <View style={{
                            paddingBottom: 10,
                            paddingTop: 5,
                            borderBottomColor: darkMode ? "#111111" : "gray",
                            //borderBottomWidth: items.length > 0 ? 0 : 1,
                            borderBottomWidth: 0,
                            marginBottom: 3,
                            height: 35
                        }}>
                            {
                                cameraUploadEnabled ? (
                                    <View style={{
                                        flexDirection: "row",
                                        justifyContent: "flex-start",
                                        paddingLeft: 15,
                                        paddingRight: 15
                                    }}>
                                        {
                                            netInfo.isConnected && netInfo.isInternetReachable ? onlyWifiUploads && netInfo.type !== "wifi" ? (
                                                <>
                                                    <Ionicon name="wifi-outline" size={20} color={"gray"} />
                                                    <Text style={{
                                                        marginLeft: 10,
                                                        color: "gray",
                                                        paddingTop: Platform.OS == "ios" ? 2 : 1
                                                    }}>
                                                        {i18n(lang, "onlyWifiUploads")}
                                                    </Text>
                                                </>
                                            ) : cameraUploadTotal > 0 ? cameraUploadTotal > cameraUploadUploaded ? (
                                                <>
                                                    <ActivityIndicator color={darkMode ? "white" : "black"} size="small" />
                                                    <Text style={{
                                                        marginLeft: 10,
                                                        color: "gray",
                                                        paddingTop: Platform.OS == "ios" ? 2 : 1
                                                    }}>
                                                        {i18n(lang, "cameraUploadProgress", true, ["__TOTAL__", "__UPLOADED__"], [cameraUploadTotal, cameraUploadUploaded])}
                                                    </Text>
                                                </>
                                            ) : (
                                                <>
                                                    <Ionicon name="checkmark-done-circle-outline" size={20} color="green" />
                                                    <Text style={{
                                                        marginLeft: 10,
                                                        color: "gray",
                                                        paddingTop: Platform.OS == "ios" ? 2 : 1
                                                    }}>
                                                        {i18n(lang, "cameraUploadEverythingUploaded")}
                                                    </Text>
                                                </>
                                            ) : (
                                                <>
                                                    <ActivityIndicator color={darkMode ? "white" : "black"} size="small" />
                                                    <Text style={{
                                                        marginLeft: 10,
                                                        color: "gray",
                                                        paddingTop: Platform.OS == "ios" ? 2 : 1
                                                    }}>
                                                        {i18n(lang, "cameraUploadFetchingAssetsFromLocal")}
                                                    </Text>
                                                </>
                                            ) : (
                                                <>
                                                    <Ionicon name="wifi-outline" size={20} color={"gray"} />
                                                    <Text style={{
                                                        marginLeft: 10,
                                                        color: "gray",
                                                        paddingTop: Platform.OS == "ios" ? 2 : 1
                                                    }}>
                                                        {i18n(lang, "deviceOffline")}
                                                    </Text>
                                                </>
                                            )
                                        }
                                    </View>
                                ) : (
                                    <View style={{
                                        flexDirection: "row",
                                        justifyContent: "space-between",
                                        paddingLeft: 5,
                                        paddingRight: 15
                                    }}>
                                        <Text style={{
                                            marginLeft: 10,
                                            color: "gray"
                                        }}>
                                            {i18n(lang, "cameraUploadNotEnabled")}
                                        </Text>
                                        {
                                            netInfo.isConnected && netInfo.isInternetReachable && (
                                                <TouchableOpacity onPress={() => {
                                                    navigationAnimation({ enable: true }).then(() => {
                                                        navigation.dispatch(StackActions.push("CameraUploadScreen"))
                                                    })
                                                }}>
                                                    <Text style={{
                                                        color: "#0A84FF",
                                                        fontWeight: "bold"
                                                    }}>
                                                        {i18n(lang, "enable")}
                                                    </Text>
                                                </TouchableOpacity>
                                            )
                                        }
                                    </View>
                                )
                            }
                        </View>
                        {
                            scrollDate.length > 0 && items.length > 0 && normalizePhotosRange(photosRange) == "all" && (
                                <View style={{
                                    backgroundColor: darkMode ? "rgba(34, 34, 34, 0.6)" : "rgba(128, 128, 128, 0.6)",
                                    width: "auto",
                                    height: "auto",
                                    borderRadius: 15,
                                    position: "absolute",
                                    marginTop: 50,
                                    marginLeft: 15,
                                    zIndex: 100,
                                    paddingTop: 5,
                                    paddingBottom: 5,
                                    paddingLeft: 8,
                                    paddingRight: 8
                                }} pointerEvents="box-none">
                                    <Text style={{
                                        color: "white",
                                        fontSize: 15
                                    }}>{scrollDate}</Text>
                                </View>
                            )
                        }
                        {
                            items.length > 0 && (
                                <>
                                    {
                                        normalizePhotosRange(photosRange) == "all" && (
                                            <View style={{
                                                backgroundColor: darkMode ? "rgba(34, 34, 34, 0.6)" : "rgba(128, 128, 128, 0.6)",
                                                width: "auto",
                                                height: "auto",
                                                borderRadius: 15,
                                                position: "absolute",
                                                marginTop: 50,
                                                zIndex: 100,
                                                paddingTop: 5,
                                                paddingBottom: 5,
                                                paddingLeft: 8,
                                                paddingRight: 8,
                                                right: 15,
                                                flexDirection: "row"
                                            }}>
                                                <TouchableOpacity onPress={() => {
                                                    let gridSize = calcPhotosGridSize(photosGridSize)
                    
                                                    if(photosGridSize >= 10){
                                                        gridSize = 10
                                                    }
                                                    else{
                                                        gridSize = gridSize + 1
                                                    }
                    
                                                    setPhotosGridSize(gridSize)
                                                }}>
                                                    <Ionicon name="remove-outline" size={24} color={photosGridSize >= 10 ? "gray" : "white"} />
                                                </TouchableOpacity>
                                                <Text style={{
                                                    color: "gray",
                                                    fontSize: 17,
                                                    marginLeft: 5
                                                }}>|</Text>
                                                <TouchableOpacity style={{
                                                    marginLeft: 6
                                                }} onPress={() => {
                                                    let gridSize = calcPhotosGridSize(photosGridSize)
                    
                                                    if(photosGridSize <= 1){
                                                        gridSize = 1
                                                    }
                                                    else{
                                                        gridSize = gridSize - 1
                                                    }
                    
                                                    setPhotosGridSize(gridSize)
                                                }}>
                                                    <Ionicon name="add-outline" size={24} color={photosGridSize <= 1 ? "gray" : "white"} />
                                                </TouchableOpacity>
                                            </View>
                                        )
                                    }
                                    <View style={{
                                        backgroundColor: darkMode ? "rgba(34, 34, 34, 0.7)" : "rgba(128, 128, 128, 0.8)",
                                        width: "auto",
                                        height: "auto",
                                        borderRadius: 15,
                                        position: "absolute",
                                        zIndex: 100,
                                        alignSelf: "center",
                                        flexDirection: "row",
                                        bottom: 10,
                                        paddingTop: 3,
                                        paddingBottom: 3,
                                        paddingLeft: 3,
                                        paddingRight: 3
                                    }}>
                                        {
                                            ["years", "months", "days", "all"].map((key, index) => {
                                                return (
                                                    <TouchableOpacity key={index} style={{
                                                        backgroundColor: normalizePhotosRange(photosRange) == key ? darkMode ? "gray" : "darkgray" : "transparent",
                                                        width: "auto",
                                                        height: "auto",
                                                        paddingTop: 5,
                                                        paddingBottom: 5,
                                                        paddingLeft: 10,
                                                        paddingRight: 10,
                                                        borderRadius: 15,
                                                        marginLeft: index == 0 ? 0 : 10
                                                    }} onPress={() => {
                                                        DeviceEventEmitter.emit("event", {
                                                            type: "unselect-all-items"
                                                        })

                                                        setScrollIndex(0)
                                                        setPhotosRange(key)
                                                    }}>
                                                        <Text style={{
                                                            color: "white"
                                                        }}>
                                                            {i18n(lang, "photosRange_" + key)}
                                                        </Text>
                                                    </TouchableOpacity>
                                                )
                                            })
                                        }
                                    </View>
                                </>
                            )
                        }
                    </>
                )
            }
            <FlatList
                data={generateItemsForItemList(items, normalizePhotosRange(photosRange), lang)}
                key={routeURL.indexOf("photos") !== -1 ? "photos:" + (normalizePhotosRange(photosRange) == "all" ? calcPhotosGridSize(photosGridSize) : normalizePhotosRange(photosRange)) : itemViewMode == "grid" ? "grid" : "list"}
                renderItem={({ item, index }) => {
                    return renderItem({ item, index, viewMode: routeURL.indexOf("photos") !== -1 ? "photos" : itemViewMode })
                }}
                keyExtractor={(item, index) => index.toString()}
                windowSize={8}
                initialNumToRender={32}
                ref={itemListRef}
                removeClippedSubviews={true}
                initialScrollIndex={(currentItems.length > 0 ? currentItems.length : generateItemsForItemList(items, normalizePhotosRange(photosRange), lang).length) > 0 ? getInitialScrollIndex() : undefined}
                numColumns={routeURL.indexOf("photos") !== -1 ? (normalizePhotosRange(photosRange) == "all" ? calcPhotosGridSize(photosGridSize) : 1) : itemViewMode == "grid" ? 2 : 1}
                getItemLayout={(data, index) => ({
                    length: (routeURL.indexOf("photos") !== -1 ? (photosRange == "all" ? (Math.floor(dimensions.window.width / calcPhotosGridSize(photosGridSize))) : (Math.floor((dimensions.window.width - (insets.left + insets.right)) - 1.5))) : (itemViewMode == "grid" ? (Math.floor((dimensions.window.width - (insets.left + insets.right)) / 2) - 19 + 40) : (55))),
                    offset: (routeURL.indexOf("photos") !== -1 ? (photosRange == "all" ? (Math.floor(dimensions.window.width / calcPhotosGridSize(photosGridSize))) : (Math.floor((dimensions.window.width - (insets.left + insets.right)) - 1.5))) : (itemViewMode == "grid" ? (Math.floor((dimensions.window.width - (insets.left + insets.right)) / 2) - 19 + 40) : (55))) * index,
                    index
                })}
                ListEmptyComponent={() => {
                    return (
                        <View style={{
                            width: "100%",
                            height: Math.floor(dimensions.screen.height - 250),
                            justifyContent: "center",
                            alignItems: "center",
                            alignContent: "center"
                        }}>
                            {
                                !loadDone ? (
                                    <View>
                                        <ActivityIndicator color={darkMode ? "white" : "black"} size="small" />
                                    </View>
                                ) : (
                                    <ListEmpty route={route} searchTerm={searchTerm} />
                                )
                            }
                        </View>
                    )
                }}
                refreshControl={
                    <RefreshControl
                        refreshing={refreshing}
                        onRefresh={async () => {
                            if(!loadDone){
                                return false
                            }

                            setRefreshing(true)
        
                            if(typeof fetchItemList == "function"){
                                try{
                                    await new Promise((resolve) => setTimeout(resolve, 500))
                                    await fetchItemList({ bypassCache: true, callStack: 1, loadFolderSizes: true })
                                }
                                catch(e){
                                    console.log(e)
                                }

                                setTimeout(() => {
                                    if(items.length > 0){
                                        items.forEach(item => {
                                            if(item.type == "folder"){
                                                getFolderSizeFromCache({ folder: item, routeURL, load: true })
                                            }
                                        })
                                    }
                                }, 250)

                                setRefreshing(false)
                            }
                        }}
                        tintColor={darkMode ? "white" : "black"}
                        size="default"
                    />
                }
                style={{
                    height: "100%",
                    width: "100%"
                }}
                onViewableItemsChanged={onViewableItemsChangedRef.current}
                viewabilityConfig={viewabilityConfigRef.current}
            />
        </View>
    )
})
Example #23
Source File: LoginScreen.js    From WhatsApp-Clone with MIT License 4 votes vote down vote up
LoginScreen = ({navigation}) => {
  const [userName, setUserName] = useState('');
  const [mobile, setMobile] = useState('');
  const [isLoading, setLoading] = useState(false);

  useEffect(() => {
    getLocalData(constants.USER_ID)
      .then(userID => {
        console.log('Login userID => ', userID);
        if (userID && userID != null && userID != '') {
          navigation.dispatch(StackActions.replace(NAV_TYPES.HOME_SCREEN));
        }
      })
      .catch(err => {
        console.log('Login Error => ', err);
      });
  }, []);

  const onLoginClick = () => {
    if (userName === '') {
      showToast({text: 'Enter your Name', type: 'danger'});
    } else if (mobile === '') {
      showToast({text: 'Enter your Mobile Number', type: 'danger'});
    } else {
      setLoading(!isLoading);
      loginUser(getLoginModel(userName, mobile))
        .then(res => {
          console.log('LOGIN RESPONSE => ' + JSON.stringify(res));
          if (res.data.success) {
            setLoading(isLoading);
            console.log('TOKEN : ', res.headers.token);
            setUserName('');
            setMobile('');
            console.log('LOGIN RESPONSE => ' + JSON.stringify(res));

            storeLocalData(constants.ACCESS_TOKEN, res.headers.token);
            storeLocalData(constants.USER_ID, res.data.id);
            storeLocalData(constants.USER_NAME, userName);

            navigation.navigate(NAV_TYPES.HOME_SCREEN, {});
          }
        })
        .catch(error => {
          console.log('LOGIN ERROR ', error);
        });
    }
  };

  const onSignUpClick = () => {
    navigation.navigate(NAV_TYPES.REGISTER, {});
  };

  return (
    <SafeAreaView style={container}>
      {isLoading && <LoadingComponent />}
      {/* {!isLoading && ( */}
      <Root style={[container, {flexDirection: 'column'}]}>
        <KeyboardAvoidingView
          behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
          style={styles.keyboardView}>
          <View style={styles.headerView}>
            <Icon type="FontAwesome" name="whatsapp" style={styles.logoStyle} />
            <_Text style={styles.logoTextStyle}>{constants.APP_NAME}</_Text>
          </View>
          <ScrollView
            keyboardShouldPersistTaps="handled"
            contentContainerStyle={{
              flex: 1,
              justifyContent: 'center',
            }}>
            <View style={styles.contentView}>
              <View style={{flexDirection: 'column'}}>
                <_Text description style={[poppinsRegular, styles.labelStyle]}>
                  Enter Name
                </_Text>

                <_TextInput
                  value={userName}
                  inputStyle={[poppinsMedium, styles.inputStyle]}
                  floatingLabel={false}
                  keyboardType={'default'}
                  containerStyle={{width: '100%', marginLeft: 0}}
                  onChangeText={data => {
                    setUserName(data.value);
                  }}
                />

                <_Text description style={[poppinsRegular, styles.labelStyle]}>
                  Mobile Number
                </_Text>

                <_TextInput
                  value={mobile}
                  inputStyle={[poppinsMedium, styles.inputStyle]}
                  floatingLabel={false}
                  keyboardType={'numeric'}
                  containerStyle={{width: '100%', marginLeft: 0}}
                  onChangeText={data => {
                    setMobile(data.value);
                  }}
                />
              </View>

              <View style={styles.buttonLoginView}>
                <Button onPress={() => onLoginClick()} style={styles.login}>
                  <Text style={{fontSize: 18, fontWeight: 'bold'}}>Login</Text>
                </Button>
                <BorderlessButton
                  onPress={() => onSignUpClick()}
                  style={styles.buttonSignupView}>
                  <Text style={styles.signup}>Sign Up</Text>
                </BorderlessButton>
              </View>
            </View>
          </ScrollView>
        </KeyboardAvoidingView>
      </Root>
      {/* )} */}
    </SafeAreaView>
  );
}
Example #24
Source File: RegisterScreen.js    From WhatsApp-Clone with MIT License 4 votes vote down vote up
RegisterScreen = ({navigation}) => {
  const [countryCode, setCountryCode] = useState('');
  const [country, setCountry] = useState('');
  const [userName, setUserName] = useState('');
  const [mobile, setMobile] = useState('');
  const [isLoading, setLoading] = useState(false);

  useEffect(() => {
    getLocalData(constants.USER_ID)
      .then(userID => {
        console.log('Login userID => ', userID);
        if (userID && userID != null && userID != '') {
          navigation.dispatch(StackActions.replace(NAV_TYPES.HOME_SCREEN));
        }
      })
      .catch(err => {
        console.log('Login Error => ', err);
      });
  }, []);

  const onSelect = country => {
    console.log(country);
    setCountryCode(country.cca2);
    setCountry(country);
  };

  const onSignUpClick = () => {
    if (country === '') {
      showToast({text: 'Select your Country', type: 'danger'});
    } else if (userName === '') {
      showToast({text: 'Enter your Name', type: 'danger'});
    } else if (mobile === '') {
      showToast({text: 'Enter your Mobile Number', type: 'danger'});
    } else {
      setLoading(!isLoading);
      loginUser(getLoginModel(userName, mobile))
        .then(res => {
          setLoading(isLoading);
          console.log('TOKEN : ', res.headers.token);
          setUserName('');
          setMobile('');
          console.log('LOGIN RESPONSE => ' + JSON.stringify(res));

          if (res.data.success) {
            storeLocalData(constants.ACCESS_TOKEN, res.headers.token);
            storeLocalData(constants.USER_ID, res.data.id);
            storeLocalData(constants.USER_NAME, userName);

            navigation.navigate(NAV_TYPES.HOME_SCREEN, {});
          }
        })
        .catch(error => {
          console.log('LOGIN ERROR ', error);
        });
    }
  };

  const onLoginClick = () => {
    navigation && navigation.goBack();
  };

  return (
    <SafeAreaView style={container}>
      {isLoading && <LoadingComponent />}
      {/* {!isLoading && ( */}
      <Root style={[container, {flexDirection: 'column'}]}>
        <KeyboardAvoidingView
          behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
          style={styles.keyboardView}>
          <View style={styles.headerView}>
            <Icon type="FontAwesome" name="whatsapp" style={styles.logoStyle} />
            <_Text style={styles.logoTextStyle}>{constants.APP_NAME}</_Text>
          </View>
          <ScrollView
            keyboardShouldPersistTaps="handled"
            contentContainerStyle={{
              flex: 1,
              justifyContent: 'center',
            }}>
            <View style={styles.contentView}>
              <_Text description style={[poppinsRegular, styles.inputStyle]}>
                Country
              </_Text>
              <View style={{flexDirection: 'column'}}>
                {/* <_TextInput editable={true} style={{width:'20%'}} /> */}
                <CountryPicker
                  containerButtonStyle={{
                    height: 40,
                    marginTop: 5,
                    justifyContent: 'center',
                  }}
                  countryCode={countryCode}
                  withCountryNameButton={true}
                  visible={false}
                  withFlag={true}
                  withCloseButton={true}
                  withAlphaFilter={true}
                  withCallingCode={true}
                  //   withCurrency={true}
                  withEmoji={true}
                  withCountryNameButton={true}
                  //   withCurrencyButton={true}
                  //   withCallingCodeButton={true}
                  withFilter={true}
                  withModal={true}
                  onSelect={onSelect}
                />
                <View style={{height: '3%', backgroundColor: GREEN}} />
              </View>

              <View style={{flexDirection: 'column', marginTop: '-4%'}}>
                <_Text description style={[poppinsRegular, styles.labelStyle]}>
                  Enter Name
                </_Text>

                <_TextInput
                  value={userName}
                  inputStyle={[poppinsMedium, styles.inputStyle]}
                  floatingLabel={false}
                  keyboardType={'default'}
                  containerStyle={{width: '100%', marginLeft: 0}}
                  onChangeText={data => {
                    setUserName(data.value);
                  }}
                />

                <_Text description style={[poppinsRegular, styles.labelStyle]}>
                  Mobile Number
                </_Text>

                <_TextInput
                  value={mobile}
                  inputStyle={[poppinsMedium, styles.inputStyle]}
                  floatingLabel={false}
                  keyboardType={'numeric'}
                  containerStyle={{width: '100%', marginLeft: 0}}
                  onChangeText={data => {
                    setMobile(data.value);
                  }}
                />
              </View>

              <View style={styles.buttonLoginView}>
                <Button onPress={() => onSignUpClick()} style={styles.login}>
                  <Text style={{fontSize: 18, fontWeight: 'bold'}}>
                    Sign Up
                  </Text>
                </Button>
                <BorderlessButton
                  onPress={() => onLoginClick()}
                  style={styles.buttonSignupView}>
                  <Text style={styles.signup}>Login</Text>
                </BorderlessButton>
              </View>
            </View>
          </ScrollView> 
        </KeyboardAvoidingView>
      </Root>
    </SafeAreaView>
  );
}
Example #25
Source File: CameraUploadScreen.js    From filen-mobile with GNU Affero General Public License v3.0 4 votes vote down vote up
CameraUploadScreen = memo(({ navigation, route }) => {
    const [darkMode, setDarkMode] = useMMKVBoolean("darkMode", storage)
    const [lang, setLang] = useMMKVString("lang", storage)
    const [userId, setUserId] = useMMKVNumber("userId", storage)
    const [cameraUploadEnabled, setCameraUploadEnabled] = useMMKVBoolean("cameraUploadEnabled:" + userId, storage)
    const [cameraUploadIncludeImages, setCameraUploadIncludeImages] = useMMKVBoolean("cameraUploadIncludeImages:" + userId, storage)
    const [cameraUploadIncludeVideos, setCameraUploadIncludeVideos] = useMMKVBoolean("cameraUploadIncludeVideos:" + userId, storage)
    const [cameraUploadFolderUUID, setCameraUploadFolderUUID] = useMMKVString("cameraUploadFolderUUID:" + userId, storage)
    const [cameraUploadFolderName, setCameraUploadFolderName] = useMMKVString("cameraUploadFolderName:" + userId, storage)
    const [hasPermissions, setHasPermissions] = useState(false)

    const chooseFolder = useCallback(() => {
        navigationAnimation({ enable: true }).then(() => {
            showToast({ type: "cameraUploadChooseFolder", message: i18n(lang, "cameraUploadChooseFolder"), navigation })

            navigation.dispatch(StackActions.push("MainScreen", {
                parent: storage.getBoolean("defaultDriveOnly:" + userId) ? storage.getString("defaultDriveUUID:" + userId) : "base"
            }))
        })
    })

    useEffect(() => {
        hasStoragePermissions().then(() => {
            hasPhotoLibraryPermissions().then(() => {
                setHasPermissions(true)
            }).catch((err) => {
                setHasPermissions(false)

                console.log(err)
            })
        }).catch((err) => {
            setHasPermissions(false)

            console.log(err)
        })
    }, [])

    return (
        <>
            <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, "cameraUpload")}
                </Text>
            </View>
            <ScrollView style={{
                height: "100%",
                width: "100%",
                backgroundColor: darkMode ? "black" : "white"
            }}>
                <SettingsGroup>
                    <SettingsButton title={i18n(lang, "enabled")} rightComponent={
                        <Switch
                            trackColor={getColor(darkMode, "switchTrackColor")}
                            thumbColor={cameraUploadEnabled ? getColor(darkMode, "switchThumbColorEnabled") : getColor(darkMode, "switchThumbColorDisabled")}
                            ios_backgroundColor={getColor(darkMode, "switchIOSBackgroundColor")}
                            disabled={!hasPermissions}
                            onValueChange={() => {
                                const newValue = !cameraUploadEnabled

                                if(newValue){
                                    if(typeof cameraUploadFolderUUID !== "string"){
                                        setCameraUploadEnabled(false)
                                        chooseFolder()

                                        return false
                                    }
                                }

                                if(newValue){
                                    setCameraUploadIncludeImages(true)
                                }

                                setCameraUploadEnabled(newValue)
                            }}
                            value={cameraUploadEnabled}
                        />
                    } />
                </SettingsGroup>
                {
                    !hasPermissions && (
                        <Text style={{
                            color: "gray",
                            fontSize: 11,
                            paddingLeft: 17,
                            paddingTop: 5,
                            paddingRight: 17
                        }}>
                            {i18n(lang, "pleaseGrantPermission")}
                        </Text>
                    )
                }
                <SettingsGroup>
                    {
                        cameraUploadEnabled ? (
                            <SettingsButton title={i18n(lang, "cameraUploadFolder")} rightComponent={
                                <Text style={{
                                    color: "gray",
                                    paddingTop: 3,
                                    paddingRight: 10,
                                    fontSize: 13
                                }}>
                                    {cameraUploadFolderName}
                                </Text>
                            } />
                        ) : (
                            <SettingsButtonLinkHighlight rightText={typeof cameraUploadFolderUUID == "string" && cameraUploadFolderUUID.length > 16 ? cameraUploadFolderName : i18n(lang, "cameraUploadChooseFolder")} onPress={() => {
                                chooseFolder()
                            }} title={i18n(lang, "cameraUploadFolder")} />
                        )
                    }
                    <SettingsButton title={i18n(lang, "cameraUploadIncludeImages")} rightComponent={
                        <Switch
                            trackColor={getColor(darkMode, "switchTrackColor")}
                            thumbColor={cameraUploadIncludeImages ? getColor(darkMode, "switchThumbColorEnabled") : getColor(darkMode, "switchThumbColorDisabled")}
                            ios_backgroundColor={getColor(darkMode, "switchIOSBackgroundColor")}
                            onValueChange={() => setCameraUploadIncludeImages(!cameraUploadIncludeImages)}
                            value={cameraUploadIncludeImages}
                        />
                    } />
                    <SettingsButton title={i18n(lang, "cameraUploadIncludeVideos")} rightComponent={
                        <Switch
                            trackColor={getColor(darkMode, "switchTrackColor")}
                            thumbColor={cameraUploadIncludeVideos ? getColor(darkMode, "switchThumbColorEnabled") : getColor(darkMode, "switchThumbColorDisabled")}
                            ios_backgroundColor={getColor(darkMode, "switchIOSBackgroundColor")}
                            onValueChange={() => setCameraUploadIncludeVideos(!cameraUploadIncludeVideos)}
                            value={cameraUploadIncludeVideos}
                        />
                    } />
                </SettingsGroup>
                <SettingsGroup>
                    <SettingsButtonLinkHighlight title={i18n(lang, "cameraUploadReset")} onPress={() => {
                        Alert.alert(i18n(lang, "cameraUploadReset"), i18n(lang, "cameraUploadResetInfo"), [
                            {
                                text: i18n(lang, "cancel"),
                                onPress: () => {
                                    return false
                                },
                                style: "cancel"
                            },
                            {
                                text: i18n(lang, "ok"),
                                onPress: () => {
                                    Alert.alert(i18n(lang, "cameraUploadReset"), i18n(lang, "areYouReallySure"), [
                                        {
                                            text: i18n(lang, "cancel"),
                                            onPress: () => {
                                                return false
                                            },
                                            style: "cancel"
                                        },
                                        {
                                            text: i18n(lang, "ok"),
                                            onPress: () => {
                                                try{
                                                    storage.delete("cameraUploadUploadedIds:" + userId)
                                                }
                                                catch(e){
                                                    console.log(e)
                                                }
            
                                                return true
                                            },
                                            style: "default"
                                        }
                                    ], {
                                        cancelable: true
                                    })
                                },
                                style: "default"
                            }
                        ], {
                            cancelable: true
                        })
                    }} />
                </SettingsGroup>
                <View style={{ height: 25 }}></View>
            </ScrollView>
        </>
    )
})