Improve the floating shell button and fix its position in the screens (#16981)

This commit is contained in:
Parvesh Monu 2023-08-21 21:30:32 +05:30 committed by GitHub
parent 92403f5d30
commit cace2a32a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 161 additions and 163 deletions

View File

@ -61,6 +61,7 @@
:active-opacity 1 :active-opacity 1
:hit-slop {:top 5 :bottom 5 :left 5 :right 5} :hit-slop {:top 5 :bottom 5 :left 5 :right 5}
:pointer-events :auto :pointer-events :auto
:style {:height 24}
:accessibility-label type} :accessibility-label type}
[rn/view [rn/view
{:style (merge {:style (merge

View File

@ -1,59 +0,0 @@
(ns quo2.components.navigation.floating-shell-button
(:require [quo2.components.buttons.dynamic-button.view :as dynamic-button]
[react-native.core :as rn]
[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
{:type type
:label label
:on-press on-press
:count (:count props)
:style style
:customization-color customization-color}]))
(defn- section
[children]
[rn/view {:style {:flex 1} :pointer-events :box-none} children])
(defn- f-floating-shell-button
[dynamic-buttons style opacity-anim]
(let [original-style (merge {:flex-direction :row
:margin-horizontal 12
:pointer-events :box-none}
style)
animated-style (reanimated/apply-animations-to-style
(if opacity-anim
{:opacity opacity-anim}
{})
original-style)]
[reanimated/view {:style animated-style}
;; Left Section
[section
[dynamic-button-view :search dynamic-buttons
{:position :absolute
:right 8}]]
;; Mid Section (jump-to)
[dynamic-button-view :jump-to dynamic-buttons nil]
;; Right Section
[section
[rn/view
{:style {:position :absolute
:flex-direction :row
:right 0}}
[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 floating-shell-button
"[floating-shell-button dynamic-buttons style opacity-anim pointer-anim]
dynamic-buttons {:button-type {:on-press on-press :count count}}
style override style
opacity-anim reanimated value (optional)"
([dynamic-buttons style]
[:f> f-floating-shell-button dynamic-buttons style nil])
([dynamic-buttons style opacity-anim]
[:f> f-floating-shell-button dynamic-buttons style opacity-anim]))

View File

@ -0,0 +1,22 @@
(ns quo2.components.navigation.floating-shell-button.style
(:require [react-native.reanimated :as reanimated]))
(defn floating-shell-button
[style opacity-anim]
(reanimated/apply-animations-to-style
(if opacity-anim
{:opacity opacity-anim}
{})
(merge
{:flex-direction :row
:height 44
:align-self :center
:padding-top 8
:padding-horizontal 12
:pointer-events :box-none}
style)))
(def right-section
{:position :absolute
:flex-direction :row
:right 0})

View File

@ -0,0 +1,49 @@
(ns quo2.components.navigation.floating-shell-button.view
(:require [react-native.core :as rn]
[react-native.reanimated :as reanimated]
[quo2.components.buttons.dynamic-button.view :as dynamic-button]
[quo2.components.navigation.floating-shell-button.style :as style]))
(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
{:type type
:label label
:on-press on-press
:count (:count props)
:style style
:customization-color customization-color}]))
(defn- section
[children]
[rn/view {:style {:flex 1} :pointer-events :box-none} children])
(defn- f-floating-shell-button
[dynamic-buttons style opacity-anim]
[reanimated/view {:style (style/floating-shell-button style opacity-anim)}
;; Left Section
[section
[dynamic-button-view :search dynamic-buttons
{:position :absolute
:right 8}]]
;; Mid Section (jump-to)
[dynamic-button-view :jump-to dynamic-buttons nil]
;; Right Section
[section
[rn/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}]]]])
(defn view
"[floating-shell-button dynamic-buttons style opacity-anim pointer-anim]
dynamic-buttons {:button-type {:on-press on-press :count count}}
style override style
opacity-anim reanimated value (optional)"
([dynamic-buttons style]
[:f> f-floating-shell-button dynamic-buttons style nil])
([dynamic-buttons style opacity-anim]
[:f> f-floating-shell-button dynamic-buttons style opacity-anim]))

View File

@ -72,7 +72,7 @@
quo2.components.messages.author.view quo2.components.messages.author.view
quo2.components.messages.gap quo2.components.messages.gap
quo2.components.messages.system-message quo2.components.messages.system-message
quo2.components.navigation.floating-shell-button quo2.components.navigation.floating-shell-button.view
quo2.components.navigation.page-nav quo2.components.navigation.page-nav
quo2.components.notifications.activity-log.view quo2.components.notifications.activity-log.view
quo2.components.notifications.activity-logs-photos.view quo2.components.notifications.activity-logs-photos.view
@ -243,7 +243,7 @@
(def static-skeleton quo2.components.loaders.skeleton.view/view) (def static-skeleton quo2.components.loaders.skeleton.view/view)
;;;; Navigation ;;;; Navigation
(def floating-shell-button quo2.components.navigation.floating-shell-button/floating-shell-button) (def floating-shell-button quo2.components.navigation.floating-shell-button.view/view)
(def page-nav quo2.components.navigation.page-nav/page-nav) (def page-nav quo2.components.navigation.page-nav/page-nav)
;;;; Markdown ;;;; Markdown

View File

@ -14,6 +14,12 @@
:shadow-offset {:width 0 :height (colors/theme-colors -4 -8)}} :shadow-offset {:width 0 :height (colors/theme-colors -4 -8)}}
{:elevation (if @focused? 10 0)})) {:elevation (if @focused? 10 0)}))
(def composer-sheet-and-jump-to-container
{:position :absolute
:bottom 0
:left 0
:right 0})
(defn sheet-container (defn sheet-container
[insets {:keys [focused?]} {:keys [container-opacity]}] [insets {:keys [focused?]} {:keys [container-opacity]}]
(reanimated/apply-animations-to-style (reanimated/apply-animations-to-style
@ -22,10 +28,6 @@
{:border-top-left-radius 20 {:border-top-left-radius 20
:border-top-right-radius 20 :border-top-right-radius 20
:padding-horizontal 20 :padding-horizontal 20
:position :absolute
:bottom 0
:left 0
:right 0
:background-color (colors/theme-colors colors/white colors/neutral-95) :background-color (colors/theme-colors colors/white colors/neutral-95)
:z-index 3 :z-index 3
:padding-bottom (:bottom insets)} :padding-bottom (:bottom insets)}
@ -87,8 +89,7 @@
:right 0 :right 0
:bottom 0 :bottom 0
:height window-height :height window-height
:background-color colors/neutral-95-opa-70 :background-color colors/neutral-95-opa-70}))
:z-index 1}))
(defn blur-container (defn blur-container
[height focused?] [height focused?]
@ -110,18 +111,11 @@
:blur-type (colors/theme-colors :light :dark) :blur-type (colors/theme-colors :light :dark)
:blur-amount 20}) :blur-amount 20})
(defn shell-container
[bottom translate-y]
(reanimated/apply-animations-to-style
{:bottom bottom ; we use height of the input directly as bottom position
:transform [{:translate-y translate-y}]}
{:position :absolute
:left 0
:right 0}))
(defn shell-button (defn shell-button
[translate-y opacity] [translate-y opacity]
(reanimated/apply-animations-to-style (reanimated/apply-animations-to-style
{:transform [{:translate-y translate-y}] {:transform [{:translate-y translate-y}]
:opacity opacity} :opacity opacity}
{})) {:position :absolute
:top 0
:align-self :center}))

View File

@ -5,9 +5,7 @@
[react-native.core :as rn] [react-native.core :as rn]
[status-im2.config :as config] [status-im2.config :as config]
[react-native.reanimated :as reanimated] [react-native.reanimated :as reanimated]
[react-native.safe-area :as safe-area]
[status-im2.contexts.chat.composer.style :as style] [status-im2.contexts.chat.composer.style :as style]
[status-im2.contexts.chat.composer.utils :as utils]
[status-im2.contexts.chat.messages.list.view :as messages.list] [status-im2.contexts.chat.messages.list.view :as messages.list]
[utils.i18n :as i18n] [utils.i18n :as i18n]
[utils.re-frame :as rf])) [utils.re-frame :as rf]))
@ -27,12 +25,8 @@
[:f> f-blur-view layout-height focused?]) [:f> f-blur-view layout-height focused?])
(defn- f-shell-button (defn- f-shell-button
[{:keys [maximized? focused?]} {:keys [height]} {:keys [reply edit]}] [{:keys [focused?]}]
(let [customization-color (rf/sub [:profile/customization-color]) (let [customization-color (rf/sub [:profile/customization-color])
insets (safe-area/get-insets)
extra-height (utils/calc-top-content-height reply edit)
neg-y (utils/calc-shell-neg-y insets maximized? extra-height)
y-container (reanimated/use-shared-value neg-y)
hide-shell? (or @focused? @messages.list/show-floating-scroll-down-button) hide-shell? (or @focused? @messages.list/show-floating-scroll-down-button)
y-shell (reanimated/use-shared-value (if hide-shell? 35 0)) y-shell (reanimated/use-shared-value (if hide-shell? 35 0))
opacity (reanimated/use-shared-value (if hide-shell? 0 1))] opacity (reanimated/use-shared-value (if hide-shell? 0 1))]
@ -41,8 +35,7 @@
(reanimated/animate opacity (if hide-shell? 0 1)) (reanimated/animate opacity (if hide-shell? 0 1))
(reanimated/animate y-shell (if hide-shell? 35 0))) (reanimated/animate y-shell (if hide-shell? 35 0)))
[@focused? @messages.list/show-floating-scroll-down-button]) [@focused? @messages.list/show-floating-scroll-down-button])
[reanimated/view [:<>
{:style (style/shell-container height y-container)}
[reanimated/view [reanimated/view
{:style (style/shell-button y-shell opacity)} {:style (style/shell-button y-shell opacity)}
[quo/floating-shell-button [quo/floating-shell-button
@ -53,11 +46,12 @@
(rf/dispatch [:shell/navigate-to-jump-to])) (rf/dispatch [:shell/navigate-to-jump-to]))
:customization-color customization-color :customization-color customization-color
:label (i18n/label :t/jump-to) :label (i18n/label :t/jump-to)
:style {:align-self :center}}} {}]] :style {:align-self :center}}}
{}]]
[quo/floating-shell-button [quo/floating-shell-button
(when @messages.list/show-floating-scroll-down-button (when @messages.list/show-floating-scroll-down-button
{:scroll-to-bottom {:on-press messages.list/scroll-to-bottom}}) {:scroll-to-bottom {:on-press messages.list/scroll-to-bottom}})
{:bottom 24}]])) {}]]))
(defn shell-button (defn shell-button
[state animations subs] [state animations subs]

View File

@ -66,62 +66,64 @@
(effects/link-previews props state animations subs) (effects/link-previews props state animations subs)
(effects/images props state animations subs) (effects/images props state animations subs)
[:<> [:<>
[sub-view/shell-button state animations subs]
(when chat-screen-loaded? (when chat-screen-loaded?
[mentions/view props state animations max-height cursor-pos [mentions/view props state animations max-height cursor-pos
(:images subs) (:images subs)
(:link-previews? subs) (:link-previews? subs)
(:reply subs) (:reply subs)
(:edit subs)]) (:edit subs)])
[gesture/gesture-detector [rn/view
{:gesture (drag-gesture/drag-gesture props state animations subs dimensions keyboard-shown)} {:style style/composer-sheet-and-jump-to-container}
[reanimated/view [sub-view/shell-button state]
{:style (style/sheet-container insets state animations) [gesture/gesture-detector
:on-layout #(handler/layout % state blur-height)} {:gesture (drag-gesture/drag-gesture props state animations subs dimensions keyboard-shown)}
[sub-view/bar] [reanimated/view
(when chat-screen-loaded? {:style (style/sheet-container insets state animations)
[:<> :on-layout #(handler/layout % state blur-height)}
[reply/view state] [sub-view/bar]
[edit/view state]])
[reanimated/touchable-opacity
{:active-opacity 1
:on-press (when @(:input-ref props) #(.focus ^js @(:input-ref props)))
:style (style/input-container (:height animations) max-height)
:accessibility-label :message-input-container}
[rn/selectable-text-input
{:ref #(reset! (:selectable-input-ref props) %)
:menu-items @(:menu-items state)
:style (style/input-view state)}
[rn/text-input
{:ref #(reset! (:input-ref props) %)
:default-value @(:text-value state)
:on-focus #(handler/focus props state animations dimensions)
:on-blur #(handler/blur state animations dimensions subs)
:on-content-size-change #(handler/content-size-change %
state
animations
subs
dimensions
(or keyboard-shown (:edit subs)))
:on-scroll #(handler/scroll % props state animations dimensions)
:on-change-text #(handler/change-text % props state)
:on-selection-change #(handler/selection-change % props state)
:on-selection #(selection/on-selection % props state)
:keyboard-appearance (theme/theme-value :light :dark)
:max-height max-height
:max-font-size-multiplier 1
:multiline true
:placeholder (i18n/label :t/type-something)
:placeholder-text-color (colors/theme-colors colors/neutral-30 colors/neutral-50)
:style (style/input-text props state subs max-height)
:max-length constants/max-text-size
:accessibility-label :chat-message-input}]]
(when chat-screen-loaded? (when chat-screen-loaded?
[:<> [:<>
[gradients/view props state animations show-bottom-gradient?] [reply/view state]
[link-preview/view] [edit/view state]])
[images/images-list]])] [reanimated/touchable-opacity
[actions/view props state animations window-height insets subs]]]])) {:active-opacity 1
:on-press (when @(:input-ref props) #(.focus ^js @(:input-ref props)))
:style (style/input-container (:height animations) max-height)
:accessibility-label :message-input-container}
[rn/selectable-text-input
{:ref #(reset! (:selectable-input-ref props) %)
:menu-items @(:menu-items state)
:style (style/input-view state)}
[rn/text-input
{:ref #(reset! (:input-ref props) %)
:default-value @(:text-value state)
:on-focus #(handler/focus props state animations dimensions)
:on-blur #(handler/blur state animations dimensions subs)
:on-content-size-change #(handler/content-size-change %
state
animations
subs
dimensions
(or keyboard-shown (:edit subs)))
:on-scroll #(handler/scroll % props state animations dimensions)
:on-change-text #(handler/change-text % props state)
:on-selection-change #(handler/selection-change % props state)
:on-selection #(selection/on-selection % props state)
:keyboard-appearance (theme/theme-value :light :dark)
:max-height max-height
:max-font-size-multiplier 1
:multiline true
:placeholder (i18n/label :t/type-something)
:placeholder-text-color (colors/theme-colors colors/neutral-30 colors/neutral-50)
:style (style/input-text props state subs max-height)
:max-length constants/max-text-size
:accessibility-label :chat-message-input}]]
(when chat-screen-loaded?
[:<>
[gradients/view props state animations show-bottom-gradient?]
[link-preview/view]
[images/images-list]])]
[actions/view props state animations window-height insets subs]]]]]))
(defn composer (defn composer
[insets] [insets]

View File

@ -3,6 +3,7 @@
[utils.i18n :as i18n] [utils.i18n :as i18n]
[utils.re-frame :as rf] [utils.re-frame :as rf]
[quo2.core :as quo] [quo2.core :as quo]
[status-im2.contexts.shell.jump-to.constants :as jump-to.constants]
[quo2.components.drawers.permission-context.view :as permission-context] [quo2.components.drawers.permission-context.view :as permission-context]
[status-im2.constants :as constants] [status-im2.constants :as constants]
[react-native.core :as rn] [react-native.core :as rn]
@ -37,13 +38,13 @@
(= contact-request-state (= contact-request-state
constants/contact-request-state-sent) constants/contact-request-state-sent)
(i18n/label :t/contact-request-chat-pending))]] (i18n/label :t/contact-request-chat-pending))]]
[rn/view {:position :absolute :top -36 :align-self :center} [quo/floating-shell-button
[quo/floating-shell-button {:jump-to
{:jump-to {:on-press (fn []
{:on-press (fn [] (when config/shell-navigation-disabled?
(when config/shell-navigation-disabled? (rf/dispatch [:chat/close true]))
(rf/dispatch [:chat/close true])) (rf/dispatch [:shell/navigate-to-jump-to]))
(rf/dispatch [:shell/navigate-to-jump-to])) :customization-color customization-color
:customization-color customization-color :label (i18n/label :t/jump-to)}}
:label (i18n/label :t/jump-to)}} {:position :absolute
{}]]])) :top (- jump-to.constants/floating-shell-button-height)}]]))

View File

@ -12,10 +12,11 @@
[status-im.ui.screens.chat.group :as chat.group] [status-im.ui.screens.chat.group :as chat.group]
[status-im.ui.screens.chat.message.gap :as message.gap] [status-im.ui.screens.chat.message.gap :as message.gap]
[status-im2.constants :as constants] [status-im2.constants :as constants]
[status-im2.contexts.chat.composer.constants :as composer.constants]
[status-im2.contexts.chat.messages.content.view :as message] [status-im2.contexts.chat.messages.content.view :as message]
[status-im2.contexts.chat.messages.list.state :as state] [status-im2.contexts.chat.messages.list.state :as state]
[status-im2.contexts.chat.messages.list.style :as style] [status-im2.contexts.chat.messages.list.style :as style]
[status-im2.contexts.shell.jump-to.constants :as jump-to.constants]
[status-im2.contexts.chat.composer.constants :as composer.constants]
[status-im2.contexts.chat.messages.navigation.style :as navigation.style] [status-im2.contexts.chat.messages.navigation.style :as navigation.style]
[utils.i18n :as i18n] [utils.i18n :as i18n]
[utils.re-frame :as rf])) [utils.re-frame :as rf]))
@ -24,7 +25,6 @@
(defonce ^:const loading-indicator-extra-spacing 250) (defonce ^:const loading-indicator-extra-spacing 250)
(defonce ^:const loading-indicator-page-loading-height 100) (defonce ^:const loading-indicator-page-loading-height 100)
(defonce ^:const scroll-animation-input-range [50 125]) (defonce ^:const scroll-animation-input-range [50 125])
(defonce ^:const spacing-between-composer-and-content 64)
(defonce ^:const min-message-height 32) (defonce ^:const min-message-height 32)
(defonce messages-list-ref (atom nil)) (defonce messages-list-ref (atom nil))
@ -129,15 +129,14 @@
[insets able-to-send-message?] [insets able-to-send-message?]
[rn/view [rn/view
{:background-color (colors/theme-colors colors/white colors/neutral-95) {:background-color (colors/theme-colors colors/white colors/neutral-95)
:margin-bottom (- 0 :margin-bottom (when platform/ios? (- style/overscroll-cover-height))
(:top insets)
(when platform/ios? style/overscroll-cover-height))
:height (+ (if able-to-send-message? :height (+ (if able-to-send-message?
(+ composer.constants/composer-default-height (+ composer.constants/composer-default-height
spacing-between-composer-and-content jump-to.constants/floating-shell-button-height
(:bottom insets)) (:bottom insets))
(- 70 (:bottom insets))) (- 70 (:bottom insets)))
(when platform/ios? style/overscroll-cover-height))}]) (when platform/ios?
(- style/overscroll-cover-height (:top insets))))}])
(defn f-list-footer-avatar (defn f-list-footer-avatar
[{:keys [scroll-y display-name online? profile-picture]}] [{:keys [scroll-y display-name online? profile-picture]}]

View File

@ -367,4 +367,4 @@
:customization-color customization-color :customization-color customization-color
:label (i18n/label :t/jump-to)}} :label (i18n/label :t/jump-to)}}
{:position :absolute {:position :absolute
:bottom 41}]])) :bottom 34}]]))

View File

@ -1,8 +1,7 @@
(ns status-im2.contexts.quo-preview.navigation.floating-shell-button (ns status-im2.contexts.quo-preview.navigation.floating-shell-button
(:require [quo2.components.navigation.floating-shell-button :as quo2] (:require [quo2.core :as quo]
[quo2.foundations.colors :as colors] [quo2.foundations.colors :as colors]
[react-native.core :as rn] [react-native.core :as rn]
[react-native.reanimated :as reanimated]
[reagent.core :as reagent] [reagent.core :as reagent]
[utils.i18n :as i18n] [utils.i18n :as i18n]
[status-im2.contexts.quo-preview.preview :as preview])) [status-im2.contexts.quo-preview.preview :as preview]))
@ -43,11 +42,6 @@
(= scroll-type :scroll-to-bottom) (= scroll-type :scroll-to-bottom)
(assoc :scroll-to-bottom {:on-press #()}))) (assoc :scroll-to-bottom {:on-press #()})))
(defn- f-shell-button
[state]
[quo2/floating-shell-button (mock-data state)
nil (reanimated/use-shared-value 1)])
(defn cool-preview (defn cool-preview
[] []
(let [state (reagent/atom {:show-jump-to? true (let [state (reagent/atom {:show-jump-to? true
@ -59,7 +53,7 @@
[rn/view [rn/view
{:padding-vertical 60 {:padding-vertical 60
:align-items :center} :align-items :center}
[:f> f-shell-button @state]]]]))) [quo/floating-shell-button (mock-data @state) nil]]]])))
(defn preview-floating-shell-button (defn preview-floating-shell-button
[] []

View File

@ -2,6 +2,7 @@
(def ^:const shell-animation-time 200) (def ^:const shell-animation-time 200)
(def ^:const switcher-card-size 160) (def ^:const switcher-card-size 160)
(def ^:const floating-shell-button-height 44)
;; Bottom tabs ;; Bottom tabs
(def ^:const bottom-tabs-container-height-android 57) (def ^:const bottom-tabs-container-height-android 57)

View File

@ -37,7 +37,7 @@
:label (i18n/label :t/jump-to) :label (i18n/label :t/jump-to)
:customization-color (rf/sub [:profile/customization-color])}} :customization-color (rf/sub [:profile/customization-color])}}
{:position :absolute {:position :absolute
:bottom (+ (utils/bottom-tabs-container-height) 12)} :bottom (utils/bottom-tabs-container-height)}
(:home-stack-opacity shared-values)]) (:home-stack-opacity shared-values)])
(defn f-shell-stack (defn f-shell-stack