[8556] fix - Last message jumps up after chat is opened
Signed-off-by: Andrey Shovkoplyas <motor4ik@gmail.com>
This commit is contained in:
parent
cb5768000a
commit
07dfc95658
|
@ -166,7 +166,8 @@
|
||||||
:on-error
|
:on-error
|
||||||
(fn [error]
|
(fn [error]
|
||||||
(log/error "can't remove a chat:" error))}]}
|
(log/error "can't remove a chat:" error))}]}
|
||||||
(navigation/navigate-to-cofx :home {}))
|
(when (not (= (:view-id db) :home))
|
||||||
|
(navigation/navigate-to-cofx :home {})))
|
||||||
(fx/merge cofx
|
(fx/merge cofx
|
||||||
(mailserver/remove-gaps chat-id)
|
(mailserver/remove-gaps chat-id)
|
||||||
(mailserver/remove-range chat-id)
|
(mailserver/remove-range chat-id)
|
||||||
|
@ -176,7 +177,8 @@
|
||||||
;; TODO: this is not accurate, if there's a pending contact
|
;; TODO: this is not accurate, if there's a pending contact
|
||||||
;; request it will not be sent anymore
|
;; request it will not be sent anymore
|
||||||
(transport.protocol/remove-chat chat-id)
|
(transport.protocol/remove-chat chat-id)
|
||||||
(navigation/navigate-to-cofx :home {}))))
|
(when (not (= (:view-id db) :home))
|
||||||
|
(navigation/navigate-to-cofx :home {})))))
|
||||||
|
|
||||||
(defn- unread-messages-number [chats]
|
(defn- unread-messages-number [chats]
|
||||||
(apply + (map :unviewed-messages-count chats)))
|
(apply + (map :unviewed-messages-count chats)))
|
||||||
|
|
|
@ -4,9 +4,10 @@
|
||||||
[status-im.utils.platform :as platform]))
|
[status-im.utils.platform :as platform]))
|
||||||
|
|
||||||
(defnstyle text-wrapper
|
(defnstyle text-wrapper
|
||||||
[{:keys [window-width height background-color opacity]}]
|
[{:keys [window-width height background-color opacity transform]}]
|
||||||
(cond-> {:flex-direction :row
|
(cond-> {:flex-direction :row
|
||||||
:justify-content :center
|
:justify-content :center
|
||||||
|
:transform [{:translateY transform}]
|
||||||
:opacity opacity
|
:opacity opacity
|
||||||
:background-color (or background-color colors/gray)
|
:background-color (or background-color colors/gray)
|
||||||
:height height}
|
:height height}
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
[status-im.utils.utils :as utils]
|
[status-im.utils.utils :as utils]
|
||||||
[status-im.utils.platform :as platform]))
|
[status-im.utils.platform :as platform]))
|
||||||
|
|
||||||
|
(def connectivity-bar-height 35)
|
||||||
|
(def neg-connectivity-bar-height (- connectivity-bar-height))
|
||||||
|
|
||||||
(defn easing [direction n]
|
(defn easing [direction n]
|
||||||
{:toValue n
|
{:toValue n
|
||||||
:easing ((if (= :in direction)
|
:easing ((if (= :in direction)
|
||||||
|
@ -52,6 +55,7 @@
|
||||||
[react/view {:style {:width parent-width
|
[react/view {:style {:width parent-width
|
||||||
:position :absolute
|
:position :absolute
|
||||||
:top -3
|
:top -3
|
||||||
|
:z-index 3
|
||||||
:height 3
|
:height 3
|
||||||
:background-color colors/white}}
|
:background-color colors/white}}
|
||||||
[react/animated-view {:style (animated-bar-style blue-bar-left-margin
|
[react/animated-view {:style (animated-bar-style blue-bar-left-margin
|
||||||
|
@ -62,40 +66,42 @@
|
||||||
colors/white)
|
colors/white)
|
||||||
:left (* 0.15 parent-width))}]]))
|
:left (* 0.15 parent-width))}]]))
|
||||||
|
|
||||||
(defonce show-connected? (reagent/atom true))
|
(def to-hide? (reagent/atom false))
|
||||||
|
|
||||||
(defn manage-visibility [connected? anim-opacity anim-height]
|
(defn manage-visibility [connected? anim-opacity anim-y]
|
||||||
(if connected?
|
(if connected?
|
||||||
(do (animation/start
|
(when @to-hide?
|
||||||
(animation/parallel
|
(animation/start
|
||||||
[(animation/timing anim-opacity
|
(animation/parallel
|
||||||
{:toValue 0
|
[(animation/timing anim-opacity
|
||||||
:delay 800
|
{:toValue 0
|
||||||
:duration 150
|
:delay 800
|
||||||
:easing (.-ease (animation/easing))
|
:duration 150
|
||||||
:useNativeDriver true})
|
:easing (.-ease (animation/easing))
|
||||||
(animation/timing anim-height
|
:useNativeDriver true})
|
||||||
{:toValue (if platform/desktop? 0 -35)
|
(animation/timing anim-y
|
||||||
:delay 800
|
{:toValue (if platform/desktop? 0 neg-connectivity-bar-height)
|
||||||
:duration 150
|
:delay 800
|
||||||
:easing (.-ease (animation/easing))
|
:duration 150
|
||||||
:useNativeDriver true})]))
|
:easing (.-ease (animation/easing))
|
||||||
(utils/set-timeout
|
:useNativeDriver true})])
|
||||||
#(reset! show-connected? false)
|
;; second param of start() - a callback that fires when animation stops
|
||||||
2000))
|
#(reset! to-hide? false)))
|
||||||
(do (reset! show-connected? true)
|
;; else
|
||||||
(animation/start
|
(animation/start
|
||||||
(animation/parallel
|
(animation/parallel
|
||||||
[(animation/timing anim-opacity
|
[(animation/timing anim-opacity
|
||||||
{:toValue 1
|
{:toValue 1
|
||||||
:duration 150
|
:duration 150
|
||||||
:easing (.-ease (animation/easing))
|
:easing (.-ease (animation/easing))
|
||||||
:useNativeDriver true})
|
:useNativeDriver true})
|
||||||
(animation/timing anim-height
|
(animation/timing anim-y
|
||||||
{:toValue (if platform/desktop? 35 0)
|
{:toValue (if platform/desktop? connectivity-bar-height 0)
|
||||||
:duration 150
|
:duration 150
|
||||||
:easing (.-ease (animation/easing))
|
:easing (.-ease (animation/easing))
|
||||||
:useNativeDriver true})])))))
|
:useNativeDriver true})])
|
||||||
|
;; second param of start() - a callback that fires when animation stops
|
||||||
|
#(reset! to-hide? true))))
|
||||||
|
|
||||||
(defn connectivity-status
|
(defn connectivity-status
|
||||||
[{:keys [connected?]} anim-translate-y]
|
[{:keys [connected?]} anim-translate-y]
|
||||||
|
@ -109,23 +115,22 @@
|
||||||
(manage-visibility (:connected? (reagent/props comp))
|
(manage-visibility (:connected? (reagent/props comp))
|
||||||
anim-opacity anim-translate-y))
|
anim-opacity anim-translate-y))
|
||||||
:reagent-render
|
:reagent-render
|
||||||
(fn [{:keys [view-id message on-press-fn
|
(fn [{:keys [view-id message on-press-fn connected? connecting?] :as opts}]
|
||||||
connected? connecting?] :as opts}]
|
|
||||||
[react/animated-view {:style (styles/text-wrapper
|
[react/animated-view {:style (styles/text-wrapper
|
||||||
(assoc opts
|
(assoc opts
|
||||||
:height (if platform/desktop?
|
:height (if platform/desktop?
|
||||||
anim-translate-y
|
anim-translate-y
|
||||||
35)
|
connectivity-bar-height)
|
||||||
:background-color (if connected?
|
:background-color (if connected?
|
||||||
colors/green
|
colors/green
|
||||||
colors/gray)
|
colors/gray)
|
||||||
|
;;TODO how does this affect desktop?
|
||||||
|
:transform anim-translate-y
|
||||||
:opacity anim-opacity
|
:opacity anim-opacity
|
||||||
:modal? (= view-id :chat-modal)))
|
:modal? (= view-id :chat-modal)))
|
||||||
:accessibility-label :connection-status-text}
|
:accessibility-label :connection-status-text}
|
||||||
(when connecting?
|
(when connecting?
|
||||||
[react/activity-indicator {:animated true
|
[react/activity-indicator {:color colors/white :margin-right 6}])
|
||||||
:color colors/white
|
|
||||||
:margin-right 6}])
|
|
||||||
(if (= message :mobile-network)
|
(if (= message :mobile-network)
|
||||||
[react/nested-text {:style styles/text
|
[react/nested-text {:style styles/text
|
||||||
:on-press on-press-fn}
|
:on-press on-press-fn}
|
||||||
|
@ -136,28 +141,60 @@
|
||||||
:on-press on-press-fn}
|
:on-press on-press-fn}
|
||||||
(i18n/label message)])])})))
|
(i18n/label message)])])})))
|
||||||
|
|
||||||
(defn connectivity-animation-wrapper [style anim-value & content]
|
|
||||||
(vec (concat
|
|
||||||
(if platform/desktop?
|
|
||||||
[react/view {:style {:flex 1}}]
|
|
||||||
[react/animated-view
|
|
||||||
{:style
|
|
||||||
(merge {:flex 1
|
|
||||||
:transform [{:translateY anim-value}]}
|
|
||||||
style)}])
|
|
||||||
content)))
|
|
||||||
|
|
||||||
(defview connectivity-view [anim-translate-y]
|
(defview connectivity-view [anim-translate-y]
|
||||||
(letsubs [status-properties [:connectivity/status-properties]
|
(letsubs [status-properties [:connectivity/status-properties]
|
||||||
view-id [:view-id]
|
view-id [:view-id]
|
||||||
window-width (reagent/atom 0)]
|
window-width (reagent/atom 0)]
|
||||||
|
{:component-will-mount
|
||||||
|
(fn []
|
||||||
|
(if (:connected? status-properties)
|
||||||
|
(animation/set-value anim-translate-y neg-connectivity-bar-height)
|
||||||
|
(animation/set-value anim-translate-y 0)))}
|
||||||
(let [{:keys [loading-indicator?]} status-properties]
|
(let [{:keys [loading-indicator?]} status-properties]
|
||||||
[react/view {:style {:align-items :stretch}
|
[react/view {:style {:align-items :stretch
|
||||||
|
:z-index 1}
|
||||||
:on-layout #(reset! window-width (-> % .-nativeEvent .-layout .-width))}
|
:on-layout #(reset! window-width (-> % .-nativeEvent .-layout .-width))}
|
||||||
(when loading-indicator?
|
(when loading-indicator?
|
||||||
[loading-indicator @window-width])
|
[loading-indicator @window-width])
|
||||||
|
;; This view below exists only to hide the connectivity-status bar when "connected".
|
||||||
|
;; Ideally connectivity-status bar would be hidden under "toolbar/toolbar",
|
||||||
|
;; but that has to be transparent(enven though it sits above the bar)
|
||||||
|
;; to show through the "loading-indicator"
|
||||||
|
;; TODO consider making the height the same height as the "toolbar/toolbar"
|
||||||
|
[react/view {:position :absolute
|
||||||
|
:top neg-connectivity-bar-height
|
||||||
|
:width @window-width
|
||||||
|
:z-index 2
|
||||||
|
:height connectivity-bar-height
|
||||||
|
:background-color colors/white}]
|
||||||
[connectivity-status
|
[connectivity-status
|
||||||
(merge status-properties
|
(merge status-properties
|
||||||
{:view-id view-id
|
{:view-id view-id
|
||||||
:window-width @window-width})
|
:window-width @window-width})
|
||||||
anim-translate-y]])))
|
anim-translate-y]])))
|
||||||
|
|
||||||
|
;; "push?" determines whether "content" gets pushed down when disconnected
|
||||||
|
;; like in :home view, or stays put like in :chat view
|
||||||
|
;; TODO determine-how-this-affects/fix desktop
|
||||||
|
(defn connectivity-animation-wrapper [style anim-value push? & content]
|
||||||
|
(vec (concat
|
||||||
|
(if platform/desktop?
|
||||||
|
[react/view {:style {:flex 1}}]
|
||||||
|
[react/animated-view
|
||||||
|
{:style (merge {:flex 1
|
||||||
|
:margin-bottom neg-connectivity-bar-height}
|
||||||
|
;; A translated view (connectivity-view in this case)
|
||||||
|
;; prevents touch interaction to component below
|
||||||
|
;; them. If we don't bring this view on the same level
|
||||||
|
;; or above as the translated view, the top
|
||||||
|
;; portion(same height as connectivity-view) of
|
||||||
|
;; "content" (which now occupies translated view's
|
||||||
|
;; natural[untranslated] position) becomes
|
||||||
|
;; unresponsive to touch
|
||||||
|
(when-not @to-hide?
|
||||||
|
{:z-index 1})
|
||||||
|
(if push?
|
||||||
|
{:transform [{:translateY anim-value}]}
|
||||||
|
{:transform [{:translateY neg-connectivity-bar-height}]})
|
||||||
|
style)}])
|
||||||
|
content)))
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
(:require [status-im.ui.components.colors :as colors]))
|
(:require [status-im.ui.components.colors :as colors]))
|
||||||
|
|
||||||
(def chat-view
|
(def chat-view
|
||||||
{:flex 1
|
{:flex 1})
|
||||||
:background-color colors/white})
|
|
||||||
|
|
||||||
(def toolbar-container
|
(def toolbar-container
|
||||||
{:flex 1
|
{:flex 1
|
||||||
|
@ -177,12 +176,6 @@
|
||||||
(def add-contact-close-icon
|
(def add-contact-close-icon
|
||||||
{:margin-right 12})
|
{:margin-right 12})
|
||||||
|
|
||||||
(def message-view-preview
|
|
||||||
{:flex 1
|
|
||||||
:align-items :center
|
|
||||||
:justify-content :center
|
|
||||||
:background-color :white})
|
|
||||||
|
|
||||||
(defn message-view-animated [opacity]
|
(defn message-view-animated [opacity]
|
||||||
{:opacity opacity
|
{:opacity opacity
|
||||||
:flex 1
|
:flex 1
|
||||||
|
@ -195,22 +188,6 @@
|
||||||
:padding-vertical 50
|
:padding-vertical 50
|
||||||
:margin-right 6})
|
:margin-right 6})
|
||||||
|
|
||||||
#_(defn intro-header-container
|
|
||||||
[height status no-messages]
|
|
||||||
(let [adjusted-height (if (< height 280) 324 height)]
|
|
||||||
(if (or no-messages (= status (or :loading :empty)))
|
|
||||||
{:flex 1
|
|
||||||
:flex-direction :column
|
|
||||||
:justify-content :center
|
|
||||||
:align-items :center
|
|
||||||
:height adjusted-height
|
|
||||||
:padding-horizontal 32}
|
|
||||||
{:flex 1
|
|
||||||
:flex-direction :column
|
|
||||||
:justify-content :center
|
|
||||||
:align-items :center
|
|
||||||
:padding-horizontal 32})))
|
|
||||||
|
|
||||||
(defn intro-header-container
|
(defn intro-header-container
|
||||||
[height status no-messages]
|
[height status no-messages]
|
||||||
(let [adjusted-height (if (< height 280) 324 height)]
|
(let [adjusted-height (if (< height 280) 324 height)]
|
||||||
|
|
|
@ -49,27 +49,6 @@
|
||||||
(list-selection/show {:title chat-name
|
(list-selection/show {:title chat-name
|
||||||
:options (actions/actions group-chat? chat-id public?)}))
|
:options (actions/actions group-chat? chat-id public?)}))
|
||||||
|
|
||||||
(defn chat-toolbar
|
|
||||||
[{:keys [chat-name group-chat chat-id contact]} public? modal?]
|
|
||||||
[react/view {:style {:z-index 100}}
|
|
||||||
[status-bar/status-bar (when modal? {:type :modal-white})]
|
|
||||||
[toolbar/toolbar
|
|
||||||
{:chat? true}
|
|
||||||
(if modal?
|
|
||||||
[toolbar/nav-button
|
|
||||||
(toolbar.actions/close toolbar.actions/default-handler)]
|
|
||||||
toolbar/nav-back-home)
|
|
||||||
[toolbar-content/toolbar-content-view]
|
|
||||||
(when-not modal?
|
|
||||||
[toolbar/actions
|
|
||||||
[{:icon :main-icons/more
|
|
||||||
:icon-opts {:color :black
|
|
||||||
:accessibility-label :chat-menu-button}
|
|
||||||
:handler #(on-options chat-id chat-name group-chat public?)}]])]
|
|
||||||
(when (and (not group-chat)
|
|
||||||
(not (contact.db/added? contact)))
|
|
||||||
[add-contact-bar chat-id])])
|
|
||||||
|
|
||||||
(defmulti message-row
|
(defmulti message-row
|
||||||
(fn [{{:keys [type]} :row}] type))
|
(fn [{{:keys [type]} :row}] type))
|
||||||
|
|
||||||
|
@ -90,7 +69,7 @@
|
||||||
|
|
||||||
(def animation-duration 200)
|
(def animation-duration 200)
|
||||||
|
|
||||||
(defview messages-view-animation [message-view]
|
(defview messages-view-animation [add-contact-bar message-view]
|
||||||
;; smooths out appearance of message-view
|
;; smooths out appearance of message-view
|
||||||
(letsubs [opacity (animation/create-value 0)]
|
(letsubs [opacity (animation/create-value 0)]
|
||||||
{:component-did-mount (fn [_]
|
{:component-did-mount (fn [_]
|
||||||
|
@ -100,19 +79,11 @@
|
||||||
{:toValue 1
|
{:toValue 1
|
||||||
:duration animation-duration
|
:duration animation-duration
|
||||||
:useNativeDriver true})))}
|
:useNativeDriver true})))}
|
||||||
[react/with-activity-indicator
|
(if platform/desktop?
|
||||||
{:style style/message-view-preview
|
message-view
|
||||||
:preview [react/view style/message-view-preview]}
|
[react/animated-view {:style (style/message-view-animated opacity)}
|
||||||
[react/touchable-without-feedback
|
add-contact-bar
|
||||||
{:on-press (fn [_]
|
message-view])))
|
||||||
(re-frame/dispatch [:chat.ui/set-chat-ui-props {:messages-focused? true
|
|
||||||
:show-stickers? false}])
|
|
||||||
(when-not platform/desktop?
|
|
||||||
(react/dismiss-keyboard!)))}
|
|
||||||
(if platform/desktop?
|
|
||||||
message-view
|
|
||||||
[react/animated-view {:style (style/message-view-animated opacity)}
|
|
||||||
message-view])]]))
|
|
||||||
|
|
||||||
(defn tribute-to-talk-header
|
(defn tribute-to-talk-header
|
||||||
[name]
|
[name]
|
||||||
|
@ -354,8 +325,7 @@
|
||||||
:input-focused? false}]))}
|
:input-focused? false}]))}
|
||||||
(let [no-messages (empty? messages)
|
(let [no-messages (empty? messages)
|
||||||
flat-list-conf
|
flat-list-conf
|
||||||
{:style {:margin-bottom -35}
|
{:data messages
|
||||||
:data messages
|
|
||||||
:ref #(reset! messages-list-ref %)
|
:ref #(reset! messages-list-ref %)
|
||||||
:footer [chat-intro-header-container chat no-messages]
|
:footer [chat-intro-header-container chat no-messages]
|
||||||
:key-fn #(or (:message-id %) (:value %))
|
:key-fn #(or (:message-id %) (:value %))
|
||||||
|
@ -427,39 +397,52 @@
|
||||||
:list-ref messages-list-ref}]))]]])))
|
:list-ref messages-list-ref}]))]]])))
|
||||||
|
|
||||||
(defview chat-root [modal?]
|
(defview chat-root [modal?]
|
||||||
(letsubs [{:keys [public? chat-id show-input?] :as current-chat}
|
(letsubs [{:keys [public? chat-id chat-name show-input? group-chat contact] :as current-chat}
|
||||||
[:chats/current-chat]
|
[:chats/current-chat]
|
||||||
current-chat-id [:chats/current-chat-id]
|
current-chat-id [:chats/current-chat-id]
|
||||||
show-message-options? [:chats/current-chat-ui-prop :show-message-options?]
|
show-message-options? [:chats/current-chat-ui-prop :show-message-options?]
|
||||||
show-stickers? [:chats/current-chat-ui-prop :show-stickers?]
|
show-stickers? [:chats/current-chat-ui-prop :show-stickers?]
|
||||||
two-pane-ui-enabled? [:two-pane-ui-enabled?]
|
two-pane-ui-enabled? [:two-pane-ui-enabled?]
|
||||||
anim-translate-y (animation/create-value (if two-pane-ui-enabled? 0 -35))]
|
anim-translate-y (animation/create-value
|
||||||
;; this check of current-chat-id is necessary only because in a fresh public chat creation sometimes
|
(if two-pane-ui-enabled? 0 connectivity/neg-connectivity-bar-height))]
|
||||||
;; this component renders before current-chat-id is set to current chat-id. Hence further down in sub
|
[react/view {:style style/chat-view
|
||||||
;; components (e.g. chat-toolbar) there can be a brief visual inconsistancy like showing 'add contact'
|
:on-layout (fn [e]
|
||||||
;; in public chat
|
(re-frame/dispatch [:set :layout-height (-> e .-nativeEvent .-layout .-height)]))}
|
||||||
(when (= chat-id current-chat-id)
|
^{:key current-chat-id}
|
||||||
[react/view {:style style/chat-view
|
[status-bar/status-bar (when modal? {:type :modal-white})]
|
||||||
:on-layout (fn [e]
|
[toolbar/toolbar
|
||||||
(re-frame/dispatch [:set :layout-height (-> e .-nativeEvent .-layout .-height)]))}
|
{:chat? true
|
||||||
^{:key current-chat-id}
|
:style {:z-index 2}}
|
||||||
[chat-toolbar current-chat public? modal?]
|
(if modal?
|
||||||
(when-not two-pane-ui-enabled?
|
[toolbar/nav-button
|
||||||
[connectivity/connectivity-view anim-translate-y])
|
(toolbar.actions/close toolbar.actions/default-handler)]
|
||||||
[connectivity/connectivity-animation-wrapper
|
toolbar/nav-back-home)
|
||||||
{}
|
[toolbar-content/toolbar-content-view]
|
||||||
anim-translate-y
|
(when-not modal?
|
||||||
[messages-view-animation
|
[toolbar/actions
|
||||||
;;TODO(kozieiev) : When FlatList in react-native-desktop become viable it should be used instead of optimized ScrollView for chat
|
[{:icon :main-icons/more
|
||||||
(if platform/desktop?
|
:icon-opts {:color :black
|
||||||
[messages-view-desktop current-chat modal?]
|
:accessibility-label :chat-menu-button}
|
||||||
[messages-view current-chat modal?])]]
|
:handler #(on-options chat-id chat-name group-chat public?)}]])]
|
||||||
(when show-input?
|
(when-not two-pane-ui-enabled?
|
||||||
[input/container])
|
[connectivity/connectivity-view anim-translate-y])
|
||||||
(when show-stickers?
|
[connectivity/connectivity-animation-wrapper
|
||||||
[stickers/stickers-view])
|
{}
|
||||||
(when show-message-options?
|
anim-translate-y
|
||||||
[message-options/view])])))
|
false
|
||||||
|
[messages-view-animation
|
||||||
|
(if (and (= chat-id current-chat-id) (not group-chat) (not (contact.db/added? contact)))
|
||||||
|
[add-contact-bar chat-id])
|
||||||
|
;;TODO(kozieiev) : When FlatList in react-native-desktop become viable it should be used instead of optimized ScrollView for chat
|
||||||
|
(if platform/desktop?
|
||||||
|
[messages-view-desktop current-chat modal?]
|
||||||
|
[messages-view current-chat modal?])]]
|
||||||
|
(when show-input?
|
||||||
|
[input/container])
|
||||||
|
(when show-stickers?
|
||||||
|
[stickers/stickers-view])
|
||||||
|
(when show-message-options?
|
||||||
|
[message-options/view])]))
|
||||||
|
|
||||||
(defview chat []
|
(defview chat []
|
||||||
[chat-root false])
|
[chat-root false])
|
||||||
|
|
|
@ -254,7 +254,7 @@
|
||||||
[message (:text content) (= from current-public-key)
|
[message (:text content) (= from current-public-key)
|
||||||
(assoc message-obj :group-chat group-chat
|
(assoc message-obj :group-chat group-chat
|
||||||
:current-public-key current-public-key)]))]]
|
:current-public-key current-public-key)]))]]
|
||||||
[connectivity/connectivity-view]])))
|
[connectivity/connectivity-view nil]])))
|
||||||
|
|
||||||
(views/defview send-button [inp-ref disconnected?]
|
(views/defview send-button [inp-ref disconnected?]
|
||||||
(views/letsubs [{:keys [input-text]} [:chats/current-chat]]
|
(views/letsubs [{:keys [input-text]} [:chats/current-chat]]
|
||||||
|
|
|
@ -51,22 +51,31 @@
|
||||||
(defonce search-input-state
|
(defonce search-input-state
|
||||||
(reagent/atom {:show? false
|
(reagent/atom {:show? false
|
||||||
:height (animation/create-value
|
:height (animation/create-value
|
||||||
(- styles/search-input-height))}))
|
(- styles/search-input-height))
|
||||||
|
:to-hide? false}))
|
||||||
|
|
||||||
(defn show-search!
|
(defn show-search!
|
||||||
[]
|
[]
|
||||||
(swap! search-input-state assoc :show? true)
|
(when-not (:to-hide? @search-input-state)
|
||||||
(animation/start
|
(swap! search-input-state assoc :show? true)
|
||||||
(animation/timing (:height @search-input-state)
|
(animation/start
|
||||||
{:toValue 0
|
(animation/timing (:height @search-input-state)
|
||||||
:duration 350
|
{:toValue 0
|
||||||
:easing (.out (animation/easing)
|
:duration 350
|
||||||
(.-quad (animation/easing)))
|
:easing (.out (animation/easing)
|
||||||
:useNativeDriver true})))
|
(.-quad (animation/easing)))
|
||||||
|
:useNativeDriver true})
|
||||||
|
#(swap! search-input-state assoc :to-hide? true))))
|
||||||
|
|
||||||
|
(defn set-search-state-visible!
|
||||||
|
[visible?]
|
||||||
|
(swap! search-input-state assoc :show? visible?)
|
||||||
|
(swap! search-input-state assoc :to-hide? visible?)
|
||||||
|
(animation/set-value (:height @search-input-state)
|
||||||
|
(if visible? 0 (- styles/search-input-height))))
|
||||||
|
|
||||||
(defn reset-height []
|
(defn reset-height []
|
||||||
(animation/set-value (:height @search-input-state)
|
(set-search-state-visible! false))
|
||||||
(- styles/search-input-height)))
|
|
||||||
|
|
||||||
(defn hide-search!
|
(defn hide-search!
|
||||||
[]
|
[]
|
||||||
|
@ -79,24 +88,16 @@
|
||||||
:duration 350
|
:duration 350
|
||||||
:easing (.in (animation/easing)
|
:easing (.in (animation/easing)
|
||||||
(.-quad (animation/easing)))
|
(.-quad (animation/easing)))
|
||||||
:useNativeDriver true})))
|
:useNativeDriver true})
|
||||||
|
#(swap! search-input-state assoc :to-hide? false)))
|
||||||
(defn set-search-state-visible!
|
|
||||||
[visible?]
|
|
||||||
(swap! search-input-state assoc :show? visible?)
|
|
||||||
(animation/set-value (:height @search-input-state)
|
|
||||||
(if visible?
|
|
||||||
styles/search-input-height
|
|
||||||
0)))
|
|
||||||
|
|
||||||
(defn search-input-wrapper
|
(defn search-input-wrapper
|
||||||
[search-filter]
|
[search-filter]
|
||||||
(reagent/create-class
|
(reagent/create-class
|
||||||
{:component-will-unmount
|
{:component-will-unmount
|
||||||
#(set-search-state-visible! false)
|
#(set-search-state-visible! (:to-hide? @search-input-state))
|
||||||
:component-did-mount
|
:component-did-mount
|
||||||
#(when search-filter
|
#(set-search-state-visible! (:to-hide? @search-input-state))
|
||||||
(set-search-state-visible! true))
|
|
||||||
:reagent-render
|
:reagent-render
|
||||||
(fn [search-filter]
|
(fn [search-filter]
|
||||||
[search-input search-filter
|
[search-input search-filter
|
||||||
|
|
|
@ -185,13 +185,15 @@
|
||||||
:margin-horizontal 32
|
:margin-horizontal 32
|
||||||
:color colors/gray})
|
:color colors/gray})
|
||||||
|
|
||||||
(def action-button-container
|
(defn action-button-container [home-width]
|
||||||
{:position :absolute
|
{:position :absolute
|
||||||
|
:z-index 2
|
||||||
:align-items :center
|
:align-items :center
|
||||||
:bottom (+ tabs.styles/tabs-diff (cond
|
:bottom (+ tabs.styles/tabs-diff (cond
|
||||||
platform/ios? 16
|
platform/ios? 16
|
||||||
platform/android? 0
|
platform/android? 0
|
||||||
platform/desktop? 6))
|
platform/desktop? 6))
|
||||||
|
:left (- (/ home-width 2) 20)
|
||||||
:width 40
|
:width 40
|
||||||
:height 40})
|
:height 40})
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
:label (i18n/label :t/get-started)}]]])
|
:label (i18n/label :t/get-started)}]]])
|
||||||
|
|
||||||
(defn home-empty-view []
|
(defn home-empty-view []
|
||||||
|
(filter.views/reset-height)
|
||||||
[react/view styles/no-chats
|
[react/view styles/no-chats
|
||||||
[react/i18n-text {:style styles/no-chats-text :key :no-recent-chats}]
|
[react/i18n-text {:style styles/no-chats-text :key :no-recent-chats}]
|
||||||
[react/view {:align-items :center :margin-top 20}
|
[react/view {:align-items :center :margin-top 20}
|
||||||
|
@ -62,14 +63,13 @@
|
||||||
(defn home-items-view [_ _ _ search-input-state]
|
(defn home-items-view [_ _ _ search-input-state]
|
||||||
(let [previous-touch (reagent/atom nil)
|
(let [previous-touch (reagent/atom nil)
|
||||||
scrolling-from-top? (reagent/atom true)]
|
scrolling-from-top? (reagent/atom true)]
|
||||||
(filter.views/reset-height)
|
|
||||||
(fn [search-filter chats all-home-items]
|
(fn [search-filter chats all-home-items]
|
||||||
(if (not-empty search-filter)
|
(if (not-empty search-filter)
|
||||||
[filter.views/home-filtered-items-list chats]
|
[filter.views/home-filtered-items-list chats]
|
||||||
[react/animated-view
|
[react/animated-view
|
||||||
(merge {:style {:flex 1
|
(merge {:style {:flex 1
|
||||||
:margin-bottom -35
|
|
||||||
:background-color :white
|
:background-color :white
|
||||||
|
:margin-bottom (- styles/search-input-height)
|
||||||
:transform [{:translateY (:height @search-input-state)}]}}
|
:transform [{:translateY (:height @search-input-state)}]}}
|
||||||
(when @scrolling-from-top?
|
(when @scrolling-from-top?
|
||||||
{:on-start-should-set-responder-capture
|
{:on-start-should-set-responder-capture
|
||||||
|
@ -86,13 +86,13 @@
|
||||||
current-timestamp (.-timestamp (.-nativeEvent event))
|
current-timestamp (.-timestamp (.-nativeEvent event))
|
||||||
[previous-position previous-timestamp] @previous-touch]
|
[previous-position previous-timestamp] @previous-touch]
|
||||||
(when (and previous-position
|
(when (and previous-position
|
||||||
|
(not (:show? @search-input-state))
|
||||||
(> 100 (- current-timestamp previous-timestamp))
|
(> 100 (- current-timestamp previous-timestamp))
|
||||||
(< 10 (- current-position
|
(< 10 (- current-position
|
||||||
previous-position)))
|
previous-position)))
|
||||||
(filter.views/show-search!)))
|
(filter.views/show-search!)))
|
||||||
false)}))
|
false)}))
|
||||||
[list/flat-list {:style {:margin-bottom (- styles/search-input-height)}
|
[list/flat-list {:data all-home-items
|
||||||
:data all-home-items
|
|
||||||
:key-fn first
|
:key-fn first
|
||||||
:footer [react/view
|
:footer [react/view
|
||||||
{:style {:height tabs.styles/tabs-diff
|
{:style {:height tabs.styles/tabs-diff
|
||||||
|
@ -105,13 +105,13 @@
|
||||||
:render-fn
|
:render-fn
|
||||||
(fn [home-item]
|
(fn [home-item]
|
||||||
[inner-item/home-list-item home-item])}]
|
[inner-item/home-list-item home-item])}]
|
||||||
(when (:show? @search-input-state)
|
(when (:to-hide? @search-input-state)
|
||||||
[react/view {:width 1
|
[react/view {:width 1
|
||||||
:height styles/search-input-height}])]))))
|
:height styles/search-input-height}])]))))
|
||||||
|
|
||||||
(views/defview home-action-button []
|
(views/defview home-action-button [home-width]
|
||||||
(views/letsubs [logging-in? [:multiaccounts/login]]
|
(views/letsubs [logging-in? [:multiaccounts/login]]
|
||||||
[react/view styles/action-button-container
|
[react/view (styles/action-button-container home-width)
|
||||||
[react/touchable-highlight {:accessibility-label :new-chat-button
|
[react/touchable-highlight {:accessibility-label :new-chat-button
|
||||||
:on-press (when-not logging-in? #(re-frame/dispatch [:bottom-sheet/show-sheet :add-new {}]))}
|
:on-press (when-not logging-in? #(re-frame/dispatch [:bottom-sheet/show-sheet :add-new {}]))}
|
||||||
[react/view styles/action-button
|
[react/view styles/action-button
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
|
|
||||||
(views/defview home [loading?]
|
(views/defview home [loading?]
|
||||||
(views/letsubs
|
(views/letsubs
|
||||||
[anim-translate-y (animation/create-value -35)
|
[anim-translate-y (animation/create-value connectivity/neg-connectivity-bar-height)
|
||||||
{:keys [search-filter chats all-home-items]} [:home-items]
|
{:keys [search-filter chats all-home-items]} [:home-items]
|
||||||
window-width [:dimensions/window-width]
|
window-width [:dimensions/window-width]
|
||||||
two-pane-ui-enabled? [:two-pane-ui-enabled?]]
|
two-pane-ui-enabled? [:two-pane-ui-enabled?]]
|
||||||
|
@ -136,41 +136,36 @@
|
||||||
(when two-pane-ui-enabled?
|
(when two-pane-ui-enabled?
|
||||||
{:border-right-width 1 :border-right-color colors/gray-light}))
|
{:border-right-width 1 :border-right-color colors/gray-light}))
|
||||||
[status-bar/status-bar {:type :main}]
|
[status-bar/status-bar {:type :main}]
|
||||||
[react/keyboard-avoiding-view {:style {:flex 1
|
[react/keyboard-avoiding-view {:style {:flex 1}
|
||||||
:align-items :center}
|
|
||||||
:on-layout (fn [e]
|
:on-layout (fn [e]
|
||||||
(re-frame/dispatch
|
(re-frame/dispatch
|
||||||
[:set-once :content-layout-height
|
[:set-once :content-layout-height
|
||||||
(-> e .-nativeEvent .-layout .-height)]))}
|
(-> e .-nativeEvent .-layout .-height)]))}
|
||||||
[react/view {:style {:flex 1
|
[toolbar/toolbar {:style {:z-index 2}} nil [toolbar/content-title (i18n/label :t/chat)]]
|
||||||
:align-self :stretch}}
|
;; toolbar, connectivity-view, cannectivity-animation-wrapper are expected
|
||||||
[toolbar/toolbar nil nil [toolbar/content-title (i18n/label :t/chat)]]
|
;; to be next to each other as siblings for them to work effctively.
|
||||||
[les-debug-info]
|
;; les-debug-info being here could disrupt that. Assuming its purpose is
|
||||||
(cond loading?
|
;; debug only, commenting it out for now.
|
||||||
[react/view {:style {:flex 1
|
;; [les-debug-info]
|
||||||
:justify-content :center
|
[connectivity/connectivity-view anim-translate-y]
|
||||||
:align-items :center}}
|
[connectivity/connectivity-animation-wrapper
|
||||||
[connectivity/connectivity-view anim-translate-y]
|
{}
|
||||||
[connectivity/connectivity-animation-wrapper
|
anim-translate-y
|
||||||
{}
|
true
|
||||||
anim-translate-y
|
(if loading?
|
||||||
[react/activity-indicator {:flex 1
|
[react/activity-indicator {:flex 1
|
||||||
:animating true}]]] :else
|
:animating true}]
|
||||||
[react/view {:style {:flex 1}}
|
[react/view {:flex 1}
|
||||||
[connectivity/connectivity-view anim-translate-y]
|
[filter.views/search-input-wrapper search-filter]
|
||||||
[connectivity/connectivity-animation-wrapper
|
(if (and (not search-filter)
|
||||||
{}
|
(empty? all-home-items))
|
||||||
anim-translate-y
|
[home-empty-view]
|
||||||
[filter.views/search-input-wrapper search-filter]
|
[home-items-view
|
||||||
(if (and (not search-filter)
|
search-filter
|
||||||
(empty? all-home-items))
|
chats
|
||||||
[home-empty-view]
|
all-home-items
|
||||||
[home-items-view
|
filter.views/search-input-state])])]
|
||||||
search-filter
|
[home-action-button home-width]]])))
|
||||||
chats
|
|
||||||
all-home-items
|
|
||||||
filter.views/search-input-state])]])]
|
|
||||||
[home-action-button]]])))
|
|
||||||
|
|
||||||
(views/defview home-wrapper []
|
(views/defview home-wrapper []
|
||||||
(views/letsubs [loading? [:chats/loading?]]
|
(views/letsubs [loading? [:chats/loading?]]
|
||||||
|
|
Loading…
Reference in New Issue