Compare commits

...

4 commits

Author SHA1 Message Date
Akinwale Ariwodola
2cb393e6ee fix merge conflicts 2019-10-11 17:25:32 +01:00
Akinwale Ariwodola
79c02825d1 preferences sync and wallet sync updates 2019-10-11 17:12:51 +01:00
Akinwale Ariwodola
f42cbb90a0 use doPreferenceGet for retrieving saved user state 2019-10-02 10:29:08 +01:00
Akinwale Ariwodola
5eba4ab2ec use shared state subscriber for preferences_set and preferences_get 2019-09-30 22:54:31 +01:00
11 changed files with 81 additions and 48 deletions

8
package-lock.json generated
View file

@ -5640,8 +5640,8 @@
} }
}, },
"lbry-redux": { "lbry-redux": {
"version": "github:lbryio/lbry-redux#7ec72a737bcd336f000c5f5085891643110298c3", "version": "github:lbryio/lbry-redux#f06e1e64a8587a183bd7333f628fca821fe81fa4",
"from": "github:lbryio/lbry-redux#7ec72a737bcd336f000c5f5085891643110298c3", "from": "github:lbryio/lbry-redux#f06e1e64a8587a183bd7333f628fca821fe81fa4",
"requires": { "requires": {
"proxy-polyfill": "0.1.6", "proxy-polyfill": "0.1.6",
"reselect": "^3.0.0", "reselect": "^3.0.0",
@ -5649,8 +5649,8 @@
} }
}, },
"lbryinc": { "lbryinc": {
"version": "github:lbryio/lbryinc#c55a2c98ab92c72149c824ee5906aed4404fd89b", "version": "github:lbryio/lbryinc#02d8571cd7fafd00d1a60f133d884eb8c5f1a306",
"from": "github:lbryio/lbryinc#c55a2c98ab92c72149c824ee5906aed4404fd89b", "from": "github:lbryio/lbryinc#02d8571cd7fafd00d1a60f133d884eb8c5f1a306",
"requires": { "requires": {
"reselect": "^3.0.0" "reselect": "^3.0.0"
} }

View file

@ -12,8 +12,8 @@
"base-64": "^0.1.0", "base-64": "^0.1.0",
"@expo/vector-icons": "^8.1.0", "@expo/vector-icons": "^8.1.0",
"gfycat-style-urls": "^1.0.3", "gfycat-style-urls": "^1.0.3",
"lbry-redux": "lbryio/lbry-redux#7ec72a737bcd336f000c5f5085891643110298c3", "lbry-redux": "lbryio/lbry-redux#f06e1e64a8587a183bd7333f628fca821fe81fa4",
"lbryinc": "lbryio/lbryinc#c55a2c98ab92c72149c824ee5906aed4404fd89b", "lbryinc": "lbryio/lbryinc#02d8571cd7fafd00d1a60f133d884eb8c5f1a306",
"lodash": ">=4.17.11", "lodash": ">=4.17.11",
"merge": ">=1.2.1", "merge": ">=1.2.1",
"moment": "^2.22.1", "moment": "^2.22.1",

View file

@ -29,7 +29,7 @@ import {
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { AppState, BackHandler, Linking, NativeModules, TextInput, ToastAndroid } from 'react-native'; import { AppState, BackHandler, Linking, NativeModules, TextInput, ToastAndroid } from 'react-native';
import { selectDrawerStack } from 'redux/selectors/drawer'; import { selectDrawerStack } from 'redux/selectors/drawer';
import { SETTINGS, doDismissToast, doPopulateSharedUserState, doToast, selectToast } from 'lbry-redux'; import { SETTINGS, doDismissToast, doPopulateSharedUserState, doPreferenceGet, doToast, selectToast } from 'lbry-redux';
import { import {
Lbryio, Lbryio,
doGetSync, doGetSync,
@ -39,6 +39,7 @@ import {
selectEmailToVerify, selectEmailToVerify,
selectEmailVerifyIsPending, selectEmailVerifyIsPending,
selectEmailVerifyErrorMessage, selectEmailVerifyErrorMessage,
selectHashChanged,
selectUser, selectUser,
} from 'lbryinc'; } from 'lbryinc';
import { makeSelectClientSetting } from 'redux/selectors/settings'; import { makeSelectClientSetting } from 'redux/selectors/settings';
@ -53,6 +54,8 @@ 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';
const SYNC_GET_INTERVAL = 1000 * 60 * 5; // every 5 minutes
const menuNavigationButton = navigation => ( const menuNavigationButton = navigation => (
<NavigationButton <NavigationButton
name="bars" name="bars"
@ -272,6 +275,7 @@ class AppWithNavigationState extends React.Component {
this.state = { this.state = {
emailVerifyDone: false, emailVerifyDone: false,
verifyPending: false, verifyPending: false,
syncHashChanged: false,
}; };
} }
@ -292,8 +296,17 @@ class AppWithNavigationState extends React.Component {
} }
componentDidMount() { componentDidMount() {
const { dispatch } = this.props;
this.emailVerifyCheckInterval = setInterval(() => this.checkEmailVerification(), 5000); this.emailVerifyCheckInterval = setInterval(() => this.checkEmailVerification(), 5000);
Linking.addEventListener('url', this._handleUrl); Linking.addEventListener('url', this._handleUrl);
// call /sync/get with interval
setInterval(() => {
this.setState({ syncHashChanged: false }); // reset local state
NativeModules.UtilityModule.getSecureValue(Constants.KEY_FIRST_RUN_PASSWORD).then(walletPassword => {
dispatch(doGetSync(walletPassword));
});
}, SYNC_GET_INTERVAL);
} }
checkEmailVerification = () => { checkEmailVerification = () => {
@ -308,8 +321,8 @@ class AppWithNavigationState extends React.Component {
getUserSettings = () => { getUserSettings = () => {
const { dispatch } = this.props; const { dispatch } = this.props;
Lbryio.call('user_settings', 'get').then(settings => { doPreferenceGet('shared', null, null, preference => {
dispatch(doPopulateSharedUserState(settings)); dispatch(doPopulateSharedUserState(preference));
}); });
}; };
@ -320,7 +333,7 @@ class AppWithNavigationState extends React.Component {
} }
componentDidUpdate() { componentDidUpdate() {
const { dispatch, user } = this.props; const { dispatch, user, hashChanged } = this.props;
if (this.state.verifyPending && this.emailVerifyCheckInterval > 0 && user && user.has_verified_email) { if (this.state.verifyPending && this.emailVerifyCheckInterval > 0 && user && user.has_verified_email) {
clearInterval(this.emailVerifyCheckInterval); clearInterval(this.emailVerifyCheckInterval);
AsyncStorage.setItem(Constants.KEY_EMAIL_VERIFY_PENDING, 'false'); AsyncStorage.setItem(Constants.KEY_EMAIL_VERIFY_PENDING, 'false');
@ -332,6 +345,11 @@ class AppWithNavigationState extends React.Component {
// get user settings after email verification // get user settings after email verification
this.getUserSettings(); this.getUserSettings();
} }
if (hashChanged && !this.state.syncHashChanged) {
this.setState({ syncHashChanged: true });
this.getUserSettings();
}
} }
componentWillUpdate(nextProps) { componentWillUpdate(nextProps) {
@ -438,6 +456,7 @@ class AppWithNavigationState extends React.Component {
const mapStateToProps = state => ({ const mapStateToProps = state => ({
backgroundPlayEnabled: makeSelectClientSetting(SETTINGS.BACKGROUND_PLAY_ENABLED)(state), backgroundPlayEnabled: makeSelectClientSetting(SETTINGS.BACKGROUND_PLAY_ENABLED)(state),
hashChanged: selectHashChanged(state),
keepDaemonRunning: makeSelectClientSetting(SETTINGS.KEEP_DAEMON_RUNNING)(state), keepDaemonRunning: makeSelectClientSetting(SETTINGS.KEEP_DAEMON_RUNNING)(state),
nav: state.nav, nav: state.nav,
toast: selectToast(state), toast: selectToast(state),

View file

@ -7,6 +7,7 @@ import {
doCreateChannel, doCreateChannel,
doToast, doToast,
} from 'lbry-redux'; } from 'lbry-redux';
import { doGetSync } from 'lbryinc';
import ChannelSelector from './view'; import ChannelSelector from './view';
const select = state => ({ const select = state => ({
@ -19,6 +20,7 @@ const perform = dispatch => ({
notify: data => dispatch(doToast(data)), notify: data => dispatch(doToast(data)),
createChannel: (name, amount) => dispatch(doCreateChannel(name, amount)), createChannel: (name, amount) => dispatch(doCreateChannel(name, amount)),
fetchChannelListMine: () => dispatch(doFetchChannelListMine()), fetchChannelListMine: () => dispatch(doFetchChannelListMine()),
getSync: password => dispatch(doGetSync(password)),
}); });
export default connect( export default connect(

View file

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { CLAIM_VALUES, isNameValid } from 'lbry-redux'; import { CLAIM_VALUES, isNameValid } from 'lbry-redux';
import { ActivityIndicator, Picker, Text, TextInput, TouchableOpacity, View } from 'react-native'; import { ActivityIndicator, NativeModules, Picker, Text, TextInput, TouchableOpacity, View } from 'react-native';
import Button from 'component/button'; import Button from 'component/button';
import Colors from 'styles/colors'; import Colors from 'styles/colors';
import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
@ -117,7 +117,7 @@ export default class ChannelSelector extends React.PureComponent {
}; };
handleCreateChannelClick = () => { handleCreateChannelClick = () => {
const { balance, createChannel, onChannelChange, notify } = this.props; const { balance, createChannel, getSync, onChannelChange, notify } = this.props;
const { newChannelBid, newChannelName } = this.state; const { newChannelBid, newChannelName } = this.state;
if (newChannelName.trim().length === 0 || !isNameValid(newChannelName.substr(1), false)) { if (newChannelName.trim().length === 0 || !isNameValid(newChannelName.substr(1), false)) {
@ -153,6 +153,9 @@ export default class ChannelSelector extends React.PureComponent {
if (onChannelChange) { if (onChannelChange) {
onChannelChange(channelName); onChannelChange(channelName);
} }
// sync wallet
NativeModules.UtilityModule.getSecureValue(Constants.KEY_FIRST_RUN_PASSWORD).then(password => getSync(password));
}; };
const failure = () => { const failure = () => {

View file

@ -13,6 +13,7 @@ import {
searchReducer, searchReducer,
tagsReducer, tagsReducer,
walletReducer, walletReducer,
sharedStateSubscriber,
} from 'lbry-redux'; } from 'lbry-redux';
import { import {
Lbryio, Lbryio,
@ -147,25 +148,28 @@ const persistor = persistStore(store, persistOptions, err => {
}); });
window.persistor = persistor; window.persistor = persistor;
let currentPayload; /**
store.subscribe(() => { * source: the reducer name
const state = store.getState(); * property: the property in the reducer-specific state
const subscriptions = state.subscriptions.subscriptions.map(({ uri }) => uri); * transform: optional method to modify the value to be stored
const tags = state.tags.followedTags; */
const sharedStateFilters = {
const newPayload = { tags: { source: 'tags', property: 'followedTags' },
version: '0.1', subscriptions: {
shared: { source: 'subscriptions',
subscriptions, property: 'subscriptions',
tags, transform: function(value) {
return value.map(({ uri }) => uri);
}, },
}; },
};
if (!isEqual(newPayload, currentPayload)) { store.subscribe(() => {
currentPayload = newPayload; try {
if (Lbryio.authToken) { const state = store.getState();
Lbryio.call('user_settings', 'set', { settings: JSON.stringify(newPayload) }); sharedStateSubscriber(state, sharedStateFilters, '0.1');
} } catch (e) {
// handle gracefully?
} }
}); });

View file

@ -12,6 +12,7 @@ import {
doUpdateChannel, doUpdateChannel,
doToast, doToast,
} from 'lbry-redux'; } from 'lbry-redux';
import { doGetSync } from 'lbryinc';
import { doPushDrawerStack, doPopDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer'; import { doPushDrawerStack, doPopDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer';
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';
@ -37,6 +38,7 @@ const perform = dispatch => ({
clearChannelFormState: () => dispatch(doClearChannelFormState()), clearChannelFormState: () => dispatch(doClearChannelFormState()),
createChannel: (name, amount, optionalParams) => dispatch(doCreateChannel(name, amount, optionalParams)), createChannel: (name, amount, optionalParams) => dispatch(doCreateChannel(name, amount, optionalParams)),
fetchChannelListMine: () => dispatch(doFetchChannelListMine()), fetchChannelListMine: () => dispatch(doFetchChannelListMine()),
getSync: password => dispatch(doGetSync(password)),
updateChannel: params => dispatch(doUpdateChannel(params)), updateChannel: params => dispatch(doUpdateChannel(params)),
updateChannelFormState: data => dispatch(doUpdateChannelFormState(data)), updateChannelFormState: data => dispatch(doUpdateChannelFormState(data)),
pushDrawerStack: (routeName, params) => dispatch(doPushDrawerStack(routeName, params)), pushDrawerStack: (routeName, params) => dispatch(doPushDrawerStack(routeName, params)),

View file

@ -376,7 +376,15 @@ export default class ChannelCreator extends React.PureComponent {
}; };
handleCreateChannelClick = () => { handleCreateChannelClick = () => {
const { balance, clearChannelFormState, createChannel, onChannelChange, notify, updateChannel } = this.props; const {
balance,
clearChannelFormState,
createChannel,
onChannelChange,
getSync,
notify,
updateChannel,
} = this.props;
const { const {
claimId, claimId,
coverImageUrl, coverImageUrl,
@ -439,6 +447,9 @@ export default class ChannelCreator extends React.PureComponent {
clearChannelFormState(); clearChannelFormState();
notify({ message: 'The channel was successfully created.' }); notify({ message: 'The channel was successfully created.' });
this.showChannelList(); this.showChannelList();
// sync wallet
NativeModules.UtilityModule.getSecureValue(Constants.KEY_FIRST_RUN_PASSWORD).then(password => getSync(password));
}; };
const failure = () => { const failure = () => {

View file

@ -12,7 +12,7 @@ import {
View, View,
} from 'react-native'; } from 'react-native';
import Colors from 'styles/colors'; import Colors from 'styles/colors';
import Constants from 'constants'; import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api
import Icon from 'react-native-vector-icons/FontAwesome5'; import Icon from 'react-native-vector-icons/FontAwesome5';
import firstRunStyle from 'styles/firstRun'; import firstRunStyle from 'styles/firstRun';
@ -45,8 +45,8 @@ class SkipAccountPage extends React.PureComponent {
/> />
</View> </View>
<Text style={firstRunStyle.rowParagraph}> <Text style={firstRunStyle.rowParagraph}>
I understand that by uninstalling LBRY I will lose any balances or published content with no recovery I understand that by uninstalling LBRY I will lose any balances or published content with no recovery option
option if it is not backed up manually (see wallet page) if it is not backed up manually (see wallet page)
</Text> </Text>
</View> </View>
</View> </View>

View file

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { Lbry } 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, Linking, NativeModules, Platform, Text, View } from 'react-native';
import { NavigationActions, StackActions } from 'react-navigation'; import { NavigationActions, StackActions } from 'react-navigation';
@ -16,8 +16,6 @@ import splashStyle from 'styles/splash';
const BLOCK_HEIGHT_INTERVAL = 1000 * 60 * 2.5; // every 2.5 minutes const BLOCK_HEIGHT_INTERVAL = 1000 * 60 * 2.5; // every 2.5 minutes
const SETTINGS_GET_INTERVAL = 1000 * 60 * 5; // every 5 minutes
const testingNetwork = 'Testing network'; const testingNetwork = 'Testing network';
const waitingForResolution = 'Waiting for name resolution'; const waitingForResolution = 'Waiting for name resolution';
@ -98,9 +96,7 @@ class SplashScreen extends React.PureComponent {
// user is authenticated, navigate to the main view // user is authenticated, navigate to the main view
if (user.has_verified_email) { if (user.has_verified_email) {
NativeModules.UtilityModule.getSecureValue(Constants.KEY_FIRST_RUN_PASSWORD).then(walletPassword => { NativeModules.UtilityModule.getSecureValue(Constants.KEY_FIRST_RUN_PASSWORD).then(walletPassword => {
if (walletPassword) { getSync(walletPassword);
getSync(walletPassword);
}
this.navigateToMain(); this.navigateToMain();
}); });
return; return;
@ -113,8 +109,9 @@ class SplashScreen extends React.PureComponent {
getUserSettings = () => { getUserSettings = () => {
const { populateSharedUserState } = this.props; const { populateSharedUserState } = this.props;
Lbryio.call('user_settings', 'get').then(settings => {
populateSharedUserState(settings); doPreferenceGet('shared', null, null, preference => {
populateSharedUserState(preference);
}); });
}; };
@ -139,14 +136,11 @@ class SplashScreen extends React.PureComponent {
// get user settings interval // get user settings interval
this.getUserSettings(); this.getUserSettings();
setInterval(() => this.getUserSettings(), SETTINGS_GET_INTERVAL);
if (user && user.id && user.has_verified_email) { if (user && user.id && user.has_verified_email) {
// user already authenticated // user already authenticated
NativeModules.UtilityModule.getSecureValue(Constants.KEY_FIRST_RUN_PASSWORD).then(walletPassword => { NativeModules.UtilityModule.getSecureValue(Constants.KEY_FIRST_RUN_PASSWORD).then(walletPassword => {
if (walletPassword) { getSync(walletPassword);
getSync(walletPassword);
}
this.navigateToMain(); this.navigateToMain();
}); });
} else { } else {

View file

@ -47,9 +47,7 @@ class WalletPage extends React.PureComponent {
const { deviceWalletSynced, getSync, user } = this.props; const { deviceWalletSynced, getSync, user } = this.props;
if (deviceWalletSynced && user && user.has_verified_email) { if (deviceWalletSynced && user && user.has_verified_email) {
NativeModules.UtilityModule.getSecureValue(Constants.KEY_FIRST_RUN_PASSWORD).then(walletPassword => { NativeModules.UtilityModule.getSecureValue(Constants.KEY_FIRST_RUN_PASSWORD).then(walletPassword => {
if (walletPassword) { getSync(walletPassword);
getSync(walletPassword);
}
}); });
} }
}; };