Preferences #56

Closed
akinwale wants to merge 4 commits from preferences into master
11 changed files with 81 additions and 48 deletions

8
package-lock.json generated
View file

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

View file

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

View file

@ -29,7 +29,7 @@ import {
import { connect } from 'react-redux';
kauffj commented 2019-10-11 22:47:33 +02:00 (Migrated from github.com)
Review

none of the logic in this file appears to affect the presentation or rendering of this component

is there a design that would separate this out more cleanly? maybe just make it it's own component?

none of the logic in this file appears to affect the presentation or rendering of this component is there a design that would separate this out more cleanly? maybe just make it it's own component?
import { AppState, BackHandler, Linking, NativeModules, TextInput, ToastAndroid } from 'react-native';
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 {
Lbryio,
doGetSync,
@ -39,6 +39,7 @@ import {
selectEmailToVerify,
selectEmailVerifyIsPending,
selectEmailVerifyErrorMessage,
selectHashChanged,
selectUser,
} from 'lbryinc';
import { makeSelectClientSetting } from 'redux/selectors/settings';
@ -53,6 +54,8 @@ import discoverStyle from 'styles/discover';
import searchStyle from 'styles/search';
import SearchRightHeaderIcon from 'component/searchRightHeaderIcon';
const SYNC_GET_INTERVAL = 1000 * 60 * 5; // every 5 minutes
const menuNavigationButton = navigation => (
<NavigationButton
name="bars"
@ -272,6 +275,7 @@ class AppWithNavigationState extends React.Component {
this.state = {
emailVerifyDone: false,
verifyPending: false,
syncHashChanged: false,
};
}
@ -292,8 +296,17 @@ class AppWithNavigationState extends React.Component {
}
componentDidMount() {
const { dispatch } = this.props;
this.emailVerifyCheckInterval = setInterval(() => this.checkEmailVerification(), 5000);
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 = () => {
@ -308,8 +321,8 @@ class AppWithNavigationState extends React.Component {
getUserSettings = () => {
const { dispatch } = this.props;
Lbryio.call('user_settings', 'get').then(settings => {
dispatch(doPopulateSharedUserState(settings));
doPreferenceGet('shared', null, null, preference => {
dispatch(doPopulateSharedUserState(preference));
});
};
@ -320,7 +333,7 @@ class AppWithNavigationState extends React.Component {
}
componentDidUpdate() {
const { dispatch, user } = this.props;
const { dispatch, user, hashChanged } = this.props;
if (this.state.verifyPending && this.emailVerifyCheckInterval > 0 && user && user.has_verified_email) {
clearInterval(this.emailVerifyCheckInterval);
kauffj commented 2019-10-11 22:48:15 +02:00 (Migrated from github.com)
Review

you should probably store the result of this setInterval call and call clearInterval on unmount

you should probably store the result of this `setInterval` call and call `clearInterval` on unmount
AsyncStorage.setItem(Constants.KEY_EMAIL_VERIFY_PENDING, 'false');
@ -332,6 +345,11 @@ class AppWithNavigationState extends React.Component {
// get user settings after email verification
this.getUserSettings();
}
if (hashChanged && !this.state.syncHashChanged) {
this.setState({ syncHashChanged: true });
this.getUserSettings();
}
}
componentWillUpdate(nextProps) {
@ -438,6 +456,7 @@ class AppWithNavigationState extends React.Component {
const mapStateToProps = state => ({
backgroundPlayEnabled: makeSelectClientSetting(SETTINGS.BACKGROUND_PLAY_ENABLED)(state),
hashChanged: selectHashChanged(state),
keepDaemonRunning: makeSelectClientSetting(SETTINGS.KEEP_DAEMON_RUNNING)(state),
nav: state.nav,
toast: selectToast(state),

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -12,7 +12,7 @@ import {
View,
} from 'react-native';
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 firstRunStyle from 'styles/firstRun';
@ -45,8 +45,8 @@ class SkipAccountPage extends React.PureComponent {
/>
</View>
<Text style={firstRunStyle.rowParagraph}>
I understand that by uninstalling LBRY I will lose any balances or published content with no recovery
option if it is not backed up manually (see wallet page)
I understand that by uninstalling LBRY I will lose any balances or published content with no recovery option
if it is not backed up manually (see wallet page)
</Text>
</View>
</View>

View file

@ -1,5 +1,5 @@
import React from 'react';
import { Lbry } from 'lbry-redux';
import { Lbry, doPreferenceGet } from 'lbry-redux';
import { Lbryio } from 'lbryinc';
import { ActivityIndicator, Linking, NativeModules, Platform, Text, View } from 'react-native';
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 SETTINGS_GET_INTERVAL = 1000 * 60 * 5; // every 5 minutes
const testingNetwork = 'Testing network';
const waitingForResolution = 'Waiting for name resolution';
@ -98,9 +96,7 @@ class SplashScreen extends React.PureComponent {
// user is authenticated, navigate to the main view
if (user.has_verified_email) {
NativeModules.UtilityModule.getSecureValue(Constants.KEY_FIRST_RUN_PASSWORD).then(walletPassword => {
if (walletPassword) {
getSync(walletPassword);
}
this.navigateToMain();
});
return;
@ -113,8 +109,9 @@ class SplashScreen extends React.PureComponent {
getUserSettings = () => {
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
this.getUserSettings();
setInterval(() => this.getUserSettings(), SETTINGS_GET_INTERVAL);
if (user && user.id && user.has_verified_email) {
// user already authenticated
NativeModules.UtilityModule.getSecureValue(Constants.KEY_FIRST_RUN_PASSWORD).then(walletPassword => {
if (walletPassword) {
getSync(walletPassword);
}
this.navigateToMain();
});
} else {

View file

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