Merge pull request #185 from status-im/feature/profile-screen

Editable profile screen

Former-commit-id: 05798fc552
This commit is contained in:
Roman Volosovskyi 2016-08-08 08:51:06 +03:00 committed by GitHub
commit 8f39f113fa
48 changed files with 786 additions and 397 deletions

View File

@ -11,6 +11,7 @@
"realm/react-native", "realm/react-native",
"react-native-action-button", "react-native-action-button",
"react-native-vector-icons/Ionicons", "react-native-vector-icons/Ionicons",
"react-native-vector-icons/Octicons",
"react-native-circle-checkbox", "react-native-circle-checkbox",
"react-native-randombytes", "react-native-randombytes",
"dismissKeyboard", "dismissKeyboard",
@ -21,7 +22,10 @@
"react-native-qrcode", "react-native-qrcode",
"react-native-orientation", "react-native-orientation",
"identicon.js", "identicon.js",
"react-native-fs" "react-native-fs",
"react-native-dialogs",
"react-native-image-resizer",
"react-native-image-crop-picker"
], ],
"imageDirs": [ "imageDirs": [
"images" "images"

View File

@ -82,7 +82,7 @@ android {
defaultConfig { defaultConfig {
applicationId "com.statusim" applicationId "com.statusim"
minSdkVersion 16 minSdkVersion 18
targetSdkVersion 22 targetSdkVersion 22
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
@ -120,6 +120,8 @@ android {
} }
dependencies { dependencies {
compile project(':react-native-image-resizer')
compile project(':react-native-dialogs')
compile project(':react-native-randombytes') compile project(':react-native-randombytes')
compile project(':react-native-android-sms-listener') compile project(':react-native-android-sms-listener')
compile project(':realm') compile project(':realm')
@ -134,6 +136,7 @@ dependencies {
compile project(':react-native-status') compile project(':react-native-status')
compile project(':react-native-orientation') compile project(':react-native-orientation')
compile project(':react-native-fs') compile project(':react-native-fs')
compile project(':react-native-image-crop-picker')
//compile(name:'statusgo-android-16', ext:'aar') //compile(name:'statusgo-android-16', ext:'aar')
compile(group: 'status-im', name: 'status-go', version: '0.1.0-201607011545-da53ec', ext: 'aar') compile(group: 'status-im', name: 'status-go', version: '0.1.0-201607011545-da53ec', ext: 'aar')

View File

@ -19,6 +19,9 @@ import com.centaurwarchief.smslistener.SmsListenerPackage;
import com.github.yamill.orientation.OrientationPackage; import com.github.yamill.orientation.OrientationPackage;
import com.rnfs.RNFSPackage; import com.rnfs.RNFSPackage;
import com.statusim.geth.module.GethPackage; import com.statusim.geth.module.GethPackage;
import com.aakashns.reactnativedialogs.ReactNativeDialogsPackage;
import fr.bamlab.rnimageresizer.ImageResizerPackage;
import com.reactnative.picker.PickerPackage;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -46,7 +49,10 @@ public class MainApplication extends Application implements ReactApplication {
new SmsListenerPackage(), new SmsListenerPackage(),
new OrientationPackage(), new OrientationPackage(),
new RNFSPackage(), new RNFSPackage(),
new GethPackage() new GethPackage(),
new ReactNativeDialogsPackage(),
new ImageResizerPackage(),
new PickerPackage()
); );
} }
}; };

View File

@ -3,6 +3,8 @@
<string name="app_name">Status</string> <string name="app_name">Status</string>
<string name="root_warning">Your phone appears to be ROOTED, by pressing CONTINUE you understand and accept the risks in using this software.</string> <string name="root_warning">Your phone appears to be ROOTED, by pressing CONTINUE you understand and accept the risks in using this software.</string>
<string name="root_okay">Continue</string> <string name="root_okay">Continue</string>

View File

@ -16,16 +16,10 @@ allprojects {
repositories { repositories {
mavenLocal() mavenLocal()
jcenter() jcenter()
maven { maven { url "$rootDir/../node_modules/react-native/android" }
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url "$rootDir/../node_modules/react-native/android"
}
// for geth // for geth
flatDir { flatDir { dirs 'libs' }
dirs 'libs' maven { url "http://185.90.37.89:8081/artifactory/libs-release-local" }
} maven { url "https://jitpack.io" }
maven {
url "http://185.90.37.89:8081/artifactory/libs-release-local"
}
} }
} }

View File

@ -1,6 +1,10 @@
rootProject.name = 'StatusIm' rootProject.name = 'StatusIm'
include ':app' include ':app'
include ':react-native-image-resizer'
project(':react-native-image-resizer').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-image-resizer/android')
include ':react-native-dialogs'
project(':react-native-dialogs').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-dialogs/android')
include ':react-native-randombytes' include ':react-native-randombytes'
project(':react-native-randombytes').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-randombytes/android') project(':react-native-randombytes').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-randombytes/android')
include ':react-native-android-sms-listener' include ':react-native-android-sms-listener'
@ -23,3 +27,5 @@ include ':react-native-orientation', ':app'
project(':react-native-orientation').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-orientation/android') project(':react-native-orientation').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-orientation/android')
include ':react-native-fs' include ':react-native-fs'
project(':react-native-fs').projectDir = new File(settingsDir, '../node_modules/react-native-fs/android') project(':react-native-fs').projectDir = new File(settingsDir, '../node_modules/react-native-fs/android')
include ':react-native-image-crop-picker'
project(':react-native-image-crop-picker').projectDir = new File(settingsDir, '../node_modules/react-native-image-crop-picker/android')

View File

@ -5,7 +5,6 @@
}; };
objectVersion = 46; objectVersion = 46;
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; }; 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; };
00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; }; 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; };
@ -49,6 +48,7 @@
D28AEFB4C39548EB80416889 /* Entypo.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 52E205D210BC48B7A553BB62 /* Entypo.ttf */; }; D28AEFB4C39548EB80416889 /* Entypo.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 52E205D210BC48B7A553BB62 /* Entypo.ttf */; };
EF2B5857B4A34E0C9707FB3F /* Octicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = B3B19223008342D096AA356E /* Octicons.ttf */; }; EF2B5857B4A34E0C9707FB3F /* Octicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = B3B19223008342D096AA356E /* Octicons.ttf */; };
FD4F213C3873473CB703B1D2 /* libRNFS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 674B3D9595A047AB8D518F4E /* libRNFS.a */; }; FD4F213C3873473CB703B1D2 /* libRNFS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 674B3D9595A047AB8D518F4E /* libRNFS.a */; };
E0AD9E8F495A4907B65104BF /* libRCTImageResizer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2BEE3436791D42248F853999 /* libRCTImageResizer.a */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */ /* Begin PBXContainerItemProxy section */
@ -284,6 +284,8 @@
CEB0E2659D1A4F5FA842057A /* EvilIcons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = EvilIcons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/EvilIcons.ttf"; sourceTree = "<group>"; }; CEB0E2659D1A4F5FA842057A /* EvilIcons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = EvilIcons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/EvilIcons.ttf"; sourceTree = "<group>"; };
DF1CD4C3D1254774ACCAE4E8 /* libBVLinearGradient.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libBVLinearGradient.a; sourceTree = "<group>"; }; DF1CD4C3D1254774ACCAE4E8 /* libBVLinearGradient.a */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = archive.ar; path = libBVLinearGradient.a; sourceTree = "<group>"; };
F090E261B9854867A728CE4F /* RealmReact.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RealmReact.xcodeproj; path = "../node_modules/realm/react-native/ios/RealmReact.xcodeproj"; sourceTree = "<group>"; }; F090E261B9854867A728CE4F /* RealmReact.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RealmReact.xcodeproj; path = "../node_modules/realm/react-native/ios/RealmReact.xcodeproj"; sourceTree = "<group>"; };
5E5A7625B76441D984EA8C0D /* RCTImageResizer.xcodeproj */ = {isa = PBXFileReference; name = "RCTImageResizer.xcodeproj"; path = "../node_modules/react-native-image-resizer/ios/RCTImageResizer.xcodeproj"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; };
2BEE3436791D42248F853999 /* libRCTImageResizer.a */ = {isa = PBXFileReference; name = "libRCTImageResizer.a"; path = "libRCTImageResizer.a"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -323,6 +325,7 @@
BA68A2377A20496EA737000D /* libz.tbd in Frameworks */, BA68A2377A20496EA737000D /* libz.tbd in Frameworks */,
3E15DFEC1F6F4D7CAE088F49 /* libTcpSockets.a in Frameworks */, 3E15DFEC1F6F4D7CAE088F49 /* libTcpSockets.a in Frameworks */,
AD5063BC2B2A4C52ACE0A0B4 /* libUdpSockets.a in Frameworks */, AD5063BC2B2A4C52ACE0A0B4 /* libUdpSockets.a in Frameworks */,
E0AD9E8F495A4907B65104BF /* libRCTImageResizer.a in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -581,6 +584,7 @@
38E1A2C8D0734EE99E2B16CE /* TcpSockets.xcodeproj */, 38E1A2C8D0734EE99E2B16CE /* TcpSockets.xcodeproj */,
2F0276A9E90843E996A0E762 /* UdpSockets.xcodeproj */, 2F0276A9E90843E996A0E762 /* UdpSockets.xcodeproj */,
439B6B4B407A4E2AACAFE5BE /* RCTJail.xcodeproj */, 439B6B4B407A4E2AACAFE5BE /* RCTJail.xcodeproj */,
5E5A7625B76441D984EA8C0D /* RCTImageResizer.xcodeproj */,
); );
name = Libraries; name = Libraries;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1074,6 +1078,7 @@
"\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
); );
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/StatusIm.app/StatusIm"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/StatusIm.app/StatusIm";
@ -1107,6 +1112,7 @@
"\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"", "\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
); );
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/StatusIm.app/StatusIm"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/StatusIm.app/StatusIm";
@ -1140,6 +1146,7 @@
"$(SRCROOT)/../node_modules/react-native-udp/ios/**", "$(SRCROOT)/../node_modules/react-native-udp/ios/**",
"$(SRCROOT)/../node_modules/react-native-status/ios/RCTJail/RCTJail/**", "$(SRCROOT)/../node_modules/react-native-status/ios/RCTJail/RCTJail/**",
"$(SRCROOT)/../node_modules/react-native-status/ios/RCTJail/RCTJail/**", "$(SRCROOT)/../node_modules/react-native-status/ios/RCTJail/RCTJail/**",
"$(SRCROOT)/../node_modules/react-native-image-resizer/ios/RCTImageResizer",
); );
INFOPLIST_FILE = StatusIm/Info.plist; INFOPLIST_FILE = StatusIm/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
@ -1180,6 +1187,7 @@
"$(SRCROOT)/../node_modules/react-native-udp/ios/**", "$(SRCROOT)/../node_modules/react-native-udp/ios/**",
"$(SRCROOT)/../node_modules/react-native-status/ios/RCTJail/RCTJail/**", "$(SRCROOT)/../node_modules/react-native-status/ios/RCTJail/RCTJail/**",
"$(SRCROOT)/../node_modules/react-native-status/ios/RCTJail/RCTJail/**", "$(SRCROOT)/../node_modules/react-native-status/ios/RCTJail/RCTJail/**",
"$(SRCROOT)/../node_modules/react-native-image-resizer/ios/RCTImageResizer",
); );
INFOPLIST_FILE = StatusIm/Info.plist; INFOPLIST_FILE = StatusIm/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
@ -1244,6 +1252,7 @@
"$(SRCROOT)/../node_modules/react-native-udp/ios/**", "$(SRCROOT)/../node_modules/react-native-udp/ios/**",
"$(SRCROOT)/../node_modules/react-native-status/ios/RCTJail/RCTJail/**", "$(SRCROOT)/../node_modules/react-native-status/ios/RCTJail/RCTJail/**",
"$(SRCROOT)/../node_modules/react-native-status/ios/RCTJail/RCTJail/**", "$(SRCROOT)/../node_modules/react-native-status/ios/RCTJail/RCTJail/**",
"$(SRCROOT)/../node_modules/react-native-image-resizer/ios/RCTImageResizer",
); );
IPHONEOS_DEPLOYMENT_TARGET = 7.0; IPHONEOS_DEPLOYMENT_TARGET = 7.0;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
@ -1297,6 +1306,7 @@
"$(SRCROOT)/../node_modules/react-native-udp/ios/**", "$(SRCROOT)/../node_modules/react-native-udp/ios/**",
"$(SRCROOT)/../node_modules/react-native-status/ios/RCTJail/RCTJail/**", "$(SRCROOT)/../node_modules/react-native-status/ios/RCTJail/RCTJail/**",
"$(SRCROOT)/../node_modules/react-native-status/ios/RCTJail/RCTJail/**", "$(SRCROOT)/../node_modules/react-native-status/ios/RCTJail/RCTJail/**",
"$(SRCROOT)/../node_modules/react-native-image-resizer/ios/RCTImageResizer",
); );
IPHONEOS_DEPLOYMENT_TARGET = 7.0; IPHONEOS_DEPLOYMENT_TARGET = 7.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;

View File

@ -34,9 +34,12 @@
"react-native-circle-checkbox": "github:paramoshkinandrew/ReactNativeCircleCheckbox", "react-native-circle-checkbox": "github:paramoshkinandrew/ReactNativeCircleCheckbox",
"react-native-contacts": "^0.2.4", "react-native-contacts": "^0.2.4",
"react-native-crypto": "^2.0.1", "react-native-crypto": "^2.0.1",
"react-native-dialogs": "0.0.16",
"react-native-fs": "^1.5.1", "react-native-fs": "^1.5.1",
"react-native-http": "github:tradle/react-native-http#834492d", "react-native-http": "github:tradle/react-native-http#834492d",
"react-native-i18n": "0.0.8", "react-native-i18n": "0.0.8",
"react-native-image-crop-picker": "^0.5.4",
"react-native-image-resizer": "github:danieldunderfelt/react-native-image-resizer",
"react-native-invertible-scroll-view": "^1.0.0", "react-native-invertible-scroll-view": "^1.0.0",
"react-native-level-fs": "^2.0.1", "react-native-level-fs": "^2.0.1",
"react-native-linear-gradient": "1.5.7", "react-native-linear-gradient": "1.5.7",

View File

@ -9,7 +9,7 @@
[re-frame "0.7.0"] [re-frame "0.7.0"]
[prismatic/schema "1.0.4"] [prismatic/schema "1.0.4"]
^{:voom {:repo "git@github.com:status-im/status-lib.git" ^{:voom {:repo "git@github.com:status-im/status-lib.git"
:branch "master"}} :branch "discover-rework"}}
[status-im/protocol "0.1.1-20160706_085008-ge61756a"] [status-im/protocol "0.1.1-20160706_085008-ge61756a"]
[natal-shell "0.3.0"] [natal-shell "0.3.0"]
[com.andrewmcveigh/cljs-time "0.4.0"]] [com.andrewmcveigh/cljs-time "0.4.0"]]

View File

@ -17,56 +17,64 @@
(defn save-account [_ [_ account]] (defn save-account [_ [_ account]]
(accounts/save-accounts [account])) (accounts/save-accounts [account] false))
(register-handler :add-account (register-handler
:add-account
(-> (fn [db [_ {:keys [address] :as account}]] (-> (fn [db [_ {:keys [address] :as account}]]
(update db :accounts assoc address account)) (update db :accounts assoc address account))
((after save-account)))) ((after save-account))))
(defn save-password [password] (defn save-password [password]
(storage/put kv/kv-store :password password)) (storage/put kv/kv-store :password password))
(defn account-created [db result password] (defn account-created [db result password]
(let [data (json->clj result) (let [data (json->clj result)
public-key (:pubkey data) public-key (:pubkey data)
address (:address data) address (:address data)
account {:public-key public-key account {:public-key public-key
:address address :address address
:name address :name address
:photo-path (identicon address)} :photo-path (identicon address)}]
]
(log/debug "account-created: " account) (log/debug "account-created: " account)
(when (not (str/blank? public-key)) (when (not (str/blank? public-key))
(do (do
;(save-password password)
(dispatch-sync [:add-account account]) (dispatch-sync [:add-account account])
(dispatch [:login-account address password]))))) (dispatch [:login-account address password])))))
(register-handler :create-account (register-handler
(-> (fn [db [_ password]] :create-account
(geth/create-account password (fn [result] (account-created db result password))) (fn [db [_ password]]
db))) (geth/create-account password (fn [result] (account-created db result password)))
db))
(defn initialize-account [db account] (register-handler
:account-update
(fn [db [_ data]]
(let [current-account-id (get db :current-account-id)
account (-> (get-in db [:accounts current-account-id])
(merge data))]
(accounts/save-accounts [account] true)
(assoc-in db [:accounts current-account-id] account))))
(defn initialize-account [db address]
(let [is-login-screen? (= (:view-id db) :login)] (let [is-login-screen? (= (:view-id db) :login)]
(dispatch [:set :login {}]) (dispatch [:set :login {}])
(dispatch [:set :is-logged-in true]) (dispatch [:set :current-account-id address])
(dispatch [:set :user-identity account]) (dispatch [:initialize-account address])
(dispatch [:initialize-account account])
(when is-login-screen? (dispatch [:navigate-to-clean default-view])))) (when is-login-screen? (dispatch [:navigate-to-clean default-view]))))
(defn logged-in [db address] (defn logged-in [db address]
(let [account (get-in db [:accounts address]) (let [is-login-screen? (= (:view-id db) :login)
is-login-screen? (= (:view-id db) :login)
new-account? (not is-login-screen?)] new-account? (not is-login-screen?)]
(log/debug "Logged in: " address account) (log/debug "Logged in: " address)
(realm/change-account-realm address new-account? (realm/change-account-realm address new-account?
#(if (nil? %) #(if (nil? %)
(initialize-account db account) (initialize-account db address)
(log/debug "Error changing acount realm: " %))))) (log/debug "Error changing acount realm: " %)))))
(register-handler :login-account (register-handler
:login-account
(-> (fn [db [_ address password]] (-> (fn [db [_ address password]]
(geth/login address password (fn [result] (geth/login address password (fn [result]
(let [data (json->clj result) (let [data (json->clj result)

View File

@ -59,7 +59,8 @@
(dispatch [:set-in [:login :error] ""]))}]]) (dispatch [:set-in [:login :error] ""]))}]])
(defview login [{platform-specific :platform-specific}] (defview login [{platform-specific :platform-specific}]
[{:keys [address password error]} [:get :login]] [{:keys [address password error]} [:get :login]
keyboard-height [:get :keyboard-height]]
[view st/screen-container [view st/screen-container
[linear-gradient {:colors ["rgba(182, 116, 241, 1)" "rgba(107, 147, 231, 1)" "rgba(43, 171, 238, 1)"] [linear-gradient {:colors ["rgba(182, 116, 241, 1)" "rgba(107, 147, 231, 1)" "rgba(43, 171, 238, 1)"]
:start [0, 0] :start [0, 0]
@ -79,20 +80,19 @@
[view st/form-container-inner [view st/form-container-inner
[address-input (or address "")] [address-input (or address "")]
[password-input error]]] [password-input error]]]
(let [keyboard-height @(subscribe [:get :keyboard-height])] [view st/bottom-actions-container
[view st/bottom-actions-container (when (= keyboard-height 0)
(when (= keyboard-height 0) [view st/recover-button-container
[view st/recover-button-container
[touchable-highlight
{:on-press #()}
[view st/recover-button
[text {:style st/recover-button-text
:platform-specific platform-specific}
(label :t/recover-access)]]]])
[view st/connect-button-container
[touchable-highlight [touchable-highlight
{:on-press #(dispatch [:login-account address password])} {:on-press #()}
[view st/connect-button [view st/recover-button
[text {:style st/connect-button-text [text {:style st/recover-button-text
:platform-specific platform-specific} :platform-specific platform-specific}
(label :t/connect)]]]]])]) (label :t/recover-access)]]]])
[view st/connect-button-container
[touchable-highlight
{:on-press #(dispatch [:login-account address password])}
[view st/connect-button
[text {:style st/connect-button-text
:platform-specific platform-specific}
(label :t/connect)]]]]]])

View File

@ -16,7 +16,7 @@
(dispatch [:set-in [:login :address] address])) (dispatch [:set-in [:login :address] address]))
(defview account-view [{:keys [address photo-path name] :as account}] (defview account-view [{:keys [address photo-path name] :as account}]
[current-account [:get :user-identity]] [current-account [:get-current-account]]
[touchable-highlight [touchable-highlight
{:onPress #(on-press address)} {:onPress #(on-press address)}
[view st/account-container [view st/account-container

View File

@ -8,7 +8,8 @@
[status-im.android.styles :refer [styles]] [status-im.android.styles :refer [styles]]
[status-im.components.react :refer [app-registry [status-im.components.react :refer [app-registry
keyboard keyboard
orientation]] orientation
show-dialog]]
[status-im.components.main-tabs :refer [main-tabs]] [status-im.components.main-tabs :refer [main-tabs]]
[status-im.contacts.views.contact-list :refer [contact-list]] [status-im.contacts.views.contact-list :refer [contact-list]]
[status-im.contacts.views.new-contact :refer [new-contact]] [status-im.contacts.views.new-contact :refer [new-contact]]
@ -24,6 +25,7 @@
[status-im.participants.views.remove :refer [remove-participants]] [status-im.participants.views.remove :refer [remove-participants]]
[status-im.group-settings.screen :refer [group-settings]] [status-im.group-settings.screen :refer [group-settings]]
[status-im.profile.screen :refer [profile my-profile]] [status-im.profile.screen :refer [profile my-profile]]
[status-im.profile.photo-capture.screen :refer [profile-photo-capture]]
[status-im.utils.utils :refer [toast]] [status-im.utils.utils :refer [toast]]
[status-im.utils.encryption] [status-im.utils.encryption]
status-im.persistence.realm.core status-im.persistence.realm.core
@ -48,9 +50,9 @@
(let [signed-up (subscribe [:get :signed-up]) (let [signed-up (subscribe [:get :signed-up])
_ (log/debug "signed up: " @signed-up) _ (log/debug "signed up: " @signed-up)
view-id (subscribe [:get :view-id]) view-id (subscribe [:get :view-id])
account (subscribe [:get :user-identity]) account-id (subscribe [:get :current-account-id])
keyboard-height (subscribe [:get :keyboard-height])] keyboard-height (subscribe [:get :keyboard-height])]
(log/debug "Current account: " @account) (log/debug "Current account: " @account-id)
(r/create-class (r/create-class
{:component-will-mount {:component-will-mount
(fn [] (fn []
@ -72,7 +74,7 @@
(dispatch [:set :keyboard-height 0])))) (dispatch [:set :keyboard-height 0]))))
:render :render
(fn [] (fn []
(let [startup-view (if @account (let [startup-view (if @account-id
(if @signed-up (if @signed-up
@view-id @view-id
:chat) :chat)
@ -94,10 +96,12 @@
:qr-scanner qr-scanner :qr-scanner qr-scanner
:chat chat :chat chat
:profile profile :profile profile
:profile-photo-capture profile-photo-capture
:accounts accounts :accounts accounts
:login login :login login
:my-profile my-profile)] :my-profile my-profile)]
[component {:platform-specific {:styles styles}}])))}))) [component {:platform-specific {:styles styles
:list-selection-fn show-dialog}}])))})))
(defn init [& [env]] (defn init [& [env]]
(dispatch-sync [:reset-app]) (dispatch-sync [:reset-app])

View File

@ -310,8 +310,9 @@
(assoc db :password-saved true))) (assoc db :password-saved true)))
(register-handler :sign-up (register-handler :sign-up
(after (fn [_ [_ phone-number]]
(dispatch [:account-update {:phone phone-number}])))
(fn [db [_ phone-number]] (fn [db [_ phone-number]]
;; todo save phone number to db
(let [formatted (format-phone-number phone-number)] (let [formatted (format-phone-number phone-number)]
(-> db (-> db
(assoc :user-phone-number formatted) (assoc :user-phone-number formatted)

View File

@ -19,7 +19,7 @@
toolbar-background2]] toolbar-background2]]
[status-im.components.status-bar :refer [status-bar]] [status-im.components.status-bar :refer [status-bar]]
[status-im.components.toolbar :refer [toolbar]] [status-im.components.toolbar :refer [toolbar]]
[status-im.components.icons.ionicons :refer [icon]] [status-im.components.icons.custom-icons :refer [ion-icon]]
[status-im.i18n :refer [label]] [status-im.i18n :refer [label]]
[status-im.chats-list.styles :as st] [status-im.chats-list.styles :as st]
[status-im.components.styles :as cst] [status-im.components.styles :as cst]
@ -80,12 +80,12 @@
{:title (label :t/new-chat) {:title (label :t/new-chat)
:buttonColor :#9b59b6 :buttonColor :#9b59b6
:onPress #(dispatch [:show-group-contacts :people])} :onPress #(dispatch [:show-group-contacts :people])}
[icon {:name :md-create [ion-icon {:name :md-create
:style st/create-icon}]] :style st/create-icon}]]
[action-button-item [action-button-item
{:title (label :t/new-group-chat) {:title (label :t/new-group-chat)
:buttonColor :#1abc9c :buttonColor :#1abc9c
:onPress #(dispatch [:show-group-new])} :onPress #(dispatch [:show-group-new])}
[icon {:name :md-person [ion-icon {:name :md-person
:style st/person-stalker-icon}]]]] :style st/person-stalker-icon}]]]]
[bottom-gradient]]))) [bottom-gradient]])))

View File

@ -1,7 +1,16 @@
(ns status-im.components.camera (ns status-im.components.camera
(:require [reagent.core :as r])) (:require [reagent.core :as r]
[clojure.walk :refer [keywordize-keys]]))
(def class (.-default (js/require "react-native-camera"))) (def camera-class (js/require "react-native-camera"))
(defn constants [t]
(-> (aget camera-class "default" "constants" t)
(js->clj)
(keywordize-keys)))
(def aspects (constants "Aspect"))
(def capture-targets (constants "CaptureTarget"))
(defn camera [props] (defn camera [props]
(r/create-element class (clj->js (merge {:inverted true} props)))) (r/create-element (.-default camera-class) (clj->js (merge {:inverted true} props))))

View File

@ -5,6 +5,7 @@
text text
image image
icon]] icon]]
[status-im.components.icons.custom-icons :refer [oct-icon]]
[status-im.components.chat-icon.styles :as st] [status-im.components.chat-icon.styles :as st]
[status-im.components.styles :refer [default-chat-color]] [status-im.components.styles :refer [default-chat-color]]
[clojure.string :as s])) [clojure.string :as s]))
@ -18,20 +19,25 @@
[image {:source {:uri photo-path} [image {:source {:uri photo-path}
:style (:chat-icon styles)}]) :style (:chat-icon styles)}])
(defn contact-online [online styles] (defn contact-badge [type styles]
(when online (when (= type :edit)
[view (:online-view styles) [view (:online-view styles)
[view (:online-dot-left styles)] (case type
[view (:online-dot-right styles)]])) :online [view
[view (:online-dot-left styles)]
[view (:online-dot-right styles)]]
:edit [view
[oct-icon {:name :pencil
:style st/photo-pencil}]])]))
(defview chat-icon-view [chat-id group-chat name online styles] (defview chat-icon-view [chat-id group-chat name online styles]
[photo-path [:chat-photo chat-id]] [photo-path [:chat-photo chat-id]]
[view (:container styles) [view (:container styles)
(if-not (s/blank? photo-path) (if-not (s/blank? photo-path)
[chat-icon photo-path styles] [chat-icon photo-path styles]
[default-chat-icon name styles]) [default-chat-icon name styles])
(when-not group-chat (when-not group-chat
[contact-online online styles])]) [contact-badge (if online :online :blank) styles])])
(defn chat-icon-view-chat-list [chat-id group-chat name color online] (defn chat-icon-view-chat-list [chat-id group-chat name color online]
[chat-icon-view chat-id group-chat name online [chat-icon-view chat-id group-chat name online
@ -65,13 +71,13 @@
(defn contact-icon-view [contact styles] (defn contact-icon-view [contact styles]
(let [photo-path (:photo-path contact) (let [photo-path (:photo-path contact)
;; TODO stub data ;; TODO: stub
online true] type :online]
[view (:container styles) [view (:container styles)
(if-not (s/blank? photo-path) (if-not (s/blank? photo-path)
[chat-icon photo-path styles] [chat-icon photo-path styles]
[default-chat-icon (:name contact) styles]) [default-chat-icon (:name contact) styles])
[contact-online online styles]])) [contact-badge type styles]]))
(defn contact-icon-contacts-tab [contact] (defn contact-icon-contacts-tab [contact]
[contact-icon-view contact [contact-icon-view contact
@ -83,7 +89,7 @@
:default-chat-icon (st/default-chat-icon-chat-list default-chat-color) :default-chat-icon (st/default-chat-icon-chat-list default-chat-color)
:default-chat-icon-text st/default-chat-icon-text}]) :default-chat-icon-text st/default-chat-icon-text}])
(defn profile-icon-view [photo-path name color online] (defn profile-icon-view [photo-path name color badge-type]
(let [styles {:container st/container-profile (let [styles {:container st/container-profile
:online-view st/online-view-profile :online-view st/online-view-profile
:online-dot-left st/online-dot-left-profile :online-dot-left st/online-dot-left-profile
@ -95,19 +101,17 @@
(if (and photo-path (not (empty? photo-path))) (if (and photo-path (not (empty? photo-path)))
[chat-icon photo-path styles] [chat-icon photo-path styles]
[default-chat-icon name styles]) [default-chat-icon name styles])
[contact-online online styles]])) [contact-badge badge-type styles]]))
(defview profile-icon [] (defview profile-icon []
[contact [:contact]] [contact [:contact]]
(let [;; TODO stub data (let [;; TODO: stub
online true type :online
color default-chat-color] color default-chat-color]
[profile-icon-view (:photo-path contact) (:name contact) color online])) [profile-icon-view (:photo-path @contact) (:name @contact) color type]))
(defview my-profile-icon [] (defn my-profile-icon [{{:keys [photo-path name]} :account
[name [:get :username] edit? :edit?}]
photo-path [:get :photo-path]] (let [type (if edit? :edit :blank)
(let [;; TODO stub data color default-chat-color]
online true [profile-icon-view photo-path name color type]))
color default-chat-color]
[profile-icon-view photo-path name color online]))

View File

@ -59,8 +59,9 @@
(def chat-icon-profile (def chat-icon-profile
(merge chat-icon (merge chat-icon
{:width 64 {:width 64
:height 64})) :height 64
:border-radius 32}))
(def online-view (def online-view
{:position :absolute {:position :absolute
@ -75,13 +76,15 @@
(def online-view-menu-item (def online-view-menu-item
(merge online-view (merge online-view
{:width 15 {:width 14
:height 15})) :height 14
:border-radius 7}))
(def online-view-profile (def online-view-profile
(merge online-view (merge online-view
{:width 24 {:width 24
:height 24})) :height 24
:border-radius 12}))
(def online-dot (def online-dot
{:position :absolute {:position :absolute
@ -93,6 +96,12 @@
(def online-dot-left (merge online-dot {:left 3})) (def online-dot-left (merge online-dot {:left 3}))
(def online-dot-right (merge online-dot {:left 9})) (def online-dot-right (merge online-dot {:left 9}))
(def photo-pencil
{:margin-left 6
:margin-top 3
:font-size 12
:color :white})
(def online-dot-menu-item (def online-dot-menu-item
(merge online-dot (merge online-dot
{:top 4 {:top 4

View File

@ -1,21 +1,43 @@
(ns status-im.components.drawer.styles (ns status-im.components.drawer.styles
(:require [status-im.components.styles :refer [font (:require [status-im.components.styles :refer [font
color-light-blue-transparent color-light-blue-transparent
color-white color-white
color-black color-black
color-blue color-blue
color-blue-transparent color-blue-transparent
selected-message-color selected-message-color
online-color online-color
separator-color separator-color
text1-color text1-color
text2-color text2-color
text3-color]])) text3-color]]))
(def drawer-menu
{:flex 1
:background-color color-white
:flex-direction :column})
(def user-photo-container
{:margin-top 40
:align-items :center
:justify-content :center})
(def user-photo (def user-photo
{:borderRadius 32 {:border-radius 32
:width 64 :width 64
:height 64}) :height 64})
(def name-container
{:margin-top 20
:margin-left 16
:margin-right 16
:align-items :center})
(def menu-items-container
{:flex 1
:margin-top 50
:align-items :stretch
:flex-direction :column})
(def menu-item-touchable (def menu-item-touchable
{:height 48 {:height 48
@ -23,42 +45,19 @@
:paddingTop 14}) :paddingTop 14})
(def menu-item-text (def menu-item-text
{:fontSize 14 {:font-size 14
:fontFamily font :line-height 21
:lineHeight 21 :color text1-color})
:color text1-color})
(def drawer-menu
{:flex 1
:backgroundColor color-white
:flexDirection :column})
(def user-photo-container
{:marginTop 40
:alignItems :center
:justifyContent :center})
(def name-container
{:marginTop 20
:alignItems :center})
(def name-text (def name-text
{:marginTop -2.5 {:color text1-color
:color text1-color :font-size 16})
:fontSize 16})
(def menu-items-container
{:flex 1
:marginTop 80
:alignItems :stretch
:flexDirection :column})
(def switch-users-container (def switch-users-container
{:paddingVertical 36 {:padding-vertical 36
:alignItems :center}) :align-items :center})
(def switch-users-text (def switch-users-text
{:fontSize 14 {:font-size 14
:fontFamily font :line-height 21
:lineHeight 21 :color text3-color})
:color text3-color})

View File

@ -1,4 +1,5 @@
(ns status-im.components.drawer.view (ns status-im.components.drawer.view
(:require-macros [status-im.utils.views :refer [defview]])
(:require [clojure.string :as s] (:require [clojure.string :as s]
[re-frame.core :refer [subscribe dispatch dispatch-sync]] [re-frame.core :refer [subscribe dispatch dispatch-sync]]
[reagent.core :as r] [reagent.core :as r]
@ -27,53 +28,67 @@
{:uri photo-path}) {:uri photo-path})
:style st/user-photo}]) :style st/user-photo}])
(defn menu-item [{:keys [name handler]}] (defn menu-item [{:keys [name handler platform-specific]}]
[touchable-opacity {:style st/menu-item-touchable [touchable-opacity {:style st/menu-item-touchable
:onPress (fn [] :onPress (fn []
(close-drawer) (close-drawer)
(handler))} (handler))}
[text {:style st/menu-item-text} [text {:style st/menu-item-text
:platform-specific platform-specific
:font :default}
name]]) name]])
(defn drawer-menu [] (defview drawer-menu [{platform-specific :platform-specific}]
(let [username (subscribe [:get :username])] [{:keys [name address photo-path]} [:get-current-account]]
(fn [] [view st/drawer-menu
[view st/drawer-menu [view st/user-photo-container
[view st/user-photo-container [user-photo {:photo-path photo-path}]]
[user-photo {}]] [view st/name-container
[view st/name-container [text {:style st/name-text
[text {:style st/name-text} :platform-specific platform-specific
@username]] :number-of-lines 1
[view st/menu-items-container :font :default}
[menu-item {:name (label :t/profile) (if (= name address)
:handler #(dispatch [:navigate-to :my-profile])}] (label :t/user-anonymous)
[menu-item {:name (label :t/settings) name)]]
:handler (fn [] [view st/menu-items-container
;; TODO not implemented [menu-item {:name (label :t/profile)
)}] :handler #(dispatch [:navigate-to :my-profile])
[menu-item {:name (label :t/discovery) :platform-specific platform-specific}]
:handler #(dispatch [:navigate-to :discovery])}] [menu-item {:name (label :t/settings)
[menu-item {:name (label :t/contacts) :handler (fn []
:handler #(dispatch [:show-contacts navigator])}] ;; TODO not implemented
[menu-item {:name (label :t/invite-friends) )
:handler (fn [] :platform-specific platform-specific}]
;; TODO not implemented [menu-item {:name (label :t/discovery)
)}] :handler #(dispatch [:navigate-to :discovery])
[menu-item {:name (label :t/faq) :platform-specific platform-specific}]
:handler (fn [])}]] [menu-item {:name (label :t/contacts)
[view st/switch-users-container :handler #(dispatch [:show-contacts navigator])
[touchable-opacity {:onPress (fn [] :platform-specific platform-specific}]
(close-drawer) [menu-item {:name (label :t/invite-friends)
(dispatch [:navigate-to :accounts]) :handler (fn []
;; TODO not implemented ;; TODO not implemented
)} )
[text {:style st/switch-users-text} :platform-specific platform-specific}]
(label :t/switch-users)]]]]))) [menu-item {:name (label :t/faq)
:handler (fn [])
:platform-specific platform-specific}]]
[view st/switch-users-container
[touchable-opacity {:onPress (fn []
(close-drawer)
(dispatch [:navigate-to :accounts])
;; TODO not implemented
)}
[text {:style st/switch-users-text
:platform-specific platform-specific
:font :default}
(label :t/switch-users)]]]])
(defn drawer-view [items] (defn drawer-view [opts items]
[drawer-layout-android {:drawerWidth 260 [drawer-layout-android {:drawerWidth 260
:drawerPosition js/ReactNative.DrawerLayoutAndroid.positions.Left :drawerPosition js/ReactNative.DrawerLayoutAndroid.positions.Left
:render-navigation-view #(r/as-element [drawer-menu]) :render-navigation-view #(r/as-element [drawer-menu opts])
:ref (fn [drawer] :ref (fn [drawer]
(reset! drawer-atom drawer))} (reset! drawer-atom drawer))}
items]) items])

View File

@ -0,0 +1,8 @@
(ns status-im.components.icons.custom-icons
(:require [reagent.core :as r]))
(def ion-icon
(r/adapt-react-class (js/require "react-native-vector-icons/Ionicons")))
(def oct-icon
(r/adapt-react-class (js/require "react-native-vector-icons/Octicons")))

View File

@ -1,4 +0,0 @@
(ns status-im.components.icons.ionicons
(:require [reagent.core :as r]))
(def icon (r/adapt-react-class (js/require "react-native-vector-icons/Ionicons")))

View File

@ -10,6 +10,7 @@
image image
touchable-highlight touchable-highlight
get-dimensions]] get-dimensions]]
[status-im.components.status-bar :refer [status-bar]]
[status-im.components.drawer.view :refer [drawer-view]] [status-im.components.drawer.view :refer [drawer-view]]
[status-im.components.animation :as anim] [status-im.components.animation :as anim]
[status-im.chats-list.screen :refer [chats-list]] [status-im.chats-list.screen :refer [chats-list]]
@ -99,12 +100,15 @@
[tab-view-container view-id [tab-view-container view-id
[screen]]) [screen]])
(defview main-tabs [] (defview main-tabs [{platform-specific :platform-specific}]
[view-id [:get :view-id] [view-id [:get :view-id]
tab-animation? [:get :prev-tab-view-id]] tab-animation? [:get :prev-tab-view-id]]
[drawer-view [view common-st/flex
[view {:style common-st/flex [status-bar {:platform-specific platform-specific}]
:pointerEvents (if tab-animation? :none :auto)} [view common-st/flex
(doall (map #(tab-view %) tab-list)) [drawer-view {:platform-specific platform-specific}
[tabs {:selected-view-id view-id [view {:style common-st/flex
:tab-list tab-list}]]]) :pointerEvents (if tab-animation? :none :auto)}
(doall (map #(tab-view %) tab-list))
[tabs {:selected-view-id view-id
:tab-list tab-list}]]]]])

View File

@ -4,4 +4,6 @@
(def class (js/require "react-native-qrcode")) (def class (js/require "react-native-qrcode"))
(defn qr-code [props] (defn qr-code [props]
(r/create-element class (clj->js (merge {:inverted true} props)))) (r/create-element
class
(clj->js (merge {:inverted true} props))))

View File

@ -6,6 +6,7 @@
(def react-native (u/require "react-native")) (def react-native (u/require "react-native"))
(def native-modules (.-NativeModules react-native)) (def native-modules (.-NativeModules react-native))
(def geth (.-Geth native-modules)) (def geth (.-Geth native-modules))
(def react-native-dialogs (u/require "react-native-dialogs"))
(def linear-gradient-module (u/require "react-native-linear-gradient")) (def linear-gradient-module (u/require "react-native-linear-gradient"))
(def dismiss-keyboard! (u/require "dismissKeyboard")) (def dismiss-keyboard! (u/require "dismissKeyboard"))
@ -57,7 +58,6 @@
(def dimensions (.-Dimensions js/ReactNative)) (def dimensions (.-Dimensions js/ReactNative))
(def keyboard (.-Keyboard react-native)) (def keyboard (.-Keyboard react-native))
;; Accessor methods for React Components ;; Accessor methods for React Components
(defn text (defn text
@ -110,6 +110,33 @@
(vec (concat [linear-gradient-class (merge {:inverted true} props)] children))) (vec (concat [linear-gradient-class (merge {:inverted true} props)] children)))
;; List dialogs
(defn show-dialog [{:keys [title options callback]}]
(let [dialog (new react-native-dialogs)]
(.set dialog (clj->js {:title title
:items options
:itemsCallback callback}))
(.show dialog)))
(defn show-action-sheet [{:keys [options callback cancel-text]}]
(.showActionSheetWithOptions (get-class "ActionSheetIOS")
(clj->js {:options (conj options cancel-text)
:cancelButtonIndex (count options)})
callback))
;; Image picker
(def image-picker-class (u/require "react-native-image-crop-picker"))
(defn show-image-picker [images-fn]
(let [image-picker (.-default image-picker-class)]
(-> image-picker
(.openPicker (clj->js {:multiple false}))
(.then images-fn))))
;; Platform ;; Platform
(def platform (def platform

View File

@ -38,7 +38,7 @@
:alignItems :center :alignItems :center
:justifyContent :center} :justifyContent :center}
[image (:image nav-action)]]] [image (:image nav-action)]]]
[touchable-highlight {:on-press #(dispatch [:navigate-back]) [touchable-highlight {:on-press #(dispatch [:navigate-back])
:accessibility-label :navigate-back} :accessibility-label :navigate-back}
[view {:width 56 [view {:width 56
:height 56 :height 56

View File

@ -15,7 +15,7 @@
[status-im.components.status-bar :refer [status-bar]] [status-im.components.status-bar :refer [status-bar]]
[status-im.components.toolbar :refer [toolbar]] [status-im.components.toolbar :refer [toolbar]]
[status-im.components.drawer.view :refer [open-drawer]] [status-im.components.drawer.view :refer [open-drawer]]
[status-im.components.icons.ionicons :refer [icon]] [status-im.components.icons.custom-icons :refer [ion-icon]]
[status-im.components.styles :refer [color-blue [status-im.components.styles :refer [color-blue
hamburger-icon hamburger-icon
icon-search icon-search
@ -101,6 +101,6 @@
{:title (label :t/new-contact) {:title (label :t/new-contact)
:buttonColor :#9b59b6 :buttonColor :#9b59b6
:onPress #(dispatch [:navigate-to :new-contact])} :onPress #(dispatch [:navigate-to :new-contact])}
[icon {:name :md-create [ion-icon {:name :md-create
:style create-icon}]]]] :style create-icon}]]]]
[bottom-gradient]]))) [bottom-gradient]])))

View File

@ -10,7 +10,6 @@
[status-im.components.status-bar :refer [status-bar]] [status-im.components.status-bar :refer [status-bar]]
[status-im.components.toolbar :refer [toolbar]] [status-im.components.toolbar :refer [toolbar]]
[status-im.components.drawer.view :refer [drawer-view open-drawer]] [status-im.components.drawer.view :refer [drawer-view open-drawer]]
[status-im.components.icons.ionicons :refer [icon]]
[status-im.components.styles :refer [color-blue [status-im.components.styles :refer [color-blue
hamburger-icon hamburger-icon
icon-search icon-search
@ -39,7 +38,7 @@
(defview contact-list [{platform-specific :platform-specific}] (defview contact-list [{platform-specific :platform-specific}]
[contacts [:contacts-with-letters]] [contacts [:contacts-with-letters]]
[drawer-view [drawer-view {:platform-specific platform-specific}
[view st/contacts-list-container [view st/contacts-list-container
[contact-list-toolbar platform-specific] [contact-list-toolbar platform-specific]
;; todo what if there is no contacts, should we show some information ;; todo what if there is no contacts, should we show some information

View File

@ -11,9 +11,16 @@
;; initial state of app-db ;; initial state of app-db
(def app-db {:identity-password "replace-me-with-user-entered-password" (def app-db {:identity-password "replace-me-with-user-entered-password"
:identity "me" :identity "me"
:is-logged-in false
:accounts {} :accounts {}
:user-identity nil :current-account-id nil
:profile-edit {:edit? false
:name nil
:email nil
:status nil
:photo-path nil}
:contacts [] :contacts []
:contacts-ids #{} :contacts-ids #{}
:selected-contacts #{} :selected-contacts #{}
@ -27,12 +34,6 @@
:signed-up false :signed-up false
:view-id default-view :view-id default-view
:navigation-stack (list default-view) :navigation-stack (list default-view)
;; TODO fix hardcoded values
:photo-path nil
:username "My Name"
:phone-number "3147984309"
:email "myemail@gmail.com"
:status "Hi, this is my status"
:current-tag nil :current-tag nil
:qr-codes {} :qr-codes {}
:new-contact {:name "" :new-contact {:name ""
@ -42,7 +43,7 @@
:keyboard-height 0 :keyboard-height 0
:disable-group-creation false :disable-group-creation false
:animations {;; todo clear this :animations {;; todo clear this
:tabs-bar-value (anim/create-value 0)}}) :tabs-bar-value (anim/create-value 0)}})
(def protocol-initialized-path [:protocol-initialized]) (def protocol-initialized-path [:protocol-initialized])
(defn chat-input-text-path [chat-id] (defn chat-input-text-path [chat-id]

View File

@ -17,6 +17,7 @@
status-im.discovery.handlers status-im.discovery.handlers
status-im.new-group.handlers status-im.new-group.handlers
status-im.participants.handlers status-im.participants.handlers
status-im.profile.handlers
status-im.commands.handlers.loading status-im.commands.handlers.loading
status-im.commands.handlers.jail status-im.commands.handlers.jail
status-im.qr-scanner.handlers status-im.qr-scanner.handlers
@ -56,7 +57,7 @@
(register-handler :initialize-db (register-handler :initialize-db
(fn [_ _] (fn [_ _]
(realm/reset-account) (realm/reset-account)
(assoc app-db :user-identity nil))) (assoc app-db :current-account-id nil)))
(register-handler :initialize-account-db (register-handler :initialize-account-db
(fn [db _] (fn [db _]
@ -66,8 +67,8 @@
(register-handler :initialize-account (register-handler :initialize-account
(u/side-effect! (u/side-effect!
(fn [_ [_ account]] (fn [_ [_ address]]
(dispatch [:initialize-protocol account]) (dispatch [:initialize-protocol address])
(dispatch [:initialize-account-db]) (dispatch [:initialize-account-db])
(dispatch [:initialize-chats]) (dispatch [:initialize-chats])
(dispatch [:load-contacts]) (dispatch [:load-contacts])

View File

@ -5,7 +5,8 @@
(defn sign-up (defn sign-up
[db phone-number handler] [db phone-number handler]
(let [{:keys [public-key address] :as account} (get-in db [:user-identity])] (let [current-account-id (get db :current-account-id)
{:keys [public-key address]} (get-in db [:accounts current-account-id])]
;(user-data/save-phone-number phone-number) ;(user-data/save-phone-number phone-number)
(log/debug "signing up with public-key" public-key "and phone " phone-number) (log/debug "signing up with public-key" public-key "and phone " phone-number)
(http-post "sign-up" {:phone-number phone-number (http-post "sign-up" {:phone-number phone-number

View File

@ -6,7 +6,8 @@
[status-im.ios.styles :refer [styles]] [status-im.ios.styles :refer [styles]]
[status-im.components.react :refer [app-registry [status-im.components.react :refer [app-registry
keyboard keyboard
orientation]] orientation
show-action-sheet]]
[status-im.components.main-tabs :refer [main-tabs]] [status-im.components.main-tabs :refer [main-tabs]]
[status-im.contacts.views.contact-list :refer [contact-list]] [status-im.contacts.views.contact-list :refer [contact-list]]
[status-im.contacts.views.new-contact :refer [new-contact]] [status-im.contacts.views.new-contact :refer [new-contact]]
@ -22,6 +23,7 @@
[status-im.participants.views.remove :refer [remove-participants]] [status-im.participants.views.remove :refer [remove-participants]]
[status-im.group-settings.screen :refer [group-settings]] [status-im.group-settings.screen :refer [group-settings]]
[status-im.profile.screen :refer [profile my-profile]] [status-im.profile.screen :refer [profile my-profile]]
[status-im.profile.photo-capture.screen :refer [profile-photo-capture]]
[status-im.utils.utils :refer [toast]] [status-im.utils.utils :refer [toast]]
[status-im.utils.encryption] [status-im.utils.encryption]
status-im.persistence.realm.core status-im.persistence.realm.core
@ -34,9 +36,9 @@
(let [signed-up (subscribe [:get :signed-up]) (let [signed-up (subscribe [:get :signed-up])
_ (log/debug "signed up: " @signed-up) _ (log/debug "signed up: " @signed-up)
view-id (subscribe [:get :view-id]) view-id (subscribe [:get :view-id])
account (subscribe [:get :user-identity]) account-id (subscribe [:get :current-account-id])
keyboard-height (subscribe [:get :keyboard-height])] keyboard-height (subscribe [:get :keyboard-height])]
(log/debug "Current account: " @account) (log/debug "Current account: " @account-id)
(r/create-class (r/create-class
{:component-will-mount {:component-will-mount
(fn [] (fn []
@ -58,7 +60,7 @@
#(dispatch [:set :keyboard-height 0])))) #(dispatch [:set :keyboard-height 0]))))
:render :render
(fn [] (fn []
(let [startup-view (if @account (let [startup-view (if @account-id
(if @signed-up (if @signed-up
@view-id @view-id
:chat) :chat)
@ -80,10 +82,12 @@
:qr-scanner qr-scanner :qr-scanner qr-scanner
:chat chat :chat chat
:profile profile :profile profile
:profile-photo-capture profile-photo-capture
:accounts accounts :accounts accounts
:login login :login login
:my-profile my-profile)] :my-profile my-profile)]
[component {:platform-specific {:styles styles}}])))}))) [component {:platform-specific {:styles styles
:list-selection-fn show-action-sheet}}])))})))
(defn init [] (defn init []
(dispatch-sync [:reset-app]) (dispatch-sync [:reset-app])

View File

@ -2,21 +2,20 @@
(:require [status-im.persistence.realm.core :as r])) (:require [status-im.persistence.realm.core :as r]))
(defn get-accounts [] (defn get-accounts []
(-> (r/get-all :base :accounts) (-> (r/get-all :base :accounts)
r/collection->map)) r/collection->map))
(defn create-account [{:keys [address public-key] :as account}] (defn save-account [update?]
(->> account #(r/create :base :accounts % update?))
(r/create :base :accounts)))
(defn save-accounts [accounts] (defn save-accounts [accounts update?]
(r/write :base #(mapv create-account accounts))) (r/write :base #(mapv (save-account update?) accounts)))
;;;;;;;;;;;;;;;;;;;;---------------------------------------------- ;;;;;;;;;;;;;;;;;;;;----------------------------------------------
(defn accounts-list [] (defn accounts-list []
(r/get-all :base :accounts)) (r/get-all :base :accounts))
(defn account-by-address [address] (defn account-by-address [address]
(r/single-cljs (r/get-by-field :base :accounts :address address))) (r/single-cljs (r/get-by-field :base :accounts :address address)))

View File

@ -11,10 +11,10 @@
(defn set-initialized [db initialized?] (defn set-initialized [db initialized?]
(assoc-in db db/protocol-initialized-path initialized?)) (assoc-in db db/protocol-initialized-path initialized?))
(defn update-identity [db identity] (defn update-identity [db {:keys [address] :as identity}]
(let [identity-string (to-edn-string identity)] (let [identity-string (to-edn-string identity)]
(s/put kv/kv-store :identity identity-string) (s/put kv/kv-store :identity identity-string)
(assoc db :user-identity identity))) (assoc-in db [:accounts address] identity)))
(defn stored-identity [db] (defn stored-identity [db]
(let [identity (s/get kv/kv-store :identity)] (let [identity (s/get kv/kv-store :identity)]

View File

@ -81,6 +81,12 @@
(register-handler :show-profile show-profile) (register-handler :show-profile show-profile)
(defn show-profile-photo-capture
[db [_ image-captured-fn]]
(push-view db :profile-photo-capture))
(register-handler :show-profile-photo-capture show-profile-photo-capture)
(defn navigate-to-clean (defn navigate-to-clean
[db [_ view-id]] [db [_ view-id]]
(-> db (-> db

View File

@ -1,32 +1,35 @@
(ns status-im.persistence.realm.schemas (ns status-im.persistence.realm.schemas
(:require [status-im.components.styles :refer [default-chat-color]])) (:require [status-im.components.styles :refer [default-chat-color]]))
(def base {:schema [{:name :accounts (def base {:schema [{:name :accounts
:primaryKey :address :primaryKey :address
:properties {:address "string" :properties {:address "string"
:public-key "string" :public-key "string"
:name "string" :name "string"
:photo-path "string"}} :phone {:type "string" :optional true}
{:name :tag :email {:type "string" :optional true}
:primaryKey :name :status {:type "string" :optional true}
:properties {:name "string" :photo-path "string"}}
:count {:type "int" {:name :tag
:optional true :primaryKey :name
:default 0}}} :properties {:name "string"
{:name :discoveries :count {:type "int"
:primaryKey :whisper-id :optional true
:properties {:name "string" :default 0}}}
:status "string" {:name :discoveries
:whisper-id "string" :primaryKey :whisper-id
:photo "string" :properties {:name "string"
:location "string" :status "string"
:tags {:type "list" :whisper-id "string"
:objectType "tag"} :photo "string"
:last-updated "date"}} :location "string"
{:name :kv-store :tags {:type "list"
:primaryKey :key :objectType "tag"}
:properties {:key "string" :last-updated "date"}}
:value "string"}}] {:name :kv-store
:primaryKey :key
:properties {:key "string"
:value "string"}}]
:schemaVersion 0}) :schemaVersion 0})
(def account {:schema [{:name :contacts (def account {:schema [{:name :contacts

View File

@ -0,0 +1,33 @@
(ns status-im.profile.handlers
(:require [re-frame.core :refer [subscribe dispatch]]
[status-im.utils.handlers :refer [register-handler]]
[status-im.components.react :refer [show-image-picker]]
[status-im.utils.image-processing :refer [img->base64]]
[status-im.i18n :refer [label]]
[status-im.utils.handlers :as u]))
(register-handler :open-image-picker
(u/side-effect!
(fn [_ _]
(show-image-picker
(fn [image]
(let [path (-> (js->clj image)
(get "path")
(subs 7))
on-success (fn [base64]
(dispatch [:set-in [:profile-edit :photo-path] (str "data:image/jpeg;base64," base64)]))
on-error (fn [type error]
(.log js/console type error))]
(img->base64 path on-success on-error)))))))
(register-handler :open-image-source-selector
(u/side-effect!
(fn [_ [_ list-selection-fn]]
(list-selection-fn {:title (label :t/image-source-title)
:options [(label :t/image-source-make-photo) (label :t/image-source-gallery)]
:callback (fn [index]
(case index
0 (dispatch [:show-profile-photo-capture])
1 (dispatch [:open-image-picker])
:default))
:cancel-text (label :t/image-source-cancel)}))))

View File

@ -0,0 +1,53 @@
(ns status-im.profile.photo-capture.screen
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
[clojure.walk :refer [keywordize-keys]]
[status-im.components.react :refer [view
image
touchable-highlight]]
[status-im.components.camera :refer [camera
aspects
capture-targets]]
[status-im.components.styles :refer [toolbar-background1
icon-search
icon-back]]
[status-im.components.icons.custom-icons :refer [ion-icon]]
[status-im.components.status-bar :refer [status-bar]]
[status-im.components.toolbar :refer [toolbar]]
[status-im.utils.image-processing :refer [img->base64]]
[status-im.profile.photo-capture.styles :as st]
[status-im.i18n :refer [label]]
[reagent.core :as r]))
(defn image-captured [path]
(let [path (subs path 5)
on-success (fn [base64]
(dispatch [:set-in [:profile-edit :photo-path] (str "data:image/jpeg;base64," base64)])
(dispatch [:navigate-back]))
on-error (fn [type error]
(.log js/console type error))]
(img->base64 path on-success on-error)))
(defn profile-photo-capture [{platform-specific :platform-specific}]
(let [camera-ref (r/atom nil)]
[view st/container
[status-bar {:platform-specific platform-specific}]
[toolbar {:title (label :t/image-source-title)
:nav-action {:image {:source {:uri :icon_back}
:style icon-back}
:handler #(dispatch [:navigate-back])}
:background-color toolbar-background1}]
[camera {:style {:flex 1}
:aspect (:fill aspects)
:captureTarget (:disk capture-targets)
:type "front"
:ref #(reset! camera-ref %)}]
[view {:style {:padding 10
:background-color toolbar-background1}}
[touchable-highlight {:style {:align-self "center"}
:on-press (fn []
(let [camera @camera-ref]
(-> (.capture camera)
(.then image-captured))))}
[view
[ion-icon {:name :md-camera
:style {:font-size 36}}]]]]]))

View File

@ -0,0 +1,5 @@
(ns status-im.profile.photo-capture.styles)
(def container
{:flex 1
:background-color :white})

View File

@ -1,30 +1,127 @@
(ns status-im.profile.screen (ns status-im.profile.screen
(:require-macros [status-im.utils.views :refer [defview]]) (:require-macros [status-im.utils.views :refer [defview]])
(:require [re-frame.core :refer [subscribe dispatch]] (:require [reagent.core :as r]
[re-frame.core :refer [subscribe dispatch]]
[status-im.components.react :refer [view [status-im.components.react :refer [view
text text
text-input
image image
icon icon
scroll-view scroll-view
touchable-highlight touchable-highlight
touchable-opacity]] touchable-opacity
show-image-picker]]
[status-im.components.icons.custom-icons :refer [oct-icon]]
[status-im.components.chat-icon.screen :refer [profile-icon [status-im.components.chat-icon.screen :refer [profile-icon
my-profile-icon]] my-profile-icon]]
[status-im.components.status-bar :refer [status-bar]]
[status-im.profile.styles :as st] [status-im.profile.styles :as st]
[status-im.components.qr-code :refer [qr-code]] [status-im.components.qr-code :refer [qr-code]]
[status-im.utils.phone-number :refer [format-phone-number
valid-mobile-number?]]
[status-im.utils.fs :refer [read-file]]
[status-im.utils.types :refer [clj->json]] [status-im.utils.types :refer [clj->json]]
[status-im.i18n :refer [label]])) [status-im.utils.image-processing :refer [img->base64]]
[status-im.i18n :refer [label]]
[clojure.string :as str]))
(defn profile-property-view [{:keys [name value]}] (defn- get-hashtags [status]
[view st/profile-property-view-container (let [hashtags (map #(subs % 1) (re-seq #"#[^ !?,;:.]+" status))]
[view st/profile-property-view-sub-container (or hashtags [])))
[text {:style st/profile-property-view-label} name]
[text {:style st/profile-property-view-value} value]]])
(defn message-user [identity] (defn- message-user [identity]
(when identity (when identity
(dispatch [:navigate-to :chat identity]))) (dispatch [:navigate-to :chat identity])))
(defn- update-profile [{name :name
email :email
photo-path :photo-path
status :status}
{new-name :name
new-email :email
new-status :status
new-photo-path :photo-path}]
(let [new-name (if (or (not new-name) (str/blank? new-name)) name new-name)
status-updated? (and (not= new-status nil)
(not= status new-status))]
(when status-updated?
(dispatch [:broadcast-status new-status (get-hashtags new-status)]))
(dispatch [:account-update {:name new-name
:email (or new-email email)
:status (or new-status status)
:photo-path (or new-photo-path photo-path)}])))
(defview toolbar [{:keys [account profile-edit-data edit?]}]
[view
[touchable-highlight {:style st/back-btn-touchable
:on-press (fn []
(dispatch [:set :profile-edit {:edit? false
:name nil
:email nil
:status nil
:photo-path nil}])
(dispatch [:navigate-back]))}
[view st/back-btn-container
[icon :back st/back-btn-icon]]]
[touchable-highlight {:style st/actions-btn-touchable
:on-press (fn []
(when edit?
(update-profile account profile-edit-data))
(dispatch [:set-in [:profile-edit :edit?] (not edit?)]))}
[view st/actions-btn-container
(if edit?
[oct-icon {:name :check
:style st/ok-btn-icon}]
[icon :dots st/edit-btn-icon])]]])
(defview status-image-view [{{:keys [list-selection-fn]} :platform-specific
{address :address
username :name} :account
photo-path :photo-path
status :status
edit? :edit?}]
[view st/status-block
[view st/user-photo-container
(if edit?
[touchable-highlight {:on-press (fn []
(dispatch [:open-image-source-selector list-selection-fn]))}
[view
[my-profile-icon {:account {:photo-path photo-path
:name username}
:edit? edit?}]]]
[my-profile-icon {:account {:photo-path photo-path
:name username}
:edit? edit?}])]
[text {:style st/username
:platform-specific platform-specific
:font :default}
(if (= username address)
(label :t/user-anonymous)
username)]
[text-input {:style st/status-input
:editable edit?
:placeholder (label :t/profile-no-status)
:on-change-text #(dispatch [:set-in [:profile-edit :status] %])}
status]])
(defview profile-property-view [{name :name
value :value
empty-value :empty-value
on-change-text :on-change-text
{edit-mode? :edit?} :profile-data
platform-specific :platform-specific}]
[view st/profile-property-view-container
[view st/profile-property-view-sub-container
[text {:style st/profile-property-view-label
:platform-specific platform-specific
:font :medium}
name]
[text-input {:style st/profile-property-view-value
:editable (and on-change-text edit-mode?)
:on-change-text on-change-text}
(or value (when-not edit-mode? empty-value))]]])
(defview profile [] (defview profile []
[{:keys [name whisper-identity phone-number]} [:contact]] [{:keys [name whisper-identity phone-number]} [:contact]]
[scroll-view {:style st/profile} [scroll-view {:style st/profile}
@ -35,9 +132,9 @@
[view st/status-block [view st/status-block
[view st/user-photo-container [view st/user-photo-container
[profile-icon]] [profile-icon]]
[text {:style st/user-name} name] [text {:style st/username} name]
;; TODO stub data ;; TODO stub data
[text {:style st/status} (label :t/not-implemented)] [text {:style st/status-input} (label :t/not-implemented)]
[view st/btns-container [view st/btns-container
[touchable-highlight {:onPress #(message-user whisper-identity)} [touchable-highlight {:onPress #(message-user whisper-identity)}
[view st/message-btn [view st/message-btn
@ -61,37 +158,53 @@
)} )}
[view [text {:style st/report-user-text} (label :t/report-user)]]]]]]) [view [text {:style st/report-user-text} (label :t/report-user)]]]]]])
(defview my-profile [_] (defview my-profile [{platform-specific :platform-specific}]
[username [:get :username] [{public-key :public-key
photo-path [:get :photo-path] address :address
phone-number [:get :phone-number] username :name
email [:get :email] email :email
status [:get :status] photo-path :photo-path
identity [:get-in [:user-identity :public-key]]] phone :phone
status :status
:as account} [:get-current-account]
{edit? :edit?
new-status :status
new-photo-path :photo-path
:as profile-edit-data} [:get :profile-edit]]
[scroll-view {:style st/profile} [scroll-view {:style st/profile}
[touchable-highlight {:style st/back-btn-touchable [status-bar {:platform-specific platform-specific}]
:on-press #(dispatch [:navigate-back])} [toolbar {:account account
[view st/back-btn-container :profile-edit-data profile-edit-data
[icon :back st/back-btn-icon]]] :edit? edit?}]
[touchable-highlight {:style st/actions-btn-touchable
:on-press (fn [] [status-image-view {:platform-specific platform-specific
;; TODO not implemented :account account
)} :photo-path (or new-photo-path photo-path)
[view st/actions-btn-container :status (if (and new-status (not (str/blank? new-status))) new-status status)
[icon :dots st/actions-btn-icon]]] :edit? edit?}]
[view st/status-block
[view st/user-photo-container
[my-profile-icon]]
[text {:style st/user-name} username]
[text {:style st/status} status]]
[scroll-view st/profile-properties-container [scroll-view st/profile-properties-container
[profile-property-view {:name (label :t/username) [profile-property-view {:name (label :t/username)
:value username}] :value (if (not= username address)
[profile-property-view {:name (label :t/phone-number) username)
:value phone-number}] :empty-value (label :t/not-specified)
[profile-property-view {:name (label :t/email) :on-change-text #(dispatch [:set-in [:profile-edit :name] %])
:value email}] :profile-data profile-edit-data
:platform-specific platform-specific}]
[profile-property-view {:name (label :t/phone-number)
:value (if-not (or (not phone) (str/blank? phone))
(format-phone-number phone))
:empty-value (label :t/not-specified)
:profile-data profile-edit-data
:platform-specific platform-specific}]
[profile-property-view {:name (label :t/email)
:value (if-not (or (not email) (str/blank? email))
email)
:empty-value (label :t/not-specified)
:on-change-text #(dispatch [:set-in [:profile-edit :email] %])
:profile-data profile-edit-data
:platform-specific platform-specific}]
[view st/qr-code-container [view st/qr-code-container
[qr-code {:value (clj->json {:name username [qr-code {:value (clj->js {:name username
:whisper-identity identity}) :whisper-identity public-key})
:size 200}]]]]) :size 150}]]]])

View File

@ -1,41 +1,20 @@
(ns status-im.profile.styles (ns status-im.profile.styles
(:require [status-im.components.styles :refer [font (:require [status-im.components.styles :refer [font
color-light-blue-transparent color-light-blue-transparent
color-white color-white
color-black color-black
color-blue color-blue
color-blue-transparent color-blue-transparent
selected-message-color selected-message-color
online-color online-color
separator-color separator-color
text1-color text1-color
text2-color]])) text2-color]]))
(def profile-property-view-container
{:height 85
:paddingHorizontal 16})
(def profile-property-view-sub-container
{:borderBottomWidth 1
:borderBottomColor separator-color})
(def profile-property-view-label
{:marginTop 16
:fontSize 14
:fontFamily font
:color text2-color})
(def profile-property-view-value
{:marginTop 11
:height 40
:fontSize 16
:fontFamily font
:color text1-color})
(def profile (def profile
{:flex 1 {:flex 1
:backgroundColor color-white :background-color color-white
:flexDirection :column}) :flex-direction :column})
(def back-btn-touchable (def back-btn-touchable
{:position :absolute}) {:position :absolute})
@ -45,98 +24,133 @@
:height 56}) :height 56})
(def back-btn-icon (def back-btn-icon
{:marginTop 21 {:margin-top 21
:marginLeft 23 :margin-left 23
:width 8 :width 8
:height 14}) :height 14})
(def actions-btn-touchable (def actions-btn-touchable
{:position :absolute {:position :absolute
:right 0}) :right 0})
(def actions-btn-container (def actions-btn-container
{:width 56 {:width 56
:height 56 :height 56
:alignItems :center :align-items :center
:justifyContent :center}) :justify-content :center})
(def actions-btn-icon (def edit-btn-icon
{:width 4 {:width 4
:height 16}) :height 16})
(def status-block (def ok-btn-icon
{:alignSelf :center {:font-size 22
:alignItems :center :color :black})
:width 249})
(def user-photo-container (def user-photo-container
{:marginTop 22}) {:margin-top 22})
(def user-name (def username
{:marginTop 16 {:margin-top 12
:fontSize 18 :font-size 18
:fontFamily font
:color text1-color}) :color text1-color})
(def status (def username-input
{:marginTop 10 {:align-self "stretch"
:fontFamily font :margin-top -8
:fontSize 14 :margin-bottom -22
:lineHeight 20 :font-size 18
:textAlign :center :text-align :center
:color text2-color}) :color text1-color})
(def status-block
{:flex-direction "column"
:align-items "center"
:justifyContent "center"})
(def status-input
{:align-self "stretch"
:margin-left 16
:margin-right 16
:height 40
:margin-top -4
:font-size 14
:line-height 20
:text-align :center
:color text2-color})
(def btns-container (def btns-container
{:marginTop 18 {:margin-top 18
:flexDirection :row}) :flex-direction :row})
(def message-btn (def message-btn
{:height 40 {:height 40
:justifyContent :center :justify-content :center
:backgroundColor color-blue :background-color color-blue
:paddingLeft 25 :padding-left 25
:paddingRight 25 :padding-right 25
:borderRadius 20}) :border-radius 20})
(def message-btn-text (def message-btn-text
{:marginTop -2.5 {:margin-top -2.5
:fontSize 14 :font-size 14
:fontFamily font :font-family font
:color color-white}) :color color-white})
(def more-btn (def more-btn
{:marginLeft 10 {:margin-left 10
:width 40 :width 40
:height 40 :height 40
:alignItems :center :align-items :center
:justifyContent :center :justify-content :center
:backgroundColor color-blue-transparent :background-color color-blue-transparent
:padding 8 :padding 8
:borderRadius 20}) :border-radius 20})
(def more-btn-image (def more-btn-image
{:width 4 {:width 4
:height 16}) :height 16})
(def profile-properties-container (def profile-properties-container
{:marginTop 20 {:margin-top 20
:alignItems :stretch :align-items :stretch
:flexDirection :column}) :flex-firection :column})
(def profile-property-view-container
{:padding-left 16})
(def profile-property-view-sub-container
{:border-bottom-width 1
:border-bottom-color separator-color
:padding-right 16})
(def profile-property-view-label
{:margin-top 18
:font-size 14
:color text2-color})
(def profile-property-view-value
{:margin-top 8
:margin-bottom 8
:padding 0
:height 40
:font-size 16
:color text1-color})
(def report-user-container (def report-user-container
{:marginTop 50 {:margin-top 50
:marginBottom 43 :margin-bottom 43
:alignItems :center}) :align-items :center})
(def report-user-text (def report-user-text
{:fontSize 14 {:font-size 14
:fontFamily font :font-family font
:lineHeight 21 :line-height 21
:color text2-color :color text2-color
;; IOS: ;; IOS:
:letterSpacing 0.5}) :letter-spacing 0.5})
(def qr-code-container (def qr-code-container
{:flex 1 {:flex 1
:alignItems :center :alignItems :center
:margin 15}) :margin 32})

View File

@ -18,8 +18,9 @@
(register-handler :initialize-protocol (register-handler :initialize-protocol
(u/side-effect! (u/side-effect!
(fn [{:keys [user-identity] :as db} [_ account]] (fn [db [_ current-account-id]]
(init-protocol (or account user-identity) (make-handler db))))) (let [current-account (get-in db [:accounts current-account-id])]
(init-protocol current-account (make-handler db))))))
(register-handler :protocol-initialized (register-handler :protocol-initialized
(fn [db [_ identity]] (fn [db [_ identity]]

View File

@ -6,7 +6,6 @@
image image
touchable-highlight]] touchable-highlight]]
[status-im.components.toolbar :refer [toolbar]] [status-im.components.toolbar :refer [toolbar]]
[status-im.components.drawer.view :refer [drawer-view open-drawer]]
[status-im.components.styles :refer [icon-qr]] [status-im.components.styles :refer [icon-qr]]
[status-im.i18n :refer [label]] [status-im.i18n :refer [label]]
[status-im.qr-scanner.styles :as st])) [status-im.qr-scanner.styles :as st]))

View File

@ -6,7 +6,6 @@
image image
touchable-highlight]] touchable-highlight]]
[status-im.components.toolbar :refer [toolbar]] [status-im.components.toolbar :refer [toolbar]]
[status-im.components.drawer.view :refer [drawer-view open-drawer]]
[status-im.components.styles :refer [icon-scan]] [status-im.components.styles :refer [icon-scan]]
[status-im.i18n :refer [label]] [status-im.i18n :refer [label]]
[status-im.qr-scanner.styles :as st])) [status-im.qr-scanner.styles :as st]))

View File

@ -12,6 +12,11 @@
(fn [db [_ k]] (fn [db [_ k]]
(reaction (k @db)))) (reaction (k @db))))
(register-sub :get-current-account
(fn [db [_ _]]
(reaction (let [current-account-id (:current-account-id @db)]
(get-in @db [:accounts current-account-id])))))
(register-sub :get-in (register-sub :get-in
(fn [db [_ path]] (fn [db [_ path]]
(reaction (get-in @db path)))) (reaction (get-in @db path))))

View File

@ -27,8 +27,17 @@
:report-user "REPORT USER" :report-user "REPORT USER"
:message "Message" :message "Message"
:username "Username" :username "Username"
:user-anonymous "Anonymous"
:not-specified "Not specified"
:phone-number "Phone number" :phone-number "Phone number"
:email "Email" :email "Email"
:profile-no-status "No status"
;;make_photo
:image-source-title "Profile image"
:image-source-make-photo "Capture"
:image-source-gallery "Select from gallery"
:image-source-cancel "Cancel"
;sign-up ;sign-up
:contacts-syncronized "Your contacts have been synchronized" :contacts-syncronized "Your contacts have been synchronized"

View File

@ -8,4 +8,9 @@
(let [result (.moveFile fs src dst) (let [result (.moveFile fs src dst)
result (.then result #(handler nil %)) result (.then result #(handler nil %))
result (.catch result #(handler % nil))] result (.catch result #(handler % nil))]
result)) result))
(defn read-file [path encoding on-read on-error]
(-> (.readFile fs path encoding)
(.then on-read)
(.catch on-error)))

View File

@ -0,0 +1,25 @@
(ns status-im.utils.image-processing
(:require [reagent.core :as r]
[status-im.utils.fs :refer [read-file]]))
(def resizer-class (js/require "react-native-image-resizer"))
(defn- resize [path max-width max-height on-resize on-error]
(let [resize-fn (aget resizer-class "default" "createResizedImage")]
(-> (resize-fn path max-width max-height "JPEG" 75 0 nil)
(.then on-resize)
(.catch on-error))))
(defn- image-base64-encode [path on-success on-error]
(let [on-encoded (fn [data]
(on-success data))
on-error (fn [error]
(on-error :base64 error))]
(read-file path "base64" on-encoded on-error)))
(defn img->base64 [path on-success on-error]
(let [on-resized (fn [path]
(image-base64-encode (subs path 5) on-success on-error))
on-error (fn [error]
(on-error :resize error))]
(resize path 150 150 on-resized on-error)))