From 937c128c08dddbc4ff09902ff1ca43137901f3ed Mon Sep 17 00:00:00 2001 From: Parvesh Monu Date: Wed, 22 Mar 2023 11:47:57 +0530 Subject: [PATCH] Onboarding app locked flow --- .../images/icons2/20x20/multi-profile@2x.png | Bin 0 -> 1118 bytes .../images/icons2/20x20/multi-profile@3x.png | Bin 0 -> 1559 bytes src/quo2/components/buttons/button.cljs | 30 ++- src/quo2/components/info/info_message.cljs | 8 +- src/quo2/components/inputs/input/style.cljs | 5 +- src/quo2/components/inputs/input/view.cljs | 2 +- .../profile/profile_card/style.cljs | 18 +- .../components/profile/profile_card/view.cljs | 157 ++++++++------ src/status_im/events.cljs | 1 + src/status_im/keycard/login.cljs | 2 +- src/status_im/multiaccounts/login/core.cljs | 11 +- src/status_im/theme/core.cljs | 8 +- .../common/confirmation_drawer/view.cljs | 27 ++- .../onboarding/common/background/style.cljs | 7 +- .../onboarding/common/background/view.cljs | 3 +- .../contexts/onboarding/events.cljs | 7 + .../contexts/onboarding/profiles/style.cljs | 60 ++++++ .../contexts/onboarding/profiles/view.cljs | 202 +++++++++++++++++- .../quo_preview/profile/profile_card.cljs | 47 ++-- src/status_im2/events.cljs | 4 +- src/status_im2/navigation/roots.cljs | 11 +- translations/en.json | 13 +- 22 files changed, 466 insertions(+), 157 deletions(-) create mode 100644 resources/images/icons2/20x20/multi-profile@2x.png create mode 100644 resources/images/icons2/20x20/multi-profile@3x.png create mode 100644 src/status_im2/contexts/onboarding/events.cljs create mode 100644 src/status_im2/contexts/onboarding/profiles/style.cljs diff --git a/resources/images/icons2/20x20/multi-profile@2x.png b/resources/images/icons2/20x20/multi-profile@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..e401a246dd82a1d1164d280650fb72e1390ed707 GIT binary patch literal 1118 zcmV-k1flzhP)vtj zL9yS5R(NG(A}9%Mv;;np;F2tCI}oSzSi-A9w={aYZS|v-)S5_;PmLNV zY7v@|cidd04+`HRgZbIVcau(2jFbE53FPa6DT$aqa`AYn2v{&&Sttu*B_^ug;bAMj zPC}{6mqI_IUG2Bkea(g(2aYQ}k6iyn@Q5hvgR{@k&Y}3 zmhpJlf%mR41u}BCZhOl84tU&mq@1-d7IQN$?+$Vq%?9uky@cG zmUv{3PLBPqjrkGHgK!m@%zw^7e3&*cs3M1K+71K>jBd~({7D^I47DHC+wSEgIc1=| zP`9|W<yAzB_Pe<=$;fQZ={7L%%#g&`Y zY3*?=%gw#8|B5VB#^)=RhVvB;;_YLJdId{W49$EVA0*J$5 z(T^-xedP{Qk9%VZYMSI9{d0&3^YOD85BUd9BN*to=?E@eCuTuGLBl~2k^IVtV++YY zB+0(ER5ua!dSD->E9%!t<$c$Cx4gUfD0Fj5D2e{|0iU0rr07*qoM6N<$f)Q~IA^-pY literal 0 HcmV?d00001 diff --git a/resources/images/icons2/20x20/multi-profile@3x.png b/resources/images/icons2/20x20/multi-profile@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..74d5de87c10d2f6615c0cd5c2eb9537028174359 GIT binary patch literal 1559 zcmV+y2I%>TP)lK@P*}lDR{&iBbOq2A5LR$u1x;5_SOK{!Agll*fpq`XNJWt5 zF+Ilg}UuH{60kAu0Ytxfgz+Brs<|G~tjgn|K-MNXYi1cl#yngj538?Y|v?>Sw$hK|_$F{o(sG z8c!5>EbIl$=K4ZdTDk+^L*KjYA_lPnD`6|=;Xq#cri4@4h_j+eB?-*Z6<=_%D`qTC zx=Xm<@(8B+2?DRRX=it};bc1UV;Pl*JWvX$o$D6DnHsIHWtt=6Z&tn1hLW)T_j#DH zOhgk zAJxO_J-YRA)Oe%70@k)~AQKG#LrzeVvEKt)6u8?GGV~m=Lkpxuziwr5FFNX|9``Uf zoZi!VXBr!mJOr4tn^(K9>{VU}?{-X3BFHR7dptHXJkMq8n6NWhW79M?E?d%L)@$TI z-Co%veYV1%OXaeBx^&OW>3_m8jf)i6wjDcoGsOBf6SQ;nbf*&{l(%HM z8IChkV|V89^U!N^Bwp?xP12aUxyDF=hoLM-s%R<`6zNSd!tls6b_vy1Xs(fT%+Cw2ao|LaE3x7s^-YT< zJtiHgg`%U#P_r2Pq7sixJd?!Ix%_Zeq!ic`^qV0kNrXS&i6bJ8mY{hBGS53?M!GeY zrr|KN_wZMYkFB+WbLCf*gwh0Vpw>o!NaVpQd+qaBn?6|U4SVh1aDu|2CQ3pofkzm< zK}M+PM+TUgG`GhI2}M*F6kuHSu>6fTA~`K%N1 z`BC0@+Dch4ES;q}H{~2UfmGNUKE>s+NgyjsC2%S2(lAJCZF*~~*xK3_6F21-6uJ$3 z|5BzI>o5pBaP_Z50p(XFsC#1WN}$#y3oDGPy4Ms#L#UZb!!l<?@! z5K&!H?fQz|?<`o}$UkG!q2uz#f~34yybG6I#|42qc5m^|4Th$ODOeZ<=FpH9Ffpq~ zEK`8swGi{r*@Pdbl;nR(TOLviue3oLT5Kp~ZoisYL#W}U0=v&O*dn{~o`ail-k*Kk$M;oz~ zbc8arOM^X}mjw0#6disnq+P0GT#1b6+C2}HpnmhLlXgz7P?j}rp|;5t{t>KoOKF~8 zbI05UaFLH*R@cJlnq4Lp2~P7Q97VRQGNgb002ov JPDHLkV1oX{(fR-Y literal 0 HcmV?d00001 diff --git a/src/quo2/components/buttons/button.cljs b/src/quo2/components/buttons/button.cljs index 4254f268dd..81d8fc9a98 100644 --- a/src/quo2/components/buttons/button.cljs +++ b/src/quo2/components/buttons/button.cljs @@ -6,12 +6,13 @@ [react-native.core :as rn] [reagent.core :as reagent])) -(def themes +(defn themes + [customization-color] {:light {:primary {:icon-color colors/white :label-color colors/white - :background-color {:default colors/primary-50 - :pressed colors/primary-60 - :disabled colors/primary-50}} + :background-color {:default (colors/custom-color customization-color 50) + :pressed (colors/custom-color customization-color 60) + :disabled (colors/custom-color customization-color 50)}} :secondary {:icon-color colors/primary-50 :label-color colors/primary-50 :background-color {:default colors/primary-50-opa-20 @@ -74,9 +75,9 @@ :disabled colors/neutral-95}}} :dark {:primary {:icon-color colors/white :label-color colors/white - :background-color {:default colors/primary-60 - :pressed colors/primary-50 - :disabled colors/primary-60}} + :background-color {:default (colors/custom-color customization-color 60) + :pressed (colors/custom-color customization-color 50) + :disabled (colors/custom-color customization-color 60)}} :secondary {:icon-color colors/primary-50 :label-color colors/primary-50 :background-color {:default colors/primary-50-opa-20 @@ -218,14 +219,15 @@ (let [pressed (reagent/atom false)] (fn [{:keys [on-press disabled type size community-color community-text-color before after above - width + width customization-color override-theme override-background-color on-long-press accessibility-label icon icon-no-color style inner-style test-ID] - :or {type :primary - size 40}} + :or {type :primary + size 40 + customization-color :primary}} children] (let [{:keys [icon-color icon-secondary-color background-color label-color border-color]} - (get-in themes + (get-in (themes customization-color) [(or override-theme (theme/get-theme)) type]) @@ -252,11 +254,7 @@ [rn/view {:style (merge (shape-style-container type icon size) - {:background-color - (if (= state :pressed) - (colors/theme-colors colors/neutral-100 colors/white) - :transparent) - :width width} + {:width width} style)} [rn/view {:style (merge diff --git a/src/quo2/components/info/info_message.cljs b/src/quo2/components/info/info_message.cljs index 564c906c45..65e9761887 100644 --- a/src/quo2/components/info/info_message.cljs +++ b/src/quo2/components/info/info_message.cljs @@ -22,18 +22,18 @@ opts {:type :default/:success/:error :size :default/:tiny - :icon :main-icons/info ;; info message icon + :icon :i/info ;; info message icon :text-color colors/white ;; text color override :icon-color colors/white ;; icon color override :no-icon-color? false ;; disable tint color for icon" - [{:keys [type size icon text-color icon-color no-icon-color?]} message] + [{:keys [type size icon text-color icon-color no-icon-color? style]} message] (let [weight (if (= size :default) :regular :medium) size (if (= size :default) :paragraph-2 :label) text-color (or text-color (get-color type)) icon-color (or icon-color text-color)] [rn/view - {:style {:flex-direction :row - :flex 1}} + {:style (merge {:flex-direction :row} + style)} [quo2.icons/icon icon {:color icon-color :no-color no-icon-color? diff --git a/src/quo2/components/inputs/input/style.cljs b/src/quo2/components/inputs/input/style.cljs index 2e5d259551..81cf923b3c 100644 --- a/src/quo2/components/inputs/input/style.cljs +++ b/src/quo2/components/inputs/input/style.cljs @@ -66,7 +66,7 @@ :padding-horizontal 8 :border-width 1 :border-color (:border-color colors-by-status) - :border-radius (if small? 10 14) + :border-radius (if small? 10 12) :opacity (if disabled? 0.3 1)}) (defn left-icon-container @@ -110,8 +110,7 @@ :color (:clear-icon variant-colors)}) (def texts-container - {:flex 1 - :flex-direction :row + {:flex-direction :row :height 18 :margin-bottom 8}) diff --git a/src/quo2/components/inputs/input/view.cljs b/src/quo2/components/inputs/input/view.cljs index 5d97d5572f..ca6148b24b 100644 --- a/src/quo2/components/inputs/input/view.cljs +++ b/src/quo2/components/inputs/input/view.cljs @@ -83,7 +83,7 @@ colors-by-status (style/status-colors status-kw blur? override-theme) variant-colors (style/variants-colors blur? override-theme) clean-props (apply dissoc props custom-props)] - [rn/view + [:<> (when (or label char-limit) [label-&-counter {:variant-colors variant-colors diff --git a/src/quo2/components/profile/profile_card/style.cljs b/src/quo2/components/profile/profile_card/style.cljs index 70f833d35a..5eb4a54688 100644 --- a/src/quo2/components/profile/profile_card/style.cljs +++ b/src/quo2/components/profile/profile_card/style.cljs @@ -2,14 +2,16 @@ (:require [quo2.foundations.colors :as colors])) (defn card-container - [customization-color padding-bottom] - {:flex-direction :column - :padding-horizontal 12 - :padding-top 12 - :padding-bottom padding-bottom - :flex 1 - :border-radius 16 - :background-color (colors/custom-color customization-color 50 40)}) + [{:keys [customization-color padding-bottom border-bottom-radius]}] + {:padding-horizontal 12 + :padding-top 12 + :padding-bottom padding-bottom + :flex 1 + :border-top-left-radius 16 + :border-top-right-radius 16 + :border-bottom-left-radius border-bottom-radius + :border-bottom-right-radius border-bottom-radius + :background-color (colors/custom-color customization-color 50 40)}) (def card-header {:flex-direction :row diff --git a/src/quo2/components/profile/profile_card/view.cljs b/src/quo2/components/profile/profile_card/view.cljs index fb158f869f..6151609b50 100644 --- a/src/quo2/components/profile/profile_card/view.cljs +++ b/src/quo2/components/profile/profile_card/view.cljs @@ -4,77 +4,104 @@ [quo2.components.icon :as icon] [quo2.components.tags.tag :as tag] [quo2.foundations.colors :as colors] + [react-native.hole-view :as hole-view] [quo2.components.markdown.text :as text] [quo2.components.buttons.button :as button] - [quo2.components.avatars.user-avatar.view :as user-avatar] - [quo2.components.profile.profile-card.style :as style])) + [quo2.components.profile.profile-card.style :as style] + [quo2.components.avatars.user-avatar.view :as user-avatar])) -(defn profile-card - [{:keys [key-card? profile-picture name hash customization-color - emoji-hash on-options-press show-emoji-hash? padding-bottom - show-options-button? show-user-hash? show-logged-in? on-card-press] +(defn- profile-card-component + [{:keys [keycard-account? profile-picture name hash + customization-color emoji-hash on-options-press + show-emoji-hash? show-options-button? show-user-hash? + show-logged-in? on-card-press login-card? last-item? card-style] :or {show-emoji-hash? false show-user-hash? false customization-color :turquoise show-options-button? false show-logged-in? false - key-card? false}}] - [rn/touchable-without-feedback - {:on-press on-card-press - :flex 1 - :accessibility-label :profile-card} - [rn/view - (style/card-container - customization-color - (or padding-bottom (if show-emoji-hash? 12 10))) - [rn/view - {:style style/card-header} - [user-avatar/user-avatar - {:full-name name - :profile-picture profile-picture - :override-theme :dark - :size :medium - :status-indicator? false}] - [rn/view {:flex-direction :row} - (when show-logged-in? - [tag/tag - {:type :icon - :size 32 - :blurred? true - :labelled? true - :resource :main-icons2/check - :accessibility-label :logged-in-tag - :icon-color colors/success-50 + keycard-account? false + login-card? false + last-item? false + card-style {:padding-horizontal 20 + :flex 1}}}] + (let [{:keys [width]} (rn/use-window-dimensions) + padding-bottom (cond + login-card? 38 + show-emoji-hash? 12 + :else 10) + border-bottom-radius (if (or (not login-card?) last-item?) 16 0)] + [rn/touchable-without-feedback + {:on-press on-card-press + :accessibility-label :profile-card} + [hole-view/hole-view + {:key (str name last-item?) ;; Key is required to force removal of holes + :style (merge {:flex-direction :row} card-style) + :holes (if (or (not login-card?) last-item?) + [] + [{:x 20 + :y 108 + :width (- width 40) + :height 50 + :borderRadius 16}])} + [rn/view + {:style (style/card-container + {:customization-color customization-color + :padding-bottom padding-bottom + :border-bottom-radius border-bottom-radius})} + [rn/view + {:style style/card-header} + [user-avatar/user-avatar + {:full-name name + :profile-picture profile-picture :override-theme :dark - :label (i18n/label :t/logged-in)}]) - (when show-options-button? - [button/button - {:size 32 - :type :blur-bg - :icon true - :override-theme :dark - :style style/option-button - :on-press on-options-press - :accessibility-label :profile-card-options} - :i/options])]] - [rn/view - {:style style/name-container} - [text/text - {:size :heading-2 - :weight :semi-bold - :number-of-lines 1 - :style style/user-name} name] - (when key-card? - (icon/icon - :i/keycard - style/keycard-icon))] - (when show-user-hash? - [text/text - {:weight :monospace - :number-of-lines 1 - :style style/user-hash} hash]) - (when (and show-emoji-hash? emoji-hash) - [text/text - {:weight :monospace - :number-of-lines 1 - :style style/emoji-hash} emoji-hash])]]) + :size :medium + :status-indicator? false + :customization-color customization-color}] + [rn/view {:flex-direction :row} + (when show-logged-in? + [tag/tag + {:type :icon + :size 32 + :blurred? true + :labelled? true + :resource :main-icons2/check + :accessibility-label :logged-in-tag + :icon-color colors/success-50 + :override-theme :dark + :label (i18n/label :t/logged-in)}]) + (when show-options-button? + [button/button + {:size 32 + :type :blur-bg + :icon true + :override-theme :dark + :style style/option-button + :on-press on-options-press + :accessibility-label :profile-card-options} + :i/options])]] + [rn/view + {:style style/name-container} + [text/text + {:size :heading-2 + :weight :semi-bold + :number-of-lines 1 + :style style/user-name} name] + (when keycard-account? + (icon/icon + :i/keycard + style/keycard-icon))] + (when show-user-hash? + [text/text + {:weight :monospace + :number-of-lines 1 + :style style/user-hash} hash]) + (when (and show-emoji-hash? emoji-hash) + [text/text + {:weight :monospace + :number-of-lines 1 + :style style/emoji-hash} emoji-hash])]]])) + +(defn profile-card + [props] + [:f> profile-card-component props]) diff --git a/src/status_im/events.cljs b/src/status_im/events.cljs index bbf52684d6..3122ab068f 100644 --- a/src/status_im/events.cljs +++ b/src/status_im/events.cljs @@ -57,6 +57,7 @@ status-im2.contexts.activity-center.events status-im2.contexts.activity-center.notification.contact-requests.events status-im2.contexts.shell.events + status-im2.contexts.onboarding.events status-im.chat.models.gaps [status-im2.navigation.events :as navigation])) diff --git a/src/status_im/keycard/login.cljs b/src/status_im/keycard/login.cljs index 37627d634a..fb552f0b84 100644 --- a/src/status_im/keycard/login.cljs +++ b/src/status_im/keycard/login.cljs @@ -17,7 +17,7 @@ [{:keys [db] :as cofx}] (rf/merge cofx {:db db} - (navigation/pop-to-root :multiaccounts-stack))) + (navigation/pop-to-root :profiles))) (rf/defn login-pin-more-icon-pressed {:events [:keycard.login.pin.ui/more-icon-pressed]} diff --git a/src/status_im/multiaccounts/login/core.cljs b/src/status_im/multiaccounts/login/core.cljs index 97c3bffbd4..b6c1b71b99 100644 --- a/src/status_im/multiaccounts/login/core.cljs +++ b/src/status_im/multiaccounts/login/core.cljs @@ -521,6 +521,7 @@ (assoc-in [:multiaccount :multiaccounts/first-account] first-account?)) ::get-tokens [network-id accounts recovered-account?]} (finish-keycard-setup) + (initialize-appearance) (transport/start-messenger) (communities/fetch) (data-store.chats/fetch-chats-rpc @@ -624,14 +625,15 @@ login) (rf/merge cofx - {:db (dissoc db :goto-key-storage?)} + {:db (dissoc db :goto-key-storage?) + :theme/change-theme :dark} (when keycard-account? {:db (-> db (assoc-in [:keycard :pin :status] nil) (assoc-in [:keycard :pin :login] []))}) #(if keycard-account? {:init-root-fx :multiaccounts-keycard} - {:init-root-fx :multiaccounts}) + {:init-root-fx :profiles}) #(when goto-key-storage? (navigation/navigate-to-cofx % :actions-not-logged-in nil)))))) @@ -730,8 +732,9 @@ keycard-multiaccount? (boolean (:keycard-pairing multiaccount))] (rf/merge cofx - {:db (update db :keycard dissoc :application-info) - :navigate-to-fx (if keycard-multiaccount? :keycard-login-pin :login)} + (merge + {:db (update db :keycard dissoc :application-info)} + (when keycard-multiaccount? {:navigate-to-fx :keycard-login-pin})) (open-login (select-keys multiaccount [:key-uid :name :public-key :identicon :images]))))) (rf/defn hide-keycard-banner diff --git a/src/status_im/theme/core.cljs b/src/status_im/theme/core.cljs index 0968e92194..0a372c7faa 100644 --- a/src/status_im/theme/core.cljs +++ b/src/status_im/theme/core.cljs @@ -1,8 +1,14 @@ (ns status-im.theme.core (:require [quo.theme :as quo.theme] - [quo2.theme :as quo2.theme])) + [quo2.theme :as quo2.theme] + [re-frame.core :as re-frame])) (defn change-theme [theme] (quo.theme/set-theme theme) (quo2.theme/set-theme theme)) + +(re-frame/reg-fx + :theme/change-theme + (fn [theme] + (change-theme theme))) diff --git a/src/status_im2/common/confirmation_drawer/view.cljs b/src/status_im2/common/confirmation_drawer/view.cljs index 7725d71c75..ea4bd15637 100644 --- a/src/status_im2/common/confirmation_drawer/view.cljs +++ b/src/status_im2/common/confirmation_drawer/view.cljs @@ -26,18 +26,23 @@ [quo/text {:style {:margin-left 10}} extra-text]])) (defn confirmation-drawer - [{:keys [title description context button-text on-press extra-action extra-text accessibility-label]}] + [{:keys [title description context button-text on-press extra-action extra-text accessibility-label + close-button-text]}] (let [extra-action-selected? (reagent/atom false)] (fn [] - (let [{:keys [group-chat chat-id public-key color name]} context - id (or chat-id public-key) - display-name - (if-not group-chat (first (rf/sub [:contacts/contact-two-names-by-identity id])) name) - contact (when-not group-chat - (rf/sub [:contacts/contact-by-address - id])) - photo-path (when-not (empty? (:images contact)) - (rf/sub [:chats/photo-path id]))] + (let [{:keys [group-chat chat-id public-key color profile-picture + name]} context + id (or chat-id public-key) + display-name (or + name + (when-not group-chat + (rf/sub [:contacts/contact-name-by-identity id]))) + contact (when-not group-chat + (rf/sub [:contacts/contact-by-address + id])) + photo-path (or profile-picture + (when-not (empty? (:images contact)) + (rf/sub [:chats/photo-path id])))] [rn/view {:style {:margin-horizontal 20} :accessibility-label accessibility-label} @@ -57,7 +62,7 @@ {:type :grey :style {:flex 0.48} ;;WUT? 0.48 , whats that ? :on-press #(rf/dispatch [:bottom-sheet/hide])} - (i18n/label :t/close)] + (or close-button-text (i18n/label :t/close))] [quo/button {:type :danger :style {:flex 0.48} diff --git a/src/status_im2/contexts/onboarding/common/background/style.cljs b/src/status_im2/contexts/onboarding/common/background/style.cljs index 6924ef8b69..066009e847 100644 --- a/src/status_im2/contexts/onboarding/common/background/style.cljs +++ b/src/status_im2/contexts/onboarding/common/background/style.cljs @@ -3,7 +3,12 @@ (def background-container {:background-color colors/neutral-95 - :flex-direction :row}) + :flex-direction :row + :position :absolute + :top 0 + :bottom 0 + :left 0 + :right 0}) (defn background-gradient-overlay [dark-overlay?] diff --git a/src/status_im2/contexts/onboarding/common/background/view.cljs b/src/status_im2/contexts/onboarding/common/background/view.cljs index a37e340b91..064d2bc377 100644 --- a/src/status_im2/contexts/onboarding/common/background/view.cljs +++ b/src/status_im2/contexts/onboarding/common/background/view.cljs @@ -11,7 +11,8 @@ {:style style/background-container} [rn/image {:blur-radius (if dark-overlay? 13 0) - :style {:flex 1} + :style {:height "100%" + :width "100%"} ;; Todo - get background image from sub using carousel index on landing page :source (resources/get-image :onboarding-bg-1)}] [linear-gradient/linear-gradient diff --git a/src/status_im2/contexts/onboarding/events.cljs b/src/status_im2/contexts/onboarding/events.cljs new file mode 100644 index 0000000000..c7ee11ae44 --- /dev/null +++ b/src/status_im2/contexts/onboarding/events.cljs @@ -0,0 +1,7 @@ +(ns status-im2.contexts.onboarding.events + (:require [utils.re-frame :as rf])) + +(rf/defn on-delete-profile-success + {:events [:onboarding/on-delete-profile-success]} + [{:keys [db]} key-uid] + {:db (update-in db [:multiaccounts/multiaccounts] dissoc key-uid)}) diff --git a/src/status_im2/contexts/onboarding/profiles/style.cljs b/src/status_im2/contexts/onboarding/profiles/style.cljs new file mode 100644 index 0000000000..f818e779ad --- /dev/null +++ b/src/status_im2/contexts/onboarding/profiles/style.cljs @@ -0,0 +1,60 @@ +(ns status-im2.contexts.onboarding.profiles.style + (:require [quo2.foundations.colors :as colors] + [react-native.platform :as platform])) + +;; Profiles Section + +(defn profiles-profile-card + [last-item?] + ;; This part needs to be improved, inverted shadow is not supported in android + ;; https://reactnative.dev/docs/shadow-props#shadowoffset-ios + ;; (merge + ;; (:shadow-1 (shadows/get-scales true :dark)) + {:padding-horizontal 20 + :margin-bottom (when-not last-item? -24)}) + +(def profiles-container + {:position :absolute + :left 0 + :top 0 + :bottom 0 + :right 0}) + +(def profiles-header + {:flex-direction :row + :padding-horizontal 20 + :padding-top 112 + :margin-bottom 20}) + +(def profiles-header-text + {:color colors/white + :flex 1}) + +;; Login Section + +(def login-container + {:position :absolute + :left 0 + :top 0 + :right 0 + :bottom 0 + :padding-top 56 + :padding-horizontal 20}) + +(def multi-profile-button + {:align-self :flex-end}) + +(def login-profile-card + {:margin-vertical 20}) + +(def keyboard-avoiding-view + {:flex 1}) + +(def info-message + {:margin-top 8}) + +(defn login-button + [] + {:margin-top 8 + :margin-bottom (if platform/android? 20 46)}) + diff --git a/src/status_im2/contexts/onboarding/profiles/view.cljs b/src/status_im2/contexts/onboarding/profiles/view.cljs index 77bca64f8f..ca103eaec0 100644 --- a/src/status_im2/contexts/onboarding/profiles/view.cljs +++ b/src/status_im2/contexts/onboarding/profiles/view.cljs @@ -1,7 +1,203 @@ (ns status-im2.contexts.onboarding.profiles.view - (:require [status-im2.contexts.onboarding.common.background.view :as background])) + (:require [quo2.core :as quo] + [utils.i18n :as i18n] + [utils.re-frame :as rf] + [taoensso.timbre :as log] + [reagent.core :as reagent] + [react-native.core :as rn] + [status-im.utils.types :as types] + [utils.security.core :as security] + [status-im.native-module.core :as status] + [status-im2.contexts.onboarding.profiles.style :as style] + [status-im2.common.confirmation-drawer.view :as confirmation-drawer] + [status-im2.contexts.onboarding.common.background.view :as background])) + +(def show-profiles? (reagent/atom false)) + +(defn login-multiaccount + [] + (rf/dispatch [:multiaccounts.login.ui/password-input-submitted])) + +(defn new-account-options + [] + [quo/action-drawer + [[{:icon :i/profile + :label (i18n/label :t/create-new-profile) + :on-press #(do + (rf/dispatch [:bottom-sheet/hide]) + (rf/dispatch [:navigate-to :new-to-status])) + :accessibility-label :create-new-profile} + {:icon :i/multi-profile + :label (i18n/label :t/add-existing-status-profile) + :on-press #(do + (rf/dispatch [:bottom-sheet/hide]) + (rf/dispatch [:navigate-to :new-to-status])) + :accessibility-label :multi-profile}]]]) + +(defn show-new-account-options + [] + (rf/dispatch [:bottom-sheet/show-sheet + {:content new-account-options}])) + +(defn delete-profile-confirmation + [key-uid context] + (confirmation-drawer/confirmation-drawer + {:title (i18n/label :remove-profile?) + :description (i18n/label :remove-profile-confirm-message) + :accessibility-label :remove-profile-confirm + :context context + :button-text (i18n/label :t/remove) + :close-button-text (i18n/label :t/cancel) + :on-press #(do + (rf/dispatch [:bottom-sheet/hide]) + (status/delete-multiaccount + key-uid + (fn [result] + (let [{:keys [error]} (types/json->clj result)] + (rf/dispatch [:onboarding/on-delete-profile-success key-uid]) + (log/info "profile deleted: error" error)))))})) + +(defn show-confirmation + [key-uid context] + (rf/dispatch [:bottom-sheet/hide]) + (rf/dispatch [:bottom-sheet/show-sheet + {:content #(delete-profile-confirmation key-uid context)}])) + +(defn profile-options + [key-uid context] + [quo/action-drawer + [[{:icon :i/delete + :label (i18n/label :remove-profile-message) + :on-press #(show-confirmation key-uid context) + :accessibility-label :remove-profile + :danger? true}]]]) + +(defn show-profile-options + [key-uid context] + (rf/dispatch [:bottom-sheet/show-sheet + {:content #(profile-options key-uid context)}])) + +(defn profile-card + [{:keys [name key-uid customization-color keycard-pairing last-index] :as multiaccount} index] + (let [last-item? (= last-index index) + profile-picture (:uri (first (:images multiaccount)))] + [quo/profile-card + {:name name + :login-card? true + :last-item? (= last-index index) + :customization-color (or customization-color :primary) + :keycard-account? keycard-pairing + :show-options-button? true + :profile-picture (when profile-picture {:uri profile-picture}) + :card-style (style/profiles-profile-card last-item?) + :on-options-press #(show-profile-options + key-uid + {:name name + :color customization-color + :profile-picture profile-picture}) + :on-card-press #(do + (rf/dispatch + [:multiaccounts.login.ui/multiaccount-selected key-uid]) + (when-not keycard-pairing (reset! show-profiles? false)))}])) + +(defn profiles-section + [] + (let [multiaccounts (vals (rf/sub [:multiaccounts/multiaccounts])) + multiaccounts (map #(assoc % :last-index (- (count multiaccounts) 1)) multiaccounts)] + [rn/view + {:style style/profiles-container} + [rn/view + {:style style/profiles-header} + [quo/text + {:size :heading-1 + :weight :semi-bold + :style style/profiles-header-text} + (i18n/label :t/profiles-on-device)] + [quo/button + {:type :primary + :size 32 + :icon true + :on-press show-new-account-options + :accessibility-label :show-new-account-options + :override-theme :dark} + :main-icons/add]] + [rn/flat-list + {:data (sort-by :timestamp > multiaccounts) + :key-fn :key-uid + :content-container-style {:padding-bottom 20} + :render-fn profile-card}]])) + +(defn login-section + [] + (let [{:keys [name customization-color error processing] + :as multiaccount} (rf/sub [:multiaccounts/login]) + sign-in-enabled? (rf/sub [:sign-in-enabled?]) + profile-picture (:uri (first (:images multiaccount)))] + [rn/keyboard-avoiding-view + {:style style/login-container} + [rn/view + {:style {:flex 1}} + [quo/button + {:size 32 + :type :blur-bg + :icon true + :on-press #(reset! show-profiles? true) + :override-theme :dark + :width 32 + :accessibility-label :show-profiles + :style style/multi-profile-button} + :i/multi-profile] + [quo/profile-card + {:name name + :customization-color (or customization-color :primary) + :profile-picture (when profile-picture {:uri profile-picture}) + :card-style style/login-profile-card}] + [quo/input + {:type :password + :blur? true + :override-theme :dark + :placeholder (i18n/label :t/type-your-password) + :auto-focus true + :error? (when (not-empty error) error) + :label (i18n/label :t/profile-password) + :secure-text-entry true + :on-change-text (fn [password] + (rf/dispatch [:set-in [:multiaccounts/login :password] + (security/mask-data password)]) + (rf/dispatch [:set-in [:multiaccounts/login :error] ""])) + :on-submit-editing (when sign-in-enabled? login-multiaccount)}] + (when (not-empty error) + [quo/info-message + {:type :error + :size :default + :icon :i/info + :style style/info-message} + (i18n/label :t/oops-wrong-password)])] + [quo/button + {:size 40 + :type :ghost + :before :i/info + :accessibility-label :forget-password-button + :override-theme :dark} + (i18n/label :t/forget-password)] + [quo/button + {:size 40 + :type :primary + :customization-color (or :primary customization-color) + :accessibility-label :login-button + :override-theme :dark + :before :i/unlocked + :disabled (or (not sign-in-enabled?) processing) + :on-press login-multiaccount + :style (style/login-button)} + (i18n/label :t/log-in)]])) (defn views [] - [:<> - [background/view true]]) + (reset! show-profiles? false) + (fn [] + [:<> + [background/view true] + (if @show-profiles? + [profiles-section] + [login-section show-profiles?])])) diff --git a/src/status_im2/contexts/quo_preview/profile/profile_card.cljs b/src/status_im2/contexts/quo_preview/profile/profile_card.cljs index bb26343358..fba28a5a4e 100644 --- a/src/status_im2/contexts/quo_preview/profile/profile_card.cljs +++ b/src/status_im2/contexts/quo_preview/profile/profile_card.cljs @@ -8,7 +8,7 @@ (def descriptor [{:label "Show: Is from key card?" - :key :key-card? + :key :keycard-account? :type :boolean} {:label "Show: Emoji hash?" :key :show-emoji-hash? @@ -22,33 +22,19 @@ {:label "Show: Logged In?" :key :show-logged-in? :type :boolean} + {:label "Login Card?" + :key :login-card? + :type :boolean} + {:label "Last Item?" + :key :last-item? + :type :boolean} {:label "Customization Color" :key :customization-color :type :select - :options [{:key :primary - :value "Primary"} - {:key :purple - :value "Purple"} - {:key :indigo - :value "Indigo"} - {:key :turquoise - :value "Turquoise"} - {:key :blue - :value "Blue"} - {:key :green - :value "Green"} - {:key :yellow - :value "Yellow"} - {:key :orange - :value "Orange"} - {:key :red - :value "Red"} - {:key :pink - :value "Pink"} - {:key :brown - :value "Brown"} - {:key :beige - :value "Beige"}]} + :options (map (fn [[color-kw _]] + {:key color-kw + :value (name color-kw)}) + colors/customization)} {:label "Name" :key :name :type :text} @@ -61,13 +47,15 @@ (defn cool-preview [] - (let [state (reagent/atom {:key-card? false + (let [state (reagent/atom {:keycard-account? false :name "Matt Grote" :on-options-press nil :on-card-press nil :show-options-button? true :show-logged-in? true :show-user-hash? false + :login-card? false + :last-item? true :on-press-sign nil :customization-color :turquoise :profile-picture (resources/get-mock-image :user-picture-male5) @@ -80,10 +68,9 @@ [rn/view {:flex 1} [preview/customizer state descriptor]] [rn/view - {:padding-vertical 60 - :flex-direction :row - :margin-horizontal 20 - :justify-content :center} + {:padding-vertical 60 + :flex-direction :row + :justify-content :center} [quo/profile-card @state]]]]))) (defn preview-profile-card diff --git a/src/status_im2/events.cljs b/src/status_im2/events.cljs index b1662b9e27..77bdbc59a4 100644 --- a/src/status_im2/events.cljs +++ b/src/status_im2/events.cljs @@ -32,9 +32,9 @@ :setup/init-theme (fn [] (theme/add-mode-change-listener #(re-frame/dispatch [:system-theme-mode-changed %])) - (quo2.theme/set-theme (if (theme/dark-mode?) :dark :light)) + (quo2.theme/set-theme :dark) ;; TODO legacy support - (quo.theme/set-theme (if (theme/dark-mode?) :dark :light)))) + (quo.theme/set-theme :dark))) (rf/defn initialize-views {:events [:setup/initialize-view]} diff --git a/src/status_im2/navigation/roots.cljs b/src/status_im2/navigation/roots.cljs index ae433f17f3..cdc4e3f08d 100644 --- a/src/status_im2/navigation/roots.cljs +++ b/src/status_im2/navigation/roots.cljs @@ -2,12 +2,13 @@ (:require [quo2.foundations.colors :as colors] [react-native.platform :as platform] [status-im2.navigation.view :as views] - [status-im2.navigation.state :as state] - [status-im2.common.theme.core :as utils.theme])) + [status-im2.navigation.state :as state])) (defn status-bar-options [] - (let [dark-mode? (if (= @state/root-id :shell-stack) (colors/dark?) (utils.theme/dark-mode?))] + ;; dark-mode? = After login we are going to use theme as per user's choice (colors/dark?) + ;; but before login we only have dark mode (dark-mode? = true) + (let [dark-mode? (if (= @state/root-id :shell-stack) (colors/dark?) true)] (if platform/android? {:navigationBar {:backgroundColor colors/neutral-100} :statusBar {:backgroundColor :transparent @@ -98,8 +99,8 @@ :multiaccounts-keycard {:root {:stack {:id :multiaccounts-stack - :children [{:component {:name :multiaccounts - :id :multiaccounts + :children [{:component {:name :profiles + :id :profiles :options (get-screen-options :multiaccounts)}} {:component {:name :keycard-login-pin :id :keycard-login-pin diff --git a/translations/en.json b/translations/en.json index b73384f822..355de0574e 100644 --- a/translations/en.json +++ b/translations/en.json @@ -2000,5 +2000,16 @@ "strength-divider-okay-label": "Okay", "strength-divider-strong-label": "Strong", "strength-divider-very-strong-label": "Very strong", - "logged-in": "Logged in" + "logged-in": "Logged in", + "profiles-on-device": "Profiles on device", + "profile-password": "Profile password", + "forget-password": "Forgot password?", + "log-in": "Log in", + "type-your-password": "Type your password", + "oops-wrong-password": "Oops, wrong password!", + "remove-profile?" : "Remove profile?", + "remove-profile-message": "Remove profile from this device", + "remove-profile-confirm-message": "All profile data will removed from device.", + "create-new-profile": "Create new profile", + "add-existing-status-profile": "Add existing Status profile" }