Commit 34b4458b authored by Sébastiaan Versteeg's avatar Sébastiaan Versteeg
Browse files

Merge branch 'feature/status-bar-upgrade' into 'master'

Move status- and appbar to new component and make statusbar translucent

See merge request !73
parents 430b4c44 429411ec
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Linking, ScrollView, Text, View, Animated, TouchableOpacity, Platform } from 'react-native';
import { Linking, ScrollView, Text, View, Animated, TouchableOpacity, Platform, StatusBar } from 'react-native';
import { connect } from 'react-redux';
import Icon from 'react-native-vector-icons/MaterialIcons';
import LinearGradient from 'react-native-linear-gradient';
import Moment from 'moment';
import StandardHeader from './StandardHeader';
import LoadingScreen from './LoadingScreen';
import ErrorScreen from './ErrorScreen';
import { colors } from '../style';
import { back } from '../actions/navigation';
import { STATUSBAR_HEIGHT } from './style/standardHeader';
import styles, { HEADER_MIN_HEIGHT, HEADER_MAX_HEIGHT, HEADER_SCROLL_DISTANCE } from './style/profile';
const getDescription = profile => ([
......@@ -117,39 +120,39 @@ class Profile extends Component {
}
getAppbar = () => {
const headerHeight = this.props.success ? this.scrollY.interpolate({
const headerHeight = this.scrollY.interpolate({
inputRange: [0, HEADER_SCROLL_DISTANCE],
outputRange: [HEADER_MAX_HEIGHT, HEADER_MIN_HEIGHT],
extrapolate: 'clamp',
}) : HEADER_MIN_HEIGHT;
const imageOpacity = this.props.success ? this.scrollY.interpolate({
});
const imageOpacity = this.scrollY.interpolate({
inputRange: [0, HEADER_SCROLL_DISTANCE / 2, HEADER_SCROLL_DISTANCE],
outputRange: [1, 1, 0],
extrapolate: 'clamp',
}) : 0;
});
const imageTranslate = this.scrollY.interpolate({
inputRange: [0, HEADER_SCROLL_DISTANCE],
outputRange: [0, -50],
extrapolate: 'clamp',
});
const textSize = this.props.success ? this.scrollY.interpolate({
const textSize = this.scrollY.interpolate({
inputRange: [0, HEADER_SCROLL_DISTANCE / 2, HEADER_SCROLL_DISTANCE],
outputRange: [30, 30, Platform.OS === 'android' ? 20 : 18],
extrapolate: 'clamp',
}) : 20;
});
const textPosLeft = this.props.success ? this.scrollY.interpolate({
const textPosLeft = this.scrollY.interpolate({
inputRange: [0, HEADER_SCROLL_DISTANCE / 2, HEADER_SCROLL_DISTANCE],
outputRange: [20, 20, Platform.OS === 'android' ? 76 : 20],
extrapolate: 'clamp',
}) : 60;
});
const textPosBottom = this.props.success ? this.scrollY.interpolate({
const textPosBottom = this.scrollY.interpolate({
inputRange: [0, HEADER_SCROLL_DISTANCE / 2, HEADER_SCROLL_DISTANCE],
outputRange: [20, 20, (HEADER_MIN_HEIGHT - this.textHeight) / 2],
outputRange: [20, 20, (HEADER_MIN_HEIGHT - this.textHeight - STATUSBAR_HEIGHT) / 2],
extrapolate: 'clamp',
}) : (HEADER_MIN_HEIGHT - 24) / 2;
});
let textStyle = {
fontSize: textSize,
......@@ -195,7 +198,7 @@ class Profile extends Component {
</TouchableOpacity>
<Animated.Text
style={[styles.title, textStyle]}
>{this.props.success ? this.props.profile.display_name : 'Profiel'}</Animated.Text>
>{this.props.profile.display_name}</Animated.Text>
</Animated.View>
</Animated.View>
);
......@@ -205,33 +208,38 @@ class Profile extends Component {
if (!this.props.hasLoaded) {
return (
<View style={styles.container}>
<StandardHeader />
<LoadingScreen />
{this.getAppbar()}
</View>
);
} else if (!this.props.success) {
return (
<View style={styles.container}>
<StandardHeader />
<ErrorScreen message="Sorry! We couldn't load any data." />
</View>
);
}
return (
<View style={styles.container}>
{
this.props.success ? (
<ScrollView
style={styles.container}
scrollEventThrottle={16}
onScroll={Animated.event([{ nativeEvent: { contentOffset: { y: this.scrollY } } }])}
>
<View style={styles.content}>
{getDescription(this.props.profile)}
{getPersonalInfo(this.props.profile)}
{getAchievements(this.props.profile)}
</View>
</ScrollView>
) : (
<View style={styles.container}>
<ErrorScreen message="Sorry! We couldn't load any data." />
</View>
)
}
<StatusBar
backgroundColor={colors.statusBar}
barStyle="light-content"
translucent
animated
/>
<ScrollView
style={styles.container}
scrollEventThrottle={16}
onScroll={Animated.event([{ nativeEvent: { contentOffset: { y: this.scrollY } } }])}
>
<View style={styles.content}>
{getDescription(this.props.profile)}
{getPersonalInfo(this.props.profile)}
{getAchievements(this.props.profile)}
</View>
</ScrollView>
{this.getAppbar()}
</View>
);
......
import React from 'react';
import { View, StatusBar, TouchableOpacity, Text } from 'react-native';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import Icon from 'react-native-vector-icons/MaterialIcons';
import { colors } from '../style';
import styles from './style/standardHeader';
import * as actions from '../actions/navigation';
const sceneToTitle = (scene) => {
switch (scene) {
case 'welcome':
return 'Welkom';
case 'event':
return 'Evenement';
case 'eventList':
return 'Agenda';
case 'pizza':
return 'Pizza';
case 'profile':
return 'Profiel';
default:
return 'ThaliApp';
}
};
const StandardHeader = props => (
<View>
<View style={styles.statusBar}>
<StatusBar
backgroundColor={colors.statusBar}
translucent
animated
barStyle="light-content"
/>
</View>
<View style={styles.appBar}>
<TouchableOpacity
onPress={props.isFirstScene ? () => props.updateDrawer(!props.drawerOpen) : props.back}
>
<Icon
name={props.isFirstScene ? 'menu' : 'arrow-back'}
style={styles.icon}
size={24}
/>
</TouchableOpacity>
<Text style={styles.title}>{sceneToTitle(props.currentScene)}</Text>
<View style={styles.rightView} />
</View>
</View>
);
StandardHeader.propTypes = {
isFirstScene: PropTypes.bool.isRequired,
currentScene: PropTypes.string.isRequired,
drawerOpen: PropTypes.bool.isRequired,
back: PropTypes.func.isRequired,
updateDrawer: PropTypes.func.isRequired,
};
const mapStateToProps = state => ({
isFirstScene: state.navigation.previousScenes.length === 0,
currentScene: state.navigation.currentScene,
drawerOpen: state.navigation.drawerOpen,
});
const mapDispatchToProps = dispatch => ({
back: () => dispatch(actions.back()),
updateDrawer: isOpen => dispatch(actions.updateDrawer(isOpen)),
});
export default connect(mapStateToProps, mapDispatchToProps)(StandardHeader);
import React from 'react';
import PropTypes from 'prop-types';
import { Text, View, StatusBar, TouchableOpacity, BackHandler } from 'react-native';
import { View, StatusBar, BackHandler } from 'react-native';
import { connect } from 'react-redux';
import Drawer from 'react-native-drawer';
import Icon from 'react-native-vector-icons/MaterialIcons';
import SnackBar from 'react-native-snackbar-component';
import Login from './Login';
import Welcome from './Welcome';
......@@ -12,6 +11,7 @@ import Event from './Event';
import Calendar from './Calendar';
import Profile from './Profile';
import Pizza from './Pizza';
import StandardHeader from './StandardHeader';
import * as actions from '../actions/navigation';
import styles from './style/navigator';
......@@ -47,21 +47,6 @@ const sceneToComponent = (scene) => {
}
};
const sceneToTitle = (scene) => {
switch (scene) {
case 'welcome':
return 'Welkom';
case 'event':
return 'Evenement';
case 'eventList':
return 'Agenda';
case 'pizza':
return 'Pizza';
default:
return 'ThaliApp';
}
};
const ReduxNavigator = (props) => {
const { currentScene, loggedIn, drawerOpen, updateDrawer, loginState,
isFirstScene, back, navigateToWelcome } = props;
......@@ -97,24 +82,7 @@ const ReduxNavigator = (props) => {
onClose={() => updateDrawer(false)}
tapToClose
>
<View style={styles.statusBar}>
<StatusBar backgroundColor={colors.darkMagenta} barStyle="light-content" />
</View>
{currentScene !== 'profile' && (
<View style={styles.appBar}>
<TouchableOpacity
onPress={props.isFirstScene ? () => props.updateDrawer(!props.drawerOpen) : props.back}
>
<Icon
name={props.isFirstScene ? 'menu' : 'arrow-back'}
onClick={props.back}
style={styles.icon}
size={24}
/>
</TouchableOpacity>
<Text style={styles.title}>{sceneToTitle(currentScene)}</Text>
<View style={styles.rightView} />
</View>)}
{currentScene !== 'profile' && <StandardHeader />}
{sceneToComponent(currentScene)}
<SnackBar visible={loginState === 'success'} textMessage={'Login success'} />
</Drawer>);
......@@ -124,7 +92,12 @@ const ReduxNavigator = (props) => {
style={styles.flex}
>
<View style={styles.statusBar}>
<StatusBar backgroundColor={colors.darkMagenta} barStyle="light-content" />
<StatusBar
backgroundColor={colors.statusBar}
barStyle="light-content"
translucent
animated
/>
</View>
<Login />
<SnackBar visible={loginState !== ''} textMessage={loginResult(loginState)} />
......
import { Dimensions } from 'react-native';
import { TOTAL_BAR_HEIGHT } from './navigator';
import { TOTAL_BAR_HEIGHT } from './standardHeader';
import { colors, create } from '../../style';
const styles = create({
......
import { Platform } from 'react-native';
import { colors, create } from '../../style';
const STATUSBAR_HEIGHT = Platform.OS === 'ios' ? 20 : 0;
export const APPBAR_HEIGHT = Platform.OS === 'ios' ? 44 : 56;
export const TOTAL_BAR_HEIGHT = APPBAR_HEIGHT + 20;
import { STATUSBAR_HEIGHT } from './standardHeader';
const styles = create({
flex: {
flex: 1,
},
statusBar: {
height: STATUSBAR_HEIGHT,
android: {
backgroundColor: colors.darkMagenta,
},
ios: {
backgroundColor: colors.magenta,
},
},
appBar: {
backgroundColor: colors.magenta,
height: APPBAR_HEIGHT,
flexDirection: 'row',
android: {
height: APPBAR_HEIGHT,
justifyContent: 'flex-start',
alignItems: 'center',
flexWrap: 'wrap',
elevation: 4,
},
ios: {
borderStyle: 'solid',
borderBottomColor: colors.darkMagenta,
borderBottomWidth: 1,
justifyContent: 'space-between',
alignItems: 'center',
},
},
title: {
color: colors.white,
android: {
fontSize: 20,
fontFamily: 'sans-serif-medium',
},
ios: {
fontSize: 18,
fontFamily: 'System',
fontWeight: '600',
},
},
icon: {
android: {
paddingLeft: 20,
paddingRight: 32,
},
ios: {
paddingLeft: 10,
paddingRight: 16,
},
color: colors.white,
},
rightView: {
ios: {
width: 24 + 16 + 10,
height: 0,
},
},
flex: {
flex: 1,
},
});
......
import { colors, create } from '../../style';
import { APPBAR_HEIGHT } from './navigator';
import { TOTAL_BAR_HEIGHT, STATUSBAR_HEIGHT } from './standardHeader';
export const HEADER_MIN_HEIGHT = APPBAR_HEIGHT;
export const HEADER_MAX_HEIGHT = 200;
export const HEADER_MIN_HEIGHT = TOTAL_BAR_HEIGHT;
export const HEADER_MAX_HEIGHT = 200 + STATUSBAR_HEIGHT;
export const HEADER_SCROLL_DISTANCE = HEADER_MAX_HEIGHT - HEADER_MIN_HEIGHT;
const styles = create({
......@@ -115,7 +115,7 @@ const styles = create({
},
icon: {
fontSize: 24,
marginTop: (HEADER_MIN_HEIGHT - 24) / 2,
marginTop: ((HEADER_MIN_HEIGHT - 24) + STATUSBAR_HEIGHT) / 2,
color: colors.white,
android: {
marginLeft: 16,
......
import { colors, create } from '../../style';
import { STATUSBAR_HEIGHT } from './standardHeader';
const styles = create({
sidebar: {
backgroundColor: colors.white,
......@@ -7,11 +9,12 @@ const styles = create({
alignItems: 'stretch',
},
headerButton: {
height: 148,
height: 148 + STATUSBAR_HEIGHT,
},
headerImage: {
width: null,
height: 148,
height: 148 + STATUSBAR_HEIGHT,
paddingTop: 16 + STATUSBAR_HEIGHT,
padding: 16,
flexDirection: 'column',
justifyContent: 'space-between',
......
import { Platform, StatusBar } from 'react-native';
import { colors, create } from '../../style';
export const STATUSBAR_HEIGHT = Platform.OS === 'ios' ? 20 : StatusBar.currentHeight;
export const APPBAR_HEIGHT = Platform.OS === 'ios' ? 44 : 56;
export const TOTAL_BAR_HEIGHT = APPBAR_HEIGHT + STATUSBAR_HEIGHT;
const styles = create({
statusBar: {
height: STATUSBAR_HEIGHT,
backgroundColor: colors.magenta,
android: {
elevation: 4,
},
},
appBar: {
backgroundColor: colors.magenta,
height: APPBAR_HEIGHT,
flexDirection: 'row',
android: {
height: APPBAR_HEIGHT,
justifyContent: 'flex-start',
alignItems: 'center',
flexWrap: 'wrap',
elevation: 4,
},
ios: {
borderStyle: 'solid',
borderBottomColor: colors.darkMagenta,
borderBottomWidth: 1,
justifyContent: 'space-between',
alignItems: 'center',
},
},
title: {
color: colors.white,
android: {
fontSize: 20,
fontFamily: 'sans-serif-medium',
},
ios: {
fontSize: 18,
fontFamily: 'System',
fontWeight: '600',
},
},
icon: {
android: {
paddingLeft: 20,
paddingRight: 32,
},
ios: {
paddingLeft: 10,
paddingRight: 16,
},
color: colors.white,
},
rightView: {
ios: {
width: 24 + 16 + 10,
height: 0,
},
},
});
export default styles;
import { Dimensions } from 'react-native';
import { TOTAL_BAR_HEIGHT } from './navigator';
import { TOTAL_BAR_HEIGHT } from './standardHeader';
import { colors, create } from '../../style';
const styles = create({
......
......@@ -11,6 +11,7 @@ export const colors = {
textColour: '#313131',
darkGrey: '#373737',
dividerGrey: 'rgba(0, 0, 0, 0.12)',
statusBar: 'rgba(0, 0, 0, 0.20)',
transparent: 'transparent',
lightGreen: '#8fcc74',
darkGreen: '#81b968',
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment