show animated activity indicator after the user presses the Play button #261

Merged
akinwale merged 3 commits from play-ux into master 2018-08-27 17:53:04 +02:00
7 changed files with 56 additions and 41 deletions

View file

@ -12,7 +12,8 @@ export default class Button extends React.PureComponent {
text, text,
icon, icon,
theme, theme,
onPress onPress,
onLayout
} = this.props; } = this.props;
let styles = [buttonStyle.button, buttonStyle.row]; let styles = [buttonStyle.button, buttonStyle.row];
@ -41,7 +42,7 @@ export default class Button extends React.PureComponent {
} }
return ( return (
<TouchableOpacity disabled={disabled} style={styles} onPress={onPress}> <TouchableOpacity disabled={disabled} style={styles} onPress={onPress} onLayout={onLayout}>
{icon && <Icon name={icon} size={18} color={'light' === theme ? Colors.DarkGrey : Colors.White} />} {icon && <Icon name={icon} size={18} color={'light' === theme ? Colors.DarkGrey : Colors.White} />}
{text && (text.trim().length > 0) && <Text style={textStyles}>{text}</Text>} {text && (text.trim().length > 0) && <Text style={textStyles}>{text}</Text>}
</TouchableOpacity> </TouchableOpacity>

View file

@ -42,7 +42,8 @@ class FileDownloadButton extends React.PureComponent {
loading, loading,
doPause, doPause,
style, style,
openFile openFile,
onButtonLayout
} = this.props; } = this.props;
if (loading || downloading) { if (loading || downloading) {
@ -67,6 +68,7 @@ class FileDownloadButton extends React.PureComponent {
return ( return (
<Button icon={isPlayable ? 'play' : null} <Button icon={isPlayable ? 'play' : null}
text={isPlayable ? 'Play' : 'Download'} text={isPlayable ? 'Play' : 'Download'}
onLayout={onButtonLayout}
style={[style, fileDownloadButtonStyle.container]} onPress={() => { style={[style, fileDownloadButtonStyle.container]} onPress={() => {
if (NativeModules.Mixpanel) { if (NativeModules.Mixpanel) {
NativeModules.Mixpanel.track('Purchase Uri', { Uri: uri }); NativeModules.Mixpanel.track('Purchase Uri', { Uri: uri });
@ -79,7 +81,8 @@ class FileDownloadButton extends React.PureComponent {
); );
} else if (fileInfo && fileInfo.download_path) { } else if (fileInfo && fileInfo.download_path) {
return ( return (
<TouchableOpacity style={[style, fileDownloadButtonStyle.container]} onPress={openFile}> <TouchableOpacity onLayout={onButtonLayout}
style={[style, fileDownloadButtonStyle.container]} onPress={openFile}>
<Text style={fileDownloadButtonStyle.text}>Open</Text> <Text style={fileDownloadButtonStyle.text}>Open</Text>
</TouchableOpacity> </TouchableOpacity>
); );

View file

@ -43,6 +43,8 @@ class FilePage extends React.PureComponent {
this.state = { this.state = {
mediaLoaded: false, mediaLoaded: false,
autoplayMedia: false, autoplayMedia: false,
downloadButtonShown: false,
downloadPressed: false,
fullscreenMode: false, fullscreenMode: false,
showImageViewer: false, showImageViewer: false,
showWebView: false, showWebView: false,
@ -123,7 +125,10 @@ class FilePage extends React.PureComponent {
'Are you sure you want to remove this file from your device?', 'Are you sure you want to remove this file from your device?',
[ [
{ text: 'No' }, { text: 'No' },
{ text: 'Yes', onPress: () => { deleteFile(fileInfo.outpoint, true); } } { text: 'Yes', onPress: () => {
deleteFile(fileInfo.outpoint, true);
this.setState({ downloadPressed: false, mediaLoaded: false });
}}
], ],
{ cancelable: true } { cancelable: true }
); );
@ -137,7 +142,10 @@ class FilePage extends React.PureComponent {
'Are you sure you want to stop downloading this file?', 'Are you sure you want to stop downloading this file?',
[ [
{ text: 'No' }, { text: 'No' },
{ text: 'Yes', onPress: () => { stopDownload(navigation.state.params.uri, fileInfo); } } { text: 'Yes', onPress: () => {
stopDownload(navigation.state.params.uri, fileInfo);
this.setState({ downloadPressed: false, mediaLoaded: false });
} }
], ],
{ cancelable: true } { cancelable: true }
); );
@ -305,40 +313,43 @@ class FilePage extends React.PureComponent {
<View style={filePageStyle.mediaContainer}> <View style={filePageStyle.mediaContainer}>
{(canOpen || (!fileInfo || (isPlayable && !canLoadMedia))) && {(canOpen || (!fileInfo || (isPlayable && !canLoadMedia))) &&
<FileItemMedia style={filePageStyle.thumbnail} title={title} thumbnail={metadata.thumbnail} />} <FileItemMedia style={filePageStyle.thumbnail} title={title} thumbnail={metadata.thumbnail} />}
{(canOpen || (isPlayable && !this.state.mediaLoaded)) && <ActivityIndicator size="large" color={Colors.LbryGreen} style={filePageStyle.loading} />} {((!this.state.downloadButtonShown || this.state.downloadPressed) && !this.state.mediaLoaded) &&
{((isPlayable && !completed && !canLoadMedia) || !completed || canOpen) && <ActivityIndicator size="large" color={Colors.LbryGreen} style={filePageStyle.loading} />}
{((isPlayable && !completed && !canLoadMedia) || !completed || canOpen) && (!this.state.downloadPressed) &&
<FileDownloadButton uri={uri} <FileDownloadButton uri={uri}
style={filePageStyle.downloadButton} style={filePageStyle.downloadButton}
openFile={openFile} openFile={openFile}
isPlayable={isPlayable} isPlayable={isPlayable}
onPlay={() => this.setState({ autoPlayMedia: true })} />} onPlay={() => this.setState({ downloadPressed: true, autoPlayMedia: true })}
onButtonLayout={() => this.setState({ downloadButtonShown: true })} />}
{!fileInfo && <FilePrice uri={uri} style={filePageStyle.filePriceContainer} textStyle={filePageStyle.filePriceText} />} {!fileInfo && <FilePrice uri={uri} style={filePageStyle.filePriceContainer} textStyle={filePageStyle.filePriceText} />}
</View> </View>
{canLoadMedia && <View style={playerBgStyle} ref={(ref) => { this.playerBackground = ref; }} {canLoadMedia && fileInfo && <View style={playerBgStyle}
onLayout={(evt) => { ref={(ref) => { this.playerBackground = ref; }}
if (!this.state.playerBgHeight) { onLayout={(evt) => {
this.setState({ playerBgHeight: evt.nativeEvent.layout.height }); if (!this.state.playerBgHeight) {
} this.setState({ playerBgHeight: evt.nativeEvent.layout.height });
}} />} }
{canLoadMedia && <MediaPlayer fileInfo={fileInfo} }} />}
ref={(ref) => { this.player = ref; }} {canLoadMedia && fileInfo && <MediaPlayer fileInfo={fileInfo}
uri={uri} ref={(ref) => { this.player = ref; }}
style={playerStyle} uri={uri}
autoPlay={this.state.autoPlayMedia} style={playerStyle}
onFullscreenToggled={this.handleFullscreenToggle} autoPlay={this.state.autoPlayMedia}
onMediaLoaded={() => { onFullscreenToggled={this.handleFullscreenToggle}
this.setState({ mediaLoaded: true }); onMediaLoaded={() => {
window.currentMediaInfo = { this.setState({ mediaLoaded: true });
title: title, window.currentMediaInfo = {
channel: channelName title: title,
}; channel: channelName
}} };
onLayout={(evt) => { }}
if (!this.state.playerHeight) { onLayout={(evt) => {
this.setState({ playerHeight: evt.nativeEvent.layout.height }); if (!this.state.playerHeight) {
} this.setState({ playerHeight: evt.nativeEvent.layout.height });
}} }
/>} }}
/>}
{ showActions && { showActions &&
<View style={filePageStyle.actions}> <View style={filePageStyle.actions}>

View file

@ -146,11 +146,13 @@ const filePageStyle = StyleSheet.create({
paddingTop: 16, paddingTop: 16,
paddingBottom: 8, paddingBottom: 8,
marginTop: -14, marginTop: -14,
width: '50%', width: '100%',
}, },
actionButton: { actionButton: {
alignSelf: 'flex-start',
backgroundColor: Colors.White, backgroundColor: Colors.White,
width: 160 paddingLeft: 24,
paddingRight: 24
}, },
loading: { loading: {
position: 'absolute', position: 'absolute',

View file

@ -36,7 +36,7 @@ version.filename = %(source.dir)s/main.py
# (list) Application requirements # (list) Application requirements
# comma seperated e.g. requirements = sqlite3,kivy # comma seperated e.g. requirements = sqlite3,kivy
requirements = openssl, sqlite3, hostpython2, android, distro, pyjnius, certifi==2018.4.16, constantly, incremental, functools32, miniupnpc==1.9, gmpy==1.17, twisted==16.6.0, appdirs==1.4.3, argparse==1.2.1, docopt==0.6.2, base58==0.2.2, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse==0.2.0, jsonrpc==1.2, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2==1.3, pyyaml==3.12, qrcode==5.2.2, requests==2.9.1, seccure==0.3.1.3, attrs==18.1.0, pyasn1, pyasn1-modules, service_identity==16.0.0, six==1.9.0, slowaes==0.1a1, txJSON-RPC==0.5, wsgiref==0.1.2, zope.interface==4.3.3, protobuf==3.2.0, keyring==10.4.0, netifaces, txupnp==0.0.1a10, git+https://github.com/lbryio/lbryschema.git@v0.0.16#egg=lbryschema, git+https://github.com/lbryio/lbryum.git#egg=lbryum, git+https://github.com/lbryio/lbry.git#egg=lbrynet, asn1crypto, cryptography==2.2.2, pyopenssl==17.4.0, treq==17.8.0, funcsigs, mock, pbr, unqlite requirements = openssl, sqlite3, hostpython2, android, distro, pyjnius, certifi==2018.4.16, constantly, incremental, functools32, miniupnpc==1.9, gmpy==1.17, twisted==16.6.0, appdirs==1.4.3, argparse==1.2.1, docopt==0.6.2, base58==0.2.2, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse==0.2.0, jsonrpc==1.2, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2==1.3, pyyaml==3.12, qrcode==5.2.2, requests==2.9.1, seccure==0.3.1.3, attrs==18.1.0, pyasn1, pyasn1-modules, service_identity==16.0.0, six==1.9.0, slowaes==0.1a1, txJSON-RPC==0.5, wsgiref==0.1.2, zope.interface==4.3.3, protobuf==3.2.0, keyring==10.4.0, netifaces, txupnp==0.0.1a10, git+https://github.com/lbryio/lbryschema.git@v0.0.16#egg=lbryschema, git+https://github.com/lbryio/lbryum.git#egg=lbryum, git+https://github.com/lbryio/lbry.git@v0.21.2#egg=lbrynet, asn1crypto, cryptography==2.2.2, pyopenssl==17.4.0, treq==17.8.0, funcsigs, mock, pbr, unqlite
# (str) Custom source folders for requirements # (str) Custom source folders for requirements
# Sets custom source for any requirements with recipes # Sets custom source for any requirements with recipes

View file

@ -36,7 +36,7 @@ version.filename = %(source.dir)s/main.py
# (list) Application requirements # (list) Application requirements
# comma seperated e.g. requirements = sqlite3,kivy # comma seperated e.g. requirements = sqlite3,kivy
requirements = openssl, sqlite3, hostpython2, android, distro, pyjnius, certifi==2018.4.16, constantly, incremental, functools32, miniupnpc==1.9, gmpy==1.17, twisted==16.6.0, appdirs==1.4.3, argparse==1.2.1, docopt==0.6.2, base58==0.2.2, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse==0.2.0, jsonrpc==1.2, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2==1.3, pyyaml==3.12, qrcode==5.2.2, requests==2.9.1, seccure==0.3.1.3, attrs==18.1.0, pyasn1, pyasn1-modules, service_identity==16.0.0, six==1.9.0, slowaes==0.1a1, txJSON-RPC==0.5, wsgiref==0.1.2, zope.interface==4.3.3, protobuf==3.2.0, keyring==10.4.0, netifaces, txupnp==0.0.1a10, git+https://github.com/lbryio/lbryschema.git@v0.0.16#egg=lbryschema, git+https://github.com/lbryio/lbryum.git#egg=lbryum, git+https://github.com/lbryio/lbry.git#egg=lbrynet, asn1crypto, cryptography==2.2.2, pyopenssl==17.4.0, treq==17.8.0, funcsigs, mock, pbr, unqlite requirements = openssl, sqlite3, hostpython2, android, distro, pyjnius, certifi==2018.4.16, constantly, incremental, functools32, miniupnpc==1.9, gmpy==1.17, twisted==16.6.0, appdirs==1.4.3, argparse==1.2.1, docopt==0.6.2, base58==0.2.2, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse==0.2.0, jsonrpc==1.2, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2==1.3, pyyaml==3.12, qrcode==5.2.2, requests==2.9.1, seccure==0.3.1.3, attrs==18.1.0, pyasn1, pyasn1-modules, service_identity==16.0.0, six==1.9.0, slowaes==0.1a1, txJSON-RPC==0.5, wsgiref==0.1.2, zope.interface==4.3.3, protobuf==3.2.0, keyring==10.4.0, netifaces, txupnp==0.0.1a10, git+https://github.com/lbryio/lbryschema.git@v0.0.16#egg=lbryschema, git+https://github.com/lbryio/lbryum.git#egg=lbryum, git+https://github.com/lbryio/lbry.git@v0.21.2#egg=lbrynet, asn1crypto, cryptography==2.2.2, pyopenssl==17.4.0, treq==17.8.0, funcsigs, mock, pbr, unqlite
# (str) Custom source folders for requirements # (str) Custom source folders for requirements
# Sets custom source for any requirements with recipes # Sets custom source for any requirements with recipes

View file

@ -36,7 +36,7 @@ version.filename = %(source.dir)s/main.py
# (list) Application requirements # (list) Application requirements
# comma seperated e.g. requirements = sqlite3,kivy # comma seperated e.g. requirements = sqlite3,kivy
requirements = openssl, sqlite3, hostpython2, android, distro, pyjnius, certifi==2018.4.16, constantly, incremental, functools32, miniupnpc==1.9, gmpy==1.17, twisted==16.6.0, appdirs==1.4.3, argparse==1.2.1, docopt==0.6.2, base58==0.2.2, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse==0.2.0, jsonrpc==1.2, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2==1.3, pyyaml==3.12, qrcode==5.2.2, requests==2.9.1, seccure==0.3.1.3, attrs==18.1.0, pyasn1, pyasn1-modules, service_identity==16.0.0, six==1.9.0, slowaes==0.1a1, txJSON-RPC==0.5, wsgiref==0.1.2, zope.interface==4.3.3, protobuf==3.2.0, keyring==10.4.0, netifaces, txupnp==0.0.1a10, git+https://github.com/lbryio/lbryschema.git@v0.0.16#egg=lbryschema, git+https://github.com/lbryio/lbryum.git#egg=lbryum, git+https://github.com/lbryio/lbry.git#egg=lbrynet, asn1crypto, cryptography==2.2.2, pyopenssl==17.4.0, treq==17.8.0, funcsigs, mock, pbr, unqlite requirements = openssl, sqlite3, hostpython2, android, distro, pyjnius, certifi==2018.4.16, constantly, incremental, functools32, miniupnpc==1.9, gmpy==1.17, twisted==16.6.0, appdirs==1.4.3, argparse==1.2.1, docopt==0.6.2, base58==0.2.2, colorama==0.3.7, dnspython==1.12.0, ecdsa==0.13, envparse==0.2.0, jsonrpc==1.2, jsonrpclib==0.1.7, jsonschema==2.5.1, pbkdf2==1.3, pyyaml==3.12, qrcode==5.2.2, requests==2.9.1, seccure==0.3.1.3, attrs==18.1.0, pyasn1, pyasn1-modules, service_identity==16.0.0, six==1.9.0, slowaes==0.1a1, txJSON-RPC==0.5, wsgiref==0.1.2, zope.interface==4.3.3, protobuf==3.2.0, keyring==10.4.0, netifaces, txupnp==0.0.1a10, git+https://github.com/lbryio/lbryschema.git@v0.0.16#egg=lbryschema, git+https://github.com/lbryio/lbryum.git#egg=lbryum, git+https://github.com/lbryio/lbry.git@v0.21.2#egg=lbrynet, asn1crypto, cryptography==2.2.2, pyopenssl==17.4.0, treq==17.8.0, funcsigs, mock, pbr, unqlite
# (str) Custom source folders for requirements # (str) Custom source folders for requirements
# Sets custom source for any requirements with recipes # Sets custom source for any requirements with recipes
@ -272,5 +272,3 @@ warn_on_root = 1
# Then, invoke the command line with the "demo" profile: # Then, invoke the command line with the "demo" profile:
# #
#buildozer --profile demo android debug #buildozer --profile demo android debug
builddir = /home/vagrant