Created
January 11, 2018 14:02
-
-
Save efstathiosntonas/0865256fa8e0a97a586a377b52b6fc5e to your computer and use it in GitHub Desktop.
Facebook Ads every X posts in React Native Flatlist
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, {Component} from 'react'; | |
import {ActivityIndicator, AsyncStorage, Dimensions, FlatList, LayoutAnimation, StyleSheet, Text, TouchableHighlight, TouchableOpacity, View, Alert, Platform} from 'react-native'; | |
import Icon from 'react-native-vector-icons/Ionicons'; | |
import {Card, CardImage, CardTitle} from 'react-native-material-cards'; | |
import ActionButton from 'react-native-circular-action-menu'; | |
import ImagePicker from 'react-native-image-crop-picker'; | |
import {MaterialIndicator} from 'react-native-indicators'; | |
import Storage from 'react-native-storage'; | |
import {EventRegister} from 'react-native-event-listeners'; | |
import shortid from 'shortid'; | |
import Orientation from 'react-native-orientation'; | |
import SplashScreen from 'rn-splash-screen'; | |
const storage = new Storage({ | |
size : 1000, | |
storageBackend: AsyncStorage, | |
defaultExpires: null, | |
enableCache : true, | |
}); | |
import { | |
// AdSettings, | |
BannerView} from 'react-native-fbads'; | |
var modCount = 0; | |
var fbKey = shortid.generate(); | |
if (Platform.OS === 'ios') { | |
var placementId = 'xxxxxxxxxxx'; | |
var type = 'standard' | |
} else { | |
placementId = 'xxxxxxxxxxx'; | |
type = 'standard'; | |
} | |
class Home extends Component { | |
constructor(props) { | |
super(props); | |
this._keyExtractor = this._keyExtractor.bind(this); | |
this._renderItem = this._renderItem.bind(this); | |
this.handleRefresh = this.handleRefresh.bind(this); | |
this.handleLoadMore = this.handleLoadMore.bind(this); | |
this.renderFooter = this.renderFooter.bind(this); | |
this.state = { | |
labels : [], | |
page : 1, | |
take : 10, | |
fetching : false, | |
modalVisible : false, | |
isActionButtonVisible: true, | |
refreshing : false, | |
loadingmore : false, | |
mounting : true, | |
selectedLanguages : [], | |
noLabelsAvailable : false, | |
noMoreData : false, | |
fbad : true, | |
fbkey : '', | |
ads : true, | |
showFBAds : true, | |
}; | |
} | |
_keyExtractor = (item, index) => index; | |
_showImage = (image, upvotes, id) => { | |
this.props.navigation.navigate('Image', {image: image, upvotes: upvotes, id: id}); | |
}; | |
_imagePicker = () => { | |
ImagePicker.openPicker({ | |
width : 768, | |
height : 1024, | |
cropping : true, | |
showCropGuidelines : true, | |
compressImageQuality: 0.8, | |
smartAlbums : ['UserLibrary'], | |
mediaType : 'photo' | |
}).then(image => { | |
this.props.navigation.navigate('Upload', image); | |
}).catch(error => { | |
if (error.code === 'E_PERMISSION_MISSING') { | |
Alert.alert('Cannot access images', 'Please allow the app to access your image library in your phone settings'); | |
} else { | |
console.log(error); | |
} | |
}); | |
}; | |
_openCamera = () => { | |
ImagePicker.openCamera({ | |
width : 768, | |
height : 1024, | |
cropping : true, | |
showCropGuidelines : true, | |
compressImageQuality: 0.8, | |
mediaType : 'photo' | |
}).then(image => { | |
this.props.navigation.navigate('Upload', image); | |
}).catch(error => { | |
if (error.code === 'E_PICKER_NO_CAMERA_PERMISSION') { | |
Alert.alert('Cannot access camera', 'Please allow the app to access camera in your phone settings'); | |
} else if (error.code === 'E_FAILED_TO_OPEN_CAMERA') { | |
Alert.alert('Cannot access camera', 'Please allow the app to access camera in your phone settings'); | |
} else { | |
console.log(error); | |
} | |
}); | |
}; | |
_onScroll = (event) => { | |
fbKey = shortid.generate(); | |
// Simple fade-in / fade-out animation | |
const CustomLayoutLinear = { | |
duration: 100, | |
create : {type: LayoutAnimation.Types.linear, property: LayoutAnimation.Properties.opacity}, | |
update : {type: LayoutAnimation.Types.linear, property: LayoutAnimation.Properties.opacity}, | |
delete : {type: LayoutAnimation.Types.linear, property: LayoutAnimation.Properties.opacity} | |
}; | |
// Check if the user is scrolling up or down by confronting the new scroll position with your own one | |
const currentOffset = event.nativeEvent.contentOffset.y; | |
const direction = (currentOffset > 0 && currentOffset > this._listViewOffset) | |
? 'down' | |
: 'up'; | |
// If the user is scrolling down (and the action-button is still visible) hide it | |
const isActionButtonVisible = direction === 'up'; | |
if (isActionButtonVisible !== this.state.isActionButtonVisible) { | |
LayoutAnimation.configureNext(CustomLayoutLinear); | |
this.setState({isActionButtonVisible}); | |
} | |
// Update your scroll position | |
this._listViewOffset = currentOffset; | |
}; | |
_listViewOffset = 0; | |
componentWillMount() { | |
storage.load({ | |
key: 'ads' | |
}).then((value) => { | |
if (value === false) { | |
this.setState({ | |
ads : false, | |
showFBAds: false | |
}); | |
} else { | |
this.setState({ | |
ads : true, | |
showFBAds: true | |
}); | |
} | |
}).catch((error) => { | |
this.setState({ | |
ads : true, | |
showFBAds: true | |
}); | |
}); | |
this.listener = EventRegister.addEventListener('languageChange', (data) => { | |
let result = data.map(function (language) { | |
return language.value; | |
}); | |
let languages = result.toString(); | |
this.setState({ | |
selectedLanguages: languages, | |
labels : [] | |
}, | |
() => { | |
this.handleRefresh(); | |
}); | |
}); | |
this.adsListener = EventRegister.addEventListener('adsRemoved', (data) => { | |
if (data === false) { | |
this.handleRefresh(); | |
} | |
}); | |
} | |
componentWillUnmount() { | |
EventRegister.removeEventListener(this.listener); | |
EventRegister.removeEventListener(this.adsListener); | |
} | |
componentDidUpdate() { | |
} | |
componentDidMount() { | |
storage.load({ | |
key: 'languages' | |
}).then(value => { | |
if (!value) { | |
this.setState({ | |
selectedLanguages: [{'label': 'English', value: 'en'}] | |
}); | |
storage.save({ | |
key : 'languages', | |
data: [this.state.selectedLanguages] | |
}); | |
} else { | |
let result = value.map(function (language) { | |
return language.value; | |
}); | |
let languages = result.toString(); | |
this.setState({ | |
selectedLanguages: languages | |
}); | |
} | |
}).catch(error => { | |
this.setState({ | |
selectedLanguages: 'en' | |
}); | |
storage.save({ | |
key : 'languages', | |
data: [this.state.selectedLanguages] | |
}); | |
}).then(() => this.makeRemoteRequest(true)); | |
if (!this.state.fetching) { | |
if(Platform.OS === 'android') { | |
SplashScreen.hide(); | |
} | |
Orientation.lockToPortrait(); | |
} | |
}; | |
onBannerAdError = (event) => { | |
console.log('Ad error :(', event.nativeEvent); | |
this.setState({fbad: false}); | |
}; | |
makeRemoteRequest = (mounting) => { | |
if (mounting) { | |
this.setState({fetching: true}); | |
} | |
const language = this.state.selectedLanguages.length ? this.state.selectedLanguages : 'en'; | |
const {take, page} = this.state; | |
const url = `https://www.xxxxxxxxxxx.com/query?take=${take}&page=${page}&languages=${language}`; | |
fetch(url) | |
.then(response => response.json()) | |
.then(response => { | |
if (response.length >= 1) { | |
this.setState(prevState => ({ | |
labels : page === 1 ? response : [...this.state.labels, ...response], | |
fetching : false, | |
refreshing : false, | |
mounting : false, | |
noLabelsAvailable: false, | |
})); | |
if ((this.state.labels.length - modCount) % 20 === 0) { | |
var fbkey = shortid.generate(); | |
this.state.labels.push({key: fbkey, type: 'ad'}); | |
modCount++; | |
} | |
} | |
else if (response.length < 1 && this.state.labels.length < 1) { | |
this.setState({ | |
noLabelsAvailable: true, | |
labels : [], | |
fetching : false, | |
loadingmore : false | |
}); | |
} | |
else if (response.length = this.state.labels.length) { | |
this.setState({ | |
noMoreData : true, | |
fetching : false, | |
refreshing : false, | |
loadingmore: false | |
}); | |
} | |
}) | |
.catch(error => { | |
console.log(error); | |
this.setState({fetching: false}); | |
}); | |
}; | |
handleRefresh = () => { | |
this.setState({page: 1, take: this.state.take}, | |
() => { | |
this.makeRemoteRequest(); | |
}); | |
modCount = 0; | |
}; | |
handleLoadMore = () => { | |
// if (!this.onEndReachedCalledDuringMomentum) { | |
this.setState({ | |
page : this.state.page + 1, | |
loadingmore: true | |
}, | |
() => { | |
this.makeRemoteRequest(); | |
}); | |
// this.onEndReachedCalledDuringMomentum = true; | |
// } | |
}; | |
renderFooter = () => { | |
if (!this.state.loadingmore) return null; | |
return ( | |
<View | |
style={{ | |
paddingVertical: 20, | |
borderTopWidth : 1, | |
borderColor : '#CED0CE' | |
}} | |
> | |
<ActivityIndicator animating size="small"/> | |
</View> | |
); | |
}; | |
_renderItem = ({item}) => { | |
switch (item.type) { | |
case 'label': | |
return <Card style={styles.card}> | |
<CardTitle title={item.description}/> | |
<TouchableOpacity style={styles.image} onPress={() => this._showImage(item.imagepath, item.upvotes, item._id)} activeOpacity={0.7}> | |
<CardImage seperator={false} id={item._id} inColumn={false} source={{uri: item.imagepath}}/> | |
</TouchableOpacity> | |
</Card>; | |
break; | |
case 'ad': | |
return (this.state.fbad && this.state.ads ? | |
<View style={styles.fbCard}> | |
<Text style={styles.cardTitle}>Sponsored</Text> | |
<BannerView | |
placementId={placementId} | |
type={type} | |
onError={this.onBannerAdError} | |
onPress={()=> console.log('click')} | |
/> | |
</View> | |
: null ); | |
break; | |
default: | |
return null; | |
} | |
}; | |
emptyList = () => { | |
return (this.state.noLabelsAvailable ? | |
<View> | |
<Text | |
style={styles.nolabels}> | |
No labels available for the selected language(s) or network error | |
</Text> | |
<View style={{flexDirection: 'row', justifyContent: 'space-around', alignContent: 'center', paddingLeft: 80, paddingRight: 80, marginBottom: 15}}> | |
<TouchableHighlight activeOpacity={0.7} underlayColor={'rgba(0,0,0,0)'} style={styles.okButton} onPress={() => { | |
this.handleRefresh(); | |
}}> | |
<Text style={{color: 'blue', marginTop: 5}}>Refresh</Text> | |
</TouchableHighlight> | |
<TouchableHighlight activeOpacity={0.7} underlayColor={'rgba(0,0,0,0)'} style={styles.okButton} onPress={() => { | |
this.props.navigation.navigate('Settings'); | |
}}> | |
<Text style={{color: 'blue', marginTop: 5}}>Settings</Text> | |
</TouchableHighlight> | |
</View> | |
</View> | |
: false) | |
}; | |
render() { | |
return ( | |
<View style={styles.container}> | |
<View style={styles.view}> | |
<View> | |
{this.state.fetching ? <MaterialIndicator color="red" style={styles.spinner} animating={this.state.fetching}/> : false} | |
<FlatList | |
data={this.state.labels} | |
keyExtractor={this._keyExtractor} | |
renderItem={this._renderItem} | |
onScroll={this._onScroll} | |
refreshing={this.state.refreshing} | |
onRefresh={this.handleRefresh} | |
onEndReached={this.handleLoadMore} | |
onEndReachedThreshold={0.01} | |
// onMomentumScrollBegin={() => { | |
// this.onEndReachedCalledDuringMomentum = false; | |
// }} | |
removeClippedSubviews={false} | |
ListEmptyComponent={this.emptyList} | |
ListFooterComponent={this.renderFooter} | |
/> | |
</View> | |
</View> | |
<View style={styles.button}> | |
{this.state.isActionButtonVisible ? | |
<ActionButton | |
buttonColor="rgba(231,76,60,1)" | |
position="right" | |
radius={80} | |
size={60} | |
elevation={5} | |
zIndex={1000}> | |
<ActionButton.Item size={55} elevation={5} buttonColor='#1976D2' title="Camera" onPress={() => this._openCamera()}> | |
<Icon name="ios-camera-outline" style={styles.actionButtonIcon}/> | |
</ActionButton.Item> | |
<ActionButton.Item size={55} elevation={5} buttonColor='#1976D2' title="Album" onPress={() => { | |
}}> | |
<Icon name="ios-albums-outline" style={styles.actionButtonIcon} onPress={() => this._imagePicker()}/> | |
</ActionButton.Item> | |
</ActionButton> : null} | |
</View> | |
</View> | |
); | |
} | |
} | |
const styles = StyleSheet.create({ | |
container : { | |
...Platform.select({ | |
ios : { | |
marginTop: 20, | |
}, | |
android: { | |
marginTop: 0 | |
} | |
}), | |
flex : 1, | |
padding : 0, | |
backgroundColor: '#f4f4f4' | |
}, | |
fbCard : { | |
justifyContent: 'space-between', | |
marginBottom: 36, | |
height: 50 | |
}, | |
cardTitle: { | |
marginBottom: 5, | |
marginLeft: 5 | |
}, | |
view : { | |
backgroundColor: '#f4f4f4', | |
}, | |
nolabels : { | |
padding: 50 | |
}, | |
button : { | |
position: 'absolute', | |
bottom : 20, | |
right : 20, | |
...Platform.select({ | |
android: { | |
height: 200, | |
width : 200 | |
} | |
}) | |
}, | |
spinner : { | |
position: 'absolute', | |
height : Dimensions.get('window').height, | |
width : Dimensions.get('window').width, | |
}, | |
actionButtonIcon: { | |
fontSize: 30, | |
height : 36, | |
color : 'white', | |
}, | |
actionButton : { | |
fontSize: 50 | |
}, | |
image : { | |
width: '100%' | |
}, | |
votes : { | |
color : 'black', | |
fontSize : 18, | |
padding : 6, | |
paddingBottom: 8 | |
}, | |
dialogView : {}, | |
dialog : { | |
padding: 20 | |
}, | |
dialogText : {}, | |
modal2 : { | |
justifyContent: 'center', | |
alignItems : 'center', | |
height : 100, | |
width : Dimensions.get('window').width / 1.2 | |
}, | |
buttonText : { | |
padding : 10, | |
fontSize: 16, | |
color : 'blue' | |
}, | |
okButton : { | |
marginTop : 15, | |
justifyContent: 'center', | |
alignSelf : 'stretch', | |
alignItems : 'center' | |
}, | |
labelText : { | |
paddingLeft: 10, | |
color : 'grey' | |
}, | |
languagesText : { | |
paddingLeft: 10, | |
paddingTop : 10, | |
color : 'grey' | |
}, | |
dialogComponent : { | |
flex: 1 | |
} | |
}); | |
export default Home; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you very much!