Skip to content

Commit

Permalink
Show where spectator SLP files will be saved (#104)
Browse files Browse the repository at this point in the history
* Shows a hint for where the spectated games will be stored
* Fixes the viewer ID being cleared when changing broadcast tabs
* Defaults the root SLP folder path to the system defaults (`Documents/Slippi` on Windows, and `~/Slippi` otherwise)
* Adjusts hooks to only lint staged changes on commit and lint all files on pre-push
  • Loading branch information
vinceau authored Nov 28, 2020
1 parent 75979c7 commit 2acc50a
Show file tree
Hide file tree
Showing 11 changed files with 468 additions and 23 deletions.
2 changes: 2 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
"indent": ["error", 2, { "SwitchCase": 0 }],
"jsx-a11y/label-has-associated-control": "off",
"jsx-a11y/label-has-for": "off",
"jsx-a11y/click-events-have-key-events": "off",
"jsx-a11y/no-static-element-interactions": "off",
"jsx-quotes": "off",
"no-bitwise": "off",
"no-case-declarations": "off",
Expand Down
10 changes: 10 additions & 0 deletions app/actions/broadcast.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ export function startBroadcast(target) {
};
}

export function fetchSpectateFolder() {
return () => {
try {
return spectateManager.fetchSpectateFolder();
} catch (err) {
return "";
}
}
}

export function stopBroadcast() {
return async () => {
broadcastManager.stop();
Expand Down
5 changes: 2 additions & 3 deletions app/actions/fileLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import * as timeUtils from '../utils/time';

import { displayError } from './error';
import { gameProfileLoad } from './game';

const electronSettings = require('electron-settings');
import { getRootSlpPath } from '../utils/settings';

export const LOAD_ROOT_FOLDER = 'LOAD_ROOT_FOLDER';
export const CHANGE_FOLDER_SELECTION = 'CHANGE_FOLDER_SELECTION';
Expand All @@ -24,7 +23,7 @@ const MIN_GAME_LENGTH_FRAMES = MIN_GAME_LENGTH_SECONDS * 60;

export function loadRootFolder() {
return async (dispatch, getState) => {
const rootFolderPath = electronSettings.get('settings.rootSlpPath');
const rootFolderPath = getRootSlpPath();
if (!rootFolderPath) {
dispatch({
type: LOAD_ROOT_FOLDER,
Expand Down
18 changes: 17 additions & 1 deletion app/components/Broadcast.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import * as firebase from 'firebase';
import classNames from 'classnames';

import {
Button, Header, Segment, Icon, Tab, Input, List, Card,
Popup, Button, Header, Segment, Icon, Tab, Input, List, Card,
} from 'semantic-ui-react';
import { Link } from 'react-router-dom';

import { shell } from 'electron';
import { ConnectionStatus } from '@slippi/slippi-js';

import CopyToClipboard from './common/CopyToClipboard';
Expand All @@ -31,6 +32,7 @@ export default class Broadcast extends Component {
stopBroadcast: PropTypes.func.isRequired,
refreshBroadcasts: PropTypes.func.isRequired,
watchBroadcast: PropTypes.func.isRequired,
fetchSpectateFolder: PropTypes.func.isRequired,

// store data
history: PropTypes.object.isRequired,
Expand Down Expand Up @@ -248,6 +250,7 @@ export default class Broadcast extends Component {
type="text"
inverted={true}
label="Viewer ID"
value={this.state.viewerId}
onChange={(event, p) => {
this.setState({
viewerId: p.value,
Expand All @@ -267,6 +270,15 @@ export default class Broadcast extends Component {

renderSpectateContent() {
const user = firebase.auth().currentUser;
const spectateFolder = this.props.fetchSpectateFolder();
const renderSpectateFolder = <Popup
size="mini"
position="top center"
content="Open location"
trigger={
<strong className={styles['highlight']} onClick={() => shell.showItemInFolder(spectateFolder)}>{spectateFolder}</strong>
}
/>

return (
<div>
Expand All @@ -285,6 +297,10 @@ export default class Broadcast extends Component {
<List.Icon name="caret right"/>
<List.Content>Once the broadcast appears, click to watch</List.Content>
</List.Item>
{spectateFolder && <List.Item>
<List.Icon name="caret right"/>
<List.Content>Spectated games will saved to: {renderSpectateFolder}</List.Content>
</List.Item>}
</List>
{this.renderRefreshButton()}
{this.renderBroadcasts()}
Expand Down
1 change: 1 addition & 0 deletions app/components/Broadcast.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
.highlight {
color: $foreground;

margin: 0 5px;
cursor: pointer;
&:hover {
text-decoration: underline;
Expand Down
12 changes: 10 additions & 2 deletions app/components/FileRow.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import log from 'electron-log';
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import { Button, Table, Icon } from 'semantic-ui-react';
import { Popup, Button, Table, Icon } from 'semantic-ui-react';
import { stages as stageUtils } from '@slippi/slippi-js';
import classNames from 'classnames';

Expand Down Expand Up @@ -109,7 +109,15 @@ export default class FileRow extends Component {
},
{
label: 'File',
content: <button type="button" className={styles['reveal-file-location']} onClick={onFileLocationClick}>{this.getFileName()}</button>,
content:
<Popup
size="mini"
position="top center"
content="Open location"
trigger={
<button type="button" className={styles['reveal-file-location']} onClick={onFileLocationClick}>{this.getFileName()}</button>
}
/>,
},
];

Expand Down
23 changes: 13 additions & 10 deletions app/domain/SpectateManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ import SlpFileWriter from './SlpFileWriter';
import { store } from '../index';
import { updateViewableBroadcasts } from '../actions/broadcast';
import { displayError } from '../actions/error';

const electronSettings = require('electron-settings');
import { getRootSlpPath } from '../utils/settings';

const SLIPPI_WS_SERVER = process.env.SLIPPI_WS_SERVER;

Expand Down Expand Up @@ -245,20 +244,24 @@ export class SpectateManager {
}));
}

watchBroadcast(broadcastId) {
if (!this.wsConnection) {
return;
}

// Get path for spectate replays in my documents
const rootFolderPath = electronSettings.get('settings.rootSlpPath');
fetchSpectateFolder() {
const rootFolderPath = getRootSlpPath();
if (!rootFolderPath) {
throw new Error(
`Files cannot be saved without a Root Replay Directory set. Please return to the
settings page and set a Replay Root Directory.`
);
}
const targetPath = path.join(rootFolderPath, 'Spectate');
return path.join(rootFolderPath, 'Spectate');
}

watchBroadcast(broadcastId) {
if (!this.wsConnection) {
return;
}

// Get path for spectate replays
const targetPath = this.fetchSpectateFolder();
fs.ensureDirSync(targetPath);

const slpSettings = {
Expand Down
4 changes: 2 additions & 2 deletions app/reducers/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
SELECT_FOLDER, SELECT_FILE, ISO_VALIDATION_START, ISO_VALIDATION_COMPLETE, SET_RESET_CONFIRM, RESETTING_DOLPHIN,
} from '../actions/settings';
import DolphinManager from '../domain/DolphinManager';
import { getDolphinPath } from '../utils/settings';
import { getRootSlpPath, getDolphinPath } from '../utils/settings';

const { app } = require('electron').remote;

Expand All @@ -27,7 +27,7 @@ function getAvailableSettings() {
},
rootSlpPath: {
location: 'settings.rootSlpPath',
defaultValue: "",
defaultValue: getRootSlpPath(),
},
playbackDolphinPath: {
location: 'settings.playbackDolphinPath',
Expand Down
17 changes: 17 additions & 0 deletions app/utils/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,20 @@ export function getDefaultDolphinPath() {
const userDataPath = app.getPath("userData")
return path.join(userDataPath, 'dolphin');
}

export function getDefaultRootSlpPath() {
let root = app.getPath("home");
if (process.platform === "win32") {
root = app.getPath("documents");
}
return path.join(root, "Slippi")
}

export function getRootSlpPath() {
const storedRootSlpPath = electronSettings.get('settings.rootSlpPath');
if (storedRootSlpPath) {
return storedRootSlpPath;
}

return getDefaultRootSlpPath();
}
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@
"husky": "^1.1.4",
"identity-obj-proxy": "^3.0.0",
"jest": "^23.6.0",
"lint-staged": "^10.5.2",
"mini-css-extract-plugin": "^0.4.4",
"node-sass": "^4.13.0",
"optimize-css-assets-webpack-plugin": "^5.0.1",
Expand Down Expand Up @@ -304,7 +305,11 @@
"browserslist": "electron 1.6",
"husky": {
"hooks": {
"pre-commit": "yarn lint --quiet"
"pre-commit": "lint-staged --quiet",
"pre-push": "yarn lint --quiet"
}
},
"lint-staged": {
"*.js": ["yarn lint --quiet --fix"]
}
}
Loading

0 comments on commit 2acc50a

Please sign in to comment.