Merge pull request #129 from status-im/issue/#120
Issue/#120
Former-commit-id: 08790ddd0d
|
@ -16,7 +16,9 @@
|
||||||
"react-native-randombytes",
|
"react-native-randombytes",
|
||||||
"dismissKeyboard",
|
"dismissKeyboard",
|
||||||
"react-native-linear-gradient",
|
"react-native-linear-gradient",
|
||||||
"react-native-android-sms-listener"
|
"react-native-android-sms-listener",
|
||||||
|
"react-native-camera",
|
||||||
|
"react-native-qrcode"
|
||||||
],
|
],
|
||||||
"imageDirs": [
|
"imageDirs": [
|
||||||
"images"
|
"images"
|
||||||
|
|
|
@ -130,6 +130,7 @@ dependencies {
|
||||||
compile project(':react-native-i18n')
|
compile project(':react-native-i18n')
|
||||||
compile project(':react-native-linear-gradient')
|
compile project(':react-native-linear-gradient')
|
||||||
compile project(':ReactNativeAndroidSmsListener')
|
compile project(':ReactNativeAndroidSmsListener')
|
||||||
|
compile project(':react-native-camera')
|
||||||
// compile(name:'geth', ext:'aar')
|
// compile(name:'geth', ext:'aar')
|
||||||
compile(group: 'status-im', name: 'android-geth', version: '1.4.0-201604110816-a97a114', ext: 'aar')
|
compile(group: 'status-im', name: 'android-geth', version: '1.4.0-201604110816-a97a114', ext: 'aar')
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
|
import com.lwansbrough.RCTCamera.*;
|
||||||
import com.i18n.reactnativei18n.ReactNativeI18n;
|
import com.i18n.reactnativei18n.ReactNativeI18n;
|
||||||
import io.realm.react.RealmReactPackage;
|
import io.realm.react.RealmReactPackage;
|
||||||
|
|
||||||
|
@ -131,6 +131,7 @@ public class MainActivity extends ReactActivity {
|
||||||
new ReactNativeI18n(),
|
new ReactNativeI18n(),
|
||||||
new RandomBytesPackage(),
|
new RandomBytesPackage(),
|
||||||
new LinearGradientPackage(),
|
new LinearGradientPackage(),
|
||||||
|
new RCTCameraPackage(),
|
||||||
new SmsListener(this)
|
new SmsListener(this)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
After Width: | Height: | Size: 526 B |
After Width: | Height: | Size: 614 B |
After Width: | Height: | Size: 613 B |
After Width: | Height: | Size: 537 B |
After Width: | Height: | Size: 202 B |
After Width: | Height: | Size: 800 B |
After Width: | Height: | Size: 330 B |
After Width: | Height: | Size: 333 B |
After Width: | Height: | Size: 340 B |
After Width: | Height: | Size: 334 B |
After Width: | Height: | Size: 174 B |
After Width: | Height: | Size: 422 B |
After Width: | Height: | Size: 826 B |
After Width: | Height: | Size: 686 B |
After Width: | Height: | Size: 823 B |
After Width: | Height: | Size: 825 B |
After Width: | Height: | Size: 233 B |
After Width: | Height: | Size: 767 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 370 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 467 B |
After Width: | Height: | Size: 1.8 KiB |
|
@ -18,3 +18,5 @@ include ':react-native-linear-gradient'
|
||||||
project(':react-native-linear-gradient').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-linear-gradient/android')
|
project(':react-native-linear-gradient').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-linear-gradient/android')
|
||||||
include ':ReactNativeAndroidSmsListener'
|
include ':ReactNativeAndroidSmsListener'
|
||||||
project(':ReactNativeAndroidSmsListener').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-android-sms-listener/android')
|
project(':ReactNativeAndroidSmsListener').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-android-sms-listener/android')
|
||||||
|
include ':react-native-camera'
|
||||||
|
project(':react-native-camera').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-camera/android')
|
||||||
|
|
|
@ -11,12 +11,14 @@
|
||||||
"react-native": "^0.24.1",
|
"react-native": "^0.24.1",
|
||||||
"react-native-action-button": "^1.1.4",
|
"react-native-action-button": "^1.1.4",
|
||||||
"react-native-android-sms-listener": "^0.1.3",
|
"react-native-android-sms-listener": "^0.1.3",
|
||||||
|
"react-native-camera": "github:codyhazelwood/react-native-camera",
|
||||||
"react-native-circle-checkbox": "^0.1.3",
|
"react-native-circle-checkbox": "^0.1.3",
|
||||||
"react-native-contacts": "^0.2.4",
|
"react-native-contacts": "^0.2.4",
|
||||||
"react-native-i18n": "0.0.8",
|
"react-native-i18n": "0.0.8",
|
||||||
"react-native-invertible-scroll-view": "^1.0.0",
|
"react-native-invertible-scroll-view": "^1.0.0",
|
||||||
"react-native-linear-gradient": "^1.5.7",
|
"react-native-linear-gradient": "^1.5.7",
|
||||||
"react-native-loading-spinner-overlay": "0.0.8",
|
"react-native-loading-spinner-overlay": "0.0.8",
|
||||||
|
"react-native-qrcode": "^0.2.2",
|
||||||
"react-native-randombytes": "^2.0.0",
|
"react-native-randombytes": "^2.0.0",
|
||||||
"react-native-vector-icons": "^1.3.4",
|
"react-native-vector-icons": "^1.3.4",
|
||||||
"realm": "^0.11.1"
|
"realm": "^0.11.1"
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
[status-im.components.react :refer [navigator app-registry]]
|
[status-im.components.react :refer [navigator app-registry]]
|
||||||
[status-im.components.main-tabs :refer [main-tabs]]
|
[status-im.components.main-tabs :refer [main-tabs]]
|
||||||
[status-im.contacts.screen :refer [contact-list]]
|
[status-im.contacts.screen :refer [contact-list]]
|
||||||
|
[status-im.contacts.views.new-contact :refer [new-contact]]
|
||||||
|
[status-im.qr-scanner.screen :refer [qr-scanner]]
|
||||||
[status-im.discovery.screen :refer [discovery]]
|
[status-im.discovery.screen :refer [discovery]]
|
||||||
[status-im.discovery.tag :refer [discovery-tag]]
|
[status-im.discovery.tag :refer [discovery-tag]]
|
||||||
[status-im.chat.screen :refer [chat]]
|
[status-im.chat.screen :refer [chat]]
|
||||||
|
@ -44,6 +46,8 @@
|
||||||
:new-group [new-group]
|
:new-group [new-group]
|
||||||
:group-settings [group-settings]
|
:group-settings [group-settings]
|
||||||
:contact-list [main-tabs]
|
:contact-list [main-tabs]
|
||||||
|
:new-contact [new-contact]
|
||||||
|
:qr-scanner [qr-scanner]
|
||||||
:chat [chat]
|
:chat [chat]
|
||||||
:profile [profile]
|
:profile [profile]
|
||||||
:my-profile [my-profile]))))
|
:my-profile [my-profile]))))
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
(ns status-im.components.camera
|
||||||
|
(:require [reagent.core :as r]))
|
||||||
|
|
||||||
|
(def class (.-default (js/require "react-native-camera")))
|
||||||
|
|
||||||
|
(defn camera [props]
|
||||||
|
(r/create-element class (clj->js (merge {:inverted true} props))))
|
|
@ -0,0 +1,7 @@
|
||||||
|
(ns status-im.components.qr-code
|
||||||
|
(:require [reagent.core :as r]))
|
||||||
|
|
||||||
|
(def class (js/require "react-native-qrcode"))
|
||||||
|
|
||||||
|
(defn qr-code [props]
|
||||||
|
(r/create-element class (clj->js (merge {:inverted true} props))))
|
|
@ -19,6 +19,7 @@
|
||||||
(def text1-color color-black)
|
(def text1-color color-black)
|
||||||
(def text2-color color-gray)
|
(def text2-color color-gray)
|
||||||
(def text3-color color-blue)
|
(def text3-color color-blue)
|
||||||
|
(def text4-color color-white)
|
||||||
(def online-color color-blue)
|
(def online-color color-blue)
|
||||||
(def new-messages-count-color color-blue-transparent)
|
(def new-messages-count-color color-blue-transparent)
|
||||||
(def chat-background color-light-gray)
|
(def chat-background color-light-gray)
|
||||||
|
@ -28,5 +29,73 @@
|
||||||
(def toolbar-background2 color-light-gray)
|
(def toolbar-background2 color-light-gray)
|
||||||
(def default-chat-color color-purple)
|
(def default-chat-color color-purple)
|
||||||
|
|
||||||
|
(def toolbar-height 56)
|
||||||
|
|
||||||
(def flex
|
(def flex
|
||||||
{:style {:flex 1}})
|
{:style {:flex 1}})
|
||||||
|
|
||||||
|
(def hamburger-icon
|
||||||
|
{:width 16
|
||||||
|
:height 12})
|
||||||
|
|
||||||
|
(def icon-search
|
||||||
|
{:width 17
|
||||||
|
:height 17})
|
||||||
|
|
||||||
|
(def create-icon
|
||||||
|
{:fontSize 20
|
||||||
|
:height 22
|
||||||
|
:color :white})
|
||||||
|
|
||||||
|
(def icon-back
|
||||||
|
{:width 8
|
||||||
|
:height 14})
|
||||||
|
|
||||||
|
(def icon-add
|
||||||
|
{:width 14
|
||||||
|
:height 14})
|
||||||
|
|
||||||
|
(def icon-ok
|
||||||
|
{:width 18
|
||||||
|
:height 14})
|
||||||
|
|
||||||
|
(def icon-qr
|
||||||
|
{:width 23
|
||||||
|
:height 22})
|
||||||
|
|
||||||
|
(def icon-plus
|
||||||
|
{:width 18
|
||||||
|
:height 18})
|
||||||
|
|
||||||
|
(def form-text-input
|
||||||
|
{:marginLeft -4
|
||||||
|
:fontSize 14
|
||||||
|
:fontFamily font
|
||||||
|
:color text1-color})
|
||||||
|
|
||||||
|
(def white-form-text-input
|
||||||
|
{:marginLeft -4
|
||||||
|
:fontSize 14
|
||||||
|
:fontFamily font
|
||||||
|
:color color-white})
|
||||||
|
|
||||||
|
(def toolbar-title-container
|
||||||
|
{:flex 1
|
||||||
|
:alignItems :center
|
||||||
|
:justifyContent :center})
|
||||||
|
|
||||||
|
(def toolbar-title-text
|
||||||
|
{:marginTop -2.5
|
||||||
|
:color text1-color
|
||||||
|
:fontSize 16
|
||||||
|
:fontFamily font})
|
||||||
|
|
||||||
|
(def button-input-container
|
||||||
|
{:flex 1
|
||||||
|
:flexDirection :row
|
||||||
|
:height 50})
|
||||||
|
|
||||||
|
(def button-input
|
||||||
|
{:flex 1
|
||||||
|
:flexDirection :column
|
||||||
|
:height 50})
|
|
@ -1,24 +1,28 @@
|
||||||
(ns status-im.components.toolbar
|
(ns status-im.components.toolbar
|
||||||
(:require [re-frame.core :refer [subscribe dispatch]]
|
(:require [re-frame.core :refer [subscribe dispatch]]
|
||||||
[status-im.components.react :refer [view
|
[status-im.components.react :refer [view
|
||||||
text-input
|
text-input
|
||||||
icon
|
icon
|
||||||
text
|
text
|
||||||
image
|
image
|
||||||
touchable-highlight]]
|
touchable-highlight]]
|
||||||
[status-im.components.styles :refer [font
|
[status-im.components.styles :refer [font
|
||||||
title-font
|
title-font
|
||||||
color-white
|
color-white
|
||||||
color-purple
|
color-purple
|
||||||
text1-color
|
text1-color
|
||||||
text2-color
|
text2-color
|
||||||
toolbar-background1]]))
|
toolbar-background1
|
||||||
|
toolbar-title-container
|
||||||
|
toolbar-title-text
|
||||||
|
icon-back
|
||||||
|
toolbar-height]]))
|
||||||
|
|
||||||
(defn toolbar [{:keys [title nav-action hide-nav? action custom-action
|
(defn toolbar [{:keys [title nav-action hide-nav? action custom-action
|
||||||
background-color custom-content style]}]
|
background-color custom-content style]}]
|
||||||
(let [style (merge {:flexDirection :row
|
(let [style (merge {:flexDirection :row
|
||||||
:backgroundColor (or background-color toolbar-background1)
|
:backgroundColor (or background-color toolbar-background1)
|
||||||
:height 56
|
:height toolbar-height
|
||||||
:elevation 2} style)]
|
:elevation 2} style)]
|
||||||
[view {:style style}
|
[view {:style style}
|
||||||
(when (not hide-nav?)
|
(when (not hide-nav?)
|
||||||
|
@ -31,20 +35,14 @@
|
||||||
[image (:image nav-action)]]]
|
[image (:image nav-action)]]]
|
||||||
[touchable-highlight {:on-press #(dispatch [:navigate-back])}
|
[touchable-highlight {:on-press #(dispatch [:navigate-back])}
|
||||||
[view {:width 56
|
[view {:width 56
|
||||||
:height 56}
|
:height 56
|
||||||
|
:alignItems :center
|
||||||
|
:justifyContent :center}
|
||||||
[image {:source {:uri :icon_back}
|
[image {:source {:uri :icon_back}
|
||||||
:style {:marginTop 21
|
:style icon-back}]]]))
|
||||||
:marginLeft 23
|
|
||||||
:width 8
|
|
||||||
:height 14}}]]]))
|
|
||||||
(or custom-content
|
(or custom-content
|
||||||
[view {:style {:flex 1
|
[view {:style toolbar-title-container}
|
||||||
:alignItems :center
|
[text {:style toolbar-title-text}
|
||||||
:justifyContent :center}}
|
|
||||||
[text {:style {:marginTop -2.5
|
|
||||||
:color text1-color
|
|
||||||
:fontSize 16
|
|
||||||
:fontFamily font}}
|
|
||||||
title]])
|
title]])
|
||||||
custom-action
|
custom-action
|
||||||
(when action
|
(when action
|
||||||
|
|
|
@ -104,3 +104,21 @@
|
||||||
(register-handler :add-contacts
|
(register-handler :add-contacts
|
||||||
(after save-contacts!)
|
(after save-contacts!)
|
||||||
add-new-contacts)
|
add-new-contacts)
|
||||||
|
|
||||||
|
(defn add-new-contact [db [_ {:keys [whisper-identity] :as contact}]]
|
||||||
|
(-> db
|
||||||
|
(update :contacts assoc whisper-identity contact)
|
||||||
|
(assoc :new-contact {:name ""
|
||||||
|
:address ""
|
||||||
|
:whisper-identity ""
|
||||||
|
:phone-number ""})))
|
||||||
|
|
||||||
|
(register-handler :add-new-contact
|
||||||
|
(after save-contact)
|
||||||
|
add-new-contact)
|
||||||
|
|
||||||
|
(defn set-new-contact-from-qr
|
||||||
|
[{:keys [new-contact] :as db} [_ _ qr-contact]]
|
||||||
|
(assoc db :new-contact (merge new-contact qr-contact)))
|
||||||
|
|
||||||
|
(register-handler :set-new-contact-from-qr set-new-contact-from-qr)
|
||||||
|
|
|
@ -6,9 +6,18 @@
|
||||||
touchable-highlight
|
touchable-highlight
|
||||||
list-view
|
list-view
|
||||||
list-item]]
|
list-item]]
|
||||||
|
[status-im.components.action-button :refer [action-button
|
||||||
|
action-button-item]]
|
||||||
[status-im.contacts.views.contact :refer [contact-view]]
|
[status-im.contacts.views.contact :refer [contact-view]]
|
||||||
[status-im.components.styles :refer [toolbar-background2]]
|
[status-im.components.styles :refer [toolbar-background2]]
|
||||||
[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.icons.ionicons :refer [icon]]
|
||||||
|
[status-im.components.styles :refer [color-blue
|
||||||
|
hamburger-icon
|
||||||
|
icon-search
|
||||||
|
create-icon
|
||||||
|
toolbar-background2]]
|
||||||
[status-im.contacts.styles :as st]
|
[status-im.contacts.styles :as st]
|
||||||
[status-im.utils.listview :as lw]
|
[status-im.utils.listview :as lw]
|
||||||
[status-im.i18n :refer [label]]))
|
[status-im.i18n :refer [label]]))
|
||||||
|
@ -17,20 +26,34 @@
|
||||||
(list-item [contact-view row]))
|
(list-item [contact-view row]))
|
||||||
|
|
||||||
(defn contact-list-toolbar []
|
(defn contact-list-toolbar []
|
||||||
[toolbar {:title (label :t/contacts)
|
[toolbar {:nav-action {:image {:source {:uri :icon_hamburger}
|
||||||
|
:style hamburger-icon}
|
||||||
|
:handler open-drawer}
|
||||||
|
:title (label :t/contacts)
|
||||||
:background-color toolbar-background2
|
:background-color toolbar-background2
|
||||||
:action {:image {:source {:uri :icon_search}
|
:action {:image {:source {:uri :icon_search}
|
||||||
:style st/search-icon}
|
:style icon-search}
|
||||||
:handler (fn [])}}])
|
:handler (fn [])}}])
|
||||||
|
|
||||||
(defview contact-list []
|
(defview contact-list []
|
||||||
[contacts [:get-contacts]]
|
[contacts [:get-contacts]]
|
||||||
[view st/contacts-list-container
|
[drawer-view
|
||||||
[contact-list-toolbar]
|
[view st/contacts-list-container
|
||||||
;; todo what if there is no contacts, should we show some information
|
[contact-list-toolbar]
|
||||||
;; about this?
|
;; todo what if there is no contacts, should we show some information
|
||||||
(when contacts
|
;; about this?
|
||||||
[list-view {:dataSource (lw/to-datasource contacts)
|
(when contacts
|
||||||
:enableEmptySections true
|
[list-view {:dataSource (lw/to-datasource contacts)
|
||||||
:renderRow render-row
|
:enableEmptySections true
|
||||||
:style st/contacts-list}])])
|
:renderRow render-row
|
||||||
|
:style st/contacts-list}])
|
||||||
|
[action-button {:buttonColor color-blue
|
||||||
|
:offsetY 16
|
||||||
|
:offsetX 16}
|
||||||
|
[action-button-item
|
||||||
|
{:title (label :t/new-contact)
|
||||||
|
:buttonColor :#9b59b6
|
||||||
|
:onPress #(dispatch [:navigate-to :new-contact])}
|
||||||
|
[icon {:name :android-create
|
||||||
|
:style create-icon}]]
|
||||||
|
]]])
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
(ns status-im.contacts.styles
|
(ns status-im.contacts.styles
|
||||||
(:require [status-im.components.styles :refer [font
|
(:require [status-im.components.styles :refer [font
|
||||||
title-font
|
title-font
|
||||||
text1-color
|
text1-color
|
||||||
color-white
|
color-white
|
||||||
online-color]]))
|
toolbar-background2
|
||||||
|
online-color]]))
|
||||||
|
|
||||||
|
|
||||||
(def search-icon
|
|
||||||
{:width 17
|
|
||||||
:height 17})
|
|
||||||
|
|
||||||
(def contacts-list-container
|
(def contacts-list-container
|
||||||
{:flex 1
|
{:flex 1
|
||||||
|
@ -67,3 +66,20 @@
|
||||||
:fontSize 16
|
:fontSize 16
|
||||||
:fontFamily font
|
:fontFamily font
|
||||||
:color text1-color})
|
:color text1-color})
|
||||||
|
|
||||||
|
; new contact
|
||||||
|
|
||||||
|
(def contact-form-container
|
||||||
|
{:flex 1
|
||||||
|
:color :white})
|
||||||
|
|
||||||
|
(def gradient-background
|
||||||
|
{:position :absolute
|
||||||
|
:top 0
|
||||||
|
:right 0
|
||||||
|
:bottom 0
|
||||||
|
:left 0})
|
||||||
|
|
||||||
|
(def form-container
|
||||||
|
{:marginLeft 16
|
||||||
|
:margin-top 50})
|
|
@ -0,0 +1,78 @@
|
||||||
|
(ns status-im.contacts.views.new-contact
|
||||||
|
(:require-macros [status-im.utils.views :refer [defview]])
|
||||||
|
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
|
||||||
|
[status-im.components.react :refer [view
|
||||||
|
text
|
||||||
|
text-input
|
||||||
|
image
|
||||||
|
linear-gradient
|
||||||
|
touchable-highlight]]
|
||||||
|
[status-im.components.toolbar :refer [toolbar]]
|
||||||
|
[status-im.components.drawer.view :refer [drawer-view open-drawer]]
|
||||||
|
[status-im.components.styles :refer [color-purple
|
||||||
|
color-white
|
||||||
|
icon-search
|
||||||
|
icon-back
|
||||||
|
icon-qr
|
||||||
|
toolbar-background1
|
||||||
|
toolbar-title-container
|
||||||
|
toolbar-title-text
|
||||||
|
button-input-container
|
||||||
|
button-input
|
||||||
|
white-form-text-input]]
|
||||||
|
[status-im.qr-scanner.views.import-button :refer [import-button]]
|
||||||
|
[status-im.i18n :refer [label]]
|
||||||
|
[status-im.contacts.styles :as st]))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(def toolbar-title
|
||||||
|
[view toolbar-title-container
|
||||||
|
[text {:style (merge toolbar-title-text {:color color-white})}
|
||||||
|
(label :t/new-contact)]])
|
||||||
|
|
||||||
|
(defview contact-name-input [name]
|
||||||
|
[]
|
||||||
|
[text-input
|
||||||
|
{:underlineColorAndroid color-white
|
||||||
|
:placeholderTextColor color-white
|
||||||
|
:style white-form-text-input
|
||||||
|
:autoFocus true
|
||||||
|
:placeholder (label :t/contact-name)
|
||||||
|
:onChangeText #(dispatch [:set-in [:new-contact :name] %])}
|
||||||
|
name])
|
||||||
|
|
||||||
|
(defview contact-whisper-id-input [whisper-identity]
|
||||||
|
[view button-input-container
|
||||||
|
[text-input
|
||||||
|
{:underlineColorAndroid color-white
|
||||||
|
:placeholderTextColor color-white
|
||||||
|
:style (merge white-form-text-input button-input)
|
||||||
|
:autoFocus true
|
||||||
|
:placeholder (label :t/whisper-identity)
|
||||||
|
:onChangeText #(dispatch [:set-in [:new-contact :whisper-identity] %])}
|
||||||
|
whisper-identity]
|
||||||
|
[import-button #(dispatch [:scan-qr-code {:toolbar-title (label :t/new-contact)} :set-new-contact-from-qr])]])
|
||||||
|
|
||||||
|
(defview new-contact []
|
||||||
|
[{:keys [name whisper-identity phone-number] :as new-contact} [:get :new-contact]]
|
||||||
|
[drawer-view
|
||||||
|
[view st/contact-form-container
|
||||||
|
[linear-gradient {:colors ["rgba(182, 116, 241, 1)" "rgba(107, 147, 231, 1)" "rgba(43, 171, 238, 1)"]
|
||||||
|
:start [0, 0]
|
||||||
|
:end [0.5, 1]
|
||||||
|
:locations [0, 0.8 ,1]
|
||||||
|
:style st/gradient-background}]
|
||||||
|
|
||||||
|
[toolbar {:background-color :transparent
|
||||||
|
:nav-action {:image {:source {:uri :icon_back_white}
|
||||||
|
:style icon-back}
|
||||||
|
:handler #(dispatch [:navigate-back])}
|
||||||
|
:custom-content toolbar-title
|
||||||
|
:action {:image {:source {:uri :icon_add}
|
||||||
|
:style icon-search}
|
||||||
|
:handler #(dispatch [:add-new-contact new-contact])}}]
|
||||||
|
[view st/form-container
|
||||||
|
[contact-whisper-id-input whisper-identity]
|
||||||
|
[contact-name-input name]
|
||||||
|
]]])
|
|
@ -29,6 +29,11 @@
|
||||||
:email "myemail@gmail.com"
|
:email "myemail@gmail.com"
|
||||||
:status "Hi, this is my status"
|
:status "Hi, this is my status"
|
||||||
:current-tag nil
|
:current-tag nil
|
||||||
|
:qr-codes {}
|
||||||
|
:new-contact {:name ""
|
||||||
|
:address ""
|
||||||
|
:whisper-identity ""
|
||||||
|
:phone-number ""}
|
||||||
:disable-group-creation false})
|
:disable-group-creation false})
|
||||||
|
|
||||||
(def protocol-initialized-path [:protocol-initialized])
|
(def protocol-initialized-path [:protocol-initialized])
|
||||||
|
|
|
@ -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.qr-scanner.handlers
|
||||||
status-im.protocol.handlers))
|
status-im.protocol.handlers))
|
||||||
|
|
||||||
;; -- Middleware ------------------------------------------------------------
|
;; -- Middleware ------------------------------------------------------------
|
||||||
|
|
|
@ -9,13 +9,15 @@
|
||||||
|
|
||||||
(set! (.-translations i18n) (clj->js {:en en/translations}))
|
(set! (.-translations i18n) (clj->js {:en en/translations}))
|
||||||
|
|
||||||
(defn label [path & options]
|
(defn label
|
||||||
(if (exists? i18n.t)
|
([path] (label path {}))
|
||||||
(.t i18n (name path) (clj->js options))
|
([path options]
|
||||||
(name path)))
|
(if (exists? i18n.t)
|
||||||
|
(.t i18n (name path) (clj->js options))
|
||||||
|
(name path))))
|
||||||
|
|
||||||
|
|
||||||
(defn label-pluralize [count path & options]
|
(defn label-pluralize [count path & options]
|
||||||
(if (exists? i18n.t)
|
(if (exists? i18n.t)
|
||||||
(.p i18n count (name path) (clj->js options))
|
(.p i18n count (name path) (clj->js options))
|
||||||
(name path)))
|
(name path)))
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
[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.profile.styles :as st]
|
[status-im.profile.styles :as st]
|
||||||
|
[status-im.components.qr-code :refer [qr-code]]
|
||||||
|
[status-im.utils.types :refer [clj->json]]
|
||||||
[status-im.i18n :refer [label]]))
|
[status-im.i18n :refer [label]]))
|
||||||
|
|
||||||
(defn profile-property-view [{:keys [name value]}]
|
(defn profile-property-view [{:keys [name value]}]
|
||||||
|
@ -64,7 +66,8 @@
|
||||||
photo-path [:get :photo-path]
|
photo-path [:get :photo-path]
|
||||||
phone-number [:get :phone-number]
|
phone-number [:get :phone-number]
|
||||||
email [:get :email]
|
email [:get :email]
|
||||||
status [:get :status]]
|
status [:get :status]
|
||||||
|
identity [:get-in [:user-identity :public]]]
|
||||||
[scroll-view {:style st/profile}
|
[scroll-view {:style st/profile}
|
||||||
[touchable-highlight {:style st/back-btn-touchable
|
[touchable-highlight {:style st/back-btn-touchable
|
||||||
:on-press #(dispatch [:navigate-back])}
|
:on-press #(dispatch [:navigate-back])}
|
||||||
|
@ -81,10 +84,14 @@
|
||||||
[my-profile-icon]]
|
[my-profile-icon]]
|
||||||
[text {:style st/user-name} username]
|
[text {:style st/user-name} username]
|
||||||
[text {:style st/status} status]]
|
[text {:style st/status} status]]
|
||||||
[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 username}]
|
||||||
[profile-property-view {:name (label :t/phone-number)
|
[profile-property-view {:name (label :t/phone-number)
|
||||||
:value phone-number}]
|
:value phone-number}]
|
||||||
[profile-property-view {:name (label :t/email)
|
[profile-property-view {:name (label :t/email)
|
||||||
:value email}]]])
|
:value email}]
|
||||||
|
[view st/qr-code-container
|
||||||
|
[qr-code {:value (clj->json {:name username
|
||||||
|
:whisper-identity identity})
|
||||||
|
:size 200}]]]])
|
||||||
|
|
|
@ -135,3 +135,8 @@
|
||||||
:color text2-color
|
:color text2-color
|
||||||
;; IOS:
|
;; IOS:
|
||||||
:letterSpacing 0.5})
|
:letterSpacing 0.5})
|
||||||
|
|
||||||
|
(def qr-code-container
|
||||||
|
{:flex 1
|
||||||
|
:alignItems :center
|
||||||
|
:margin 15})
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
(ns status-im.qr-scanner.handlers
|
||||||
|
(:require [re-frame.core :refer [register-handler after dispatch debug enrich]]
|
||||||
|
[status-im.navigation.handlers :as nav]
|
||||||
|
[status-im.utils.handlers :as u]))
|
||||||
|
|
||||||
|
(defmethod nav/preload-data! :qr-scanner
|
||||||
|
[db [_ _ identifier]]
|
||||||
|
(assoc db :current-qr-context identifier))
|
||||||
|
|
||||||
|
(defn set-current-identifier [db [_ identifier handler]]
|
||||||
|
(assoc-in db [:qr-codes identifier] handler))
|
||||||
|
|
||||||
|
(defn navigate-to-scanner
|
||||||
|
[_ [_ identifier]]
|
||||||
|
(dispatch [:navigate-to :qr-scanner identifier]))
|
||||||
|
|
||||||
|
(register-handler :scan-qr-code
|
||||||
|
(after navigate-to-scanner)
|
||||||
|
set-current-identifier)
|
||||||
|
|
||||||
|
(register-handler :clear-qr-code
|
||||||
|
(fn [db [_ identifier]]
|
||||||
|
(update db :qr-codes dissoc identifier)))
|
||||||
|
|
||||||
|
(defn handle-qr-request
|
||||||
|
[db [_ context data]]
|
||||||
|
(let [handler (get-in db [:qr-codes context])]
|
||||||
|
(dispatch [handler context data])))
|
||||||
|
|
||||||
|
(defn clear-qr-request [db [_ context]]
|
||||||
|
(-> db
|
||||||
|
(update :qr-codes dissoc context)
|
||||||
|
(dissoc :current-qr-context)))
|
||||||
|
|
||||||
|
(register-handler :set-qr-code
|
||||||
|
(-> (u/side-effect! handle-qr-request)
|
||||||
|
((enrich clear-qr-request))
|
||||||
|
((after #(dispatch [:navigate-back])))))
|
|
@ -0,0 +1,37 @@
|
||||||
|
(ns status-im.qr-scanner.screen
|
||||||
|
(:require-macros [status-im.utils.views :refer [defview]])
|
||||||
|
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
|
||||||
|
[status-im.components.react :refer [view
|
||||||
|
image]]
|
||||||
|
[status-im.components.camera :refer [camera]]
|
||||||
|
[status-im.components.styles :refer [toolbar-background1
|
||||||
|
icon-search]]
|
||||||
|
[status-im.components.toolbar :refer [toolbar]]
|
||||||
|
[status-im.qr-scanner.styles :as st]
|
||||||
|
[status-im.utils.types :refer [json->clj]]))
|
||||||
|
|
||||||
|
(defn qr-scanner-toolbar [title]
|
||||||
|
[toolbar {:title title
|
||||||
|
:background-color toolbar-background1
|
||||||
|
:action {:image {:source {:uri :icon_lock_white}
|
||||||
|
:style icon-search}
|
||||||
|
:handler #()}}])
|
||||||
|
|
||||||
|
(defview qr-scanner []
|
||||||
|
[identifier [:get :current-qr-context]]
|
||||||
|
[view st/barcode-scanner-container
|
||||||
|
[qr-scanner-toolbar (:toolbar-title identifier)]
|
||||||
|
[camera {;:on-bar-code-read #(js/alert "ok")
|
||||||
|
:onBarCodeRead #(let [data (json->clj (.-data %))]
|
||||||
|
(dispatch [:set-qr-code identifier data]))
|
||||||
|
:style st/barcode-scanner}]
|
||||||
|
[view st/rectangle-container
|
||||||
|
[view st/rectangle
|
||||||
|
[image {:source {:uri :corner_left_top}
|
||||||
|
:style st/corner-left-top}]
|
||||||
|
[image {:source {:uri :corner_right_top}
|
||||||
|
:style st/corner-right-top}]
|
||||||
|
[image {:source {:uri :corner_right_bottom}
|
||||||
|
:style st/corner-right-bottom}]
|
||||||
|
[image {:source {:uri :corner_left_bottom}
|
||||||
|
:style st/corner-left-bottom}]]]])
|
|
@ -0,0 +1,76 @@
|
||||||
|
(ns status-im.qr-scanner.styles
|
||||||
|
(:require [status-im.components.styles :refer [toolbar-height
|
||||||
|
color-white]]))
|
||||||
|
|
||||||
|
(def barcode-scanner-container
|
||||||
|
{:flex 1
|
||||||
|
:backgroundColor :white})
|
||||||
|
|
||||||
|
(def barcode-scanner
|
||||||
|
{:flex 1
|
||||||
|
:justifyContent :flex-end
|
||||||
|
:alignItems :center})
|
||||||
|
|
||||||
|
(def rectangle-container
|
||||||
|
{:position :absolute
|
||||||
|
:left 0
|
||||||
|
:top toolbar-height
|
||||||
|
:bottom 0
|
||||||
|
:right 0
|
||||||
|
:flex 1
|
||||||
|
:alignItems :center
|
||||||
|
:justifyContent :center
|
||||||
|
:backgroundColor :transparent})
|
||||||
|
|
||||||
|
(def rectangle
|
||||||
|
{:height 250
|
||||||
|
:width 250
|
||||||
|
:backgroundColor :transparent})
|
||||||
|
|
||||||
|
(def corner-left-top
|
||||||
|
{:position :absolute
|
||||||
|
:left 0
|
||||||
|
:top 0
|
||||||
|
:width 56
|
||||||
|
:height 56})
|
||||||
|
|
||||||
|
(def corner-right-top
|
||||||
|
{:position :absolute
|
||||||
|
:right 0
|
||||||
|
:top 0
|
||||||
|
:width 56
|
||||||
|
:height 56})
|
||||||
|
|
||||||
|
(def corner-right-bottom
|
||||||
|
{:position :absolute
|
||||||
|
:right 0
|
||||||
|
:bottom 0
|
||||||
|
:width 56
|
||||||
|
:height 56})
|
||||||
|
|
||||||
|
(def corner-left-bottom
|
||||||
|
{:position :absolute
|
||||||
|
:left 0
|
||||||
|
:bottom 0
|
||||||
|
:width 56
|
||||||
|
:height 56})
|
||||||
|
|
||||||
|
(def import-button
|
||||||
|
{:position :absolute
|
||||||
|
:right 16
|
||||||
|
:flex 1
|
||||||
|
:height 50
|
||||||
|
:alignItems :center})
|
||||||
|
|
||||||
|
(def import-button-content
|
||||||
|
{:flex 1
|
||||||
|
:flexDirection :row
|
||||||
|
:height 50
|
||||||
|
:alignItems :center
|
||||||
|
:alignSelf :center})
|
||||||
|
|
||||||
|
(def import-text
|
||||||
|
{:flex 1
|
||||||
|
:flexDirection :column
|
||||||
|
:color color-white
|
||||||
|
:margin-left 8})
|
|
@ -0,0 +1,23 @@
|
||||||
|
(ns status-im.qr-scanner.views.import-button
|
||||||
|
(:require-macros [status-im.utils.views :refer [defview]])
|
||||||
|
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
|
||||||
|
[status-im.components.react :refer [view
|
||||||
|
text
|
||||||
|
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]))
|
||||||
|
|
||||||
|
|
||||||
|
(defview import-button [handler]
|
||||||
|
[]
|
||||||
|
[view st/import-button
|
||||||
|
[touchable-highlight
|
||||||
|
{:on-press handler}
|
||||||
|
[view st/import-button-content
|
||||||
|
[image {:source {:uri :icon_qr}
|
||||||
|
:style icon-qr}]
|
||||||
|
[text {:style st/import-text} (label :t/import-qr)]]]])
|
|
@ -115,8 +115,18 @@
|
||||||
:You "You"
|
:You "You"
|
||||||
|
|
||||||
;new-contact
|
;new-contact
|
||||||
:import-qr "Import from QR"
|
:import-qr "Import"
|
||||||
:contact-name "Contact Name"
|
:contact-name "Contact Name"
|
||||||
:contact-address "Contact Address"
|
:whisper-identity "Whisper Identity"
|
||||||
|
|
||||||
|
;login
|
||||||
|
:recover-from-passphrase "Recover from passphrase"
|
||||||
|
:connect "Connect"
|
||||||
|
:address "Address"
|
||||||
|
:password "Password"
|
||||||
|
:login "Login"
|
||||||
|
|
||||||
|
;users
|
||||||
|
:add-account "Add account"
|
||||||
|
|
||||||
})
|
})
|
|
@ -6,4 +6,10 @@
|
||||||
s))
|
s))
|
||||||
|
|
||||||
(defn to-edn-string [value]
|
(defn to-edn-string [value]
|
||||||
(with-out-str (pr value)))
|
(with-out-str (pr value)))
|
||||||
|
|
||||||
|
(defn clj->json [data]
|
||||||
|
(.stringify js/JSON (clj->js data)))
|
||||||
|
|
||||||
|
(defn json->clj [data]
|
||||||
|
(js->clj (.parse js/JSON data) :keywordize-keys true))
|
||||||
|
|