From 4b105c2cdf2396eed3873e90517dc9ee9aeff0e8 Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 19 Jan 2024 15:29:46 +0100 Subject: [PATCH 1/7] pure rn experiment 2 --- src/legacy/status_im/bottom_sheet/sheets.cljs | 2 +- .../account_avatar/component_spec.cljs | 4 +- .../avatars/account_avatar/style.cljs | 5 +- .../avatars/account_avatar/view.cljs | 17 +- .../components/avatars/group_avatar/view.cljs | 50 ++-- .../components/avatars/user_avatar/view.cljs | 3 +- .../avatars/wallet_user_avatar/view.cljs | 17 +- .../browser/browser_input/style.cljs | 6 +- src/quo/components/buttons/button/view.cljs | 200 +++++++------ .../buttons/dynamic_button/view.cljs | 83 +++--- .../buttons/logout_button/view.cljs | 49 ++-- .../buttons/slide_button/component_spec.cljs | 4 +- .../dividers/strength_divider/view.cljs | 12 +- .../drawer_buttons/component_spec.cljs | 66 ++--- .../dropdowns/dropdown/properties.cljs | 2 +- .../components/dropdowns/dropdown/view.cljs | 46 +-- .../dropdowns/network_dropdown/style.cljs | 6 +- .../dropdowns/network_dropdown/view.cljs | 38 +-- src/quo/components/icon.cljs | 38 +-- src/quo/components/icons/svg.cljs | 151 +++++----- .../inputs/address_input/style.cljs | 3 +- src/quo/components/inputs/input/style.cljs | 2 +- .../inputs/recovery_phrase/style.cljs | 2 +- .../components/inputs/search_input/style.cljs | 3 +- .../components/inputs/title_input/view.cljs | 133 ++++----- .../components/list_items/address/view.cljs | 80 +++--- .../list_items/saved_address/view.cljs | 109 ++++---- src/quo/components/markdown/text.cljs | 32 +-- .../floating_shell_button/view.cljs | 40 +-- .../components/navigation/page_nav/view.cljs | 262 ++++++++++-------- .../notifications/count_down_circle.cljs | 10 +- .../components/notifications/toast/view.cljs | 6 +- src/quo/components/overlay/view.cljs | 15 +- .../settings/category/settings/view.cljs | 35 +-- .../components/settings/category/style.cljs | 6 +- .../components/settings/category/view.cljs | 8 +- .../settings/settings_item/view.cljs | 116 ++++---- .../components/share/share_qr_code/view.cljs | 21 +- src/quo/components/tabs/tab/view.cljs | 12 +- .../components/wallet/address_text/view.cljs | 39 +-- .../components/wallet/network_link/view.cljs | 73 ++--- .../wallet/wallet_activity/view.cljs | 16 +- .../wallet/wallet_overview/view.cljs | 2 +- src/quo/foundations/customization_colors.cljs | 6 +- src/quo/theme.cljs | 7 +- src/react_native/blur.cljs | 2 + src/react_native/fast_image.cljs | 64 ++--- src/react_native/pure.cljs | 55 ++++ src/react_native/reanimated.cljs | 2 + src/react_native/svg.cljs | 24 +- src/status_im/common/scan_qr_code/view.cljs | 2 +- .../contexts/communities/home/view.cljs | 11 +- .../contexts/onboarding/intro/view.cljs | 28 +- .../preview/quo/drawers/drawer_buttons.cljs | 12 +- .../quo/notifications/activity_logs.cljs | 2 +- .../profile/settings/header/header_shape.cljs | 32 ++- .../profile/settings/header/view.cljs | 63 +++-- .../contexts/profile/settings/list_items.cljs | 5 +- .../contexts/profile/settings/view.cljs | 82 +++--- .../jump_to/components/bottom_tabs/view.cljs | 2 +- .../components/jump_to_screen/view.cljs | 2 +- src/status_im/navigation/view.cljs | 4 +- src/status_im/setup/dev.cljs | 211 ++++++++++++++ src/test_helpers/component.cljs | 6 +- src/utils/re_frame.cljs | 10 + 65 files changed, 1400 insertions(+), 1056 deletions(-) create mode 100644 src/react_native/pure.cljs diff --git a/src/legacy/status_im/bottom_sheet/sheets.cljs b/src/legacy/status_im/bottom_sheet/sheets.cljs index 1f531fb5258..ca96c3154aa 100644 --- a/src/legacy/status_im/bottom_sheet/sheets.cljs +++ b/src/legacy/status_im/bottom_sheet/sheets.cljs @@ -32,7 +32,7 @@ (rn/hw-back-add-listener dismiss-bottom-sheet-callback) (fn [] (rn/hw-back-remove-listener dismiss-bottom-sheet-callback)))) - [theme/provider {:theme (or page-theme (theme/get-theme))} + [theme/provider (or page-theme (theme/get-theme)) [bottom-sheet/bottom-sheet opts (when content [content (when options options)])]])])) diff --git a/src/quo/components/avatars/account_avatar/component_spec.cljs b/src/quo/components/avatars/account_avatar/component_spec.cljs index 0be906c59ad..f63de93c59e 100644 --- a/src/quo/components/avatars/account_avatar/component_spec.cljs +++ b/src/quo/components/avatars/account_avatar/component_spec.cljs @@ -29,7 +29,7 @@ {:height (:size opts) :width (:size opts) :borderRadius (style/get-border-radius (:size opts)) - :backgroundColor (colors/resolve-color (:customization-color opts) :dark)}) + :backgroundColor (colors/resolve-color (:customization-color opts) :light)}) (h/is-truthy (h/query-by-label-text :account-emoji)) (h/has-style (h/query-by-label-text :account-emoji) {:fontSize (style/get-emoji-size (:size opts))}) @@ -65,7 +65,7 @@ {:height (:size opts) :width (:size opts) :borderRadius (style/get-border-radius (:size opts)) - :backgroundColor (colors/resolve-color (:customization-color opts) :dark)}) + :backgroundColor (colors/resolve-color (:customization-color opts) :light)}) (h/is-truthy (h/query-by-label-text :account-emoji)) (h/has-style (h/query-by-label-text :account-emoji) {:fontSize (style/get-emoji-size (:size opts))}) diff --git a/src/quo/components/avatars/account_avatar/style.cljs b/src/quo/components/avatars/account_avatar/style.cljs index 97fbc34aaf5..25d87527cb7 100644 --- a/src/quo/components/avatars/account_avatar/style.cljs +++ b/src/quo/components/avatars/account_avatar/style.cljs @@ -56,9 +56,10 @@ (defn root-container - [{:keys [type size theme customization-color] + [{:keys [type size customization-color] :or {size default-size - customization-color :blue}}] + customization-color :blue}} + theme] (let [watch-only? (= type :watch-only) width (cond-> size (keyword? size) (container-size size))] diff --git a/src/quo/components/avatars/account_avatar/view.cljs b/src/quo/components/avatars/account_avatar/view.cljs index 570ea5fe9ab..a6082a6ecb8 100644 --- a/src/quo/components/avatars/account_avatar/view.cljs +++ b/src/quo/components/avatars/account_avatar/view.cljs @@ -3,9 +3,9 @@ [clojure.string :as string] [quo.components.avatars.account-avatar.style :as style] [quo.theme :as quo.theme] - [react-native.core :as rn])) + [react-native.pure :as rn.pure])) -(defn- view-internal +(defn- view-pure "Opts: :type - keyword -> :default/:watch-only @@ -21,15 +21,16 @@ :or {size style/default-size emoji "🍑"} :as opts}] - (let [emoji-size (style/get-emoji-size size)] - [rn/view + (let [theme (quo.theme/use-theme) + emoji-size (style/get-emoji-size size)] + (rn.pure/view {:accessible true :accessibility-label :account-avatar - :style (style/root-container opts)} - [rn/text + :style (style/root-container opts theme)} + (rn.pure/text {:accessibility-label :account-emoji :adjusts-font-size-to-fit true :style {:font-size emoji-size}} - (when emoji (string/trim emoji))]])) + (when emoji (string/trim emoji)))))) -(def view (quo.theme/with-theme view-internal)) +(defn view [params] (rn.pure/func view-pure params)) diff --git a/src/quo/components/avatars/group_avatar/view.cljs b/src/quo/components/avatars/group_avatar/view.cljs index d248881e7fb..faf4a6191a6 100644 --- a/src/quo/components/avatars/group_avatar/view.cljs +++ b/src/quo/components/avatars/group_avatar/view.cljs @@ -4,8 +4,8 @@ [quo.components.icon :as icon] [quo.foundations.colors :as colors] [quo.theme :as quo.theme] - [react-native.core :as rn] - [react-native.fast-image :as fast-image])) + [react-native.fast-image :as fast-image] + [react-native.pure :as rn.pure])) (def sizes {:size-20 {:icon 12 @@ -19,27 +19,27 @@ :size-80 {:icon 32 :container 80}}) -(defn- view-internal - [_] - (fn [{:keys [size theme customization-color picture icon-name] - :or {size :size-20 - customization-color :blue - picture nil - icon-name :i/group}}] - (let [container-size (get-in sizes [size :container]) - icon-size (get-in sizes [size :icon])] - [rn/view - {:accessibility-label :group-avatar - :style (style/container {:container-size container-size - :customization-color customization-color - :theme theme})} - (if picture - [fast-image/fast-image - {:source picture - :style {:width container-size - :height container-size}}] - [icon/icon icon-name - {:size icon-size - :color colors/white-opa-70}])]))) +(defn- view-pure + [{:keys [size customization-color picture icon-name] + :or {size :size-20 + customization-color :blue + picture nil + icon-name :i/group}}] + (let [theme (quo.theme/use-theme) + container-size (get-in sizes [size :container]) + icon-size (get-in sizes [size :icon])] + (rn.pure/view + {:accessibility-label :group-avatar + :style (style/container {:container-size container-size + :customization-color customization-color + :theme theme})} + (if picture + (fast-image/fast-image + {:source picture + :style {:width container-size + :height container-size}}) + (icon/icon icon-name + {:size icon-size + :color colors/white-opa-70}))))) -(def view (quo.theme/with-theme view-internal)) +(defn view [props] (rn.pure/func view-pure props)) diff --git a/src/quo/components/avatars/user_avatar/view.cljs b/src/quo/components/avatars/user_avatar/view.cljs index 621ef9845e0..0dad31c14f0 100644 --- a/src/quo/components/avatars/user_avatar/view.cljs +++ b/src/quo/components/avatars/user_avatar/view.cljs @@ -86,7 +86,8 @@ {:length amount-initials :full-name full-name :font-size (:font-size (text/text-style {:size - font-size})) + font-size} + nil)) :indicator-size (when status-indicator? (:status-indicator sizes)) :indicator-border (when status-indicator? diff --git a/src/quo/components/avatars/wallet_user_avatar/view.cljs b/src/quo/components/avatars/wallet_user_avatar/view.cljs index 2c39204344f..794bb2f41aa 100644 --- a/src/quo/components/avatars/wallet_user_avatar/view.cljs +++ b/src/quo/components/avatars/wallet_user_avatar/view.cljs @@ -3,7 +3,7 @@ [quo.components.avatars.wallet-user-avatar.style :as style] [quo.components.markdown.text :as text] [quo.theme :as quo.theme] - [react-native.core :as rn] + [react-native.pure :as rn.pure] utils.string)) (def properties @@ -34,7 +34,7 @@ (= size second-smallest-possible))) (def biggest-possible (last (keys properties))) -(defn- view-internal +(defn- view-pure "Options: :full-name - string (default: nil) - used to generate initials @@ -44,18 +44,19 @@ :monospace? - boolean (default: false) - use monospace font :lowercase? - boolean (default: false) - lowercase text :neutral? - boolean (default: false) - use neutral colors variant" - [{:keys [full-name customization-color size theme monospace? lowercase? neutral?] + [{:keys [full-name customization-color size monospace? lowercase? neutral?] :or {size biggest-possible}}] - (let [circle-size (:size (size properties)) + (let [theme (quo.theme/use-theme) + circle-size (:size (size properties)) small? (check-if-size-small size) initials (utils.string/get-initials full-name (if small? 1 2))] - [rn/view + (rn.pure/view {:style (style/container circle-size customization-color neutral? theme)} - [text/text + (text/text {:accessibility-label :wallet-user-avatar :size (:font-size (size properties)) :weight (if monospace? :monospace (:font-weight (size properties))) :style (style/text customization-color neutral? theme)} - (if (and initials lowercase?) (string/lower-case initials) initials)]])) + (if (and initials lowercase?) (string/lower-case initials) initials))))) -(def wallet-user-avatar (quo.theme/with-theme view-internal)) +(defn wallet-user-avatar [params] (rn.pure/func view-pure params)) diff --git a/src/quo/components/browser/browser_input/style.cljs b/src/quo/components/browser/browser_input/style.cljs index 021324c5b1d..14396e3d6c2 100644 --- a/src/quo/components/browser/browser_input/style.cljs +++ b/src/quo/components/browser/browser_input/style.cljs @@ -17,7 +17,8 @@ (defn input [disabled?] (assoc (text/text-style {:size :paragraph-1 - :weight :regular}) + :weight :regular} + nil) :flex 1 :min-height 36 :min-width 120 @@ -47,7 +48,8 @@ (defn text [] (assoc (text/text-style {:size :paragraph-1 - :weight :medium}) + :weight :medium} + nil) :color (colors/theme-colors colors/neutral-100 colors/white))) diff --git a/src/quo/components/buttons/button/view.cljs b/src/quo/components/buttons/button/view.cljs index 37df55236aa..43416224855 100644 --- a/src/quo/components/buttons/button/view.cljs +++ b/src/quo/components/buttons/button/view.cljs @@ -7,10 +7,9 @@ [quo.foundations.customization-colors :as customization-colors] [quo.theme :as theme] [react-native.blur :as blur] - [react-native.core :as rn] - [reagent.core :as reagent])) + [react-native.pure :as rn.pure])) -(defn- button-internal +(defn- button-pure "with label [button opts \"label\"] opts @@ -29,104 +28,103 @@ :theme :light/:dark only icon [button {:icon-only? true} :i/close-circle]" - [_ _] - (let [pressed-state? (reagent/atom false)] - (fn - [{:keys [on-press on-long-press disabled? type background size icon-left icon-right icon-top - customization-color theme accessibility-label icon-only? container-style inner-style - pressed? on-press-in on-press-out] - :or {type :primary - size 40 - customization-color (cond (= type :primary) :blue - (= type :positive) :success - (= type :danger) :danger - :else nil)}} - children] - (let [{:keys [icon-color background-color label-color border-color blur-type - blur-overlay-color border-radius]} - (button-properties/get-values {:customization-color customization-color - :background background - :type type - :theme theme - :pressed? (if pressed? pressed? @pressed-state?) - :icon-only? icon-only?}) - icon-size (when (= 24 size) 12)] - [rn/touchable-without-feedback - {:disabled disabled? - :accessibility-label accessibility-label - :on-press-in (fn [] - (reset! pressed-state? true) - (when on-press-in (on-press-in))) - :on-press-out (fn [] - (reset! pressed-state? nil) - (when on-press-out (on-press-out))) - :on-press on-press - :on-long-press on-long-press} - [rn/view - {:style (merge - (style/shape-style-container size border-radius) - container-style)} - [rn/view - {:style (merge - (style/style-container {:size size - :disabled? disabled? - :border-radius border-radius - :background-color background-color - :border-color border-color - :icon-only? icon-only? - :icon-top icon-top - :icon-left icon-left - :icon-right icon-right}) - inner-style)} - (when customization-color - [customization-colors/overlay - {:customization-color customization-color - :theme theme - :pressed? (if pressed? pressed? @pressed-state?)}]) - (when (= background :photo) - [blur/view - {:blur-radius 20 - :blur-type blur-type - :overlay-color blur-overlay-color - :style style/blur-view}]) - (when icon-top - [rn/view - [quo.icons/icon icon-top - {:container-style {:margin-bottom 2} - :color icon-color - :size icon-size}]]) - (when icon-left - [rn/view - {:style (style/icon-left-icon-style - {:size size - :icon-size icon-size})} - [quo.icons/icon icon-left - {:color icon-color - :size icon-size}]]) - [rn/view - (cond - icon-only? - [quo.icons/icon children - {:color label-color - :size icon-size}] + [{:keys [on-press on-long-press disabled? type background size icon-left icon-right icon-top + customization-color accessibility-label icon-only? container-style inner-style + pressed? on-press-in on-press-out] + :or {type :primary + size 40 + customization-color (cond (= type :primary) :blue + (= type :positive) :success + (= type :danger) :danger + :else nil)}} + children] + (let [[pressed-state? set-pressed-state] (rn.pure/use-state false) + theme (theme/use-theme) + {:keys [icon-color background-color label-color border-color blur-type + blur-overlay-color border-radius]} + (button-properties/get-values {:customization-color customization-color + :background background + :type type + :theme theme + :pressed? (if pressed? pressed? pressed-state?) + :icon-only? icon-only?}) + icon-size (when (= 24 size) 12)] + (rn.pure/touchable-without-feedback + {:disabled disabled? + :accessibility-label accessibility-label + :on-press-in (fn [] + (set-pressed-state true) + (when on-press-in (on-press-in))) + :on-press-out (fn [] + (set-pressed-state nil) + (when on-press-out (on-press-out))) + :on-press on-press + :on-long-press on-long-press} + (rn.pure/view + {:style (merge + (style/shape-style-container size border-radius) + container-style)} + (rn.pure/view + {:style (merge + (style/style-container {:size size + :disabled? disabled? + :border-radius border-radius + :background-color background-color + :border-color border-color + :icon-only? icon-only? + :icon-top icon-top + :icon-left icon-left + :icon-right icon-right}) + inner-style)} + (when customization-color + (customization-colors/overlay + {:customization-color customization-color + :theme theme + :pressed? (if pressed? pressed? pressed-state?)})) + (when (= background :photo) + (blur/view-pure + {:blur-radius 20 + :blur-type blur-type + :overlay-color blur-overlay-color + :style style/blur-view})) + (when icon-top + (rn.pure/view + (quo.icons/icon icon-top + {:container-style {:margin-bottom 2} + :color icon-color + :size icon-size}))) + (when icon-left + (rn.pure/view + {:style (style/icon-left-icon-style + {:size size + :icon-size icon-size})} + (quo.icons/icon icon-left + {:color icon-color + :size icon-size}))) + (rn.pure/view + (cond + icon-only? + (quo.icons/icon children + {:color label-color + :size icon-size}) - (string? children) - [text/text - {:size (when (#{56 24} size) :paragraph-2) - :weight :medium - :number-of-lines 1 - :style {:color label-color}} - children] + (string? children) + (text/text + {:size (when (#{56 24} size) :paragraph-2) + :weight :medium + :number-of-lines 1 + :style {:color label-color}} + children) - (vector? children) - children)] - (when icon-right - [rn/view - {:style (style/icon-right-icon-style - {:size size - :icon-size icon-size})} - [quo.icons/icon icon-right - {:color icon-color - :size icon-size}]])]]])))) + (vector? children) + children)) + (when icon-right + (rn.pure/view + {:style (style/icon-right-icon-style + {:size size + :icon-size icon-size})} + (quo.icons/icon icon-right + {:color icon-color + :size icon-size})))))))) -(def button (theme/with-theme button-internal)) +(defn button [props children] (rn.pure/func button-pure props children)) diff --git a/src/quo/components/buttons/dynamic_button/view.cljs b/src/quo/components/buttons/dynamic_button/view.cljs index 1b75bcb86ac..443358da9c8 100644 --- a/src/quo/components/buttons/dynamic_button/view.cljs +++ b/src/quo/components/buttons/dynamic_button/view.cljs @@ -5,8 +5,7 @@ [quo.components.markdown.text :as text] [quo.foundations.colors :as colors] [quo.theme :as quo.theme] - [react-native.core :as rn] - [reagent.core :as reagent])) + [react-native.pure :as rn.pure])) (defn- get-button-color [{:keys [type pressed? customization-color theme]}] @@ -32,7 +31,7 @@ (defn- icon-view [type theme] - [icon/icon + (icon/icon (case type :jump-to :i/jump-to :mention :i/mention @@ -43,50 +42,50 @@ :scroll-to-bottom :i/arrow-down) {:size 12 :color (get-icon-and-text-color type theme) - :container-style (style/container type)}]) + :container-style (style/container type)})) -(defn- view-internal +(defn- view-pure "[dynamic-button opts] opts {:type :jump-to/:mention/:notification-down/:notification-up/:search/:search-with-label/:scroll-to-bottom :on-press fn :count mentions or notifications count :customization-color customize jump-to and mention button color}" - [_] - (let [pressed? (reagent/atom false)] - (fn [{:keys [type label on-press customization-color style theme] :as args}] - [rn/touchable-opacity - {:on-press-in #(reset! pressed? true) - :on-press-out #(reset! pressed? false) - :on-press on-press - :active-opacity 1 - :hit-slop {:top 5 :bottom 5 :left 5 :right 5} - :pointer-events :auto - :style {:height 24} - :accessibility-label type} - [rn/view - {:style (merge - {:flex-direction :row - :height 24 - :border-radius 12 - :background-color (get-button-color {:type type - :pressed? @pressed? - :customization-color (or customization-color - :primary) - :theme theme})} - style)} - (when (#{:mention :search :search-with-label :scroll-to-bottom} type) - [icon-view type]) - (when (#{:jump-to :mention :notification-down :notification-up :search-with-label} type) - [text/text - {:weight :medium - :size :paragraph-2 - :style (assoc (style/text type) :color (get-icon-and-text-color type theme))} - (case type - :jump-to label - :search-with-label label - (:mention :notification-down :notification-up) (str (:count args)))]) - (when (#{:jump-to :notification-down :notification-up} type) - [icon-view type theme])]]))) + [{:keys [type label on-press customization-color style] :as args}] + (let [[pressed? set-pressed] (rn.pure/use-state false) + theme (quo.theme/use-theme)] + (rn.pure/touchable-opacity + {:on-press-in #(set-pressed true) + :on-press-out #(set-pressed false) + :on-press on-press + :active-opacity 1 + :hit-slop {:top 5 :bottom 5 :left 5 :right 5} + :pointer-events :auto + :style {:height 24} + :accessibility-label type} + (rn.pure/view + {:style (merge + {:flex-direction :row + :height 24 + :border-radius 12 + :background-color (get-button-color {:type type + :pressed? pressed? + :customization-color (or customization-color + :primary) + :theme theme})} + style)} + (when (#{:mention :search :search-with-label :scroll-to-bottom} type) + (icon-view type theme)) + (when (#{:jump-to :mention :notification-down :notification-up :search-with-label} type) + (text/text + {:weight :medium + :size :paragraph-2 + :style (assoc (style/text type) :color (get-icon-and-text-color type theme))} + (case type + :jump-to label + :search-with-label label + (:mention :notification-down :notification-up) (str (:count args))))) + (when (#{:jump-to :notification-down :notification-up} type) + (icon-view type theme)))))) -(def view (quo.theme/with-theme view-internal)) +(defn view [props] (rn.pure/func view-pure props)) diff --git a/src/quo/components/buttons/logout_button/view.cljs b/src/quo/components/buttons/logout_button/view.cljs index 0199a13a37e..50152b5b930 100644 --- a/src/quo/components/buttons/logout_button/view.cljs +++ b/src/quo/components/buttons/logout_button/view.cljs @@ -4,31 +4,30 @@ [quo.components.icon :as icon] [quo.components.markdown.text :as text] [quo.foundations.colors :as colors] - [quo.theme :as quo.theme] - [react-native.core :as rn] - [reagent.core :as reagent] + quo.theme + [react-native.pure :as rn.pure] [utils.i18n :as i18n])) -(defn- view-internal - [_] - (let [pressed? (reagent/atom false) - on-press-in #(reset! pressed? true) - on-press-out #(reset! pressed? nil)] - (fn - [{:keys [on-press on-long-press disabled? theme container-style]}] - [rn/pressable - {:accessibility-label :log-out-button - :on-press on-press - :on-press-in on-press-in - :on-press-out on-press-out - :on-long-press on-long-press - :disabled disabled? - :style (merge (style/main {:pressed? @pressed? - :theme theme - :disabled? disabled?}) - container-style)} - [icon/icon :i/log-out {:color (if pressed? colors/white-opa-40 colors/white-opa-70)}] - [text/text {:weight :medium :size :paragraph-1} - (i18n/label :t/logout)]]))) +(defn- view-pure + [{:keys [on-press on-long-press disabled? container-style]}] + (let [[pressed? set-pressed] (rn.pure/use-state false) + theme (quo.theme/use-theme)] + (rn.pure/pressable + {:accessibility-label :log-out-button + :on-press on-press + :on-press-in #(set-pressed true) + :on-press-out #(set-pressed nil) + :on-long-press on-long-press + :disabled disabled? + :style (merge (style/main {:pressed? pressed? + :theme theme + :disabled? disabled?}) + container-style)} + (icon/icon :i/log-out {:color (if pressed? colors/white-opa-40 colors/white-opa-70)}) + (text/text + {:weight :medium :size :paragraph-1} + (i18n/label :t/logout))))) -(def view (quo.theme/with-theme view-internal)) +(defn view + [props] + (rn.pure/func view-pure props)) diff --git a/src/quo/components/buttons/slide_button/component_spec.cljs b/src/quo/components/buttons/slide_button/component_spec.cljs index 7a1c66fe3db..904906f080e 100644 --- a/src/quo/components/buttons/slide_button/component_spec.cljs +++ b/src/quo/components/buttons/slide_button/component_spec.cljs @@ -59,7 +59,7 @@ (def ^:private default-props {:on-complete identity - :track-text :test-track-text + :track-text ":test-track-text" :track-icon :face-id}) (h/describe "slide-button" @@ -67,7 +67,7 @@ (h/test "render the correct text" (h/render [slide-button/view default-props]) - (h/is-truthy (h/get-by-text :test-track-text))) + (h/is-truthy (h/get-by-text ":test-track-text"))) (h/test "render the disabled button" (h/render [slide-button/view (assoc default-props :disabled? true)]) diff --git a/src/quo/components/dividers/strength_divider/view.cljs b/src/quo/components/dividers/strength_divider/view.cljs index b98d93ccdd7..3be2a4ca3b5 100644 --- a/src/quo/components/dividers/strength_divider/view.cljs +++ b/src/quo/components/dividers/strength_divider/view.cljs @@ -32,19 +32,19 @@ [{:keys [color percentage]}] (let [strength-indicator-radius 6.5 strength-indicator-circumference (* 2 Math/PI strength-indicator-radius)] - [svg/svg + (svg/svg {:view-box "0 0 16 16" :width 14.2 :transform [{:rotate "270deg"}] :height 14.2} - [svg/circle + (svg/circle {:cx 8 :cy 8 :r strength-indicator-radius :fill :transparent :stroke-width 1.2 - :stroke (colors/alpha color 0.2)}] - [svg/circle + :stroke (colors/alpha color 0.2)}) + (svg/circle {:cx 8 :cy 8 :r strength-indicator-radius @@ -52,8 +52,8 @@ :stroke-width 1.2 :stroke-dasharray strength-indicator-circumference :stroke-dashoffset (* (- 100 percentage) 0.01 strength-indicator-circumference) - :stroke color}] - [svg/circle]])) + :stroke color} + (svg/circle))))) (defn strength-indicator [type] diff --git a/src/quo/components/drawers/drawer_buttons/component_spec.cljs b/src/quo/components/drawers/drawer_buttons/component_spec.cljs index 4432392b769..4fe817b9fcd 100644 --- a/src/quo/components/drawers/drawer_buttons/component_spec.cljs +++ b/src/quo/components/drawers/drawer_buttons/component_spec.cljs @@ -1,7 +1,7 @@ (ns quo.components.drawers.drawer-buttons.component-spec (:require [quo.components.drawers.drawer-buttons.view :as drawer-buttons] - [react-native.core :as rn] + [react-native.pure :as rn.pure] [react-native.safe-area :as safe-area] [test-helpers.component :as h])) @@ -10,24 +10,24 @@ (h/test "the top heading and subheading render" (h/render [drawer-buttons/view - {:top-card {:heading :top-heading} - :bottom-card {:heading :bottom-heading}} - :top-sub-heading - :bottom-sub-heading]) - (-> (js/expect (h/get-by-text "top-heading")) + {:top-card {:heading ":top-heading"} + :bottom-card {:heading ":bottom-heading"}} + ":top-sub-heading" + ":bottom-sub-heading"]) + (-> (js/expect (h/get-by-text ":top-heading")) (.toBeTruthy)) - (-> (js/expect (h/get-by-text "top-sub-heading")) + (-> (js/expect (h/get-by-text ":top-sub-heading")) (.toBeTruthy))) (h/test "the bottom heading and subheading render" (h/render [drawer-buttons/view - {:top-card {:heading :top-heading} - :bottom-card {:heading :bottom-heading}} - :top-sub-heading - :bottom-sub-heading]) - (-> (js/expect (h/get-by-text "bottom-heading")) + {:top-card {:heading ":top-heading"} + :bottom-card {:heading ":bottom-heading"}} + ":top-sub-heading" + ":bottom-sub-heading"]) + (-> (js/expect (h/get-by-text ":bottom-heading")) (.toBeTruthy)) - (-> (js/expect (h/get-by-text "bottom-sub-heading")) + (-> (js/expect (h/get-by-text ":bottom-sub-heading")) (.toBeTruthy))) (h/test "it clicks the top card" @@ -35,40 +35,40 @@ (with-redefs [safe-area/get-top (fn [] 10)] (h/render [drawer-buttons/view {:top-card {:on-press event - :heading :top-heading} - :bottom-card {:heading :bottom-heading}} - :top-sub-heading - :bottom-sub-heading]) - (h/fire-event :press (h/get-by-text "top-heading")) + :heading ":top-heading"} + :bottom-card {:heading ":bottom-heading"}} + ":top-sub-heading" + ":bottom-sub-heading"]) + (h/fire-event :press (h/get-by-text ":top-heading")) (-> (js/expect event) (.toHaveBeenCalled))))) (h/test "it clicks the bottom card" (let [event (h/mock-fn)] (h/render [drawer-buttons/view - {:top-card {:heading :top-heading} + {:top-card {:heading ":top-heading"} :bottom-card {:on-press event - :heading :bottom-heading}} - :top-sub-heading - :bottom-sub-heading]) - (h/fire-event :press (h/get-by-text "bottom-heading")) + :heading ":bottom-heading"}} + ":top-sub-heading" + ":bottom-sub-heading"]) + (h/fire-event :press (h/get-by-text ":bottom-heading")) (-> (js/expect event) (.toHaveBeenCalled)))) (h/test "the top card child renders with a render prop" (h/render [drawer-buttons/view - {:top-card {:heading :top-heading} - :bottom-card {:heading :bottom-heading}} - [rn/text :top-render-fn] - :bottom-sub-heading]) - (-> (js/expect (h/get-by-text "top-render-fn")) + {:top-card {:heading ":top-heading"} + :bottom-card {:heading ":bottom-heading"}} + (rn.pure/text ":top-render-fn") + ":bottom-sub-heading"]) + (-> (js/expect (h/get-by-text ":top-render-fn")) (.toBeTruthy))) (h/test "the bottom card child renders with a render prop" (h/render [drawer-buttons/view - {:top-card {:heading :top-heading} - :bottom-card {:heading :bottom-heading}} - :top-sub-heading - [rn/text :bottom-render-fn]]) - (-> (js/expect (h/get-by-text "bottom-render-fn")) + {:top-card {:heading ":top-heading"} + :bottom-card {:heading ":bottom-heading"}} + ":top-sub-heading" + (rn.pure/text ":bottom-render-fn")]) + (-> (js/expect (h/get-by-text ":bottom-render-fn")) (.toBeTruthy)))) diff --git a/src/quo/components/dropdowns/dropdown/properties.cljs b/src/quo/components/dropdowns/dropdown/properties.cljs index a7272142325..8cd447bd403 100644 --- a/src/quo/components/dropdowns/dropdown/properties.cljs +++ b/src/quo/components/dropdowns/dropdown/properties.cljs @@ -109,7 +109,7 @@ (colors/theme-colors colors/neutral-10 colors/neutral-80 theme))}) (defn get-colors - [{:keys [customization-color theme type state background size]}] + [{:keys [customization-color type state background size]} theme] (let [active? (= state :active)] (cond (and (= background :photo) (= type :grey)) (grey-photo theme active? size) diff --git a/src/quo/components/dropdowns/dropdown/view.cljs b/src/quo/components/dropdowns/dropdown/view.cljs index 655e3b8d042..c9038c162a8 100644 --- a/src/quo/components/dropdowns/dropdown/view.cljs +++ b/src/quo/components/dropdowns/dropdown/view.cljs @@ -5,12 +5,12 @@ [quo.components.icon :as icon] [quo.components.markdown.text :as text] [quo.foundations.customization-colors :as customization-colors] - [quo.theme :as theme] + quo.theme [react-native.blur :as blur] - [react-native.core :as rn])) + [react-native.pure :as rn.pure])) -(defn- view-internal - [{:keys [type size state background customization-color theme on-press icon-name icon? emoji? +(defn- view-pure + [{:keys [type size state background customization-color on-press icon-name icon? emoji? accessibility-label no-icon-color?] :or {type :grey size :size-40 @@ -20,61 +20,62 @@ icon-name :i/placeholder} :as props} text] - (let [{:keys [icon-size text-size emoji-size border-radius] + (let [theme (quo.theme/use-theme) + {:keys [icon-size text-size emoji-size border-radius] :as size-properties} (properties/sizes size) {:keys [left-icon-color right-icon-color right-icon-color-2 label-color blur-type blur-overlay-color] - :as colors} (properties/get-colors props) + :as colors} (properties/get-colors props theme) right-icon (if (= state :active) :i/pullup :i/dropdown) customization-type? (= type :customization) show-blur-background? (and (= background :photo) (= type :grey) (nil? (properties/sizes-to-exclude-blur-in-photo-bg size)))] - [rn/pressable + (rn.pure/pressable {:accessibility-label (or accessibility-label :dropdown) :disabled (= state :disabled) :on-press on-press :style (style/root-container size-properties colors props)} (when show-blur-background? - [blur/view + (blur/view-pure {:blur-radius 20 :blur-type blur-type :overlay-color blur-overlay-color - :style style/blur-view}]) + :style style/blur-view})) (when customization-type? - [customization-colors/overlay + (customization-colors/overlay {:customization-color customization-color :theme theme :pressed? (= state :active) - :border-radius border-radius}]) + :border-radius border-radius})) (if emoji? - [rn/text + (rn.pure/text {:adjusts-font-size-to-fit true :style {:font-size emoji-size}} - text] - [:<> + text) + (rn.pure/fragment (when icon? - [icon/icon + (icon/icon icon-name {:accessibility-label :left-icon :color left-icon-color :no-color no-icon-color? :size icon-size - :container-style style/left-icon}]) - [text/text + :container-style style/left-icon})) + (text/text {:size text-size :weight :medium :number-of-lines 1 :style (style/right-icon label-color)} - text] - [icon/icon + text) + (icon/icon right-icon {:size icon-size :accessibility-label :right-icon :color right-icon-color - :color-2 right-icon-color-2}]])])) + :color-2 right-icon-color-2})))))) -(def view +(defn view "Props: - type: :outline |:grey (default) | :ghost | :customization - size: :size-40 (default) | :size-32 | :size-24 @@ -87,4 +88,5 @@ - on-press: function Child: string - used as label or emoji (for emoji only)" - (theme/with-theme view-internal)) + [props text] + (rn.pure/func view-pure props text)) diff --git a/src/quo/components/dropdowns/network_dropdown/style.cljs b/src/quo/components/dropdowns/network_dropdown/style.cljs index cb0efe2b573..73569333ad6 100644 --- a/src/quo/components/dropdowns/network_dropdown/style.cljs +++ b/src/quo/components/dropdowns/network_dropdown/style.cljs @@ -3,7 +3,7 @@ [quo.foundations.colors :as colors])) (defn container-border-color - [{:keys [state blur? theme pressed?]}] + [{:keys [state blur? pressed?]} theme] (let [default-color (if blur? (colors/theme-colors colors/neutral-80-opa-5 colors/white-opa-5 theme) (colors/theme-colors colors/neutral-30 colors/neutral-70 theme)) @@ -15,11 +15,11 @@ :default (if pressed? active-color default-color)))) (defn dropdown-container - [{:keys [state] :as props}] + [{:keys [state] :as props} theme] {:border-width 1 :border-radius 10 :padding-horizontal 8 :padding-vertical 6 :opacity (if (= state :disabled) 0.3 1) - :border-color (container-border-color props) + :border-color (container-border-color props theme) :align-items :center}) diff --git a/src/quo/components/dropdowns/network_dropdown/view.cljs b/src/quo/components/dropdowns/network_dropdown/view.cljs index 35c2b9fbaa2..f1dc19eec04 100644 --- a/src/quo/components/dropdowns/network_dropdown/view.cljs +++ b/src/quo/components/dropdowns/network_dropdown/view.cljs @@ -3,25 +3,25 @@ [quo.components.dropdowns.network-dropdown.style :as style] [quo.components.list-items.preview-list.view :as preview-list] [quo.theme :as quo.theme] - [react-native.core :as rn] + [react-native.pure :as rn.pure] [reagent.core :as reagent])) -(defn- internal-view - [_ _] - (let [pressed? (reagent/atom false)] - (fn - [{:keys [on-press state] :as props} networks] - [rn/pressable - {:style (style/dropdown-container (merge props {:pressed? @pressed?})) - :accessibility-label :network-dropdown - :disabled (= state :disabled) - :on-press on-press - :on-press-in (fn [] (reset! pressed? true)) - :on-press-out (fn [] (reset! pressed? false))} - [preview-list/view - {:type :network - :list-size (count networks) - :size :size-20} - networks]]))) +(defn- view-pure + [{:keys [on-press state] :as props} networks] + (let [theme (quo.theme/use-theme) + [pressed? set-pressed] (rn.pure/use-state false)] + (rn.pure/pressable + {:style (style/dropdown-container (merge props {:pressed? pressed?}) theme) + :accessibility-label :network-dropdown + :disabled (= state :disabled) + :on-press on-press + :on-press-in #(set-pressed true) + :on-press-out #(set-pressed false)} + (reagent/as-element + [preview-list/view + {:type :network + :list-size (count networks) + :size :size-20} + networks])))) -(def view (quo.theme/with-theme internal-view)) +(defn view [props networks] (rn.pure/func view-pure props networks)) diff --git a/src/quo/components/icon.cljs b/src/quo/components/icon.cljs index 6ad3ed72571..78be891667f 100644 --- a/src/quo/components/icon.cljs +++ b/src/quo/components/icon.cljs @@ -5,7 +5,7 @@ [quo.components.icons.svg :as icons.svg] [quo.foundations.colors :as colors] [quo.theme :as quo.theme] - [react-native.core :as rn])) + [react-native.pure :as rn.pure])) (defn- valid-color? [color] @@ -15,7 +15,7 @@ (not (string/blank? color)))))) (defn- image-icon-style - [{:keys [color no-color size container-style theme]}] + [{:keys [color no-color size container-style]} theme] (cond-> {:width size :height size} (not no-color) @@ -26,29 +26,29 @@ :always (merge container-style))) -(defn memo-icon-fn +(defn icon-pure [{:keys [color color-2 container-style size accessibility-label] :or {accessibility-label :icon} :as props} icon-name] - (let [size (or size 20)] - (with-meta - (if-let [svg-icon (icons.svg/get-icon icon-name size)] - [svg-icon - (cond-> {:size size - :accessibility-label accessibility-label - :style container-style} - (valid-color? color) (assoc :color color) - (valid-color? color-2) (assoc :color-2 color-2))] - [rn/image - {:style (image-icon-style (assoc props :size size)) - :accessibility-label accessibility-label - :source (icons/icon-source (str (name icon-name) size))}]) - {:key icon-name}))) + (let [size (or size 20) + theme (quo.theme/use-theme)] + (if-let [svg-icon (icons.svg/icon icon-name size)] + (svg-icon + (cond-> {:size size + :accessibility-label accessibility-label + :style container-style} + (valid-color? color) (assoc :color color) + (valid-color? color-2) (assoc :color-2 color-2))) + (rn.pure/image + {:key icon-name + :style (image-icon-style (assoc props :size size) theme) + :accessibility-label accessibility-label + :source (icons/icon-source (str (name icon-name) size))})))) -(def ^:private themed-icon (memoize (quo.theme/with-theme memo-icon-fn))) +(def icon-pure-memo (memoize icon-pure)) (defn icon ([icon-name] (icon icon-name nil)) ([icon-name params] - (themed-icon params icon-name))) + (rn.pure/func icon-pure-memo params icon-name))) diff --git a/src/quo/components/icons/svg.cljs b/src/quo/components/icons/svg.cljs index 9cdfc46f716..1a7ac9cb74e 100644 --- a/src/quo/components/icons/svg.cljs +++ b/src/quo/components/icons/svg.cljs @@ -12,174 +12,179 @@ [{:keys [size accessibility-label style] :or {size 20}} & children] - (into [svg/svg + (apply svg/svg {:accessibility-label accessibility-label :style style :width size :height size :view-box (str "0 0 " size " " size) - :fill :none}] - children)) + :fill :none} + children)) (defn- clear-20 [{:keys [color color-2] :or {color colors/neutral-100 color-2 colors/white} :as props}] - [container props - [svg/path + (container + props + (svg/path {:d "M3 10C3 6.13401 6.13401 3 10 3C13.866 3 17 6.13401 17 10C17 13.866 13.866 17 10 17C6.13401 17 3 13.866 3 10Z" - :fill color}] - [svg/path + :fill color}) + (svg/path {:d "M9.15142 9.99998L7.07566 12.0757L7.9242 12.9243L9.99994 10.8485L12.0757 12.9242L12.9242 12.0757L10.8485 9.99998L12.9242 7.92421L12.0757 7.07568L9.99994 9.15145L7.92421 7.07572L7.07568 7.92425L9.15142 9.99998Z" - :fill color-2}]]) + :fill color-2}))) (defn- dropdown-20 [{:keys [color color-2] :or {color colors/neutral-100 color-2 colors/white} :as props}] - [container props - [svg/path + (container + props + (svg/path {:d "M3 10C3 6.13401 6.13401 3 10 3C13.866 3 17 6.13401 17 10C17 13.866 13.866 17 10 17C6.13401 17 3 13.866 3 10Z" - :fill color}] - [svg/path + :fill color}) + (svg/path {:d "M7 8.5L10 11.5L13 8.5" :stroke color-2 - :stroke-width 1.2}]]) + :stroke-width 1.2}))) (defn- pullup-20 [{:keys [color color-2] :or {color colors/neutral-100 color-2 colors/white} :as props}] - [container props - [svg/path + (container + props + (svg/path {:d "M3 10C3 6.13401 6.13401 3 10 3C13.866 3 17 6.13401 17 10C17 13.866 13.866 17 10 17C6.13401 17 3 13.866 3 10Z" - :fill color}] - [svg/path + :fill color}) + (svg/path {:d "M7 11.5L10 8.5L13 11.5" :stroke color-2 - :stroke-width 1.2}]]) + :stroke-width 1.2}))) (defn- dropdown-12 [{:keys [color color-2] :or {color colors/neutral-100 color-2 colors/white} :as props}] - [container props - [svg/circle - {:cx 6 - :cy 6 - :r 6 - :fill color}] - [svg/path - {:d - "M3.5 5L6 7.5L8.5 5" - :stroke color-2 - :stroke-width 1.1}]]) + (container props + (svg/circle + {:cx 6 + :cy 6 + :r 6 + :fill color}) + (svg/path + {:d + "M3.5 5L6 7.5L8.5 5" + :stroke color-2 + :stroke-width 1.1}))) (defn- pullup-12 [{:keys [color color-2] :or {color colors/neutral-100 color-2 colors/white} :as props}] - [container props - [svg/circle - {:cx 6 - :cy 6 - :r 6 - :fill color}] - [svg/path - {:d - "M3.5 7L6 4.5L8.5 7" - :stroke color-2 - :stroke-width 1.1}]]) + (container props + (svg/circle + {:cx 6 + :cy 6 + :r 6 + :fill color}) + (svg/path + {:d + "M3.5 7L6 4.5L8.5 7" + :stroke color-2 + :stroke-width 1.1}))) (defn- contact-12 [{:keys [color color-2] :or {color colors/neutral-100 color-2 colors/white} :as props}] - [container props - [svg/circle + (container + props + (svg/circle {:cx 6 :cy 6 :r 6 - :fill color}] - [svg/path + :fill color}) + (svg/path {:d "M2.79504 9.01494C2.89473 8.85584 3.00297 8.70977 3.11963 8.5761C3.90594 7.67512 4.97212 7.45024 5.99992 7.45024C7.02772 7.45024 8.0939 7.67512 8.88021 8.5761C8.99688 8.70978 9.10512 8.85585 9.2048 9.01495C8.9501 9.28561 8.66149 9.52401 8.34577 9.72335C8.25403 9.55824 8.15512 9.41818 8.05145 9.29939C7.56503 8.74204 6.88121 8.55024 5.99992 8.55024C5.11862 8.55024 4.43481 8.74204 3.94839 9.29939C3.84472 9.41818 3.74582 9.55824 3.65408 9.72334C3.33835 9.524 3.04975 9.2856 2.79504 9.01494ZM5.99992 3.5502C5.47525 3.5502 5.04992 3.97552 5.04992 4.5002C5.04992 5.02487 5.47525 5.4502 5.99992 5.4502C6.52459 5.4502 6.94992 5.02487 6.94992 4.5002C6.94992 3.97552 6.52459 3.5502 5.99992 3.5502ZM3.94992 4.5002C3.94992 3.36801 4.86773 2.4502 5.99992 2.4502C7.1321 2.4502 8.04992 3.36801 8.04992 4.5002C8.04992 5.63238 7.1321 6.5502 5.99992 6.5502C4.86773 6.5502 3.94992 5.63238 3.94992 4.5002Z" - :fill color-2}]]) + :fill color-2}))) (defn- contact-20 [{:keys [color color-2] :or {color colors/neutral-100 color-2 colors/white} :as props}] - [container props - [svg/circle + (container + props + (svg/circle {:cx 10 :cy 10 :r 7.5 - :fill color}] - [svg/path + :fill color}) + (svg/path {:d "M8.65002 7.99998C8.65002 7.25439 9.25443 6.64998 10 6.64998C10.7456 6.64998 11.35 7.25439 11.35 7.99998C11.35 8.74556 10.7456 9.34998 10 9.34998C9.25443 9.34998 8.65002 8.74556 8.65002 7.99998ZM10 5.34998C8.53646 5.34998 7.35002 6.53642 7.35002 7.99998C7.35002 9.46353 8.53646 10.65 10 10.65C11.4636 10.65 12.65 9.46353 12.65 7.99998C12.65 6.53642 11.4636 5.34998 10 5.34998ZM10 13.65C8.67557 13.65 7.53064 14.4186 6.98692 15.5341C6.60094 15.3235 6.23942 15.0737 5.90771 14.79C6.69408 13.3369 8.23179 12.35 10 12.35C11.7682 12.35 13.306 13.3369 14.0923 14.79C13.7606 15.0737 13.3991 15.3235 13.0131 15.5341C12.4694 14.4186 11.3245 13.65 10 13.65Z" - :fill color-2}]]) + :fill color-2}))) (defn- verified-20 [{:keys [color color-2] :or {color colors/neutral-100 color-2 colors/white} :as props}] - [container props - [svg/path + (container + props + (svg/path {:d "M18 10C18 8.77003 17.1118 7.74751 15.9418 7.53891C16.6216 6.56407 16.5267 5.21294 15.6569 4.34321C14.7872 3.47344 13.436 3.37852 12.4611 4.05845C12.2526 2.88834 11.23 2 10 2C8.77 2 7.74747 2.88827 7.53889 4.05832C6.56406 3.37846 5.21292 3.47339 4.34318 4.34313C3.47343 5.21288 3.3785 6.56404 4.05839 7.53888C2.88831 7.74743 2 8.76998 2 10C2 11.23 2.88824 12.2525 4.05826 12.4611C3.3784 13.4359 3.47333 14.7871 4.34307 15.6568C5.21284 16.5266 6.56403 16.6215 7.53887 15.9416C7.74741 17.1117 8.76996 18 10 18C11.23 18 12.2525 17.1117 12.4611 15.9417C13.4359 16.6215 14.7871 16.5266 15.6568 15.6569C16.5265 14.7871 16.6215 13.436 15.9416 12.4611C17.1117 12.2526 18 11.23 18 10Z" - :fill color}] - [svg/path + :fill color}) + (svg/path {:d "M7.25 10.75L9.25 12.25L12.75 7.75" :stroke color-2 - :stroke-width "1.2"}]]) + :stroke-width "1.2"}))) (defn- untrustworthy-20 [{:keys [color color-2] :or {color colors/neutral-100 color-2 colors/white} :as props}] - [container props - [svg/path + (container + props + (svg/path {:d "M10 2L15.6569 4.34315L18 10L15.6569 15.6569L10 18L4.34315 15.6569L2 10L4.34315 4.34315L10 2Z" - :fill color}] - [svg/path + :fill color}) + (svg/path {:d "M10.75 5.5L10.55 11.5H9.45L9.25 5.5H10.75ZM10 13C10.4142 13 10.75 13.3358 10.75 13.75C10.75 14.1642 10.4142 14.5 10 14.5C9.58579 14.5 9.25 14.1642 9.25 13.75C9.25 13.3358 9.58579 13 10 13Z" - :fill color-2}]]) + :fill color-2}))) (def ^:private icons - {:i/clear-20 clear-20 - :i/dropdown-20 dropdown-20 - :i/pullup-20 pullup-20 - :i/dropdown-12 dropdown-12 - :i/pullup-12 pullup-12 - :i/contact-12 contact-12 - :i/contact-20 contact-20 - :i/verified-20 verified-20 - :i/untrustworthy-20 untrustworthy-20}) + {:i/clear-20 (memoize clear-20) + :i/dropdown-20 (memoize dropdown-20) + :i/pullup-20 (memoize pullup-20) + :i/dropdown-12 (memoize dropdown-12) + :i/pullup-12 (memoize pullup-12) + :i/contact-12 (memoize contact-12) + :i/contact-20 (memoize contact-20) + :i/verified-20 (memoize verified-20) + :i/untrustworthy-20 (memoize untrustworthy-20)}) (defn- append-to-keyword [k & xs] - (keyword (apply str - (subs (str k) 1) - xs))) + (keyword (apply str (subs (str k) 1) xs))) -(defn get-icon +(defn icon [icon-name size] (get icons (append-to-keyword icon-name "-" size))) diff --git a/src/quo/components/inputs/address_input/style.cljs b/src/quo/components/inputs/address_input/style.cljs index fe44f770a82..2bd9e6dbe93 100644 --- a/src/quo/components/inputs/address_input/style.cljs +++ b/src/quo/components/inputs/address_input/style.cljs @@ -29,7 +29,8 @@ (defn input-text [theme] (assoc (text/text-style {:size :paragraph-1 - :weight :monospace}) + :weight :monospace} + nil) :flex 1 :color (colors/theme-colors colors/neutral-100 colors/white theme) :margin-top (if platform/ios? 0 -4) diff --git a/src/quo/components/inputs/input/style.cljs b/src/quo/components/inputs/input/style.cljs index 584ddc60fb9..e7da8003884 100644 --- a/src/quo/components/inputs/input/style.cljs +++ b/src/quo/components/inputs/input/style.cljs @@ -86,7 +86,7 @@ (defn input [colors-by-status small? multiple-lines? weight] (let [padding (if small? 4 8) - base-props (assoc (text/text-style {:size :paragraph-1 :weight (or weight :regular)}) + base-props (assoc (text/text-style {:size :paragraph-1 :weight (or weight :regular)} nil) :flex 1 :padding-right 0 :padding-left padding diff --git a/src/quo/components/inputs/recovery_phrase/style.cljs b/src/quo/components/inputs/recovery_phrase/style.cljs index 58e9108886f..a248875e837 100644 --- a/src/quo/components/inputs/recovery_phrase/style.cljs +++ b/src/quo/components/inputs/recovery_phrase/style.cljs @@ -13,7 +13,7 @@ (defn input [] - (assoc (text/text-style {}) + (assoc (text/text-style {} nil) :height 32 :flex-grow 1 :padding-vertical 5 diff --git a/src/quo/components/inputs/search_input/style.cljs b/src/quo/components/inputs/search_input/style.cljs index 0b4d92c4052..fa1f641840a 100644 --- a/src/quo/components/inputs/search_input/style.cljs +++ b/src/quo/components/inputs/search_input/style.cljs @@ -63,7 +63,8 @@ (defn input-text [disabled?] (assoc (text/text-style {:size :paragraph-1 - :weight :regular}) + :weight :regular} + nil) :flex 1 :padding-vertical 5 :min-width 120 diff --git a/src/quo/components/inputs/title_input/view.cljs b/src/quo/components/inputs/title_input/view.cljs index 17c84ae30ce..73da55b3350 100644 --- a/src/quo/components/inputs/title_input/view.cljs +++ b/src/quo/components/inputs/title_input/view.cljs @@ -4,8 +4,7 @@ [quo.components.inputs.title-input.style :as style] [quo.components.markdown.text :as text] [quo.theme :as quo.theme] - [react-native.core :as rn] - [reagent.core :as reagent])) + [react-native.pure :as rn.pure])) (defn- pad-0 [value] @@ -13,7 +12,7 @@ (str 0 value) value)) -(defn- view-internal +(defn- view-pure [{:keys [blur? on-change-text auto-focus @@ -22,72 +21,74 @@ default-value return-key-type size - theme on-focus on-blur - container-style] + container-style + customization-color + disabled?] :or {max-length 0 auto-focus false default-value ""}}] - (let [focused? (reagent/atom auto-focus) - value (reagent/atom default-value) - input-ref (atom nil) - on-change (fn [v] - (reset! value v) - (when on-change-text - (on-change-text v)))] - (fn [{:keys [customization-color disabled?]}] - [rn/view - {:style (merge (style/container disabled?) container-style)} - [rn/view {:style style/text-input-container} - [rn/text-input - {:style - (text/text-style - {:size (or size :heading-1) - :weight :semi-bold - :style (style/title-text theme)}) - :default-value default-value - :accessibility-label :profile-title-input - :keyboard-appearance (quo.theme/theme-value :light :dark theme) - :return-key-type return-key-type - :on-focus (fn [] - (when (fn? on-focus) - (on-focus)) - (reset! focused? true)) - :on-blur (fn [] - (when (fn? on-blur) - (on-blur)) - (reset! focused? false)) - :auto-focus auto-focus - :input-mode :text - :on-change-text on-change - :editable (not disabled?) - :max-length max-length - :placeholder placeholder - :ref #(reset! input-ref %) - :selection-color (style/get-selection-color customization-color blur? theme) - :placeholder-text-color (if @focused? - (style/get-focused-placeholder-color blur? theme) - (style/get-placeholder-color blur? theme))}]] - [rn/view - {:style (style/counter-container @focused?)} - (if @focused? - [text/text - [text/text - {:style (style/char-count blur? theme) - :size :paragraph-2} - (pad-0 - (str - (count @value)))] - [text/text - {:style (style/char-count blur? theme) - :size :paragraph-2} - (str "/" - (pad-0 - (str max-length)))]] - [rn/pressable - {:on-press #(when-not disabled? - (.focus ^js @input-ref))} - [icon/icon :i/edit {:color (style/get-char-count-color blur? theme)}]])]]))) + (let [theme (quo.theme/use-theme) + [focused? set-focused] (rn.pure/use-state auto-focus) + [value set-value] (rn.pure/use-state default-value) + input-ref (atom nil) + on-change (fn [v] + (set-value v) + (when on-change-text + (on-change-text v)))] + (rn.pure/view + {:style (merge (style/container disabled?) container-style)} + (rn.pure/view + {:style style/text-input-container} + (rn.pure/text-input + {:style + (text/text-style + {:size (or size :heading-1) + :weight :semi-bold + :style (style/title-text theme)} + nil) + :default-value default-value + :accessibility-label :profile-title-input + :keyboard-appearance (quo.theme/theme-value :light :dark theme) + :return-key-type return-key-type + :on-focus (fn [] + (when (fn? on-focus) + (on-focus)) + (set-focused true)) + :on-blur (fn [] + (when (fn? on-blur) + (on-blur)) + (set-focused false)) + :auto-focus auto-focus + :input-mode :text + :on-change-text on-change + :editable (not disabled?) + :max-length max-length + :placeholder placeholder + :ref #(reset! input-ref %) + :selection-color (style/get-selection-color customization-color blur? theme) + :placeholder-text-color (if focused? + (style/get-focused-placeholder-color blur? theme) + (style/get-placeholder-color blur? theme))})) + (rn.pure/view + {:style (style/counter-container focused?)} + (if focused? + (text/text + (text/text + {:style (style/char-count blur? theme) + :size :paragraph-2} + (pad-0 + (str + (count value)))) + (text/text + {:style (style/char-count blur? theme) + :size :paragraph-2} + (str "/" + (pad-0 + (str max-length))))) + (rn.pure/pressable + {:on-press #(when-not disabled? (.focus ^js @input-ref))} + (icon/icon :i/edit {:color (style/get-char-count-color blur? theme)}))))))) -(def view (quo.theme/with-theme view-internal)) +(defn view [props] (rn.pure/func view-pure props)) diff --git a/src/quo/components/list_items/address/view.cljs b/src/quo/components/list_items/address/view.cljs index a536eeef182..7139ec82a7c 100644 --- a/src/quo/components/list_items/address/view.cljs +++ b/src/quo/components/list_items/address/view.cljs @@ -5,63 +5,65 @@ [quo.components.markdown.text :as text] [quo.foundations.colors :as colors] [quo.theme :as quo.theme] - [react-native.core :as rn] - [reagent.core :as reagent] + [react-native.pure :as rn.pure] [utils.address :as address])) (defn- left-container [{:keys [theme address networks blur?]}] - [rn/view {:style style/left-container} - [wallet-user-avatar/wallet-user-avatar + (rn.pure/view + {:style style/left-container} + (wallet-user-avatar/wallet-user-avatar {:size :size-32 :full-name "0 x" :monospace? true :lowercase? true - :neutral? true}] - [rn/view {:style style/account-container} - [text/text {:size :paragraph-1} + :neutral? true}) + (rn.pure/view + {:style style/account-container} + (text/text + {:size :paragraph-1} (map (fn [network] ^{:key (str network)} - [text/text + (text/text {:size :paragraph-1 :weight :semi-bold :style {:color (colors/resolve-color (:network-name network) theme)}} - (str (:short-name network) ":")]) + (str (:short-name network) ":"))) networks) - [text/text + (text/text {:size :paragraph-1 :weight :monospace :style {:color (if blur? colors/white (colors/theme-colors colors/neutral-100 colors/white theme))}} - (address/get-shortened-key address)]]]]) + (address/get-shortened-key address)))))) -(defn- internal-view - [] - (let [state (reagent/atom :default) - active? (atom false) - timer (atom nil) - on-press-in (fn [] - (when-not (= @state :selected) - (reset! timer (js/setTimeout #(reset! state :pressed) 100))))] - (fn [{:keys [networks address customization-color on-press active-state? blur? theme] - :or {customization-color :blue}}] - (let [on-press-out (fn [] - (let [new-state (if (or (not active-state?) @active?) :default :active)] - (when @timer (js/clearTimeout @timer)) - (reset! timer nil) - (reset! active? (= new-state :active)) - (reset! state new-state)))] - [rn/pressable - {:style (style/container @state customization-color blur?) - :on-press-in on-press-in - :on-press-out on-press-out - :on-press on-press - :accessibility-label :container} - [left-container - {:theme theme - :networks networks - :address address - :blur? blur?}]])))) +(defn- view-pure + [{:keys [networks address customization-color on-press active-state? blur?] + :or {customization-color :blue}}] + (let [theme (quo.theme/use-theme) + [state set-state] (rn.pure/use-state :default) + active? (atom false) + timer (atom nil) + on-press-in (fn [] + (when-not (= state :selected) + (reset! timer (js/setTimeout #(set-state :pressed) 100)))) + on-press-out (fn [] + (let [new-state (if (or (not active-state?) @active?) :default :active)] + (when @timer (js/clearTimeout @timer)) + (reset! timer nil) + (reset! active? (= new-state :active)) + (set-state new-state)))] + (rn.pure/pressable + {:style (style/container state customization-color blur?) + :on-press-in on-press-in + :on-press-out on-press-out + :on-press on-press + :accessibility-label :container} + (left-container + {:theme theme + :networks networks + :address address + :blur? blur?})))) -(def view (quo.theme/with-theme internal-view)) +(defn view [params] (rn.pure/func view-pure params)) diff --git a/src/quo/components/list_items/saved_address/view.cljs b/src/quo/components/list_items/saved_address/view.cljs index 4f4a2a0aaf1..4900f2c13ed 100644 --- a/src/quo/components/list_items/saved_address/view.cljs +++ b/src/quo/components/list_items/saved_address/view.cljs @@ -6,71 +6,72 @@ [quo.components.markdown.text :as text] [quo.foundations.colors :as colors] [quo.theme :as quo.theme] - [react-native.core :as rn] - [reagent.core :as reagent] + [react-native.pure :as rn.pure] [utils.address :as address])) (defn- left-container [{:keys [blur? theme name ens address customization-color]}] - [rn/view {:style style/left-container} - [wallet-user-avatar/wallet-user-avatar + (rn.pure/view + {:style style/left-container} + (wallet-user-avatar/wallet-user-avatar {:size :size-32 :full-name name - :customization-color customization-color}] - [rn/view {:style style/account-container} - [text/text + :customization-color customization-color}) + (rn.pure/view + {:style style/account-container} + (text/text {:weight :semi-bold :size :paragraph-1 :style style/name-text} - name] - [text/text {:size :paragraph-2} - [text/text + name) + (text/text + {:size :paragraph-2} + (text/text {:size :paragraph-2 :weight :monospace :style (style/account-address blur? theme)} - (or ens (address/get-shortened-key address))]]]]) + (or ens (address/get-shortened-key address))))))) -(defn- internal-view - [] - (let [state (reagent/atom :default) - active? (atom false) - timer (atom nil) - on-press-in (fn [] - (when-not (= @state :selected) - (reset! timer (js/setTimeout #(reset! state :pressed) 100))))] - (fn [{:keys [blur? user-props active-state? customization-color - on-press - on-options-press - theme] - :or {customization-color :blue - blur? false}}] - (let [on-press-out (fn [] - (let [new-state (if (or (not active-state?) @active?) :default :active)] - (when @timer (js/clearTimeout @timer)) - (reset! timer nil) - (reset! active? (= new-state :active)) - (reset! state new-state)))] - [rn/pressable - {:style (style/container - {:state @state :blur? blur? :customization-color customization-color}) - :on-press-in on-press-in - :on-press-out on-press-out - :on-press on-press - :accessibility-label :container} - [left-container - {:blur? blur? - :theme theme - :name (:name user-props) - :ens (:ens user-props) - :address (:address user-props) - :customization-color (or (:customization-color user-props) :blue)}] - (when on-options-press - [rn/pressable - {:accessibility-label :options-button - :on-press on-options-press} - [icon/icon :i/options - {:color (if blur? - colors/white-opa-70 - (colors/theme-colors colors/neutral-50 colors/neutral-40 theme))}]])])))) +(defn- view-pure + [{:keys [blur? user-props active-state? customization-color + on-press + on-options-press] + :or {customization-color :blue + blur? false}}] + (let [theme (quo.theme/use-theme) + [state set-state] (rn.pure/use-state :default) + active? (atom false) + timer (atom nil) + on-press-in (fn [] + (when-not (= state :selected) + (reset! timer (js/setTimeout #(set-state :pressed) 100)))) + on-press-out (fn [] + (let [new-state (if (or (not active-state?) @active?) :default :active)] + (when @timer (js/clearTimeout @timer)) + (reset! timer nil) + (reset! active? (= new-state :active)) + (set-state new-state)))] + (rn.pure/pressable + {:style (style/container + {:state state :blur? blur? :customization-color customization-color}) + :on-press-in on-press-in + :on-press-out on-press-out + :on-press on-press + :accessibility-label :container} + (left-container + {:blur? blur? + :theme theme + :name (:name user-props) + :ens (:ens user-props) + :address (:address user-props) + :customization-color (or (:customization-color user-props) :blue)}) + (when on-options-press + (rn.pure/pressable + {:accessibility-label :options-button + :on-press on-options-press} + (icon/icon :i/options + {:color (if blur? + colors/white-opa-70 + (colors/theme-colors colors/neutral-50 colors/neutral-40 theme))})))))) -(def view (quo.theme/with-theme internal-view)) +(defn view [props] (rn.pure/func view-pure props)) diff --git a/src/quo/components/markdown/text.cljs b/src/quo/components/markdown/text.cljs index 21b5b42277a..309454ca4eb 100644 --- a/src/quo/components/markdown/text.cljs +++ b/src/quo/components/markdown/text.cljs @@ -3,11 +3,10 @@ [quo.foundations.colors :as colors] [quo.foundations.typography :as typography] [quo.theme :as quo.theme] - [react-native.core :as rn] - [reagent.core :as reagent])) + [react-native.pure :as rn.pure])) (defn text-style - [{:keys [size align weight style theme]}] + [{:keys [size align weight style]} theme] (merge (case (or weight :regular) :regular typography/font-regular :medium typography/font-medium @@ -30,19 +29,18 @@ :color (if (= (or theme (quo.theme/get-theme)) :dark) colors/white colors/neutral-100))))) -(defn- text-view-internal - [props & children] - (let [style (text-style props)] - (into [rn/text - (merge {:style style} - (dissoc props :style :size :align :weight :color :theme))] - children))) - -(def ^:private text-view (quo.theme/with-theme text-view-internal)) +(defn text-pure + [props children] + (let [theme (quo.theme/use-theme) + style (text-style props theme)] + (apply rn.pure/text + (-> props + (assoc :style style) + (dissoc :size :align :weight :color :theme)) + children))) (defn text - [] - (let [this (reagent/current-component) - props (reagent/props this) - children (reagent/children this)] - (into [text-view props] children))) + [& children] + (let [props (first children) + props (when (map? props) props)] + (rn.pure/func text-pure props (if props (rest children) children)))) diff --git a/src/quo/components/navigation/floating_shell_button/view.cljs b/src/quo/components/navigation/floating_shell_button/view.cljs index e59a49956fc..c52b5ff89c3 100644 --- a/src/quo/components/navigation/floating_shell_button/view.cljs +++ b/src/quo/components/navigation/floating_shell_button/view.cljs @@ -2,42 +2,44 @@ (:require [quo.components.buttons.dynamic-button.view :as dynamic-button] [quo.components.navigation.floating-shell-button.style :as style] - [react-native.core :as rn] + [react-native.pure :as rn.pure] [react-native.reanimated :as reanimated])) (defn dynamic-button-view [type dynamic-buttons style] (when-let [{:keys [on-press customization-color label] :as props} (get dynamic-buttons type)] - [dynamic-button/view + (dynamic-button/view {:type type :label label :on-press on-press :count (:count props) :style style - :customization-color customization-color}])) + :customization-color customization-color}))) (defn- section [children] - [rn/view {:style {:flex 1} :pointer-events :box-none} children]) + (rn.pure/view {:style {:flex 1} :pointer-events :box-none} children)) -(defn- f-floating-shell-button +(defn- floating-shell-button-pure [dynamic-buttons style opacity-anim] - [reanimated/view {:style (style/floating-shell-button style opacity-anim)} + (reanimated/view-pure + {:style (style/floating-shell-button style opacity-anim)} ;; Left Section - [section - [dynamic-button-view :search dynamic-buttons - {:position :absolute - :right 8}]] + (section + (dynamic-button-view :search + dynamic-buttons + {:position :absolute + :right 8})) ;; Mid Section (jump-to) - [dynamic-button-view :jump-to dynamic-buttons nil] + (dynamic-button-view :jump-to dynamic-buttons nil) ;; Right Section - [section - [rn/view + (section + (rn.pure/view {:style style/right-section} - [dynamic-button-view :mention dynamic-buttons {:margin-left 8}] - [dynamic-button-view :notification-down dynamic-buttons {:margin-left 8}] - [dynamic-button-view :notification-up dynamic-buttons {:margin-left 8}] - [dynamic-button-view :scroll-to-bottom dynamic-buttons {:margin-left 8}]]]]) + (dynamic-button-view :mention dynamic-buttons {:margin-left 8}) + (dynamic-button-view :notification-down dynamic-buttons {:margin-left 8}) + (dynamic-button-view :notification-up dynamic-buttons {:margin-left 8}) + (dynamic-button-view :scroll-to-bottom dynamic-buttons {:margin-left 8}))))) (defn view "[floating-shell-button dynamic-buttons style opacity-anim pointer-anim] @@ -45,6 +47,6 @@ style override style opacity-anim reanimated value (optional)" ([dynamic-buttons style] - [:f> f-floating-shell-button dynamic-buttons style nil]) + (rn.pure/func floating-shell-button-pure dynamic-buttons style nil)) ([dynamic-buttons style opacity-anim] - [:f> f-floating-shell-button dynamic-buttons style opacity-anim])) + (rn.pure/func floating-shell-button-pure dynamic-buttons style opacity-anim))) diff --git a/src/quo/components/navigation/page_nav/view.cljs b/src/quo/components/navigation/page_nav/view.cljs index 077f086c8fe..4d256d844f4 100644 --- a/src/quo/components/navigation/page_nav/view.cljs +++ b/src/quo/components/navigation/page_nav/view.cljs @@ -10,8 +10,8 @@ [quo.components.icon :as icons] [quo.components.markdown.text :as text] [quo.components.navigation.page-nav.style :as style] - [quo.theme :as theme] - [react-native.core :as rn])) + [quo.theme :as quo.theme] + [react-native.pure :as rn.pure])) (def ^:private button-type {:white :grey @@ -26,28 +26,30 @@ [{:keys [margin-top background on-press accessibility-label icon-name behind-overlay?] :or {background :white}} & children] - (into [rn/view {:style (style/container margin-top)} - (when icon-name - [button/button - {:type (button-type background) - :icon-only? true - :size 32 - :on-press on-press - :background (if behind-overlay? - :blur - (button-properties/backgrounds background)) - :accessibility-label accessibility-label} - icon-name])] - children)) + (apply + rn.pure/view + {:style (style/container margin-top)} + (when icon-name + (button/button + {:type (button-type background) + :icon-only? true + :size 32 + :on-press on-press + :background (if behind-overlay? + :blur + (button-properties/backgrounds background)) + :accessibility-label accessibility-label} + icon-name)) + children)) -(defn- right-section-spacing [] [rn/view {:style style/right-actions-spacing}]) +(defn- right-section-spacing [] (rn.pure/view {:style style/right-actions-spacing})) (defn- add-right-buttons-xf [max-actions background behind-overlay?] (comp (filter map?) (take max-actions) (map (fn [{:keys [icon-name label] :as button-props}] - [button/button + (button/button (assoc button-props :type (button-type background) :icon-only? icon-name @@ -56,134 +58,150 @@ :background (if behind-overlay? :blur (when (button-properties/backgrounds background) background))) - (or label icon-name)])) - (interpose [right-section-spacing]))) + (or label icon-name)))) + (interpose (right-section-spacing)))) (defn- account-switcher-content [{:keys [customization-color on-press emoji type]}] - [rn/pressable {:on-press on-press} - [account-avatar/view + (rn.pure/pressable + {:on-press on-press} + (account-avatar/view {:emoji emoji :size 32 :type (or type :default) - :customization-color customization-color}]]) + :customization-color customization-color}))) (defn- right-content [{:keys [background content max-actions min-size? support-account-switcher? account-switcher behind-overlay?] :or {support-account-switcher? true}}] - [rn/view (when min-size? {:style style/right-content-min-size}) + (rn.pure/view + (when min-size? {:style style/right-content-min-size}) (cond (and support-account-switcher? (= content :account-switcher)) - [account-switcher-content account-switcher] + (account-switcher-content account-switcher) (coll? content) - (into [rn/view {:style style/right-actions-container}] - (add-right-buttons-xf max-actions background behind-overlay?) - content) + (apply rn.pure/view + {:style style/right-actions-container} + (into [] + (add-right-buttons-xf max-actions background behind-overlay?) + content)) :else - nil)]) + nil))) (defn- title-center [{:keys [centered? title center-opacity]}] - [rn/view {:style (style/center-content-container centered? center-opacity)} - [text/text + (rn.pure/view + {:style (style/center-content-container centered? center-opacity)} + (text/text {:weight :medium :size :paragraph-1 :number-of-lines 1} - title]]) + title))) (defn- dropdown-center - [{:keys [theme background dropdown-on-press dropdown-selected? dropdown-text center-opacity]}] - (let [dropdown-type (cond + [{:keys [background dropdown-on-press dropdown-selected? dropdown-text center-opacity]}] + (let [theme (quo.theme/use-theme) + dropdown-type (cond (= background :photo) :grey (and (= theme :dark) (= background :blur)) :grey :else :ghost) dropdown-state (if dropdown-selected? :active :default)] - [rn/view {:style (style/center-content-container true center-opacity)} - [dropdown/view + (rn.pure/view + {:style (style/center-content-container true center-opacity)} + (dropdown/view {:type dropdown-type :state dropdown-state :size :size-32 :background (when (dropdown-properties/backgrounds background) background) :on-press dropdown-on-press} - dropdown-text]])) + dropdown-text)))) (defn- token-center [{:keys [theme background token-logo token-name token-abbreviation center-opacity]}] - [rn/view {:style (style/center-content-container false center-opacity)} - [rn/image {:style style/token-logo :source token-logo}] - [text/text + (rn.pure/view + {:style (style/center-content-container false center-opacity)} + (rn.pure/image {:style style/token-logo :source token-logo}) + (text/text {:style style/token-name :weight :semi-bold :size :paragraph-1 :number-of-lines 1} - token-name] - [text/text + token-name) + (text/text {:style (style/token-abbreviation theme background) :weight :medium :size :paragraph-2 :number-of-lines 1} - token-abbreviation]]) + token-abbreviation))) (defn- channel-center [{:keys [theme background channel-emoji channel-name channel-icon center-opacity]}] - [rn/view {:style (style/center-content-container false center-opacity)} - [rn/text {:style style/channel-emoji} - channel-emoji] - [text/text + (rn.pure/view + {:style (style/center-content-container false center-opacity)} + (rn.pure/text + {:style style/channel-emoji} + channel-emoji) + (text/text {:style style/channel-name :weight :semi-bold :size :paragraph-1 :number-of-lines 1} - (str "# " channel-name)] - [icons/icon channel-icon {:size 16 :color (style/channel-icon-color theme background)}]]) + (str "# " channel-name)) + (icons/icon channel-icon {:size 16 :color (style/channel-icon-color theme background)}))) (defn- title-description-center [{:keys [background theme picture title description center-opacity]}] - [rn/view {:style (style/center-content-container false center-opacity)} + (rn.pure/view + {:style (style/center-content-container false center-opacity)} (when picture - [rn/view {:style style/group-avatar-picture} - [group-avatar/view {:picture picture :size :size-28}]]) - [rn/view {:style style/title-description-container} - [text/text + (rn.pure/view + {:style style/group-avatar-picture} + (group-avatar/view {:picture picture :size :size-28}))) + (rn.pure/view + {:style style/title-description-container} + (text/text {:style style/title-description-title :weight :semi-bold :size :paragraph-1 :number-of-lines 1} - title] - [text/text + title) + (text/text {:style (style/title-description-description theme background) :weight :medium :size :paragraph-2 :number-of-lines 1} - description]]]) + description)))) (defn- community-network-center [{:keys [type community-logo network-logo community-name network-name center-opacity]}] (let [community? (= type :community) shown-logo (if community? community-logo network-logo) shown-name (if community? community-name network-name)] - [rn/view {:style (style/center-content-container false center-opacity)} - [rn/image + (rn.pure/view + {:style (style/center-content-container false center-opacity)} + (rn.pure/image {:style style/community-network-logo - :source shown-logo}] - [text/text + :source shown-logo}) + (text/text {:weight :semi-bold :size :paragraph-1 :number-of-lines 1} - shown-name]])) + shown-name)))) (defn- wallet-networks-center [{:keys [networks networks-on-press background center-opacity]}] - [rn/view {:style (style/center-content-container true center-opacity)} - [network-dropdown/view + (rn.pure/view + {:style (style/center-content-container true center-opacity)} + (network-dropdown/view {:state :default :on-press networks-on-press - :blur? (= background :blur)} networks]]) + :blur? (= background :blur)} + networks))) -(defn- view-internal +(defn- view-pure "behind-overlay is necessary for us to know if the page-nav buttons are under the bottom sheet overlay or not." [{:keys [type right-side background text-align account-switcher behind-overlay?] :or {type :no-title @@ -193,83 +211,84 @@ :as props}] (case type :no-title - [page-nav-base props - [right-content + (page-nav-base + props + (right-content {:background background :content right-side :max-actions 3 :behind-overlay? behind-overlay? - :account-switcher account-switcher}]] + :account-switcher account-switcher})) :title (let [centered? (= text-align :center)] - [page-nav-base props - [title-center (assoc props :centered? centered?)] - [right-content - {:background background - :content right-side - :max-actions (if centered? 1 3) - :min-size? centered? - :account-switcher account-switcher}]]) + (page-nav-base props + (title-center (assoc props :centered? centered?)) + (right-content + {:background background + :content right-side + :max-actions (if centered? 1 3) + :min-size? centered? + :account-switcher account-switcher}))) :dropdown - [page-nav-base props - [dropdown-center props] - [right-content - {:background background - :content right-side - :max-actions 1 - :support-account-switcher? false}]] + (page-nav-base props + (dropdown-center props) + (right-content + {:background background + :content right-side + :max-actions 1 + :support-account-switcher? false})) :token - [page-nav-base props - [token-center props] - [right-content - {:background background - :content right-side - :max-actions 3 - :account-switcher account-switcher}]] + (page-nav-base props + (token-center props) + (right-content + {:background background + :content right-side + :max-actions 3 + :account-switcher account-switcher})) :channel - [page-nav-base props - [channel-center props] - [right-content - {:background background - :content right-side - :max-actions 3 - :support-account-switcher? false}]] + (page-nav-base props + (channel-center props) + (right-content + {:background background + :content right-side + :max-actions 3 + :support-account-switcher? false})) :title-description - [page-nav-base props - [title-description-center props] - [right-content - {:background background - :content right-side - :max-actions 2 - :support-account-switcher? false}]] + (page-nav-base props + (title-description-center props) + (right-content + {:background background + :content right-side + :max-actions 2 + :support-account-switcher? false})) :wallet-networks - [page-nav-base props - [wallet-networks-center props] - [right-content - {:background background - :content right-side - :max-actions 1 - :min-size? true - :account-switcher account-switcher}]] + (page-nav-base props + (wallet-networks-center props) + (right-content + {:background background + :content right-side + :max-actions 1 + :min-size? true + :account-switcher account-switcher})) (:community :network) - [page-nav-base props - [community-network-center props] - [right-content - {:background background - :content right-side - :max-actions 3 - :support-account-switcher? false}]] + (page-nav-base props + (community-network-center props) + (right-content + {:background background + :content right-side + :max-actions 3 + :support-account-switcher? false})) nil)) -(def page-nav +(defn page-nav "Props: - type: defaults to `:no-title`. - background: @@ -320,4 +339,5 @@ `:network` - network-name - network-logo a valid rn/image `:source` value" - (theme/with-theme view-internal)) + [props] + (rn.pure/func view-pure props)) diff --git a/src/quo/components/notifications/count_down_circle.cljs b/src/quo/components/notifications/count_down_circle.cljs index 51ec1d08f83..07db1fdac5d 100644 --- a/src/quo/components/notifications/count_down_circle.cljs +++ b/src/quo/components/notifications/count_down_circle.cljs @@ -89,20 +89,20 @@ {:style {:position :relative :width size :height size}} - [svg/svg + (svg/svg {:view-box (str "0 0 " size " " size) :width size :height size} - [svg/path - {:d path :fill :none :stroke (or trail-color :transparent) :stroke-width stroke-width}] + (svg/path + {:d path :fill :none :stroke (or trail-color :transparent) :stroke-width stroke-width}) (when-not (= @display-time duration) - [svg/path + (svg/path {:d path :fill :none :stroke (or color (get-in themes [:color theme])) :stroke-linecap :square :stroke-width stroke-width :stroke-dasharray path-length - :stroke-dashoffset (linear-ease @display-time 0 path-length duration)}])]])}))) + :stroke-dashoffset (linear-ease @display-time 0 path-length duration)})))])}))) (def circle-timer (quo.theme/with-theme circle-timer-internal)) diff --git a/src/quo/components/notifications/toast/view.cljs b/src/quo/components/notifications/toast/view.cljs index de2888134a2..e5c574cc95f 100644 --- a/src/quo/components/notifications/toast/view.cljs +++ b/src/quo/components/notifications/toast/view.cljs @@ -80,13 +80,13 @@ :positive :i/correct :negative :i/incorrect :neutral icon)] - [quo.theme/provider {:theme context-theme} + [quo.theme/provider context-theme [toast-container {:left (cond user [user-avatar/user-avatar user] icon-name - [icon/icon icon-name (style/icon type context-theme)] - ) + [icon/icon icon-name (style/icon type context-theme)]) + :title title :text text :right (if undo-duration diff --git a/src/quo/components/overlay/view.cljs b/src/quo/components/overlay/view.cljs index 8855ec0e36b..3aed465d0af 100644 --- a/src/quo/components/overlay/view.cljs +++ b/src/quo/components/overlay/view.cljs @@ -2,19 +2,20 @@ (:require [quo.components.overlay.style :as style] [react-native.blur :as blur] - [react-native.core :as rn])) + [react-native.pure :as rn.pure])) (defn view [{:keys [type container-style]} & children] - [rn/view {:style (style/overlay-background type)} + (rn.pure/view + {:style (style/overlay-background type)} (if (= type :shell) - [blur/view + (blur/view-pure {:blur-amount 20 :blur-radius 25 :blur-type :transparent :overlay-color :transparent :style style/container} - [rn/view {:style (merge style/blur-container container-style)} - children]] - [rn/view {:style (merge style/container container-style)} - children])]) + (rn.pure/view {:style (merge style/blur-container container-style)} + children)) + (rn.pure/view {:style (merge style/container container-style)} + children)))) diff --git a/src/quo/components/settings/category/settings/view.cljs b/src/quo/components/settings/category/settings/view.cljs index e347d2de41f..04afc1c2768 100644 --- a/src/quo/components/settings/category/settings/view.cljs +++ b/src/quo/components/settings/category/settings/view.cljs @@ -4,24 +4,25 @@ [quo.components.settings.category.style :as style] [quo.components.settings.settings-item.view :as settings-item] [quo.theme :as quo.theme] - [react-native.core :as rn])) + [react-native.pure :as rn.pure])) -(defn- category-internal - [{:keys [label data container-style] :as props}] - (let [settings-item (filter identity data)] - [rn/view {:style (merge (style/container label) container-style)} +(defn settings-category + [{:keys [label data container-style blur?]}] + (let [theme (quo.theme/use-theme) + items (filter identity data)] + (rn.pure/view + {:style (merge (style/container label) container-style)} (when label - [text/text + (text/text {:weight :medium :size :paragraph-2 - :style (style/label props)} - label]) - [rn/view {:style (style/settings-items props)} - (for [item settings-item] - ^{:key item} - [:<> - [settings-item/view item] - (when-not (= item (last settings-item)) - [rn/view {:style (style/settings-separator props)}])])]])) - -(def settings-category (quo.theme/with-theme category-internal)) + :style (style/label theme blur?)} + label)) + (rn.pure/view + {:style (style/settings-items theme blur?)} + (for [item items] + (rn.pure/fragment + {:key (:title item)} + (settings-item/view item) + (when-not (= item (last data)) + (rn.pure/view {:style (style/settings-separator theme blur?)})))))))) diff --git a/src/quo/components/settings/category/style.cljs b/src/quo/components/settings/category/style.cljs index e10db83a519..dc667d0f1c2 100644 --- a/src/quo/components/settings/category/style.cljs +++ b/src/quo/components/settings/category/style.cljs @@ -11,7 +11,7 @@ :padding-bottom 8}) (defn settings-items - [{:keys [blur? theme]}] + [theme blur?] {:margin-top 12 :border-radius 16 :background-color (if blur? @@ -23,7 +23,7 @@ (colors/theme-colors colors/neutral-10 colors/neutral-80 theme))}) (defn label - [{:keys [blur? theme]}] + [theme blur?] {:color (if blur? colors/white-opa-40 (colors/theme-colors colors/neutral-50 colors/neutral-40 theme))}) @@ -32,7 +32,7 @@ {:margin-top 12}) (defn settings-separator - [{:keys [blur? theme]}] + [theme blur?] {:height 1 :background-color (if blur? colors/white-opa-5 diff --git a/src/quo/components/settings/category/view.cljs b/src/quo/components/settings/category/view.cljs index 6fd33ca3fdb..91131c6061b 100644 --- a/src/quo/components/settings/category/view.cljs +++ b/src/quo/components/settings/category/view.cljs @@ -1,10 +1,12 @@ (ns quo.components.settings.category.view (:require [quo.components.settings.category.reorder.view :as reorder] - [quo.components.settings.category.settings.view :as settings])) + [quo.components.settings.category.settings.view :as settings] + [react-native.pure :as rn.pure] + [reagent.core :as reagent])) (defn category [{:keys [list-type] :as props}] (if (= list-type :settings) - [settings/settings-category props] - [reorder/reorder-category props])) + (rn.pure/func settings/settings-category props) + (reagent/as-element [reorder/reorder-category props]))) diff --git a/src/quo/components/settings/settings_item/view.cljs b/src/quo/components/settings/settings_item/view.cljs index a660c16e2ff..abbf035c878 100644 --- a/src/quo/components/settings/settings_item/view.cljs +++ b/src/quo/components/settings/settings_item/view.cljs @@ -12,51 +12,56 @@ [quo.components.tags.status-tags :as status-tags] [quo.foundations.colors :as colors] [quo.theme :as quo.theme] - [react-native.core :as rn] + [react-native.pure :as rn.pure] + [reagent.core :as reagent] [utils.i18n :as i18n])) (defn status-description [{:keys [description-props blur? theme]}] (let [{:keys [online? text]} description-props] - [rn/view {:style style/status-container} - [rn/view {:style (style/status-dot online? blur?)}] - [text/text + (rn.pure/view + {:style style/status-container} + (rn.pure/view {:style (style/status-dot online? blur?)}) + (text/text {:size :paragraph-2 :style (style/color blur? theme)} - (if online? (i18n/label :t/online-now) text)]])) + (if online? (i18n/label :t/online-now) text))))) (defn text-description [{:keys [description-props blur? theme]}] (let [{:keys [text icon]} description-props] - [rn/view + (rn.pure/view {:style (style/sub-container :center)} - [text/text + (text/text {:size :paragraph-2 :style (style/color blur? theme)} - text] + text) (when icon - [icon/icon icon + (icon/icon + icon (merge (style/color blur? theme) {:size 16 - :container-style {:margin-left 4}})])])) + :container-style {:margin-left 4}})))))) (defn description-component [{:keys [description] :as props}] (case description - :text [text-description props] - :text-plus-icon [text-description props] - :status [status-description props] + :text (text-description props) + :text-plus-icon (text-description props) + :status (status-description props) nil)) (defn image-component - [{:keys [image image-props description tag blur? theme]}] - [rn/view - {:style (style/image-container description tag image)} - (case image - :icon [icon/icon image-props (style/color blur? theme)] - :avatar [user-avatar/user-avatar image-props] - :icon-avatar [icon-avatar/icon-avatar image-props] - nil)]) + [{:keys [image image-props description tag blur?]}] + (let [theme (quo.theme/use-theme)] + (rn.pure/view + {:style (style/image-container description tag image)} + (reagent/as-element + (case image + :icon [icon/icon image-props (style/color blur? theme)] + :avatar [user-avatar/user-avatar image-props] + :icon-avatar [icon-avatar/icon-avatar image-props] + nil))))) (defn tag-component [{:keys [tag tag-props]}] @@ -77,46 +82,53 @@ (defn label-component [{:keys [label label-props blur? theme]}] - [rn/view {:accessibility-label :label-component} + (rn.pure/view + {:accessibility-label :label-component} (case label - :text [text/text + :text (text/text {:style (style/color blur? theme)} - label-props] - :color [rn/view - {:style (style/label-dot label-props)}] - :preview [preview-list/view {:type (:type label-props) :size :size-24} - (:data label-props)] - nil)]) + label-props) + :color (rn.pure/view + {:style (style/label-dot label-props)}) + :preview (reagent/as-element + [preview-list/view {:type (:type label-props) :size :size-24} + (:data label-props)]) + nil))) (defn action-component [{:keys [action action-props blur? theme]}] - [rn/view {:style {:margin-left 12}} + (rn.pure/view + {:style {:margin-left 12}} (case action - :arrow [icon/icon (or (:icon action-props) :i/chevron-right) (style/color blur? theme)] - :button [button/button - (merge action-props - {:type :outline - :size 24}) - (:button-text action-props)] - :selector [selectors/view action-props] - nil)]) + :arrow (icon/icon (or (:icon action-props) :i/chevron-right) + (style/color blur? theme)) + :button (reagent/as-element + [button/button + (merge action-props + {:type :outline + :size 24}) + (:button-text action-props)]) + :selector (reagent/as-element [selectors/view action-props]) + nil))) -(defn- internal-view +(defn view [{:keys [title on-press action-props accessibility-label blur? container-style] :as props}] - [rn/pressable + (rn.pure/pressable {:style (merge style/container container-style) :on-press on-press :accessibility-label accessibility-label} - [rn/view {:style (style/left-sub-container props)} - [image-component props] - [rn/view {:style (style/left-container (:image props))} - [text/text + (rn.pure/view + {:style (style/left-sub-container props)} + (rn.pure/func image-component props) + (rn.pure/view + {:style (style/left-container (:image props))} + (text/text {:weight :medium - :style {:color (when blur? colors/white)}} title] - [description-component props] - [tag-component props]]] - [rn/view {:style (style/sub-container (:alignment action-props))} - [label-component props] - [action-component props]]]) - -(def view (quo.theme/with-theme internal-view)) + :style {:color (when blur? colors/white)}} + title) + (description-component props))) + (reagent/as-element [tag-component props]) + (rn.pure/view + {:style (style/sub-container (:alignment action-props))} + (label-component props) + (action-component props)))) diff --git a/src/quo/components/share/share_qr_code/view.cljs b/src/quo/components/share/share_qr_code/view.cljs index f614cec2448..26f3f750731 100644 --- a/src/quo/components/share/share_qr_code/view.cljs +++ b/src/quo/components/share/share_qr_code/view.cljs @@ -71,18 +71,15 @@ (defn- network-colored-text [network-short-name] - [text/text {:style (style/network-short-name-text network-short-name)} - (str network-short-name ":")]) + (text/text + {:style (style/network-short-name-text network-short-name)} + (str network-short-name ":"))) (defn- wallet-multichain-colored-address [full-address] - (let [[networks address] (as-> full-address $ - (string/split $ ":") - [(butlast $) (last $)]) - ->network-hiccup-xf (map #(vector network-colored-text %))] - (as-> networks $ - (into [:<>] ->network-hiccup-xf $) - (conj $ address)))) + (let [[networks address] (let [parts (string/split full-address ":")] + [(butlast parts) (last parts)])] + (apply text/text (conj (mapv network-colored-text networks) address)))) (defn- profile-bottom [{:keys [component-width qr-data on-text-press on-text-long-press share-qr-type]}] @@ -111,7 +108,7 @@ {:width component-width :on-press on-text-press :on-long-press on-text-long-press} - [wallet-multichain-colored-address qr-data]] + (wallet-multichain-colored-address qr-data)] [button/button {:icon-only? true :type :grey @@ -144,7 +141,7 @@ [share-button {:on-press on-share-press}]] (when (#{:wallet-legacy :wallet-multichain} share-qr-type) [header props]) - [quo.theme/provider {:theme :light} + [quo.theme/provider :light [qr-code/view {:qr-image-uri qr-image-uri :size (style/qr-code-size component-width) @@ -195,7 +192,7 @@ [props] (reagent/with-let [component-width (reagent/atom nil) container-component [rn/view {:background-color style/overlay-color}]] - [quo.theme/provider {:theme :dark} + [quo.theme/provider :dark [rn/view {:accessibility-label :share-qr-code :style style/outer-container diff --git a/src/quo/components/tabs/tab/view.cljs b/src/quo/components/tabs/tab/view.cljs index ffce2e235d2..7acf7b03f8a 100644 --- a/src/quo/components/tabs/tab/view.cljs +++ b/src/quo/components/tabs/tab/view.cljs @@ -13,22 +13,22 @@ [{:keys [height width background-color disabled]}] ;; Do not add a view-box property, it'll cause an artifact where the SVG is ;; rendered slightly smaller than the proper width and height. - [svg/svg + (svg/svg {:width width :height height :fill background-color :fill-opacity (when disabled style/tab-background-opacity)} - [svg/path + (svg/path {:d "M 11.468 6.781 C 11.004 6.923 10.511 7 10 7 C 7.239 7 5 4.761 5 2 C 5 1.489 5.077 0.996 5.219 0.532 C 4.687 0.351 4.134 0.213 3.564 0.123 C 2.787 0 1.858 0 0 0 L 0 32 C 1.858 32 2.787 32 3.564 31.877 C 7.843 31.199 11.199 27.843 11.877 23.564 C 12 22.787 12 21.858 12 20 L 12 12 C 12 10.142 12 9.213 11.877 8.436 C 11.787 7.866 11.649 7.313 11.468 6.781 Z" - :clip-path "url(#clip0_5514_84289)"}] - [svg/defs - [svg/clip-path {:id "clip0_5514_84289"} - [svg/rect {:width width :height height :fill :none}]]]]) + :clip-path "url(#clip0_5514_84289)"}) + (svg/defs + (svg/clip-path {:id "clip0_5514_84289"} + (svg/rect {:width width :height height :fill :none}))))) (defn- content [{:keys [size label]} children] diff --git a/src/quo/components/wallet/address_text/view.cljs b/src/quo/components/wallet/address_text/view.cljs index fb8b8cd89ad..58121a9cad6 100644 --- a/src/quo/components/wallet/address_text/view.cljs +++ b/src/quo/components/wallet/address_text/view.cljs @@ -3,29 +3,32 @@ [quo.components.wallet.address-text.style :as style] [quo.foundations.colors :as colors] [quo.theme] + [react-native.pure :as rn.pure] [utils.address :as utils])) (defn- colored-network-text - [theme network] + [network theme] (let [{:keys [network-name short-name]} network] - [text/text + (text/text {:size :paragraph-2 :style {:color (colors/resolve-color network-name theme)}} - (str short-name ":")])) + (str short-name ":")))) -(defn- view-internal - [{:keys [networks address blur? theme format]}] - (let [network-text-xf (map #(colored-network-text theme %)) - address-text [text/text - {:size :paragraph-2 - ;; TODO: monospace font https://github.com/status-im/status-mobile/issues/17009 - :weight :monospace - :style (style/address-text format blur? theme)} - (if (= format :short) - (utils/get-short-wallet-address address) - address)]] - (as-> networks $ - (into [text/text] network-text-xf $) - (conj $ address-text)))) +(defn- view-pure + [{:keys [networks address blur? format]}] + (let [theme (quo.theme/use-theme) + address-text (text/text + {:size :paragraph-2 + ;; TODO: monospace font https://github.com/status-im/status-mobile/issues/17009 + :weight :monospace + :style (style/address-text format blur? theme)} + (if (= format :short) + (utils/get-short-wallet-address address) + address))] + (apply text/text + (-> (mapv #(colored-network-text % theme) networks) + (conj address-text))))) -(def view (quo.theme/with-theme view-internal)) +(defn view + [params] + (rn.pure/func view-pure params)) diff --git a/src/quo/components/wallet/network_link/view.cljs b/src/quo/components/wallet/network_link/view.cljs index b25d0e5e3e5..abe56737995 100644 --- a/src/quo/components/wallet/network_link/view.cljs +++ b/src/quo/components/wallet/network_link/view.cljs @@ -7,74 +7,75 @@ (defn link-linear [{:keys [source theme]}] - [svg/svg {:xmlns "http://www.w3.org/2000/svg" :width "73" :height "10" :fill :none} - [svg/path {:stroke (colors/resolve-color source theme) :d "M68 5H5"}] - [svg/circle - {:cx "68" - :cy "5" - :r "4" - :fill (colors/theme-colors colors/white colors/neutral-90 theme) - :stroke (colors/resolve-color source theme)}] - [svg/circle - {:cx "5" - :cy "5" - :r "4" - :fill (colors/theme-colors colors/white colors/neutral-90 theme) - :stroke (colors/resolve-color source theme)}]]) + (svg/svg {:xmlns "http://www.w3.org/2000/svg" :width "73" :height "10" :fill :none} + (svg/path {:stroke (colors/resolve-color source theme) :d "M68 5H5"}) + (svg/circle + {:cx "68" + :cy "5" + :r "4" + :fill (colors/theme-colors colors/white colors/neutral-90 theme) + :stroke (colors/resolve-color source theme)}) + (svg/circle + {:cx "5" + :cy "5" + :r "4" + :fill (colors/theme-colors colors/white colors/neutral-90 theme) + :stroke (colors/resolve-color source theme)}))) (defn link-1x [{:keys [source destination theme]}] - [svg/svg {:xmlns "http://www.w3.org/2000/svg" :width "73" :height "66" :fill :none} - [svg/path - {:stroke "url(#gradient)" :d "M68 5h-9.364c-11.046 0-20 8.954-20 20v16c0 11.046-8.955 20-20 20H5"}] - [svg/circle + (svg/svg + {:xmlns "http://www.w3.org/2000/svg" :width "73" :height "66" :fill :none} + (svg/path + {:stroke "url(#gradient)" :d "M68 5h-9.364c-11.046 0-20 8.954-20 20v16c0 11.046-8.955 20-20 20H5"}) + (svg/circle {:cx "68" :cy "5" :r "4" :fill (colors/theme-colors colors/white colors/neutral-90 theme) - :stroke (colors/resolve-color destination theme)}] - [svg/circle + :stroke (colors/resolve-color destination theme)}) + (svg/circle {:cx "5" :cy "61" :r "4" :fill (colors/theme-colors colors/white colors/neutral-90 theme) - :stroke (colors/resolve-color source theme)}] - [svg/defs - [svg/linear-gradient + :stroke (colors/resolve-color source theme)}) + (svg/defs + (svg/linear-gradient {:id "gradient" :x1 "72.271" :x2 "82.385" :y1 "5" :y2 "34.155" :gradientUnits "userSpaceOnUse"} - [svg/stop {:stopColor (colors/resolve-color destination theme)}] - [svg/stop {:offset "1" :stopColor (colors/resolve-color source theme)}]]]]) + (svg/stop {:stopColor (colors/resolve-color destination theme)}) + (svg/stop {:offset "1" :stopColor (colors/resolve-color source theme)}))))) (defn link-2x [{:keys [source destination theme]}] - [svg/svg + (svg/svg {:width "73" :height "122" :viewBox "0 0 73 122" :fill "none" :xmlns "http://www.w3.org/2000/svg"} - [svg/path + (svg/path {:d "M67.9999 5L58.6356 5C47.5899 5 38.6356 13.9543 38.6356 25L38.6356 97C38.6356 108.046 29.6813 117 18.6356 117L5.00006 117" - :stroke "url(#gradient)"}] - [svg/circle + :stroke "url(#gradient)"}) + (svg/circle {:cx "68" :cy "5" :r "4" :fill (colors/theme-colors colors/white colors/neutral-90 theme) - :stroke (colors/resolve-color destination theme)}] - [svg/circle + :stroke (colors/resolve-color destination theme)}) + (svg/circle {:cx "5" :cy "117" :r "4" :fill (colors/theme-colors colors/white colors/neutral-90 theme) - :stroke (colors/resolve-color source theme)}] - [svg/defs - [svg/linear-gradient + :stroke (colors/resolve-color source theme)}) + (svg/defs + (svg/linear-gradient {:id "gradient" :x1 "72.2711" :y1 "5.00001" :x2 "102.867" :y2 "49.0993" :gradientUnits "userSpaceOnUse"} - [svg/stop {:stop-color (colors/resolve-color destination theme)}] - [svg/stop {:offset "1" :stop-color (colors/resolve-color source theme)}]]]]) + (svg/stop {:stop-color (colors/resolve-color destination theme)}) + (svg/stop {:offset "1" :stop-color (colors/resolve-color source theme)}))))) (defn- view-internal [{:keys [shape container-style] :as props}] diff --git a/src/quo/components/wallet/wallet_activity/view.cljs b/src/quo/components/wallet/wallet_activity/view.cljs index a63fbc49c67..7a49c86cb44 100644 --- a/src/quo/components/wallet/wallet_activity/view.cljs +++ b/src/quo/components/wallet/wallet_activity/view.cljs @@ -11,13 +11,13 @@ [utils.i18n :as i18n])) (def transaction-translation - {:receive [i18n/label :t/receive] - :send [i18n/label :t/send] - :swap [i18n/label :t/swap] - :bridge [i18n/label :t/bridge] - :buy [i18n/label :t/buy] - :destroy [i18n/label :t/destroy] - :mint [i18n/label :t/mint]}) + {:receive (i18n/label :t/receive) + :send (i18n/label :t/send) + :swap (i18n/label :t/swap) + :bridge (i18n/label :t/bridge) + :buy (i18n/label :t/buy) + :destroy (i18n/label :t/destroy) + :mint (i18n/label :t/mint)}) (def transaction-icon {:receive :i/receive @@ -49,7 +49,7 @@ {:weight :semi-bold :size :paragraph-1 :style (style/transaction-header theme)} - (transaction transaction-translation)] + (get transaction-translation transaction)] (when (> counter 1) [rn/view (style/transaction-counter-container theme blur?) [text/text diff --git a/src/quo/components/wallet/wallet_overview/view.cljs b/src/quo/components/wallet/wallet_overview/view.cljs index ce62fcc98c2..b9d62a411a8 100644 --- a/src/quo/components/wallet/wallet_overview/view.cljs +++ b/src/quo/components/wallet/wallet_overview/view.cljs @@ -102,7 +102,7 @@ :size :paragraph-2 :style {:color (style/color-text-paragraph theme) :margin-right 8}} - (time-frame time-frames)] + (get time-frames time-frame)] (when (and (= state :default) (not= metrics :none)) [view-metrics {:metrics metrics diff --git a/src/quo/foundations/customization_colors.cljs b/src/quo/foundations/customization_colors.cljs index cb6c822a94d..84820ac9b40 100644 --- a/src/quo/foundations/customization_colors.cljs +++ b/src/quo/foundations/customization_colors.cljs @@ -1,7 +1,7 @@ (ns quo.foundations.customization-colors (:require [quo.foundations.colors :as colors] - [react-native.core :as rn])) + [react-native.pure :as rn.pure])) (defn get-overlay-color [theme pressed? customization-color] @@ -12,11 +12,11 @@ (defn overlay [{:keys [theme pressed? customization-color border-radius]}] - [rn/view + (rn.pure/view {:position :absolute :top 0 :left 0 :right 0 :bottom 0 :border-radius border-radius - :background-color (get-overlay-color theme pressed? customization-color)}]) + :background-color (get-overlay-color theme pressed? customization-color)})) diff --git a/src/quo/theme.cljs b/src/quo/theme.cljs index c92091d6b71..bb8b4f07910 100644 --- a/src/quo/theme.cljs +++ b/src/quo/theme.cljs @@ -42,16 +42,15 @@ (defn use-theme "A hook that returns the current theme context." [] - (utils.transforms/js->clj (rn/use-context theme-context))) + (keyword (rn/use-context theme-context))) (defn use-theme-value [] - (keyword (:theme (use-theme)))) + (use-theme)) (defn ^:private f-with-theme [component props & args] - (let [theme (-> (use-theme) :theme keyword)] - (into [component (assoc props :theme theme)] args))) + (into [component (assoc props :theme (use-theme))] args)) (defn with-theme "Create a functional component that assoc `:theme` into the first arg of diff --git a/src/react_native/blur.cljs b/src/react_native/blur.cljs index cad23cafb23..cc3184ad7ec 100644 --- a/src/react_native/blur.cljs +++ b/src/react_native/blur.cljs @@ -3,8 +3,10 @@ ["@react-native-community/blur" :as blur] [react-native.core :as rn] [react-native.platform :as platform] + [react-native.pure :as rn.pure] [reagent.core :as reagent])) +(def view-pure (rn.pure/get-create-element-fn (.-BlurView blur))) (def view (reagent/adapt-react-class (.-BlurView blur))) ;; blur view is currently not working correctly on Android. diff --git a/src/react_native/fast_image.cljs b/src/react_native/fast_image.cljs index 995b3c332c3..e1377cb83f2 100644 --- a/src/react_native/fast_image.cljs +++ b/src/react_native/fast_image.cljs @@ -1,40 +1,36 @@ (ns react-native.fast-image (:require ["react-native-fast-image" :as FastImage] - [react-native.core :as rn] - [reagent.core :as reagent])) + [react-native.pure :as rn.pure])) -(def fast-image-class (reagent/adapt-react-class ^js FastImage)) +(def fast-image-class (rn.pure/get-create-element-fn FastImage)) -(defn placeholder - [style child] - [rn/view {:style (merge style {:flex 1 :justify-content :center :align-items :center})} - child]) +(defn fast-image-pure + [{:keys [source] :as props}] + (let [[loaded? set-loaded] (rn.pure/use-state false) + [error? set-error] (rn.pure/use-state false)] + (fast-image-class + (merge + props + {:source (if (string? source) + {:uri source + :priority :high} + source) + :on-error (fn [e] + (when-let [on-error (:on-error props)] + (on-error e)) + (set-error true)) + :on-load (fn [e] + (when-let [on-load (:on-load props)] + (on-load e)) + (set-loaded true) + (set-error false))}) + (when (or error? (not loaded?)) + (rn.pure/view {:style (merge (:style props) + {:flex 1 :justify-content :center :align-items :center})} + (if error? + (rn.pure/text "X") + (when-not loaded? + (rn.pure/activity-indicator {:animating true})))))))) -(defn fast-image - [_] - (let [loaded? (reagent/atom false) - error? (reagent/atom false)] - (fn [{:keys [source] :as props}] - [fast-image-class - (merge - props - {:source (if (string? source) - {:uri source - :priority :high} - source) - :on-error (fn [e] - (when-let [on-error (:on-error props)] - (on-error e)) - (reset! error? true)) - :on-load (fn [e] - (when-let [on-load (:on-load props)] - (on-load e)) - (reset! loaded? true) - (reset! error? false))}) - (when (or @error? (not @loaded?)) - [placeholder (:style props) - (if @error? - [rn/text "X"] - (when-not @loaded? - [rn/activity-indicator {:animating true}]))])]))) +(defn fast-image [props] (rn.pure/func fast-image-pure props)) diff --git a/src/react_native/pure.cljs b/src/react_native/pure.cljs new file mode 100644 index 00000000000..649ca762610 --- /dev/null +++ b/src/react_native/pure.cljs @@ -0,0 +1,55 @@ +(ns react-native.pure + (:require ["react" :refer (Fragment useState createElement)] + ["react-native" :refer + (ActivityIndicator + View + Text + TextInput + SafeAreaView + TouchableHighlight + TouchableOpacity + TouchableWithoutFeedback + FlatList + Pressable + FlatList + Image)] + [reagent.impl.template :as reagent.template])) + +(def use-state useState) + +(defn get-create-element-fn + [type] + (fn [& children] + (let [props (first children)] + (if (map? props) + (apply createElement type (reagent.template/convert-prop-value props) (rest children)) + (apply createElement type nil children))))) + +(def view (get-create-element-fn View)) +(def text (get-create-element-fn Text)) +(def text-input (get-create-element-fn TextInput)) +(def safe-area (get-create-element-fn SafeAreaView)) +(def touchable (get-create-element-fn TouchableHighlight)) +(def touchable-opacity (get-create-element-fn TouchableOpacity)) +(def touchable-without-feedback (get-create-element-fn TouchableWithoutFeedback)) +(def fragment (get-create-element-fn Fragment)) +(def pressable (get-create-element-fn Pressable)) +(def image-element (get-create-element-fn Image)) +(def activity-indicator (get-create-element-fn ActivityIndicator)) + +(defn image + [{:keys [source] :as props}] + (image-element + (if (string? source) + ;;why are we doing this? + (assoc props :source {:uri source}) + props))) + +(defn func + [component-fn & props] + ;;idk if it's ok to pass props like this, time will show + (createElement #(apply component-fn props) nil)) + +(defn flat-list + [props] + (createElement FlatList props)) diff --git a/src/react_native/reanimated.cljs b/src/react_native/reanimated.cljs index 3c045d97518..0fffa24a5f2 100644 --- a/src/react_native/reanimated.cljs +++ b/src/react_native/reanimated.cljs @@ -24,6 +24,7 @@ ["react-native-redash" :refer (withPause)] [oops.core :as oops] [react-native.flat-list :as rn-flat-list] + [react-native.pure :as rn.pure] [reagent.core :as reagent] [utils.transforms :as transforms] [utils.worklets.core :as worklets.core])) @@ -41,6 +42,7 @@ (def create-animated-component (comp reagent/adapt-react-class (.-createAnimatedComponent reanimated))) (def ^:private view* (reagent/adapt-react-class (.-View reanimated))) +(def view-pure (rn.pure/get-create-element-fn (.-View reanimated))) (defn view [] diff --git a/src/react_native/svg.cljs b/src/react_native/svg.cljs index e9397c2d873..05e3f38ca5b 100644 --- a/src/react_native/svg.cljs +++ b/src/react_native/svg.cljs @@ -1,16 +1,16 @@ (ns react-native.svg (:require ["react-native-svg" :as Svg] - [reagent.core :as reagent])) + [react-native.pure :as rn.pure])) -(def svg (reagent/adapt-react-class Svg/default)) -(def path (reagent/adapt-react-class Svg/Path)) -(def rect (reagent/adapt-react-class Svg/Rect)) -(def clip-path (reagent/adapt-react-class Svg/ClipPath)) -(def defs (reagent/adapt-react-class Svg/Defs)) -(def circle (reagent/adapt-react-class Svg/Circle)) -(def svg-xml (reagent/adapt-react-class Svg/SvgXml)) -(def svg-uri (reagent/adapt-react-class Svg/SvgUri)) -(def g (reagent/adapt-react-class Svg/G)) -(def linear-gradient (reagent/adapt-react-class Svg/LinearGradient)) -(def stop (reagent/adapt-react-class Svg/Stop)) +(def svg (rn.pure/get-create-element-fn Svg/default)) +(def path (rn.pure/get-create-element-fn Svg/Path)) +(def rect (rn.pure/get-create-element-fn Svg/Rect)) +(def clippath (rn.pure/get-create-element-fn Svg/ClipPath)) +(def defs (rn.pure/get-create-element-fn Svg/Defs)) +(def circle (rn.pure/get-create-element-fn Svg/Circle)) +(def svg-xml (rn.pure/get-create-element-fn Svg/SvgXml)) +(def svg-uri (rn.pure/get-create-element-fn Svg/SvgUri)) +(def g (rn.pure/get-create-element-fn Svg/G)) +(def linear-gradient (rn.pure/get-create-element-fn Svg/LinearGradient)) +(def stop (rn.pure/get-create-element-fn Svg/Stop)) diff --git a/src/status_im/common/scan_qr_code/view.cljs b/src/status_im/common/scan_qr_code/view.cljs index 5ee2734c23e..4d028546058 100644 --- a/src/status_im/common/scan_qr_code/view.cljs +++ b/src/status_im/common/scan_qr_code/view.cljs @@ -237,7 +237,7 @@ [scan-qr-code-tab @qr-view-finder (when subtitle true)] [rn/view {:style style/flex-spacer}] (when show-camera? - [quo.theme/provider {:theme :light} + [quo.theme/provider :light [quo/button {:icon-only? true :type :grey diff --git a/src/status_im/contexts/communities/home/view.cljs b/src/status_im/contexts/communities/home/view.cljs index 021eb3cbf0f..08f8550900e 100644 --- a/src/status_im/contexts/communities/home/view.cljs +++ b/src/status_im/contexts/communities/home/view.cljs @@ -16,7 +16,8 @@ [utils.debounce :as debounce] [utils.i18n :as i18n] [utils.number] - [utils.re-frame :as rf])) + [utils.re-frame :as rf] + [react-native.pure :as rn.pure])) (defn item-render [{:keys [id] :as item}] @@ -46,11 +47,11 @@ [theme] {:joined {:title (i18n/label :t/no-communities) - :description [:<> - [rn/text {:style {:text-decoration-line :line-through}} - (i18n/label :t/no-communities-description-strikethrough)] + :description (rn.pure/text + (rn.pure/text {:style {:text-decoration-line :line-through}} + (i18n/label :t/no-communities-description-strikethrough)) " " - (i18n/label :t/no-communities-description)] + (i18n/label :t/no-communities-description)) :image (resources/get-themed-image :no-communities theme)} :pending {:title (i18n/label :t/no-pending-communities) diff --git a/src/status_im/contexts/onboarding/intro/view.cljs b/src/status_im/contexts/onboarding/intro/view.cljs index e9bc1f07379..52a5caecbbc 100644 --- a/src/status_im/contexts/onboarding/intro/view.cljs +++ b/src/status_im/contexts/onboarding/intro/view.cljs @@ -33,21 +33,21 @@ 1000)) :heading (i18n/label :t/new-to-status) :accessibility-label :new-to-status-button}} - [quo/text + (quo/text {:size :paragraph-2 :weight :regular :style style/plain-text} - (i18n/label :t/you-already-use-status)] - [quo/text {:style style/text-container} - [quo/text - {:size :paragraph-2 - :weight :regular - :style style/plain-text} - (i18n/label :t/by-continuing-you-accept)] - [quo/text - {:on-press #(debounce/dispatch-and-chill [:open-modal :privacy-policy] 1000) - :size :paragraph-2 - :weight :regular - :style style/highlighted-text} - (i18n/label :t/terms-of-service)]]] + (i18n/label :t/you-already-use-status)) + (quo/text {:style style/text-container} + (quo/text + {:size :paragraph-2 + :weight :regular + :style style/plain-text} + (i18n/label :t/by-continuing-you-accept)) + (quo/text + {:on-press #(debounce/dispatch-and-chill [:open-modal :privacy-policy] 1000) + :size :paragraph-2 + :weight :regular + :style style/highlighted-text} + (i18n/label :t/terms-of-service)))] [overlay/view]]) diff --git a/src/status_im/contexts/preview/quo/drawers/drawer_buttons.cljs b/src/status_im/contexts/preview/quo/drawers/drawer_buttons.cljs index a9441fcdae5..b8845ba32fd 100644 --- a/src/status_im/contexts/preview/quo/drawers/drawer_buttons.cljs +++ b/src/status_im/contexts/preview/quo/drawers/drawer_buttons.cljs @@ -15,22 +15,22 @@ (defn text-with-link [] - [quo/text + (quo/text {:style {:flex 1 :flex-wrap :wrap}} - [quo/text + (quo/text {:size :paragraph-2 :style {:flex 1 :color (colors/alpha colors/white 0.7)} :weight :semi-bold} - "By continuing you accept our "] - [quo/text + "By continuing you accept our ") + (quo/text {:on-press #(js/alert "Terms of use clicked") :size :paragraph-2 :style {:flex 1 :color colors/white} :weight :semi-bold} - "Terms of Use"]]) + "Terms of Use"))) (defn view [] @@ -48,4 +48,4 @@ :bottom-card {:on-press #(js/alert "bottom card clicked") :heading (:bottom-heading @state)}} (:top-sub-heading @state) - [text-with-link]]]))) + (text-with-link)]]))) diff --git a/src/status_im/contexts/preview/quo/notifications/activity_logs.cljs b/src/status_im/contexts/preview/quo/notifications/activity_logs.cljs index e4602f3564a..555f37e8047 100644 --- a/src/status_im/contexts/preview/quo/notifications/activity_logs.cljs +++ b/src/status_im/contexts/preview/quo/notifications/activity_logs.cljs @@ -173,7 +173,7 @@ {:flex 1 :padding 16} [preview/customizer state descriptor]] - [quo.theme/provider {:theme :dark} + [quo.theme/provider :dark [rn/view {:background-color colors/neutral-90 :flex-direction :row diff --git a/src/status_im/contexts/profile/settings/header/header_shape.cljs b/src/status_im/contexts/profile/settings/header/header_shape.cljs index 71322e324b6..e00dced0a1a 100644 --- a/src/status_im/contexts/profile/settings/header/header_shape.cljs +++ b/src/status_im/contexts/profile/settings/header/header_shape.cljs @@ -1,36 +1,40 @@ (ns status-im.contexts.profile.settings.header.header-shape (:require [quo.foundations.colors :as colors] - [react-native.core :as rn] + [react-native.pure :as rn.pure] [react-native.reanimated :as reanimated] [react-native.svg :as svg] + [reagent.core :as reagent] [status-im.contexts.profile.settings.header.style :as style])) (defn left-radius [background-color] - [svg/svg {:width "20" :height "20" :viewBox "0 0 20 20" :fill "none"} - [svg/path + (svg/svg + {:width "20" :height "20" :viewBox "0 0 20 20" :fill "none"} + (svg/path {:d "M20 0C7 2 0 10 0 20V0H15Z" - :fill background-color}]]) + :fill background-color}))) (defn right-radius [background-color] - [svg/svg {:width "20" :height "21" :viewBox "0 0 20 21" :fill "none"} - [svg/path + (svg/svg + {:width "20" :height "21" :viewBox "0 0 20 21" :fill "none"} + (svg/path {:d "M20 20V0H0C11 0 20 9 20 20Z" - :fill background-color}]]) + :fill background-color}))) -(defn f-view +(defn view-pure [{:keys [scroll-y customization-color theme]}] (let [background-color (colors/resolve-color customization-color theme 40) opacity-animation (reanimated/interpolate scroll-y [0 45 50] [1 1 0])] - [:<> - [rn/view {:style (style/header-middle-shape background-color)}] - [reanimated/view {:style (style/radius-container opacity-animation)} - [left-radius background-color] - [right-radius background-color]]])) + (rn.pure/fragment + (rn.pure/view {:style (style/header-middle-shape background-color)}) + (reagent/as-element + [reanimated/view {:style (style/radius-container opacity-animation)} + (left-radius background-color) + (right-radius background-color)])))) (defn view [props] - [:f> f-view props]) + (rn.pure/func view-pure props)) diff --git a/src/status_im/contexts/profile/settings/header/view.cljs b/src/status_im/contexts/profile/settings/header/view.cljs index 07a4fe597c5..1918c7490ee 100644 --- a/src/status_im/contexts/profile/settings/header/view.cljs +++ b/src/status_im/contexts/profile/settings/header/view.cljs @@ -2,7 +2,8 @@ (:require [clojure.string :as string] [quo.core :as quo] [quo.theme :as quo.theme] - [react-native.core :as rn] + [react-native.pure :as rn.pure] + [reagent.core :as reagent] [status-im.contexts.profile.settings.header.avatar :as header.avatar] [status-im.contexts.profile.settings.header.header-shape :as header.shape] [status-im.contexts.profile.settings.header.style :as style] @@ -11,33 +12,38 @@ [status-im.contexts.profile.utils :as profile.utils] [utils.re-frame :as rf])) -(defn- f-view - [{:keys [theme scroll-y]}] - (let [{:keys [public-key emoji-hash] :as profile} (rf/sub [:profile/profile-with-image]) - online? (rf/sub [:visibility-status-updates/online? - public-key]) - status (rf/sub +(defn- view-pure + [{:keys [scroll-y]}] + (let [theme (quo.theme/use-theme) + {:keys [public-key emoji-hash] :as profile} (rf/use-subscription [:profile/profile-with-image]) + online? (rf/use-subscription + [:visibility-status-updates/online? + public-key]) + status (rf/use-subscription [:visibility-status-updates/visibility-status-update public-key]) - customization-color (rf/sub [:profile/customization-color]) + customization-color (rf/use-subscription [:profile/customization-color]) full-name (profile.utils/displayed-name profile) profile-picture (profile.utils/photo profile) emoji-string (string/join emoji-hash) {:keys [status-title status-icon]} (header.utils/visibility-status-type-data status)] - [:<> - [header.shape/view + (rn.pure/fragment + (header.shape/view {:scroll-y scroll-y :customization-color customization-color - :theme theme}] - [rn/view {:style style/avatar-row-wrapper} - [header.avatar/view - {:scroll-y scroll-y - :display-name full-name - :online? online? - :customization-color customization-color - :profile-picture profile-picture}] - [rn/view {:style {:margin-bottom 4}} - [quo/dropdown + :theme theme}) + (rn.pure/view + {:style style/avatar-row-wrapper} + (reagent/as-element + [header.avatar/view + {:scroll-y scroll-y + :display-name full-name + :online? online? + :customization-color customization-color + :profile-picture profile-picture}]) + (rn.pure/view + {:style {:margin-bottom 4}} + (quo/dropdown {:background :blur :size :size-32 :type :outline @@ -48,11 +54,14 @@ {:shell? true :theme :dark :content (fn [] [visibility-sheet/view])}])} - status-title]]] - [quo/text-combinations - {:title-accessibility-label :username - :container-style style/title-container - :emoji-hash emoji-string - :title full-name}]])) + status-title))) + (reagent/as-element + [quo/text-combinations + {:title-accessibility-label :username + :container-style style/title-container + :emoji-hash emoji-string + :title full-name}])))) -(def view (quo.theme/with-theme f-view)) +(defn view + [params] + (rn.pure/func view-pure params)) diff --git a/src/status_im/contexts/profile/settings/list_items.cljs b/src/status_im/contexts/profile/settings/list_items.cljs index 8be148d89a0..b9f223a0f36 100644 --- a/src/status_im/contexts/profile/settings/list_items.cljs +++ b/src/status_im/contexts/profile/settings/list_items.cljs @@ -5,7 +5,8 @@ [utils.re-frame :as rf])) (def items - [[{:title (i18n/label :t/edit-profile) + (array + [{:title (i18n/label :t/edit-profile) :on-press #(rf/dispatch [:open-modal :edit-profile]) :image-props :i/edit :image :icon @@ -102,4 +103,4 @@ :action :arrow} {:title (i18n/label :t/status-help) :on-press not-implemented/alert - :action :arrow}]]) + :action :arrow}])) diff --git a/src/status_im/contexts/profile/settings/view.cljs b/src/status_im/contexts/profile/settings/view.cljs index 7c49262479e..ae2382f03ac 100644 --- a/src/status_im/contexts/profile/settings/view.cljs +++ b/src/status_im/contexts/profile/settings/view.cljs @@ -2,7 +2,7 @@ (:require [oops.core :as oops] [quo.core :as quo] [quo.theme :as quo.theme] - [react-native.core :as rn] + [react-native.pure :as rn.pure] [react-native.reanimated :as reanimated] [react-native.safe-area :as safe-area] [status-im.common.not-implemented :as not-implemented] @@ -15,61 +15,61 @@ [utils.re-frame :as rf])) (defn- settings-item-view - [data] - [rf/delay-render - [quo/category - {:list-type :settings - :container-style {:padding-bottom 0} - :blur? true - :data data}]]) + [^js data] + (quo/category + {:list-type :settings + :container-style {:padding-bottom 0} + :blur? true + :data (.-item data)})) (defn scroll-handler - [event scroll-y] + [scroll-y event] (let [current-y (oops/oget event "nativeEvent.contentOffset.y")] (reanimated/set-shared-value scroll-y current-y))) (defn- footer - [logout-press] - [rf/delay-render - [rn/view {:style style/footer-container} - [quo/logout-button {:on-press logout-press}]]]) - -(defn- get-item-layout - [_ index] - #js {:length 100 :offset (* 100 index) :index index}) + [] + (rn.pure/view + {:style style/footer-container} + (quo/logout-button {:on-press #(rf/dispatch [:multiaccounts.logout.ui/logout-pressed])}))) (defn- settings-view - [theme] + [] (let [insets (safe-area/get-insets) - customization-color (rf/sub [:profile/customization-color]) + theme (quo.theme/use-theme) + customization-color (rf/use-subscription [:profile/customization-color]) scroll-y (reanimated/use-shared-value 0) - logout-press #(rf/dispatch [:multiaccounts.logout.ui/logout-pressed])] - [quo/overlay {:type :shell} - [rn/view + on-scroll (partial scroll-handler scroll-y) + header (partial settings.header/view {:scroll-y scroll-y}) + key-extractor #(:title (first %1))] + (quo/overlay + {:type :shell} + (rn.pure/view {:key :header :style (style/navigation-wrapper {:customization-color customization-color :inset (:top insets) :theme theme})} - [quo/page-nav + (quo/page-nav {:background :blur :icon-name :i/close :on-press #(rf/dispatch [:navigate-back]) :right-side [{:icon-name :i/multi-profile :on-press #(rf/dispatch [:open-modal :sign-in])} {:icon-name :i/qr-code :on-press #(debounce/dispatch-and-chill [:open-modal :share-shell] 1000)} - {:icon-name :i/share :on-press not-implemented/alert}]}]] - [rn/flat-list - {:key :list - :header [settings.header/view {:scroll-y scroll-y}] - :data settings.items/items - :shows-vertical-scroll-indicator false - :render-fn settings-item-view - :get-item-layout get-item-layout - :footer [footer logout-press] - :scroll-event-throttle 16 - :on-scroll #(scroll-handler % scroll-y) - :bounces false}] - [quo/floating-shell-button + {:icon-name :i/share :on-press not-implemented/alert}]})) + (rn.pure/flat-list + #js + {:key "settings-flat-list" + :keyExtractor key-extractor + :ListHeaderComponent header + :data settings.items/items + :showsVerticalScrollIndicator false + :renderItem settings-item-view + :ListFooterComponent footer + :scrollEventThrottle 16 + :onScroll on-scroll + :bounces false}) + (quo/floating-shell-button {:key :shell :jump-to {:on-press (fn [] @@ -78,10 +78,8 @@ :customization-color customization-color :label (i18n/label :t/jump-to)}} {:position :absolute - :bottom jump-to.constants/floating-shell-button-height}]])) - -(defn- internal-view - [props] - [:f> settings-view props]) + :bottom jump-to.constants/floating-shell-button-height})))) -(def view (quo.theme/with-theme internal-view)) +(defn view + [] + (rn.pure/func settings-view)) diff --git a/src/status_im/contexts/shell/jump_to/components/bottom_tabs/view.cljs b/src/status_im/contexts/shell/jump_to/components/bottom_tabs/view.cljs index 5ae0bffb4ed..026d14907cb 100644 --- a/src/status_im/contexts/shell/jump_to/components/bottom_tabs/view.cljs +++ b/src/status_im/contexts/shell/jump_to/components/bottom_tabs/view.cljs @@ -56,7 +56,7 @@ shared-values))] (utils/load-stack @state/selected-stack-id) (reanimated/set-shared-value (:pass-through? shared-values) pass-through?) - [quo.theme/provider {:theme :dark} + [quo.theme/provider :dark [reanimated/view {:style (style/bottom-tabs-container pass-through? (:bottom-tabs-height shared-values))} (when pass-through? diff --git a/src/status_im/contexts/shell/jump_to/components/jump_to_screen/view.cljs b/src/status_im/contexts/shell/jump_to/components/jump_to_screen/view.cljs index 97f7bff559c..cc95b287326 100644 --- a/src/status_im/contexts/shell/jump_to/components/jump_to_screen/view.cljs +++ b/src/status_im/contexts/shell/jump_to/components/jump_to_screen/view.cljs @@ -92,7 +92,7 @@ width (rf/sub [:dimensions/window-width]) top (safe-area/get-top) shell-margin (/ (- width (* 2 shell.constants/switcher-card-size)) 3)] - [theme/provider {:theme :dark} + [theme/provider :dark [rn/view {:style {:top 0 :left 0 diff --git a/src/status_im/navigation/view.cljs b/src/status_im/navigation/view.cljs index c63a449eae0..d17669b1727 100644 --- a/src/status_im/navigation/view.cljs +++ b/src/status_im/navigation/view.cljs @@ -63,7 +63,7 @@ background-color (or (get-in options [:layout :backgroundColor]) (when sheet? :transparent))] ^{:key (str "root" screen-key @reloader/cnt)} - [theme/provider {:theme (or theme user-theme)} + [theme/provider (or theme user-theme) [rn/view {:style (wrapped-screen-style insets background-color)} [inactive] (if sheet? @@ -83,7 +83,7 @@ insets (safe-area/get-insets) user-theme (theme/get-theme)] ^{:key (str "sheet" @reloader/cnt)} - [theme/provider {:theme (or theme user-theme)} + [theme/provider (or theme user-theme) [inactive] [rn/keyboard-avoiding-view {:style {:position :relative :flex 1} diff --git a/src/status_im/setup/dev.cljs b/src/status_im/setup/dev.cljs index f6790348002..db03372b015 100644 --- a/src/status_im/setup/dev.cljs +++ b/src/status_im/setup/dev.cljs @@ -2,6 +2,7 @@ (:require ["react-native" :refer (DevSettings LogBox)] [react-native.platform :as platform] + [reagent.impl.template :as reagent.template] [status-im.setup.schema :as schema] [utils.re-frame :as rf])) @@ -32,6 +33,216 @@ ;; team adds it to the ;; icon set it will be added to project. ;; 6. Setting a timer for a long period of time. Not sure why this error is happening +(set! + reagent.template/prop-name-cache + #js + {:class "className" + :for "htmlFor" + :charset "charSet" + :value "value" + :style "style" + :flex "flex" + :background-color "backgroundColor" + :flex-direction "flexDirection" + :position "position" + :overflow "overflow" + :top "top" + :bottom "bottom" + :left "left" + :right "right" + :on-layout "onLayout" + :blur-amount "blurAmount" + :blur-radius "blurRadius" + :blur-type "blurType" + :overlay-color "overlayColor" + :gesture "gesture" + :width "width" + :margin-left "marginLeft" + :padding-top "paddingTop" + :height "height" + :resize-mode "resizeMode" + :resize-method "resizeMethod" + :margin-top "marginTop" + :source "source" + :padding-horizontal "paddingHorizontal" + :font-family "fontFamily" + :font-size "fontSize" + :line-height "lineHeight" + :letter-spacing "letterSpacing" + :text-align "textAlign" + :color "color" + :margin-right "marginRight" + :border-radius "borderRadius" + :behavior "behavior" + :keyboardVerticalOffset "keyboardVerticalOffset" + :justify-content "justifyContent" + :margin-bottom "marginBottom" + :keyboard-should-persist-taps "keyboardShouldPersistTaps" + :disabled "disabled" + :accessibility-label "accessibilityLabel" + :on-press-in "onPressIn" + :on-press-out "onPressOut" + :on-press "onPress" + :on-long-press "onLongPress" + :align-items "alignItems" + :padding-right "paddingRight" + :border-width "borderWidth" + :padding-left "paddingLeft" + :border-color "borderColor" + :padding-bottom "paddingBottom" + :key "key" + :tint-color "tintColor" + :holes "holes" + :border-top-right-radius "borderTopRightRadius" + :border-bottom-left-radius "borderBottomLeftRadius" + :border-top-left-radius "borderTopLeftRadius" + :border-bottom-right-radius "borderBottomRightRadius" + :uri "uri" + :number-of-lines "numberOfLines" + :opacity "opacity" + :auto-complete "autoComplete" + :auto-capitalize "autoCapitalize" + :placeholder "placeholder" + :editable "editable" + :on-focus "onFocus" + :default-value "defaultValue" + :on-blur "onBlur" + :cursor-color "cursorColor" + :placeholder-text-color "placeholderTextColor" + :on-change-text "onChangeText" + :auto-focus "autoFocus" + :secure-text-entry "secureTextEntry" + :keyboard-appearance "keyboardAppearance" + :pointerEvents "pointerEvents" + :animating "animating" + :renderItem "renderItem" + :ref "ref" + :num-columns "numColumns" + :ListHeaderComponent "ListHeaderComponent" + :content-container-style "contentContainerStyle" + :keyExtractor "keyExtractor" + :column-wrapper-style "columnWrapperStyle" + :margin-horizontal "marginHorizontal" + :content-inset-adjustment-behavior "contentInsetAdjustmentBehavior" + :data "data" + :colors "colors" + :start "start" + :x "x" + :y "y" + :end "end" + :padding "padding" + :on-error "onError" + :on-load "onLoad" + :z-index "zIndex" + :test-ID "testID" + :on-scroll "onScroll" + :get-item-layout "getItemLayout" + :scroll-event-throttle "scrollEventThrottle" + :on-end-reached "onEndReached" + :padding-vertical "paddingVertical" + :underlay-color "underlayColor" + :flex-wrap "flexWrap" + :flex-shrink "flexShrink" + :monospace "monospace" + :ellipsize-mode "ellipsizeMode" + :shadow-offset "shadowOffset" + :shadow-color "shadowColor" + :elevation "elevation" + :shadow-opacity "shadowOpacity" + :shadow-radius "shadowRadius" + :pointer-events "pointerEvents" + :active-opacity "activeOpacity" + :hit-slop "hitSlop" + :max-width "maxWidth" + :icon-color "iconColor" + :display "display" + :flex-grow "flexGrow" + :d "d" + :fill "fill" + :viewBox "viewBox" + :transform "transform" + :scale "scale" + :stroke "stroke" + :stroke-width "strokeWidth" + :view-box "viewBox" + :gap "gap" + :accessible "accessible" + :keyboard-vertical-offset "keyboardVerticalOffset" + :scroll-indicator-insets "scrollIndicatorInsets" + :on-content-size-change "onContentSizeChange" + :render-data "renderData" + :theme "theme" + :context "context" + :in-pinned-view? "inPinnedView?" + :community-admin? "communityAdmin?" + :current-public-key "currentPublicKey" + :able-to-send-message? "ableToSendMessage?" + :message-pin-enabled "messagePinEnabled" + :community? "community?" + :group-admin? "groupAdmin?" + :group-chat "groupChat" + :public? "public?" + :chat-id "chatId" + :can-delete-message-for-everyone? "canDeleteMessageForEveryone?" + :space-keeper "spaceKeeper" + :keyboard-shown? "keyboardShown?" + :insets "insets" + :on-scroll-begin-drag "onScrollBeginDrag" + :ListFooterComponent "ListFooterComponent" + :on-momentum-scroll-end "onMomentumScrollEnd" + :on-momentum-scroll-begin "onMomentumScrollBegin" + :bounces "bounces" + :keyboard-dismiss-mode "keyboardDismissMode" + :scroll-enabled "scrollEnabled" + :on-viewable-items-changed "onViewableItemsChanged" + :inverted "inverted" + :on-scroll-to-index-failed "onScrollToIndexFailed" + :max-height "maxHeight" + :margin-vertical "marginVertical" + :text-transform "textTransform" + :align-self "alignSelf" + :mask-element "maskElement" + :cursor-position "cursorPosition" + :input-ref "inputRef" + :menu-items "menuItems" + :min-height "minHeight" + :max-length "maxLength" + :multiline "multiline" + :text-align-vertical "textAlignVertical" + :on-selection-change "onSelectionChange" + :on-selection "onSelection" + :max-font-size-multiplier "maxFontSizeMultiplier" + :snap-to-interval "snapToInterval" + :horizontal "horizontal" + :shows-horizontal-scroll-indicator "showsHorizontalScrollIndicator" + :on-clear "onClear" + :loading-message "loadingMessage" + :container-style "containerStyle" + :deceleration-rate "decelerationRate" + :ItemSeparatorComponent "ItemSeparatorComponent" + :native-ID "nativeID" + :customization-color "customizationColor" + :shows-vertical-scroll-indicator "showsVerticalScrollIndicator" + :ellipis-mode "ellipisMode" + :border-style "borderStyle" + :ignore-offset "ignoreOffset" + :important-for-accessibility "importantForAccessibility" + :return-key-type "returnKeyType" + :margin "margin" + :auto-complete-type "autoCompleteType" + :underline-color-android "underlineColorAndroid" + :clear-button-mode "clearButtonMode" + :on-submit-editing "onSubmitEditing" + :keyboard-type "keyboardType" + :auto-correct "autoCorrect" + :render-fn "renderFn" + :header "header" + :ListEmptyComponent "ListEmptyComponent" + :key-fn "keyFn" + :empty-component "emptyComponent" + :border-top-width "borderTopWidth" + :border-top-color "borderTopColor"}) + (defn setup [] diff --git a/src/test_helpers/component.cljs b/src/test_helpers/component.cljs index a093f994c31..5050b623c82 100644 --- a/src/test_helpers/component.cljs +++ b/src/test_helpers/component.cljs @@ -52,9 +52,13 @@ [component] (rtl/render (reagent/as-element component))) +(defn render-pure + [component] + (rtl/render component)) + (defn render-with-theme-provider [component theme] - (rtl/render (reagent/as-element [quo.theme/provider {:theme theme} component]))) + (rtl/render (reagent/as-element [quo.theme/provider theme component]))) (def unmount "Unmount rendered component. diff --git a/src/utils/re_frame.cljs b/src/utils/re_frame.cljs index c35b5b08ead..55ca6563356 100644 --- a/src/utils/re_frame.cljs +++ b/src/utils/re_frame.cljs @@ -1,6 +1,7 @@ (ns utils.re-frame (:require-macros utils.re-frame) (:require + ["react" :refer (useState useEffect)] [re-frame.core :as re-frame] [re-frame.interceptor :as interceptor] [reagent.core :as reagent] @@ -94,3 +95,12 @@ (def dispatch-sync re-frame/dispatch-sync) (def reg-event-fx re-frame/reg-event-fx) + +(defn use-subscription + [sub-vec] + (let [[state set-state] (useState)] + (useEffect (fn [] + (let [track (reagent/track! #(set-state @(re-frame/subscribe sub-vec)))] + #(reagent/dispose! track))) + #js []) + state)) From 0610fba8419d412cd7e9832f65e978d4d83f0c26 Mon Sep 17 00:00:00 2001 From: andrey Date: Fri, 26 Jan 2024 14:42:15 +0100 Subject: [PATCH 2/7] lint --- src/status_im/contexts/communities/home/view.cljs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/status_im/contexts/communities/home/view.cljs b/src/status_im/contexts/communities/home/view.cljs index 08f8550900e..eefeb011481 100644 --- a/src/status_im/contexts/communities/home/view.cljs +++ b/src/status_im/contexts/communities/home/view.cljs @@ -3,7 +3,7 @@ [oops.core :as oops] [quo.core :as quo] [quo.theme :as quo.theme] - [react-native.core :as rn] + [react-native.pure :as rn.pure] [react-native.reanimated :as reanimated] [status-im.common.home.banner.view :as common.banner] [status-im.common.home.empty-state.view :as common.empty-state] @@ -16,8 +16,7 @@ [utils.debounce :as debounce] [utils.i18n :as i18n] [utils.number] - [utils.re-frame :as rf] - [react-native.pure :as rn.pure])) + [utils.re-frame :as rf])) (defn item-render [{:keys [id] :as item}] From aebe12b64791c9f3db0522366acb8349d922e049 Mon Sep 17 00:00:00 2001 From: andrey Date: Mon, 29 Jan 2024 10:00:48 +0100 Subject: [PATCH 3/7] implement memo --- src/react_native/pure.cljs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/react_native/pure.cljs b/src/react_native/pure.cljs index 649ca762610..988c5e8f86d 100644 --- a/src/react_native/pure.cljs +++ b/src/react_native/pure.cljs @@ -1,5 +1,5 @@ (ns react-native.pure - (:require ["react" :refer (Fragment useState createElement)] + (:require ["react" :refer (Fragment useState createElement memo)] ["react-native" :refer (ActivityIndicator View @@ -45,10 +45,14 @@ (assoc props :source {:uri source}) props))) +(def memo-fn-cache (atom {})) + (defn func [component-fn & props] - ;;idk if it's ok to pass props like this, time will show - (createElement #(apply component-fn props) nil)) + (when-not (get @memo-fn-cache component-fn) + (swap! memo-fn-cache assoc component-fn (memo #(apply component-fn (.-props %)) + #(= (.-props %1) (.-props %2))))) + (createElement (get @memo-fn-cache component-fn) #js {:props props})) (defn flat-list [props] From cab0f4a2555f346388f402d60748e51fbe25eddb Mon Sep 17 00:00:00 2001 From: andrey Date: Mon, 29 Jan 2024 10:36:34 +0100 Subject: [PATCH 4/7] fixes --- src/quo/components/overlay/view.cljs | 28 +++++++++++++++---- .../components/profile/collectible/view.cljs | 12 ++++---- src/quo/components/tabs/tab/view.cljs | 5 ++-- src/quo/core.cljs | 1 + src/react_native/pure.cljs | 6 ++-- src/react_native/svg.cljs | 2 +- .../contexts/profile/settings/view.cljs | 2 +- 7 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/quo/components/overlay/view.cljs b/src/quo/components/overlay/view.cljs index 3aed465d0af..0975dceaf37 100644 --- a/src/quo/components/overlay/view.cljs +++ b/src/quo/components/overlay/view.cljs @@ -2,9 +2,10 @@ (:require [quo.components.overlay.style :as style] [react-native.blur :as blur] + [react-native.core :as rn] [react-native.pure :as rn.pure])) -(defn view +(defn view-pure [{:keys [type container-style]} & children] (rn.pure/view {:style (style/overlay-background type)} @@ -15,7 +16,24 @@ :blur-type :transparent :overlay-color :transparent :style style/container} - (rn.pure/view {:style (merge style/blur-container container-style)} - children)) - (rn.pure/view {:style (merge style/container container-style)} - children)))) + (apply rn.pure/view + {:style (merge style/blur-container container-style)} + children)) + (apply rn.pure/view + {:style (merge style/container container-style)} + children)))) + +(defn view + [{:keys [type container-style]} & children] + [rn/view {:style (style/overlay-background type)} + (if (= type :shell) + [blur/view + {:blur-amount 20 + :blur-radius 25 + :blur-type :transparent + :overlay-color :transparent + :style style/container} + [rn/view {:style (merge style/blur-container container-style)} + children]] + [rn/view {:style (merge style/container container-style)} + children])]) diff --git a/src/quo/components/profile/collectible/view.cljs b/src/quo/components/profile/collectible/view.cljs index 7260857e3a6..f8484836182 100644 --- a/src/quo/components/profile/collectible/view.cljs +++ b/src/quo/components/profile/collectible/view.cljs @@ -4,6 +4,7 @@ [quo.components.profile.collectible.style :as style] [react-native.core :as rn] [react-native.fast-image :as fast-image] + [react-native.pure :as rn.pure] [react-native.svg :as svg])) (defn remaining-tiles @@ -19,18 +20,19 @@ [{:keys [style size resource]}] (let [svg? (and (map? resource) (:svg? resource)) image-style (style/tile-style-by-size size)] - [rn/view {:style style} + (rn.pure/view + {:style style} (if svg? - [rn/view + (rn.pure/view {:style {:border-radius (:border-radius image-style) :overflow :hidden}} - [svg/svg-uri (assoc image-style :uri (:uri resource))]] - [fast-image/fast-image + (svg/svg-uri (assoc image-style :uri (:uri resource)))) + (fast-image/fast-image {:style image-style :source (if (string? resource) {:uri resource :priority :low} - resource)}])])) + resource)}))))) (defn two-tiles [{:keys [images size]}] diff --git a/src/quo/components/tabs/tab/view.cljs b/src/quo/components/tabs/tab/view.cljs index 7acf7b03f8a..1ceed1be522 100644 --- a/src/quo/components/tabs/tab/view.cljs +++ b/src/quo/components/tabs/tab/view.cljs @@ -27,8 +27,9 @@ 9.213 11.877 8.436 C 11.787 7.866 11.649 7.313 11.468 6.781 Z" :clip-path "url(#clip0_5514_84289)"}) (svg/defs - (svg/clip-path {:id "clip0_5514_84289"} - (svg/rect {:width width :height height :fill :none}))))) + (svg/clip-path + {:id "clip0_5514_84289"} + (svg/rect {:width width :height height :fill :none}))))) (defn- content [{:keys [size label]} children] diff --git a/src/quo/core.cljs b/src/quo/core.cljs index df7503f27a0..33d2327e84b 100644 --- a/src/quo/core.cljs +++ b/src/quo/core.cljs @@ -340,6 +340,7 @@ ;;;; Overlay (def overlay quo.components.overlay.view/view) +(def overlay-pure quo.components.overlay.view/view-pure) ;;;; Password (def tips quo.components.password.tips.view/view) diff --git a/src/react_native/pure.cljs b/src/react_native/pure.cljs index 988c5e8f86d..af65000634d 100644 --- a/src/react_native/pure.cljs +++ b/src/react_native/pure.cljs @@ -50,8 +50,10 @@ (defn func [component-fn & props] (when-not (get @memo-fn-cache component-fn) - (swap! memo-fn-cache assoc component-fn (memo #(apply component-fn (.-props %)) - #(= (.-props %1) (.-props %2))))) + (swap! memo-fn-cache assoc + component-fn + (memo #(apply component-fn (.-props %)) + #(= (.-props %1) (.-props %2))))) (createElement (get @memo-fn-cache component-fn) #js {:props props})) (defn flat-list diff --git a/src/react_native/svg.cljs b/src/react_native/svg.cljs index 05e3f38ca5b..19f575f6624 100644 --- a/src/react_native/svg.cljs +++ b/src/react_native/svg.cljs @@ -6,7 +6,7 @@ (def svg (rn.pure/get-create-element-fn Svg/default)) (def path (rn.pure/get-create-element-fn Svg/Path)) (def rect (rn.pure/get-create-element-fn Svg/Rect)) -(def clippath (rn.pure/get-create-element-fn Svg/ClipPath)) +(def clip-path (rn.pure/get-create-element-fn Svg/ClipPath)) (def defs (rn.pure/get-create-element-fn Svg/Defs)) (def circle (rn.pure/get-create-element-fn Svg/Circle)) (def svg-xml (rn.pure/get-create-element-fn Svg/SvgXml)) diff --git a/src/status_im/contexts/profile/settings/view.cljs b/src/status_im/contexts/profile/settings/view.cljs index ae2382f03ac..8617764635f 100644 --- a/src/status_im/contexts/profile/settings/view.cljs +++ b/src/status_im/contexts/profile/settings/view.cljs @@ -42,7 +42,7 @@ on-scroll (partial scroll-handler scroll-y) header (partial settings.header/view {:scroll-y scroll-y}) key-extractor #(:title (first %1))] - (quo/overlay + (quo/overlay-pure {:type :shell} (rn.pure/view {:key :header From 684e5053d0eb1de37c495a501f75fad889e660ba Mon Sep 17 00:00:00 2001 From: andrey Date: Mon, 29 Jan 2024 13:16:35 +0100 Subject: [PATCH 5/7] normalize text children --- src/quo/components/markdown/text.cljs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/quo/components/markdown/text.cljs b/src/quo/components/markdown/text.cljs index 309454ca4eb..653a94996a8 100644 --- a/src/quo/components/markdown/text.cljs +++ b/src/quo/components/markdown/text.cljs @@ -3,7 +3,8 @@ [quo.foundations.colors :as colors] [quo.foundations.typography :as typography] [quo.theme :as quo.theme] - [react-native.pure :as rn.pure])) + [react-native.pure :as rn.pure] + [reagent.core :as reagent])) (defn text-style [{:keys [size align weight style]} theme] @@ -29,10 +30,19 @@ :color (if (= (or theme (quo.theme/get-theme)) :dark) colors/white colors/neutral-100))))) +;NOTE this is temporary for cases when hiccup is still used, can be removed after moving away from +;reagent library +(defn normalize-children + [children] + (if (vector? (first children)) + (reagent/as-element (into [:<>] children)) + children)) + (defn text-pure [props children] - (let [theme (quo.theme/use-theme) - style (text-style props theme)] + (let [theme (quo.theme/use-theme) + style (text-style props theme) + children (normalize-children children)] (apply rn.pure/text (-> props (assoc :style style) From 3d8b72b8565515123a8d44843ec696b89b47beaa Mon Sep 17 00:00:00 2001 From: andrey Date: Mon, 29 Jan 2024 14:38:05 +0100 Subject: [PATCH 6/7] normalize text children --- src/quo/components/markdown/text.cljs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/quo/components/markdown/text.cljs b/src/quo/components/markdown/text.cljs index 653a94996a8..d7046729fd8 100644 --- a/src/quo/components/markdown/text.cljs +++ b/src/quo/components/markdown/text.cljs @@ -35,7 +35,7 @@ (defn normalize-children [children] (if (vector? (first children)) - (reagent/as-element (into [:<>] children)) + [(reagent/as-element (into [:<>] children))] children)) (defn text-pure From c950d849fb713458c722d677027d6d89c2047d4c Mon Sep 17 00:00:00 2001 From: andrey Date: Tue, 30 Jan 2024 12:57:37 +0100 Subject: [PATCH 7/7] normalize text children fix --- src/quo/components/markdown/text.cljs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/quo/components/markdown/text.cljs b/src/quo/components/markdown/text.cljs index d7046729fd8..707d282c7a8 100644 --- a/src/quo/components/markdown/text.cljs +++ b/src/quo/components/markdown/text.cljs @@ -34,7 +34,7 @@ ;reagent library (defn normalize-children [children] - (if (vector? (first children)) + (if (some vector? children) [(reagent/as-element (into [:<>] children))] children))