Improve the floating shell button and fix its position in the screens (#16981)
This commit is contained in:
parent
92403f5d30
commit
cace2a32a0
|
@ -61,6 +61,7 @@
|
|||
:active-opacity 1
|
||||
:hit-slop {:top 5 :bottom 5 :left 5 :right 5}
|
||||
:pointer-events :auto
|
||||
:style {:height 24}
|
||||
:accessibility-label type}
|
||||
[rn/view
|
||||
{:style (merge
|
||||
|
|
|
@ -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]))
|
|
@ -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})
|
|
@ -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]))
|
|
@ -72,7 +72,7 @@
|
|||
quo2.components.messages.author.view
|
||||
quo2.components.messages.gap
|
||||
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.notifications.activity-log.view
|
||||
quo2.components.notifications.activity-logs-photos.view
|
||||
|
@ -243,7 +243,7 @@
|
|||
(def static-skeleton quo2.components.loaders.skeleton.view/view)
|
||||
|
||||
;;;; 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)
|
||||
|
||||
;;;; Markdown
|
||||
|
|
|
@ -14,6 +14,12 @@
|
|||
:shadow-offset {:width 0 :height (colors/theme-colors -4 -8)}}
|
||||
{:elevation (if @focused? 10 0)}))
|
||||
|
||||
(def composer-sheet-and-jump-to-container
|
||||
{:position :absolute
|
||||
:bottom 0
|
||||
:left 0
|
||||
:right 0})
|
||||
|
||||
(defn sheet-container
|
||||
[insets {:keys [focused?]} {:keys [container-opacity]}]
|
||||
(reanimated/apply-animations-to-style
|
||||
|
@ -22,10 +28,6 @@
|
|||
{:border-top-left-radius 20
|
||||
:border-top-right-radius 20
|
||||
:padding-horizontal 20
|
||||
:position :absolute
|
||||
:bottom 0
|
||||
:left 0
|
||||
:right 0
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-95)
|
||||
:z-index 3
|
||||
:padding-bottom (:bottom insets)}
|
||||
|
@ -87,8 +89,7 @@
|
|||
:right 0
|
||||
:bottom 0
|
||||
:height window-height
|
||||
:background-color colors/neutral-95-opa-70
|
||||
:z-index 1}))
|
||||
:background-color colors/neutral-95-opa-70}))
|
||||
|
||||
(defn blur-container
|
||||
[height focused?]
|
||||
|
@ -110,18 +111,11 @@
|
|||
:blur-type (colors/theme-colors :light :dark)
|
||||
: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
|
||||
[translate-y opacity]
|
||||
(reanimated/apply-animations-to-style
|
||||
{:transform [{:translate-y translate-y}]
|
||||
:opacity opacity}
|
||||
{}))
|
||||
{:position :absolute
|
||||
:top 0
|
||||
:align-self :center}))
|
||||
|
|
|
@ -5,9 +5,7 @@
|
|||
[react-native.core :as rn]
|
||||
[status-im2.config :as config]
|
||||
[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.utils :as utils]
|
||||
[status-im2.contexts.chat.messages.list.view :as messages.list]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
@ -27,12 +25,8 @@
|
|||
[:f> f-blur-view layout-height focused?])
|
||||
|
||||
(defn- f-shell-button
|
||||
[{:keys [maximized? focused?]} {:keys [height]} {:keys [reply edit]}]
|
||||
[{:keys [focused?]}]
|
||||
(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)
|
||||
y-shell (reanimated/use-shared-value (if hide-shell? 35 0))
|
||||
opacity (reanimated/use-shared-value (if hide-shell? 0 1))]
|
||||
|
@ -41,8 +35,7 @@
|
|||
(reanimated/animate opacity (if hide-shell? 0 1))
|
||||
(reanimated/animate y-shell (if hide-shell? 35 0)))
|
||||
[@focused? @messages.list/show-floating-scroll-down-button])
|
||||
[reanimated/view
|
||||
{:style (style/shell-container height y-container)}
|
||||
[:<>
|
||||
[reanimated/view
|
||||
{:style (style/shell-button y-shell opacity)}
|
||||
[quo/floating-shell-button
|
||||
|
@ -53,11 +46,12 @@
|
|||
(rf/dispatch [:shell/navigate-to-jump-to]))
|
||||
:customization-color customization-color
|
||||
:label (i18n/label :t/jump-to)
|
||||
:style {:align-self :center}}} {}]]
|
||||
:style {:align-self :center}}}
|
||||
{}]]
|
||||
[quo/floating-shell-button
|
||||
(when @messages.list/show-floating-scroll-down-button
|
||||
{:scroll-to-bottom {:on-press messages.list/scroll-to-bottom}})
|
||||
{:bottom 24}]]))
|
||||
{}]]))
|
||||
|
||||
(defn shell-button
|
||||
[state animations subs]
|
||||
|
|
|
@ -66,62 +66,64 @@
|
|||
(effects/link-previews props state animations subs)
|
||||
(effects/images props state animations subs)
|
||||
[:<>
|
||||
[sub-view/shell-button state animations subs]
|
||||
(when chat-screen-loaded?
|
||||
[mentions/view props state animations max-height cursor-pos
|
||||
(:images subs)
|
||||
(:link-previews? subs)
|
||||
(:reply subs)
|
||||
(:edit subs)])
|
||||
[gesture/gesture-detector
|
||||
{:gesture (drag-gesture/drag-gesture props state animations subs dimensions keyboard-shown)}
|
||||
[reanimated/view
|
||||
{:style (style/sheet-container insets state animations)
|
||||
:on-layout #(handler/layout % state blur-height)}
|
||||
[sub-view/bar]
|
||||
(when chat-screen-loaded?
|
||||
[:<>
|
||||
[reply/view state]
|
||||
[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}]]
|
||||
[rn/view
|
||||
{:style style/composer-sheet-and-jump-to-container}
|
||||
[sub-view/shell-button state]
|
||||
[gesture/gesture-detector
|
||||
{:gesture (drag-gesture/drag-gesture props state animations subs dimensions keyboard-shown)}
|
||||
[reanimated/view
|
||||
{:style (style/sheet-container insets state animations)
|
||||
:on-layout #(handler/layout % state blur-height)}
|
||||
[sub-view/bar]
|
||||
(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]]]]))
|
||||
[reply/view state]
|
||||
[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?
|
||||
[:<>
|
||||
[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
|
||||
[insets]
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[quo2.core :as quo]
|
||||
[status-im2.contexts.shell.jump-to.constants :as jump-to.constants]
|
||||
[quo2.components.drawers.permission-context.view :as permission-context]
|
||||
[status-im2.constants :as constants]
|
||||
[react-native.core :as rn]
|
||||
|
@ -37,13 +38,13 @@
|
|||
(= contact-request-state
|
||||
constants/contact-request-state-sent)
|
||||
(i18n/label :t/contact-request-chat-pending))]]
|
||||
[rn/view {:position :absolute :top -36 :align-self :center}
|
||||
[quo/floating-shell-button
|
||||
{:jump-to
|
||||
{:on-press (fn []
|
||||
(when config/shell-navigation-disabled?
|
||||
(rf/dispatch [:chat/close true]))
|
||||
(rf/dispatch [:shell/navigate-to-jump-to]))
|
||||
:customization-color customization-color
|
||||
:label (i18n/label :t/jump-to)}}
|
||||
{}]]]))
|
||||
[quo/floating-shell-button
|
||||
{:jump-to
|
||||
{:on-press (fn []
|
||||
(when config/shell-navigation-disabled?
|
||||
(rf/dispatch [:chat/close true]))
|
||||
(rf/dispatch [:shell/navigate-to-jump-to]))
|
||||
:customization-color customization-color
|
||||
:label (i18n/label :t/jump-to)}}
|
||||
{:position :absolute
|
||||
:top (- jump-to.constants/floating-shell-button-height)}]]))
|
||||
|
|
|
@ -12,10 +12,11 @@
|
|||
[status-im.ui.screens.chat.group :as chat.group]
|
||||
[status-im.ui.screens.chat.message.gap :as message.gap]
|
||||
[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.list.state :as state]
|
||||
[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]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
@ -24,7 +25,6 @@
|
|||
(defonce ^:const loading-indicator-extra-spacing 250)
|
||||
(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))
|
||||
|
@ -129,15 +129,14 @@
|
|||
[insets able-to-send-message?]
|
||||
[rn/view
|
||||
{:background-color (colors/theme-colors colors/white colors/neutral-95)
|
||||
:margin-bottom (- 0
|
||||
(:top insets)
|
||||
(when platform/ios? style/overscroll-cover-height))
|
||||
:margin-bottom (when platform/ios? (- style/overscroll-cover-height))
|
||||
:height (+ (if able-to-send-message?
|
||||
(+ composer.constants/composer-default-height
|
||||
spacing-between-composer-and-content
|
||||
jump-to.constants/floating-shell-button-height
|
||||
(: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
|
||||
[{:keys [scroll-y display-name online? profile-picture]}]
|
||||
|
|
|
@ -367,4 +367,4 @@
|
|||
:customization-color customization-color
|
||||
:label (i18n/label :t/jump-to)}}
|
||||
{:position :absolute
|
||||
:bottom 41}]]))
|
||||
:bottom 34}]]))
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
(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]
|
||||
[react-native.core :as rn]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[reagent.core :as reagent]
|
||||
[utils.i18n :as i18n]
|
||||
[status-im2.contexts.quo-preview.preview :as preview]))
|
||||
|
@ -43,11 +42,6 @@
|
|||
(= scroll-type :scroll-to-bottom)
|
||||
(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
|
||||
[]
|
||||
(let [state (reagent/atom {:show-jump-to? true
|
||||
|
@ -59,7 +53,7 @@
|
|||
[rn/view
|
||||
{:padding-vertical 60
|
||||
:align-items :center}
|
||||
[:f> f-shell-button @state]]]])))
|
||||
[quo/floating-shell-button (mock-data @state) nil]]]])))
|
||||
|
||||
(defn preview-floating-shell-button
|
||||
[]
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
(def ^:const shell-animation-time 200)
|
||||
(def ^:const switcher-card-size 160)
|
||||
(def ^:const floating-shell-button-height 44)
|
||||
|
||||
;; Bottom tabs
|
||||
(def ^:const bottom-tabs-container-height-android 57)
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
:label (i18n/label :t/jump-to)
|
||||
:customization-color (rf/sub [:profile/customization-color])}}
|
||||
{:position :absolute
|
||||
:bottom (+ (utils/bottom-tabs-container-height) 12)}
|
||||
:bottom (utils/bottom-tabs-container-height)}
|
||||
(:home-stack-opacity shared-values)])
|
||||
|
||||
(defn f-shell-stack
|
||||
|
|
Loading…
Reference in New Issue