From 2a9bf5bb6ab894a0ab2138667a3cf77ffe009e7e Mon Sep 17 00:00:00 2001 From: Arnaud Vergnet Date: Sun, 12 Jul 2020 11:37:11 +0200 Subject: [PATCH] Added mascot to every main screen and allow cancel with back button --- src/components/Mascot/MascotPopup.js | 28 +++++++- src/managers/AsyncStorageManager.js | 20 ++++-- src/screens/Planning/PlanningScreen.js | 90 ++++++++++++++++++-------- src/screens/Services/ServicesScreen.js | 70 ++++++++++++++++---- translations/en.json | 10 ++- 5 files changed, 168 insertions(+), 50 deletions(-) diff --git a/src/components/Mascot/MascotPopup.js b/src/components/Mascot/MascotPopup.js index d267e8e..890cc0f 100644 --- a/src/components/Mascot/MascotPopup.js +++ b/src/components/Mascot/MascotPopup.js @@ -4,7 +4,7 @@ import * as React from 'react'; import {Avatar, Button, Card, Paragraph, Portal, withTheme} from 'react-native-paper'; import Mascot from "./Mascot"; import * as Animatable from "react-native-animatable"; -import {Dimensions, ScrollView, TouchableWithoutFeedback, View} from "react-native"; +import {BackHandler, Dimensions, ScrollView, TouchableWithoutFeedback, View} from "react-native"; import type {CustomTheme} from "../../managers/ThemeManager"; type Props = { @@ -62,13 +62,35 @@ class MascotPopup extends React.Component { } shouldComponentUpdate(nextProps: Props): boolean { - if (nextProps.visible) + if (nextProps.visible) { this.state.shouldShowDialog = true; - else if (nextProps.visible !== this.props.visible) + }else if (nextProps.visible !== this.props.visible) { setTimeout(this.onAnimationEnd, 300); + } return true; } + componentDidMount(): * { + BackHandler.addEventListener( + 'hardwareBackPress', + this.onBackButtonPressAndroid + ) + } + + onBackButtonPressAndroid = () => { + if (this.state.shouldShowDialog) { + const cancel = this.props.buttons.cancel; + const action = this.props.buttons.action; + if (cancel != null) + cancel.onPress(); + else + action.onPress(); + return true; + } else { + return false; + } + }; + getSpeechBubble() { return ( { refreshing: false, agendaItems: {}, calendarShowing: false, + mascotDialogVisible: AsyncStorageManager.getInstance().preferences.eventsShowBanner.current === "1" }; currentDate = getDateOnlyString(getCurrentDateString()); @@ -100,6 +105,18 @@ class PlanningScreen extends React.Component { } }; + /** + * Callback used when closing the banner. + * This hides the banner and saves to preferences to prevent it from reopening + */ + onHideMascotDialog = () => { + this.setState({mascotDialogVisible: false}); + AsyncStorageManager.getInstance().savePref( + AsyncStorageManager.getInstance().preferences.eventsShowBanner.key, + '0' + ); + }; + /** * Function used to check if a row has changed * @@ -206,34 +223,51 @@ class PlanningScreen extends React.Component { render() { return ( - + + + + ); } } diff --git a/src/screens/Services/ServicesScreen.js b/src/screens/Services/ServicesScreen.js index 898a6ea..4da18de 100644 --- a/src/screens/Services/ServicesScreen.js +++ b/src/screens/Services/ServicesScreen.js @@ -14,6 +14,9 @@ import MaterialHeaderButtons, {Item} from "../../components/Overrides/CustomHead import ConnectionManager from "../../managers/ConnectionManager"; import {StackNavigationProp} from "@react-navigation/stack"; import AvailableWebsites from "../../constants/AvailableWebsites"; +import {MASCOT_STYLE} from "../../components/Mascot/Mascot"; +import MascotPopup from "../../components/Mascot/MascotPopup"; +import AsyncStorageManager from "../../managers/AsyncStorageManager"; type Props = { navigation: StackNavigationProp, @@ -21,6 +24,11 @@ type Props = { theme: CustomTheme, } +type State = { + mascotDialogVisible: boolean, +} + + export type listItem = { title: string, description: string, @@ -49,7 +57,7 @@ const EMAIL_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/Bluemind. const ENT_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/ENT.png"; const ACCOUNT_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/Account.png"; -class ServicesScreen extends React.Component { +class ServicesScreen extends React.Component { amicaleDataset: cardList; studentsDataset: cardList; @@ -57,6 +65,10 @@ class ServicesScreen extends React.Component { finalDataset: Array + state = { + mascotDialogVisible: AsyncStorageManager.getInstance().preferences.servicesShowBanner.current === "1" + } + constructor(props) { super(props); const nav = props.navigation; @@ -187,6 +199,19 @@ class ServicesScreen extends React.Component { }); } + + /** + * Callback used when closing the banner. + * This hides the banner and saves to preferences to prevent it from reopening + */ + onHideMascotDialog = () => { + this.setState({mascotDialogVisible: false}); + AsyncStorageManager.getInstance().savePref( + AsyncStorageManager.getInstance().preferences.servicesShowBanner.key, + '0' + ); + }; + getAboutButton = () => @@ -271,18 +296,37 @@ class ServicesScreen extends React.Component { render() { const {containerPaddingTop, scrollIndicatorInsetTop, onScroll} = this.props.collapsibleStack; - return } - /> + return ( + + } + /> + + + ); } } diff --git a/translations/en.json b/translations/en.json index 3e77ae3..9f4aabc 100644 --- a/translations/en.json +++ b/translations/en.json @@ -436,10 +436,18 @@ "ent": "See your grades", "insaAccount": "See your information and change your password", "equipment": "Book a BBQ or other equipment" + }, + "mascot": { + "title": "So handy!", + "message": "There a lot of thing you can do with Campus!\n\nHere is a list of every service provided by the app.", + "button": "Thx buddy" } }, "planningScreen": { - "invalidEvent": "Could not find the event. Please make sure the event you are trying to access is valid." + "invalidEvent": "Could not find the event. Please make sure the event you are trying to access is valid.", + "mascotTitle": "Let's party!", + "mascotMessage": "At the INSA, it's not all about classes!\n\nIf you want to see new people, this page is just for you. Here you will find the list of every event organised by students!", + "mascotButton": "Thx!" }, "feedbackScreen": { "bugs": "Report Bugs",