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 diff is collapsed.
...@@ -42,8 +42,10 @@ import { ...@@ -42,8 +42,10 @@ import {
} from 'react-native'; } from 'react-native';
import { selectDrawerStack } from 'redux/selectors/drawer'; import { selectDrawerStack } from 'redux/selectors/drawer';
import { import {
Lbry,
ACTIONS, ACTIONS,
SETTINGS, SETTINGS,
doBalanceSubscribe,
doDismissToast, doDismissToast,
doPopulateSharedUserState, doPopulateSharedUserState,
doPreferenceGet, doPreferenceGet,
...@@ -52,6 +54,8 @@ import { ...@@ -52,6 +54,8 @@ import {
} from 'lbry-redux'; } from 'lbry-redux';
import { import {
Lbryio, Lbryio,
doBlackListedOutpointsSubscribe,
doFilteredOutpointsSubscribe,
doGetSync, doGetSync,
doUserCheckEmailVerified, doUserCheckEmailVerified,
doUserEmailVerify, doUserEmailVerify,
...@@ -75,6 +79,7 @@ import discoverStyle from 'styles/discover'; ...@@ -75,6 +79,7 @@ import discoverStyle from 'styles/discover';
import searchStyle from 'styles/search'; import searchStyle from 'styles/search';
import SearchRightHeaderIcon from 'component/searchRightHeaderIcon'; import SearchRightHeaderIcon from 'component/searchRightHeaderIcon';
import Snackbar from 'react-native-snackbar'; import Snackbar from 'react-native-snackbar';
import { doSetSdkReady } from 'redux/actions/settings';
const SYNC_GET_INTERVAL = 1000 * 60 * 5; // every 5 minutes const SYNC_GET_INTERVAL = 1000 * 60 * 5; // every 5 minutes
...@@ -327,6 +332,7 @@ class AppWithNavigationState extends React.Component { ...@@ -327,6 +332,7 @@ class AppWithNavigationState extends React.Component {
this.emailVerifyCheckInterval = setInterval(() => this.checkEmailVerification(), 5000); this.emailVerifyCheckInterval = setInterval(() => this.checkEmailVerification(), 5000);
Linking.addEventListener('url', this._handleUrl); Linking.addEventListener('url', this._handleUrl);
DeviceEventEmitter.addListener('onSdkReady', this.handleSdkReady);
DeviceEventEmitter.addListener('onDownloadAborted', this.handleDownloadAborted); DeviceEventEmitter.addListener('onDownloadAborted', this.handleDownloadAborted);
DeviceEventEmitter.addListener('onDownloadStarted', this.handleDownloadStarted); DeviceEventEmitter.addListener('onDownloadStarted', this.handleDownloadStarted);
DeviceEventEmitter.addListener('onDownloadUpdated', this.handleDownloadUpdated); DeviceEventEmitter.addListener('onDownloadUpdated', this.handleDownloadUpdated);
...@@ -366,6 +372,46 @@ class AppWithNavigationState extends React.Component { ...@@ -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 => { handleDownloadStarted = evt => {
const { dispatch } = this.props; const { dispatch } = this.props;
const { uri, outpoint, fileInfo } = evt; const { uri, outpoint, fileInfo } = evt;
...@@ -401,6 +447,7 @@ class AppWithNavigationState extends React.Component { ...@@ -401,6 +447,7 @@ class AppWithNavigationState extends React.Component {
}; };
componentWillUnmount() { componentWillUnmount() {
DeviceEventEmitter.removeListener('onSdkReady', this.handleSdkReady);
DeviceEventEmitter.removeListener('onDownloadAborted', this.handleDownloadAborted); DeviceEventEmitter.removeListener('onDownloadAborted', this.handleDownloadAborted);
DeviceEventEmitter.removeListener('onDownloadStarted', this.handleDownloadStarted); DeviceEventEmitter.removeListener('onDownloadStarted', this.handleDownloadStarted);
DeviceEventEmitter.removeListener('onDownloadUpdated', this.handleDownloadUpdated); DeviceEventEmitter.removeListener('onDownloadUpdated', this.handleDownloadUpdated);
......
...@@ -19,7 +19,4 @@ const perform = dispatch => ({ ...@@ -19,7 +19,4 @@ const perform = dispatch => ({
resolveUri: uri => dispatch(doResolveUri(uri)), resolveUri: uri => dispatch(doResolveUri(uri)),
}); });
export default connect( export default connect(select, perform)(ChannelIconItem);
select,
perform
)(ChannelIconItem);
...@@ -23,7 +23,4 @@ const perform = dispatch => ({ ...@@ -23,7 +23,4 @@ const perform = dispatch => ({
claimSearch: options => dispatch(doClaimSearch(options)), claimSearch: options => dispatch(doClaimSearch(options)),
}); });
export default connect( export default connect(select, perform)(ClaimList);
select,
perform,
)(ClaimList);
...@@ -36,7 +36,4 @@ const perform = dispatch => ({ ...@@ -36,7 +36,4 @@ const perform = dispatch => ({
setPlayerVisible: (visible, uri) => dispatch(doSetPlayerVisible(visible, uri)), setPlayerVisible: (visible, uri) => dispatch(doSetPlayerVisible(visible, uri)),
}); });
export default connect( export default connect(select, perform)(ClaimResultItem);
select,
perform,
)(ClaimResultItem);
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { doFetchChannelListMine, selectMyChannelClaims } from 'lbry-redux'; import { doToast, selectMyChannelClaims } from 'lbry-redux';
import { selectUser } from 'lbryinc'; import { selectUser } from 'lbryinc';
import { selectSdkReady } from 'redux/selectors/settings';
import DrawerContent from './view'; import DrawerContent from './view';
const select = state => ({ const select = state => ({
channels: selectMyChannelClaims(state), channels: selectMyChannelClaims(state),
sdkReady: selectSdkReady(state),
user: selectUser(state), user: selectUser(state),
}); });
const perform = dispatch => ({ const perform = dispatch => ({
fetchChannelListMine: () => dispatch(doFetchChannelListMine(1, 99999, true)), notify: data => dispatch(doToast(data)),
}); });
export default connect( export default connect(select, perform)(DrawerContent);
select,
perform,
)(DrawerContent);
...@@ -31,13 +31,17 @@ const groupedMenuItems = { ...@@ -31,13 +31,17 @@ const groupedMenuItems = {
}; };
const groupNames = Object.keys(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 { class DrawerContent extends React.PureComponent {
componentDidMount() {
const { fetchChannelListMine } = this.props;
fetchChannelListMine();
}
getAvatarImageUrl = () => { getAvatarImageUrl = () => {
const { channels = [] } = this.props; const { channels = [] } = this.props;
if (channels) { if (channels) {
...@@ -62,6 +66,21 @@ class DrawerContent extends React.PureComponent { ...@@ -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() { render() {
const { activeTintColor, navigation, user, onItemPress } = this.props; const { activeTintColor, navigation, user, onItemPress } = this.props;
const { state } = navigation; const { state } = navigation;
...@@ -157,7 +176,7 @@ class DrawerContent extends React.PureComponent { ...@@ -157,7 +176,7 @@ class DrawerContent extends React.PureComponent {
focused ? discoverStyle.menuItemTouchAreaFocused : null, focused ? discoverStyle.menuItemTouchAreaFocused : null,
]} ]}
key={item.label} key={item.label}
onPress={() => navigation.navigate({ routeName: item.route })} onPress={() => this.handleItemPress(item.route)}
delayPressIn={0} delayPressIn={0}
> >
<View style={discoverStyle.menuItemIcon}> <View style={discoverStyle.menuItemIcon}>
......
...@@ -35,7 +35,4 @@ const perform = dispatch => ({ ...@@ -35,7 +35,4 @@ const perform = dispatch => ({
setPlayerVisible: (visible, uri) => dispatch(doSetPlayerVisible(visible, uri)), setPlayerVisible: (visible, uri) => dispatch(doSetPlayerVisible(visible, uri)),
}); });
export default connect( export default connect(select, perform)(FileItem);
select,
perform,
)(FileItem);
...@@ -36,7 +36,4 @@ const perform = dispatch => ({ ...@@ -36,7 +36,4 @@ const perform = dispatch => ({
setPlayerVisible: (visible, uri) => dispatch(doSetPlayerVisible(visible, uri)), setPlayerVisible: (visible, uri) => dispatch(doSetPlayerVisible(visible, uri)),
}); });
export default connect( export default connect(select, perform)(FileListItem);
select,
perform,
)(FileListItem);
...@@ -125,7 +125,9 @@ class FileListItem extends React.PureComponent { ...@@ -125,7 +125,9 @@ class FileListItem extends React.PureComponent {
const outpointsToHide = !blackListedOutpoints const outpointsToHide = !blackListedOutpoints
? filteredOutpoints ? filteredOutpoints
: blackListedOutpoints.concat(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? // TODO: hide channels on tag pages?
...@@ -143,10 +145,14 @@ class FileListItem extends React.PureComponent { ...@@ -143,10 +145,14 @@ class FileListItem extends React.PureComponent {
<View> <View>
{isRepost && ( {isRepost && (
<View style={fileListStyle.repostInfo}> <View style={fileListStyle.repostInfo}>
<Icon name={"retweet"} size={14} style={fileListStyle.repostIcon} /> <Icon name={'retweet'} size={14} style={fileListStyle.repostIcon} />
<Text style={fileListStyle.repostChannelName}> <Text style={fileListStyle.repostChannelName}>
<Link text={repostChannel} <Link
onPress={() => navigateToUri(navigation, normalizeURI(repostChannelUrl), null, false, null, false)} /> reposted</Text> text={repostChannel}
onPress={() => navigateToUri(navigation, normalizeURI(repostChannelUrl), null, false, null, false)}
/>{' '}
reposted
</Text>
</View> </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 => ({ ...@@ -23,7 +23,4 @@ const perform = dispatch => ({
unsubscribe: subscription => doChannelUnsubscribe(subscription), unsubscribe: subscription => doChannelUnsubscribe(subscription),
}); });
export default connect( export default connect(select, perform)(SuggestedSubscriptionItem);
select,
perform,
)(SuggestedSubscriptionItem);
...@@ -16,7 +16,4 @@ const perform = dispatch => ({ ...@@ -16,7 +16,4 @@ const perform = dispatch => ({
claimSearch: options => dispatch(doClaimSearch(options)), claimSearch: options => dispatch(doClaimSearch(options)),
}); });
export default connect( export default connect(select, perform)(SuggestedSubscriptions);
select,
perform
)(SuggestedSubscriptions);
...@@ -24,7 +24,4 @@ const perform = dispatch => ({ ...@@ -24,7 +24,4 @@ const perform = dispatch => ({
claimSearch: options => dispatch(doClaimSearch(options)), claimSearch: options => dispatch(doClaimSearch(options)),
}); });
export default connect( export default connect(select, perform)(SuggestedSubscriptionsGrid);
select,
perform,
)(SuggestedSubscriptionsGrid);
...@@ -46,6 +46,8 @@ const Constants = { ...@@ -46,6 +46,8 @@ const Constants = {
SETTING_DEVICE_WALLET_SYNCED: 'deviceWalletSynced', SETTING_DEVICE_WALLET_SYNCED: 'deviceWalletSynced',
SETTING_DHT_ENABLED: 'dhtEnabled', SETTING_DHT_ENABLED: 'dhtEnabled',
ACTION_SDK_READY: 'SDK_READY',
ACTION_DELETE_COMPLETED_BLOBS: 'DELETE_COMPLETED_BLOBS', ACTION_DELETE_COMPLETED_BLOBS: 'DELETE_COMPLETED_BLOBS',
ACTION_FIRST_RUN_PAGE_CHANGED: 'FIRST_RUN_PAGE_CHANGED', ACTION_FIRST_RUN_PAGE_CHANGED: 'FIRST_RUN_PAGE_CHANGED',
......
...@@ -55,6 +55,10 @@ import settingsReducer from 'redux/reducers/settings'; ...@@ -55,6 +55,10 @@ import settingsReducer from 'redux/reducers/settings';
import thunk from 'redux-thunk'; import thunk from 'redux-thunk';
window.__ = __; window.__ = __;
if (!NativeModules.UtilityModule.dhtEnabled) {
Lbry.alternateConnectionString = 'https://api.lbry.tv/api/v1/proxy';
Lbry.methodsUsingAlternateConnectionString = ['claim_search', 'resolve'];
}
const globalExceptionHandler = (error, isFatal) => { const globalExceptionHandler = (error, isFatal) => {
if (error && NativeModules.Firebase) { if (error && NativeModules.Firebase) {
......
...@@ -22,6 +22,7 @@ import { ...@@ -22,6 +22,7 @@ import {
import { doUpdateChannelFormState, doClearChannelFormState } from 'redux/actions/form'; import { doUpdateChannelFormState, doClearChannelFormState } from 'redux/actions/form';
import { selectDrawerStack } from 'redux/selectors/drawer'; import { selectDrawerStack } from 'redux/selectors/drawer';
import { selectChannelFormState, selectHasChannelFormState } from 'redux/selectors/form'; 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 Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
import ChannelCreator from './view'; import ChannelCreator from './view';
...@@ -33,6 +34,7 @@ const select = state => ({ ...@@ -33,6 +34,7 @@ const select = state => ({
fetchingChannels: selectFetchingMyChannels(state), fetchingChannels: selectFetchingMyChannels(state),
balance: selectBalance(state), balance: selectBalance(state),
hasFormState: selectHasChannelFormState(state), hasFormState: selectHasChannelFormState(state),
sdkReady: selectSdkReady(state),
updatingChannel: selectUpdatingChannel(state), updatingChannel: selectUpdatingChannel(state),
updateChannelError: selectUpdateChannelError(state), updateChannelError: selectUpdateChannelError(state),
}); });
...@@ -52,7 +54,4 @@ const perform = dispatch => ({ ...@@ -52,7 +54,4 @@ const perform = dispatch => ({
setExplicitNavigateBack: flag => dispatch(doSetExplicitNavigateBack(flag)), setExplicitNavigateBack: flag => dispatch(doSetExplicitNavigateBack(flag)),
}); });
export default connect( export default connect(select, perform)(ChannelCreator);
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