From 1e81b2cd7b9d27fa6b73c758a13242bfe508335d Mon Sep 17 00:00:00 2001 From: Arnaud Vergnet Date: Wed, 5 Aug 2020 20:58:28 +0200 Subject: [PATCH] Improve remaining files to match linter --- App.js | 4 +- index.js | 1 + metro.config.js | 17 +- .../Amicale/Vote/VoteNotAvailable.js | 4 +- src/components/Amicale/Vote/VoteResults.js | 4 +- src/components/Amicale/Vote/VoteWait.js | 4 +- .../Animations/AnimatedAccordion.js | 4 +- .../Animations/AnimatedBottomBar.js | 7 +- .../Collapsible/CollapsibleComponent.js | 2 +- src/components/Home/ActionsDashboardItem.js | 4 +- src/components/Home/EventDashboardItem.js | 4 +- src/components/Home/SmallDashboardItem.js | 4 +- src/components/Lists/Clubs/ClubListItem.js | 4 +- .../DashboardEdit/DashboardEditAccordion.js | 4 +- .../Lists/DashboardEdit/DashboardEditItem.js | 4 +- .../DashboardEdit/DashboardEditPreviewItem.js | 4 +- .../Lists/Equipment/EquipmentListItem.js | 4 +- .../Lists/PlanexGroups/GroupListAccordion.js | 4 +- .../Lists/PlanexGroups/GroupListItem.js | 4 +- src/components/Mascot/MascotPopup.js | 4 +- src/components/Overrides/CustomAgenda.js | 4 +- src/components/Overrides/CustomHTML.js | 4 +- .../Overrides/CustomHeaderButton.js | 4 +- src/components/Overrides/CustomModal.js | 4 +- src/components/Overrides/CustomSlider.js | 4 +- src/components/Screens/BasicLoadingScreen.js | 4 +- src/components/Screens/ErrorView.js | 15 +- src/components/Screens/WebSectionList.js | 2 +- src/components/Screens/WebViewScreen.js | 2 +- src/components/Tabbar/CustomTabBar.js | 4 +- src/components/Tabbar/TabHomeIcon.js | 4 +- src/components/Tabbar/TabIcon.js | 4 +- src/screens/About/AboutScreen.js | 4 +- src/screens/Game/logic/Piece.js | 326 +++++++++--------- src/screens/Home/HomeScreen.js | 4 +- src/screens/Planex/PlanexScreen.js | 4 +- src/screens/Services/ServicesSectionScreen.js | 2 +- src/utils/AutoHideHandler.js | 129 ++++--- src/utils/CollapsibleUtils.js | 70 ++-- 39 files changed, 362 insertions(+), 323 deletions(-) diff --git a/App.js b/App.js index 15a91ba..3a0042c 100644 --- a/App.js +++ b/App.js @@ -10,7 +10,7 @@ import {OverflowMenuProvider} from 'react-navigation-header-buttons'; import LocaleManager from './src/managers/LocaleManager'; import AsyncStorageManager from './src/managers/AsyncStorageManager'; import CustomIntroSlider from './src/components/Overrides/CustomIntroSlider'; -import type {CustomTheme} from './src/managers/ThemeManager'; +import type {CustomThemeType} from './src/managers/ThemeManager'; import ThemeManager from './src/managers/ThemeManager'; import MainNavigator from './src/navigation/MainNavigator'; import AprilFoolsManager from './src/managers/AprilFoolsManager'; @@ -35,7 +35,7 @@ type StateType = { showIntro: boolean, showUpdate: boolean, showAprilFools: boolean, - currentTheme: CustomTheme | null, + currentTheme: CustomThemeType | null, }; export default class App extends React.Component { diff --git a/index.js b/index.js index a850d03..e9e66f0 100644 --- a/index.js +++ b/index.js @@ -6,4 +6,5 @@ import {AppRegistry} from 'react-native'; import App from './App'; import {name as appName} from './app.json'; +// eslint-disable-next-line flowtype/require-return-type AppRegistry.registerComponent(appName, () => App); diff --git a/metro.config.js b/metro.config.js index 783f349..4c78812 100644 --- a/metro.config.js +++ b/metro.config.js @@ -6,12 +6,13 @@ */ module.exports = { - transformer: { - getTransformOptions: async () => ({ - transform: { - experimentalImportSupport: false, - inlineRequires: false, - }, - }), - }, + transformer: { + // eslint-disable-next-line flowtype/require-return-type + getTransformOptions: async () => ({ + transform: { + experimentalImportSupport: false, + inlineRequires: false, + }, + }), + }, }; diff --git a/src/components/Amicale/Vote/VoteNotAvailable.js b/src/components/Amicale/Vote/VoteNotAvailable.js index 7240009..61a319c 100644 --- a/src/components/Amicale/Vote/VoteNotAvailable.js +++ b/src/components/Amicale/Vote/VoteNotAvailable.js @@ -4,10 +4,10 @@ import * as React from 'react'; import {View} from 'react-native'; import {Headline, withTheme} from 'react-native-paper'; import i18n from 'i18n-js'; -import type {CustomTheme} from '../../../managers/ThemeManager'; +import type {CustomThemeType} from '../../../managers/ThemeManager'; type PropsType = { - theme: CustomTheme, + theme: CustomThemeType, }; class VoteNotAvailable extends React.Component { diff --git a/src/components/Amicale/Vote/VoteResults.js b/src/components/Amicale/Vote/VoteResults.js index 931e3d0..5e69d4f 100644 --- a/src/components/Amicale/Vote/VoteResults.js +++ b/src/components/Amicale/Vote/VoteResults.js @@ -12,12 +12,12 @@ import { import {FlatList, StyleSheet} from 'react-native'; import i18n from 'i18n-js'; import type {VoteTeamType} from '../../../screens/Amicale/VoteScreen'; -import type {CustomTheme} from '../../../managers/ThemeManager'; +import type {CustomThemeType} from '../../../managers/ThemeManager'; type PropsType = { teams: Array, dateEnd: string, - theme: CustomTheme, + theme: CustomThemeType, }; const styles = StyleSheet.create({ diff --git a/src/components/Amicale/Vote/VoteWait.js b/src/components/Amicale/Vote/VoteWait.js index e882aaf..624ad71 100644 --- a/src/components/Amicale/Vote/VoteWait.js +++ b/src/components/Amicale/Vote/VoteWait.js @@ -9,14 +9,14 @@ import { } from 'react-native-paper'; import {StyleSheet} from 'react-native'; import i18n from 'i18n-js'; -import type {CustomTheme} from '../../../managers/ThemeManager'; +import type {CustomThemeType} from '../../../managers/ThemeManager'; type PropsType = { startDate: string | null, justVoted: boolean, hasVoted: boolean, isVoteRunning: boolean, - theme: CustomTheme, + theme: CustomThemeType, }; const styles = StyleSheet.create({ diff --git a/src/components/Animations/AnimatedAccordion.js b/src/components/Animations/AnimatedAccordion.js index 18e324c..f54da60 100644 --- a/src/components/Animations/AnimatedAccordion.js +++ b/src/components/Animations/AnimatedAccordion.js @@ -5,10 +5,10 @@ import {View} from 'react-native'; import {List, withTheme} from 'react-native-paper'; import Collapsible from 'react-native-collapsible'; import * as Animatable from 'react-native-animatable'; -import type {CustomTheme} from '../../managers/ThemeManager'; +import type {CustomThemeType} from '../../managers/ThemeManager'; type PropsType = { - theme: CustomTheme, + theme: CustomThemeType, title: string, subtitle?: string, left?: () => React.Node, diff --git a/src/components/Animations/AnimatedBottomBar.js b/src/components/Animations/AnimatedBottomBar.js index 1471171..d7fe932 100644 --- a/src/components/Animations/AnimatedBottomBar.js +++ b/src/components/Animations/AnimatedBottomBar.js @@ -7,13 +7,14 @@ import * as Animatable from 'react-native-animatable'; import {StackNavigationProp} from '@react-navigation/stack'; import AutoHideHandler from '../../utils/AutoHideHandler'; import CustomTabBar from '../Tabbar/CustomTabBar'; -import type {CustomTheme} from '../../managers/ThemeManager'; +import type {CustomThemeType} from '../../managers/ThemeManager'; +import type {OnScrollType} from '../../utils/AutoHideHandler'; const AnimatedFAB = Animatable.createAnimatableComponent(FAB); type PropsType = { navigation: StackNavigationProp, - theme: CustomTheme, + theme: CustomThemeType, onPress: (action: string, data?: string) => void, seekAttention: boolean, }; @@ -94,7 +95,7 @@ class AnimatedBottomBar extends React.Component { } }; - onScroll = (event: SyntheticEvent) => { + onScroll = (event: OnScrollType) => { this.hideHandler.onScroll(event); }; diff --git a/src/components/Collapsible/CollapsibleComponent.js b/src/components/Collapsible/CollapsibleComponent.js index c9be36f..bb1b693 100644 --- a/src/components/Collapsible/CollapsibleComponent.js +++ b/src/components/Collapsible/CollapsibleComponent.js @@ -2,7 +2,7 @@ import * as React from 'react'; import {Collapsible} from 'react-navigation-collapsible'; -import {withCollapsible} from '../../utils/withCollapsible'; +import withCollapsible from '../../utils/withCollapsible'; import CustomTabBar from '../Tabbar/CustomTabBar'; export type CollapsibleComponentPropsType = { diff --git a/src/components/Home/ActionsDashboardItem.js b/src/components/Home/ActionsDashboardItem.js index 662c459..24efae0 100644 --- a/src/components/Home/ActionsDashboardItem.js +++ b/src/components/Home/ActionsDashboardItem.js @@ -5,11 +5,11 @@ import {List, withTheme} from 'react-native-paper'; import {View} from 'react-native'; import i18n from 'i18n-js'; import {StackNavigationProp} from '@react-navigation/stack'; -import type {CustomTheme} from '../../managers/ThemeManager'; +import type {CustomThemeType} from '../../managers/ThemeManager'; type PropsType = { navigation: StackNavigationProp, - theme: CustomTheme, + theme: CustomThemeType, }; class ActionsDashBoardItem extends React.Component { diff --git a/src/components/Home/EventDashboardItem.js b/src/components/Home/EventDashboardItem.js index f9f06b7..6fb948e 100644 --- a/src/components/Home/EventDashboardItem.js +++ b/src/components/Home/EventDashboardItem.js @@ -10,12 +10,12 @@ import { } 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 = { eventNumber: number, clickAction: () => void, - theme: CustomTheme, + theme: CustomThemeType, children?: React.Node, }; diff --git a/src/components/Home/SmallDashboardItem.js b/src/components/Home/SmallDashboardItem.js index 5f2e5d6..492ad69 100644 --- a/src/components/Home/SmallDashboardItem.js +++ b/src/components/Home/SmallDashboardItem.js @@ -4,13 +4,13 @@ import * as React from 'react'; import {Badge, TouchableRipple, withTheme} from 'react-native-paper'; import {Dimensions, Image, View} from 'react-native'; import * as Animatable from 'react-native-animatable'; -import type {CustomTheme} from '../../managers/ThemeManager'; +import type {CustomThemeType} from '../../managers/ThemeManager'; type PropsType = { image: string | null, onPress: () => void | null, badgeCount: number | null, - theme: CustomTheme, + theme: CustomThemeType, }; const AnimatableBadge = Animatable.createAnimatableComponent(Badge); diff --git a/src/components/Lists/Clubs/ClubListItem.js b/src/components/Lists/Clubs/ClubListItem.js index ce59d42..297ca7f 100644 --- a/src/components/Lists/Clubs/ClubListItem.js +++ b/src/components/Lists/Clubs/ClubListItem.js @@ -7,14 +7,14 @@ import type { ClubCategoryType, ClubType, } from '../../../screens/Amicale/Clubs/ClubListScreen'; -import type {CustomTheme} from '../../../managers/ThemeManager'; +import type {CustomThemeType} from '../../../managers/ThemeManager'; type PropsType = { onPress: () => void, categoryTranslator: (id: number) => ClubCategoryType, item: ClubType, height: number, - theme: CustomTheme, + theme: CustomThemeType, }; class ClubListItem extends React.Component { diff --git a/src/components/Lists/DashboardEdit/DashboardEditAccordion.js b/src/components/Lists/DashboardEdit/DashboardEditAccordion.js index 67146ef..cd89992 100644 --- a/src/components/Lists/DashboardEdit/DashboardEditAccordion.js +++ b/src/components/Lists/DashboardEdit/DashboardEditAccordion.js @@ -10,13 +10,13 @@ import type { ServiceCategoryType, ServiceItemType, } from '../../../managers/ServicesManager'; -import type {CustomTheme} from '../../../managers/ThemeManager'; +import type {CustomThemeType} from '../../../managers/ThemeManager'; type PropsType = { item: ServiceCategoryType, activeDashboard: Array, onPress: (service: ServiceItemType) => void, - theme: CustomTheme, + theme: CustomThemeType, }; const LIST_ITEM_HEIGHT = 64; diff --git a/src/components/Lists/DashboardEdit/DashboardEditItem.js b/src/components/Lists/DashboardEdit/DashboardEditItem.js index f2d2038..bbfcbc2 100644 --- a/src/components/Lists/DashboardEdit/DashboardEditItem.js +++ b/src/components/Lists/DashboardEdit/DashboardEditItem.js @@ -3,7 +3,7 @@ import * as React from 'react'; import {Image} from 'react-native'; import {List, withTheme} from 'react-native-paper'; -import type {CustomTheme} from '../../../managers/ThemeManager'; +import type {CustomThemeType} from '../../../managers/ThemeManager'; import type {ServiceItemType} from '../../../managers/ServicesManager'; type PropsType = { @@ -11,7 +11,7 @@ type PropsType = { isActive: boolean, height: number, onPress: () => void, - theme: CustomTheme, + theme: CustomThemeType, }; class DashboardEditItem extends React.Component { diff --git a/src/components/Lists/DashboardEdit/DashboardEditPreviewItem.js b/src/components/Lists/DashboardEdit/DashboardEditPreviewItem.js index 0077284..1b6459b 100644 --- a/src/components/Lists/DashboardEdit/DashboardEditPreviewItem.js +++ b/src/components/Lists/DashboardEdit/DashboardEditPreviewItem.js @@ -3,13 +3,13 @@ import * as React from 'react'; import {TouchableRipple, withTheme} from 'react-native-paper'; import {Dimensions, Image, View} from 'react-native'; -import type {CustomTheme} from '../../../managers/ThemeManager'; +import type {CustomThemeType} from '../../../managers/ThemeManager'; type PropsType = { image: string, isActive: boolean, onPress: () => void, - theme: CustomTheme, + theme: CustomThemeType, }; /** diff --git a/src/components/Lists/Equipment/EquipmentListItem.js b/src/components/Lists/Equipment/EquipmentListItem.js index e1c32fa..1231523 100644 --- a/src/components/Lists/Equipment/EquipmentListItem.js +++ b/src/components/Lists/Equipment/EquipmentListItem.js @@ -4,7 +4,7 @@ import * as React from 'react'; import {Avatar, List, withTheme} from 'react-native-paper'; import i18n from 'i18n-js'; import {StackNavigationProp} from '@react-navigation/stack'; -import type {CustomTheme} from '../../../managers/ThemeManager'; +import type {CustomThemeType} from '../../../managers/ThemeManager'; import type {DeviceType} from '../../../screens/Amicale/Equipment/EquipmentListScreen'; import { getFirstEquipmentAvailability, @@ -17,7 +17,7 @@ type PropsType = { userDeviceRentDates: [string, string], item: DeviceType, height: number, - theme: CustomTheme, + theme: CustomThemeType, }; class EquipmentListItem extends React.Component { diff --git a/src/components/Lists/PlanexGroups/GroupListAccordion.js b/src/components/Lists/PlanexGroups/GroupListAccordion.js index 154ea71..75ffce7 100644 --- a/src/components/Lists/PlanexGroups/GroupListAccordion.js +++ b/src/components/Lists/PlanexGroups/GroupListAccordion.js @@ -10,7 +10,7 @@ import type { PlanexGroupType, PlanexGroupCategoryType, } from '../../../screens/Planex/GroupSelectionScreen'; -import type {CustomTheme} from '../../../managers/ThemeManager'; +import type {CustomThemeType} from '../../../managers/ThemeManager'; type PropsType = { item: PlanexGroupCategoryType, @@ -19,7 +19,7 @@ type PropsType = { currentSearchString: string, favoriteNumber: number, height: number, - theme: CustomTheme, + theme: CustomThemeType, }; const LIST_ITEM_HEIGHT = 64; diff --git a/src/components/Lists/PlanexGroups/GroupListItem.js b/src/components/Lists/PlanexGroups/GroupListItem.js index 6ba8b5c..0a9d753 100644 --- a/src/components/Lists/PlanexGroups/GroupListItem.js +++ b/src/components/Lists/PlanexGroups/GroupListItem.js @@ -2,11 +2,11 @@ import * as React from 'react'; import {IconButton, List, withTheme} from 'react-native-paper'; -import type {CustomTheme} from '../../../managers/ThemeManager'; +import type {CustomThemeType} from '../../../managers/ThemeManager'; import type {PlanexGroupType} from '../../../screens/Planex/GroupSelectionScreen'; type PropsType = { - theme: CustomTheme, + theme: CustomThemeType, onPress: () => void, onStarPress: () => void, item: PlanexGroupType, diff --git a/src/components/Mascot/MascotPopup.js b/src/components/Mascot/MascotPopup.js index e4b6688..d73de67 100644 --- a/src/components/Mascot/MascotPopup.js +++ b/src/components/Mascot/MascotPopup.js @@ -18,12 +18,12 @@ import { View, } from 'react-native'; import Mascot from './Mascot'; -import type {CustomTheme} from '../../managers/ThemeManager'; +import type {CustomThemeType} from '../../managers/ThemeManager'; import SpeechArrow from './SpeechArrow'; import AsyncStorageManager from '../../managers/AsyncStorageManager'; type PropsType = { - theme: CustomTheme, + theme: CustomThemeType, icon: string, title: string, message: string, diff --git a/src/components/Overrides/CustomAgenda.js b/src/components/Overrides/CustomAgenda.js index eaf4f20..0add7ac 100644 --- a/src/components/Overrides/CustomAgenda.js +++ b/src/components/Overrides/CustomAgenda.js @@ -4,10 +4,10 @@ import * as React from 'react'; import {View} from 'react-native'; import {withTheme} from 'react-native-paper'; import {Agenda} from 'react-native-calendars'; -import type {CustomTheme} from '../../managers/ThemeManager'; +import type {CustomThemeType} from '../../managers/ThemeManager'; type PropsType = { - theme: CustomTheme, + theme: CustomThemeType, onRef: (ref: Agenda) => void, }; diff --git a/src/components/Overrides/CustomHTML.js b/src/components/Overrides/CustomHTML.js index d3f2d93..d741a41 100644 --- a/src/components/Overrides/CustomHTML.js +++ b/src/components/Overrides/CustomHTML.js @@ -5,10 +5,10 @@ import * as React from 'react'; import {Text, withTheme} from 'react-native-paper'; import HTML from 'react-native-render-html'; import {Linking} from 'react-native'; -import type {CustomTheme} from '../../managers/ThemeManager'; +import type {CustomThemeType} from '../../managers/ThemeManager'; type PropsType = { - theme: CustomTheme, + theme: CustomThemeType, html: string, }; diff --git a/src/components/Overrides/CustomHeaderButton.js b/src/components/Overrides/CustomHeaderButton.js index 47c0c1f..9991df0 100644 --- a/src/components/Overrides/CustomHeaderButton.js +++ b/src/components/Overrides/CustomHeaderButton.js @@ -4,10 +4,10 @@ import * as React from 'react'; import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'; import {HeaderButton, HeaderButtons} from 'react-navigation-header-buttons'; import {withTheme} from 'react-native-paper'; -import type {CustomTheme} from '../../managers/ThemeManager'; +import type {CustomThemeType} from '../../managers/ThemeManager'; const MaterialHeaderButton = (props: { - theme: CustomTheme, + theme: CustomThemeType, color: string, }): React.Node => { const {color, theme} = props; diff --git a/src/components/Overrides/CustomModal.js b/src/components/Overrides/CustomModal.js index b11868a..8c49181 100644 --- a/src/components/Overrides/CustomModal.js +++ b/src/components/Overrides/CustomModal.js @@ -5,7 +5,7 @@ import {withTheme} from 'react-native-paper'; import {Modalize} from 'react-native-modalize'; import {View} from 'react-native-animatable'; import CustomTabBar from '../Tabbar/CustomTabBar'; -import type {CustomTheme} from '../../managers/ThemeManager'; +import type {CustomThemeType} from '../../managers/ThemeManager'; /** * Abstraction layer for Modalize component, using custom configuration @@ -14,7 +14,7 @@ import type {CustomTheme} from '../../managers/ThemeManager'; * @return {*} */ function CustomModal(props: { - theme: CustomTheme, + theme: CustomThemeType, onRef: (re: Modalize) => void, children?: React.Node, }): React.Node { diff --git a/src/components/Overrides/CustomSlider.js b/src/components/Overrides/CustomSlider.js index 419ca02..b62276b 100644 --- a/src/components/Overrides/CustomSlider.js +++ b/src/components/Overrides/CustomSlider.js @@ -4,10 +4,10 @@ import * as React from 'react'; import {Text, withTheme} from 'react-native-paper'; import {View} from 'react-native-animatable'; import Slider, {SliderProps} from '@react-native-community/slider'; -import type {CustomTheme} from '../../managers/ThemeManager'; +import type {CustomThemeType} from '../../managers/ThemeManager'; type PropsType = { - theme: CustomTheme, + theme: CustomThemeType, valueSuffix?: string, ...SliderProps, }; diff --git a/src/components/Screens/BasicLoadingScreen.js b/src/components/Screens/BasicLoadingScreen.js index 2b21eb3..8b875ac 100644 --- a/src/components/Screens/BasicLoadingScreen.js +++ b/src/components/Screens/BasicLoadingScreen.js @@ -3,7 +3,7 @@ import * as React from 'react'; import {View} from 'react-native'; import {ActivityIndicator, withTheme} from 'react-native-paper'; -import type {CustomTheme} from '../../managers/ThemeManager'; +import type {CustomThemeType} from '../../managers/ThemeManager'; /** * Component used to display a header button @@ -12,7 +12,7 @@ import type {CustomTheme} from '../../managers/ThemeManager'; * @return {*} */ function BasicLoadingScreen(props: { - theme: CustomTheme, + theme: CustomThemeType, isAbsolute: boolean, }): React.Node { const {theme, isAbsolute} = props; diff --git a/src/components/Screens/ErrorView.js b/src/components/Screens/ErrorView.js index 3383c7a..4b5b0a8 100644 --- a/src/components/Screens/ErrorView.js +++ b/src/components/Screens/ErrorView.js @@ -8,11 +8,11 @@ import i18n from 'i18n-js'; import * as Animatable from 'react-native-animatable'; import {StackNavigationProp} from '@react-navigation/stack'; import {ERROR_TYPE} from '../../utils/WebData'; -import type {CustomTheme} from '../../managers/ThemeManager'; +import type {CustomThemeType} from '../../managers/ThemeManager'; type PropsType = { navigation: StackNavigationProp, - theme: CustomTheme, + theme: CustomThemeType, route: {name: string}, onRefresh?: () => void, errorCode?: number, @@ -47,7 +47,7 @@ const styles = StyleSheet.create({ class ErrorView extends React.PureComponent { static defaultProps = { - onRefresh: (): void => null, + onRefresh: () => {}, errorCode: 0, icon: '', message: '', @@ -141,10 +141,12 @@ class ErrorView extends React.PureComponent { this.icon = 'alert-circle-outline'; break; } - this.message += `\n\nCode ${props.errorCode}`; + this.message += `\n\nCode ${ + props.errorCode != null ? props.errorCode : -1 + }`; } else { - this.message = props.message; - this.icon = props.icon; + this.message = props.message != null ? props.message : ''; + this.icon = props.icon != null ? props.icon : ''; } } @@ -168,6 +170,7 @@ class ErrorView extends React.PureComponent { void, onLongPress: () => void, - theme: CustomTheme, + theme: CustomThemeType, tabBarHeight: number, }; diff --git a/src/components/Tabbar/TabIcon.js b/src/components/Tabbar/TabIcon.js index effafaf..b41af1e 100644 --- a/src/components/Tabbar/TabIcon.js +++ b/src/components/Tabbar/TabIcon.js @@ -6,7 +6,7 @@ import {TouchableRipple, withTheme} from 'react-native-paper'; import type {MaterialCommunityIconsGlyphs} from 'react-native-vector-icons/MaterialCommunityIcons'; import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'; import * as Animatable from 'react-native-animatable'; -import type {CustomTheme} from '../../managers/ThemeManager'; +import type {CustomThemeType} from '../../managers/ThemeManager'; type PropsType = { focused: boolean, @@ -15,7 +15,7 @@ type PropsType = { icon: MaterialCommunityIconsGlyphs, onPress: () => void, onLongPress: () => void, - theme: CustomTheme, + theme: CustomThemeType, extraData: null | boolean | number | string, }; diff --git a/src/screens/About/AboutScreen.js b/src/screens/About/AboutScreen.js index e9a7371..be07840 100644 --- a/src/screens/About/AboutScreen.js +++ b/src/screens/About/AboutScreen.js @@ -145,9 +145,7 @@ class AboutScreen extends React.Component { */ additionalDevData = [ { - onPressCallback: () => { - console.log('Meme this'); - }, + onPressCallback: () => {}, icon: 'account', text: 'Yohan SIMARD', showChevron: false, diff --git a/src/screens/Game/logic/Piece.js b/src/screens/Game/logic/Piece.js index 34060ba..6ebab11 100644 --- a/src/screens/Game/logic/Piece.js +++ b/src/screens/Game/logic/Piece.js @@ -1,14 +1,16 @@ -import ShapeL from "../Shapes/ShapeL"; -import ShapeI from "../Shapes/ShapeI"; -import ShapeJ from "../Shapes/ShapeJ"; -import ShapeO from "../Shapes/ShapeO"; -import ShapeS from "../Shapes/ShapeS"; -import ShapeT from "../Shapes/ShapeT"; -import ShapeZ from "../Shapes/ShapeZ"; -import type {Coordinates} from '../Shapes/BaseShape'; -import BaseShape from "../Shapes/BaseShape"; -import type {Grid} from "../components/GridComponent"; -import type {CustomTheme} from "../../../managers/ThemeManager"; +// @flow + +import ShapeL from '../Shapes/ShapeL'; +import ShapeI from '../Shapes/ShapeI'; +import ShapeJ from '../Shapes/ShapeJ'; +import ShapeO from '../Shapes/ShapeO'; +import ShapeS from '../Shapes/ShapeS'; +import ShapeT from '../Shapes/ShapeT'; +import ShapeZ from '../Shapes/ShapeZ'; +import type {CoordinatesType} from '../Shapes/BaseShape'; +import BaseShape from '../Shapes/BaseShape'; +import type {GridType} from '../components/GridComponent'; +import type {CustomThemeType} from '../../../managers/ThemeManager'; /** * Class used as an abstraction layer for shapes. @@ -16,157 +18,167 @@ import type {CustomTheme} from "../../../managers/ThemeManager"; * */ export default class Piece { + shapes = [ShapeL, ShapeI, ShapeJ, ShapeO, ShapeS, ShapeT, ShapeZ]; - #shapes = [ - ShapeL, - ShapeI, - ShapeJ, - ShapeO, - ShapeS, - ShapeT, - ShapeZ, - ]; - #currentShape: BaseShape; - #theme: CustomTheme; + currentShape: BaseShape; - /** - * Initializes this piece's color and shape - * - * @param theme Object containing current theme - */ - constructor(theme: CustomTheme) { - this.#currentShape = this.getRandomShape(theme); - this.#theme = theme; + theme: CustomThemeType; + + /** + * Initializes this piece's color and shape + * + * @param theme Object containing current theme + */ + constructor(theme: CustomThemeType) { + this.currentShape = this.getRandomShape(theme); + this.theme = theme; + } + + /** + * Gets a random shape object + * + * @param theme Object containing current theme + */ + getRandomShape(theme: CustomThemeType): BaseShape { + return new this.shapes[Math.floor(Math.random() * 7)](theme); + } + + /** + * Removes the piece from the given grid + * + * @param grid The grid to remove the piece from + */ + removeFromGrid(grid: GridType) { + const pos: Array = this.currentShape.getCellsCoordinates( + true, + ); + pos.forEach((coordinates: CoordinatesType) => { + // eslint-disable-next-line no-param-reassign + grid[coordinates.y][coordinates.x] = { + color: this.theme.colors.tetrisBackground, + isEmpty: true, + key: grid[coordinates.y][coordinates.x].key, + }; + }); + } + + /** + * Adds this piece to the given grid + * + * @param grid The grid to add the piece to + * @param isPreview Should we use this piece's current position to determine the cells? + */ + toGrid(grid: GridType, isPreview: boolean) { + const pos: Array = this.currentShape.getCellsCoordinates( + !isPreview, + ); + pos.forEach((coordinates: CoordinatesType) => { + // eslint-disable-next-line no-param-reassign + grid[coordinates.y][coordinates.x] = { + color: this.currentShape.getColor(), + isEmpty: false, + key: grid[coordinates.y][coordinates.x].key, + }; + }); + } + + /** + * Checks if the piece's current position is valid + * + * @param grid The current game grid + * @param width The grid's width + * @param height The grid's height + * @return {boolean} If the position is valid + */ + isPositionValid(grid: GridType, width: number, height: number): boolean { + let isValid = true; + const pos: Array = this.currentShape.getCellsCoordinates( + true, + ); + for (let i = 0; i < pos.length; i += 1) { + if ( + pos[i].x >= width || + pos[i].x < 0 || + pos[i].y >= height || + pos[i].y < 0 || + !grid[pos[i].y][pos[i].x].isEmpty + ) { + isValid = false; + break; + } } + return isValid; + } - /** - * Gets a random shape object - * - * @param theme Object containing current theme - */ - getRandomShape(theme: CustomTheme) { - return new this.#shapes[Math.floor(Math.random() * 7)](theme); + /** + * Tries to move the piece by the given offset on the given grid + * + * @param x Position X offset + * @param y Position Y offset + * @param grid The grid to move the piece on + * @param width The grid's width + * @param height The grid's height + * @param freezeCallback Callback to use if the piece should freeze itself + * @return {boolean} True if the move was valid, false otherwise + */ + tryMove( + x: number, + y: number, + grid: GridType, + width: number, + height: number, + freezeCallback: () => void, + ): boolean { + let newX = x; + let newY = y; + if (x > 1) newX = 1; // Prevent moving from more than one tile + if (x < -1) newX = -1; + if (y > 1) newY = 1; + if (y < -1) newY = -1; + if (x !== 0 && y !== 0) newY = 0; // Prevent diagonal movement + + this.removeFromGrid(grid); + this.currentShape.move(newX, newY); + const isValid = this.isPositionValid(grid, width, height); + + if (!isValid) this.currentShape.move(-newX, -newY); + + const shouldFreeze = !isValid && newY !== 0; + this.toGrid(grid, false); + if (shouldFreeze) freezeCallback(); + return isValid; + } + + /** + * Tries to rotate the piece + * + * @param grid The grid to rotate the piece on + * @param width The grid's width + * @param height The grid's height + * @return {boolean} True if the rotation was valid, false otherwise + */ + tryRotate(grid: GridType, width: number, height: number): boolean { + this.removeFromGrid(grid); + this.currentShape.rotate(true); + if (!this.isPositionValid(grid, width, height)) { + this.currentShape.rotate(false); + this.toGrid(grid, false); + return false; } + this.toGrid(grid, false); + return true; + } - /** - * Removes the piece from the given grid - * - * @param grid The grid to remove the piece from - */ - removeFromGrid(grid: Grid) { - const pos: Array = this.#currentShape.getCellsCoordinates(true); - for (let i = 0; i < pos.length; i++) { - grid[pos[i].y][pos[i].x] = { - color: this.#theme.colors.tetrisBackground, - isEmpty: true, - key: grid[pos[i].y][pos[i].x].key - }; - } - } + /** + * Gets this piece used cells coordinates + * + * @return {Array} An array of coordinates + */ + getCoordinates(): Array { + return this.currentShape.getCellsCoordinates(true); + } - /** - * Adds this piece to the given grid - * - * @param grid The grid to add the piece to - * @param isPreview Should we use this piece's current position to determine the cells? - */ - toGrid(grid: Grid, isPreview: boolean) { - const pos: Array = this.#currentShape.getCellsCoordinates(!isPreview); - for (let i = 0; i < pos.length; i++) { - grid[pos[i].y][pos[i].x] = { - color: this.#currentShape.getColor(), - isEmpty: false, - key: grid[pos[i].y][pos[i].x].key - }; - } - } - - /** - * Checks if the piece's current position is valid - * - * @param grid The current game grid - * @param width The grid's width - * @param height The grid's height - * @return {boolean} If the position is valid - */ - isPositionValid(grid: Grid, width: number, height: number) { - let isValid = true; - const pos: Array = this.#currentShape.getCellsCoordinates(true); - for (let i = 0; i < pos.length; i++) { - if (pos[i].x >= width - || pos[i].x < 0 - || pos[i].y >= height - || pos[i].y < 0 - || !grid[pos[i].y][pos[i].x].isEmpty) { - isValid = false; - break; - } - } - return isValid; - } - - /** - * Tries to move the piece by the given offset on the given grid - * - * @param x Position X offset - * @param y Position Y offset - * @param grid The grid to move the piece on - * @param width The grid's width - * @param height The grid's height - * @param freezeCallback Callback to use if the piece should freeze itself - * @return {boolean} True if the move was valid, false otherwise - */ - tryMove(x: number, y: number, grid: Grid, width: number, height: number, freezeCallback: () => void) { - if (x > 1) x = 1; // Prevent moving from more than one tile - if (x < -1) x = -1; - if (y > 1) y = 1; - if (y < -1) y = -1; - if (x !== 0 && y !== 0) y = 0; // Prevent diagonal movement - - this.removeFromGrid(grid); - this.#currentShape.move(x, y); - let isValid = this.isPositionValid(grid, width, height); - - if (!isValid) - this.#currentShape.move(-x, -y); - - let shouldFreeze = !isValid && y !== 0; - this.toGrid(grid, false); - if (shouldFreeze) - freezeCallback(); - return isValid; - } - - /** - * Tries to rotate the piece - * - * @param grid The grid to rotate the piece on - * @param width The grid's width - * @param height The grid's height - * @return {boolean} True if the rotation was valid, false otherwise - */ - tryRotate(grid: Grid, width: number, height: number) { - this.removeFromGrid(grid); - this.#currentShape.rotate(true); - if (!this.isPositionValid(grid, width, height)) { - this.#currentShape.rotate(false); - this.toGrid(grid, false); - return false; - } - this.toGrid(grid, false); - return true; - } - - /** - * Gets this piece used cells coordinates - * - * @return {Array} An array of coordinates - */ - getCoordinates(): Array { - return this.#currentShape.getCellsCoordinates(true); - } - - getCurrentShape() { - return this.#currentShape; - } + getCurrentShape(): BaseShape { + return this.currentShape; + } } diff --git a/src/screens/Home/HomeScreen.js b/src/screens/Home/HomeScreen.js index 0ff2582..06c90d9 100644 --- a/src/screens/Home/HomeScreen.js +++ b/src/screens/Home/HomeScreen.js @@ -19,7 +19,7 @@ import MaterialHeaderButtons, { Item, } from '../../components/Overrides/CustomHeaderButton'; import AnimatedFAB from '../../components/Animations/AnimatedFAB'; -import type {CustomTheme} from '../../managers/ThemeManager'; +import type {CustomThemeType} from '../../managers/ThemeManager'; import ConnectionManager from '../../managers/ConnectionManager'; import LogoutDialog from '../../components/Amicale/LogoutDialog'; import AsyncStorageManager from '../../managers/AsyncStorageManager'; @@ -78,7 +78,7 @@ type RawDashboardType = { type PropsType = { navigation: StackNavigationProp, route: {params: {nextScreen: string, data: {...}}}, - theme: CustomTheme, + theme: CustomThemeType, }; type StateType = { diff --git a/src/screens/Planex/PlanexScreen.js b/src/screens/Planex/PlanexScreen.js index 483fe7b..5e2b6c6 100644 --- a/src/screens/Planex/PlanexScreen.js +++ b/src/screens/Planex/PlanexScreen.js @@ -6,7 +6,7 @@ import i18n from 'i18n-js'; import {View} from 'react-native'; import {CommonActions} from '@react-navigation/native'; import {StackNavigationProp} from '@react-navigation/stack'; -import type {CustomTheme} from '../../managers/ThemeManager'; +import type {CustomThemeType} from '../../managers/ThemeManager'; import ThemeManager from '../../managers/ThemeManager'; import WebViewScreen from '../../components/Screens/WebViewScreen'; import AsyncStorageManager from '../../managers/AsyncStorageManager'; @@ -22,7 +22,7 @@ import MascotPopup from '../../components/Mascot/MascotPopup'; type PropsType = { navigation: StackNavigationProp, route: {params: {group: PlanexGroupType}}, - theme: CustomTheme, + theme: CustomThemeType, }; type StateType = { diff --git a/src/screens/Services/ServicesSectionScreen.js b/src/screens/Services/ServicesSectionScreen.js index d35d779..d1823b2 100644 --- a/src/screens/Services/ServicesSectionScreen.js +++ b/src/screens/Services/ServicesSectionScreen.js @@ -6,7 +6,7 @@ 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 withCollapsible from '../../utils/withCollapsible'; import type {ServiceCategoryType} from '../../managers/ServicesManager'; type PropsType = { diff --git a/src/utils/AutoHideHandler.js b/src/utils/AutoHideHandler.js index feabf99..7fe0524 100644 --- a/src/utils/AutoHideHandler.js +++ b/src/utils/AutoHideHandler.js @@ -1,70 +1,85 @@ // @flow -import * as React from 'react'; - const speedOffset = 5; +type ListenerFunctionType = (shouldHide: boolean) => void; + +export type OnScrollType = { + nativeEvent: { + contentInset: {bottom: number, left: number, right: number, top: number}, + contentOffset: {x: number, y: number}, + contentSize: {height: number, width: number}, + layoutMeasurement: {height: number, width: number}, + zoomScale: number, + }, +}; + /** * Class used to detect when to show or hide a component based on scrolling */ export default class AutoHideHandler { + lastOffset: number; - lastOffset: number; - isHidden: boolean; + isHidden: boolean; - listeners: Array; + listeners: Array; - constructor(startHidden: boolean) { - this.listeners = []; - this.isHidden = startHidden; + constructor(startHidden: boolean) { + this.listeners = []; + this.isHidden = startHidden; + } + + /** + * Adds a listener to the hide event + * + * @param listener + */ + addListener(listener: (shouldHide: boolean) => void) { + this.listeners.push(listener); + } + + /** + * Notifies every listener whether they should hide or show. + * + * @param shouldHide + */ + notifyListeners(shouldHide: boolean) { + this.listeners.forEach((func: ListenerFunctionType) => { + func(shouldHide); + }); + } + + /** + * Callback to be used on the onScroll animated component event. + * + * Detects if the current speed exceeds a threshold and notifies listeners to hide or show. + * + * The hide even is triggered when the user scrolls down, and the show event on scroll up. + * This does not take into account the speed when the y coordinate is negative, to prevent hiding on over scroll. + * (When scrolling up and hitting the top on ios for example) + * + * //TODO Known issue: + * When refreshing a list with the pull down gesture on ios, + * this can trigger the hide event as it scrolls down the list to show the refresh indicator. + * Android shows the refresh indicator on top of the list so this is not an issue. + * + * @param event The scroll event generated by the animated component onScroll prop + */ + onScroll(event: OnScrollType) { + const {nativeEvent} = event; + const speed = + nativeEvent.contentOffset.y < 0 + ? 0 + : this.lastOffset - nativeEvent.contentOffset.y; + if (speed < -speedOffset && !this.isHidden) { + // Go down + this.notifyListeners(true); + this.isHidden = true; + } else if (speed > speedOffset && this.isHidden) { + // Go up + this.notifyListeners(false); + this.isHidden = false; } - - /** - * Adds a listener to the hide event - * - * @param listener - */ - addListener(listener: Function) { - this.listeners.push(listener); - } - - /** - * Notifies every listener whether they should hide or show. - * - * @param shouldHide - */ - notifyListeners(shouldHide: boolean) { - for (let i = 0; i < this.listeners.length; i++) { - this.listeners[i](shouldHide); - } - } - - /** - * Callback to be used on the onScroll animated component event. - * - * Detects if the current speed exceeds a threshold and notifies listeners to hide or show. - * - * The hide even is triggered when the user scrolls down, and the show event on scroll up. - * This does not take into account the speed when the y coordinate is negative, to prevent hiding on over scroll. - * (When scrolling up and hitting the top on ios for example) - * - * //TODO Known issue: - * When refreshing a list with the pull down gesture on ios, - * this can trigger the hide event as it scrolls down the list to show the refresh indicator. - * Android shows the refresh indicator on top of the list so this is not an issue. - * - * @param nativeEvent The scroll event generated by the animated component onScroll prop - */ - onScroll({nativeEvent}: Object) { - const speed = nativeEvent.contentOffset.y < 0 ? 0 : this.lastOffset - nativeEvent.contentOffset.y; - if (speed < -speedOffset && !this.isHidden) { // Go down - this.notifyListeners(true); - this.isHidden = true; - } else if (speed > speedOffset && this.isHidden) { // Go up - this.notifyListeners(false); - this.isHidden = false; - } - this.lastOffset = nativeEvent.contentOffset.y; - } - + this.lastOffset = nativeEvent.contentOffset.y; + } } diff --git a/src/utils/CollapsibleUtils.js b/src/utils/CollapsibleUtils.js index c72734b..c836fd8 100644 --- a/src/utils/CollapsibleUtils.js +++ b/src/utils/CollapsibleUtils.js @@ -1,9 +1,9 @@ // @flow import * as React from 'react'; -import {useTheme} from "react-native-paper"; -import {createCollapsibleStack} from "react-navigation-collapsible"; -import StackNavigator, {StackNavigationOptions} from "@react-navigation/stack"; +import {useTheme} from 'react-native-paper'; +import {createCollapsibleStack} from 'react-navigation-collapsible'; +import StackNavigator, {StackNavigationOptions} from '@react-navigation/stack'; /** * Creates a navigation stack with the collapsible library, allowing the header to collapse on scroll. @@ -22,32 +22,34 @@ import StackNavigator, {StackNavigationOptions} from "@react-navigation/stack"; * @returns {JSX.Element} */ export function createScreenCollapsibleStack( - name: string, - Stack: StackNavigator, - component: React.ComponentType, - title: string, - useNativeDriver?: boolean, - options?: StackNavigationOptions, - headerColor?: string) { - const {colors} = useTheme(); - const screenOptions = options != null ? options : {}; - return createCollapsibleStack( - , - { - collapsedColor: headerColor!=null ? headerColor :colors.surface, - useNativeDriver: useNativeDriver != null ? useNativeDriver : true, // native driver does not work with webview - } - ) + name: string, + Stack: StackNavigator, + // eslint-disable-next-line flowtype/no-weak-types + component: React.ComponentType, + title: string, + useNativeDriver?: boolean, + options?: StackNavigationOptions, + headerColor?: string, +): React.Node { + const {colors} = useTheme(); + const screenOptions = options != null ? options : {}; + return createCollapsibleStack( + , + { + collapsedColor: headerColor != null ? headerColor : colors.surface, + useNativeDriver: useNativeDriver != null ? useNativeDriver : true, // native driver does not work with webview + }, + ); } /** @@ -62,6 +64,12 @@ export function createScreenCollapsibleStack( * @param title * @returns {JSX.Element} */ -export function getWebsiteStack(name: string, Stack: any, component: any, title: string) { - return createScreenCollapsibleStack(name, Stack, component, title, false); +export function getWebsiteStack( + name: string, + Stack: StackNavigator, + // eslint-disable-next-line flowtype/no-weak-types + component: React.ComponentType, + title: string, +): React.Node { + return createScreenCollapsibleStack(name, Stack, component, title, false); }