How to hide splash screen once images are loaded - javascript

I am using expo and want to show the splash screen until images are all loaded. I am loading images from a url.
What is supposed to happen is when onLoad is called, numberOfImagesLoaded increases by 1, and useAppIsReady is run again. Then there is a check
const imagesAreLoaded = numberOfImagesLoaded > 2;.
When numberOfImagesLoaded > 2, appIsReady is true, then onLayoutRootView gets called and the splash screen gets hidden.
However, I am not sure why when onLoad is called, numberOfImagesLoaded in useAppIsReady does not seem to increase.
App.js
import { StatusBar } from "expo-status-bar";
import { Image, StyleSheet, Text, View } from "react-native";
import { useFonts } from "expo-font";
import * as SplashScreen from "expo-splash-screen";
import React, { useCallback, useState } from "react";
import useAppIsReady from "./useAppIsReady";
import data from "./data";
SplashScreen.preventAutoHideAsync();
export default function App() {
const [numberOfImagesLoaded, setNumberOfImagesLoaded] = useState(0);
const appIsReady = useAppIsReady(numberOfImagesLoaded);
const onLayoutRootView = useCallback(async () => {
if (appIsReady) {
await SplashScreen.hideAsync();
}
}, [appIsReady]);
if (!appIsReady) {
return null;
}
return (
<View onLayout={onLayoutRootView} style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
<Images setNumberOfImagesLoaded={setNumberOfImagesLoaded} />
<StatusBar style="auto" />
</View>
);
}
const Images = ({ setNumberOfImagesLoaded }) => {
return (
<>
{data.map(({ imgSrc }) => {
return (
<MyImage
key={imgSrc}
imgSrc={imgSrc}
setNumberOfImagesLoaded={setNumberOfImagesLoaded}
/>
);
})}
</>
);
};
const MyImage = ({ imgSrc, setNumberOfImagesLoaded }) => {
const onLoad = () => {
setNumberOfImagesLoaded((prev) => prev + 1);
};
return (
<Image source={{ uri: imgSrc }} style={styles.image} onLoad={onLoad} />
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
image: {
flex: 1,
width: "100%",
},
});
useAppIsReady.js
import { useFonts } from "expo-font";
import * as SplashScreen from "expo-splash-screen";
import React, { useState, useCallback } from "react";
const useAppIsReady = (numberOfImagesLoaded) => {
const [appIsReady, setAppIsReady] = useState(false);
// Load fonts
const baseAssetsPath = "./assets/fonts";
const fonts_by_path = {
"DMSans-Regular": require(`${baseAssetsPath}/DMSans-Regular.ttf`),
"DMSans-Bold": require(`${baseAssetsPath}/DMSans-Bold.ttf`),
"DMSans-BoldItalic": require(`${baseAssetsPath}/DMSans-BoldItalic.ttf`),
"DMSans-Medium": require(`${baseAssetsPath}/DMSans-Medium.ttf`),
"DMSans-MediumItalic": require(`${baseAssetsPath}/DMSans-MediumItalic.ttf`),
"DMSans-Italic": require(`${baseAssetsPath}/DMSans-Italic.ttf`),
};
const [fontsLoaded] = useFonts(fonts_by_path);
// Load images
console.log(numberOfImagesLoaded);
const imagesAreLoaded = numberOfImagesLoaded > 2;
// const imagesAreLoaded = true;
if (fontsLoaded && imagesAreLoaded && !appIsReady) {
setAppIsReady(true);
}
return appIsReady;
};
export default useAppIsReady;
Here is a link to the repo
https://github.com/Bijig0/loading-imgs-testing

Related

Audio is not automatically closing while pressing backbutton in REACT NATIVE application

In a media player application, I try to use "expo-av" library to build a playlist. everything is working fine. But when I press on the backbutton, it is not behaving properly. I tried in many way. but nothing works for me.
I tried while handling backButton, like, sound.unloadAsync(), sound.stopAsync(), setSound(null).
import React, { useEffect, useState } from 'react';
import {
View,
BackHandler,
Text,
TouchableWithoutFeedback,
StyleSheet,
} from 'react-native';
import * as Progress from 'react-native-progress';
import { connect } from 'react-redux';
import { MaterialCommunityIcons } from '#expo/vector-icons';
import { Audio } from 'expo-av';
const sectionsAllCards = [
{
id: 'audio-01',
name: 'Body scan: Generic under mindfulness',
link: 'Bodyscan.m4a',
}
];
const MusicPlayerList = ({ navigation, route, ...props }) => {
const [isPlaying, setIsPlaying] = useState(false);
const [progress, setProgress] = useState(0);
const [audioIndex, setAudioIndex] = useState(0);
const [soundObject, setSoundObject] = useState(null);
const audioSources = [
require('../../assests/musics/Bodyscan.m4a')
];
const togglePlayback = async () => {
if (isPlaying) await soundObject.pauseAsync();
else await soundObject.playAsync();
setIsPlaying(!isPlaying);
};
const onPlaybackStatusUpdate = (status) => {
setProgress(status.positionMillis / status.durationMillis);
};
useEffect(() => {
const loadAudio = async () => {
const source = audioSources[audioIndex];
const sound = new Audio.Sound();
try {
await sound.loadAsync(source);
setSoundObject(sound);
sound.setOnPlaybackStatusUpdate(onPlaybackStatusUpdate);
} catch (error) {
console.log(error);
}
};
loadAudio();
}, [audioIndex]);
async function handleBackButtonClick() {
navigation.navigate('LoginSignup');
return true;
}
useEffect(() => {
BackHandler.addEventListener(
'hardwareBackPress',
handleBackButtonClick,
);
return () => {
BackHandler.removeEventListener(
'hardwareBackPress',
handleBackButtonClick,
);
};
}, []);
const handleOnPress = async (index) => {
if (index === audioIndex) togglePlayback();
else {
setIsPlaying(false);
setProgress(0);
await soundObject.stopAsync();
setSoundObject(null);
setAudioIndex(index);
}
};
return (
<View style={{ backgroundColor: '#efefef', flex: 1 }}>
{sectionsAllCards.map((card, index) => (
<TouchableWithoutFeedback
key={card.id}
onPress={() => handleOnPress(index)}
>
<View style={styles.boxContainer}>
<Text style={styles.audioText}>{card.name}</Text>
<View style={styles.audioIconContainer}>
{progress >= 0 && progress <= 1 && (
<View>
<Progress.Circle
style={styles.progress}
progress={audioIndex === index ? progress : 0}
indeterminate={false}
showsText={false}
size={60}
borderWidth={2}
color={'#479162'}
/>
<Text
style={{
position: 'absolute',
left: 11,
top: 10,
}}
>
<MaterialCommunityIcons
name={
isPlaying && audioIndex === index
? 'pause'
: 'play'
}
size={38}
style={{ color: '#479162' }}
/>
</Text>
</View>
)}
</View>
</View>
</TouchableWithoutFeedback>
))}
</View>
);
};
const styles = StyleSheet.create({
boxContainer: {
},
audioText: {
},
});
const mapStateToProps = (state) => ({
accessToken: state.auth.accessToken,
});
export default connect(mapStateToProps, {})(MusicPlayerList);

React native - create one common function that can be shared between 2 or more screens

I have 2 screens, SignUpScreen and CreateCommunityScreen, and these 2 screens have an icon which calls the same function pickImage whenever the icon is clicked. How do I create one function for both screens? Here's what I have so far, but I encountered the error "Error: You attempted to set the key _V with the value 1 on an object that is meant to be immutable and has been frozen." Thanks in advance.
pickImage function
import * as ImagePicker from "expo-image-picker";
const pickImage = async () => {
let imageURI = "";
const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
if (status === "granted") {
let selectedImage = await ImagePicker.launchImageLibraryAsync({
allowsEditing: true,
aspect: [4, 3],
quality: 1,
});
if (!selectedImage.cancelled) {
imageURI = selectedImage.uri;
}
return imageURI;
}
};
export default pickImage;
SignUpScreen
import React, { useState } from "react";
import { View, Text, Image, StyleSheet } from "react-native";
import AppBrand from "../../component/AppBrand";
import AuthenticationForm from "../../component/AuthenticationForm";
import CustomButtonLink from "../../component/CustomButtonLink";
import DefaultProfileIcon from "../../component/DefaultProfileIcon";
import pickImage from "../../helper/pickImage";
const SignUpScreen = ({ navigation }) => {
const [image, setImage] = useState(null);
return (
<View>
<AppBrand />
<DefaultProfileIcon
onPress={() => {
setImage(pickImage);
console.log(image);
}}
/>
<AuthenticationForm
btnName={"SIGN UP"}
onNavigate={() => {
console.log("image", image);
console.log("Stays on Sign Up");
}}
/>
<CustomButtonLink
custBtnLinkName={"Cancel"}
style={styles.spacing_Cancel}
onNavigate={() => {
navigation.navigate("Sign In");
}}
/>
{image && (
<Image source={{ uri: image }} style={{ width: 200, height: 200 }} />
)}
</View>
);
};
const styles = StyleSheet.create({
spacing_Cancel: {
marginTop: 170,
alignItems: "center",
},
});
export default SignUpScreen;
Create a file where all the common functions are present (eg. Helper.js)
Add the functions in helper file and export it
export function getIcon(){
Console.log("Get icon function called")
}
Now import the file where you want to use it in different screens
eg:
import Helper from '..path of the file'
and use it like
Helper.getIcon()

using Onclick, fetch api data in react native

I am new to React Native.
I am facing an issue with this view. Basically it is something like this when you click a button it generates any random number, now this random number becomes an id and it goes to at the end of the API url, And using this new API - with ID at the end of it. - data gets fetched. Now i've divided this task in two parts generating random number code (i.e. snippet 1) and fetching data from api ( i.e. snippet 2). As of now, I don't know how to combine them because i am new to react native so a little help here would be appreciated from anyone.
Snipppet 1
import { StyleSheet, View, Button, Text } from 'react-native';
export default class MyProject extends Component {
constructor(){
super();
this.state={
// This is our Default number value
NumberHolder : 0
}
}
GenerateRandomNumber=()=>
{
var RandomNumber = Math.floor(Math.random() * 5000) + 1 ;
this.setState({
NumberHolder : RandomNumber
})
}
render() {
return (
<View style={styles.MainContainer} >
<Text style={{marginBottom: 10, fontSize: 20}}>{this.state.NumberHolder}</Text>
<Button title="Generate Random Number" onPress={this.GenerateRandomNumber} />
</View>
);
}
}
const styles = StyleSheet.create(
{
MainContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}
});
Snippet 2
import React, { useState } from "react";
import { Box, FlatList, Center, NativeBaseProvider, Button } from "native-base";
import { StyleSheet, View, ActivityIndicator, Text, TouchableOpacity, Image } from 'react-native';
export default function MyFUnction() {
const [data, setData] = useState(null);
const [visible, setVisible] = useState(true);
const fetchData = async () => {
const resp = await fetch("https://jsonplaceholder.typicode.com/photos/7");
const data = await resp.json();
setData(data);
setVisible(false);
};
const renderItem = ({ item }) => {
return (
<TouchableOpacity style={styles.list}>
<Text>{item.title}</Text>
</TouchableOpacity>
);
};
return (
<NativeBaseProvider>
<Center flex={1}>
{visible && <Button onPress={() => fetchData()}>Press</Button>}
{data && (
<FlatList
data={data}
renderItem={(item) => this.renderItem(item)}
keyExtractor={(item) => item.id.toString()}
/>
)}
</Center>
</NativeBaseProvider>
);
}
const styles = StyleSheet.create({
list: {
paddingVertical: 4,
margin: 5,
backgroundColor: '#fff',
},
});
Thanks in advance!!
I think you must understand components clearly! React is component based! But your case is not 2 components! You have a component for fetching api and showing in list! Generating a random number is not a component, but it is a method(or function) in your list component! I think it is better to use one component for list and wrap a function to it for generating random number.
import React, { useState } from "react";
import { Box, FlatList, Center, NativeBaseProvider, Button } from "native-base";
import { StyleSheet, View, ActivityIndicator, Text, TouchableOpacity, Image } from 'react-native';
export default function MyFUnction() {
const [data, setData] = useState(null);
const [visible, setVisible] = useState(true);
const generatRandomNumber = () => {
return Math.floor(Math.random() * 5000) + 1
}
const fetchData = async () => {
const resp = await fetch(`https://jsonplaceholder.typicode.com/photos/${generatRandomNumber()}`);
const data = await resp.json();
setData(data);
setVisible(false);
};
const renderItem = ({ item }) => {
return (
<TouchableOpacity style={styles.list}>
<Text>{item.title}</Text>
</TouchableOpacity>
);
};
return (
<NativeBaseProvider>
<Center flex={1}>
{visible && <Button onPress={() => fetchData()}>Press</Button>}
{data && (
<FlatList
data={data}
renderItem={(item) => this.renderItem(item)}
keyExtractor={(item) => item.id.toString()}
/>
)}
</Center>
</NativeBaseProvider>
);
}
const styles = StyleSheet.create({
list: {
paddingVertical: 4,
margin: 5,
backgroundColor: '#fff',
},
});
But if you want to passing data between components you are have, it is not related to function or class component and you can pass data between them with props! So your code like this:
Random Number Component
import { StyleSheet, View, Button, Text } from 'react-native';
export default class MyProject extends Component {
constructor(props){ //edited
super(props); //edited
this.state={
// This is our Default number value
NumberHolder : 0
}
}
GenerateRandomNumber=()=>
{
var RandomNumber = Math.floor(Math.random() * 5000) + 1 ;
this.props.randomNumber(RandomNumber)
}
render() {
return (
<View style={styles.MainContainer} >
<Text style={{marginBottom: 10, fontSize: 20}}>{this.state.NumberHolder}</Text>
<Button title="Generate Random Number" onPress={this.GenerateRandomNumber} />
</View>
);
}
}
const styles = StyleSheet.create(
{
MainContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}
});
Your list component:
import React, { useState } from "react";
import { Box, FlatList, Center, NativeBaseProvider, Button } from "native-base";
import { StyleSheet, View, ActivityIndicator, Text, TouchableOpacity, Image } from 'react-native';
// import MyProject
export default function MyFUnction() {
const [data, setData] = useState(null);
const [visible, setVisible] = useState(true);
const [number, setNumber] = useState(null);
const fetchData = async () => {
const resp = await fetch(`https://jsonplaceholder.typicode.com/photos/${number}`);
const data = await resp.json();
setData(data);
setVisible(false);
};
const renderItem = ({ item }) => {
return (
<TouchableOpacity style={styles.list}>
<Text>{item.title}</Text>
</TouchableOpacity>
);
};
return (
<NativeBaseProvider>
<Center flex={1}>
<MyProject radomNumber={(number) => setNumber(number)}
{visible && <Button onPress={() => fetchData()}>Press</Button>}
{data && (
<FlatList
data={data}
renderItem={(item) => this.renderItem(item)}
keyExtractor={(item) => item.id.toString()}
/>
)}
</Center>
</NativeBaseProvider>
);
}
const styles = StyleSheet.create({
list: {
paddingVertical: 4,
margin: 5,
backgroundColor: '#fff',
},
});
thanks everyone for helping me.
here i am posting answer to my question, if anybody in future need an answer.
import React, { useEffect, useState, Component } from 'react';
import { StyleSheet, View, Button, FlatList, Text, Image } from 'react-native';
export default class MyProject extends Component {
constructor(){
super();
this.state={
// This is our Default number value
NumberHolder : 1,
books: []
}
}
GenerateRandomNumber=()=>
{
var RandomNumber = Math.floor(Math.random() * 5000) + 1;
fetch(`https://jsonplaceholder.typicode.com/photos/${RandomNumber}`)
.then((response) => response.json())
.then(booksList => {
this.setState({ books: booksList });
});
this.setState({
NumberHolder : RandomNumber
})
}
render() {
let Image_Http_URL ={ uri: 'https://reactnativecode.com/wp-content/uploads/2017/05/react_thumb_install.png'};
return (
<View style={styles.MainContainer} >
<Text style={{marginBottom: 10, fontSize: 20}}>{this.state.NumberHolder}</Text>
<Image
style={{width: '100%', height: 200,resizeMode : 'stretch' }}
source={{uri: this.state.books.url}}
/>
<Text style={{marginBottom: 10, fontSize: 12}}>{this.state.books.title}</Text>
<Text style={{marginBottom: 10, fontSize: 12}}>{this.state.books.url}</Text>
<Text style={{marginBottom: 10, fontSize: 12}}>{this.state.books.thumbnailUrl}</Text>
<Button title="Generate Random Number" onPress={this.GenerateRandomNumber} />
</View>
);
}
}
const styles = StyleSheet.create(
{
MainContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
}
});

react-navigation drawer updating multiple times

I am building an application with React Native and React Navigation, I have made all the settings and it is working, however, when the drawer is fired the image is updated multiple times causing spikes and failures to trigger buttons contained in it.
e.g.:
I am using:
react: 16.8.3,
react-native: 0.59.1,
react-native-ui-kitten: ^3.1.2,
react-navigation: ^3.4.0
I was using version 3 of RN and to try to solve I went back to version 2 but without success.
I put some warnings in the method that executes the image and saw that it is called whenever there is this update.
I already changed the image in different sizes and formats but it also did not help.
I already tested on cell phones and emulators but with no success.
Drawer:
import React, { Component } from 'react';
import {
TouchableHighlight,
View,
ScrollView,
Image,
Platform,
StyleSheet,
} from 'react-native';
import {
RkStyleSheet,
RkText,
RkTheme,
} from 'react-native-ui-kitten';
import Icon from 'react-native-vector-icons/Ionicons';
import Routes from '../../config/navigation/routes';
import logo from '../../assets/smallLogo.png';
export default function SideNavigation(props) {
const onMenuItemPressed = item => {
props.navigation.navigate(item.id);
};
const renderIcon = () => (<Image style={styles.image} source={logo}/>);
const renderMenuItem = item => (
<TouchableHighlight style={styles.container} key={item.id} underlayColor={RkTheme.current.colors.button.underlay} activeOpacity={1} onPress={() => onMenuItemPressed(item)}>
<View style={styles.content}>
<View style={styles.content}>
<RkText style={styles.icon} rkType='moon primary xlarge'><Icon name={item.icon} size={25}/></RkText>
<RkText rkType='regular'>{item.title}</RkText>
</View>
{/*<RkText rkType='awesome secondaryColor small'>{FontAwesome.chevronRight}</RkText>*/}
</View>
</TouchableHighlight>
);
const renderMenu = () => Routes.map(renderMenuItem);
return (
<View style={styles.root}>
<ScrollView showsVerticalScrollIndicator={false}>
<View style={[styles.container, styles.content]}>
{renderIcon()}
</View>
{renderMenu()}
</ScrollView>
</View>
)
}
const styles = RkStyleSheet.create(theme => ({
container: {
height: 60,
paddingHorizontal: 16,
borderTopWidth: StyleSheet.hairlineWidth,
borderColor: theme.colors.border.base,
},
root: {
paddingTop: Platform.OS === 'ios' ? 20 : 0,
backgroundColor: theme.colors.screen.base
},
content: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
},
icon: {
marginRight: 13,
},
image:{
resizeMode: 'contain',
maxWidth: 125
}
}));
Drawer setup:
import React, {Component} from 'react';
import { View, Text} from 'react-native';
import Login from './screens/login';
import PasswordRecovery from './screens/passwordRecovery';
import Home from './screens/home';
import SideNavigator from './components/sideMenu';
import { bootstrap } from './config/bootstrap';
import {
createDrawerNavigator,
createStackNavigator,
createAppContainer
} from 'react-navigation';
import { withRkTheme } from 'react-native-ui-kitten';
import NavBar from './components/navBar';
import AppRoutes from './config/navigation/routesBuilder';
import Splash from './screens/splash';
bootstrap();
const renderHeader = (navigation, props) => {
const ThemedNavigationBar = withRkTheme(NavBar);
return (
<ThemedNavigationBar navigation={navigation} headerProps={props} />
);
};
const App = createStackNavigator({
Splash: Splash,
Login: Login,
PasswordRecovery: PasswordRecovery,
Main: createDrawerNavigator({
...AppRoutes
},{
contentComponent: props => {
const SideNav = withRkTheme(SideNavigator);
return <SideNav {...props}/>
}
}),
},
{
headerMode: 'none',
})
export default createAppContainer(App);
Routes setup:
import React from 'react';
import _ from 'lodash';
import { createStackNavigator } from 'react-navigation';
import { withRkTheme } from 'react-native-ui-kitten';
import transition from './transitions';
import Routes from './routes';
import NavBar from '../../components/navBar';
const main = {};
const flatRoutes = {};
const routeMapping = (route) => ({
screen: withRkTheme(route.screen),
title: route.title,
});
(Routes).forEach(route => {
flatRoutes[route.id] = routeMapping(route);
main[route.id] = routeMapping(route);
route.children.forEach(nestedRoute => {
flatRoutes[nestedRoute.id] = routeMapping(nestedRoute);
});
});
const renderHeader = (navigation, props) => {
const ThemedNavigationBar = withRkTheme(NavBar);
return (
<ThemedNavigationBar navigation={navigation} headerProps={props} />
);
};
const DrawerRoutes = Object.keys(main).reduce((routes, name) => {
const rawRoutes = routes;
rawRoutes[name] = {
name,
screen: createStackNavigator(flatRoutes, {
initialRouteName: name,
headerMode: 'screen',
cardStyle: { backgroundColor: 'transparent' },
transitionConfig: transition,
defaultNavigationOptions: ({ navigation }) => ({
gesturesEnabled: false,
header: (props) => renderHeader(navigation, props),
}),
}),
};
return rawRoutes;
}, {});
const AppRoutes = DrawerRoutes;

Issue with photos length

I am facing 2 issues related to length of my selected photos:
When selecting photos, it lets me to select 5 photos without any issue (it fits my length restriction), however it doesn't save the chosen photos, when I go to the next screen. In another scenario, when I am at the same screen where I choose photos and I choose 6 photos, it selects the 6 photo but the warning popup will appear and say that its currently supports 5, then when I go to next screen its saves the selected photos unlike previously.
If I deselect photos and then try to select another photos (still in my length limit) popup jumps with selection limit and doesn't let me choose photos, when I go to the next screen it saves the changes from previous selection and not from current one.
import React from 'react';
import {
View,
ScrollView,
Image,
Dimensions,
TextInput,
Text,
StatusBar,
TouchableHighlight,
Linking,
Keyboard,
CameraRoll,
KeyboardAvoidingView
} from 'react-native';
import {connect} from 'react-redux';
import {ActionCreators} from '../redux/actions';
import {bindActionCreators} from 'redux';
import Colors from '../constants/Colors';
import api from '../api';
import {
getEmailAddress,
showError,
renderMessageBar,
registerMessageBar,
unregisterMessageBar
} from '../utils/ComponentUtils';
import {
regularHeader,
mainHeader
} from '../utils/Headers';
import {NavigationActions} from 'react-navigation';
import {SelectionLimitDialog} from '../utils/Dialogs';
import {ifIphoneX, isIphoneX} from 'react-native-iphone-x-helper';
import {SafeAreaView} from 'react-navigation';
// specific component imports.
import {List, ListItem} from 'react-native-elements'
import {Button} from 'react-native-elements'
import Loader from '../components/Loader';
import LoaderError from '../components/LoaderError';
import SelectedPhoto from '../components/SelectedPhoto';
class MultiSafeeScreen extends React.Component
{
static navigationOptions = ({navigation}) => {
const {params} = navigation.state;
const isIncome = params ? params.isIncome : false;
const notificationAction = params ? params.notificationAction : () => {};
const isShowBack = params ? params.isShowBack : false;
return mainHeader({
isShowBack: isShowBack,
backAction: () => navigation.goBack(),
notificationAction: () => notificationAction(),
income: isIncome
});
};
constructor(props) {
super(props);
this.selectedPhotos = [];
this.state = {
photos: null,
loader: {
loading: 0,
message: "Loading photos..."
},
selectedPhotos: [],
supportLength: 5
};
this.props.navigation.setParams({notificationAction: this.onNotification, isIncome: this.props.isNewNotifications});
}
UNSAFE_componentWillReceiveProps(newProps) {
if (newProps.isNewNotifications !== this.props.isNewNotifications) {
this.props.navigation.setParams({notificationAction: this.onNotification, isIncome: newProps.isNewNotifications});
}
}
componentDidMount() {
registerMessageBar(this.refs.alert);
let options = {
first: 30,
assetType: 'Photos',
}
CameraRoll.getPhotos(options)
.then(r => {
this.setState({
photos: r.edges,
loader: {
loading: 1,
message: "Loading photos..."
},
});
})
.catch((err) => {
//Error Loading Images
});
StatusBar.setHidden(false);
}
componentWillUnmount() {
unregisterMessageBar();
this.props.setSelectedPhotos(0);
}
onNotification = () => {
this.props.setNewNotifications(false);
this.props.navigation.navigate("Notifications");
}
closeKeyboard = () => {
Keyboard.dismiss();
}
onSelectPhoto = (photo, index) => {
let photos = new Set([...this.selectedPhotos]);
let len = photos.size + 1 ;
console.log('photos')
if (len > this.state.supportLength) {
this.limitDialog.open();
this.setState({selectedPhotos: this.selectedPhotos});
this.props.setSelectedPhotos(len);
}
else {
photos.add(photo);
this.selectedPhotos = Array.from(photos);
}
}
onDeselectPhoto = (photo, index) => {
let photos = new Set([...this.state.selectedPhotos]);
let len = photos.size - 1;
photos.delete(photo);
this.setState({selectedPhotos: Array.from(photos)});
this.props.setSelectedPhotos(len);
}
onNext = () => {
this.props.navigation.navigate("MultiSafeeCreate", {
isShowBack: true,
selected: [...this.state.selectedPhotos]
});
}
renderLoader() {
let {width, height} = Dimensions.get('window');
let photoWidth = width/3;
if (this.state.loader.loading === 0) {
return <Loader style={{justifyContent: 'center', alignItems: 'center'}} message={this.state.loader.message}/>
}
else if (this.state.loader.loading === 2) {
return <LoaderError style={{justifyContent: 'center', alignItems: 'center'}} message={this.state.loader.message}/>
}
// if photos are null do nothing, else if empty show onbording
// if has photos show photos.
if (this.state.photos === null) {
return <Loader style={{justifyContent: 'center', alignItems: 'center'}} message={this.state.loader.message}/>
}
else {
return (
<View style={{width: width, maxHeight: 600}}>
<ScrollView >
<View style={{flexDirection: 'row', width: width, flexWrap: 'wrap',marginBottom:40, justifyContent: 'space-between'}}>
{
this.state.photos.map((p, i) => {
return (
<SelectedPhoto
key={i}
index={i}
style={{
width: photoWidth,
height: photoWidth,
}}
borderColor = "white"
limit={this.state.supportLength}
photo={p}
onSelectPhoto={this.onSelectPhoto}
onDeselectPhoto={this.onDeselectPhoto}
/>
);
})
}
</View>
</ScrollView>
<View style={{ position:'absolute', right:-15, top:475 }}>
<Button
onPress={this.onNext}
containerViewStyle={{width: width}}
backgroundColor={Colors.red}
title='NEXT' />
</View>
</View>
);
}
}
render() {
return (
<View style={{flex: 1, backgroundColor: Colors.white}}>
{this.renderLoader()}
<SelectionLimitDialog ref={(el) => this.limitDialog = el} />
{renderMessageBar()}
</View>
);
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(ActionCreators, dispatch);
}
function mapStatesToProps(state) {
return {
isNewNotifications: state.isNewNotifications
};
}
export default connect(mapStatesToProps, mapDispatchToProps)(MultiSafeeScreen);

Categories