import React, {useState, useEffect, useRef} from 'react';
import {
SafeAreaView,
StyleSheet,
View,
Text,
Dimensions,
Animated,
Image,
StatusBar
} from 'react-native';
import {TabView, TabBar, SceneMap} from 'react-native-tab-view';
import Icon from 'react-native-vector-icons/FontAwesome';
import IconF from 'react-native-vector-icons/Feather';
import ProfileFlatList from '../components/ProfileFlatList.js';
import { Thumbnail, Button, Tab, Tabs, TabHeading } from 'native-base';
const DATA = [
{image:require('../../assets/4.jpg'),isDraft:true,draftCount:'24',draftIcon:'inbox'},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/2.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/1.png'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/1.png'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/2.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false}
];
const DATA1 = [
{image:require('../../assets/4.jpg'),isDraft:true,draftCount:'24',draftIcon:'inbox'},
{image:require('../../assets/3.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/2.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/1.png'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/1.png'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false},
{image:require('../../assets/2.jpg'),view:'205k',heart:'110k', heartIcon:'heart',viewIcon:'play',iconColor:'rgba(255,255,255,0.95)',textColor:'rgba(255,255,255,0.95)',isDraft:false}
];
const TabBarHeight = 48;
const HeaderHeight = 390;
const tab1ItemSize = (Dimensions.get('window').width - 30) / 3;
class TabScene extends React.Component {
render = () => {
const windowHeight = Dimensions.get('window').height;
const {
numCols,
data,
renderItem,
onGetRef,
scrollY,
onScrollEndDrag,
onMomentumScrollEnd,
onMomentumScrollBegin,
} = this.props;
return (
<Animated.FlatList
scrollToOverflowEnabled={true}
numColumns={numCols}
ref={onGetRef}
scrollEventThrottle={16}
onScroll={Animated.event(
[{nativeEvent: {contentOffset: {y: scrollY}}}],
{useNativeDriver: true},
)}
onMomentumScrollBegin={onMomentumScrollBegin}
onScrollEndDrag={onScrollEndDrag}
onMomentumScrollEnd={onMomentumScrollEnd}
ItemSeparatorComponent={() => <View style={{height: 10}} />}
ListHeaderComponent={() => <View style={{height: 10}} />}
contentContainerStyle={{
paddingTop: HeaderHeight + TabBarHeight,
paddingHorizontal: 10,
minHeight: windowHeight - TabBarHeight,
}}
showsHorizontalScrollIndicator={false}
data={data}
renderItem={renderItem}
showsVerticalScrollIndicator={false}
keyExtractor={(item, index) => index.toString()}
/>
);
};
}
const Profile = () => {
const [tabIndex, setIndex] = useState(0);
const [routes] = useState([
{key: 'tab1', title: 'Tab1'},
{key: 'tab2', title: 'Tab2'},
]);
const scrollY = useRef(new Animated.Value(0)).current;
let listRefArr = useRef([]);
let listOffset = useRef({});
let isListGliding = useRef(false);
useEffect(() => {
scrollY.addListener(({value}) => {
const curRoute = routes[tabIndex].key;
listOffset.current[curRoute] = value;
});
return () => {
scrollY.removeAllListeners();
};
}, [routes, tabIndex]);
const syncScrollOffset = () => {
const curRouteKey = routes[tabIndex].key;
listRefArr.current.forEach((item) => {
// sync value except current route
if (item.key !== curRouteKey) {
// if header has not yet been collapsed, scroll to current offset
if (scrollY._value < HeaderHeight && scrollY._value >= 0) {
if (item.value) {
item.value.scrollToOffset({
offset: scrollY._value,
animated: false,
});
// we should also update the offset here
listOffset.current[item.key] = scrollY._value;
}
// if header has been collapsed, scroll to HeaderHeight
} else if (scrollY._value >= HeaderHeight) {
if (listOffset.current[item.key] < HeaderHeight ||
listOffset.current[item.key] == null) {
if (item.value) {
item.value.scrollToOffset({
offset: HeaderHeight,
animated: false,
});
listOffset.current[item.key] = HeaderHeight;
}
}
}
}
});
};
const onMomentumScrollBegin = () => {
isListGliding.current = true;
};
const onMomentumScrollEnd = () => {
isListGliding.current = false;
syncScrollOffset();
};
const onScrollEndDrag = () => {
syncScrollOffset();
};
const renderHeader = () => {
const y = scrollY.interpolate({
inputRange: [0, HeaderHeight],
outputRange: [0, -HeaderHeight],
extrapolateRight: 'clamp',
});
return (
<Animated.View style={[styles.header, {transform: [{translateY: y}]}]}>
<View style={{width: "100%",}}>
<View style={{height:250,backgroundColor:'red'}}>
<Image source={require('../../assets/2.jpg')} style={styles.topBG}></Image>
<View style={styles.overlay} ></View>
</View>
<View style={{height:220, borderTopLeftRadius:30,borderTopRightRadius:30, marginTop:-40,backgroundColor:'#fff'}}>
<View style={{flex:0.3,flexDirection:'row',}}>
<View style={{marginTop:-40,marginLeft:50,
marginBottom:15,
shadowColor: '#000',
borderRadius:600,
shadowOffset: {
width: 0,
height: 1,
},
shadowOpacity: 0.2,
shadowRadius: 1.50,
elevation:10}}>
<Thumbnail large source={require('../../assets/4.jpg')} style={{borderWidth:3,borderColor:'white',}}/>
</View>
<View style={{marginLeft:15, marginTop:10}}>
<Text>@itsandysworld</Text>
<Text style={{color:'#c6c6c6'}}>ID: MT1989861</Text>
</View>
</View>
<View style={{flex:1,justifyContent:'space-around'}}>
<View style={{flexDirection:'row',justifyContent:'space-evenly',paddingHorizontal:40,marginTop:20}}>
<View style={{marginHorizontal:15,alignItems:'center',}}>
<Text>504</Text>
<Text style={{color:'#898b90'}}>Following</Text>
</View>
<View style={{borderRightColor:'#f1f1f1',borderRightWidth:2,height:20,marginTop:10}}></View>
<View style={{marginHorizontal:15,alignItems:'center',}}>
<Text>210.8K</Text>
<Text style={{color:'#898b90'}}>Fans</Text>
</View>
<View style={{borderRightColor:'#f1f1f1',borderRightWidth:2,height:20,marginTop:10}}></View>
<View style={{marginHorizontal:15,alignItems:'center',}}>
<Text>2.8m</Text>
<Text style={{color:'#898b90'}}>Hearts</Text>
</View>
</View>
<View style={{flexDirection:'row',justifyContent:'space-evenly',marginTop:5,paddingHorizontal:40, marginTop:40}}>
<Button bordered style={{width:130},styles.outlineBtn}>
<Text style={styles.outlineText}>Message</Text>
</Button>
<Button bordered style={styles.outlineBtn}>
<IconF name="user-check" color="#000"></IconF>
</Button>
<Button bordered style={styles.outlineBtn}>
<IconF name="video" color="#000"></IconF>
</Button>
</View>
<View style={{padding:10,alignItems:'center', marginTop:30, marginBottom:5}}>
<Text style={{color:'#969498'}}>#AndyFam</Text>
<Text style={{color:'#969498'}}>What's up AndyFam <Icon name='heart' color='#969498'></Icon> Don't forget to</Text>
<Text style={{color:'#969498'}}>subscribe to my YouTube</Text>
</View>
<View style={{borderTopColor:'#efefef',borderTopWidth:1,width:'90%',marginTop:25, marginLeft:20,}}></View>
</View>
</View>
</View>
</Animated.View>
);
};
const rednerTab1Item = ({item, index}) => {
return (
<View style={{ flex: 1,
marginLeft: index % 3 === 0 ? 0 : 10,
width: tab1ItemSize,
height: tab1ItemSize,
}}>
<Image style={{justifyContent: 'center',
alignItems: 'center',
width: '100%',
height: '100%',
borderRadius:8,
resizeMode: 'cover',}}
source={item.image } />
{item.isDraft &&
<View style={{
...StyleSheet.absoluteFillObject,
backgroundColor: 'rgba(0,0,0,0.6)',
borderRadius:8,
justifyContent: 'center',
alignItems: 'center',
}} >
<IconF name={item.draftIcon} color='#fff' size={20} style={{marginTop:35}}></IconF>
<Text style={{color:'#fff',marginTop:5,fontSize:12}}>Draft</Text>
<Text style={{color:'#fff',fontSize:12}}>{item.draftCount}</Text>
</View>
}
<View style={styles.bottomIcon}>
<View style={styles.bottomIconRow} >
<Text style={{color:item.textColor,fontSize:12}}><Icon name={item.viewIcon} color={item.iconColor} size={8}></Icon> {item.view}</Text>
<Text style={{color:item.textColor,fontSize:12}}><Icon name={item.heartIcon} color={item.iconColor} size={8}></Icon> {item.heart}</Text>
</View>
</View>
</View>
);
};
const renderLabel = ({route, focused}) => {
return (
<>
{route.key == 'tab1' &&
<Image height={20} width={20} style={{tintColor:focused ?"#fd0d3a" :"#c3c3c3"}} source={require('../../assets/profile_list_icon.png')}/>
}
{route.key == 'tab2' &&
<IconF size={20} name="heart" color={focused ?"#fd0d3a" :"#c3c3c3"} />
}
</>
);
};
const renderScene = ({route}) => {
const focused = route.key === routes[tabIndex].key;
let numCols;
let data;
let renderItem;
switch (route.key) {
case 'tab1':
numCols = 3;
data = DATA;
renderItem = rednerTab1Item;
break;
case 'tab2':
numCols = 3;
data = DATA1;
renderItem = rednerTab1Item;
break;
default:
return null;
}
return (
<TabScene
numCols={numCols}
data={data}
renderItem={renderItem}
scrollY={scrollY}
onMomentumScrollBegin={onMomentumScrollBegin}
onScrollEndDrag={onScrollEndDrag}
onMomentumScrollEnd={onMomentumScrollEnd}
onGetRef={(ref) => {
if (ref) {
const found = listRefArr.current.find((e) => e.key === route.key);
if (!found) {
listRefArr.current.push({
key: route.key,
value: ref,
});
}
}
}}
/>
);
};
const renderTabBar = (props) => {
const y = scrollY.interpolate({
inputRange: [0, HeaderHeight],
outputRange: [HeaderHeight, 0],
extrapolateRight: 'clamp',
});
return (
<Animated.View
style={{
top: 0,
zIndex: 1,
position: 'absolute',
transform: [{translateY: y}],
width: '100%',
}}>
<TabBar
{...props}
onTabPress={({route, preventDefault}) => {
if (isListGliding.current) {
preventDefault();
}
}}
style={styles.tab}
renderLabel={renderLabel}
indicatorStyle={styles.indicator}
/>
</Animated.View>
);
};
const renderTabView = () => {
return (
<TabView
onIndexChange={(index) => setIndex(index)}
navigationState={{index: tabIndex, routes}}
renderScene={renderScene}
renderTabBar={renderTabBar}
initialLayout={{
height: 0,
width: Dimensions.get('window').width,
}}
/>
);
};
return (
<>
<StatusBar
backgroundColor = "#fff"
barStyle = "light-content"
/>
<SafeAreaView style={{flex: 1, backgroundColor:'#fff'}}>
<View style={{flex: 1}}>
{renderTabView()}
{renderHeader()}
</View>
</SafeAreaView>
</>
);
};
const styles = StyleSheet.create({
header: {
top: 0,
height: 300,
width: '100%',
backgroundColor: '#40C4FF',
alignItems: 'center',
justifyContent: 'center',
position: 'absolute',
},
tab: {elevation: 0, shadowOpacity: 0, backgroundColor: '#fff'},
indicator: {backgroundColor: '#fd0d3a'},
container: {
flex: 1,
flexDirection: "column",
backgroundColor:'#fff'
},
row:{
flexDirection:"column",
margin:30,
},
overlay: {
...StyleSheet.absoluteFillObject,
backgroundColor: 'rgba(0,0,0,0.4)',
},
topBG:{
// flex: 1,
width:'100%',
resizeMode: 'cover',
},
outlineBtn:{
borderColor:'#c3c3c3',
paddingHorizontal:15,
borderRadius: 3,
alignItems:'center',
height:45,
// width:130
},
outlineText:{
color:'#000',
fontSize: 15,
textAlign: 'center',
padding:10,
alignSelf:'center',
backgroundColor: 'transparent'
},
tabBarUnderlineStyle:{
backgroundColor:'#fff',
height:2.5,
},
imageThumbnail: {
justifyContent: 'center',
alignItems: 'center',
height: 100,
},
bottomIconRow:{
flex:1,
flexDirection:'row',
justifyContent: 'space-evenly',
paddingHorizontal:0,
},
bottomIcon:{
//backgroundColor:'green',
position:'absolute',
bottom:0,
width:'100%',
marginBottom:8
}
});
export default Profile;