@react-navigation/native#useIsFocused JavaScript Examples
The following examples show how to use
@react-navigation/native#useIsFocused.
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: TransitionView.js From actual with MIT License | 6 votes |
export default function TransitionView({ navigation, children }) {
let fadeAnim = useRef(new Animated.Value(1)).current;
let focused = useIsFocused();
let prevFocused = useRef(focused);
// A cheap effect to make up for the fact that we are using transparent cards,
// and the new native animator doesn't automatically fade out the previous
// card as it's going away (or coming in if going back). This works fine for
// navigating forwards, but less than ideal going backwards because it won't
// fade in until the gesture finishes. Need to look into how to perform custom
// gesture-based navigations
useEffect(() => {
if (prevFocused.current !== focused) {
Animated.timing(fadeAnim, {
toValue: focused ? 1 : 0,
duration: 200,
useNativeDriver: true
}).start();
}
}, [focused]);
useEffect(() => {
prevFocused.current = focused;
});
return (
<Animated.View style={{ flex: 1, opacity: fadeAnim }} children={children} />
);
}
Example #2
Source File: Header.js From monsuivipsy with Apache License 2.0 | 5 votes |
Header = ({ title, navigation }) => {
const needUpdate = useContext(NeedUpdateContext);
const [settingsVisible, setSettingsVisible] = useState(false);
const [drawerVisible, setDrawerVisible] = useState();
const [badge, setBadge] = useState(false);
const updateBadge = useCallback(async () => {
const news = await getBadgeNotesVersion();
const supported = await localStorage.getSupported();
const badgeProNPS = await localStorage.getVisitProNPS();
setBadge(needUpdate || news || (supported === "PRO" && !badgeProNPS));
}, [needUpdate]);
const isFocused = useIsFocused();
useEffect(() => {
if (isFocused) updateBadge();
}, [isFocused, updateBadge]);
return (
<View style={styles.container}>
<Settings visible={settingsVisible} navigation={navigation} onClick={() => setSettingsVisible(false)} />
<Drawer
visible={drawerVisible}
navigation={navigation}
onClick={() => {
updateBadge();
setDrawerVisible(false);
}}
/>
<Icon
color="#fff"
badge={badge}
icon="BurgerSvg"
width={20}
height={20}
onPress={() => setDrawerVisible(true)}
/>
<Text style={styles.title}>{title}</Text>
<Icon
color="#fff"
spin={settingsVisible}
icon="GearSvg"
width={25}
height={25}
onPress={() => setSettingsVisible(true)}
/>
</View>
);
}
Example #3
Source File: index.js From tcap-mobile with GNU General Public License v3.0 | 5 votes |
TransactionHistory = () =>{
const isFocused = useIsFocused();
const walletService = WalletService.getInstance();
const accAddress = walletUtils.createAddressFromPrivateKey(walletService.pk);
const [isLoading, setIsLoading] = useState(false);
const [list , setList] = useState([]);
const [refreshing,setRefreshing] = useState(false);
useEffect(()=>{
if(isFocused)
loadHistory();
},[isFocused]);
const onRefresh = () =>{
setRefreshing(true);
loadHistory();
setTimeout(()=>{setRefreshing(false);},500);
};
const loadHistory = () =>{
setIsLoading(true);
apiServices.getTransactionHistory(accAddress)
.then((data)=>{
setList(data);
setIsLoading(false);
})
.catch(()=>{
setIsLoading(false);
});
};
const renderEachItem = ({ index,item }) =>{
return <HistoryCard historyData={item} key={index} />;
};
return(
<View style={styles.container}>
<Text style={styles.titleBar_title}>Transaction Activities</Text>
<FlatList
data={list}
initialNumToRender={5}
keyExtractor={item=>item.txnId.toString()}
refreshControl={
<RefreshControl
onRefresh={onRefresh} refreshing={refreshing}
title="Refreshing History .."
titleColor={'#fff'} />
}
removeClippedSubviews={true}
renderItem = {renderEachItem}
showsVerticalScrollIndicator={false}
style={{flex:1,marginTop:moderateScale(20)}}
/>
<LoadingIndicator
message={'Please wait while fetching your transactions...'}
visible={isLoading}
/>
</View>
);
}
Example #4
Source File: Tabs.js From MediBuddy with MIT License | 5 votes |
function Tabs() {
const isFocused = useIsFocused();
const safeArea = useSafeArea();
let tabBarProps = {};
if (isTablet) {
tabBarProps = {
tabBar: props => <TabBar {...props} />,
};
}
return (
<React.Fragment>
<Tab.Navigator
initialRouteName="Feed"
shifting={true}
labeled={false}
sceneAnimationEnabled={false}
activeColor="#00aea2"
inactiveColor="#95a5a6"
barStyle={{ backgroundColor: '#ffff' }}
{...tabBarProps}>
<Tab.Screen
name="Appointments"
component={MyAppointments}
options={{
tabBarIcon: 'calendar-clock',
}}
/>
<Tab.Screen
name="Patients"
component={Patients}
options={{
tabBarIcon: 'account-multiple',
}}
/>
<Tab.Screen
name="Departments"
component={Departments}
options={{
tabBarIcon: 'layers',
}}
/>
<Tab.Screen
name="Reports"
component={Reports}
options={{
tabBarIcon: 'book-open',
}}
/>
</Tab.Navigator>
<Portal>
<FAB
visible={isFocused} // show FAB only when this screen is focused
icon="plus-box"
label={isTablet ? 'Create new' : null}
style={[
styles.fab,
{
bottom: safeArea.bottom + 65,
},
]}
/>
</Portal>
</React.Fragment>
);
}
Example #5
Source File: MainScreen.js From filen-mobile with GNU Affero General Public License v3.0 | 4 votes |
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 #6
Source File: Entry.js From universal-verifier-app with GNU General Public License v3.0 | 4 votes |
function Entry({ navigation }) {
const [cards, setCards] = useState([]);
const [filteredCards, setFilteredCards] = useState([]);
const [search, setSearch] = useState('');
const isFocused = useIsFocused();
const {colors, isDark} = useTheme();
const onNewVaccine = (e) => {
navigation.navigate('QRReader')
}
const actions = [{
text: "New Vaccine",
icon: <FontAwesome5 name={'syringe'} style={styles.icon} solid />,
name: "bt_vaccine",
position: 0
}
];
const filter = (cards, text) => {
if (text && text.length > 0) {
const lowerText = text.toLowerCase();
return cards.filter(function (item) {
return JSON.stringify(item).toLowerCase().includes(lowerText);
});
} else {
return cards;
}
}
const searchFilter = (text) => {
setFilteredCards(filter(cards, text));
setSearch(text);
}
const load = async () => {
let cards = await listCards();
setCards(cards);
setFilteredCards(filter(cards, search));
};
const removeItem = async (signature) => {
const remaining = await removeCard(signature);
setCards(remaining);
setFilteredCards(filter(remaining, search));
}
useEffect(() => {
changeNavigationBarColor(colors.background, !isDark);
load();
}, [isFocused]);
return (
<View style={styles.container} backgroundColor={colors.background}>
<StatusBar
backgroundColor={colors.background}
barStyle={isDark ? "light-content" : "dark-content"}/>
<SearchBar round lightTheme={!isDark}
containerStyle={{backgroundColor:colors.background,
borderBottomColor: colors.divisor,
borderTopColor: colors.background, paddingBottom: 4, paddingTop: 0}}
placeholder="Search Here..."
onChangeText={text => searchFilter(text)}
value={search}
inputContainerStyle={{marginLeft: 7, marginRight: 7, backgroundColor:colors.background}}
/>
<SafeAreaView style={styles.flatList}>
<View style={styles.border}>
<FlatList
data={filteredCards}
keyExtractor={item => item.signature}
contentContainerStyle={filteredCards.length == 0 && styles.centerEmptySet}
ListEmptyComponent={<NoCards colors={colors} />}
renderItem={({item}) => {
if (item.format === "CRED" && item.type === "BADGE")
return <View style={styles.listItem}><VaccineCard detail={item} colors={colors} navigation={navigation} removeItem={removeItem} pressable/></View>
if (item.format === "CRED" && item.type === "COUPON")
return <View style={styles.listItem}><CouponCard detail={item} colors={colors} navigation={navigation} removeItem={removeItem} pressable/></View>
if (item.format === "CRED" && item.type === "STATUS")
return <View style={styles.listItem}><StatusCard detail={item} colors={colors} navigation={navigation} removeItem={removeItem} pressable/></View>
if (item.format === "CRED" && item.type === "PASSKEY")
return <View style={styles.listItem}><PassKeyCard detail={item} colors={colors} navigation={navigation} removeItem={removeItem} pressable/></View>
if (item.format === "DIVOC" && item.type === "COWIN")
return <View style={styles.listItem}><CowinCard detail={item} colors={colors} navigation={navigation} removeItem={removeItem} pressable/></View>
if (item.format === "SHC" && item.type === "FHIRBundle")
return <View style={styles.listItem}><SHCCard detail={item} colors={colors} navigation={navigation} removeItem={removeItem} pressable/></View>
if (item.format === "DCC" && item.type === "DCC")
return <View style={styles.listItem}><DCCCard detail={item} colors={colors} navigation={navigation} removeItem={removeItem} pressable/></View>
if (item.format === "DCC" && item.type === "UY")
return <View style={styles.listItem}><DCCUYCard detail={item} colors={colors} navigation={navigation} removeItem={removeItem} pressable/></View>
if (item.format === "VDS" && item.type === "icao.vacc")
return <View style={styles.listItem}><VDSVaxCard detail={item} colors={colors} navigation={navigation} removeItem={removeItem} pressable/></View>
if (item.format === "VDS" && item.type === "icao.test")
return <View style={styles.listItem}><VDSTestCard detail={item} colors={colors} navigation={navigation} removeItem={removeItem} pressable/></View>
}} />
</View>
</SafeAreaView>
<FloatingAction
actions={actions}
overrideWithAction={true}
onPressItem={onNewVaccine}
/>
</View>
);
}
Example #7
Source File: Locked.js From universal-verifier-app with GNU General Public License v3.0 | 4 votes |
function Locked({ navigation, route }) {
const {authData, signIn} = useContext(AuthContext);
const isFocused = useIsFocused();
const {colors, isDark} = useTheme();
const [isTryingToSignIn, setIsTryingToSignIn] = useState(false);
const handleBiometricAuthFailure = async (error: string) => {
switch (error) {
case 'NOT_ENROLLED':
Alert.alert(
`Not Enrolled`,
'This device does not have biometric login enabled.',
);
break;
case 'NOT_PRESENT':
Alert.alert('', 'This device does not have the required hardware.');
return;
case 'AUTHENTICATION_FAILED':
Alert.alert('', 'Authentication failed too many times');
break;
case 'NOT_AVAILABLE':
Alert.alert('', 'Authentication is not available.');
break;
default:
}
};
const signInBiometricAuth = async () => {
if (isTryingToSignIn) {
await LocalAuthentication.cancelAuthenticate();
}
console.log("Logging in");
setIsTryingToSignIn(true);
const authenticateResult = await LocalAuthentication.authenticateAsync({
promptMessage: 'Login with Biometrics',
cancelLabel: 'Cancel',
disableDeviceFallback: true,
fallbackLabel: 'Use PIN'
});
console.log("Logged in", authenticateResult);
if (authenticateResult.success) {
signIn();
} else {
handleBiometricAuthFailure(authenticateResult);
}
setIsTryingToSignIn(false);
}
const unlock = async () => {
if (isTryingToSignIn) return;
if (!authData && !isTryingToSignIn && AppState.currentState === "active") {
signInBiometricAuth();
}
}
useEffect(() => {
changeNavigationBarColor(colors.background, !isDark);
}, [isFocused]);
return (
<View style={styles.container} backgroundColor={colors.background}>
<StatusBar
backgroundColor={colors.background}
barStyle={isDark ? "light-content" : "dark-content"}/>
<Image
style={styles.logo}
color={colors.primary}
source={{
uri: 'data:image/png;base64,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',
}}
/>
<Text>App Locked</Text>
<TouchableOpacity
style={[styles.button, {backgroundColor: colors.primary}]}
onPress={unlock}
hitSlop={{top: 20, bottom: 20, left: 20, right: 20}}
>
<Text style={[styles.buttonText, { color: '#fff'}]}>Unlock</Text>
</TouchableOpacity>
</View>
);
}
Example #8
Source File: Camera.js From InstagramClone with Apache License 2.0 | 4 votes |
export default function VideoScreen(props) {
const [hasPermission, setHasPermission] = useState(null);
const [cameraType, setCameraType] = useState(Camera.Constants.Type.back);
const [isPreview, setIsPreview] = useState(false);
const [isCameraReady, setIsCameraReady] = useState(false);
const [isFlash, setIsFlash] = useState(false);
const [isVideoRecording, setIsVideoRecording] = useState(false);
const [type, setType] = useState(0);
const [showGallery, setShowGallery] = useState(true)
const [galleryItems, setGalleryItems] = useState([])
const [galleryScrollRef, setGalleryScrollRef] = useState(null)
const [galleryPickedImage, setGalleryPickedImage] = useState(null)
const cameraRef = useRef();
const isFocused = useIsFocused();
useEffect(() => {
(async () => {
const cameraPermissions = await Camera.requestPermissionsAsync();
const galleryPermissions = await MediaLibrary.requestPermissionsAsync();
const audioPermissions = await Audio.requestPermissionsAsync();
if (cameraPermissions.status === 'granted' && audioPermissions.status === 'granted' && galleryPermissions.status === 'granted') {
const getPhotos = await MediaLibrary.getAssetsAsync({ sortBy: ['creationTime'], mediaType: ['photo', 'video'] })
setGalleryItems(getPhotos)
setGalleryPickedImage(getPhotos.assets[0])
setHasPermission(true)
}
})();
}, []);
const onCameraReady = () => {
setIsCameraReady(true);
};
const takePicture = async () => {
if (cameraRef.current) {
const options = { quality: 0.5, base64: true, skipProcessing: true };
const data = await cameraRef.current.takePictureAsync(options);
const source = data.uri;
if (source) {
props.navigation.navigate('Save', { source, imageSource: null, type })
}
}
};
const recordVideo = async () => {
if (cameraRef.current) {
try {
const options = { maxDuration: 60, quality: Camera.Constants.VideoQuality['480p'] }
const videoRecordPromise = cameraRef.current.recordAsync(options);
if (videoRecordPromise) {
setIsVideoRecording(true);
const data = await videoRecordPromise;
const source = data.uri;
let imageSource = await generateThumbnail(source)
props.navigation.navigate('Save', { source, imageSource, type })
}
} catch (error) {
console.warn(error);
}
}
};
const generateThumbnail = async (source) => {
try {
const { uri } = await VideoThumbnails.getThumbnailAsync(
source,
{
time: 5000,
}
);
return uri;
} catch (e) {
console.warn(e);
}
};
const stopVideoRecording = async () => {
if (cameraRef.current) {
setIsVideoRecording(false);
cameraRef.current.stopRecording();
}
};
const switchCamera = () => {
if (isPreview) {
return;
}
setCameraType((prevCameraType) =>
prevCameraType === Camera.Constants.Type.back
? Camera.Constants.Type.front
: Camera.Constants.Type.back
);
};
const handleGoToSaveOnGalleryPick = async () => {
let type = galleryPickedImage.mediaType == 'video' ? 0 : 1
const loadedAsset = await MediaLibrary.getAssetInfoAsync(galleryPickedImage);
let imageSource = null
if (type == 0) {
imageSource = await generateThumbnail(galleryPickedImage.uri)
}
props.navigation.navigate('Save', {
source: loadedAsset.localUri,
type,
imageSource
})
}
const renderCaptureControl = () => (
<View>
<View style={{ justifyContent: 'space-evenly', width: '100%', alignItems: 'center', flexDirection: 'row', backgroundColor: 'white' }}>
<TouchableOpacity disabled={!isCameraReady} onPress={() => setIsFlash(!isFlash)} >
<Feather style={utils.margin15} name={"zap"} size={25} color="black" />
</TouchableOpacity>
<TouchableOpacity disabled={!isCameraReady} onPress={switchCamera}>
<Feather style={utils.margin15} name="rotate-cw" size={25} color="black" />
</TouchableOpacity>
{type == 0 ?
<TouchableOpacity
activeOpacity={0.7}
disabled={!isCameraReady}
onLongPress={recordVideo}
onPressOut={stopVideoRecording}
style={styles.capture}
/>
:
<TouchableOpacity
activeOpacity={0.7}
disabled={!isCameraReady}
onPress={takePicture}
style={styles.capturePicture}
/>}
<TouchableOpacity disabled={!isCameraReady} onPress={() => type == 1 ? setType(0) : setType(1)} >
<Feather style={utils.margin15} name={type == 0 ? "camera" : "video"} size={25} color="black" />
</TouchableOpacity>
<TouchableOpacity onPress={() => setShowGallery(true)} >
<Feather style={utils.margin15} name={"image"} size={25} color="black" />
</TouchableOpacity>
</View>
</View>
);
if (hasPermission === null) {
return <View />;
}
if (hasPermission === false) {
return <Text style={styles.text}>No access to camera</Text>;
}
if (showGallery) {
return (
<ScrollView
ref={(ref) => setGalleryScrollRef(ref)}
style={[container.container, utils.backgroundWhite]}>
<View
style={[{ aspectRatio: 1 / 1, height: WINDOW_WIDTH }]}>
<Image
style={{ flex: 1 }}
source={{ uri: galleryPickedImage.uri }}
style={[{ aspectRatio: 1 / 1, height: WINDOW_WIDTH }]}
ratio={'1:1'}
/>
</View>
<View style={{ justifyContent: 'flex-end', alignItems: 'center', marginRight: 20, marginVertical: 10, flexDirection: 'row' }}>
<TouchableOpacity
style={{ alignItems: 'center', backgroundColor: 'gray', paddingHorizontal: 20, paddingVertical: 10, marginRight: 15, borderRadius: 50, borderWidth: 1, borderColor: 'black' }}
onPress={() => handleGoToSaveOnGalleryPick()} >
<Text style={{ fontWeight: 'bold', color: 'white', paddingBottom: 1 }}>Continue</Text>
</TouchableOpacity>
<TouchableOpacity style={{ alignItems: 'center', backgroundColor: 'gray', borderRadius: 50, borderWidth: 1, borderColor: 'black' }} onPress={() => setShowGallery(false)} >
<Feather style={{ padding: 10 }} name={"camera"} size={20} color="white" />
</TouchableOpacity>
</View>
<View style={{ flex: 1 }, [utils.borderTopGray]}>
<FlatList
numColumns={3}
horizontal={false}
data={galleryItems.assets}
contentContainerStyle={{
flexGrow: 1,
}}
renderItem={({ item }) => (
<TouchableOpacity
style={[container.containerImage, utils.borderWhite]}
onPress={() => { galleryScrollRef.scrollTo({ x: 0, y: 0, animated: true }); setGalleryPickedImage(item); }}>
<Image
style={container.image}
source={{ uri: item.uri }}
/>
</TouchableOpacity>
)}
/>
</View>
</ScrollView>
)
}
return (
<View style={{ flex: 1, flexDirection: 'column', backgroundColor: 'white' }}>
<View
style={[{ aspectRatio: 1 / 1, height: WINDOW_WIDTH }]}>
{isFocused ?
<Camera
ref={cameraRef}
style={{ flex: 1 }}
type={cameraType}
flashMode={isFlash ? Camera.Constants.FlashMode.torch : Camera.Constants.FlashMode.off}
style={[{ aspectRatio: 1 / 1, height: WINDOW_WIDTH }]}
ratio={'1:1'}
onCameraReady={onCameraReady}
/>
: null}
</View>
<View style={[{
flexDirection: 'row',
alignItems: 'center',
flex: 1,
}]}>
<View>
{renderCaptureControl()}
</View>
</View>
</View>
);
}
Example #9
Source File: Post.js From InstagramClone with Apache License 2.0 | 4 votes |
function Post(props) {
const [item, setItem] = useState(props.route.params.item)
const [user, setUser] = useState(props.route.params.user)
const [currentUserLike, setCurrentUserLike] = useState(false)
const [unmutted, setUnmutted] = useState(true)
const [videoref, setvideoref] = useState(null)
const [sheetRef, setSheetRef] = useState(useRef(null))
const [modalShow, setModalShow] = useState({ visible: false, item: null })
const [isValid, setIsValid] = useState(true);
const [exists, setExists] = useState(false);
const [loaded, setLoaded] = useState(false);
const isFocused = useIsFocused();
useEffect(() => {
if (props.route.params.notification != undefined) {
firebase.firestore()
.collection("users")
.doc(props.route.params.user)
.get()
.then((snapshot) => {
if (snapshot.exists) {
let user = snapshot.data();
user.uid = snapshot.id;
setUser(user)
}
})
firebase.firestore()
.collection("posts")
.doc(props.route.params.user)
.collection("userPosts")
.doc(props.route.params.item)
.get()
.then((snapshot) => {
if (snapshot.exists) {
let post = snapshot.data();
post.id = snapshot.id;
setItem(post)
setLoaded(true)
setExists(true)
}
})
firebase.firestore()
.collection("posts")
.doc(props.route.params.user)
.collection("userPosts")
.doc(props.route.params.item)
.collection("likes")
.doc(firebase.auth().currentUser.uid)
.onSnapshot((snapshot) => {
let currentUserLike = false;
if (snapshot.exists) {
currentUserLike = true;
}
setCurrentUserLike(currentUserLike)
})
}
else {
firebase.firestore()
.collection("posts")
.doc(props.route.params.user.uid)
.collection("userPosts")
.doc(props.route.params.item.id)
.collection("likes")
.doc(firebase.auth().currentUser.uid)
.onSnapshot((snapshot) => {
let currentUserLike = false;
if (snapshot.exists) {
currentUserLike = true;
}
setCurrentUserLike(currentUserLike)
})
setItem(props.route.params.item)
setUser(props.route.params.user)
setLoaded(true)
setExists(true)
}
}, [props.route.params.notification, props.route.params.item])
useEffect(() => {
if (videoref !== null) {
videoref.setIsMutedAsync(props.route.params.unmutted)
}
setUnmutted(props.route.params.unmutted)
}, [props.route.params.unmutted])
useEffect(() => {
if (videoref !== null) {
if (isFocused) {
videoref.playAsync()
} else {
videoref.stopAsync()
}
}
}, [props.route.params.index, props.route.params.inViewPort])
const onUsernamePress = (username, matchIndex) => {
props.navigation.navigate("ProfileOther", { username, uid: undefined })
}
const onLikePress = (userId, postId, item) => {
item.likesCount += 1;
setCurrentUserLike(true)
firebase.firestore()
.collection("posts")
.doc(userId)
.collection("userPosts")
.doc(postId)
.collection("likes")
.doc(firebase.auth().currentUser.uid)
.set({})
.then()
props.sendNotification(user.notificationToken, "New Like", `${props.currentUser.name} liked your post`, { type: 0, postId, user: firebase.auth().currentUser.uid })
}
const onDislikePress = (userId, postId, item) => {
item.likesCount -= 1;
setCurrentUserLike(false)
firebase.firestore()
.collection("posts")
.doc(userId)
.collection("userPosts")
.doc(postId)
.collection("likes")
.doc(firebase.auth().currentUser.uid)
.delete()
}
if (!exists && loaded) {
return (
<View style={{ height: '100%', justifyContent: 'center', margin: 'auto' }}>
<FontAwesome5 style={{ alignSelf: 'center', marginBottom: 20 }} name="dizzy" size={40} color="black" />
<Text style={[text.notAvailable]}>Post does not exist</Text>
</View>
)
}
if (!loaded) {
return (<View></View>)
}
if (user == undefined) {
return (<View></View>)
}
if (item == null) {
return (<View />)
}
const _handleVideoRef = (component) => {
setvideoref(component);
if (component !== null) {
component.setIsMutedAsync(props.route.params.unmutted)
}
}
if (videoref !== null) {
videoref.setIsMutedAsync(unmutted)
if (isFocused && props.route.params.index == props.route.params.inViewPort) {
videoref.playAsync()
} else {
videoref.stopAsync()
}
}
if (sheetRef.current !== null && !props.route.params.feed) {
if (modalShow.visible) {
sheetRef.snapTo(0)
} else {
sheetRef.snapTo(1)
}
}
return (
<View style={[container.container, utils.backgroundWhite]}>
<View>
<View style={[container.horizontal, { alignItems: 'center', padding: 10 }]}>
<TouchableOpacity
style={[container.horizontal, { alignItems: 'center' }]}
onPress={() => props.navigation.navigate("ProfileOther", { uid: user.uid, username: undefined })}>
{user.image == 'default' ?
(
<FontAwesome5
style={[utils.profileImageSmall]}
name="user-circle" size={35} color="black" />
)
:
(
<Image
style={[utils.profileImageSmall]}
source={{
uri: user.image
}}
/>
)
}
<View style={{ alignSelf: 'center' }}>
<Text style={[text.bold, text.medium, { marginBottom: 0 }]} >{user.name}</Text>
</View>
</TouchableOpacity>
<TouchableOpacity
style={[{ marginLeft: 'auto' }]}
onPress={() => {
if (props.route.params.feed) {
props.route.params.setModalShow({ visible: true, item })
} else {
setModalShow({ visible: true, item })
}
}}>
<Feather
name="more-vertical" size={20} color="black" />
</TouchableOpacity>
</View>
{item.type == 0 ?
<View>
{props.route.params.index == props.route.params.inViewPort && isFocused ?
<View>
<VideoPlayer
videoProps={{
isLooping: true,
shouldPlay: true,
resizeMode: Video.RESIZE_MODE_COVER,
source: {
uri: item.downloadURL,
},
videoRef: _handleVideoRef,
}}
inFullscreen={false}
showControlsOnLoad={true}
showFullscreenButton={false}
height={WINDOW_WIDTH}
width={WINDOW_WIDTH}
shouldPlay={true}
isLooping={true}
style={{
aspectRatio: 1 / 1, height: WINDOW_WIDTH,
width: WINDOW_WIDTH, backgroundColor: 'black'
}}
/>
<TouchableOpacity
style={{ position: 'absolute', borderRadius: 500, backgroundColor: 'black', width: 40, height: 40, alignItems: 'center', justifyContent: 'center', margin: 10, right: 0 }}
activeOpacity={1}
onPress={() => {
if (videoref == null) {
return;
}
if (unmutted) {
if (props.route.params.setUnmuttedMain == undefined) {
setUnmutted(false)
} else {
props.route.params.setUnmuttedMain(false)
}
} else {
if (props.route.params.setUnmuttedMain == undefined) {
setUnmutted(true)
} else {
props.route.params.setUnmuttedMain(true)
}
}
}}>
{!unmutted ?
<Feather name="volume-2" size={20} color="white" />
:
<Feather name="volume-x" size={20} color="white" />
}
</TouchableOpacity>
</View>
:
<View style={{ marginTop: 4 }}>
<CachedImage
cacheKey={item.id}
style={[container.image]}
source={{ uri: item.downloadURLStill }}
/>
</View>
}
</View>
:
<CachedImage
cacheKey={item.id}
style={container.image}
source={{ uri: item.downloadURL }}
/>
}
<View style={[utils.padding10, container.horizontal]}>
{currentUserLike ?
(
<Entypo name="heart" size={30} color="red" onPress={() => onDislikePress(user.uid, item.id, item)} />
)
:
(
<Feather name="heart" size={30} color="black" onPress={() => onLikePress(user.uid, item.id, item)} />
)
}
<Feather style={utils.margin15Left} name="message-square" size={30} color="black" onPress={() => props.navigation.navigate('Comment', { postId: item.id, uid: user.uid, user })} />
<Feather style={utils.margin15Left} name="share" size={26} color="black" onPress={() => props.navigation.navigate('ChatList', { postId: item.id, post: { ...item, user: user }, share: true })} />
</View>
<View style={[container.container, utils.padding10Sides]}>
<Text style={[text.bold, text.medium]}>
{item.likesCount} likes
</Text>
<Text style={[utils.margin15Right, utils.margin5Bottom]}>
<Text style={[text.bold]}
onPress={() => props.navigation.navigate("ProfileOther", { uid: user.uid, username: undefined })}>
{user.name}
</Text>
<Text> </Text>
<ParsedText
parse={
[
{ pattern: /@(\w+)/, style: { color: 'green', fontWeight: 'bold' }, onPress: onUsernamePress },
]
}
>{item.caption}</ParsedText>
</Text>
<Text
style={[text.grey, utils.margin5Bottom]} onPress={() => props.navigation.navigate('Comment', { postId: item.id, uid: user.uid, user })}>
View all {item.commentsCount} Comments
</Text>
<Text
style={[text.grey, text.small, utils.margin5Bottom]}>
{timeDifference(new Date(), item.creation.toDate())}
</Text>
</View>
</View>
<BottomSheet
bottomSheerColor="#FFFFFF"
ref={setSheetRef}
initialPosition={0} //200, 300
snapPoints={[300, 0]}
isBackDrop={true}
isBackDropDismissByPress={true}
isRoundBorderWithTipHeader={true}
backDropColor="black"
isModal
containerStyle={{ backgroundColor: "white" }}
tipStyle={{ backgroundColor: "white" }}
headerStyle={{ backgroundColor: "white", flex: 1 }}
bodyStyle={{ backgroundColor: "white", flex: 1, borderRadius: 20 }}
body={
<View>
{modalShow.item != null ?
<View>
<TouchableOpacity style={{ padding: 20 }}
onPress={() => {
props.navigation.navigate("ProfileOther", { uid: modalShow.item.user.uid, username: undefined });
setModalShow({ visible: false, item: null });
}}>
<Text >Profile</Text>
</TouchableOpacity>
<Divider />
{props.route.params.user.uid == firebase.auth().currentUser.uid ?
<TouchableOpacity style={{ padding: 20 }}
onPress={() => {
props.deletePost(modalShow.item).then(() => {
props.fetchUserPosts()
props.navigation.popToTop()
})
setModalShow({ visible: false, item: null });
}}>
<Text >Delete</Text>
</TouchableOpacity>
: null}
<Divider />
<TouchableOpacity style={{ padding: 20 }} onPress={() => setModalShow({ visible: false, item: null })}>
<Text >Cancel</Text>
</TouchableOpacity>
</View>
: null}
</View>
}
/>
<Snackbar
visible={isValid.boolSnack}
duration={2000}
onDismiss={() => { setIsValid({ boolSnack: false }) }}>
{isValid.message}
</Snackbar>
</View>
)
}
Example #10
Source File: index.js From tcap-mobile with GNU General Public License v3.0 | 4 votes |
TransferHomeScreen = ({...props}) =>{
const isFocused = useIsFocused();
const {
updateVerifiedAccountBalances,verifiedBalances,exchangeRates,navigation,
selectedCurrency,route,isAccountUnlockedFromServer,setIsAccountUnlocked,
accountDetails
} = props;
const {email,phoneNumber} = accountDetails;
const walletService = WalletService.getInstance();
const pk = walletService.pk;
const accAddress = walletUtils.createAddressFromPrivateKey(pk);
const [selectedAsset, setSelectedAsset] = useState(verifiedBalances[0]);
const [amountToTransfer, setAmountToTransfer] = useState('');
// testAddress (for testing)
// const testAddress = '0xD8f647855876549d2623f52126CE40D053a2ef6A';
const [address, setAddress] = useState('');
const [remarks , setRemarks] = useState('');
const [modal, setModal] = useState(false);
const [fee , setFee] = useState(0);
const [errorMessage, setErrorMessage] = useState('');
const [errorTitle, setErrorTitle] = useState('');
const [showError, setShowError] = useState(false);
const [loader, setLoader] = useState(true);
const [indicatingMssg , setIndicatingMsg] = useState('Please Wait...');
const [showTransactionUi , setShowTransactionUi] = useState(false);
useEffect(()=>{
if(verifiedBalances.length) setShowTransactionUi(true);
updateVerifiedAccountBalances(accAddress);
},[]);
useEffect(()=>{
if(isFocused)
{
const {scannedAddress} = route.params;
if(scannedAddress) setAddress(scannedAddress);
}
},[isFocused]);
useEffect(()=>{
if(verifiedBalances.length) {
setSelectedAsset(verifiedBalances[0]);
setTimeout(()=>{
setShowTransactionUi(true);
refreshAssets(verifiedBalances[0]);
},200);
}
else setLoader(false);
},[verifiedBalances.length]);
const checkAccountIsUnlocked = () =>{
if(isAccountUnlockedFromServer)
{
setLoader(false);
const data = { selectedAsset,address,remarks,fee,amountToTransfer};
navigation.navigate('TransferConfirmationScreen',{transactionData:data});
}
else
fallbackToBlockChain();
};
const fallbackToBlockChain = async() =>{
const isSigningKeySet = await walletService.unlockZksyncWallet(selectedAsset.symbol,true);
if(isSigningKeySet)
{
setIsAccountUnlocked(true);
apiServices.updateIsAccountUnlockedWithServer(email,phoneNumber).then();
setLoader(false);
const data = { selectedAsset,address,remarks,fee,amountToTransfer};
navigation.navigate('TransferConfirmationScreen',{transactionData:data});
}
else{
setLoader(false);
navigation.navigate('AccountUnlockScreen');
}
};
const refreshAssets = (currentAsset) =>{
setIndicatingMsg('Please Wait...');
setLoader(true);
updateVerifiedAccountBalances(accAddress);
apiServices.getTransferFundProcessingFee(currentAsset.symbol,accAddress)
.then(data=>{
setLoader(false);
setFee(data.totalFee);
})
.catch(()=>{
setLoader(false);
});
};
const checkValidData = () =>{
const max = walletUtils.getAssetDisplayText( selectedAsset.symbol,selectedAsset.value);
const totalAmt = parseFloat(amountToTransfer) + parseFloat(fee);
if(!amountToTransfer)
{
setShowError(true);
setErrorMessage('Please enter an Amount to begin Transfer');
setErrorTitle('Amount cannot be empty');
}
else if(totalAmt > max)
{
setShowError(true);
setErrorMessage('Please add more funds to account before this transaction');
setErrorTitle('Insufficient balance');
}
else if(!address.length)
{
setShowError(true);
setErrorMessage('Please enter a valid address');
setErrorTitle('Invalid Addess');
}
else{
setLoader(true);
setIndicatingMsg('Checking Account Please Wait.. It Takes a while to check from the Main BlockChain.');
checkAccountIsUnlocked();
}
};
const setNewAsset = (item) =>{
setSelectedAsset(item);
setModal(false);
refreshAssets(item);
};
const renderAssetOptions = () => {
return(
<View style={styles.assetModal}>
<View style={styles.modalHeader}>
<Text style={{color:Colors.white}}>Select From Available Funds</Text>
</View>
{
verifiedBalances.map((item,index)=>(
<TouchableOpacity key={index} onPress={()=>setNewAsset(item)} style={styles.eachAsset}>
<Text style={{fontSize:moderateScale(16),fontWeight:'bold'}}>{item.symbol.toUpperCase()}</Text>
<Text style={{fontSize:moderateScale(16),fontWeight:'bold'}}>{walletUtils.getAssetDisplayText( item.symbol,item.value)}</Text>
</TouchableOpacity>
))
}
</View>
);
};
const setMaxTransferLimit = () =>{
const maxBalance = walletUtils.getAssetDisplayText( selectedAsset.symbol,selectedAsset.value);
setAmountToTransfer(maxBalance-fee);
};
const renderAssets = () =>{
if(showTransactionUi)
return (
<ScrollView>
<View style={GlobalStyles.primaryCard}>
<Text style={GlobalStyles.titleTypo}> Amount / Asset</Text>
<View style={GlobalStyles.inputBox}>
<View style={{flexDirection:'row',justifyContent:'space-between',alignItems:'center',width:'100%'}}>
<TextInput
keyboardType={'decimal-pad'}
onChangeText={(amt) => {
setAmountToTransfer(amt);
}}
placeholder={'Enter Amount'}
placeholderTextColor={Colors.tintColorGreyedDark}
style={styles.inputText}
value={amountToTransfer.toString()}
/>
<TouchableOpacity onPress={()=>setModal(true)} style={{flexDirection:'row',alignItems:'center'}}>
<Text style={styles.assetTitle}>{selectedAsset.symbol.toUpperCase()}</Text>
<Icon color={Colors.green} name={'angle-down'} size={moderateScale(22)} style={{marginLeft:moderateScale(5)}} />
</TouchableOpacity>
</View>
<View style={styles.bottomInputBar}>
<Text style={{color:Colors.green,maxWidth:moderateScale(150)}}> ~ {selectedCurrency.symbol} {walletUtils.getAssetDisplayTextInSelectedCurrency(selectedAsset.symbol.toLowerCase(),amountToTransfer, exchangeRates)}</Text>
<TouchableOpacity onPress={()=>setMaxTransferLimit()}>
<Text style={{fontSize:moderateScale(12),fontWeight:'bold',color:Colors.activeTintRed}}>MAX : {walletUtils.getAssetDisplayText( selectedAsset.symbol,selectedAsset.value)} {selectedAsset.symbol.toUpperCase()} </Text>
</TouchableOpacity>
</View>
</View>
<Text style={GlobalStyles.titleTypo}> To Addess</Text>
<View style={GlobalStyles.inputBox}>
<TextInput
autoCapitalize={'none'}
autoCorrect={false}
keyboardType={'email-address'}
onChangeText={(addr) => {
setAddress(addr);
}}
placeholder={'Enter Address'}
placeholderTextColor={Colors.tintColorGreyedDark}
style={{color:Colors.white,width:'100%'}}
value={address}
/>
</View>
{/* TODO - FUTURE */}
{/* <Text style={GlobalStyles.titleTypo}> Any Remarks</Text>
<View style={GlobalStyles.inputBox}>
<TextInput
autoCorrect={false}
onChangeText={remarks => {
setRemarks(remarks);
}}
placeholder={'Short Remarks'}
placeholderTextColor={Colors.tintColorGreyedDark}
style={{color:Colors.white,width:'100%'}}
/>
</View> */}
</View>
</ScrollView>
);
return (
<View style={GlobalStyles.primaryCard}>
<Text style={{...GlobalStyles.titleTypo,textAlign:'center'}}> Your Account donot have</Text>
<Text style={{...GlobalStyles.titleTypo,textAlign:'center'}}> sufficient balance</Text>
</View>
);
};
return(
<SafeAreaView style={GlobalStyles.appContainer}>
<View style={styles.wrapper}>
<AppHeader headerTitle={'Transfer Funds'} >
<TouchableOpacity onPress={()=>navigation.navigate('ScannerScreen')}>
<Image
resizeMode={'contain'}
source={require('../../../../../../assets/images/icons/scanner.svg')}
style={styles.qrScanner}
/>
</TouchableOpacity>
</AppHeader>
{renderAssets()}
{
showTransactionUi && (
<>
<TouchableOpacity onPress={()=>checkValidData()} style={styles.transferButton}>
<Text style={styles.proceedText}>Proceed</Text>
</TouchableOpacity>
<Text style={styles.feeText}>
Fee : {fee}{' '+selectedAsset.symbol.toUpperCase()+' '}
~ {selectedCurrency.symbol} {walletUtils.getAssetDisplayTextInSelectedCurrency(selectedAsset.symbol.toLowerCase(),fee, exchangeRates)}
</Text>
</>
)
}
</View>
<Modal
animationIn={'slideInRight'}
animationOut={'slideOutRight'}
backdropColor={'#000'}
dismissable={true}
isVisible={modal}
onBackButtonPress={()=>setModal(false)}
onBackdropPress={()=>setModal(false)}
style={{justifyContent:'center',alignItems:'center',padding:0}}
useNativeDriver={true}
>
{renderAssetOptions()}
</Modal>
<LoadingIndicator
message={indicatingMssg}
visible={loader}
/>
<ErrorDialog
message={errorMessage}
onDismiss={() => {
setShowError(false);
}}
title={errorTitle}
visible={showError}
/>
</SafeAreaView>
);
}