Improved theme handling and performance

This commit is contained in:
keplyx 2020-03-09 23:15:13 +01:00
parent da24621c67
commit 7bac5a6ddc
16 changed files with 183 additions and 176 deletions

View file

@ -1,11 +1,10 @@
// @flow // @flow
import * as React from 'react'; import * as React from 'react';
import {MaterialCommunityIcons} from "@expo/vector-icons";
import {View} from "react-native"; import {View} from "react-native";
import HTML from "react-native-render-html"; import HTML from "react-native-render-html";
import i18n from "i18n-js"; import i18n from "i18n-js";
import {Avatar, Card, Text, withTheme, Button} from 'react-native-paper'; import {Avatar, Button, Card, withTheme} from 'react-native-paper';
import PlanningEventManager from "../utils/PlanningEventManager"; import PlanningEventManager from "../utils/PlanningEventManager";

View file

@ -1,5 +1,5 @@
import * as React from 'react'; import * as React from 'react';
import {Card, Avatar, List, Text, withTheme} from 'react-native-paper'; import {Avatar, Card, Text, withTheme} from 'react-native-paper';
import {View} from "react-native"; import {View} from "react-native";
import ProxiwashConstants from "../constants/ProxiwashConstants"; import ProxiwashConstants from "../constants/ProxiwashConstants";

View file

@ -21,7 +21,7 @@ type State = {
/** /**
* Class used to define a navigation drawer * Class used to define a navigation drawer
*/ */
export default class SideBar extends React.Component<Props, State> { export default class SideBar extends React.PureComponent<Props, State> {
dataSet: Array<Object>; dataSet: Array<Object>;
@ -122,11 +122,6 @@ export default class SideBar extends React.Component<Props, State> {
this.getRenderItem = this.getRenderItem.bind(this); this.getRenderItem = this.getRenderItem.bind(this);
} }
shouldComponentUpdate(nextProps: Props, nextState: State): boolean {
return nextState.active !== this.state.active;
}
onListItemPress(item: Object) { onListItemPress(item: Object) {
if (item.link === undefined) if (item.link === undefined)
this.props.navigation.navigate(item.route); this.props.navigation.navigate(item.route);

View file

@ -36,7 +36,7 @@ const MIN_REFRESH_TIME = 5 * 1000;
* @prop fontSize {number} The icon size. Use 26 if unspecified * @prop fontSize {number} The icon size. Use 26 if unspecified
* @prop width {number} The icon width. Use 30 if unspecified * @prop width {number} The icon width. Use 30 if unspecified
*/ */
export default class WebSectionList extends React.Component<Props, State> { export default class WebSectionList extends React.PureComponent<Props, State> {
static defaultProps = { static defaultProps = {
renderSectionHeader: null, renderSectionHeader: null,

View file

@ -3,8 +3,7 @@
import * as React from 'react'; import * as React from 'react';
import {View} from 'react-native'; import {View} from 'react-native';
import WebView from "react-native-webview"; import WebView from "react-native-webview";
import ThemeManager from "../utils/ThemeManager"; import {ActivityIndicator, withTheme} from 'react-native-paper';
import {ActivityIndicator} from 'react-native-paper';
import HeaderButton from "./HeaderButton"; import HeaderButton from "./HeaderButton";
type Props = { type Props = {
@ -24,28 +23,31 @@ type Props = {
/** /**
* Class defining a webview screen. * Class defining a webview screen.
*/ */
export default class WebViewScreen extends React.Component<Props> { class WebViewScreen extends React.PureComponent<Props> {
static defaultProps = { static defaultProps = {
hasBackButton: false, hasBackButton: false,
hasSideMenu: true, hasSideMenu: true,
hasFooter: true, hasFooter: true,
}; };
webviewArray: Array<WebView> = []; webviewRef: Object;
onRefreshClicked: Function; onRefreshClicked: Function;
onWebviewRef: Function; onWebviewRef: Function;
onGoBackWebview: Function; onGoBackWebview: Function;
onGoForwardWebview: Function; onGoForwardWebview: Function;
onOpenWebLink: Function; getRenderLoading: Function;
constructor() { colors: Object;
super();
constructor(props) {
super(props);
this.onRefreshClicked = this.onRefreshClicked.bind(this); this.onRefreshClicked = this.onRefreshClicked.bind(this);
this.onWebviewRef = this.onWebviewRef.bind(this); this.onWebviewRef = this.onWebviewRef.bind(this);
this.onGoBackWebview = this.onGoBackWebview.bind(this); this.onGoBackWebview = this.onGoBackWebview.bind(this);
this.onGoForwardWebview = this.onGoForwardWebview.bind(this); this.onGoForwardWebview = this.onGoForwardWebview.bind(this);
this.onOpenWebLink = this.onOpenWebLink.bind(this); this.getRenderLoading = this.getRenderLoading.bind(this);
this.colors = props.theme.colors;
} }
componentDidMount() { componentDidMount() {
@ -73,38 +75,28 @@ export default class WebViewScreen extends React.Component<Props> {
}; };
onRefreshClicked() { onRefreshClicked() {
for (let view of this.webviewArray) { if (this.webviewRef !== null)
if (view !== null) this.webviewRef.reload();
view.reload();
}
} }
onGoBackWebview() { onGoBackWebview() {
for (let view of this.webviewArray) { if (this.webviewRef !== null)
if (view !== null) this.webviewRef.goBack();
view.goBack();
}
} }
onGoForwardWebview() { onGoForwardWebview() {
for (let view of this.webviewArray) { if (this.webviewRef !== null)
if (view !== null) this.webviewRef.goForward();
view.goForward();
}
} }
onOpenWebLink() { onWebviewRef(ref: Object) {
this.openWebLink(this.props.data[0]['url']) this.webviewRef = ref
}
onWebviewRef(ref: WebView) {
this.webviewArray.push(ref)
} }
getRenderLoading() { getRenderLoading() {
return ( return (
<View style={{ <View style={{
backgroundColor: ThemeManager.getCurrentThemeVariables().background, backgroundColor: this.colors.background,
position: 'absolute', position: 'absolute',
top: 0, top: 0,
right: 0, right: 0,
@ -117,34 +109,28 @@ export default class WebViewScreen extends React.Component<Props> {
<ActivityIndicator <ActivityIndicator
animating={true} animating={true}
size={'large'} size={'large'}
color={ThemeManager.getCurrentThemeVariables().primary}/> color={this.colors.primary}/>
</View> </View>
); );
} }
getWebview(obj: Object) {
return (
<WebView
ref={this.onWebviewRef}
source={{uri: obj['url']}}
style={{
width: '100%',
height: '100%',
}}
startInLoadingState={true}
injectedJavaScript={obj['customJS']}
javaScriptEnabled={true}
renderLoading={this.getRenderLoading}
/>
);
}
render() { render() {
// console.log("rendering WebViewScreen"); // console.log("rendering WebViewScreen");
this.webviewArray = [];
return ( return (
this.getWebview(this.props.data[0]) <WebView
ref={this.onWebviewRef}
source={{uri: this.props.data[0]['url']}}
style={{
width: '100%',
height: '100%',
}}
startInLoadingState={true}
injectedJavaScript={this.props.data[0]['customJS']}
javaScriptEnabled={true}
renderLoading={this.getRenderLoading}
/>
); );
} }
} }
export default withTheme(WebViewScreen);

View file

@ -6,8 +6,7 @@ import i18n from "i18n-js";
import appJson from '../../app'; import appJson from '../../app';
import AsyncStorageManager from "../../utils/AsyncStorageManager"; import AsyncStorageManager from "../../utils/AsyncStorageManager";
import CustomModal from "../../components/CustomModal"; import CustomModal from "../../components/CustomModal";
import ThemeManager from "../../utils/ThemeManager"; import {Avatar, Button, Card, List, Text, Title, withTheme} from 'react-native-paper';
import {Avatar, Button, Card, List, Text, Title} from 'react-native-paper';
const links = { const links = {
appstore: 'https://apps.apple.com/us/app/campus-amicale-insat/id1477722148', appstore: 'https://apps.apple.com/us/app/campus-amicale-insat/id1477722148',
@ -59,7 +58,7 @@ function openWebLink(link) {
/** /**
* Class defining an about screen. This screen shows the user information about the app and it's author. * Class defining an about screen. This screen shows the user information about the app and it's author.
*/ */
export default class AboutScreen extends React.Component<Props, State> { class AboutScreen extends React.Component<Props, State> {
debugTapCounter = 0; debugTapCounter = 0;
modalRef: Object; modalRef: Object;
@ -188,11 +187,14 @@ export default class AboutScreen extends React.Component<Props, State> {
getMainCard: Function; getMainCard: Function;
onModalRef: Function; onModalRef: Function;
constructor(props: any) { colors: object;
constructor(props) {
super(props); super(props);
this.getCardItem = this.getCardItem.bind(this); this.getCardItem = this.getCardItem.bind(this);
this.getMainCard = this.getMainCard.bind(this); this.getMainCard = this.getMainCard.bind(this);
this.onModalRef = this.onModalRef.bind(this); this.onModalRef = this.onModalRef.bind(this);
this.colors = props.theme.colors;
} }
getAppCard() { getAppCard() {
@ -326,7 +328,7 @@ export default class AboutScreen extends React.Component<Props, State> {
icon="email" icon="email"
mode="contained" mode="contained"
dark={true} dark={true}
color={ThemeManager.getCurrentThemeVariables().primary} color={this.colors.primary}
style={{ style={{
marginTop: 20, marginTop: 20,
marginLeft: 'auto', marginLeft: 'auto',
@ -339,7 +341,7 @@ export default class AboutScreen extends React.Component<Props, State> {
icon="git" icon="git"
mode="contained" mode="contained"
dark={true} dark={true}
color={ThemeManager.getCurrentThemeVariables().primary} color={this.colors.primary}
style={{ style={{
marginTop: 20, marginTop: 20,
marginLeft: 'auto', marginLeft: 'auto',
@ -391,3 +393,5 @@ export default class AboutScreen extends React.Component<Props, State> {
); );
} }
} }
export default withTheme(AboutScreen);

View file

@ -1,12 +1,11 @@
// @flow // @flow
import * as React from 'react'; import * as React from 'react';
import ThemeManager from '../../utils/ThemeManager';
import {Alert, Clipboard, ScrollView, View} from "react-native"; import {Alert, Clipboard, ScrollView, View} from "react-native";
import AsyncStorageManager from "../../utils/AsyncStorageManager"; import AsyncStorageManager from "../../utils/AsyncStorageManager";
import NotificationsManager from "../../utils/NotificationsManager"; import NotificationsManager from "../../utils/NotificationsManager";
import CustomModal from "../../components/CustomModal"; import CustomModal from "../../components/CustomModal";
import {Button, Card, List, Subheading, TextInput, Title} from 'react-native-paper'; import {Button, Card, List, Subheading, TextInput, Title, withTheme} from 'react-native-paper';
type Props = { type Props = {
navigation: Object, navigation: Object,
@ -20,7 +19,7 @@ type State = {
/** /**
* Class defining the Debug screen. This screen allows the user to get detailed information on the app/device. * Class defining the Debug screen. This screen allows the user to get detailed information on the app/device.
*/ */
export default class DebugScreen extends React.Component<Props, State> { class DebugScreen extends React.Component<Props, State> {
modalRef: Object; modalRef: Object;
modalInputValue = ''; modalInputValue = '';
@ -31,9 +30,12 @@ export default class DebugScreen extends React.Component<Props, State> {
onModalRef: Function; onModalRef: Function;
constructor(props: any) { colors: Object;
constructor(props) {
super(props); super(props);
this.onModalRef = this.onModalRef.bind(this); this.onModalRef = this.onModalRef.bind(this);
this.colors = props.theme.colors;
} }
static getGeneralItem(onPressCallback: Function, icon: ?string, title: string, subtitle: string) { static getGeneralItem(onPressCallback: Function, icon: ?string, title: string, subtitle: string) {
@ -103,14 +105,14 @@ export default class DebugScreen extends React.Component<Props, State> {
<Button <Button
mode="contained" mode="contained"
dark={true} dark={true}
color={ThemeManager.getCurrentThemeVariables().success} color={this.colors.success}
onPress={() => this.saveNewPrefs(this.state.modalCurrentDisplayItem.key, this.modalInputValue)}> onPress={() => this.saveNewPrefs(this.state.modalCurrentDisplayItem.key, this.modalInputValue)}>
Save new value Save new value
</Button> </Button>
<Button <Button
mode="contained" mode="contained"
dark={true} dark={true}
color={ThemeManager.getCurrentThemeVariables().danger} color={this.colors.danger}
onPress={() => this.saveNewPrefs(this.state.modalCurrentDisplayItem.key, this.state.modalCurrentDisplayItem.default)}> onPress={() => this.saveNewPrefs(this.state.modalCurrentDisplayItem.key, this.state.modalCurrentDisplayItem.default)}>
Reset to default Reset to default
</Button> </Button>
@ -166,3 +168,5 @@ export default class DebugScreen extends React.Component<Props, State> {
); );
} }
} }
export default withTheme(DebugScreen);

View file

@ -3,11 +3,10 @@
import * as React from 'react'; import * as React from 'react';
import {View} from 'react-native'; import {View} from 'react-native';
import i18n from "i18n-js"; import i18n from "i18n-js";
import ThemeManager from "../utils/ThemeManager";
import DashboardItem from "../components/EventDashboardItem"; import DashboardItem from "../components/EventDashboardItem";
import * as WebBrowser from 'expo-web-browser'; import * as WebBrowser from 'expo-web-browser';
import WebSectionList from "../components/WebSectionList"; import WebSectionList from "../components/WebSectionList";
import {Text} from 'react-native-paper'; import {Text, withTheme} from 'react-native-paper';
import FeedItem from "../components/FeedItem"; import FeedItem from "../components/FeedItem";
import SquareDashboardItem from "../components/SquareDashboardItem"; import SquareDashboardItem from "../components/SquareDashboardItem";
import PreviewEventDashboardItem from "../components/PreviewEventDashboardItem"; import PreviewEventDashboardItem from "../components/PreviewEventDashboardItem";
@ -26,12 +25,13 @@ const REFRESH_TIME = 1000 * 20; // Refresh every 20 seconds
type Props = { type Props = {
navigation: Object, navigation: Object,
theme: Object,
} }
/** /**
* Class defining the app's home screen * Class defining the app's home screen
*/ */
export default class HomeScreen extends React.Component<Props> { class HomeScreen extends React.Component<Props> {
onProxiwashClick: Function; onProxiwashClick: Function;
onTutorInsaClick: Function; onTutorInsaClick: Function;
@ -40,14 +40,17 @@ export default class HomeScreen extends React.Component<Props> {
getRenderItem: Function; getRenderItem: Function;
createDataset: Function; createDataset: Function;
constructor() { colors : Object;
super();
constructor(props) {
super(props);
this.onProxiwashClick = this.onProxiwashClick.bind(this); this.onProxiwashClick = this.onProxiwashClick.bind(this);
this.onTutorInsaClick = this.onTutorInsaClick.bind(this); this.onTutorInsaClick = this.onTutorInsaClick.bind(this);
this.onMenuClick = this.onMenuClick.bind(this); this.onMenuClick = this.onMenuClick.bind(this);
this.onProximoClick = this.onProximoClick.bind(this); this.onProximoClick = this.onProximoClick.bind(this);
this.getRenderItem = this.getRenderItem.bind(this); this.getRenderItem = this.getRenderItem.bind(this);
this.createDataset = this.createDataset.bind(this); this.createDataset = this.createDataset.bind(this);
this.colors = props.theme.colors;
} }
/** /**
@ -338,35 +341,35 @@ export default class HomeScreen extends React.Component<Props> {
margin: 10, margin: 10,
}}> }}>
<SquareDashboardItem <SquareDashboardItem
color={ThemeManager.getCurrentThemeVariables().proxiwashColor} color={this.colors.proxiwashColor}
icon={'washing-machine'} icon={'washing-machine'}
clickAction={this.onProxiwashClick} clickAction={this.onProxiwashClick}
isAvailable={parseInt(proxiwashData['washers']) > 0} isAvailable={parseInt(proxiwashData['washers']) > 0}
badgeNumber={proxiwashData['washers']} badgeNumber={proxiwashData['washers']}
/> />
<SquareDashboardItem <SquareDashboardItem
color={ThemeManager.getCurrentThemeVariables().proxiwashColor} color={this.colors.proxiwashColor}
icon={'tumble-dryer'} icon={'tumble-dryer'}
clickAction={this.onProxiwashClick} clickAction={this.onProxiwashClick}
isAvailable={parseInt(proxiwashData['dryers']) > 0} isAvailable={parseInt(proxiwashData['dryers']) > 0}
badgeNumber={proxiwashData['dryers']} badgeNumber={proxiwashData['dryers']}
/> />
<SquareDashboardItem <SquareDashboardItem
color={ThemeManager.getCurrentThemeVariables().tutorinsaColor} color={this.colors.tutorinsaColor}
icon={'school'} icon={'school'}
clickAction={this.onTutorInsaClick} clickAction={this.onTutorInsaClick}
isAvailable={tutorinsaData > 0} isAvailable={tutorinsaData > 0}
badgeNumber={tutorinsaData} badgeNumber={tutorinsaData}
/> />
<SquareDashboardItem <SquareDashboardItem
color={ThemeManager.getCurrentThemeVariables().proximoColor} color={this.colors.proximoColor}
icon={'shopping'} icon={'shopping'}
clickAction={this.onProximoClick} clickAction={this.onProximoClick}
isAvailable={parseInt(proximoData) > 0} isAvailable={parseInt(proximoData) > 0}
badgeNumber={parseInt(proximoData)} badgeNumber={parseInt(proximoData)}
/> />
<SquareDashboardItem <SquareDashboardItem
color={ThemeManager.getCurrentThemeVariables().menuColor} color={this.colors.menuColor}
icon={'silverware-fork-knife'} icon={'silverware-fork-knife'}
clickAction={this.onMenuClick} clickAction={this.onMenuClick}
isAvailable={menuData.length > 0} isAvailable={menuData.length > 0}
@ -413,3 +416,5 @@ export default class HomeScreen extends React.Component<Props> {
); );
} }
} }
export default withTheme(HomeScreen);

View file

@ -6,7 +6,7 @@ import ThemeManager from "../../utils/ThemeManager";
import HTML from "react-native-render-html"; import HTML from "react-native-render-html";
import {Linking} from "expo"; import {Linking} from "expo";
import PlanningEventManager from '../../utils/PlanningEventManager'; import PlanningEventManager from '../../utils/PlanningEventManager';
import {Card} from 'react-native-paper'; import {Card, withTheme} from 'react-native-paper';
type Props = { type Props = {
navigation: Object, navigation: Object,
@ -20,10 +20,17 @@ function openWebLink(event, link) {
/** /**
* Class defining an about screen. This screen shows the user information about the app and it's author. * Class defining an about screen. This screen shows the user information about the app and it's author.
*/ */
export default class PlanningDisplayScreen extends React.Component<Props> { class PlanningDisplayScreen extends React.Component<Props> {
displayData = this.props.route.params['data']; displayData = this.props.route.params['data'];
colors: Object;
constructor(props) {
super(props);
this.colors = props.theme.colors;
}
render() { render() {
// console.log("rendering planningDisplayScreen"); // console.log("rendering planningDisplayScreen");
return ( return (
@ -44,8 +51,8 @@ export default class PlanningDisplayScreen extends React.Component<Props> {
<Card.Content> <Card.Content>
<HTML html={"<div>" + this.displayData.description + "</div>"} <HTML html={"<div>" + this.displayData.description + "</div>"}
tagsStyles={{ tagsStyles={{
p: {color: ThemeManager.getCurrentThemeVariables().text,}, p: {color: this.colors.text,},
div: {color: ThemeManager.getCurrentThemeVariables().text} div: {color: this.colors.text}
}} }}
onLinkPress={openWebLink}/> onLinkPress={openWebLink}/>
</Card.Content> </Card.Content>
@ -54,3 +61,5 @@ export default class PlanningDisplayScreen extends React.Component<Props> {
); );
} }
} }
export default withTheme(PlanningDisplayScreen);

View file

@ -3,7 +3,7 @@
import * as React from 'react'; import * as React from 'react';
import {Image, ScrollView, View} from 'react-native'; import {Image, ScrollView, View} from 'react-native';
import i18n from "i18n-js"; import i18n from "i18n-js";
import {Text, Card, List, Paragraph} from 'react-native-paper'; import {Card, List, Paragraph, Text} from 'react-native-paper';
type Props = { type Props = {
navigation: Object, navigation: Object,

View file

@ -3,9 +3,8 @@
import * as React from 'react'; import * as React from 'react';
import {FlatList, Image, ScrollView, View} from "react-native"; import {FlatList, Image, ScrollView, View} from "react-native";
import i18n from "i18n-js"; import i18n from "i18n-js";
import ThemeManager from "../../utils/ThemeManager";
import CustomModal from "../../components/CustomModal"; import CustomModal from "../../components/CustomModal";
import {Avatar, IconButton, List, RadioButton, Searchbar, Subheading, Text, Title} from "react-native-paper"; import {Avatar, IconButton, List, RadioButton, Searchbar, Subheading, Text, Title, withTheme} from "react-native-paper";
function sortPrice(a, b) { function sortPrice(a, b) {
return a.price - b.price; return a.price - b.price;
@ -45,7 +44,7 @@ type State = {
/** /**
* Class defining proximo's article list of a certain category. * Class defining proximo's article list of a certain category.
*/ */
export default class ProximoListScreen extends React.Component<Props, State> { class ProximoListScreen extends React.Component<Props, State> {
modalRef: Object; modalRef: Object;
originalData: Array<Object>; originalData: Array<Object>;
@ -56,7 +55,9 @@ export default class ProximoListScreen extends React.Component<Props, State> {
renderItem: Function; renderItem: Function;
onModalRef: Function; onModalRef: Function;
constructor(props: any) { colors: Object;
constructor(props) {
super(props); super(props);
this.originalData = this.props.route.params['data']['data']; this.originalData = this.props.route.params['data']['data'];
this.shouldFocusSearchBar = this.props.route.params['shouldFocusSearchBar']; this.shouldFocusSearchBar = this.props.route.params['shouldFocusSearchBar'];
@ -70,6 +71,7 @@ export default class ProximoListScreen extends React.Component<Props, State> {
this.onSortMenuPress = this.onSortMenuPress.bind(this); this.onSortMenuPress = this.onSortMenuPress.bind(this);
this.renderItem = this.renderItem.bind(this); this.renderItem = this.renderItem.bind(this);
this.onModalRef = this.onModalRef.bind(this); this.onModalRef = this.onModalRef.bind(this);
this.colors = props.theme.colors;
} }
@ -133,11 +135,11 @@ export default class ProximoListScreen extends React.Component<Props, State> {
getStockColor(availableStock: number) { getStockColor(availableStock: number) {
let color: string; let color: string;
if (availableStock > 3) if (availableStock > 3)
color = ThemeManager.getCurrentThemeVariables().success; color = this.colors.success;
else if (availableStock > 0) else if (availableStock > 0)
color = ThemeManager.getCurrentThemeVariables().warning; color = this.colors.warning;
else else
color = ThemeManager.getCurrentThemeVariables().danger; color = this.colors.danger;
return color; return color;
} }
@ -270,7 +272,7 @@ export default class ProximoListScreen extends React.Component<Props, State> {
return ( return (
<IconButton <IconButton
icon="sort" icon="sort"
color={ThemeManager.getCurrentThemeVariables().text} color={this.colors.text}
size={26} size={26}
onPress={this.onSortMenuPress} onPress={this.onSortMenuPress}
/> />
@ -322,3 +324,5 @@ export default class ProximoListScreen extends React.Component<Props, State> {
); );
} }
} }
export default withTheme(ProximoListScreen);

View file

@ -3,9 +3,8 @@
import * as React from 'react'; import * as React from 'react';
import {View} from 'react-native' import {View} from 'react-native'
import i18n from "i18n-js"; import i18n from "i18n-js";
import ThemeManager from "../../utils/ThemeManager";
import WebSectionList from "../../components/WebSectionList"; import WebSectionList from "../../components/WebSectionList";
import {IconButton, List} from 'react-native-paper'; import {List, withTheme} from 'react-native-paper';
import HeaderButton from "../../components/HeaderButton"; import HeaderButton from "../../components/HeaderButton";
const DATA_URL = "https://etud.insa-toulouse.fr/~proximo/data/stock-v2.json"; const DATA_URL = "https://etud.insa-toulouse.fr/~proximo/data/stock-v2.json";
@ -22,7 +21,7 @@ type State = {
* Class defining the main proximo screen. This screen shows the different categories of articles * Class defining the main proximo screen. This screen shows the different categories of articles
* offered by proximo. * offered by proximo.
*/ */
export default class ProximoMainScreen extends React.Component<Props, State> { class ProximoMainScreen extends React.Component<Props, State> {
articles: Object; articles: Object;
@ -31,12 +30,15 @@ export default class ProximoMainScreen extends React.Component<Props, State> {
getRenderItem: Function; getRenderItem: Function;
createDataset: Function; createDataset: Function;
constructor() { colors: Object;
super();
constructor(props) {
super(props);
this.onPressSearchBtn = this.onPressSearchBtn.bind(this); this.onPressSearchBtn = this.onPressSearchBtn.bind(this);
this.onPressAboutBtn = this.onPressAboutBtn.bind(this); this.onPressAboutBtn = this.onPressAboutBtn.bind(this);
this.getRenderItem = this.getRenderItem.bind(this); this.getRenderItem = this.getRenderItem.bind(this);
this.createDataset = this.createDataset.bind(this); this.createDataset = this.createDataset.bind(this);
this.colors = props.theme.colors;
} }
static sortFinalData(a: Object, b: Object) { static sortFinalData(a: Object, b: Object) {
@ -180,7 +182,7 @@ export default class ProximoMainScreen extends React.Component<Props, State> {
left={props => <List.Icon left={props => <List.Icon
{...props} {...props}
icon={item.type.icon} icon={item.type.icon}
color={ThemeManager.getCurrentThemeVariables().primary}/>} color={this.colors.primary}/>}
right={props => <List.Icon {...props} icon={'chevron-right'}/>} right={props => <List.Icon {...props} icon={'chevron-right'}/>}
/> />
); );
@ -202,3 +204,4 @@ export default class ProximoMainScreen extends React.Component<Props, State> {
} }
} }
export default withTheme(ProximoMainScreen);

View file

@ -1,7 +1,7 @@
// @flow // @flow
import * as React from 'react'; import * as React from 'react';
import {Image, View, ScrollView} from 'react-native'; import {Image, ScrollView, View} from 'react-native';
import i18n from "i18n-js"; import i18n from "i18n-js";
import {Card, List, Paragraph, Text, Title} from 'react-native-paper'; import {Card, List, Paragraph, Text, Title} from 'react-native-paper';

View file

@ -7,12 +7,11 @@ import WebSectionList from "../../components/WebSectionList";
import NotificationsManager from "../../utils/NotificationsManager"; import NotificationsManager from "../../utils/NotificationsManager";
import AsyncStorageManager from "../../utils/AsyncStorageManager"; import AsyncStorageManager from "../../utils/AsyncStorageManager";
import * as Expo from "expo"; import * as Expo from "expo";
import {Avatar, Banner, Button, Card, Text} from 'react-native-paper'; import {Avatar, Banner, Button, Card, Text, withTheme} from 'react-native-paper';
import HeaderButton from "../../components/HeaderButton"; import HeaderButton from "../../components/HeaderButton";
import ProxiwashListItem from "../../components/ProxiwashListItem"; import ProxiwashListItem from "../../components/ProxiwashListItem";
import ProxiwashConstants from "../../constants/ProxiwashConstants"; import ProxiwashConstants from "../../constants/ProxiwashConstants";
import CustomModal from "../../components/CustomModal"; import CustomModal from "../../components/CustomModal";
import ThemeManager from "../../utils/ThemeManager";
const DATA_URL = "https://etud.insa-toulouse.fr/~amicale_app/washinsa/washinsa.json"; const DATA_URL = "https://etud.insa-toulouse.fr/~amicale_app/washinsa/washinsa.json";
@ -24,6 +23,7 @@ const REFRESH_TIME = 1000 * 10; // Refresh every 10 seconds
type Props = { type Props = {
navigation: Object, navigation: Object,
theme: Object,
} }
type State = { type State = {
@ -39,7 +39,7 @@ type State = {
* Class defining the app's proxiwash screen. This screen shows information about washing machines and * Class defining the app's proxiwash screen. This screen shows information about washing machines and
* dryers, taken from a scrapper reading proxiwash website * dryers, taken from a scrapper reading proxiwash website
*/ */
export default class ProxiwashScreen extends React.Component<Props, State> { class ProxiwashScreen extends React.Component<Props, State> {
modalRef: Object; modalRef: Object;
@ -51,6 +51,7 @@ export default class ProxiwashScreen extends React.Component<Props, State> {
onModalRef: Function; onModalRef: Function;
fetchedData: Object; fetchedData: Object;
colors: Object;
state = { state = {
refreshing: false, refreshing: false,
@ -65,8 +66,8 @@ export default class ProxiwashScreen extends React.Component<Props, State> {
/** /**
* Creates machine state parameters using current theme and translations * Creates machine state parameters using current theme and translations
*/ */
constructor() { constructor(props) {
super(); super(props);
stateStrings[ProxiwashConstants.machineStates.TERMINE] = i18n.t('proxiwashScreen.states.finished'); stateStrings[ProxiwashConstants.machineStates.TERMINE] = i18n.t('proxiwashScreen.states.finished');
stateStrings[ProxiwashConstants.machineStates.DISPONIBLE] = i18n.t('proxiwashScreen.states.ready'); stateStrings[ProxiwashConstants.machineStates.DISPONIBLE] = i18n.t('proxiwashScreen.states.ready');
stateStrings[ProxiwashConstants.machineStates["EN COURS"]] = i18n.t('proxiwashScreen.states.running'); stateStrings[ProxiwashConstants.machineStates["EN COURS"]] = i18n.t('proxiwashScreen.states.running');
@ -92,6 +93,7 @@ export default class ProxiwashScreen extends React.Component<Props, State> {
this.createDataset = this.createDataset.bind(this); this.createDataset = this.createDataset.bind(this);
this.onHideBanner = this.onHideBanner.bind(this); this.onHideBanner = this.onHideBanner.bind(this);
this.onModalRef = this.onModalRef.bind(this); this.onModalRef = this.onModalRef.bind(this);
this.colors = props.theme.colors;
} }
onHideBanner() { onHideBanner() {
@ -301,7 +303,7 @@ export default class ProxiwashScreen extends React.Component<Props, State> {
title={title} title={title}
left={() => <Avatar.Icon left={() => <Avatar.Icon
icon={isDryer ? 'tumble-dryer' : 'washing-machine'} icon={isDryer ? 'tumble-dryer' : 'washing-machine'}
color={ThemeManager.getCurrentThemeVariables().text} color={this.colors.text}
style={{backgroundColor: 'transparent'}}/>} style={{backgroundColor: 'transparent'}}/>}
/> />
@ -338,41 +340,6 @@ export default class ProxiwashScreen extends React.Component<Props, State> {
this.modalRef = ref; this.modalRef = ref;
} }
render() {
const nav = this.props.navigation;
return (
<View>
<Banner
visible={this.state.bannerVisible}
actions={[
{
label: 'OK',
onPress: this.onHideBanner,
},
]}
icon={() => <Avatar.Icon
icon={'information'}
size={40}
/>}
>
{i18n.t('proxiwashScreen.enableNotificationsTip')}
</Banner>
<CustomModal onRef={this.onModalRef}>
{this.state.modalCurrentDisplayItem}
</CustomModal>
<WebSectionList
createDataset={this.createDataset}
navigation={nav}
fetchUrl={DATA_URL}
renderItem={this.getRenderItem}
renderSectionHeader={this.getRenderSectionHeader}
autoRefreshTime={REFRESH_TIME}
refreshOnFocus={true}/>
</View>
);
}
getMachineAvailableNumber(isDryer: boolean) { getMachineAvailableNumber(isDryer: boolean) {
let data; let data;
if (isDryer) if (isDryer)
@ -403,7 +370,7 @@ export default class ProxiwashScreen extends React.Component<Props, State> {
subtitle={subtitle} subtitle={subtitle}
left={() => <Avatar.Icon left={() => <Avatar.Icon
icon={isDryer ? 'tumble-dryer' : 'washing-machine'} icon={isDryer ? 'tumble-dryer' : 'washing-machine'}
color={ThemeManager.getCurrentThemeVariables().primary} color={this.colors.primary}
style={{backgroundColor: 'transparent'}} style={{backgroundColor: 'transparent'}}
/>} />}
/> />
@ -440,4 +407,41 @@ export default class ProxiwashScreen extends React.Component<Props, State> {
/> />
); );
} }
render() {
const nav = this.props.navigation;
return (
<View>
<Banner
visible={this.state.bannerVisible}
actions={[
{
label: 'OK',
onPress: this.onHideBanner,
},
]}
icon={() => <Avatar.Icon
icon={'information'}
size={40}
/>}
>
{i18n.t('proxiwashScreen.enableNotificationsTip')}
</Banner>
<CustomModal onRef={this.onModalRef}>
{this.state.modalCurrentDisplayItem}
</CustomModal>
<WebSectionList
createDataset={this.createDataset}
navigation={nav}
fetchUrl={DATA_URL}
renderItem={this.getRenderItem}
renderSectionHeader={this.getRenderSectionHeader}
autoRefreshTime={REFRESH_TIME}
refreshOnFocus={true}/>
</View>
);
} }
}
export default withTheme(ProxiwashScreen);

View file

@ -2,10 +2,9 @@
import * as React from 'react'; import * as React from 'react';
import {View} from 'react-native'; import {View} from 'react-native';
import ThemeManager from "../utils/ThemeManager";
import i18n from "i18n-js"; import i18n from "i18n-js";
import WebSectionList from "../components/WebSectionList"; import WebSectionList from "../components/WebSectionList";
import {Card, Text} from 'react-native-paper'; import {Card, Text, withTheme} from 'react-native-paper';
import AprilFoolsManager from "../utils/AprilFoolsManager"; import AprilFoolsManager from "../utils/AprilFoolsManager";
const DATA_URL = "https://etud.insa-toulouse.fr/~amicale_app/menu/menu_data.json"; const DATA_URL = "https://etud.insa-toulouse.fr/~amicale_app/menu/menu_data.json";
@ -18,7 +17,7 @@ type Props = {
* Class defining the app's menu screen. * Class defining the app's menu screen.
* This screen fetches data from etud to render the RU menu * This screen fetches data from etud to render the RU menu
*/ */
export default class SelfMenuScreen extends React.Component<Props> { class SelfMenuScreen extends React.Component<Props> {
// Hard code strings as toLocaleDateString does not work on current android JS engine // Hard code strings as toLocaleDateString does not work on current android JS engine
daysOfWeek = []; daysOfWeek = [];
@ -27,9 +26,10 @@ export default class SelfMenuScreen extends React.Component<Props> {
getRenderItem: Function; getRenderItem: Function;
getRenderSectionHeader: Function; getRenderSectionHeader: Function;
createDataset: Function; createDataset: Function;
colors: Object;
constructor() { constructor(props) {
super(); super(props);
this.daysOfWeek.push(i18n.t("date.daysOfWeek.monday")); this.daysOfWeek.push(i18n.t("date.daysOfWeek.monday"));
this.daysOfWeek.push(i18n.t("date.daysOfWeek.tuesday")); this.daysOfWeek.push(i18n.t("date.daysOfWeek.tuesday"));
this.daysOfWeek.push(i18n.t("date.daysOfWeek.wednesday")); this.daysOfWeek.push(i18n.t("date.daysOfWeek.wednesday"));
@ -54,6 +54,7 @@ export default class SelfMenuScreen extends React.Component<Props> {
this.getRenderItem = this.getRenderItem.bind(this); this.getRenderItem = this.getRenderItem.bind(this);
this.getRenderSectionHeader = this.getRenderSectionHeader.bind(this); this.getRenderSectionHeader = this.getRenderSectionHeader.bind(this);
this.createDataset = this.createDataset.bind(this); this.createDataset = this.createDataset.bind(this);
this.colors = props.theme.colors;
} }
getKeyExtractor(item: Object) { getKeyExtractor(item: Object) {
@ -138,7 +139,7 @@ export default class SelfMenuScreen extends React.Component<Props> {
marginLeft: 'auto', marginLeft: 'auto',
marginRight: 'auto', marginRight: 'auto',
borderBottomWidth: 1, borderBottomWidth: 1,
borderBottomColor: ThemeManager.getCurrentThemeVariables().primary, borderBottomColor: this.colors.primary,
marginTop: 5, marginTop: 5,
marginBottom: 5, marginBottom: 5,
}}/> }}/>
@ -178,3 +179,4 @@ export default class SelfMenuScreen extends React.Component<Props> {
} }
} }
export default withTheme(SelfMenuScreen);

View file

@ -132,14 +132,6 @@ export default class ThemeManager {
return ThemeManager.getWhiteTheme(); return ThemeManager.getWhiteTheme();
} }
/**
* Get the variables contained in the current theme
* @returns {Object}
*/
static getCurrentThemeVariables(): Object {
return ThemeManager.getCurrentTheme().colors;
}
/** /**
* Set the function to be called when the theme is changed (allows for general reload of the app) * Set the function to be called when the theme is changed (allows for general reload of the app)
* @param callback Function to call after theme change * @param callback Function to call after theme change