diff --git a/app.json b/app.json index b7dd184..5c11660 100644 --- a/app.json +++ b/app.json @@ -10,7 +10,7 @@ "android", "web" ], - "version": "0.0.14", + "version": "0.0.15", "orientation": "portrait", "primaryColor": "#be1522", "icon": "./assets/android.icon.png", @@ -36,7 +36,7 @@ }, "android": { "package": "fr.amicaleinsat.application", - "versionCode": 2, + "versionCode": 3, "icon": "./assets/android.icon.png", "adaptiveIcon": { "foregroundImage": "./assets/android.adaptive-icon.png", diff --git a/assets/ios.icon.png b/assets/ios.icon.png index 24e660e..5266412 100644 Binary files a/assets/ios.icon.png and b/assets/ios.icon.png differ diff --git a/navigation/AppNavigator.js b/navigation/AppNavigator.js index b649a0f..f6dfc49 100644 --- a/navigation/AppNavigator.js +++ b/navigation/AppNavigator.js @@ -9,6 +9,7 @@ import AboutDependenciesScreen from '../screens/About/AboutDependenciesScreen'; import ProxiwashAboutScreen from '../screens/ProxiwashAboutScreen'; import ProximoAboutScreen from '../screens/Proximo/ProximoAboutScreen'; import SelfMenuScreen from '../screens/SelfMenuScreen'; +import DebugScreen from '../screens/DebugScreen'; import {fromRight} from "react-navigation-transitions"; /** @@ -25,6 +26,7 @@ export default createAppContainer( SelfMenuScreen: {screen: SelfMenuScreen}, ProxiwashAboutScreen: {screen: ProxiwashAboutScreen}, ProximoAboutScreen: {screen: ProximoAboutScreen}, + DebugScreen: {screen: DebugScreen}, }, { initialRouteName: "Main", diff --git a/screens/About/AboutScreen.js b/screens/About/AboutScreen.js index 3470075..efc3b4b 100644 --- a/screens/About/AboutScreen.js +++ b/screens/About/AboutScreen.js @@ -1,13 +1,14 @@ // @flow import * as React from 'react'; -import {Alert, FlatList, Linking, Platform} from 'react-native'; +import {FlatList, Linking, Platform, View} from 'react-native'; import {Body, Card, CardItem, Container, Content, H1, Left, Right, Text, Thumbnail} from 'native-base'; import CustomHeader from "../../components/CustomHeader"; import i18n from "i18n-js"; import appJson from '../../app'; import packageJson from '../../package'; import CustomMaterialIcon from "../../components/CustomMaterialIcon"; +import AsyncStorageManager from "../../utils/AsyncStorageManager"; const links = { appstore: 'https://qwant.com', @@ -27,6 +28,10 @@ type Props = { navigation: Object, }; +type State = { + isDebugUnlocked: boolean, +}; + /** * Opens a link in the device's browser * @param link The link to open @@ -38,7 +43,13 @@ function openWebLink(link) { /** * Class defining an about screen. This screen shows the user information about the app and it's author. */ -export default class AboutScreen extends React.Component { +export default class AboutScreen extends React.Component { + + debugTapCounter = 0; + + state = { + isDebugUnlocked: AsyncStorageManager.getInstance().preferences.debugUnlocked.current === '1' + }; /** * Data to be displayed in the app card @@ -80,6 +91,13 @@ export default class AboutScreen extends React.Component { text: i18n.t('aboutScreen.license'), showChevron: true }, + { + onPressCallback: () => this.props.navigation.navigate('DebugScreen'), + icon: 'bug-check', + text: i18n.t('aboutScreen.debug'), + showChevron: true, + showOnlyDebug: true + }, ]; /** @@ -87,7 +105,7 @@ export default class AboutScreen extends React.Component { */ authorData: Array = [ { - onPressCallback: () => Alert.alert('Coucou', 'Whaou'), + onPressCallback: () => this.tryUnlockDebugMode(), icon: 'account-circle', text: 'Arnaud VERGNET', showChevron: false @@ -137,26 +155,48 @@ export default class AboutScreen extends React.Component { * @param icon The icon name to use from MaterialCommunityIcons * @param text The text to show * @param showChevron Whether to show a chevron indicating this button will change screen + * @param showOnlyInDebug Should we show te current item only in debug mode? * @returns {React.Node} */ - static getCardItem(onPressCallback: Function, icon: string, text: string, showChevron: boolean) { - return ( - - - - {text} - - {showChevron ? - - - - : - - } - ) - ; + getCardItem(onPressCallback: Function, icon: string, text: string, showChevron: boolean, showOnlyInDebug: boolean) { + let shouldShow = !showOnlyInDebug || (showOnlyInDebug && this.state.isDebugUnlocked); + if (shouldShow) { + return ( + + + + {text} + + {showChevron ? + + + + : + + } + ) + ; + } else { + return + } + + } + + tryUnlockDebugMode() { + this.debugTapCounter = this.debugTapCounter + 1; + console.log(this.debugTapCounter); + if (this.debugTapCounter >= 4) { + this.unlockDebugMode(); + } + } + + unlockDebugMode() { + console.log('unlocked'); + this.setState({isDebugUnlocked: true}); + let key = AsyncStorageManager.getInstance().preferences.debugUnlocked.key; + AsyncStorageManager.getInstance().savePref(key, '1'); } render() { @@ -168,9 +208,9 @@ export default class AboutScreen extends React.Component { - + -

Amicale INSA Toulouse

+

CAMPUS - Amicale INSAT

v.{appJson.expo.version} @@ -179,9 +219,10 @@ export default class AboutScreen extends React.Component {
item.icon} renderItem={({item}) => - AboutScreen.getCardItem(item.onPressCallback, item.icon, item.text, item.showChevron) + this.getCardItem(item.onPressCallback, item.icon, item.text, item.showChevron, item.showOnlyDebug) } />
@@ -192,9 +233,10 @@ export default class AboutScreen extends React.Component { item.icon} renderItem={({item}) => - AboutScreen.getCardItem(item.onPressCallback, item.icon, item.text, item.showChevron) + this.getCardItem(item.onPressCallback, item.icon, item.text, item.showChevron, item.showOnlyDebug) } /> @@ -205,9 +247,10 @@ export default class AboutScreen extends React.Component { item.icon} renderItem={({item}) => - AboutScreen.getCardItem(item.onPressCallback, item.icon, item.text, item.showChevron) + this.getCardItem(item.onPressCallback, item.icon, item.text, item.showChevron, item.showOnlyDebug) } /> diff --git a/screens/DebugScreen.js b/screens/DebugScreen.js new file mode 100644 index 0000000..37a6c37 --- /dev/null +++ b/screens/DebugScreen.js @@ -0,0 +1,99 @@ +// @flow + +import * as React from 'react'; +import {Body, Card, CardItem, Container, Content, Left, List, ListItem, Right, Text,} from "native-base"; +import CustomHeader from "../components/CustomHeader"; +import ThemeManager from '../utils/ThemeManager'; +import i18n from "i18n-js"; +import CustomMaterialIcon from "../components/CustomMaterialIcon"; +import Touchable from "react-native-platform-touchable"; +import {Alert, Platform, Clipboard} from "react-native"; +import AsyncStorageManager from "../utils/AsyncStorageManager"; +import NotificationsManager from "../utils/NotificationsManager"; + +type Props = { + navigation: Object, +}; + +/** + * Class defining the Debug screen. This screen allows the user to get detailed information on the app/device. + */ +export default class DebugScreen extends React.Component { + + alertCurrentExpoToken() { + let token = AsyncStorageManager.getInstance().preferences.expoToken.current; + console.log(token); + Alert.alert( + 'Expo Token', + token, + [ + {text: 'Copy', onPress: () => Clipboard.setString(token)}, + {text: 'OK'} + ] + ); + } + + async forceExpoTokenUpdate() { + await NotificationsManager.forceExpoTokenUpdate(); + this.alertCurrentExpoToken(); + } + + + static getGeneralItem(onPressCallback: Function, icon: string, title: string, subtitle: string) { + return ( + + + + + + + {title} + + + {subtitle} + + + + + ); + } + + getRightButton() { + return ( + this.props.navigation.navigate('AboutScreen')}> + + + ); + } + + render() { + const nav = this.props.navigation; + return ( + + + + + + + Notifications + + + + {DebugScreen.getGeneralItem(() => this.alertCurrentExpoToken(), 'bell', 'Get current Expo Token', '')} + {DebugScreen.getGeneralItem(() => this.forceExpoTokenUpdate(),'bell-ring', 'Force Expo token update', '')} + + + + + + ); + } +} diff --git a/translations/en.json b/translations/en.json index 8b1a9f4..096d4b2 100644 --- a/translations/en.json +++ b/translations/en.json @@ -6,7 +6,8 @@ "proximo": "Proximo", "menuSelf": "RU Menu", "settings": "Settings", - "about": "About" + "about": "About", + "debug": "Debug" }, "intro": { "slide1": { @@ -15,15 +16,15 @@ }, "slide2": { "title": "Stay up to date", - "text": "CAMPUS will soon allow you to be aware of any event occuring on the campus, from pancake sales to Enfoiros concerts!" + "text": "CAMPUS will soon allow you to be aware of any event occurring on the campus, from pancake sales to Enfoiros concerts!" }, "slide3": { "title": "Never forget your laundry", - "text": "CAMPUS will inform you on the availability of washing machines and will remind you just before yours finishes !" + "text": "CAMPUS will inform you on the availability of washing machines and will remind you just before yours finishes!" }, "slide4": { "title": "Proximo", - "text": "Are you short on pasta? Or you maybe you feel a little peckish, then lookup the stock for your insa shop in real time" + "text": "Are you short on pasta? Or you maybe you feel a little peckish, then look up your INSA shop's stock in real time" }, "slide5": { "title": "Planex", @@ -31,7 +32,7 @@ }, "slide6": { "title": "Still in development", - "text": "New features coming soon, do not hesitate to give us feedback to improve the app" + "text": "New features are coming soon, do not hesitate to give us feedback to improve the app" } }, "settingsScreen": { @@ -66,6 +67,7 @@ "bugs": "Report Bugs", "changelog": "Changelog", "license": "License", + "debug": "Debug", "author": "Author", "mail": "Send an email", "technologies": "Technologies", diff --git a/translations/fr.json b/translations/fr.json index 242b268..532f12d 100644 --- a/translations/fr.json +++ b/translations/fr.json @@ -6,7 +6,8 @@ "proximo": "Proximo", "menuSelf": "Menu Ru", "settings": "Paramètres", - "about": "À Propos" + "about": "À Propos", + "debug": "Debug" }, "intro": { "slide1": { @@ -66,6 +67,7 @@ "bugs": "Rapporter des Bugs", "changelog": "Historique des modifications", "license": "Licence", + "debug": "Debug", "author": "Auteur", "mail": "Envoyer un mail", "technologies": "Technologies", @@ -127,7 +129,7 @@ "states": { "finished": "TERMINE", "ready": "DISPONIBLE", - "running": "En COURS", + "running": "EN COURS", "broken": "HORS SERVICE", "error": "ERREUR" }, diff --git a/utils/AsyncStorageManager.js b/utils/AsyncStorageManager.js index ce3dfe4..f571c2f 100644 --- a/utils/AsyncStorageManager.js +++ b/utils/AsyncStorageManager.js @@ -48,6 +48,11 @@ export default class AsyncStorageManager { key: 'expoToken', default: '', current: '', + }, + debugUnlocked: { + key: 'debugUnlocked', + default: '0', + current: '', } }; diff --git a/utils/NotificationsManager.js b/utils/NotificationsManager.js index 811d505..8ad7a51 100644 --- a/utils/NotificationsManager.js +++ b/utils/NotificationsManager.js @@ -95,12 +95,20 @@ export default class NotificationsManager { static async initExpoToken() { let token = AsyncStorageManager.getInstance().preferences.expoToken.current; if (token === '') { + await NotificationsManager.askPermissions(); let expoToken = await Notifications.getExpoPushTokenAsync(); // Save token for instant use later on AsyncStorageManager.getInstance().savePref(AsyncStorageManager.getInstance().preferences.expoToken.key, expoToken); } } + static async forceExpoTokenUpdate() { + await NotificationsManager.askPermissions(); + let expoToken = await Notifications.getExpoPushTokenAsync(); + // Save token for instant use later on + AsyncStorageManager.getInstance().savePref(AsyncStorageManager.getInstance().preferences.expoToken.key, expoToken); + } + static getMachineNotificationWatchlist(callback: Function) { let token = AsyncStorageManager.getInstance().preferences.expoToken.current; if (token === '') {