application-amicale/screens/Planning/PlanningScreen.js

259 lines
8.7 KiB
JavaScript
Raw Normal View History

// @flow
import * as React from 'react';
2020-03-08 12:05:22 +01:00
import {BackHandler, View} from 'react-native';
2019-06-25 22:20:24 +02:00
import i18n from "i18n-js";
import {LocaleConfig} from 'react-native-calendars';
2020-03-08 14:22:03 +01:00
import WebDataManager from "../../utils/WebDataManager";
2020-03-22 11:21:55 +01:00
import type {eventObject} from "../../utils/PlanningEventManager";
2020-03-08 14:22:03 +01:00
import PlanningEventManager from '../../utils/PlanningEventManager';
2020-03-08 12:05:22 +01:00
import {Avatar, Divider, List} from 'react-native-paper';
2020-03-08 14:22:03 +01:00
import CustomAgenda from "../../components/CustomAgenda";
2019-09-15 15:12:26 +02:00
LocaleConfig.locales['fr'] = {
2019-11-14 15:23:25 +01:00
monthNames: ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'],
monthNamesShort: ['Janv.', 'Févr.', 'Mars', 'Avril', 'Mai', 'Juin', 'Juil.', 'Août', 'Sept.', 'Oct.', 'Nov.', 'Déc.'],
dayNames: ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'],
dayNamesShort: ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam'],
today: 'Aujourd\'hui'
};
2019-06-25 22:20:24 +02:00
type Props = {
navigation: Object,
}
2019-09-15 15:12:26 +02:00
type State = {
refreshing: boolean,
agendaItems: Object,
calendarShowing: boolean,
2019-09-15 15:12:26 +02:00
};
2020-03-22 10:00:35 +01:00
const FETCH_URL = "https://www.amicale-insat.fr/api/event/list";
2020-03-08 12:05:22 +01:00
const AGENDA_MONTH_SPAN = 3;
2019-09-15 15:12:26 +02:00
2019-06-29 15:43:57 +02:00
/**
* Class defining the app's planning screen
*/
2019-09-15 15:12:26 +02:00
export default class PlanningScreen extends React.Component<Props, State> {
agendaRef: Object;
2019-09-15 15:12:26 +02:00
webDataManager: WebDataManager;
lastRefresh: Date;
minTimeBetweenRefresh = 60;
2019-11-14 15:23:25 +01:00
didFocusSubscription: Function;
willBlurSubscription: Function;
2020-02-11 01:05:24 +01:00
2020-01-31 16:51:43 +01:00
state = {
refreshing: false,
agendaItems: {},
calendarShowing: false,
};
2020-02-23 18:15:30 +01:00
onRefresh: Function;
onCalendarToggled: Function;
getRenderItem: Function;
getRenderEmptyDate: Function;
onAgendaRef: Function;
onCalendarToggled: Function;
onBackButtonPressAndroid: Function;
2020-03-21 20:32:28 +01:00
currentDate = PlanningEventManager.getDateOnlyString(PlanningEventManager.getCurrentDateString());
2020-02-23 18:15:30 +01:00
2019-09-15 15:12:26 +02:00
constructor(props: any) {
super(props);
this.webDataManager = new WebDataManager(FETCH_URL);
if (i18n.currentLocale().startsWith("fr")) {
LocaleConfig.defaultLocale = 'fr';
}
2020-02-11 01:05:24 +01:00
// Create references for functions required in the render function
2020-02-23 18:15:30 +01:00
this.onRefresh = this.onRefresh.bind(this);
2020-02-11 01:05:24 +01:00
this.onCalendarToggled = this.onCalendarToggled.bind(this);
this.getRenderItem = this.getRenderItem.bind(this);
this.getRenderEmptyDate = this.getRenderEmptyDate.bind(this);
2020-02-23 18:15:30 +01:00
this.onAgendaRef = this.onAgendaRef.bind(this);
2020-02-11 01:05:24 +01:00
this.onCalendarToggled = this.onCalendarToggled.bind(this);
this.onBackButtonPressAndroid = this.onBackButtonPressAndroid.bind(this);
}
2020-03-29 15:59:25 +02:00
/**
* Captures focus and blur events to hook on android back button
*/
2019-09-15 15:12:26 +02:00
componentDidMount() {
2020-02-23 18:15:30 +01:00
this.onRefresh();
this.didFocusSubscription = this.props.navigation.addListener(
'focus',
() =>
BackHandler.addEventListener(
'hardwareBackPress',
this.onBackButtonPressAndroid
)
);
2019-11-14 15:23:25 +01:00
this.willBlurSubscription = this.props.navigation.addListener(
'blur',
2020-01-31 16:51:43 +01:00
() =>
BackHandler.removeEventListener(
'hardwareBackPress',
this.onBackButtonPressAndroid
)
);
}
2020-03-29 15:59:25 +02:00
/**
* Overrides default android back button behaviour to close the calendar if it was open.
*
* @return {boolean}
*/
2020-02-11 01:05:24 +01:00
onBackButtonPressAndroid() {
if (this.state.calendarShowing) {
2019-11-14 15:23:25 +01:00
this.agendaRef.chooseDay(this.agendaRef.state.selectedDay);
return true;
} else {
return false;
}
};
2020-03-29 15:59:25 +02:00
/**
* Function used to check if a row has changed
*
* @param r1
* @param r2
* @return {boolean}
*/
2019-09-15 15:12:26 +02:00
rowHasChanged(r1: Object, r2: Object) {
2020-03-08 12:05:22 +01:00
return false;
// if (r1 !== undefined && r2 !== undefined)
// return r1.title !== r2.title;
// else return !(r1 === undefined && r2 === undefined);
2019-09-15 15:12:26 +02:00
}
/**
2020-03-29 15:59:25 +02:00
* Refreshes data and shows an animation while doing it
2019-09-15 15:12:26 +02:00
*/
2020-02-23 18:15:30 +01:00
onRefresh = () => {
let canRefresh;
if (this.lastRefresh !== undefined)
canRefresh = (new Date().getTime() - this.lastRefresh.getTime()) / 1000 > this.minTimeBetweenRefresh;
else
canRefresh = true;
if (canRefresh) {
this.setState({refreshing: true});
this.webDataManager.readData()
.then((fetchedData) => {
this.setState({
refreshing: false,
2020-03-22 10:37:59 +01:00
agendaItems: PlanningEventManager.generateEventAgenda(fetchedData, AGENDA_MONTH_SPAN)
});
this.lastRefresh = new Date();
})
2020-03-22 10:37:59 +01:00
.catch(() => {
this.setState({
refreshing: false,
});
2019-09-15 15:12:26 +02:00
});
}
2019-09-15 15:12:26 +02:00
};
2020-03-29 15:59:25 +02:00
/**
* Callback used when receiving the agenda ref
*
* @param ref
*/
onAgendaRef(ref: Object) {
2020-02-11 01:05:24 +01:00
this.agendaRef = ref;
}
2020-03-29 15:59:25 +02:00
/**
* Callback used when a button is pressed to toggle the calendar
*
* @param isCalendarOpened True is the calendar is already open, false otherwise
*/
2020-02-23 18:15:30 +01:00
onCalendarToggled(isCalendarOpened: boolean) {
this.setState({calendarShowing: isCalendarOpened});
2020-02-11 01:05:24 +01:00
}
2020-03-29 15:59:25 +02:00
/**
* Gets an event render item
*
* @param item The current event to render
* @return {*}
*/
2020-03-22 11:21:55 +01:00
getRenderItem(item: eventObject) {
2020-03-22 10:37:59 +01:00
const onPress = this.props.navigation.navigate.bind(this, 'PlanningDisplayScreen', {data: item});
if (item.logo !== null) {
return (
<View>
<Divider/>
<List.Item
title={item.title}
description={PlanningEventManager.getFormattedEventTime(item["date_begin"], item["date_end"])}
left={() => <Avatar.Image
source={{uri: item.logo}}
style={{backgroundColor: 'transparent'}}
/>}
onPress={onPress}
/>
</View>
);
} else {
return (
<View>
<Divider/>
<List.Item
title={item.title}
description={PlanningEventManager.getFormattedEventTime(item["date_begin"], item["date_end"])}
onPress={onPress}
/>
</View>
);
}
}
2020-03-29 15:59:25 +02:00
/**
* Gets an empty render item for an empty date
*
* @return {*}
*/
2020-03-22 10:37:59 +01:00
getRenderEmptyDate() {
return (
<Divider/>
);
}
2019-09-15 15:12:26 +02:00
render() {
2020-02-11 01:05:24 +01:00
// console.log("rendering PlanningScreen");
2019-09-15 15:12:26 +02:00
return (
<CustomAgenda
2020-03-06 09:12:56 +01:00
// the list of items that have to be displayed in agenda. If you want to render item as empty date
// the value of date key kas to be an empty array []. If there exists no value for date key it is
// considered that the date in question is not yet loaded
items={this.state.agendaItems}
// initially selected day
selected={this.currentDate}
// Minimum date that can be selected, dates before minDate will be grayed out. Default = undefined
minDate={this.currentDate}
// Max amount of months allowed to scroll to the past. Default = 50
pastScrollRange={1}
// Max amount of months allowed to scroll to the future. Default = 50
futureScrollRange={AGENDA_MONTH_SPAN}
// If provided, a standard RefreshControl will be added for "Pull to Refresh" functionality. Make sure to also set the refreshing prop correctly.
onRefresh={this.onRefresh}
// callback that fires when the calendar is opened or closed
onCalendarToggled={this.onCalendarToggled}
// Set this true while waiting for new data from a refresh
refreshing={this.state.refreshing}
renderItem={this.getRenderItem}
renderEmptyDate={this.getRenderEmptyDate}
rowHasChanged={this.rowHasChanged}
// If firstDay=1 week starts from Monday. Note that dayNames and dayNamesShort should still start from Sunday.
firstDay={1}
// ref to this agenda in order to handle back button event
onRef={this.onAgendaRef}
2020-03-06 09:12:56 +01:00
/>
2019-06-25 22:20:24 +02:00
);
}
}