Skip to content

Commit 9f4e1db

Browse files
manseRyota Mannari
authored and
Ryota Mannari
committed
feat: Reimplements example app
1 parent 20e1d34 commit 9f4e1db

File tree

4 files changed

+209
-103
lines changed

4 files changed

+209
-103
lines changed

example/App.js

+199-100
Original file line numberDiff line numberDiff line change
@@ -1,114 +1,213 @@
1-
/**
2-
* Sample React Native App
3-
* https://github.com/facebook/react-native
4-
*
5-
* @format
6-
* @flow
7-
*/
1+
import React, { Component } from 'react';
2+
import { FlatList, StatusBar, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
3+
import { BrightcovePlayer, BrightcovePlayerPoster, BrightcovePlayerUtil } from 'react-native-brightcove-player';
84

9-
import React from 'react';
10-
import {
11-
SafeAreaView,
12-
StyleSheet,
13-
ScrollView,
14-
View,
15-
Text,
16-
StatusBar,
17-
} from 'react-native';
5+
const ACCOUNT_ID = '5434391461001';
6+
const POLICY_KEY =
7+
'BCpkADawqM0T8lW3nMChuAbrcunBBHmh4YkNl5e6ZrKQwPiK_Y83RAOF4DP5tyBF_ONBVgrEjqW6fbV0nKRuHvjRU3E8jdT9WMTOXfJODoPML6NUDCYTwTHxtNlr5YdyGYaCPLhMUZ3Xu61L';
8+
const PLAYLIST_REF_ID = 'brightcove-native-sdk-plist';
189

19-
import {
20-
Header,
21-
LearnMoreLinks,
22-
Colors,
23-
DebugInstructions,
24-
ReloadInstructions,
25-
} from 'react-native/Libraries/NewAppScreen';
10+
export default class App extends Component {
11+
state = {
12+
videos: [],
13+
offlineVideos: [],
14+
playback: {
15+
referenceId: null,
16+
videoToken: null
17+
}
18+
};
2619

27-
const App: () => React$Node = () => {
28-
return (
29-
<>
30-
<StatusBar barStyle="dark-content" />
31-
<SafeAreaView>
32-
<ScrollView
33-
contentInsetAdjustmentBehavior="automatic"
34-
style={styles.scrollView}>
35-
<Header />
36-
{global.HermesInternal == null ? null : (
37-
<View style={styles.engine}>
38-
<Text style={styles.footer}>Engine: Hermes</Text>
39-
</View>
40-
)}
41-
<View style={styles.body}>
42-
<View style={styles.sectionContainer}>
43-
<Text style={styles.sectionTitle}>Step One</Text>
44-
<Text style={styles.sectionDescription}>
45-
Edit <Text style={styles.highlight}>App.js</Text> to change this
46-
screen and then come back to see your edits.
47-
</Text>
48-
</View>
49-
<View style={styles.sectionContainer}>
50-
<Text style={styles.sectionTitle}>See Your Changes</Text>
51-
<Text style={styles.sectionDescription}>
52-
<ReloadInstructions />
53-
</Text>
54-
</View>
55-
<View style={styles.sectionContainer}>
56-
<Text style={styles.sectionTitle}>Debug</Text>
57-
<Text style={styles.sectionDescription}>
58-
<DebugInstructions />
59-
</Text>
60-
</View>
61-
<View style={styles.sectionContainer}>
62-
<Text style={styles.sectionTitle}>Learn More</Text>
63-
<Text style={styles.sectionDescription}>
64-
Read the docs to discover what to do next:
65-
</Text>
66-
</View>
67-
<LearnMoreLinks />
68-
</View>
69-
</ScrollView>
70-
</SafeAreaView>
71-
</>
72-
);
73-
};
20+
componentDidMount() {
21+
BrightcovePlayerUtil.getPlaylistWithReferenceId(
22+
ACCOUNT_ID,
23+
POLICY_KEY,
24+
PLAYLIST_REF_ID
25+
)
26+
.then(videos => {
27+
this.setState({
28+
videos
29+
});
30+
})
31+
.catch(console.warn);
32+
BrightcovePlayerUtil.getOfflineVideoStatuses(ACCOUNT_ID, POLICY_KEY)
33+
.then(offlineVideos => {
34+
this.setState({
35+
offlineVideos
36+
});
37+
})
38+
.catch(console.warn);
39+
this.disposer = BrightcovePlayerUtil.addOfflineNotificationListener(
40+
offlineVideos => {
41+
this.setState({
42+
offlineVideos
43+
});
44+
}
45+
);
46+
}
47+
48+
requestDownload(videoId) {
49+
BrightcovePlayerUtil.requestDownloadVideoWithVideoId(
50+
ACCOUNT_ID,
51+
POLICY_KEY,
52+
videoId
53+
).catch(() => {});
54+
}
55+
56+
play(item) {
57+
const downloadStatus = this.state.offlineVideos.find(
58+
video => video.videoId === item.videoId
59+
);
60+
this.setState({
61+
playback:
62+
downloadStatus && downloadStatus.downloadProgress === 1
63+
? {
64+
videoToken: downloadStatus.videoToken
65+
}
66+
: {
67+
referenceId: item.referenceId
68+
}
69+
});
70+
}
71+
72+
delete(videoToken) {
73+
BrightcovePlayerUtil.deleteOfflineVideo(
74+
ACCOUNT_ID,
75+
POLICY_KEY,
76+
videoToken
77+
).catch(console.warn);
78+
}
79+
80+
componentWillUnmount() {
81+
this.disposer && this.disposer();
82+
}
83+
84+
render() {
85+
return (
86+
<View style={styles.container}>
87+
<StatusBar barStyle="light-content" />
88+
<BrightcovePlayer
89+
style={styles.video}
90+
accountId={ACCOUNT_ID}
91+
policyKey={POLICY_KEY}
92+
autoPlay
93+
{...this.state.playback}
94+
/>
95+
<FlatList
96+
style={styles.list}
97+
extraData={this.state.offlineVideos}
98+
data={this.state.videos}
99+
keyExtractor={item => item.referenceId}
100+
renderItem={({ item }) => {
101+
const downloadStatus = this.state.offlineVideos.find(
102+
video => video.videoId === item.videoId
103+
);
104+
return (
105+
<View style={styles.listItem}>
106+
<TouchableOpacity
107+
style={styles.mainButton}
108+
onPress={() => this.play(item)}
109+
>
110+
<BrightcovePlayerPoster
111+
style={styles.poster}
112+
accountId={ACCOUNT_ID}
113+
policyKey={POLICY_KEY}
114+
referenceId={item.referenceId}
115+
/>
116+
<View style={styles.body}>
117+
<Text style={styles.name}>{item.name}</Text>
118+
<Text>{item.description}</Text>
119+
{downloadStatus ? (
120+
<Text style={styles.offlineBanner}>
121+
{downloadStatus.downloadProgress === 1
122+
? 'OFFLINE PLAYBACK'
123+
: `DOWNLOADING: ${Math.floor(
124+
downloadStatus.downloadProgress * 100
125+
)}%`}
126+
</Text>
127+
) : null}
128+
<Text style={styles.duration}>
129+
{`0${Math.floor(item.duration / 60000) % 60}`.substr(-2)}:
130+
{`0${Math.floor(item.duration / 1000) % 60}`.substr(-2)}
131+
</Text>
132+
</View>
133+
</TouchableOpacity>
134+
<TouchableOpacity
135+
style={styles.downloadButton}
136+
onPress={() => {
137+
if (!downloadStatus) {
138+
this.requestDownload(item.videoId);
139+
} else {
140+
this.delete(downloadStatus.videoToken);
141+
}
142+
}}
143+
>
144+
<Text>
145+
{!downloadStatus
146+
? '💾'
147+
: downloadStatus.downloadProgress === 1
148+
? '🗑'
149+
: '⏳'}
150+
</Text>
151+
</TouchableOpacity>
152+
</View>
153+
);
154+
}}
155+
/>
156+
</View>
157+
);
158+
}
159+
}
74160

75161
const styles = StyleSheet.create({
76-
scrollView: {
77-
backgroundColor: Colors.lighter,
162+
container: {
163+
flex: 1,
164+
flexDirection: 'column'
78165
},
79-
engine: {
80-
position: 'absolute',
81-
right: 0,
166+
video: {
167+
width: '100%',
168+
height: 260
82169
},
83-
body: {
84-
backgroundColor: Colors.white,
170+
list: {
171+
flex: 1
172+
},
173+
listItem: {
174+
flexDirection: 'row',
175+
borderBottomWidth: 1,
176+
borderBottomColor: 'lightgray'
85177
},
86-
sectionContainer: {
87-
marginTop: 32,
88-
paddingHorizontal: 24,
178+
mainButton: {
179+
flex: 1,
180+
flexDirection: 'row'
89181
},
90-
sectionTitle: {
91-
fontSize: 24,
92-
fontWeight: '600',
93-
color: Colors.black,
182+
body: {
183+
flex: 1,
184+
padding: 10,
185+
flexDirection: 'column'
94186
},
95-
sectionDescription: {
96-
marginTop: 8,
97-
fontSize: 18,
98-
fontWeight: '400',
99-
color: Colors.dark,
187+
name: {
188+
fontSize: 14,
189+
fontWeight: 'bold'
100190
},
101-
highlight: {
102-
fontWeight: '700',
191+
offlineBanner: {
192+
fontSize: 10,
193+
fontWeight: 'bold',
194+
color: 'white',
195+
alignSelf: 'flex-start',
196+
padding: 3,
197+
backgroundColor: 'deepskyblue'
103198
},
104-
footer: {
105-
color: Colors.dark,
106-
fontSize: 12,
107-
fontWeight: '600',
108-
padding: 4,
109-
paddingRight: 12,
110-
textAlign: 'right',
199+
duration: {
200+
marginTop: 'auto',
201+
opacity: 0.5
111202
},
203+
poster: {
204+
width: 100,
205+
height: 100,
206+
backgroundColor: 'black'
207+
},
208+
downloadButton: {
209+
padding: 16,
210+
marginLeft: 'auto',
211+
alignSelf: 'center'
212+
}
112213
});
113-
114-
export default App;

example/package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
},
1212
"dependencies": {
1313
"react": "16.9.0",
14-
"react-native": "0.61.2"
14+
"react-native": "0.61.2",
15+
"react-native-brightcove-player": "1.7.0"
1516
},
1617
"devDependencies": {
1718
"@babel/core": "^7.6.4",

example/yarn.lock

+7-1
Original file line numberDiff line numberDiff line change
@@ -5088,7 +5088,7 @@ prompts@^2.0.1:
50885088
kleur "^3.0.3"
50895089
sisteransi "^1.0.3"
50905090

5091-
prop-types@^15.6.2, prop-types@^15.7.2:
5091+
prop-types@^15.5.10, prop-types@^15.6.2, prop-types@^15.7.2:
50925092
version "15.7.2"
50935093
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
50945094
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
@@ -5158,6 +5158,12 @@ react-is@^16.8.1, react-is@^16.8.4, react-is@^16.9.0:
51585158
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.10.2.tgz#984120fd4d16800e9a738208ab1fba422d23b5ab"
51595159
integrity sha512-INBT1QEgtcCCgvccr5/86CfD71fw9EPmDxgiJX4I2Ddr6ZsV6iFXsuby+qWJPtmNuMY0zByTsG4468P7nHuNWA==
51605160

5161+
"react-native-brightcove-player@https://github.com/manse/react-native-brightcove-player.git#rn60":
5162+
version "1.6.7"
5163+
resolved "https://github.com/manse/react-native-brightcove-player.git#7ffbd93557d56910bd5e007914849d6eba4e51a7"
5164+
dependencies:
5165+
prop-types "^15.5.10"
5166+
51615167
51625168
version "0.61.2"
51635169
resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.61.2.tgz#987b91b063557f8ebec803fdfea2044a24bdbe4d"

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-native-brightcove-player",
3-
"version": "1.6.7",
3+
"version": "1.7.0",
44
"description": "A React Native implementation of Brightcove Player SDK.",
55
"main": "index.js",
66
"repository": {

0 commit comments

Comments
 (0)