mirror of
https://github.com/ecency/ecency-mobile.git
synced 2024-11-24 00:46:27 +03:00
commit
c273a22195
1
.gitignore
vendored
1
.gitignore
vendored
@ -35,6 +35,7 @@ local.properties
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
config.js
|
||||
|
||||
# BUCK
|
||||
buck-out/
|
||||
|
@ -19,6 +19,12 @@
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
<data android:scheme="esteem"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
|
||||
</application>
|
||||
|
@ -8,7 +8,7 @@ buildscript {
|
||||
jcenter()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.0.1'
|
||||
classpath 'com.android.tools.build:gradle:3.1.4'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
@ -17,5 +17,4 @@
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
|
||||
android.useDeprecatedNdk=true
|
||||
android.enableAapt2=false
|
||||
android.useDeprecatedNdk=true
|
@ -22,6 +22,17 @@
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>app.esteem.mobile</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>esteem</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
|
29
package-lock.json
generated
29
package-lock.json
generated
@ -2455,7 +2455,7 @@
|
||||
},
|
||||
"buffer": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/buffer/-/buffer-3.6.0.tgz",
|
||||
"resolved": "http://registry.npmjs.org/buffer/-/buffer-3.6.0.tgz",
|
||||
"integrity": "sha1-pyyTb3e5a/UvX357RnGAYoVR3vs=",
|
||||
"requires": {
|
||||
"base64-js": "0.0.8",
|
||||
@ -3021,6 +3021,22 @@
|
||||
"gud": "1.0.0"
|
||||
}
|
||||
},
|
||||
"cross-fetch": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-1.1.1.tgz",
|
||||
"integrity": "sha512-+VJE04+UfxxmBfcnmAu/lKor53RUCx/1ilOti4p+JgrnLQ4AZZIRoe2OEd76VaHyWQmQxqKnV+TaqjHC4r0HWw==",
|
||||
"requires": {
|
||||
"node-fetch": "1.7.3",
|
||||
"whatwg-fetch": "2.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"whatwg-fetch": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz",
|
||||
"integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ="
|
||||
}
|
||||
}
|
||||
},
|
||||
"cross-spawn": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
|
||||
@ -9914,6 +9930,15 @@
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
|
||||
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
|
||||
},
|
||||
"sc2-sdk": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/sc2-sdk/-/sc2-sdk-1.0.2.tgz",
|
||||
"integrity": "sha512-QADFzQYCsm6OOQE3cxd/NEhSTEtcohzJ6KQN4E5YaEO/bl2WgWy1Dgz4SFRhjIwTh5luzad2TqfUN7uF4IL8xg==",
|
||||
"requires": {
|
||||
"cross-fetch": "^1.1.1",
|
||||
"debug": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"secp256k1": {
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.5.0.tgz",
|
||||
@ -9939,7 +9964,7 @@
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
|
||||
"resolved": "http://registry.npmjs.org/commander/-/commander-2.8.1.tgz",
|
||||
"integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=",
|
||||
"requires": {
|
||||
"graceful-readlink": "1.0.1"
|
||||
|
@ -42,7 +42,8 @@
|
||||
"redux-promise": "^0.6.0",
|
||||
"redux-thunk": "^2.3.0",
|
||||
"remarkable": "^1.7.1",
|
||||
"rn-placeholder": "^1.2.0"
|
||||
"rn-placeholder": "^1.2.0",
|
||||
"sc2-sdk": "^1.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-eslint": "^8.2.6",
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 57 KiB |
BIN
src/assets/esteem@2x.png
Normal file
BIN
src/assets/esteem@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
BIN
src/assets/esteem_selected@2x.png
Normal file
BIN
src/assets/esteem_selected@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
@ -11,6 +11,7 @@ import {
|
||||
import Ionicons from "react-native-vector-icons/Ionicons";
|
||||
import { Navigation } from "react-native-navigation";
|
||||
import { lookupAccounts } from "../../providers/steem/dsteem";
|
||||
import { SEARCH_API_TOKEN } from "../../../config";
|
||||
|
||||
export default class Search extends Component {
|
||||
constructor() {
|
||||
@ -30,12 +31,15 @@ export default class Search extends Component {
|
||||
};
|
||||
|
||||
handleSearch = async text => {
|
||||
if (text.length < 3) return null;
|
||||
if (text.length < 3) return;
|
||||
let users;
|
||||
let posts;
|
||||
let scroll_id;
|
||||
|
||||
await this.setState({ loading: true });
|
||||
await this.setState({
|
||||
loading: true,
|
||||
text: text
|
||||
});
|
||||
|
||||
users = await lookupAccounts(text);
|
||||
|
||||
@ -47,7 +51,7 @@ export default class Search extends Component {
|
||||
headers: {
|
||||
// TODO: Create a config file for authorization
|
||||
|
||||
Authorization: "KEY",
|
||||
Authorization: SEARCH_API_TOKEN,
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
@ -73,9 +77,10 @@ export default class Search extends Component {
|
||||
return (
|
||||
<View
|
||||
style={{
|
||||
backgroundColor: "rgba(0, 0, 0, 0.7)",
|
||||
backgroundColor: "rgba(0, 0, 0, 0.8)",
|
||||
height: Dimensions.get("window").height,
|
||||
paddingTop: 25,
|
||||
flex: 1
|
||||
}}
|
||||
>
|
||||
<View
|
||||
|
@ -323,7 +323,9 @@ export const goToNoAuthScreens = () =>
|
||||
],
|
||||
options: {
|
||||
topBar: {
|
||||
visible: false,
|
||||
visible: true,
|
||||
noBorder: true,
|
||||
elevation: 0
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -1,170 +1,212 @@
|
||||
/*eslint-disable no-unused-vars*/
|
||||
/*eslint-disable no-console*/
|
||||
import * as dsteem from "dsteem";
|
||||
import { getAccount } from "./dsteem";
|
||||
import { setUserData, setAuthStatus } from "../../realm/realm";
|
||||
/*eslint-disable-next-line no-unused-vars*/
|
||||
import { encryptKey, decryptKey } from "../../utils/crypto";
|
||||
import { encryptKey } from "../../utils/crypto";
|
||||
import steemConnect from "./steemConnectAPI";
|
||||
/*eslint-enable no-unused-vars*/
|
||||
|
||||
export const Login = (username, password) => {
|
||||
let account;
|
||||
let publicKeys;
|
||||
let privateKeys;
|
||||
let isPassword;
|
||||
let isPostingKey;
|
||||
let pinCode = "pinCode";
|
||||
let account;
|
||||
let publicKeys;
|
||||
let privateKeys;
|
||||
let isPassword;
|
||||
let isPostingKey;
|
||||
let pinCode = "pinCode";
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
// Get user account data from STEEM Blockchain
|
||||
getAccount(username)
|
||||
.then(result => {
|
||||
if (result.length < 1) {
|
||||
reject(new Error("Wrong @username"));
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
// Get user account data from STEEM Blockchain
|
||||
getAccount(username)
|
||||
.then(result => {
|
||||
if (result.length < 1) {
|
||||
reject(new Error("Wrong @username"));
|
||||
}
|
||||
|
||||
account = result[0];
|
||||
account = result[0];
|
||||
|
||||
// Public keys of user
|
||||
publicKeys = {
|
||||
active: account["active"].key_auths.map(x => x[0]),
|
||||
memo: account["memo_key"],
|
||||
owner: account["owner"].key_auths.map(x => x[0]),
|
||||
posting: account["posting"].key_auths.map(x => x[0]),
|
||||
};
|
||||
})
|
||||
.then(() => {
|
||||
try {
|
||||
// Set private keys of user
|
||||
privateKeys = {
|
||||
active: dsteem.PrivateKey.fromLogin(
|
||||
username,
|
||||
password,
|
||||
"active"
|
||||
).toString(),
|
||||
memo: dsteem.PrivateKey.fromLogin(
|
||||
username,
|
||||
password,
|
||||
"memo"
|
||||
).toString(),
|
||||
owner: dsteem.PrivateKey.fromLogin(
|
||||
username,
|
||||
password,
|
||||
"owner"
|
||||
).toString(),
|
||||
posting: dsteem.PrivateKey.fromLogin(
|
||||
username,
|
||||
password,
|
||||
"posting"
|
||||
).toString(),
|
||||
};
|
||||
} catch (error) {
|
||||
reject(new Error("Wrong Key/Password"));
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
// Validate Pasword/Key
|
||||
try {
|
||||
// Validate Master Key
|
||||
/*eslint-disable no-mixed-spaces-and-tabs*/
|
||||
isPassword =
|
||||
// Public keys of user
|
||||
publicKeys = {
|
||||
active: account["active"].key_auths.map(x => x[0]),
|
||||
memo: account["memo_key"],
|
||||
owner: account["owner"].key_auths.map(x => x[0]),
|
||||
posting: account["posting"].key_auths.map(x => x[0]),
|
||||
};
|
||||
})
|
||||
.then(() => {
|
||||
try {
|
||||
// Set private keys of user
|
||||
privateKeys = {
|
||||
active: dsteem.PrivateKey.fromLogin(
|
||||
username,
|
||||
password,
|
||||
"active"
|
||||
).toString(),
|
||||
memo: dsteem.PrivateKey.fromLogin(
|
||||
username,
|
||||
password,
|
||||
"memo"
|
||||
).toString(),
|
||||
owner: dsteem.PrivateKey.fromLogin(
|
||||
username,
|
||||
password,
|
||||
"owner"
|
||||
).toString(),
|
||||
posting: dsteem.PrivateKey.fromLogin(
|
||||
username,
|
||||
password,
|
||||
"posting"
|
||||
).toString(),
|
||||
};
|
||||
} catch (error) {
|
||||
reject(new Error("Wrong Key/Password"));
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
// Validate Pasword/Key
|
||||
try {
|
||||
// Validate Master Key
|
||||
/*eslint-disable no-mixed-spaces-and-tabs*/
|
||||
isPassword =
|
||||
dsteem.PrivateKey.fromLogin(
|
||||
username,
|
||||
password,
|
||||
"posting"
|
||||
username,
|
||||
password,
|
||||
"posting"
|
||||
)
|
||||
.createPublic()
|
||||
.toString() === publicKeys.posting.toString();
|
||||
.createPublic()
|
||||
.toString() === publicKeys.posting.toString();
|
||||
|
||||
if (isPassword) {
|
||||
/**
|
||||
if (isPassword) {
|
||||
/**
|
||||
* User data
|
||||
* TODO: Encryption
|
||||
*/
|
||||
let userData = {
|
||||
username: username,
|
||||
authType: "masterKey",
|
||||
masterKey: encryptKey(password, pinCode),
|
||||
postingKey: encryptKey(
|
||||
privateKeys.posting,
|
||||
pinCode
|
||||
),
|
||||
activeKey: encryptKey(privateKeys.active, pinCode),
|
||||
memoKey: encryptKey(privateKeys.memo, pinCode),
|
||||
};
|
||||
let authData = {
|
||||
isLoggedIn: true,
|
||||
};
|
||||
let userData = {
|
||||
username: username,
|
||||
authType: "masterKey",
|
||||
masterKey: encryptKey(password, pinCode),
|
||||
postingKey: encryptKey(
|
||||
privateKeys.posting,
|
||||
pinCode
|
||||
),
|
||||
activeKey: encryptKey(privateKeys.active, pinCode),
|
||||
memoKey: encryptKey(privateKeys.memo, pinCode),
|
||||
accessToken: ""
|
||||
};
|
||||
let authData = {
|
||||
isLoggedIn: true,
|
||||
};
|
||||
|
||||
// Set auth state to true
|
||||
setAuthStatus(authData)
|
||||
.then(() => {
|
||||
// Save user data to Realm DB
|
||||
setUserData(userData)
|
||||
.then(() => {
|
||||
resolve(isPassword);
|
||||
})
|
||||
.catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
} else {
|
||||
// Validate Posting Key
|
||||
isPostingKey =
|
||||
// Set auth state to true
|
||||
setAuthStatus(authData)
|
||||
.then(() => {
|
||||
// Save user data to Realm DB
|
||||
setUserData(userData)
|
||||
.then(() => {
|
||||
resolve(isPassword);
|
||||
})
|
||||
.catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
} else {
|
||||
// Validate Posting Key
|
||||
isPostingKey =
|
||||
publicKeys.posting.toString() ===
|
||||
dsteem.PrivateKey.fromString(password)
|
||||
.createPublic()
|
||||
.toString();
|
||||
.createPublic()
|
||||
.toString();
|
||||
|
||||
/**
|
||||
/**
|
||||
* User data
|
||||
* TODO: Encryption
|
||||
*/
|
||||
let userData = {
|
||||
username: username,
|
||||
authType: "postingKey",
|
||||
postingKey: privateKeys.posting,
|
||||
masterKey: "",
|
||||
activeKey: "",
|
||||
memoKey: "",
|
||||
};
|
||||
let userData = {
|
||||
username: username,
|
||||
authType: "postingKey",
|
||||
postingKey: privateKeys.posting,
|
||||
masterKey: "",
|
||||
activeKey: "",
|
||||
memoKey: "",
|
||||
accessToken: ""
|
||||
};
|
||||
|
||||
let authData = {
|
||||
isLoggedIn: true,
|
||||
};
|
||||
let authData = {
|
||||
isLoggedIn: true,
|
||||
};
|
||||
|
||||
try {
|
||||
if (isPostingKey) {
|
||||
// Set auth state to true
|
||||
setAuthStatus(authData)
|
||||
.then(() => {
|
||||
// Save user data to Realm DB
|
||||
setUserData(userData)
|
||||
.then(() => {
|
||||
resolve(isPostingKey);
|
||||
})
|
||||
.catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
} else {
|
||||
reject(new Error("Wrong Key/Password"));
|
||||
}
|
||||
} catch (error) {
|
||||
reject(new Error("Wrong Key/Password"));
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
reject(new Error("Wrong Key/Password"));
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
// eslint-disable-next-line
|
||||
try {
|
||||
if (isPostingKey) {
|
||||
// Set auth state to true
|
||||
setAuthStatus(authData)
|
||||
.then(() => {
|
||||
// Save user data to Realm DB
|
||||
setUserData(userData)
|
||||
.then(() => {
|
||||
resolve(isPostingKey);
|
||||
})
|
||||
.catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
reject(err);
|
||||
});
|
||||
} else {
|
||||
reject(new Error("Wrong Key/Password"));
|
||||
}
|
||||
} catch (error) {
|
||||
reject(new Error("Wrong Key/Password"));
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
reject(new Error("Wrong Key/Password"));
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
// eslint-disable-next-line
|
||||
console.log(err);
|
||||
reject(new Error("Check your username"));
|
||||
});
|
||||
});
|
||||
reject(new Error("Check your username"));
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const loginWithSC2 = async (access_token, pinCode) => {
|
||||
let account;
|
||||
|
||||
await steemConnect.setAccessToken(access_token);
|
||||
account = await steemConnect.me();
|
||||
|
||||
console.log(account._id);
|
||||
console.log(account.name);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
let userData = {
|
||||
username: account.name,
|
||||
authType: "steemConnect",
|
||||
accessToken: encryptKey(access_token, pinCode),
|
||||
postingKey: "",
|
||||
masterKey: "",
|
||||
activeKey: "",
|
||||
memoKey: ""
|
||||
};
|
||||
|
||||
let authData = {
|
||||
isLoggedIn: true
|
||||
};
|
||||
|
||||
setAuthStatus(authData).then(() => {
|
||||
setUserData(userData).then(() => {
|
||||
resolve(true);
|
||||
}).catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
}).catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
|
||||
});
|
||||
};
|
@ -9,7 +9,7 @@ import { parsePosts, parseComments } from "../../utils/postParser";
|
||||
|
||||
let rewardFund = null;
|
||||
let medianPrice = null;
|
||||
let client;
|
||||
let client = new Client("https://api.steemit.com");
|
||||
|
||||
getClient = async () => {
|
||||
let server = await AsyncStorage.getItem("server");
|
||||
|
188
src/providers/steem/steemConnect.js
Normal file
188
src/providers/steem/steemConnect.js
Normal file
@ -0,0 +1,188 @@
|
||||
import steemConnect from "./steemConnectAPI";
|
||||
|
||||
/**
|
||||
* @method to upvote/unvote a content
|
||||
* @param {*} vote
|
||||
*/
|
||||
export const vote = (vote) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
steemConnect.vote(vote.voter, vote.author, vote.permlink, vote.weight).then(result => {
|
||||
console.log(result);
|
||||
resolve(result);
|
||||
}).catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @method to submit a comment/reply
|
||||
* @param {*} comment
|
||||
*/
|
||||
export const comment = (comment) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
steemConnect.comment(comment.parentAuthor, comment.parentPermlink, comment.author, comment.permlink, comment.title, comment.body, comment.jsonMetadata).then(result => {
|
||||
console.log(result);
|
||||
resolve(result);
|
||||
}).catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const post = (post) => {
|
||||
|
||||
// Create empty array for the operations
|
||||
const operations = [];
|
||||
|
||||
// Create the object for the post
|
||||
const commentOp = [
|
||||
"comment",
|
||||
{
|
||||
parent_author: "", // Since it is a post, parent author is empty
|
||||
parent_permlink: post.tags[0], // Parent permlink will be the 0th index in the tags array
|
||||
author: post.author, // Author is the current logged in username
|
||||
permlink: post.permlink, // Permlink of the post
|
||||
title: post.title, // Title of the post
|
||||
body: post.description, // Description of the post
|
||||
json_metadata: post.json_metadata, // JSON string with the tags, app, and format
|
||||
},
|
||||
];
|
||||
operations.push(commentOp);
|
||||
|
||||
const commentOptionsConfig = prepareBeneficiaries(post);
|
||||
|
||||
operations.push(commentOptionsConfig);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
steemConnect.broadcast(operations).then(result => {
|
||||
console.log(result);
|
||||
resolve(result);
|
||||
}).catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const prepareBeneficiaries = (post) => {
|
||||
|
||||
let beneficiariesObject = {
|
||||
author: post.author,
|
||||
permlink: post.permlink,
|
||||
allow_votes: true,
|
||||
allow_curation_rewards: true,
|
||||
max_accepted_payout: "1000000.000 SBD",
|
||||
percent_steem_dollars: "10000",
|
||||
extensions: [
|
||||
[
|
||||
0, {
|
||||
beneficiaries: [
|
||||
{
|
||||
account: "esteemapp",
|
||||
weight: 1000 // 10%
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
};
|
||||
|
||||
return ["comment_options", beneficiariesObject];
|
||||
};
|
||||
|
||||
export const follow = (data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
steemConnect.follow(data.follower, data.following).then(result => {
|
||||
resolve(result);
|
||||
}).catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const unFollow = (data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
steemConnect.unfollow(data.unfollower, data.unfollowing).then(result => {
|
||||
resolve(result);
|
||||
}).catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @method to claim rewards
|
||||
* @param {*} data
|
||||
*/
|
||||
export const claimRewards = (data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
steemConnect.claimRewardBalance(data.account, data.rewardSteem, data.rewardSBD, data.VESTS).then(result => {
|
||||
resolve(result);
|
||||
}).catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @method to mute/block an user
|
||||
* @param {*} data
|
||||
*/
|
||||
export const muteUser = (data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
steemConnect.ignore(data.follower, data.following).then(result => {
|
||||
resolve(result);
|
||||
}).catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const reblogPost = (data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
steemConnect.reblog(data.account, data.author, data.permlink).then(result => {
|
||||
resolve(result);
|
||||
}).catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const removeAccessToken = (data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
steemConnect.removeAccessToken();
|
||||
resolve();
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @method to revoke access token (SteemConnect logout function)
|
||||
*/
|
||||
export const revokeToken = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
steemConnect.revokeToken();
|
||||
resolve();
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @method to update user profile data
|
||||
* @param {*} data
|
||||
*/
|
||||
export const updateUserMetadata = (data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
steemConnect.updateUserMetadata(data).then(result => {
|
||||
resolve(result);
|
||||
}).catch(error => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
};
|
8
src/providers/steem/steemConnectAPI.js
Normal file
8
src/providers/steem/steemConnectAPI.js
Normal file
@ -0,0 +1,8 @@
|
||||
import sc2 from "sc2-sdk";
|
||||
|
||||
const api = sc2.Initialize({
|
||||
app: "esteem-app",
|
||||
callbackURL: "http://localhost:3415",
|
||||
});
|
||||
|
||||
export default api;
|
@ -5,91 +5,92 @@ const USER_SCHEMA = "user";
|
||||
const AUTH_SCHEMA = "auth";
|
||||
|
||||
const userSchema = {
|
||||
name: USER_SCHEMA,
|
||||
properties: {
|
||||
username: { type: "string" },
|
||||
authType: { type: "string" },
|
||||
postingKey: { type: "string" },
|
||||
activeKey: { type: "string" },
|
||||
memoKey: { type: "string" },
|
||||
masterKey: { type: "string" },
|
||||
},
|
||||
name: USER_SCHEMA,
|
||||
properties: {
|
||||
username: { type: "string" },
|
||||
authType: { type: "string" },
|
||||
postingKey: { type: "string" },
|
||||
activeKey: { type: "string" },
|
||||
memoKey: { type: "string" },
|
||||
masterKey: { type: "string" },
|
||||
accessToken: { type: "string" },
|
||||
},
|
||||
};
|
||||
|
||||
const authSchema = {
|
||||
name: AUTH_SCHEMA,
|
||||
properties: {
|
||||
isLoggedIn: { type: "bool", default: false },
|
||||
},
|
||||
name: AUTH_SCHEMA,
|
||||
properties: {
|
||||
isLoggedIn: { type: "bool", default: false },
|
||||
},
|
||||
};
|
||||
|
||||
let realm = new Realm({ schema: [userSchema, authSchema] });
|
||||
|
||||
export const getUserData = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
let user = realm.objects(USER_SCHEMA);
|
||||
resolve(user);
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
let user = realm.objects(USER_SCHEMA);
|
||||
resolve(user);
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const setUserData = userData => {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
realm.write(() => {
|
||||
realm.create(userSchema.name, userData);
|
||||
resolve(userData);
|
||||
});
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
realm.write(() => {
|
||||
realm.create(userSchema.name, userData);
|
||||
resolve(userData);
|
||||
});
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const removeUserData = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
setAuthStatus({ isLoggedIn: true }).then(() => {
|
||||
try {
|
||||
realm.write(() => {
|
||||
realm.deleteAll();
|
||||
});
|
||||
resolve();
|
||||
} catch (error) {
|
||||
alert(error);
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
return new Promise((resolve, reject) => {
|
||||
setAuthStatus({ isLoggedIn: true }).then(() => {
|
||||
try {
|
||||
realm.write(() => {
|
||||
realm.deleteAll();
|
||||
});
|
||||
resolve();
|
||||
} catch (error) {
|
||||
alert(error);
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const getAuthStatus = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
let auth = realm.objects(AUTH_SCHEMA);
|
||||
if (auth["0"]) {
|
||||
resolve(auth["0"].isLoggedIn);
|
||||
} else {
|
||||
resolve(false);
|
||||
}
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
let auth = realm.objects(AUTH_SCHEMA);
|
||||
if (auth["0"]) {
|
||||
resolve(auth["0"].isLoggedIn);
|
||||
} else {
|
||||
resolve(false);
|
||||
}
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const setAuthStatus = authStatus => {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
realm.write(() => {
|
||||
realm.create(authSchema.name, authStatus);
|
||||
resolve(authStatus);
|
||||
});
|
||||
} catch (error) {
|
||||
alert(error);
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
realm.write(() => {
|
||||
realm.create(authSchema.name, authStatus);
|
||||
resolve(authStatus);
|
||||
});
|
||||
} catch (error) {
|
||||
alert(error);
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -36,6 +36,8 @@ export default class Home extends React.PureComponent {
|
||||
animate: true,
|
||||
hideOnScroll: true,
|
||||
drawBehind: false,
|
||||
noBorder: true,
|
||||
elevation: 0,
|
||||
},
|
||||
layout: {
|
||||
backgroundColor: "#f5fcff",
|
||||
|
@ -14,6 +14,7 @@ import Editor from "./editor/editor";
|
||||
import Discover from "./discover/discover";
|
||||
import Settings from "./settings/settings";
|
||||
import Notifications from "./notifications/notification";
|
||||
import SteemConnect from "./steem-connect/steemConnect";
|
||||
import PostCard from "../components/post-card/postCard";
|
||||
import Search from "../components/search/search";
|
||||
|
||||
@ -40,6 +41,7 @@ function registerScreens() {
|
||||
Navigation.registerComponent("navigation.eSteem.Author", () => Author);
|
||||
Navigation.registerComponent("navigation.eSteem.PostCard", () => PostCard);
|
||||
Navigation.registerComponent("navigation.eSteem.Search", () => Search);
|
||||
Navigation.registerComponent("navigation.eSteem.SteemConnect", () => SteemConnect);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
@ -5,36 +5,86 @@ import {
|
||||
Text,
|
||||
StyleSheet,
|
||||
Image,
|
||||
StatusBar,
|
||||
TouchableOpacity,
|
||||
Linking,
|
||||
BackHandler,
|
||||
Dimensions,
|
||||
TextInput,
|
||||
WebView
|
||||
} from "react-native";
|
||||
import {
|
||||
Item,
|
||||
Header,
|
||||
Input,
|
||||
Card,
|
||||
Button,
|
||||
Container,
|
||||
Icon,
|
||||
Left,
|
||||
Right,
|
||||
Body,
|
||||
Label,
|
||||
Thumbnail,
|
||||
} from "native-base";
|
||||
import Ionicons from "react-native-vector-icons/Ionicons";
|
||||
|
||||
import Tabs from "../home/customTab";
|
||||
import ScrollableTabView from "@esteemapp/react-native-scrollable-tab-view";
|
||||
import { Login } from "../../providers/steem/auth";
|
||||
import { lookupAccounts } from "../../providers/steem/dsteem";
|
||||
import { goToAuthScreens } from "../../navigation";
|
||||
|
||||
import RNRestart from "react-native-restart";
|
||||
import { Navigation } from "react-native-navigation";
|
||||
import FastImage from "react-native-fast-image";
|
||||
|
||||
class LoginPage extends Component {
|
||||
static get options() {
|
||||
return {
|
||||
_statusBar: {
|
||||
visible: true,
|
||||
drawBehind: false,
|
||||
},
|
||||
topBar: {
|
||||
animate: true,
|
||||
hideOnScroll: false,
|
||||
drawBehind: false,
|
||||
noBorder: true,
|
||||
visible: true,
|
||||
elevation: 0,
|
||||
leftButtons: {},
|
||||
rightButtons: [
|
||||
{
|
||||
id: "signup",
|
||||
text: "Sign Up",
|
||||
color: "#a7adaf",
|
||||
marginRight: 50
|
||||
}
|
||||
],
|
||||
},
|
||||
layout: {
|
||||
backgroundColor: "#f5fcff",
|
||||
},
|
||||
bottomTabs: {
|
||||
visible: false,
|
||||
drawBehind: true,
|
||||
},
|
||||
};
|
||||
}
|
||||
constructor(props) {
|
||||
super(props);
|
||||
Navigation.events().bindComponent(this);
|
||||
this.handleUsername = this.handleUsername.bind(this);
|
||||
this.state = {
|
||||
username: "",
|
||||
password: "",
|
||||
isLoading: false,
|
||||
isUsernameValid: true,
|
||||
usernameBorderColor: "#c1c5c7",
|
||||
passwordBorderColor: "#c1c5c7"
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
BackHandler.addEventListener("hardwareBackPress", () => {
|
||||
Navigation.pop(this.props.componentId);
|
||||
return true;
|
||||
});
|
||||
Linking.getInitialURL().then((url) => {
|
||||
console.log(url);
|
||||
});
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
BackHandler.removeEventListener("hardwareBackPress");
|
||||
}
|
||||
|
||||
doLogin = () => {
|
||||
this.setState({ isLoading: true });
|
||||
|
||||
@ -53,239 +103,310 @@ class LoginPage extends Component {
|
||||
});
|
||||
};
|
||||
|
||||
handleUsername = async (username) => {
|
||||
await this.setState({ username });
|
||||
let validUsers = await lookupAccounts(username);
|
||||
await this.setState({ isUsernameValid: validUsers.includes(username) });
|
||||
}
|
||||
|
||||
navigationButtonPressed({ buttonId }) {
|
||||
if (buttonId === "signup") {
|
||||
Linking.openURL("https://signup.steemit.com/?ref=esteem")
|
||||
.catch(err => console.error('An error occurred', err));
|
||||
}
|
||||
}
|
||||
|
||||
loginwithSc2 = () => {
|
||||
Navigation.showModal({
|
||||
stack: {
|
||||
children: [{
|
||||
component: {
|
||||
name: "navigation.eSteem.SteemConnect",
|
||||
passProps: {},
|
||||
options: {
|
||||
topBar: {
|
||||
title: {
|
||||
text: "Login via SC2"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}]
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Container style={styles.container}>
|
||||
<Header style={{ backgroundColor: "white", height: 80 }}>
|
||||
<Left>
|
||||
<Button
|
||||
transparent
|
||||
onPress={() => this.props.navigation.toggleDrawer()}
|
||||
>
|
||||
<Thumbnail
|
||||
style={{
|
||||
width: 32,
|
||||
height: 32,
|
||||
borderRadius: 16,
|
||||
margin: 10,
|
||||
}}
|
||||
source={require("../../assets/esteem.jpg")}
|
||||
/>
|
||||
</Button>
|
||||
</Left>
|
||||
<Body />
|
||||
<Right>
|
||||
<Text
|
||||
style={{
|
||||
color: "#a7adaf",
|
||||
marginHorizontal: 20,
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
>
|
||||
Sign Up
|
||||
</Text>
|
||||
</Right>
|
||||
</Header>
|
||||
<View style={styles.header}>
|
||||
<View
|
||||
style={{
|
||||
flex: 0.5,
|
||||
alignItems: "center",
|
||||
paddingLeft: 10,
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 40,
|
||||
fontWeight: "600",
|
||||
color: "#626262",
|
||||
marginTop: 35,
|
||||
}}
|
||||
>
|
||||
Sign in
|
||||
</Text>
|
||||
<Text style={{ color: "#a7adaf", marginTop: 20 }}>
|
||||
with your username {"\n"} and password {"\n"} to get
|
||||
all the {"\n"}{" "}
|
||||
<Text
|
||||
style={{ fontWeight: "bold", color: "#a7adaf" }}
|
||||
>
|
||||
benefits of eSteem
|
||||
</Text>{" "}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={{ flex: 0.5, overflow: "hidden", padding: 0 }}>
|
||||
<Image
|
||||
style={{
|
||||
width: 220,
|
||||
height: 304,
|
||||
marginTop: 10,
|
||||
marginLeft: 20,
|
||||
}}
|
||||
source={require("../../assets/love_mascot.png")}
|
||||
<View style={{ flex: 1 }}>
|
||||
<ScrollableTabView
|
||||
style={styles.tabView}
|
||||
renderTabBar={() => (
|
||||
<Tabs
|
||||
style={styles.tabbar}
|
||||
tabUnderlineDefaultWidth={100} // default containerWidth / (numberOfTabs * 4)
|
||||
tabUnderlineScaleX={2} // default 3
|
||||
activeColor={"#357ce6"}
|
||||
inactiveColor={"#222"}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
)}>
|
||||
<View tabLabel="Sign in" style={styles.tabbarItem}>
|
||||
|
||||
<View
|
||||
style={{ padding: 30, backgroundColor: "white", flex: 0.4 }}
|
||||
>
|
||||
<View>
|
||||
<Item
|
||||
rounded
|
||||
<View
|
||||
style={{
|
||||
margin: 5,
|
||||
backgroundColor: "#f6f6f6",
|
||||
height: 40,
|
||||
marginVertical: 10,
|
||||
overflow: "hidden",
|
||||
borderColor: "white",
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
name="at"
|
||||
style={{
|
||||
backgroundColor: "#ececec",
|
||||
height: 40,
|
||||
width: 40,
|
||||
alignItems: "center",
|
||||
padding: 8,
|
||||
color: "#a7adaf",
|
||||
fontWeight: "bold",
|
||||
}}
|
||||
/>
|
||||
<Input
|
||||
backgroundColor: '#f5f5f5',
|
||||
height: 60,
|
||||
borderBottomWidth: 2,
|
||||
borderBottomColor: this.state.isUsernameValid ? (this.state.usernameBorderColor) : ('red'),
|
||||
borderTopLeftRadius: 8,
|
||||
borderTopRightRadius: 8,
|
||||
marginHorizontal: 30,
|
||||
marginVertical: 20,
|
||||
flexDirection: 'row'
|
||||
}}>
|
||||
{ (this.state.username.length > 2) ? (
|
||||
<View style={{ flex: 0.15 }}>
|
||||
<FastImage
|
||||
style={{
|
||||
width: 24,
|
||||
height: 24,
|
||||
borderRadius: 12,
|
||||
top: 15,
|
||||
marginLeft: 12,
|
||||
}}
|
||||
source={ { uri: `https://steemitimages.com/u/${this.state.username}/avatar/small`, priority: FastImage.priority.high } }
|
||||
resizeMode={FastImage.resizeMode.cover}
|
||||
/>
|
||||
</View>
|
||||
) : (
|
||||
<Ionicons
|
||||
name="md-at"
|
||||
style={{
|
||||
flex: 0.15,
|
||||
fontSize: 25,
|
||||
top: 18,
|
||||
left: 12,
|
||||
color: "#c1c5c7",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<TextInput
|
||||
onFocus={() => this.setState({ usernameBorderColor: '#357ce6' })}
|
||||
onSubmitEditing={() => this.setState({ usernameBorderColor: '#c1c5c7' })}
|
||||
autoCapitalize="none"
|
||||
placeholder="username"
|
||||
onChangeText={text =>
|
||||
this.setState({ username: text })
|
||||
}
|
||||
editable={true}
|
||||
textContentType='username'
|
||||
onChangeText={text => { this.handleUsername(text) }}
|
||||
value={this.state.username}
|
||||
/>
|
||||
</Item>
|
||||
style={{
|
||||
height: 60,
|
||||
flex: 0.7
|
||||
}}/>
|
||||
|
||||
<Item
|
||||
rounded
|
||||
{ (this.state.username.length > 0) ? (
|
||||
<Ionicons
|
||||
onPress={() => this.setState({ username: '' })}
|
||||
name="md-close-circle"
|
||||
style={{
|
||||
flex: 0.15,
|
||||
fontSize: 25,
|
||||
top: 18,
|
||||
left: 8,
|
||||
color: "#c1c5c7",
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
null
|
||||
)}
|
||||
</View>
|
||||
|
||||
<View
|
||||
style={{
|
||||
margin: 5,
|
||||
backgroundColor: "#f6f6f6",
|
||||
height: 40,
|
||||
marginVertical: 10,
|
||||
overflow: "hidden",
|
||||
borderColor: "white",
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
backgroundColor: '#f5f5f5',
|
||||
height: 60,
|
||||
borderBottomWidth: 2,
|
||||
borderBottomColor: this.state.passwordBorderColor,
|
||||
borderTopLeftRadius: 8,
|
||||
borderTopRightRadius: 8,
|
||||
marginHorizontal: 30,
|
||||
marginVertical: 20,
|
||||
flexDirection: 'row'
|
||||
}}>
|
||||
<Ionicons
|
||||
name="md-lock"
|
||||
style={{
|
||||
backgroundColor: "#ececec",
|
||||
height: 40,
|
||||
width: 40,
|
||||
alignItems: "center",
|
||||
paddingVertical: 7,
|
||||
paddingLeft: 13,
|
||||
color: "#a7adaf",
|
||||
fontWeight: "bold",
|
||||
flex: 0.15,
|
||||
fontSize: 25,
|
||||
top: 18,
|
||||
left: 14,
|
||||
color: "#c1c5c7",
|
||||
}}
|
||||
/>
|
||||
<Input
|
||||
<TextInput
|
||||
onFocus={() => this.setState({ passwordBorderColor: '#357ce6' })}
|
||||
onSubmitEditing={() => this.setState({ passwordBorderColor: '#c1c5c7' })}
|
||||
secureTextEntry={true}
|
||||
placeholder="Password or WIF"
|
||||
textContentType='password'
|
||||
onChangeText={text =>
|
||||
this.setState({ password: text })
|
||||
}
|
||||
value={this.state.password}
|
||||
/>
|
||||
</Item>
|
||||
<View />
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
borderBottomColor: "lightgray",
|
||||
borderBottomWidth: 0.7,
|
||||
marginVertical: 20,
|
||||
}}
|
||||
/>
|
||||
<View
|
||||
style={{ flexDirection: "row", alignItems: "center" }}
|
||||
>
|
||||
<Icon
|
||||
name="information-circle"
|
||||
style={{
|
||||
flex: 0.15,
|
||||
color: "#a7adaf",
|
||||
fontSize: 25,
|
||||
paddingLeft: 10,
|
||||
}}
|
||||
/>
|
||||
<Text style={{ flex: 0.85, color: "#a7adaf" }}>
|
||||
Don't worry! {"\n"}
|
||||
Your password is kept locally on your device and
|
||||
removed upon logout!
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
style={{
|
||||
height: 60,
|
||||
flex: 0.7,
|
||||
width: '100%'
|
||||
}}/>
|
||||
|
||||
<View style={styles.footer}>
|
||||
<View style={{ flex: 0.6, alignItems: "flex-end" }}>
|
||||
<Text
|
||||
onPress={() => {
|
||||
this.props.navigation.goBack();
|
||||
}}
|
||||
style={{
|
||||
color: "#a7adaf",
|
||||
fontSize: 18,
|
||||
margin: 25,
|
||||
}}
|
||||
>
|
||||
Skip this screen
|
||||
</Text>
|
||||
</View>
|
||||
<View style={{ flex: 0.4, alignItems: "center" }}>
|
||||
{this.state.isLoading ? (
|
||||
<Button
|
||||
style={{
|
||||
borderRadius: 25,
|
||||
padding: 5,
|
||||
backgroundColor: "#007EE5",
|
||||
width: 130,
|
||||
height: 35,
|
||||
marginTop: 20,
|
||||
}}
|
||||
>
|
||||
<ActivityIndicator
|
||||
color="white"
|
||||
style={{ marginHorizontal: 50 }}
|
||||
/>
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
style={{
|
||||
borderRadius: 25,
|
||||
padding: 5,
|
||||
backgroundColor: "#007EE5",
|
||||
width: 130,
|
||||
height: 35,
|
||||
marginTop: 20,
|
||||
}}
|
||||
onPress={() => {
|
||||
this.doLogin();
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
{ (this.state.password.length > 0) ? (
|
||||
<Ionicons
|
||||
onPress={() => this.setState({ password: '' })}
|
||||
name="md-close-circle"
|
||||
style={{
|
||||
color: "white",
|
||||
fontWeight: "bold",
|
||||
marginHorizontal: 40,
|
||||
flex: 0.15,
|
||||
fontSize: 25,
|
||||
top: 18,
|
||||
left: 8,
|
||||
color: "#c1c5c7",
|
||||
}}
|
||||
>
|
||||
Login
|
||||
</Text>
|
||||
</Button>
|
||||
)}
|
||||
/>
|
||||
) : (
|
||||
null
|
||||
)}
|
||||
|
||||
</View>
|
||||
|
||||
<View style={{ flexDirection: 'row', marginHorizontal: 30, paddingLeft: 10 }}>
|
||||
<Ionicons
|
||||
color='#c1c5c7'
|
||||
style={{ flex: 0.125, fontSize: 25, alignSelf: 'center' }}
|
||||
name='ios-information-circle-outline'/>
|
||||
<Text
|
||||
style={{ flex: 0.875, color: '#788187' }}>
|
||||
User credentials are kept locally on the device. Credentials are removed upon logout!
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<View style={{ flexDirection: 'row', margin: 30 }}>
|
||||
<View style={{ flex: 0.6 }}>
|
||||
<TouchableOpacity
|
||||
onPress={goToAuthScreens}
|
||||
style={{ alignContent: 'center', padding: '9%' }}>
|
||||
<Text
|
||||
style={{ color: '#788187', alignSelf: 'center', fontWeight: 'bold' }}>
|
||||
Cancel
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<TouchableOpacity
|
||||
onPress={this.doLogin}
|
||||
style={{
|
||||
flex: 0.4,
|
||||
width: 100,
|
||||
height: 50,
|
||||
borderRadius: 30,
|
||||
backgroundColor: '#357ce6',
|
||||
flexDirection: 'row',
|
||||
}}>
|
||||
{ !this.state.isLoading ? (
|
||||
<View style={{ flex: 1, flexDirection: 'row' }}>
|
||||
<Ionicons
|
||||
color='white'
|
||||
name='md-person'
|
||||
style={{
|
||||
alignSelf: 'center',
|
||||
fontSize: 25,
|
||||
flex: 0.4,
|
||||
left: 15
|
||||
}}/>
|
||||
<Text style={{
|
||||
color: 'white',
|
||||
fontWeight: '600',
|
||||
alignSelf: 'center',
|
||||
fontSize: 16,
|
||||
flex: 0.6,
|
||||
}}>
|
||||
LOGIN
|
||||
</Text>
|
||||
</View>
|
||||
) : (
|
||||
<ActivityIndicator color='white'
|
||||
style={{ alignSelf: 'center', flex: 1 }}/>
|
||||
) }
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
</View>
|
||||
</View>
|
||||
</Container>
|
||||
<View tabLabel="SteemConnect" style={styles.steemConnectTab}>
|
||||
<View
|
||||
style={{ flex: 1, flexDirection: 'row', maxHeight: 200, overflow: 'hidden', backgroundColor: '#ffffff' }}>
|
||||
<View style={{ flex: 0.4 }}>
|
||||
<View style={{ alignSelf: 'center', height: 100, top: 70, left: 20 }}>
|
||||
<Text style={{ textAlign: 'center', textAlignVertical: 'center', fontSize: 20, fontWeight: 'bold', color: '#788187', bottom: 10 }}>
|
||||
Sign in
|
||||
</Text>
|
||||
<Text style={{ textAlign: 'center', textAlignVertical: 'center', color: '#788187', fontSize: 14, fontWeight: '400' }}>
|
||||
To get all
|
||||
the benefits
|
||||
using eSteem
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style={{ flex: 0.6 }}>
|
||||
<Image style={{ width: 217, height: 300, left: 55, top: 10 }} source={require('../../assets/love_mascot.png')} />
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View style={{ flex: 1, backgroundColor: '#ffffff', marginTop: 10 }}>
|
||||
<View style={{ flexDirection: 'row', marginHorizontal: 30, paddingLeft: 10, marginTop: 20 }}>
|
||||
<Ionicons
|
||||
color='#c1c5c7'
|
||||
style={{ flex: 0.125, fontSize: 25, alignSelf: 'center' }}
|
||||
name='ios-information-circle-outline'/>
|
||||
<Text
|
||||
style={{ flex: 0.875, color: '#788187' }}>
|
||||
If you don't want to keep your password encrypted and saved on your device, you can use Steemconnect.
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View style={{ alignItems: 'flex-end', backgroundColor: '#ffffff' }}>
|
||||
<TouchableOpacity
|
||||
onPress={this.loginwithSc2}
|
||||
style={{
|
||||
width: 200,
|
||||
height: 50,
|
||||
borderRadius: 30,
|
||||
backgroundColor: '#357ce6',
|
||||
flexDirection: 'row',
|
||||
margin: 20
|
||||
}}>
|
||||
<View style={{ flex: 1, flexDirection: 'row' }}>
|
||||
<Ionicons
|
||||
color='white'
|
||||
name='md-person'
|
||||
style={{
|
||||
alignSelf: 'center',
|
||||
fontSize: 25,
|
||||
marginHorizontal: 20
|
||||
}}/>
|
||||
<Text style={{
|
||||
color: 'white',
|
||||
fontWeight: '400',
|
||||
alignSelf: 'center',
|
||||
fontSize: 16,
|
||||
}}>
|
||||
steem
|
||||
<Text style={{ fontWeight: '800' }}>
|
||||
connect
|
||||
</Text>
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</ScrollableTabView>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -300,7 +421,7 @@ const styles = StyleSheet.create({
|
||||
flexDirection: "row",
|
||||
padding: 0,
|
||||
backgroundColor: "white",
|
||||
marginVertical: 10,
|
||||
marginBottom: 10,
|
||||
height: 200,
|
||||
flex: 0.4,
|
||||
},
|
||||
@ -312,5 +433,24 @@ const styles = StyleSheet.create({
|
||||
backgroundColor: "white",
|
||||
flexDirection: "row",
|
||||
},
|
||||
tabView: {
|
||||
alignSelf: "center",
|
||||
backgroundColor: "transparent",
|
||||
},
|
||||
tabbar: {
|
||||
alignSelf: "center",
|
||||
height: 40,
|
||||
backgroundColor: "white",
|
||||
},
|
||||
tabbarItem: {
|
||||
flex: 1,
|
||||
backgroundColor: "#ffffff",
|
||||
minWidth: Dimensions.get("window").width / 1,
|
||||
},
|
||||
steemConnectTab: {
|
||||
flex: 1,
|
||||
backgroundColor: "#e9e9e9",
|
||||
minWidth: Dimensions.get("window").width / 1,
|
||||
},
|
||||
});
|
||||
export default LoginPage;
|
||||
|
@ -2,119 +2,119 @@
|
||||
import React, { Component } from "react";
|
||||
import { Image } from "react-native";
|
||||
import {
|
||||
Content,
|
||||
Text,
|
||||
List,
|
||||
ListItem,
|
||||
Icon,
|
||||
Container,
|
||||
Left,
|
||||
Right,
|
||||
Badge,
|
||||
Content,
|
||||
Text,
|
||||
List,
|
||||
ListItem,
|
||||
Icon,
|
||||
Container,
|
||||
Left,
|
||||
Right,
|
||||
Badge,
|
||||
} from "native-base";
|
||||
import styles from "./style";
|
||||
import { Navigation } from "react-native-navigation";
|
||||
|
||||
const drawerCover = require("../../assets/drawer-cover.png");
|
||||
const drawerImage = require("../../assets/esteem.jpg");
|
||||
const drawerImage = require("../../assets/esteem.png");
|
||||
const datas = [
|
||||
{
|
||||
name: "Login",
|
||||
route: "Login",
|
||||
icon: "log-in",
|
||||
bg: "#C5F442",
|
||||
},
|
||||
{
|
||||
name: "Login",
|
||||
route: "Login",
|
||||
icon: "log-in",
|
||||
bg: "#C5F442",
|
||||
},
|
||||
];
|
||||
|
||||
export default class LoggedOutSideBar extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
shadowOffsetWidth: 1,
|
||||
shadowRadius: 4,
|
||||
};
|
||||
}
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
shadowOffsetWidth: 1,
|
||||
shadowRadius: 4,
|
||||
};
|
||||
}
|
||||
|
||||
hideSideMenu() {
|
||||
Navigation.mergeOptions("Component14", {
|
||||
sideMenu: {
|
||||
["right"]: {
|
||||
visible: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
hideSideMenu() {
|
||||
Navigation.mergeOptions("Component14", {
|
||||
sideMenu: {
|
||||
["right"]: {
|
||||
visible: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Container>
|
||||
<Content
|
||||
bounces={false}
|
||||
style={{ flex: 1, backgroundColor: "#fff" }}
|
||||
>
|
||||
<Image source={drawerCover} style={styles.drawerCover} />
|
||||
<Image
|
||||
square
|
||||
style={styles.drawerImage}
|
||||
source={drawerImage}
|
||||
/>
|
||||
render() {
|
||||
return (
|
||||
<Container>
|
||||
<Content
|
||||
bounces={false}
|
||||
style={{ flex: 1, backgroundColor: "#fff" }}
|
||||
>
|
||||
<Image source={drawerCover} style={styles.drawerCover} />
|
||||
<Image
|
||||
square
|
||||
style={styles.drawerImage}
|
||||
source={drawerImage}
|
||||
/>
|
||||
|
||||
<List
|
||||
dataArray={datas}
|
||||
renderRow={data => (
|
||||
<ListItem
|
||||
button
|
||||
noBorder
|
||||
onPress={() => {
|
||||
Navigation.push("tab1Stack", {
|
||||
component: {
|
||||
name: `navigation.eSteem.${
|
||||
data.route
|
||||
}`,
|
||||
passProps: {},
|
||||
options: {
|
||||
topBar: {
|
||||
title: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
this.hideSideMenu();
|
||||
}}
|
||||
>
|
||||
<Left>
|
||||
<Icon
|
||||
active
|
||||
name={data.icon}
|
||||
style={{
|
||||
color: "#777",
|
||||
fontSize: 26,
|
||||
width: 30,
|
||||
}}
|
||||
/>
|
||||
<Text style={styles.text}>{data.name}</Text>
|
||||
</Left>
|
||||
{data.types && (
|
||||
<Right style={{ flex: 1 }}>
|
||||
<Badge
|
||||
style={{
|
||||
borderRadius: 3,
|
||||
height: 25,
|
||||
width: 72,
|
||||
backgroundColor: data.bg,
|
||||
}}
|
||||
>
|
||||
<Text style={styles.badgeText}>{`${
|
||||
data.types
|
||||
} Types`}</Text>
|
||||
</Badge>
|
||||
</Right>
|
||||
)}
|
||||
</ListItem>
|
||||
)}
|
||||
/>
|
||||
</Content>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
<List
|
||||
dataArray={datas}
|
||||
renderRow={data => (
|
||||
<ListItem
|
||||
button
|
||||
noBorder
|
||||
onPress={() => {
|
||||
Navigation.push("tab1Stack", {
|
||||
component: {
|
||||
name: `navigation.eSteem.${
|
||||
data.route
|
||||
}`,
|
||||
passProps: {},
|
||||
options: {
|
||||
topBar: {
|
||||
title: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
this.hideSideMenu();
|
||||
}}
|
||||
>
|
||||
<Left>
|
||||
<Icon
|
||||
active
|
||||
name={data.icon}
|
||||
style={{
|
||||
color: "#777",
|
||||
fontSize: 26,
|
||||
width: 30,
|
||||
}}
|
||||
/>
|
||||
<Text style={styles.text}>{data.name}</Text>
|
||||
</Left>
|
||||
{data.types && (
|
||||
<Right style={{ flex: 1 }}>
|
||||
<Badge
|
||||
style={{
|
||||
borderRadius: 3,
|
||||
height: 25,
|
||||
width: 72,
|
||||
backgroundColor: data.bg,
|
||||
}}
|
||||
>
|
||||
<Text style={styles.badgeText}>{`${
|
||||
data.types
|
||||
} Types`}</Text>
|
||||
</Badge>
|
||||
</Right>
|
||||
)}
|
||||
</ListItem>
|
||||
)}
|
||||
/>
|
||||
</Content>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
40
src/screens/steem-connect/steemConnect.js
Normal file
40
src/screens/steem-connect/steemConnect.js
Normal file
@ -0,0 +1,40 @@
|
||||
import React, { Component } from "react";
|
||||
import { View, WebView } from "react-native";
|
||||
import { loginWithSC2 } from "../../providers/steem/auth";
|
||||
import { steemConnectOptions } from "./config";
|
||||
import RNRestart from "react-native-restart";
|
||||
import { Navigation } from "react-native-navigation";
|
||||
|
||||
export default class SteemConnect extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
};
|
||||
}
|
||||
|
||||
onNavigationStateChange(event) {
|
||||
let access_token = event.url.match(/\?(?:access_token)\=([\S\s]*?)\&/)[1];
|
||||
if(access_token) {
|
||||
loginWithSC2(access_token, "pinCode").then(result => {
|
||||
if(result === true) {
|
||||
// TODO: Handle pinCode and navigate to home page
|
||||
|
||||
} else {
|
||||
Navigation.dismissModal(this.props.componentId);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View style={{ flex: 1 }}>
|
||||
<WebView
|
||||
onNavigationStateChange={state => this.onNavigationStateChange(state)}
|
||||
source={{
|
||||
uri: `${steemConnectOptions.base_url}?client_id=${steemConnectOptions.client_id}&redirect_uri=${steemConnectOptions.redirect_uri}&${steemConnectOptions.scope}`
|
||||
}}/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user