Improved doc and typing, improved API connection handling

This commit is contained in:
Arnaud Vergnet 2020-07-01 13:14:17 +02:00
parent 3f14f7bb96
commit b813aa0b83
6 changed files with 138 additions and 76 deletions

View file

@ -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'))
}
}

View file

@ -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,

View file

@ -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) {

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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',
},
};
}