fixes before release #95

Merged
akinwale merged 2 commits from pre-release-fixes into master 2019-12-11 09:06:11 +01:00
7 changed files with 156 additions and 83 deletions
Showing only changes of commit 6fe9e9a5f7 - Show all commits

View file

@ -95,6 +95,7 @@ const Constants = {
FULL_ROUTE_NAME_WALLET: 'WalletStack', FULL_ROUTE_NAME_WALLET: 'WalletStack',
ROUTE_FILE: 'File', ROUTE_FILE: 'File',
DRAWER_ROUTE_FILE_VIEW: 'FileView',
ITEM_CREATE_A_CHANNEL: 'Create a channel...', ITEM_CREATE_A_CHANNEL: 'Create a channel...',
ITEM_ANONYMOUS: 'Publish anonymously', ITEM_ANONYMOUS: 'Publish anonymously',
@ -167,4 +168,8 @@ export const DrawerRoutes = [
]; ];
// sub-pages for main routes // sub-pages for main routes
export const InnerDrawerRoutes = [Constants.DRAWER_ROUTE_CHANNEL_CREATOR_FORM, Constants.DRAWER_ROUTE_PUBLISH_FORM]; export const InnerDrawerRoutes = [
Constants.DRAWER_ROUTE_CHANNEL_CREATOR_FORM,
Constants.DRAWER_ROUTE_PUBLISH_FORM,
Constants.DRAWER_ROUTE_FILE_VIEW,
];

View file

@ -44,7 +44,7 @@ import {
doDeleteFile, doDeleteFile,
doStopDownloadingFile, doStopDownloadingFile,
} from 'redux/actions/file'; } from 'redux/actions/file';
import { doPopDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer'; import { doPushDrawerStack, doPopDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer';
import { doToggleFullscreenMode } from 'redux/actions/settings'; import { doToggleFullscreenMode } from 'redux/actions/settings';
import { selectDrawerStack } from 'redux/selectors/drawer'; import { selectDrawerStack } from 'redux/selectors/drawer';
import FilePage from './view'; import FilePage from './view';
@ -92,6 +92,7 @@ const perform = dispatch => ({
fileGet: (uri, saveFile) => dispatch(doFileGet(uri, saveFile)), fileGet: (uri, saveFile) => dispatch(doFileGet(uri, saveFile)),
notify: data => dispatch(doToast(data)), notify: data => dispatch(doToast(data)),
popDrawerStack: () => dispatch(doPopDrawerStack()), popDrawerStack: () => dispatch(doPopDrawerStack()),
pushDrawerStack: (routeName, params) => dispatch(doPushDrawerStack(routeName, params)),
purchaseUri: (uri, costInfo, saveFile) => dispatch(doPurchaseUri(uri, costInfo, saveFile)), purchaseUri: (uri, costInfo, saveFile) => dispatch(doPurchaseUri(uri, costInfo, saveFile)),
deletePurchasedUri: uri => dispatch(doDeletePurchasedUri(uri)), deletePurchasedUri: uri => dispatch(doDeletePurchasedUri(uri)),
resolveUri: uri => dispatch(doResolveUri(uri)), resolveUri: uri => dispatch(doResolveUri(uri)),

View file

@ -44,6 +44,7 @@ import Video from 'react-native-video';
import FileRewardsDriver from 'component/fileRewardsDriver'; import FileRewardsDriver from 'component/fileRewardsDriver';
import filePageStyle from 'styles/filePage'; import filePageStyle from 'styles/filePage';
import uriBarStyle from 'styles/uriBar'; import uriBarStyle from 'styles/uriBar';
import _ from 'lodash';
class FilePage extends React.PureComponent { class FilePage extends React.PureComponent {
static navigationOptions = { static navigationOptions = {
@ -62,8 +63,9 @@ class FilePage extends React.PureComponent {
super(props); super(props);
this.state = { this.state = {
attemptAutoGet: false, attemptAutoGet: false,
autoPlayMedia: false, autoOpened: false,
autoDownloadStarted: false, autoDownloadStarted: false,
autoPlayMedia: false,
downloadButtonShown: false, downloadButtonShown: false,
downloadPressed: false, downloadPressed: false,
fileViewLogged: false, fileViewLogged: false,
@ -127,6 +129,17 @@ class FilePage extends React.PureComponent {
this.onComponentFocused(); this.onComponentFocused();
} }
difference = (object, base) => {
function changes(object, base) {
return _.transform(object, function(result, value, key) {
if (!_.isEqual(value, base[key])) {
result[key] = _.isObject(value) && _.isObject(base[key]) ? changes(value, base[key]) : value;
}
});
}
return changes(object, base);
};
componentWillReceiveProps(nextProps) { componentWillReceiveProps(nextProps) {
const { const {
claim, claim,
@ -136,6 +149,7 @@ class FilePage extends React.PureComponent {
navigation, navigation,
contentType, contentType,
notify, notify,
drawerStack: prevDrawerStack,
} = this.props; } = this.props;
const { uri } = navigation.state.params; const { uri } = navigation.state.params;
const { const {
@ -145,6 +159,7 @@ class FilePage extends React.PureComponent {
purchasedUris, purchasedUris,
purchaseUriErrorMessage, purchaseUriErrorMessage,
streamingUrl, streamingUrl,
drawerStack,
} = nextProps; } = nextProps;
if (Constants.ROUTE_FILE === currentRoute && currentRoute !== prevRoute) { if (Constants.ROUTE_FILE === currentRoute && currentRoute !== prevRoute) {
@ -184,6 +199,17 @@ class FilePage extends React.PureComponent {
this.setState({ streamingMode: true, currentStreamUrl: fileInfo.streaming_url }); this.setState({ streamingMode: true, currentStreamUrl: fileInfo.streaming_url });
} }
} }
if (
prevDrawerStack[prevDrawerStack.length - 1].route === Constants.DRAWER_ROUTE_FILE_VIEW &&
prevDrawerStack.length !== drawerStack.length
) {
this.setState({
downloadPressed: false,
showImageViewer: false,
showWebView: false,
});
}
} }
componentDidUpdate(prevProps) { componentDidUpdate(prevProps) {
@ -633,6 +659,39 @@ class FilePage extends React.PureComponent {
} }
}; };
openFile = (localFileUri, mediaType) => {
const { pushDrawerStack } = this.props;
const isWebViewable = mediaType === 'text';
if (mediaType === 'image') {
// use image viewer
if (!this.state.showImageViewer) {
this.setState(
{
imageUrls: [
{
url: localFileUri,
},
],
showImageViewer: true,
},
() => pushDrawerStack(Constants.DRAWER_ROUTE_FILE_VIEW)
);
}
}
if (isWebViewable) {
// show webview
if (!this.state.showWebView) {
this.setState(
{
showWebView: true,
},
() => pushDrawerStack(Constants.DRAWER_ROUTE_FILE_VIEW)
);
}
}
};
render() { render() {
const { const {
balance, balance,
@ -651,6 +710,7 @@ class FilePage extends React.PureComponent {
navigation, navigation,
position, position,
purchaseUri, purchaseUri,
pushDrawerStack,
isSearchingRecommendContent, isSearchingRecommendContent,
recommendedContent, recommendedContent,
thumbnail, thumbnail,
@ -746,6 +806,7 @@ class FilePage extends React.PureComponent {
const description = metadata.description ? metadata.description : null; const description = metadata.description ? metadata.description : null;
const mediaType = Lbry.getMediaType(contentType); const mediaType = Lbry.getMediaType(contentType);
const isPlayable = mediaType === 'video' || mediaType === 'audio'; const isPlayable = mediaType === 'video' || mediaType === 'audio';
const isWebViewable = mediaType === 'text';
const { height, signing_channel: signingChannel, value } = claim; const { height, signing_channel: signingChannel, value } = claim;
const channelName = signingChannel && signingChannel.name; const channelName = signingChannel && signingChannel.name;
const channelClaimId = claim && claim.signing_channel && claim.signing_channel.claim_id; const channelClaimId = claim && claim.signing_channel && claim.signing_channel.claim_id;
@ -784,35 +845,10 @@ class FilePage extends React.PureComponent {
(fileInfo && (fileInfo.written_bytes >= 2097152 || fileInfo.written_bytes === fileInfo.total_bytes)); // 2MB = 1024*1024*2 (fileInfo && (fileInfo.written_bytes >= 2097152 || fileInfo.written_bytes === fileInfo.total_bytes)); // 2MB = 1024*1024*2
const duration = claim && claim.value && claim.value.video ? claim.value.video.duration : null; const duration = claim && claim.value && claim.value.video ? claim.value.video.duration : null;
const isViewable = mediaType === 'image' || mediaType === 'text'; const isViewable = mediaType === 'image' || mediaType === 'text';
const isWebViewable = mediaType === 'text';
const canOpen = isViewable && completed; const canOpen = isViewable && completed;
const localFileUri = this.localUriForFileInfo(fileInfo); const localFileUri = this.localUriForFileInfo(fileInfo);
const unsupported = !isPlayable && !canOpen; const unsupported = !isPlayable && !canOpen;
const openFile = () => {
if (mediaType === 'image') {
// use image viewer
if (!this.state.showImageViewer) {
this.setState({
imageUrls: [
{
url: localFileUri,
},
],
showImageViewer: true,
});
}
}
if (isWebViewable) {
// show webview
if (!this.state.showWebView) {
this.setState({
showWebView: true,
});
}
}
};
if (fileInfo && !this.state.autoDownloadStarted && this.state.uriVars && this.state.uriVars.download === 'true') { if (fileInfo && !this.state.autoDownloadStarted && this.state.uriVars && this.state.uriVars.download === 'true') {
this.setState({ autoDownloadStarted: true }, () => { this.setState({ autoDownloadStarted: true }, () => {
purchaseUri(uri, costInfo, !isPlayable); purchaseUri(uri, costInfo, !isPlayable);
@ -822,9 +858,9 @@ class FilePage extends React.PureComponent {
}); });
} }
if (this.state.downloadPressed && canOpen) { if (this.state.downloadPressed && canOpen && !this.state.autoOpened) {
// automatically open a web viewable or image file after the download button is pressed // automatically open a web viewable or image file after the download button is pressed
openFile(); this.setState({ autoOpened: true }, () => this.openFile(localFileUri, mediaType));
} }
return ( return (
@ -889,7 +925,7 @@ class FilePage extends React.PureComponent {
<FileDownloadButton <FileDownloadButton
uri={claim && claim.permanent_url ? claim.permanent_url : uri} uri={claim && claim.permanent_url ? claim.permanent_url : uri}
style={filePageStyle.downloadButton} style={filePageStyle.downloadButton}
openFile={openFile} openFile={() => this.openFile(localFileUri, mediaType)}
isPlayable={isPlayable} isPlayable={isPlayable}
isViewable={isViewable} isViewable={isViewable}
onPlay={this.onFileDownloadButtonPlayed} onPlay={this.onFileDownloadButtonPlayed}
@ -975,7 +1011,7 @@ class FilePage extends React.PureComponent {
<View style={filePageStyle.largeButtonsRow}> <View style={filePageStyle.largeButtonsRow}>
<TouchableOpacity style={filePageStyle.largeButton} onPress={this.handleSharePress}> <TouchableOpacity style={filePageStyle.largeButton} onPress={this.handleSharePress}>
<Icon name={'share-alt'} size={20} style={filePageStyle.largeButtonIcon} /> <Icon name={'share-alt'} size={16} style={filePageStyle.largeButtonIcon} />
<Text style={filePageStyle.largeButtonText}>{__('Share')}</Text> <Text style={filePageStyle.largeButtonText}>{__('Share')}</Text>
</TouchableOpacity> </TouchableOpacity>
@ -983,17 +1019,19 @@ class FilePage extends React.PureComponent {
style={filePageStyle.largeButton} style={filePageStyle.largeButton}
onPress={() => this.setState({ showTipView: true })} onPress={() => this.setState({ showTipView: true })}
> >
<Icon name={'gift'} size={20} style={filePageStyle.largeButtonIcon} /> <Icon name={'gift'} size={16} style={filePageStyle.largeButtonIcon} />
<Text style={filePageStyle.largeButtonText}>{__('Tip')}</Text> <Text style={filePageStyle.largeButtonText}>{__('Tip')}</Text>
</TouchableOpacity> </TouchableOpacity>
{!canEdit && (
<View style={filePageStyle.sharedLargeButton}> <View style={filePageStyle.sharedLargeButton}>
{!isPlayable && !fileInfo && ( {!fileInfo ||
(fileInfo.written_bytes <= 0 && !completed && (
<TouchableOpacity style={filePageStyle.innerLargeButton} onPress={this.onDownloadPressed}> <TouchableOpacity style={filePageStyle.innerLargeButton} onPress={this.onDownloadPressed}>
<Icon name={'download'} size={20} style={filePageStyle.largeButtonIcon} /> <Icon name={'download'} size={16} style={filePageStyle.largeButtonIcon} />
<Text style={filePageStyle.largeButtonText}>{__('Download')}</Text> <Text style={filePageStyle.largeButtonText}>{__('Download')}</Text>
</TouchableOpacity> </TouchableOpacity>
)} ))}
{!completed && {!completed &&
fileInfo && fileInfo &&
@ -1002,32 +1040,40 @@ class FilePage extends React.PureComponent {
fileInfo.written_bytes < fileInfo.total_bytes && fileInfo.written_bytes < fileInfo.total_bytes &&
!this.state.stopDownloadConfirmed && ( !this.state.stopDownloadConfirmed && (
<TouchableOpacity style={filePageStyle.innerLargeButton} onPress={this.onStopDownloadPressed}> <TouchableOpacity style={filePageStyle.innerLargeButton} onPress={this.onStopDownloadPressed}>
<Icon name={'stop'} size={20} style={filePageStyle.largeButtonIcon} /> <Icon name={'stop'} size={16} style={filePageStyle.largeButtonIcon} />
<Text style={filePageStyle.largeButtonText}>{__('Stop')}</Text> <Text style={filePageStyle.largeButtonText}>{__('Stop')}</Text>
</TouchableOpacity> </TouchableOpacity>
)} )}
{completed && fileInfo && fileInfo.written_bytes >= fileInfo.total_bytes && (
<TouchableOpacity style={filePageStyle.innerLargeButton} onPress={this.onOpenFilePressed}>
<Icon name={'folder-open'} size={16} style={filePageStyle.largeButtonIcon} />
<Text style={filePageStyle.largeButtonText}>{__('Open')}</Text>
</TouchableOpacity>
)}
</View> </View>
)}
{!canEdit && ( {!canEdit && (
<TouchableOpacity <TouchableOpacity
style={filePageStyle.largeButton} style={filePageStyle.largeButton}
onPress={() => Linking.openURL(`https://lbry.com/dmca/${claim.claim_id}`)} onPress={() => Linking.openURL(`https://lbry.com/dmca/${claim.claim_id}`)}
> >
<Icon name={'flag'} size={20} style={filePageStyle.largeButtonIcon} /> <Icon name={'flag'} size={16} style={filePageStyle.largeButtonIcon} />
<Text style={filePageStyle.largeButtonText}>{__('Report')}</Text> <Text style={filePageStyle.largeButtonText}>{__('Report')}</Text>
</TouchableOpacity> </TouchableOpacity>
)} )}
{canEdit && ( {canEdit && (
<TouchableOpacity style={filePageStyle.largeButton} onPress={this.onEditPressed}> <TouchableOpacity style={filePageStyle.largeButton} onPress={this.onEditPressed}>
<Icon name={'edit'} size={20} style={filePageStyle.largeButtonIcon} /> <Icon name={'edit'} size={16} style={filePageStyle.largeButtonIcon} />
<Text style={filePageStyle.largeButtonText}>{__('Edit')}</Text> <Text style={filePageStyle.largeButtonText}>{__('Edit')}</Text>
</TouchableOpacity> </TouchableOpacity>
)} )}
{(completed || canEdit) && ( {(completed || canEdit) && (
<TouchableOpacity style={filePageStyle.largeButton} onPress={this.onDeletePressed}> <TouchableOpacity style={filePageStyle.largeButton} onPress={this.onDeletePressed}>
<Icon name={'trash-alt'} size={20} style={filePageStyle.largeButtonIcon} /> <Icon name={'trash-alt'} size={16} style={filePageStyle.largeButtonIcon} />
<Text style={filePageStyle.largeButtonText}>{__('Delete')}</Text> <Text style={filePageStyle.largeButtonText}>{__('Delete')}</Text>
</TouchableOpacity> </TouchableOpacity>
)} )}

View file

@ -11,7 +11,6 @@ import settingsStyle from 'styles/settings';
const languageOptions = [ const languageOptions = [
{ code: 'default', name: 'Use device language' }, { code: 'default', name: 'Use device language' },
{ code: 'ar', name: 'Arabic' },
{ code: 'en', name: 'English' }, { code: 'en', name: 'English' },
{ code: 'gu', name: 'Gujarati' }, { code: 'gu', name: 'Gujarati' },
{ code: 'hi', name: 'Hindi' }, { code: 'hi', name: 'Hindi' },
@ -90,7 +89,14 @@ class SettingsPage extends React.PureComponent {
} }
// check the local filesystem for the language first? Or download remote strings first? // check the local filesystem for the language first? Or download remote strings first?
if (language === 'en') {
// don't attempt to download English
NativeModules.UtilityModule.setNativeStringSetting(SETTINGS.LANGUAGE, language);
// update state and client setting
window.language = language;
setClientSetting(SETTINGS.LANGUAGE, value);
} else {
// download and save the language file // download and save the language file
this.setState({ downloadingLanguage: true }, () => { this.setState({ downloadingLanguage: true }, () => {
fetch('https://lbry.com/i18n/get/lbry-mobile/app-strings/' + language + '.json') fetch('https://lbry.com/i18n/get/lbry-mobile/app-strings/' + language + '.json')
@ -104,7 +110,7 @@ class SettingsPage extends React.PureComponent {
// save the setting outside redux because when the first component mounts, the redux value isn't loaded yet // save the setting outside redux because when the first component mounts, the redux value isn't loaded yet
// so we have to load it from native settings // so we have to load it from native settings
NativeModules.UtilityModule.setNativeStringSetting(SETTINGS.LANGUAGE, value); NativeModules.UtilityModule.setNativeStringSetting(SETTINGS.LANGUAGE, language);
// update state and client setting // update state and client setting
window.language = language; window.language = language;
@ -117,6 +123,7 @@ class SettingsPage extends React.PureComponent {
this.setState({ downloadingLanguage: false }); this.setState({ downloadingLanguage: false });
}); });
}); });
}
}; };
handleBackPressed = () => { handleBackPressed = () => {

View file

@ -235,7 +235,7 @@ class SplashScreen extends React.PureComponent {
} }
if (headerSyncProgress < 100) { if (headerSyncProgress < 100) {
const downloadProgress = isNaN(parseInt(headerSyncProgress, 10)) ? '0' : headerSyncProgress; const downloadProgress = isNaN(parseInt(headerSyncProgress, 10)) ? '0' : headerSyncProgress || '0';
this.setState({ this.setState({
message: __('Blockchain Sync'), message: __('Blockchain Sync'),
details: __('Catching up with the blockchain (%progress%%)', { progress: downloadProgress }), details: __('Catching up with the blockchain (%progress%%)', { progress: downloadProgress }),

View file

@ -384,7 +384,7 @@ const filePageStyle = StyleSheet.create({
sharedLargeButton: { sharedLargeButton: {
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
marginRight: 36, flex: 0.2,
}, },
innerLargeButton: { innerLargeButton: {
alignItems: 'center', alignItems: 'center',
@ -393,7 +393,7 @@ const filePageStyle = StyleSheet.create({
largeButton: { largeButton: {
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
marginRight: 36, flex: 0.2,
}, },
largeButtonIcon: { largeButtonIcon: {
color: Colors.DescriptionGrey, color: Colors.DescriptionGrey,
@ -406,8 +406,8 @@ const filePageStyle = StyleSheet.create({
largeButtonsRow: { largeButtonsRow: {
flexDirection: 'row', flexDirection: 'row',
alignItems: 'center', alignItems: 'center',
marginLeft: 20, marginLeft: 16,
marginRight: 20, marginRight: 16,
marginTop: 12, marginTop: 12,
marginBottom: 12, marginBottom: 12,
}, },

View file

@ -155,6 +155,14 @@ export function navigateToUri(navigation, uri, additionalParams, isNavigatingBac
} }
export function navigateBack(navigation, drawerStack, popDrawerStack) { export function navigateBack(navigation, drawerStack, popDrawerStack) {
if (drawerStack[drawerStack.length - 1].route === Constants.DRAWER_ROUTE_FILE_VIEW) {
// inner file_view (web / image view) is handled differently
if (popDrawerStack) {
popDrawerStack();
}
return;
}
if (popDrawerStack) { if (popDrawerStack) {
popDrawerStack(); popDrawerStack();
} }
@ -186,6 +194,12 @@ export function navigateBack(navigation, drawerStack, popDrawerStack) {
} }
export function dispatchNavigateBack(dispatch, nav, drawerStack) { export function dispatchNavigateBack(dispatch, nav, drawerStack) {
if (drawerStack[drawerStack.length - 1].route === Constants.DRAWER_ROUTE_FILE_VIEW) {
// inner file_view (web / image view) is handled differently
dispatch(doPopDrawerStack());
return;
}
dispatch(doPopDrawerStack()); dispatch(doPopDrawerStack());
const target = drawerStack[drawerStack.length > 1 ? drawerStack.length - 2 : 0]; const target = drawerStack[drawerStack.length > 1 ? drawerStack.length - 2 : 0];