forked from vergnet/application-amicale
Improved doc and typing, improved API connection handling
This commit is contained in:
parent
3f14f7bb96
commit
b813aa0b83
6 changed files with 138 additions and 76 deletions
|
@ -1,3 +1,5 @@
|
|||
// @flow
|
||||
|
||||
import i18n from "i18n-js";
|
||||
|
||||
/**
|
||||
|
@ -43,8 +45,8 @@ export default class Update {
|
|||
this.titleList = [];
|
||||
this.descriptionList = [];
|
||||
for (let i = 0; i < Update.slidesNumber; i++) {
|
||||
this.titleList.push(i18n.t('intro.updateSlide'+ i + '.title'))
|
||||
this.descriptionList.push(i18n.t('intro.updateSlide'+ i + '.text'))
|
||||
this.titleList.push(i18n.t('intro.updateSlide' + i + '.title'))
|
||||
this.descriptionList.push(i18n.t('intro.updateSlide' + i + '.text'))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
// @flow
|
||||
|
||||
import type {Machine} from "../screens/Proxiwash/ProxiwashScreen";
|
||||
|
||||
/**
|
||||
* Singleton class used to manage themes
|
||||
* Singleton class used to manage april fools
|
||||
*/
|
||||
export default class AprilFoolsManager {
|
||||
|
||||
static instance: AprilFoolsManager | null = null;
|
||||
|
||||
aprilFoolsEnabled: boolean;
|
||||
|
||||
static fakeMachineNumber = [
|
||||
"",
|
||||
"cos(ln(1))",
|
||||
|
@ -24,6 +23,7 @@ export default class AprilFoolsManager {
|
|||
"1×10¹+1×10⁰",
|
||||
"Re(√192e^(iπ/6))",
|
||||
];
|
||||
aprilFoolsEnabled: boolean;
|
||||
|
||||
constructor() {
|
||||
let today = new Date();
|
||||
|
@ -40,7 +40,13 @@ export default class AprilFoolsManager {
|
|||
AprilFoolsManager.instance;
|
||||
}
|
||||
|
||||
static getFakeMenuItem(menu: Object) {
|
||||
/**
|
||||
* Adds fake menu entries
|
||||
*
|
||||
* @param menu
|
||||
* @returns {Object}
|
||||
*/
|
||||
static getFakeMenuItem(menu: Array<{dishes: Array<{name: string}>}>) {
|
||||
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"});
|
||||
|
@ -49,16 +55,26 @@ export default class AprilFoolsManager {
|
|||
return menu;
|
||||
}
|
||||
|
||||
static getNewProxiwashDryerOrderedList(dryers: Array<Object>) {
|
||||
if (dryers !== undefined) {
|
||||
/**
|
||||
* Changes proxiwash dryers order
|
||||
*
|
||||
* @param dryers
|
||||
*/
|
||||
static getNewProxiwashDryerOrderedList(dryers: Array<Machine> | null) {
|
||||
if (dryers != null) {
|
||||
let second = dryers[1];
|
||||
dryers.splice(1, 1);
|
||||
dryers.push(second);
|
||||
}
|
||||
}
|
||||
|
||||
static getNewProxiwashWasherOrderedList(washers: Array<Object>) {
|
||||
if (washers !== undefined) {
|
||||
/**
|
||||
* Changes proxiwash washers order
|
||||
*
|
||||
* @param washers
|
||||
*/
|
||||
static getNewProxiwashWasherOrderedList(washers: Array<Machine> | null) {
|
||||
if (washers != null) {
|
||||
let first = washers[0];
|
||||
let second = washers[1];
|
||||
let fifth = washers[4];
|
||||
|
@ -67,14 +83,25 @@ export default class AprilFoolsManager {
|
|||
washers.splice(4, 1, ninth);
|
||||
washers.splice(1, 1, first);
|
||||
washers.splice(0, 1, fifth);
|
||||
// washers.push(fifth);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the new display number for the given machine number
|
||||
*
|
||||
* @param number
|
||||
* @returns {string}
|
||||
*/
|
||||
static getProxiwashMachineDisplayNumber(number: number) {
|
||||
return AprilFoolsManager.fakeMachineNumber[number];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the new and ugly april fools theme
|
||||
*
|
||||
* @param currentTheme
|
||||
* @returns {{colors: {textDisabled: string, agendaDayTextColor: string, surface: string, background: string, dividerBackground: string, accent: string, agendaBackgroundColor: string, tabIcon: string, card: string, primary: string}}}
|
||||
*/
|
||||
static getAprilFoolsTheme(currentTheme: Object) {
|
||||
return {
|
||||
...currentTheme,
|
||||
|
|
|
@ -23,15 +23,13 @@ export default class ConnectionManager {
|
|||
#email: string;
|
||||
#token: string | null;
|
||||
|
||||
listeners: Array<Function>;
|
||||
|
||||
constructor() {
|
||||
this.#token = null;
|
||||
this.listeners = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get this class instance or create one if none is found
|
||||
* Gets this class instance or create one if none is found
|
||||
*
|
||||
* @returns {ConnectionManager}
|
||||
*/
|
||||
static getInstance(): ConnectionManager {
|
||||
|
@ -40,21 +38,20 @@ export default class ConnectionManager {
|
|||
ConnectionManager.instance;
|
||||
}
|
||||
|
||||
getToken() {
|
||||
/**
|
||||
* Gets the current token
|
||||
*
|
||||
* @returns {string | null}
|
||||
*/
|
||||
getToken(): string | null {
|
||||
return this.#token;
|
||||
}
|
||||
|
||||
onLoginStateChange(newState: boolean) {
|
||||
for (let i = 0; i < this.listeners.length; i++) {
|
||||
if (this.listeners[i] !== undefined)
|
||||
this.listeners[i](newState);
|
||||
}
|
||||
}
|
||||
|
||||
addLoginStateListener(listener: Function) {
|
||||
this.listeners.push(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to recover login token from the secure keychain
|
||||
*
|
||||
* @returns {Promise<R>}
|
||||
*/
|
||||
async recoverLogin() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.getToken() !== null)
|
||||
|
@ -64,7 +61,6 @@ export default class ConnectionManager {
|
|||
.then((data) => {
|
||||
if (data) {
|
||||
this.#token = data.password;
|
||||
this.onLoginStateChange(true);
|
||||
resolve(this.#token);
|
||||
} else
|
||||
reject(false);
|
||||
|
@ -76,17 +72,28 @@ export default class ConnectionManager {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the user has a valid token
|
||||
*
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isLoggedIn() {
|
||||
return this.getToken() !== null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the login token in the secure keychain
|
||||
*
|
||||
* @param email
|
||||
* @param token
|
||||
* @returns {Promise<R>}
|
||||
*/
|
||||
async saveLogin(email: string, token: string) {
|
||||
return new Promise((resolve, reject) => {
|
||||
Keychain.setInternetCredentials(SERVER_NAME, 'token', token)
|
||||
.then(() => {
|
||||
this.#token = token;
|
||||
this.#email = email;
|
||||
this.onLoginStateChange(true);
|
||||
resolve(true);
|
||||
})
|
||||
.catch(() => {
|
||||
|
@ -95,12 +102,16 @@ export default class ConnectionManager {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes the login token from the keychain
|
||||
*
|
||||
* @returns {Promise<R>}
|
||||
*/
|
||||
async disconnect() {
|
||||
return new Promise((resolve, reject) => {
|
||||
Keychain.resetInternetCredentials(SERVER_NAME)
|
||||
.then(() => {
|
||||
this.#token = null;
|
||||
this.onLoginStateChange(false);
|
||||
resolve(true);
|
||||
})
|
||||
.catch(() => {
|
||||
|
@ -109,6 +120,16 @@ export default class ConnectionManager {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends the given login and password to the api.
|
||||
* If the combination is valid, the login token is received and saved in the secure keychain.
|
||||
* If not, the promise is rejected with the corresponding error code.
|
||||
*
|
||||
* @param email
|
||||
* @param password
|
||||
* @returns {Promise<R>}
|
||||
*/
|
||||
async connect(email: string, password: string) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const data = {
|
||||
|
@ -117,19 +138,28 @@ export default class ConnectionManager {
|
|||
};
|
||||
apiRequest(AUTH_PATH, 'POST', data)
|
||||
.then((response) => {
|
||||
this.saveLogin(email, response.token)
|
||||
.then(() => {
|
||||
resolve(true);
|
||||
})
|
||||
.catch(() => {
|
||||
reject(ERROR_TYPE.TOKEN_SAVE);
|
||||
});
|
||||
if (this.isConnectionResponseValid(response)) {
|
||||
this.saveLogin(email, response.token)
|
||||
.then(() => {
|
||||
resolve(true);
|
||||
})
|
||||
.catch(() => {
|
||||
reject(ERROR_TYPE.TOKEN_SAVE);
|
||||
});
|
||||
} else
|
||||
reject(ERROR_TYPE.SERVER_ERROR);
|
||||
})
|
||||
.catch((error) => reject(error));
|
||||
});
|
||||
}
|
||||
|
||||
isConnectionResponseValid(response: Object) {
|
||||
/**
|
||||
* Checks if the API connection response is correctly formatted
|
||||
*
|
||||
* @param response
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isConnectionResponseValid(response: { [key: string]: any }) {
|
||||
let valid = isResponseValid(response);
|
||||
|
||||
if (valid && response.error === ERROR_TYPE.SUCCESS)
|
||||
|
@ -140,6 +170,13 @@ export default class ConnectionManager {
|
|||
return valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an authenticated request with the login token to the API
|
||||
*
|
||||
* @param path
|
||||
* @param params
|
||||
* @returns {Promise<R>}
|
||||
*/
|
||||
async authenticatedRequest(path: string, params: Object) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.getToken() !== null) {
|
||||
|
|
|
@ -45,6 +45,10 @@ export default class DateManager {
|
|||
DateManager.instance;
|
||||
}
|
||||
|
||||
static isWeekend(date: Date) {
|
||||
return date.getDay() === 6 || date.getDay() === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a translated string representing the given date.
|
||||
*
|
||||
|
@ -58,8 +62,4 @@ export default class DateManager {
|
|||
return this.daysOfWeek[date.getDay()] + " " + date.getDate() + " " + this.monthsOfYear[date.getMonth()] + " " + date.getFullYear();
|
||||
}
|
||||
|
||||
static isWeekend(date: Date) {
|
||||
return date.getDay() === 6 || date.getDay() === 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,8 +19,4 @@ export default class LocaleManager {
|
|||
i18n.translations = {fr, en};
|
||||
i18n.locale = RNLocalize.findBestAvailableLanguage(["en", "fr"]).languageTag;
|
||||
}
|
||||
|
||||
static getCurrentLocale() {
|
||||
return RNLocalize.findBestAvailableLanguage(["en", "fr"]).languageTag;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,15 +46,15 @@ export type CustomTheme = {
|
|||
|
||||
// Tetris
|
||||
tetrisBackground: string,
|
||||
tetrisBorder:string,
|
||||
tetrisScore:string,
|
||||
tetrisI : string,
|
||||
tetrisO : string,
|
||||
tetrisT : string,
|
||||
tetrisS : string,
|
||||
tetrisZ : string,
|
||||
tetrisJ : string,
|
||||
tetrisL : string,
|
||||
tetrisBorder: string,
|
||||
tetrisScore: string,
|
||||
tetrisI: string,
|
||||
tetrisO: string,
|
||||
tetrisT: string,
|
||||
tetrisS: string,
|
||||
tetrisZ: string,
|
||||
tetrisJ: string,
|
||||
tetrisL: string,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -116,16 +116,16 @@ export default class ThemeManager {
|
|||
tutorinsaColor: '#f93943',
|
||||
|
||||
// Tetris
|
||||
tetrisBackground:'#e6e6e6',
|
||||
tetrisBorder:'#2f2f2f',
|
||||
tetrisScore:'#e2bd33',
|
||||
tetrisI : '#3cd9e6',
|
||||
tetrisO : '#ffdd00',
|
||||
tetrisT : '#a716e5',
|
||||
tetrisS : '#09c528',
|
||||
tetrisZ : '#ff0009',
|
||||
tetrisJ : '#2a67e3',
|
||||
tetrisL : '#da742d',
|
||||
tetrisBackground: '#e6e6e6',
|
||||
tetrisBorder: '#2f2f2f',
|
||||
tetrisScore: '#e2bd33',
|
||||
tetrisI: '#3cd9e6',
|
||||
tetrisO: '#ffdd00',
|
||||
tetrisT: '#a716e5',
|
||||
tetrisS: '#09c528',
|
||||
tetrisZ: '#ff0009',
|
||||
tetrisJ: '#2a67e3',
|
||||
tetrisL: '#da742d',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -176,16 +176,16 @@ export default class ThemeManager {
|
|||
tutorinsaColor: '#f93943',
|
||||
|
||||
// Tetris
|
||||
tetrisBackground:'#2c2c2c',
|
||||
tetrisBorder:'#1b1b1b',
|
||||
tetrisScore:'#e2d707',
|
||||
tetrisI : '#30b3be',
|
||||
tetrisO : '#c1a700',
|
||||
tetrisT : '#9114c7',
|
||||
tetrisS : '#08a121',
|
||||
tetrisZ : '#b50008',
|
||||
tetrisJ : '#0f37b9',
|
||||
tetrisL : '#b96226',
|
||||
tetrisBackground: '#2c2c2c',
|
||||
tetrisBorder: '#1b1b1b',
|
||||
tetrisScore: '#e2d707',
|
||||
tetrisI: '#30b3be',
|
||||
tetrisO: '#c1a700',
|
||||
tetrisT: '#9114c7',
|
||||
tetrisS: '#08a121',
|
||||
tetrisZ: '#b50008',
|
||||
tetrisJ: '#0f37b9',
|
||||
tetrisL: '#b96226',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue