Compare commits

..

3 commits

Author SHA1 Message Date
Arnaud Vergnet
38afbf02a3 Update services screens to use TypeScript 2020-09-22 22:40:38 +02:00
Arnaud Vergnet
2eb4a3e0c1 Update Proximo screens to use TypeScript 2020-09-22 22:35:24 +02:00
Arnaud Vergnet
9f4dcda7d9 Update proxiwash screens to use TypeScript 2020-09-22 22:29:39 +02:00
13 changed files with 431 additions and 444 deletions

View file

@ -38,6 +38,7 @@ import CollapsibleSectionList from '../Collapsible/CollapsibleSectionList';
export type SectionListDataType<ItemT> = Array<{
title: string;
icon?: string;
data: Array<ItemT>;
keyExtractor?: (data: ItemT) => string;
}>;

View file

@ -17,16 +17,17 @@
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/
export enum MachineStates {
AVAILABLE,
RUNNING,
RUNNING_NOT_STARTED,
FINISHED,
UNAVAILABLE,
ERROR,
UNKNOWN,
}
export default {
machineStates: {
AVAILABLE: 0,
RUNNING: 1,
RUNNING_NOT_STARTED: 2,
FINISHED: 3,
UNAVAILABLE: 4,
ERROR: 5,
UNKNOWN: 6,
},
stateIcons: [
'radiobox-blank',
'progress-check',

View file

@ -1,122 +0,0 @@
/*
* Copyright (c) 2019 - 2020 Arnaud Vergnet.
*
* This file is part of Campus INSAT.
*
* Campus INSAT is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Campus INSAT is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/
// @flow
import * as React from 'react';
import {Image, View} from 'react-native';
import i18n from 'i18n-js';
import {Card, Avatar, Paragraph, Title} from 'react-native-paper';
import CollapsibleScrollView from '../../components/Collapsible/CollapsibleScrollView';
import type {CardTitleIconPropsType} from '../../constants/PaperStyles';
import ProxiwashConstants from '../../constants/ProxiwashConstants';
const LOGO = 'https://etud.insa-toulouse.fr/~amicale_app/images/Proxiwash.png';
export type LaundromatType = {
id: string,
title: string,
subtitle: string,
description: string,
tarif: string,
paymentMethods: string,
icon: string,
url: string,
};
/**
* Class defining the proxiwash about screen.
*/
export default class ProxiwashAboutScreen extends React.Component<null> {
static getCardItem(item: LaundromatType): React.Node {
return (
<Card style={{margin: 5}}>
<Card.Title
title={i18n.t(item.title)}
subtitle={i18n.t(item.subtitle)}
left={(iconProps: CardTitleIconPropsType): React.Node => (
<Avatar.Icon size={iconProps.size} icon={item.icon} />
)}
/>
<Card.Content>
<Paragraph>{i18n.t(item.description)}</Paragraph>
<Title>{i18n.t('screens.proxiwash.tariffs')}</Title>
<Paragraph>{i18n.t(item.tarif)}</Paragraph>
<Title>{i18n.t('screens.proxiwash.paymentMethods')}</Title>
<Paragraph>{i18n.t(item.paymentMethods)}</Paragraph>
</Card.Content>
</Card>
);
}
render(): React.Node {
return (
<CollapsibleScrollView style={{padding: 5}} hasTab>
<View
style={{
width: '100%',
height: 100,
marginTop: 20,
marginBottom: 20,
justifyContent: 'center',
alignItems: 'center',
}}>
<Image
source={{uri: LOGO}}
style={{height: '100%', width: '100%', resizeMode: 'contain'}}
/>
</View>
{ProxiwashAboutScreen.getCardItem(ProxiwashConstants.washinsa)}
{ProxiwashAboutScreen.getCardItem(ProxiwashConstants.tripodeB)}
<Card style={{margin: 5}}>
<Card.Title
title={i18n.t('screens.proxiwash.dryer')}
left={(iconProps: CardTitleIconPropsType): React.Node => (
<Avatar.Icon size={iconProps.size} icon="tumble-dryer" />
)}
/>
<Card.Content>
<Title>{i18n.t('screens.proxiwash.procedure')}</Title>
<Paragraph>{i18n.t('screens.proxiwash.dryerProcedure')}</Paragraph>
<Title>{i18n.t('screens.proxiwash.tips')}</Title>
<Paragraph>{i18n.t('screens.proxiwash.dryerTips')}</Paragraph>
</Card.Content>
</Card>
<Card style={{margin: 5}}>
<Card.Title
title={i18n.t('screens.proxiwash.washer')}
left={(iconProps: CardTitleIconPropsType): React.Node => (
<Avatar.Icon size={iconProps.size} icon="washing-machine" />
)}
/>
<Card.Content>
<Title>{i18n.t('screens.proxiwash.procedure')}</Title>
<Paragraph>{i18n.t('screens.proxiwash.washerProcedure')}</Paragraph>
<Title>{i18n.t('screens.proxiwash.tips')}</Title>
<Paragraph>{i18n.t('screens.proxiwash.washerTips')}</Paragraph>
</Card.Content>
</Card>
</CollapsibleScrollView>
);
}
}

View file

@ -0,0 +1,117 @@
/*
* Copyright (c) 2019 - 2020 Arnaud Vergnet.
*
* This file is part of Campus INSAT.
*
* Campus INSAT is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Campus INSAT is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/
import * as React from 'react';
import {Image, View} from 'react-native';
import i18n from 'i18n-js';
import {Card, Avatar, Paragraph, Title} from 'react-native-paper';
import CollapsibleScrollView from '../../components/Collapsible/CollapsibleScrollView';
import ProxiwashConstants from '../../constants/ProxiwashConstants';
const LOGO = 'https://etud.insa-toulouse.fr/~amicale_app/images/Proxiwash.png';
export type LaundromatType = {
id: string;
title: string;
subtitle: string;
description: string;
tarif: string;
paymentMethods: string;
icon: string;
url: string;
};
function getCardItem(item: LaundromatType) {
return (
<Card style={{margin: 5}}>
<Card.Title
title={i18n.t(item.title)}
subtitle={i18n.t(item.subtitle)}
left={(iconProps) => (
<Avatar.Icon size={iconProps.size} icon={item.icon} />
)}
/>
<Card.Content>
<Paragraph>{i18n.t(item.description)}</Paragraph>
<Title>{i18n.t('screens.proxiwash.tariffs')}</Title>
<Paragraph>{i18n.t(item.tarif)}</Paragraph>
<Title>{i18n.t('screens.proxiwash.paymentMethods')}</Title>
<Paragraph>{i18n.t(item.paymentMethods)}</Paragraph>
</Card.Content>
</Card>
);
}
/**
* Class defining the proxiwash about screen.
*/
export default function ProxiwashAboutScreen() {
return (
<CollapsibleScrollView style={{padding: 5}} hasTab>
<View
style={{
width: '100%',
height: 100,
marginTop: 20,
marginBottom: 20,
justifyContent: 'center',
alignItems: 'center',
}}>
<Image
source={{uri: LOGO}}
style={{height: '100%', width: '100%', resizeMode: 'contain'}}
/>
</View>
{getCardItem(ProxiwashConstants.washinsa)}
{getCardItem(ProxiwashConstants.tripodeB)}
<Card style={{margin: 5}}>
<Card.Title
title={i18n.t('screens.proxiwash.dryer')}
left={(iconProps) => (
<Avatar.Icon size={iconProps.size} icon="tumble-dryer" />
)}
/>
<Card.Content>
<Title>{i18n.t('screens.proxiwash.procedure')}</Title>
<Paragraph>{i18n.t('screens.proxiwash.dryerProcedure')}</Paragraph>
<Title>{i18n.t('screens.proxiwash.tips')}</Title>
<Paragraph>{i18n.t('screens.proxiwash.dryerTips')}</Paragraph>
</Card.Content>
</Card>
<Card style={{margin: 5}}>
<Card.Title
title={i18n.t('screens.proxiwash.washer')}
left={(iconProps) => (
<Avatar.Icon size={iconProps.size} icon="washing-machine" />
)}
/>
<Card.Content>
<Title>{i18n.t('screens.proxiwash.procedure')}</Title>
<Paragraph>{i18n.t('screens.proxiwash.washerProcedure')}</Paragraph>
<Title>{i18n.t('screens.proxiwash.tips')}</Title>
<Paragraph>{i18n.t('screens.proxiwash.washerTips')}</Paragraph>
</Card.Content>
</Card>
</CollapsibleScrollView>
);
}

View file

@ -17,8 +17,6 @@
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/
// @flow
import * as React from 'react';
import {Alert, View} from 'react-native';
import i18n from 'i18n-js';
@ -29,14 +27,15 @@ import WebSectionList from '../../components/Screens/WebSectionList';
import * as Notifications from '../../utils/Notifications';
import AsyncStorageManager from '../../managers/AsyncStorageManager';
import ProxiwashListItem from '../../components/Lists/Proxiwash/ProxiwashListItem';
import ProxiwashConstants from '../../constants/ProxiwashConstants';
import ProxiwashConstants, {
MachineStates,
} from '../../constants/ProxiwashConstants';
import CustomModal from '../../components/Overrides/CustomModal';
import AprilFoolsManager from '../../managers/AprilFoolsManager';
import MaterialHeaderButtons, {
Item,
} from '../../components/Overrides/CustomHeaderButton';
import ProxiwashSectionHeader from '../../components/Lists/Proxiwash/ProxiwashSectionHeader';
import type {CustomThemeType} from '../../managers/ThemeManager';
import {
getCleanedMachineWatched,
getMachineEndDate,
@ -47,31 +46,41 @@ import MascotPopup from '../../components/Mascot/MascotPopup';
import type {SectionListDataType} from '../../components/Screens/WebSectionList';
import type {LaundromatType} from './ProxiwashAboutScreen';
const modalStateStrings = {};
const modalStateStrings: {[key in MachineStates]: string} = {
[MachineStates.AVAILABLE]: i18n.t('screens.proxiwash.modal.ready'),
[MachineStates.RUNNING]: i18n.t('screens.proxiwash.modal.running'),
[MachineStates.RUNNING_NOT_STARTED]: i18n.t(
'screens.proxiwash.modal.runningNotStarted',
),
[MachineStates.FINISHED]: i18n.t('screens.proxiwash.modal.finished'),
[MachineStates.UNAVAILABLE]: i18n.t('screens.proxiwash.modal.broken'),
[MachineStates.ERROR]: i18n.t('screens.proxiwash.modal.error'),
[MachineStates.UNKNOWN]: i18n.t('screens.proxiwash.modal.unknown'),
};
const REFRESH_TIME = 1000 * 10; // Refresh every 10 seconds
const LIST_ITEM_HEIGHT = 64;
export type ProxiwashMachineType = {
number: string,
state: string,
maxWeight: number,
startTime: string,
endTime: string,
donePercent: string,
remainingTime: string,
program: string,
number: string;
state: MachineStates;
maxWeight: number;
startTime: string;
endTime: string;
donePercent: string;
remainingTime: string;
program: string;
};
type PropsType = {
navigation: StackNavigationProp,
theme: CustomThemeType,
navigation: StackNavigationProp<any>;
theme: ReactNativePaper.Theme;
};
type StateType = {
modalCurrentDisplayItem: React.Node,
machinesWatched: Array<ProxiwashMachineType>,
selectedWash: string,
modalCurrentDisplayItem: React.ReactNode;
machinesWatched: Array<ProxiwashMachineType>;
selectedWash: string;
};
/**
@ -92,15 +101,17 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
modalRef: null | Modalize;
fetchedData: {
dryers: Array<ProxiwashMachineType>,
washers: Array<ProxiwashMachineType>,
dryers: Array<ProxiwashMachineType>;
washers: Array<ProxiwashMachineType>;
};
/**
* Creates machine state parameters using current theme and translations
*/
constructor() {
super();
constructor(props: PropsType) {
super(props);
this.modalRef = null;
this.fetchedData = {dryers: [], washers: []};
this.state = {
modalCurrentDisplayItem: null,
machinesWatched: AsyncStorageManager.getObject(
@ -110,27 +121,6 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
AsyncStorageManager.PREFERENCES.selectedWash.key,
),
};
modalStateStrings[ProxiwashConstants.machineStates.AVAILABLE] = i18n.t(
'screens.proxiwash.modal.ready',
);
modalStateStrings[ProxiwashConstants.machineStates.RUNNING] = i18n.t(
'screens.proxiwash.modal.running',
);
modalStateStrings[
ProxiwashConstants.machineStates.RUNNING_NOT_STARTED
] = i18n.t('screens.proxiwash.modal.runningNotStarted');
modalStateStrings[ProxiwashConstants.machineStates.FINISHED] = i18n.t(
'screens.proxiwash.modal.finished',
);
modalStateStrings[ProxiwashConstants.machineStates.UNAVAILABLE] = i18n.t(
'screens.proxiwash.modal.broken',
);
modalStateStrings[ProxiwashConstants.machineStates.ERROR] = i18n.t(
'screens.proxiwash.modal.error',
);
modalStateStrings[ProxiwashConstants.machineStates.UNKNOWN] = i18n.t(
'screens.proxiwash.modal.unknown',
);
}
/**
@ -139,12 +129,12 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
componentDidMount() {
const {navigation} = this.props;
navigation.setOptions({
headerRight: (): React.Node => (
headerRight: () => (
<MaterialHeaderButtons>
<Item
title="switch"
iconName="swap-horizontal"
onPress={():void => navigation.navigate('settings')}
onPress={(): void => navigation.navigate('settings')}
/>
<Item
title="information"
@ -164,10 +154,10 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
);
if (selected !== state.selectedWash) {
this.setState({
selectedWash: selected
selectedWash: selected,
});
}
}
};
/**
* Callback used when pressing the about button.
@ -208,29 +198,27 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
* @param isDryer True if the given item is a dryer
* @return {*}
*/
getModalContent(
title: string,
item: ProxiwashMachineType,
isDryer: boolean,
): React.Node {
getModalContent(title: string, item: ProxiwashMachineType, isDryer: boolean) {
const {props, state} = this;
let button = {
let button: {text: string; icon: string; onPress: () => void} = {
text: i18n.t('screens.proxiwash.modal.ok'),
icon: '',
onPress: undefined,
onPress: () => undefined,
};
let message = modalStateStrings[item.state];
const onPress = this.onSetupNotificationsPress.bind(this, item);
if (item.state === ProxiwashConstants.machineStates.RUNNING) {
const onPress = () => this.onSetupNotificationsPress(item);
if (item.state === MachineStates.RUNNING) {
let remainingTime = parseInt(item.remainingTime, 10);
if (remainingTime < 0) remainingTime = 0;
if (remainingTime < 0) {
remainingTime = 0;
}
button = {
text: isMachineWatched(item, state.machinesWatched)
? i18n.t('screens.proxiwash.modal.disableNotifications')
: i18n.t('screens.proxiwash.modal.enableNotifications'),
icon: '',
onPress,
onPress: onPress,
};
message = i18n.t('screens.proxiwash.modal.running', {
start: item.startTime,
@ -247,7 +235,7 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
}}>
<Card.Title
title={title}
left={(): React.Node => (
left={() => (
<Avatar.Icon
icon={isDryer ? 'tumble-dryer' : 'washing-machine'}
color={props.theme.colors.text}
@ -259,7 +247,7 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
<Text>{message}</Text>
</Card.Content>
{button.onPress !== undefined ? (
{button.onPress ? (
<Card.Actions>
<Button
icon={button.icon}
@ -280,11 +268,7 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
* @param section The section to render
* @return {*}
*/
getRenderSectionHeader = ({
section,
}: {
section: {title: string},
}): React.Node => {
getRenderSectionHeader = ({section}: {section: {title: string}}) => {
const isDryer = section.title === i18n.t('screens.proxiwash.dryers');
const nbAvailable = this.getMachineAvailableNumber(isDryer);
return (
@ -307,9 +291,9 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
item,
section,
}: {
item: ProxiwashMachineType,
section: {title: string},
}): React.Node => {
item: ProxiwashMachineType;
section: {title: string};
}) => {
const {machinesWatched} = this.state;
const isDryer = section.title === i18n.t('screens.proxiwash.dryers');
return (
@ -369,12 +353,16 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
*/
getMachineAvailableNumber(isDryer: boolean): number {
let data;
if (isDryer) data = this.fetchedData.dryers;
else data = this.fetchedData.washers;
if (isDryer) {
data = this.fetchedData.dryers;
} else {
data = this.fetchedData.washers;
}
let count = 0;
data.forEach((machine: ProxiwashMachineType) => {
if (machine.state === ProxiwashConstants.machineStates.AVAILABLE)
if (machine.state === MachineStates.AVAILABLE) {
count += 1;
}
});
return count;
}
@ -386,8 +374,8 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
* @return {*}
*/
createDataset = (fetchedData: {
dryers: Array<ProxiwashMachineType>,
washers: Array<ProxiwashMachineType>,
dryers: Array<ProxiwashMachineType>;
washers: Array<ProxiwashMachineType>;
}): SectionListDataType<ProxiwashMachineType> => {
const {state} = this;
let data = fetchedData;
@ -466,8 +454,9 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
if (
machine.number === selectedMachine.number &&
machine.endTime === selectedMachine.endTime
)
) {
newList.splice(index, 1);
}
});
this.saveNewWatchedList(newList);
}
@ -480,7 +469,7 @@ class ProxiwashScreen extends React.Component<PropsType, StateType> {
);
}
render(): React.Node {
render() {
const {state} = this;
const {navigation} = this.props;
let data: LaundromatType;

View file

@ -1,83 +0,0 @@
/*
* Copyright (c) 2019 - 2020 Arnaud Vergnet.
*
* This file is part of Campus INSAT.
*
* Campus INSAT is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Campus INSAT is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/
// @flow
import * as React from 'react';
import {Image, View} from 'react-native';
import i18n from 'i18n-js';
import {Card, Avatar, Paragraph, Text} from 'react-native-paper';
import CustomTabBar from '../../../components/Tabbar/CustomTabBar';
import CollapsibleScrollView from '../../../components/Collapsible/CollapsibleScrollView';
import type {CardTitleIconPropsType} from '../../../constants/PaperStyles';
const LOGO = 'https://etud.insa-toulouse.fr/~amicale_app/images/Proximo.png';
/**
* Class defining the proximo about screen.
*/
// eslint-disable-next-line react/prefer-stateless-function
export default class ProximoAboutScreen extends React.Component<null> {
render(): React.Node {
return (
<CollapsibleScrollView style={{padding: 5}}>
<View
style={{
width: '100%',
height: 100,
marginTop: 20,
marginBottom: 20,
justifyContent: 'center',
alignItems: 'center',
}}>
<Image
source={{uri: LOGO}}
style={{height: '100%', width: '100%', resizeMode: 'contain'}}
/>
</View>
<Text>{i18n.t('screens.proximo.description')}</Text>
<Card style={{margin: 5}}>
<Card.Title
title={i18n.t('screens.proximo.openingHours')}
left={(iconProps: CardTitleIconPropsType): React.Node => (
<Avatar.Icon size={iconProps.size} icon="clock-outline" />
)}
/>
<Card.Content>
<Paragraph>18h30 - 19h30</Paragraph>
</Card.Content>
</Card>
<Card
style={{margin: 5, marginBottom: CustomTabBar.TAB_BAR_HEIGHT + 20}}>
<Card.Title
title={i18n.t('screens.proximo.paymentMethods')}
left={(iconProps: CardTitleIconPropsType): React.Node => (
<Avatar.Icon size={iconProps.size} icon="cash" />
)}
/>
<Card.Content>
<Paragraph>
{i18n.t('screens.proximo.paymentMethodsDescription')}
</Paragraph>
</Card.Content>
</Card>
</CollapsibleScrollView>
);
}
}

View file

@ -0,0 +1,78 @@
/*
* Copyright (c) 2019 - 2020 Arnaud Vergnet.
*
* This file is part of Campus INSAT.
*
* Campus INSAT is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Campus INSAT is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/
// @flow
import * as React from 'react';
import {Image, View} from 'react-native';
import i18n from 'i18n-js';
import {Card, Avatar, Paragraph, Text} from 'react-native-paper';
import CustomTabBar from '../../../components/Tabbar/CustomTabBar';
import CollapsibleScrollView from '../../../components/Collapsible/CollapsibleScrollView';
const LOGO = 'https://etud.insa-toulouse.fr/~amicale_app/images/Proximo.png';
/**
* Class defining the proximo about screen.
*/
export default function ProximoAboutScreen() {
return (
<CollapsibleScrollView style={{padding: 5}}>
<View
style={{
width: '100%',
height: 100,
marginTop: 20,
marginBottom: 20,
justifyContent: 'center',
alignItems: 'center',
}}>
<Image
source={{uri: LOGO}}
style={{height: '100%', width: '100%', resizeMode: 'contain'}}
/>
</View>
<Text>{i18n.t('screens.proximo.description')}</Text>
<Card style={{margin: 5}}>
<Card.Title
title={i18n.t('screens.proximo.openingHours')}
left={(iconProps) => (
<Avatar.Icon size={iconProps.size} icon="clock-outline" />
)}
/>
<Card.Content>
<Paragraph>18h30 - 19h30</Paragraph>
</Card.Content>
</Card>
<Card style={{margin: 5, marginBottom: CustomTabBar.TAB_BAR_HEIGHT + 20}}>
<Card.Title
title={i18n.t('screens.proximo.paymentMethods')}
left={(iconProps) => (
<Avatar.Icon size={iconProps.size} icon="cash" />
)}
/>
<Card.Content>
<Paragraph>
{i18n.t('screens.proximo.paymentMethodsDescription')}
</Paragraph>
</Card.Content>
</Card>
</CollapsibleScrollView>
);
}

View file

@ -17,8 +17,6 @@
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/
// @flow
import * as React from 'react';
import {Image, Platform, ScrollView, View} from 'react-native';
import i18n from 'i18n-js';
@ -38,7 +36,6 @@ import ProximoListItem from '../../../components/Lists/Proximo/ProximoListItem';
import MaterialHeaderButtons, {
Item,
} from '../../../components/Overrides/CustomHeaderButton';
import type {CustomThemeType} from '../../../managers/ThemeManager';
import CollapsibleFlatList from '../../../components/Collapsible/CollapsibleFlatList';
import type {ProximoArticleType} from './ProximoMainScreen';
@ -54,34 +51,42 @@ function sortPriceReverse(
}
function sortName(a: ProximoArticleType, b: ProximoArticleType): number {
if (a.name.toLowerCase() < b.name.toLowerCase()) return -1;
if (a.name.toLowerCase() > b.name.toLowerCase()) return 1;
if (a.name.toLowerCase() < b.name.toLowerCase()) {
return -1;
}
if (a.name.toLowerCase() > b.name.toLowerCase()) {
return 1;
}
return 0;
}
function sortNameReverse(a: ProximoArticleType, b: ProximoArticleType): number {
if (a.name.toLowerCase() < b.name.toLowerCase()) return 1;
if (a.name.toLowerCase() > b.name.toLowerCase()) return -1;
if (a.name.toLowerCase() < b.name.toLowerCase()) {
return 1;
}
if (a.name.toLowerCase() > b.name.toLowerCase()) {
return -1;
}
return 0;
}
const LIST_ITEM_HEIGHT = 84;
type PropsType = {
navigation: StackNavigationProp,
navigation: StackNavigationProp<any>;
route: {
params: {
data: {data: Array<ProximoArticleType>},
shouldFocusSearchBar: boolean,
},
},
theme: CustomThemeType,
data: {data: Array<ProximoArticleType>};
shouldFocusSearchBar: boolean;
};
};
theme: ReactNativePaper.Theme;
};
type StateType = {
currentSortMode: number,
modalCurrentDisplayItem: React.Node,
currentSearchString: string,
currentSortMode: number;
modalCurrentDisplayItem: React.ReactNode;
currentSearchString: string;
};
/**
@ -96,6 +101,7 @@ class ProximoListScreen extends React.Component<PropsType, StateType> {
constructor(props: PropsType) {
super(props);
this.modalRef = null;
this.listData = props.route.params.data.data.sort(sortName);
this.shouldFocusSearchBar = props.route.params.shouldFocusSearchBar;
this.state = {
@ -186,7 +192,9 @@ class ProximoListScreen extends React.Component<PropsType, StateType> {
this.listData.sort(sortName);
break;
}
if (this.modalRef && currentMode !== currentSortMode) this.modalRef.close();
if (this.modalRef && currentMode !== currentSortMode) {
this.modalRef.close();
}
}
/**
@ -198,9 +206,13 @@ class ProximoListScreen extends React.Component<PropsType, StateType> {
getStockColor(availableStock: number): string {
const {theme} = this.props;
let color: string;
if (availableStock > 3) color = theme.colors.success;
else if (availableStock > 0) color = theme.colors.warning;
else color = theme.colors.danger;
if (availableStock > 3) {
color = theme.colors.success;
} else if (availableStock > 0) {
color = theme.colors.warning;
} else {
color = theme.colors.danger;
}
return color;
}
@ -209,7 +221,7 @@ class ProximoListScreen extends React.Component<PropsType, StateType> {
*
* @return {*}
*/
getSortMenuButton = (): React.Node => {
getSortMenuButton = () => {
return (
<MaterialHeaderButtons>
<Item title="main" iconName="sort" onPress={this.onSortMenuPress} />
@ -222,8 +234,9 @@ class ProximoListScreen extends React.Component<PropsType, StateType> {
*
* @return {*}
*/
getSearchBar = (): React.Node => {
getSearchBar = () => {
return (
// @ts-ignore
<Searchbar
placeholder={i18n.t('screens.proximo.search')}
onChangeText={this.onSearchStringChange}
@ -237,7 +250,7 @@ class ProximoListScreen extends React.Component<PropsType, StateType> {
* @param item The article to display
* @return {*}
*/
getModalItemContent(item: ProximoArticleType): React.Node {
getModalItemContent(item: ProximoArticleType) {
return (
<View
style={{
@ -284,7 +297,7 @@ class ProximoListScreen extends React.Component<PropsType, StateType> {
*
* @return {*}
*/
getModalSortMenu(): React.Node {
getModalSortMenu() {
const {currentSortMode} = this.state;
return (
<View
@ -299,22 +312,22 @@ class ProximoListScreen extends React.Component<PropsType, StateType> {
onValueChange={(value: string) => {
this.setSortMode(value);
}}
value={currentSortMode}>
value={currentSortMode.toString()}>
<RadioButton.Item
label={i18n.t('screens.proximo.sortPrice')}
value={1}
value={'1'}
/>
<RadioButton.Item
label={i18n.t('screens.proximo.sortPriceReverse')}
value={2}
value={'2'}
/>
<RadioButton.Item
label={i18n.t('screens.proximo.sortName')}
value={3}
value={'3'}
/>
<RadioButton.Item
label={i18n.t('screens.proximo.sortNameReverse')}
value={4}
value={'4'}
/>
</RadioButton.Group>
</View>
@ -327,7 +340,7 @@ class ProximoListScreen extends React.Component<PropsType, StateType> {
* @param item The article to render
* @return {*}
*/
getRenderItem = ({item}: {item: ProximoArticleType}): React.Node => {
getRenderItem = ({item}: {item: ProximoArticleType}) => {
const {currentSearchString} = this.state;
if (stringMatchQuery(item.name, currentSearchString)) {
const onPress = () => {
@ -364,15 +377,15 @@ class ProximoListScreen extends React.Component<PropsType, StateType> {
};
itemLayout = (
data: ProximoArticleType,
data: Array<ProximoArticleType> | null | undefined,
index: number,
): {length: number, offset: number, index: number} => ({
): {length: number; offset: number; index: number} => ({
length: LIST_ITEM_HEIGHT,
offset: LIST_ITEM_HEIGHT * index,
index,
});
render(): React.Node {
render() {
const {state} = this;
return (
<View

View file

@ -27,43 +27,41 @@ import WebSectionList from '../../../components/Screens/WebSectionList';
import MaterialHeaderButtons, {
Item,
} from '../../../components/Overrides/CustomHeaderButton';
import type {CustomThemeType} from '../../../managers/ThemeManager';
import type {SectionListDataType} from '../../../components/Screens/WebSectionList';
import type {ListIconPropsType} from '../../../constants/PaperStyles';
const DATA_URL = 'https://etud.insa-toulouse.fr/~proximo/data/stock-v2.json';
const LIST_ITEM_HEIGHT = 84;
export type ProximoCategoryType = {
name: string,
icon: string,
id: string,
name: string;
icon: string;
id: string;
};
export type ProximoArticleType = {
name: string,
description: string,
quantity: string,
price: string,
code: string,
id: string,
type: Array<string>,
image: string,
name: string;
description: string;
quantity: string;
price: string;
code: string;
id: string;
type: Array<string>;
image: string;
};
export type ProximoMainListItemType = {
type: ProximoCategoryType,
data: Array<ProximoArticleType>,
type: ProximoCategoryType;
data: Array<ProximoArticleType>;
};
export type ProximoDataType = {
types: Array<ProximoCategoryType>,
articles: Array<ProximoArticleType>,
types: Array<ProximoCategoryType>;
articles: Array<ProximoArticleType>;
};
type PropsType = {
navigation: StackNavigationProp,
theme: CustomThemeType,
navigation: StackNavigationProp<any>;
theme: ReactNativePaper.Theme;
};
/**
@ -87,12 +85,20 @@ class ProximoMainScreen extends React.Component<PropsType> {
const str2 = b.type.name.toLowerCase();
// Make 'All' category with id -1 stick to the top
if (a.type.id === -1) return -1;
if (b.type.id === -1) return 1;
if (a.type.id === '-1') {
return -1;
}
if (b.type.id === '-1') {
return 1;
}
// Sort others by name ascending
if (str1 < str2) return -1;
if (str1 > str2) return 1;
if (str1 < str2) {
return -1;
}
if (str1 > str2) {
return 1;
}
return 0;
}
@ -105,16 +111,17 @@ class ProximoMainScreen extends React.Component<PropsType> {
*/
static getAvailableArticles(
articles: Array<ProximoArticleType> | null,
type: ?ProximoCategoryType,
type?: ProximoCategoryType,
): Array<ProximoArticleType> {
const availableArticles = [];
const availableArticles: Array<ProximoArticleType> = [];
if (articles != null) {
articles.forEach((article: ProximoArticleType) => {
if (
((type != null && article.type.includes(type.id)) || type == null) &&
parseInt(article.quantity, 10) > 0
)
) {
availableArticles.push(article);
}
});
}
return availableArticles;
@ -122,13 +129,18 @@ class ProximoMainScreen extends React.Component<PropsType> {
articles: Array<ProximoArticleType> | null;
constructor(props: PropsType) {
super(props);
this.articles = null;
}
/**
* Creates header button
*/
componentDidMount() {
const {navigation} = this.props;
navigation.setOptions({
headerRight: (): React.Node => this.getHeaderButtons(),
headerRight: () => this.getHeaderButtons(),
});
}
@ -168,7 +180,7 @@ class ProximoMainScreen extends React.Component<PropsType> {
* Gets the header buttons
* @return {*}
*/
getHeaderButtons(): React.Node {
getHeaderButtons() {
return (
<MaterialHeaderButtons>
<Item
@ -199,7 +211,7 @@ class ProximoMainScreen extends React.Component<PropsType> {
* @param item The category to render
* @return {*}
*/
getRenderItem = ({item}: {item: ProximoMainListItemType}): React.Node => {
getRenderItem = ({item}: {item: ProximoMainListItemType}) => {
const {navigation, theme} = this.props;
const dataToSend = {
shouldFocusSearchBar: false,
@ -219,14 +231,14 @@ class ProximoMainScreen extends React.Component<PropsType> {
title={item.type.name}
description={subtitle}
onPress={onPress}
left={(props: ListIconPropsType): React.Node => (
left={(props) => (
<List.Icon
style={props.style}
icon={item.type.icon}
color={theme.colors.primary}
/>
)}
right={(props: ListIconPropsType): React.Node => (
right={(props) => (
<List.Icon
color={props.color}
style={props.style}
@ -295,7 +307,7 @@ class ProximoMainScreen extends React.Component<PropsType> {
return finalData;
}
render(): React.Node {
render() {
const {navigation} = this.props;
return (
<WebSectionList

View file

@ -17,8 +17,6 @@
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/
// @flow
import * as React from 'react';
import {View} from 'react-native';
import {Card, Text, withTheme} from 'react-native-paper';
@ -26,32 +24,31 @@ import {StackNavigationProp} from '@react-navigation/stack';
import i18n from 'i18n-js';
import DateManager from '../../managers/DateManager';
import WebSectionList from '../../components/Screens/WebSectionList';
import type {CustomThemeType} from '../../managers/ThemeManager';
import type {SectionListDataType} from '../../components/Screens/WebSectionList';
const DATA_URL =
'https://etud.insa-toulouse.fr/~amicale_app/menu/menu_data.json';
type PropsType = {
navigation: StackNavigationProp,
theme: CustomThemeType,
navigation: StackNavigationProp<any>;
theme: ReactNativePaper.Theme;
};
export type RuFoodCategoryType = {
name: string,
dishes: Array<{name: string}>,
name: string;
dishes: Array<{name: string}>;
};
type RuMealType = {
name: string,
foodcategory: Array<RuFoodCategoryType>,
name: string;
foodcategory: Array<RuFoodCategoryType>;
};
type RawRuMenuType = {
restaurant_id: number,
id: number,
date: string,
meal: Array<RuMealType>,
restaurant_id: number;
id: number;
date: string;
meal: Array<RuMealType>;
};
/**
@ -77,7 +74,7 @@ class SelfMenuScreen extends React.Component<PropsType> {
createDataset = (
fetchedData: Array<RawRuMenuType>,
): SectionListDataType<RuFoodCategoryType> => {
let result = [];
let result: SectionListDataType<RuFoodCategoryType> = [];
if (fetchedData == null || fetchedData.length === 0) {
result = [
{
@ -104,11 +101,7 @@ class SelfMenuScreen extends React.Component<PropsType> {
* @param section The section to render the header from
* @return {*}
*/
getRenderSectionHeader = ({
section,
}: {
section: {title: string},
}): React.Node => {
getRenderSectionHeader = ({section}: {section: {title: string}}) => {
return (
<Card
style={{
@ -141,7 +134,7 @@ class SelfMenuScreen extends React.Component<PropsType> {
* @param item The item to render
* @return {*}
*/
getRenderItem = ({item}: {item: RuFoodCategoryType}): React.Node => {
getRenderItem = ({item}: {item: RuFoodCategoryType}) => {
const {theme} = this.props;
return (
<Card
@ -163,7 +156,7 @@ class SelfMenuScreen extends React.Component<PropsType> {
}}
/>
<Card.Content>
{item.dishes.map((object: {name: string}): React.Node =>
{item.dishes.map((object: {name: string}) =>
object.name !== '' ? (
<Text
style={{
@ -188,7 +181,7 @@ class SelfMenuScreen extends React.Component<PropsType> {
*/
getKeyExtractor = (item: RuFoodCategoryType): string => item.name;
render(): React.Node {
render() {
const {navigation} = this.props;
return (
<WebSectionList

View file

@ -17,8 +17,6 @@
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/
// @flow
import * as React from 'react';
import {Image, View} from 'react-native';
import {
@ -32,7 +30,6 @@ import {
import i18n from 'i18n-js';
import {StackNavigationProp} from '@react-navigation/stack';
import CardList from '../../components/Lists/CardList/CardList';
import type {CustomThemeType} from '../../managers/ThemeManager';
import MaterialHeaderButtons, {
Item,
} from '../../components/Overrides/CustomHeaderButton';
@ -46,8 +43,8 @@ import CollapsibleFlatList from '../../components/Collapsible/CollapsibleFlatLis
import type {ServiceCategoryType} from '../../managers/ServicesManager';
type PropsType = {
navigation: StackNavigationProp,
theme: CustomThemeType,
navigation: StackNavigationProp<any>;
theme: ReactNativePaper.Theme;
};
class ServicesScreen extends React.Component<PropsType> {
@ -68,7 +65,7 @@ class ServicesScreen extends React.Component<PropsType> {
});
}
getAboutButton = (): React.Node => (
getAboutButton = () => (
<MaterialHeaderButtons>
<Item
title="information"
@ -92,12 +89,11 @@ class ServicesScreen extends React.Component<PropsType> {
* @param source The source image to display. Can be a string for icons or a number for local images
* @returns {*}
*/
getListTitleImage(source: string | number): React.Node {
getListTitleImage(source: string | number) {
const {props} = this;
if (typeof source === 'number')
if (typeof source === 'number') {
return (
<Image
size={48}
source={source}
style={{
width: 48,
@ -105,6 +101,7 @@ class ServicesScreen extends React.Component<PropsType> {
}}
/>
);
}
return (
<Avatar.Icon
size={48}
@ -121,7 +118,7 @@ class ServicesScreen extends React.Component<PropsType> {
* @param item
* @returns {*}
*/
getRenderItem = ({item}: {item: ServiceCategoryType}): React.Node => {
getRenderItem = ({item}: {item: ServiceCategoryType}) => {
const {props} = this;
return (
<TouchableRipple
@ -136,8 +133,8 @@ class ServicesScreen extends React.Component<PropsType> {
<Card.Title
title={item.title}
subtitle={item.subtitle}
left={(): React.Node => this.getListTitleImage(item.image)}
right={(): React.Node => <List.Icon icon="chevron-right" />}
left={() => this.getListTitleImage(item.image)}
right={() => <List.Icon icon="chevron-right" />}
/>
<CardList dataset={item.content} isHorizontal />
</View>
@ -147,14 +144,14 @@ class ServicesScreen extends React.Component<PropsType> {
keyExtractor = (item: ServiceCategoryType): string => item.title;
render(): React.Node {
render() {
return (
<View>
<CollapsibleFlatList
data={this.finalDataset}
renderItem={this.getRenderItem}
keyExtractor={this.keyExtractor}
ItemSeparatorComponent={(): React.Node => <Divider />}
ItemSeparatorComponent={() => <Divider />}
hasTab
/>
<MascotPopup
@ -163,7 +160,6 @@ class ServicesScreen extends React.Component<PropsType> {
message={i18n.t('screens.services.mascotDialog.message')}
icon="cloud-question"
buttons={{
action: null,
cancel: {
message: i18n.t('screens.services.mascotDialog.button'),
icon: 'check',

View file

@ -17,28 +17,25 @@
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/
// @flow
import * as React from 'react';
import {Collapsible} from 'react-navigation-collapsible';
import {CommonActions} from '@react-navigation/native';
import {StackNavigationProp} from '@react-navigation/stack';
import CardList from '../../components/Lists/CardList/CardList';
import CustomTabBar from '../../components/Tabbar/CustomTabBar';
import withCollapsible from '../../utils/withCollapsible';
import type {ServiceCategoryType} from '../../managers/ServicesManager';
type PropsType = {
navigation: StackNavigationProp,
route: {params: {data: ServiceCategoryType | null}},
collapsibleStack: Collapsible,
navigation: StackNavigationProp<any>;
route: {params: {data: ServiceCategoryType | null}};
collapsibleStack: Collapsible;
};
class ServicesSectionScreen extends React.Component<PropsType> {
finalDataset: ServiceCategoryType;
finalDataset: null | ServiceCategoryType;
constructor(props: PropsType) {
super(props);
this.finalDataset = null;
this.handleNavigationParams();
}
@ -47,38 +44,24 @@ class ServicesSectionScreen extends React.Component<PropsType> {
*/
handleNavigationParams() {
const {props} = this;
if (props.route.params != null) {
if (props.route.params.data != null) {
this.finalDataset = props.route.params.data;
// reset params to prevent infinite loop
props.navigation.dispatch(CommonActions.setParams({data: null}));
props.navigation.setOptions({
headerTitle: this.finalDataset.title,
});
}
if (props.route.params.data) {
this.finalDataset = props.route.params.data;
// reset params to prevent infinite loop
props.navigation.dispatch(CommonActions.setParams({data: null}));
props.navigation.setOptions({
headerTitle: this.finalDataset.title,
});
}
}
render(): React.Node {
const {props} = this;
const {
containerPaddingTop,
scrollIndicatorInsetTop,
onScroll,
} = props.collapsibleStack;
render() {
if (!this.finalDataset) {
return null;
}
return (
<CardList
dataset={this.finalDataset.content}
isHorizontal={false}
onScroll={onScroll}
contentContainerStyle={{
paddingTop: containerPaddingTop,
paddingBottom: CustomTabBar.TAB_BAR_HEIGHT + 20,
}}
scrollIndicatorInsets={{top: scrollIndicatorInsetTop}}
/>
<CardList dataset={this.finalDataset.content} isHorizontal={false} />
);
}
}
export default withCollapsible(ServicesSectionScreen);
export default ServicesSectionScreen;

View file

@ -17,8 +17,6 @@
* along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
*/
// @flow
import * as React from 'react';
import {StackNavigationProp} from '@react-navigation/stack';
import WebViewScreen from '../../components/Screens/WebViewScreen';
@ -26,21 +24,24 @@ import AvailableWebsites from '../../constants/AvailableWebsites';
import BasicLoadingScreen from '../../components/Screens/BasicLoadingScreen';
type PropsType = {
navigation: StackNavigationProp,
route: {params: {host: string, path: string | null, title: string}},
navigation: StackNavigationProp<any>;
route: {params: {host: string; path: string | null; title: string}};
};
const ENABLE_MOBILE_STRING = `<meta name="viewport" content="width=device-width, initial-scale=1.0">`;
const ENABLE_MOBILE_STRING =
'<meta name="viewport" content="width=device-width, initial-scale=1.0">';
const AVAILABLE_ROOMS_STYLE = `<style>body,body>.container2{padding-top:0;width:100%}b,body>.container2>h1,body>.container2>h3,br,header{display:none}.table-bordered td,.table-bordered th{border:none;border-right:1px solid #dee2e6;border-bottom:1px solid #dee2e6}.table{padding:0;margin:0;width:200%;max-width:200%;display:block}tbody{display:block;width:100%}thead{display:block;width:100%}.table tbody tr,tbody tr[bgcolor],thead tr{width:100%;display:inline-flex}.table tbody td,.table thead td[colspan]{padding:0;flex:1;height:50px;margin:0}.table tbody td[bgcolor=white],.table thead td,.table>tbody>tr>td:nth-child(1){flex:0 0 150px;height:50px}</style>`;
const BIB_STYLE = `<style>.hero-unit,.navbar,footer{display:none}.hero-unit-form,.hero-unit2,.hero-unit3{background-color:#fff;box-shadow:none;padding:0;margin:0}.hero-unit-form h4{font-size:2rem;line-height:2rem}.btn{font-size:1.5rem;line-height:1.5rem;padding:20px}.btn-danger{background-image:none;background-color:#be1522}.table{font-size:.8rem}.table td{padding:0;height:18.2333px;border:none;border-bottom:1px solid #c1c1c1}.table td[style="max-width:55px;"]{max-width:110px!important}.table-bordered{min-width:50px}th{height:50px}.table-bordered{border-collapse:collapse}</style>`;
const AVAILABLE_ROOMS_STYLE =
'<style>body,body>.container2{padding-top:0;width:100%}b,body>.container2>h1,body>.container2>h3,br,header{display:none}.table-bordered td,.table-bordered th{border:none;border-right:1px solid #dee2e6;border-bottom:1px solid #dee2e6}.table{padding:0;margin:0;width:200%;max-width:200%;display:block}tbody{display:block;width:100%}thead{display:block;width:100%}.table tbody tr,tbody tr[bgcolor],thead tr{width:100%;display:inline-flex}.table tbody td,.table thead td[colspan]{padding:0;flex:1;height:50px;margin:0}.table tbody td[bgcolor=white],.table thead td,.table>tbody>tr>td:nth-child(1){flex:0 0 150px;height:50px}</style>';
const BIB_STYLE =
'<style>.hero-unit,.navbar,footer{display:none}.hero-unit-form,.hero-unit2,.hero-unit3{background-color:#fff;box-shadow:none;padding:0;margin:0}.hero-unit-form h4{font-size:2rem;line-height:2rem}.btn{font-size:1.5rem;line-height:1.5rem;padding:20px}.btn-danger{background-image:none;background-color:#be1522}.table{font-size:.8rem}.table td{padding:0;height:18.2333px;border:none;border-bottom:1px solid #c1c1c1}.table td[style="max-width:55px;"]{max-width:110px!important}.table-bordered{min-width:50px}th{height:50px}.table-bordered{border-collapse:collapse}</style>';
const BIB_BACK_BUTTON =
`<div style='width: 100%; display: flex'>` +
"<div style='width: 100%; display: flex'>" +
`<a style='margin: auto' href='${AvailableWebsites.websites.BIB}'>` +
`<button id='customBackButton' class='btn btn-primary'>Retour</button>` +
`</a>` +
`</div>`;
"<button id='customBackButton' class='btn btn-primary'>Retour</button>" +
'</a>' +
'</div>';
class WebsiteScreen extends React.Component<PropsType> {
fullUrl: string;
@ -53,6 +54,8 @@ class WebsiteScreen extends React.Component<PropsType> {
constructor(props: PropsType) {
super(props);
this.fullUrl = '';
this.host = '';
props.navigation.addListener('focus', this.onScreenFocus);
this.injectedJS = {};
this.customPaddingFunctions = {};
@ -63,7 +66,7 @@ class WebsiteScreen extends React.Component<PropsType> {
this.injectedJS[AvailableWebsites.websites.BIB] =
`document.querySelector('head').innerHTML += '${ENABLE_MOBILE_STRING}';` +
`document.querySelector('head').innerHTML += '${BIB_STYLE}';` +
`if ($(".hero-unit-form").length > 0 && $("#customBackButton").length === 0)` +
'if ($(".hero-unit-form").length > 0 && $("#customBackButton").length === 0)' +
`$(".hero-unit-form").append("${BIB_BACK_BUTTON}");true;`;
this.customPaddingFunctions[AvailableWebsites.websites.BLUEMIND] = (
@ -72,7 +75,7 @@ class WebsiteScreen extends React.Component<PropsType> {
return (
`$('head').append('${ENABLE_MOBILE_STRING}');` +
`$('.minwidth').css('top', ${padding}` +
`$('#mailview-bottom').css('min-height', 500);`
"$('#mailview-bottom').css('min-height', 500);"
);
};
this.customPaddingFunctions[AvailableWebsites.websites.WIKETUD] = (
@ -103,20 +106,26 @@ class WebsiteScreen extends React.Component<PropsType> {
if (this.host != null && path != null) {
path = path.replace(this.host, '');
this.fullUrl = this.host + path;
} else this.fullUrl = this.host;
} else {
this.fullUrl = this.host;
}
if (title != null) navigation.setOptions({title});
if (title != null) {
navigation.setOptions({title});
}
}
}
render(): React.Node {
render() {
const {navigation} = this.props;
let injectedJavascript = '';
let customPadding = null;
if (this.host != null && this.injectedJS[this.host] != null)
if (this.host != null && this.injectedJS[this.host] != null) {
injectedJavascript = this.injectedJS[this.host];
if (this.host != null && this.customPaddingFunctions[this.host] != null)
}
if (this.host != null && this.customPaddingFunctions[this.host] != null) {
customPadding = this.customPaddingFunctions[this.host];
}
if (this.fullUrl != null) {
return (