From a89d8ac229d3d3742dd061931c705bbdc5e2ef21 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Fri, 25 May 2018 18:39:02 +0100 Subject: [PATCH] add support for viewing images, HTML and text files in the app --- app/package-lock.json | 15 ++- app/package.json | 1 + app/src/component/fileDownloadButton/view.js | 8 +- app/src/page/file/view.js | 113 +++++++++++++------ app/src/styles/filePage.js | 9 ++ 5 files changed, 106 insertions(+), 40 deletions(-) diff --git a/app/package-lock.json b/app/package-lock.json index 26573f87..7b5fc652 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -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", diff --git a/app/package.json b/app/package.json index b5e54e15..72c1b095 100644 --- a/app/package.json +++ b/app/package.json @@ -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", diff --git a/app/src/component/fileDownloadButton/view.js b/app/src/component/fileDownloadButton/view.js index 5eb2993e..883d7b78 100644 --- a/app/src/component/fileDownloadButton/view.js +++ b/app/src/component/fileDownloadButton/view.js @@ -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 ( - openFile()}> + Open ); diff --git a/app/src/page/file/view.js b/app/src/page/file/view.js index d5ee3487..fd887e02 100644 --- a/app/src/page/file/view.js +++ b/app/src/page/file/view.js @@ -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 = ( - - {(!fileInfo || (isPlayable && !canLoadMedia)) && - } - {isPlayable && !this.state.mediaLoaded && } - {!completed && !canLoadMedia && } - {!fileInfo && } - - {canLoadMedia && } - {canLoadMedia && { this.setState({ mediaLoaded: true }); }}/>} - - { showActions && - - {completed &&