Skip to content

Commit ae5fa2e

Browse files
committed
add a simple state machine
The player can only ever be in one state, "paused", "playing", or "checking".
1 parent fadf9dc commit ae5fa2e

File tree

1 file changed

+62
-35
lines changed

1 file changed

+62
-35
lines changed

source/views/streaming/radio.js

Lines changed: 62 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@ type Viewport = {
2929
height: number,
3030
}
3131

32+
type PlayState = 'paused' | 'playing' | 'checking'
33+
3234
type Props = {}
3335

3436
type State = {
35-
refreshing: boolean,
36-
paused: boolean,
37+
playState: PlayState,
3738
streamError: ?Object,
38-
uplinkError: boolean,
39-
message: string,
39+
uplinkError: ?string,
4040
viewport: Viewport,
4141
}
4242

@@ -47,11 +47,9 @@ export default class KSTOView extends React.PureComponent<void, Props, State> {
4747
}
4848

4949
state = {
50-
refreshing: false,
51-
paused: true,
50+
playState: 'paused',
5251
streamError: null,
53-
uplinkError: false,
54-
message: '',
52+
uplinkError: null,
5553
viewport: Dimensions.get('window'),
5654
}
5755

@@ -68,36 +66,66 @@ export default class KSTOView extends React.PureComponent<void, Props, State> {
6866
}
6967

7068
// check the stream uplink status
71-
fetchUplinkStatus = async () => {
69+
isUplinkUp = async () => {
7270
try {
7371
await promiseTimeout(6000, fetch(kstoStatus))
74-
this.setState(() => ({uplinkError: false, message: ''}))
72+
return true
7573
} catch (err) {
76-
this.setState(() => ({
77-
uplinkError: true,
78-
message: 'The KSTO stream is down. Sorry!',
79-
}))
80-
}
81-
82-
// If the stream is down or we had an error, pause the player
83-
if (this.state.uplinkError) {
84-
this.setState(() => ({paused: true}))
74+
return false
8575
}
8676
}
8777

88-
changeControl = () => {
89-
this.setState(state => ({paused: !state.paused}))
78+
onPlay = async () => {
79+
this.setState(() => ({playState: 'checking'}))
9080

91-
// If we try to play...
92-
if (this.state.paused) {
93-
// Fetch the uplink status
94-
this.fetchUplinkStatus()
81+
const uplinkStatus = await this.isUplinkUp()
82+
83+
if (uplinkStatus) {
84+
this.setState(() => ({playState: 'playing'}))
85+
} else {
86+
this.setState(() => ({
87+
playState: 'paused',
88+
uplinkError: 'The KSTO stream is down. Sorry!',
89+
}))
9590
}
9691
}
9792

93+
onPause = () => {
94+
this.setState(() => ({
95+
playState: 'paused',
96+
uplinkError: null,
97+
}))
98+
}
99+
98100
// error from react-native-video
99101
onError = (e: any) => {
100-
this.setState(() => ({streamError: e, paused: true}))
102+
this.setState(() => ({streamError: e, playState: 'paused'}))
103+
}
104+
105+
renderButton = (state: PlayState) => {
106+
switch (state) {
107+
case 'paused':
108+
return (
109+
<ActionButton icon="ios-play" text="Listen" onPress={this.onPlay} />
110+
)
111+
112+
case 'checking':
113+
return (
114+
<ActionButton
115+
icon="ios-more"
116+
text="Starting"
117+
onPress={this.onPause}
118+
/>
119+
)
120+
121+
case 'playing':
122+
return (
123+
<ActionButton icon="ios-pause" text="Pause" onPress={this.onPause} />
124+
)
125+
126+
default:
127+
return <ActionButton icon="ios-bug" text="Error" onPress={() => {}} />
128+
}
101129
}
102130

103131
render() {
@@ -113,10 +141,12 @@ export default class KSTOView extends React.PureComponent<void, Props, State> {
113141
height: logoWidth,
114142
}
115143

116-
const ErrorMessage = this.state.uplinkError
117-
? <Text style={styles.status}>{this.state.message}</Text>
144+
const error = this.state.uplinkError
145+
? <Text style={styles.status}>{this.state.uplinkError}</Text>
118146
: null
119147

148+
const button = this.renderButton(this.state.playState)
149+
120150
return (
121151
<ScrollView
122152
contentContainerStyle={[styles.root, sideways && landscape.root]}
@@ -130,20 +160,17 @@ export default class KSTOView extends React.PureComponent<void, Props, State> {
130160
</View>
131161

132162
<View style={styles.container}>
133-
{ErrorMessage}
134163
<Title />
135164

136-
<PlayPauseButton
137-
onPress={this.changeControl}
138-
paused={this.state.paused}
139-
/>
165+
{error}
166+
{button}
140167

141-
{!this.state.paused
168+
{this.state.playState === 'playing'
142169
? <Video
143170
source={{uri: kstoStream}}
144171
playInBackground={true}
145172
playWhenInactive={true}
146-
paused={this.state.paused}
173+
paused={this.state.playState !== 'playing'}
147174
onError={this.onError}
148175
/>
149176
: null}

0 commit comments

Comments
 (0)