From fcbc70956b8321dd6c64406a4baace9efe73448d Mon Sep 17 00:00:00 2001 From: Arnaud Vergnet Date: Wed, 5 Aug 2020 18:39:44 +0200 Subject: [PATCH] Improve Services screen components to match linter --- .../Lists/Proxiwash/ProxiwashListItem.js | 4 +- .../Lists/Proxiwash/ProxiwashSectionHeader.js | 4 +- src/components/Screens/WebViewScreen.js | 4 +- src/managers/AprilFoolsManager.js | 5 +- src/screens/Proxiwash/ProxiwashScreen.js | 4 +- .../Services/Proximo/ProximoListScreen.js | 4 +- .../Services/Proximo/ProximoMainScreen.js | 4 +- src/screens/Services/SelfMenuScreen.js | 315 ++++++++++-------- src/screens/Services/ServicesScreen.js | 4 +- src/screens/Services/WebsiteScreen.js | 183 +++++----- 10 files changed, 280 insertions(+), 251 deletions(-) diff --git a/src/components/Lists/Proxiwash/ProxiwashListItem.js b/src/components/Lists/Proxiwash/ProxiwashListItem.js index bc22bdf..cc7a0a8 100644 --- a/src/components/Lists/Proxiwash/ProxiwashListItem.js +++ b/src/components/Lists/Proxiwash/ProxiwashListItem.js @@ -15,12 +15,12 @@ import i18n from 'i18n-js'; import * as Animatable from 'react-native-animatable'; import ProxiwashConstants from '../../../constants/ProxiwashConstants'; import AprilFoolsManager from '../../../managers/AprilFoolsManager'; -import type {CustomTheme} from '../../../managers/ThemeManager'; +import type {CustomThemeType} from '../../../managers/ThemeManager'; import type {ProxiwashMachineType} from '../../../screens/Proxiwash/ProxiwashScreen'; type PropsType = { item: ProxiwashMachineType, - theme: CustomTheme, + theme: CustomThemeType, onPress: ( title: string, item: ProxiwashMachineType, diff --git a/src/components/Lists/Proxiwash/ProxiwashSectionHeader.js b/src/components/Lists/Proxiwash/ProxiwashSectionHeader.js index 3c7d2ef..188e3a4 100644 --- a/src/components/Lists/Proxiwash/ProxiwashSectionHeader.js +++ b/src/components/Lists/Proxiwash/ProxiwashSectionHeader.js @@ -4,10 +4,10 @@ import * as React from 'react'; import {Avatar, Text, withTheme} from 'react-native-paper'; import {StyleSheet, View} from 'react-native'; import i18n from 'i18n-js'; -import type {CustomTheme} from '../../../managers/ThemeManager'; +import type {CustomThemeType} from '../../../managers/ThemeManager'; type PropsType = { - theme: CustomTheme, + theme: CustomThemeType, title: string, isDryer: boolean, nbAvailable: number, diff --git a/src/components/Screens/WebViewScreen.js b/src/components/Screens/WebViewScreen.js index 9dc715a..3811e7b 100644 --- a/src/components/Screens/WebViewScreen.js +++ b/src/components/Screens/WebViewScreen.js @@ -13,7 +13,7 @@ import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityI import {withTheme} from 'react-native-paper'; import {StackNavigationProp} from '@react-navigation/stack'; import {Collapsible} from 'react-navigation-collapsible'; -import type {CustomTheme} from '../../managers/ThemeManager'; +import type {CustomThemeType} from '../../managers/ThemeManager'; import {withCollapsible} from '../../utils/withCollapsible'; import MaterialHeaderButtons, {Item} from '../Overrides/CustomHeaderButton'; import {ERROR_TYPE} from '../../utils/WebData'; @@ -22,7 +22,7 @@ import BasicLoadingScreen from './BasicLoadingScreen'; type PropsType = { navigation: StackNavigationProp, - theme: CustomTheme, + theme: CustomThemeType, url: string, collapsibleStack: Collapsible, onMessage: (event: {nativeEvent: {data: string}}) => void, diff --git a/src/managers/AprilFoolsManager.js b/src/managers/AprilFoolsManager.js index 1afc9a5..b3aafbd 100644 --- a/src/managers/AprilFoolsManager.js +++ b/src/managers/AprilFoolsManager.js @@ -2,6 +2,7 @@ import type {ProxiwashMachineType} from '../screens/Proxiwash/ProxiwashScreen'; import type {CustomThemeType} from './ThemeManager'; +import type {RuFoodCategoryType} from '../screens/Services/SelfMenuScreen'; /** * Singleton class used to manage april fools @@ -49,8 +50,8 @@ export default class AprilFoolsManager { * @returns {Object} */ static getFakeMenuItem( - menu: Array<{dishes: Array<{name: string}>}>, - ): Array<{dishes: Array<{name: string}>}> { + menu: Array, + ): Array { menu[1].dishes.splice(4, 0, {name: 'Coq au vin'}); menu[1].dishes.splice(2, 0, {name: "Bat'Soupe"}); menu[1].dishes.splice(1, 0, {name: 'Pave de loup'}); diff --git a/src/screens/Proxiwash/ProxiwashScreen.js b/src/screens/Proxiwash/ProxiwashScreen.js index 986cf78..2cbb3c7 100644 --- a/src/screens/Proxiwash/ProxiwashScreen.js +++ b/src/screens/Proxiwash/ProxiwashScreen.js @@ -17,7 +17,7 @@ import MaterialHeaderButtons, { Item, } from '../../components/Overrides/CustomHeaderButton'; import ProxiwashSectionHeader from '../../components/Lists/Proxiwash/ProxiwashSectionHeader'; -import type {CustomTheme} from '../../managers/ThemeManager'; +import type {CustomThemeType} from '../../managers/ThemeManager'; import { getCleanedMachineWatched, getMachineEndDate, @@ -47,7 +47,7 @@ export type ProxiwashMachineType = { type PropsType = { navigation: StackNavigationProp, - theme: CustomTheme, + theme: CustomThemeType, }; type StateType = { diff --git a/src/screens/Services/Proximo/ProximoListScreen.js b/src/screens/Services/Proximo/ProximoListScreen.js index c405cc6..cebe697 100644 --- a/src/screens/Services/Proximo/ProximoListScreen.js +++ b/src/screens/Services/Proximo/ProximoListScreen.js @@ -19,7 +19,7 @@ import ProximoListItem from '../../../components/Lists/Proximo/ProximoListItem'; import MaterialHeaderButtons, { Item, } from '../../../components/Overrides/CustomHeaderButton'; -import type {CustomTheme} from '../../../managers/ThemeManager'; +import type {CustomThemeType} from '../../../managers/ThemeManager'; import CollapsibleFlatList from '../../../components/Collapsible/CollapsibleFlatList'; import type {ProximoArticleType} from './ProximoMainScreen'; @@ -56,7 +56,7 @@ type PropsType = { shouldFocusSearchBar: boolean, }, }, - theme: CustomTheme, + theme: CustomThemeType, }; type StateType = { diff --git a/src/screens/Services/Proximo/ProximoMainScreen.js b/src/screens/Services/Proximo/ProximoMainScreen.js index ab9f546..367989b 100644 --- a/src/screens/Services/Proximo/ProximoMainScreen.js +++ b/src/screens/Services/Proximo/ProximoMainScreen.js @@ -8,7 +8,7 @@ import WebSectionList from '../../../components/Screens/WebSectionList'; import MaterialHeaderButtons, { Item, } from '../../../components/Overrides/CustomHeaderButton'; -import type {CustomTheme} from '../../../managers/ThemeManager'; +import type {CustomThemeType} from '../../../managers/ThemeManager'; import type {SectionListDataType} from '../../../components/Screens/WebSectionList'; const DATA_URL = 'https://etud.insa-toulouse.fr/~proximo/data/stock-v2.json'; @@ -43,7 +43,7 @@ export type ProximoDataType = { type PropsType = { navigation: StackNavigationProp, - theme: CustomTheme, + theme: CustomThemeType, }; /** diff --git a/src/screens/Services/SelfMenuScreen.js b/src/screens/Services/SelfMenuScreen.js index 87c3a4a..3ca9b0b 100644 --- a/src/screens/Services/SelfMenuScreen.js +++ b/src/screens/Services/SelfMenuScreen.js @@ -2,167 +2,188 @@ import * as React from 'react'; import {View} from 'react-native'; -import DateManager from "../../managers/DateManager"; -import WebSectionList from "../../components/Screens/WebSectionList"; import {Card, Text, withTheme} from 'react-native-paper'; -import AprilFoolsManager from "../../managers/AprilFoolsManager"; -import {StackNavigationProp} from "@react-navigation/stack"; -import type {CustomTheme} from "../../managers/ThemeManager"; +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"; +const DATA_URL = + 'https://etud.insa-toulouse.fr/~amicale_app/menu/menu_data.json'; -type Props = { - navigation: StackNavigationProp, - theme: CustomTheme, -} +type PropsType = { + navigation: StackNavigationProp, + theme: CustomThemeType, +}; + +export type RuFoodCategoryType = { + name: string, + dishes: Array<{name: string}>, +}; + +type RuMealType = { + name: string, + foodcategory: Array, +}; + +type RawRuMenuType = { + restaurant_id: number, + id: number, + date: string, + meal: Array, +}; /** * Class defining the app's menu screen. */ -class SelfMenuScreen extends React.Component { +class SelfMenuScreen extends React.Component { + /** + * Formats the given string to make sure it starts with a capital letter + * + * @param name The string to format + * @return {string} The formatted string + */ + static formatName(name: string): string { + return name.charAt(0) + name.substr(1).toLowerCase(); + } - /** - * 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: Array, + ): SectionListDataType => { + let result = []; + if (fetchedData == null || fetchedData.length === 0) { + result = [ + { + title: i18n.t('general.notAvailable'), + data: [], + keyExtractor: this.getKeyExtractor, + }, + ]; + } else { + fetchedData.forEach((item: RawRuMenuType) => { + result.push({ + title: DateManager.getInstance().getTranslatedDate(item.date), + data: item.meal[0].foodcategory, + keyExtractor: this.getKeyExtractor, + }); + }); } + return result; + }; - /** - * Creates the dataset to be used in the FlatList - * - * @param fetchedData - * @return {[]} - */ - createDataset = (fetchedData: Object) => { - let result = []; - if (fetchedData == null || Object.keys(fetchedData).length === 0) { - result = [ - { - title: i18n.t("general.notAvailable"), - data: [], - keyExtractor: this.getKeyExtractor - } - ]; - } else { - if (AprilFoolsManager.getInstance().isAprilFoolsEnabled() && fetchedData.length > 0) - fetchedData[0].meal[0].foodcategory = AprilFoolsManager.getFakeMenuItem(fetchedData[0].meal[0].foodcategory); - // fetched data is an array here - for (let i = 0; i < fetchedData.length; i++) { - result.push( - { - title: DateManager.getInstance().getTranslatedDate(fetchedData[i].date), - data: fetchedData[i].meal[0].foodcategory, - keyExtractor: this.getKeyExtractor, - } - ); - } - } - return result - }; + /** + * Gets the render section header + * + * @param section The section to render the header from + * @return {*} + */ + getRenderSectionHeader = ({ + section, + }: { + section: {title: string}, + }): React.Node => { + return ( + + + + ); + }; - /** - * Gets the render section header - * - * @param section The section to render the header from - * @return {*} - */ - getRenderSectionHeader = ({section}: Object) => { - return ( - - - - ); - }; + /** + * Gets a FlatList render item + * + * @param item The item to render + * @return {*} + */ + getRenderItem = ({item}: {item: RuFoodCategoryType}): React.Node => { + const {theme} = this.props; + return ( + + + + + {item.dishes.map((object: {name: string}): React.Node => + object.name !== '' ? ( + + {SelfMenuScreen.formatName(object.name)} + + ) : null, + )} + + + ); + }; - /** - * Gets a FlatList render item - * - * @param item The item to render - * @return {*} - */ - getRenderItem = ({item}: Object) => { - return ( - - - - - {item.dishes.map((object) => - - {object.name !== "" ? - {this.formatName(object.name)} - : } - )} - - - ); - }; + /** + * Extract a key for the given item + * + * @param item The item to extract the key from + * @return {*} The extracted key + */ + getKeyExtractor = (item: RuFoodCategoryType): string => item.name; - /** - * 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(); - } - - render() { - const nav = this.props.navigation; - return ( - - ); - } + render(): React.Node { + const {navigation} = this.props; + return ( + + ); + } } export default withTheme(SelfMenuScreen); diff --git a/src/screens/Services/ServicesScreen.js b/src/screens/Services/ServicesScreen.js index e54e9d4..03c9c65 100644 --- a/src/screens/Services/ServicesScreen.js +++ b/src/screens/Services/ServicesScreen.js @@ -13,7 +13,7 @@ import { import i18n from 'i18n-js'; import {StackNavigationProp} from '@react-navigation/stack'; import CardList from '../../components/Lists/CardList/CardList'; -import type {CustomTheme} from '../../managers/ThemeManager'; +import type {CustomThemeType} from '../../managers/ThemeManager'; import MaterialHeaderButtons, { Item, } from '../../components/Overrides/CustomHeaderButton'; @@ -28,7 +28,7 @@ import type {ServiceCategoryType} from '../../managers/ServicesManager'; type PropsType = { navigation: StackNavigationProp, - theme: CustomTheme, + theme: CustomThemeType, }; class ServicesScreen extends React.Component { diff --git a/src/screens/Services/WebsiteScreen.js b/src/screens/Services/WebsiteScreen.js index 1ace1e2..44d2130 100644 --- a/src/screens/Services/WebsiteScreen.js +++ b/src/screens/Services/WebsiteScreen.js @@ -1,109 +1,116 @@ // @flow - import * as React from 'react'; -import {StackNavigationProp} from "@react-navigation/stack"; -import WebViewScreen from "../../components/Screens/WebViewScreen"; -import AvailableWebsites from "../../constants/AvailableWebsites"; -import BasicLoadingScreen from "../../components/Screens/BasicLoadingScreen"; +import {StackNavigationProp} from '@react-navigation/stack'; +import WebViewScreen from '../../components/Screens/WebViewScreen'; +import AvailableWebsites from '../../constants/AvailableWebsites'; +import BasicLoadingScreen from '../../components/Screens/BasicLoadingScreen'; -type Props = { - navigation: StackNavigationProp, - route: { params: { host: string, path: string | null, title: string } }, -} +type PropsType = { + navigation: StackNavigationProp, + route: {params: {host: string, path: string | null, title: string}}, +}; -class WebsiteScreen extends React.Component { +const ENABLE_MOBILE_STRING = ``; - fullUrl: string; - injectedJS: { [key: string]: string }; - customPaddingFunctions: {[key: string]: (padding: string) => string} +const AVAILABLE_ROOMS_STYLE = ``; +const BIB_STYLE = ``; - host: string; +const BIB_BACK_BUTTON = + `
` + + `` + + `` + + `` + + `
`; - constructor(props: Props) { - super(props); - this.props.navigation.addListener('focus', this.onScreenFocus); - this.injectedJS = {}; - this.customPaddingFunctions = {}; - this.injectedJS[AvailableWebsites.websites.AVAILABLE_ROOMS] = - 'document.querySelector(\'head\').innerHTML += \'\';' + - 'document.querySelector(\'head\').innerHTML += \'\'; true;'; +class WebsiteScreen extends React.Component { + fullUrl: string; - this.injectedJS[AvailableWebsites.websites.BIB] = - 'document.querySelector(\'head\').innerHTML += \'\';' + - 'document.querySelector(\'head\').innerHTML += \'\';' + - 'if ($(".hero-unit-form").length > 0 && $("#customBackButton").length === 0)' + - '$(".hero-unit-form").append("' + - '
' + - '' + - '' + - '' + - '
");true;'; + injectedJS: {[key: string]: string}; - this.customPaddingFunctions[AvailableWebsites.websites.BLUEMIND] = (padding: string) => { - return ( - "$('head').append('');" + - "$('.minwidth').css('top', " + padding + ");" + - "$('#mailview-bottom').css('min-height', 500);" - ); - }; - this.customPaddingFunctions[AvailableWebsites.websites.WIKETUD] = (padding: string) => { - return ( - "$('#p-logo-text').css('top', 10 + " + padding + ");" + - "$('#site-navigation h2').css('top', 10 + " + padding + ");" + - "$('#site-tools h2').css('top', 10 + " + padding + ");" + - "$('#user-tools h2').css('top', 10 + " + padding + ");" - ); - } - } + customPaddingFunctions: {[key: string]: (padding: string) => string}; - onScreenFocus = () => { - this.handleNavigationParams(); + host: string; + + constructor(props: PropsType) { + super(props); + props.navigation.addListener('focus', this.onScreenFocus); + this.injectedJS = {}; + this.customPaddingFunctions = {}; + this.injectedJS[AvailableWebsites.websites.AVAILABLE_ROOMS] = + `document.querySelector('head').innerHTML += '${ENABLE_MOBILE_STRING}';` + + `document.querySelector('head').innerHTML += '${AVAILABLE_ROOMS_STYLE}'; true;`; + + 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)` + + `$(".hero-unit-form").append("${BIB_BACK_BUTTON}");true;`; + + this.customPaddingFunctions[AvailableWebsites.websites.BLUEMIND] = ( + padding: string, + ): string => { + return ( + `$('head').append('${ENABLE_MOBILE_STRING}');` + + `$('.minwidth').css('top', ${padding}` + + `$('#mailview-bottom').css('min-height', 500);` + ); }; + this.customPaddingFunctions[AvailableWebsites.websites.WIKETUD] = ( + padding: string, + ): string => { + return ( + `$('#p-logo-text').css('top', 10 + ${padding});` + + `$('#site-navigation h2').css('top', 10 + ${padding});` + + `$('#site-tools h2').css('top', 10 + ${padding});` + + `$('#user-tools h2').css('top', 10 + ${padding});` + ); + }; + } - /** - * - */ - handleNavigationParams() { - if (this.props.route.params != null) { - this.host = this.props.route.params.host; - let path = this.props.route.params.path; - const title = this.props.route.params.title; - if (this.host != null && path != null) { - path = path.replace(this.host, ""); - this.fullUrl = this.host + path; - }else - this.fullUrl = this.host; + onScreenFocus = () => { + this.handleNavigationParams(); + }; - if (title != null) - this.props.navigation.setOptions({title: title}); - } + /** + * + */ + handleNavigationParams() { + const {route, navigation} = this.props; + if (route.params != null) { + this.host = route.params.host; + let {path} = route.params; + const {title} = route.params; + if (this.host != null && path != null) { + path = path.replace(this.host, ''); + this.fullUrl = this.host + path; + } else this.fullUrl = this.host; + + if (title != null) navigation.setOptions({title}); } + } - render() { - let injectedJavascript = ""; - let customPadding = null; - if (this.host != null && this.injectedJS[this.host] != null) - injectedJavascript = this.injectedJS[this.host]; - if (this.host != null && this.customPaddingFunctions[this.host] != null) - customPadding = this.customPaddingFunctions[this.host]; - - if (this.fullUrl != null) { - return ( - - ); - } else { - return ( - - ); - } + render(): React.Node { + const {navigation} = this.props; + let injectedJavascript = ''; + let customPadding = null; + if (this.host != null && this.injectedJS[this.host] != null) + injectedJavascript = this.injectedJS[this.host]; + if (this.host != null && this.customPaddingFunctions[this.host] != null) + customPadding = this.customPaddingFunctions[this.host]; + if (this.fullUrl != null) { + return ( + + ); } + return ; + } } export default WebsiteScreen;