diff --git a/.env b/.env index 094c61e7b7..9d31feb57e 100644 --- a/.env +++ b/.env @@ -34,3 +34,4 @@ STICKERS_TEST_ENABLED=1 LOCAL_PAIRING_ENABLED=1 TEST_STATEOFUS=1 FAST_CREATE_COMMUNITY_ENABLED=1 +FLAG_NEW_CONTACT_UI_ENABLED=0 diff --git a/src/legacy/status_im/profile/core.cljs b/src/legacy/status_im/profile/core.cljs index b897f97b0a..94b3d238c4 100644 --- a/src/legacy/status_im/profile/core.cljs +++ b/src/legacy/status_im/profile/core.cljs @@ -72,18 +72,3 @@ {:events [:show-tooltip]} [_ tooltip-id] {:show-tooltip tooltip-id}) - -(rf/defn show-profile - {:events [:chat.ui/show-profile]} - [{:keys [db]} identity ens-name] - (let [my-public-key (get-in db [:profile/profile :public-key])] - (if (not= my-public-key identity) - {:db (-> db - (assoc :contacts/identity identity) - (assoc :contacts/ens-name ens-name)) - :dispatch [:contacts/build-contact - {:pubkey identity - :ens ens-name - :success-fn (fn [_] - {:dispatch [:open-modal :profile]})}]} - {:dispatch [:navigate-to :my-profile]}))) diff --git a/src/status_im/common/scalable_avatar/style.cljs b/src/status_im/common/scalable_avatar/style.cljs new file mode 100644 index 0000000000..60a289994f --- /dev/null +++ b/src/status_im/common/scalable_avatar/style.cljs @@ -0,0 +1,11 @@ +(ns status-im.common.scalable-avatar.style) + +(defn wrapper + [{:keys [scale margin-top margin border-color]}] + [{:transform [{:scale scale}] + :margin-top margin-top + :margin-left margin + :margin-bottom margin} + {:border-width 4 + :border-color border-color + :border-radius 100}]) diff --git a/src/status_im/contexts/profile/settings/header/avatar.cljs b/src/status_im/common/scalable_avatar/view.cljs similarity index 72% rename from src/status_im/contexts/profile/settings/header/avatar.cljs rename to src/status_im/common/scalable_avatar/view.cljs index 9b6c9a9c21..3bdee91abf 100644 --- a/src/status_im/contexts/profile/settings/header/avatar.cljs +++ b/src/status_im/common/scalable_avatar/view.cljs @@ -1,16 +1,14 @@ -(ns status-im.contexts.profile.settings.header.avatar +(ns status-im.common.scalable-avatar.view (:require [quo.core :as quo] - [quo.theme :as quo.theme] [react-native.reanimated :as reanimated] - [status-im.contexts.profile.settings.header.style :as style])) - + [status-im.common.scalable-avatar.style :as style])) (def scroll-animation-input-range [0 50]) (def header-extrapolation-option {:extrapolateLeft "clamp" :extrapolateRight "clamp"}) (defn f-avatar - [{:keys [scroll-y full-name online? profile-picture customization-color]}] + [{:keys [scroll-y full-name online? profile-picture customization-color border-color]}] (let [image-scale-animation (reanimated/interpolate scroll-y scroll-animation-input-range [1 0.4] @@ -21,14 +19,13 @@ header-extrapolation-option) image-side-margin-animation (reanimated/interpolate scroll-y scroll-animation-input-range - [0 -20] - header-extrapolation-option) - theme (quo.theme/get-theme)] + [-4 -20] + header-extrapolation-option)] [reanimated/view - {:style (style/avatar-container theme - image-scale-animation - image-top-margin-animation - image-side-margin-animation)} + {:style (style/wrapper {:scale image-scale-animation + :margin-top image-top-margin-animation + :margin image-side-margin-animation + :border-color border-color})} [quo/user-avatar {:full-name full-name :online? online? diff --git a/src/status_im/common/scroll_page/style.cljs b/src/status_im/common/scroll_page/style.cljs index 35b9380364..a4763a872a 100644 --- a/src/status_im/common/scroll_page/style.cljs +++ b/src/status_im/common/scroll_page/style.cljs @@ -75,3 +75,9 @@ :width picture-diameter :height picture-diameter :background-color (colors/theme-colors colors/white colors/neutral-95 theme)}) + +(defn cover-background + [cover-color] + {:background-color cover-color + :height 167 + :margin-bottom -16}) diff --git a/src/status_im/common/scroll_page/view.cljs b/src/status_im/common/scroll_page/view.cljs index 9c526d1354..c68beeccbf 100644 --- a/src/status_im/common/scroll_page/view.cljs +++ b/src/status_im/common/scroll_page/view.cljs @@ -98,9 +98,9 @@ (defn scroll-page [_ _ _] (let [scroll-height (reagent/atom negative-scroll-position-0)] - (fn [{:keys [theme cover-image logo on-scroll + (fn [{:keys [theme cover-image cover-color logo on-scroll collapsed? height top-nav title-colum background-color navigate-back? page-nav-props - overlay-shown? sticky-header]} + overlay-shown? sticky-header children-style]} children] [:<> [:f> f-scroll-page-header @@ -125,6 +125,8 @@ "nativeEvent.contentOffset.y"))) (when on-scroll (on-scroll @scroll-height)))} + (when cover-color + [rn/view {:style (style/cover-background cover-color)}]) (when cover-image [rn/view {:style {:height (if collapsed? 110 151)}} [rn/image @@ -136,8 +138,10 @@ :flex 1}}]]) (when children [rn/view - {:style (style/children-container {:border-radius (diff-with-max-min @scroll-height 16 0) - :background-color background-color})} + {:style (style/children-container (merge + children-style + {:border-radius (diff-with-max-min @scroll-height 16 0) + :background-color background-color}))} (when (and (not collapsed?) cover-image) [:f> f-display-picture @scroll-height logo theme]) children])]]))) diff --git a/src/status_im/contexts/chat/events.cljs b/src/status_im/contexts/chat/events.cljs index 5b02b553ac..50af142c95 100644 --- a/src/status_im/contexts/chat/events.cljs +++ b/src/status_im/contexts/chat/events.cljs @@ -14,6 +14,7 @@ [status-im.contexts.chat.messenger.messages.delete-message-for-me.events :as delete-for-me] [status-im.contexts.chat.messenger.messages.delete-message.events :as delete-message] [status-im.contexts.chat.messenger.messages.list.state :as chat.state] + [status-im.feature-flags :as ff] [status-im.navigation.events :as navigation] [taoensso.timbre :as log] [utils.datetime :as datetime] @@ -431,3 +432,20 @@ [:chat/inputs current-chat-id :metadata :sending-image] dissoc (:uri original))}))) + +(rf/reg-event-fx :chat.ui/show-profile + (fn [{:keys [db]} [public-key ens-name]] + (let [my-public-key (get-in db [:profile/profile :public-key])] + (if (not= my-public-key public-key) + {:db (-> db + (assoc :contacts/identity public-key) + (assoc :contacts/ens-name ens-name)) + :dispatch [:contacts/build-contact + {:pubkey public-key + :ens ens-name + :success-fn (fn [_] + {:dispatch [:open-modal + (if (ff/enabled? ::ff/profile.new-contact-ui) + :contact-profile + :profile)]})}]} + {:dispatch [:navigate-to :my-profile]})))) diff --git a/src/status_im/contexts/profile/contact/header/style.cljs b/src/status_im/contexts/profile/contact/header/style.cljs new file mode 100644 index 0000000000..6523436a2b --- /dev/null +++ b/src/status_im/contexts/profile/contact/header/style.cljs @@ -0,0 +1,17 @@ +(ns status-im.contexts.profile.contact.header.style + (:require [quo.foundations.colors :as colors] + [react-native.reanimated :as reanimated])) + +(def avatar-wrapper + {:margin-top -40 + :padding-left 20 + :align-items :flex-start}) + +(defn header-container + [border-radius theme margin-top] + (reanimated/apply-animations-to-style + {:border-top-left-radius border-radius + :border-top-right-radius border-radius} + {:background-color (colors/theme-colors colors/white colors/neutral-95 theme) + :padding-horizontal 20 + :margin-top margin-top})) diff --git a/src/status_im/contexts/profile/contact/header/view.cljs b/src/status_im/contexts/profile/contact/header/view.cljs new file mode 100644 index 0000000000..8e5978512c --- /dev/null +++ b/src/status_im/contexts/profile/contact/header/view.cljs @@ -0,0 +1,34 @@ +(ns status-im.contexts.profile.contact.header.view + (:require [quo.core :as quo] + [quo.foundations.colors :as colors] + [quo.theme] + [react-native.core :as rn] + [status-im.common.scalable-avatar.view :as avatar] + [status-im.contexts.profile.contact.header.style :as style] + [status-im.contexts.profile.utils :as profile.utils] + [utils.re-frame :as rf])) + +(defn view + [{:keys [scroll-y]}] + (let [{:keys [public-key customization-color + emoji-hash bio] + :as profile} (rf/sub [:contacts/current-contact]) + customization-color (or customization-color :blue) + full-name (profile.utils/displayed-name profile) + profile-picture (profile.utils/photo profile) + online? (rf/sub [:visibility-status-updates/online? public-key]) + theme (quo.theme/use-theme-value)] + [rn/view {:style style/header-container} + [rn/view {:style style/avatar-wrapper} + [avatar/view + {:scroll-y scroll-y + :full-name full-name + :online? online? + :profile-picture profile-picture + :border-color (colors/theme-colors colors/white colors/neutral-95 theme) + :customization-color customization-color}]] + [quo/page-top + {:title full-name + :description :text + :description-text bio + :emoji-dash emoji-hash}]])) diff --git a/src/status_im/contexts/profile/contact/view.cljs b/src/status_im/contexts/profile/contact/view.cljs new file mode 100644 index 0000000000..cb225afedd --- /dev/null +++ b/src/status_im/contexts/profile/contact/view.cljs @@ -0,0 +1,24 @@ +(ns status-im.contexts.profile.contact.view + (:require [quo.foundations.colors :as colors] + [quo.theme] + [react-native.reanimated :as reanimated] + [status-im.common.not-implemented :as not-implemented] + [status-im.common.scroll-page.view :as scroll-page] + [status-im.contexts.profile.contact.header.view :as contact-header] + [utils.re-frame :as rf])) + +(defn view + [] + (let [{:keys [customization-color]} (rf/sub [:contacts/current-contact]) + scroll-y (reanimated/use-shared-value 0) + theme (quo.theme/use-theme-value)] + [scroll-page/scroll-page + {:navigate-back? true + :height 148 + :on-scroll #(reanimated/set-shared-value scroll-y %) + ;TODO remove colors/primary-50 when #18733 merged. + :cover-color (or customization-color colors/primary-50) + :background-color (colors/theme-colors colors/white colors/neutral-95 theme) + :page-nav-props {:right-side [{:icon-name :i/options + :on-press not-implemented/alert}]}} + [contact-header/view {:scroll-y scroll-y}]])) diff --git a/src/status_im/contexts/profile/settings/header/view.cljs b/src/status_im/contexts/profile/settings/header/view.cljs index 32b79b6006..699572ef5e 100644 --- a/src/status_im/contexts/profile/settings/header/view.cljs +++ b/src/status_im/contexts/profile/settings/header/view.cljs @@ -1,9 +1,10 @@ (ns status-im.contexts.profile.settings.header.view (:require [clojure.string :as string] [quo.core :as quo] - [quo.theme :as quo.theme] + [quo.foundations.colors :as colors] + [quo.theme] [react-native.core :as rn] - [status-im.contexts.profile.settings.header.avatar :as header.avatar] + [status-im.common.scalable-avatar.view :as 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] @@ -13,28 +14,31 @@ (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 - [:visibility-status-updates/visibility-status-update - public-key]) - customization-color (rf/sub [:profile/customization-color]) - bio (:bio profile) - 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)] + (let [{:keys [public-key emoji-hash bio] :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) + {:keys [status-title status-icon]} (header.utils/visibility-status-type-data status) + border-theme (quo.theme/get-theme)] [:<> [header.shape/view {:scroll-y scroll-y :customization-color customization-color :theme theme}] [rn/view {:style style/avatar-row-wrapper} - [header.avatar/view + [avatar/view {:scroll-y scroll-y :display-name full-name :online? online? + :border-color (colors/theme-colors colors/border-avatar-light + colors/neutral-80-opa-80 + border-theme) :customization-color customization-color :profile-picture profile-picture}] [rn/view {:style {:margin-bottom 4}} diff --git a/src/status_im/feature_flags.cljs b/src/status_im/feature_flags.cljs index ecd3ba0323..d503ee8c71 100644 --- a/src/status_im/feature_flags.cljs +++ b/src/status_im/feature_flags.cljs @@ -13,7 +13,8 @@ {::wallet.edit-default-keypair (enabled-in-env? :FLAG_EDIT_DEFAULT_KEYPAIR_ENABLED) ::wallet.bridge-token (enabled-in-env? :FLAG_BRIDGE_TOKEN_ENABLED) ::wallet.remove-account (enabled-in-env? :FLAG_REMOVE_ACCOUNT_ENABLED) - ::wallet.network-filter (enabled-in-env? :FLAG_NETWORK_FILTER_ENABLED)})) + ::wallet.network-filter (enabled-in-env? :FLAG_NETWORK_FILTER_ENABLED) + ::profile.new-contact-ui (enabled-in-env? :FLAG_NEW_CONTACT_UI_ENABLED)})) (defn feature-flags [] @feature-flags-config) diff --git a/src/status_im/navigation/screens.cljs b/src/status_im/navigation/screens.cljs index 3951833d9f..2c0df02ca4 100644 --- a/src/status_im/navigation/screens.cljs +++ b/src/status_im/navigation/screens.cljs @@ -36,6 +36,7 @@ [status-im.contexts.preview.quo.component-preview.view :as component-preview] [status-im.contexts.preview.quo.main :as quo.preview] [status-im.contexts.preview.status-im.main :as status-im-preview] + [status-im.contexts.profile.contact.view :as contact-profile] [status-im.contexts.profile.edit.accent-colour.view :as edit-accent-colour] [status-im.contexts.profile.edit.bio.view :as edit-bio] [status-im.contexts.profile.edit.name.view :as edit-name] @@ -202,6 +203,10 @@ :options options/transparent-modal-screen-options :component edit-bio/view} + {:name :contact-profile + :options {:modalPresentationStyle :overCurrentContext} + :component contact-profile/view} + {:name :new-to-status :options {:theme :dark :layout options/onboarding-transparent-layout