Skip to content

Commit 63266f3

Browse files
committed
Bug fixes
1 parent 9d612cb commit 63266f3

11 files changed

Lines changed: 211 additions & 180 deletions

File tree

client/public/favicon.ico

-3.78 KB
Binary file not shown.

client/public/favicon.png

1.45 KB
Loading

client/public/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
1010
-->
1111
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
12-
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
12+
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.png">
1313
<!--
1414
Notice the use of %PUBLIC_URL% in the tags above.
1515
It will be replaced with the URL of the `public` folder during the build.

client/src/App.js

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@ class App extends Component {
2525
this.state = {
2626
driveInfo: {},
2727
};
28-
subscribeToDriveInfo(this.handleDriveInfo);
28+
subscribeToDriveInfo(this.handleDriveInfo, this);
2929
}
3030

3131
handleDriveInfo(driveInfo) {
32-
let driveState = Object.assign({}, this.state.driveInfo);
33-
driveState[driveInfo.driveId] = driveInfo;
32+
console.log('Got Drive Info');
33+
console.debug(driveInfo);
3434
this.setState({
35-
driveInfo: driveState,
35+
driveInfo: driveInfo,
3636
});
3737
}
3838

@@ -41,15 +41,15 @@ class App extends Component {
4141
<Container className="App" fluid>
4242
<Header />
4343
<Row>
44-
{
45-
Object.keys(this.state.driveInfo).map((driveId) =>
46-
<Col md="6" xs="12">
44+
{Object.keys(this.state.driveInfo).map((driveId) => {
45+
let driveInfo = this.state.driveInfo[driveId];
46+
return <Col md="6" xs="12">
4747
<DiscPanel driveId={driveId}
48-
discTitle={this.state.driveInfo[driveId].discTitle}
49-
/>
48+
discName={driveInfo.discName}
49+
driveState={driveInfo.driveState}
50+
/>
5051
</Col>
51-
)
52-
}
52+
})}
5353
</Row>
5454
</Container>
5555
);

client/src/DiscInfo/DiscInfo.js

Lines changed: 64 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@ import $ from 'jquery';
44

55
import {
66
Button,
7-
Card,
8-
CardBody,
9-
CardTitle,
107
Form,
118
FormGroup,
129
Input,
@@ -23,9 +20,14 @@ class DiscInfo extends Component {
2320

2421
constructor(props) {
2522
super(props);
23+
let selectedTracks = {};
24+
this.props.tracks.map((trackInfo, trackId) => {
25+
selectedTracks[trackId] = trackInfo.isAutoSelected;
26+
});
2627
this.state = {
2728
checkAll: false,
28-
discName: this.props.discTitle,
29+
discName: false,
30+
selectedTracks: {},
2931
};
3032
}
3133

@@ -38,11 +40,23 @@ class DiscInfo extends Component {
3840
// Toggle the checkbox on all tracks.
3941
toggleAllTracks(event) {
4042
let $target = $(event.target);
41-
this.state.checkAll = $target.prop('checked');
43+
this.setState({
44+
checkAll: $target.prop('checked'),
45+
});
4246
this.getTrackCheckboxes(event.target)
4347
.prop('checked', this.state.checkAll);
4448
}
4549

50+
toggleTrack(trackId) {
51+
let changeObj = {};
52+
changeObj[trackId] = !this.selectedTracks[trackId];
53+
this.setState({
54+
selectedTracks: Object.assign(
55+
this.selectedTracks, changeObj
56+
)
57+
})
58+
}
59+
4660
// Command the server to rip certain tracks for this disc.
4761
ripTracks(event) {
4862
let ripTrackIds = this.getTrackCheckboxes(event.target)
@@ -56,15 +70,20 @@ class DiscInfo extends Component {
5670
}
5771

5872
render(){
59-
return(
60-
<Form onSubmit={ this.handleSubmit }>
61-
<fieldset { ...(this.props.isRipping ? 'disabled' : '') } >
73+
return (<div>
74+
<h1 className={ this.props.name ? 'invisible' : '' }>
75+
Drive is {this.props.driveState}
76+
</h1>
77+
<Form onSubmit={ this.handleSubmit }
78+
className={ !this.props.name ? 'invisible' : '' }
79+
>
80+
<fieldset { ...(this.props.isRipping ? {disabled: 'disabled'} : {}) } >
6281
<FormGroup>
6382
<Label for="discName">
6483
Name
6584
</Label>
6685
<Input type="text"
67-
value={ this.state.discName }
86+
value={ this.state.discName || this.props.name }
6887
onChange={
6988
(event) => {
7089
this.setState({discName: event.target.value})
@@ -78,8 +97,8 @@ class DiscInfo extends Component {
7897
<tr>
7998
<th>
8099
<Input type="checkbox"
81-
checked={this.state.checkAll}
82-
onChange={this.toggleAllTracks} />
100+
{ ...(this.state.checkAll ? {checked: 'checked'}: {}) }
101+
onChange={ (e) => this.toggleAllTracks(e) } />
83102
</th>
84103
<th>#</th>
85104
<th>Source</th>
@@ -90,49 +109,47 @@ class DiscInfo extends Component {
90109
</tr>
91110
</thead>
92111
<tbody>
93-
{
94-
this.props.tracks.map(function(trackInfo) {
95-
return <tr>
96-
<td>
97-
<Input type="checkbox"
98-
name="selectTrack"
99-
data-track-id={ trackInfo.id }
100-
{ ...(trackInfo.isAutoSelected ? 'checked' : '') }
101-
/>
102-
</td>
103-
<td>{ trackInfo.orderWeight }</td>
104-
<td>{ trackInfo.name }</td>
105-
<td>{ trackInfo.chapterCount }</td>
106-
<td>{ trackInfo.diskSize }</td>
107-
<td>{ trackInfo.streams.metadata }</td>
108-
<td>{ trackInfo.segments.map }</td>
109-
</tr>;
110-
})
111-
}
112+
{this.props.tracks && this.props.tracks.map(function(trackInfo, trackId) {
113+
return <tr onClick={ (e) => this.toggleTrack(trackId) }>
114+
<td>
115+
<Input type="checkbox"
116+
name="selectTrack"
117+
data-track-id={ trackId }
118+
checked={ this.state.selectedTracks[trackId] }
119+
onChange={ (e) => this.toggleTrack(trackId) }
120+
/>s
121+
</td>
122+
<td>{ trackInfo.orderWeight }</td>
123+
<td>{ trackInfo.name }</td>
124+
<td>{ trackInfo.chapterCount }</td>
125+
<td>{ trackInfo.diskSize }</td>
126+
<td>{ trackInfo.streams.length }</td>
127+
<td>{ trackInfo.segmentsMap }</td>
128+
</tr>;
129+
})}
112130
</tbody>
113131
</Table>
114132
</FormGroup>
115133
<FormGroup>
116-
<Button onClick={this.ripTracks} />
134+
<Button onClick={ (e) => this.ripTracks(e) } />
117135
</FormGroup>
118136
</fieldset>
119137
</Form>
120-
);
138+
</div>);
121139
}
122140
}
123141

124142
DiscInfo.propTypes = {
143+
driveState: PropTypes.string.isRequired,
125144
isRipping: PropTypes.bool,
126-
metadata: PropTypes.shape({
127-
lngCode: PropTypes.string.isRequired,
128-
lngName: PropTypes.string.isRequired,
129-
}),
145+
metadataLngCode: PropTypes.string.isRequired,
146+
metadataLngName: PropTypes.string.isRequired,
130147
name: PropTypes.string.isRequired,
131148
orderWeight: PropTypes.number.isRequired,
149+
panelTitle: PropTypes.string,
132150
sanitized: PropTypes.string,
133151
treeInfo: PropTypes.string.isRequired,
134-
driveId: PropTypes.string.isRequired,
135-
discType: PropTypes.string.isRequired,
152+
type: PropTypes.string.isRequired,
136153
volumeName: PropTypes.string.isRequired,
137154
tracks: PropTypes.arrayOf(PropTypes.shape({
138155
id: PropTypes.number.isRequired,
@@ -142,33 +159,24 @@ DiscInfo.propTypes = {
142159
diskSize: PropTypes.string.isRequired,
143160
diskSizeBytes: PropTypes.number.isRequired,
144161
duration: PropTypes.string.isRequired,
145-
metadata: PropTypes.shape({
146-
lngCode: PropTypes.string.isRequired,
147-
lngName: PropTypes.string.isRequired,
148-
}),
162+
metadataLngCode: PropTypes.string.isRequired,
163+
metadataLngName: PropTypes.string.isRequired,
149164
name: PropTypes.string.isRequired,
150165
orderWeight: PropTypes.number.isRequired,
151-
outputFileName: PropTypes.string.isRequired,
152-
segments: PropTypes.shape({
153-
count: PropTypes.number.isRequired,
154-
map: PropTypes.string.isRequired,
155-
}),
166+
outputFilename: PropTypes.string.isRequired,
167+
panelTitle: PropTypes.string,
168+
segmentsCount: PropTypes.number.isRequired,
169+
segmentsMap: PropTypes.string.isRequired,
156170
sourceFileName: PropTypes.string.isRequired,
157171
treeInfo: PropTypes.string.isRequired,
158-
streams: PropTypes.shape({
159-
metadata: PropTypes.shape({
160-
audio: PropTypes.number.isRequired,
161-
subtitle: PropTypes.number.isRequired,
162-
video: PropTypes.number.isRequired,
163-
}),
164-
details: PropTypes.any,
165-
})
172+
streams: PropTypes.arrayOf(
173+
PropTypes.objectOf(PropTypes.string)
174+
),
166175
})),
167176
};
168177

169178
DiscInfo.defaultProps = {
170179
isRipping: false,
171-
tracks: [],
172180
};
173181

174182
export default DiscInfo;

client/src/DiscPanel/DiscPanel.js

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,6 @@ import {
66
Card,
77
CardBody,
88
CardTitle,
9-
Form,
10-
FormGroup,
11-
Input,
12-
Label,
13-
Table,
149
} from 'reactstrap';
1510

1611
import DiscInfo from '../DiscInfo';
@@ -28,12 +23,14 @@ class DiscPanel extends Component {
2823
this.state = {
2924
discInfo: {},
3025
};
31-
subscribeToDiscInfo(this.handleDriveInfo, this.props.driveId);
26+
subscribeToDiscInfo(this.handleDiscInfo, this, this.props.driveId);
3227
}
3328

34-
handleDriveInfo(discInfo) {
29+
handleDiscInfo(discInfo) {
30+
console.log('Got disc info');
31+
console.debug(discInfo);
3532
this.setState({
36-
discInfo: discInfo,
33+
discInfo: discInfo[this.props.driveId] || {},
3734
});
3835
}
3936

@@ -47,16 +44,22 @@ class DiscPanel extends Component {
4744
<Card>
4845
<CardBody>
4946
<CardTitle>
50-
[{ this.props.driveId }] { this.props.discTitle }
47+
<span>
48+
{ this.props.driveId }
49+
</span>
50+
&nbsp;-&nbsp;
51+
<span>
52+
{ this.props.discName || 'No Disc' }
53+
</span>
5154
</CardTitle>
52-
<Button>
53-
<span className="glyphicon glyphicon-refresh"
54-
onClick={ this.refreshDiscInfo }
55-
/>
55+
<Button onClick={ () => this.refreshDiscInfo() }>
56+
<span className="glyphicon glyphicon-refresh" />
5657
</Button>
5758
</CardBody>
5859
<CardBody>
59-
<DiscInfo { ...this.state.discInfo } />
60+
<DiscInfo driveState={ this.props.driveState }
61+
{ ...this.state.discInfo }
62+
/>
6063
</CardBody>
6164
</Card>
6265
</div>
@@ -66,7 +69,8 @@ class DiscPanel extends Component {
6669

6770
DiscPanel.propTypes = {
6871
driveId: PropTypes.number.isRequired,
69-
discTitle: PropTypes.string.isRequired,
72+
discName: PropTypes.string.isRequired,
73+
driveState: PropTypes.string.isRequired,
7074
};
7175

7276
DiscPanel.defaultProps = {

client/src/api.js

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,47 @@
1-
import openSocket from 'socket.io-client';
1+
import io from 'socket.io-client';
22

33
import {
44
SERVER_PORT,
55
} from './settings.json';
66

7-
const socket = openSocket(`http://localhost:${SERVER_PORT}`);
7+
const socket = io();
88

9-
function subscribeTo(eventName, callback, sendData) {
10-
socket.on(eventName, receiveData => callback(receiveData));
11-
socket.emit(`subscribeTo${eventName}`, sendData);
9+
function waitForSocket(callback, ...args) {
10+
console.debug('Waiting for socket to become available.');
11+
if (socket.id) {
12+
console.debug('Socket is available.');
13+
callback(...args);
14+
} else {
15+
setTimeout(waitForSocket, 1000, callback, ...args);
16+
}
17+
}
18+
19+
function subscribeTo(eventName, callback, context, sendData) {
20+
console.debug(`Subscribing to "${eventName}".`);
21+
waitForSocket(() => {
22+
socket.on(
23+
eventName,
24+
context ? callback.bind(context) : callback
25+
);
26+
socket.emit(`subscribeTo${eventName}`, sendData);
27+
});
1228
}
1329

1430
function doAction(actionName, sendData) {
15-
socket.emit(`do${actionName}`, sendData);
31+
console.debug(`Performing action "${actionName}".`);
32+
waitForSocket(() => {
33+
socket.emit(`do${actionName}`, sendData);
34+
});
1635
}
1736

1837
// Listen for updates to disc-level information on a drive.
19-
function subscribeToDiscInfo(callback, driveId) {
20-
subscribeTo('DiscInfo', callback, { driveId });
38+
function subscribeToDiscInfo(callback, context, driveId) {
39+
subscribeTo('DiscInfo', callback, context, { driveId });
2140
}
2241

2342
// Listen for updates to any drive-level information.
24-
function subscribeToDriveInfo(callback) {
25-
subscribeTo('DriveInfo', callback);
43+
function subscribeToDriveInfo(callback, context) {
44+
subscribeTo('DriveInfo', callback, context);
2645
}
2746

2847
// Start ripping tracks on a drive.

0 commit comments

Comments
 (0)