From 761132732bf7803cecf5f111268be716ab2737ee Mon Sep 17 00:00:00 2001 From: Arnaud Vergnet Date: Sun, 12 Jul 2020 00:04:33 +0200 Subject: [PATCH] Added a new mascot dialog to replace banners --- assets/mascot/mascot.png | Bin 0 -> 29382 bytes assets/mascot/mascot_eyes_cute.png | Bin 0 -> 2239 bytes assets/mascot/mascot_eyes_girly.png | Bin 0 -> 2187 bytes assets/mascot/mascot_eyes_normal.png | Bin 0 -> 1723 bytes assets/mascot/mascot_eyes_wink.png | Bin 0 -> 1811 bytes assets/mascot/mascot_glasses.png | Bin 0 -> 3808 bytes src/components/Home/ActionsDashboardItem.js | 54 +---- src/components/Mascot/Mascot.js | 148 +++++++++++++ src/components/Mascot/MascotPopup.js | 225 ++++++++++++++++++++ src/managers/ThemeManager.js | 13 +- src/screens/Home/HomeScreen.js | 104 ++++----- src/screens/Planex/PlanexScreen.js | 71 +++--- src/screens/Proxiwash/ProxiwashScreen.js | 55 ++--- translations/en.json | 9 +- 14 files changed, 489 insertions(+), 190 deletions(-) create mode 100644 assets/mascot/mascot.png create mode 100644 assets/mascot/mascot_eyes_cute.png create mode 100644 assets/mascot/mascot_eyes_girly.png create mode 100644 assets/mascot/mascot_eyes_normal.png create mode 100644 assets/mascot/mascot_eyes_wink.png create mode 100644 assets/mascot/mascot_glasses.png create mode 100644 src/components/Mascot/Mascot.js create mode 100644 src/components/Mascot/MascotPopup.js diff --git a/assets/mascot/mascot.png b/assets/mascot/mascot.png new file mode 100644 index 0000000000000000000000000000000000000000..023c9a0e076b2b13e48967eaf0237012339c8bfe GIT binary patch literal 29382 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 literal 0 HcmV?d00001 diff --git a/assets/mascot/mascot_eyes_cute.png b/assets/mascot/mascot_eyes_cute.png new file mode 100644 index 0000000000000000000000000000000000000000..41e9716c6e394a88ba499a7dc0466621971a48cd GIT binary patch literal 2239 zcmeHH`BTz)82)%79Azoq68(hv$9fnfI=n3woE@el-BV zE{v1?WdIb!U!bZYXIguO_vCFyxYIQ<0P4+OpzxOTG(b*jM>=>#x|4z;WBeilK}<}H z0pTW*?C%#IXh4d<=PcOl2SC*sV}I5oHg|rQPs|b=+&=2+Y?4MiVpWtjQ>~Ms2`?)- zf6-I31r|V{RraQ;o-4UnkXJ|AqO^Bw*KyDNNFZDu2smtF{ZmMg|L;br`nhjv%}!oW zy5w);4UbW!-5r5T*wPi7aNTg>auPqz0ydIE=40gAzSpq_P%{#5@hbxs;1*2LQW1q54ku&(gE2%H zvq0dbf~<9=-U#-r{26_JV(ruT^uj{>+FERdcm2aV8ZhL*X9-Q%paQ&7V!9fNjQ7?~ zVc3IR+Dc`;l_N^vVU+PHA3t`2WI-&E6f+ox8>{oJVsYexkVDVN$QY`N(ksk-{fLt_ zF@>=WoqP;%dV-7zI-zqg8jVK3Oq52%t&69t(k30zXst!vt0XGTPFV#6H$3S2+h}oS z=A^~Vq1f>t)51*A*z2?i*`~D6e57pVFlY#p%vS621_uV-jgI2Z`}s&jldTb=3GVBt z4uULy92RG0GRbnZ4}QALo}-28l)=hlL`hDxwi ziuzznJ}RNN`_|$Ji$Hw-5+3TIco11M9i){g{@9tl?uy0sSY%6m-Bpy$vd-K|pBA5EV`3tp zq$gy>ic`L12^xx4o2!G1U(EI~7{_^dJifK_30kYq^2XP*!_bi7``d1eo{+%U*cSyx zw^rw_SthK`jmaeAzEOaAgoE9wh{6y^B*RAr-X|Zx?0k?sl927K4zqn#y+|s}wqcqi zd#LI3S!0fMHJNtS*VmKBTJAF1&&#vLl`D00bTqNDsuSCYr!ea9xQ^0Kpusch=&AUN zz78ASX;bn<_72j7)=8}9O+P4KlfM_#R%=wrQe@PJ{N127#kDHgPj+eBvJxe%0L8_X zYAkb(PCvyZ17=t^^h0r-(bjAeN`Z20*4bQ7Xm`(o41!-u-e>nLZl!Mv2W}-SjIE1E zpQs_i)3)-YgIVnWti6-*NPFtDSwaqPGrD3!4`$xsQJb9l%pVQG;L=~A7;2*7^4Z~< zC21tY<0iHv!ngVozw4GeKvDS&Q(RixZ5)|I`(g;j!NtDf9Pal2%bBem literal 0 HcmV?d00001 diff --git a/assets/mascot/mascot_eyes_girly.png b/assets/mascot/mascot_eyes_girly.png new file mode 100644 index 0000000000000000000000000000000000000000..23b2eea617660b9613daebec3772b110aa4a67dc GIT binary patch literal 2187 zcmeH{|2NZn9LL{M>5I9g4xt-Yv!STCAro%GK2{^&O}>9mtVUb1jq2R#+L79P$(NJ4 zH=^5_XkxoIk+5i+kTBoM^(}vem8d3A0+3?nZU9ujlT4PI#_HqML(;Jx#^#RTlwCkN=OJtsw%%J1IfRihpp8Ame zflr!{wsHGc$)k-6#Ur26sO!D>hRHM$q>S~WzBd9}C6B4vK=#(7aVK!Q?5XV6Fisik z?1Ma;z7s)(F~s}{72cT*ht4dPlyS94VYj)E`E0WtIO;)TG~|qP%sb_$G8C?e6oe41 zeL*GtdXg_=5gtRd5vxHHoB|Y5_zlV<`l|wU&Nn7GUqrQ9w-A~njK9V%B{KYM>#e|@ z@h9*Sq~e%Rksw-h(&J_zQ;@}Wrlrv1Pmsh0L}Ot` z?Uz-^g`U41oQe6h*Ch~I@?%6fOC4$uKbW zS73L2sW|cs{6y6XLnXbE#vtc>*8R$)RA__P_mAO?5B)9I&4tHSjkQ4RykKwqR5#yB z3mEtJL&NB5n!xC#fT;mwlGo7Z2di0^#Rwe}{sl0q?_R#@66`RHAw&vmRe=drOy(^{ z+huEjGM-&lh-UY6eO;$Bcy6GFtvNn~pUCyrr=Y4E%E0qco(Vs0g89O)Pf4kytPV!; zV;pn~gaLKd?{O=&9G$GOv9W^IV4s1^^xH7`KY;ZF<9P}BwY?qv_Hh7nZm=#UJlqgP zoNcGU^ephh4Zd+0l!+#Yox8vHi@ri4@rdd!Kb!0FEO7`|fFdP6mG)smbb$IDq$jJi z%D?*0Fv}7Sac&@*TaqKNU?orq8BSt>VN*w*S$qmrvGi{cS3?q_YrFrNz)aIFZEYoQ zQv0yKWVXlJnXM|zr)gx|ucB|x&d#p0YfKn?#y+nGjH9Uxe!8-YL+4m*W# z2~kg_9c~+&@BQQz8X;_~N~Gm!FV!48>Q z01kCr7zEk7)u7a@795!5yW^#B%vT=+;34gTMCdoNvbpc=*Zs(=B(RQ3Qyq1mt{7Ru Q1#SR=oUy0br$TT14_R(|qyPW_ literal 0 HcmV?d00001 diff --git a/assets/mascot/mascot_eyes_normal.png b/assets/mascot/mascot_eyes_normal.png new file mode 100644 index 0000000000000000000000000000000000000000..ba4d06c2e8ef12838cc1f200ed019ece80f34f86 GIT binary patch literal 1723 zcmeAS@N?(olHy`uVBq!ia0y~yVEh8Y9Be?5)7S2I0V&P`kH}&M2EM}}%y>M1MG8<* zvcxr_Bsf2(yEr+qAXP8FD1G)j8z}|`HV;o1$B>FSZ|@rVtE9@X zeMtAbGug?^t+B~P#Cf6VJQbEGDWTr2RblSQJsWqPKa?JDzAxZ%K%r%Hhl)zVgLghp zrZrvYIqGC`TKA32?#)HNf2-ziI=S!tng8*&Gt0}$gn;fC1;Zf(UaY^hfScjhs);GD z9(_)nG@0=l6GKU+&dGAmI`2z9L0fvKd&;R-78r^%{E%O%UOD55MY!{x%RjVFE>_9s zUl7Nz;B32Ro&R^odv^2GX0F?n!SEn{zIx@f>-?Wj7tVQ7cXTT=LuPE~^qWchGxvBH z1!uA|7(99RwCwhq>$&@{YrkP;XuIYAvUWy%pS%``6Q;cO?Z-OSUz;nI@V=Wf(NUaX z%D2!--+xv7`KS{A?c)yzd5)4D)%z-(&oMGMzfJYZTYUcfd2wlJ>7y@SW?sxO>;C%n zYf@g`yIrRB;dg`?c&3&I8=VOc3+wv)`SYT?H*ZF6+_R_V?k%^Ydl?U0_+g@YsHUW3 zi-ncdE}>`B`S|#{s`lQ?{Hs2-oPCek_X`j6G*9`&MMa%@@+9T>`{m1)ZQ8Km!sKGc zW>uin&&_9^eEj%P`nivfPsy)W8_w)(I4Ja@VEddUU!$(9d-LwyJ&W}8^yk-}Gcug2 zo}>4EVSi7L$nD#=W#2E%&&?Ix8ud0byI#&Ap1~kQZpjh;$7$*5-GBf7)lS^EeS7$s zGiOSozL!3YW!xSlUBc*)ne6$`<5S&sZmC|ku<-EBJ9f-iq_Jt|&Y4@cZZ(;`{!VE9 zyeE%u6tOq#`)&C5xBmC{;E;{7T^m04o7I{5M_varE(p5p*>`!j0Z`>)FKY&dNh;qj z&knHn`VM1MG8<* zvcxr_Bsf2(yEr+qAXP8FD1G)j8z}|`wgsLpjv*Cu-rn_H@w8ax z_(yYNo{51P!E(kztygn&bf%`bo0YxM@tk;RirXTOBN{U|ZAjKPOIc{6DEe9TRo{4JSr{zr(nI3S^uA1IKgYx%v;4Qz^q(t!t=?62!-C;J)!fM1 zt4l7pU-fQQV`8}Wwowcuxp-I7i2#NJx8APn+p-5Jx$t2UBg5;D371dTg!~PQwTdxe zNYE_{zi+Y|D7m?LDKo>hlzQ#yKlg{f6z3HcV2HSR^Xm4saW59X>TEP(Vpv_VV(V0( zu{&=W`}i;+kMRZG9v@C)%K6>&%L{U6_lQwl$<}i=+25= z|Lsq4F`W4jae4mDy2Cw>`TZ>a6+Av0!_dGuC;sn^Pfh#MTZ{cx-?ryO!Q0143 z)7?L(zFHD`?)L2;yFa%+uZ^2)w|xo2fspE`y3&7zrPrj+@89|~pY7ePKQkB(c+JZx zl$2k+F6w#D@@Z#&tg$K;HfCbbz7hQQ%94)%tMV-SEO)OekBWI!o)_fCkRa;6eMbv_ zPQtaLS0}P=wp&@2XQIHcVH5Z2_*o(!vaj~>p4+qYW9YyA#`*Uj*Z`HEH_^Q3zxuOT z<~w2TXLTWS_jndFHmK^Ys>|K<_vJp{IkjG2!zKsqFBMK_X5hBDzNFy&jKhDprR`1g zLTWF(+MmwOaP8$IweaWc&v%^j_1)*czq0Q&!-4;oKI`6h%#D+a-5|!W!BcN_UG^`& ztj`-ZS8Xm_dH&WDR)&b>&TIEH-?E7bsJ;8c&5|LZ`CHij?Vo^(iju#km;PnQWiX)}Y-bo4Zr?h1Z9mYMIro2fnv z_2P4T=Fi2crCX|!UnpGV|Nm!hY^`B|7{iUQb+T3mM6UD5GB9kLz4phAt7~U)4%vJ+ g>TqBP_$AacPdd)FMa*TBC@4TYUHx3vIVCg!01P<4sQ>@~ literal 0 HcmV?d00001 diff --git a/assets/mascot/mascot_glasses.png b/assets/mascot/mascot_glasses.png new file mode 100644 index 0000000000000000000000000000000000000000..78de4df8f6472308a95321c5a2b262910293386b GIT binary patch literal 3808 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 U(~Ga@)%o^@J0Q=}&iEz&5AL%H!vFvP literal 0 HcmV?d00001 diff --git a/src/components/Home/ActionsDashboardItem.js b/src/components/Home/ActionsDashboardItem.js index a4a920e..013124f 100644 --- a/src/components/Home/ActionsDashboardItem.js +++ b/src/components/Home/ActionsDashboardItem.js @@ -1,61 +1,33 @@ // @flow import * as React from 'react'; -import {Avatar, Card, List, withTheme} from 'react-native-paper'; -import {StyleSheet, View} from "react-native"; +import {List, withTheme} from 'react-native-paper'; +import {View} from "react-native"; import type {CustomTheme} from "../../managers/ThemeManager"; import i18n from 'i18n-js'; import {StackNavigationProp} from "@react-navigation/stack"; -const ICON_AMICALE = require("../../../assets/amicale.png"); - type Props = { navigation: StackNavigationProp, theme: CustomTheme, - isLoggedIn: boolean, } class ActionsDashBoardItem extends React.Component { shouldComponentUpdate(nextProps: Props): boolean { - return (nextProps.theme.dark !== this.props.theme.dark) - || (nextProps.isLoggedIn !== this.props.isLoggedIn); + return (nextProps.theme.dark !== this.props.theme.dark); } render() { - const isLoggedIn = this.props.isLoggedIn; return ( - - } - right={props => } - onPress={isLoggedIn - ? () => this.props.navigation.navigate("profile") - : () => this.props.navigation.navigate("login", {nextScreen: "profile"})} - style={styles.list} - /> - } right={props => } onPress={() => this.props.navigation.navigate("feedback")} - style={{...styles.list, marginLeft: 10, marginRight: 10}} + style={{paddingTop: 0, paddingBottom: 0, marginLeft: 10, marginRight: 10}} /> @@ -63,22 +35,4 @@ class ActionsDashBoardItem extends React.Component { } } -const styles = StyleSheet.create({ - card: { - width: 'auto', - margin: 10, - borderWidth: 1, - }, - avatar: { - backgroundColor: 'transparent', - marginTop: 'auto', - marginBottom: 'auto', - }, - list: { - // height: 50, - paddingTop: 0, - paddingBottom: 0, - } -}); - export default withTheme(ActionsDashBoardItem); diff --git a/src/components/Mascot/Mascot.js b/src/components/Mascot/Mascot.js new file mode 100644 index 0000000..6977779 --- /dev/null +++ b/src/components/Mascot/Mascot.js @@ -0,0 +1,148 @@ +// @flow + +import * as React from 'react'; +import * as Animatable from "react-native-animatable"; +import {Image, View} from "react-native-animatable"; + +type Props = { + size: number, + emotion: number, + animated: boolean, +} + +const MASCOT_IMAGE = require("../../../assets/mascot/mascot.png"); +const MASCOT_EYES_NORMAL = require("../../../assets/mascot/mascot_eyes_normal.png"); +const MASCOT_EYES_GIRLY = require("../../../assets/mascot/mascot_eyes_girly.png"); +const MASCOT_EYES_CUTE = require("../../../assets/mascot/mascot_eyes_cute.png"); +const MASCOT_EYES_WINK = require("../../../assets/mascot/mascot_eyes_wink.png"); +const MASCOT_GLASSES = require("../../../assets/mascot/mascot_glasses.png"); + +export const EYE_STYLE = { + NORMAL: 0, + GIRLY: 2, + CUTE: 3, + WINK: 4, +} + +export const MASCOT_STYLE = { + NORMAL: 0, + HAPPY: 1, + GIRLY: 2, + WINK: 3, + CUTE: 4, + INTELLO: 5, +}; + + +class Mascot extends React.Component { + + static defaultProps = { + animated: false + } + + eyeList: { [key: number]: number | string } + + constructor(props: Props) { + super(props); + this.eyeList = {}; + this.eyeList[EYE_STYLE.NORMAL] = MASCOT_EYES_NORMAL; + this.eyeList[EYE_STYLE.GIRLY] = MASCOT_EYES_GIRLY; + this.eyeList[EYE_STYLE.CUTE] = MASCOT_EYES_CUTE; + this.eyeList[EYE_STYLE.WINK] = MASCOT_EYES_WINK; + } + + getGlasses() { + return + } + + getEye(style: number, isRight: boolean) { + const eye = this.eyeList[style]; + return + } + + getEyes(emotion: number) { + let final = []; + final.push(); + if (emotion === MASCOT_STYLE.CUTE) { + final.push(this.getEye(EYE_STYLE.CUTE, true)); + final.push(this.getEye(EYE_STYLE.CUTE, false)); + } else if (emotion === MASCOT_STYLE.GIRLY) { + final.push(this.getEye(EYE_STYLE.GIRLY, true)); + final.push(this.getEye(EYE_STYLE.GIRLY, false)); + } else if (emotion === MASCOT_STYLE.HAPPY) { + final.push(this.getEye(EYE_STYLE.WINK, true)); + final.push(this.getEye(EYE_STYLE.WINK, false)); + } else if (emotion === MASCOT_STYLE.WINK) { + final.push(this.getEye(EYE_STYLE.WINK, true)); + final.push(this.getEye(EYE_STYLE.NORMAL, false)); + } else { + final.push(this.getEye(EYE_STYLE.NORMAL, true)); + final.push(this.getEye(EYE_STYLE.NORMAL, false)); + } + + if (emotion === MASCOT_STYLE.INTELLO) { + final.push(this.getGlasses()) + } + final.push(); + return final; + } + + render() { + const size = this.props.size; + return ( + + + + {this.getEyes(this.props.emotion)} + + + ); + } +} + +export default Mascot; diff --git a/src/components/Mascot/MascotPopup.js b/src/components/Mascot/MascotPopup.js new file mode 100644 index 0000000..d267e8e --- /dev/null +++ b/src/components/Mascot/MascotPopup.js @@ -0,0 +1,225 @@ +// @flow + +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 type {CustomTheme} from "../../managers/ThemeManager"; + +type Props = { + visible: boolean, + theme: CustomTheme, + icon: string, + title: string, + message: string, + buttons: { + action: { + message: string, + icon: string | null, + color: string | null, + onPress: () => void, + }, + cancel: { + message: string, + icon: string | null, + color: string | null, + onPress: () => void, + } + }, + emotion: number, +} + +type State = { + shouldShowDialog: boolean; +} + + +class MascotPopup extends React.Component { + + mascotSize: number; + windowWidth: number; + windowHeight: number; + + state = { + shouldShowDialog: this.props.visible, + }; + + + constructor(props: Props) { + super(props); + + this.windowWidth = Dimensions.get('window').width; + this.windowHeight = Dimensions.get('window').height; + + this.mascotSize = Dimensions.get('window').height / 6; + } + + onAnimationEnd = () => { + this.setState({ + shouldShowDialog: this.props.visible, + }) + } + + shouldComponentUpdate(nextProps: Props): boolean { + if (nextProps.visible) + this.state.shouldShowDialog = true; + else if (nextProps.visible !== this.props.visible) + setTimeout(this.onAnimationEnd, 300); + return true; + } + + getSpeechBubble() { + return ( + + + + + + : null} + /> + + + + + {this.props.message} + + + + + + {this.getButtons()} + + + + ); + } + + getMascot() { + return ( + + + + ); + } + + getButtons() { + const action = this.props.buttons.action; + const cancel = this.props.buttons.cancel; + return ( + + {cancel != null + ? + : null} + {action != null + ? + : null} + + ); + } + + getBackground() { + return ( + + + + + ); + } + + render() { + if (this.state.shouldShowDialog) { + return ( + + {this.getBackground()} + + {this.getMascot()} + {this.getSpeechBubble()} + + + ); + } else + return null; + + } +} + +export default withTheme(MascotPopup); diff --git a/src/managers/ThemeManager.js b/src/managers/ThemeManager.js index 1c7e398..c68c57a 100644 --- a/src/managers/ThemeManager.js +++ b/src/managers/ThemeManager.js @@ -55,6 +55,9 @@ export type CustomTheme = { tetrisZ: string, tetrisJ: string, tetrisL: string, + + // Mascot Popup + mascotMessageArrow: string, }, } @@ -83,7 +86,7 @@ export default class ThemeManager { primary: '#be1522', accent: '#be1522', tabIcon: "#929292", - card: "rgb(255, 255, 255)", + card: "#fff", dividerBackground: '#e2e2e2', ripple: "rgba(0,0,0,0.2)", textDisabled: '#c1c1c1', @@ -126,6 +129,9 @@ export default class ThemeManager { tetrisZ: '#ff0009', tetrisJ: '#2a67e3', tetrisL: '#da742d', + + // Mascot Popup + mascotMessageArrow: "#dedede", }, }; } @@ -144,7 +150,7 @@ export default class ThemeManager { accent: '#be1522', tabBackground: "#181818", tabIcon: "#6d6d6d", - card: "rgb(18, 18, 18)", + card: "rgb(18,18,18)", dividerBackground: '#222222', ripple: "rgba(255,255,255,0.2)", textDisabled: '#5b5b5b', @@ -186,6 +192,9 @@ export default class ThemeManager { tetrisZ: '#b50008', tetrisJ: '#0f37b9', tetrisL: '#b96226', + + // Mascot Popup + mascotMessageArrow: "#323232", }, }; } diff --git a/src/screens/Home/HomeScreen.js b/src/screens/Home/HomeScreen.js index 54b660e..3254a8b 100644 --- a/src/screens/Home/HomeScreen.js +++ b/src/screens/Home/HomeScreen.js @@ -5,7 +5,7 @@ import {FlatList} from 'react-native'; import i18n from "i18n-js"; import DashboardItem from "../../components/Home/EventDashboardItem"; import WebSectionList from "../../components/Screens/WebSectionList"; -import {Avatar, Banner, withTheme} from 'react-native-paper'; +import {withTheme} from 'react-native-paper'; import FeedItem from "../../components/Home/FeedItem"; import SquareDashboardItem from "../../components/Home/SmallDashboardItem"; import PreviewEventDashboardItem from "../../components/Home/PreviewEventDashboardItem"; @@ -19,10 +19,10 @@ import type {CustomTheme} from "../../managers/ThemeManager"; import {View} from "react-native-animatable"; import ConnectionManager from "../../managers/ConnectionManager"; import LogoutDialog from "../../components/Amicale/LogoutDialog"; -import {withCollapsible} from "../../utils/withCollapsible"; -import {Collapsible} from "react-navigation-collapsible"; import AsyncStorageManager from "../../managers/AsyncStorageManager"; import AvailableWebsites from "../../constants/AvailableWebsites"; +import {MASCOT_STYLE} from "../../components/Mascot/Mascot"; +import MascotPopup from "../../components/Mascot/MascotPopup"; // import DATA from "../dashboard_data.json"; @@ -97,12 +97,11 @@ type Props = { navigation: StackNavigationProp, route: { params: any, ... }, theme: CustomTheme, - collapsibleStack: Collapsible, } type State = { dialogVisible: boolean, - bannerVisible: boolean, + mascotDialogVisible: boolean, } /** @@ -115,16 +114,19 @@ class HomeScreen extends React.Component { fabRef: { current: null | AnimatedFAB }; currentNewFeed: Array; - state = { - dialogVisible: false, - bannerVisible: false, - } - constructor(props) { super(props); this.fabRef = React.createRef(); this.currentNewFeed = []; - this.isLoggedIn = null; + this.isLoggedIn = ConnectionManager.getInstance().isLoggedIn(); + this.props.navigation.setOptions({ + headerRight: this.getHeaderButton, + }); + this.state = { + dialogVisible: false, + mascotDialogVisible: AsyncStorageManager.getInstance().preferences.homeShowBanner.current === "1" + && !this.isLoggedIn, + } } /** @@ -142,13 +144,6 @@ class HomeScreen extends React.Component { this.props.navigation.addListener('focus', this.onScreenFocus); // Handle link open when home is focused this.props.navigation.addListener('state', this.handleNavigationParams); - setTimeout(this.onBannerTimeout, 2000); - } - - onBannerTimeout = () => { - this.setState({ - bannerVisible: AsyncStorageManager.getInstance().preferences.homeShowBanner.current === "1" - }) } /** @@ -161,9 +156,6 @@ class HomeScreen extends React.Component { headerRight: this.getHeaderButton, }); } - if (this.isLoggedIn) { - this.setState({bannerVisible: false}) - } // handle link open when home is not focused or created this.handleNavigationParams(); }; @@ -203,6 +195,14 @@ class HomeScreen extends React.Component { ; }; + hideMascotDialog = () => { + AsyncStorageManager.getInstance().savePref( + AsyncStorageManager.getInstance().preferences.homeShowBanner.key, + '0' + ); + this.setState({mascotDialogVisible: false}) + }; + showDisconnectDialog = () => this.setState({dialogVisible: true}); hideDisconnectDialog = () => this.setState({dialogVisible: false}); @@ -569,29 +569,16 @@ class HomeScreen extends React.Component { this.fabRef.current.onScroll(event); }; - /** - * Callback used when closing the banner. - * This hides the banner and saves to preferences to prevent it from reopening. - */ - onHideBanner = () => { - this.setState({bannerVisible: false}); - AsyncStorageManager.getInstance().savePref( - AsyncStorageManager.getInstance().preferences.homeShowBanner.key, - '0' - ); - }; - /** * Callback when pressing the login button on the banner. * This hides the banner and takes the user to the login page. */ - onLoginBanner = () => { - this.onHideBanner(); + onLogin = () => { + this.hideMascotDialog(); this.props.navigation.navigate("login", {nextScreen: "profile"}); } render() { - const {containerPaddingTop} = this.props.collapsibleStack; return ( { showError={false} /> + { visible={this.state.dialogVisible} onDismiss={this.hideDisconnectDialog} /> - } - > - {i18n.t('homeScreen.loginBanner.message')} - ); } } -export default withCollapsible(withTheme(HomeScreen)); +export default withTheme(HomeScreen); diff --git a/src/screens/Planex/PlanexScreen.js b/src/screens/Planex/PlanexScreen.js index 07e75a7..c2c5d6e 100644 --- a/src/screens/Planex/PlanexScreen.js +++ b/src/screens/Planex/PlanexScreen.js @@ -4,30 +4,29 @@ import * as React from 'react'; import type {CustomTheme} from "../../managers/ThemeManager"; import ThemeManager from "../../managers/ThemeManager"; import WebViewScreen from "../../components/Screens/WebViewScreen"; -import {Avatar, Banner, withTheme} from "react-native-paper"; +import {withTheme} from "react-native-paper"; import i18n from "i18n-js"; import {View} from "react-native"; import AsyncStorageManager from "../../managers/AsyncStorageManager"; import AlertDialog from "../../components/Dialogs/AlertDialog"; -import {withCollapsible} from "../../utils/withCollapsible"; import {dateToString, getTimeOnlyString} from "../../utils/Planning"; import DateManager from "../../managers/DateManager"; import AnimatedBottomBar from "../../components/Animations/AnimatedBottomBar"; import {CommonActions} from "@react-navigation/native"; import ErrorView from "../../components/Screens/ErrorView"; import {StackNavigationProp} from "@react-navigation/stack"; -import {Collapsible} from "react-navigation-collapsible"; import type {group} from "./GroupSelectionScreen"; +import {MASCOT_STYLE} from "../../components/Mascot/Mascot"; +import MascotPopup from "../../components/Mascot/MascotPopup"; type Props = { navigation: StackNavigationProp, route: { params: { group: group } }, theme: CustomTheme, - collapsibleStack: Collapsible, } type State = { - bannerVisible: boolean, + mascotDialogVisible: boolean, dialogVisible: boolean, dialogTitle: string, dialogMessage: string, @@ -144,7 +143,9 @@ class PlanexScreen extends React.Component { props.navigation.setOptions({title: currentGroup.name}) } this.state = { - bannerVisible: false, + mascotDialogVisible: + AsyncStorageManager.getInstance().preferences.planexShowBanner.current === '1' && + AsyncStorageManager.getInstance().preferences.defaultStartScreen.current !== 'Planex', dialogVisible: false, dialogTitle: "", dialogMessage: "", @@ -158,23 +159,14 @@ class PlanexScreen extends React.Component { */ componentDidMount() { this.props.navigation.addListener('focus', this.onScreenFocus); - setTimeout(this.onBannerTimeout, 2000); - } - - onBannerTimeout = () => { - this.setState({ - bannerVisible: - AsyncStorageManager.getInstance().preferences.planexShowBanner.current === '1' && - AsyncStorageManager.getInstance().preferences.defaultStartScreen.current !== 'Planex' - }) } /** * Callback used when closing the banner. * This hides the banner and saves to preferences to prevent it from reopening */ - onHideBanner = () => { - this.setState({bannerVisible: false}); + onMascotDialogCancel = () => { + this.setState({mascotDialogVisible: false}); AsyncStorageManager.getInstance().savePref( AsyncStorageManager.getInstance().preferences.planexShowBanner.key, '0' @@ -187,7 +179,7 @@ class PlanexScreen extends React.Component { * This will hide the banner and open the SettingsScreen */ onGoToSettings = () => { - this.onHideBanner(); + this.onMascotDialogCancel(); this.props.navigation.navigate('settings'); }; @@ -356,7 +348,6 @@ class PlanexScreen extends React.Component { } render() { - const {containerPaddingTop} = this.props.collapsibleStack; return ( { ? this.getWebView() : {this.getWebView()}} - } - > - {i18n.t('planexScreen.enableStartScreen')} - + cancel: { + message: i18n.t("planexScreen.enableStartCancel"), + icon: "close", + color: this.props.theme.colors.warning, + onPress: this.onMascotDialogCancel, + } + }} + emotion={MASCOT_STYLE.INTELLO} + /> { } } -export default withCollapsible(withTheme(PlanexScreen)); +export default withTheme(PlanexScreen); diff --git a/src/screens/Proxiwash/ProxiwashScreen.js b/src/screens/Proxiwash/ProxiwashScreen.js index 3d6df27..522cde4 100644 --- a/src/screens/Proxiwash/ProxiwashScreen.js +++ b/src/screens/Proxiwash/ProxiwashScreen.js @@ -6,19 +6,19 @@ import i18n from "i18n-js"; import WebSectionList from "../../components/Screens/WebSectionList"; import * as Notifications from "../../utils/Notifications"; import AsyncStorageManager from "../../managers/AsyncStorageManager"; -import {Avatar, Banner, Button, Card, Text, withTheme} from 'react-native-paper'; +import {Avatar, Button, Card, Text, withTheme} from 'react-native-paper'; import ProxiwashListItem from "../../components/Lists/Proxiwash/ProxiwashListItem"; import ProxiwashConstants 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 {withCollapsible} from "../../utils/withCollapsible"; import type {CustomTheme} from "../../managers/ThemeManager"; -import {Collapsible} from "react-navigation-collapsible"; import {StackNavigationProp} from "@react-navigation/stack"; import {getCleanedMachineWatched, getMachineEndDate, isMachineWatched} from "../../utils/Proxiwash"; import {Modalize} from "react-native-modalize"; +import {MASCOT_STYLE} from "../../components/Mascot/Mascot"; +import MascotPopup from "../../components/Mascot/MascotPopup"; const DATA_URL = "https://etud.insa-toulouse.fr/~amicale_app/v2/washinsa/washinsa_data.json"; @@ -40,14 +40,13 @@ export type Machine = { type Props = { navigation: StackNavigationProp, theme: CustomTheme, - collapsibleStack: Collapsible, } type State = { refreshing: boolean, modalCurrentDisplayItem: React.Node, machinesWatched: Array, - bannerVisible: boolean, + mascotDialogVisible: boolean, }; @@ -68,7 +67,7 @@ class ProxiwashScreen extends React.Component { refreshing: false, modalCurrentDisplayItem: null, machinesWatched: JSON.parse(AsyncStorageManager.getInstance().preferences.proxiwashWatchedMachines.current), - bannerVisible: false, + mascotDialogVisible: AsyncStorageManager.getInstance().preferences.proxiwashShowBanner.current === "1", }; /** @@ -89,8 +88,8 @@ class ProxiwashScreen extends React.Component { * Callback used when closing the banner. * This hides the banner and saves to preferences to prevent it from reopening */ - onHideBanner = () => { - this.setState({bannerVisible: false}); + onHideMascotDialog = () => { + this.setState({mascotDialogVisible: false}); AsyncStorageManager.getInstance().savePref( AsyncStorageManager.getInstance().preferences.proxiwashShowBanner.key, '0' @@ -107,11 +106,6 @@ class ProxiwashScreen extends React.Component { , }); - setTimeout(this.onBannerTimeout, 2000); - } - - onBannerTimeout = () => { - this.setState({bannerVisible: AsyncStorageManager.getInstance().preferences.proxiwashShowBanner.current === "1"}) } /** @@ -401,7 +395,6 @@ class ProxiwashScreen extends React.Component { render() { const nav = this.props.navigation; - const {containerPaddingTop} = this.props.collapsibleStack; return ( { refreshOnFocus={true} updateData={this.state.machinesWatched.length}/> - } - > - {i18n.t('proxiwashScreen.enableNotificationsTip')} - + emotion={MASCOT_STYLE.NORMAL} + /> {this.state.modalCurrentDisplayItem} @@ -448,4 +437,4 @@ class ProxiwashScreen extends React.Component { } } -export default withCollapsible(withTheme(ProxiwashScreen)); +export default withTheme(ProxiwashScreen); diff --git a/translations/en.json b/translations/en.json index 57c5b1f..3e77ae3 100644 --- a/translations/en.json +++ b/translations/en.json @@ -116,7 +116,8 @@ "loginBanner": { "login": "Login", "later": "Later", - "message": "Login to your Amicale account to get access to more services!" + "title": "Welcome, you!", + "message": "Login to your Amicale account to get access to more services!\n\nYou will still be able to login later." } }, "aboutScreen": { @@ -179,9 +180,10 @@ "dryerTips": "The advised dryer length is 35 minutes for 14 kg of laundry. You can choose a shorter length if the dryer is not fully charged.", "procedure": "Procedure", "tips": "Tips", - "enableNotificationsTip": "Click on a running machine to enable notifications", + "enableNotificationsTip": "Click on a running machine to enable notifications!\n\nYou will never forget your laundry again.", "numAvailable": "available", "numAvailablePlural": "available", + "bannerTitle": "Notifications!", "bannerButton": "Got it!", "modal": { "enableNotifications": "Notify me", @@ -215,7 +217,8 @@ } }, "planexScreen": { - "enableStartScreen": "Come here often? Set it as default screen!", + "enableStartScreenTitle": "Come here often?", + "enableStartScreenMessage": "Set it as default screen!\n\nCampus will start on Planex so you never miss a class. Click on the button bellow to navigate to the settings page.", "enableStartOK": "Yes please!", "enableStartCancel": "Later", "noGroupSelected": "No group selected. Please select your group using the big beautiful red button bellow.",