merging with master

This commit is contained in:
u-e 2019-07-23 20:03:29 +03:00
commit ebd8c9108b
35 changed files with 370 additions and 169 deletions

View File

@ -3,6 +3,7 @@ BACKEND_URL=
NEW_IMAGE_API=
OLD_IMAGE_API=
PIN_KEY=
DEFAULT_PIN=
SEARCH_API_TOKEN=
SEARCH_API_URL=
SERVER_LIST_API=

View File

@ -35,12 +35,12 @@ android_library(
android_build_config(
name = "build_config",
package = "app.esteem.mobile",
package = "app.esteem.mobile.android",
)
android_resource(
name = "res",
package = "app.esteem.mobile",
package = "app.esteem.mobile.android",
res = "src/main/res",
)

View File

@ -110,7 +110,7 @@ android {
}
defaultConfig {
applicationId "app.esteem.mobile"
applicationId "app.esteem.mobile.android"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode versionMajor * 10000 + versionMinor * 100 + versionPatch

View File

@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="app.esteem.mobile">
package="app.esteem.mobile.android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA"/>

View File

@ -1,4 +1,4 @@
package app.esteem.mobile;
package app.esteem.mobile.android;
import com.facebook.react.ReactActivity;

View File

@ -1,4 +1,4 @@
package app.esteem.mobile;
package app.esteem.mobile.android;
import android.app.Application;

View File

@ -1,7 +1,7 @@
import React, { Component } from 'react';
import { Animated, Easing, View } from 'react-native';
import { connect } from 'react-redux';
import { withNavigation } from 'react-navigation';
import { NavigationActions } from 'react-navigation';
// Components
import SubPostButton from './subPostButtonView';
@ -95,14 +95,13 @@ class PostButtonsForAndroid extends Component {
};
_handleSubButtonPress = (route, action) => {
const { navigation } = this.props;
navigation.navigate({
const { dispatch } = this.props;
const navigateAction = NavigationActions.navigate({
routeName: route,
params: {
action,
},
params: { action },
action: NavigationActions.navigate({ routeName: route }),
});
dispatch(navigateAction);
};
render() {
@ -177,4 +176,4 @@ const mapStateToProps = state => ({
isCollapsePostButtonOpen: state.ui.isCollapsePostButton,
});
export default connect(mapStateToProps)(withNavigation(PostButtonsForAndroid));
export default connect(mapStateToProps)(PostButtonsForAndroid);

View File

@ -1,5 +1,6 @@
import React, { PureComponent, Fragment } from 'react';
import { connect } from 'react-redux';
import get from 'lodash/get';
// Component
import PostsView from '../view/postsView';
@ -53,7 +54,9 @@ class PostsContainer extends PureComponent {
return (
<PostsView
handleOnScrollStart={this._handleOnScrollStart}
currentAccountUsername={currentAccount && currentAccount.username}
currentAccountUsername={
currentAccount && (get(currentAccount, 'username') || get(currentAccount, 'name'))
}
setFeedPosts={this._setFeedPosts}
feedPosts={feedPosts}
isConnected={isConnected}

View File

@ -22,7 +22,7 @@ class PostsView extends Component {
super(props);
this.state = {
posts: props.feedPosts,
posts: props.isConnected ? [] : props.feedPosts,
startAuthor: '',
startPermlink: '',
refreshing: false,
@ -178,7 +178,10 @@ class PostsView extends Component {
}
}
setFeedPosts(_posts);
if (posts.length < 5) {
setFeedPosts(_posts);
}
if (refreshing && newPosts.length > 0) {
this.setState({
posts: _posts,

View File

@ -27,7 +27,7 @@ class WalletContainer extends PureComponent {
// Component Functions
_navigate = async (transferType, fundType) => {
const { dispatch, walletData } = this.props;
const { dispatch, walletData, isPinCodeOpen, navigation } = this.props;
let balance;
switch (fundType) {
@ -47,12 +47,19 @@ class WalletContainer extends PureComponent {
break;
}
dispatch(
openPinCodeModal({
navigateTo: ROUTES.SCREENS.TRANSFER,
navigateParams: { transferType, fundType, balance },
}),
);
if (isPinCodeOpen) {
dispatch(
openPinCodeModal({
navigateTo: ROUTES.SCREENS.TRANSFER,
navigateParams: { transferType, fundType, balance },
}),
);
} else {
navigation.navigate({
routeName: ROUTES.SCREENS.TRANSFER,
params: { transferType, fundType, balance },
});
}
};
render() {
@ -69,4 +76,8 @@ class WalletContainer extends PureComponent {
}
}
export default connect()(withNavigation(WalletContainer));
const mapStateToProps = state => ({
isPinCodeOpen: state.application.isPinCodeOpen,
});
export default connect(mapStateToProps)(withNavigation(WalletContainer));

View File

@ -3,7 +3,7 @@
"curation_reward": "কিউরেটর পুরস্কার",
"author_reward": "Whats up everyone",
"comment_benefactor_reward": "মন্তব্য উপকারিতার পুরস্কার",
"claim_reward_balance": "এখানে iOS ডিভাইসগুলির জন্য eSteem Mobile 2 সাম্প্রতিক আপডেট। নতুন মোবাইল ক্লায়েন্ট পুনঃপ্রতিষ্ঠিত ইউজার ইন্টারফেসের সাথে Steem Blockchain এর জন্য।\n\n>এই সংস্করণটি eSteem 1.6.0 থেকে আলাদা, আপনি আগে এটি ব্যবহার করতে পারেন। এটি নিজে নিজে আপডেট হবে না। এখানে নতুন সংস্করণ ডাউনলোড করুন: [iOS](https:\/\/itunes.apple.com\/WebObjects\/MZStore.woa\/wa\/viewSoftware?id=1451896376&mt=8), [Android](https:\/\/play.google.com\/store\/apps\/details?id=app.esteem.mobile)\n\n**2.0.8 তে কি কি নতুন**\n\nআমাদের Android ব্যবহারকারীদের জন্য সমস্ত কার্যকারিতা আছে। আপনি কিছু সমস্যা খুঁজে পেলে আমাদের রিপোর্ট করুন, যাতে আমরা এটি আরো উন্নত করতে পারি। এখন থেকে আমাদের Android এবং iOS রিলিজগুলো সমস্ত ব্যবহারকারীদের সন্তুষ্ট করতে সক্ষম হবে।\n\nকিছু বৈশিষ্ট্য:\n\n* পোস্ট করতে, কমেন্ট করতে, ভোট দিতে পারবেন\n* বিজ্ঞপ্তি দেওয়া হবে, কার্যক্রম উন্নত\n* একাধিক অ্যাকাউন্ট সমর্থন করা হবে\n* Steemconnect এর মাধ্যমে এবং ঐতিহ্যবাহী লগইন করতে পারবেন\n* কন্টেন্ট খসড়া, বুকমার্ক, পছন্দের তালিকায় রাখতে পারবেন\n* সুন্দর এবং সহজ সম্পাদক, ছবি আপলোড, ক্যাপচার সমর্থন করা হবে\n* সার্ভার নির্বাচন \/ পরিবর্তন করা যাবে\n* রিওয়ার্ড নির্বাচন \/ পরিবর্তন করা যাবে\n* গাঢ় থিম রয়েছে\n* ইংরেজির পাশাপাশি আরও ৫টি ভাষায় কথা বলার ব্যবস্থা রয়েছে\n* পিন কোড দ্বারা নিরাপত্তার ব্যবস্থা রয়েছে\n* এবং আরো অনেক কিছু\n\nঅ্যাপল অ্যাপস্টোর থেকে ডাউনলোড করে এটি পরীক্ষা করে দেখুন এবং আপনার কেমন লাগে তা আমাদের জানান ...\n\nAndroid Version খুঁজছেন?\n\n** পরীক্ষকগণ **\nআমরা এখনও বিটা পরীক্ষক খুঁজছি, মন্তব্য বা GitHub এ এখানে বাগ রিপোর্ট করুন। টেস্ট পুরস্কৃত করা হবে।",
"claim_reward_balance": "Claim Reward Balance",
"transfer": "স্থানান্তর",
"transfer_to_vesting": "Vesting কাছে হস্তান্তর",
"transfer_from_savings": "সঞ্চয় থেকে স্থানান্তর করুন",

View File

@ -106,6 +106,7 @@
"transfers": "Transfers"
},
"pincode": "PIN code",
"reset_pin": "Reset Pin Code",
"reset": "Reset",
"nsfw_content": "NSFW Content",
"send_feedback": "Send Feedback",

View File

@ -204,8 +204,8 @@
"confirm": "Megerősítés",
"removed": "Eltávolítva",
"same_user": "Ez a felhasználó már szerepel a listán",
"unknow_error": "An error occurred",
"error": "Error"
"unknow_error": "Hiba történt",
"error": "Hiba"
},
"post": {
"reblog_alert": "Biztos, hogy megosztod?",
@ -311,8 +311,8 @@
},
"promote": {
"title": "Promote",
"days": "days",
"user": "User",
"days": "nap",
"user": "Felhasználó",
"permlink": "Permlink",
"information": "Are you sure to transfer to promote?"
}

View File

@ -204,8 +204,8 @@
"confirm": "Xác nhận",
"removed": "Đã xóa",
"same_user": "Người dùng này đã được thêm vào danh sách",
"unknow_error": "An error occurred",
"error": "Error"
"unknow_error": "Đã xảy ra lỗi",
"error": "Lỗi"
},
"post": {
"reblog_alert": "Bạn có chắc chắn muốn đăng lại không?",
@ -309,10 +309,10 @@
"estimated_weekly": "Dự kiến hàng tuần"
},
"promote": {
"title": "Promote",
"days": "days",
"user": "User",
"permlink": "Permlink",
"information": "Are you sure to transfer to promote?"
"title": "Quảng bá",
"days": "những ngày",
"user": "Người dùng",
"permlink": "Đường dẫn thân thiện với người dùng",
"information": "Bạn có chắc chắn chuyển tiền để quảng bá?"
}
}

View File

@ -73,7 +73,7 @@ class PointsContainer extends Component {
// Component Functions
_handleOnPressTransfer = index => {
const { dispatch } = this.props;
const { dispatch, isPinCodeOpen, navigation } = this.props;
const { balance } = this.state;
let navigateTo;
let navigateParams;
@ -99,12 +99,19 @@ class PointsContainer extends Component {
break;
}
dispatch(
openPinCodeModal({
navigateTo,
navigateParams,
}),
);
if (isPinCodeOpen) {
dispatch(
openPinCodeModal({
navigateTo,
navigateParams,
}),
);
} else {
navigation.navigate({
routeName: navigateTo,
params: navigateParams,
});
}
};
_groomUserActivities = userActivities =>
@ -232,6 +239,12 @@ class PointsContainer extends Component {
refreshing,
userActivities,
userPoints,
handleOnPressTransfer: this._handleOnPressTransfer,
balance,
getUserBalance: this._getUserBalance,
promote: this._promote,
getAccount,
getUserDataWithUsername,
})
);
}
@ -244,7 +257,8 @@ const mapStateToProps = state => ({
isConnected: state.application.isConnected,
accounts: state.account.otherAccounts,
currentAccount: state.account.currentAccount,
pinCode: state.application.pin,
pinCode: state.account.pin,
isPinCodeOpen: state.application.isPinCodeOpen,
});
export default withNavigation(connect(mapStateToProps)(injectIntl(PointsContainer)));

View File

@ -151,6 +151,7 @@ class TransferContainer extends Component {
navigation.goBack();
})
.catch(err => {
navigation.goBack();
dispatch(toastNotification(err.message));
});
};

View File

@ -1,14 +1,32 @@
import React from 'react';
import { Provider } from 'react-redux';
import { Provider, connect } from 'react-redux';
import { PersistGate } from 'redux-persist/integration/react';
import { IntlProvider } from 'react-intl';
import { flattenMessages } from './utils/flattenMessages';
import messages from './config/locales';
import Application from './screens/application';
import { store, persistor } from './redux/store/store';
export default () => (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
const _renderApp = ({ locale }) => (
<PersistGate loading={null} persistor={persistor}>
<IntlProvider locale={locale} messages={flattenMessages(messages[locale])}>
<Application />
</PersistGate>
</Provider>
</IntlProvider>
</PersistGate>
);
const mapStateToProps = state => ({
locale: state.application.language,
});
const App = connect(mapStateToProps)(_renderApp);
export default () => {
return (
<Provider store={store}>
<App />
</Provider>
);
};

View File

@ -23,22 +23,6 @@ export const userActivity = (us, ty, bl = '', tx = '') =>
});
});
export const transfer = (sender, receiver, amount) =>
new Promise(resolve => {
ePointApi
.post('/transfer', {
se: sender,
re: receiver,
am: amount,
})
.then(res => {
resolve(res.data);
})
.catch(error => {
Alert.alert('Error', error.message);
});
});
export const getUser = username =>
new Promise(resolve => {
ePointApi

View File

@ -154,27 +154,32 @@ export const setUserDataWithPinCode = async data => {
}
};
export const updatePinCode = async data => {
try {
await setPinCode(data.pinCode);
const users = await getUserData();
if (users && users.length > 0) {
users.forEach(async userData => {
if (userData.authType === AUTH_TYPE.MASTER_KEY) {
data.password = decryptKey(userData.masterKey, data.oldPinCode);
} else if (userData.authType === AUTH_TYPE.STEEM_CONNECT) {
data.accessToken = decryptKey(userData.accessToken, data.oldPinCode);
export const updatePinCode = data =>
new Promise((resolve, reject) => {
let currentUser = null;
try {
setPinCode(data.pinCode);
getUserData().then(users => {
if (users && users.length > 0) {
users.forEach(userData => {
if (userData.authType === AUTH_TYPE.MASTER_KEY) {
data.password = decryptKey(userData.masterKey, data.oldPinCode);
} else if (userData.authType === AUTH_TYPE.STEEM_CONNECT) {
data.accessToken = decryptKey(userData.accessToken, data.oldPinCode);
}
const updatedUserData = getUpdatedUserData(userData, data);
updateUserData(updatedUserData);
if (userData.username === data.username) {
currentUser = updatedUserData;
}
resolve(currentUser);
});
}
const updatedUserData = getUpdatedUserData(userData, data);
await updateUserData(updatedUserData);
});
return true;
} catch (error) {
reject(error.message);
}
return false;
} catch (error) {
return Promise.reject(new Error('auth.unknow_error'));
}
};
});
export const verifyPinCode = async data => {
const pinHash = await getPinCode();

View File

@ -5,7 +5,7 @@ import get from 'lodash/get';
import { getServer } from '../../realm/realm';
import { getUnreadActivityCount } from '../esteem/esteem';
import { userActivity, transfer } from '../esteem/ePoint';
import { userActivity } from '../esteem/ePoint';
// Utils
import { decryptKey } from '../../utils/crypto';
@ -537,7 +537,6 @@ export const transferToken = (currentAccount, pin, data) => {
.transfer(args, privateKey)
.then(result => {
if (result) {
transfer(get(data, 'from'), get(data, 'destination'), get(data, 'ammount'));
resolve(result);
}
})

View File

@ -47,6 +47,7 @@ const settingsSchema = {
properties: {
currency: { type: 'string', default: null },
isDarkTheme: { type: 'bool', default: false },
isPinCodeOpen: { type: 'bool', default: true },
isDefaultFooter: { type: 'bool', default: true },
language: { type: 'string', default: null },
notification: { type: 'bool', default: true },
@ -82,7 +83,7 @@ const authSchema = {
const realm = new Realm({
path: 'esteem.realm',
schema: [userSchema, authSchema, draftSchema, settingsSchema, applicationSchema, scAccounts],
schemaVersion: 2,
schemaVersion: 3,
migration,
});
@ -374,6 +375,31 @@ export const getPinCode = () =>
// SETTINGS
export const getPinCodeOpen = () =>
new Promise((resolve, reject) => {
try {
if (settings[0]) {
resolve(settings[0].isPinCodeOpen);
} else {
resolve(false);
}
} catch (error) {
reject(error);
}
});
export const setPinCodeOpen = status =>
new Promise((resolve, reject) => {
try {
realm.write(() => {
settings[0].isPinCodeOpen = status;
resolve(true);
});
} catch (error) {
reject(error);
}
});
export const setTheme = isDarkTheme =>
new Promise((resolve, reject) => {
try {
@ -386,6 +412,19 @@ export const setTheme = isDarkTheme =>
}
});
export const getTheme = () =>
new Promise((resolve, reject) => {
try {
if (settings[0]) {
resolve(settings[0].isDarkTheme);
} else {
resolve(false);
}
} catch (error) {
reject(error);
}
});
export const setDefaultFooter = isDefaultFooter =>
new Promise((resolve, reject) => {
try {
@ -448,19 +487,6 @@ export const setNsfw = nsfw =>
}
});
export const getTheme = () =>
new Promise((resolve, reject) => {
try {
if (settings[0]) {
resolve(settings[0].isDarkTheme);
} else {
resolve(false);
}
} catch (error) {
reject(error);
}
});
export const setLanguage = selectedLanguage =>
new Promise((resolve, reject) => {
try {

View File

@ -25,6 +25,7 @@ import {
SET_NSFW,
SET_UPVOTE_PERCENT,
SET_PIN_CODE,
IS_PIN_CODE_OPEN,
} from '../constants/constants';
export const login = payload => ({
@ -132,6 +133,11 @@ export const isDarkTheme = payload => ({
type: IS_DARK_THEME,
});
export const isPinCodeOpen = payload => ({
payload,
type: IS_PIN_CODE_OPEN,
});
export const setConnectivityStatus = payload => ({
payload,
type: IS_CONNECTED,

View File

@ -8,6 +8,7 @@ export const ACTIVE_APPLICATION = 'ACTIVE_APPLICATION';
export const CLOSE_PIN_CODE_MODAL = 'CLOSE_PIN_CODE_MODAL';
export const IS_CONNECTED = 'IS_CONNECTED';
export const IS_DARK_THEME = 'IS_DARK_THEME';
export const IS_PIN_CODE_OPEN = 'IS_PIN_CODE_OPEN';
export const IS_LOGGED_IN = 'IS_LOGGED_IN';
export const IS_LOGIN_DONE = 'IS_LOGIN_DONE';
export const IS_NOTIFICATION_OPEN = 'IS_NOTIFICATION_OPEN';

View File

@ -1,3 +1,5 @@
import get from 'lodash/get';
import {
FETCH_ACCOUNT_FAIL,
FETCHING_ACCOUNT,
@ -45,7 +47,11 @@ export default function(state = initialState, action) {
case ADD_OTHER_ACCOUNT:
return {
...state,
otherAccounts: [...state.otherAccounts, action.payload],
otherAccounts: state.otherAccounts.some(
({ username }) => username === get(action.payload, 'username'),
)
? [...state.otherAccounts]
: [...state.otherAccounts, action.payload],
isFetching: false,
hasError: false,
errorMessage: null,

View File

@ -23,6 +23,7 @@ import {
SET_NSFW,
SET_UPVOTE_PERCENT,
SET_PIN_CODE,
IS_PIN_CODE_OPEN,
} from '../constants/constants';
const initialState = {
@ -55,6 +56,7 @@ const initialState = {
upvotePercent: 1,
nsfw: 'Always show',
pin: null,
isPinCodeOpen: true,
};
export default function(state = initialState, action) {
@ -175,6 +177,10 @@ export default function(state = initialState, action) {
return Object.assign({}, state, {
isDarkTheme: action.payload,
});
case IS_PIN_CODE_OPEN:
return Object.assign({}, state, {
isPinCodeOpen: action.payload,
});
case SET_UPVOTE_PERCENT:
return Object.assign({}, state, {
upvotePercent: action.payload,

View File

@ -7,7 +7,7 @@ import {
const initialState = {
activeBottomTab: 'HomeTabbar',
isCollapsePostButton: false,
toastNotifcaion: '',
toastNotification: '',
};
export default function(state = initialState, action) {

View File

@ -13,7 +13,7 @@ const persistConfig = {
// Storage Method (React Native)
storage: AsyncStorage,
// Blacklist (Don't Save Specific Reducers)
blacklist: ['nav', 'application'],
blacklist: ['nav', 'application', 'ui'],
};
// Middleware: Redux Persist Persisted Reducer

View File

@ -10,6 +10,7 @@ import { connect } from 'react-redux';
import { addLocaleData } from 'react-intl';
import { NavigationActions } from 'react-navigation';
import { bindActionCreators } from 'redux';
import EStyleSheet from 'react-native-extended-stylesheet';
// Languages
import en from 'react-intl/locale-data/en';
@ -69,8 +70,15 @@ import {
setUpvotePercent,
setNsfw,
isDefaultFooter,
isPinCodeOpen,
setPinCode as savePinCode,
} from '../../../redux/actions/applicationActions';
import { encryptKey } from '../../../utils/crypto';
import darkTheme from '../../../themes/darkTheme';
import lightTheme from '../../../themes/lightTheme';
addLocaleData([...en, ...ru, ...de, ...id, ...it, ...hu, ...tr, ...ko, ...pt, ...lt, ...fa]);
class ApplicationContainer extends Component {
@ -85,6 +93,11 @@ class ApplicationContainer extends Component {
};
}
componentWillMount() {
const { isDarkTheme: _isDarkTheme } = this.props;
EStyleSheet.build(_isDarkTheme ? darkTheme : lightTheme);
}
componentDidMount = () => {
const { isIos } = this.state;
@ -127,6 +140,7 @@ class ApplicationContainer extends Component {
componentWillUnmount() {
const { isIos } = this.state;
const { isPinCodeOpen: _isPinCodeOpen } = this.props;
if (!isIos) BackHandler.removeEventListener('hardwareBackPress', this._onBackPress);
@ -137,6 +151,10 @@ class ApplicationContainer extends Component {
AppState.removeEventListener('change', this._handleAppStateChange);
if (_isPinCodeOpen) {
clearTimeout(this._pinCodeTimer);
}
this.netListener();
}
@ -231,6 +249,7 @@ class ApplicationContainer extends Component {
_handleAppStateChange = nextAppState => {
const { appState } = this.state;
const { isPinCodeOpen: _isPinCodeOpen } = this.props;
getExistUser().then(isExistUser => {
if (isExistUser) {
@ -239,7 +258,9 @@ class ApplicationContainer extends Component {
}
if (appState.match(/inactive|background/) && nextAppState === 'active') {
clearTimeout(this._pinCodeTimer);
if (_isPinCodeOpen) {
clearTimeout(this._pinCodeTimer);
}
}
}
});
@ -248,11 +269,13 @@ class ApplicationContainer extends Component {
};
_startPinCodeTimer = () => {
const { dispatch } = this.props;
const { dispatch, isPinCodeOpen: _isPinCodeOpen } = this.props;
this._pinCodeTimer = setTimeout(() => {
dispatch(openPinCodeModal());
}, 1 * 60 * 1000);
if (_isPinCodeOpen) {
this._pinCodeTimer = setTimeout(() => {
dispatch(openPinCodeModal());
}, 1 * 60 * 1000);
}
};
_fetchApp = async () => {
@ -347,7 +370,7 @@ class ApplicationContainer extends Component {
};
_getUserDataFromRealm = async () => {
const { dispatch, pinCode } = this.props;
const { dispatch, pinCode, isPinCodeOpen: _isPinCodeOpen } = this.props;
let realmData = [];
let currentUsername;
@ -406,8 +429,11 @@ class ApplicationContainer extends Component {
}),
);
// If in dev mode pin code does not show
if (!isExistUser || !pinCode) {
if ((!isExistUser || !pinCode) && _isPinCodeOpen) {
dispatch(openPinCodeModal());
} else if (!_isPinCodeOpen) {
const encryptedPin = encryptKey(Config.DEFAULT_PIN, Config.PIN_KEY);
dispatch(savePinCode(encryptedPin));
}
dispatch(activeApplication());
@ -449,6 +475,7 @@ class ApplicationContainer extends Component {
if (settings) {
if (settings.isDarkTheme !== '') dispatch(isDarkTheme(settings.isDarkTheme));
if (settings.isPinCodeOpen !== '') dispatch(isPinCodeOpen(settings.isPinCodeOpen));
if (settings.language !== '') dispatch(setLanguage(settings.language));
if (settings.server !== '') dispatch(setApi(settings.server));
if (settings.upvotePercent !== '') {
@ -535,7 +562,9 @@ class ApplicationContainer extends Component {
};
_switchAccount = async targetAccountUsername => {
const { dispatch } = this.props;
const { dispatch, isConnected } = this.props;
if (!isConnected) return;
const accountData = await switchAccount(targetAccountUsername);
@ -580,6 +609,7 @@ export default connect(
isDarkTheme: state.application.isDarkTheme,
selectedLanguage: state.application.language,
notificationSettings: state.application.isNotificationOpen,
isPinCodeOpen: state.application.isPinCodeOpen,
isLogingOut: state.application.isLogingOut,
isLoggedIn: state.application.isLoggedIn,
isConnected: state.application.isConnected,

View File

@ -1,9 +1,11 @@
import React from 'react';
import React, { Fragment } from 'react';
import ApplicationScreen from './screen/applicationScreen';
import ApplicationContainer from './container/applicationContainer';
import Launch from '../launch';
import { Modal } from '../../components';
import { PinCode } from '../pinCode';
const Application = () => (
<ApplicationContainer>
@ -21,14 +23,23 @@ const Application = () => (
return <Launch />;
}
return (
<ApplicationScreen
isConnected={isConnected}
locale={locale}
toastNotification={toastNotification}
isReady={isReady}
isDarkTheme={isDarkTheme}
isPinCodeReqiure={isPinCodeReqiure}
/>
<Fragment>
<Modal
isOpen={isPinCodeReqiure}
isFullScreen
swipeToClose={false}
backButtonClose={false}
>
<PinCode />
</Modal>
<ApplicationScreen
isConnected={isConnected}
locale={locale}
toastNotification={toastNotification}
isReady={isReady}
isDarkTheme={isDarkTheme}
/>
</Fragment>
);
}}
</ApplicationContainer>

View File

@ -1,10 +1,9 @@
import React, { Component, Fragment } from 'react';
import { IntlProvider } from 'react-intl';
import { StatusBar, Platform, View } from 'react-native';
import EStyleSheet from 'react-native-extended-stylesheet';
import { connect } from 'react-redux';
import { ReduxNavigation } from '../../../navigation/reduxNavigation';
import { flattenMessages } from '../../../utils/flattenMessages';
import messages from '../../../config/locales';
// Services
import { toastNotification as toastNotificationAction } from '../../../redux/actions/uiAction';
@ -12,8 +11,6 @@ import { toastNotification as toastNotificationAction } from '../../../redux/act
// Components
import { NoInternetConnection } from '../../../components/basicUIElements';
import { ToastNotification } from '../../../components/toastNotification';
import { Modal } from '../../../components';
import { PinCode } from '../../pinCode';
import PostButtonForAndroid from '../../../components/postButton/view/postButtonsForAndroid';
// Themes (Styles)
@ -47,14 +44,7 @@ class ApplicationScreen extends Component {
};
render() {
const {
isConnected,
isDarkTheme,
locale,
toastNotification,
isReady,
isPinCodeReqiure,
} = this.props;
const { isConnected, isDarkTheme, toastNotification, isReady } = this.props;
const { isShowToastNotification } = this.state;
const barStyle = isDarkTheme ? 'light-content' : 'dark-content';
const barColor = isDarkTheme ? '#1e2835' : '#fff';
@ -66,21 +56,10 @@ class ApplicationScreen extends Component {
) : (
<StatusBar barStyle={barStyle} backgroundColor={barColor} />
)}
<IntlProvider locale={locale} messages={flattenMessages(messages[locale])}>
<Fragment>
{!isConnected && <NoInternetConnection />}
<ReduxNavigation />
<Modal
isOpen={isPinCodeReqiure}
isFullScreen
swipeToClose={false}
backButtonClose={false}
>
<PinCode setWrappedComponentState={this._setWrappedComponentState} />
</Modal>
</Fragment>
</IntlProvider>
<Fragment>
{!isConnected && <NoInternetConnection />}
<ReduxNavigation />
</Fragment>
{Platform.OS === 'android' && <PostButtonForAndroid />}
{isShowToastNotification && (
@ -95,4 +74,4 @@ class ApplicationScreen extends Component {
}
}
export default ApplicationScreen;
export default connect()(ApplicationScreen);

View File

@ -47,7 +47,7 @@ class LoginContainer extends PureComponent {
// Component Functions
_handleOnPressLogin = (username, password) => {
const { dispatch, intl } = this.props;
const { dispatch, intl, isPinCodeOpen, navigation } = this.props;
this.setState({ isLoading: true });
@ -56,10 +56,16 @@ class LoginContainer extends PureComponent {
if (result) {
dispatch(updateCurrentAccount({ ...result }));
dispatch(addOtherAccount({ username: result.name }));
dispatch(openPinCodeModal({ navigateTo: ROUTES.DRAWER.MAIN }));
dispatch(loginAction(true));
userActivity(result.name, 20);
this._setPushToken(result.name);
if (isPinCodeOpen) {
dispatch(openPinCodeModal({ navigateTo: ROUTES.DRAWER.MAIN }));
} else {
navigation.navigate({
routeName: ROUTES.DRAWER.MAIN,
});
}
}
})
.catch(err => {
@ -110,7 +116,7 @@ class LoginContainer extends PureComponent {
_getAccountsWithUsername = async username => {
const { intl, isConnected } = this.props;
if (isConnected) return null;
if (!isConnected) return null;
try {
const validUsers = await lookupAccounts(username);
@ -152,6 +158,7 @@ const mapStateToProps = state => ({
notificationDetails: state.application.notificationDetails,
notificationSettings: state.application.isNotificationOpen,
isConnected: state.application.isConnected,
isPinCodeOpen: state.application.isPinCodeOpen,
});
export default injectIntl(connect(mapStateToProps)(LoginContainer));

View File

@ -4,6 +4,7 @@ import { connect } from 'react-redux';
import { injectIntl } from 'react-intl';
import Config from 'react-native-config';
import { NavigationActions } from 'react-navigation';
import get from 'lodash/get';
// Actions & Services
import {
@ -41,8 +42,8 @@ class PinCodeContainer extends Component {
isExistUser: null,
informationText: '',
pinCode: null,
isOldPinVerified: false,
oldPinCode: null,
isOldPinVerified: get(props.pinCodeParams, 'isOldPinVerified', false),
oldPinCode: get(props.pinCodeParams, 'oldPinCode', null),
};
}
@ -86,7 +87,7 @@ class PinCodeContainer extends Component {
const {
currentAccount,
dispatch,
pinCodeParams: { navigateTo, navigateParams, accessToken },
pinCodeParams: { navigateTo, navigateParams, accessToken, callback },
intl,
} = this.props;
const { isOldPinVerified, oldPinCode } = this.state;
@ -107,6 +108,7 @@ class PinCodeContainer extends Component {
dispatch(updateCurrentAccount({ ..._currentAccount }));
this._savePinCode(pin);
if (callback) callback(pin, oldPinCode);
dispatch(closePinCodeModal());
if (navigateTo) {
const navigateAction = NavigationActions.navigate({
@ -150,8 +152,9 @@ class PinCodeContainer extends Component {
const {
currentAccount,
dispatch,
pinCodeParams: { navigateTo, navigateParams, accessToken },
pinCodeParams: { navigateTo, navigateParams, accessToken, callback },
} = this.props;
const { oldPinCode } = this.state;
const pinData = {
pinCode: pin,
@ -168,6 +171,7 @@ class PinCodeContainer extends Component {
setExistUser(true).then(() => {
this._savePinCode(pin);
if (callback) callback(pin, oldPinCode);
dispatch(closePinCodeModal());
if (navigateTo) {
const navigateAction = NavigationActions.navigate({
@ -188,9 +192,10 @@ class PinCodeContainer extends Component {
const {
currentAccount,
dispatch,
pinCodeParams: { navigateTo, navigateParams, accessToken },
pinCodeParams: { navigateTo, navigateParams, accessToken, callback },
intl,
} = this.props;
const { oldPinCode } = this.state;
// If the user is exist, we are just checking to pin and navigating to home screen
const pinData = {
@ -208,6 +213,7 @@ class PinCodeContainer extends Component {
[_currentAccount.local] = realmData;
dispatch(updateCurrentAccount({ ..._currentAccount }));
dispatch(closePinCodeModal());
if (callback) callback(pin, oldPinCode);
if (navigateTo) {
const navigateAction = NavigationActions.navigate({
routeName: navigateTo,

View File

@ -5,6 +5,7 @@ import AppCenter from 'appcenter';
import Push from 'appcenter-push';
import { Client } from 'dsteem';
import VersionNumber from 'react-native-version-number';
import Config from 'react-native-config';
// Realm
import {
@ -15,6 +16,7 @@ import {
setLanguage as setLanguage2DB,
setNsfw as setNsfw2DB,
setTheme,
setPinCodeOpen,
} from '../../../realm/realm';
// Services and Actions
@ -27,10 +29,14 @@ import {
isDefaultFooter,
openPinCodeModal,
setNsfw,
isPinCodeOpen,
setPinCode as savePinCode,
} from '../../../redux/actions/applicationActions';
import { toastNotification } from '../../../redux/actions/uiAction';
import { setPushToken, getNodes } from '../../../providers/esteem/esteem';
import { checkClient } from '../../../providers/steem/dsteem';
import { updatePinCode } from '../../../providers/steem/auth';
import { updateCurrentAccount } from '../../../redux/actions/accountAction';
// Middleware
// Constants
@ -39,6 +45,7 @@ import { VALUE as LANGUAGE_VALUE } from '../../../constants/options/language';
// Utilities
import { sendEmail } from '../../../utils/sendEmail';
import { encryptKey, decryptKey } from '../../../utils/crypto';
// Component
import SettingsScreen from '../screen/settingsScreen';
@ -165,6 +172,25 @@ class SettingsContainer extends Component {
dispatch(isDefaultFooter(action));
// setDefaultFooter(action);
break;
case 'pincode':
if (action) {
dispatch(
openPinCodeModal({
callback: () => this._setDefaultPinCode(action),
isReset: true,
isOldPinVerified: true,
oldPinCode: Config.DEFAULT_PIN,
}),
);
} else {
dispatch(
openPinCodeModal({
callback: () => this._setDefaultPinCode(action),
}),
);
}
break;
default:
break;
}
@ -207,7 +233,7 @@ class SettingsContainer extends Component {
_handleButtonPress = actionType => {
const { dispatch } = this.props;
switch (actionType) {
case 'pincode':
case 'reset_pin':
dispatch(openPinCodeModal({ isReset: true }));
break;
@ -285,6 +311,34 @@ class SettingsContainer extends Component {
}
};
_setDefaultPinCode = action => {
const { dispatch, username, currentAccount, pinCode } = this.props;
if (!action) {
const oldPinCode = decryptKey(pinCode, Config.PIN_KEY);
const pinData = {
pinCode: Config.DEFAULT_PIN,
username,
oldPinCode,
};
updatePinCode(pinData).then(response => {
const _currentAccount = currentAccount;
_currentAccount.local = response;
dispatch(updateCurrentAccount({ ..._currentAccount }));
const encryptedPin = encryptKey(Config.DEFAULT_PIN, Config.PIN_KEY);
dispatch(savePinCode(encryptedPin));
setPinCodeOpen(action);
dispatch(isPinCodeOpen(action));
});
} else {
setPinCodeOpen(action);
dispatch(isPinCodeOpen(action));
}
};
render() {
const { serverList, isNotificationMenuOpen } = this.state;
@ -302,6 +356,8 @@ class SettingsContainer extends Component {
const mapStateToProps = state => ({
isDarkTheme: state.application.isDarkTheme,
isPinCodeOpen: state.application.isPinCodeOpen,
pinCode: state.application.pin,
isDefaultFooter: state.application.isDefaultFooter,
isLoggedIn: state.application.isLoggedIn,
isNotificationSettingsOpen: state.application.isNotificationOpen,
@ -316,7 +372,9 @@ const mapStateToProps = state => ({
selectedApi: state.application.api,
selectedCurrency: state.application.currency,
selectedLanguage: state.application.language,
username: state.account.currentAccount && state.account.currentAccount.name,
currentAccount: state.account.currentAccount,
});
export default connect(mapStateToProps)(SettingsContainer);

View File

@ -37,6 +37,7 @@ class SettingsScreen extends PureComponent {
handleOnChange,
intl,
isDarkTheme,
isPinCodeOpen,
isLoggedIn,
isNotificationSettingsOpen,
nsfw,
@ -125,16 +126,28 @@ class SettingsScreen extends PureComponent {
handleOnChange={handleOnChange}
/>
{!!isLoggedIn && (
<SettingsItem
title={intl.formatMessage({
id: 'settings.pincode',
})}
type="toggle"
actionType="pincode"
isOn={isPinCodeOpen}
handleOnChange={handleOnChange}
/>
)}
{!!isLoggedIn && !!isPinCodeOpen && (
<Fragment>
<SettingsItem
title={intl.formatMessage({
id: 'settings.pincode',
id: 'settings.reset_pin',
})}
text={intl.formatMessage({
id: 'settings.reset',
})}
type="button"
actionType="pincode"
actionType="reset_pin"
handleOnButtonPress={handleOnButtonPress}
/>
</Fragment>

View File

@ -2,6 +2,7 @@ import React, { PureComponent } from 'react';
import { View, WebView, Alert } from 'react-native';
import { connect } from 'react-redux';
import { injectIntl } from 'react-intl';
import { withNavigation } from 'react-navigation';
import { loginWithSC2 } from '../../providers/steem/auth';
import { steemConnectOptions } from './config';
@ -23,7 +24,7 @@ class SteemConnect extends PureComponent {
_onNavigationStateChange = event => {
let code;
const { dispatch, handleOnModalClose, intl } = this.props;
const { dispatch, handleOnModalClose, intl, isPinCodeOpen, navigation } = this.props;
const { isLoading } = this.state;
if (event.url.indexOf('?code=') > -1) {
this.webview.stopLoading();
@ -42,12 +43,20 @@ class SteemConnect extends PureComponent {
dispatch(updateCurrentAccount({ ...result }));
dispatch(addOtherAccount({ username: result.name }));
dispatch(loginAction(true));
dispatch(
openPinCodeModal({
accessToken: result.accessToken,
navigateTo: ROUTES.DRAWER.MAIN,
}),
);
if (isPinCodeOpen) {
dispatch(
openPinCodeModal({
accessToken: result.accessToken,
navigateTo: ROUTES.DRAWER.MAIN,
}),
);
} else {
navigation.navigate({
routeName: ROUTES.DRAWER.MAIN,
params: { accessToken: result.accessToken },
});
}
} else {
// TODO: Error alert (Toast Message)
}
@ -86,4 +95,8 @@ class SteemConnect extends PureComponent {
}
}
export default injectIntl(connect()(SteemConnect));
const mapStateToProps = state => ({
isPinCodeOpen: state.application.isPinCodeOpen,
});
export default injectIntl(connect(mapStateToProps)(withNavigation(SteemConnect)));