Refactor compose (#18339)
- Removed show-floating-scroll-down-button? reagent atom - Created event for scroll-to-bottom-fn - Renamed chat.ui/close-chat
This commit is contained in:
parent
0e4c1b3c17
commit
425ef64901
|
@ -39,7 +39,7 @@ export function interpolateNavigationViewOpacity(props) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function messagesListOnScroll(distanceFromListTop, callback) {
|
export function messagesListOnScroll(distanceFromListTop, chatListScrollY, callback) {
|
||||||
return function (event) {
|
return function (event) {
|
||||||
'worklet';
|
'worklet';
|
||||||
const currentY = event.contentOffset.y;
|
const currentY = event.contentOffset.y;
|
||||||
|
@ -47,7 +47,8 @@ export function messagesListOnScroll(distanceFromListTop, callback) {
|
||||||
const contentSizeY = event.contentSize.height - layoutHeight;
|
const contentSizeY = event.contentSize.height - layoutHeight;
|
||||||
const newDistance = contentSizeY - currentY;
|
const newDistance = contentSizeY - currentY;
|
||||||
distanceFromListTop.value = newDistance;
|
distanceFromListTop.value = newDistance;
|
||||||
runOnJS(callback)(currentY, layoutHeight, newDistance);
|
chatListScrollY.value = currentY;
|
||||||
|
runOnJS(callback)(layoutHeight, newDistance);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,3 +65,28 @@ export function placeholderZIndex(isCalculationsComplete) {
|
||||||
return isCalculationsComplete.value ? 0 : 2;
|
return isCalculationsComplete.value ? 0 : 2;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function scrollDownButtonOpacity(chatListScrollY, isComposerFocused, windowHeight) {
|
||||||
|
return useDerivedValue(function () {
|
||||||
|
'worklet';
|
||||||
|
if (isComposerFocused.value) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return chatListScrollY.value > windowHeight * 0.75 ? 1 : 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function jumpToButtonOpacity(scrollDownButtonOpacity, isComposerFocused) {
|
||||||
|
return useDerivedValue(function () {
|
||||||
|
'worklet';
|
||||||
|
return withTiming(scrollDownButtonOpacity.value == 1 || isComposerFocused.value ? 0 : 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function jumpToButtonPosition(scrollDownButtonOpacity, isComposerFocused) {
|
||||||
|
return useDerivedValue(function () {
|
||||||
|
'worklet';
|
||||||
|
return withTiming(scrollDownButtonOpacity.value == 1 || isComposerFocused.value ? 35 : 0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -95,7 +95,8 @@
|
||||||
:button-text (i18n/label :t/confirm)
|
:button-text (i18n/label :t/confirm)
|
||||||
:close-button-text (i18n/label :t/cancel)
|
:close-button-text (i18n/label :t/cancel)
|
||||||
:on-press (fn []
|
:on-press (fn []
|
||||||
(hide-sheet-and-dispatch [:chat.ui/close-chat chat-id])
|
(hide-sheet-and-dispatch [:chat.ui/close-and-remove-chat
|
||||||
|
chat-id])
|
||||||
(when inside-chat?
|
(when inside-chat?
|
||||||
(rf/dispatch [:navigate-back])))}])}]))
|
(rf/dispatch [:navigate-back])))}])}]))
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
(ns status-im.contexts.chat.effects
|
(ns status-im.contexts.chat.effects
|
||||||
(:require
|
(:require
|
||||||
[react-native.async-storage :as async-storage]
|
[react-native.async-storage :as async-storage]
|
||||||
|
[status-im.contexts.chat.messenger.messages.list.state :as chat.state]
|
||||||
[status-im.contexts.shell.jump-to.constants :as shell.constants]
|
[status-im.contexts.shell.jump-to.constants :as shell.constants]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
@ -16,3 +17,9 @@
|
||||||
(when (= stored-key-uid key-uid)
|
(when (= stored-key-uid key-uid)
|
||||||
(rf/dispatch [:chat/pop-to-root-and-navigate-to-chat chat-id
|
(rf/dispatch [:chat/pop-to-root-and-navigate-to-chat chat-id
|
||||||
shell.constants/open-screen-without-animation])))))))))
|
shell.constants/open-screen-without-animation])))))))))
|
||||||
|
|
||||||
|
(rf/reg-fx :effects.chat/scroll-to-bottom
|
||||||
|
(fn []
|
||||||
|
(some-> ^js @chat.state/messages-list-ref
|
||||||
|
(.scrollToOffset #js
|
||||||
|
{:animated true}))))
|
||||||
|
|
|
@ -281,7 +281,7 @@
|
||||||
|
|
||||||
(rf/defn close-and-remove-chat
|
(rf/defn close-and-remove-chat
|
||||||
"Closes the chat and removes it from chat list while retaining history, producing all necessary effects for that"
|
"Closes the chat and removes it from chat list while retaining history, producing all necessary effects for that"
|
||||||
{:events [:chat.ui/close-chat]}
|
{:events [:chat.ui/close-and-remove-chat]}
|
||||||
[{:keys [db now] :as cofx} chat-id]
|
[{:keys [db now] :as cofx} chat-id]
|
||||||
(rf/merge cofx
|
(rf/merge cofx
|
||||||
{:effects/push-notifications-clear-message-notifications [chat-id]
|
{:effects/push-notifications-clear-message-notifications [chat-id]
|
||||||
|
@ -386,7 +386,7 @@
|
||||||
:confirm-button-text (i18n/label :t/delete)
|
:confirm-button-text (i18n/label :t/delete)
|
||||||
:on-accept #(do
|
:on-accept #(do
|
||||||
(rf/dispatch [:hide-bottom-sheet])
|
(rf/dispatch [:hide-bottom-sheet])
|
||||||
(rf/dispatch [:chat.ui/close-chat chat-id]))}})
|
(rf/dispatch [:chat.ui/close-and-remove-chat chat-id]))}})
|
||||||
|
|
||||||
(rf/defn navigate-to-user-pinned-messages
|
(rf/defn navigate-to-user-pinned-messages
|
||||||
"Takes coeffects map and chat-id, returns effects necessary for navigation and preloading data"
|
"Takes coeffects map and chat-id, returns effects necessary for navigation and preloading data"
|
||||||
|
@ -447,3 +447,8 @@
|
||||||
:params [{:id chat-id}]
|
:params [{:id chat-id}]
|
||||||
:on-success #()
|
:on-success #()
|
||||||
:on-error #(log/error "failed to fetch messages for chat" chat-id %)}]})
|
:on-error #(log/error "failed to fetch messages for chat" chat-id %)}]})
|
||||||
|
|
||||||
|
(rf/defn scroll-to-bottom
|
||||||
|
{:events [:chat.ui/scroll-to-bottom]}
|
||||||
|
[_]
|
||||||
|
{:effects.chat/scroll-to-bottom nil})
|
||||||
|
|
|
@ -20,8 +20,7 @@
|
||||||
{:keys [text-value focused? maximized?]}
|
{:keys [text-value focused? maximized?]}
|
||||||
{:keys [height saved-height last-height opacity background-y container-opacity]}
|
{:keys [height saved-height last-height opacity background-y container-opacity]}
|
||||||
window-height
|
window-height
|
||||||
edit
|
edit]
|
||||||
scroll-to-bottom-fn]
|
|
||||||
(reanimated/animate height comp-constants/input-height)
|
(reanimated/animate height comp-constants/input-height)
|
||||||
(reanimated/set-shared-value saved-height comp-constants/input-height)
|
(reanimated/set-shared-value saved-height comp-constants/input-height)
|
||||||
(reanimated/set-shared-value last-height comp-constants/input-height)
|
(reanimated/set-shared-value last-height comp-constants/input-height)
|
||||||
|
@ -39,11 +38,11 @@
|
||||||
(reset! text-value "")
|
(reset! text-value "")
|
||||||
(reset! sending-links? false)
|
(reset! sending-links? false)
|
||||||
(reset! sending-images? false)
|
(reset! sending-images? false)
|
||||||
(when (and (not (some? edit)) scroll-to-bottom-fn)
|
(when-not (some? edit)
|
||||||
(scroll-to-bottom-fn)))
|
(rf/dispatch [:chat.ui/scroll-to-bottom])))
|
||||||
|
|
||||||
(defn f-send-button
|
(defn f-send-button
|
||||||
[props state animations window-height images? btn-opacity scroll-to-bottom-fn z-index edit]
|
[props state animations window-height images? btn-opacity z-index edit]
|
||||||
(let [{:keys [text-value]} state
|
(let [{:keys [text-value]} state
|
||||||
customization-color (rf/sub [:profile/customization-color])]
|
customization-color (rf/sub [:profile/customization-color])]
|
||||||
(rn/use-effect (fn []
|
(rn/use-effect (fn []
|
||||||
|
@ -61,19 +60,17 @@
|
||||||
[reanimated/view
|
[reanimated/view
|
||||||
{:style (style/send-button btn-opacity @z-index)}
|
{:style (style/send-button btn-opacity @z-index)}
|
||||||
[quo/button
|
[quo/button
|
||||||
{:icon-only? true
|
{:icon-only? true
|
||||||
:size 32
|
:size 32
|
||||||
:customization-color customization-color
|
:customization-color customization-color
|
||||||
:accessibility-label :send-message-button
|
:accessibility-label :send-message-button
|
||||||
:on-press #(send-message props state animations window-height edit scroll-to-bottom-fn)}
|
:on-press #(send-message props state animations window-height edit)}
|
||||||
:i/arrow-up]]))
|
:i/arrow-up]]))
|
||||||
|
|
||||||
(defn send-button
|
(defn send-button
|
||||||
[props {:keys [text-value] :as state} animations window-height images? edit btn-opacity
|
[props {:keys [text-value] :as state} animations window-height images? edit btn-opacity]
|
||||||
scroll-to-bottom-fn]
|
|
||||||
(let [z-index (reagent/atom (if (and (empty? @text-value) (not images?)) 0 1))]
|
(let [z-index (reagent/atom (if (and (empty? @text-value) (not images?)) 0 1))]
|
||||||
[:f> f-send-button props state animations window-height images? btn-opacity scroll-to-bottom-fn
|
[:f> f-send-button props state animations window-height images? btn-opacity z-index edit]))
|
||||||
z-index edit]))
|
|
||||||
|
|
||||||
(defn disabled-audio-button
|
(defn disabled-audio-button
|
||||||
[opacity]
|
[opacity]
|
||||||
|
@ -231,7 +228,7 @@
|
||||||
:icon :i/format}])
|
:icon :i/format}])
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[props state animations window-height insets scroll-to-bottom-fn {:keys [edit images]}]
|
[props state animations window-height insets {:keys [edit images]}]
|
||||||
(let [send-btn-opacity (reanimated/use-shared-value 0)
|
(let [send-btn-opacity (reanimated/use-shared-value 0)
|
||||||
audio-btn-opacity (reanimated/interpolate send-btn-opacity [0 1] [1 0])]
|
audio-btn-opacity (reanimated/interpolate send-btn-opacity [0 1] [1 0])]
|
||||||
[rn/view {:style style/actions-container}
|
[rn/view {:style style/actions-container}
|
||||||
|
@ -242,8 +239,7 @@
|
||||||
[image-button props animations insets edit]
|
[image-button props animations insets edit]
|
||||||
[reaction-button]
|
[reaction-button]
|
||||||
[format-button]]
|
[format-button]]
|
||||||
[:f> send-button props state animations window-height images edit send-btn-opacity
|
[:f> send-button props state animations window-height images edit send-btn-opacity]
|
||||||
scroll-to-bottom-fn]
|
|
||||||
(when (and (not edit) (not images))
|
(when (and (not edit) (not images))
|
||||||
;; TODO(alwx): needs to be replaced with an `audio-button` later. See
|
;; TODO(alwx): needs to be replaced with an `audio-button` later. See
|
||||||
;; https://github.com/status-im/status-mobile/issues/16084 for more details.
|
;; https://github.com/status-im/status-mobile/issues/16084 for more details.
|
||||||
|
|
|
@ -16,11 +16,11 @@
|
||||||
(defn focus
|
(defn focus
|
||||||
"Animate to the `saved-height`, display background-overlay if needed, and set cursor position"
|
"Animate to the `saved-height`, display background-overlay if needed, and set cursor position"
|
||||||
[{:keys [input-ref] :as props}
|
[{:keys [input-ref] :as props}
|
||||||
{:keys [text-value focused? lock-selection? saved-cursor-position]}
|
{:keys [text-value focused? lock-selection? saved-cursor-position composer-focused?]}
|
||||||
{:keys [height saved-height last-height opacity background-y container-opacity]
|
{:keys [height saved-height last-height opacity background-y container-opacity]
|
||||||
:as animations}
|
:as animations}
|
||||||
{:keys [max-height] :as dimensions}
|
{:keys [max-height] :as dimensions}]
|
||||||
show-floating-scroll-down-button?]
|
(reanimated/set-shared-value composer-focused? true)
|
||||||
(reset! focused? true)
|
(reset! focused? true)
|
||||||
(rf/dispatch [:chat.ui/set-input-focused true])
|
(rf/dispatch [:chat.ui/set-input-focused true])
|
||||||
(let [last-height-value (reanimated/get-shared-value last-height)]
|
(let [last-height-value (reanimated/get-shared-value last-height)]
|
||||||
|
@ -35,13 +35,12 @@
|
||||||
(when (and (not-empty @text-value) @input-ref)
|
(when (and (not-empty @text-value) @input-ref)
|
||||||
(.setNativeProps ^js @input-ref
|
(.setNativeProps ^js @input-ref
|
||||||
(clj->js {:selection {:start @saved-cursor-position :end @saved-cursor-position}})))
|
(clj->js {:selection {:start @saved-cursor-position :end @saved-cursor-position}})))
|
||||||
(kb/handle-refocus-emoji-kb-ios props animations dimensions)
|
(kb/handle-refocus-emoji-kb-ios props animations dimensions))
|
||||||
(reset! show-floating-scroll-down-button? false))
|
|
||||||
|
|
||||||
(defn blur
|
(defn blur
|
||||||
"Save the current height, minimize the composer, animate-out the background, and save cursor position"
|
"Save the current height, minimize the composer, animate-out the background, and save cursor position"
|
||||||
[{:keys [text-value focused? lock-selection? cursor-position saved-cursor-position gradient-z-index
|
[{:keys [text-value focused? lock-selection? cursor-position saved-cursor-position gradient-z-index
|
||||||
maximized? recording?]}
|
maximized? recording? composer-focused?]}
|
||||||
{:keys [height saved-height last-height gradient-opacity container-opacity opacity background-y]}
|
{:keys [height saved-height last-height gradient-opacity container-opacity opacity background-y]}
|
||||||
{:keys [content-height max-height window-height]}
|
{:keys [content-height max-height window-height]}
|
||||||
{:keys [images link-previews? reply]}]
|
{:keys [images link-previews? reply]}]
|
||||||
|
@ -53,6 +52,7 @@
|
||||||
max-height
|
max-height
|
||||||
content-height
|
content-height
|
||||||
saved-height)]
|
saved-height)]
|
||||||
|
(reanimated/set-shared-value composer-focused? false)
|
||||||
(reset! focused? false)
|
(reset! focused? false)
|
||||||
(rf/dispatch [:chat.ui/set-input-focused false])
|
(rf/dispatch [:chat.ui/set-input-focused false])
|
||||||
(reanimated/set-shared-value last-height reopen-height)
|
(reanimated/set-shared-value last-height reopen-height)
|
||||||
|
|
|
@ -6,7 +6,8 @@
|
||||||
[react-native.reanimated :as reanimated]
|
[react-native.reanimated :as reanimated]
|
||||||
[status-im.contexts.chat.messenger.composer.style :as style]
|
[status-im.contexts.chat.messenger.composer.style :as style]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]
|
||||||
|
[utils.worklets.chat.messages :as worklets]))
|
||||||
|
|
||||||
(defn bar
|
(defn bar
|
||||||
[theme]
|
[theme]
|
||||||
|
@ -23,33 +24,33 @@
|
||||||
[:f> f-blur-view props])
|
[:f> f-blur-view props])
|
||||||
|
|
||||||
(defn- f-shell-button
|
(defn- f-shell-button
|
||||||
[{:keys [focused?]} scroll-to-bottom-fn show-floating-scroll-down-button?]
|
[{:keys [composer-focused?]} chat-list-scroll-y window-height]
|
||||||
(let [customization-color (rf/sub [:profile/customization-color])
|
(let [customization-color (rf/sub [:profile/customization-color])
|
||||||
hide-shell? (or @focused? @show-floating-scroll-down-button?)
|
scroll-down-button-opacity (worklets/scroll-down-button-opacity
|
||||||
y-shell (reanimated/use-shared-value (if hide-shell? 35 0))
|
chat-list-scroll-y
|
||||||
opacity (reanimated/use-shared-value (if hide-shell? 0 1))]
|
composer-focused?
|
||||||
(rn/use-effect
|
window-height)
|
||||||
(fn []
|
jump-to-button-opacity (worklets/jump-to-button-opacity
|
||||||
(reanimated/animate opacity (if hide-shell? 0 1))
|
scroll-down-button-opacity
|
||||||
(reanimated/animate y-shell (if hide-shell? 35 0)))
|
composer-focused?)
|
||||||
[@focused? @show-floating-scroll-down-button?])
|
jump-to-button-position (worklets/jump-to-button-position
|
||||||
|
scroll-down-button-opacity
|
||||||
|
composer-focused?)]
|
||||||
[:<>
|
[:<>
|
||||||
[reanimated/view
|
[reanimated/view
|
||||||
{:style (style/shell-button y-shell opacity)}
|
{:style (style/shell-button jump-to-button-position jump-to-button-opacity)}
|
||||||
[quo/floating-shell-button
|
[quo/floating-shell-button
|
||||||
{:jump-to
|
{:jump-to
|
||||||
{:on-press (fn []
|
{:on-press #(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}}}
|
||||||
{}]]
|
{}]]
|
||||||
(when (and (not @focused?)
|
[quo/floating-shell-button
|
||||||
@show-floating-scroll-down-button?)
|
{:scroll-to-bottom {:on-press #(rf/dispatch [:chat.ui/scroll-to-bottom])}}
|
||||||
[quo/floating-shell-button
|
style/scroll-to-bottom-button
|
||||||
{:scroll-to-bottom {:on-press scroll-to-bottom-fn}}
|
scroll-down-button-opacity]]))
|
||||||
style/scroll-to-bottom-button])]))
|
|
||||||
|
|
||||||
(defn shell-button
|
(defn shell-button
|
||||||
[state scroll-to-bottom-fn show-floating-scroll-down-button?]
|
[state chat-list-scroll-y window-height]
|
||||||
[:f> f-shell-button state scroll-to-bottom-fn show-floating-scroll-down-button?])
|
[:f> f-shell-button state chat-list-scroll-y window-height])
|
||||||
|
|
|
@ -193,7 +193,8 @@
|
||||||
:record-permission? (reagent/atom true)
|
:record-permission? (reagent/atom true)
|
||||||
:recording? (reagent/atom false)
|
:recording? (reagent/atom false)
|
||||||
:first-level? (reagent/atom true)
|
:first-level? (reagent/atom true)
|
||||||
:menu-items (reagent/atom selection/first-level-menu-items)})
|
:menu-items (reagent/atom selection/first-level-menu-items)
|
||||||
|
:composer-focused? (reanimated/use-shared-value false)})
|
||||||
|
|
||||||
(defn init-subs
|
(defn init-subs
|
||||||
[]
|
[]
|
||||||
|
|
|
@ -30,8 +30,7 @@
|
||||||
|
|
||||||
(defn sheet-component
|
(defn sheet-component
|
||||||
[{:keys [insets
|
[{:keys [insets
|
||||||
scroll-to-bottom-fn
|
chat-list-scroll-y
|
||||||
show-floating-scroll-down-button?
|
|
||||||
window-height
|
window-height
|
||||||
blur-height
|
blur-height
|
||||||
opacity
|
opacity
|
||||||
|
@ -89,7 +88,7 @@
|
||||||
(:edit subscriptions)]
|
(:edit subscriptions)]
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style style/composer-sheet-and-jump-to-container}
|
{:style style/composer-sheet-and-jump-to-container}
|
||||||
[sub-view/shell-button state scroll-to-bottom-fn show-floating-scroll-down-button?]
|
[sub-view/shell-button state chat-list-scroll-y window-height]
|
||||||
[gesture/gesture-detector
|
[gesture/gesture-detector
|
||||||
{:gesture
|
{:gesture
|
||||||
(drag-gesture/drag-gesture props state animations dimensions keyboard-shown)}
|
(drag-gesture/drag-gesture props state animations dimensions keyboard-shown)}
|
||||||
|
@ -114,42 +113,39 @@
|
||||||
:menu-items @(:menu-items state)
|
:menu-items @(:menu-items state)
|
||||||
:style (style/input-view state)}
|
:style (style/input-view state)}
|
||||||
[rn/text-input
|
[rn/text-input
|
||||||
{:ref #(reset! (:input-ref props) %)
|
{:ref #(reset! (:input-ref props) %)
|
||||||
:default-value @(:text-value state)
|
:default-value @(:text-value state)
|
||||||
:on-focus
|
:on-focus #(handler/focus props state animations dimensions)
|
||||||
#(handler/focus props state animations dimensions show-floating-scroll-down-button?)
|
:on-blur #(handler/blur state animations dimensions subscriptions)
|
||||||
:on-blur #(handler/blur state animations dimensions subscriptions)
|
:on-content-size-change #(handler/content-size-change %
|
||||||
:on-content-size-change #(handler/content-size-change %
|
state
|
||||||
state
|
animations
|
||||||
animations
|
dimensions
|
||||||
dimensions
|
(or keyboard-shown
|
||||||
(or keyboard-shown
|
(:edit subscriptions)))
|
||||||
(:edit subscriptions)))
|
:on-scroll #(handler/scroll % props state animations dimensions)
|
||||||
:on-scroll #(handler/scroll % props state animations dimensions)
|
:on-change-text #(handler/change-text % props state)
|
||||||
:on-change-text #(handler/change-text % props state)
|
:on-selection-change #(handler/selection-change % props state)
|
||||||
:on-selection-change #(handler/selection-change % props state)
|
:on-selection #(selection/on-selection % props state)
|
||||||
:on-selection #(selection/on-selection % props state)
|
:keyboard-appearance (quo.theme/theme-value :light :dark)
|
||||||
:keyboard-appearance (quo.theme/theme-value :light :dark)
|
|
||||||
:max-font-size-multiplier 1
|
:max-font-size-multiplier 1
|
||||||
:multiline true
|
:multiline true
|
||||||
:placeholder (i18n/label :t/type-something)
|
:placeholder (i18n/label :t/type-something)
|
||||||
:placeholder-text-color (colors/theme-colors colors/neutral-40 colors/neutral-50)
|
:placeholder-text-color (colors/theme-colors colors/neutral-40 colors/neutral-50)
|
||||||
:style (style/input-text props
|
:style (style/input-text props
|
||||||
state
|
state
|
||||||
{:max-height max-height
|
{:max-height max-height
|
||||||
:theme theme})
|
:theme theme})
|
||||||
:max-length constants/max-text-size
|
:max-length constants/max-text-size
|
||||||
:accessibility-label :chat-message-input}]]]
|
:accessibility-label :chat-message-input}]]]
|
||||||
[:<>
|
[:<>
|
||||||
[gradients/view props state animations show-bottom-gradient?]
|
[gradients/view props state animations show-bottom-gradient?]
|
||||||
[link-preview/view]
|
[link-preview/view]
|
||||||
[images/images-list]]
|
[images/images-list]]
|
||||||
[:f> actions/view props state animations window-height insets scroll-to-bottom-fn
|
[:f> actions/view props state animations window-height insets subscriptions]]]]]))
|
||||||
subscriptions]]]]]))
|
|
||||||
|
|
||||||
(defn f-composer
|
(defn f-composer
|
||||||
[{:keys [insets scroll-to-bottom-fn show-floating-scroll-down-button?
|
[{:keys [insets chat-list-scroll-y messages-list-on-layout-finished?]}]
|
||||||
messages-list-on-layout-finished?]}]
|
|
||||||
(let [window-height (:height (rn/get-window))
|
(let [window-height (:height (rn/get-window))
|
||||||
theme (quo.theme/use-theme-value)
|
theme (quo.theme/use-theme-value)
|
||||||
opacity (reanimated/use-shared-value 0)
|
opacity (reanimated/use-shared-value 0)
|
||||||
|
@ -159,8 +155,7 @@
|
||||||
(:bottom insets)))
|
(:bottom insets)))
|
||||||
extra-params {:insets insets
|
extra-params {:insets insets
|
||||||
:window-height window-height
|
:window-height window-height
|
||||||
:scroll-to-bottom-fn scroll-to-bottom-fn
|
:chat-list-scroll-y chat-list-scroll-y
|
||||||
:show-floating-scroll-down-button? show-floating-scroll-down-button?
|
|
||||||
:blur-height blur-height
|
:blur-height blur-height
|
||||||
:opacity opacity
|
:opacity opacity
|
||||||
:background-y background-y
|
:background-y background-y
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
(ns status-im.contexts.chat.messenger.messages.list.state)
|
(ns status-im.contexts.chat.messenger.messages.list.state)
|
||||||
|
|
||||||
|
(defonce messages-list-ref (atom nil))
|
||||||
(defonce first-not-visible-item (atom nil))
|
(defonce first-not-visible-item (atom nil))
|
||||||
|
|
||||||
(defonce scrolling (atom nil))
|
(defonce scrolling (atom nil))
|
||||||
|
|
|
@ -23,37 +23,16 @@
|
||||||
[utils.re-frame :as rf]
|
[utils.re-frame :as rf]
|
||||||
[utils.worklets.chat.messages :as worklets]))
|
[utils.worklets.chat.messages :as worklets]))
|
||||||
|
|
||||||
(defonce ^:const threshold-percentage-to-show-floating-scroll-down-button 75)
|
|
||||||
(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 min-message-height 32)
|
(defonce ^:const min-message-height 32)
|
||||||
(defonce messages-list-ref (atom nil))
|
|
||||||
|
|
||||||
(defn list-key-fn [{:keys [message-id value]}] (or message-id value))
|
(defn list-key-fn [{:keys [message-id value]}] (or message-id value))
|
||||||
(defn list-ref [ref] (reset! messages-list-ref ref))
|
(defn list-ref [ref] (reset! state/messages-list-ref ref))
|
||||||
|
|
||||||
(defn scroll-to-bottom
|
|
||||||
[]
|
|
||||||
(some-> ^js @messages-list-ref
|
|
||||||
(.scrollToOffset #js
|
|
||||||
{:animated true})))
|
|
||||||
|
|
||||||
(defn on-scroll-fn
|
|
||||||
[show-floating-scroll-down-button? distance-atom layout-height-atom]
|
|
||||||
(fn [y layout-height new-distance]
|
|
||||||
(let [threshold-height (* (/ layout-height 100)
|
|
||||||
threshold-percentage-to-show-floating-scroll-down-button)
|
|
||||||
reached-threshold? (> y threshold-height)]
|
|
||||||
(when (not= layout-height @layout-height-atom)
|
|
||||||
(reset! layout-height-atom layout-height))
|
|
||||||
(reset! distance-atom new-distance)
|
|
||||||
(when (not= reached-threshold? @show-floating-scroll-down-button?)
|
|
||||||
(rn/configure-next (:ease-in-ease-out rn/layout-animation-presets))
|
|
||||||
(reset! show-floating-scroll-down-button? reached-threshold?)))))
|
|
||||||
|
|
||||||
(defn on-viewable-items-changed
|
(defn on-viewable-items-changed
|
||||||
[e]
|
[e]
|
||||||
(when @messages-list-ref
|
(when @state/messages-list-ref
|
||||||
(reset! state/first-not-visible-item
|
(reset! state/first-not-visible-item
|
||||||
(when-let [last-visible-element (aget (oops/oget e "viewableItems")
|
(when-let [last-visible-element (aget (oops/oget e "viewableItems")
|
||||||
(dec (oops/oget e "viewableItems.length")))]
|
(dec (oops/oget e "viewableItems.length")))]
|
||||||
|
@ -61,7 +40,7 @@
|
||||||
;; Get first not visible element, if it's a datemark/gap
|
;; Get first not visible element, if it's a datemark/gap
|
||||||
;; we might add messages on receiving as they do not have
|
;; we might add messages on receiving as they do not have
|
||||||
;; a clock value, but usually it will be a message
|
;; a clock value, but usually it will be a message
|
||||||
first-not-visible (aget (oops/oget @messages-list-ref "props.data") (inc index))]
|
first-not-visible (aget (oops/oget @state/messages-list-ref "props.data") (inc index))]
|
||||||
(when (and first-not-visible
|
(when (and first-not-visible
|
||||||
(= :message (:type first-not-visible)))
|
(= :message (:type first-not-visible)))
|
||||||
first-not-visible))))))
|
first-not-visible))))))
|
||||||
|
@ -300,9 +279,16 @@
|
||||||
(reanimated/set-shared-value calculations-complete? true))
|
(reanimated/set-shared-value calculations-complete? true))
|
||||||
(js/setTimeout #(reset! messages-list-on-layout-finished? true) 1000)))
|
(js/setTimeout #(reset! messages-list-on-layout-finished? true) 1000)))
|
||||||
|
|
||||||
|
(defn on-scroll-fn
|
||||||
|
[distance-atom layout-height-atom]
|
||||||
|
(fn [layout-height new-distance]
|
||||||
|
(when (not= layout-height @layout-height-atom)
|
||||||
|
(reset! layout-height-atom layout-height))
|
||||||
|
(reset! distance-atom new-distance)))
|
||||||
|
|
||||||
(defn f-messages-list-content
|
(defn f-messages-list-content
|
||||||
[{:keys [insets distance-from-list-top content-height layout-height cover-bg-color distance-atom
|
[{:keys [insets distance-from-list-top content-height layout-height cover-bg-color distance-atom
|
||||||
show-floating-scroll-down-button? calculations-complete? messages-list-on-layout-finished?]}]
|
calculations-complete? messages-list-on-layout-finished? chat-list-scroll-y]}]
|
||||||
(let [theme (quo.theme/use-theme-value)
|
(let [theme (quo.theme/use-theme-value)
|
||||||
chat (rf/sub [:chats/current-chat-chat-view])
|
chat (rf/sub [:chats/current-chat-chat-view])
|
||||||
{:keys [keyboard-shown]} (hooks/use-keyboard)
|
{:keys [keyboard-shown]} (hooks/use-keyboard)
|
||||||
|
@ -354,9 +340,8 @@
|
||||||
:on-scroll (reanimated/use-animated-scroll-handler
|
:on-scroll (reanimated/use-animated-scroll-handler
|
||||||
(worklets/messages-list-on-scroll
|
(worklets/messages-list-on-scroll
|
||||||
distance-from-list-top
|
distance-from-list-top
|
||||||
(on-scroll-fn show-floating-scroll-down-button?
|
chat-list-scroll-y
|
||||||
distance-atom
|
(on-scroll-fn distance-atom layout-height)))
|
||||||
layout-height)))
|
|
||||||
:style {:background-color (colors/theme-colors colors/white
|
:style {:background-color (colors/theme-colors colors/white
|
||||||
colors/neutral-95
|
colors/neutral-95
|
||||||
theme)}
|
theme)}
|
||||||
|
|
|
@ -20,9 +20,9 @@
|
||||||
content-height (atom 0)
|
content-height (atom 0)
|
||||||
layout-height (atom 0)
|
layout-height (atom 0)
|
||||||
distance-atom (atom 0)
|
distance-atom (atom 0)
|
||||||
show-floating-scroll-down-button? (reagent/atom false)
|
|
||||||
messages-list-on-layout-finished? (reagent/atom false)
|
messages-list-on-layout-finished? (reagent/atom false)
|
||||||
distance-from-list-top (reanimated/use-shared-value 0)]
|
distance-from-list-top (reanimated/use-shared-value 0)
|
||||||
|
chat-list-scroll-y (reanimated/use-shared-value 0)]
|
||||||
[rn/keyboard-avoiding-view
|
[rn/keyboard-avoiding-view
|
||||||
{:style style/keyboard-avoiding-container
|
{:style style/keyboard-avoiding-container
|
||||||
:keyboard-vertical-offset (- (:bottom insets))}
|
:keyboard-vertical-offset (- (:bottom insets))}
|
||||||
|
@ -36,14 +36,13 @@
|
||||||
:distance-atom distance-atom
|
:distance-atom distance-atom
|
||||||
:calculations-complete? calculations-complete?
|
:calculations-complete? calculations-complete?
|
||||||
:distance-from-list-top distance-from-list-top
|
:distance-from-list-top distance-from-list-top
|
||||||
|
:chat-list-scroll-y chat-list-scroll-y
|
||||||
:messages-list-on-layout-finished? messages-list-on-layout-finished?
|
:messages-list-on-layout-finished? messages-list-on-layout-finished?
|
||||||
:cover-bg-color :turquoise
|
:cover-bg-color :turquoise}]
|
||||||
:show-floating-scroll-down-button? show-floating-scroll-down-button?}]
|
|
||||||
[composer.view/composer
|
[composer.view/composer
|
||||||
{:insets insets
|
{:insets insets
|
||||||
:scroll-to-bottom-fn list.view/scroll-to-bottom
|
:chat-list-scroll-y chat-list-scroll-y
|
||||||
:messages-list-on-layout-finished? messages-list-on-layout-finished?
|
:messages-list-on-layout-finished? messages-list-on-layout-finished?}]]))
|
||||||
:show-floating-scroll-down-button? show-floating-scroll-down-button?}]]))
|
|
||||||
|
|
||||||
(defn lazy-chat-screen
|
(defn lazy-chat-screen
|
||||||
[calculations-complete?]
|
[calculations-complete?]
|
||||||
|
|
|
@ -23,9 +23,10 @@
|
||||||
[props]
|
[props]
|
||||||
(.interpolateNavigationViewOpacity ^js messages-worklets (clj->js props)))
|
(.interpolateNavigationViewOpacity ^js messages-worklets (clj->js props)))
|
||||||
|
|
||||||
|
;;;; Messages List
|
||||||
(defn messages-list-on-scroll
|
(defn messages-list-on-scroll
|
||||||
[distance-from-list-top callback]
|
[distance-from-list-top chat-list-scroll-y callback]
|
||||||
(.messagesListOnScroll ^js messages-worklets distance-from-list-top callback))
|
(.messagesListOnScroll ^js messages-worklets distance-from-list-top chat-list-scroll-y callback))
|
||||||
|
|
||||||
;;;; Placeholder
|
;;;; Placeholder
|
||||||
(defn placeholder-opacity
|
(defn placeholder-opacity
|
||||||
|
@ -35,3 +36,16 @@
|
||||||
(defn placeholder-z-index
|
(defn placeholder-z-index
|
||||||
[calculations-complete?]
|
[calculations-complete?]
|
||||||
(.placeholderZIndex ^js messages-worklets calculations-complete?))
|
(.placeholderZIndex ^js messages-worklets calculations-complete?))
|
||||||
|
|
||||||
|
;;;; Common
|
||||||
|
(defn scroll-down-button-opacity
|
||||||
|
[chat-list-scroll-y composer-focused? window-height]
|
||||||
|
(.scrollDownButtonOpacity ^js messages-worklets chat-list-scroll-y composer-focused? window-height))
|
||||||
|
|
||||||
|
(defn jump-to-button-opacity
|
||||||
|
[scroll-down-button-opacity-sv composer-focused?]
|
||||||
|
(.jumpToButtonOpacity ^js messages-worklets scroll-down-button-opacity-sv composer-focused?))
|
||||||
|
|
||||||
|
(defn jump-to-button-position
|
||||||
|
[scroll-down-button-opacity-sv composer-focused?]
|
||||||
|
(.jumpToButtonPosition ^js messages-worklets scroll-down-button-opacity-sv composer-focused?))
|
||||||
|
|
Loading…
Reference in New Issue