Unverified Commit 12d7fbd4 authored by Akinwale Ariwodola's avatar Akinwale Ariwodola Committed by GitHub
Browse files

lbry.tv hybrid mode (#132)

* use lbry.tv for resolve and claim_search
* gracefully handle dynamic sdk ready state
* update pinned lbry-redux commit
* use empty state view when sdk is not ready
* traditional mode if dht is enabled
parent 4645a8f4
Subproject commit bfd3c711abc4f693dbb68b06fdfce67036b1e4a3
Subproject commit e9f25546979eee36751353c187dc9944ab1e508e
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -42,8 +42,10 @@ import {
} from 'react-native';
import { selectDrawerStack } from 'redux/selectors/drawer';
import {
Lbry,
ACTIONS,
SETTINGS,
doBalanceSubscribe,
doDismissToast,
doPopulateSharedUserState,
doPreferenceGet,
......@@ -52,6 +54,8 @@ import {
} from 'lbry-redux';
import {
Lbryio,
doBlackListedOutpointsSubscribe,
doFilteredOutpointsSubscribe,
doGetSync,
doUserCheckEmailVerified,
doUserEmailVerify,
......@@ -75,6 +79,7 @@ import discoverStyle from 'styles/discover';
import searchStyle from 'styles/search';
import SearchRightHeaderIcon from 'component/searchRightHeaderIcon';
import Snackbar from 'react-native-snackbar';
import { doSetSdkReady } from 'redux/actions/settings';
const SYNC_GET_INTERVAL = 1000 * 60 * 5; // every 5 minutes
......@@ -327,6 +332,7 @@ class AppWithNavigationState extends React.Component {
this.emailVerifyCheckInterval = setInterval(() => this.checkEmailVerification(), 5000);
Linking.addEventListener('url', this._handleUrl);
DeviceEventEmitter.addListener('onSdkReady', this.handleSdkReady);
DeviceEventEmitter.addListener('onDownloadAborted', this.handleDownloadAborted);
DeviceEventEmitter.addListener('onDownloadStarted', this.handleDownloadStarted);
DeviceEventEmitter.addListener('onDownloadUpdated', this.handleDownloadUpdated);
......@@ -366,6 +372,46 @@ class AppWithNavigationState extends React.Component {
);
};
handleSdkReady = () => {
const { dispatch } = this.props;
dispatch(doSetSdkReady());
dispatch(doBalanceSubscribe());
dispatch(doBlackListedOutpointsSubscribe());
dispatch(doFilteredOutpointsSubscribe());
Lbry.wallet_status().then(secureWalletStatus => {
// For now, automatically unlock the wallet if a password is set so that downloads work
NativeModules.UtilityModule.getSecureValue(Constants.KEY_WALLET_PASSWORD).then(password => {
if ((secureWalletStatus.is_encrypted && !secureWalletStatus.is_locked) || secureWalletStatus.is_locked) {
this.setState({
message: __('Unlocking account'),
details: __('Decrypting wallet'),
});
// unlock the wallet and then finish the splash screen
Lbry.wallet_unlock({ password: password || '' }).then(unlocked => {
if (unlocked) {
} else {
// this.handleAccountUnlockFailed();
}
});
}
});
});
};
handleAccountUnlockFailed() {
const { dispatch } = this.props;
dispatch(
doToast({
message: __(
'Your wallet failed to unlock, which means you may not be able to play any videos or access your funds. Restart the app to fix this.',
),
isError: true,
}),
);
}
handleDownloadStarted = evt => {
const { dispatch } = this.props;
const { uri, outpoint, fileInfo } = evt;
......@@ -401,6 +447,7 @@ class AppWithNavigationState extends React.Component {
};
componentWillUnmount() {
DeviceEventEmitter.removeListener('onSdkReady', this.handleSdkReady);
DeviceEventEmitter.removeListener('onDownloadAborted', this.handleDownloadAborted);
DeviceEventEmitter.removeListener('onDownloadStarted', this.handleDownloadStarted);
DeviceEventEmitter.removeListener('onDownloadUpdated', this.handleDownloadUpdated);
......
......@@ -19,7 +19,4 @@ const perform = dispatch => ({
resolveUri: uri => dispatch(doResolveUri(uri)),
});
export default connect(
select,
perform
)(ChannelIconItem);
export default connect(select, perform)(ChannelIconItem);
......@@ -23,7 +23,4 @@ const perform = dispatch => ({
claimSearch: options => dispatch(doClaimSearch(options)),
});
export default connect(
select,
perform,
)(ClaimList);
export default connect(select, perform)(ClaimList);
......@@ -36,7 +36,4 @@ const perform = dispatch => ({
setPlayerVisible: (visible, uri) => dispatch(doSetPlayerVisible(visible, uri)),
});
export default connect(
select,
perform,
)(ClaimResultItem);
export default connect(select, perform)(ClaimResultItem);
import { connect } from 'react-redux';
import { doFetchChannelListMine, selectMyChannelClaims } from 'lbry-redux';
import { doToast, selectMyChannelClaims } from 'lbry-redux';
import { selectUser } from 'lbryinc';
import { selectSdkReady } from 'redux/selectors/settings';
import DrawerContent from './view';
const select = state => ({
channels: selectMyChannelClaims(state),
sdkReady: selectSdkReady(state),
user: selectUser(state),
});
const perform = dispatch => ({
fetchChannelListMine: () => dispatch(doFetchChannelListMine(1, 99999, true)),
notify: data => dispatch(doToast(data)),
});
export default connect(
select,
perform,
)(DrawerContent);
export default connect(select, perform)(DrawerContent);
......@@ -31,13 +31,17 @@ const groupedMenuItems = {
};
const groupNames = Object.keys(groupedMenuItems);
const routesRequiringSdkReady = [
Constants.DRAWER_ROUTE_CHANNEL_CREATOR,
Constants.DRAWER_ROUTE_MY_LBRY,
Constants.DRAWER_ROUTE_PUBLISHES,
Constants.DRAWER_ROUTE_PUBLISH,
Constants.DRAWER_ROUTE_WALLET,
Constants.DRAWER_ROUTE_REWARDS,
Constants.DRAWER_ROUTE_INVITES,
];
class DrawerContent extends React.PureComponent {
componentDidMount() {
const { fetchChannelListMine } = this.props;
fetchChannelListMine();
}
getAvatarImageUrl = () => {
const { channels = [] } = this.props;
if (channels) {
......@@ -62,6 +66,21 @@ class DrawerContent extends React.PureComponent {
});
};
handleItemPress = routeName => {
const { navigation, notify, sdkReady } = this.props;
if (!sdkReady && routesRequiringSdkReady.includes(routeName)) {
if (navigation.closeDrawer) {
navigation.closeDrawer();
}
notify({
message: __('The background service is still initializing. Please try again when initialization is complete.'),
});
return;
}
navigation.navigate({ routeName: routeName });
};
render() {
const { activeTintColor, navigation, user, onItemPress } = this.props;
const { state } = navigation;
......@@ -157,7 +176,7 @@ class DrawerContent extends React.PureComponent {
focused ? discoverStyle.menuItemTouchAreaFocused : null,
]}
key={item.label}
onPress={() => navigation.navigate({ routeName: item.route })}
onPress={() => this.handleItemPress(item.route)}
delayPressIn={0}
>
<View style={discoverStyle.menuItemIcon}>
......
......@@ -35,7 +35,4 @@ const perform = dispatch => ({
setPlayerVisible: (visible, uri) => dispatch(doSetPlayerVisible(visible, uri)),
});
export default connect(
select,
perform,
)(FileItem);
export default connect(select, perform)(FileItem);
......@@ -36,7 +36,4 @@ const perform = dispatch => ({
setPlayerVisible: (visible, uri) => dispatch(doSetPlayerVisible(visible, uri)),
});
export default connect(
select,
perform,
)(FileListItem);
export default connect(select, perform)(FileListItem);
......@@ -125,7 +125,9 @@ class FileListItem extends React.PureComponent {
const outpointsToHide = !blackListedOutpoints
? filteredOutpoints
: blackListedOutpoints.concat(filteredOutpoints);
shouldHide = outpointsToHide.some(outpoint => outpoint.txid === claim.txid && outpoint.nout === claim.nout);
shouldHide = outpointsToHide.some(
outpoint => outpoint && outpoint.txid === claim.txid && outpoint.nout === claim.nout,
);
}
// TODO: hide channels on tag pages?
......@@ -143,10 +145,14 @@ class FileListItem extends React.PureComponent {
<View>
{isRepost && (
<View style={fileListStyle.repostInfo}>
<Icon name={"retweet"} size={14} style={fileListStyle.repostIcon} />
<Icon name={'retweet'} size={14} style={fileListStyle.repostIcon} />
<Text style={fileListStyle.repostChannelName}>
<Link text={repostChannel}
onPress={() => navigateToUri(navigation, normalizeURI(repostChannelUrl), null, false, null, false)} /> reposted</Text>
<Link
text={repostChannel}
onPress={() => navigateToUri(navigation, normalizeURI(repostChannelUrl), null, false, null, false)}
/>{' '}
reposted
</Text>
</View>
)}
......
import { connect } from 'react-redux';
import SdkLoadingStatus from './view';
export default connect()(SdkLoadingStatus);
import { ActivityIndicator, Text, View } from 'react-native';
import React from 'react';
import discoverStyle from 'styles/discover';
import Colors from 'styles/colors';
export default class SdkLoadingStatus extends React.PureComponent {
render() {
return (
<View style={discoverStyle.sdkLoading}>
<ActivityIndicator color={Colors.White} size={'small'} />
<Text style={discoverStyle.sdkLoadingText}>{__('The LBRY background service is initializing...')}</Text>
</View>
);
}
}
......@@ -23,7 +23,4 @@ const perform = dispatch => ({
unsubscribe: subscription => doChannelUnsubscribe(subscription),
});
export default connect(
select,
perform,
)(SuggestedSubscriptionItem);
export default connect(select, perform)(SuggestedSubscriptionItem);
......@@ -16,7 +16,4 @@ const perform = dispatch => ({
claimSearch: options => dispatch(doClaimSearch(options)),
});
export default connect(
select,
perform
)(SuggestedSubscriptions);
export default connect(select, perform)(SuggestedSubscriptions);
......@@ -24,7 +24,4 @@ const perform = dispatch => ({
claimSearch: options => dispatch(doClaimSearch(options)),
});
export default connect(
select,
perform,
)(SuggestedSubscriptionsGrid);
export default connect(select, perform)(SuggestedSubscriptionsGrid);
......@@ -46,6 +46,8 @@ const Constants = {
SETTING_DEVICE_WALLET_SYNCED: 'deviceWalletSynced',
SETTING_DHT_ENABLED: 'dhtEnabled',
ACTION_SDK_READY: 'SDK_READY',
ACTION_DELETE_COMPLETED_BLOBS: 'DELETE_COMPLETED_BLOBS',
ACTION_FIRST_RUN_PAGE_CHANGED: 'FIRST_RUN_PAGE_CHANGED',
......
......@@ -55,6 +55,10 @@ import settingsReducer from 'redux/reducers/settings';
import thunk from 'redux-thunk';
window.__ = __;
if (!NativeModules.UtilityModule.dhtEnabled) {
Lbry.alternateConnectionString = 'https://api.lbry.tv/api/v1/proxy';
Lbry.methodsUsingAlternateConnectionString = ['claim_search', 'resolve'];
}
const globalExceptionHandler = (error, isFatal) => {
if (error && NativeModules.Firebase) {
......
......@@ -22,6 +22,7 @@ import {
import { doUpdateChannelFormState, doClearChannelFormState } from 'redux/actions/form';
import { selectDrawerStack } from 'redux/selectors/drawer';
import { selectChannelFormState, selectHasChannelFormState } from 'redux/selectors/form';
import { selectSdkReady } from 'redux/selectors/settings';
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
import ChannelCreator from './view';
......@@ -33,6 +34,7 @@ const select = state => ({
fetchingChannels: selectFetchingMyChannels(state),
balance: selectBalance(state),
hasFormState: selectHasChannelFormState(state),
sdkReady: selectSdkReady(state),
updatingChannel: selectUpdatingChannel(state),
updateChannelError: selectUpdateChannelError(state),
});
......@@ -52,7 +54,4 @@ const perform = dispatch => ({
setExplicitNavigateBack: flag => dispatch(doSetExplicitNavigateBack(flag)),
});
export default connect(
select,
perform,
)(ChannelCreator);
export default connect(select, perform)(ChannelCreator);
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment