Skip to content

Commit

Permalink
fix(App): Better error handling for config loader, missing songs and …
Browse files Browse the repository at this point in the history
…osu scan (#400)
  • Loading branch information
yadPe authored Apr 10, 2021
1 parent e3271f7 commit 5540b44
Show file tree
Hide file tree
Showing 11 changed files with 117 additions and 54 deletions.
15 changes: 14 additions & 1 deletion src/App/Providers/AudioPlayer/Audioplayer.re
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
open AudioPlayerProvider;

[@bs.val] external alert: string => unit = "alert";

let audio = Audio.make();

let _play = () => {
Expand Down Expand Up @@ -38,6 +40,7 @@ let setVolume = Audio.setVolume(audio);

[@react.component]
let make = (~children) => {
let playlistErrorCount = React.useRef(0);
let (playingState, setPlayingState) = React.useState(() => initialState);
let (playlist: playlist, setPlaylist) = React.useState(() => [||]);
let (playlistID: string, setPlaylistID) = React.useState(() => "");
Expand Down Expand Up @@ -236,7 +239,17 @@ let make = (~children) => {
audio,
_e => {
setPlayingState(oldState => {...oldState, isPlaying: false});
playNext();
let skipCount = playlistErrorCount->React.Ref.current;
if (skipCount > 12 || skipCount >= playlist->Js_array.length - 1) {
playlistErrorCount->React.Ref.setCurrent(0);
setPlaylist(~beatmapPlaylist=[||], ~playlistID="", ());
alert(
"Failed to play song from a playlist multiple times, please check your osu songs folder setting in the Settings section",
);
} else {
playNext();
playlistErrorCount->React.Ref.setCurrent(skipCount + 1);
};
},
);

Expand Down
4 changes: 2 additions & 2 deletions src/App/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import TitleBar from './modules/common/TitleBar.bs';
import config from '../shared/config';
import { getAppear } from './helpers/css.utils';
import AutoUpdater from './modules/AutoUpdater';
import { useOsuDbAutoScan } from './modules/Settings/utils/useScanOsuSongs';

const useStyles = createUseStyles({
...getAppear(),
Expand All @@ -26,7 +25,8 @@ const useStyles = createUseStyles({

const App = () => {
const classes = useStyles();
useOsuDbAutoScan();
// Already done by the PlayOsu component
// useOsuDbAutoScan();

return (
<>
Expand Down
48 changes: 32 additions & 16 deletions src/App/modules/Settings/helpers/ConfLoader.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,45 @@
import { readJSONSync, writeJSON } from 'fs-extra';
/* eslint-disable no-console */
import { readJSONSync } from 'fs-extra';
import fs from 'fs';
import { join } from 'path';
import { error, warn } from 'electron-log';
import { remote } from 'electron';
import baseConf from './baseConf';
import store from '../../../../shared/store';

class ConfLoader {
constructor() {
this.path = remote.app.getPath('documents') + '/Beatconnect/config.json';
this.path = join(remote.app.getPath('documents'), 'Beatconnect', 'config.json');
this.conf = null;
}

get config() {
try {
this.conf = { ...baseConf, ...readJSONSync(this.path) };
const userConfig = readJSONSync(this.path);
this.conf = { ...this.conf, ...userConfig };
return this.conf;
} catch (err) {
// assume conf file does not exist
warn('[Conf loader]: Failed to get user config creating a new one', err);
this.conf = baseConf;
return this.conf;
}
console.log('confLoader', this.conf);
}

save = () => {
let { conf } = this;
const { settings } = store.getState();
conf = { ...conf, ...settings };
this.conf = conf;
writeJSON(this.path, this.conf, { EOL: '\n', spaces: 2 })
.then(console.log('config daved!'))
.catch(console.error);
};
async save(userSettings) {
if (!this.conf) {
console.log('Didnt save config cause its falsy');
return;
}
this.conf = { ...this.conf, ...userSettings };
try {
const json = JSON.stringify(this.conf);
fs.writeFileSync(this.path, json, { flag: 'w' });
console.log('config daved!');
} catch (e) {
console.error('config ooofed!');
error('[config loader]: failed to write use config');
}
}
}

export default new ConfLoader();
const configLoader = new ConfLoader();
export default configLoader;
4 changes: 2 additions & 2 deletions src/App/modules/Settings/helpers/baseConf.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import config from '../../../../shared/config';

export default {
export default Object.freeze({
userPreferences: {
volume: 50,
targetServer: 'osuMain',
Expand Down Expand Up @@ -60,4 +60,4 @@ export default {
'Request the bot to connect to the specified match (Bot must be added as match referee before with `!mp addref`).',
},
],
};
});
6 changes: 5 additions & 1 deletion src/App/modules/Settings/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import useSettingsUtils from './utils/useSettingsUtils';
import { useOsuDbScan } from './utils/useScanOsuSongs';
import { clearCollections } from '../MyLibrary/actions';
import { scanOsuCollection } from './utils/scanOsuCollections';
import store from '../../../shared/store';

const Settings = ({ userPreferences }) => {
const { irc, osuApi, prefix, osuSongsPath, osuPath, lastScan, importMethod } = userPreferences;
Expand All @@ -36,7 +37,10 @@ const Settings = ({ userPreferences }) => {
};

useEffect(() => {
return ConfLoader.save;
return () => {
const { settings } = store.getState();
ConfLoader.save(settings);
};
}, []);

const settings = {
Expand Down
4 changes: 2 additions & 2 deletions src/App/modules/Settings/reducer/reducer.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import ConfLoader from '../helpers/ConfLoader';
import confLoader from '../helpers/ConfLoader';

export default (settings = ConfLoader.conf, { type, payload }) => {
export default (settings = confLoader.config, { type, payload }) => {
let { userPreferences } = settings;
switch (type) {
case 'VOLUME':
Expand Down
11 changes: 6 additions & 5 deletions src/App/modules/Settings/utils/scanOsuCollections.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ import store from '../../../../shared/store';

export const scanOsuCollection = async osuPath => {
if (!osuPath) return undefined;
const maybeCollections = await ipcRenderer.invoke('scan-osu-collections', osuPath);
if (maybeCollections instanceof Error) {
try {
const maybeCollections = await ipcRenderer.invoke('scan-osu-collections', osuPath);
store.dispatch({ type: 'SET-OSU-COLLECTIONS', payload: maybeCollections });
return maybeCollections;
} catch (e) {
// eslint-disable-next-line no-alert
alert(`Failed to scan osu collections ${maybeCollections.message}`);
alert(`Failed to scan osu collections ${e.message}`);
return {};
}
store.dispatch({ type: 'SET-OSU-COLLECTIONS', payload: maybeCollections });
return maybeCollections;
};
24 changes: 10 additions & 14 deletions src/App/modules/Settings/utils/useScanOsuSongs.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,16 @@ export const useOsuDbScan = () => {
}
setIsScanning(true);
addTask({ name: 'Scanning beatmaps', status: 'running', description: '', section: 'Settings' });
const result = await ipcRenderer.invoke('osuSongsScan', { osuPath });

terminate('Scanning beatmaps');
setIsScanning(false);
if (result.error) {
throw new Error(`Error while scannings song: ${result.error}`);
} else {
try {
const result = await ipcRenderer.invoke('osuSongsScan', { osuPath });
history.set(result);
setLastScan({ date: Date.now(), beatmaps: Object.keys(result.beatmaps).length });
} catch (e) {
error(`Error while scannings song: ${e.message}`);
alert(`Failed to scan beatmaps, please check your songs and osu! path in settings section\n ${e.message}`);
} finally {
terminate('Scanning beatmaps');
setIsScanning(false);
}
};

Expand All @@ -46,13 +47,8 @@ export const useOsuDbAutoScan = () => {
const osuPath = useSelector(getOsuPath);
useEffect(() => {
if (osuPath && osuSongsPath !== '') {
osuDbScan()
.then(() => console.log('Osu db scan success!'))
.catch(err => {
error(`Error while scannings song: ${err.message}`);
alert('Failed to scan beatmaps, check your songs and osu! path in settings section');
});
scanOsuCollection(osuPath).then(() => console.log('Collection scan success!'));
osuDbScan();
scanOsuCollection(osuPath);
}
}, []);
};
32 changes: 30 additions & 2 deletions src/App/modules/Settings/utils/useSettingsUtils.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
import { remote } from 'electron';
import { remote, ipcRenderer } from 'electron';
import { error } from 'electron-log';
import { join } from 'path';
import { useSelector } from 'react-redux';
import { useDownloadQueue } from '../../../Providers/downloadManager';
import { useSetTheme } from '../../../Providers/ThemeProvider';
import { saveThemeAccentColor, setImportMethod, setOsuSongsPath, setOsuPath } from '../reducer/actions';
import { getOsuSongPath } from '../reducer/selectors';

const checkOsuPath = async path => {
try {
const isPathValid = await ipcRenderer.invoke('validate-osu-path', path);
return !!isPathValid;
} catch (e) {
// eslint-disable-next-line no-alert
alert(`An error occured while setting the osu folder, please try again.`);
error('[osuPathSetup]: ', e);
return false;
}
};

const useSettingsUtils = ({ osuSongsPath, importMethod }) => {
const { setPath } = useDownloadQueue();
const { setAccentColor } = useSetTheme();
const currentOsuSongsPath = useSelector(getOsuSongPath);

const osuPathSetup = async song => {
const { filePaths } = await remote.dialog.showOpenDialog({
Expand All @@ -15,7 +32,18 @@ const useSettingsUtils = ({ osuSongsPath, importMethod }) => {
if (song === 'song') {
setPath(importMethod, filePaths[0]);
setOsuSongsPath(filePaths[0]);
} else setOsuPath(filePaths[0]);
} else {
const isValid = await checkOsuPath(filePaths[0]);
if (!isValid) {
// eslint-disable-next-line no-alert
alert(`The provided folder doesn't seems be a valid osu folder.`);
return;
}
setOsuPath(filePaths[0]);
if (!currentOsuSongsPath) {
setOsuSongsPath(join(filePaths[0], 'Songs'));
}
}
}
};

Expand Down
3 changes: 2 additions & 1 deletion src/App/modules/common/NavPanel/SidePanel/VolumeControl.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,9 @@ const useStyle = createUseStyles({

const denounceSave = throttle(
(vol, save) => {
const { settings } = store.getState();
save(convertRange(vol, 0, 1, 0, 100));
ConfLoader.save();
ConfLoader.save(settings);
},
1000,
{ leading: false },
Expand Down
20 changes: 12 additions & 8 deletions src/electron/ipcMessages.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const log = require('electron-log');
const { error } = require('electron-log');
const { ipcMain, dialog, shell } = require('electron');
const fs = require('fs').promises;
const { join } = require('path');
const { downloadAndSetWallpaper } = require('./wallpaper');
const { readCollectionDB } = require('./helpers/osuCollections/collections.utils');
Expand All @@ -12,7 +13,8 @@ ipcMain.handle('osuSongsScan', async (event, { osuPath }) => {
const [beatmaps, overallDuration, overallUnplayedCount] = await scanOsuDb(`${osuPath}/osu!.db`);
return { beatmaps, overallDuration, overallUnplayedCount };
} catch (e) {
return { error: e.message };
error(`[scan-osu-songs]: ${e.message}`);
throw e;
}
});

Expand Down Expand Up @@ -47,13 +49,15 @@ ipcMain.handle('scan-osu-collections', async (event, osuPath) => {
return collection;
} catch (e) {
error(`[scan-osu-collections]: ${e.message}`);
return e;
throw e;
}
});

// try {
// const osuSongsScanProcess = fork(join(__dirname, './processes/osuSongsScan.js'));
// osuSongsScanProcess.stdout.pipe(process.stdout);
// } catch (e) {
// console.error(e);
// }
ipcMain.handle('validate-osu-path', async (event, osuPath) => {
try {
const isPathValid = await fs.stat(`${osuPath}/osu!.db`);
return isPathValid.isFile();
} catch {
return false;
}
});

0 comments on commit 5540b44

Please sign in to comment.