transaction screens UI refresh

This commit is contained in:
Gustavo Nunes 2017-03-28 15:23:58 -03:00 committed by Roman Volosovskyi
parent b1adf7aa68
commit abf0128a1a
44 changed files with 604 additions and 283 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 253 B

After

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 226 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 201 B

After

Width:  |  Height:  |  Size: 251 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 329 B

After

Width:  |  Height:  |  Size: 384 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 934 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 549 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 401 B

After

Width:  |  Height:  |  Size: 603 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 767 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 546 B

After

Width:  |  Height:  |  Size: 886 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "icon_arrow_left_white.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 767 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 401 B

After

Width:  |  Height:  |  Size: 384 B

View File

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "iconOkBig.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "iconOkBig@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "iconOkBig@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 934 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -22,7 +22,9 @@
[status-im.accounts.login.screen :refer [login]]
[status-im.accounts.recover.screen :refer [recover]]
[status-im.accounts.screen :refer [accounts]]
[status-im.transactions.screen :refer [confirm]]
[status-im.transactions.screens.confirmation-success :refer [confirmation-success]]
[status-im.transactions.screens.pending-transactions :refer [pending-transactions]]
[status-im.transactions.screens.transaction-details :refer [transaction-details]]
[status-im.chats-list.screen :refer [chats-list]]
[status-im.new-chat.screen :refer [new-chat]]
[status-im.new-group.screen-public :refer [new-public-group]]
@ -149,7 +151,9 @@
(let [component (case @modal-view
:qr-scanner qr-scanner
:qr-code-view qr-code-view
:confirm confirm
:pending-transactions pending-transactions
:transaction-details transaction-details
:confirmation-success confirmation-success
:contact-list-modal contact-list-modal)]
[component])]])]]))))})))

View File

@ -73,7 +73,7 @@
(if (:sent-to-jail? message)
;; todo there could be other reasons for "long-running"
;; hanling of the command besides sendTransaction
(dispatch [:navigate-to-modal :confirm])
(dispatch [:navigate-to-modal :pending-transactions])
(cond
(console-command? chat-id command-name)
(dispatch [:invoke-console-command-handler! params'])

View File

@ -16,8 +16,8 @@
{:style st/gradient-top
:colors st/gradient-top-colors}]))
(defn separator [style]
[view st/separator-wrapper
(defn separator [style wrapper-style]
[view (merge st/separator-wrapper wrapper-style)
[view (merge st/separator style)]])
(defn form-spacer []

View File

@ -13,12 +13,19 @@
(def color-gray6 "#212121")
(def color-steel "#838b91")
(def color-white "white")
(def color-white-transparent "#ffffff66")
(def color-white-transparent-2 "#fefefe21")
(def color-light-blue "#628fe3")
(def color-light-blue-transparent "#628fe333")
(def color-light-blue2 "#eff3fc")
(def color-light-blue3 "#a0bcf0")
(def color-dark-blue-1 "#252c4a")
(def color-dark-blue-2 "#1f253f")
(def color-dark-blue-3 "#191f37")
(def color-light-gray "#EEF2F5")
(def color-red "red")
(def color-light-red "#e86363")
(def color-light-red2 "#f47979")
(def color-separator "#D6D6D6")

View File

@ -41,4 +41,5 @@
(merge input-error-text-style
{:color color
:background-color :transparent
:font-size 12})))
:font-size 12
:line-height 20})))

View File

@ -115,8 +115,8 @@
max-length]} (r/state component)
{:keys [wrapper-style input-style label-hidden? line-color focus-line-color focus-line-height
secure-text-entry label-color error-color error label value on-focus on-blur validator
auto-focus on-change-text on-change on-end-editing editable placeholder auto-capitalize
multiline number-of-lines]}
auto-focus on-change-text on-change on-end-editing editable placeholder
placeholder-text-color auto-capitalize multiline number-of-lines]}
(merge default-props (r/props component))
line-color (if error error-color line-color)
focus-line-color (if error error-color focus-line-color)
@ -126,50 +126,51 @@
[view (merge st/text-field-container wrapper-style)
(when-not label-hidden?
[animated-text {:style (st/label label-top label-font-size label-color)} label])
[text-input {:ref #(reset! input-ref %)
:style (merge st/text-input input-style)
:placeholder (or placeholder "")
:editable editable
:multiline multiline
:number-of-lines number-of-lines
:secure-text-entry secure-text-entry
:auto-capitalize auto-capitalize
:on-focus #(on-input-focus {:component component
:animation {:top label-top
:to-top (:label-top config)
:font-size label-font-size
:to-font-size (:label-font-small config)
:line-width line-width
:line-height line-height
:to-line-height focus-line-height}
:onFocus on-focus})
:on-blur #(on-input-blur {:component component
:value (or current-value value)
:animation {:top label-top
:to-top (:label-bottom config)
:font-size label-font-size
:to-font-size (:label-font-large config)
:line-width line-width
:line-height line-height
:to-line-width 0
:to-line-height 1}
:onBlur on-blur})
:on-change-text (fn [text]
(r/set-state component {:current-value text})
(if (or (not validator) (validator text))
(do
(r/set-state component {:valid-value text
:temp-value nil})
(on-change-text text))
(r/set-state component {:temp-value valid-value
:max-length (count valid-value)})))
:on-change #(on-change %)
:default-value value
:value temp-value
:max-length max-length
:on-submit-editing #(.blur @input-ref)
:on-end-editing (when on-end-editing on-end-editing)
:auto-focus (true? auto-focus)}]
[text-input {:ref #(reset! input-ref %)
:style (merge st/text-input input-style)
:placeholder (or placeholder "")
:placeholder-text-color placeholder-text-color
:editable editable
:multiline multiline
:number-of-lines number-of-lines
:secure-text-entry secure-text-entry
:auto-capitalize auto-capitalize
:on-focus #(on-input-focus {:component component
:animation {:top label-top
:to-top (:label-top config)
:font-size label-font-size
:to-font-size (:label-font-small config)
:line-width line-width
:line-height line-height
:to-line-height focus-line-height}
:onFocus on-focus})
:on-blur #(on-input-blur {:component component
:value (or current-value value)
:animation {:top label-top
:to-top (:label-bottom config)
:font-size label-font-size
:to-font-size (:label-font-large config)
:line-width line-width
:line-height line-height
:to-line-width 0
:to-line-height 1}
:onBlur on-blur})
:on-change-text (fn [text]
(r/set-state component {:current-value text})
(if (or (not validator) (validator text))
(do
(r/set-state component {:valid-value text
:temp-value nil})
(on-change-text text))
(r/set-state component {:temp-value valid-value
:max-length (count valid-value)})))
:on-change #(on-change %)
:default-value value
:value temp-value
:max-length max-length
:on-submit-editing #(.blur @input-ref)
:on-end-editing (when on-end-editing on-end-editing)
:auto-focus (true? auto-focus)}]
[view {:style (st/underline-container line-color)
:onLayout #(r/set-state component {:max-line-width (get-width %)})}
[animated-view {:style (st/underline focus-line-color line-width line-height)}]]

View File

@ -45,3 +45,7 @@
:style st/action-default}
:handler handler})
(defn close-white [handler]
{:image {:source {:uri :icon_close_white}
:style st/action-default}
:handler handler})

View File

@ -25,6 +25,7 @@
background-color :background-color
custom-content :custom-content
hide-border? :hide-border?
border-style :border-style
style :style}]
(let [style (merge (st/toolbar-wrapper background-color) style)]
[view {:style style}
@ -66,7 +67,7 @@
custom-action)]]
[sync-state-gradient-view]
(when-not hide-border?
[view st/toolbar-border-container
[view (merge st/toolbar-border-container border-style)
[view st/toolbar-border]])]))
(def search-text-input (r/atom nil))
@ -122,4 +123,3 @@
nav-action)
:custom-content [toolbar-with-search-content opts]
:actions actions}]))

View File

@ -20,7 +20,9 @@
[status-im.accounts.login.screen :refer [login]]
[status-im.accounts.recover.screen :refer [recover]]
[status-im.accounts.screen :refer [accounts]]
[status-im.transactions.screen :refer [confirm]]
[status-im.transactions.screens.confirmation-success :refer [confirmation-success]]
[status-im.transactions.screens.pending-transactions :refer [pending-transactions]]
[status-im.transactions.screens.transaction-details :refer [transaction-details]]
[status-im.chats-list.screen :refer [chats-list]]
[status-im.new-chat.screen :refer [new-chat]]
[status-im.new-group.screen-private :refer [new-group
@ -131,7 +133,9 @@
(let [component (case @modal-view
:qr-scanner qr-scanner
:qr-code-view qr-code-view
:confirm confirm
:pending-transactions pending-transactions
:transaction-details transaction-details
:confirmation-success confirmation-success
:contact-list-modal contact-list-modal)]
[component])]])]))))})))

View File

@ -22,7 +22,7 @@
;; && :navigation-replace <- on success
(defmethod nav/preload-data! :confirm
(defmethod nav/preload-data! :pending-transactions
[{:keys [transactions-queue] :as db} _]
(-> db
(assoc :transactions transactions-queue
@ -30,6 +30,14 @@
:wrong-password? false)
(assoc-in [:confirm-transactions :password] "")))
(defmethod nav/preload-data! :transaction-details
[db [_ _ transaction]]
(-> db
(assoc :selected-transaction transaction
:wrong-password-counter 0
:wrong-password? false)
(assoc-in [:confirm-transactions :password] "")))
(defn on-unlock
[ids password]
(dispatch [:set :wrong-password? false])
@ -47,6 +55,11 @@
(let [ids (keys transactions)]
(on-unlock ids password)))))
(register-handler :accept-transaction
(u/side-effect!
(fn [{:keys [transactions]} [_ password id]]
(on-unlock (list id) password))))
(register-handler :deny-transactions
(u/side-effect!
(fn [{:keys [transactions]}]
@ -56,8 +69,7 @@
(dispatch [::remove-pending-messages messages-ids])
(dispatch [::remove-transactions ids])
(doseq [id ids]
(dispatch [::discard-transaction id]))
(dispatch [:navigate-back])))))
(dispatch [::discard-transaction id]))))))
(register-handler :deny-transaction
(u/side-effect!
@ -80,9 +92,6 @@
(update :transactions-queue #(apply dissoc % hashes)))))
(register-handler ::remove-transaction
(after (fn [{:keys [modal]}]
(when (= :confirm modal)
(dispatch [:navigate-back]))))
(fn [db [_ hash]]
(-> db
(update :transactions dissoc hash)
@ -119,21 +128,22 @@
(status/discard-transaction id)))))
(register-handler ::transaction-queued
(after #(dispatch [:navigate-to-modal :confirm]))
(after #(dispatch [:navigate-to-modal :pending-transactions]))
(fn [db [_ {:keys [id message_id args]}]]
(let [{:keys [from to value]} args]
(let [{:keys [from to value data]} args]
(if (valid-hex? to)
(let [transaction {:id id
:from from
:to to
:value (.toDecimal js/Web3.prototype value)
:data data
:message-id message_id}]
(assoc-in db [:transactions-queue id] transaction))
db))))
(register-handler :transaction-completed
(u/side-effect!
(fn [{:keys [transactions]} [_ {:keys [id response]}]]
(fn [{:keys [transactions modal]} [_ {:keys [id response]}]]
(let [{:keys [hash error] :as parsed-response} (t/json->clj response)
{:keys [message-id]} (transactions id)]
(log/debug :parsed-response parsed-response)
@ -144,7 +154,10 @@
:message-id message-id}])
(dispatch [::check-completed-transaction!
{:message-id message-id}]))
(dispatch [::remove-transaction id])))))))
(dispatch [::remove-transaction id]))
(when (or (= modal :pending-transactions)
(= modal :transaction-details))
(dispatch [:navigate-to-modal :confirmation-success])))))))
(register-handler ::add-transactions-hash
(fn [db [_ {:keys [id hash message-id]}]]
@ -189,10 +202,15 @@
(not= discard-code error_code)
(do (when message_id
(dispatch [::remove-pending-message message_id]))
(dispatch [:clear-selected-transaction])
(dispatch [::remove-transaction id]))
:else nil))))
(register-handler :clear-selected-transaction
(fn [db _]
(dissoc db :selected-transaction)))
(def attempts-limit 3)
(register-handler :set-wrong-password!

View File

@ -1,62 +0,0 @@
(ns status-im.transactions.screen
(:require-macros [status-im.utils.views :refer [defview]])
(:require [re-frame.core :refer [subscribe dispatch]]
[status-im.components.react :refer [view
text
image
icon
scroll-view
touchable-highlight
touchable-opacity]]
[status-im.components.styles :refer [icon-ok
icon-close]]
[status-im.components.carousel.carousel :refer [carousel]]
[status-im.components.status-bar :refer [status-bar]]
[status-im.components.toolbar.view :refer [toolbar]]
[status-im.components.toolbar.styles :refer [toolbar-title-container]]
[status-im.components.text-field.view :refer [text-field]]
[status-im.transactions.views.transaction-page :refer [transaction-page]]
[status-im.transactions.styles :as st]
[status-im.i18n :refer [label label-pluralize]]
[clojure.string :as s]))
(defview confirm []
[transactions [:transactions]
{:keys [password]} [:get :confirm-transactions]
wrong-password? [:wrong-password?]]
[view st/transactions-screen
[status-bar {:type :transparent}]
[toolbar
{:style st/transactions-toolbar
:nav-action {:image {:source {:uri :icon_close_white}
:style icon-close}
:handler #(dispatch [:deny-transactions])}
:custom-content [view {:style toolbar-title-container}
[text {:style st/toolbar-title-text}
(label-pluralize (count transactions) :t/confirm-transactions)]]
:actions [{:image {:source {:uri (if-not (s/blank? password)
:icon_ok
:icon_ok_disabled_inversed)}
:style icon-ok}
:handler (when-not (s/blank? password)
#(dispatch [:accept-transactions password]))}]}]
[view st/carousel-container
[carousel {:pageStyle st/carousel-page-style
:gap 8
:sneak 16
:count (count transactions)}
(when transactions
(for [transaction transactions]
[transaction-page transaction]))]]
[view st/form-container
[text-field
{:editable true
:error (when wrong-password? (label :t/wrong-password))
:error-color :#ffffff80 #_:#7099e6
:label (label :t/password)
:secure-text-entry true
:label-color :#ffffff80
:line-color :white
:auto-capitalize :none
:input-style st/password-style
:on-change-text #(dispatch [:set-in [:confirm-transactions :password] %])}]]])

View File

@ -0,0 +1,25 @@
(ns status-im.transactions.screens.confirmation-success
(:require-macros [status-im.utils.views :refer [defview]])
(:require [re-frame.core :as rf]
[status-im.components.react :as rn]
[status-im.components.sticky-button :as sticky-button]
[status-im.components.status-bar :as status-bar]
[status-im.transactions.views.list-item :as transactions-list-item]
[status-im.transactions.styles.screens :as st]
[status-im.i18n :as i18n]))
(defview confirmation-success []
[quantity [:get :confirmed-transactions-count]]
[rn/view {:style st/success-screen}
[status-bar/status-bar {:type :transparent}]
[rn/view {:style st/success-screen-content-container}
[rn/view {:style st/success-icon-container}
[rn/image {:source {:uri :icon_ok_white}
:style st/success-icon}]]
[rn/view
[rn/text {:style st/success-text}
(i18n/label-pluralize quantity :t/transactions-confirmed)]]]
[sticky-button/sticky-button
(i18n/label :t/got-it)
#(do (rf/dispatch [:navigate-back])
(rf/dispatch [:set :confirmed-transactions-count 0]))]])

View File

@ -0,0 +1,69 @@
(ns status-im.transactions.screens.pending-transactions
(:require-macros [status-im.utils.views :refer [defview]])
(:require [re-frame.core :as rf]
[status-im.components.common.common :as common]
[status-im.components.react :as rn]
[status-im.components.sticky-button :as sticky-button]
[status-im.components.status-bar :as status-bar]
[status-im.components.toolbar-new.actions :as act]
[status-im.components.toolbar-new.view :as toolbar]
[status-im.transactions.views.list-item :as transactions-list-item]
[status-im.transactions.views.password-form :as password-form]
[status-im.transactions.styles.screens :as st]
[status-im.utils.listview :as lw]
[status-im.utils.platform :as platform]
[status-im.i18n :as i18n]))
(defn toolbar-view [transactions]
[toolbar/toolbar
{:background-color st/transactions-toolbar-background
:nav-action (act/close-white #(do (rf/dispatch [:deny-transactions])
(rf/dispatch [:navigate-back])))
:border-style st/toolbar-border
:custom-content [rn/view {:style st/toolbar-title-container}
[rn/text {:style st/toolbar-title-text
:font :toolbar-title}
(i18n/label :t/pending-transactions)]
[rn/text {:style st/toolbar-title-count
:font :toolbar-title}
(count transactions)]]}])
(defn render-separator-fn [transactions-count]
(fn [_ row-id _]
(when (< row-id (dec transactions-count))
(rn/list-item
^{:key row-id}
[common/separator {} st/transactions-list-separator]))))
(defn render-row-fn [row _ _]
(rn/list-item
[rn/touchable-highlight {:on-press #(rf/dispatch [:navigate-to-modal :transaction-details row])}
[rn/view
[transactions-list-item/view row]]]))
(defview pending-transactions []
[transactions [:transactions]
{:keys [password]} [:get :confirm-transactions]
confirmed? [:get-in [:transactions-list-ui-props :confirmed?]]]
{:component-did-update #(when-not (seq transactions) (rf/dispatch [:navigate-back]))
:component-will-unmount #(rf/dispatch [:set-in [:transactions-list-ui-props :confirmed?] false])}
[(if platform/ios? rn/keyboard-avoiding-view rn/view) (merge {:behavior :padding} st/transactions-screen)
[status-bar/status-bar {:type (if platform/ios? :transparent :main)}]
[toolbar-view transactions]
[rn/view {:style st/transactions-screen-content-container}
[rn/list-view {:style st/transactions-list
:dataSource (lw/to-datasource transactions)
:renderSeparator (render-separator-fn (count transactions))
:renderRow render-row-fn}]
(when confirmed?
[password-form/view (count transactions)])]
(let [confirm-text (if confirmed?
(i18n/label :t/confirm)
(i18n/label-pluralize (count transactions) :t/confirm-transactions))
confirm-fn (if confirmed?
#(do (rf/dispatch [:accept-transactions password])
(rf/dispatch [:set :confirmed-transactions-count (count transactions)]))
#(rf/dispatch [:set-in [:transactions-list-ui-props :confirmed?] true]))]
[sticky-button/sticky-button confirm-text confirm-fn])])

View File

@ -0,0 +1,70 @@
(ns status-im.transactions.screens.transaction-details
(:require-macros [status-im.utils.views :refer [defview]])
(:require [re-frame.core :as rf]
[status-im.components.react :as rn]
[status-im.components.common.common :as common]
[status-im.components.sticky-button :as sticky-button]
[status-im.components.status-bar :as status-bar]
[status-im.components.toolbar-new.actions :as act]
[status-im.components.toolbar-new.view :as toolbar]
[status-im.i18n :as i18n]
[status-im.transactions.styles.screens :as st]
[status-im.transactions.views.list-item :as transactions-list-item]
[status-im.transactions.views.password-form :as password-form]
[status-im.utils.platform :as platform]))
(defn toolbar-view []
[toolbar/toolbar
{:background-color st/transactions-toolbar-background
:nav-action (act/back-white #(rf/dispatch [:navigate-to-modal :pending-transactions]))
:border-style st/toolbar-border
:custom-content [rn/view {:style st/toolbar-title-container}
[rn/text {:style st/toolbar-title-text
:font :toolbar-title}
(i18n/label :t/transaction)]]}])
(defn detail-item [title content name?]
[rn/view {:style st/details-item}
[rn/text {:style st/details-item-title} title]
[rn/text {:style (st/details-item-content name?)
:number-of-lines 1}
content]])
(defn detail-data [content]
[rn/view {:style st/details-data}
[rn/text {:style st/details-data-title} (i18n/label :t/data)]
[rn/text {:style st/details-data-content} content]])
(defview details [{:keys [to data] :as transaction}]
[current-account [:get-current-account]
recipient [:contact-by-address to]]
(let [recipient-name (or (:name recipient) to)]
[rn/view
[detail-item (i18n/label :t/to) recipient-name true]
[detail-item (i18n/label :t/from) (:name current-account) true]
[detail-data data]]))
(defview transaction-details []
[{:keys [id] :as transaction} [:get :selected-transaction]
{:keys [password]} [:get :confirm-transactions]
confirmed? [:get-in [:transaction-details-ui-props :confirmed?]]]
{:component-did-update #(when-not transaction (rf/dispatch [:navigate-to-modal :pending-transactions]))
:component-will-unmount #(rf/dispatch [:set-in [:transaction-details-ui-props :confirmed?] false])}
[(if platform/ios? rn/keyboard-avoiding-view rn/view) (merge {:behavior :padding} st/transactions-screen)
[status-bar/status-bar {:type (if platform/ios? :transparent :main)}]
[toolbar-view]
[rn/scroll-view st/details-screen-content-container
[transactions-list-item/view transaction #(rf/dispatch [:navigate-to-modal :pending-transactions])]
(when platform/ios? [common/separator {} st/details-separator])
[details transaction]]
(when confirmed? [password-form/view 1])
(let [confirm-text (if confirmed?
(i18n/label :t/confirm)
(i18n/label-pluralize 1 :t/confirm-transactions))
confirm-fn (if confirmed?
#(do (rf/dispatch [:accept-transaction password id])
(rf/dispatch [:set :confirmed-transactions-count 1]))
#(rf/dispatch [:set-in [:transaction-details-ui-props :confirmed?] true]))]
[sticky-button/sticky-button confirm-text confirm-fn])])

View File

@ -1,105 +0,0 @@
(ns status-im.transactions.styles
(:require [status-im.components.styles :refer [color-gray
color-black]]))
(def transactions-screen
{:flex 1
:backgroundColor "#828b92"})
(def transactions-toolbar
{:backgroundColor "#828b92"
:elevation 0})
(def toolbar-title-text
{:color :white
:fontSize 16})
(def carousel-page-style
{})
(def form-container
{:flex 1
:paddingLeft 16})
(def password-style
{:color :white
:font-size 12})
;transaction-page
(def transaction-page
{:flex 1
:backgroundColor "#f3f4f4"})
(def title-bar
{:backgroundColor :white
:height 39
:justifyContent :center})
(def title-bar-text
{:color "#838c93"
:font-size 13
:margin-left 12
:margin-right 30})
(def icon-close-container
{:position :absolute
:right 12
:top 13})
(def icon-close
{:width 12
:height 12})
(def transaction-info-container
{:flex 1
:paddingTop 6})
(def scroll-view-container
{:flex 1})
(def scroll-view
{:flex 1
:height 175})
(def scroll-view-content
{:paddingVertical 6})
(def transaction-info-row
{:flex 1
:flexDirection :row})
(def transaction-info-column-title
{:flex 0.4
:flexDirection :column
:paddingHorizontal 6})
(def transaction-info-column-value
{:flex 0.6
:flexDirection :column
:paddingHorizontal 6})
(def transaction-info-item
{:flex 1
:padding 6})
(def transaction-info-title
{:textAlign :right
:color color-gray
:fontSize 14
:lineHeight 20})
(def transaction-info-value
{:color color-black
:fontSize 14
:lineHeight 20
})
(def scroll-view-item
{:flex 1
:height 20
:padding 6 })
(def carousel-container
{:min-height 215
:flex 1})

View File

@ -0,0 +1,52 @@
(ns status-im.transactions.styles.list-item
(:require-macros [status-im.utils.styles :refer [defstyle]])
(:require [status-im.components.styles :as st]))
(def item
{:padding-vertical 20
:padding-horizontal 16
:flex 1
:flex-direction :row
:align-items :center})
(def item-photo
{:width 86
:height 48
:border-radius 100
:background-color st/color-dark-blue-3
:flex-direction :row
:align-items :center})
(def item-info
{:margin-left 16
:flex 1})
(defstyle item-info-recipient
{:color st/color-light-blue
:font-size 15
:flex-shrink 1
:android {:margin-bottom 5}
:ios {:margin-bottom 4}})
(defstyle item-info-amount
{:color st/color-white
:android {:font-size 19}
:ios {:font-size 20}})
(def item-deny-btn
{:margin-left 16})
(def item-deny-btn-icon
{:width 24
:height 24})
(def photo-size 48)
(def photo-placeholder
{:width 48
:height 48})
(def item-photo-icon
{:margin-left 4
:width 24
:height 24})

View File

@ -0,0 +1,30 @@
(ns status-im.transactions.styles.password-form
(:require-macros [status-im.utils.styles :refer [defnstyle defstyle]])
(:require [status-im.components.styles :as st]))
(defnstyle password-container [error?]
{:margin-bottom (if error? 42 24)
:padding-left 16
:ios {:border-top-width 1
:border-top-color st/color-white-transparent-2}})
(def password-title
{:color st/color-white
:font-size 15
:margin-top 16
:margin-bottom 12})
(def password-input-wrapper
{:position :relative
:height 52
:padding-top 0
:padding-bottom 0
:margin-bottom 0})
(defstyle password-input
{:color :white
:height 52
:padding-left 0
:padding-top 24
:android {:font-size 16}
:ios {:font-size 17}})

View File

@ -0,0 +1,129 @@
(ns status-im.transactions.styles.screens
(:require-macros [status-im.utils.styles :refer [defstyle]])
(:require [status-im.components.styles :as st]
[status-im.utils.platform :as platform]))
;; common
(def transactions-toolbar-background (if platform/ios?
st/color-dark-blue-2
st/color-dark-blue-1))
(defstyle toolbar-title-container
{:flex 1
:flex-direction :row
:align-self :stretch
:padding-left 30
:ios {:align-items :center
:justify-content :center
:padding-bottom 16}})
(def toolbar-title-text
{:color st/color-white
:font-size 17})
(defstyle toolbar-title-count
{:color st/color-white
:font-size 17
:margin-left 8
:android {:opacity 0.2}
:ios {:opacity 0.6}})
(defstyle toolbar-border
{:ios {:background-color st/color-white
:opacity 0.1}})
;; pending-transactions
(def transactions-screen
{:flex 1
:background-color st/color-dark-blue-2})
(def transactions-screen-content-container
{:flex 1
:justify-content :space-between})
(defstyle transactions-list
{:flex 1
:android {:padding-vertical 8}})
(def transactions-list-separator
{:margin-left 16
:opacity 0.1})
;; transaction-details
(defstyle details-screen-content-container
{:flex 1
:android {:padding-top 8}})
(def details-separator
{:margin-bottom 10
:margin-left 16
:opacity 0.1})
(def details-item
{:margin-top 10
:padding-left 16
:padding-right 16
:flex-direction :row})
(defstyle details-item-title
{:width 80
:font-size 15
:color st/color-white
:android {:opacity 0.2
:margin-right 24}
:ios {:opacity 0.5
:margin-right 8
:text-align :right}})
(defn details-item-content [name?]
{:font-size 15
:flex-shrink 1
:color (if name? st/color-light-blue st/color-white)})
(defstyle details-data
{:margin-top 16
:padding 16
:background-color st/color-dark-blue-3
:ios {:margin-horizontal 16}})
(defstyle details-data-title
{:font-size 15
:color st/color-white
:android {:opacity 0.2}
:ios {:opacity 0.5}})
(def details-data-content
{:font-size 15
:color st/color-white
:margin-top 8})
;; confirmation-success
(def success-screen
{:flex 1
:background-color st/color-dark-blue-2})
(def success-screen-content-container
{:flex 1
:align-items :center
:justify-content :center})
(def success-icon-container
{:background-color st/color-light-blue
:border-radius 100
:height 133
:width 133
:justify-content :center
:align-items :center})
(def success-icon
{:height 40
:width 54})
(def success-text
{:font-size 17
:color st/color-light-blue3
:margin-top 26})

View File

@ -0,0 +1,39 @@
(ns status-im.transactions.views.list-item
(:require-macros [status-im.utils.views :refer [defview]])
(:require [re-frame.core :as rf]
[status-im.components.chat-icon.screen :as chat-icon]
[status-im.components.react :as rn]
[status-im.i18n :as i18n]
[status-im.transactions.styles.list-item :as st]))
(defview item-image [contact]
[rn/view {:style st/item-photo}
(if-not (empty? contact)
[chat-icon/chat-icon (:photo-path contact) {:size st/photo-size}]
[rn/view {:style st/photo-placeholder}])
[rn/image {:source {:uri :icon_arrow_left_white}
:style st/item-photo-icon}]])
(defn item-info [recipient-name value]
[rn/view {:style st/item-info}
[rn/text {:style st/item-info-recipient
:number-of-lines 1}
recipient-name]
[rn/text {:style st/item-info-amount} value]])
(defn deny-btn [transaction-id on-deny]
[rn/touchable-highlight {:on-press #(do (rf/dispatch [:deny-transaction transaction-id])
(when on-deny (on-deny)))}
[rn/view {:style st/item-deny-btn}
[rn/image {:source {:uri :icon_close_white}
:style st/item-deny-btn-icon}]]])
(defview view [{:keys [to value id] :as transaction} on-deny]
[recipient [:contact-by-address to]]
(let [eth-value (.fromWei js/Web3.prototype value "ether")
value (str (i18n/label-number eth-value) " ETH")
recipient-name (or (:name recipient) to)]
[rn/view {:style st/item}
[item-image recipient]
[item-info recipient-name value]
[deny-btn id on-deny]]))

View File

@ -0,0 +1,29 @@
(ns status-im.transactions.views.password-form
(:require-macros [status-im.utils.views :refer [defview]])
(:require [re-frame.core :as rf]
[status-im.components.react :as rn]
[status-im.components.styles :as common-st]
[status-im.components.text-field.view :as text-field]
[status-im.transactions.styles.password-form :as st]
[status-im.i18n :as i18n]))
(defview view [transaction-quantity]
[wrong-password? [:wrong-password?]]
(let [error? wrong-password?]
[rn/view (st/password-container error?)
[rn/text {:style st/password-title}
(i18n/label-pluralize transaction-quantity :t/enter-password-transactions)]
[text-field/text-field
{:editable true
:secure-text-entry true
:label-hidden? true
:error (when error? (i18n/label :t/wrong-password))
:error-color common-st/color-light-red2
:placeholder (i18n/label :t/password)
:placeholder-text-color common-st/color-white-transparent
:line-color common-st/color-light-blue
:focus-line-height 2
:wrapper-style st/password-input-wrapper
:input-style st/password-input
:auto-focus true
:on-change-text #(rf/dispatch [:set-in [:confirm-transactions :password] %])}]]))

View File

@ -1,50 +0,0 @@
(ns status-im.transactions.views.transaction-page
(:require-macros [status-im.utils.views :refer [defview]])
(:require [re-frame.core :refer [subscribe dispatch]]
[status-im.components.react :refer [view
text
image
icon
scroll-view
touchable-highlight
touchable-opacity]]
[status-im.components.styles :refer [icon-close]]
[status-im.transactions.styles :as st]
[status-im.i18n :refer [label label-pluralize label-number]]))
(defn title-bar [title id]
[view st/title-bar
[text {:style st/title-bar-text
:font :medium
:number-of-lines 1}
title]
[touchable-highlight {:style st/icon-close-container
:on-press #(dispatch [:deny-transaction id])}
[view [image {:source {:uri :icon_close_gray}
:style st/icon-close}]]]])
(defn transaction-info [index [name value]]
[view {:style st/transaction-info-item
:key index}
[view {:style st/transaction-info-row}
[view st/transaction-info-column-title
[text {:style st/transaction-info-title} name]]
[view st/transaction-info-column-value
[text {:style st/transaction-info-value} value]]]])
(defview transaction-page [{:keys [id from to value] :as transaction}]
[{:keys [name] :as contact} [:contact-by-address to]]
(let [eth-value (.fromWei js/Web3.prototype value "ether")
title (str (label-number eth-value) " ETH to " (or name to))
transactions-info [[(label :t/status) (label :t/pending-confirmation)]
[(label :t/recipient) (or name to)]
[(label :t/value) (str (label-number eth-value) " ETH")]]]
[view {:style st/transaction-page
:key id}
[title-bar title id]
[view st/scroll-view-container
[scroll-view {:style st/scroll-view
:contentContainerStyle st/scroll-view-content
:showsVerticalScrollIndicator true
:scrollEnabled true}
(map-indexed transaction-info transactions-info)]]]))

View File

@ -269,15 +269,27 @@
:not-enough-eth (str "Not enough ETH on balance "
"({{balance}} ETH)")
;transactions
:confirm "Confirm"
:confirm-transactions {:one "Confirm transaction"
:other "Confirm {{count}} transactions"
:zero "No transactions"}
:transactions-confirmed {:one "Transaction confirmed"
:other "{{count}} transactions confirmed"
:zero "No transactions confirmed"}
:transaction "Transaction"
:pending-transactions "Pending transactions"
:enter-password-transactions {:one "Enter your password to confirm the transaction"
:other "Enter your password to confirm the transactions"}
:status "Status"
:pending-confirmation "Pending confirmation"
:recipient "Recipient"
:one-more-item "One more item"
:fee "Fee"
:value "Value"
:to "To"
:from "From"
:data "Data"
:got-it "Got it"
;:webview
:web-view-error "oops, error"})