Tag search result #71
10 changed files with 124 additions and 26 deletions
|
@ -27,7 +27,15 @@ import {
|
||||||
createNavigationReducer,
|
createNavigationReducer,
|
||||||
} from 'react-navigation-redux-helpers';
|
} from 'react-navigation-redux-helpers';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { AppState, BackHandler, Linking, NativeModules, TextInput, ToastAndroid } from 'react-native';
|
import {
|
||||||
|
AppState,
|
||||||
|
BackHandler,
|
||||||
|
DeviceEventEmitter,
|
||||||
|
Linking,
|
||||||
|
NativeModules,
|
||||||
|
TextInput,
|
||||||
|
ToastAndroid,
|
||||||
|
} from 'react-native';
|
||||||
import { selectDrawerStack } from 'redux/selectors/drawer';
|
import { selectDrawerStack } from 'redux/selectors/drawer';
|
||||||
import { SETTINGS, doDismissToast, doPopulateSharedUserState, doPreferenceGet, doToast, selectToast } from 'lbry-redux';
|
import { SETTINGS, doDismissToast, doPopulateSharedUserState, doPreferenceGet, doToast, selectToast } from 'lbry-redux';
|
||||||
import {
|
import {
|
||||||
|
|
|
@ -66,7 +66,9 @@ class FileItem extends React.PureComponent {
|
||||||
|
|
||||||
let shouldHide = false;
|
let shouldHide = false;
|
||||||
if (blackListedOutpoints || filteredOutpoints) {
|
if (blackListedOutpoints || filteredOutpoints) {
|
||||||
const outpointsToHide = blackListedOutpoints.concat(filteredOutpoints);
|
const outpointsToHide = !blackListedOutpoints
|
||||||
|
? filteredOutpoints
|
||||||
|
: blackListedOutpoints.concat(filteredOutpoints);
|
||||||
shouldHide = outpointsToHide.some(outpoint => outpoint.txid === claim.txid && outpoint.nout === claim.nout);
|
shouldHide = outpointsToHide.some(outpoint => outpoint.txid === claim.txid && outpoint.nout === claim.nout);
|
||||||
}
|
}
|
||||||
if (shouldHide) {
|
if (shouldHide) {
|
||||||
|
|
|
@ -120,7 +120,9 @@ class FileListItem extends React.PureComponent {
|
||||||
shortChannelUri = signingChannel ? signingChannel.short_url : null;
|
shortChannelUri = signingChannel ? signingChannel.short_url : null;
|
||||||
|
|
||||||
if (blackListedOutpoints || filteredOutpoints) {
|
if (blackListedOutpoints || filteredOutpoints) {
|
||||||
const outpointsToHide = blackListedOutpoints.concat(filteredOutpoints);
|
const outpointsToHide = !blackListedOutpoints
|
||||||
|
? filteredOutpoints
|
||||||
|
: blackListedOutpoints.concat(filteredOutpoints);
|
||||||
shouldHide = outpointsToHide.some(outpoint => outpoint.txid === claim.txid && outpoint.nout === claim.nout);
|
shouldHide = outpointsToHide.some(outpoint => outpoint.txid === claim.txid && outpoint.nout === claim.nout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,9 @@ class SuggestedSubscriptionItem extends React.PureComponent {
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<SubscribeButton style={subscriptionsStyle.suggestedItemSubscribe} uri={normalizeURI(uri)} />
|
{claim && (
|
||||||
|
<SubscribeButton style={subscriptionsStyle.suggestedItemSubscribe} uri={normalizeURI(claim.permanent_url)} />
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,8 @@ class WalletSend extends React.PureComponent<Props> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { balance } = this.props;
|
const { balance } = this.props;
|
||||||
const canSend = this.state.address && this.state.amount > 0 && this.state.address.trim().length > 0;
|
const canSend =
|
||||||
|
this.state.address && this.state.amount > 0 && this.state.address.trim().length > 0 && this.state.addressValid;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={walletStyle.card}>
|
<View style={walletStyle.card}>
|
||||||
|
@ -94,7 +95,7 @@ class WalletSend extends React.PureComponent<Props> {
|
||||||
this.setState({
|
this.setState({
|
||||||
address: value,
|
address: value,
|
||||||
addressChanged: true,
|
addressChanged: true,
|
||||||
addressValid: value.trim().length == 0 || regexAddress.test(value),
|
addressValid: value.trim().length === 0 || regexAddress.test(value),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
onBlur={this.handleAddressInputBlur}
|
onBlur={this.handleAddressInputBlur}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {
|
||||||
Alert,
|
Alert,
|
||||||
DeviceEventEmitter,
|
DeviceEventEmitter,
|
||||||
Dimensions,
|
Dimensions,
|
||||||
|
Image,
|
||||||
Linking,
|
Linking,
|
||||||
NativeModules,
|
NativeModules,
|
||||||
ScrollView,
|
ScrollView,
|
||||||
|
@ -739,6 +740,7 @@ class FilePage extends React.PureComponent {
|
||||||
const isWebViewable = 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 openFile = () => {
|
const openFile = () => {
|
||||||
if (mediaType === 'image') {
|
if (mediaType === 'image') {
|
||||||
|
@ -809,9 +811,30 @@ class FilePage extends React.PureComponent {
|
||||||
thumbnail={thumbnail}
|
thumbnail={thumbnail}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{(!this.state.downloadButtonShown || this.state.downloadPressed) && !this.state.mediaLoaded && (
|
{!unsupported &&
|
||||||
|
(!this.state.downloadButtonShown || this.state.downloadPressed) &&
|
||||||
|
!this.state.mediaLoaded && (
|
||||||
<ActivityIndicator size="large" color={Colors.NextLbryGreen} style={filePageStyle.loading} />
|
<ActivityIndicator size="large" color={Colors.NextLbryGreen} style={filePageStyle.loading} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{unsupported && fileInfo && completed && (
|
||||||
|
<View style={filePageStyle.unsupportedContent}>
|
||||||
|
<Image
|
||||||
|
style={filePageStyle.unsupportedContentImage}
|
||||||
|
resizeMode={'stretch'}
|
||||||
|
source={require('../../assets/gerbil-happy.png')}
|
||||||
|
/>
|
||||||
|
<View style={filePageStyle.unspportedContentTextContainer}>
|
||||||
|
<Text style={filePageStyle.unsupportedContentTitle}>Unsupported Content</Text>
|
||||||
|
<Text style={filePageStyle.unsupportedContentText}>
|
||||||
|
Sorry, we are unable to display this content in the app. You can find the file named{' '}
|
||||||
|
<Text style={filePageStyle.unsupportedContentFilename}>{fileInfo.file_name}</Text> in your
|
||||||
|
downloads folder.
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
|
||||||
{((isPlayable && !completed && !canLoadMedia) ||
|
{((isPlayable && !completed && !canLoadMedia) ||
|
||||||
canOpen ||
|
canOpen ||
|
||||||
(!completed && !this.state.streamingMode)) &&
|
(!completed && !this.state.streamingMode)) &&
|
||||||
|
|
|
@ -142,7 +142,7 @@ class SearchPage extends React.PureComponent {
|
||||||
<FileListItem uri={currentUri} featuredResult style={searchStyle.featuredResultItem} navigation={navigation} />
|
<FileListItem uri={currentUri} featuredResult style={searchStyle.featuredResultItem} navigation={navigation} />
|
||||||
{showTagResult && (
|
{showTagResult && (
|
||||||
<TouchableOpacity style={searchStyle.tagResultItem} onPress={() => this.handleTagResultPressed(query)}>
|
<TouchableOpacity style={searchStyle.tagResultItem} onPress={() => this.handleTagResultPressed(query)}>
|
||||||
<Text style={searchStyle.tagResultTitle}>#{query}</Text>
|
<Text style={searchStyle.tagResultTitle}>#{query.toLowerCase()}</Text>
|
||||||
<Text style={searchStyle.tagResultDescription}>Explore content for this tag</Text>
|
<Text style={searchStyle.tagResultDescription}>Explore content for this tag</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
)}
|
)}
|
||||||
|
@ -152,7 +152,7 @@ class SearchPage extends React.PureComponent {
|
||||||
|
|
||||||
handleTagResultPressed = tag => {
|
handleTagResultPressed = tag => {
|
||||||
const { navigation } = this.props;
|
const { navigation } = this.props;
|
||||||
navigation.navigate({ routeName: Constants.DRAWER_ROUTE_TAG, key: `tagPage`, params: { tag } });
|
navigation.navigate({ routeName: Constants.DRAWER_ROUTE_TAG, key: `tagPage`, params: { tag: tag.toLowerCase() } });
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -140,7 +140,7 @@ class SettingsPage extends React.PureComponent {
|
||||||
|
|
||||||
<View style={settingsStyle.row}>
|
<View style={settingsStyle.row}>
|
||||||
<View style={settingsStyle.switchText}>
|
<View style={settingsStyle.switchText}>
|
||||||
<Text style={settingsStyle.label}>{__('Tags you follow')}</Text>
|
<Text style={settingsStyle.label}>{__('Content Interests')}</Text>
|
||||||
</View>
|
</View>
|
||||||
<View style={settingsStyle.switchContainer}>
|
<View style={settingsStyle.switchContainer}>
|
||||||
<Switch
|
<Switch
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Lbry, doPreferenceGet } from 'lbry-redux';
|
import { Lbry, doPreferenceGet } from 'lbry-redux';
|
||||||
import { Lbryio } from 'lbryinc';
|
import { Lbryio } from 'lbryinc';
|
||||||
import { ActivityIndicator, Linking, NativeModules, Platform, Text, View } from 'react-native';
|
import { ActivityIndicator, DeviceEventEmitter, Linking, NativeModules, Platform, Text, View } from 'react-native';
|
||||||
import { NavigationActions, StackActions } from 'react-navigation';
|
import { NavigationActions, StackActions } from 'react-navigation';
|
||||||
import { decode as atob } from 'base-64';
|
import { decode as atob } from 'base-64';
|
||||||
import { navigateToUri, transformUrl } from 'utils/helper';
|
import { navigateToUri, transformUrl } from 'utils/helper';
|
||||||
|
@ -52,7 +52,10 @@ class SplashScreen extends React.PureComponent {
|
||||||
});
|
});
|
||||||
navigation.dispatch(resetAction);
|
navigation.dispatch(resetAction);
|
||||||
|
|
||||||
const launchUrl = navigation.state.params ? navigation.state.params.launchUrl : this.state.launchUrl;
|
const launchUrl =
|
||||||
|
navigation.state.params && navigation.state.params.launchUrl
|
||||||
|
? navigation.state.params.launchUrl
|
||||||
|
: this.state.launchUrl;
|
||||||
if (launchUrl) {
|
if (launchUrl) {
|
||||||
if (launchUrl.startsWith('lbry://?verify=')) {
|
if (launchUrl.startsWith('lbry://?verify=')) {
|
||||||
let verification = {};
|
let verification = {};
|
||||||
|
@ -118,6 +121,12 @@ class SplashScreen extends React.PureComponent {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onNotificationTargetLaunch = evt => {
|
||||||
|
if (evt.url && evt.url.startsWith('lbry://')) {
|
||||||
|
this.setState({ launchUrl: evt.url });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
finishSplashScreen = () => {
|
finishSplashScreen = () => {
|
||||||
const {
|
const {
|
||||||
authenticate,
|
authenticate,
|
||||||
|
@ -149,7 +158,10 @@ class SplashScreen extends React.PureComponent {
|
||||||
NativeModules.VersionInfo.getAppVersion().then(appVersion => {
|
NativeModules.VersionInfo.getAppVersion().then(appVersion => {
|
||||||
this.setState({ shouldAuthenticate: true });
|
this.setState({ shouldAuthenticate: true });
|
||||||
NativeModules.Firebase.getMessagingToken()
|
NativeModules.Firebase.getMessagingToken()
|
||||||
.then(firebaseToken => authenticate(appVersion, Platform.OS, firebaseToken))
|
.then(firebaseToken => {
|
||||||
|
console.log(firebaseToken);
|
||||||
|
authenticate(appVersion, Platform.OS, firebaseToken);
|
||||||
|
})
|
||||||
.catch(() => authenticate(appVersion, Platform.OS));
|
.catch(() => authenticate(appVersion, Platform.OS));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -250,6 +262,14 @@ class SplashScreen extends React.PureComponent {
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentWillMount() {
|
||||||
|
DeviceEventEmitter.addListener('onNotificationTargetLaunch', this.onNotificationTargetLaunch);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
DeviceEventEmitter.removeListener('onNotificationTargetLaunch', this.onNotificationTargetLaunch);
|
||||||
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
NativeModules.Firebase.track('app_launch', null);
|
NativeModules.Firebase.track('app_launch', null);
|
||||||
NativeModules.Firebase.setCurrentScreen('Splash');
|
NativeModules.Firebase.setCurrentScreen('Splash');
|
||||||
|
@ -259,18 +279,13 @@ class SplashScreen extends React.PureComponent {
|
||||||
if (url) {
|
if (url) {
|
||||||
this.setState({ launchUrl: url });
|
this.setState({ launchUrl: url });
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
// Start measuring the first launch time from the splash screen
|
NativeModules.UtilityModule.getNotificationLaunchTarget().then(target => {
|
||||||
// (time to first user interaction - after first run completed)
|
if (target) {
|
||||||
AsyncStorage.getItem('hasLaunched').then(value => {
|
this.setState({ launchUrl: target });
|
||||||
if (value !== 'true') {
|
|
||||||
AsyncStorage.setItem('hasLaunched', 'true');
|
|
||||||
// only set firstLaunchTime since we've determined that this is the first app launch ever
|
|
||||||
AsyncStorage.setItem('firstLaunchTime', String(moment().unix()));
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
|
// Only connect after checking initial launch url / notification launch target
|
||||||
Lbry.connect()
|
Lbry.connect()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.updateStatus();
|
this.updateStatus();
|
||||||
|
@ -283,6 +298,18 @@ class SplashScreen extends React.PureComponent {
|
||||||
'We could not establish a connection to the daemon. Your data connection may be preventing LBRY from connecting. Contact hello@lbry.com if you think this is a software bug.',
|
'We could not establish a connection to the daemon. Your data connection may be preventing LBRY from connecting. Contact hello@lbry.com if you think this is a software bug.',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Start measuring the first launch time from the splash screen
|
||||||
|
// (time to first user interaction - after first run completed)
|
||||||
|
AsyncStorage.getItem('hasLaunched').then(value => {
|
||||||
|
if (value !== 'true') {
|
||||||
|
AsyncStorage.setItem('hasLaunched', 'true');
|
||||||
|
// only set firstLaunchTime since we've determined that this is the first app launch ever
|
||||||
|
AsyncStorage.setItem('firstLaunchTime', String(moment().unix()));
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleContinueAnywayPressed = () => {
|
handleContinueAnywayPressed = () => {
|
||||||
|
|
|
@ -402,6 +402,39 @@ const filePageStyle = StyleSheet.create({
|
||||||
marginTop: 12,
|
marginTop: 12,
|
||||||
marginBottom: 12,
|
marginBottom: 12,
|
||||||
},
|
},
|
||||||
|
unsupportedContent: {
|
||||||
|
position: 'absolute',
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
top: 0,
|
||||||
|
bottom: 16,
|
||||||
|
padding: 24,
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: Colors.White,
|
||||||
|
},
|
||||||
|
unspportedContentTextContainer: {
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
|
unsupportedContentFilename: {
|
||||||
|
color: Colors.LbryGreen,
|
||||||
|
fontFamily: 'Inter-UI-SemiBold',
|
||||||
|
fontSize: 16,
|
||||||
|
},
|
||||||
|
unsupportedContentImage: {
|
||||||
|
width: 64,
|
||||||
|
height: 80,
|
||||||
|
marginRight: 24,
|
||||||
|
},
|
||||||
|
unsupportedContentTitle: {
|
||||||
|
fontFamily: 'Inter-UI-Regular',
|
||||||
|
fontSize: 20,
|
||||||
|
},
|
||||||
|
unsupportedContentText: {
|
||||||
|
fontFamily: 'Inter-UI-Regular',
|
||||||
|
fontSize: 16,
|
||||||
|
marginTop: 4,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default filePageStyle;
|
export default filePageStyle;
|
||||||
|
|
Loading…
Reference in a new issue