add support for viewing images, HTML and text files in the app
This commit is contained in:
parent
3c8e7d13e0
commit
a89d8ac229
5 changed files with 106 additions and 40 deletions
15
app/package-lock.json
generated
15
app/package-lock.json
generated
|
@ -3953,7 +3953,7 @@
|
|||
}
|
||||
},
|
||||
"lbry-redux": {
|
||||
"version": "github:lbryio/lbry-redux#30c18725d8c6c141c30c57f0a324d0abb8963b99",
|
||||
"version": "github:lbryio/lbry-redux#8cbeed792906335577bbf4382a2707f8e463e242",
|
||||
"requires": {
|
||||
"proxy-polyfill": "0.1.6",
|
||||
"reselect": "3.0.1"
|
||||
|
@ -5174,6 +5174,19 @@
|
|||
"react-native-drawer-layout": "1.3.2"
|
||||
}
|
||||
},
|
||||
"react-native-image-pan-zoom": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/react-native-image-pan-zoom/-/react-native-image-pan-zoom-2.1.3.tgz",
|
||||
"integrity": "sha512-KnuSM0Rs+XD7EFovgJfGsU/Bl0sFIvqTZQ04hebW9dtuKekBOBMEEnuuvTxrktbBBhzDlwgxRrVWlTt6PGREDw=="
|
||||
},
|
||||
"react-native-image-zoom-viewer": {
|
||||
"version": "2.2.5",
|
||||
"resolved": "https://registry.npmjs.org/react-native-image-zoom-viewer/-/react-native-image-zoom-viewer-2.2.5.tgz",
|
||||
"integrity": "sha512-kXpetilVqHajZDYrc8QjPEmB7wRNxoOlmtZaATshNZKUp7DABL7lubdKxqfC3GiFuvVfp6Ei8hkaADRF53AeTw==",
|
||||
"requires": {
|
||||
"react-native-image-pan-zoom": "2.1.3"
|
||||
}
|
||||
},
|
||||
"react-native-safe-area-view": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-safe-area-view/-/react-native-safe-area-view-0.7.0.tgz",
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
"moment": "^2.22.1",
|
||||
"react": "16.2.0",
|
||||
"react-native": "0.55.3",
|
||||
"react-native-image-zoom-viewer": "^2.2.5",
|
||||
"react-native-vector-icons": "^4.5.0",
|
||||
"react-native-video": "2.0.0",
|
||||
"react-navigation": "^1.5.12",
|
||||
|
|
|
@ -39,13 +39,9 @@ class FileDownloadButton extends React.PureComponent {
|
|||
loading,
|
||||
doPause,
|
||||
style,
|
||||
openFile
|
||||
} = this.props;
|
||||
|
||||
const openFile = () => {
|
||||
//openInShell(fileInfo.download_path);
|
||||
//doPause();
|
||||
};
|
||||
|
||||
if (loading || downloading) {
|
||||
const progress =
|
||||
fileInfo && fileInfo.written_bytes ? fileInfo.written_bytes / fileInfo.total_bytes * 100 : 0,
|
||||
|
@ -77,7 +73,7 @@ class FileDownloadButton extends React.PureComponent {
|
|||
);
|
||||
} else if (fileInfo && fileInfo.download_path) {
|
||||
return (
|
||||
<TouchableOpacity style={[style, fileDownloadButtonStyle.container]} onPress={() => openFile()}>
|
||||
<TouchableOpacity style={[style, fileDownloadButtonStyle.container]} onPress={openFile}>
|
||||
<Text style={fileDownloadButtonStyle.text}>Open</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
|
|
|
@ -4,14 +4,17 @@ import {
|
|||
ActivityIndicator,
|
||||
Alert,
|
||||
Button,
|
||||
Text,
|
||||
TextInput,
|
||||
View,
|
||||
NativeModules,
|
||||
ScrollView,
|
||||
StatusBar,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TextInput,
|
||||
TouchableOpacity,
|
||||
NativeModules
|
||||
View,
|
||||
WebView
|
||||
} from 'react-native';
|
||||
import ImageViewer from 'react-native-image-zoom-viewer';
|
||||
import Colors from '../../styles/colors';
|
||||
import ChannelPage from '../channel';
|
||||
import FileDownloadButton from '../../component/fileDownloadButton';
|
||||
|
@ -31,7 +34,10 @@ class FilePage extends React.PureComponent {
|
|||
super(props);
|
||||
this.state = {
|
||||
mediaLoaded: false,
|
||||
fullscreenMode: false
|
||||
fullscreenMode: false,
|
||||
showImageViewer: false,
|
||||
showWebView: false,
|
||||
imageUrls: null
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -120,6 +126,13 @@ class FilePage extends React.PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
localUriForFileInfo = (fileInfo) => {
|
||||
if (!fileInfo) {
|
||||
return null;
|
||||
}
|
||||
return 'file:///' + fileInfo.download_path;
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
claim,
|
||||
|
@ -163,7 +176,7 @@ class FilePage extends React.PureComponent {
|
|||
const mediaType = Lbry.getMediaType(contentType);
|
||||
const isPlayable = mediaType === 'video' || mediaType === 'audio';
|
||||
const { height, channel_name: channelName, value } = claim;
|
||||
const showActions = !this.state.fullscreenMode &&
|
||||
const showActions = !this.state.fullscreenMode && !this.state.showImageViewer && !this.state.showWebView &&
|
||||
(completed || (fileInfo && !fileInfo.stopped && fileInfo.written_bytes < fileInfo.total_bytes));
|
||||
const channelClaimId =
|
||||
value && value.publisherSignature && value.publisherSignature.certificateId;
|
||||
|
@ -175,35 +188,69 @@ class FilePage extends React.PureComponent {
|
|||
// at least 2MB (or the full download) before media can be loaded
|
||||
const canLoadMedia = fileInfo &&
|
||||
(fileInfo.written_bytes >= 2097152 || fileInfo.written_bytes == fileInfo.total_bytes); // 2MB = 1024*1024*2
|
||||
|
||||
const canOpen = (mediaType === 'image' || mediaType === 'text') && completed;
|
||||
const isWebViewable = mediaType === 'text';
|
||||
const localFileUri = this.localUriForFileInfo(fileInfo);
|
||||
|
||||
const openFile = () => {
|
||||
if (mediaType === 'image') {
|
||||
// use image viewer
|
||||
this.setState({
|
||||
imageUrls: [{
|
||||
url: localFileUri
|
||||
}],
|
||||
showImageViewer: true
|
||||
});
|
||||
}
|
||||
if (isWebViewable) {
|
||||
// show webview
|
||||
this.setState({
|
||||
showWebView: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
innerContent = (
|
||||
<View style={filePageStyle.pageContainer}>
|
||||
<View style={filePageStyle.mediaContainer}>
|
||||
{(!fileInfo || (isPlayable && !canLoadMedia)) &&
|
||||
<FileItemMedia style={filePageStyle.thumbnail} title={title} thumbnail={metadata.thumbnail} />}
|
||||
{isPlayable && !this.state.mediaLoaded && <ActivityIndicator size="large" color={Colors.LbryGreen} style={filePageStyle.loading} />}
|
||||
{!completed && !canLoadMedia && <FileDownloadButton uri={uri} style={filePageStyle.downloadButton} />}
|
||||
{!fileInfo && <FilePrice uri={uri} style={filePageStyle.filePriceContainer} textStyle={filePageStyle.filePriceText} />}
|
||||
</View>
|
||||
{canLoadMedia && <View style={playerBgStyle} />}
|
||||
{canLoadMedia && <MediaPlayer fileInfo={fileInfo}
|
||||
uri={uri}
|
||||
style={playerStyle}
|
||||
onFullscreenToggled={this.handleFullscreenToggle}
|
||||
onMediaLoaded={() => { this.setState({ mediaLoaded: true }); }}/>}
|
||||
|
||||
{ showActions &&
|
||||
<View style={filePageStyle.actions}>
|
||||
{completed && <Button color="red" title="Delete" onPress={this.onDeletePressed} />}
|
||||
{!completed && fileInfo && !fileInfo.stopped && fileInfo.written_bytes < fileInfo.total_bytes &&
|
||||
<Button color="red" title="Stop Download" onPress={this.onStopDownloadPressed} />
|
||||
}
|
||||
</View>}
|
||||
<ScrollView style={showActions ? filePageStyle.scrollContainerActions : filePageStyle.scrollContainer}>
|
||||
<Text style={filePageStyle.title} selectable={true}>{title}</Text>
|
||||
{channelName && <Text style={filePageStyle.channelName} selectable={true}>{channelName}</Text>}
|
||||
{description && <Text style={filePageStyle.description} selectable={true}>{description}</Text>}
|
||||
</ScrollView>
|
||||
{this.state.showWebView && isWebViewable && <WebView source={{ uri: localFileUri }}
|
||||
style={filePageStyle.viewer} />}
|
||||
|
||||
{this.state.showImageViewer && <ImageViewer style={StyleSheet.flatten(filePageStyle.viewer)}
|
||||
imageUrls={this.state.imageUrls}
|
||||
renderIndicator={() => null} />}
|
||||
|
||||
{!this.state.showWebView && (
|
||||
<View style={filePageStyle.pageContainer}>
|
||||
<View style={filePageStyle.mediaContainer}>
|
||||
{(canOpen || (!fileInfo || (isPlayable && !canLoadMedia))) &&
|
||||
<FileItemMedia style={filePageStyle.thumbnail} title={title} thumbnail={metadata.thumbnail} />}
|
||||
{(canOpen || (isPlayable && !this.state.mediaLoaded)) && <ActivityIndicator size="large" color={Colors.LbryGreen} style={filePageStyle.loading} />}
|
||||
{((isPlayable && !completed && !canLoadMedia) || !completed || canOpen) &&
|
||||
<FileDownloadButton uri={uri} style={filePageStyle.downloadButton} openFile={openFile} />}
|
||||
{!fileInfo && <FilePrice uri={uri} style={filePageStyle.filePriceContainer} textStyle={filePageStyle.filePriceText} />}
|
||||
</View>
|
||||
{canLoadMedia && <View style={playerBgStyle} />}
|
||||
{canLoadMedia && <MediaPlayer fileInfo={fileInfo}
|
||||
uri={uri}
|
||||
style={playerStyle}
|
||||
onFullscreenToggled={this.handleFullscreenToggle}
|
||||
onMediaLoaded={() => { this.setState({ mediaLoaded: true }); }}/>}
|
||||
|
||||
{ showActions &&
|
||||
<View style={filePageStyle.actions}>
|
||||
{completed && <Button color="red" title="Delete" onPress={this.onDeletePressed} />}
|
||||
{!completed && fileInfo && !fileInfo.stopped && fileInfo.written_bytes < fileInfo.total_bytes &&
|
||||
<Button color="red" title="Stop Download" onPress={this.onStopDownloadPressed} />
|
||||
}
|
||||
</View>}
|
||||
<ScrollView style={showActions ? filePageStyle.scrollContainerActions : filePageStyle.scrollContainer}>
|
||||
<Text style={filePageStyle.title} selectable={true}>{title}</Text>
|
||||
{channelName && <Text style={filePageStyle.channelName} selectable={true}>{channelName}</Text>}
|
||||
{description && <Text style={filePageStyle.description} selectable={true}>{description}</Text>}
|
||||
</ScrollView>
|
||||
</View>
|
||||
)}
|
||||
|
||||
<UriBar value={uri} navigation={navigation} />
|
||||
</View>
|
||||
);
|
||||
|
|
|
@ -143,6 +143,15 @@ const filePageStyle = StyleSheet.create({
|
|||
fontSize: 20,
|
||||
textAlign: 'center',
|
||||
marginLeft: 10
|
||||
},
|
||||
viewer: {
|
||||
position: 'absolute',
|
||||
flex: 1,
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
zIndex: 100
|
||||
}
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue