diff --git a/src/quo/theme.cljs b/src/quo/theme.cljs index 5fba1edaac..212e55a2c5 100644 --- a/src/quo/theme.cljs +++ b/src/quo/theme.cljs @@ -1,7 +1,11 @@ (ns quo.theme - (:require [quo.design-system.colors :as colors])) + (:require [quo.design-system.colors :as colors] + [reagent.core :as reagent])) -(def theme (atom nil)) +(def theme (reagent/atom nil)) + +(defn dark? [] + (= :dark @theme)) (defn get-theme [] @theme) diff --git a/src/quo2/components/button.cljs b/src/quo2/components/button.cljs index f96284ad1d..4371071b65 100644 --- a/src/quo2/components/button.cljs +++ b/src/quo2/components/button.cljs @@ -1,10 +1,10 @@ (ns quo2.components.button (:require [quo.react-native :as rn] - [status-im.ui.components.icons.icons :as icons] [quo2.foundations.colors :as colors] [quo2.components.text :as text] [quo.theme :as theme] - [reagent.core :as reagent])) + [reagent.core :as reagent] + [quo2.components.icon :as quo2.icons])) (def themes {:light {:primary {:icon-color colors/white :label {:style {:color colors/white}} @@ -16,9 +16,9 @@ :background-color {:default colors/primary-50-opa-20 :pressed colors/primary-50-opa-40 :disabled colors/primary-50-opa-20}} - :grey {:icon-color colors/neutral-50 + :grey {:icon-color colors/black :label {:style {:color colors/black}} - :background-color {:default colors/neutral-40 + :background-color {:default colors/neutral-20 :pressed colors/neutral-30 :disabled colors/neutral-20}} :outline {:icon-color colors/neutral-50 @@ -61,7 +61,7 @@ :pressed colors/danger-40 :disabled colors/danger-50}}}}) -(defn style-container [type size disabled background-color border-color icon above] +(defn style-container [type size disabled background-color border-color icon above width before after] (merge {:height size :align-items :center :justify-content :center @@ -74,7 +74,14 @@ 32 10 24 8)) :background-color background-color - :padding-horizontal (if icon 0 (case size 56 16 40 16 32 12 24 8))} + :padding-horizontal (when-not (or icon before after) + (case size 56 16 40 16 32 12 24 8)) + :padding-left (when-not (or icon before) + (case size 56 16 40 16 32 12 24 8)) + :padding-right (when-not (or icon after) + (case size 56 16 40 16 32 12 24 8))} + (when width + {:width width}) (when icon {:width size}) (when border-color @@ -97,14 +104,15 @@ [button {:icon true} :main-icons/close-circle]" [_ _] (let [pressed (reagent/atom false)] - (fn [{:keys [on-press disabled type size before after above + (fn [{:keys [on-press disabled type size before after above width on-long-press accessibility-label icon] :or {type :primary size 40}} children] (let [{:keys [icon-color background-color label border-color]} (get-in themes [(theme/get-theme) type]) - state (cond disabled :disabled @pressed :pressed :else :default)] + state (cond disabled :disabled @pressed :pressed :else :default) + icon-size (when (= 24 size) 12)] [rn/touchable-without-feedback (merge {:disabled disabled :accessibility-label accessibility-label} (when on-press @@ -118,17 +126,33 @@ {:on-press-out (fn [] (reset! pressed nil))}) - [rn/view {:style (style-container type size disabled (get background-color state) (get border-color state) icon above)} + [rn/view {:style (style-container + type + size + disabled + (get background-color state) + (get border-color state) + icon + above + width + before + after)} (when above [rn/view - [icons/icon above {:color icon-color}]]) + [quo2.icons/icon above {:container-style {:margin-bottom 2} + :color icon-color + :size icon-size}]]) (when before [rn/view - [icons/icon before {:color icon-color}]]) + [quo2.icons/icon before {:container-style {:margin-left (if (= size 40) 12 8) + :margin-right 4} + :color icon-color + :size icon-size}]]) [rn/view (cond icon - [icons/icon children {:color icon-color}] + [quo2.icons/icon children {:color icon-color + :size icon-size}] (string? children) [text/text (merge {:size (when (#{56 24} size) :paragraph-2) @@ -141,4 +165,7 @@ children)] (when after [rn/view - [icons/icon after {:color icon-color}]])]])))) \ No newline at end of file + [quo2.icons/icon after {:container-style {:margin-left 4 + :margin-right (if (= size 40) 12 8)} + :color icon-color + :size icon-size}]])]])))) \ No newline at end of file diff --git a/src/quo2/components/icon.cljs b/src/quo2/components/icon.cljs new file mode 100644 index 0000000000..0d160f8d3a --- /dev/null +++ b/src/quo2/components/icon.cljs @@ -0,0 +1,10 @@ +(ns quo2.components.icon + (:require [status-im.ui.components.icons.icons :as icons])) + +(defn icon + ([icon-name] (icon icon-name nil)) + ([icon-name {:keys [size] :as props}] + (let [size (or size 20)] + [icons/icon (str (name icon-name) size) (merge props + {:width size + :height size})]))) \ No newline at end of file diff --git a/src/quo2/components/tabs.cljs b/src/quo2/components/tabs.cljs index 11abed7e82..e9eae85286 100644 --- a/src/quo2/components/tabs.cljs +++ b/src/quo2/components/tabs.cljs @@ -5,7 +5,7 @@ (defn tabs [{:keys [default-active on-change]}] (let [active-tab-id (reagent/atom default-active)] - (fn [{:keys [data size]}] + (fn [{:keys [data size] :or {size 32}}] (let [active-id @active-tab-id] [rn/view {:flex-direction :row} (for [{:keys [label id]} data] diff --git a/src/quo2/foundations/colors.cljs b/src/quo2/foundations/colors.cljs index e18060d7f6..c229ee76e8 100644 --- a/src/quo2/foundations/colors.cljs +++ b/src/quo2/foundations/colors.cljs @@ -1,5 +1,6 @@ (ns quo2.foundations.colors - (:require [clojure.string :as string])) + (:require [clojure.string :as string] + [quo.theme :as theme])) (defn alpha [value opacity] (if (string/starts-with? value "#") @@ -173,4 +174,7 @@ (def info-50-opa-10 (alpha info-50 0.1)) (def info-50-opa-20 (alpha info-50 0.2)) (def info-50-opa-30 (alpha info-50 0.3)) -(def info-50-opa-40 (alpha info-50 0.4)) \ No newline at end of file +(def info-50-opa-40 (alpha info-50 0.4)) + +(defn theme-colors [light dark] + (if (theme/dark?) dark light)) \ No newline at end of file diff --git a/src/quo2/foundations/typography.cljs b/src/quo2/foundations/typography.cljs index 66bc411b0e..c239bc7d15 100644 --- a/src/quo2/foundations/typography.cljs +++ b/src/quo2/foundations/typography.cljs @@ -2,23 +2,24 @@ (def heading-1 {:font-size 27 :line-height 32.4 - :letter-spacing -2.1}) + :letter-spacing -0.5}) (def heading-2 {:font-size 19 :line-height 25.65 - :letter-spacing -1.6}) + :letter-spacing -0.4}) (def paragraph-1 {:font-size 15 :line-height 21.75 - :letter-spacing -0.9}) + :letter-spacing -0.1}) (def paragraph-2 {:font-size 13 :line-height 18.2 - :letter-spacing -0.3}) + :letter-spacing 0}) (def label {:font-size 11 :line-height 15.62 - :letter-spacing -0.055}) + :letter-spacing -0.055 + :text-transform :uppercase}) (def font-regular {:font-family "Inter-Regular"}) ; 400 diff --git a/src/quo2/screens/button.cljs b/src/quo2/screens/button.cljs index f6253a8d56..140d888d1f 100644 --- a/src/quo2/screens/button.cljs +++ b/src/quo2/screens/button.cljs @@ -70,12 +70,12 @@ :theme :before :after) {:on-press #(println "Hello world!")} (when @above - {:above :main-icons/close-circle}) + {:above :main-icons2/placeholder}) (when @before - {:before :main-icons/back}) + {:before :main-icons2/placeholder}) (when @after - {:after :main-icons/next})) - (if @icon :main-icons/close-circle @label)]]]))) + {:after :main-icons2/placeholder})) + (if @icon :main-icons2/placeholder @label)]]]))) (defn preview-button [] [rn/view {:background-color (:ui-background @colors/theme) diff --git a/src/quo2/screens/segmented.cljs b/src/quo2/screens/segmented.cljs index 3c8b95aa59..cd541ea146 100644 --- a/src/quo2/screens/segmented.cljs +++ b/src/quo2/screens/segmented.cljs @@ -8,12 +8,8 @@ (def descriptor [{:label "Size:" :key :size :type :select - :options [{:key 32 - :value "32"} - {:key 28 + :options [{:key 28 :value "28"} - {:key 24 - :value "24"} {:key 20 :value "20"}]}]) diff --git a/src/quo2/screens/tabs.cljs b/src/quo2/screens/tabs.cljs index 723c0c1fcf..7bdbe3fb14 100644 --- a/src/quo2/screens/tabs.cljs +++ b/src/quo2/screens/tabs.cljs @@ -10,12 +10,8 @@ :type :select :options [{:key 32 :value "32"} - {:key 28 - :value "28"} {:key 24 - :value "24"} - {:key 20 - :value "20"}]}]) + :value "24"}]}]) (defn cool-preview [] (let [state (reagent/atom {:size 32})] diff --git a/src/quo2/screens/text.cljs b/src/quo2/screens/text.cljs index 4bc327310b..268648cf07 100644 --- a/src/quo2/screens/text.cljs +++ b/src/quo2/screens/text.cljs @@ -27,8 +27,6 @@ :value "Medium"} {:key :semi-bold :value "Semi-bold"} - {:key :bold - :value "Bold"} {:key :monospace :value "Monospace"}]}]) diff --git a/src/status_im/ui/screens/screens.cljs b/src/status_im/ui/screens/screens.cljs index 7f9f700e1b..e937c29342 100644 --- a/src/status_im/ui/screens/screens.cljs +++ b/src/status_im/ui/screens/screens.cljs @@ -121,7 +121,8 @@ [status-im.ui.screens.wallet.recipient.views :as recipient] [status-im.ui.screens.wallet.send.views :as wallet.send] [quo2.screens.main :as quo2.preview] - [status-im.utils.config :as config])) + [status-im.utils.config :as config] + [quo2.foundations.colors :as quo2.colors])) (def components [{:name :chat-toolbar @@ -357,6 +358,7 @@ {:name :wallet :insets {:top false} :on-focus [:wallet/tab-opened] + :options {:statusBar {:backgroundColor quo2.colors/neutral-5}} :component wallet.accounts/accounts-overview} {:name :wallet-account ;;TODO dynamic title diff --git a/src/status_im/ui/screens/wallet/account/views.cljs b/src/status_im/ui/screens/wallet/account/views.cljs index bda115efe9..f968bcf4d1 100644 --- a/src/status_im/ui/screens/wallet/account/views.cljs +++ b/src/status_im/ui/screens/wallet/account/views.cljs @@ -13,14 +13,20 @@ [status-im.utils.config :as config] [status-im.ui.screens.wallet.account.styles :as styles] [status-im.ui.screens.wallet.accounts.sheets :as sheets] - [status-im.ui.screens.wallet.accounts.views :as accounts] + [status-im.ui.screens.wallet.accounts.common :as common] [status-im.ui.screens.wallet.transactions.views :as history] [status-im.ui.components.tabs :as tabs] [status-im.ui.screens.wallet.collectibles.views :as collectibles.views] - [status-im.ui.screens.wallet.buy-crypto.views :as buy-crypto]) + [status-im.ui.screens.wallet.buy-crypto.views :as buy-crypto] + [quo2.foundations.colors :as quo2.colors] + [status-im.utils.handlers :refer [ + (= tab :tokens) + [react/scroll-view (for [item tokens] ^{:key (:name item)} - [accounts/render-asset item nil nil (:code currency)])] + [common/render-asset-new item nil nil (:code currency)])] (= tab :nft) [:<> [opensea-link address] @@ -134,7 +141,7 @@ [react/view {:align-items :center :margin-top 32} [react/text {:style {:color colors/gray}} (i18n/label :t/no-collectibles)]]))] - (= tab :history) + (= tab :activity) [transactions address])]))) (views/defview bottom-send-recv-buttons [{:keys [address type] :as account} anim-y] @@ -201,6 +208,76 @@ :title (i18n/label :t/swap) :on-press #(re-frame/dispatch [:open-modal :token-swap])}]]) +(views/defview assets-and-collections [address] + (views/letsubs [{:keys [tokens]} [:wallet/visible-assets-with-values address] + currency [:wallet/currency] + opensea-enabled? [:opensea-enabled?] + collectible-collection [:wallet/collectible-collection address] + ethereum-network? [:ethereum-network?]] + (let [{:keys [tab]} @state] + [react/view {:flex 1} + [react/view {:flex-direction :row :margin-bottom 8 :padding-horizontal 4} + [tabs/tab-title state :assets (i18n/label :t/wallet-assets) (= tab :assets)] + (when ethereum-network? + [tabs/tab-title state :nft (i18n/label :t/wallet-collectibles) (= tab :nft)]) + [tabs/tab-title state :history (i18n/label :t/history) (= tab :history)]] + [quo/separator {:style {:margin-top -8}}] + (cond + (= tab :assets) + [:<> + (for [item tokens] + ^{:key (:name item)} + [common/render-asset item nil nil (:code currency)])] + (= tab :nft) + [:<> + [opensea-link address] + ;; Hide collectibles behind a feature flag + (when config/collectibles-enabled? + (cond + (not opensea-enabled?) + [collectibles.views/enable-opensea-view] + + (and opensea-enabled? (seq collectible-collection)) + [collectibles.views/nft-collections address] + + :else + [react/view {:align-items :center :margin-top 32} + [react/text {:style {:color colors/gray}} + (i18n/label :t/no-collectibles)]]))] + (= tab :history) + [transactions address])]))) + +(defn account-new [selected-account] + (let [;{:keys [name address] :as account} ( (for [item tokens] ^{:key (:name item)} - [render-asset item nil nil (:code currency)])])) + [common/render-asset item nil nil (:code currency)])])) (views/defview send-button [] (views/letsubs [account [:multiaccount/default-account]] @@ -108,7 +93,8 @@ ^{:key i} [dot {:selected (= selected i)}])]) -(views/defview accounts [] +;;ACCOUNTS OLD +(views/defview accounts-old [] (views/letsubs [accounts [:multiaccount/visible-accounts] keycard? [:keycard-multiaccount?] window-width [:dimensions/window-width] @@ -133,17 +119,18 @@ [account-card account keycard? card-width])) [add-card card-width]]] (let [columns (Math/ceil (/ (inc (count accounts)) 2)) - totalwidth (* (styles/page-width card-width) columns) + totalwidth (* (styles/page-width card-width) columns) n (Math/ceil (/ totalwidth window-width))] (when (> n 1) [dots-selector {:selected @index :n n}]))]))) -(views/defview total-value [{:keys [animation minimized]}] - (views/letsubs [currency [:wallet/currency] - portfolio-value [:portfolio-value] - empty-balances? [:empty-balances?] - frozen-card? [:keycard/frozen-card?] +;;TOTAL VALUE OLD +(views/defview total-value-old [{:keys [animation minimized]}] + (views/letsubs [currency [:wallet/currency] + portfolio-value [:portfolio-value] + empty-balances? [:empty-balances?] + frozen-card? [:keycard/frozen-card?] {:keys [mnemonic]} [:multiaccount]] [reanimated/view {:style (styles/container {:minimized minimized})} (when (or @@ -174,8 +161,8 @@ (i18n/label :t/your-card-is-frozen) (i18n/label :t/back-up-your-seed-phrase))]]]]) - [reanimated/view {:style (styles/value-container {:minimized minimized - :animation animation}) + [reanimated/view {:style (styles/value-container {:minimized minimized + :animation animation}) :pointer-events :none} [reanimated/view {:style {:justify-content :center}} [quo/text {:animated? true @@ -192,39 +179,130 @@ [quo/text {:color :secondary} (i18n/label :t/wallet-total-value)]])])) -;; Note(rasom): sometimes `refreshing` might get stuck on iOS if action happened -;; too fast. By updating this atom in 1s we ensure that `refreshing?` property -;; is updated properly in this case. -(def updates-counter (reagent/atom 0)) +(views/defview total-value [] + (views/letsubs [currency [:wallet/currency] + portfolio-value [:portfolio-value]] + ;empty-balances? [:empty-balances?] + ;frozen-card? [:keycard/frozen-card?] + ;{:keys [mnemonic]} [:multiaccount]] + [react/view {:padding-vertical 12} + [quo2.text/text (i18n/label :t/wallet-total-value)] + [quo2.text/text {:size :heading-1 :weight :semi-bold} + (str portfolio-value " " (:code currency))] + [react/scroll-view {:horizontal true}]] + #_[reanimated/view {:style (styles/container {:minimized minimized})} + (when (or + (and frozen-card? minimized) + (and mnemonic minimized (not empty-balances?))) + [reanimated/view {:style (styles/accounts-mnemonic {:animation animation})} + [react/touchable-highlight + {:on-press #(re-frame/dispatch + (if frozen-card? + [::keycard.login/reset-pin] + [:navigate-to :backup-seed]))} + [react/view {:flex-direction :row + :align-items :center} + [react/view {:width 14 + :height 14 + :background-color colors/gray + :border-radius 7 + :align-items :center + :justify-content :center + :margin-right 9} + [react/text {:style {:color colors/white + :font-size 13 + :font-weight "700"}} + "!"]] + [react/text {:style {:color colors/gray} + :accessibility-label :back-up-your-seed-phrase-warning} + (if frozen-card? + (i18n/label :t/your-card-is-frozen) + (i18n/label :t/back-up-your-seed-phrase))]]]]) -(defn schedule-counter-reset [] - (utils.utils/set-timeout - (fn [] - (swap! updates-counter inc) - (when @(re-frame/subscribe [:wallet/refreshing-history?]) - (schedule-counter-reset))) - 1000)) + [reanimated/view {:style (styles/value-container {:minimized minimized + :animation animation}) + :pointer-events :none} + [reanimated/view {:style {:justify-content :center}} + [quo/text {:animated? true + :weight :semi-bold + :style (styles/value-text {:minimized minimized})} + portfolio-value + [quo/text {:animated? true + :size :inherit + :weight :inherit + :color :secondary} + (str " " (:code currency))]]]] + (when-not minimized + [reanimated/view + [quo/text {:color :secondary} + (i18n/label :t/wallet-total-value)]])])) -(defn refresh-action [] - (schedule-counter-reset) - (re-frame/dispatch [:wallet.ui/pull-to-refresh-history])) - -(defn refresh-control [refreshing?] - (reagent/as-element - [rn/refresh-control - {:refreshing (boolean refreshing?) - :onRefresh refresh-action}])) +(views/defview accounts [selected-account-atom] + (views/letsubs [accounts [:multiaccount/visible-accounts]] + ;keycard? [:keycard-multiaccount?]] + (do + (reset! selected-account-atom (:address (first accounts))) + (let [accounts-data (for [account accounts] + {:label (:name account) + :id (:address account)})] + [react/scroll-view {:horizontal true + :shows-horizontal-scroll-indicator false + :scroll-event-throttle 64 + :margin-top 12 + :margin-bottom 20} + [react/view {:flex-direction :row} + [quo2.tabs/tabs {:default-active (:address (first accounts)) + :on-change #(reset! selected-account-atom %) + :data accounts-data}] + [quo2.button/button {:type :grey + :size 32 + :on-press #(re-frame/dispatch [:bottom-sheet/show-sheet + {:content sheets/add-account + :content-height 260}])} + "Add account"]]])))) (defn accounts-overview [] + (let [mnemonic @(re-frame/subscribe [:mnemonic]) + ;mainnet? @(re-frame/subscribe [:mainnet?]) + selected-account-atom (reagent/atom nil)] + (fn [] + [safe-area/consumer + (fn [insets] + [react/view {:style {:flex 1 + :padding-top (:top insets) + :background-color (quo2.colors/theme-colors quo2.colors/neutral-5 quo2.colors/neutral-95)}} + [react/view {:padding-horizontal 20} + [react/view {:flex-direction :row :height 56 :align-items :center :justify-content :flex-end} + [quo2.button/button {:icon true + :size 32 + :type :grey + :accessibility-label :accounts-qr-code + :on-press #(re-frame/dispatch + [::qr-scanner/scan-code + {:handler :wallet.send/qr-scanner-result}])} + :main-icons2/placeholder] + [react/view {:width 12}] + [quo2.button/button {:icon true + :size 32 + :type :grey + :on-press #(re-frame/dispatch [:bottom-sheet/show-sheet + {:content (sheets/accounts-options mnemonic)}]) + :accessibility-label :accounts-more-options} + :main-icons2/placeholder]] + [total-value] + [accounts selected-account-atom]] + [account.views/account-new @selected-account-atom]])]))) + +(defn accounts-overview-old [] (let [mnemonic @(re-frame/subscribe [:mnemonic]) mainnet? @(re-frame/subscribe [:mainnet?])] [react/view {:style {:flex 1}} [quo/animated-header - {:extended-header total-value - :refresh-control refresh-control + {:extended-header total-value-old + :refresh-control common/refresh-control :refreshing-sub (re-frame/subscribe [:wallet/refreshing-history?]) - :refreshing-counter updates-counter + :refreshing-counter common/updates-counter :use-insets true :right-accessories [{:on-press #(re-frame/dispatch [::qr-scanner/scan-code @@ -235,9 +313,9 @@ {:content (sheets/accounts-options mnemonic)}]) :icon :main-icons/more :accessibility-label :accounts-more-options}]} - [accounts] + [accounts-old] (when mainnet? [buy-crypto/banner]) [assets] [react/view {:height 68}]] - [send-button]])) + [send-button]])) \ 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 687f26c6ba..2cb189b048 100644 --- a/src/status_im/ui/screens/wallet/components/views.cljs +++ b/src/status_im/ui/screens/wallet/components/views.cljs @@ -8,10 +8,10 @@ (defn separator-dark [] [react/view (styles/separator-dark)]) -(defn token-icon [{:keys [style source image-style]}] +(defn token-icon [{:keys [style source image-style width height]}] [react/view {:style style} [react/image {:source (if (fn? source) (source) source) :style (merge - {:width 40 - :height 40} + {:width (or width 40) + :height (or height 40)} image-style)}]]) \ No newline at end of file diff --git a/src/status_im/ui/screens/wallet/send/sheets.cljs b/src/status_im/ui/screens/wallet/send/sheets.cljs index 5bea5f960b..f513b9790f 100644 --- a/src/status_im/ui/screens/wallet/send/sheets.cljs +++ b/src/status_im/ui/screens/wallet/send/sheets.cljs @@ -6,7 +6,7 @@ [quo.core :as quo] [status-im.ui.components.chat-icon.screen :as chat-icon] [status-im.ui.components.list.views :as list] - [status-im.ui.screens.wallet.accounts.views :as wallet.accounts])) + [status-im.ui.screens.wallet.accounts.common :as common])) (views/defview assets [address] (views/letsubs [{:keys [tokens]} [:wallet/visible-assets-with-values address] @@ -15,7 +15,7 @@ (for [token tokens] ^{:key (str (:symbol token))} [react/touchable-highlight {:on-press #(re-frame/dispatch [:wallet.send/set-symbol (:symbol token)])} - [wallet.accounts/render-asset token nil nil (:code currency)]])])) + [common/render-asset token nil nil (:code currency)]])])) (defn render-account [account _ _ {:keys [field event]}] [quo/list-item