diff --git a/config/lang/en.json b/config/lang/en.json index 4953f345..61f78c5c 100644 --- a/config/lang/en.json +++ b/config/lang/en.json @@ -97,6 +97,7 @@ "sortByGenres": "By genres", "sortByDeveloper": "By developer", "sortByPublisher": "By publisher", + "noInternet": "Internet connection has been lost. Some features, including fetching games data on IGDB, will be disabled.", "genresNames": { "Point-and-click": "Point-and-click", "Fighting": "Fighting", diff --git a/config/lang/fr.json b/config/lang/fr.json index e7745115..a2124003 100644 --- a/config/lang/fr.json +++ b/config/lang/fr.json @@ -97,6 +97,7 @@ "sortByGenres": "Par genres", "sortByDeveloper": "Par développeur", "sortByPublisher": "Par éditeur", + "noInternet": "La connexion internet a été perdue. Certains fonctionnalités, dont la récupération de données sur IGDB, seront désactivées.", "genresNames": { "Point-and-click": "Point-and-click", "Fighting": "Combat", diff --git a/sources/client/app/AppState.ts b/sources/client/app/AppState.ts index 7361299c..01ec9563 100644 --- a/sources/client/app/AppState.ts +++ b/sources/client/app/AppState.ts @@ -21,11 +21,12 @@ import { settingsModalVisible, timePlayedEditionModalVisible } from './reducers/modals'; -import { modulesConfig, settings } from './reducers/settings'; +import { internetConnection, modulesConfig, settings } from './reducers/settings'; export interface AppState { settings: any; modulesConfig: any; + internetConnection: boolean; potentialGames: GamesCollection; playableGames: GamesCollection; selectedGame: PlayableGame; @@ -44,6 +45,7 @@ export interface AppState { export const vitrineStore: Store = createStore(combineReducers({ settings, modulesConfig, + internetConnection, potentialGames, playableGames, selectedGame, @@ -60,6 +62,7 @@ export const vitrineStore: Store = createStore(combineReducers({ }), { settings: null, modulesConfig: null, + internetConnection: true, potentialGames: new GamesCollection(), playableGames: new GamesCollection(), selectedGame: null, diff --git a/sources/client/app/actions/actionsTypes.ts b/sources/client/app/actions/actionsTypes.ts index b480c138..8a42e4f6 100644 --- a/sources/client/app/actions/actionsTypes.ts +++ b/sources/client/app/actions/actionsTypes.ts @@ -6,6 +6,7 @@ export interface Action { export enum ActionType { UPDATE_SETTINGS = 'UPDATE_SETTINGS', UPDATE_MODULES_CONFIG = 'UPDATE_MODULES_CONFIG', + SET_INTERNET_CONNECTION = 'INTERNET_CONNECTION', REFRESH_GAMES = 'REFRESH_GAMES', ADD_POTENTIAL_GAMES = 'ADD_POTENTIAL_GAMES', diff --git a/sources/client/app/actions/settings.ts b/sources/client/app/actions/settings.ts index 7c6107e1..c4a2347c 100644 --- a/sources/client/app/actions/settings.ts +++ b/sources/client/app/actions/settings.ts @@ -17,3 +17,12 @@ export function updateModulesConfig(modulesConfig: any): Action { } }; } + +export function setInternetConnection(internetConnection: boolean): Action { + return { + type: ActionType.SET_INTERNET_CONNECTION, + payload: { + internetConnection + } + }; +} diff --git a/sources/client/app/components/App.tsx b/sources/client/app/components/App.tsx index e47f43c6..e8bf6363 100644 --- a/sources/client/app/components/App.tsx +++ b/sources/client/app/components/App.tsx @@ -6,6 +6,7 @@ import * as React from 'react'; import { getEnvFolder } from '../../../models/env'; import { Vitrine } from '../containers/Vitrine'; +import { notify } from '../helpers'; import { localizer } from '../Localizer'; import { serverListener } from '../ServerListener'; import { ErrorsWrapper } from './ErrorsWrapper'; @@ -14,6 +15,7 @@ interface Props { settings: any; updateSettings: (settings: any) => void; updateModulesConfig: (modulesConfig: any) => void; + setInternetConnection: (internetConnection: boolean) => void; } interface State { @@ -50,6 +52,14 @@ export class App extends React.Component { }); } + private handleInternetConnection() { + this.props.setInternetConnection(window.navigator.onLine); + + if (!window.navigator.onLine) { + notify(localizer.f('noInternet'), true, true); + } + } + public componentDidMount() { serverListener.listen('init-settings', (settings: any, modulesConfig: any) => { this.props.updateSettings(settings); @@ -60,9 +70,18 @@ export class App extends React.Component { serverListener.send('ready'); }); }); + serverListener.listen('set-internet-connection', this.handleInternetConnection.bind(this)); + window.addEventListener('online', this.handleInternetConnection.bind(this)); + window.addEventListener('offline', this.handleInternetConnection.bind(this)); + serverListener.send('settings-asked'); } + public componentWillUnmount() { + window.removeEventListener('online', this.handleInternetConnection.bind(this)); + window.removeEventListener('offline', this.handleInternetConnection.bind(this)); + } + public render(): JSX.Element { return (this.state.settingsReceived) ? ( diff --git a/sources/client/app/components/GameAddModal.tsx b/sources/client/app/components/GameAddModal.tsx index 059eed1b..ee58a80b 100644 --- a/sources/client/app/components/GameAddModal.tsx +++ b/sources/client/app/components/GameAddModal.tsx @@ -20,6 +20,7 @@ import { faFolderOpen } from '@fortawesome/fontawesome-free-solid'; import { PlayableGame } from '../../../models/PlayableGame'; interface Props { + internetConnection: boolean; selectedGame: PlayableGame; potentialGameToAdd: PotentialGame; gameToEdit: PlayableGame; @@ -515,7 +516,7 @@ export class GameAddModal extends VitrineComponent {