forked from vergnet/application-amicale
Improved doc
This commit is contained in:
parent
03549957a8
commit
fac9d8208e
14 changed files with 433 additions and 151 deletions
|
@ -56,6 +56,7 @@ class HomeScreen extends React.Component<Props> {
|
|||
|
||||
/**
|
||||
* Converts a dateString using Unix Timestamp to a formatted date
|
||||
*
|
||||
* @param dateString {string} The Unix Timestamp representation of a date
|
||||
* @return {string} The formatted output date
|
||||
*/
|
||||
|
@ -80,10 +81,22 @@ class HomeScreen extends React.Component<Props> {
|
|||
this.props.navigation.navigate('SelfMenuScreen');
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a key for the given item
|
||||
*
|
||||
* @param item The item to extract the key from
|
||||
* @return {*} The extracted key
|
||||
*/
|
||||
getKeyExtractor(item: Object) {
|
||||
return item !== undefined ? item.id : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the dataset to be used in the FlatList
|
||||
*
|
||||
* @param fetchedData
|
||||
* @return {*}
|
||||
*/
|
||||
createDataset(fetchedData: Object) {
|
||||
// fetchedData = DATA;
|
||||
let newsData = [];
|
||||
|
@ -110,6 +123,12 @@ class HomeScreen extends React.Component<Props> {
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the dataset associated to the dashboard to be displayed in the FlatList as a section
|
||||
*
|
||||
* @param dashboardData
|
||||
* @return {*}
|
||||
*/
|
||||
generateDashboardDataset(dashboardData: Object) {
|
||||
let dataset = [
|
||||
|
||||
|
@ -145,6 +164,12 @@ class HomeScreen extends React.Component<Props> {
|
|||
return dataset
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a dashboard item
|
||||
*
|
||||
* @param item The item to display
|
||||
* @return {*}
|
||||
*/
|
||||
getDashboardItem(item: Object) {
|
||||
let content = item['content'];
|
||||
if (item['id'] === 'event')
|
||||
|
@ -154,7 +179,7 @@ class HomeScreen extends React.Component<Props> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the time limit depending on the current day:
|
||||
* Gets the time limit depending on the current day:
|
||||
* 17:30 for every day of the week except for thursday 11:30
|
||||
* 00:00 on weekends
|
||||
*/
|
||||
|
@ -170,7 +195,8 @@ class HomeScreen extends React.Component<Props> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the duration (in milliseconds) of an event
|
||||
* Gets the duration (in milliseconds) of an event
|
||||
*
|
||||
* @param event {Object}
|
||||
* @return {number} The number of milliseconds
|
||||
*/
|
||||
|
@ -184,7 +210,7 @@ class HomeScreen extends React.Component<Props> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get events starting after the limit
|
||||
* Gets events starting after the limit
|
||||
*
|
||||
* @param events
|
||||
* @param limit
|
||||
|
@ -202,8 +228,9 @@ class HomeScreen extends React.Component<Props> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get the event with the longest duration in the given array.
|
||||
* Gets the event with the longest duration in the given array.
|
||||
* If all events have the same duration, return the first in the array.
|
||||
*
|
||||
* @param events
|
||||
*/
|
||||
getLongestEvent(events: Array<Object>): Object {
|
||||
|
@ -220,7 +247,7 @@ class HomeScreen extends React.Component<Props> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get events that have not yet ended/started
|
||||
* Gets events that have not yet ended/started
|
||||
*
|
||||
* @param events
|
||||
*/
|
||||
|
@ -243,7 +270,7 @@ class HomeScreen extends React.Component<Props> {
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Gets the event to display in the preview
|
||||
*
|
||||
* @param events
|
||||
* @return {Object}
|
||||
|
@ -266,7 +293,13 @@ class HomeScreen extends React.Component<Props> {
|
|||
return displayEvent;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the event render item.
|
||||
* If a preview is available, it will be rendered inside
|
||||
*
|
||||
* @param content
|
||||
* @return {*}
|
||||
*/
|
||||
getDashboardEventItem(content: Array<Object>) {
|
||||
let icon = 'calendar-range';
|
||||
let title = i18n.t('homeScreen.dashboard.todayEventsTitle');
|
||||
|
@ -310,7 +343,12 @@ class HomeScreen extends React.Component<Props> {
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets a classic dashboard item.
|
||||
*
|
||||
* @param content
|
||||
* @return {*}
|
||||
*/
|
||||
getDashboardMiddleItem(content: Array<Object>) {
|
||||
let proxiwashData = content[0]['data'];
|
||||
let tutorinsaData = content[1]['data'];
|
||||
|
@ -367,6 +405,12 @@ class HomeScreen extends React.Component<Props> {
|
|||
WebBrowser.openBrowserAsync(link);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a render item for the given feed object
|
||||
*
|
||||
* @param item The feed item to display
|
||||
* @return {*}
|
||||
*/
|
||||
getFeedItem(item: Object) {
|
||||
const onImagePress = this.openLink.bind(this, item.full_picture);
|
||||
const onOutLinkPress = this.openLink.bind(this, item.permalink_url);
|
||||
|
@ -382,6 +426,13 @@ class HomeScreen extends React.Component<Props> {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a FlatList render item
|
||||
*
|
||||
* @param item The item to display
|
||||
* @param section The current section
|
||||
* @return {*}
|
||||
*/
|
||||
getRenderItem({item, section}: Object) {
|
||||
return (section['id'] === SECTIONS_ID[0] ?
|
||||
this.getDashboardItem(item) : this.getFeedItem(item));
|
||||
|
|
|
@ -18,7 +18,7 @@ function openWebLink(event, link) {
|
|||
}
|
||||
|
||||
/**
|
||||
* Class defining an about screen. This screen shows the user information about the app and it's author.
|
||||
* Class defining a planning event information page.
|
||||
*/
|
||||
class PlanningDisplayScreen extends React.Component<Props> {
|
||||
|
||||
|
|
|
@ -78,6 +78,9 @@ export default class PlanningScreen extends React.Component<Props, State> {
|
|||
this.onBackButtonPressAndroid = this.onBackButtonPressAndroid.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Captures focus and blur events to hook on android back button
|
||||
*/
|
||||
componentDidMount() {
|
||||
this.onRefresh();
|
||||
this.didFocusSubscription = this.props.navigation.addListener(
|
||||
|
@ -98,6 +101,11 @@ export default class PlanningScreen extends React.Component<Props, State> {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides default android back button behaviour to close the calendar if it was open.
|
||||
*
|
||||
* @return {boolean}
|
||||
*/
|
||||
onBackButtonPressAndroid() {
|
||||
if (this.state.calendarShowing) {
|
||||
this.agendaRef.chooseDay(this.agendaRef.state.selectedDay);
|
||||
|
@ -107,6 +115,13 @@ export default class PlanningScreen extends React.Component<Props, State> {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Function used to check if a row has changed
|
||||
*
|
||||
* @param r1
|
||||
* @param r2
|
||||
* @return {boolean}
|
||||
*/
|
||||
rowHasChanged(r1: Object, r2: Object) {
|
||||
return false;
|
||||
// if (r1 !== undefined && r2 !== undefined)
|
||||
|
@ -115,8 +130,7 @@ export default class PlanningScreen extends React.Component<Props, State> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Refresh data and show a toast if any error occurred
|
||||
* @private
|
||||
* Refreshes data and shows an animation while doing it
|
||||
*/
|
||||
onRefresh = () => {
|
||||
let canRefresh;
|
||||
|
@ -143,14 +157,30 @@ export default class PlanningScreen extends React.Component<Props, State> {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback used when receiving the agenda ref
|
||||
*
|
||||
* @param ref
|
||||
*/
|
||||
onAgendaRef(ref: Object) {
|
||||
this.agendaRef = ref;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback used when a button is pressed to toggle the calendar
|
||||
*
|
||||
* @param isCalendarOpened True is the calendar is already open, false otherwise
|
||||
*/
|
||||
onCalendarToggled(isCalendarOpened: boolean) {
|
||||
this.setState({calendarShowing: isCalendarOpened});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an event render item
|
||||
*
|
||||
* @param item The current event to render
|
||||
* @return {*}
|
||||
*/
|
||||
getRenderItem(item: eventObject) {
|
||||
const onPress = this.props.navigation.navigate.bind(this, 'PlanningDisplayScreen', {data: item});
|
||||
if (item.logo !== null) {
|
||||
|
@ -182,6 +212,11 @@ export default class PlanningScreen extends React.Component<Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an empty render item for an empty date
|
||||
*
|
||||
* @return {*}
|
||||
*/
|
||||
getRenderEmptyDate() {
|
||||
return (
|
||||
<Divider/>
|
||||
|
|
|
@ -10,7 +10,7 @@ type Props = {
|
|||
};
|
||||
|
||||
/**
|
||||
* Class defining an about screen. This screen shows the user information about the app and it's author.
|
||||
* Class defining the proximo about screen.
|
||||
*/
|
||||
export default class ProximoAboutScreen extends React.Component<Props> {
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// @flow
|
||||
|
||||
import * as React from 'react';
|
||||
import {Platform, Image, ScrollView, View} from "react-native";
|
||||
import {Image, Platform, ScrollView, View} from "react-native";
|
||||
import i18n from "i18n-js";
|
||||
import CustomModal from "../../components/CustomModal";
|
||||
import {Avatar, IconButton, List, RadioButton, Searchbar, Subheading, Text, Title, withTheme} from "react-native-paper";
|
||||
|
@ -77,10 +77,10 @@ class ProximoListScreen extends React.Component<Props, State> {
|
|||
|
||||
|
||||
/**
|
||||
* Set the sort mode from state when components are ready
|
||||
* Creates the header content
|
||||
*/
|
||||
componentDidMount() {
|
||||
const button = this.getSortMenu.bind(this);
|
||||
const button = this.getSortMenuButton.bind(this);
|
||||
const title = this.getSearchBar.bind(this);
|
||||
this.props.navigation.setOptions({
|
||||
headerRight: button,
|
||||
|
@ -93,7 +93,50 @@ class ProximoListScreen extends React.Component<Props, State> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Set the current sort mode.
|
||||
* Gets the header search bar
|
||||
*
|
||||
* @return {*}
|
||||
*/
|
||||
getSearchBar() {
|
||||
return (
|
||||
<Searchbar
|
||||
placeholder={i18n.t('proximoScreen.search')}
|
||||
onChangeText={this.onSearchStringChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the sort menu header button
|
||||
*
|
||||
* @return {*}
|
||||
*/
|
||||
getSortMenuButton() {
|
||||
return (
|
||||
<IconButton
|
||||
icon="sort"
|
||||
color={this.colors.text}
|
||||
size={26}
|
||||
onPress={this.onSortMenuPress}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback used when clicking on the sort menu button.
|
||||
* It will open the modal to show a sort selection
|
||||
*/
|
||||
onSortMenuPress() {
|
||||
this.setState({
|
||||
modalCurrentDisplayItem: this.getModalSortMenu()
|
||||
});
|
||||
if (this.modalRef) {
|
||||
this.modalRef.open();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current sort mode.
|
||||
*
|
||||
* @param mode The number representing the mode
|
||||
*/
|
||||
|
@ -121,19 +164,10 @@ class ProximoListScreen extends React.Component<Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
getSearchBar() {
|
||||
return (
|
||||
<Searchbar
|
||||
placeholder={i18n.t('proximoScreen.search')}
|
||||
onChangeText={this.onSearchStringChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* get color depending on quantity available
|
||||
* Gets a color depending on the quantity available
|
||||
*
|
||||
* @param availableStock
|
||||
* @param availableStock The quantity available
|
||||
* @return
|
||||
*/
|
||||
getStockColor(availableStock: number) {
|
||||
|
@ -147,13 +181,21 @@ class ProximoListScreen extends React.Component<Props, State> {
|
|||
return color;
|
||||
}
|
||||
|
||||
sanitizeString(str: string) {
|
||||
/**
|
||||
* Sanitizes the given string to improve search performance
|
||||
*
|
||||
* @param str The string to sanitize
|
||||
* @return {string} The sanitized string
|
||||
*/
|
||||
sanitizeString(str: string): string {
|
||||
return str.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns only the articles whose name contains str. Case and accents insensitive.
|
||||
* @param str
|
||||
* Returns only articles whose name contains the given string.
|
||||
* Case and accents insensitive.
|
||||
*
|
||||
* @param str The string used to filter article names
|
||||
* @returns {[]}
|
||||
*/
|
||||
filterData(str: string) {
|
||||
|
@ -169,12 +211,23 @@ class ProximoListScreen extends React.Component<Props, State> {
|
|||
return filteredData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback used when the search changes
|
||||
*
|
||||
* @param str The new search string
|
||||
*/
|
||||
onSearchStringChange(str: string) {
|
||||
this.setState({
|
||||
currentlyDisplayedData: this.filterData(str)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the modal content depending on the given article
|
||||
*
|
||||
* @param item The article to display
|
||||
* @return {*}
|
||||
*/
|
||||
getModalItemContent(item: Object) {
|
||||
return (
|
||||
<View style={{
|
||||
|
@ -206,6 +259,11 @@ class ProximoListScreen extends React.Component<Props, State> {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the modal content to display a sort menu
|
||||
*
|
||||
* @return {*}
|
||||
*/
|
||||
getModalSortMenu() {
|
||||
return (
|
||||
<View style={{
|
||||
|
@ -254,6 +312,12 @@ class ProximoListScreen extends React.Component<Props, State> {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback used when clicking an article in the list.
|
||||
* It opens the modal to show detailed information about the article
|
||||
*
|
||||
* @param item The article pressed
|
||||
*/
|
||||
onListItemPress(item: Object) {
|
||||
this.setState({
|
||||
modalCurrentDisplayItem: this.getModalItemContent(item)
|
||||
|
@ -263,26 +327,12 @@ class ProximoListScreen extends React.Component<Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
onSortMenuPress() {
|
||||
this.setState({
|
||||
modalCurrentDisplayItem: this.getModalSortMenu()
|
||||
});
|
||||
if (this.modalRef) {
|
||||
this.modalRef.open();
|
||||
}
|
||||
}
|
||||
|
||||
getSortMenu() {
|
||||
return (
|
||||
<IconButton
|
||||
icon="sort"
|
||||
color={this.colors.text}
|
||||
size={26}
|
||||
onPress={this.onSortMenuPress}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a render item for the given article
|
||||
*
|
||||
* @param item The article to render
|
||||
* @return {*}
|
||||
*/
|
||||
renderItem({item}: Object) {
|
||||
const onPress = this.onListItemPress.bind(this, item);
|
||||
return (
|
||||
|
@ -301,10 +351,21 @@ class ProximoListScreen extends React.Component<Props, State> {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts a key for the given article
|
||||
*
|
||||
* @param item The article to extract the key from
|
||||
* @return {*} The extracted key
|
||||
*/
|
||||
keyExtractor(item: Object) {
|
||||
return item.name + item.code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback used when receiving the modal ref
|
||||
*
|
||||
* @param ref
|
||||
*/
|
||||
onModalRef(ref: Object) {
|
||||
this.modalRef = ref;
|
||||
}
|
||||
|
|
|
@ -18,8 +18,8 @@ type State = {
|
|||
}
|
||||
|
||||
/**
|
||||
* Class defining the main proximo screen. This screen shows the different categories of articles
|
||||
* offered by proximo.
|
||||
* Class defining the main proximo screen.
|
||||
* This screen shows the different categories of articles offered by proximo.
|
||||
*/
|
||||
class ProximoMainScreen extends React.Component<Props, State> {
|
||||
|
||||
|
@ -41,6 +41,14 @@ class ProximoMainScreen extends React.Component<Props, State> {
|
|||
this.colors = props.theme.colors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function used to sort items in the list.
|
||||
* Makes the All category stick to the top and sorts the others by name ascending
|
||||
*
|
||||
* @param a
|
||||
* @param b
|
||||
* @return {number}
|
||||
*/
|
||||
static sortFinalData(a: Object, b: Object) {
|
||||
let str1 = a.type.name.toLowerCase();
|
||||
let str2 = b.type.name.toLowerCase();
|
||||
|
@ -59,17 +67,76 @@ class ProximoMainScreen extends React.Component<Props, State> {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates header button
|
||||
*/
|
||||
componentDidMount() {
|
||||
const rightButton = this.getRightButton.bind(this);
|
||||
const rightButton = this.getHeaderButtons.bind(this);
|
||||
this.props.navigation.setOptions({
|
||||
headerRight: rightButton,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback used when the search button is pressed.
|
||||
* This will open a new ProximoListScreen with all items displayed
|
||||
*/
|
||||
onPressSearchBtn() {
|
||||
let searchScreenData = {
|
||||
shouldFocusSearchBar: true,
|
||||
data: {
|
||||
type: {
|
||||
id: "0",
|
||||
name: i18n.t('proximoScreen.all'),
|
||||
icon: 'star'
|
||||
},
|
||||
data: this.articles !== undefined ?
|
||||
this.getAvailableArticles(this.articles, undefined) : []
|
||||
},
|
||||
};
|
||||
this.props.navigation.navigate('ProximoListScreen', searchScreenData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback used when the about button is pressed.
|
||||
* This will open the ProximoAboutScreen
|
||||
*/
|
||||
onPressAboutBtn() {
|
||||
this.props.navigation.navigate('ProximoAboutScreen');
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the header buttons
|
||||
* @return {*}
|
||||
*/
|
||||
getHeaderButtons() {
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
}}>
|
||||
<HeaderButton icon={'magnify'} onPress={this.onPressSearchBtn}/>
|
||||
<HeaderButton icon={'information'} onPress={this.onPressAboutBtn}/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts a key for the given category
|
||||
*
|
||||
* @param item The category to extract the key from
|
||||
* @return {*} The extracted key
|
||||
*/
|
||||
getKeyExtractor(item: Object) {
|
||||
return item !== undefined ? item.type['id'] : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the dataset to be used in the FlatList
|
||||
*
|
||||
* @param fetchedData
|
||||
* @return {*}
|
||||
* */
|
||||
createDataset(fetchedData: Object) {
|
||||
return [
|
||||
{
|
||||
|
@ -133,39 +200,12 @@ class ProximoMainScreen extends React.Component<Props, State> {
|
|||
return availableArticles;
|
||||
}
|
||||
|
||||
onPressSearchBtn() {
|
||||
let searchScreenData = {
|
||||
shouldFocusSearchBar: true,
|
||||
data: {
|
||||
type: {
|
||||
id: "0",
|
||||
name: i18n.t('proximoScreen.all'),
|
||||
icon: 'star'
|
||||
},
|
||||
data: this.articles !== undefined ?
|
||||
this.getAvailableArticles(this.articles, undefined) : []
|
||||
},
|
||||
};
|
||||
this.props.navigation.navigate('ProximoListScreen', searchScreenData);
|
||||
}
|
||||
|
||||
onPressAboutBtn() {
|
||||
this.props.navigation.navigate('ProximoAboutScreen');
|
||||
}
|
||||
|
||||
getRightButton() {
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
flexDirection: 'row',
|
||||
}}>
|
||||
<HeaderButton icon={'magnify'} onPress={this.onPressSearchBtn}/>
|
||||
<HeaderButton icon={'information'} onPress={this.onPressAboutBtn}/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the given category render item
|
||||
*
|
||||
* @param item The category to render
|
||||
* @return {*}
|
||||
*/
|
||||
getRenderItem({item}: Object) {
|
||||
let dataToSend = {
|
||||
shouldFocusSearchBar: false,
|
||||
|
|
|
@ -10,7 +10,7 @@ type Props = {
|
|||
};
|
||||
|
||||
/**
|
||||
* Class defining an about screen. This screen shows the user information about the app and it's author.
|
||||
* Class defining the proxiwash about screen.
|
||||
*/
|
||||
export default class ProxiwashAboutScreen extends React.Component<Props> {
|
||||
|
||||
|
|
|
@ -58,7 +58,6 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
|||
refreshing: false,
|
||||
firstLoading: true,
|
||||
fetchedData: {},
|
||||
// machinesWatched: JSON.parse(dataString),
|
||||
machinesWatched: [],
|
||||
modalCurrentDisplayItem: null,
|
||||
bannerVisible: AsyncStorageManager.getInstance().preferences.proxiwashShowBanner.current === '1',
|
||||
|
@ -97,6 +96,10 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
|||
this.colors = props.theme.colors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback used when closing the banner.
|
||||
* This hides the banner and saves to preferences to prevent it from reopening
|
||||
*/
|
||||
onHideBanner() {
|
||||
this.setState({bannerVisible: false});
|
||||
AsyncStorageManager.getInstance().savePref(
|
||||
|
@ -109,7 +112,7 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
|||
* Setup notification channel for android and add listeners to detect notifications fired
|
||||
*/
|
||||
componentDidMount() {
|
||||
const rightButton = this.getRightButton.bind(this);
|
||||
const rightButton = this.getAboutButton.bind(this);
|
||||
this.props.navigation.setOptions({
|
||||
headerRight: rightButton,
|
||||
});
|
||||
|
@ -134,16 +137,35 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
getDryersKeyExtractor(item: Object) {
|
||||
return item !== undefined ? "dryer" + item.number : undefined;
|
||||
}
|
||||
|
||||
getWashersKeyExtractor(item: Object) {
|
||||
return item !== undefined ? "washer" + item.number : undefined;
|
||||
/**
|
||||
* Callback used when pressing the about button.
|
||||
* This will open the ProxiwashAboutScreen.
|
||||
*/
|
||||
onAboutPress() {
|
||||
this.props.navigation.navigate('ProxiwashAboutScreen');
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup notifications for the machine with the given ID.
|
||||
* Gets the about header button
|
||||
*
|
||||
* @return {*}
|
||||
*/
|
||||
getAboutButton() {
|
||||
return <HeaderButton icon={'information'} onPress={this.onAboutPress}/>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the key for the given item
|
||||
*
|
||||
* @param item The item to extract the key from
|
||||
* @return {*} The extracted key
|
||||
*/
|
||||
getKeyExtractor(item: Object) {
|
||||
return item !== undefined ? item.number : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setups notifications for the machine with the given ID.
|
||||
* One notification will be sent at the end of the program.
|
||||
* Another will be send a few minutes before the end, based on the value of reminderNotifTime
|
||||
*
|
||||
|
@ -162,6 +184,9 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a warning telling the user notifications are disabled for the app
|
||||
*/
|
||||
showNotificationsDisabledWarning() {
|
||||
Alert.alert(
|
||||
i18n.t("proxiwashScreen.modal.notificationErrorTitle"),
|
||||
|
@ -170,7 +195,7 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Stop scheduled notifications for the machine of the given ID.
|
||||
* Stops scheduled notifications for the machine of the given ID.
|
||||
* This will also remove the notification if it was already shown.
|
||||
*
|
||||
* @param machineId The machine's ID
|
||||
|
@ -187,7 +212,7 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Add the given notifications associated to a machine ID to the watchlist, and save the array to the preferences
|
||||
* Adds the given notifications associated to a machine ID to the watchlist, and saves the array to the preferences
|
||||
*
|
||||
* @param machineId
|
||||
*/
|
||||
|
@ -198,7 +223,7 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
|||
}
|
||||
|
||||
/**
|
||||
* remove the given index from the watchlist array and save it to preferences
|
||||
* Removes the given index from the watchlist array and saves it to preferences
|
||||
*
|
||||
* @param index
|
||||
*/
|
||||
|
@ -209,14 +234,12 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Set the given data as the watchlist and save it to preferences
|
||||
* Sets the given data as the watchlist
|
||||
*
|
||||
* @param data
|
||||
*/
|
||||
updateNotificationState(data: Array<Object>) {
|
||||
this.setState({machinesWatched: data});
|
||||
// let prefKey = AsyncStorageManager.getInstance().preferences.proxiwashWatchedMachines.key;
|
||||
// AsyncStorageManager.getInstance().savePref(prefKey, JSON.stringify(data));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -229,6 +252,12 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
|||
return this.state.machinesWatched.indexOf(machineID) !== -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the dataset to be used by the flatlist
|
||||
*
|
||||
* @param fetchedData
|
||||
* @return {*}
|
||||
*/
|
||||
createDataset(fetchedData: Object) {
|
||||
let data = fetchedData;
|
||||
if (AprilFoolsManager.getInstance().isAprilFoolsEnabled()) {
|
||||
|
@ -244,18 +273,25 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
|||
icon: 'tumble-dryer',
|
||||
data: data.dryers === undefined ? [] : data.dryers,
|
||||
extraData: this.state,
|
||||
keyExtractor: this.getDryersKeyExtractor
|
||||
keyExtractor: this.getKeyExtractor
|
||||
},
|
||||
{
|
||||
title: i18n.t('proxiwashScreen.washers'),
|
||||
icon: 'washing-machine',
|
||||
data: data.washers === undefined ? [] : data.washers,
|
||||
extraData: this.state,
|
||||
keyExtractor: this.getWashersKeyExtractor
|
||||
keyExtractor: this.getKeyExtractor
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a modal for the given item
|
||||
*
|
||||
* @param title The title to use
|
||||
* @param item The item to display information for in the modal
|
||||
* @param isDryer True if the given item is a dryer
|
||||
*/
|
||||
showModal(title: string, item: Object, isDryer: boolean) {
|
||||
this.setState({
|
||||
modalCurrentDisplayItem: this.getModalContent(title, item, isDryer)
|
||||
|
@ -265,6 +301,11 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback used when the user clicks on enable notifications for a machine
|
||||
*
|
||||
* @param machineId The machine's id to set notifications for
|
||||
*/
|
||||
onSetupNotificationsPress(machineId: string) {
|
||||
if (this.modalRef) {
|
||||
this.modalRef.close();
|
||||
|
@ -272,6 +313,15 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
|||
this.setupNotifications(machineId)
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the modal content.
|
||||
* This shows information for the given machine.
|
||||
*
|
||||
* @param title The title to use
|
||||
* @param item The item to display information for in the modal
|
||||
* @param isDryer True if the given item is a dryer
|
||||
* @return {*}
|
||||
*/
|
||||
getModalContent(title: string, item: Object, isDryer: boolean) {
|
||||
let button = {
|
||||
text: i18n.t("proxiwashScreen.modal.ok"),
|
||||
|
@ -334,20 +384,21 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
|||
);
|
||||
}
|
||||
|
||||
onAboutPress() {
|
||||
this.props.navigation.navigate('ProxiwashAboutScreen');
|
||||
}
|
||||
|
||||
getRightButton() {
|
||||
return (
|
||||
<HeaderButton icon={'information'} onPress={this.onAboutPress}/>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback used when receiving modal ref
|
||||
*
|
||||
* @param ref
|
||||
*/
|
||||
onModalRef(ref: Object) {
|
||||
this.modalRef = ref;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of machines available
|
||||
*
|
||||
* @param isDryer True if we are only checking for dryer, false for washers
|
||||
* @return {number} The number of machines available
|
||||
*/
|
||||
getMachineAvailableNumber(isDryer: boolean) {
|
||||
let data;
|
||||
if (isDryer)
|
||||
|
@ -362,6 +413,12 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
|||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the section render item
|
||||
*
|
||||
* @param section The section to render
|
||||
* @return {*}
|
||||
*/
|
||||
getRenderSectionHeader({section}: Object) {
|
||||
const isDryer = section.title === i18n.t('proxiwashScreen.dryers');
|
||||
const nbAvailable = this.getMachineAvailableNumber(isDryer);
|
||||
|
@ -401,7 +458,7 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get list item to be rendered
|
||||
* Gets the list item to be rendered
|
||||
*
|
||||
* @param item The object containing the item's FetchedData
|
||||
* @param section The object describing the current SectionList section
|
||||
|
@ -467,7 +524,6 @@ class ProxiwashScreen extends React.Component<Props, State> {
|
|||
refreshOnFocus={true}
|
||||
updateData={this.state.machinesWatched.length}/>
|
||||
</View>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ type Props = {
|
|||
|
||||
/**
|
||||
* Class defining the app's menu screen.
|
||||
* This screen fetches data from etud to render the RU menu
|
||||
*/
|
||||
class SelfMenuScreen extends React.Component<Props> {
|
||||
|
||||
|
@ -33,10 +32,22 @@ class SelfMenuScreen extends React.Component<Props> {
|
|||
this.colors = props.theme.colors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract a key for the given item
|
||||
*
|
||||
* @param item The item to extract the key from
|
||||
* @return {*} The extracted key
|
||||
*/
|
||||
getKeyExtractor(item: Object) {
|
||||
return item !== undefined ? item['name'] : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the dataset to be used in the FlatList
|
||||
*
|
||||
* @param fetchedData
|
||||
* @return {[]}
|
||||
*/
|
||||
createDataset(fetchedData: Object) {
|
||||
let result = [];
|
||||
// Prevent crash by giving a default value when fetchedData is empty (not yet available)
|
||||
|
@ -66,6 +77,12 @@ class SelfMenuScreen extends React.Component<Props> {
|
|||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the render section header
|
||||
*
|
||||
* @param section The section to render the header from
|
||||
* @return {*}
|
||||
*/
|
||||
getRenderSectionHeader({section}: Object) {
|
||||
return (
|
||||
<Card style={{
|
||||
|
@ -92,6 +109,12 @@ class SelfMenuScreen extends React.Component<Props> {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a FlatList render item
|
||||
*
|
||||
* @param item The item to render
|
||||
* @return {*}
|
||||
*/
|
||||
getRenderItem({item}: Object) {
|
||||
return (
|
||||
<Card style={{
|
||||
|
@ -128,6 +151,12 @@ class SelfMenuScreen extends React.Component<Props> {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the given string to make sure it starts with a capital letter
|
||||
*
|
||||
* @param name The string to format
|
||||
* @return {string} The formatted string
|
||||
*/
|
||||
formatName(name: String) {
|
||||
return name.charAt(0) + name.substr(1).toLowerCase();
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ export default class SettingsScreen extends React.Component<Props, State> {
|
|||
state = {
|
||||
nightMode: ThemeManager.getNightMode(),
|
||||
nightModeFollowSystem: AsyncStorageManager.getInstance().preferences.nightModeFollowSystem.current === '1' &&
|
||||
Appearance.getColorScheme() !== 'no-preference',
|
||||
Appearance.getColorScheme() !== 'no-preference',
|
||||
proxiwashNotifPickerSelected: AsyncStorageManager.getInstance().preferences.proxiwashNotifications.current,
|
||||
startScreenPickerSelected: AsyncStorageManager.getInstance().preferences.defaultStartScreen.current,
|
||||
};
|
||||
|
@ -46,7 +46,7 @@ export default class SettingsScreen extends React.Component<Props, State> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Save the value for the proxiwash reminder notification time
|
||||
* Saves the value for the proxiwash reminder notification time
|
||||
*
|
||||
* @param value The value to store
|
||||
*/
|
||||
|
@ -65,7 +65,7 @@ export default class SettingsScreen extends React.Component<Props, State> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Save the value for the proxiwash reminder notification time
|
||||
* Saves the value for the proxiwash reminder notification time
|
||||
*
|
||||
* @param value The value to store
|
||||
*/
|
||||
|
@ -118,7 +118,7 @@ export default class SettingsScreen extends React.Component<Props, State> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Toggle night mode and save it to preferences
|
||||
* Toggles night mode and saves it to preferences
|
||||
*/
|
||||
onToggleNightMode() {
|
||||
ThemeManager.getInstance().setNightMode(!this.state.nightMode);
|
||||
|
@ -138,7 +138,7 @@ export default class SettingsScreen extends React.Component<Props, State> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get a list item using a checkbox control
|
||||
* Gets a list item using a checkbox control
|
||||
*
|
||||
* @param onPressCallback The callback when the checkbox state changes
|
||||
* @param icon The icon name to display on the list item
|
||||
|
@ -178,15 +178,15 @@ export default class SettingsScreen extends React.Component<Props, State> {
|
|||
) : null}
|
||||
{
|
||||
Appearance.getColorScheme() === 'no-preference' || !this.state.nightModeFollowSystem ?
|
||||
this.getToggleItem(
|
||||
this.onToggleNightMode,
|
||||
'theme-light-dark',
|
||||
i18n.t('settingsScreen.nightMode'),
|
||||
this.state.nightMode ?
|
||||
i18n.t('settingsScreen.nightModeSubOn') :
|
||||
i18n.t('settingsScreen.nightModeSubOff'),
|
||||
this.state.nightMode
|
||||
) : null
|
||||
this.getToggleItem(
|
||||
this.onToggleNightMode,
|
||||
'theme-light-dark',
|
||||
i18n.t('settingsScreen.nightMode'),
|
||||
this.state.nightMode ?
|
||||
i18n.t('settingsScreen.nightModeSubOn') :
|
||||
i18n.t('settingsScreen.nightModeSubOff'),
|
||||
this.state.nightMode
|
||||
) : null
|
||||
}
|
||||
<List.Accordion
|
||||
title={i18n.t('settingsScreen.startScreen')}
|
||||
|
@ -209,7 +209,6 @@ export default class SettingsScreen extends React.Component<Props, State> {
|
|||
</List.Accordion>
|
||||
</List.Section>
|
||||
</Card>
|
||||
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -14,14 +14,16 @@ const PC_URL = 'http://planex.insa-toulouse.fr/sallesInfo.php';
|
|||
const CUSTOM_CSS_GENERAL = 'https://etud.insa-toulouse.fr/~amicale_app/custom_css/rooms/customMobile.css';
|
||||
|
||||
/**
|
||||
* Class defining the app's planex screen.
|
||||
* This screen uses a webview to render the planex page
|
||||
* Class defining the app's available rooms screen.
|
||||
* This screen uses a webview to render the page
|
||||
*/
|
||||
export default class AvailableRoomScreen extends React.Component<Props> {
|
||||
|
||||
customInjectedJS: string;
|
||||
customBibInjectedJS: string;
|
||||
|
||||
/**
|
||||
* Defines custom injected JavaScript to improve the page display on mobile
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
this.customInjectedJS =
|
||||
|
|
|
@ -13,14 +13,17 @@ const CUSTOM_CSS_GENERAL = 'https://etud.insa-toulouse.fr/~amicale_app/custom_cs
|
|||
const CUSTOM_CSS_Bib = 'https://etud.insa-toulouse.fr/~amicale_app/custom_css/rooms/customBibMobile.css';
|
||||
|
||||
/**
|
||||
* Class defining the app's planex screen.
|
||||
* This screen uses a webview to render the planex page
|
||||
* Class defining the app's Bib screen.
|
||||
* This screen uses a webview to render the page
|
||||
*/
|
||||
export default class AvailableRoomScreen extends React.Component<Props> {
|
||||
|
||||
customInjectedJS: string;
|
||||
customBibInjectedJS: string;
|
||||
|
||||
/**
|
||||
* Defines custom injected JavaScript to improve the page display on mobile
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
this.customInjectedJS =
|
||||
|
|
|
@ -80,15 +80,23 @@ const OBSERVE_MUTATIONS_INJECTED =
|
|||
' removeAlpha($(this));\n' +
|
||||
'});';
|
||||
/**
|
||||
* Class defining the app's planex screen.
|
||||
* This screen uses a webview to render the planex page
|
||||
* Class defining the app's Planex screen.
|
||||
* This screen uses a webview to render the page
|
||||
*/
|
||||
export default class PlanexScreen extends React.Component<Props, State> {
|
||||
|
||||
customInjectedJS: string;
|
||||
onHideBanner: Function;
|
||||
onGoToSettings: Function;
|
||||
state = {
|
||||
bannerVisible:
|
||||
AsyncStorageManager.getInstance().preferences.planexShowBanner.current === '1' &&
|
||||
AsyncStorageManager.getInstance().preferences.defaultStartScreen.current !== 'Planex',
|
||||
};
|
||||
|
||||
/**
|
||||
* Defines custom injected JavaScript to improve the page display on mobile
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
this.customInjectedJS =
|
||||
|
@ -102,17 +110,15 @@ export default class PlanexScreen extends React.Component<Props, State> {
|
|||
|
||||
this.customInjectedJS +=
|
||||
'removeAlpha();' +
|
||||
'});true;'; // Prevent crash on ios
|
||||
'});true;'; // Prevents crash on ios
|
||||
this.onHideBanner = this.onHideBanner.bind(this);
|
||||
this.onGoToSettings = this.onGoToSettings.bind(this);
|
||||
}
|
||||
|
||||
state = {
|
||||
bannerVisible:
|
||||
AsyncStorageManager.getInstance().preferences.planexShowBanner.current === '1' &&
|
||||
AsyncStorageManager.getInstance().preferences.defaultStartScreen.current !== 'Planex',
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback used when closing the banner.
|
||||
* This hides the banner and saves to preferences to prevent it from reopening
|
||||
*/
|
||||
onHideBanner() {
|
||||
this.setState({bannerVisible: false});
|
||||
AsyncStorageManager.getInstance().savePref(
|
||||
|
@ -121,6 +127,11 @@ export default class PlanexScreen extends React.Component<Props, State> {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback used when the used click on the navigate to settings button.
|
||||
* This will hide the banner and open the SettingsScreen
|
||||
*
|
||||
*/
|
||||
onGoToSettings() {
|
||||
this.onHideBanner();
|
||||
this.props.navigation.navigate('SettingsScreen');
|
||||
|
|
|
@ -39,11 +39,6 @@ export default class AsyncStorageManager {
|
|||
default: '5',
|
||||
current: '',
|
||||
},
|
||||
proxiwashWatchedMachines: {
|
||||
key: 'proxiwashWatchedMachines',
|
||||
default: '[]',
|
||||
current: '',
|
||||
},
|
||||
nightModeFollowSystem: {
|
||||
key: 'nightModeFollowSystem',
|
||||
default: '1',
|
||||
|
|
Loading…
Reference in a new issue