Skip to content

Commit

Permalink
support for hiding unused game
Browse files Browse the repository at this point in the history
  • Loading branch information
TanninOne committed Oct 13, 2016
1 parent 92adf77 commit 97c9a42
Show file tree
Hide file tree
Showing 12 changed files with 126 additions and 36 deletions.
6 changes: 6 additions & 0 deletions src/extensions/gamemode_management/actions/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ export const addDiscoveredTool =
(gameId: string, toolId: string, result: IToolDiscoveryResult) => {
return { gameId, toolId, result }; });

/**
* hide or unhide a game
*/
export const setGameHidden = createAction('SET_GAME_HIDDEN',
(gameId: string, hidden: boolean) => { return { gameId, hidden }; });

/**
* add a search path (path that is searched for game installations)
*/
Expand Down
24 changes: 21 additions & 3 deletions src/extensions/gamemode_management/reducers/settings.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { IReducerSpec } from '../../../types/IExtensionContext';
import { addDiscoveredGame, addDiscoveredTool, setGameMode } from '../actions/settings';
import { addSearchPath, removeSearchPath } from '../actions/settings';
import { addSearchPath, removeSearchPath, setGameHidden } from '../actions/settings';
import update = require('react-addons-update');

/**
Expand All @@ -15,8 +15,7 @@ export const settingsReducer: IReducerSpec = {
// don't replace previously discovered tools as the settings
// there may also be user configuration
if (state.discovered[payload.id] !== undefined) {
payload.result.tools = Object.assign({},
payload.result.tools, state.discovered[payload.id].tools);
payload.result = Object.assign({}, state.discovered[payload.id], payload.result);
}

return update(state, {
Expand All @@ -36,6 +35,25 @@ export const settingsReducer: IReducerSpec = {
},
});
},
[setGameHidden]: (state, payload) => {
if (!(payload.gameId in state.discovered)) {
return update(state, {
discovered: {
[payload.gameId]: { $set: {
hidden: payload.hidden,
} },
},
});
} else {
return update(state, {
discovered: {
[payload.gameId]: {
hidden: { $set: payload.hidden },
},
},
});
}
},
[addSearchPath]: (state, payload) => {
if (state.searchPaths === undefined) {
state = update(state, {
Expand Down
5 changes: 3 additions & 2 deletions src/extensions/gamemode_management/types/IStateEx.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { IState } from '../../../types/IState';

export interface IDiscoveryResult {
path: string;
modPath: string;
path?: string;
modPath?: string;
hidden?: boolean;
tools?: {
[id: string]: IToolDiscoveryResult;
};
Expand Down
3 changes: 1 addition & 2 deletions src/extensions/gamemode_management/util/discovery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ export function quickDiscovery(knownGames: IGame[], onDiscoveredGame: Discovered
path: gamePath,
modPath: game.queryModPath(),
tools: {},
hidden: false,
});
} else {
log('debug', 'game not found', game.id);
Expand All @@ -77,7 +78,6 @@ export function quickDiscovery(knownGames: IGame[], onDiscoveredGame: Discovered
onDiscoveredGame(game.id, {
path: resolvedPath,
modPath: game.queryModPath(),
tools: {},
});
return null;
}).catch((err) => {
Expand Down Expand Up @@ -183,7 +183,6 @@ function testGameDirValid(game: IGame, testPath: string, onDiscoveredGame: Disco
onDiscoveredGame(game.id, {
path: testPath,
modPath: game.queryModPath(),
tools: {},
});
}).catch(() => {
log('info', 'invalid', { game: game.id, path: testPath });
Expand Down
54 changes: 40 additions & 14 deletions src/extensions/gamemode_management/views/GamePicker.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { IComponentContext } from '../../../types/IComponentContext';
import { IGame } from '../../../types/IGame';
import { ComponentEx, connect, translate } from '../../../util/ComponentEx';
import getAttr from '../../../util/getAttr';
import { Button } from '../../../views/TooltipControls';

import { setGameMode } from '../actions/settings';
import { setGameHidden, setGameMode } from '../actions/settings';
import { IDiscoveryResult, IDiscoveryState, IGameStored, IStateEx } from '../types/IStateEx';

import GameThumbnail from './GameThumbnail';

import * as React from 'react';
import { Button, ProgressBar } from 'react-bootstrap';
import { ProgressBar } from 'react-bootstrap';
import { Fixed, Flex, Layout } from 'react-layout-pane';

import { log } from '../../../util/log';
Expand All @@ -25,14 +27,19 @@ interface IConnectedProps {

interface IActionProps {
onManage: (gameId: string) => void;
onHide: (gameId: string, hidden: boolean) => void;
}

interface IState {
showHidden: boolean;
}

/**
* picker/configuration for game modes
*
* @class GamePicker
*/
class GamePicker extends ComponentEx<IConnectedProps & IActionProps, {}> {
class GamePicker extends ComponentEx<IConnectedProps & IActionProps, IState> {

public static contextTypes: React.ValidationMap<any> = {
api: React.PropTypes.object.isRequired,
Expand All @@ -44,18 +51,26 @@ class GamePicker extends ComponentEx<IConnectedProps & IActionProps, {}> {
super(props);

this.state = {
discovery: {
percent: 0,
label: '',
},
showHidden: false,
};
}

public render(): JSX.Element {
let { t } = this.props;
const { discovery } = this.props;
const { t, discovery } = this.props;
const { showHidden } = this.state;
return (
<Layout type='column'>
<Fixed>
<div>
<Button
id='show-hidden-games'
tooltip={ t('Show / Hide Hidden games') }
onClick={ this.toggleHidden }
>
<Icon name={ showHidden ? 'eye-slash' : 'eye' }/>
</Button>
</div>
</Fixed>
<Flex style={{ height: '100%', overflowY: 'auto' }}>
<span style={{ display: 'table' }}>
<h3>{ t('Discovered') }</h3>
Expand All @@ -74,11 +89,13 @@ class GamePicker extends ComponentEx<IConnectedProps & IActionProps, {}> {
min={ 0 }
max={ 100 }
now={ discovery.progress }
label={ `${discovery.directory}` }
label={ discovery.directory }
/>
</Flex>
<Fixed>
<Button
id='start-discovery'
tooltip={ discovery.running ? t('Stop search') : t('Search for games') }
onClick={ discovery.running ? this.stopDiscovery : this.startDiscovery }
>
<Icon name={ discovery.running ? 'stop' : 'search' } />
Expand All @@ -90,6 +107,10 @@ class GamePicker extends ComponentEx<IConnectedProps & IActionProps, {}> {
);
}

private toggleHidden = () => {
this.setState(update(this.state, { showHidden: { $set: !this.state.showHidden } }));
}

private startDiscovery = () => {
this.context.api.events.emit('start-discovery', (percent: number, label: string) => {
log('info', 'progress', { percent, label });
Expand All @@ -107,18 +128,22 @@ class GamePicker extends ComponentEx<IConnectedProps & IActionProps, {}> {
}

private renderGames = (discovered: boolean) => {
let { onManage, knownGames, discoveredGames, gameMode } = this.props;
const { onManage, onHide, knownGames, discoveredGames, gameMode } = this.props;
const { showHidden } = this.state;

const games = knownGames.filter((game: IGame) => {
return (game.id in discoveredGames) === discovered;
const games: IGameStored[] = knownGames.filter((game: IGame) => {
return (((getAttr(discoveredGames, game.id, { path: '' }).path !== '') === discovered)
&& (showHidden || !getAttr(discoveredGames, game.id, { hidden: false }).hidden));
});

return games.map((game) => {
return games.map((game: IGameStored) => {
return (
<GameThumbnail
key={game.id}
game={game}
onManage={discovered ? onManage : undefined}
hidden={getAttr(discoveredGames, game.id, { hidden: false }).hidden}
onHide={onHide}
active={game.id === gameMode}
/>
);
Expand All @@ -138,6 +163,7 @@ function mapStateToProps(state: IStateEx): IConnectedProps {
function mapDispatchToProps(dispatch): IActionProps {
return {
onManage: (gameId: string) => dispatch(setGameMode(gameId)),
onHide: (gameId: string, hidden: boolean) => dispatch(setGameHidden(gameId, hidden)),
};
}

Expand Down
53 changes: 44 additions & 9 deletions src/extensions/gamemode_management/views/GameThumbnail.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
import * as React from 'react';
import { Button, Panel } from 'react-bootstrap';
import { ComponentEx, translate } from '../../../util/ComponentEx';
import { Button } from '../../../views/TooltipControls';

import { IGameStored } from '../types/IStateEx';

import { ComponentEx, translate } from '../../../util/ComponentEx';

import * as path from 'path';
import * as React from 'react';
import { Panel } from 'react-bootstrap';

import Icon = require('react-fontawesome');

interface IProps {
game: IGameStored;
hidden: boolean;
onManage?: (id: string) => void;
onHide: (id: string, hidden: boolean) => void;
active: boolean;
}

Expand All @@ -36,16 +40,47 @@ class GameThumbnail extends ComponentEx<IProps, {}> {
<div className='game-thumbnail-bottom'>
<h3>{ t(game.name) }</h3>
{ this.renderManageButton() }
{ this.renderHideButton() }
</div>
</Panel>
);
}

private renderManageButton = () => {
const { t, active } = this.props;
return (this.clickHandler !== undefined && !active)
? <Button onClick={ this.clickHandler }>{ t('Manage') }</Button>
: null;
private renderManageButton() {
const { t, active, game } = this.props;
let buttonId = `manage-${game.id}`;

if (this.clickHandler === undefined || active) {
return null;
}

return (
<Button
id={buttonId}
tooltip={t('Manage')}
onClick={this.clickHandler}
>
<Icon name='asterisk' />
</Button>
);
}

private toggleHidden = () => {
const { game, hidden, onHide } = this.props;
onHide(game.id, !hidden);
}

private renderHideButton() {
const { t, hidden, game } = this.props;
return (
<Button
id={`showhide-${game.id}`}
tooltip={ hidden ? t('Show') : t('Hide') }
onClick={ this.toggleHidden }
>
{ hidden ? <Icon name='eye' /> : <Icon name='eye-slash' /> }
</Button>
);
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/extensions/mod_management/modActivation.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import getAttr from '../../util/getAttr';
import { log } from '../../util/log';

import { IProfileMod } from '../profile_management/types/IProfile';

import { IMod } from './types/IMod';
import { IModActivator } from './types/IModActivator';
import getAttr from './util/getAttr';

import { log } from '../../util/log';

import * as Promise from 'bluebird';

Expand Down
2 changes: 1 addition & 1 deletion src/extensions/mod_management/views/HeaderCell.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { SortDirection } from '../../../types/SortDirection';
import getAttr from '../../../util/getAttr';
import SortIndicator from '../../../views/SortIndicator';

import { IAttributeState } from '../types/IAttributeState';
import { IModAttribute } from '../types/IModAttribute';
import getAttr from '../util/getAttr';

import * as React from 'react';

Expand Down
2 changes: 1 addition & 1 deletion src/extensions/mod_management/views/ModList.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { SortDirection } from '../../../types/SortDirection';
import { ComponentEx, connect, extend, translate } from '../../../util/ComponentEx';
import getAttr from '../../../util/getAttr';

import { IGameModeSettings } from '../../gamemode_management/types/IStateEx';

Expand All @@ -13,7 +14,6 @@ import { IMod } from '../types/IMod';
import { IModAttribute } from '../types/IModAttribute';
import { IStateMods } from '../types/IStateMods';
import { IStateModSettings } from '../types/IStateSettings';
import getAttr from '../util/getAttr';

import AttributeToggle from './AttributeToggle';
import HeaderCell from './HeaderCell';
Expand Down
3 changes: 2 additions & 1 deletion src/extensions/mod_management/views/ModRow.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import getAttr from '../../../util/getAttr';

import { IProfileMod } from '../../profile_management/types/IProfile';

import { IMod } from '../types/IMod';
import { IModAttribute } from '../types/IModAttribute';
import getAttr from '../util/getAttr';

import * as React from 'react';
import { Checkbox } from 'react-bootstrap';
Expand Down
4 changes: 4 additions & 0 deletions src/extensions/welcome_screen/WelcomeScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ class WelcomeScreen extends React.Component<IWelcomeScreenProps, IWelcomeScreenS
private renderSupportedToolsIcons = (game: IGame): JSX.Element => {
let knownTools: ISupportedTool[] = game.supportedTools;

if (knownTools === null) {
return null;
}

return (
<div>
{ knownTools.map((tool) => this.renderSupportedTool(game, tool)) }
Expand Down
File renamed without changes.

0 comments on commit 97c9a42

Please sign in to comment.