Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Vitrine to work without Internet #62

Merged
merged 2 commits into from
May 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions config/lang/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
5 changes: 4 additions & 1 deletion sources/client/app/AppState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<PotentialGame>;
playableGames: GamesCollection<PlayableGame>;
selectedGame: PlayableGame;
Expand All @@ -44,6 +45,7 @@ export interface AppState {
export const vitrineStore: Store<AppState> = createStore(combineReducers({
settings,
modulesConfig,
internetConnection,
potentialGames,
playableGames,
selectedGame,
Expand All @@ -60,6 +62,7 @@ export const vitrineStore: Store<AppState> = createStore(combineReducers({
}), {
settings: null,
modulesConfig: null,
internetConnection: true,
potentialGames: new GamesCollection<PotentialGame>(),
playableGames: new GamesCollection<PlayableGame>(),
selectedGame: null,
Expand Down
1 change: 1 addition & 0 deletions sources/client/app/actions/actionsTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
9 changes: 9 additions & 0 deletions sources/client/app/actions/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,12 @@ export function updateModulesConfig(modulesConfig: any): Action {
}
};
}

export function setInternetConnection(internetConnection: boolean): Action {
return {
type: ActionType.SET_INTERNET_CONNECTION,
payload: {
internetConnection
}
};
}
19 changes: 19 additions & 0 deletions sources/client/app/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -14,6 +15,7 @@ interface Props {
settings: any;
updateSettings: (settings: any) => void;
updateModulesConfig: (modulesConfig: any) => void;
setInternetConnection: (internetConnection: boolean) => void;
}

interface State {
Expand Down Expand Up @@ -50,6 +52,14 @@ export class App extends React.Component<Props, State> {
});
}

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);
Expand All @@ -60,9 +70,18 @@ export class App extends React.Component<Props, State> {
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) ? (
<ErrorsWrapper>
Expand Down
3 changes: 2 additions & 1 deletion sources/client/app/components/GameAddModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -515,7 +516,7 @@ export class GameAddModal extends VitrineComponent<Props, State> {
<Modal.Actions>
<Button
secondary={true}
disabled={!this.state.gameData.name}
disabled={!this.state.gameData.name || !this.props.internetConnection}
loading={this.state.igdbButtonLoading}
onClick={this.searchIgdbButton}
>
Expand Down
13 changes: 8 additions & 5 deletions sources/client/app/containers/App.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
import { connect, Dispatch } from 'react-redux';

import { Action } from '../actions/actionsTypes';
import { updateModulesConfig, updateSettings } from '../actions/settings';
import { setInternetConnection, updateModulesConfig, updateSettings } from '../actions/settings';
import { AppState } from '../AppState';
import { App as VisualApp } from '../components/App';
import { App as AppComponent } from '../components/App';

const mapStateToProps = (state: AppState) => ({
settings: state.settings
});

const mapDispatchToProps = (dispatch: Dispatch<Action>) => ({
updateSettings: (settings: any) => {
updateSettings(settings: any) {
dispatch(updateSettings(settings));
},
updateModulesConfig: (modulesConfig: any) => {
updateModulesConfig(modulesConfig: any) {
dispatch(updateModulesConfig(modulesConfig));
},
setInternetConnection(internetConnection: boolean) {
dispatch(setInternetConnection(internetConnection));
}
});

export const App = connect(mapStateToProps, mapDispatchToProps)(VisualApp);
export const App = connect(mapStateToProps, mapDispatchToProps)(AppComponent);
12 changes: 6 additions & 6 deletions sources/client/app/containers/ContextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,25 @@ import { Action } from '../actions/actionsTypes';
import { launchGame, setGameToEdit } from '../actions/games';
import { openGameAddModal, openTimePlayedEditionModal } from '../actions/modals';
import { AppState } from '../AppState';
import { ContextMenu as VisualContextMenu } from '../components/ContextMenu';
import { ContextMenu as ContextMenuComponent } from '../components/ContextMenu';

const mapStateToProps = (state: AppState) => ({
playableGames: state.playableGames
});

const mapDispatchToProps = (dispatch: Dispatch<Action>) => ({
launchGame: (launchedGame: PlayableGame) => {
launchGame(launchedGame: PlayableGame) {
dispatch(launchGame(launchedGame));
},
setGameToEdit: (gameToEdit: PlayableGame) => {
setGameToEdit(gameToEdit: PlayableGame) {
dispatch(setGameToEdit(gameToEdit));
},
openGameAddModal: () => {
openGameAddModal() {
dispatch(openGameAddModal());
},
openTimePlayedEditionModal: () => {
openTimePlayedEditionModal() {
dispatch(openTimePlayedEditionModal());
}
});

export const ContextMenu = connect(mapStateToProps, mapDispatchToProps)(VisualContextMenu);
export const ContextMenu = connect(mapStateToProps, mapDispatchToProps)(ContextMenuComponent);
6 changes: 3 additions & 3 deletions sources/client/app/containers/EmulatorSettingsRow.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { connect, Dispatch } from 'react-redux';
import { connect } from 'react-redux';

import { AppState } from '../AppState';
import { EmulatorSettingsRow as VisualEmulatorSettingsRow } from '../components/EmulatorSettingsRow';
import { EmulatorSettingsRow as EmulatorSettingsRowComponent } from '../components/EmulatorSettingsRow';

const mapStateToProps = (state: AppState) => ({
platforms: state.modulesConfig.emulated.platforms,
});

const mapDispatchToProps = () => ({});

export const EmulatorSettingsRow = connect(mapStateToProps, mapDispatchToProps)(VisualEmulatorSettingsRow);
export const EmulatorSettingsRow = connect(mapStateToProps, mapDispatchToProps)(EmulatorSettingsRowComponent);
23 changes: 12 additions & 11 deletions sources/client/app/containers/GameAddModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ import { PlayableGame } from '../../../models/PlayableGame';
import { PotentialGame } from '../../../models/PotentialGame';
import { Action } from '../actions/actionsTypes';
import { addPlayableGames, editPlayableGame, selectGame, setGameToEdit, setPotentialGameToAdd } from '../actions/games';
import { closeGameAddModal, closeIgdbResearchModal, closeTimePlayedEditionModal, openIgdbResearchModal } from '../actions/modals';
import { closeGameAddModal, closeIgdbResearchModal, closeTimePlayedEditionModal } from '../actions/modals';
import { AppState } from '../AppState';
import { GameAddModal as VisualGameAddModal } from '../components/GameAddModal';
import { GameAddModal as GameAddModalComponent } from '../components/GameAddModal';

const mapStateToProps = (state: AppState) => ({
internetConnection: state.internetConnection,
selectedGame: state.selectedGame,
potentialGameToAdd: state.potentialGameToAdd,
gameToEdit: state.gameToEdit,
Expand All @@ -17,30 +18,30 @@ const mapStateToProps = (state: AppState) => ({
});

const mapDispatchToProps = (dispatch: Dispatch<Action>) => ({
addPlayableGames: (playableGames: PlayableGame[]) => {
addPlayableGames(playableGames: PlayableGame[]) {
dispatch(addPlayableGames(playableGames));
},
editPlayableGame: (playableGame: PlayableGame) => {
editPlayableGame(playableGame: PlayableGame) {
dispatch(editPlayableGame(playableGame));
},
setPotentialGameToAdd: (potentialGame: PotentialGame) => {
setPotentialGameToAdd(potentialGame: PotentialGame) {
dispatch(setPotentialGameToAdd(potentialGame));
},
setGameToEdit: (playableGame: PlayableGame) => {
setGameToEdit(playableGame: PlayableGame) {
dispatch(setGameToEdit(playableGame));
},
selectGame: (selectedGame: PlayableGame) => {
selectGame(selectedGame: PlayableGame) {
dispatch(selectGame(selectedGame));
},
closeGameAddModal: () => {
closeGameAddModal() {
dispatch(closeGameAddModal());
},
closeIgdbResearchModal: () => {
closeIgdbResearchModal() {
dispatch(closeIgdbResearchModal());
},
closeTimePlayedEditionModal: () => {
closeTimePlayedEditionModal() {
dispatch(closeTimePlayedEditionModal());
}
});

export const GameAddModal = connect(mapStateToProps, mapDispatchToProps)(VisualGameAddModal);
export const GameAddModal = connect(mapStateToProps, mapDispatchToProps)(GameAddModalComponent);
4 changes: 2 additions & 2 deletions sources/client/app/containers/GameContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { connect } from 'react-redux';

import { AppState } from '../AppState';
import { GameContainer as VisualGameContainer } from '../components/GameContainer';
import { GameContainer as GameContainerComponent } from '../components/GameContainer';

const mapStateToProps = (state: AppState) => ({
selectedGame: state.selectedGame
});

const mapDispatchToProps = () => ({});

export const GameContainer = connect(mapStateToProps, mapDispatchToProps)(VisualGameContainer);
export const GameContainer = connect(mapStateToProps, mapDispatchToProps)(GameContainerComponent);
8 changes: 4 additions & 4 deletions sources/client/app/containers/IgdbResearchModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@ import { connect, Dispatch } from 'react-redux';
import { Action } from '../actions/actionsTypes';
import { closeIgdbResearchModal, openIgdbResearchModal } from '../actions/modals';
import { AppState } from '../AppState';
import { IgdbResearchModal as VisualIgdbResearchModal } from '../components/IgdbResearchModal';
import { IgdbResearchModal as IgdbResearchModalComponent } from '../components/IgdbResearchModal';

const mapStateToProps = (state: AppState) => ({
visible: state.igdbResearchModalVisible
});

const mapDispatchToProps = (dispatch: Dispatch<Action>) => ({
openIgdbResearchModal: () => {
openIgdbResearchModal() {
dispatch(openIgdbResearchModal());
},
closeIgdbResearchModal: () => {
closeIgdbResearchModal() {
dispatch(closeIgdbResearchModal());
}
});

export const IgdbResearchModal = connect(mapStateToProps, mapDispatchToProps)(VisualIgdbResearchModal);
export const IgdbResearchModal = connect(mapStateToProps, mapDispatchToProps)(IgdbResearchModalComponent);
10 changes: 5 additions & 5 deletions sources/client/app/containers/PotentialGamesAddModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,23 @@ import { Action } from '../actions/actionsTypes';
import { setPotentialGameToAdd } from '../actions/games';
import { closePotentialGamesAddModal, openGameAddModal } from '../actions/modals';
import { AppState } from '../AppState';
import { PotentialGamesAddModal as VisualPotentialGamesAddModal } from '../components/PotentialGamesAddModal';
import { PotentialGamesAddModal as PotentialGamesAddModalComponent } from '../components/PotentialGamesAddModal';

const mapStateToProps = (state: AppState) => ({
potentialGames: state.potentialGames,
visible: state.potentialGamesAddModalVisible
});

const mapDispatchToProps = (dispatch: Dispatch<Action>) => ({
setPotentialGameToAdd: (potentialGame: PotentialGame) => {
setPotentialGameToAdd(potentialGame: PotentialGame) {
dispatch(setPotentialGameToAdd(potentialGame));
},
openGameAddModal: () => {
openGameAddModal() {
dispatch(openGameAddModal());
},
closePotentialGamesAddModal: () => {
closePotentialGamesAddModal() {
dispatch(closePotentialGamesAddModal());
}
});

export const PotentialGamesAddModal = connect(mapStateToProps, mapDispatchToProps)(VisualPotentialGamesAddModal);
export const PotentialGamesAddModal = connect(mapStateToProps, mapDispatchToProps)(PotentialGamesAddModalComponent);
8 changes: 4 additions & 4 deletions sources/client/app/containers/SettingsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Action } from '../actions/actionsTypes';
import { closeSettingsModal } from '../actions/modals';
import { updateSettings } from '../actions/settings';
import { AppState } from '../AppState';
import { SettingsModal as VisualSettingsModal } from '../components/SettingsModal';
import { SettingsModal as SettingsModalComponent } from '../components/SettingsModal';

const mapStateToProps = (state: AppState) => ({
settings: state.settings,
Expand All @@ -13,12 +13,12 @@ const mapStateToProps = (state: AppState) => ({
});

const mapDispatchToProps = (dispatch: Dispatch<Action>) => ({
updateSettings: (settings: any) => {
updateSettings(settings: any) {
dispatch(updateSettings(settings));
},
closeSettingsModal: () => {
closeSettingsModal() {
dispatch(closeSettingsModal());
}
});

export const SettingsModal = connect(mapStateToProps, mapDispatchToProps)(VisualSettingsModal);
export const SettingsModal = connect(mapStateToProps, mapDispatchToProps)(SettingsModalComponent);
Loading