Merge pull request #185 from status-im/feature/profile-screen
Editable profile screen
Former-commit-id: 05798fc552
This commit is contained in:
commit
8f39f113fa
|
@ -11,6 +11,7 @@
|
|||
"realm/react-native",
|
||||
"react-native-action-button",
|
||||
"react-native-vector-icons/Ionicons",
|
||||
"react-native-vector-icons/Octicons",
|
||||
"react-native-circle-checkbox",
|
||||
"react-native-randombytes",
|
||||
"dismissKeyboard",
|
||||
|
@ -21,7 +22,10 @@
|
|||
"react-native-qrcode",
|
||||
"react-native-orientation",
|
||||
"identicon.js",
|
||||
"react-native-fs"
|
||||
"react-native-fs",
|
||||
"react-native-dialogs",
|
||||
"react-native-image-resizer",
|
||||
"react-native-image-crop-picker"
|
||||
],
|
||||
"imageDirs": [
|
||||
"images"
|
||||
|
|
|
@ -82,7 +82,7 @@ android {
|
|||
|
||||
defaultConfig {
|
||||
applicationId "com.statusim"
|
||||
minSdkVersion 16
|
||||
minSdkVersion 18
|
||||
targetSdkVersion 22
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
@ -120,6 +120,8 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
compile project(':react-native-image-resizer')
|
||||
compile project(':react-native-dialogs')
|
||||
compile project(':react-native-randombytes')
|
||||
compile project(':react-native-android-sms-listener')
|
||||
compile project(':realm')
|
||||
|
@ -134,6 +136,7 @@ dependencies {
|
|||
compile project(':react-native-status')
|
||||
compile project(':react-native-orientation')
|
||||
compile project(':react-native-fs')
|
||||
compile project(':react-native-image-crop-picker')
|
||||
//compile(name:'statusgo-android-16', ext:'aar')
|
||||
compile(group: 'status-im', name: 'status-go', version: '0.1.0-201607011545-da53ec', ext: 'aar')
|
||||
|
||||
|
|
|
@ -19,6 +19,9 @@ import com.centaurwarchief.smslistener.SmsListenerPackage;
|
|||
import com.github.yamill.orientation.OrientationPackage;
|
||||
import com.rnfs.RNFSPackage;
|
||||
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.List;
|
||||
|
@ -46,7 +49,10 @@ public class MainApplication extends Application implements ReactApplication {
|
|||
new SmsListenerPackage(),
|
||||
new OrientationPackage(),
|
||||
new RNFSPackage(),
|
||||
new GethPackage()
|
||||
new GethPackage(),
|
||||
new ReactNativeDialogsPackage(),
|
||||
new ImageResizerPackage(),
|
||||
new PickerPackage()
|
||||
);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
<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_okay">Continue</string>
|
||||
|
|
|
@ -16,16 +16,10 @@ allprojects {
|
|||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
maven {
|
||||
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
|
||||
url "$rootDir/../node_modules/react-native/android"
|
||||
}
|
||||
maven { url "$rootDir/../node_modules/react-native/android" }
|
||||
// for geth
|
||||
flatDir {
|
||||
dirs 'libs'
|
||||
}
|
||||
maven {
|
||||
url "http://185.90.37.89:8081/artifactory/libs-release-local"
|
||||
}
|
||||
flatDir { dirs 'libs' }
|
||||
maven { url "http://185.90.37.89:8081/artifactory/libs-release-local" }
|
||||
maven { url "https://jitpack.io" }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
rootProject.name = 'StatusIm'
|
||||
|
||||
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'
|
||||
project(':react-native-randombytes').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-randombytes/android')
|
||||
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')
|
||||
include ':react-native-fs'
|
||||
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')
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.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 */; };
|
||||
EF2B5857B4A34E0C9707FB3F /* Octicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = B3B19223008342D096AA356E /* Octicons.ttf */; };
|
||||
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 */
|
||||
|
||||
/* 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>"; };
|
||||
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>"; };
|
||||
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 */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
@ -323,6 +325,7 @@
|
|||
BA68A2377A20496EA737000D /* libz.tbd in Frameworks */,
|
||||
3E15DFEC1F6F4D7CAE088F49 /* libTcpSockets.a in Frameworks */,
|
||||
AD5063BC2B2A4C52ACE0A0B4 /* libUdpSockets.a in Frameworks */,
|
||||
E0AD9E8F495A4907B65104BF /* libRCTImageResizer.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -581,6 +584,7 @@
|
|||
38E1A2C8D0734EE99E2B16CE /* TcpSockets.xcodeproj */,
|
||||
2F0276A9E90843E996A0E762 /* UdpSockets.xcodeproj */,
|
||||
439B6B4B407A4E2AACAFE5BE /* RCTJail.xcodeproj */,
|
||||
5E5A7625B76441D984EA8C0D /* RCTImageResizer.xcodeproj */,
|
||||
);
|
||||
name = Libraries;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1074,6 +1078,7 @@
|
|||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
);
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/StatusIm.app/StatusIm";
|
||||
|
@ -1107,6 +1112,7 @@
|
|||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
"\"$(SRCROOT)/$(TARGET_NAME)\"",
|
||||
);
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/StatusIm.app/StatusIm";
|
||||
|
@ -1140,6 +1146,7 @@
|
|||
"$(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-image-resizer/ios/RCTImageResizer",
|
||||
);
|
||||
INFOPLIST_FILE = StatusIm/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
|
@ -1180,6 +1187,7 @@
|
|||
"$(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-image-resizer/ios/RCTImageResizer",
|
||||
);
|
||||
INFOPLIST_FILE = StatusIm/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
|
@ -1244,6 +1252,7 @@
|
|||
"$(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-image-resizer/ios/RCTImageResizer",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
|
@ -1297,6 +1306,7 @@
|
|||
"$(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-image-resizer/ios/RCTImageResizer",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
|
|
|
@ -34,9 +34,12 @@
|
|||
"react-native-circle-checkbox": "github:paramoshkinandrew/ReactNativeCircleCheckbox",
|
||||
"react-native-contacts": "^0.2.4",
|
||||
"react-native-crypto": "^2.0.1",
|
||||
"react-native-dialogs": "0.0.16",
|
||||
"react-native-fs": "^1.5.1",
|
||||
"react-native-http": "github:tradle/react-native-http#834492d",
|
||||
"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-level-fs": "^2.0.1",
|
||||
"react-native-linear-gradient": "1.5.7",
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
[re-frame "0.7.0"]
|
||||
[prismatic/schema "1.0.4"]
|
||||
^{:voom {:repo "git@github.com:status-im/status-lib.git"
|
||||
:branch "master"}}
|
||||
:branch "discover-rework"}}
|
||||
[status-im/protocol "0.1.1-20160706_085008-ge61756a"]
|
||||
[natal-shell "0.3.0"]
|
||||
[com.andrewmcveigh/cljs-time "0.4.0"]]
|
||||
|
|
|
@ -17,9 +17,10 @@
|
|||
|
||||
|
||||
(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}]]
|
||||
(update db :accounts assoc address account))
|
||||
((after save-account))))
|
||||
|
@ -34,39 +35,46 @@
|
|||
account {:public-key public-key
|
||||
:address address
|
||||
:name address
|
||||
:photo-path (identicon address)}
|
||||
]
|
||||
:photo-path (identicon address)}]
|
||||
(log/debug "account-created: " account)
|
||||
(when (not (str/blank? public-key))
|
||||
(do
|
||||
;(save-password password)
|
||||
(dispatch-sync [:add-account account])
|
||||
(dispatch [:login-account address password])))))
|
||||
|
||||
(register-handler :create-account
|
||||
(-> (fn [db [_ password]]
|
||||
(register-handler
|
||||
:create-account
|
||||
(fn [db [_ password]]
|
||||
(geth/create-account password (fn [result] (account-created db result password)))
|
||||
db)))
|
||||
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)]
|
||||
(dispatch [:set :login {}])
|
||||
(dispatch [:set :is-logged-in true])
|
||||
(dispatch [:set :user-identity account])
|
||||
(dispatch [:initialize-account account])
|
||||
(dispatch [:set :current-account-id address])
|
||||
(dispatch [:initialize-account address])
|
||||
(when is-login-screen? (dispatch [:navigate-to-clean default-view]))))
|
||||
|
||||
(defn logged-in [db address]
|
||||
(let [account (get-in db [:accounts address])
|
||||
is-login-screen? (= (:view-id db) :login)
|
||||
(let [is-login-screen? (= (:view-id db) :login)
|
||||
new-account? (not is-login-screen?)]
|
||||
(log/debug "Logged in: " address account)
|
||||
(log/debug "Logged in: " address)
|
||||
(realm/change-account-realm address new-account?
|
||||
#(if (nil? %)
|
||||
(initialize-account db account)
|
||||
(initialize-account db address)
|
||||
(log/debug "Error changing acount realm: " %)))))
|
||||
|
||||
(register-handler :login-account
|
||||
(register-handler
|
||||
:login-account
|
||||
(-> (fn [db [_ address password]]
|
||||
(geth/login address password (fn [result]
|
||||
(let [data (json->clj result)
|
||||
|
|
|
@ -59,7 +59,8 @@
|
|||
(dispatch [:set-in [:login :error] ""]))}]])
|
||||
|
||||
(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
|
||||
[linear-gradient {:colors ["rgba(182, 116, 241, 1)" "rgba(107, 147, 231, 1)" "rgba(43, 171, 238, 1)"]
|
||||
:start [0, 0]
|
||||
|
@ -79,7 +80,6 @@
|
|||
[view st/form-container-inner
|
||||
[address-input (or address "")]
|
||||
[password-input error]]]
|
||||
(let [keyboard-height @(subscribe [:get :keyboard-height])]
|
||||
[view st/bottom-actions-container
|
||||
(when (= keyboard-height 0)
|
||||
[view st/recover-button-container
|
||||
|
@ -95,4 +95,4 @@
|
|||
[view st/connect-button
|
||||
[text {:style st/connect-button-text
|
||||
:platform-specific platform-specific}
|
||||
(label :t/connect)]]]]])])
|
||||
(label :t/connect)]]]]]])
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
(dispatch [:set-in [:login :address] address]))
|
||||
|
||||
(defview account-view [{:keys [address photo-path name] :as account}]
|
||||
[current-account [:get :user-identity]]
|
||||
[current-account [:get-current-account]]
|
||||
[touchable-highlight
|
||||
{:onPress #(on-press address)}
|
||||
[view st/account-container
|
||||
|
|
|
@ -8,7 +8,8 @@
|
|||
[status-im.android.styles :refer [styles]]
|
||||
[status-im.components.react :refer [app-registry
|
||||
keyboard
|
||||
orientation]]
|
||||
orientation
|
||||
show-dialog]]
|
||||
[status-im.components.main-tabs :refer [main-tabs]]
|
||||
[status-im.contacts.views.contact-list :refer [contact-list]]
|
||||
[status-im.contacts.views.new-contact :refer [new-contact]]
|
||||
|
@ -24,6 +25,7 @@
|
|||
[status-im.participants.views.remove :refer [remove-participants]]
|
||||
[status-im.group-settings.screen :refer [group-settings]]
|
||||
[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.encryption]
|
||||
status-im.persistence.realm.core
|
||||
|
@ -48,9 +50,9 @@
|
|||
(let [signed-up (subscribe [:get :signed-up])
|
||||
_ (log/debug "signed up: " @signed-up)
|
||||
view-id (subscribe [:get :view-id])
|
||||
account (subscribe [:get :user-identity])
|
||||
account-id (subscribe [:get :current-account-id])
|
||||
keyboard-height (subscribe [:get :keyboard-height])]
|
||||
(log/debug "Current account: " @account)
|
||||
(log/debug "Current account: " @account-id)
|
||||
(r/create-class
|
||||
{:component-will-mount
|
||||
(fn []
|
||||
|
@ -72,7 +74,7 @@
|
|||
(dispatch [:set :keyboard-height 0]))))
|
||||
:render
|
||||
(fn []
|
||||
(let [startup-view (if @account
|
||||
(let [startup-view (if @account-id
|
||||
(if @signed-up
|
||||
@view-id
|
||||
:chat)
|
||||
|
@ -94,10 +96,12 @@
|
|||
:qr-scanner qr-scanner
|
||||
:chat chat
|
||||
:profile profile
|
||||
:profile-photo-capture profile-photo-capture
|
||||
:accounts accounts
|
||||
:login login
|
||||
:my-profile my-profile)]
|
||||
[component {:platform-specific {:styles styles}}])))})))
|
||||
[component {:platform-specific {:styles styles
|
||||
:list-selection-fn show-dialog}}])))})))
|
||||
|
||||
(defn init [& [env]]
|
||||
(dispatch-sync [:reset-app])
|
||||
|
|
|
@ -310,8 +310,9 @@
|
|||
(assoc db :password-saved true)))
|
||||
|
||||
(register-handler :sign-up
|
||||
(after (fn [_ [_ phone-number]]
|
||||
(dispatch [:account-update {:phone phone-number}])))
|
||||
(fn [db [_ phone-number]]
|
||||
;; todo save phone number to db
|
||||
(let [formatted (format-phone-number phone-number)]
|
||||
(-> db
|
||||
(assoc :user-phone-number formatted)
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
toolbar-background2]]
|
||||
[status-im.components.status-bar :refer [status-bar]]
|
||||
[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.chats-list.styles :as st]
|
||||
[status-im.components.styles :as cst]
|
||||
|
@ -80,12 +80,12 @@
|
|||
{:title (label :t/new-chat)
|
||||
:buttonColor :#9b59b6
|
||||
:onPress #(dispatch [:show-group-contacts :people])}
|
||||
[icon {:name :md-create
|
||||
[ion-icon {:name :md-create
|
||||
:style st/create-icon}]]
|
||||
[action-button-item
|
||||
{:title (label :t/new-group-chat)
|
||||
:buttonColor :#1abc9c
|
||||
:onPress #(dispatch [:show-group-new])}
|
||||
[icon {:name :md-person
|
||||
[ion-icon {:name :md-person
|
||||
:style st/person-stalker-icon}]]]]
|
||||
[bottom-gradient]])))
|
||||
|
|
|
@ -1,7 +1,16 @@
|
|||
(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]
|
||||
(r/create-element class (clj->js (merge {:inverted true} props))))
|
||||
(r/create-element (.-default camera-class) (clj->js (merge {:inverted true} props))))
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
text
|
||||
image
|
||||
icon]]
|
||||
[status-im.components.icons.custom-icons :refer [oct-icon]]
|
||||
[status-im.components.chat-icon.styles :as st]
|
||||
[status-im.components.styles :refer [default-chat-color]]
|
||||
[clojure.string :as s]))
|
||||
|
@ -18,11 +19,16 @@
|
|||
[image {:source {:uri photo-path}
|
||||
:style (:chat-icon styles)}])
|
||||
|
||||
(defn contact-online [online styles]
|
||||
(when online
|
||||
(defn contact-badge [type styles]
|
||||
(when (= type :edit)
|
||||
[view (:online-view styles)
|
||||
(case type
|
||||
:online [view
|
||||
[view (:online-dot-left styles)]
|
||||
[view (:online-dot-right 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]
|
||||
[photo-path [:chat-photo chat-id]]
|
||||
|
@ -31,7 +37,7 @@
|
|||
[chat-icon photo-path styles]
|
||||
[default-chat-icon name styles])
|
||||
(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]
|
||||
[chat-icon-view chat-id group-chat name online
|
||||
|
@ -65,13 +71,13 @@
|
|||
|
||||
(defn contact-icon-view [contact styles]
|
||||
(let [photo-path (:photo-path contact)
|
||||
;; TODO stub data
|
||||
online true]
|
||||
;; TODO: stub
|
||||
type :online]
|
||||
[view (:container styles)
|
||||
(if-not (s/blank? photo-path)
|
||||
[chat-icon photo-path styles]
|
||||
[default-chat-icon (:name contact) styles])
|
||||
[contact-online online styles]]))
|
||||
[contact-badge type styles]]))
|
||||
|
||||
(defn contact-icon-contacts-tab [contact]
|
||||
[contact-icon-view contact
|
||||
|
@ -83,7 +89,7 @@
|
|||
:default-chat-icon (st/default-chat-icon-chat-list default-chat-color)
|
||||
: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
|
||||
:online-view st/online-view-profile
|
||||
:online-dot-left st/online-dot-left-profile
|
||||
|
@ -95,19 +101,17 @@
|
|||
(if (and photo-path (not (empty? photo-path)))
|
||||
[chat-icon photo-path styles]
|
||||
[default-chat-icon name styles])
|
||||
[contact-online online styles]]))
|
||||
[contact-badge badge-type styles]]))
|
||||
|
||||
(defview profile-icon []
|
||||
[contact [:contact]]
|
||||
(let [;; TODO stub data
|
||||
online true
|
||||
(let [;; TODO: stub
|
||||
type :online
|
||||
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 []
|
||||
[name [:get :username]
|
||||
photo-path [:get :photo-path]]
|
||||
(let [;; TODO stub data
|
||||
online true
|
||||
(defn my-profile-icon [{{:keys [photo-path name]} :account
|
||||
edit? :edit?}]
|
||||
(let [type (if edit? :edit :blank)
|
||||
color default-chat-color]
|
||||
[profile-icon-view photo-path name color online]))
|
||||
[profile-icon-view photo-path name color type]))
|
||||
|
|
|
@ -60,7 +60,8 @@
|
|||
(def chat-icon-profile
|
||||
(merge chat-icon
|
||||
{:width 64
|
||||
:height 64}))
|
||||
:height 64
|
||||
:border-radius 32}))
|
||||
|
||||
(def online-view
|
||||
{:position :absolute
|
||||
|
@ -75,13 +76,15 @@
|
|||
|
||||
(def online-view-menu-item
|
||||
(merge online-view
|
||||
{:width 15
|
||||
:height 15}))
|
||||
{:width 14
|
||||
:height 14
|
||||
:border-radius 7}))
|
||||
|
||||
(def online-view-profile
|
||||
(merge online-view
|
||||
{:width 24
|
||||
:height 24}))
|
||||
:height 24
|
||||
:border-radius 12}))
|
||||
|
||||
(def online-dot
|
||||
{:position :absolute
|
||||
|
@ -93,6 +96,12 @@
|
|||
(def online-dot-left (merge online-dot {:left 3}))
|
||||
(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
|
||||
(merge online-dot
|
||||
{:top 4
|
||||
|
|
|
@ -12,53 +12,52 @@
|
|||
text2-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
|
||||
{:borderRadius 32
|
||||
{:border-radius 32
|
||||
:width 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
|
||||
{:height 48
|
||||
:paddingLeft 16
|
||||
:paddingTop 14})
|
||||
|
||||
(def menu-item-text
|
||||
{:fontSize 14
|
||||
:fontFamily font
|
||||
:lineHeight 21
|
||||
{:font-size 14
|
||||
:line-height 21
|
||||
: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
|
||||
{:marginTop -2.5
|
||||
:color text1-color
|
||||
:fontSize 16})
|
||||
|
||||
(def menu-items-container
|
||||
{:flex 1
|
||||
:marginTop 80
|
||||
:alignItems :stretch
|
||||
:flexDirection :column})
|
||||
{:color text1-color
|
||||
:font-size 16})
|
||||
|
||||
(def switch-users-container
|
||||
{:paddingVertical 36
|
||||
:alignItems :center})
|
||||
{:padding-vertical 36
|
||||
:align-items :center})
|
||||
|
||||
(def switch-users-text
|
||||
{:fontSize 14
|
||||
:fontFamily font
|
||||
:lineHeight 21
|
||||
{:font-size 14
|
||||
:line-height 21
|
||||
:color text3-color})
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
(ns status-im.components.drawer.view
|
||||
(:require-macros [status-im.utils.views :refer [defview]])
|
||||
(:require [clojure.string :as s]
|
||||
[re-frame.core :refer [subscribe dispatch dispatch-sync]]
|
||||
[reagent.core :as r]
|
||||
|
@ -27,53 +28,67 @@
|
|||
{:uri photo-path})
|
||||
: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
|
||||
:onPress (fn []
|
||||
(close-drawer)
|
||||
(handler))}
|
||||
[text {:style st/menu-item-text}
|
||||
[text {:style st/menu-item-text
|
||||
:platform-specific platform-specific
|
||||
:font :default}
|
||||
name]])
|
||||
|
||||
(defn drawer-menu []
|
||||
(let [username (subscribe [:get :username])]
|
||||
(fn []
|
||||
(defview drawer-menu [{platform-specific :platform-specific}]
|
||||
[{:keys [name address photo-path]} [:get-current-account]]
|
||||
[view st/drawer-menu
|
||||
[view st/user-photo-container
|
||||
[user-photo {}]]
|
||||
[user-photo {:photo-path photo-path}]]
|
||||
[view st/name-container
|
||||
[text {:style st/name-text}
|
||||
@username]]
|
||||
[text {:style st/name-text
|
||||
:platform-specific platform-specific
|
||||
:number-of-lines 1
|
||||
:font :default}
|
||||
(if (= name address)
|
||||
(label :t/user-anonymous)
|
||||
name)]]
|
||||
[view st/menu-items-container
|
||||
[menu-item {:name (label :t/profile)
|
||||
:handler #(dispatch [:navigate-to :my-profile])}]
|
||||
:handler #(dispatch [:navigate-to :my-profile])
|
||||
:platform-specific platform-specific}]
|
||||
[menu-item {:name (label :t/settings)
|
||||
:handler (fn []
|
||||
;; TODO not implemented
|
||||
)}]
|
||||
)
|
||||
:platform-specific platform-specific}]
|
||||
[menu-item {:name (label :t/discovery)
|
||||
:handler #(dispatch [:navigate-to :discovery])}]
|
||||
:handler #(dispatch [:navigate-to :discovery])
|
||||
:platform-specific platform-specific}]
|
||||
[menu-item {:name (label :t/contacts)
|
||||
:handler #(dispatch [:show-contacts navigator])}]
|
||||
:handler #(dispatch [:show-contacts navigator])
|
||||
:platform-specific platform-specific}]
|
||||
[menu-item {:name (label :t/invite-friends)
|
||||
:handler (fn []
|
||||
;; TODO not implemented
|
||||
)}]
|
||||
)
|
||||
:platform-specific platform-specific}]
|
||||
[menu-item {:name (label :t/faq)
|
||||
:handler (fn [])}]]
|
||||
: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}
|
||||
(label :t/switch-users)]]]])))
|
||||
[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
|
||||
: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]
|
||||
(reset! drawer-atom drawer))}
|
||||
items])
|
||||
|
|
|
@ -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")))
|
|
@ -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")))
|
|
@ -10,6 +10,7 @@
|
|||
image
|
||||
touchable-highlight
|
||||
get-dimensions]]
|
||||
[status-im.components.status-bar :refer [status-bar]]
|
||||
[status-im.components.drawer.view :refer [drawer-view]]
|
||||
[status-im.components.animation :as anim]
|
||||
[status-im.chats-list.screen :refer [chats-list]]
|
||||
|
@ -99,12 +100,15 @@
|
|||
[tab-view-container view-id
|
||||
[screen]])
|
||||
|
||||
(defview main-tabs []
|
||||
(defview main-tabs [{platform-specific :platform-specific}]
|
||||
[view-id [:get :view-id]
|
||||
tab-animation? [:get :prev-tab-view-id]]
|
||||
[drawer-view
|
||||
[view common-st/flex
|
||||
[status-bar {:platform-specific platform-specific}]
|
||||
[view common-st/flex
|
||||
[drawer-view {:platform-specific platform-specific}
|
||||
[view {:style common-st/flex
|
||||
:pointerEvents (if tab-animation? :none :auto)}
|
||||
(doall (map #(tab-view %) tab-list))
|
||||
[tabs {:selected-view-id view-id
|
||||
:tab-list tab-list}]]])
|
||||
:tab-list tab-list}]]]]])
|
||||
|
|
|
@ -4,4 +4,6 @@
|
|||
(def class (js/require "react-native-qrcode"))
|
||||
|
||||
(defn qr-code [props]
|
||||
(r/create-element class (clj->js (merge {:inverted true} props))))
|
||||
(r/create-element
|
||||
class
|
||||
(clj->js (merge {:inverted true} props))))
|
|
@ -6,6 +6,7 @@
|
|||
(def react-native (u/require "react-native"))
|
||||
(def native-modules (.-NativeModules react-native))
|
||||
(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 dismiss-keyboard! (u/require "dismissKeyboard"))
|
||||
|
@ -57,7 +58,6 @@
|
|||
(def dimensions (.-Dimensions js/ReactNative))
|
||||
(def keyboard (.-Keyboard react-native))
|
||||
|
||||
|
||||
;; Accessor methods for React Components
|
||||
|
||||
(defn text
|
||||
|
@ -110,6 +110,33 @@
|
|||
(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
|
||||
|
||||
(def platform
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
[status-im.components.status-bar :refer [status-bar]]
|
||||
[status-im.components.toolbar :refer [toolbar]]
|
||||
[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
|
||||
hamburger-icon
|
||||
icon-search
|
||||
|
@ -101,6 +101,6 @@
|
|||
{:title (label :t/new-contact)
|
||||
:buttonColor :#9b59b6
|
||||
:onPress #(dispatch [:navigate-to :new-contact])}
|
||||
[icon {:name :md-create
|
||||
[ion-icon {:name :md-create
|
||||
:style create-icon}]]]]
|
||||
[bottom-gradient]])))
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
[status-im.components.status-bar :refer [status-bar]]
|
||||
[status-im.components.toolbar :refer [toolbar]]
|
||||
[status-im.components.drawer.view :refer [drawer-view open-drawer]]
|
||||
[status-im.components.icons.ionicons :refer [icon]]
|
||||
[status-im.components.styles :refer [color-blue
|
||||
hamburger-icon
|
||||
icon-search
|
||||
|
@ -39,7 +38,7 @@
|
|||
|
||||
(defview contact-list [{platform-specific :platform-specific}]
|
||||
[contacts [:contacts-with-letters]]
|
||||
[drawer-view
|
||||
[drawer-view {:platform-specific platform-specific}
|
||||
[view st/contacts-list-container
|
||||
[contact-list-toolbar platform-specific]
|
||||
;; todo what if there is no contacts, should we show some information
|
||||
|
|
|
@ -11,9 +11,16 @@
|
|||
;; initial state of app-db
|
||||
(def app-db {:identity-password "replace-me-with-user-entered-password"
|
||||
:identity "me"
|
||||
:is-logged-in false
|
||||
|
||||
:accounts {}
|
||||
:user-identity nil
|
||||
:current-account-id nil
|
||||
|
||||
:profile-edit {:edit? false
|
||||
:name nil
|
||||
:email nil
|
||||
:status nil
|
||||
:photo-path nil}
|
||||
|
||||
:contacts []
|
||||
:contacts-ids #{}
|
||||
:selected-contacts #{}
|
||||
|
@ -27,12 +34,6 @@
|
|||
:signed-up false
|
||||
:view-id 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
|
||||
:qr-codes {}
|
||||
:new-contact {:name ""
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
status-im.discovery.handlers
|
||||
status-im.new-group.handlers
|
||||
status-im.participants.handlers
|
||||
status-im.profile.handlers
|
||||
status-im.commands.handlers.loading
|
||||
status-im.commands.handlers.jail
|
||||
status-im.qr-scanner.handlers
|
||||
|
@ -56,7 +57,7 @@
|
|||
(register-handler :initialize-db
|
||||
(fn [_ _]
|
||||
(realm/reset-account)
|
||||
(assoc app-db :user-identity nil)))
|
||||
(assoc app-db :current-account-id nil)))
|
||||
|
||||
(register-handler :initialize-account-db
|
||||
(fn [db _]
|
||||
|
@ -66,8 +67,8 @@
|
|||
|
||||
(register-handler :initialize-account
|
||||
(u/side-effect!
|
||||
(fn [_ [_ account]]
|
||||
(dispatch [:initialize-protocol account])
|
||||
(fn [_ [_ address]]
|
||||
(dispatch [:initialize-protocol address])
|
||||
(dispatch [:initialize-account-db])
|
||||
(dispatch [:initialize-chats])
|
||||
(dispatch [:load-contacts])
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
|
||||
(defn sign-up
|
||||
[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)
|
||||
(log/debug "signing up with public-key" public-key "and phone " phone-number)
|
||||
(http-post "sign-up" {:phone-number phone-number
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
[status-im.ios.styles :refer [styles]]
|
||||
[status-im.components.react :refer [app-registry
|
||||
keyboard
|
||||
orientation]]
|
||||
orientation
|
||||
show-action-sheet]]
|
||||
[status-im.components.main-tabs :refer [main-tabs]]
|
||||
[status-im.contacts.views.contact-list :refer [contact-list]]
|
||||
[status-im.contacts.views.new-contact :refer [new-contact]]
|
||||
|
@ -22,6 +23,7 @@
|
|||
[status-im.participants.views.remove :refer [remove-participants]]
|
||||
[status-im.group-settings.screen :refer [group-settings]]
|
||||
[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.encryption]
|
||||
status-im.persistence.realm.core
|
||||
|
@ -34,9 +36,9 @@
|
|||
(let [signed-up (subscribe [:get :signed-up])
|
||||
_ (log/debug "signed up: " @signed-up)
|
||||
view-id (subscribe [:get :view-id])
|
||||
account (subscribe [:get :user-identity])
|
||||
account-id (subscribe [:get :current-account-id])
|
||||
keyboard-height (subscribe [:get :keyboard-height])]
|
||||
(log/debug "Current account: " @account)
|
||||
(log/debug "Current account: " @account-id)
|
||||
(r/create-class
|
||||
{:component-will-mount
|
||||
(fn []
|
||||
|
@ -58,7 +60,7 @@
|
|||
#(dispatch [:set :keyboard-height 0]))))
|
||||
:render
|
||||
(fn []
|
||||
(let [startup-view (if @account
|
||||
(let [startup-view (if @account-id
|
||||
(if @signed-up
|
||||
@view-id
|
||||
:chat)
|
||||
|
@ -80,10 +82,12 @@
|
|||
:qr-scanner qr-scanner
|
||||
:chat chat
|
||||
:profile profile
|
||||
:profile-photo-capture profile-photo-capture
|
||||
:accounts accounts
|
||||
:login login
|
||||
:my-profile my-profile)]
|
||||
[component {:platform-specific {:styles styles}}])))})))
|
||||
[component {:platform-specific {:styles styles
|
||||
:list-selection-fn show-action-sheet}}])))})))
|
||||
|
||||
(defn init []
|
||||
(dispatch-sync [:reset-app])
|
||||
|
|
|
@ -5,12 +5,11 @@
|
|||
(-> (r/get-all :base :accounts)
|
||||
r/collection->map))
|
||||
|
||||
(defn create-account [{:keys [address public-key] :as account}]
|
||||
(->> account
|
||||
(r/create :base :accounts)))
|
||||
(defn save-account [update?]
|
||||
#(r/create :base :accounts % update?))
|
||||
|
||||
(defn save-accounts [accounts]
|
||||
(r/write :base #(mapv create-account accounts)))
|
||||
(defn save-accounts [accounts update?]
|
||||
(r/write :base #(mapv (save-account update?) accounts)))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;----------------------------------------------
|
||||
|
|
|
@ -11,10 +11,10 @@
|
|||
(defn set-initialized [db 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)]
|
||||
(s/put kv/kv-store :identity identity-string)
|
||||
(assoc db :user-identity identity)))
|
||||
(assoc-in db [:accounts address] identity)))
|
||||
|
||||
(defn stored-identity [db]
|
||||
(let [identity (s/get kv/kv-store :identity)]
|
||||
|
|
|
@ -81,6 +81,12 @@
|
|||
|
||||
(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
|
||||
[db [_ view-id]]
|
||||
(-> db
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
:properties {:address "string"
|
||||
:public-key "string"
|
||||
:name "string"
|
||||
:phone {:type "string" :optional true}
|
||||
:email {:type "string" :optional true}
|
||||
:status {:type "string" :optional true}
|
||||
:photo-path "string"}}
|
||||
{:name :tag
|
||||
:primaryKey :name
|
||||
|
|
|
@ -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)}))))
|
|
@ -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}}]]]]]))
|
|
@ -0,0 +1,5 @@
|
|||
(ns status-im.profile.photo-capture.styles)
|
||||
|
||||
(def container
|
||||
{:flex 1
|
||||
:background-color :white})
|
|
@ -1,30 +1,127 @@
|
|||
(ns status-im.profile.screen
|
||||
(: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
|
||||
text
|
||||
text-input
|
||||
image
|
||||
icon
|
||||
scroll-view
|
||||
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
|
||||
my-profile-icon]]
|
||||
[status-im.components.status-bar :refer [status-bar]]
|
||||
[status-im.profile.styles :as st]
|
||||
[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.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]}]
|
||||
[view st/profile-property-view-container
|
||||
[view st/profile-property-view-sub-container
|
||||
[text {:style st/profile-property-view-label} name]
|
||||
[text {:style st/profile-property-view-value} value]]])
|
||||
(defn- get-hashtags [status]
|
||||
(let [hashtags (map #(subs % 1) (re-seq #"#[^ !?,;:.]+" status))]
|
||||
(or hashtags [])))
|
||||
|
||||
(defn message-user [identity]
|
||||
(defn- message-user [identity]
|
||||
(when 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 []
|
||||
[{:keys [name whisper-identity phone-number]} [:contact]]
|
||||
[scroll-view {:style st/profile}
|
||||
|
@ -35,9 +132,9 @@
|
|||
[view st/status-block
|
||||
[view st/user-photo-container
|
||||
[profile-icon]]
|
||||
[text {:style st/user-name} name]
|
||||
[text {:style st/username} name]
|
||||
;; TODO stub data
|
||||
[text {:style st/status} (label :t/not-implemented)]
|
||||
[text {:style st/status-input} (label :t/not-implemented)]
|
||||
[view st/btns-container
|
||||
[touchable-highlight {:onPress #(message-user whisper-identity)}
|
||||
[view st/message-btn
|
||||
|
@ -61,37 +158,53 @@
|
|||
)}
|
||||
[view [text {:style st/report-user-text} (label :t/report-user)]]]]]])
|
||||
|
||||
(defview my-profile [_]
|
||||
[username [:get :username]
|
||||
photo-path [:get :photo-path]
|
||||
phone-number [:get :phone-number]
|
||||
email [:get :email]
|
||||
status [:get :status]
|
||||
identity [:get-in [:user-identity :public-key]]]
|
||||
(defview my-profile [{platform-specific :platform-specific}]
|
||||
[{public-key :public-key
|
||||
address :address
|
||||
username :name
|
||||
email :email
|
||||
photo-path :photo-path
|
||||
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}
|
||||
[touchable-highlight {:style st/back-btn-touchable
|
||||
:on-press #(dispatch [:navigate-back])}
|
||||
[view st/back-btn-container
|
||||
[icon :back st/back-btn-icon]]]
|
||||
[touchable-highlight {:style st/actions-btn-touchable
|
||||
:on-press (fn []
|
||||
;; TODO not implemented
|
||||
)}
|
||||
[view st/actions-btn-container
|
||||
[icon :dots st/actions-btn-icon]]]
|
||||
[view st/status-block
|
||||
[view st/user-photo-container
|
||||
[my-profile-icon]]
|
||||
[text {:style st/user-name} username]
|
||||
[text {:style st/status} status]]
|
||||
[status-bar {:platform-specific platform-specific}]
|
||||
[toolbar {:account account
|
||||
:profile-edit-data profile-edit-data
|
||||
:edit? edit?}]
|
||||
|
||||
[status-image-view {:platform-specific platform-specific
|
||||
:account account
|
||||
:photo-path (or new-photo-path photo-path)
|
||||
:status (if (and new-status (not (str/blank? new-status))) new-status status)
|
||||
:edit? edit?}]
|
||||
|
||||
[scroll-view st/profile-properties-container
|
||||
[profile-property-view {:name (label :t/username)
|
||||
:value username}]
|
||||
:value (if (not= username address)
|
||||
username)
|
||||
:empty-value (label :t/not-specified)
|
||||
:on-change-text #(dispatch [:set-in [:profile-edit :name] %])
|
||||
:profile-data profile-edit-data
|
||||
:platform-specific platform-specific}]
|
||||
[profile-property-view {:name (label :t/phone-number)
|
||||
:value 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 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
|
||||
[qr-code {:value (clj->json {:name username
|
||||
:whisper-identity identity})
|
||||
:size 200}]]]])
|
||||
[qr-code {:value (clj->js {:name username
|
||||
:whisper-identity public-key})
|
||||
:size 150}]]]])
|
||||
|
|
|
@ -11,31 +11,10 @@
|
|||
text1-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
|
||||
{:flex 1
|
||||
:backgroundColor color-white
|
||||
:flexDirection :column})
|
||||
:background-color color-white
|
||||
:flex-direction :column})
|
||||
|
||||
(def back-btn-touchable
|
||||
{:position :absolute})
|
||||
|
@ -45,8 +24,8 @@
|
|||
:height 56})
|
||||
|
||||
(def back-btn-icon
|
||||
{:marginTop 21
|
||||
:marginLeft 23
|
||||
{:margin-top 21
|
||||
:margin-left 23
|
||||
:width 8
|
||||
:height 14})
|
||||
|
||||
|
@ -57,86 +36,121 @@
|
|||
(def actions-btn-container
|
||||
{:width 56
|
||||
:height 56
|
||||
:alignItems :center
|
||||
:justifyContent :center})
|
||||
:align-items :center
|
||||
:justify-content :center})
|
||||
|
||||
(def actions-btn-icon
|
||||
(def edit-btn-icon
|
||||
{:width 4
|
||||
:height 16})
|
||||
|
||||
(def status-block
|
||||
{:alignSelf :center
|
||||
:alignItems :center
|
||||
:width 249})
|
||||
(def ok-btn-icon
|
||||
{:font-size 22
|
||||
:color :black})
|
||||
|
||||
(def user-photo-container
|
||||
{:marginTop 22})
|
||||
{:margin-top 22})
|
||||
|
||||
(def user-name
|
||||
{:marginTop 16
|
||||
:fontSize 18
|
||||
:fontFamily font
|
||||
(def username
|
||||
{:margin-top 12
|
||||
:font-size 18
|
||||
:color text1-color})
|
||||
|
||||
(def status
|
||||
{:marginTop 10
|
||||
:fontFamily font
|
||||
:fontSize 14
|
||||
:lineHeight 20
|
||||
:textAlign :center
|
||||
(def username-input
|
||||
{:align-self "stretch"
|
||||
:margin-top -8
|
||||
:margin-bottom -22
|
||||
:font-size 18
|
||||
:text-align :center
|
||||
: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
|
||||
{:marginTop 18
|
||||
:flexDirection :row})
|
||||
{:margin-top 18
|
||||
:flex-direction :row})
|
||||
|
||||
(def message-btn
|
||||
{:height 40
|
||||
:justifyContent :center
|
||||
:backgroundColor color-blue
|
||||
:paddingLeft 25
|
||||
:paddingRight 25
|
||||
:borderRadius 20})
|
||||
:justify-content :center
|
||||
:background-color color-blue
|
||||
:padding-left 25
|
||||
:padding-right 25
|
||||
:border-radius 20})
|
||||
|
||||
(def message-btn-text
|
||||
{:marginTop -2.5
|
||||
:fontSize 14
|
||||
:fontFamily font
|
||||
{:margin-top -2.5
|
||||
:font-size 14
|
||||
:font-family font
|
||||
:color color-white})
|
||||
|
||||
(def more-btn
|
||||
{:marginLeft 10
|
||||
{:margin-left 10
|
||||
:width 40
|
||||
:height 40
|
||||
:alignItems :center
|
||||
:justifyContent :center
|
||||
:backgroundColor color-blue-transparent
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:background-color color-blue-transparent
|
||||
:padding 8
|
||||
:borderRadius 20})
|
||||
:border-radius 20})
|
||||
|
||||
(def more-btn-image
|
||||
{:width 4
|
||||
:height 16})
|
||||
|
||||
(def profile-properties-container
|
||||
{:marginTop 20
|
||||
:alignItems :stretch
|
||||
:flexDirection :column})
|
||||
{:margin-top 20
|
||||
:align-items :stretch
|
||||
: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
|
||||
{:marginTop 50
|
||||
:marginBottom 43
|
||||
:alignItems :center})
|
||||
{:margin-top 50
|
||||
:margin-bottom 43
|
||||
:align-items :center})
|
||||
|
||||
(def report-user-text
|
||||
{:fontSize 14
|
||||
:fontFamily font
|
||||
:lineHeight 21
|
||||
{:font-size 14
|
||||
:font-family font
|
||||
:line-height 21
|
||||
:color text2-color
|
||||
;; IOS:
|
||||
:letterSpacing 0.5})
|
||||
:letter-spacing 0.5})
|
||||
|
||||
(def qr-code-container
|
||||
{:flex 1
|
||||
:alignItems :center
|
||||
:margin 15})
|
||||
:margin 32})
|
||||
|
|
|
@ -18,8 +18,9 @@
|
|||
|
||||
(register-handler :initialize-protocol
|
||||
(u/side-effect!
|
||||
(fn [{:keys [user-identity] :as db} [_ account]]
|
||||
(init-protocol (or account user-identity) (make-handler db)))))
|
||||
(fn [db [_ current-account-id]]
|
||||
(let [current-account (get-in db [:accounts current-account-id])]
|
||||
(init-protocol current-account (make-handler db))))))
|
||||
|
||||
(register-handler :protocol-initialized
|
||||
(fn [db [_ identity]]
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
image
|
||||
touchable-highlight]]
|
||||
[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.i18n :refer [label]]
|
||||
[status-im.qr-scanner.styles :as st]))
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
image
|
||||
touchable-highlight]]
|
||||
[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.i18n :refer [label]]
|
||||
[status-im.qr-scanner.styles :as st]))
|
||||
|
|
|
@ -12,6 +12,11 @@
|
|||
(fn [db [_ k]]
|
||||
(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
|
||||
(fn [db [_ path]]
|
||||
(reaction (get-in @db path))))
|
||||
|
|
|
@ -27,8 +27,17 @@
|
|||
:report-user "REPORT USER"
|
||||
:message "Message"
|
||||
:username "Username"
|
||||
:user-anonymous "Anonymous"
|
||||
:not-specified "Not specified"
|
||||
:phone-number "Phone number"
|
||||
: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
|
||||
:contacts-syncronized "Your contacts have been synchronized"
|
||||
|
|
|
@ -9,3 +9,8 @@
|
|||
result (.then result #(handler nil %))
|
||||
result (.catch result #(handler % nil))]
|
||||
result))
|
||||
|
||||
(defn read-file [path encoding on-read on-error]
|
||||
(-> (.readFile fs path encoding)
|
||||
(.then on-read)
|
||||
(.catch on-error)))
|
|
@ -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)))
|
Loading…
Reference in New Issue