From d958c96d673751b19ae9f3f911f4ce70e89d9bc6 Mon Sep 17 00:00:00 2001 From: Julien Eluard Date: Thu, 18 Jan 2018 10:27:11 +0100 Subject: [PATCH] [ISSUE #2881] Updated wallet / send transaction to latest design Signed-off-by: Oskar Thoren --- package-lock.json | 6 +- package.json | 2 +- src/status_im/android/platform.cljs | 14 +- src/status_im/chat/screen.cljs | 23 +- src/status_im/chat/styles/input/input.cljs | 5 +- .../chat/styles/message/message.cljs | 5 +- src/status_im/ios/platform.cljs | 21 +- src/status_im/translations/en.cljs | 9 +- .../ui/components/action_button/styles.cljs | 22 +- src/status_im/ui/components/action_sheet.cljs | 16 +- .../ui/components/bottom_buttons/styles.cljs | 23 ++ .../ui/components/bottom_buttons/view.cljs | 21 ++ .../ui/components/button/styles.cljs | 47 ++-- src/status_im/ui/components/button/view.cljs | 37 ++- src/status_im/ui/components/camera.cljs | 13 +- .../ui/components/carousel/carousel.cljs | 46 ++-- .../ui/components/chat_icon/screen.cljs | 10 +- src/status_im/ui/components/colors.cljs | 9 +- src/status_im/ui/components/context_menu.cljs | 48 ++-- src/status_im/ui/components/dialog.cljs | 15 ++ src/status_im/ui/components/list/styles.cljs | 34 +-- src/status_im/ui/components/list/views.cljs | 15 +- .../ui/components/list_selection.cljs | 55 ++-- src/status_im/ui/components/permissions.cljs | 5 +- .../ui/components/qr_code_viewer/styles.cljs | 4 +- .../ui/components/status_bar/styles.cljs | 52 ++-- .../ui/components/status_bar/view.cljs | 3 +- src/status_im/ui/components/styles.cljs | 2 + .../ui/components/sync_state/gradient.cljs | 120 --------- .../ui/components/sync_state/styles.cljs | 28 +-- src/status_im/ui/components/toolbar/view.cljs | 160 ++++++------ .../ui/screens/accounts/login/styles.cljs | 8 +- .../ui/screens/accounts/login/views.cljs | 4 +- src/status_im/ui/screens/accounts/styles.cljs | 3 +- src/status_im/ui/screens/contacts/subs.cljs | 31 ++- src/status_im/ui/screens/contacts/views.cljs | 16 +- src/status_im/ui/screens/discover/styles.cljs | 7 +- .../ui/screens/group/chat_settings/views.cljs | 4 +- .../ui/screens/group/edit_contacts/views.cljs | 12 +- src/status_im/ui/screens/group/views.cljs | 8 +- src/status_im/ui/screens/home/views.cljs | 2 +- src/status_im/ui/screens/main_tabs/views.cljs | 2 +- .../ui/screens/network_settings/styles.cljs | 13 +- .../offline_messaging_settings/views.cljs | 3 +- .../ui/screens/profile/edit/views.cljs | 0 src/status_im/ui/screens/profile/styles.cljs | 4 +- src/status_im/ui/screens/profile/views.cljs | 51 ++-- .../ui/screens/qr_scanner/events.cljs | 8 +- src/status_im/ui/screens/views.cljs | 12 +- .../wallet/choose_recipient/events.cljs | 21 +- .../wallet/choose_recipient/styles.cljs | 133 ++++------ .../wallet/choose_recipient/views.cljs | 133 ++++------ .../ui/screens/wallet/components.cljs | 75 ++++++ .../screens/wallet/components/animations.cljs | 4 +- .../ui/screens/wallet/components/styles.cljs | 126 +++++----- .../ui/screens/wallet/components/views.cljs | 238 ++++++++++-------- src/status_im/ui/screens/wallet/db.cljs | 2 +- .../ui/screens/wallet/main/styles.cljs | 7 +- .../ui/screens/wallet/main/views.cljs | 17 +- .../ui/screens/wallet/request/styles.cljs | 5 +- .../ui/screens/wallet/request/views.cljs | 36 ++- src/status_im/ui/screens/wallet/send/db.cljs | 6 +- .../ui/screens/wallet/send/events.cljs | 5 - .../ui/screens/wallet/send/styles.cljs | 95 +++---- .../ui/screens/wallet/send/subs.cljs | 12 +- .../ui/screens/wallet/send/views.cljs | 224 +++++++---------- .../ui/screens/wallet/settings/views.cljs | 18 +- src/status_im/ui/screens/wallet/styles.cljs | 47 +++- .../screens/wallet/transactions/styles.cljs | 14 +- .../ui/screens/wallet/transactions/views.cljs | 124 +++++---- src/status_im/utils/identicon.cljs | 5 +- src/status_im/utils/utils.cljs | 7 + 72 files changed, 1126 insertions(+), 1286 deletions(-) create mode 100644 src/status_im/ui/components/bottom_buttons/styles.cljs create mode 100644 src/status_im/ui/components/bottom_buttons/view.cljs create mode 100644 src/status_im/ui/components/dialog.cljs delete mode 100644 src/status_im/ui/components/sync_state/gradient.cljs create mode 100644 src/status_im/ui/screens/profile/edit/views.cljs create mode 100644 src/status_im/ui/screens/wallet/components.cljs diff --git a/package-lock.json b/package-lock.json index c09fc2a90b..6b6ab9cb4e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7885,9 +7885,9 @@ "integrity": "sha1-v74cRNilsUpvOjpAXYrab1R6UW4=" }, "react-native-popup-menu": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/react-native-popup-menu/-/react-native-popup-menu-0.8.3.tgz", - "integrity": "sha1-HbsLT4iclBC2myKKidV7Vq6lzC4=" + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/react-native-popup-menu/-/react-native-popup-menu-0.12.2.tgz", + "integrity": "sha1-ZWi1LPZFZj8GClUPIyQfoVUr+g4=" }, "react-native-qrcode": { "version": "0.2.6", diff --git a/package.json b/package.json index e4b57fe843..6f7c2df352 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "react-native-linear-gradient": "2.4.0", "react-native-orientation": "3.1.0", "react-native-os": "1.1.0", - "react-native-popup-menu": "0.8.3", + "react-native-popup-menu": "0.12.2", "react-native-qrcode": "0.2.6", "react-native-randombytes": "3.0.0", "react-native-sortable-listview": "0.2.6", diff --git a/src/status_im/android/platform.cljs b/src/status_im/android/platform.cljs index 77dde04f0f..8dd8734f63 100644 --- a/src/status_im/android/platform.cljs +++ b/src/status_im/android/platform.cljs @@ -1,5 +1,4 @@ -(ns status-im.android.platform - (:require [status-im.react-native.js-dependencies :as rn-dependencies])) +(ns status-im.android.platform) (def fonts {:light {:font-family "Roboto-Light"} @@ -9,21 +8,10 @@ :toolbar-title {:font-family "Roboto-Regular"} :roboto-mono {:font-family "RobotoMono-Medium"}}) -;; Dialogs - -(defn show-dialog [{:keys [title options callback]}] - (let [dialog (new rn-dependencies/dialogs)] - (.set dialog (clj->js {:title title - :items (mapv :text options) - :itemsCallback callback})) - (.show dialog))) - - ;; Structure to be exported (def platform-specific {:fonts fonts - :list-selection-fn show-dialog :tabs {:tab-shadows? true} :chats {:action-button? true :new-chat-in-toolbar? false diff --git a/src/status_im/chat/screen.cljs b/src/status_im/chat/screen.cljs index 5aee3a79c8..f88d0e4b23 100644 --- a/src/status_im/chat/screen.cljs +++ b/src/status_im/chat/screen.cljs @@ -17,14 +17,13 @@ [status-im.ui.components.icons.vector-icons :as vector-icons] [status-im.ui.components.status-bar.view :as status-bar] [status-im.ui.components.chat-icon.screen :as chat-icon-screen] - [status-im.ui.components.animation :as anim] - [status-im.ui.components.animation :as anim] [status-im.ui.components.sync-state.offline :as offline] - [status-im.ui.components.toolbar.view :as toolbar])) + [status-im.ui.components.toolbar.view :as toolbar] + [status-im.ui.components.animation :as animation])) (defview chat-icon [] - (letsubs [{:keys [chat-id group-chat name color]} [:get-current-chat]] - [chat-icon-screen/chat-icon-view-action chat-id group-chat name color true])) + (letsubs [{:keys [chat-id group-chat name]} [:get-current-chat]] + [chat-icon-screen/chat-icon-view-action chat-id group-chat name true])) (defn- toolbar-action [show-actions?] [react/touchable-highlight @@ -51,7 +50,7 @@ creating? [:get :accounts/creating-account?]] [react/view [status-bar/status-bar] - [toolbar/toolbar {:show-sync-bar? true} + [toolbar/toolbar {} (when-not (or show-actions? creating?) (if (empty? accounts) [toolbar/nav-clear-text (i18n/label :t/recover) @@ -76,15 +75,15 @@ (defview messages-view-animation [message-view] ;; smooths out appearance of message-view - (letsubs [opacity (anim/create-value 0) + (letsubs [opacity (animation/create-value 0) duration (if platform/android? 100 200) timeout (if platform/android? 50 0)] {:component-did-mount (fn [component] - (anim/start - (anim/anim-sequence - [(anim/anim-delay timeout) - (anim/spring opacity {:toValue 1 - :duration duration})])))} + (animation/start + (animation/anim-sequence + [(animation/anim-delay timeout) + (animation/spring opacity {:toValue 1 + :duration duration})])))} [react/with-activity-indicator {:style style/message-view-preview :preview [react/view style/message-view-preview]} diff --git a/src/status_im/chat/styles/input/input.cljs b/src/status_im/chat/styles/input/input.cljs index de84a80224..66cbb5a4c8 100644 --- a/src/status_im/chat/styles/input/input.cljs +++ b/src/status_im/chat/styles/input/input.cljs @@ -36,7 +36,7 @@ {:flex-direction :row :align-items :flex-end}) -(defnstyle input-root [content-height anim-margin] +(defn input-root [content-height anim-margin] {:align-items :flex-start :background-color color-input :flex-direction :row @@ -45,8 +45,7 @@ :margin-top anim-margin :padding-left 10 :padding-right 10 - :android {:border-radius 4} - :ios {:border-radius 8}}) + :border-radius 8}) (defnstyle input-touch-handler-view [container-width] {:position :absolute diff --git a/src/status_im/chat/styles/message/message.cljs b/src/status_im/chat/styles/message/message.cljs index a8f10156d2..59c1387537 100644 --- a/src/status_im/chat/styles/message/message.cljs +++ b/src/status_im/chat/styles/message/message.cljs @@ -95,12 +95,11 @@ (merge style-message-text {:marginTop (if incoming-group 4 0)})) -(defnstyle message-view +(defn message-view [{:keys [content-type outgoing group-chat selected]}] (merge {:padding 12 :backgroundColor styles/color-white - :android {:border-radius 4} - :ios {:border-radius 8}} + :border-radius 8} (when (= content-type constants/content-type-command) {:paddingTop 10 :paddingBottom 14}))) diff --git a/src/status_im/ios/platform.cljs b/src/status_im/ios/platform.cljs index af08549638..440b07d62b 100644 --- a/src/status_im/ios/platform.cljs +++ b/src/status_im/ios/platform.cljs @@ -1,7 +1,4 @@ -(ns status-im.ios.platform - (:require [status-im.i18n :refer [label]] - [status-im.utils.core :as utils] - [status-im.react-native.js-dependencies :as rn-dependencies])) +(ns status-im.ios.platform) (def fonts {:light {:font-family "SFUIText-Light"} @@ -12,26 +9,10 @@ :toolbar-title {:font-family "SFUIText-Semibold"} :roboto-mono {:font-family "RobotoMono-Medium"}}) -;; Dialogs - -(defn action-sheet-options [options] - (let [destructive-opt-index (utils/first-index :destructive? options) - cancel-option {:text (label :t/cancel)} - options (conj options cancel-option)] - (clj->js (merge {:options (mapv :text options) - :cancelButtonIndex (dec (count options))} - (when destructive-opt-index {:destructiveButtonIndex destructive-opt-index}))))) - -(defn show-action-sheet [{:keys [options callback]}] - (.showActionSheetWithOptions (.-ActionSheetIOS rn-dependencies/react-native) - (action-sheet-options options) - callback)) - ;; Structure to be exported (def platform-specific {:fonts fonts - :list-selection-fn show-action-sheet :tabs {:tab-shadows? false} :chats {:action-button? false :new-chat-in-toolbar? true diff --git a/src/status_im/translations/en.cljs b/src/status_im/translations/en.cljs index 90c5624672..f00050e99a 100644 --- a/src/status_im/translations/en.cljs +++ b/src/status_im/translations/en.cljs @@ -263,6 +263,10 @@ :unsigned-transaction-expired "Unsigned transaction expired" :status "Status" :recipient "Recipient" + :specify-recipient "Specify recipient..." + :recipient-code "Enter recipient address" + :enter-contact-code "Enter Contact Code" + :recent-recipients "Recent recipients" :to "To" :from "From" :data "Data" @@ -312,9 +316,10 @@ :send-request "Send request" :share "Share" :eth "ETH" + :gwei "Gwei" :currency "Currency" :usd-currency "USD" - :amount-placeholder "Specify amount" + :amount-placeholder "Specify amount..." :transactions "Transactions" :transaction-details "Transaction details" :transaction-failed "Transaction failed" @@ -342,6 +347,7 @@ :not-applicable "Not applicable for unsigned transactions" :send-transaction "Send transaction" :receive-transaction "Receive transaction" + :new-transaction "New Transaction" :transaction-history "Transaction History" ;; Wallet Send @@ -357,6 +363,7 @@ :wallet-transaction-total-fee "Total Fee" :validation-amount-invalid-number "Amount is not a valid number" :validation-amount-is-too-precise "Amount is too precise. The smallest unit you can send is 1 Wei (1x10^-18 ETH)" + :scan-qr-code "Scan a QR code with a wallet address" diff --git a/src/status_im/ui/components/action_button/styles.cljs b/src/status_im/ui/components/action_button/styles.cljs index ee680e0cf0..848cf6c814 100644 --- a/src/status_im/ui/components/action_button/styles.cljs +++ b/src/status_im/ui/components/action_button/styles.cljs @@ -1,12 +1,6 @@ (ns status-im.ui.components.action-button.styles (:require-macros [status-im.utils.styles :refer [defstyle defnstyle]]) - (:require [status-im.utils.platform :as p] - [status-im.ui.components.styles :refer [color-white - color-light-blue-transparent - color-light-blue - color-light-gray - color-black - color-gray4]])) + (:require [status-im.ui.components.styles :as styles])) (defstyle action-button {:padding-left 16 @@ -15,34 +9,34 @@ :ios {:height 63} :android {:height 56}}) -(defnstyle action-button-icon-container [cyrcle-color] +(defnstyle action-button-icon-container [circle-color] {:border-radius 50 :width 40 :height 40 :align-items :center :justify-content :center - :ios {:background-color (or cyrcle-color color-light-blue-transparent)}}) + :ios {:background-color (or circle-color styles/color-light-blue-transparent)}}) (def action-button-label-container {:padding-left 16}) (defstyle action-button-label - {:ios {:color color-light-blue + {:ios {:color styles/color-light-blue :letter-spacing -0.2 :font-size 17 :line-height 20} - :android {:color color-black + :android {:color styles/color-black :font-size 16}}) (defstyle actions-list - {:background-color color-white + {:background-color styles/color-white :android {:padding-top 8 :padding-bottom 8}}) (def action-button-label-disabled (merge action-button-label - {:color color-gray4})) + {:color styles/color-gray4})) (defstyle action-button-icon-container-disabled {:border-radius 50 @@ -50,5 +44,5 @@ :height 40 :align-items :center :justify-content :center - :ios {:background-color color-light-gray}}) + :ios {:background-color styles/color-light-gray}}) diff --git a/src/status_im/ui/components/action_sheet.cljs b/src/status_im/ui/components/action_sheet.cljs index 277a17c47c..91bcef8ebb 100644 --- a/src/status_im/ui/components/action_sheet.cljs +++ b/src/status_im/ui/components/action_sheet.cljs @@ -6,19 +6,19 @@ (defn- callback [options] (fn [index] (when (< index (count options)) - (when-let [handler (:actione (nth options index))] + (when-let [handler (:action (nth options index))] (handler))))) -(defn- options [options] +(defn- prepare-options [title message options] (let [destructive-opt-index (utils/first-index :destructive? options)] ;; TODO Can only be a single destructive? (clj->js (merge {:options (conj (mapv :label options) (i18n/label :t/cancel)) :cancelButtonIndex (count options)} (when destructive-opt-index - {:destructiveButtonIndex destructive-opt-index}))))) + {:destructiveButtonIndex destructive-opt-index}) + (when title {:title title}) + (when message {:message message}))))) -(defn show [{:keys [title message options callback]}] +(defn show [{:keys [title message options]}] (.showActionSheetWithOptions (.-ActionSheetIOS rn-dependencies/react-native) - (merge (options options) - (when title {:title title}) - (when message {:message message})) - callback)) + (prepare-options title message options) + (callback options))) diff --git a/src/status_im/ui/components/bottom_buttons/styles.cljs b/src/status_im/ui/components/bottom_buttons/styles.cljs new file mode 100644 index 0000000000..34a258aea2 --- /dev/null +++ b/src/status_im/ui/components/bottom_buttons/styles.cljs @@ -0,0 +1,23 @@ +(ns status-im.ui.components.bottom-buttons.styles + (:require [status-im.ui.components.colors :as colors])) + +(def wrapper + {:position :absolute + :bottom 0 + :left 0 + :right 0}) + +(def border + {:margin-horizontal 16 + :border-top-width 1 + :border-color colors/white-light-transparent}) + +(def container + {:flex-direction :row + :align-items :center + :justify-content :space-between}) + +(def container-single + {:flex-direction :row + :align-items :center + :justify-content :center}) diff --git a/src/status_im/ui/components/bottom_buttons/view.cljs b/src/status_im/ui/components/bottom_buttons/view.cljs new file mode 100644 index 0000000000..62d7a27d38 --- /dev/null +++ b/src/status_im/ui/components/bottom_buttons/view.cljs @@ -0,0 +1,21 @@ +(ns status-im.ui.components.bottom-buttons.view + (:require [status-im.ui.components.bottom-buttons.styles :as styles] + [status-im.ui.components.react :as react])) + +(defn bottom-button + ([button] (bottom-button nil button)) + ([style button] + [react/view styles/wrapper + [react/view styles/border] + [react/view (merge styles/container-single style) + button]])) + +(defn bottom-buttons + ([left right] (bottom-buttons nil left right)) + ([style left right] + [react/view styles/wrapper + [react/view styles/border] + [react/view (merge styles/container style) + left + [react/view {:flex 1}] + right]])) diff --git a/src/status_im/ui/components/button/styles.cljs b/src/status_im/ui/components/button/styles.cljs index 277137ce23..9046577a6f 100644 --- a/src/status_im/ui/components/button/styles.cljs +++ b/src/status_im/ui/components/button/styles.cljs @@ -10,13 +10,12 @@ (def button-container styles/flex) -(defnstyle button [disabled?] - {:flex-direction :row - :justify-content :center - :align-items :center - :android {:background-color border-color} - :ios (when-not disabled? - {:background-color border-color})}) +(def button + {:flex-direction :row + :justify-content :center + :align-items :center + :padding-horizontal 12}) + (defn- border [position] (let [radius (if platform/ios? 8 4)] @@ -39,27 +38,27 @@ (merge {:border-color border-color} (border position))) -(defnstyle button-text [disabled?] +(defstyle button-text {:font-weight :normal :color styles/color-white :padding-horizontal 16 - :android (merge - {:font-size 14 - :padding-vertical 10 - :letter-spacing 0.5} - (when disabled? {:opacity 0.4})) - :ios (merge - {:font-size 15 - :padding-vertical 9 - :letter-spacing -0.2} - (when disabled? {:opacity 0.6}))}) + :android {:font-size 14 + :padding-vertical 10 + :letter-spacing 0.5} + :ios {:font-size 15 + :padding-vertical 9 + :letter-spacing -0.2}}) + +(defstyle button-text-disabled + {:android {:opacity 0.4} + :ios {:opacity 0.6}}) + (defstyle button-borders - {:android {:border-radius 4} - :ios {:border-radius 8 - ;; Border radius is ignored with transparent background unless overflow "hidden" is used - ;; See https://github.com/facebook/react-native/issues/13760 - :overflow :hidden}}) + {:border-radius 8 + :ios {;; Border radius is ignored with transparent background unless overflow "hidden" is used + ;; See https://github.com/facebook/react-native/issues/13760 + :overflow :hidden}}) (def primary-button (merge @@ -73,4 +72,4 @@ button-borders {:background-color styles/color-blue4-transparent})) -(def secondary-button-text {:color styles/color-blue4}) \ No newline at end of file +(def secondary-button-text {:color styles/color-blue4}) diff --git a/src/status_im/ui/components/button/view.cljs b/src/status_im/ui/components/button/view.cljs index 9b92dded55..13e1b41884 100644 --- a/src/status_im/ui/components/button/view.cljs +++ b/src/status_im/ui/components/button/view.cljs @@ -1,36 +1,33 @@ (ns status-im.ui.components.button.view - (:require [status-im.ui.components.button.styles :as button.styles] + (:require [status-im.ui.components.button.styles :as styles] [status-im.ui.components.react :as react] [status-im.utils.platform :as platform])) -(defn button-text [{:keys [disabled? text-style]} label] - [react/text {:style (merge (button.styles/button-text disabled?) - text-style) - :font (if platform/android? :medium :default) - :uppercase? (get-in platform/platform-specific [:uppercase?])} - label]) - -(defn button [{:keys [on-press style disabled? fit-to-text?] :as props} label] - [react/touchable-highlight (merge {:underlay-color button.styles/border-color-high} +(defn button [{:keys [on-press style disabled? fit-to-text? text-style] :or {fit-to-text? true}} label icon] + [react/touchable-highlight (merge {:underlay-color styles/border-color-high} (when-not fit-to-text? - {:style button.styles/button-container}) + {:style styles/button-container}) (when (and on-press (not disabled?)) {:on-press on-press})) - [react/view {:style (merge (button.styles/button disabled?) + [react/view {:style (merge styles/button style)} - [button-text props - label]]]) + [react/text {:style (merge styles/button-text + text-style + (when disabled? + {:opacity 0.4})) + :font (if platform/android? :medium :default) + :uppercase? (get-in platform/platform-specific [:uppercase?])} + label] + icon]]) (defn primary-button [{:keys [style text-style] :as m} label] [button (assoc m - :fit-to-text? true - :style (merge button.styles/primary-button style) - :text-style (merge button.styles/primary-button-text text-style)) + :style (merge styles/primary-button style) + :text-style (merge styles/primary-button-text text-style)) label]) (defn secondary-button [{:keys [style text-style] :as m} label] [button (assoc m - :fit-to-text? true - :style (merge button.styles/secondary-button style) - :text-style (merge button.styles/secondary-button-text text-style)) + :style (merge styles/secondary-button style) + :text-style (merge styles/secondary-button-text text-style)) label]) diff --git a/src/status_im/ui/components/camera.cljs b/src/status_im/ui/components/camera.cljs index 7f053f441e..831bb047e5 100644 --- a/src/status_im/ui/components/camera.cljs +++ b/src/status_im/ui/components/camera.cljs @@ -2,7 +2,6 @@ (:require [goog.object :as object] [reagent.core :as r] [clojure.walk :refer [keywordize-keys]] - [status-im.utils.platform :as platform] [status-im.react-native.js-dependencies :as rn-dependecies])) (def default-camera (.-default rn-dependecies/camera)) @@ -19,15 +18,13 @@ (defn set-torch [state] (set! (.-torchMode default-camera) (get torch-modes state))) -(defn request-access [callback] - (if platform/android? - (callback true) - (-> (.checkVideoAuthorizationStatus default-camera) - (.then #(callback %)) - (.catch #(callback false))))) +(defn request-access-ios [then else] + (-> (.checkVideoAuthorizationStatus default-camera) + (.then then) + (.catch else))) (defn camera [props] (r/create-element default-camera (clj->js (merge {:inverted true} props)))) (defn get-qr-code-data [code] - (.-data code)) \ No newline at end of file + (.-data code)) diff --git a/src/status_im/ui/components/carousel/carousel.cljs b/src/status_im/ui/components/carousel/carousel.cljs index 66435f0fb3..3b82c4aefb 100644 --- a/src/status_im/ui/components/carousel/carousel.cljs +++ b/src/status_im/ui/components/carousel/carousel.cljs @@ -1,12 +1,8 @@ (ns status-im.ui.components.carousel.carousel (:require [reagent.impl.component :as rc] - [status-im.ui.components.react :refer [view - scroll-view - touchable-without-feedback - text]] + [status-im.ui.components.react :as react] [status-im.ui.components.carousel.styles :as st] [taoensso.timbre :as log] - [status-im.ui.components.react :as r] [status-im.react-native.js-dependencies :as rn-dependencies])) @@ -160,15 +156,15 @@ gap (get-gap data) count (get-count data)] (doall (map-indexed (fn [index child] - (let [page-index index - touchable-data {:key index - :onPress #(go-to-page component page-index)}] - [touchable-without-feedback touchable-data - [view {:style [(st/page index count page-width gap) - page-style] - :onLayout #(log/debug "view onLayout" %)} + (let [page-index index + touchable-data {:key index + :onPress #(go-to-page component page-index)}] + [react/touchable-without-feedback touchable-data + [react/view {:style [(st/page index count page-width gap) + page-style] + :onLayout #(log/debug "view onLayout" %)} - child]])) children)))) + child]])) children)))) (defn reagent-render [data children] (let [starting-position (atom 0) @@ -176,18 +172,18 @@ state (reagent.core/state component) gap (get-gap state)] (log/debug "reagent-render: " data state) - [view {:style st/scroll-view-container} - [scroll-view {:contentContainerStyle (st/content-container gap) - :automaticallyAdjustContentInsets false - :bounces false - :decelerationRate 0.9 - :horizontal true - :onLayout #(on-layout-change % component) - :scrollEnabled (not (get state :scrolling?)) - :onScrollBeginDrag #(reset! starting-position (get-current-position %)) - :onScrollEndDrag #(on-scroll-end % component @starting-position) - :showsHorizontalScrollIndicator false - :ref #(set! (.-scrollView component) %)} + [react/view {:style st/scroll-view-container} + [react/scroll-view {:contentContainerStyle (st/content-container gap) + :automaticallyAdjustContentInsets false + :bounces false + :decelerationRate 0.9 + :horizontal true + :onLayout #(on-layout-change % component) + :scrollEnabled (not (get state :scrolling?)) + :onScrollBeginDrag #(reset! starting-position (get-current-position %)) + :onScrollEndDrag #(on-scroll-end % component @starting-position) + :showsHorizontalScrollIndicator false + :ref #(set! (.-scrollView component) %)} (get-pages component state children)]])) (defn carousel [_ _] diff --git a/src/status_im/ui/components/chat_icon/screen.cljs b/src/status_im/ui/components/chat_icon/screen.cljs index 8399fa3ef6..5b2db9ab0f 100644 --- a/src/status_im/ui/components/chat_icon/screen.cljs +++ b/src/status_im/ui/components/chat_icon/screen.cljs @@ -1,11 +1,11 @@ (ns status-im.ui.components.chat-icon.screen (:require-macros [status-im.utils.views :refer [defview letsubs]]) - (:require [status-im.ui.components.react :as react] + (:require [clojure.string :as string] + [status-im.i18n :as i18n] + [status-im.ui.components.react :as react] [status-im.ui.components.chat-icon.styles :as styles] [status-im.ui.components.styles :as components.styles] - [status-im.react-native.resources :as resources] - [clojure.string :as string] - [status-im.i18n :as i18n])) + [status-im.react-native.resources :as resources])) (defn default-chat-icon [name styles] [react/view (:default-chat-icon styles) @@ -64,7 +64,7 @@ :default-chat-icon (styles/default-chat-icon-chat-list color) :default-chat-icon-text styles/default-chat-icon-text}]) -(defn chat-icon-view-action [chat-id group-chat name _color online] +(defn chat-icon-view-action [chat-id group-chat name online] ^{:key chat-id} [chat-icon-view chat-id group-chat name online {:container styles/container-chat-list diff --git a/src/status_im/ui/components/colors.cljs b/src/status_im/ui/components/colors.cljs index 8bb96b059f..be5e8cd0db 100644 --- a/src/status_im/ui/components/colors.cljs +++ b/src/status_im/ui/components/colors.cljs @@ -3,9 +3,12 @@ (def white "#ffffff") (def white-light-transparent "rgba(255, 255, 255, 0.1)") ;; Used as icon background color for a dark foreground (def white-transparent "rgba(255, 255, 255, 0.2)") ;; Used as icon color on dark background -(def blue "#4360df") ;; Used as main wallet color +(def white-lighter-transparent "rgba(255, 255, 255, 0.6)") ;; Used for input placeholder color (def black "#000000") ;; Used as the default text color -(def gray "#939ba1") ;; Used as a background for a light foreground and for text descriptions +(def gray "#939ba1") ;; Used as a background for a light foreground and as section header and secondary text color +(def gray-light "#d9dae1") ;; Used as divider color +(def gray-lighter "#eef2f5") ;; Used as a background or shadow +(def blue "#4360df") ;; Used as main wallet color (def red "#ff2d55") ;; Used to highlight errors or "dangerous" actions (def light-gray "#eef2f5") ;; Used as a background or shadow -(def text-light-gray "#212121") ;; Used for labels (home items) \ No newline at end of file +(def text-light-gray "#212121") ;; Used for labels (home items) diff --git a/src/status_im/ui/components/context_menu.cljs b/src/status_im/ui/components/context_menu.cljs index 3300bb9b93..5cbbf6a50f 100644 --- a/src/status_im/ui/components/context_menu.cljs +++ b/src/status_im/ui/components/context_menu.cljs @@ -1,16 +1,17 @@ (ns status-im.ui.components.context-menu - (:require [goog.object :as object] + (:require [status-im.react-native.js-dependencies :as rn-dependencies] + [status-im.ui.components.action-sheet :as action-sheet] + [status-im.ui.components.react :as react] + [goog.object :as object] [reagent.core :as r] [status-im.ui.components.styles :as st] - [status-im.utils.platform :refer [platform-specific ios?]] - [status-im.ui.components.react :as rn] - [status-im.react-native.js-dependencies :as rn-dependencies])) + [status-im.utils.platform :as platform])) (defn- get-property [name] (object/get rn-dependencies/popup-menu name)) (defn- get-class [name] - (rn/adapt-class (get-property name))) + (react/adapt-class (get-property name))) (def menu (get-class "Menu")) (def menu-context (get-class "MenuContext")) @@ -18,7 +19,7 @@ (def menu-options (get-class "MenuOptions")) (def menu-option (get-class "MenuOption")) -(defn context-menu-options [custom-styles] +(defn- context-menu-options [custom-styles] {:customStyles {:optionsContainer (merge {:elevation 2 :margin-top 0 @@ -33,39 +34,22 @@ :height 48} (:optionWrapper custom-styles))}}) -(defn context-menu-text [destructive?] +(defn- context-menu-text [destructive?] {:font-size 15 :line-height 20 :color (if destructive? st/color-light-red st/text1-color)}) -(def list-selection-fn (:list-selection-fn platform-specific)) - -(defn open-ios-menu [title options] - (list-selection-fn {:options options - :title title - :callback (fn [index] - (when (< index (count options)) - (when-let [handler (:value (nth options index))] - (handler))))}) - nil) - (defn context-menu [trigger options & custom-styles trigger-style] - (if ios? - [rn/touchable-highlight {:style trigger-style - :on-press #(open-ios-menu nil options)} - [rn/view + (if platform/ios? + [react/touchable-highlight {:style trigger-style + :on-press #(action-sheet/show options)} + [react/view trigger]] [menu {:onSelect #(when % (do (%) nil))} [menu-trigger {:style trigger-style} trigger] [menu-options (context-menu-options custom-styles) - (for [{:keys [style value destructive?] :as option} options] + (for [{:keys [style action destructive?] :as option} options] ^{:key option} - [menu-option {:value value} - [rn/text {:style (merge (context-menu-text destructive?) style)} - (:text option)]])]])) - -(defn modal-menu [trigger style title options] - [rn/touchable-highlight {:style style - :on-press #(open-ios-menu title options)} - [rn/view - trigger]]) + [menu-option {:value action} + [react/text {:style (merge (context-menu-text destructive?) style)} + (:label option)]])]])) diff --git a/src/status_im/ui/components/dialog.cljs b/src/status_im/ui/components/dialog.cljs new file mode 100644 index 0000000000..dcf310f76d --- /dev/null +++ b/src/status_im/ui/components/dialog.cljs @@ -0,0 +1,15 @@ +(ns status-im.ui.components.dialog + (:require [status-im.react-native.js-dependencies :as rn-dependencies])) + +(defn- callback [options] + (fn [index] + (when (< index (count options)) + (when-let [handler (:action (nth options index))] + (handler))))) + +(defn- show [{:keys [title options]}] + (let [dialog (new rn-dependencies/dialogs)] + (.set dialog (clj->js {:title title + :items (mapv :label options) + :itemsCallback (callback options)})) + (.show dialog))) diff --git a/src/status_im/ui/components/list/styles.cljs b/src/status_im/ui/components/list/styles.cljs index 24546eea2b..60c685fe32 100644 --- a/src/status_im/ui/components/list/styles.cljs +++ b/src/status_im/ui/components/list/styles.cljs @@ -1,7 +1,6 @@ (ns status-im.ui.components.list.styles (:require-macros [status-im.utils.styles :refer [defstyle]]) - (:require [status-im.ui.components.styles :as styles] - [status-im.utils.platform :as platform])) + (:require [status-im.ui.components.colors :as colors])) (def item {:flex-direction :row @@ -19,25 +18,27 @@ :justify-content :center}) (def primary-text-base - {:font-size 17 - :color styles/color-black}) + {:font-size 16 + :color colors/black}) (def primary-text (merge primary-text-base - {:padding-top (if platform/ios? 13 14)})) + {:padding-top 12})) (def primary-text-only (merge primary-text-base {:padding-vertical 16})) (def secondary-text - {:font-size 16 - :color styles/color-gray4 + {:font-size 14 + :color colors/gray :padding-top 4}) +(def image-size 40) + (def item-image - {:width 40 - :height 40}) + {:width image-size + :height image-size}) (def icon-size 24) (def icon-wrapper-size (+ icon-size (* 2 8))) @@ -61,9 +62,9 @@ :margin-vertical vertical-margin}) (def content-item-wrapper - {:flex 1 - :justify-content :center - :margin-left horizontal-margin}) + {:flex 1 + :justify-content :center + :margin-horizontal horizontal-margin}) (def right-item-wrapper {:justify-content :center @@ -71,16 +72,15 @@ (def base-separator {:height 1 - :background-color styles/color-gray5 - :opacity 0.5}) + :background-color colors/gray-light}) (def separator (merge base-separator - {:margin-left 70})) + {:margin-left 70})) (defstyle list-header-footer-spacing - {:android {:background-color styles/color-white + {:android {:background-color colors/white :height 8}}) (defstyle section-separator @@ -90,7 +90,7 @@ (defstyle section-header {:font-size 14 - :color styles/color-gray4 + :color colors/gray :margin-left 16 :android {:margin-top 11 :margin-bottom 3} diff --git a/src/status_im/ui/components/list/views.cljs b/src/status_im/ui/components/list/views.cljs index cf3a6d47b6..b486bcc4d2 100644 --- a/src/status_im/ui/components/list/views.cljs +++ b/src/status_im/ui/components/list/views.cljs @@ -31,20 +31,21 @@ (defn item ([content] (item nil content)) - ([left-action content] (item left-action content nil)) - ([left-action content right-action] + ([left content] (item left content nil)) + ([left content right] [react/view {:style styles/item} [react/view {:style styles/left-item-wrapper} - left-action] + left] [react/view {:style styles/content-item-wrapper} content] - (when right-action + (when right [react/view {:style styles/right-item-wrapper} - right-action])])) + right])])) (defn touchable-item [handler item] [react/touchable-highlight {:on-press handler} - item]) + [react/view + item]]) (defn item-icon [{:keys [icon style icon-opts]}] @@ -84,7 +85,7 @@ (def item-icon-forward [item-icon {:style styles/item-icon :icon :icons/forward - :icon-opts {:color colors/white-transparent}}]) + :icon-opts {:color colors/white-light-transparent}}]) (defn- wrap-render-fn [f] (fn [data] diff --git a/src/status_im/ui/components/list_selection.cljs b/src/status_im/ui/components/list_selection.cljs index 43b045404c..ad24427833 100644 --- a/src/status_im/ui/components/list_selection.cljs +++ b/src/status_im/ui/components/list_selection.cljs @@ -1,41 +1,36 @@ (ns status-im.ui.components.list-selection (:require [re-frame.core :as re-frame] - [status-im.ui.components.react :refer [copy-to-clipboard - sharing - linking]] - [status-im.utils.platform :refer [platform-specific ios?]] - [status-im.i18n :refer [label]])) + [status-im.i18n :as i18n] + [status-im.ui.components.action-sheet :as action-sheet] + [status-im.ui.components.dialog :as dialog] + [status-im.ui.components.react :as react] + [status-im.utils.platform :as platform])) -(defn open-share [content] +(defn- open-share [content] (when (or (:message content) (:url content)) - (.share sharing (clj->js content)))) + (.share react/sharing (clj->js content)))) (defn share-options [text] - [{:text (label :t/sharing-copy-to-clipboard) - :value #(copy-to-clipboard text)} - {:text (label :t/sharing-share) - :value #(open-share {:message text})}]) + [{:label (i18n/label :t/sharing-copy-to-clipboard) + :action #(react/copy-to-clipboard text)} + {:label (i18n/label :t/sharing-share) + :action #(open-share {:message text})}]) + +(defn show [options] + (if platform/ios? + (action-sheet/show options) + (dialog/show options))) (defn share [text dialog-title] - (let [list-selection-fn (:list-selection-fn platform-specific)] - (list-selection-fn {:title dialog-title - :options (share-options text) - :callback (fn [index] - (case index - 0 (copy-to-clipboard text) - 1 (open-share {:message text}) - :default)) - :cancel-text (label :t/sharing-cancel)}))) + (show {:title dialog-title + :options (share-options text) + :cancel-text (i18n/label :t/sharing-cancel)})) (defn browse [link] - (let [list-selection-fn (:list-selection-fn platform-specific)] - (list-selection-fn {:title (label :t/browsing-title) - :options [{:text (label :t/browsing-open-in-browser)} - {:text (label :t/browsing-open-in-web-browser)}] - :callback (fn [index] - (case index - 0 (re-frame/dispatch [:open-browser {:url link}]) - 1 (.openURL linking link) - :default)) - :cancel-text (label :t/browsing-cancel)}))) + (show {:title (i18n/label :t/browsing-title) + :options [{:text (i18n/label :t/browsing-open-in-browser) + :action (re-frame/dispatch [:open-browser {:url link}])} + {:text (i18n/label :t/browsing-open-in-web-browser) + :action (.openURL react/linking link)}] + :cancel-text (i18n/label :t/browsing-cancel)})) diff --git a/src/status_im/ui/components/permissions.cljs b/src/status_im/ui/components/permissions.cljs index 6f113e101e..a81dd57741 100644 --- a/src/status_im/ui/components/permissions.cljs +++ b/src/status_im/ui/components/permissions.cljs @@ -1,6 +1,7 @@ (ns status-im.ui.components.permissions (:require [status-im.utils.platform :as platform] [taoensso.timbre :as log] + [status-im.ui.components.camera :as camera] [status-im.react-native.js-dependencies :as rn-dependencies])) (def permissions-class (.-PermissionsAndroid rn-dependencies/react-native)) @@ -27,4 +28,6 @@ (else-fn))) (.catch else-fn)))) - (then))) + (if ((set permissions) :camera) + (camera/request-access-ios then else) + (then)))) diff --git a/src/status_im/ui/components/qr_code_viewer/styles.cljs b/src/status_im/ui/components/qr_code_viewer/styles.cljs index 7239a3818b..abd8026cde 100644 --- a/src/status_im/ui/components/qr_code_viewer/styles.cljs +++ b/src/status_im/ui/components/qr_code_viewer/styles.cljs @@ -66,13 +66,13 @@ :justify-content :center}) (def qr-code - {:background-color colors/light-gray + {:background-color colors/gray-lighter :flex-grow 1 :align-items :center :justify-content :center}) (def footer - {:background-color colors/light-gray + {:background-color colors/gray-lighter :flex-direction :row :justify-content :center :padding-bottom 50}) diff --git a/src/status_im/ui/components/status_bar/styles.cljs b/src/status_im/ui/components/status_bar/styles.cljs index c591d39b6a..e287c5a5d8 100644 --- a/src/status_im/ui/components/status_bar/styles.cljs +++ b/src/status_im/ui/components/status_bar/styles.cljs @@ -1,8 +1,11 @@ (ns status-im.ui.components.status-bar.styles - (:require [status-im.ui.components.styles :as styles] + (:require [status-im.ui.components.colors :as colors] + [status-im.ui.components.styles :as styles] [status-im.utils.platform :as platform]) (:require-macros [status-im.utils.styles :refer [defstyle]])) +(def elevation 2) + (defn- create-status-bar-style [{:keys [background-color bar-style translucent?] :or {bar-style "light-content"}}] {:background-color (if translucent? "transparent" background-color) @@ -17,13 +20,13 @@ ;; :main (defstyle status-bar-main - {:ios (create-status-bar-style {:background-color styles/color-white + {:ios (create-status-bar-style {:background-color colors/white :bar-style "default"}) :android (create-status-bar-style {:translucent? true :bar-style "dark-content"})}) (def view-main - (create-view-style {:background-color styles/color-white})) + (create-view-style {:background-color colors/white})) ;; :transparent (defstyle status-bar-transparent @@ -45,25 +48,25 @@ ;; :modal-white (defstyle status-bar-modal-white - {:ios (create-status-bar-style {:background-color styles/color-white + {:ios (create-status-bar-style {:background-color colors/white :bar-style "default"}) :android (create-status-bar-style {:background-color styles/color-black :bar-style "light-content"})}) (defstyle view-modal-white - {:ios (create-view-style {:background-color styles/color-white}) + {:ios (create-view-style {:background-color colors/white}) :android (create-view-style {:background-color styles/color-black :height 0})}) ;; :modal-wallet -(defstyle status-bar-modal-wallet - {:ios (create-status-bar-style {:background-color styles/color-blue4}) - :android (create-status-bar-style {:background-color styles/color-black})}) +(def status-bar-modal-wallet + (create-status-bar-style {:background-color colors/blue})) -(defstyle view-model-wallet - {:ios (create-view-style {:background-color styles/color-blue4}) - :android (create-view-style {:background-color styles/color-black - :height 0})}) +(defstyle view-modal-wallet + {:ios (create-view-style {:background-color colors/blue}) + :android (create-view-style {:background-color colors/blue + :height 0 + :elevation elevation})}) ;; :transaction (defstyle status-bar-transaction @@ -75,21 +78,32 @@ :android (create-view-style {:background-color styles/color-dark-blue-2 :height 0})}) -;; :wallet -(defstyle status-bar-wallet - {:ios (create-status-bar-style {:background-color styles/color-blue4}) +;; TODO(jeluard) Fix status-bar mess by removing useless view and introducing 2dn level tab-bar + +;; :wallet HOME +(defstyle status-bar-wallet-tab + {:ios (create-status-bar-style {:background-color colors/blue}) :android (create-status-bar-style {:translucent? true})}) -(def view-wallet +(def view-wallet-tab (create-view-style {:background-color styles/color-blue4})) +;; :wallet +(defstyle status-bar-wallet + {:ios (create-status-bar-style {:background-color colors/blue}) + :android (create-status-bar-style {:translucent? true})}) + +(def view-wallet + (create-view-style {:background-color styles/color-blue4 + :elevation elevation})) + ;; :default (defstyle status-bar-default - {:ios (create-status-bar-style {:background-color styles/color-white + {:ios (create-status-bar-style {:background-color colors/white :bar-style "default"}) :android (create-status-bar-style {:translucent? true :bar-style "dark-content"})}) (defstyle view-default - (create-view-style {:background-color styles/color-white - :elevation 2})) + (create-view-style {:background-color colors/white + :elevation elevation})) diff --git a/src/status_im/ui/components/status_bar/view.cljs b/src/status_im/ui/components/status_bar/view.cljs index 4f0db8ca9d..03b2521677 100644 --- a/src/status_im/ui/components/status_bar/view.cljs +++ b/src/status_im/ui/components/status_bar/view.cljs @@ -9,9 +9,10 @@ :transparent [styles/status-bar-transparent styles/view-transparent] :modal [styles/status-bar-modal styles/view-modal] :modal-white [styles/status-bar-modal-white styles/view-modal-white] - :modal-wallet [styles/status-bar-modal-wallet styles/view-model-wallet] + :modal-wallet [styles/status-bar-modal-wallet styles/view-modal-wallet] :transaction [styles/status-bar-transaction styles/view-transaction] :wallet [styles/status-bar-wallet styles/view-wallet] + :wallet-tab [styles/status-bar-wallet-tab styles/view-wallet-tab] [styles/status-bar-default styles/view-default])] [react/view [react/status-bar status-bar-style] diff --git a/src/status_im/ui/components/styles.cljs b/src/status_im/ui/components/styles.cljs index f8f5bdb139..4d5d2b1a95 100644 --- a/src/status_im/ui/components/styles.cljs +++ b/src/status_im/ui/components/styles.cljs @@ -160,6 +160,8 @@ {:background-color color-white :flex 1}) +(def border-radius 8) + ;; TODO(goranjovic): replace all platform conditional uppercase styling with a reference to this var (def uppercase? (condp = platform/platform diff --git a/src/status_im/ui/components/sync_state/gradient.cljs b/src/status_im/ui/components/sync_state/gradient.cljs deleted file mode 100644 index dc82caa4ae..0000000000 --- a/src/status_im/ui/components/sync_state/gradient.cljs +++ /dev/null @@ -1,120 +0,0 @@ -(ns status-im.ui.components.sync-state.gradient - (:require [re-frame.core :refer [subscribe dispatch]] - [reagent.core :as r] - [status-im.ui.components.react :refer [view - text - animated-view - linear-gradient - get-dimensions]] - [status-im.ui.components.sync-state.styles :as st] - [status-im.ui.components.animation :as anim] - [taoensso.timbre :as log])) - -(def gradient-animation-duration 700) -(def synced-disappear-delay 2500) -(def gradient-width 250) -(def in-progress-animation-delay 1500) - -(def window-width (:width (get-dimensions "window"))) - -(declare start-gradient-reverse-animation) - -(defn- start-gradient-animation [{:keys [gradient-position sync-state] :as context}] - (when (= @sync-state :in-progress) - (anim/start - (anim/timing gradient-position - {:toValue (- window-width (/ gradient-width 3)) - :duration gradient-animation-duration}) - (fn [_] - (start-gradient-reverse-animation context))))) - -(defn- start-gradient-reverse-animation [{:keys [gradient-position sync-state] :as context}] - (when (= @sync-state :in-progress) - (anim/start - (anim/timing gradient-position - {:toValue (- 0 (* 2 (/ gradient-width 3))) - :duration gradient-animation-duration}) - (fn [_] - (start-gradient-animation context))))) - -(defn- start-synced-animation [{:keys [sync-state-opacity in-progress-opacity synced-opacity]}] - (anim/start - (anim/timing in-progress-opacity {:toValue 0.0 - :duration 250})) - (anim/start - (anim/timing synced-opacity {:toValue 1.0 - :duration 250}) - (fn [_] - (anim/start - (anim/timing sync-state-opacity {:toValue 0.0 - :duration 250 - :delay synced-disappear-delay}) - (fn [_] - (dispatch [:set :sync-state :done])))))) - -(defn start-in-progress-animation [component] - (r/set-state component - {:pending? true - :animation (js/setTimeout - (fn [] - (dispatch [:set :sync-state :in-progress]) - (r/set-state component {:pending? false})) - in-progress-animation-delay)})) - -(defn start-offline-animation [{:keys [sync-state-opacity]}] - (anim/start - (anim/timing sync-state-opacity {:toValue 0.0 - :duration 250}))) - -(defn clear-pending-animation [component] - (let [{:keys [pending? animation]} (r/state component)] - (when pending? - (r/set-state component {:pending? false}) - (js/clearTimeout animation)))) - - -(defn sync-state-gradient-view [] - (let [sync-state (subscribe [:sync-state]) - gradient-position (anim/create-value 0) - sync-state-opacity (anim/create-value 0.0) - in-progress-opacity (anim/create-value 0.0) - synced-opacity (anim/create-value 0.0) - - context {:sync-state sync-state - :gradient-position gradient-position - - :sync-state-opacity sync-state-opacity - :in-progress-opacity in-progress-opacity - :synced-opacity synced-opacity} - on-update (fn [component _] - (case @sync-state - :pending (start-in-progress-animation component) - :in-progress (do - (anim/set-value gradient-position 0) - (anim/set-value sync-state-opacity 1) - (anim/set-value in-progress-opacity 1) - (anim/set-value synced-opacity 0) - (start-gradient-animation context)) - :synced (start-synced-animation context) - :done (clear-pending-animation component) - :offline (do (clear-pending-animation component) - (start-offline-animation context)) - (log/debug "Sync state:" @sync-state)))] - (r/create-class - {:component-did-mount - on-update - :component-did-update - on-update - :display-name "sync-state-gradient-view" - :reagent-render - (fn [] - [view st/sync-style-gradient - [animated-view {:style (st/loading-wrapper sync-state-opacity)} - [animated-view {:style (st/gradient-wrapper in-progress-opacity gradient-position)} - [linear-gradient {:colors ["#89b1fe" "#8b5fe4" "#8b5fe4" "#89b1fe"] - :start {:x 0 :y 1} - :end {:x 1 :y 1} - :locations [0 0.3 0.7 1] - :style (st/gradient gradient-width)}]] - (when (not= @sync-state :in-progress) - [animated-view {:style (st/synced-wrapper synced-opacity window-width)}])]])}))) diff --git a/src/status_im/ui/components/sync_state/styles.cljs b/src/status_im/ui/components/sync_state/styles.cljs index 2da180dbe2..e9848f7cd7 100644 --- a/src/status_im/ui/components/sync_state/styles.cljs +++ b/src/status_im/ui/components/sync_state/styles.cljs @@ -1,31 +1,5 @@ (ns status-im.ui.components.sync-state.styles - (:require-macros [status-im.utils.styles :refer [defstyle defnstyle]])) - -(def sync-style-gradient - {:position :relative - :height 0 - :top -2}) - -(defn loading-wrapper [opacity] - {:background-color "#89b1fe" - :opacity opacity - :height 2}) - -(defn gradient-wrapper [in-progress-opacity position] - {:position :absolute - :left position - :opacity in-progress-opacity}) - -(defn gradient [width] - {:width width - :height 2}) - -(defn synced-wrapper [opacity window-width] - {:opacity opacity - :position :absolute - :width window-width - :background-color "#5fc48d" - :height 2}) + (:require-macros [status-im.utils.styles :refer [defnstyle]])) (defnstyle offline-wrapper [top opacity window-width pending?] {:ios {:z-index 0} diff --git a/src/status_im/ui/components/toolbar/view.cljs b/src/status_im/ui/components/toolbar/view.cljs index e0b024da83..6c4aa0109c 100644 --- a/src/status_im/ui/components/toolbar/view.cljs +++ b/src/status_im/ui/components/toolbar/view.cljs @@ -1,49 +1,51 @@ (ns status-im.ui.components.toolbar.view - (:require [reagent.core :as r] - [re-frame.core :as rf] - [status-im.ui.components.react :as rn] - [status-im.ui.components.sync-state.gradient :as sync-state-gradient-view] - [status-im.ui.components.styles :as st] - [status-im.ui.components.context-menu :as context-menu] - [status-im.ui.components.toolbar.actions :as act] - [status-im.ui.components.toolbar.styles :as tst] - [status-im.ui.components.icons.vector-icons :as vi] - [status-im.utils.platform :as platform])) + (:require [reagent.core :as reagent] + [re-frame.core :as re-frame] + [status-im.ui.components.colors :as colors] + [status-im.ui.components.icons.vector-icons :as vector-icons] + [status-im.ui.components.list-selection :as list-selection] + [status-im.ui.components.react :as react] + [status-im.ui.components.styles :as components.styles] + [status-im.ui.components.toolbar.actions :as actions] + [status-im.ui.components.toolbar.styles :as styles] + [status-im.utils.platform :as platform] + [status-im.utils.utils :as utils])) ;; Navigation item (defn nav-item - [{:keys [handler accessibility-label style] :or {handler #(rf/dispatch [:navigate-back])}} item] - [rn/touchable-highlight + [{:keys [handler accessibility-label style] :or {handler #(re-frame/dispatch [:navigate-back])}} item] + [react/touchable-highlight (merge {:on-press handler} (when accessibility-label {:accessibility-label accessibility-label})) - [rn/view {:style style} + [react/view {:style style} item]]) (defn nav-button [{:keys [icon icon-opts] :as props}] - [nav-item (merge {:style tst/nav-item-button} props) - [vi/icon icon icon-opts]]) + [nav-item (merge {:style styles/nav-item-button} props) + [vector-icons/icon icon icon-opts]]) (defn nav-text ([text] (nav-text text nil)) - ([text handler] (nav-text nil text handler)) + ([props text] (nav-text props text nil)) ([props text handler] - [rn/text (merge {:style (merge tst/item tst/item-text) :on-press (or handler #(rf/dispatch [:navigate-back]))}) + [react/text (utils/deep-merge {:style (merge styles/item styles/item-text) :on-press (or handler #(re-frame/dispatch [:navigate-back]))} + props) text])) (defn nav-clear-text ([text] (nav-clear-text text nil)) ([text handler] - (nav-text tst/item-text-white-background text handler))) + (nav-text styles/item-text-white-background text handler))) -(def default-nav-back [nav-button act/default-back]) +(def default-nav-back [nav-button actions/default-back]) ;; Content (defn content-wrapper [content] - [rn/view {:style tst/toolbar-container} + [react/view {:style styles/toolbar-container} content]) (defn content-title @@ -51,39 +53,37 @@ ([title-style title] (content-title title-style title nil nil)) ([title-style title subtitle-style subtitle] - [rn/view {:style tst/toolbar-title-container} - [rn/text {:style (merge tst/toolbar-title-text title-style) - :font :toolbar-title} + [react/view {:style styles/toolbar-title-container} + [react/text {:style (merge styles/toolbar-title-text title-style) + :font :toolbar-title} title] - (when subtitle [rn/text {:style subtitle-style} subtitle])])) + (when subtitle + [react/text {:style subtitle-style} + subtitle])])) ;; Actions (defn text-action [{:keys [style handler disabled?]} title] - [rn/text {:style (merge tst/item tst/item-text style - (when disabled? tst/toolbar-text-action-disabled)) - :on-press (when-not disabled? handler)} + [react/text {:style (merge styles/item styles/item-text style + (when disabled? styles/toolbar-text-action-disabled)) + :on-press (when-not disabled? handler)} title]) -(def blank-action [rn/view {:style (merge tst/item tst/toolbar-action)}]) - -(defn- option-actions [icon icon-opts options] - [context-menu/context-menu - [rn/view {:style tst/toolbar-action} - [vi/icon icon icon-opts]] - options - nil - tst/item]) +(def blank-action [react/view {:style (merge styles/item styles/toolbar-action)}]) (defn- icon-action [icon {:keys [overlay-style] :as icon-opts} handler] - [rn/touchable-highlight {:on-press handler} - [rn/view {:style (merge tst/item tst/toolbar-action)} + [react/touchable-highlight {:on-press handler} + [react/view {:style (merge styles/item styles/toolbar-action)} (when overlay-style - [rn/view overlay-style]) - [vi/icon icon icon-opts]]]) + [react/view overlay-style]) + [vector-icons/icon icon icon-opts]]]) + +(defn- option-actions [icon icon-opts options] + [icon-action icon icon-opts + #(list-selection/show {:options options})]) (defn actions [v] - [rn/view {:style tst/toolbar-actions} + [react/view {:style styles/toolbar-actions} (for [{:keys [image icon icon-opts options handler]} v] (with-meta (cond (= image :blank) @@ -98,72 +98,72 @@ (defn toolbar ([props nav-item content-item] (toolbar props nav-item content-item [actions [{:image :blank}]])) - ([{:keys [background-color style flat? show-sync-bar?]} + ([{:keys [background-color style flat?]} nav-item content-item action-items] - ;; TODO remove extra view wen we remove sync-state-gradient - [rn/view - [rn/view {:style (merge (tst/toolbar background-color flat?) style)} - ;; On iOS title must be centered. Current solution is a workaround and eventually this will be sorted out using flex - (when platform/ios? - [rn/view tst/ios-content-item - content-item]) - (when nav-item - [rn/view {:style (tst/toolbar-nav-actions-container 0)} - nav-item]) - (if platform/ios? - [rn/view st/flex] - content-item) - action-items] - (when show-sync-bar? [sync-state-gradient-view/sync-state-gradient-view])])) + [react/view {:style (merge (styles/toolbar background-color flat?) style)} + ;; On iOS title must be centered. Current solution is a workaround and eventually this will be sorted out using flex + (when platform/ios? + [react/view styles/ios-content-item + content-item]) + (when nav-item + [react/view {:style (styles/toolbar-nav-actions-container 0)} + nav-item]) + (if platform/ios? + [react/view components.styles/flex] + content-item) + action-items])) (defn simple-toolbar - "A simple toolbar whose content is a single line text" + "A simple toolbar composed of a nav-back item and a single line title." ([] (simple-toolbar nil)) - ([title] (toolbar nil default-nav-back [content-title title]))) + ([title] (simple-toolbar nil title)) + ([m title] (simple-toolbar m default-nav-back title)) + ([m nav-back title] + (toolbar m nav-back [content-title title]))) -(def search-text-input (r/atom nil)) +(def search-text-input (reagent/atom nil)) (defn- toolbar-search-submit [on-search-submit] - (let [text @(rf/subscribe [:get-in [:toolbar-search :text]])] + (let [text @(re-frame/subscribe [:get-in [:toolbar-search :text]])] (on-search-submit text) - (rf/dispatch [:set-in [:toolbar-search :text] nil]))) + (re-frame/dispatch [:set-in [:toolbar-search :text] nil]))) (defn- toolbar-with-search-content [{:keys [show-search? search-placeholder title custom-title on-search-submit]}] - [rn/view tst/toolbar-with-search-content + [react/view styles/toolbar-with-search-content (if show-search? - [rn/text-input - {:style tst/toolbar-search-input + [react/text-input + {:style styles/toolbar-search-input :ref #(reset! search-text-input %) :auto-focus true :placeholder search-placeholder - :placeholder-text-color st/color-gray4 - :on-change-text #(rf/dispatch [:set-in [:toolbar-search :text] %]) + :placeholder-text-color colors/gray + :on-change-text #(re-frame/dispatch [:set-in [:toolbar-search :text] %]) :on-submit-editing (when on-search-submit #(toolbar-search-submit on-search-submit))}] (or custom-title - [rn/view - [rn/text {:style tst/toolbar-title-text - :font :toolbar-title} + [react/view + [react/text {:style styles/toolbar-title-text + :font :toolbar-title} title]]))]) (defn- toggle-search-fn [text] - (rf/dispatch [:set-in [:toolbar-search :show] text]) - (rf/dispatch [:set-in [:toolbar-search :text] ""])) + (re-frame/dispatch [:set-in [:toolbar-search :show] text]) + (re-frame/dispatch [:set-in [:toolbar-search :text] ""])) (defn- search-actions [show-search? search-text search-key actions] (if show-search? (if (pos? (count search-text)) - [(act/close #(do - (.clear @search-text-input) - (rf/dispatch [:set-in [:toolbar-search :text] ""])))] - [act/search-icon]) - (into [(act/search #(toggle-search-fn search-key))] actions))) + [(actions/close #(do + (.clear @search-text-input) + (re-frame/dispatch [:set-in [:toolbar-search :text] ""])))] + [actions/search-icon]) + (into [(actions/search #(toggle-search-fn search-key))] actions))) (defn toolbar-with-search [{:keys [show-search? @@ -178,7 +178,7 @@ :style style} [nav-button (if show-search? - (act/back #(toggle-search-fn nil)) - (or nav-action (if modal? act/default-close act/default-back)))] + (actions/back #(toggle-search-fn nil)) + (or nav-action (if modal? actions/default-close actions/default-back)))] [toolbar-with-search-content opts] - [actions (search-actions show-search? search-text search-key (:actions opts))]]) \ No newline at end of file + [actions (search-actions show-search? search-text search-key (:actions opts))]]) diff --git a/src/status_im/ui/screens/accounts/login/styles.cljs b/src/status_im/ui/screens/accounts/login/styles.cljs index b3390d1909..900f7d61ce 100644 --- a/src/status_im/ui/screens/accounts/login/styles.cljs +++ b/src/status_im/ui/screens/accounts/login/styles.cljs @@ -12,8 +12,7 @@ (defstyle login-badge-container {:background-color :white - :ios {:border-radius 8 - :padding-top 16 + :ios {:padding-top 16 :height 150} :android {:border-radius 4 :padding-top 12 @@ -29,13 +28,12 @@ (merge sign-it-text {:color st/color-gray2})) -(defstyle sign-in-button +(def sign-in-button {:background-color st/color-blue3 :align-items :center :justify-content :center :height 52 - :ios {:border-radius 8} - :android {:border-radius 4}}) + :border-radius 8}) (def processing-view {:position :absolute diff --git a/src/status_im/ui/screens/accounts/login/views.cljs b/src/status_im/ui/screens/accounts/login/views.cljs index 4148f4be62..3ec67193e4 100644 --- a/src/status_im/ui/screens/accounts/login/views.cljs +++ b/src/status_im/ui/screens/accounts/login/views.cljs @@ -14,9 +14,7 @@ [status-im.ui.components.react :as components])) (defn login-toolbar [] - [toolbar/toolbar - {:background-color :transparent - :hide-border? true} + [toolbar/toolbar {:background-color :transparent} [toolbar/nav-button (act/back-white #(dispatch [:navigate-back]))] [toolbar/content-title {:color :white} (i18n/label :t/sign-in-to-status)]]) diff --git a/src/status_im/ui/screens/accounts/styles.cljs b/src/status_im/ui/screens/accounts/styles.cljs index 359ad208bb..a0683372ff 100644 --- a/src/status_im/ui/screens/accounts/styles.cljs +++ b/src/status_im/ui/screens/accounts/styles.cljs @@ -49,8 +49,7 @@ {:background-color :white :justify-content :center :height 64 - :ios {:border-radius 8} - :android {:border-radius 4}}) + :border-radius 8}) (def account-badge {:flex-direction :row diff --git a/src/status_im/ui/screens/contacts/subs.cljs b/src/status_im/ui/screens/contacts/subs.cljs index 18eed4887e..cb415b0fbf 100644 --- a/src/status_im/ui/screens/contacts/subs.cljs +++ b/src/status_im/ui/screens/contacts/subs.cljs @@ -1,7 +1,8 @@ (ns status-im.ui.screens.contacts.subs - (:require [re-frame.core :refer [reg-sub subscribe]] - [status-im.utils.identicon :refer [identicon]] - [clojure.string :as str])) + (:require [clojure.string :as string] + [re-frame.core :refer [reg-sub subscribe]] + [status-im.utils.ethereum.core :as ethereum] + [status-im.utils.identicon :as identicon])) (reg-sub :current-contact (fn [db [_ k]] @@ -94,9 +95,9 @@ (defn search-filter [text item] (let [name (-> (or (:name item) "") - (str/lower-case)) - text (str/lower-case text)] - (not= (str/index-of name text) nil))) + (string/lower-case)) + text (string/lower-case text)] + (not= (string/index-of name text) nil))) (defn search-filter-reaction [contacts text] (if text @@ -177,7 +178,7 @@ contacts)) (reg-sub :contacts-by-chat - (fn [[_ fn chat-id] _] + (fn [[_ _ chat-id] _] [(subscribe [:get-chat chat-id]) (subscribe [:get-contacts])]) chat-contacts) @@ -196,7 +197,21 @@ (:photo-path (first contacts)) :else - (identicon chat-id))))) + (identicon/identicon chat-id))))) + +(defn- address= [{:keys [address] :as contact} s] + (when (and address (= (ethereum/normalized-address s) + (ethereum/normalized-address address))) + contact)) + +(defn- contact-by-address [[_ contact] s] + (when (address= contact s) + contact)) + +(reg-sub :contact/by-address + :<- [:get-contacts] + (fn [contacts [_ address]] + (some #(contact-by-address % address) contacts))) (reg-sub :contacts/by-address :<- [:get-contacts] diff --git a/src/status_im/ui/screens/contacts/views.cljs b/src/status_im/ui/screens/contacts/views.cljs index e2d20b4440..4f7626a37f 100644 --- a/src/status_im/ui/screens/contacts/views.cljs +++ b/src/status_im/ui/screens/contacts/views.cljs @@ -41,19 +41,19 @@ [toolbar/content-title (label :t/edit-contacts)]]) (defn contact-options [{:keys [unremovable?] :as contact} group] - (let [delete-contact-opt {:value #(u/show-confirmation + (let [delete-contact-opt {:action #(u/show-confirmation (str (label :t/delete-contact) "?") (label :t/delete-contact-confirmation) (label :t/delete) (fn [] (dispatch [:hide-contact contact]))) - :text (label :t/delete-contact) + :label (label :t/delete-contact) :destructive? true} options (if unremovable? [] [delete-contact-opt])] (if group (conj options - {:value #(dispatch [:remove-contact-from-group - (:whisper-identity contact) - (:group-id group)]) - :text (label :t/remove-from-group)}) + {:action #(dispatch [:remove-contact-from-group + (:whisper-identity contact) + (:group-id group)]) + :label (label :t/remove-from-group)}) options))) (defn contact-group-form [{:keys [contacts contacts-count group edit? click-handler]}] @@ -63,8 +63,8 @@ [common/form-title subtitle {:count-value contacts-count :extended? edit? - :options [{:value #(dispatch [:navigate-to :edit-contact-group group :contact-group]) - :text (label :t/edit-group)}]}]) + :options [{:action #(dispatch [:navigate-to :edit-contact-group group :contact-group]) + :label (label :t/edit-group)}]}]) [view st/contacts-list [common/list-footer] (doall diff --git a/src/status_im/ui/screens/discover/styles.cljs b/src/status_im/ui/screens/discover/styles.cljs index 217cab6e51..6946edeaef 100644 --- a/src/status_im/ui/screens/discover/styles.cljs +++ b/src/status_im/ui/screens/discover/styles.cljs @@ -143,12 +143,11 @@ :margin-bottom 4 :margin-right 2}}) -(defstyle chat-button-container +(def chat-button-container {:justify-content :center :align-items :center :background-color styles/color-blue4-transparent - :ios {:border-radius 8} - :android {:border-radius 4}}) + :border-radius 8}) (defstyle chat-button-inner {:flex-direction :row @@ -257,7 +256,7 @@ :justify-content :center :align-items :center :flex-direction :column - :ios {:border-radius 8 + :ios { :border-color styles/color-light-blue6} :android {:border-radius 4}}) diff --git a/src/status_im/ui/screens/group/chat_settings/views.cljs b/src/status_im/ui/screens/group/chat_settings/views.cljs index f713f4f412..91db38a7c2 100644 --- a/src/status_im/ui/screens/group/chat_settings/views.cljs +++ b/src/status_im/ui/screens/group/chat_settings/views.cljs @@ -28,8 +28,8 @@ [view [contact-view {:contact row - :extend-options [{:value #(dispatch [:remove-group-chat-participants #{(:whisper-identity row)}]) - :text (label :t/remove)}] + :extend-options [{:action #(dispatch [:remove-group-chat-participants #{(:whisper-identity row)}]) + :label (label :t/remove)}] :extended? admin?}] (when-not (= row (last limited-contacts)) [common/list-separator])]) diff --git a/src/status_im/ui/screens/group/edit_contacts/views.cljs b/src/status_im/ui/screens/group/edit_contacts/views.cljs index ddf70e4217..a1831d16a8 100644 --- a/src/status_im/ui/screens/group/edit_contacts/views.cljs +++ b/src/status_im/ui/screens/group/edit_contacts/views.cljs @@ -33,16 +33,16 @@ :header list/default-header}]]) (defn chat-extended-options [item] - [{:value #(re-frame/dispatch [:remove-group-chat-participants #{(:whisper-identity item)}]) - :text (i18n/label :t/remove)}]) + [{:action #(re-frame/dispatch [:remove-group-chat-participants #{(:whisper-identity item)}]) + :label (i18n/label :t/remove)}]) (defn contact-extended-options [group-id] (fn [item] - [{:value #(re-frame/dispatch [:remove-contact-from-group - (:whisper-identity item) - group-id]) + [{:action #(re-frame/dispatch [:remove-contact-from-group + (:whisper-identity item) + group-id]) :accessibility-label :remove-button - :text (i18n/label :t/remove-from-group)}])) + :label (i18n/label :t/remove-from-group)}])) (defview edit-chat-group-contact-list [] (letsubs [chat-name [:chat :name] diff --git a/src/status_im/ui/screens/group/views.cljs b/src/status_im/ui/screens/group/views.cljs index 9ba02f275d..30cb409764 100644 --- a/src/status_im/ui/screens/group/views.cljs +++ b/src/status_im/ui/screens/group/views.cljs @@ -106,10 +106,10 @@ [view [contact-view {:contact row - :extend-options [{:value #(dispatch [:remove-contact-from-group - (:whisper-identity row) - (:group-id group)]) - :text (label :t/remove-from-group)}] + :extend-options [{:action #(dispatch [:remove-contact-from-group + (:whisper-identity row) + (:group-id group)]) + :label (label :t/remove-from-group)}] :extended? true}] (when-not (= row (last contacts)) [common/list-separator])]) diff --git a/src/status_im/ui/screens/home/views.cljs b/src/status_im/ui/screens/home/views.cljs index 316828d291..d52a83611d 100644 --- a/src/status_im/ui/screens/home/views.cljs +++ b/src/status_im/ui/screens/home/views.cljs @@ -15,7 +15,7 @@ [status-im.utils.platform :as platform])) (defn toolbar-view [] - [toolbar/toolbar {:show-sync-bar? true} + [toolbar/toolbar {} nil [toolbar/content-title (i18n/label :t/status)] [toolbar/actions diff --git a/src/status_im/ui/screens/main_tabs/views.cljs b/src/status_im/ui/screens/main_tabs/views.cljs index 4368d29109..fc848534bc 100644 --- a/src/status_im/ui/screens/main_tabs/views.cljs +++ b/src/status_im/ui/screens/main_tabs/views.cljs @@ -52,7 +52,7 @@ (views/defview main-tabs [] (views/letsubs [view-id [:get :view-id]] [react/view common.styles/flex - [status-bar.view/status-bar {:type (if (= view-id :wallet) :wallet :main)}] + [status-bar.view/status-bar {:type (if (= view-id :wallet) :wallet-tab :main)}] [react/view common.styles/main-container [react/with-activity-indicator diff --git a/src/status_im/ui/screens/network_settings/styles.cljs b/src/status_im/ui/screens/network_settings/styles.cljs index 85ff2e091d..ed68441c0b 100644 --- a/src/status_im/ui/screens/network_settings/styles.cljs +++ b/src/status_im/ui/screens/network_settings/styles.cljs @@ -33,9 +33,8 @@ :align-items :center :justify-content :center :background-color common/color-light-blue - :ios {:border-radius 8 - :opacity 0.9} - :android {:border-radius 4}}) + :border-radius 8 + :ios {:opacity 0.9}}) (defstyle connect-button-label {:color common/color-white @@ -84,10 +83,10 @@ :align-items :center :justify-content :center :background-color common/color-light-blue-transparent - :ios {:width 343 - :border-radius 8} - :android {:width 328 - :border-radius 4}}) + :border-radius 8 + :ios {:width 343} + + :android {:width 328}}) (defstyle edit-button-label {:color common/color-light-blue diff --git a/src/status_im/ui/screens/offline_messaging_settings/views.cljs b/src/status_im/ui/screens/offline_messaging_settings/views.cljs index cc93b0f203..a735dd2053 100644 --- a/src/status_im/ui/screens/offline_messaging_settings/views.cljs +++ b/src/status_im/ui/screens/offline_messaging_settings/views.cljs @@ -33,7 +33,8 @@ [react/view styles/wnode-item-inner [react/text {:style styles/wnode-item-name-text} name] - #_(when connected? + #_ + (when connected? [react/text {:style styles/wnode-item-connected-text} (i18n/label :t/connected)])]]]]))) diff --git a/src/status_im/ui/screens/profile/edit/views.cljs b/src/status_im/ui/screens/profile/edit/views.cljs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/status_im/ui/screens/profile/styles.cljs b/src/status_im/ui/screens/profile/styles.cljs index b5101af3d3..e7acab13e1 100644 --- a/src/status_im/ui/screens/profile/styles.cljs +++ b/src/status_im/ui/screens/profile/styles.cljs @@ -35,7 +35,7 @@ (def profile-status-container {:background-color colors/gray :margin-top 16 - :border-radius 4 + :border-radius 8 :padding 16 :max-height 114}) @@ -201,7 +201,7 @@ (defstyle edit-profile-status {:background-color styles/color-light-gray - :border-radius 4 + :border-radius 8 :height 90 :padding-horizontal 16 :padding-bottom 16 diff --git a/src/status_im/ui/screens/profile/views.cljs b/src/status_im/ui/screens/profile/views.cljs index 9480ada2a1..3ad7681e0a 100644 --- a/src/status_im/ui/screens/profile/views.cljs +++ b/src/status_im/ui/screens/profile/views.cljs @@ -42,8 +42,8 @@ [toolbar/toolbar {} nil [toolbar/content-title ""] - [common/icon-or-label {:on-press #(re-frame/dispatch [:my-profile/save-profile])} - :t/done {} :icons/ok {:color colors/blue}]]) + [common/icon-or-label {:on-press #(re-frame/dispatch [:my-profile/save-profile])} + :t/done {} :icons/ok {:color colors/blue}]]) (defn profile-toolbar [contact] [toolbar/toolbar {} @@ -52,8 +52,8 @@ [toolbar/actions (when (and (not (:pending? contact)) (not (:unremovable? contact))) - [(actions/opts [{:value #(re-frame/dispatch [:hide-contact contact]) - :text (i18n/label :t/remove-from-contacts)}])])]]) + [(actions/opts [{:action #(re-frame/dispatch [:hide-contact contact]) + :label (i18n/label :t/remove-from-contacts)}])])]]) (defn online-text [last-online] (let [last-online-date (time/to-date last-online) @@ -88,27 +88,24 @@ :on-change-text #(re-frame/dispatch [:my-profile/update-name %])}]]) (def profile-icon-options - [{:text (i18n/label :t/image-source-gallery) - :value #(re-frame/dispatch [:my-profile/update-picture])} - {:text (i18n/label :t/image-source-make-photo) - :value (fn [] - (re-frame/dispatch [:request-permissions - [:camera :write-external-storage] - (fn [] - (camera/request-access - #(if % - (re-frame/dispatch [:navigate-to :profile-photo-capture]) - (utils/show-popup (i18n/label :t/error) - (i18n/label :t/camera-access-error)))))]))}]) + [{:label (i18n/label :t/image-source-gallery) + :action #(re-frame/dispatch [:my-profile/update-picture])} + {:label (i18n/label :t/image-source-make-photo) + :action (fn [] + (re-frame/dispatch [:request-permissions + [:camera :write-external-storage] + #(re-frame/dispatch [:navigate-to :profile-photo-capture]) + #(utils/show-popup (i18n/label :t/error) + (i18n/label :t/camera-access-error))]))}]) + (defn profile-badge-edit [{:keys [name last-online] :as account}] [react/view styles/profile-badge-edit - [context-menu/modal-menu - [chat-icon.screen/my-profile-icon {:account account - :edit? true}] - styles/modal-menu - (i18n/label :t/image-source-title) - profile-icon-options] + [react/touchable-highlight {:on-press #(list-selection/show {:title (i18n/label :t/image-source-title) + :options profile-icon-options})} + [react/view styles/modal-menu + [chat-icon.screen/my-profile-icon {:account account + :edit? true}]]] [react/view styles/profile-badge-name-container [profile-name-input name] (when-not (nil? last-online) @@ -164,15 +161,15 @@ (defn profile-options [contact k text] (into [] - (concat [{:value (show-qr contact k text) - :text (i18n/label :t/show-qr)}] + (concat [{:action (show-qr contact k text) + :label (i18n/label :t/show-qr)}] (when text (list-selection/share-options text))))) (defn profile-info-address-item [{:keys [address] :as contact}] [profile-info-item {:label (i18n/label :t/address) - :value address + :action address :options (profile-options contact :address address) :text-mode :middle :accessibility-label :profile-address}]) @@ -180,7 +177,7 @@ (defn profile-info-public-key-item [public-key contact] [profile-info-item {:label (i18n/label :t/public-key) - :value public-key + :action public-key :options (profile-options contact :public-key public-key) :text-mode :middle :accessibility-label :profile-public-key}]) @@ -207,7 +204,7 @@ (i18n/label :t/not-specified) phone)] [profile-info-item {:label (i18n/label :t/phone-number) - :value phone-text + :action phone-text :options options :empty-value? phone-empty? :accessibility-label :profile-phone-number}])) diff --git a/src/status_im/ui/screens/qr_scanner/events.cljs b/src/status_im/ui/screens/qr_scanner/events.cljs index 56e73839ee..f66f916e97 100644 --- a/src/status_im/ui/screens/qr_scanner/events.cljs +++ b/src/status_im/ui/screens/qr_scanner/events.cljs @@ -17,11 +17,9 @@ [_ [_ identifier]] (re-frame/dispatch [:request-permissions [:camera] - (fn [] - (camera/request-access - #(if % (re-frame/dispatch [:navigate-to :qr-scanner identifier]) - (utils/show-popup (i18n/label :t/error) - (i18n/label :t/camera-access-error)))))])) + #(re-frame/dispatch [:navigate-to :qr-scanner identifier]) + #(utils/show-popup (i18n/label :t/error) + (i18n/label :t/camera-access-error))])) (register-handler :scan-qr-code (re-frame/after navigate-to-scanner) diff --git a/src/status_im/ui/screens/views.cljs b/src/status_im/ui/screens/views.cljs index 114ac1fa80..1f7f886dbf 100644 --- a/src/status_im/ui/screens/views.cljs +++ b/src/status_im/ui/screens/views.cljs @@ -41,6 +41,7 @@ [status-im.ui.screens.wallet.settings.views :as wallet-settings] [status-im.ui.screens.wallet.transactions.views :as wallet-transactions] [status-im.ui.screens.wallet.send.transaction-sent.views :refer [transaction-sent transaction-sent-modal]] + [status-im.ui.screens.wallet.components.views :refer [contact-code recent-recipients recipient-qr-code]] [status-im.ui.components.status-bar.view :as status-bar] [status-im.ui.screens.discover.search-results.views :as discover-search] [status-im.ui.screens.discover.recent-statuses.views :as discover-recent] @@ -96,6 +97,7 @@ {:view :wallet-send-transaction :parent :wallet + :hide? (not android?) :component send-transaction} {:view :wallet-request-transaction @@ -108,6 +110,7 @@ {:view :choose-recipient :parent :wallet-send-transaction + :hide? true :component choose-recipient} {:view :wallet-transaction-sent @@ -134,7 +137,6 @@ :browser browser :wallet-send-transaction send-transaction :wallet-transaction-sent transaction-sent - :choose-recipient choose-recipient :wallet-request-transaction request-transaction (:transactions-history :unsigned-transactions) wallet-transactions/transactions :wallet-transaction-details wallet-transactions/transaction-details @@ -169,11 +171,15 @@ :paste-json-text paste-json-text :add-rpc-url add-rpc-url :network-details network-details + :recent-recipients recent-recipients + :recipient-qr-code recipient-qr-code + :contact-code contact-code :qr-viewer qr-code-viewer/qr-viewer (throw (str "Unknown view: " current-view)))] [(if android? menu-context view) common-styles/flex [view common-styles/flex - (if (and signed-up? + (if (and android? + signed-up? (#{:home :wallet :my-profile :chat :wallet-send-transaction :choose-recipient :wallet-transaction-sent :transactions-history :unsigned-transactions :wallet-request-transaction :edit-my-profile @@ -184,7 +190,7 @@ (when modal-view [view common-styles/modal [modal {:animation-type :slide - :transparent false + :transparent true :on-request-close #(dispatch [:navigate-back])} (let [component (case modal-view :qr-scanner qr-scanner diff --git a/src/status_im/ui/screens/wallet/choose_recipient/events.cljs b/src/status_im/ui/screens/wallet/choose_recipient/events.cljs index 7a2fc72f65..3b29668dda 100644 --- a/src/status_im/ui/screens/wallet/choose_recipient/events.cljs +++ b/src/status_im/ui/screens/wallet/choose_recipient/events.cljs @@ -13,16 +13,15 @@ toggled-state (if (= :on flashlight-state) :off :on)] (assoc-in db [:wallet :send-transaction :camera-flashlight] toggled-state)))) -(defn- fill-request-details [db {:keys [address name value symbol gas gasPrice] :as m}] +(defn- fill-request-details [db {:keys [address name value symbol gas gasPrice]}] {:pre [(not (nil? address))]} (update-in db [:wallet :send-transaction] - #(cond-> (assoc % :to address) - value (assoc :amount value) - name (assoc :to-name name) - symbol (assoc :symbol symbol) - gas (assoc :gas (money/bignumber gas)) - gasPrice (assoc :gas-price (money/bignumber gasPrice)) + #(cond-> (assoc % :to address :to-name name) + value (assoc :amount value) + symbol (assoc :symbol symbol) + gas (assoc :gas (money/bignumber gas)) + gasPrice (assoc :gas-price (money/bignumber gasPrice)) (and symbol (not gasPrice)) (assoc :gas-price (ethereum/estimate-gas symbol))))) @@ -37,12 +36,13 @@ (handlers/register-handler-fx :wallet/fill-request-from-url - (fn [{{:keys [web3 network] :as db} :db} [_ data name]] + (fn [{{:keys [network] :as db} :db} [_ data]] (let [{:keys [view-id]} db current-chain-id (get-in constants/default-networks [network :raw-config :NetworkId]) {:keys [address chain-id] :as details} (extract-details data current-chain-id) valid-network? (boolean (= current-chain-id chain-id))] - (cond-> {:db db} + (cond-> {:db db + :dispatch [:navigate-back]} (and address (= :choose-recipient view-id)) (assoc :dispatch [:navigate-back]) (and address valid-network?) (update :db #(fill-request-details % details)) (not address) (assoc :show-error (i18n/label :t/wallet-invalid-address {:data data})) @@ -52,5 +52,4 @@ :wallet/fill-request-from-contact (fn [{db :db} [_ {:keys [address name]}]] {:db (fill-request-details db {:address address :name name}) - :dispatch-n [[:navigate-back] - [:navigate-back]]})) + :dispatch [:navigate-back]})) diff --git a/src/status_im/ui/screens/wallet/choose_recipient/styles.cljs b/src/status_im/ui/screens/wallet/choose_recipient/styles.cljs index b10a0ffbe0..5121fa2b2e 100644 --- a/src/status_im/ui/screens/wallet/choose_recipient/styles.cljs +++ b/src/status_im/ui/screens/wallet/choose_recipient/styles.cljs @@ -1,38 +1,12 @@ (ns status-im.ui.screens.wallet.choose-recipient.styles - (:require-macros [status-im.utils.styles :refer [defnstyle defstyle]]) - (:require [status-im.ui.components.styles :as styles])) + (:require [status-im.ui.components.colors :as colors])) + +(def toolbar + {:background-color :transparent}) (def wallet-container {:flex 1 - :background-color styles/color-blue4}) - -(def toolbar-buttons-container - {:flex-direction :row - :flex-shrink 1 - :justify-content :space-between - :width 68 - :margin-right 12}) - -(def choose-recipient-container - {:flex-direction :row - :padding-top 20 - :padding-bottom 20 - :justify-content :center}) - -(def choose-recipient-label - {:color :white}) - -(defstyle recipient-buttons - {:flex-direction :column - :margin-horizontal 28 - :margin-vertical 20 - :border-radius 8 - :ios {:background-color styles/color-blue6}}) - -(def recipient-icon {:margin-right 20}) - -(def recipient-icon-disabled {:margin-right 20 - :opacity 0.3}) + :background-color colors/blue}) (def recipient-button {:flex-direction :row @@ -45,24 +19,12 @@ :align-self :center :font-size 14}) -(def recipient-button-text-disabled - (merge recipient-button-text {:color "rgba(255, 255, 255, 0.3)"})) - -(defnstyle recipient-touchable [divider?] - (cond-> {:border-color styles/color-gray-transparent-light} - divider? (assoc :ios {:border-bottom-width 1}))) - -(def recipient-touchable-disabled - {:background-color styles/color-blue4 - :border-bottom-left-radius 8 - :border-bottom-right-radius 8 - :border-left-width 1 - :border-bottom-width 1 - :border-right-width 1 - :border-color "rgba(255, 255, 255, 0.3)"}) - (def qr-container - {:flex 1}) + {:position :absolute + :top 0 + :left 0 + :right 0 + :bottom 0}) (def preview {:flex 1 @@ -74,25 +36,21 @@ :width 40 :height 40}) -(defn corner-left-bottom [dimension] - (let [viewport-offset 0.1666] - (merge corner-dimensions {:bottom (* viewport-offset dimension) - :left (* viewport-offset dimension)}))) +(defn corner-left-bottom [height width size] + (merge corner-dimensions {:bottom (int (/ (- height size) 2)) + :left (int (/ (- width size) 2))})) -(defn corner-right-bottom [dimension] - (let [viewport-offset 0.1666] - (merge corner-dimensions {:right (* viewport-offset dimension) - :bottom (* viewport-offset dimension)}))) +(defn corner-right-bottom [height width size] + (merge corner-dimensions {:right (int (/ (- width size) 2)) + :bottom (int (/ (- height size) 2))})) -(defn corner-left-top [dimension] - (let [viewport-offset 0.1666] - (merge corner-dimensions {:top (* viewport-offset dimension) - :left (* viewport-offset dimension)}))) +(defn corner-left-top [height width size] + (merge corner-dimensions {:top (int (/ (- height size) 2)) + :left (int (/ (- width size) 2))})) -(defn corner-right-top [dimension] - (let [viewport-offset 0.1666] - (merge corner-dimensions {:top (* viewport-offset dimension) - :right (* viewport-offset dimension)}))) +(defn corner-right-top [height width size] + (merge corner-dimensions {:top (int (/ (- height size) 2)) + :right (int (/ (- width size) 2))})) (def viewfinder-port {:position :absolute :left 0 @@ -101,24 +59,37 @@ :right 0 :flex 1}) -(defn viewfinder-translucent [height width side] - (let [viewport-offset 0.1666 - min-dimension (min height width) - min-offset (* viewport-offset min-dimension)] +(defn viewfinder-translucent [height width size side] + (let [top-bottom-width width + top-bottom-height (int (/ (- height size) 2)) + left-right-width (int (/ (- width size) 2)) + left-right-height (- height (* 2 top-bottom-height))] (cond-> {:position :absolute :background-color :black :opacity 0.7} - (= :top side) (assoc :height min-offset - :width width) - (= :right side) (assoc :height (- height min-offset) - :width min-offset - :bottom 0 - :right 0) - (= :bottom side) (assoc :height min-offset - :width (- width min-offset) + (= :top side) (assoc :height top-bottom-height + :width top-bottom-width) + (= :right side) (assoc :height left-right-height + :width left-right-width + :top top-bottom-height + :right 0) + (= :bottom side) (assoc :height top-bottom-height + :width top-bottom-width :bottom 0 - :left 0) - (= :left side) (assoc :height (- height (* 2 min-offset)) - :width min-offset - :top min-offset - :left 0)))) + :left 0) + (= :left side) (assoc :height left-right-height + :width left-right-width + :top top-bottom-height + :left 0)))) + +(def qr-code + {:flex 1 + :background-color colors/white-lighter-transparent + :align-items :center}) + +(defn qr-code-text [dimensions] + {:zIndex 1 + :padding-top 20 + :color :white + :text-align :center + :width (int (/ (:width dimensions) 2))}) diff --git a/src/status_im/ui/screens/wallet/choose_recipient/views.cljs b/src/status_im/ui/screens/wallet/choose_recipient/views.cljs index 0db613b9dc..5f22aeca4b 100644 --- a/src/status_im/ui/screens/wallet/choose_recipient/views.cljs +++ b/src/status_im/ui/screens/wallet/choose_recipient/views.cljs @@ -1,100 +1,65 @@ (ns status-im.ui.screens.wallet.choose-recipient.views (:require-macros [status-im.utils.views :refer [defview letsubs]]) - (:require [clojure.string :as string] - [re-frame.core :as re-frame] + (:require [re-frame.core :as re-frame] + [status-im.i18n :as i18n] + [status-im.ui.components.bottom-buttons.view :as bottom-buttons] + [status-im.ui.components.button.view :as button] [status-im.ui.components.camera :as camera] - [status-im.ui.components.icons.vector-icons :as vector-icons] [status-im.ui.components.react :as react] [status-im.ui.components.status-bar.view :as status-bar] + [status-im.ui.components.toolbar.actions :as actions] [status-im.ui.components.toolbar.view :as toolbar] - [status-im.ui.components.toolbar.actions :as act] - [status-im.i18n :as i18n] [status-im.ui.screens.wallet.choose-recipient.styles :as styles] - [status-im.utils.platform :as platform] - [status-im.ui.screens.wallet.styles :as wallet.styles])) + [status-im.utils.platform :as platform])) -(defn choose-from-contacts [] - (re-frame/dispatch [:navigate-to-modal - :contact-list-modal - {:handler #(re-frame/dispatch [:wallet/fill-request-from-contact %]) - :action :send - :params {:hide-actions? true}}])) - -(defn toolbar-view [camera-flashlight] - [toolbar/toolbar {:style wallet.styles/toolbar} - [toolbar/nav-button (act/back-white act/default-handler)] - [toolbar/content-title {:color :white} (i18n/label :t/wallet-choose-recipient)] - [toolbar/actions [{:icon (if (= :on camera-flashlight) :icons/flash-active - :icons/flash-inactive) +(defn- toolbar-view [camera-flashlight] + [toolbar/toolbar styles/toolbar + [toolbar/nav-button (actions/back-white actions/default-handler)] + [toolbar/content-title {:color :white} + (i18n/label :t/wallet-choose-recipient)] + [toolbar/actions [{:icon (if (= :on camera-flashlight) + :icons/flash-active + :icons/flash-inactive) :icon-opts {:color :white} - :handler #(re-frame/dispatch [:wallet/toggle-flashlight])}]]]) + :handler #(re-frame/dispatch [:wallet/toggle-flashlight])}]]]) -(defn recipient-buttons [] - [react/view {:style styles/recipient-buttons} - [react/touchable-highlight {:style (styles/recipient-touchable true) - :on-press choose-from-contacts} - [react/view {:style styles/recipient-button} - [react/text {:style styles/recipient-button-text} - (i18n/label :t/wallet-choose-from-contacts)] - [vector-icons/icon :icons/qr {:color :white - :container-style styles/recipient-icon}]]] - [react/touchable-highlight {:style (styles/recipient-touchable true) - :on-press #(react/get-from-clipboard - (fn [clipboard] - (re-frame/dispatch [:wallet/fill-request-from-url (string/trim-newline clipboard) nil])))} - [react/view {:style styles/recipient-button} - [react/text {:style styles/recipient-button-text} - (i18n/label :t/wallet-address-from-clipboard)] - [vector-icons/icon :icons/copy-from {:color :white - :container-style styles/recipient-icon}]]] - [react/touchable-highlight {:style styles/recipient-touchable-disabled} - [react/view {:style styles/recipient-button} - [react/text {:style styles/recipient-button-text-disabled} - (i18n/label :t/wallet-browse-photos)] - [vector-icons/icon :icons/browse {:color :white - :container-style styles/recipient-icon-disabled}]]]]) +(defn- viewfinder [{:keys [height width]} size] + [react/view {:style styles/viewfinder-port} + [react/view {:style (styles/viewfinder-translucent height width size :top)}] + [react/view {:style (styles/viewfinder-translucent height width size :right)}] + [react/view {:style (styles/viewfinder-translucent height width size :bottom)}] + [react/view {:style (styles/viewfinder-translucent height width size :left)}] + [react/image {:source {:uri :corner_left_top} + :style (styles/corner-left-top height width size)}] + [react/image {:source {:uri :corner_right_top} + :style (styles/corner-right-top height width size)}] + [react/image {:source {:uri :corner_left_bottom} + :style (styles/corner-left-bottom height width size)}] + [react/image {:source {:uri :corner_right_bottom} + :style (styles/corner-right-bottom height width size)}]]) -(defn viewfinder [{:keys [height width]}] - (let [min-dimension (min height width)] - [react/view {:style styles/viewfinder-port} - [react/view {:style (styles/viewfinder-translucent height width :top)}] - [react/view {:style (styles/viewfinder-translucent height width :right)}] - [react/view {:style (styles/viewfinder-translucent height width :bottom)}] - [react/view {:style (styles/viewfinder-translucent height width :left)}] - [react/image {:source {:uri :corner_left_top} - :style (styles/corner-left-top min-dimension)}] - [react/image {:source {:uri :corner_right_top} - :style (styles/corner-right-top min-dimension)}] - [react/image {:source {:uri :corner_left_bottom} - :style (styles/corner-left-bottom min-dimension)}] - [react/image {:source {:uri :corner_right_bottom} - :style (styles/corner-right-bottom min-dimension)}]])) +(defn- size [{:keys [height width]}] + (int (* 2 (/ (min height width) 3)))) (defview choose-recipient [] - (letsubs [camera-dimensions [:wallet.send/camera-dimensions] + (letsubs [dimensions (react/get-dimensions "window") camera-flashlight [:wallet.send/camera-flashlight] - camera-permitted? [:wallet.send/camera-permitted?] view [:get :view-id]] - [react/view {:style styles/wallet-container} - [status-bar/status-bar {:type :wallet}] + [react/view {:style styles/qr-code} + [status-bar/status-bar {:type :transparent}] [toolbar-view camera-flashlight] - [react/view {:style styles/qr-container - :pointerEvents :none - :on-layout #(let [layout (.. % -nativeEvent -layout)] - (re-frame/dispatch [:wallet.send/set-camera-dimensions - {:width (.-width layout) - :height (.-height layout)}]))} - - (when (and - (= view :choose-recipient) - (or platform/android? - camera-permitted?)) - [react/with-activity-indicator - {} - [camera/camera {:style styles/preview - :aspect :fill - :captureAudio false - :torchMode (camera/set-torch camera-flashlight) - :onBarCodeRead #(re-frame/dispatch [:wallet/fill-request-from-url (camera/get-qr-code-data %) nil])}]]) - [viewfinder camera-dimensions]] - [recipient-buttons]])) + [react/text {:style (styles/qr-code-text dimensions)} + (i18n/label :t/scan-qr-code)] + [react/view {:style styles/qr-container + :pointer-events :none} + [react/with-activity-indicator + {} + [camera/camera {:style styles/preview + :aspect :fill + :captureAudio false + :torchMode (camera/set-torch camera-flashlight) + :onBarCodeRead #(re-frame/dispatch [:wallet/fill-request-from-url (camera/get-qr-code-data %) nil])}]] + [viewfinder dimensions (size dimensions)]] + [bottom-buttons/bottom-button + [button/button {:disabled? false :on-press #(re-frame/dispatch [:navigate-back])} + (i18n/label :t/cancel)]]])) diff --git a/src/status_im/ui/screens/wallet/components.cljs b/src/status_im/ui/screens/wallet/components.cljs new file mode 100644 index 0000000000..e3636e7e87 --- /dev/null +++ b/src/status_im/ui/screens/wallet/components.cljs @@ -0,0 +1,75 @@ +(ns status-im.ui.screens.wallet.components + " + Higher-level components used in the wallet screens. + " + (:require [status-im.utils.utils :as utils] + [status-im.ui.components.colors :as colors] + [status-im.ui.components.icons.vector-icons :as vector-icons] + [status-im.ui.components.react :as react] + [status-im.ui.components.status-bar.view :as status-bar] + [status-im.ui.components.toolbar.actions :as actions] + [status-im.ui.components.toolbar.view :as toolbar] + [status-im.ui.screens.wallet.styles :as styles])) + +;; Wallet tab has a different coloring scheme (dark) that forces color changes (background, text) +;; It might be replaced by some theme mechanism + +(defn text-input [props text] + [react/text-input (utils/deep-merge {:placeholder-text-color colors/white-lighter-transparent + :selection-color colors/white + :style {:color colors/white + :font-size 15 + :height 52 + :letter-spacing -0.2}} + props) + text]) + +(defn- toolbar [action title] + [toolbar/toolbar {:style styles/toolbar} + [toolbar/nav-button action] + [toolbar/content-title {:color :white} + title]]) + +(defn simple-screen [title content] + [react/view {:flex 1 :background-color colors/blue} + [status-bar/status-bar {:type :wallet}] + [toolbar (actions/back-white actions/default-handler) + title] + content]) + +(defn- cartouche-content [{:keys [disabled?]} content] + [react/view {:style (styles/cartouche-content-wrapper disabled?)} + [react/view {:flex 1} + content]]) + +(defn cartouche [{:keys [disabled? on-press icon] :or {icon :icons/forward} :as m} header content] + [react/view {:style styles/cartouche-container} + [react/text {:style styles/cartouche-header} + header] + (if (or disabled? (nil? on-press)) + [cartouche-content m content] + [react/touchable-highlight {:on-press on-press} + [react/view + [cartouche-content m + (if-not (true? disabled?) + [react/view styles/cartouche-icon-wrapper + [react/view {:flex 1} ;; Let content shrink if needed + content] + [vector-icons/icon icon {:color :white}]] + content)]]])]) + +(defn- cartouche-primary-text [s] + [react/text {:style styles/cartouche-primary-text} + s]) + +(defn- cartouche-secondary-text [s] + [react/text {:style styles/cartouche-secondary-text} + s]) + +(defn cartouche-text-content [primary secondary] + [react/view {:flex-direction :row + :justify-content :space-between + :padding-horizontal 15 + :padding-vertical 15} + [cartouche-primary-text primary] + [cartouche-secondary-text secondary]]) diff --git a/src/status_im/ui/screens/wallet/components/animations.cljs b/src/status_im/ui/screens/wallet/components/animations.cljs index c97422fd21..6848a5fbac 100644 --- a/src/status_im/ui/screens/wallet/components/animations.cljs +++ b/src/status_im/ui/screens/wallet/components/animations.cljs @@ -7,6 +7,6 @@ (animation/parallel [(animation/timing opacity-value {:toValue 1 :duration 500}) - (animation/timing bottom-value {:toValue 8.5 + (animation/timing bottom-value {:toValue -40 :easing (.bezier (animation/easing) 0.685, 0.000, 0.025, 1.185) - :duration 500})])))) \ No newline at end of file + :duration 500})])))) diff --git a/src/status_im/ui/screens/wallet/components/styles.cljs b/src/status_im/ui/screens/wallet/components/styles.cljs index d05d69ca6e..9b59fb9e2c 100644 --- a/src/status_im/ui/screens/wallet/components/styles.cljs +++ b/src/status_im/ui/screens/wallet/components/styles.cljs @@ -1,24 +1,23 @@ (ns status-im.ui.screens.wallet.components.styles (:require-macros [status-im.utils.styles :refer [defnstyle defstyle]]) - (:require [status-im.ui.components.styles :as styles])) + (:require [status-im.ui.components.colors :as colors] + [status-im.ui.components.styles :as styles])) (def text-content - {:color :white}) + {:color colors/white}) (def text-secondary-content - {:color styles/color-white-transparent}) + {:color colors/white-lighter-transparent}) (def text {:margin-right 10}) (def text-list-primary-content - (merge text {:color styles/color-black})) + (merge text {:color colors/black})) (def text-input (merge text-content - {:padding-left 14 - :padding-right 14 - :font-size 15 + {:font-size 15 :padding-bottom 0 :padding-top 0 :height 52 @@ -36,15 +35,14 @@ (def label-transparent (merge label - {:color styles/color-white-transparent})) + {:color colors/white-lighter-transparent})) -(defnstyle amount-container [active?] +(defn amount-container [active?] {:height 52 :background-color (if active? - styles/color-white-transparent-4 + colors/white-light-transparent styles/color-white-transparent-3) - :ios {:border-radius 8} - :android {:border-radius 4}}) + :border-radius 8}) (def network {:color :white @@ -56,11 +54,11 @@ :height 27 :border-radius 100 :border-width 1 - :border-color styles/color-white-transparent-4 + :border-color colors/white-light-transparent :align-items :center :justify-content :center}) -(defstyle asset-container +(def asset-container {:margin-top 8 :height 52 :background-color styles/color-white-transparent-3 @@ -68,12 +66,23 @@ :padding-left 14 :padding-vertical 14 :padding-right 8 - :ios {:border-radius 8} - :android {:border-radius 4}}) + :border-radius 8}) + +(def asset-container-read-only + {:margin-top 8 + :height 52 + :border-color styles/color-white-transparent-3 + :border-width 1 + :justify-content :center + :padding-left 14 + :padding-vertical 14 + :padding-right 8 + :border-radius 8}) (def asset-content-container - {:flex-direction :row - :align-items :center}) + {:flex-direction :row + :align-items :center + :margin-vertical 11}) (def asset-icon {:background-color styles/color-gray9 @@ -97,37 +106,19 @@ (defstyle container-disabled {:border-width 1 - :border-color styles/color-white-transparent-4 + :border-color colors/white-light-transparent :background-color nil - :ios {:border-radius 8} - :android {:border-radius 4}}) + :border-radius 8}) - -(defstyle recipient-container - {:flex-direction :row - :flex 1 - :margin-top 8 - :height 52 - :align-items :center - :background-color styles/color-white-transparent-3 - :padding-vertical 14 - :padding-left 14 - :padding-right 8 - :ios {:border-radius 8} - :android {:border-radius 4}}) - -(defstyle wallet-container +(def wallet-container {:flex-direction :row :margin-top 8 :height 52 - ;;TODO disabled :border-width 1 - :border-color styles/color-white-transparent-4 - ;:background-color styles/color-white-transparent-3 + :border-color colors/white-light-transparent :align-items :center :padding 14 - :ios {:border-radius 8} - :android {:border-radius 4}}) + :border-radius 8}) (def wallet-name {:color :white @@ -135,11 +126,34 @@ :letter-spacing -0.2}) (defn participant [address?] - {:color (if address? :white styles/color-white-transparent) + {:color (if address? :white colors/white-lighter-transparent) :flex-shrink 1 :font-size 15 :letter-spacing -0.2}) +(def recipient-container + {:flex-direction :row}) + +(def recipient-icon + {:margin-top 11}) + +(def recipient-name + {:flex 1 + :flex-direction :column + :margin-horizontal 12 + :margin-vertical 16}) + +(def recipient-address + {:margin-vertical 17 + :color colors/white}) + +(def recipient-no-address + {:color colors/white-lighter-transparent}) + +(def recent-recipients + {:flex 1 + :background-color colors/white}) + (def wallet-value-container {:flex 1 :flex-direction :row}) @@ -191,31 +205,3 @@ (def tooltip-triangle {:width 16 :height 8}) - -(def recipient-name-container - {:padding-right 6}) - -(def today-variation-container - {:border-radius 100 - :margin-left 8 - :padding-horizontal 8 - :padding-vertical 4}) - -(def today-variation-container-positive - (merge today-variation-container - {:background-color styles/color-green-1})) - -(def today-variation-container-negative - (merge today-variation-container - {:background-color styles/color-red-3})) - -(def today-variation - {:font-size 12}) - -(def today-variation-positive - (merge today-variation - {:color styles/color-green-2})) - -(def today-variation-negative - (merge today-variation - {:color styles/color-red-4})) \ No newline at end of file diff --git a/src/status_im/ui/screens/wallet/components/views.cljs b/src/status_im/ui/screens/wallet/components/views.cljs index 745f6eb870..e33cae0648 100644 --- a/src/status_im/ui/screens/wallet/components/views.cljs +++ b/src/status_im/ui/screens/wallet/components/views.cljs @@ -1,64 +1,44 @@ (ns status-im.ui.screens.wallet.components.views (:require-macros [status-im.utils.views :as views]) - (:require [reagent.core :as reagent] + (:require [clojure.string :as string] + [reagent.core :as reagent] [re-frame.core :as re-frame] - [status-im.ui.components.react :as react] - [status-im.ui.components.status-bar.view :as status-bar] - [status-im.ui.components.styles :as components.styles] - [status-im.ui.screens.wallet.components.styles :as styles] [status-im.i18n :as i18n] [status-im.ui.components.animation :as animation] + [status-im.ui.components.bottom-buttons.view :as bottom-buttons] + [status-im.ui.components.button.view :as button] + [status-im.ui.components.chat-icon.screen :as chat-icon] [status-im.ui.components.icons.vector-icons :as vector-icons] [status-im.ui.components.list.views :as list] - [status-im.ui.components.toolbar.view :as toolbar] + [status-im.ui.components.list.styles :as list.styles] + [status-im.ui.components.list-selection :as list-selection] + [status-im.ui.components.react :as react] + [status-im.ui.components.styles :as components.styles] + [status-im.ui.screens.wallet.components :as components] + [status-im.ui.screens.wallet.components.animations :as animations] + [status-im.ui.screens.wallet.components.styles :as styles] + [status-im.ui.screens.wallet.choose-recipient.views :as choose-recipient] + [status-im.ui.screens.wallet.main.views :as main] + [status-im.ui.screens.wallet.utils :as wallet.utils] [status-im.utils.ethereum.core :as ethereum] [status-im.utils.ethereum.tokens :as tokens] - [status-im.utils.platform :as platform] - [status-im.ui.screens.wallet.components.animations :as animations] - [status-im.ui.screens.wallet.main.views :as main] - [status-im.ui.screens.wallet.utils :as wallet.utils])) + [status-im.utils.platform :as platform])) -(views/defview tooltip [label & [style]] - (views/letsubs [bottom-value (animation/create-value 16) +(views/defview tooltip [label] + (views/letsubs [bottom-value (animation/create-value -30) opacity-value (animation/create-value 0)] {:component-did-mount (animations/animate-tooltip bottom-value opacity-value)} [react/view styles/tooltip-container - [react/animated-view {:style (merge (styles/tooltip-animated bottom-value opacity-value) style)} + [react/animated-view {:style (styles/tooltip-animated bottom-value opacity-value)} [react/view styles/tooltip-text-container [react/text {:style styles/tooltip-text} label]] [vector-icons/icon :icons/tooltip-triangle {:color :white :style styles/tooltip-triangle}]]])) -(defn amount-input [] - (let [active? (reagent/atom false)] - (fn [& [{:keys [input-options style error disabled?]}]] - (let [{:keys [on-focus on-blur]} input-options] - [react/view components.styles/flex - [react/text {:style styles/label} (i18n/label :t/amount)] - [react/view styles/amount-text-input-container - [react/view (merge (styles/amount-container @active?) (if disabled? styles/container-disabled style)) - [react/text-input - (merge - {:style styles/text-input} - (if disabled? - {:editable false} - {:keyboard-type :numeric - :placeholder (i18n/label :t/amount-placeholder) - :placeholder-text-color components.styles/color-white-transparent - :selection-color components.styles/color-white - :style styles/text-input - :on-focus #(do (reset! active? true) - (when on-focus (on-focus))) - :on-blur #(do (reset! active? false) - (when on-blur (on-blur)))}) - (dissoc input-options :on-focus :on-blur))]] - (when-not (nil? error) - [tooltip error])]])))) - -(views/defview view-asset [symbol] +(defn view-asset [symbol] [react/view [react/text {:style styles/label} (i18n/label :t/wallet-asset)] - [react/view styles/asset-container + [react/view styles/asset-container-read-only [react/text {:style styles/asset-text} (name symbol)]]]) @@ -76,11 +56,9 @@ [list/item-image icon] [list/item-content [react/view {:flex-direction :row} - [react/text {:style (merge styles/text-list-primary-content) - :number-of-lines 1} + [react/text {:style styles/text-list-primary-content} name] - [react/text {:uppercase? true - :number-of-lines 1} + [react/text {:uppercase? true} (clojure.core/name symbol)]] [list/item-secondary (wallet.utils/format-amount (symbol balance) decimals)]]]]]) @@ -88,14 +66,11 @@ (views/letsubs [network [:network] visible-tokens [:wallet.settings/visible-tokens] balance [:balance]] - [react/view components.styles/flex - [status-bar/status-bar {}] - [toolbar/toolbar {} - [toolbar/nav-clear-text (i18n/label :t/done)] - [toolbar/content-title (i18n/label :t/wallet-assets)]] - [react/view {:style components.styles/flex} - [list/flat-list {:data (concat [tokens/ethereum] (main/current-tokens visible-tokens network)) - :render-fn #(render-token % balance type)}]]])) + [components/simple-screen (i18n/label :t/wallet-assets) + [react/view {:style (assoc components.styles/flex :background-color :white)} + [list/flat-list {:default-separator? true + :data (concat [tokens/ethereum] (main/current-tokens visible-tokens network)) + :render-fn #(render-token % balance type)}]]])) (defn send-assets [] [assets :send]) @@ -109,54 +84,115 @@ :request :wallet-request-assets (throw (str "Unknown type: " k)))) -(views/defview choose-asset [{:keys [type symbol]}] +(views/defview asset-selector [{:keys [disabled? type symbol]}] (views/letsubs [balance [:balance] network [:network]] (let [{:keys [name icon decimals]} (tokens/asset-for (ethereum/network->chain-keyword network) symbol)] - [react/view - [react/text {:style styles/label} - (i18n/label :t/wallet-asset)] - [react/touchable-highlight {:style styles/asset-container - :on-press #(re-frame/dispatch [:navigate-to (type->view type)])} - [react/view styles/asset-content-container - [list/item-image (assoc icon :style styles/asset-icon :image-style {:width 32 :height 32})] - [react/view styles/asset-text-content - [react/view styles/asset-label-content - [react/text {:style (merge styles/text-content styles/asset-label)} - name] - [react/text {:style styles/text-secondary-content} - (clojure.core/name symbol)]] - [react/text {:style (merge styles/text-secondary-content styles/asset-label)} - (str (wallet.utils/format-amount (symbol balance) decimals))]] - [vector-icons/icon :icons/forward {:color :white}]]]]))) + [components/cartouche {:disabled? disabled? :on-press #(re-frame/dispatch [:navigate-to (type->view type)])} + (i18n/label :t/wallet-asset) + [react/view styles/asset-content-container + [list/item-image (assoc icon :style styles/asset-icon :image-style {:width 32 :height 32})] + [react/view styles/asset-text-content + [react/view styles/asset-label-content + [react/text {:style (merge styles/text-content styles/asset-label)} + name] + [react/text {:style styles/text-secondary-content} + (clojure.core/name symbol)]] + [react/text {:style (merge styles/text-secondary-content styles/asset-label)} + (str (wallet.utils/format-amount (symbol balance) decimals))]]]]))) -(defn choose-recipient-content [{:keys [address name on-press style]}] - (let [address? (and (not (nil? address)) (not= address ""))] - [react/view - [react/text {:style styles/label} (i18n/label :t/recipient)] - [react/view (merge styles/recipient-container - (when-not on-press styles/container-disabled) - style) - (when name - [react/view styles/recipient-name-container - [react/text {:style (styles/participant true) - :number-of-lines 1} - name]]) +(defn- recipient-address [address] + [react/text {:style (merge styles/recipient-address (when-not address styles/recipient-no-address))} + (or (ethereum/normalized-address address) (i18n/label :t/specify-recipient))]) + +(views/defview recipient-contact [address name] + (views/letsubs [contact [:contact/by-address address]] + (let [address? (and (not (nil? address)) (not= address ""))] + [react/view styles/recipient-container + [react/view styles/recipient-icon + [chat-icon/chat-icon (:photo-path contact) {:size list.styles/image-size}]] + [react/view styles/recipient-name + [react/text {:style (styles/participant true) + :number-of-lines 1} + name] + [react/text {:style (styles/participant (and (not name) address?))} + (ethereum/normalized-address address)]]]))) + +(defn render-contact [contact] + [list/touchable-item #(re-frame/dispatch [:wallet/fill-request-from-contact contact]) + [list/item + [chat-icon/chat-icon (:photo-path contact) {:size list.styles/image-size}] + [list/item-content + [list/item-primary (:name contact)] + [react/text {:style list.styles/secondary-text} + (ethereum/normalized-address (:address contact))]]]]) + +(views/defview recent-recipients [] + (views/letsubs [contacts [:contacts-filtered :all-added-people-contacts]] + [components/simple-screen + (i18n/label :t/recipient) + [react/view styles/recent-recipients + [list/flat-list {:data contacts + :render-fn render-contact}]]])) + +(defn contact-code [] + (let [content (reagent/atom nil)] + (fn [] [react/view components.styles/flex - [react/text {:style (styles/participant (and (not name) address?)) - :number-of-lines 1 - :ellipsizeMode :middle} - (if address? address "Choose recipient...")]] - (when on-press - [vector-icons/icon :icons/forward {:color :white}])]])) + [components/simple-screen + (i18n/label :t/recipient) + [react/view components.styles/flex + [components/cartouche {} + (i18n/label :t/recipient) + [components/text-input {:multiline true + :placeholder (i18n/label :t/recipient-code) + :on-change-text #(reset! content %)}]] + [bottom-buttons/bottom-button + [button/button {:disabled? (string/blank? @content) + :on-press #(re-frame/dispatch [:wallet/fill-request-from-url @content])} + (i18n/label :t/done)]]]]]))) -(defn choose-recipient [{:keys [on-press] :as m}] - (if on-press - [react/touchable-highlight {:on-press on-press} - [react/view ;; TODO(jeluard) remove extra view when migrating to latest RN - [choose-recipient-content m]]] - [react/view - [choose-recipient-content m]])) +(defn recipient-qr-code [] + [choose-recipient/choose-recipient]) + +(defn- request-camera-permissions [] + (re-frame/dispatch [:request-permissions [:camera] + #(re-frame/dispatch [:navigate-to :recipient-qr-code])])) + +(defn- on-choose-recipient [] + (list-selection/show {:title (i18n/label :t/wallet-choose-recipient) + :options [{:label (i18n/label :t/recent-recipients) + :action #(re-frame/dispatch [:navigate-to :recent-recipients])} + {:label (i18n/label :t/scan-qr) + :action request-camera-permissions} + {:label (i18n/label :t/enter-contact-code) + :action #(re-frame/dispatch [:navigate-to :contact-code])}]})) + +(defn recipient-selector [{:keys [name address disabled?]}] + [components/cartouche {:on-press on-choose-recipient :disabled? disabled? :icon :icons/dots-horizontal} + (i18n/label :t/wallet-choose-recipient) + (if name + [recipient-contact address name] + [recipient-address address])]) + +(defn- amount-input [{:keys [input-options disabled?]}] + [react/view components.styles/flex + [components/text-input + (merge + (if disabled? + {:editable false} + {:keyboard-type :numeric + :placeholder (i18n/label :t/amount-placeholder) + :style components.styles/flex}) + input-options)]]) + +(defn amount-selector [{:keys [error disabled?] :as m}] + [react/view + [components/cartouche {:disabled? disabled?} + (i18n/label :t/amount) + [amount-input m]] + (when error + [tooltip error])]) (defn separator [] [react/view styles/separator]) @@ -165,15 +201,3 @@ [react/text {:style styles/button-text :font (if platform/android? :medium :default) :uppercase? (get-in platform/platform-specific [:uppercase?])} label]) - -(defn change-display [change] - (let [pos-change? (or (pos? change) (zero? change))] - [react/view {:style (if pos-change? - styles/today-variation-container-positive - styles/today-variation-container-negative)} - [react/text {:style (if pos-change? - styles/today-variation-positive - styles/today-variation-negative)} - (if change - (str (when pos-change? "+") change "%") - "-%")]])) diff --git a/src/status_im/ui/screens/wallet/db.cljs b/src/status_im/ui/screens/wallet/db.cljs index 9965a39101..ed364ae63e 100644 --- a/src/status_im/ui/screens/wallet/db.cljs +++ b/src/status_im/ui/screens/wallet/db.cljs @@ -38,4 +38,4 @@ {:error (i18n/label :t/validation-amount-is-too-precise) :value value} :else - {:value value})))) \ No newline at end of file + {:value value})))) diff --git a/src/status_im/ui/screens/wallet/main/styles.cljs b/src/status_im/ui/screens/wallet/main/styles.cljs index 460b68031f..e560502d0a 100644 --- a/src/status_im/ui/screens/wallet/main/styles.cljs +++ b/src/status_im/ui/screens/wallet/main/styles.cljs @@ -66,7 +66,7 @@ {:background-color colors/blue}) (def action - {:background-color colors/white-light-transparent + {:background-color colors/white-transparent :border-radius 50}) (def action-label @@ -74,7 +74,7 @@ (def action-separator {:height 1 - :background-color colors/white-transparent + :background-color colors/white-light-transparent :margin-left 70}) ;; Assets section @@ -116,6 +116,3 @@ {:font-size 16 :color styles/color-gray4 :margin-left 6}) - -(defn asset-border [color] - {:border-color color :border-width 1 :border-radius 32}) diff --git a/src/status_im/ui/screens/wallet/main/views.cljs b/src/status_im/ui/screens/wallet/main/views.cljs index ccf27125cf..2e572a2670 100644 --- a/src/status_im/ui/screens/wallet/main/views.cljs +++ b/src/status_im/ui/screens/wallet/main/views.cljs @@ -2,7 +2,6 @@ (:require-macros [status-im.utils.views :refer [defview letsubs]]) (:require [re-frame.core :as re-frame] [status-im.i18n :as i18n] - [status-im.ui.components.colors :as colors] [status-im.ui.components.styles :as components.styles] [status-im.ui.components.list.views :as list] [status-im.ui.components.react :as react] @@ -18,12 +17,12 @@ [status-im.utils.platform :as platform])) (defn toolbar-view [] - [toolbar/toolbar {:style wallet.styles/toolbar} + [toolbar/toolbar {:style wallet.styles/toolbar :flat? true} nil [toolbar/content-wrapper] [toolbar/actions - [(assoc (act/opts [{:text (i18n/label :t/wallet-manage-assets) - :value #(re-frame/dispatch [:navigate-to-modal :wallet-settings-assets])}]) + [(assoc (act/opts [{:label (i18n/label :t/wallet-manage-assets) + :action #(re-frame/dispatch [:navigate-to-modal :wallet-settings-assets])}]) :icon-opts {:color :white})]]]) (defn- total-section [usd-value syncing? error-message] @@ -38,23 +37,23 @@ [react/text {:style styles/total-balance-currency} (i18n/label :t/usd-currency)]] [react/text {:style styles/total-value} (i18n/label :t/wallet-total-value)]]]) -(defn- render-action [{:keys [name icon action]}] +(defn- render-action [{:keys [label icon action]}] [react/touchable-highlight {:on-press action} [react/view [list/item [list/item-icon {:icon icon :style styles/action :icon-opts {:color :white}}] [list/item-primary-only {:style styles/action-label} - name] + label] list/item-icon-forward]]]) (def actions - [{:name (i18n/label :t/send-transaction) + [{:label (i18n/label :t/send-transaction) :icon :icons/arrow-right :action #(re-frame/dispatch [:navigate-to :wallet-send-transaction])} - {:name (i18n/label :t/receive-transaction) + {:label (i18n/label :t/receive-transaction) :icon :icons/arrow-left :action #(re-frame/dispatch [:navigate-to :wallet-request-transaction])} - {:name (i18n/label :t/transaction-history) + {:label (i18n/label :t/transaction-history) :icon :icons/transaction-history :action #(re-frame/dispatch [:navigate-to :transactions-history])}]) diff --git a/src/status_im/ui/screens/wallet/request/styles.cljs b/src/status_im/ui/screens/wallet/request/styles.cljs index 3962429df1..f7ffaa61ce 100644 --- a/src/status_im/ui/screens/wallet/request/styles.cljs +++ b/src/status_im/ui/screens/wallet/request/styles.cljs @@ -6,12 +6,11 @@ {:flex 1 :align-items :center}) -(defstyle qr-container +(def qr-container {:margin-top 8 :padding 16 :background-color styles/color-white - :ios {:border-radius 8} - :android {:border-radius 4}}) + :border-radius 8}) (def share-icon-container {:margin-right 8}) diff --git a/src/status_im/ui/screens/wallet/request/views.cljs b/src/status_im/ui/screens/wallet/request/views.cljs index 7c385ea525..ee1d15b89c 100644 --- a/src/status_im/ui/screens/wallet/request/views.cljs +++ b/src/status_im/ui/screens/wallet/request/views.cljs @@ -1,24 +1,24 @@ (ns status-im.ui.screens.wallet.request.views (:require-macros [status-im.utils.views :as views]) (:require [re-frame.core :as re-frame] + [status-im.i18n :as i18n] + [status-im.ui.components.common.common :as common] + [status-im.ui.components.icons.vector-icons :as vector-icons] [status-im.ui.components.react :as react] - [status-im.ui.components.qr-code-viewer.views :as components.qr-code-viewer] + [status-im.ui.components.status-bar.view :as status-bar] + [status-im.ui.components.styles :as components.styles] + [status-im.ui.components.qr-code-viewer.views :as qr-code-viewer] [status-im.ui.components.toolbar.actions :as actions] [status-im.ui.components.toolbar.view :as toolbar] - [status-im.ui.components.status-bar.view :as status-bar] - [status-im.ui.screens.wallet.styles :as wallet.styles] - [status-im.ui.components.common.common :as common] - [status-im.ui.components.icons.vector-icons :as vi] [status-im.ui.screens.wallet.components.views :as components] [status-im.ui.screens.wallet.request.styles :as styles] - [status-im.ui.components.styles :as components.styles] - [status-im.i18n :as i18n] + [status-im.ui.screens.wallet.styles :as wallet.styles] [status-im.utils.ethereum.core :as ethereum] [status-im.utils.ethereum.eip681 :as eip681] [status-im.utils.ethereum.tokens :as tokens])) (defn toolbar-view [] - [toolbar/toolbar {:style wallet.styles/toolbar :hide-border? true} + [toolbar/toolbar {:style wallet.styles/toolbar} [toolbar/nav-button (actions/back-white actions/default-handler)] [toolbar/content-title {:color :white} (i18n/label :t/request-transaction)]]) @@ -37,7 +37,7 @@ (views/defview qr-code [amount symbol] (views/letsubs [account [:get-current-account] chain-id [:get-network-id]] - [components.qr-code-viewer/qr-code + [qr-code-viewer/qr-code (let [address (ethereum/normalized-address (:address account)) params {:chain-id chain-id :value amount :symbol (or symbol :ETH)}] {:value (generate-value address params) @@ -61,22 +61,20 @@ [react/with-activity-indicator {:style wallet.styles/qr-code-preview} [qr-code amount symbol]]]] - [react/view wallet.styles/amount-container - [components/amount-input - {:error amount-error - :input-options {:on-focus (fn [] (when @scroll (js/setTimeout #(.scrollToEnd @scroll) 100))) - :on-change-text #(re-frame/dispatch [:wallet.request/set-and-validate-amount %])}}]] - [react/view wallet.styles/choose-asset-container - [components/choose-asset {:type :request - :symbol symbol}]]]] + [components/amount-selector + {:error amount-error + :input-options {:on-focus (fn [] (when @scroll (js/setTimeout #(.scrollToEnd @scroll) 100))) + :on-change-text #(re-frame/dispatch [:wallet.request/set-and-validate-amount %])}}] + [components/asset-selector {:type :request + :symbol symbol}]]] [components/separator] [react/view wallet.styles/buttons-container [react/touchable-highlight {:style wallet.styles/button :disabled true} [react/view (wallet.styles/button-container false) - [vi/icon :icons/share {:color :white :container-style styles/share-icon-container}] + [vector-icons/icon :icons/share {:color :white :container-style styles/share-icon-container}] [components/button-text (i18n/label :t/share)]]] [react/view components.styles/flex] [react/touchable-highlight {:style wallet.styles/button :disabled (not request-enabled?) :on-press send-request} [react/view (wallet.styles/button-container request-enabled?) [components/button-text (i18n/label :t/send-request)] - [vi/icon :icons/forward {:color :white :container-style wallet.styles/forward-icon-container}]]]]])) + [vector-icons/icon :icons/forward {:color :white :container-style wallet.styles/forward-icon-container}]]]]])) diff --git a/src/status_im/ui/screens/wallet/send/db.cljs b/src/status_im/ui/screens/wallet/send/db.cljs index 0a2e3c94bd..4eac7ff76a 100644 --- a/src/status_im/ui/screens/wallet/send/db.cljs +++ b/src/status_im/ui/screens/wallet/send/db.cljs @@ -15,9 +15,7 @@ (spec/def ::later? (spec/nilable boolean?)) (spec/def ::height double?) (spec/def ::width double?) -(spec/def ::camera-dimensions (spec/keys :req-un [::height ::width])) (spec/def ::camera-flashlight #{:on :off}) -(spec/def ::camera-permitted? boolean?) (spec/def ::in-progress? boolean?) (spec/def ::from-chat? (spec/nilable boolean?)) (spec/def ::symbol (spec/nilable keyword?)) @@ -28,6 +26,6 @@ (spec/def :wallet/send-transaction (allowed-keys :opt-un [::amount ::to ::to-name ::amount-error ::password ::waiting-signal? ::signing? ::id ::later? - ::camera-dimensions ::camera-flashlight ::in-progress? - ::wrong-password? ::camera-permitted? ::from-chat? ::symbol ::advanced? + ::camera-flashlight ::in-progress? + ::wrong-password? ::from-chat? ::symbol ::advanced? ::gas ::gas-price])) diff --git a/src/status_im/ui/screens/wallet/send/events.cljs b/src/status_im/ui/screens/wallet/send/events.cljs index 8a6d2e15ed..cf6e198b56 100644 --- a/src/status_im/ui/screens/wallet/send/events.cljs +++ b/src/status_im/ui/screens/wallet/send/events.cljs @@ -255,11 +255,6 @@ :signing? false :wrong-password? false)})) -(handlers/register-handler-fx - :wallet.send/set-camera-dimensions - (fn [{:keys [db]} [_ camera-dimensions]] - {:db (assoc-in db [:wallet :send-transaction :camera-dimensions] camera-dimensions)})) - (handlers/register-handler-fx :wallet.send/set-password (fn [{:keys [db]} [_ password]] diff --git a/src/status_im/ui/screens/wallet/send/styles.cljs b/src/status_im/ui/screens/wallet/send/styles.cljs index 1c432e8a1e..747be4546d 100644 --- a/src/status_im/ui/screens/wallet/send/styles.cljs +++ b/src/status_im/ui/screens/wallet/send/styles.cljs @@ -1,29 +1,11 @@ (ns status-im.ui.screens.wallet.send.styles - (:require-macros [status-im.utils.styles :refer [defnstyle defstyle]]) - (:require [status-im.ui.components.styles :as styles] + (:require [status-im.ui.components.colors :as colors] + [status-im.ui.components.styles :as styles] [status-im.ui.screens.wallet.components.styles :as wallet.components.styles])) -(def toolbar - {:background-color styles/color-blue5 - :elevation 0 - :padding-bottom 10}) - -(def toolbar-title-container +(def send-transaction-form {:flex 1 - :flex-direction :row - :margin-left 6}) - -(def toolbar-title-text - {:color styles/color-white - :font-size 17 - :margin-right 4}) - -(def toolbar-icon - {:width 24 - :height 24}) - -(def toolbar-title-icon - (merge toolbar-icon {:opacity 0.4})) + :padding-bottom 60}) (defn animated-sign-panel [bottom-value] {:position :absolute @@ -34,7 +16,7 @@ (defn sign-panel [opacity-value] {:opacity opacity-value :border-radius 8 - :background-color :white + :background-color colors/white :padding-top 12 :padding-horizontal 12}) @@ -43,12 +25,12 @@ :height 36 :align-items :center :justify-content :center - :background-color styles/color-light-gray}) + :background-color colors/gray-lighter}) (def signing-phrase {:font-size 15 :letter-spacing -0.2 - :color :black}) + :color colors/black}) (def signing-phrase-description {:padding-top 8}) @@ -71,13 +53,16 @@ :left 0 :align-items :center :justify-content :center - :background-color (str styles/color-black "1A")}) + :background-color (str colors/black "1A")}) (def empty-text {:text-align :center :margin-top 22 :margin-horizontal 92}) +(def advanced-cartouche + {:padding-bottom 50}) + (def advanced-button {:flex-direction :row :background-color styles/color-blue6 @@ -89,63 +74,43 @@ {:align-items :center}) (def advanced-wrapper - {:margin-horizontal 15}) + {:margin-top 24 + :margin-bottom 16}) (def advanced-options-wrapper - {:height 52 - :background-color styles/color-white-transparent-3 - :border-radius 4 - :margin-top 16 - :margin-bottom 16 - :align-items :center - :flex-direction :row - :padding-vertical 14 - :padding-right 8 - :ios {:border-radius 8} - :android {:border-radius 4}}) + {:align-items :center + :flex-direction :row}) (def advanced-options-text-wrapper - {:flex 1 - :flex-direction :row - :justify-content :space-between - :margin-horizontal 15}) + {:flex 1 + :flex-direction :row + :justify-content :space-between + :margin-vertical 15}) (def advanced-label {:text-align-vertical :center :margin-left 4}) (def advanced-fees-text - {:color styles/color-white}) + {:color colors/white}) (def advanced-fees-details-text - {:color styles/color-white-transparent}) + {:color colors/white-lighter-transparent}) (def transaction-fee-block-wrapper - {:flex-direction :row - :margin-top 15}) - -(def transaction-fee-column-wrapper - {:flex 0.5 - :margin-horizontal 15}) - -(def transaction-fee-bubble - (merge advanced-options-wrapper - {:flex-direction :row - :justify-content :space-between - :padding-horizontal 15})) - -(def transaction-fee-bubble-read-only - (merge transaction-fee-bubble - {:background-color styles/color-blue6})) + {:flex-direction :row}) (def transaction-fee-info {:margin 15}) (def transaction-fee-input - {:flex 1 - :keyboard-type :numeric + {:keyboard-type :numeric :auto-capitalize "none" :placeholder "0.000" - :placeholder-text-color styles/color-white-transparent - :selection-color :white - :style wallet.components.styles/text-input}) \ No newline at end of file + :placeholder-text-color colors/white-lighter-transparent + :selection-color colors/white + :style wallet.components.styles/text-input}) + +(def sign-buttons + {:background-color colors/blue + :padding-vertical 8}) diff --git a/src/status_im/ui/screens/wallet/send/subs.cljs b/src/status_im/ui/screens/wallet/send/subs.cljs index cb9a6e5bbd..bedec400d8 100644 --- a/src/status_im/ui/screens/wallet/send/subs.cljs +++ b/src/status_im/ui/screens/wallet/send/subs.cljs @@ -31,21 +31,11 @@ (fn [send-transaction] (:advanced? send-transaction))) -(re-frame/reg-sub :wallet.send/camera-dimensions - :<- [::send-transaction] - (fn [send-transaction] - (:camera-dimensions send-transaction))) - (re-frame/reg-sub :wallet.send/camera-flashlight :<- [::send-transaction] (fn [send-transaction] (:camera-flashlight send-transaction))) -(re-frame/reg-sub :wallet.send/camera-permitted? - :<- [::send-transaction] - (fn [send-transaction] - (:camera-permitted? send-transaction))) - (re-frame/reg-sub :wallet.send/wrong-password? :<- [::send-transaction] (fn [send-transaction] @@ -79,7 +69,7 @@ (re-frame/reg-sub :wallet.send/transaction :<- [::send-transaction] :<- [:balance] - (fn [[{:keys [amount to symbol] :as transaction} balance]] + (fn [[{:keys [amount symbol] :as transaction} balance]] (assoc transaction :sufficient-funds? (or (nil? amount) (money/sufficient-funds? amount (get balance symbol)))))) diff --git a/src/status_im/ui/screens/wallet/send/views.cljs b/src/status_im/ui/screens/wallet/send/views.cljs index 1137c0d255..608a554fad 100644 --- a/src/status_im/ui/screens/wallet/send/views.cljs +++ b/src/status_im/ui/screens/wallet/send/views.cljs @@ -2,9 +2,9 @@ (:require [re-frame.core :as re-frame] [status-im.i18n :as i18n] [status-im.ui.components.animation :as animation] - [status-im.ui.components.camera :as camera] + [status-im.ui.components.bottom-buttons.view :as bottom-buttons] + [status-im.ui.components.button.view :as button] [status-im.ui.components.common.common :as common] - [status-im.ui.components.styles :as styles] [status-im.ui.components.icons.vector-icons :as vector-icons] [status-im.ui.components.react :as react] [status-im.ui.components.status-bar.view :as status-bar] @@ -13,11 +13,11 @@ [status-im.ui.components.toolbar.view :as toolbar] [status-im.ui.screens.wallet.components.styles :as wallet.components.styles] [status-im.ui.screens.wallet.components.views :as components] + [status-im.ui.screens.wallet.components :as wallet.components] [status-im.ui.screens.wallet.send.animations :as send.animations] [status-im.ui.screens.wallet.send.styles :as send.styles] [status-im.ui.screens.wallet.styles :as wallet.styles] [status-im.utils.money :as money] - [status-im.utils.platform :as platform] [status-im.utils.utils :as utils]) (:require-macros [status-im.utils.views :refer [defview letsubs]])) @@ -56,16 +56,15 @@ ;; "Cancel" and "Sign Transaction >" buttons, signing with password (defview signing-buttons [cancel-handler sign-handler in-progress?] (letsubs [sign-enabled? [:wallet.send/sign-password-enabled?]] - [react/view wallet.styles/buttons-container - [react/touchable-highlight {:style wallet.styles/button :on-press cancel-handler} - [react/view (wallet.styles/button-container true) - [components/button-text (i18n/label :t/cancel)]]] - [react/view components.styles/flex] - [react/touchable-highlight {:style wallet.styles/button :on-press sign-handler} - [react/view (wallet.styles/button-container sign-enabled?) - (when in-progress? [react/activity-indicator {:animating? true}]) - [components/button-text (i18n/label :t/transactions-sign-transaction)] - [vector-icons/icon :icons/forward {:color :white :container-style wallet.styles/forward-icon-container}]]]])) + [bottom-buttons/bottom-buttons + send.styles/sign-buttons + [button/button {:style components.styles/flex + :on-press cancel-handler} + (i18n/label :t/cancel)] + [button/button {:style (wallet.styles/button-container sign-enabled?) + :on-press sign-handler} + (i18n/label :t/transactions-sign-transaction) + [vector-icons/icon :icons/forward {:color :white :container-style wallet.styles/forward-icon-container}]]])) (defn- sign-enabled? [amount-error to amount] (and @@ -75,46 +74,30 @@ ;; "Sign Later" and "Sign Transaction >" buttons (defn- sign-buttons [amount-error to amount sufficient-funds? sign-later-handler] - (let [sign-enabled? (sign-enabled? amount-error to amount) + (let [sign-enabled? (sign-enabled? amount-error to amount) immediate-sign-enabled? (and sign-enabled? sufficient-funds?)] - [react/view wallet.styles/buttons-container + [bottom-buttons/bottom-buttons + send.styles/sign-buttons (when sign-enabled? - [react/touchable-highlight {:style wallet.styles/button :on-press sign-later-handler} - [react/view (wallet.styles/button-container sign-enabled?) - [components/button-text (i18n/label :t/transactions-sign-later)]]]) - [react/view components.styles/flex] - [react/touchable-highlight {:style wallet.styles/button - :on-press (when immediate-sign-enabled? #(re-frame/dispatch [:wallet.send/set-signing? true]))} - [react/view (wallet.styles/button-container immediate-sign-enabled?) - [components/button-text (i18n/label :t/transactions-sign-transaction)] - [vector-icons/icon :icons/forward {:color :white :container-style wallet.styles/forward-icon-container}]]]])) + [button/button {:style components.styles/flex + :on-press sign-later-handler} + (i18n/label :t/transactions-sign-later)]) + [button/button {:style components.styles/flex + :disabled? (not immediate-sign-enabled?) + :on-press #(re-frame/dispatch [:wallet.send/set-signing? true]) + :text-style {:color :white}} + (i18n/label :t/transactions-sign-transaction) + [vector-icons/icon :icons/forward {:color (if immediate-sign-enabled? :white :gray) :container-style wallet.styles/forward-icon-container}]]])) -(defn- request-camera-permissions [] - (when platform/android? - (re-frame/dispatch [:request-permissions [:camera]])) - (camera/request-access - (fn [permitted?] - (re-frame/dispatch [:set-in [:wallet :send-transaction :camera-permitted?] permitted?]) - (re-frame/dispatch [:navigate-to :choose-recipient])))) +(defn handler [discard?] + (if discard? + #(re-frame/dispatch [:wallet/discard-transaction-navigate-back]) + act/default-handler)) -(defn- toolbar-modal [from-chat?] +(defn- toolbar [discard? action title] [toolbar/toolbar {:style wallet.styles/toolbar} - [toolbar/nav-button (act/close-white (if from-chat? - #(re-frame/dispatch [:wallet/discard-transaction-navigate-back]) - act/default-handler))] - [toolbar/content-title {:color :white} (i18n/label :t/send-transaction)]]) - -(defn- toolbar-view [signing?] - [toolbar/toolbar {:style wallet.styles/toolbar} - [toolbar/nav-button (act/back-white (if signing? - #(re-frame/dispatch [:wallet/discard-transaction-navigate-back]) - act/default-handler))] - [toolbar/content-title {:color :white} (i18n/label :t/send-transaction)]]) - -(defn- transaction-fee-toolbar [] - [toolbar/toolbar {:style wallet.styles/toolbar} - [toolbar/nav-button (act/close-white #(re-frame/dispatch [:wallet/discard-transaction-navigate-back]))] - [toolbar/content-title {:color :white} (i18n/label :t/wallet-transaction-fee)]]) + [toolbar/nav-button (action (handler discard?))] + [toolbar/content-title {:color :white} title]]) (defn- max-fee [gas gas-price] (when (and gas gas-price) @@ -125,109 +108,83 @@ [react/keyboard-avoiding-view wallet.styles/wallet-modal-container [react/view components.styles/flex [status-bar/status-bar {:type :modal-wallet}] - [transaction-fee-toolbar] - [react/view send.styles/transaction-fee-block-wrapper - [react/view send.styles/transaction-fee-column-wrapper - [react/text {:style send.styles/advanced-fees-text} - (i18n/label :t/gas-limit)] + [toolbar true act/close-white + (i18n/label :t/wallet-transaction-fee)] + [react/view {:flex-direction :row} + [wallet.components/cartouche {} + (i18n/label :t/gas-limit) + [react/text-input (merge send.styles/transaction-fee-input + {:on-change-text #(re-frame/dispatch [:wallet.send/set-gas %]) + :default-value (str (money/to-fixed gas))})]] + [wallet.components/cartouche {} + (i18n/label :t/gas-price) [react/view send.styles/advanced-options-wrapper - [react/text-input (merge send.styles/transaction-fee-input - {:on-change-text #(re-frame/dispatch [:wallet.send/set-gas %]) - :default-value (str (money/to-fixed gas))})]]] - - [react/view send.styles/transaction-fee-column-wrapper - [react/text {:style send.styles/advanced-fees-text} - (i18n/label :t/gas-price)] - [react/view send.styles/transaction-fee-bubble [react/text-input (merge send.styles/transaction-fee-input {:on-change-text #(re-frame/dispatch [:wallet.send/set-gas-price (money/->wei :gwei %)]) :default-value (str (money/to-fixed (money/wei-> :gwei gas-price)))})] - [react/text {:style send.styles/advanced-fees-details-text} - "Gwei"]]]] + [wallet.components/cartouche-secondary-text + (i18n/label :t/gwei)]]]] [react/view send.styles/transaction-fee-info [react/text {:style send.styles/advanced-fees-text} (i18n/label :t/wallet-transaction-fee-details)]] [components/separator] [react/view send.styles/transaction-fee-block-wrapper - [react/view send.styles/transaction-fee-column-wrapper - [react/text {:style send.styles/advanced-fees-text} - (i18n/label :t/amount)] - [react/view send.styles/transaction-fee-bubble-read-only - [react/text {:style send.styles/advanced-fees-text} - (str (money/to-fixed (money/wei->ether amount)))] - [react/text {:style send.styles/advanced-fees-details-text} - (name symbol)]]] - [react/view send.styles/transaction-fee-column-wrapper - [react/text {:style send.styles/advanced-fees-text} - (i18n/label :t/wallet-transaction-total-fee)] - [react/view send.styles/transaction-fee-bubble-read-only - [react/text {:style send.styles/advanced-fees-text} - (str (money/to-fixed (max-fee gas gas-price)))] - [react/text {:style send.styles/advanced-fees-details-text} - "ETH"]]]]]])) + [wallet.components/cartouche {:disabled? true} + (i18n/label :t/amount) + [wallet.components/cartouche-text-content + (str (money/to-fixed (money/wei->ether amount))) + (name symbol)]] + [wallet.components/cartouche {:disabled? true} + (i18n/label :t/wallet-transaction-total-fee) + [wallet.components/cartouche-text-content + (str (money/to-fixed (max-fee gas gas-price))) + (i18n/label :t/eth)]]]]])) -(defn- advanced-options-wrapper [on-press content] - (if on-press - [react/touchable-highlight {:on-press on-press} - [react/view - content]] - [react/view - content])) +(defn- advanced-cartouche [{:keys [gas gas-price]} modal?] + [react/view send.styles/advanced-cartouche + [wallet.components/cartouche {:disabled? modal? :on-press #(re-frame/dispatch [:navigate-to-modal :wallet-transaction-fee])} + (i18n/label :t/wallet-transaction-fee) + [react/view send.styles/advanced-options-text-wrapper + [react/text {:style send.styles/advanced-fees-text} + (str (money/to-fixed (max-fee gas gas-price)) " " (i18n/label :t/eth))] + [react/text {:style send.styles/advanced-fees-details-text} + (str (money/to-fixed gas) " * " (money/to-fixed (money/wei-> :gwei gas-price)) (i18n/label :t/gwei))]]]]) -(defn- advanced-options [{:keys [gas gas-price]} on-press] - [react/touchable-highlight {:on-press on-press} - [react/view - [react/text {:style wallet.components.styles/label} - (i18n/label :t/wallet-transaction-fee)] - [advanced-options-wrapper on-press - [react/view send.styles/advanced-options-wrapper - [react/view send.styles/advanced-options-text-wrapper - [react/text {:style send.styles/advanced-fees-text} - (str (money/to-fixed (max-fee gas gas-price)) " ETH")] - [react/text {:style send.styles/advanced-fees-details-text} - (str (money/to-fixed gas) " * " (money/to-fixed (money/wei-> :gwei gas-price)) "GWEI")]] - (when on-press - [vector-icons/icon :icons/forward {:color :white}])]]]]) +(defn- advanced-options [advanced? transaction modal?] + [react/view {:style send.styles/advanced-wrapper} + [react/touchable-highlight {:on-press #(re-frame/dispatch [:wallet.send/toggle-advanced (not advanced?)])} + [react/view {:style send.styles/advanced-button-wrapper} + [react/view {:style send.styles/advanced-button} + [react/text {:style (merge wallet.components.styles/label send.styles/advanced-label)} + (i18n/label :t/wallet-advanced)] + [vector-icons/icon (if advanced? :icons/up :icons/down) {:color :white}]]]] + (when advanced? + [advanced-cartouche transaction modal?])]) (defn- send-transaction-panel [{:keys [modal? transaction scroll advanced? symbol]}] (let [{:keys [amount amount-error signing? to to-name sufficient-funds? in-progress? from-chat?]} transaction] [react/keyboard-avoiding-view wallet.styles/wallet-modal-container [react/view components.styles/flex [status-bar/status-bar {:type (if modal? :modal-wallet :wallet)}] - (if modal? [toolbar-modal from-chat?] [toolbar-view signing?]) + [toolbar from-chat? (if modal? act/close-white act/back-white) + (i18n/label :t/send-transaction)] [common/network-info {:text-color :white}] [react/scroll-view (merge {:keyboardShouldPersistTaps :always} (when-not modal? {:ref #(reset! scroll %)})) - [react/view components.styles/flex - [react/view wallet.styles/choose-participant-container - [components/choose-recipient (merge {:address to - :name to-name} - (when-not modal? - {:on-press request-camera-permissions}))]] - [react/view wallet.styles/choose-asset-container - (if modal? - [components/view-asset symbol] - [components/choose-asset {:type :send - :symbol symbol}])] - [react/view wallet.styles/amount-container - [components/amount-input - (merge - {:error (or amount-error - (when-not sufficient-funds? (i18n/label :t/wallet-insufficient-funds))) - :input-options {:default-value (str (money/wei->ether amount)) - :on-focus (fn [] (when @scroll (js/setTimeout #(.scrollToEnd @scroll) 100))) - :on-change-text #(re-frame/dispatch [:wallet.send/set-and-validate-amount %])}} - (when modal? - {:disabled? true}))]] - [react/view {:style send.styles/advanced-wrapper} - [react/touchable-highlight {:on-press #(re-frame/dispatch [:wallet.send/toggle-advanced (not advanced?)])} - [react/view {:style send.styles/advanced-button-wrapper} - [react/view {:style send.styles/advanced-button} - [react/text {:style (merge wallet.components.styles/label send.styles/advanced-label)} - (i18n/label :t/wallet-advanced)] - [vector-icons/icon (if advanced? :icons/up :icons/down) {:color :white}]]]] - (when advanced? - [advanced-options transaction (when-not modal? #(re-frame/dispatch [:navigate-to-modal :wallet-transaction-fee]))])]]] - [components/separator] + [react/view send.styles/send-transaction-form + [components/recipient-selector {:disabled? modal? + :address to + :name to-name}] + [components/asset-selector {:disabled? modal? + :type :send + :symbol symbol}] + [components/amount-selector {:disabled? modal? + :error (or amount-error + (when-not sufficient-funds? (i18n/label :t/wallet-insufficient-funds))) + :input-options {:default-value (str (money/to-fixed (money/wei->ether amount))) + :max-length 21 + :on-focus (fn [] (when @scroll (js/setTimeout #(.scrollToEnd @scroll) 100))) + :on-change-text #(re-frame/dispatch [:wallet.send/set-and-validate-amount %])}}] + [advanced-options advanced? transaction modal?]]] (if signing? [signing-buttons #(re-frame/dispatch (if modal? [:wallet/cancel-signing-modal] [:wallet/discard-transaction])) @@ -257,5 +214,6 @@ [react/view wallet.styles/wallet-modal-container [react/view components.styles/flex [status-bar/status-bar {:type :modal-wallet}] - [toolbar-modal false] + [toolbar false act/close-white + (i18n/label :t/send-transaction)] [react/text {:style send.styles/empty-text} (i18n/label :t/unsigned-transaction-expired)]]]))) diff --git a/src/status_im/ui/screens/wallet/settings/views.cljs b/src/status_im/ui/screens/wallet/settings/views.cljs index 31ab4258eb..f42498d59d 100644 --- a/src/status_im/ui/screens/wallet/settings/views.cljs +++ b/src/status_im/ui/screens/wallet/settings/views.cljs @@ -1,13 +1,15 @@ (ns status-im.ui.screens.wallet.settings.views (:require-macros [status-im.utils.views :refer [defview letsubs]]) (:require [re-frame.core :as re-frame] + [status-im.i18n :as i18n] [status-im.ui.components.list.views :as list] [status-im.ui.components.react :as react] + [status-im.ui.components.styles :as components.styles] [status-im.ui.components.toolbar.view :as toolbar] - [status-im.i18n :as i18n] + [status-im.ui.screens.wallet.styles :as wallet.styles] [status-im.utils.ethereum.core :as ethereum] - [status-im.utils.ethereum.tokens :as tokens] - [status-im.ui.components.styles :as components.styles])) + [status-im.utils.ethereum.tokens :as tokens])) + (defn- render-token [{:keys [symbol name icon]} visible-tokens] [list/item @@ -21,10 +23,12 @@ (defview manage-assets [] (letsubs [network [:network] visible-tokens [:wallet.settings/visible-tokens]] - [react/view components.styles/flex - [toolbar/toolbar {} - [toolbar/nav-clear-text (i18n/label :t/done)] - [toolbar/content-title (i18n/label :t/wallet-assets)]] + [react/view (merge components.styles/flex {:background-color :white}) + [toolbar/toolbar #_{} {:style wallet.styles/toolbar} + [toolbar/nav-text {:style {:color :white}} + (i18n/label :t/done)] + [toolbar/content-title {:color :white} + (i18n/label :t/wallet-assets)]] [react/view {:style components.styles/flex} [list/flat-list {:data (tokens/tokens-for (ethereum/network->chain-keyword network)) :render-fn #(render-token % visible-tokens)}]]])) diff --git a/src/status_im/ui/screens/wallet/styles.cljs b/src/status_im/ui/screens/wallet/styles.cljs index 7c5c722853..e57d732ac0 100644 --- a/src/status_im/ui/screens/wallet/styles.cljs +++ b/src/status_im/ui/screens/wallet/styles.cljs @@ -10,7 +10,7 @@ :justify-content :center :ios {:border-radius 20 :margin-top 6} - :android {:border-radius 4 + :android { :margin-top 18} :background-color colors/blue}) @@ -44,9 +44,12 @@ (def wallet-container {:flex 1}) -(defstyle toolbar +(def toolbar + {:background-color colors/blue}) + +(defstyle toolbar-modal {:background-color colors/blue - :android {:elevation 0}}) + :android {:elevation 2}}) (def buttons-container {:flex-direction :row @@ -69,19 +72,43 @@ {:flex 1 :background-color colors/blue}) -(def choose-participant-container - {:margin-top 16 - :margin-horizontal 15}) - (def amount-container {:margin-top 16 :margin-bottom 16 :margin-horizontal 15 :flex-direction :row}) -(def choose-asset-container - {:margin-top 16 - :margin-horizontal 15}) +(def cartouche-container + {:flex 1 + :margin-top 16 + :margin-horizontal 16}) + +(def cartouche-header + {:color colors/white}) + +(defn cartouche-content-wrapper [disabled?] + (merge + {:flex-direction :row + :margin-top 8 + :border-radius styles/border-radius + :padding-left 14 + :padding-right 8} + (if disabled? + {:border-color colors/white-light-transparent + :border-width 1} + {:background-color colors/white-transparent}))) + +(def cartouche-icon-wrapper + {:flex 1 + :flex-direction :row + :justify-content :space-between + :align-items :center}) + +(def cartouche-primary-text + {:color styles/color-white}) + +(def cartouche-secondary-text + {:color styles/color-white-transparent}) (def qr-code-preview {:width 256 diff --git a/src/status_im/ui/screens/wallet/transactions/styles.cljs b/src/status_im/ui/screens/wallet/transactions/styles.cljs index 0962f4cda9..3d85c42578 100644 --- a/src/status_im/ui/screens/wallet/transactions/styles.cljs +++ b/src/status_im/ui/screens/wallet/transactions/styles.cljs @@ -1,13 +1,13 @@ (ns status-im.ui.screens.wallet.transactions.styles (:require-macros [status-im.utils.styles :refer [defnstyle defstyle]]) - (:require [status-im.ui.components.styles :as styles] - [status-im.ui.screens.main-tabs.styles :as tabs.styles] - [status-im.utils.platform :as platform])) + (:require [status-im.ui.components.colors :as colors] + [status-im.ui.components.styles :as styles] + [status-im.ui.screens.main-tabs.styles :as tabs.styles])) (def error-container {:align-self :center :justify-content :center - :border-radius 4 + :border-radius 8 :padding-vertical 4 :flex-direction :row :background-color styles/color-gray9}) @@ -234,4 +234,8 @@ :width 4 :height 4 :border-radius 2 - :background-color styles/color-cyan}) \ No newline at end of file + :background-color styles/color-cyan}) + +(def filter-container + {:flex 1}) + ;:background-color colors/white}) diff --git a/src/status_im/ui/screens/wallet/transactions/views.cljs b/src/status_im/ui/screens/wallet/transactions/views.cljs index 6cddd9d0b0..d599562ed0 100644 --- a/src/status_im/ui/screens/wallet/transactions/views.cljs +++ b/src/status_im/ui/screens/wallet/transactions/views.cljs @@ -1,19 +1,17 @@ (ns status-im.ui.screens.wallet.transactions.views + (:require-macros [status-im.utils.views :refer [defview letsubs]]) (:require [re-frame.core :as re-frame] + [status-im.i18n :as i18n] [status-im.ui.components.button.view :as button] - [status-im.ui.components.checkbox.view :as checkbox] [status-im.ui.components.list.views :as list] [status-im.ui.components.react :as react] [status-im.ui.components.status-bar.view :as status-bar] - [status-im.ui.components.styles :as styles] + [status-im.ui.components.styles :as components.styles] [status-im.ui.components.toolbar.actions :as actions] [status-im.ui.components.toolbar.view :as toolbar] - [status-im.i18n :as i18n] - [status-im.ui.screens.wallet.transactions.styles :as transactions.styles] + [status-im.ui.screens.wallet.transactions.styles :as styles] [status-im.ui.screens.wallet.views :as wallet.views] - [status-im.utils.money :as money] - [status-im.ui.components.styles :as common.styles]) - (:require-macros [status-im.utils.views :refer [defview letsubs]])) + [status-im.utils.money :as money])) (defn on-delete-transaction [{:keys [id]}] @@ -23,7 +21,7 @@ (merge {:icon :icons/filter :handler #(re-frame/dispatch [:navigate-to-modal :wallet-transactions-filter])} - (when filter? {:icon-opts {:overlay-style transactions.styles/corner-dot}}))) + (when filter? {:icon-opts {:overlay-style styles/corner-dot}}))) (defn- all-checked? [filter-data] (and (every? :checked? (:type filter-data)) @@ -40,7 +38,7 @@ (defn action-buttons [{:keys [id] :as transaction}] - [react/view {:style transactions.styles/action-buttons} + [react/view {:style styles/action-buttons} [button/primary-button {:style {:margin-right 12} :on-press #(re-frame/dispatch [:wallet/show-sign-transaction id])} (i18n/label :t/transactions-sign)] @@ -53,17 +51,17 @@ (defn- transaction-icon [k background-color color] {:icon k :icon-opts {:color color} - :style (transactions.styles/transaction-icon-background background-color)}) + :style (styles/transaction-icon-background background-color)}) (defn- transaction-type->icon [k] (case k - :unsigned (transaction-icon :icons/dots-horizontal styles/color-gray4-transparent styles/color-gray7) - :inbound (transaction-icon :icons/arrow-left styles/color-green-3-light styles/color-green-3) - :outbound (transaction-icon :icons/arrow-right styles/color-blue4-transparent styles/color-blue4) - (:postponed :pending) (transaction-icon :icons/arrow-right styles/color-gray4-transparent styles/color-gray7) + :unsigned (transaction-icon :icons/dots-horizontal components.styles/color-gray4-transparent components.styles/color-gray7) + :inbound (transaction-icon :icons/arrow-left components.styles/color-green-3-light components.styles/color-green-3) + :outbound (transaction-icon :icons/arrow-right components.styles/color-blue4-transparent components.styles/color-blue4) + (:postponed :pending) (transaction-icon :icons/arrow-right components.styles/color-gray4-transparent components.styles/color-gray7) (throw (str "Unknown transaction type: " k)))) -(defn render-transaction [{:keys [hash from-contact to-contact to from type value symbol time-formatted] :as transaction}] +(defn render-transaction [{:keys [hash from-contact to-contact to from type value time-formatted] :as transaction}] (let [[label contact address] (if (inbound? type) [(i18n/label :t/from) from-contact from] [(i18n/label :t/to) to-contact to])] @@ -72,20 +70,20 @@ [list/item [list/item-icon (transaction-type->icon (keyword type))] [list/item-content - [react/view {:style transactions.styles/amount-time} - [react/text {:style transactions.styles/tx-amount + [react/view {:style styles/amount-time} + [react/text {:style styles/tx-amount :ellipsize-mode "tail" :number-of-lines 1} (money/wei->str :eth value)] - [react/text {:style transactions.styles/tx-time} + [react/text {:style styles/tx-time} time-formatted]] - [react/view {:style transactions.styles/address-row} - [react/text {:style transactions.styles/address-label} + [react/view {:style styles/address-row} + [react/text {:style styles/address-label} label] (when contact - [react/text {:style transactions.styles/address-contact} + [react/text {:style styles/address-contact} contact]) - [react/text {:style transactions.styles/address-hash + [react/text {:style styles/address-hash :ellipsize-mode "middle" :number-of-lines 1} address]] @@ -93,10 +91,7 @@ [action-buttons transaction])] [list/item-icon {:icon :icons/forward :style {:margin-top 10} - :icon-opts transactions.styles/forward}]]]])) - -;; TODO(yenda) hook with re-frame -(defn- empty-text [s] [react/text {:style transactions.styles/empty-text} s]) + :icon-opts styles/forward}]]]])) (defn filtered-transaction? [transaction filter-data] (:checked? (some #(when (= (:type transaction) (:id %)) %) (:type filter-data)))) @@ -109,21 +104,23 @@ transactions-loading? [:wallet.transactions/transactions-loading?] error-message [:wallet.transactions/error-message?] filter-data [:wallet.transactions/filters]] - [react/view styles/flex + [react/view components.styles/flex (when error-message - [wallet.views/error-message-view transactions.styles/error-container transactions.styles/error-message]) + [wallet.views/error-message-view styles/error-container styles/error-message]) [list/section-list {:sections (map #(update-transactions % filter-data) transactions-history-list) :render-fn render-transaction - :empty-component (empty-text (i18n/label :t/transactions-history-empty)) + :empty-component [react/text {:style styles/empty-text} + (i18n/label :t/transactions-history-empty)] :on-refresh #(re-frame/dispatch [:update-transactions]) :refreshing (boolean transactions-loading?)}]])) (defview unsigned-list [] (letsubs [transactions [:wallet.transactions/unsigned-transactions-list]] - [react/view {:style styles/flex} + [react/view {:style components.styles/flex} [list/flat-list {:data transactions :render-fn render-transaction - :empty-component (empty-text (i18n/label :t/transactions-unsigned-empty))}]])) + :empty-component [react/text {:style styles/empty-text} + (i18n/label :t/transactions-unsigned-empty)]}]])) ;; Filter history @@ -146,29 +143,29 @@ (defview filter-history [] (letsubs [filter-data [:wallet.transactions/filters]] - [react/view styles/flex + [react/view styles/filter-container [toolbar/toolbar {} [toolbar/nav-clear-text (i18n/label :t/done)] [toolbar/content-title (i18n/label :t/transactions-filter-title)] [toolbar/text-action {:handler #(re-frame/dispatch [:wallet.transactions/filter-all]) :disabled? (all-checked? filter-data)} (i18n/label :t/transactions-filter-select-all)]] - [react/view {:style styles/flex} + [react/view {:style (merge {:background-color :white} components.styles/flex)} [list/section-list {:sections (wrap-filter-data filter-data)}]]])) (defn history-tab [active?] [react/text {:uppercase? true - :style (transactions.styles/tab-title active?)} + :style (styles/tab-title active?)} (i18n/label :t/transactions-history)]) (defview unsigned-tab [active?] (letsubs [unsigned-transactions-count [:wallet.transactions/unsigned-transactions-count]] [react/view {:flex-direction :row} - [react/text {:style (transactions.styles/tab-title active?) + [react/text {:style (styles/tab-title active?) :uppercase? true} (i18n/label :t/transactions-unsigned)] (when (pos? unsigned-transactions-count) - [react/text {:style transactions.styles/tab-unsigned-transactions-count} + [react/text {:style styles/tab-unsigned-transactions-count} (str " " unsigned-transactions-count)])])) (def tabs-list @@ -178,21 +175,21 @@ :content unsigned-tab}]) (defn tab [view-id content active?] - [react/touchable-highlight {:style common.styles/flex + [react/touchable-highlight {:style components.styles/flex :disabled active? :on-press #(re-frame/dispatch [:navigation-replace view-id])} - [react/view {:style (transactions.styles/tab active?)} + [react/view {:style (styles/tab active?)} [content active?]]]) (defn tabs [current-view-id] - [react/view {:style transactions.styles/tabs-container} + [react/view {:style styles/tabs-container} (for [{:keys [content view-id]} tabs-list] ^{:key view-id} [tab view-id content (= view-id current-view-id)])]) (defview transactions [] (letsubs [current-tab [:get :view-id] filter-data [:wallet.transactions/filters]] - [react/view {:style styles/flex} + [react/view {:style components.styles/flex} [status-bar/status-bar] [toolbar-view current-tab filter-data] [tabs current-tab] @@ -209,41 +206,41 @@ (defn details-header [{:keys [value date type symbol]}] - [react/view {:style transactions.styles/details-header} - [react/view {:style transactions.styles/details-header-icon} + [react/view {:style styles/details-header} + [react/view {:style styles/details-header-icon} [list/item-icon (transaction-type->icon type)]] - [react/view {:style transactions.styles/details-header-infos} - [react/text {:style transactions.styles/details-header-value} (pretty-print-asset symbol value)] - [react/text {:style transactions.styles/details-header-date} date]]]) + [react/view {:style styles/details-header-infos} + [react/text {:style styles/details-header-value} (pretty-print-asset symbol value)] + [react/text {:style styles/details-header-date} date]]]) (defn progress-bar [progress] - [react/view {:style transactions.styles/progress-bar} - [react/view {:style (transactions.styles/progress-bar-done progress)}] - [react/view {:style (transactions.styles/progress-bar-todo (- 100 progress))}]]) + [react/view {:style styles/progress-bar} + [react/view {:style (styles/progress-bar-done progress)}] + [react/view {:style (styles/progress-bar-todo (- 100 progress))}]]) (defn details-confirmations [confirmations confirmations-progress] - [react/view {:style transactions.styles/details-block} + [react/view {:style styles/details-block} [progress-bar confirmations-progress] - [react/text {:style transactions.styles/details-confirmations-count} + [react/text {:style styles/details-confirmations-count} (str confirmations " " (i18n/label :t/confirmations))] - [react/text {:style transactions.styles/details-confirmations-helper-text} + [react/text {:style styles/details-confirmations-helper-text} (i18n/label :t/confirmations-helper-text)]]) (defn details-list-row ([label value] (details-list-row label value nil)) ([label value extra-value] - [react/view {:style transactions.styles/details-row} - [react/text {:style transactions.styles/details-item-label} (i18n/label label)] - [react/view {:style transactions.styles/details-item-value-wrapper} - [react/text {:style transactions.styles/details-item-value} (str value)] - [react/text {:style transactions.styles/details-item-extra-value} (str extra-value)]]])) + [react/view {:style styles/details-row} + [react/text {:style styles/details-item-label} (i18n/label label)] + [react/view {:style styles/details-item-value-wrapper} + [react/text {:style styles/details-item-value} (str value)] + [react/text {:style styles/details-item-extra-value} (str extra-value)]]])) (defn details-list [{:keys [block hash from from-wallet from-contact to to-wallet to-contact gas-limit gas-price-gwei gas-price-eth gas-used cost nonce data]}] - [react/view {:style transactions.styles/details-block} + [react/view {:style styles/details-block} [details-list-row :t/block block] [details-list-row :t/hash hash] [details-list-row :t/from @@ -260,23 +257,24 @@ [details-list-row :t/data data]]) (defn details-action [hash url] - [(actions/opts [{:text (i18n/label :t/copy-transaction-hash) :value #(react/copy-to-clipboard hash)} - {:text (i18n/label :t/open-on-etherscan) :value #(.openURL react/linking url)}])]) + [(actions/opts [{:label (i18n/label :t/copy-transaction-hash) :action #(react/copy-to-clipboard hash)} + {:label (i18n/label :t/open-on-etherscan) :action #(.openURL react/linking url)}])]) (defview transaction-details [] (letsubs [{:keys [hash url type] :as transaction} [:wallet.transactions/transaction-details] confirmations [:wallet.transactions.details/confirmations] confirmations-progress [:wallet.transactions.details/confirmations-progress]] - [react/view {:style styles/flex} + [react/view {:style components.styles/flex} [status-bar/status-bar] [toolbar/toolbar {} toolbar/default-nav-back [toolbar/content-title (i18n/label :t/transaction-details)] (when transaction [toolbar/actions (details-action hash url)])] (if transaction - [react/scroll-view {:style styles/main-container} + [react/scroll-view {:style components.styles/main-container} [details-header transaction] [details-confirmations confirmations confirmations-progress] - [react/view {:style transactions.styles/details-separator}] + [react/view {:style styles/details-separator}] [details-list transaction]] - [empty-text (i18n/label :t/unsigned-transaction-expired)])])) + [react/text {:style styles/empty-text} + (i18n/label :t/unsigned-transaction-expired)])])) diff --git a/src/status_im/utils/identicon.cljs b/src/status_im/utils/identicon.cljs index f81c7c9409..0222d99e50 100644 --- a/src/status_im/utils/identicon.cljs +++ b/src/status_im/utils/identicon.cljs @@ -6,6 +6,5 @@ (defn identicon ([hash] (identicon hash default-size)) ([hash options] - (str "data:image/png;base64," - (str (new dependencies/identicon-js hash options))))) - + (str "data:image/png;base64," + (str (new dependencies/identicon-js hash options))))) diff --git a/src/status_im/utils/utils.cljs b/src/status_im/utils/utils.cljs index 79819ef045..f129b0c623 100644 --- a/src/status_im/utils/utils.cljs +++ b/src/status_im/utils/utils.cljs @@ -80,3 +80,10 @@ (.catch (or on-error (fn [error] (show-popup "Error" (str error)))))))) + +(defn deep-merge + "Recursively merge maps" + [& maps] + (if (every? map? maps) + (apply merge-with deep-merge maps) + (last maps)))