[#17393] feat: add new setting ui (#18118)

This commit is contained in:
Mohsen 2023-12-20 17:03:49 +03:00 committed by GitHub
parent 32cfd214ca
commit f631e1fe9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 309 additions and 76 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 714 B

After

Width:  |  Height:  |  Size: 609 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 873 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 579 B

View File

@ -2,6 +2,7 @@
(:require
[cljs.test :refer-macros [deftest is testing]]
[legacy.status-im.browser.core :as browser]
[utils.i18n :as i18n]
[utils.url :as url]))
(defn has-wrong-properties?
@ -35,7 +36,7 @@
:history-index 0
:history ["https://cryptokitties.co"]
:dapp? false
:name "Browser"}))
:name (i18n/label :t/browser)}))
"some properties of the browser are not correct")
(testing "then a second dapp"
@ -70,7 +71,7 @@
:history-index 0
:history ["https://cryptokitties.co"]
:dapp? false
:name "Browser"}))
:name (i18n/label :t/browser)}))
"some properties of the browser are not correct")
(is (nil? (browser/navigate-to-next-page result-open-existing))
"nothing should happen if user tries to navigate to next page")
@ -90,7 +91,7 @@
:history-index 1
:history ["https://cryptokitties.co" dapp1-url2]
:dapp? false
:name "Browser"}))
:name (i18n/label :t/browser)}))
"some properties of the browser are not correct")
(testing "then navigates to previous page"
@ -103,7 +104,7 @@
:history-index 0
:history ["https://cryptokitties.co" dapp1-url2]
:dapp? false
:name "Browser"}))
:name (i18n/label :t/browser)}))
"some properties of the browser are not correct")
(testing "then navigates to next page")
@ -116,5 +117,5 @@
:history-index 1
:history ["https://cryptokitties.co" dapp1-url2]
:dapp? false
:name "Browser"}))
:name (i18n/label :t/browser)}))
"some properties of the browser are not correct"))))))))))))

View File

@ -0,0 +1,31 @@
(ns quo.components.buttons.logout-button.component-spec
(:require
[quo.components.buttons.logout-button.view :as logout-button]
[test-helpers.component :as h]))
(h/describe "button tests"
(h/test "default render of logout button component"
(h/render [logout-button/view])
(h/is-truthy (h/get-by-label-text :log-out-button)))
(h/test "button on-press works"
(let [event (h/mock-fn)]
(h/render [logout-button/view
{:on-press event}])
(h/fire-event :press (h/get-by-label-text :log-out-button))
(h/was-called event)))
(h/test "button on-press disabled when disabled"
(let [event (h/mock-fn)]
(h/render [logout-button/view
{:on-press event
:disabled? true}])
(h/fire-event :press (h/get-by-label-text :log-out-button))
(h/was-not-called event)))
(h/test "button on-long-press works"
(let [event (h/mock-fn)]
(h/render [logout-button/view
{:on-long-press event}])
(h/fire-event :long-press (h/get-by-label-text :log-out-button))
(h/was-called event))))

View File

@ -0,0 +1,15 @@
(ns quo.components.buttons.logout-button.style
(:require
[quo.foundations.colors :as colors]))
(defn main
[{:keys [pressed? disabled?]}]
{:background-color (if pressed? colors/danger-50-opa-40 colors/danger-50-opa-30)
:border-radius 12
:height 40
:gap 4
:padding-right 3
:flex-direction :row
:justify-content :center
:align-items :center
:opacity (when disabled? 0.2)})

View File

@ -0,0 +1,34 @@
(ns quo.components.buttons.logout-button.view
(:require
[quo.components.buttons.logout-button.style :as style]
[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]
[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)]])))
(def view (quo.theme/with-theme view-internal))

View File

@ -12,11 +12,24 @@
:flex-direction :row})
(defn container
[sub-label disabled?]
{:border-radius 12
:height (if sub-label 56 48)
:opacity (when disabled? 0.3)
:margin-horizontal 8})
[{:keys [sub-label disabled? state customization-color blur? theme]}]
(cond-> {:border-radius 12
:margin-horizontal 8}
sub-label
(assoc :height 56)
(not sub-label)
(assoc :height 48)
disabled?
(assoc :opacity 0.3)
(= state :selected)
(assoc :background-color
(if blur?
colors/white-opa-5
(colors/resolve-color customization-color theme 5)))))
(defn row-container
[sub-label]

View File

@ -38,13 +38,22 @@
add-divider?
theme
accessibility-label
icon-color]}]
icon-color
no-icon-color?
state
customization-color
blur?]}]
[:<>
(when add-divider?
[divider theme])
[maybe-pressable disabled?
{:accessibility-label accessibility-label
:style (style/container sub-label disabled?)
:style (style/container {:sub-label sub-label
:disabled? disabled?
:state state
:customization-color customization-color
:blur? blur?
:theme theme})
:underlay-color (colors/theme-colors colors/neutral-5 colors/neutral-90 theme)
:on-press on-press}
[rn/view
@ -54,8 +63,9 @@
:accessible true
:style (style/left-icon sub-label)}
[icon/icon icon
{:color (or icon-color (get-icon-color danger? theme))
:size 20}]]
{:color (or icon-color (get-icon-color danger? theme))
:no-color no-icon-color?
:size 20}]]
[rn/view
{:style style/text-container}
[text/text
@ -72,7 +82,7 @@
:style {:color
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
sub-label])]
(when (or right-text right-icon)
(when (or right-text right-icon (= state :selected))
[rn/view {:style style/right-side-container}
(when right-text
[text/text
@ -87,6 +97,13 @@
:accessibility-label :right-icon-for-action}
[icon/icon right-icon
{:color (get-icon-color danger? theme)
:size 20}]])
(when (= state :selected)
[rn/view {:style style/right-icon}
[icon/icon :i/check
{:color (if blur?
colors/white
(colors/resolve-color customization-color theme))
:size 20}]])])]]])
(def ^:private action (quo.theme/with-theme action-internal))

View File

@ -11,7 +11,7 @@
(defn- view-internal
[{:keys [type size state background customization-color theme on-press icon-name icon? emoji?
accessibility-label]
accessibility-label no-icon-color?]
:or {type :grey
size :size-40
state :default
@ -58,6 +58,7 @@
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
@ -75,14 +76,15 @@
(def view
"Props:
- type: :outline |:grey (default) | :ghost | :customization
- size: :size-40 (default) | :size-32 | :size-24
- state: :default (default) | :active | :disabled
- emoji?: boolean
- icon?: boolean
- background: :blur | :photo (optional)
- icon-name: keyword
- on-press: function
- type: :outline |:grey (default) | :ghost | :customization
- size: :size-40 (default) | :size-32 | :size-24
- state: :default (default) | :active | :disabled
- emoji?: boolean
- icon?: boolean
- no-icon-color?: boolean
- background: :blur | :photo (optional)
- icon-name: keyword
- on-press: function
Child: string - used as label or emoji (for emoji only)"
(theme/with-theme view-internal))

View File

@ -8,8 +8,8 @@
[react-native.core :as rn]))
(defn- category-internal
[{:keys [label data blur? theme]}]
[rn/view {:style (style/container label)}
[{:keys [label data blur? container-style theme]}]
[rn/view {:style (merge (style/container label) container-style)}
(when label
[text/text
{:weight :medium

View File

@ -17,7 +17,7 @@
:background-color (if blur?
colors/white-opa-5
(colors/theme-colors colors/white colors/neutral-95 theme))
:border-width 1
:border-width (if blur? 0 1)
:border-color (if blur?
colors/white-opa-5
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))})

View File

@ -2,12 +2,12 @@
(:require
[quo.foundations.colors :as colors]))
(defn container
[{:keys [container-style]}]
(merge {:padding 12
:flex-direction :row
:justify-content :space-between}
container-style))
(def container
{:padding-horizontal 12
:padding-top 12
:padding-bottom 14
:flex-direction :row
:justify-content :space-between})
(defn left-sub-container
[{:keys [tag description]}]

View File

@ -101,9 +101,9 @@
nil)])
(defn- internal-view
[{:keys [title on-press action-props accessibility-label] :as props}]
[{:keys [title on-press action-props accessibility-label container-style] :as props}]
[rn/pressable
{:style (style/container props)
{:style (merge style/container container-style)
:on-press on-press
:accessibility-label accessibility-label}
[rn/view {:style (style/left-sub-container props)}

View File

@ -12,5 +12,6 @@
(def emoji-hash
{:margin-top 8
:letter-spacing 0.5
:letter-spacing 2
:font-size 13
:line-height 20.5})

View File

@ -59,8 +59,9 @@
description])
(when emoji-hash
[text/text
{:number-of-lines 1
:style style/emoji-hash}
{:number-of-lines 1
:accessibility-label :emoji-hash
:style style/emoji-hash}
emoji-hash])])
(def view (theme/with-theme view-internal))

View File

@ -14,6 +14,7 @@
quo.components.buttons.button.view
quo.components.buttons.composer-button.view
quo.components.buttons.dynamic-button.view
quo.components.buttons.logout-button.view
quo.components.buttons.predictive-keyboard.view
quo.components.buttons.slide-button.view
quo.components.buttons.wallet-button.view
@ -182,6 +183,7 @@
(def button quo.components.buttons.button.view/button)
(def composer-button quo.components.buttons.composer-button.view/view)
(def dynamic-button quo.components.buttons.dynamic-button.view/view)
(def logout-button quo.components.buttons.logout-button.view/view)
(def predictive-keyboard quo.components.buttons.predictive-keyboard.view/view)
(def slide-button quo.components.buttons.slide-button.view/view)
(def wallet-button quo.components.buttons.wallet-button.view/view)

View File

@ -6,6 +6,7 @@
[quo.components.browser.browser-input.component-spec]
[quo.components.buttons.button.component-spec]
[quo.components.buttons.composer-button.component-spec]
[quo.components.buttons.logout-button.component-spec]
[quo.components.buttons.predictive-keyboard.component-spec]
[quo.components.buttons.slide-button.component-spec]
[quo.components.buttons.wallet-button.component-spec]

View File

@ -33,7 +33,7 @@
:unread-indicator/new :mention
nil)]
[quo/top-nav
{:avatar-on-press #(rf/dispatch [:navigate-to :my-profile])
{:avatar-on-press #(rf/dispatch [:open-modal :settings])
:scan-on-press #(js/alert "to be implemented")
:activity-center-on-press #(rf/dispatch [:activity-center/open])
:qr-code-on-press #(dispatch-and-chill [:open-modal :share-shell] 1000)

View File

@ -13,7 +13,7 @@
[{:keys [scroll-y full-name online? profile-picture customization-color]}]
(let [image-scale-animation (reanimated/interpolate scroll-y
scroll-animation-input-range
[1 0.5]
[1 0.4]
header-extrapolation-option)
image-top-margin-animation (reanimated/interpolate scroll-y
scroll-animation-input-range

View File

@ -0,0 +1,21 @@
(ns status-im.contexts.profile.settings.header.utils
(:require [status-im.constants :as constants]
[utils.i18n :as i18n]))
(defn visibility-status-type-data
[{:keys [status-type]}]
(condp = status-type
constants/visibility-status-automatic
{:status-title (i18n/label :t/status-automatic)
:status-icon :i/automatic}
constants/visibility-status-always-online
{:status-title (i18n/label :t/online)
:status-icon :i/online}
constants/visibility-status-inactive
{:status-title (i18n/label :t/offline)
:status-icon :i/offline}
{:status-title (i18n/label :t/offline)
:status-icon :i/offline}))

View File

@ -3,12 +3,12 @@
[quo.core :as quo]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[status-im.common.not-implemented :as not-implemented]
[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]
[status-im.contexts.profile.settings.header.utils :as header.utils]
[status-im.contexts.profile.settings.visibility-sheet.view :as visibility-sheet]
[status-im.contexts.profile.utils :as profile.utils]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn- f-view
@ -16,10 +16,14 @@
(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
[:visibility-status-updates/visibility-status-update
public-key])
customization-color (rf/sub [:profile/customization-color])
full-name (profile.utils/displayed-name profile)
profile-picture (profile.utils/photo profile)
emoji-string (string/join emoji-hash)]
emoji-string (string/join emoji-hash)
{:keys [status-title status-icon]} (header.utils/visibility-status-type-data status)]
[:<>
[header.shape/view
{:scroll-y scroll-y
@ -34,16 +38,21 @@
:profile-picture profile-picture}]
[rn/view {:style {:margin-bottom 4}}
[quo/dropdown
{:background :blur
:size :size-32
:type :outline
:icon? true
:icon-name :i/online
:on-press not-implemented/alert}
(i18n/label :t/online)]]]
{:background :blur
:size :size-32
:type :outline
:icon? true
:no-icon-color? true
:icon-name status-icon
:on-press #(rf/dispatch [:show-bottom-sheet
{:shell? true
:theme :dark
:content (fn [] [visibility-sheet/view])}])}
status-title]]]
[quo/text-combinations
{:container-style style/title-container
:emoji-hash emoji-string
:title full-name}]]))
{:title-accessibility-label :username
:container-style style/title-container
:emoji-hash emoji-string
:title full-name}]]))
(def view (quo.theme/with-theme f-view))

View File

@ -8,73 +8,93 @@
:on-press not-implemented/alert
:image-props :i/edit
:image :icon
:blur? true
:action :arrow}
{:title (i18n/label :t/password)
:on-press not-implemented/alert
:image-props :i/password
:image :icon
:blur? true
:action :arrow}]
[{:title (i18n/label :t/messages)
:on-press not-implemented/alert
:image-props :i/messages
:image :icon
:blur? true
:action :arrow}
{:title (i18n/label :t/wallet)
:on-press not-implemented/alert
:image-props :i/wallet
:image :icon
:blur? true
:action :arrow}
{:title (i18n/label :t/dapps)
:on-press not-implemented/alert
:image-props :i/placeholder
:image :icon
:blur? true
:action :arrow}
{:title "Browser"
{:title (i18n/label :t/browser)
:on-press not-implemented/alert
:image-props :i/browser
:image :icon
:blur? true
:action :arrow}
{:title (i18n/label :t/keycard)
:on-press not-implemented/alert
:image-props :i/keycard
:image :icon
:blur? true
:action :arrow}]
[{:title (i18n/label :t/syncing)
:on-press not-implemented/alert
:on-press #(rf/dispatch [:navigate-to :settings-syncing])
:image-props :i/syncing
:image :icon
:blur? true
:action :arrow}
{:title (i18n/label :t/notifications)
:on-press not-implemented/alert
:image-props :i/notifications
:on-press #(rf/dispatch [:navigate-to :notifications])
:image-props :i/activity-center
:image :icon
:blur? true
:action :arrow}
{:title (i18n/label :t/appearance)
:on-press not-implemented/alert
:on-press #(rf/dispatch [:navigate-to :appearance])
:image-props :i/light
:image :icon
:blur? true
:action :arrow}
{:title (i18n/label :t/language-and-currency)
:on-press not-implemented/alert
:image-props :i/globe
:image :icon
:blur? true
:action :arrow}]
[{:title (i18n/label :t/data-usage)
:on-press not-implemented/alert
:image-props :i/mobile
:image :icon
:blur? true
:action :arrow}
{:title (i18n/label :t/advanced)
:on-press not-implemented/alert
:on-press #(rf/dispatch [:navigate-to :advanced-settings])
:image-props :i/settings
:image :icon
:blur? true
:action :arrow}]
;; temporary link to legacy settings
[{:title "Legacy settings"
:on-press #(rf/dispatch [:navigate-to :my-profile])
:action :arrow
:image :icon
:image-props :i/toggle}]
:blur? true
:image-props :i/toggle}
{:title "Quo preview"
:on-press #(rf/dispatch [:navigate-to :quo-preview])
:action :arrow
:image :icon
:blur? true
:image-props :i/light}]
[{:title (i18n/label :t/about)
:on-press not-implemented/alert
:action :arrow}

View File

@ -7,5 +7,7 @@
:background-color (colors/resolve-color customization-color theme 40)})
(def footer-container
{:padding-horizontal 20
{:margin-top 8
:margin-bottom 50
:padding-horizontal 20
:padding-vertical 12})

View File

@ -9,6 +9,7 @@
[status-im.contexts.profile.settings.header.view :as settings.header]
[status-im.contexts.profile.settings.list-items :as settings.items]
[status-im.contexts.profile.settings.style :as style]
[status-im.contexts.shell.jump-to.constants :as jump-to.constants]
[utils.debounce :as debounce]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@ -16,9 +17,10 @@
(defn- settings-item-view
[data]
[quo/category
{:list-type :settings
:blur? true
:data data}])
{:list-type :settings
:container-style {:padding-bottom 0}
:blur? true
:data data}])
(defn scroll-handler
[event scroll-y]
@ -28,11 +30,11 @@
(defn- footer
[logout-press]
[rn/view {:style style/footer-container}
[quo/button
{:on-press logout-press
:type :danger
:icon-left :i/log-out}
(i18n/label :t/logout)]])
[quo/logout-button {:on-press logout-press}]])
(defn- get-item-layout
[_ index]
#js {:length 48 :offset (* 48 index) :index index})
(defn- settings-view
[theme]
@ -42,7 +44,8 @@
logout-press #(rf/dispatch [:multiaccounts.logout.ui/logout-pressed])]
[quo/overlay {:type :shell}
[rn/view
{:style (style/navigation-wrapper {:customization-color customization-color
{:key :header
:style (style/navigation-wrapper {:customization-color customization-color
:inset (:top insets)
:theme theme})}
[quo/page-nav
@ -50,19 +53,33 @@
: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 not-implemented/alert}
{:icon-name :i/share
:on-press #(debounce/dispatch-and-chill [:open-modal :share-shell] 1000)}]}]]
{: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
{:header [settings.header/view {:scroll-y scroll-y}]
{:key :list
:header [settings.header/view {:scroll-y scroll-y}]
:data settings.items/items
:key-fn :title
:get-item-layout get-item-layout
:initial-num-to-render 6
:max-to-render-per-batch 6
:shows-vertical-scroll-indicator false
:render-fn settings-item-view
:footer [footer logout-press]
:scroll-event-throttle 16
:on-scroll #(scroll-handler % scroll-y)
:bounces false}]]))
:bounces false}]
[quo/floating-shell-button
{:key :shell
:jump-to
{:on-press (fn []
(rf/dispatch [:navigate-back])
(debounce/dispatch-and-chill [:shell/navigate-to-jump-to] 500))
:customization-color customization-color
:label (i18n/label :t/jump-to)}}
{:position :absolute
:bottom jump-to.constants/floating-shell-button-height}]]))
(defn- internal-view
[props]

View File

@ -0,0 +1,46 @@
(ns status-im.contexts.profile.settings.visibility-sheet.view
(:require [quo.core :as quo]
[status-im.constants :as constants]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn change-visibility-status
[status-type]
(rf/dispatch
[:visibility-status-updates/delayed-visibility-status-update status-type])
(rf/dispatch [:hide-bottom-sheet]))
(defn view
[]
(let [{:keys [public-key]} (rf/sub [:profile/profile])
{:keys [status-type]} (rf/sub
[:visibility-status-updates/visibility-status-update
public-key])
customization-color (rf/sub [:profile/customization-color])]
[quo/action-drawer
[[{:icon :i/online
:no-icon-color? true
:blur? true
:state (when (= status-type constants/visibility-status-always-online) :selected)
:customization-color customization-color
:accessibility-label :online
:label (i18n/label :t/online)
:on-press #(change-visibility-status constants/visibility-status-always-online)}
{:icon :i/offline
:no-icon-color? true
:blur? true
:state (when (= status-type constants/visibility-status-inactive) :selected)
:accessibility-label :offline
:customization-color customization-color
:label (i18n/label :t/offline)
:sub-label (i18n/label :t/status-inactive-subtitle)
:on-press #(change-visibility-status constants/visibility-status-inactive)}
{:icon :i/automatic
:no-icon-color? true
:blur? true
:state (when (= status-type constants/visibility-status-automatic) :selected)
:accessibility-label :automatic
:customization-color customization-color
:label (i18n/label :t/status-automatic)
:sub-label (i18n/label :t/status-automatic-subtitle)
:on-press #(change-visibility-status constants/visibility-status-automatic)}]]]))