Move animation to views
This commit is contained in:
parent
217f0f93d8
commit
c229902a77
|
@ -51,7 +51,7 @@
|
|||
(register-handler :start-cancel-command
|
||||
(fn [db _]
|
||||
(if (commands/get-chat-command-to-msg-id db)
|
||||
(dispatch [:animate-cancel-command #(dispatch [:cancel-command])])
|
||||
(dispatch [:animate-cancel-command])
|
||||
(dispatch [:cancel-command #(dispatch [:cancel-command])]))
|
||||
db))
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
(ns status-im.chat.handlers.animation
|
||||
(:require [re-frame.core :refer [register-handler after dispatch]]
|
||||
[status-im.components.animation :as anim]
|
||||
[status-im.components.drag-drop :as drag]
|
||||
[status-im.models.commands :as commands]
|
||||
[status-im.handlers.content-suggestions :refer [get-content-suggestions]]
|
||||
|
@ -15,56 +14,30 @@
|
|||
(fn [db _]
|
||||
(assoc-in db [:animations :commands-input-is-switching?] false)))
|
||||
|
||||
(defn animate-cancel-command! [{{:keys [response-height-anim-value
|
||||
message-input-buttons-scale
|
||||
message-input-offset
|
||||
messages-offset-anim-value]} :animations}
|
||||
[_ on-animation-stop]]
|
||||
(let [height-to-value zero-height]
|
||||
(anim/start (anim/spring response-height-anim-value {:toValue height-to-value})
|
||||
(fn []
|
||||
(dispatch [:finish-animate-cancel-command])
|
||||
(on-animation-stop)))
|
||||
(anim/start (anim/timing message-input-buttons-scale {:toValue 1
|
||||
:duration response-input-hiding-duration}))
|
||||
(anim/start (anim/timing message-input-offset {:toValue 0
|
||||
:duration response-input-hiding-duration}))
|
||||
(anim/start (anim/spring messages-offset-anim-value {:toValue 0}))))
|
||||
|
||||
(register-handler :animate-cancel-command
|
||||
(after animate-cancel-command!)
|
||||
(fn [db _]
|
||||
(let [hiding? (get-in db [:animations :commands-input-is-switching?])]
|
||||
(if-not hiding?
|
||||
(assoc-in db [:animations :commands-input-is-switching?] true)
|
||||
(-> db
|
||||
(assoc-in [:animations :commands-input-is-switching?] true)
|
||||
(assoc-in [:animations :message-input-buttons-scale] 1)
|
||||
(assoc-in [:animations :message-input-offset] 0)
|
||||
(assoc-in [:animations :to-response-height] zero-height)
|
||||
(assoc-in [:animations :messages-offset] 0))
|
||||
db))))
|
||||
|
||||
(register-handler :finish-animate-response-resize
|
||||
(fn [db _]
|
||||
(let [fixed (get-in db [:animations :response-height-fixed])]
|
||||
(let [fixed (get-in db [:animations :to-response-height])]
|
||||
(-> db
|
||||
(assoc-in [:animations :response-height] fixed)
|
||||
(assoc-in [:animations :response-height-current] fixed)
|
||||
(assoc-in [:animations :response-resize?] false)))))
|
||||
|
||||
(register-handler :set-response-height
|
||||
(fn [db [_ value]]
|
||||
(assoc-in db [:animations :response-height] value)))
|
||||
|
||||
(defn animate-response-resize! [{{height-anim-value :response-height-anim-value
|
||||
from :response-height
|
||||
to :response-height-fixed} :animations}]
|
||||
(anim/remove-all-listeners height-anim-value)
|
||||
(anim/set-value height-anim-value from)
|
||||
(anim/add-listener height-anim-value
|
||||
(fn [val]
|
||||
(dispatch [:set-response-height (anim/value val)])))
|
||||
(anim/start (anim/spring height-anim-value {:toValue to})
|
||||
(fn []
|
||||
(anim/remove-all-listeners height-anim-value)
|
||||
(dispatch [:finish-animate-response-resize]))))
|
||||
(assoc-in db [:animations :response-height-current] value)))
|
||||
|
||||
(register-handler :animate-response-resize
|
||||
(after animate-response-resize!)
|
||||
(fn [db _]
|
||||
(assoc-in db [:animations :response-resize?] true)))
|
||||
|
||||
|
@ -80,30 +53,21 @@
|
|||
(min response-height-normal (+ suggestions-height request-info-height)))))
|
||||
|
||||
(defn update-response-height [db]
|
||||
(assoc-in db [:animations :response-height-fixed] (get-response-height db)))
|
||||
(assoc-in db [:animations :to-response-height] (get-response-height db)))
|
||||
|
||||
(register-handler :finish-show-response!
|
||||
(register-handler :finish-show-response
|
||||
(fn [db _]
|
||||
(assoc-in db [:animations :commands-input-is-switching?] false)))
|
||||
|
||||
(defn animate-show-response! [{{scale-anim-value :message-input-buttons-scale
|
||||
input-offset-anim-value :message-input-offset
|
||||
messages-offset-anim-value :messages-offset-anim-value} :animations}]
|
||||
(let [to-value 0.1]
|
||||
(anim/start (anim/timing scale-anim-value {:toValue to-value
|
||||
:duration response-input-hiding-duration})
|
||||
#(dispatch [:finish-show-response!]))
|
||||
(anim/start (anim/timing input-offset-anim-value {:toValue -40
|
||||
:duration response-input-hiding-duration}))
|
||||
(anim/start (anim/spring messages-offset-anim-value {:toValue request-info-height}))))
|
||||
|
||||
(register-handler :animate-show-response
|
||||
(after animate-show-response!)
|
||||
(fn [db _]
|
||||
(dispatch [:animate-response-resize])
|
||||
(-> db
|
||||
(assoc-in [:animations :commands-input-is-switching?] true)
|
||||
(assoc-in [:animations :response-height] zero-height)
|
||||
(assoc-in [:animations :response-height-current] zero-height)
|
||||
(assoc-in [:animations :message-input-buttons-scale] 0.1)
|
||||
(assoc-in [:animations :message-input-offset] -40)
|
||||
(assoc-in [:animations :messages-offset] request-info-height)
|
||||
(update-response-height))))
|
||||
|
||||
(register-handler :set-response-max-height
|
||||
|
@ -112,12 +76,12 @@
|
|||
|
||||
(register-handler :on-drag-response
|
||||
(fn [db [_ dy]]
|
||||
(let [fixed (get-in db [:animations :response-height-fixed])]
|
||||
(assoc-in db [:animations :response-height] (- fixed dy)))))
|
||||
(let [fixed (get-in db [:animations :to-response-height])]
|
||||
(assoc-in db [:animations :response-height-current] (- fixed dy)))))
|
||||
|
||||
(register-handler :fix-response-height
|
||||
(fn [db _]
|
||||
(let [current (get-in db [:animations :response-height])
|
||||
(let [current (get-in db [:animations :response-height-current])
|
||||
normal-height response-height-normal
|
||||
max-height (get-in db [:animations :response-height-max])
|
||||
delta (/ normal-height 2)
|
||||
|
@ -126,7 +90,7 @@
|
|||
(<= current (+ zero-height normal-height delta)) (get-response-height db)
|
||||
:else max-height)]
|
||||
(dispatch [:animate-response-resize])
|
||||
(assoc-in db [:animations :response-height-fixed] new-fixed))))
|
||||
(assoc-in db [:animations :to-response-height] new-fixed))))
|
||||
|
||||
(defn create-response-pan-responder []
|
||||
(drag/create-pan-responder
|
||||
|
|
|
@ -22,7 +22,9 @@
|
|||
[status-im.chat.views.suggestions :refer [suggestions-view]]
|
||||
[status-im.chat.views.response :refer [response-view]]
|
||||
[status-im.chat.views.new-message :refer [chat-message-new]]
|
||||
[status-im.i18n :refer [label label-pluralize]]))
|
||||
[status-im.i18n :refer [label label-pluralize]]
|
||||
[status-im.components.animation :as anim]
|
||||
[reagent.core :as r]))
|
||||
|
||||
|
||||
(defn contacts-by-identity [contacts]
|
||||
|
@ -217,17 +219,41 @@
|
|||
:custom-action [toolbar-action]}])))
|
||||
|
||||
(defview messages-view [group-chat]
|
||||
[messages [:chat :messages]
|
||||
contacts [:chat :contacts]
|
||||
messages-offset [:get-in [:animations :messages-offset-anim-value]]]
|
||||
(let [contacts' (contacts-by-identity contacts)]
|
||||
[animated-view {:style (st/messages-container messages-offset)}
|
||||
[list-view {:renderRow (message-row contacts' group-chat)
|
||||
:renderScrollComponent #(invertible-scroll-view (js->clj %))
|
||||
:onEndReached #(dispatch [:load-more-messages])
|
||||
:enableEmptySections true
|
||||
:keyboardShouldPersistTaps true
|
||||
:dataSource (to-datasource messages)}]]))
|
||||
[messages [:chat :messages]
|
||||
contacts [:chat :contacts]]
|
||||
(let [contacts' (contacts-by-identity contacts)]
|
||||
[list-view {:renderRow (message-row contacts' group-chat)
|
||||
:renderScrollComponent #(invertible-scroll-view (js->clj %))
|
||||
:onEndReached #(dispatch [:load-more-messages])
|
||||
:enableEmptySections true
|
||||
:keyboardShouldPersistTaps true
|
||||
:dataSource (to-datasource messages)}]))
|
||||
|
||||
(defn messages-container-animation-logic [{:keys [to-value val]}]
|
||||
(fn [_]
|
||||
(let [to-value @to-value]
|
||||
(anim/start (anim/spring val {:toValue to-value})
|
||||
(fn [arg]
|
||||
(when (.-finished arg)
|
||||
(dispatch [:set-in [:animations ::messages-offset-current] to-value])))))))
|
||||
|
||||
(defn messages-container [messages]
|
||||
(let [to-messages-offset (subscribe [:get-in [:animations :messages-offset]])
|
||||
cur-messages-offset (subscribe [:get-in [:animations ::messages-offset-current]])
|
||||
messages-offset (anim/create-value (or @cur-messages-offset 0))
|
||||
context {:to-value to-messages-offset
|
||||
:val messages-offset}
|
||||
on-update (messages-container-animation-logic context)]
|
||||
(r/create-class
|
||||
{:component-did-mount
|
||||
on-update
|
||||
:component-did-update
|
||||
on-update
|
||||
:reagent-render
|
||||
(fn [messages]
|
||||
@to-messages-offset
|
||||
[animated-view {:style (st/messages-container messages-offset)}
|
||||
messages])})))
|
||||
|
||||
(defview chat []
|
||||
[group-chat [:chat :group-chat]
|
||||
|
@ -236,7 +262,8 @@
|
|||
to-msg-id [:get-chat-command-to-msg-id]]
|
||||
[view st/chat-view
|
||||
[chat-toolbar]
|
||||
[messages-view group-chat]
|
||||
[messages-container
|
||||
[messages-view group-chat]]
|
||||
(when group-chat [typing-all])
|
||||
(cond
|
||||
(and command to-msg-id) [response-view]
|
||||
|
|
|
@ -1,17 +1,20 @@
|
|||
(ns status-im.chat.views.plain-input
|
||||
(:require-macros [status-im.utils.views :refer [defview]])
|
||||
(:require [re-frame.core :refer [subscribe dispatch]]
|
||||
[reagent.core :as r]
|
||||
[status-im.components.react :refer [view
|
||||
animated-view
|
||||
icon
|
||||
touchable-highlight
|
||||
text-input
|
||||
dismiss-keyboard!]]
|
||||
[status-im.components.animation :as anim]
|
||||
[status-im.chat.views.command :as command]
|
||||
[status-im.chat.views.response :as response]
|
||||
[status-im.chat.styles.plain-input :as st]
|
||||
[status-im.chat.styles.input :as st-command]
|
||||
[status-im.chat.styles.response :as st-response]))
|
||||
[status-im.chat.styles.response :as st-response]
|
||||
[status-im.constants :refer [response-input-hiding-duration]]))
|
||||
|
||||
(defn set-input-message [message]
|
||||
(dispatch [:set-chat-input-text message]))
|
||||
|
@ -30,29 +33,95 @@
|
|||
(when (message-valid? staged-commands message)
|
||||
(send dismiss-keyboard)))
|
||||
|
||||
(defview commands-button [animation?]
|
||||
[typing-command? [:typing-command?]
|
||||
buttons-scale [:get-in [:animations :message-input-buttons-scale]]]
|
||||
[touchable-highlight {:disabled animation?
|
||||
:on-press #(dispatch [:switch-command-suggestions])
|
||||
:style st/message-input-button-touchable}
|
||||
[animated-view {:style (st/message-input-button buttons-scale)}
|
||||
(if typing-command?
|
||||
[icon :close-gray st/close-icon]
|
||||
[icon :list st/list-icon])]])
|
||||
(defn commands-button-animation-logic [{:keys [to-value val]}]
|
||||
(fn [_]
|
||||
(let [to-scale @to-value
|
||||
minimum 0.1
|
||||
scale (cond (< 1 to-scale) 1
|
||||
(< to-scale minimum) minimum
|
||||
:else to-scale)]
|
||||
(anim/start (anim/timing val {:toValue scale
|
||||
:duration response-input-hiding-duration})
|
||||
(fn [arg]
|
||||
(when (.-finished arg)
|
||||
(dispatch [:set-in [:animations ::message-input-buttons-scale-current] scale])
|
||||
(when (= to-scale minimum)
|
||||
(dispatch [:finish-show-response]))))))))
|
||||
|
||||
(defview smile-button [animation?]
|
||||
[buttons-scale [:get-in [:animations :message-input-buttons-scale]]]
|
||||
[touchable-highlight {:disabled animation?
|
||||
:on-press #(dispatch [:switch-command-suggestions])
|
||||
:style st/message-input-button-touchable}
|
||||
[animated-view {:style (st/message-input-button buttons-scale)}
|
||||
[icon :smile st/smile-icon]]])
|
||||
(defn commands-button [animation?]
|
||||
(let [typing-command? (subscribe [:typing-command?])
|
||||
to-scale (subscribe [:get-in [:animations :message-input-buttons-scale]])
|
||||
cur-scale (subscribe [:get-in [:animations ::message-input-buttons-scale-current]])
|
||||
buttons-scale (anim/create-value (or @cur-scale 1))
|
||||
context {:to-value to-scale
|
||||
:val buttons-scale}
|
||||
on-update (commands-button-animation-logic context)]
|
||||
(r/create-class
|
||||
{:component-did-mount
|
||||
on-update
|
||||
:component-did-update
|
||||
on-update
|
||||
:reagent-render
|
||||
(fn [animation?]
|
||||
(let [typing-command? @typing-command?]
|
||||
@to-scale
|
||||
[touchable-highlight {:disabled animation?
|
||||
:on-press #(dispatch [:switch-command-suggestions])
|
||||
:style st/message-input-button-touchable}
|
||||
[animated-view {:style (st/message-input-button buttons-scale)}
|
||||
(if typing-command?
|
||||
[icon :close-gray st/close-icon]
|
||||
[icon :list st/list-icon])]]))})))
|
||||
|
||||
(defview message-input-container [input]
|
||||
[message-input-offset [:get-in [:animations :message-input-offset]]]
|
||||
[animated-view {:style (st/message-input-container message-input-offset)}
|
||||
input])
|
||||
(defn smile-button [animation?]
|
||||
(let [to-scale (subscribe [:get-in [:animations :message-input-buttons-scale]])
|
||||
cur-scale (subscribe [:get-in [:animations ::message-input-buttons-scale-current]])
|
||||
buttons-scale (anim/create-value (or @cur-scale 1))
|
||||
context {:to-value to-scale
|
||||
:val buttons-scale}
|
||||
on-update (commands-button-animation-logic context)]
|
||||
(r/create-class
|
||||
{:component-did-mount
|
||||
on-update
|
||||
:component-did-update
|
||||
on-update
|
||||
:reagent-render
|
||||
(fn [animation?]
|
||||
@to-scale
|
||||
[touchable-highlight {:disabled animation?
|
||||
:on-press (fn []
|
||||
;; TODO emoticons: not implemented
|
||||
)
|
||||
:style st/message-input-button-touchable}
|
||||
[animated-view {:style (st/message-input-button buttons-scale)}
|
||||
[icon :smile st/smile-icon]]])})))
|
||||
|
||||
(defn message-input-container-animation-logic [{:keys [to-value val]}]
|
||||
(fn [_]
|
||||
(let [to-value @to-value]
|
||||
(anim/start (anim/timing val {:toValue to-value
|
||||
:duration response-input-hiding-duration})
|
||||
(fn [arg]
|
||||
(when (.-finished arg)
|
||||
(dispatch [:set-in [:animations ::message-input-offset-current] to-value])))))))
|
||||
|
||||
(defn message-input-container [input]
|
||||
(let [to-message-input-offset (subscribe [:get-in [:animations :message-input-offset]])
|
||||
cur-message-input-offset (subscribe [:get-in [:animations ::message-input-offset-current]])
|
||||
message-input-offset (anim/create-value (or @cur-message-input-offset 0))
|
||||
context {:to-value to-message-input-offset
|
||||
:val message-input-offset}
|
||||
on-update (message-input-container-animation-logic context)]
|
||||
(r/create-class
|
||||
{:component-did-mount
|
||||
on-update
|
||||
:component-did-update
|
||||
on-update
|
||||
:reagent-render
|
||||
(fn [input]
|
||||
@to-message-input-offset
|
||||
[animated-view {:style (st/message-input-container message-input-offset)}
|
||||
input])})))
|
||||
|
||||
(defview plain-message-input-view [{:keys [input-options validator]}]
|
||||
[input-message [:get-chat-input-text]
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
(ns status-im.chat.views.response
|
||||
(:require-macros [status-im.utils.views :refer [defview]])
|
||||
(:require-macros [reagent.ratom :refer [reaction]]
|
||||
[status-im.utils.views :refer [defview]])
|
||||
(:require [re-frame.core :refer [subscribe dispatch]]
|
||||
[reagent.core :as r]
|
||||
[status-im.components.react :refer [view
|
||||
animated-view
|
||||
icon
|
||||
|
@ -10,7 +12,9 @@
|
|||
touchable-highlight]]
|
||||
[status-im.components.drag-drop :as drag]
|
||||
[status-im.chat.views.response-suggestions :refer [response-suggestions-view]]
|
||||
[status-im.chat.styles.response :as st]))
|
||||
[status-im.chat.styles.response :as st]
|
||||
[status-im.chat.styles.plain-input :refer [input-height]]
|
||||
[status-im.components.animation :as anim]))
|
||||
|
||||
(defn drag-icon []
|
||||
[view st/drag-container
|
||||
|
@ -40,20 +44,54 @@
|
|||
[view st/cancel-container
|
||||
[icon :close-white st/cancel-icon]]]]])
|
||||
|
||||
(defview response-view []
|
||||
[pan-responder [:get-in [:animations :response-pan-responder]]
|
||||
response-height [:get-in [:animations :response-height]]
|
||||
anim-height [:get-in [:animations :response-height-anim-value]]
|
||||
commands-input-is-switching? [:get-in [:animations :commands-input-is-switching?]]
|
||||
response-resize? [:get-in [:animations :response-resize?]]]
|
||||
(defn inner-container-animation-logic [{:keys [animation? to-value current-value val]}]
|
||||
(fn [_]
|
||||
(if @animation?
|
||||
(let [to-value @to-value]
|
||||
(anim/start (anim/spring val {:toValue to-value})
|
||||
(fn [arg]
|
||||
(when (.-finished arg)
|
||||
(dispatch [:set-in [:animations :response-height-current] to-value])
|
||||
(dispatch [:finish-animate-response-resize])
|
||||
(when (= to-value input-height)
|
||||
(dispatch [:finish-animate-cancel-command])
|
||||
(dispatch [:cancel-command]))))))
|
||||
(anim/set-value val @current-value))))
|
||||
|
||||
(defn inner-container [content]
|
||||
(let [pan-responder (subscribe [:get-in [:animations :response-pan-responder]])
|
||||
commands-input-is-switching? (subscribe [:get-in [:animations :commands-input-is-switching?]])
|
||||
response-resize? (subscribe [:get-in [:animations :response-resize?]])
|
||||
|
||||
to-response-height (subscribe [:get-in [:animations :to-response-height]])
|
||||
cur-response-height (subscribe [:get-in [:animations :response-height-current]])
|
||||
response-height (anim/create-value (or @cur-response-height 0))
|
||||
context {:animation? (reaction (or @commands-input-is-switching? @response-resize?))
|
||||
:to-value to-response-height
|
||||
:current-value cur-response-height
|
||||
:val response-height}
|
||||
on-update (inner-container-animation-logic context)]
|
||||
(r/create-class
|
||||
{:component-did-mount
|
||||
on-update
|
||||
:component-did-update
|
||||
on-update
|
||||
:reagent-render
|
||||
(fn [content]
|
||||
@to-response-height
|
||||
[animated-view (merge (drag/pan-handlers @pan-responder)
|
||||
{:style (st/response-view (if (or @commands-input-is-switching? @response-resize?)
|
||||
response-height
|
||||
(or @cur-response-height 0)))})
|
||||
content])})))
|
||||
|
||||
(defn response-view []
|
||||
[view {:style st/container
|
||||
:onLayout (fn [event]
|
||||
(let [height (.. event -nativeEvent -layout -height)]
|
||||
(dispatch [:set-response-max-height height])))}
|
||||
[animated-view (merge (drag/pan-handlers pan-responder)
|
||||
{:style (st/response-view (if (or commands-input-is-switching? response-resize?)
|
||||
anim-height
|
||||
response-height))})
|
||||
[request-info]
|
||||
[response-suggestions-view]
|
||||
[view st/input-placeholder]]])
|
||||
[inner-container
|
||||
[view
|
||||
[request-info]
|
||||
[response-suggestions-view]
|
||||
[view st/input-placeholder]]]])
|
||||
|
|
|
@ -33,14 +33,13 @@
|
|||
:current-tag nil
|
||||
:disable-group-creation false
|
||||
:animations {;; mutable data
|
||||
:response-height nil
|
||||
:response-height-fixed nil
|
||||
:to-response-height nil
|
||||
:response-height-current nil
|
||||
:response-pan-responder nil
|
||||
:message-input-offset (anim/create-value 0)
|
||||
:message-input-buttons-scale (anim/create-value 1)
|
||||
:message-input-offset 0
|
||||
:message-input-buttons-scale 1
|
||||
:commands-input-is-switching? false
|
||||
:response-height-anim-value (anim/create-value 0)
|
||||
:messages-offset-anim-value (anim/create-value 0)
|
||||
:messages-offset 0
|
||||
:response-resize? false}})
|
||||
|
||||
(def protocol-initialized-path [:protocol-initialized])
|
||||
|
|
Loading…
Reference in New Issue