Skip to content
This repository has been archived by the owner on Jun 6, 2022. It is now read-only.

Commit

Permalink
Fixing a number of bugs related to importing
Browse files Browse the repository at this point in the history
- Grids in import list will now be the correct size
- Fixed issue where previously imported games were not idenfied
correctly
- Imported games no longer appear in import list, resulting in less
duplicate imports
  - Games will still appear after the first import
  - Duplicate games can still be added after first import
- Fixed a bug where grid images would be deleted during import of they
already existing from a previous import
- Added additional error logging around importing
  • Loading branch information
aranel616 committed Jan 8, 2021
1 parent 2633ad0 commit 6222596
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 36 deletions.
5 changes: 3 additions & 2 deletions .babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"presets": ["@babel/preset-env", "@babel/preset-react"],
"plugins": [
["@babel/plugin-proposal-decorators", { "decoratorsBeforeExport": false }],
["@babel/plugin-proposal-class-properties", { "loose": true }]
["@babel/plugin-proposal-class-properties", { "loose": true }],
"@babel/plugin-transform-runtime"
]
}
}
5 changes: 3 additions & 2 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@
"react/jsx-indent": ["error", 2],
"class-methods-use-this": ["off"],
"no-underscore-dangle": ["off"],
"no-param-reassign": ["error", { "props": false }],
"no-param-reassign": ["off"],
"react/forbid-prop-types": ["off"],
"jsx-a11y/click-events-have-key-events": ["off"],
"jsx-a11y/no-static-element-interactions": ["off"],
"linebreak-style": ["off"]
"linebreak-style": ["off"],
"arrow-body-style": ["off"]
}
}
11 changes: 11 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
"@babel/core": "^7.12.10",
"@babel/plugin-proposal-class-properties": "^7.12.1",
"@babel/plugin-proposal-decorators": "^7.12.12",
"@babel/plugin-transform-runtime": "^7.12.10",
"@babel/preset-env": "^7.12.11",
"@babel/preset-react": "^7.12.10",
"babel-loader": "^8.2.2",
Expand Down
10 changes: 7 additions & 3 deletions src/js/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ const { remote } = electron;
const log = window.require('electron-log');
log.catchErrors({ showDialog: true });


window.Steam = Steam;

class App extends React.Component {
Expand Down Expand Up @@ -84,7 +83,10 @@ class App extends React.Component {
const navWidth = 48;
const { showBack, isMaximized, redirectTo } = this.state;

const navigationTopNodes = [<SplitViewCommand key="0" label="Library" icon="Library" onClick={() => this.handleNavRedirect('/')} />, <SplitViewCommand key="1" label="Import Games" icon="ImportAll" onClick={() => this.handleNavRedirect('/import')} />];
const navigationTopNodes = [
<SplitViewCommand key="0" label="Library" icon="Library" onClick={() => this.handleNavRedirect('/')} />,
<SplitViewCommand key="1" label="Import Games" icon="ImportAll" onClick={() => this.handleNavRedirect('/import')} />,
];

let backBtn;
let titleWidth = '100%';
Expand All @@ -109,7 +111,7 @@ class App extends React.Component {
}}
size={22}
>
Back
Back
</IconButton>
</Link>
);
Expand Down Expand Up @@ -181,10 +183,12 @@ class App extends React.Component {
<Route exact path="/import" component={Import} />
<Route exact path="/game" component={Game} />
<Route exact path="/search" component={Search} />

</div>
</NavigationView>
</div>
</Router>

<ToastHandler />
</UWPThemeProvider>
);
Expand Down
26 changes: 15 additions & 11 deletions src/js/Components/toastHandler.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,21 @@ class ToastHandler extends React.Component {

render() {
const { toasts } = this.state;
return toasts.slice(0).map((x, i) => (
<Toast
key={i}
defaultShow={x.show}
logoNode={<Icon>{x.toast.logoNode}</Icon>}
title={x.toast.title}
showCloseIcon
>
{x.toast.contents}
</Toast>
));
return (
<>
{toasts.slice(0).map((x, i) => (
<Toast
key={i}
defaultShow={x.show}
logoNode={<Icon>{x.toast.logoNode}</Icon>}
title={x.toast.title}
showCloseIcon
>
{x.toast.contents}
</Toast>
))}
</>
);
}
}

Expand Down
67 changes: 53 additions & 14 deletions src/js/Import.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ class Import extends React.Component {
};
}

componentDidMount() {
async componentDidMount() {
const nonSteamGames = await Steam.getNonSteamGames();

Promise.all(this.platforms.map((platform) => platform.class.isInstalled()))
.then((values) => {
// Set .installed
Expand All @@ -59,7 +61,18 @@ class Import extends React.Component {
const getGames = installedPlatforms
.reduce((promise, platform) => promise.then(() => {
this.setState({ loadingText: `Grabbing games from ${platform.name}...` });

return platform.class.getGames().then((games) => {
// Filter out any games that are already imported
if (nonSteamGames && nonSteamGames[platform.id]) {
games = games.filter((game) => {
return !nonSteamGames[platform.id].find((nonSteamGame) => {
return nonSteamGame.gameId === game.id;
});
});
}

// nonSteamGames[platform.id].gameId
// Populate games array
platform.games = games;
});
Expand All @@ -75,11 +88,20 @@ class Import extends React.Component {
installedPlatforms.forEach((platform) => {
// Get grids for each platform
const ids = platform.games.map((x) => encodeURIComponent(x.id));
const getGrids = this.SGDB.getGrids({ type: platform.id, id: ids.join(',') }).then((res) => {

const getGrids = this.SGDB.getGrids({
type: platform.id,
id: ids.join(','),
dimensions: ['460x215', '920x430'],
}).then((res) => {
platform.grids = this._formatResponse(ids, res);
}).catch(() => {
// show an error toast
}).catch((e) => {
log.error('Erorr getting grids from SGDB');
console.error(e);
// @todo Fallback to text search
// @todo show an error toast
});

gridsPromises.push(getGrids);
});

Expand All @@ -98,15 +120,25 @@ class Import extends React.Component {

saveImportedGames(games) {
const gamesStorage = this.store.get('games', {});

games.forEach((game) => {
gamesStorage[metrohash64(game.exe + (game.params !== 'undefined' ? game.params : ''))] = game;
const key = game.exe + (
typeof game.params !== 'undefined'
? game.params
: ''
);

const configId = metrohash64(key);
gamesStorage[configId] = game;
});

this.store.set('games', gamesStorage);
}

// @todo this is horrible but can't be arsed right now
_formatResponse(ids, res) {
let formatted = false;

// if only single id then return first grid
if (ids.length === 1) {
if (res.length > 0) {
Expand All @@ -116,7 +148,9 @@ class Import extends React.Component {
// if multiple ids treat each object as a request
formatted = res.map((x) => {
if (x.success) {
if (x.data[0]) return x.data[0];
if (x.data[0]) {
return x.data[0];
}
}
return false;
});
Expand Down Expand Up @@ -167,30 +201,32 @@ class Import extends React.Component {
const getPosters = this.SGDB.getGrids({ type: platform.id, id: ids.join(','), dimensions: ['600x900'] }).then((res) => {
posters = this._formatResponse(ids, res);
}).catch(() => {
// show an error toast
// @todo show an error toast
});

// Get heroes
const getHeroes = this.SGDB.getHeroes({ type: platform.id, id: ids.join(',') }).then((res) => {
heroes = this._formatResponse(ids, res);
}).catch(() => {
// show an error toast
// @todo show an error toast
});

Promise.all([getPosters, getHeroes]).then(() => {
const downloadPromises = [];

games.forEach((game, i) => {
const appId = Steam.generateNewAppId(game.exe, game.name);

// Take (legacy) grids from when we got them for the ImportList
const savedGrid = platform.grids[platform.games.indexOf(games[i])];

if (platform.grids[i] && savedGrid) {
const appIdOld = Steam.generateAppId(game.exe, game.name);
const saveGrids = Steam.addAsset('horizontalGrid', appId, savedGrid.url).then((dest) => {
// Symlink to old appid so it works in BPM
Lnf.sync(dest, join(dirname(dest), `${appIdOld}${extname(dest)}`));
});
downloadPromises.push(saveGrids);

downloadPromises.push(Steam.addAsset('horizontalGrid', appId, savedGrid.url));

// Old app id is for Big Picture Mode
downloadPromises.push(Steam.addAsset('horizontalGrid', appIdOld, savedGrid.url));
}

// Download posters
Expand All @@ -213,6 +249,8 @@ class Import extends React.Component {
});
});
}).catch((err) => {
log.error('Cannot import while Steam is running');

if (err.type === 'OpenError') {
PubSub.publish('toast', {
logoNode: 'Error',
Expand Down Expand Up @@ -257,7 +295,7 @@ class Import extends React.Component {
>
{
installedPlatforms.map((platform) => {
if (!platform.error) {
if (!platform.error && platform.games.length) {
return (
<div key={platform.id}>
<h5 style={{ float: 'left', ...theme.typographyStyles.subTitle }}>{platform.name}</h5>
Expand All @@ -276,6 +314,7 @@ class Import extends React.Component {
</div>
);
}

return <></>;
})
}
Expand Down
18 changes: 14 additions & 4 deletions src/js/Steam.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ class Steam {
const appName = item.appname || item.AppName || item.appName;
const exe = item.exe || item.Exe;
const appid = this.generateNewAppId(exe, appName);

const configId = metrohash64(exe + item.LaunchOptions);

if (store.has(`games.${configId}`)) {
const storedGame = store.get(`games.${configId}`);
if (typeof games[storedGame.platform] === 'undefined') {
Expand Down Expand Up @@ -323,9 +323,10 @@ class Steam {
files.forEach((file) => {
fs.unlinkSync(file);
});

fs.writeFileSync(dest, data.read());
resolve(dest);
});
fs.writeFileSync(dest, data.read());
resolve(dest);
});
}).on('error', (err) => {
fs.unlink(dest);
Expand Down Expand Up @@ -383,8 +384,10 @@ class Steam {
static addCategory(games, categoryId) {
return new Promise((resolve, reject) => {
const levelDBPath = join(process.env.localappdata, 'Steam', 'htmlcache', 'Local Storage', 'leveldb');

this.getLoggedInUser().then((user) => {
const cats = new Categories(levelDBPath, String(user));

cats.read().then(() => {
this.getCurrentUserGridPath().then((userGridPath) => {
const localConfigPath = join(userGridPath, '../', 'localconfig.vdf');
Expand Down Expand Up @@ -429,7 +432,14 @@ class Steam {
localConfig.UserLocalConfigStore.WebStorage['user-collections'] = JSON.stringify(collections).replace(/"/g, '\\"'); // I hate Steam

const newVDF = VDF.stringify(localConfig);
fs.writeFileSync(localConfigPath, newVDF);

try {
fs.writeFileSync(localConfigPath, newVDF);
} catch (e) {
log.error('Error writing categories file');
console.error(e);
}

cats.close();
return resolve();
});
Expand Down

0 comments on commit 6222596

Please sign in to comment.