From 224d6c7cad30834582921cc875b7408983751951 Mon Sep 17 00:00:00 2001 From: Alexander Date: Tue, 11 Jul 2023 20:30:22 +0200 Subject: [PATCH] Top bar fixes (#16506) * Recent fixes * More fix attempts (more successful now) * Updates for `on-content-size-change` * Lint fix * Update * View fixes --- .../contexts/chat/messages/list/view.cljs | 88 ++++++++++++------- .../chat/messages/navigation/view.cljs | 70 ++++++++------- .../contexts/chat/messages/view.cljs | 5 +- 3 files changed, 92 insertions(+), 71 deletions(-) diff --git a/src/status_im2/contexts/chat/messages/list/view.cljs b/src/status_im2/contexts/chat/messages/list/view.cljs index 4d4fb93481..9a75f1e535 100644 --- a/src/status_im2/contexts/chat/messages/list/view.cljs +++ b/src/status_im2/contexts/chat/messages/list/view.cljs @@ -25,6 +25,7 @@ (defonce ^:const loading-indicator-page-loading-height 100) (defonce ^:const scroll-animation-input-range [50 125]) (defonce ^:const spacing-between-composer-and-content 64) +(defonce ^:const min-message-height 32) (defonce messages-list-ref (atom nil)) (defonce messages-view-height (reagent/atom 0)) @@ -64,9 +65,8 @@ (dec (oops/oget e "viewableItems.length")))] (let [index (oops/oget last-visible-element "index") ;; Get first not visible element, if it's a datemark/gap - ;; we might unnecessarely add messages on receiving as - ;; they do not have a clock value, but most of the times - ;; it will be a message + ;; we might add messages on receiving as they do not have + ;; a clock value, but usually it will be a message first-not-visible (aget (oops/oget @messages-list-ref "props.data") (inc index))] (when (and first-not-visible (= :message (:type first-not-visible))) @@ -138,7 +138,7 @@ (when platform/ios? style/overscroll-cover-height))}]) (defn f-list-footer-avatar - [{:keys [scroll-y display-name online? photo-path]}] + [{:keys [scroll-y display-name online? profile-picture]}] (let [image-scale-animation (reanimated/interpolate scroll-y scroll-animation-input-range [1 0.5] @@ -158,7 +158,7 @@ [quo/user-avatar {:full-name display-name :online? online? - :profile-picture photo-path + :profile-picture profile-picture :size :big}]])) (defn list-footer-avatar @@ -193,7 +193,8 @@ [{:keys [chat scroll-y cover-bg-color on-layout shell-animation-complete?]}] (let [{:keys [chat-id chat-name emoji chat-type group-chat]} chat - all-loaded? (rf/sub [:chats/all-loaded? chat-id]) + all-loaded? (when shell-animation-complete? + (rf/sub [:chats/all-loaded? chat-id])) display-name (if (= chat-type constants/one-to-one-chat-type) (first (rf/sub [:contacts/contact-two-names-by-identity chat-id])) (str emoji " " chat-name)) @@ -251,18 +252,20 @@ (defn render-fn [{:keys [type value content-type] :as message-data} _ _ - {:keys [context keyboard-shown? insets]}] + {:keys [context keyboard-shown?]}] ;;TODO temporary hide mutual-state-updates https://github.com/status-im/status-mobile/issues/16254 (when (not= content-type constants/content-type-system-mutual-state-update) - (if (= type :header) - [list-header insets] - [rn/view - (add-inverted-y-android {:background-color (colors/theme-colors colors/white colors/neutral-95)}) - (if (= type :datemark) - [quo/divider-date value] - (if (= content-type constants/content-type-gap) - [message.gap/gap message-data] - [message/message message-data context keyboard-shown?]))]))) + [rn/view + (add-inverted-y-android {:background-color (colors/theme-colors colors/white colors/neutral-95)}) + (cond + (= type :datemark) + [quo/divider-date value] + + (= content-type constants/content-type-gap) + [message.gap/gap message-data] + + :else + [message/message message-data context keyboard-shown?])])) (defn scroll-handler [event scroll-y] @@ -272,8 +275,10 @@ (reanimated/set-shared-value scroll-y (- content-size-y current-y)))) (defn f-messages-list-content - [{:keys [chat insets scroll-y cover-bg-color keyboard-shown? shared-all-loaded?]}] - (let [shell-animation-complete? (rf/sub [:shell/animation-complete? (:chat-type chat)]) + [{:keys [chat insets scroll-y content-height cover-bg-color keyboard-shown?]}] + (let [{window-height :height} (rn/get-window) + {:keys [keyboard-height]} (hooks/use-keyboard) + shell-animation-complete? (rf/sub [:shell/animation-complete? (:chat-type chat)]) context (when shell-animation-complete? (rf/sub [:chats/current-chat-message-list-view-context])) messages (when shell-animation-complete? @@ -282,16 +287,12 @@ (rf/sub [:chats/recording?])) all-loaded? (when shell-animation-complete? (rf/sub [:chats/all-loaded? (:chat-id chat)]))] - ;; NOTE(rasom): Top bar needs to react on `all-loaded?` only after messages - ;; rendering, otherwise animation flickers - (rn/use-effect (fn [] - (reset! shared-all-loaded? all-loaded?)) - [all-loaded?]) [rn/view {:style {:flex 1}} [rn/flat-list {:key-fn list-key-fn :ref list-ref :header [:<> + [list-header insets] (when (= (:chat-type chat) constants/private-group-chat-type) [list-group-chat-header chat])] :footer [list-footer @@ -300,12 +301,29 @@ :cover-bg-color cover-bg-color :on-layout footer-on-layout :shell-animation-complete? shell-animation-complete?}] - :data (into [{:type :header}] messages) + :data messages :render-data {:context context :keyboard-shown? keyboard-shown? :insets insets} :render-fn render-fn :on-viewable-items-changed on-viewable-items-changed + :on-content-size-change (fn [_ y] + ;; NOTE(alwx): here we set the initial value of `scroll-y` + ;; which is needed because by default the chat is scrolled to the + ;; bottom + ;; and no initial `on-scroll` event is getting triggered + (let [scroll-y-shared (reanimated/get-shared-value scroll-y) + content-height-shared (reanimated/get-shared-value + content-height)] + (when (or (= scroll-y-shared 0) + (> (Math/abs (- content-height-shared y)) + min-message-height)) + (reanimated/set-shared-value scroll-y + (- y + window-height + (- (when keyboard-shown? + keyboard-height)))) + (reanimated/set-shared-value content-height y)))) :on-end-reached #(list-on-end-reached scroll-y) :on-scroll-to-index-failed identity :scroll-indicator-insets {:top (- composer.constants/composer-default-height 16)} @@ -338,13 +356,16 @@ [{:keys [chat cover-bg-color header-comp footer-comp]}] (let [insets (safe-area/get-insets) scroll-y (reanimated/use-shared-value 0) - all-loaded? (reagent/atom false) + content-height (reanimated/use-shared-value 0) {:keys [keyboard-height keyboard-shown]} (hooks/use-keyboard)] (rn/use-effect (fn [] - (when keyboard-shown + (if keyboard-shown (reanimated/set-shared-value scroll-y (+ (reanimated/get-shared-value scroll-y) + keyboard-height)) + (reanimated/set-shared-value scroll-y + (- (reanimated/get-shared-value scroll-y) keyboard-height)))) [keyboard-shown keyboard-height]) [rn/keyboard-avoiding-view @@ -353,17 +374,16 @@ (when header-comp [header-comp - {:scroll-y scroll-y - :shared-all-loaded? all-loaded?}]) + {:scroll-y scroll-y}]) [:f> f-messages-list-content - {:chat chat - :insets insets - :scroll-y scroll-y - :cover-bg-color cover-bg-color - :keyboard-shown? keyboard-shown - :shared-all-loaded? all-loaded?}] + {:chat chat + :insets insets + :scroll-y scroll-y + :content-height content-height + :cover-bg-color cover-bg-color + :keyboard-shown? keyboard-shown}] (when footer-comp [footer-comp {:insets insets}])])) diff --git a/src/status_im2/contexts/chat/messages/navigation/view.cljs b/src/status_im2/contexts/chat/messages/navigation/view.cljs index c670978a2f..597263f46e 100644 --- a/src/status_im2/contexts/chat/messages/navigation/view.cljs +++ b/src/status_im2/contexts/chat/messages/navigation/view.cljs @@ -14,42 +14,44 @@ [status-im2.common.home.actions.view :as actions])) (defn f-navigation-view - [{:keys [scroll-y shared-all-loaded?]}] + [{:keys [scroll-y]}] (let [{:keys [group-chat chat-id chat-name emoji chat-type] - :as chat} (rf/sub [:chats/current-chat-chat-view]) - all-loaded? @shared-all-loaded? - display-name (if (= chat-type constants/one-to-one-chat-type) - (first (rf/sub [:contacts/contact-two-names-by-identity chat-id])) - (str emoji " " chat-name)) - online? (rf/sub [:visibility-status-updates/online? chat-id]) - contact (when-not group-chat - (rf/sub [:contacts/contact-by-address chat-id])) - photo-path (when-not (empty? (:images contact)) - (rf/sub [:chats/photo-path chat-id])) - opacity-animation (reanimated/interpolate scroll-y - [style/navigation-bar-height - (+ style/navigation-bar-height 30)] - [0 1] - {:extrapolateLeft "clamp" - :extrapolateRight "extend"}) - banner-opacity-animation (reanimated/interpolate scroll-y - [(+ style/navigation-bar-height 150) - (+ style/navigation-bar-height 200)] - [0 1] - {:extrapolateLeft "clamp" - :extrapolateRight "extend"}) - translate-animation (reanimated/interpolate scroll-y - [(+ style/navigation-bar-height 25) - (+ style/navigation-bar-height 100)] - [50 0] - {:extrapolateLeft "clamp" - :extrapolateRight "clamp"}) - title-opacity-animation (reanimated/interpolate scroll-y - [0 50] - [0 1] - {:extrapolateLeft "clamp" - :extrapolateRight "clamp"})] + :as chat} (rf/sub [:chats/current-chat-chat-view]) + shell-animation-complete? (rf/sub [:shell/animation-complete? (:chat-type chat)]) + all-loaded? (when shell-animation-complete? + (rf/sub [:chats/all-loaded? (:chat-id chat)])) + display-name (if (= chat-type constants/one-to-one-chat-type) + (first (rf/sub [:contacts/contact-two-names-by-identity chat-id])) + (str emoji " " chat-name)) + online? (rf/sub [:visibility-status-updates/online? chat-id]) + contact (when-not group-chat + (rf/sub [:contacts/contact-by-address chat-id])) + photo-path (when-not (empty? (:images contact)) + (rf/sub [:chats/photo-path chat-id])) + opacity-animation (reanimated/interpolate scroll-y + [style/navigation-bar-height + (+ style/navigation-bar-height 30)] + [0 1] + {:extrapolateLeft "clamp" + :extrapolateRight "extend"}) + banner-opacity-animation (reanimated/interpolate scroll-y + [(+ style/navigation-bar-height 150) + (+ style/navigation-bar-height 200)] + [0 1] + {:extrapolateLeft "clamp" + :extrapolateRight "extend"}) + translate-animation (reanimated/interpolate scroll-y + [(+ style/navigation-bar-height 25) + (+ style/navigation-bar-height 100)] + [50 0] + {:extrapolateLeft "clamp" + :extrapolateRight "clamp"}) + title-opacity-animation (reanimated/interpolate scroll-y + [0 50] + [0 1] + {:extrapolateLeft "clamp" + :extrapolateRight "clamp"})] [rn/view {:style style/navigation-view} [reanimated/view {:style (style/animated-background-view all-loaded? opacity-animation)}] diff --git a/src/status_im2/contexts/chat/messages/view.cljs b/src/status_im2/contexts/chat/messages/view.cljs index 94b419bb90..551368e88c 100644 --- a/src/status_im2/contexts/chat/messages/view.cljs +++ b/src/status_im2/contexts/chat/messages/view.cljs @@ -23,11 +23,10 @@ [messages.list/messages-list {:cover-bg-color :turquoise :chat chat - :header-comp (fn [{:keys [scroll-y shared-all-loaded?]}] + :header-comp (fn [{:keys [scroll-y]}] [:f> messages.navigation/f-navigation-view - {:scroll-y scroll-y - :shared-all-loaded? shared-all-loaded?}]) + {:scroll-y scroll-y}]) :footer-comp (fn [{:keys [insets]}] (if-not able-to-send-message? [contact-requests.bottom-drawer/view chat-id contact-request-state