forked from vergnet/application-amicale
Hide qr code fab button when scrolling down using spring animation
This commit is contained in:
parent
7128a68641
commit
f88c98537a
2 changed files with 72 additions and 14 deletions
|
@ -4,7 +4,7 @@ import * as React from 'react';
|
||||||
import {ERROR_TYPE, readData} from "../../utils/WebData";
|
import {ERROR_TYPE, readData} from "../../utils/WebData";
|
||||||
import i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
import {Snackbar} from 'react-native-paper';
|
import {Snackbar} from 'react-native-paper';
|
||||||
import {RefreshControl, SectionList, View} from "react-native";
|
import {Animated, RefreshControl, View} from "react-native";
|
||||||
import ErrorView from "../Custom/ErrorView";
|
import ErrorView from "../Custom/ErrorView";
|
||||||
import BasicLoadingScreen from "../Custom/BasicLoadingScreen";
|
import BasicLoadingScreen from "../Custom/BasicLoadingScreen";
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ type Props = {
|
||||||
createDataset: Function,
|
createDataset: Function,
|
||||||
updateData: number,
|
updateData: number,
|
||||||
itemHeight: number | null,
|
itemHeight: number | null,
|
||||||
|
onScroll: Function,
|
||||||
}
|
}
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
|
@ -178,7 +179,7 @@ export default class WebSectionList extends React.PureComponent<Props, State> {
|
||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
{/*$FlowFixMe*/}
|
{/*$FlowFixMe*/}
|
||||||
<SectionList
|
<Animated.SectionList
|
||||||
sections={dataset}
|
sections={dataset}
|
||||||
extraData={this.props.updateData}
|
extraData={this.props.updateData}
|
||||||
refreshControl={
|
refreshControl={
|
||||||
|
@ -203,6 +204,8 @@ export default class WebSectionList extends React.PureComponent<Props, State> {
|
||||||
}
|
}
|
||||||
removeClippedSubviews={true}
|
removeClippedSubviews={true}
|
||||||
getItemLayout={this.props.itemHeight !== null ? this.itemLayout : undefined}
|
getItemLayout={this.props.itemHeight !== null ? this.itemLayout : undefined}
|
||||||
|
// Animations
|
||||||
|
onScroll={this.props.onScroll}
|
||||||
/>
|
/>
|
||||||
<Snackbar
|
<Snackbar
|
||||||
visible={this.state.snackbarVisible}
|
visible={this.state.snackbarVisible}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {FlatList, StyleSheet, View} from 'react-native';
|
import {Animated, FlatList, StyleSheet, View} from 'react-native';
|
||||||
import i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
import DashboardItem from "../components/Home/EventDashboardItem";
|
import DashboardItem from "../components/Home/EventDashboardItem";
|
||||||
import WebSectionList from "../components/Lists/WebSectionList";
|
import WebSectionList from "../components/Lists/WebSectionList";
|
||||||
|
@ -14,6 +14,7 @@ import ActionsDashBoardItem from "../components/Home/ActionsDashboardItem";
|
||||||
import ConnectionManager from "../managers/ConnectionManager";
|
import ConnectionManager from "../managers/ConnectionManager";
|
||||||
import {CommonActions} from '@react-navigation/native';
|
import {CommonActions} from '@react-navigation/native';
|
||||||
import MaterialHeaderButtons, {Item} from "../components/Custom/HeaderButton";
|
import MaterialHeaderButtons, {Item} from "../components/Custom/HeaderButton";
|
||||||
|
import {AnimatedValue} from "react-native-reanimated";
|
||||||
// import DATA from "../dashboard_data.json";
|
// import DATA from "../dashboard_data.json";
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,6 +27,8 @@ const SECTIONS_ID = [
|
||||||
'news_feed'
|
'news_feed'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const AnimatedFAB = Animated.createAnimatedComponent(FAB);
|
||||||
|
|
||||||
const REFRESH_TIME = 1000 * 20; // Refresh every 20 seconds
|
const REFRESH_TIME = 1000 * 20; // Refresh every 20 seconds
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
@ -34,19 +37,35 @@ type Props = {
|
||||||
theme: Object,
|
theme: Object,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type State = {
|
||||||
|
showFab: boolean,
|
||||||
|
fabPosition: AnimatedValue
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class defining the app's home screen
|
* Class defining the app's home screen
|
||||||
*/
|
*/
|
||||||
class HomeScreen extends React.Component<Props> {
|
class HomeScreen extends React.Component<Props, State> {
|
||||||
|
|
||||||
colors: Object;
|
colors: Object;
|
||||||
|
|
||||||
isLoggedIn: boolean | null;
|
isLoggedIn: boolean | null;
|
||||||
|
isAnimationDownPlaying: boolean;
|
||||||
|
isAnimationUpPlaying: boolean;
|
||||||
|
|
||||||
|
downAnimation;
|
||||||
|
upAnimation;
|
||||||
|
|
||||||
|
state = {
|
||||||
|
showFab: true,
|
||||||
|
fabPosition: new Animated.Value(0),
|
||||||
|
};
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.colors = props.theme.colors;
|
this.colors = props.theme.colors;
|
||||||
|
this.isAnimationDownPlaying = false;
|
||||||
|
this.isAnimationUpPlaying = false;
|
||||||
this.isLoggedIn = null;
|
this.isLoggedIn = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,7 +398,7 @@ class HomeScreen extends React.Component<Props> {
|
||||||
}
|
}
|
||||||
|
|
||||||
dashboardRowRenderItem = ({item}: Object) => {
|
dashboardRowRenderItem = ({item}: Object) => {
|
||||||
return(
|
return (
|
||||||
<SquareDashboardItem
|
<SquareDashboardItem
|
||||||
color={item.color}
|
color={item.color}
|
||||||
icon={item.icon}
|
icon={item.icon}
|
||||||
|
@ -398,14 +417,14 @@ class HomeScreen extends React.Component<Props> {
|
||||||
*/
|
*/
|
||||||
getDashboardRow(content: Array<Object>) {
|
getDashboardRow(content: Array<Object>) {
|
||||||
return <FlatList
|
return <FlatList
|
||||||
data={content}
|
data={content}
|
||||||
renderItem={this.dashboardRowRenderItem}
|
renderItem={this.dashboardRowRenderItem}
|
||||||
horizontal={true}
|
horizontal={true}
|
||||||
contentContainerStyle={{
|
contentContainerStyle={{
|
||||||
marginLeft: 'auto',
|
marginLeft: 'auto',
|
||||||
marginRight: 'auto',
|
marginRight: 'auto',
|
||||||
}}
|
}}
|
||||||
/>;
|
/>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -441,6 +460,38 @@ class HomeScreen extends React.Component<Props> {
|
||||||
|
|
||||||
openScanner = () => this.props.navigation.navigate("scanner");
|
openScanner = () => this.props.navigation.navigate("scanner");
|
||||||
|
|
||||||
|
onScroll = ({nativeEvent}: Object) => {
|
||||||
|
if (nativeEvent.velocity.y > 0.2) { // Go down
|
||||||
|
if (!this.isAnimationDownPlaying) {
|
||||||
|
this.isAnimationDownPlaying = true;
|
||||||
|
if (this.isAnimationUpPlaying)
|
||||||
|
this.upAnimation.stop();
|
||||||
|
this.downAnimation = Animated.spring(this.state.fabPosition, {
|
||||||
|
toValue: 100,
|
||||||
|
duration: 50,
|
||||||
|
useNativeDriver: true,
|
||||||
|
});
|
||||||
|
this.downAnimation.start(() => {
|
||||||
|
this.isAnimationDownPlaying = false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else if (nativeEvent.velocity.y < -0.2) { // Go up
|
||||||
|
if (!this.isAnimationUpPlaying) {
|
||||||
|
this.isAnimationUpPlaying = true;
|
||||||
|
if (this.isAnimationDownPlaying)
|
||||||
|
this.downAnimation.stop();
|
||||||
|
this.upAnimation = Animated.spring(this.state.fabPosition, {
|
||||||
|
toValue: 0,
|
||||||
|
duration: 50,
|
||||||
|
useNativeDriver: true,
|
||||||
|
});
|
||||||
|
this.upAnimation.start(() => {
|
||||||
|
this.isAnimationUpPlaying = false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const nav = this.props.navigation;
|
const nav = this.props.navigation;
|
||||||
return (
|
return (
|
||||||
|
@ -453,9 +504,13 @@ class HomeScreen extends React.Component<Props> {
|
||||||
fetchUrl={DATA_URL}
|
fetchUrl={DATA_URL}
|
||||||
renderItem={this.getRenderItem}
|
renderItem={this.getRenderItem}
|
||||||
itemHeight={FEED_ITEM_HEIGHT}
|
itemHeight={FEED_ITEM_HEIGHT}
|
||||||
|
onScroll={this.onScroll}
|
||||||
/>
|
/>
|
||||||
<FAB
|
<AnimatedFAB
|
||||||
style={styles.fab}
|
style={{
|
||||||
|
...styles.fab,
|
||||||
|
transform: [{translateY: this.state.fabPosition}]
|
||||||
|
}}
|
||||||
icon="qrcode-scan"
|
icon="qrcode-scan"
|
||||||
onPress={this.openScanner}
|
onPress={this.openScanner}
|
||||||
/>
|
/>
|
||||||
|
|
Loading…
Reference in a new issue