// @flow import * as React from 'react'; import {Content, H1, H2, H3, Text} from 'native-base'; import i18n from "i18n-js"; import {View, Image} from "react-native"; import ThemeManager from "../utils/ThemeManager"; import {Linking} from "expo"; import BaseContainer from "../components/BaseContainer"; import {Agenda} from 'react-native-calendars'; import HTML from 'react-native-render-html'; import Touchable from 'react-native-platform-touchable'; import Modalize from 'react-native-modalize'; import WebDataManager from "../utils/WebDataManager"; type Props = { navigation: Object, } type State = { modalCurrentDisplayItem: Object, refreshing: boolean, agendaItems: Object, }; const FETCH_URL = "https://amicale-insat.fr/event/json/list"; const AGENDA_MONTH_SPAN = 6; /** * Opens a link in the device's browser * @param link The link to open */ function openWebLink(link) { Linking.openURL(link).catch((err) => console.error('Error opening link', err)); } /** * Class defining the app's planning screen */ export default class PlanningScreen extends React.Component { modalRef: { current: null | Modalize }; webDataManager: WebDataManager; lastRefresh: Date; minTimeBetweenRefresh = 60; constructor(props: any) { super(props); this.modalRef = React.createRef(); this.webDataManager = new WebDataManager(FETCH_URL); } componentDidMount() { this._onRefresh(); } state = { modalCurrentDisplayItem: {}, refreshing: false, agendaItems: {}, }; getCurrentDate() { let today = new Date(); return this.getFormattedDate(today); } getFormattedDate(date: Date) { let dd = String(date.getDate()).padStart(2, '0'); let mm = String(date.getMonth() + 1).padStart(2, '0'); //January is 0! let yyyy = date.getFullYear(); return yyyy + '-' + mm + '-' + dd; } generateEmptyCalendar() { let end = new Date(new Date().setMonth(new Date().getMonth() + AGENDA_MONTH_SPAN + 1)); let daysOfYear = {}; for (let d = new Date(2019, 8, 1); d <= end; d.setDate(d.getDate() + 1)) { daysOfYear[this.getFormattedDate(new Date(d))] = [] } return daysOfYear; } getModalContent() { return (

{this.state.modalCurrentDisplayItem.title}

{this.getFormattedTime(this.state.modalCurrentDisplayItem)}

{this.state.modalCurrentDisplayItem.logo !== null ? : } {this.state.modalCurrentDisplayItem.description !== null ? // Surround description with div to allow text styling if the description is not html " + this.state.modalCurrentDisplayItem.description + ""} tagsStyles={{ p: {color: ThemeManager.getCurrentThemeVariables().textColor}, div: {color: ThemeManager.getCurrentThemeVariables().textColor} }}/> : }
); } showItemDetails(item: Object) { this.setState({ modalCurrentDisplayItem: item, }); if (this.modalRef.current) { this.modalRef.current.open(); } } getRenderItem(item: Object) { return ( this.showItemDetails(item)}> {this.getFormattedTime(item)}

{item.title}

{item.logo !== null ? : }
); } getRenderEmptyDate() { return ( ); } rowHasChanged(r1: Object, r2: Object) { if (r1 !== undefined && r2 !== undefined) return r1.title !== r2.title; else return !(r1 === undefined && r2 === undefined); } /** * Refresh data and show a toast if any error occurred * @private */ _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, }); this.generateEventAgenda(fetchedData); this.lastRefresh = new Date(); }) .catch((err) => { this.setState({ refreshing: false, }); console.log(err); }); } }; generateEventAgenda(eventList: Array) { let agendaItems = this.generateEmptyCalendar(); for (let i = 0; i < eventList.length; i++) { if (agendaItems[this.getEventStartDate(eventList[i])] !== undefined) { this.pushEventInOrder(agendaItems, eventList[i], this.getEventStartDate(eventList[i])); } } this.setState({agendaItems: agendaItems}) } pushEventInOrder(agendaItems: Object, event: Object, startDate: string) { if (agendaItems[startDate].length === 0) agendaItems[startDate].push(event); else { for (let i = 0; i < agendaItems[startDate].length; i++) { if (this.isEventBefore(event, agendaItems[startDate][i])) { agendaItems[startDate].splice(i, 0, event); break; } else if (i === agendaItems[startDate].length - 1) { agendaItems[startDate].push(event); break; } } } } isEventBefore(event1: Object, event2: Object) { let date1 = new Date(); let date2 = new Date(); let timeArray = this.getEventStartTime(event1).split(":"); date1.setHours(parseInt(timeArray[0]), parseInt(timeArray[1])); timeArray = this.getEventStartTime(event2).split(":"); date2.setHours(parseInt(timeArray[0]), parseInt(timeArray[1])); return date1 < date2; } getEventStartDate(event: Object) { return event.date_begin.split(" ")[0]; } getEventStartTime(event: Object) { if (event !== undefined && Object.keys(event).length > 0 && event.date_begin !== null) return this.formatTime(event.date_begin.split(" ")[1]); else return ""; } getEventEndTime(event: Object) { if (event !== undefined && Object.keys(event).length > 0 && event.date_end !== null) return this.formatTime(event.date_end.split(" ")[1]); else return ""; } getFormattedTime(event: Object) { if (this.getEventEndTime(event) !== "") return this.getEventStartTime(event) + " - " + this.getEventEndTime(event) else return this.getEventStartTime(event); } formatTime(time: string) { let array = time.split(':'); return array[0] + ':' + array[1]; } onModalClosed() { this.setState({ modalCurrentDisplayItem: {}, }); } render() { const nav = this.props.navigation; return ( this.onModalClosed()}> {this.getModalContent()} this._onRefresh()} // Set this true while waiting for new data from a refresh refreshing={this.state.refreshing} renderItem={(item) => this.getRenderItem(item)} renderEmptyDate={() => this.getRenderEmptyDate()} rowHasChanged={() => this.rowHasChanged()} // agenda theme theme={{ backgroundColor: ThemeManager.getCurrentThemeVariables().agendaBackgroundColor, calendarBackground: ThemeManager.getCurrentThemeVariables().containerBgColor, textSectionTitleColor: ThemeManager.getCurrentThemeVariables().listNoteColor, selectedDayBackgroundColor: ThemeManager.getCurrentThemeVariables().brandPrimary, selectedDayTextColor: '#ffffff', todayTextColor: ThemeManager.getCurrentThemeVariables().brandPrimary, dayTextColor: ThemeManager.getCurrentThemeVariables().textColor, textDisabledColor: ThemeManager.getCurrentThemeVariables().textDisabledColor, dotColor: ThemeManager.getCurrentThemeVariables().brandPrimary, selectedDotColor: '#ffffff', arrowColor: 'orange', monthTextColor: ThemeManager.getCurrentThemeVariables().brandPrimary, indicatorColor: ThemeManager.getCurrentThemeVariables().brandPrimary, textDayFontWeight: '300', textMonthFontWeight: 'bold', textDayHeaderFontWeight: '300', textDayFontSize: 16, textMonthFontSize: 16, textDayHeaderFontSize: 16, agendaDayTextColor: ThemeManager.getCurrentThemeVariables().listNoteColor, agendaDayNumColor: ThemeManager.getCurrentThemeVariables().listNoteColor, agendaTodayColor: ThemeManager.getCurrentThemeVariables().brandPrimary, agendaKnobColor: ThemeManager.getCurrentThemeVariables().brandPrimary, // Fix for days hiding behind knob 'stylesheet.calendar.header': { week: { marginTop: 0, flexDirection: 'row', justifyContent: 'space-between' } } }} /> ); } }