diff --git a/ComApp/src/App.js b/ComApp/src/App.js
index cd73224..7c6eb47 100644
--- a/ComApp/src/App.js
+++ b/ComApp/src/App.js
@@ -3,6 +3,14 @@ import React from 'react';
// Redux
import { Provider } from 'react-redux';
import { store } from './App/Store/ConfigureStore';
+// Deps
+import 'react-native-gesture-handler';
+import { NavigationContainer } from '@react-navigation/native';
+import { createNativeStackNavigator } from '@react-navigation/native-stack';
+import { TouchableOpacity, View, Image, Text, TextInput, StyleSheet, Alert } from 'react-native';
+import Icon from 'react-native-vector-icons/FontAwesome5';
+import FlashMessage, { showMessage } from 'react-native-flash-message';
+import * as SplashScreen from 'expo-splash-screen';
// i18n
import i18n from "./I18n";
// Controllers
@@ -10,117 +18,60 @@ import SyncController from './App/Controllers/SyncController';
// Views
import InstallScreen from './App/Views/InstallScreen';
import LoginScreen from './App/Views/LoginScreen';
+
+import OnlyVideosScreen from './App/Views/OnlyVideosScreen';
+import ContactScreen from './App/Views/ContactScreen';
+import ContactDetailsScreen from './App/Views/ContactDetailsScreen';
// END V2
import SyncScreen from './App/Views/SyncScreen';
import HomeScreen from './App/Views/HomeScreen';
-import 'react-native-gesture-handler';
-import { NavigationContainer } from '@react-navigation/native';
-import { createNativeStackNavigator } from '@react-navigation/native-stack';
-import { TouchableOpacity, View, Image, Text, TextInput, StyleSheet, Alert } from 'react-native';
-import Icon from 'react-native-vector-icons/FontAwesome5';
-
-import FlashMessage, { showMessage } from 'react-native-flash-message';
-import * as SplashScreen from 'expo-splash-screen';
import DirectoriesScreen from './Views/Directories';
import VideoScreen from './Views/Video';
import PDFScreen from './Views/PDF';
-import ContactScreen from './Views/Contact';
-import ContactDetailsScreen from './Views/ContactDetails';
-import OnlyVideosScreen from './Views/OnlyVideos';
+
import SearchScreen from "./Views/Search";
import MySpaceScreen from './Views/MySpace';
+// V2
//SplashScreen.preventAutoHideAsync(); //Keep
-// V2
store.dispatch({ type: 'INIT_APP' });
store.dispatch({ type: 'INIT_LOCALE' });
store.dispatch({ type: 'INIT_USERS' });
- // END V2
+
const Stack = createNativeStackNavigator();
+// END V2
class App extends React.Component {
state = {
- logged: false,
+ isSetup: false,
+ isLogged: false,
searchTxt: '',
- sendEmail: '',
- ShowIsActive: '0'
+ sendEmail: ''
};
- componentDidMount(): void {
-
+ componentDidMount() {
const unsubscribe = store.subscribe(this.handleChange.bind(this));
- // if (Sync.isLogged()) {
- // store.dispatch({
- // type: 'SET_CURRENT_USER',
- // data: CommonModel.get('isLogged').value,
- // });
- // store.dispatch({ type: 'SET_LOGGED', data: true });
- // }
+ if (SyncController.isLogged()) {
+ store.dispatch({ type: 'SET_CURRENT_USER' });
+ store.dispatch({ type: 'SET_LOGGED', data: true });
+ }
+ this.setState({
+ isSetup: store.getState().app.isSetup,
+ isLogged: store.getState().app.logged,
+ });
}
handleChange() {
- const logged = store.getState().app.logged;
- if (logged === false) {
- CommonModel.delete('isLogged');
- }
- if (logged !== undefined) {
- this.setState({ logged: logged });
- }
- this.setState({ ShowIsActive: store.getState().app.ShowIsActive });
- }
-
- LogoTitle(title) {
- return (
-
-
- {title}
-
- );
- }
-
- SendEmail() {
- return (
-
- this.setState({ sendEmail: text })} />
- {
- if (this.state.sendEmail.length > 0) {
- if (Helpers.isEmailValid(this.state.sendEmail)) {
- const email = {
- email: this.state.sendEmail,
- subject: i18n.t('app.file_sharing'),
- message: '',
- documents: JSON.stringify([store.getState().currentOpenedDoc]),
- user_id: store.getState().currentUser.id
- };
- store.dispatch({ type: 'SEND_BROCHURE', data: email });
- showMessage({
- message: i18n.t('global.message_sent') + '.',
- description: i18n.t('global.message_will_be_sent_after_sync') + '.',
- type: 'success',
- duration: 1500,
- });
- this.setState({ sendEmail: '' });
- } else {
- Alert.alert(i18n.t('global.warning') + ' !', i18n.t('error.invalid_email_address') + '.', [
- { text: 'OK' },
- ],
- { cancelable: false },
- );
- }
- }
- }}>
-
-
-
- );
+ this.setState({
+ isSetup: store.getState().app.isSetup,
+ isLogged: store.getState().app.logged,
+ }); // to force re-rendering
+ console.log("state changed")
}
render() {
@@ -128,7 +79,7 @@ class App extends React.Component {
- {store.getState().app.isSetup === false &&
+ {this.state.isSetup === false &&
{
store.dispatch({ type: 'EDIT_LOCALE' });
- this.setState({ state: this.state }); // to force re-rendering
}}
style={{ marginRight: 15 }}>
@@ -149,7 +99,7 @@ class App extends React.Component {
})}
/>
}
- {this.state.logged === false ? (
+ {this.state.isLogged === false ? (
{
store.dispatch({ type: 'EDIT_LOCALE' });
- this.setState({ state: this.state }); // to force re-rendering
}}
style={{ marginRight: 15 }}>
@@ -170,7 +119,7 @@ class App extends React.Component {
})}
/>
) : (
- ({
@@ -198,7 +147,7 @@ class App extends React.Component {
style={{ marginRight: 25 }}>
- {this.state.ShowIsActive === '1' && (
+ {store.getState().app.ShowIsActive === '1' && (
navigation.navigation.navigate('MySpaceScreen')}
style={{ marginRight: 25 }}>
@@ -224,12 +173,14 @@ class App extends React.Component {
),
})}
- />
+ />
)}
this.LogoTitle(i18n.t('global.synchronization')) }}
+ options={{
+ headerTitle: () => this.LogoTitle(i18n.t('global.synchronization'))
+ }}
/>
+
+ {title}
+
+ );
+ }
+
+ SendEmail() {
+ return (
+
+ this.setState({ sendEmail: text })} />
+ {
+ if (this.state.sendEmail.length > 0) {
+ if (Helpers.isEmailValid(this.state.sendEmail)) {
+ const email = {
+ email: this.state.sendEmail,
+ subject: i18n.t('app.file_sharing'),
+ message: '',
+ documents: JSON.stringify([store.getState().currentOpenedDoc]),
+ user_id: store.getState().currentUser.id
+ };
+ store.dispatch({ type: 'SEND_BROCHURE', data: email });
+ showMessage({
+ message: i18n.t('global.message_sent') + '.',
+ description: i18n.t('global.message_will_be_sent_after_sync') + '.',
+ type: 'success',
+ duration: 1500,
+ });
+ this.setState({ sendEmail: '' });
+ } else {
+ Alert.alert(i18n.t('global.warning') + ' !', i18n.t('error.invalid_email_address') + '.', [
+ { text: 'OK' },
+ ],
+ { cancelable: false },
+ );
+ }
+ }
+ }}>
+
+
+
+ );
+ }
+
renderFlag() {
let flag;
switch (store.getState().locale.locale) {
diff --git a/ComApp/src/App/Controllers/SyncController.js b/ComApp/src/App/Controllers/SyncController.js
index fc9a75c..259566f 100644
--- a/ComApp/src/App/Controllers/SyncController.js
+++ b/ComApp/src/App/Controllers/SyncController.js
@@ -135,14 +135,6 @@ class SyncController {
return true;
}
- isInstalled() {
- const test = Setting.get('installed');
- if (test === false) {
- return false;
- }
- return true;
- }
-
isLogged() {
const logged = Setting.get('isLogged');
const loggedTime = Setting.get('loggedTime');
diff --git a/ComApp/src/App/Store/Actions/actionType.js b/ComApp/src/App/Store/Actions/actionType.js
index 510d597..0ed17e9 100644
--- a/ComApp/src/App/Store/Actions/actionType.js
+++ b/ComApp/src/App/Store/Actions/actionType.js
@@ -7,4 +7,6 @@ export const INIT_USERS = "INIT_USERS";
export const INIT_CONTACT = "INIT_CONTACT";
export const ADD_CONTACT = "ADD_CONTACT";
export const EDIT_CONTACT = "EDIT_CONTACT";
-export const DELETE_CONTACT = "DELETE_CONTACT";
\ No newline at end of file
+export const DELETE_CONTACT = "DELETE_CONTACT";
+// Documents
+export const INIT_DOCUMENTS = "INIT_DOCUMENTS";
\ No newline at end of file
diff --git a/ComApp/src/App/Store/Actions/contacts.js b/ComApp/src/App/Store/Actions/contacts.js
index e8b15f2..9773353 100644
--- a/ComApp/src/App/Store/Actions/contacts.js
+++ b/ComApp/src/App/Store/Actions/contacts.js
@@ -2,20 +2,23 @@ import { INIT_CONTACT, ADD_CONTACT, EDIT_CONTACT, DELETE_CONTACT } from "./actio
/**
* Init contact
+ * @param {object} currentUser The currentUser
* @param {object} data The contact data
*/
-export const initContact = data => {
+export const initContact = (currentUser, data) => {
return {
type: INIT_CONTACT,
+ currentUser,
data,
};
};
/**
* Add contact
+ * @param {object} currentUser The currentUser
* @param {object} data The contact data
*/
-export const addContact = data => {
+export const addContact = (currentUser, data) => {
return {
type: ADD_CONTACT,
data,
@@ -24,10 +27,11 @@ export const addContact = data => {
/**
* Edit contact
+ * @param {object} currentUser The currentUser
* @param {string} uid The contact uid
* @param {object} data The contact data
*/
-export const editContact = (uid, data) => {
+export const editContact = (currentUser, uid, data) => {
return {
type: EDIT_CONTACT,
uid,
@@ -37,9 +41,10 @@ export const editContact = (uid, data) => {
/**
* Delete contact
+ * @param {object} currentUser The currentUser
* @param {string} uid The contact uid
*/
-export const deleteContact = uid => {
+export const deleteContact = (currentUser, uid) => {
return {
type: DELETE_CONTACT,
uid,
diff --git a/ComApp/src/App/Store/Actions/documents.js b/ComApp/src/App/Store/Actions/documents.js
new file mode 100644
index 0000000..87ae7c4
--- /dev/null
+++ b/ComApp/src/App/Store/Actions/documents.js
@@ -0,0 +1,16 @@
+import { INIT_DOCUMENTS } from "./actionType";
+
+/**
+ * Init contact
+ * @param {string} lang The lang
+ * @param {object} directories Directories
+ * @param {object} data The document data
+ */
+export const initDocuments = (lang, directories, data) => {
+ return {
+ type: INIT_DOCUMENTS,
+ lang,
+ directories,
+ data,
+ };
+};
\ No newline at end of file
diff --git a/ComApp/src/App/Store/Actions/locale.js b/ComApp/src/App/Store/Actions/locales.js
similarity index 100%
rename from ComApp/src/App/Store/Actions/locale.js
rename to ComApp/src/App/Store/Actions/locales.js
diff --git a/ComApp/src/App/Store/ConfigureStore.js b/ComApp/src/App/Store/ConfigureStore.js
index 5b9f8a5..f0d1a8d 100644
--- a/ComApp/src/App/Store/ConfigureStore.js
+++ b/ComApp/src/App/Store/ConfigureStore.js
@@ -1,13 +1,15 @@
import { createStore, combineReducers } from "redux";
import appReducer from "./Reducers/AppReducer";
+import contactsReducer from "./Reducers/contacts";
+import documentsReducer from "./Reducers/documents";
import localesReducer from "./Reducers/locales";
import usersReducer from "./Reducers/users";
-import contactsReducer from "./Reducers/contacts";
const rootReducer = combineReducers({
app: appReducer,
contacts: contactsReducer,
+ documents: documentsReducer,
locale: localesReducer,
users: usersReducer
});
diff --git a/ComApp/src/App/Store/Reducers/AppReducer.js b/ComApp/src/App/Store/Reducers/AppReducer.js
index 732e316..a6deb7f 100644
--- a/ComApp/src/App/Store/Reducers/AppReducer.js
+++ b/ComApp/src/App/Store/Reducers/AppReducer.js
@@ -1,15 +1,14 @@
import SyncController from "../../Controllers/SyncController";
// Database
-import { Setting, Directory, Document, SendBrochure } from '../../../Database';
+import { Setting, Directory, SendBrochure } from '../../../Database';
const initialState = {
isSetup: false,
locale: 'fr',
- directories: {},
- documents: {},
- syncVersion: 0,
- logged: undefined,
currentUser: {},
+ logged: false,
+ directories: {},
+ syncVersion: 0,
currentOpenedDoc: {},
ShowIsActive: 0,
};
@@ -34,26 +33,20 @@ const reducer = (state = initialState, action) => {
let directories = Directory.getAll(
state.currentUser.role,
state.currentUser.authorizedFolders,
- false,
+ true,
state.locale
);
- let docs = Document.getAll(directories);
let ShowIsActive = Setting.get('ShowIsActive');
return {
...state,
- directories: Directory.getAll(
- state.currentUser.role,
- state.currentUser.authorizedFolders,
- true,
- state.locale
- ),
- documents: docs.filter(item => item.lang === state.locale),
+ directories: directories,
ShowIsActive: ShowIsActive === undefined ? false : ShowIsActive.value,
};
case 'SET_CURRENT_USER':
+ let user = Setting.get('isLogged').value
return {
...state,
- currentUser: JSON.parse(action.data),
+ currentUser: JSON.parse(user),
};
case 'SET_LOGGED':
if (action.data === false) {
diff --git a/ComApp/src/App/Store/Reducers/contacts.js b/ComApp/src/App/Store/Reducers/contacts.js
index 07d83e7..d0c26ad 100644
--- a/ComApp/src/App/Store/Reducers/contacts.js
+++ b/ComApp/src/App/Store/Reducers/contacts.js
@@ -6,29 +6,33 @@ const initialState = [];
const reducer = (state = initialState, action) => {
switch (action.type) {
- case INIT_CONTACT:
+ case INIT_CONTACT: {
return {
...state,
- contacts: Contact.getByUser(state.currentUser.id),
+ contacts: Contact.getByUser(action.currentUser.id),
};
- case ADD_CONTACT:
+ }
+ case ADD_CONTACT: {
Contact.add(action.data);
return {
...state,
- contacts: Contact.getByUser(state.currentUser.id),
+ contacts: Contact.getByUser(action.currentUser.id),
};
- case EDIT_CONTACT:
+ }
+ case EDIT_CONTACT: {
Contact.update(action.data);
return {
...state,
- contacts: Contact.getByUser(state.currentUser.id),
+ contacts: Contact.getByUser(action.currentUser.id),
};
- case DELETE_CONTACT:
+ }
+ case DELETE_CONTACT: {
Contact.delete(action.data);
return {
...state,
- contacts: Contact.getByUser(state.currentUser.id),
+ contacts: Contact.getByUser(action.currentUser.id),
};
+ }
default: {
return state;
diff --git a/ComApp/src/App/Store/Reducers/documents.js b/ComApp/src/App/Store/Reducers/documents.js
new file mode 100644
index 0000000..596a15d
--- /dev/null
+++ b/ComApp/src/App/Store/Reducers/documents.js
@@ -0,0 +1,23 @@
+import { INIT_DOCUMENTS } from "../Actions/actionType";
+// Models
+import { Document } from "../../../Database";
+
+const initialState = [];
+
+const reducer = (state = initialState, action) => {
+ switch (action.type) {
+ case INIT_DOCUMENTS: {
+ let docs = Document.getAll(action.directories);
+ return [
+ ...state,
+ docs.filter(item => item.lang === action.lang)
+ ];
+ }
+
+ default: {
+ return state;
+ }
+ }
+};
+
+export default reducer;
diff --git a/ComApp/src/App/Views/ContactDetailsScreen.js b/ComApp/src/App/Views/ContactDetailsScreen.js
index cb94e38..1dd5b40 100644
--- a/ComApp/src/App/Views/ContactDetailsScreen.js
+++ b/ComApp/src/App/Views/ContactDetailsScreen.js
@@ -31,7 +31,7 @@ import { BarCodeScanner } from 'expo-barcode-scanner';
function mapStateToProps(state) {
return {
- contacts: state.app.contacts,
+ contacts: state.contacts.contacts,
currentUser: state.app.currentUser,
};
}
diff --git a/ComApp/src/App/Views/ContactScreen.js b/ComApp/src/App/Views/ContactScreen.js
index c1420ae..c805aef 100644
--- a/ComApp/src/App/Views/ContactScreen.js
+++ b/ComApp/src/App/Views/ContactScreen.js
@@ -27,8 +27,8 @@ import styles from '../../Resources/Styles/ContactStyle';
function mapStateToProps(state) {
return {
- users: state.app.users,
- contacts: state.app.contacts,
+ users: state.users.users,
+ contacts: state.contacts.contacts,
documents: state.app.documents,
currentUser: state.app.currentUser,
};
diff --git a/ComApp/src/App/Views/HomeScreen.js b/ComApp/src/App/Views/HomeScreen.js
index 1dff59f..cefdc8a 100644
--- a/ComApp/src/App/Views/HomeScreen.js
+++ b/ComApp/src/App/Views/HomeScreen.js
@@ -4,6 +4,7 @@ import { View, ImageBackground, TouchableOpacity, Text, Image } from 'react-nati
import commonStyles from '../../Resources/CommonStyles';
// Redux
import { connect } from 'react-redux';
+import { initDocuments } from '../Store/Actions/documents';
// Style
import styles from '../../Resources/Styles/HomeStyle';
// Translations
@@ -18,10 +19,19 @@ function mapStateToProps(state) {
};
}
+const mapDispatchToProps = dispatch => {
+ return {
+ init: (locale, directories) => {
+ dispatch({ type: 'INIT' })
+ dispatch(initDocuments(locale, directories))
+ }
+ };
+};
+
class HomeScreen extends React.Component {
componentDidMount() {
- this.props.dispatch({ type: 'INIT' });
+ this.props.init(this.props.locale.value, this.props.directories);
}
render() {
@@ -52,4 +62,4 @@ class HomeScreen extends React.Component {
}
}
-export default connect(mapStateToProps)(HomeScreen);
\ No newline at end of file
+export default connect(mapStateToProps, mapDispatchToProps)(HomeScreen);
\ No newline at end of file
diff --git a/ComApp/src/App/Views/LoginScreen.js b/ComApp/src/App/Views/LoginScreen.js
index 41f2cb5..929a4ef 100644
--- a/ComApp/src/App/Views/LoginScreen.js
+++ b/ComApp/src/App/Views/LoginScreen.js
@@ -1,6 +1,8 @@
import React from 'react';
import { View, ImageBackground, TextInput, Button, Image, Alert } from 'react-native';
+// Redux
import { connect } from 'react-redux';
+import { initContact } from '../Store/Actions/contacts';
// Common Styles
import commonStyles from '../../Resources/CommonStyles';
// Style
@@ -17,11 +19,23 @@ import SyncController from '../Controllers/SyncController';
function mapStateToProps(state) {
return {
+ app: state.app,
users: state.users.users,
locale: state.locale.locale,
};
}
+const mapDispatchToProps = dispatch => {
+ return {
+ initContact: currentUser => dispatch(initContact(currentUser)),
+ setCurrentUser: user => dispatch({
+ type: 'SET_CURRENT_USER',
+ data: JSON.stringify(user),
+ }),
+ setIsLogged: () => dispatch({ type: 'SET_LOGGED', data: true })
+ };
+};
+
class LoginScreen extends React.Component {
state = {
login: 'v@b.t',
@@ -85,7 +99,13 @@ class LoginScreen extends React.Component {
return;
}
const lastUser = Setting.get('lastUser');
- if (lastUser === false || lastUser === undefined || lastUser.value === user.id.toString()) {
+ // Si on est sur une installation
+ if (lastUser === false || lastUser === undefined) {
+ this.loginAction(user, true);
+ return;
+ }
+ // Si on a deja une install avec une précédente connexion
+ if (lastUser.value === user.id.toString()) {
this.loginAction(user);
} else {
// Si user !== last user && last user not synced
@@ -108,15 +128,13 @@ class LoginScreen extends React.Component {
loginAction(user, forceSync = false) {
this.setState({ login: '', password: '' });
LoginController.login(user);
- this.props.dispatch({
- type: 'SET_CURRENT_USER',
- data: JSON.stringify(user),
- });
- this.props.dispatch({ type: 'SET_LOGGED', data: true });
+ this.props.setCurrentUser(user);
+ this.props.setIsLogged();
+ this.props.initContact(this.props.app.currentUser);
if (forceSync === true) {
- this.props.navigation.navigate('SyncScreen', { isInstalled: true, forceSync: true });
+ this.props.navigation.navigate('SyncScreen', { forceSync: true });
}
}
}
-export default connect(mapStateToProps)(LoginScreen);
\ No newline at end of file
+export default connect(mapStateToProps, mapDispatchToProps)(LoginScreen);
\ No newline at end of file
diff --git a/ComApp/src/App/Views/OnlyVideosScreen.js b/ComApp/src/App/Views/OnlyVideosScreen.js
index 1db6193..19b2ccc 100644
--- a/ComApp/src/App/Views/OnlyVideosScreen.js
+++ b/ComApp/src/App/Views/OnlyVideosScreen.js
@@ -14,7 +14,7 @@ import styles from '../../Resources/Styles/OnlyVideosStyle';
function mapStateToProps(state) {
return {
- documents: state.app.documents,
+ documents: state.documents,
};
}
diff --git a/ComApp/src/App/Views/SyncScreen.js b/ComApp/src/App/Views/SyncScreen.js
index eae4805..cfbbe90 100644
--- a/ComApp/src/App/Views/SyncScreen.js
+++ b/ComApp/src/App/Views/SyncScreen.js
@@ -2,6 +2,7 @@ import React from 'react';
import { View, Button, Alert, Text } from 'react-native';
// Redux
import { connect } from 'react-redux';
+import { initDocuments } from '../Store/Actions/documents';
// Style
import styles from '../../Resources/Styles/SyncStyle';
// Translations
@@ -20,9 +21,28 @@ function mapStateToProps(state) {
documents: state.app.documents,
syncVersion: state.app.syncVersion,
currentUser: state.app.currentUser,
+ directories: state.app.directories,
+ locale: state.locale.locale,
};
}
+const mapDispatchToProps = dispatch => {
+ return {
+ init: (locale, directories) => {
+ dispatch({ type: 'INIT' })
+ dispatch(initDocuments(locale, directories))
+ },
+ updateVersion: version => dispatch({
+ type: 'UPDATE_VERSION',
+ data: version,
+ }),
+ updateShowIsActive: value => dispatch({
+ type: 'UPDATE_SHOW_IS_ACTIVE',
+ data: value,
+ })
+ };
+};
+
class SyncScreen extends React.Component {
state = {
progress: 0,
@@ -86,14 +106,8 @@ class SyncScreen extends React.Component {
i18n.t('error.error_has_occurred')
);
});
- this.props.dispatch({
- type: 'UPDATE_VERSION',
- data: resVersion.version,
- });
- this.props.dispatch({
- type: 'UPDATE_SHOW_IS_ACTIVE',
- data: resVersion.ShowIsActive,
- });
+ this.props.updateVersion(resVersion.version);
+ this.props.updateShowIsActive(resVersion.ShowIsActive);
this.setState({ newApp: resVersion.newApp });
// getUsers
this.setState({ txtStep: i18n.t('sync_s.updating_users') + '...' });
@@ -280,7 +294,7 @@ class SyncScreen extends React.Component {
}
finishSync(version) {
- this.props.dispatch({ type: 'INIT' });
+ this.props.init(this.props.locale.value, this.props.directories);
SyncController.updateVersion(version);
this.setState({ txtStep: i18n.t('sync_s.update_completed') + '.', processing: false });
if (this.state.newApp === true) {
@@ -304,4 +318,4 @@ class SyncScreen extends React.Component {
}
-export default connect(mapStateToProps)(SyncScreen);
\ No newline at end of file
+export default connect(mapStateToProps, mapDispatchToProps)(SyncScreen);
\ No newline at end of file
diff --git a/ComApp/src/Locales/fr.json b/ComApp/src/Locales/fr.json
index afc8fd6..cac7764 100644
--- a/ComApp/src/Locales/fr.json
+++ b/ComApp/src/Locales/fr.json
@@ -54,6 +54,7 @@
"no_result": "Aucun résultat"
},
"sync_s": {
+ "back_home": "Retour à l'accueil",
"download": "Téléchargement",
"update_completed": "Mise à jour effectuée",
"updating_docs": "Mise à jour des documents",