Response suggestions animation

This commit is contained in:
virvar 2016-05-30 16:50:23 +03:00
parent a495fa7961
commit b9fcad3df5
13 changed files with 119 additions and 23 deletions

View File

@ -2,12 +2,14 @@
(:require [re-frame.core :refer [register-handler enrich after debug dispatch]] (:require [re-frame.core :refer [register-handler enrich after debug dispatch]]
[status-im.models.commands :as commands] [status-im.models.commands :as commands]
[clojure.string :as str] [clojure.string :as str]
[status-im.components.animation :as anim]
[status-im.components.styles :refer [default-chat-color]] [status-im.components.styles :refer [default-chat-color]]
[status-im.chat.suggestions :as suggestions] [status-im.chat.suggestions :as suggestions]
[status-im.protocol.api :as api] [status-im.protocol.api :as api]
[status-im.models.messages :as messages] [status-im.models.messages :as messages]
[status-im.constants :refer [text-content-type [status-im.constants :refer [text-content-type
content-type-command]] content-type-command
response-input-hiding-duration]]
[status-im.utils.random :as random] [status-im.utils.random :as random]
[status-im.chat.sign-up :as sign-up-service] [status-im.chat.sign-up :as sign-up-service]
[status-im.models.chats :as chats] [status-im.models.chats :as chats]
@ -15,6 +17,7 @@
[status-im.utils.handlers :as u] [status-im.utils.handlers :as u]
[status-im.persistence.realm :as r] [status-im.persistence.realm :as r]
[status-im.handlers.server :as server] [status-im.handlers.server :as server]
[status-im.handlers.content-suggestions :refer [get-content-suggestions]]
[status-im.utils.phone-number :refer [format-phone-number]] [status-im.utils.phone-number :refer [format-phone-number]]
[status-im.utils.datetime :as time])) [status-im.utils.datetime :as time]))
@ -38,9 +41,26 @@
(register-handler :cancel-command (register-handler :cancel-command
(fn [{:keys [current-chat-id] :as db} _] (fn [{:keys [current-chat-id] :as db} _]
(-> db (-> db
(assoc-in [:animations :response-input-is-hiding?] false)
(assoc-in [:chats current-chat-id :command-input] {}) (assoc-in [:chats current-chat-id :command-input] {})
(update-in [:chats current-chat-id :input-text] safe-trim)))) (update-in [:chats current-chat-id :input-text] safe-trim))))
(defn animate-cancel-command [db height]
(anim/add-listener height (fn [val]
(when (<= (.-value val) 1)
(anim/remove-all-listeners height)
(anim/stop-animation height)
(dispatch [:cancel-command]))))
(anim/start (anim/timing height {:toValue 1, :duration response-input-hiding-duration}))
(assoc-in db [:animations :response-input-is-hiding?] true))
(register-handler :start-cancel-command
(fn [{{height :response-suggestions-height
hiding? :response-input-is-hiding?} :animations :as db} _]
(if-not hiding?
(animate-cancel-command db height)
db)))
(register-handler :set-chat-command-content (register-handler :set-chat-command-content
(fn [{:keys [current-chat-id] :as db} [_ content]] (fn [{:keys [current-chat-id] :as db} [_ content]]
(-> db (-> db

View File

@ -7,6 +7,8 @@
chat-background chat-background
color-black]])) color-black]]))
(def request-info-height 61)
(def drag-touchable (def drag-touchable
{:height 16 {:height 16
:alignItems :center}) :alignItems :center})
@ -47,9 +49,13 @@
:opacity 0.69 :opacity 0.69
:color color-white}) :color color-white})
(defn request-view [height]
{:flexDirection :column
:height height})
(defn request-info [color] (defn request-info [color]
{:flexDirection :column {:flexDirection :column
:height 61 :height request-info-height
:backgroundColor color}) :backgroundColor color})
(def inner-container (def inner-container

View File

@ -13,6 +13,7 @@
text2-color text2-color
text3-color]])) text3-color]]))
(def min-suggestions-height 150)
(def header-height 50) (def header-height 50)
(def suggestion-height 56) (def suggestion-height 56)

View File

@ -4,8 +4,12 @@
[status-im.db :as db] [status-im.db :as db]
;todo handlers in subs?... ;todo handlers in subs?...
[status-im.chat.suggestions :refer [status-im.chat.suggestions :refer
[get-suggestions typing-command? get-content-suggestions]] [get-suggestions typing-command?]]
[status-im.models.commands :as commands] [status-im.models.commands :as commands]
[status-im.components.animation :as anim]
[status-im.constants :refer [response-suggesstion-resize-duration]]
[status-im.chat.styles.response :as response-styles]
[status-im.chat.styles.response-suggestions :as response-suggestions-styles]
[status-im.handlers.content-suggestions :refer [get-content-suggestions]])) [status-im.handlers.content-suggestions :refer [get-content-suggestions]]))
(register-sub :chat-properties (register-sub :chat-properties
@ -91,8 +95,25 @@
(fn [db _] (fn [db _]
(reaction (typing-command? @db)))) (reaction (typing-command? @db))))
(defn update-response-suggestions-height [db]
(when-not (get-in db [:animations :response-input-is-hiding?])
(let [command (commands/get-chat-command db)
text (commands/get-chat-command-content db)
suggestions (get-content-suggestions db command text)
suggestions-height (min response-suggestions-styles/min-suggestions-height
(reduce + 0 (map #(if (:header %)
response-suggestions-styles/header-height
response-suggestions-styles/suggestion-height)
suggestions)))
height (+ suggestions-height response-styles/request-info-height)
anim-value (get-in db [:animations :response-suggestions-height])]
(anim/start (anim/timing anim-value {:toValue height, :duration response-suggesstion-resize-duration}))))
db)
(register-sub :get-content-suggestions (register-sub :get-content-suggestions
(fn [db _] (fn [db _]
(let [command (reaction (commands/get-chat-command @db)) (let [command (reaction (commands/get-chat-command @db))
text (reaction (commands/get-chat-command-content @db))] text (reaction (commands/get-chat-command-content @db))
(reaction (get-content-suggestions @db @command @text))))) suggestions (reaction (get-content-suggestions @db @command @text))]
(reaction (do (update-response-suggestions-height @db)
@suggestions)))))

View File

@ -8,7 +8,6 @@
dismiss-keyboard!]] dismiss-keyboard!]]
[status-im.chat.views.suggestions :refer [suggestions-view]] [status-im.chat.views.suggestions :refer [suggestions-view]]
[status-im.chat.views.content-suggestions :refer [content-suggestions-view]] [status-im.chat.views.content-suggestions :refer [content-suggestions-view]]
[status-im.chat.views.response-suggestions :refer [response-suggestions-view]]
[status-im.chat.views.command :as command] [status-im.chat.views.command :as command]
[status-im.chat.views.response :as response] [status-im.chat.views.response :as response]
[status-im.chat.styles.plain-input :as st] [status-im.chat.styles.plain-input :as st]
@ -44,9 +43,8 @@
command @command command @command
response? (and command @to-msg-id)] response? (and command @to-msg-id)]
[view st/input-container [view st/input-container
(if response? [response/request-info command])
(cond (cond
response? [response-suggestions-view] response? [response/request-view]
command [content-suggestions-view] command [content-suggestions-view]
:else [suggestions-view]) :else [suggestions-view])
[view st/input-view [view st/input-view

View File

@ -1,12 +1,14 @@
(ns status-im.chat.views.response (ns status-im.chat.views.response
(:require-macros [status-im.utils.views :refer [defview]])
(:require [re-frame.core :refer [subscribe dispatch]] (:require [re-frame.core :refer [subscribe dispatch]]
[status-im.components.react :refer [view [status-im.components.react :refer [view
animated-view
icon icon
image image
text text
text-input text-input
touchable-highlight]] touchable-highlight]]
[status-im.chat.views.command :as command] [status-im.chat.views.response-suggestions :refer [response-suggestions-view]]
[status-im.chat.styles.response :as st])) [status-im.chat.styles.response :as st]))
(defn drag-touchable [] (defn drag-touchable []
@ -30,12 +32,19 @@
;; TODO stub data: request message info ;; TODO stub data: request message info
"By ???, MMM 1st at HH:mm"]]) "By ???, MMM 1st at HH:mm"]])
(defn request-info [command] (defview request-info []
[command [:get-chat-command]]
[view (st/request-info (:color command)) [view (st/request-info (:color command))
[drag-touchable] [drag-touchable]
[view st/inner-container [view st/inner-container
[command-icon nil] [command-icon nil]
[info-container command] [info-container command]
[touchable-highlight {:on-press command/cancel-command-input} [touchable-highlight {:on-press #(dispatch [:start-cancel-command])}
[view st/cancel-container [view st/cancel-container
[icon :close-white st/cancel-icon]]]]]) [icon :close-white st/cancel-icon]]]]])
(defview request-view []
[height [:get-in [:animations :response-suggestions-height]]]
[animated-view {:style (st/request-view height)}
[request-info]
[response-suggestions-view]])

View File

@ -32,8 +32,7 @@
(defview response-suggestions-view [] (defview response-suggestions-view []
[suggestions [:get-content-suggestions]] [suggestions [:get-content-suggestions]]
(when (seq suggestions) (when (seq suggestions)
[view nil [view (st/suggestions-container suggestions)
[view (st/suggestions-container suggestions) [list-view {:dataSource (to-datasource suggestions)
[list-view {:dataSource (to-datasource suggestions) :keyboardShouldPersistTaps true
:keyboardShouldPersistTaps true :renderRow render-row}]]))
:renderRow render-row}]]]))

View File

@ -1,11 +1,11 @@
(ns status-im.chat.views.suggestions (ns status-im.chat.views.suggestions
(:require [re-frame.core :refer [subscribe dispatch]] (:require [re-frame.core :refer [subscribe dispatch]]
[status-im.components.react :refer [view [status-im.components.react :refer [view
text text
icon icon
touchable-highlight touchable-highlight
list-view list-view
list-item]] list-item]]
[status-im.utils.listview :refer [to-datasource]] [status-im.utils.listview :refer [to-datasource]]
[status-im.chat.styles.suggestions :as st])) [status-im.chat.styles.suggestions :as st]))

View File

@ -0,0 +1,29 @@
(ns status-im.components.animation
(:require [status-im.components.react :refer [animated]]))
(defn start [anim]
(.start anim))
(defn timing [anim-value config]
(.timing animated anim-value (clj->js config)))
(defn spring [anim-value config]
(.spring animated anim-value (clj->js config)))
(defn add-listener [anim-value listener]
(.addListener anim-value listener))
(defn remove-all-listeners [anim-value]
(.removeAllListeners anim-value))
(defn stop-animation [anim-value]
(.stopAnimation anim-value))
(defn value [anim-value]
(.-value anim-value))
(defn set-value [anim-value value]
(.setValue anim-value value))
(defn create-value [value]
(js/React.Animated.Value. value))

View File

@ -34,6 +34,10 @@
(def picker (r/adapt-react-class (.-Picker js/React))) (def picker (r/adapt-react-class (.-Picker js/React)))
(def picker-item (r/adapt-react-class (.-Item (.-Picker js/React)))) (def picker-item (r/adapt-react-class (.-Item (.-Picker js/React))))
(def animated (.-Animated js/React))
(def animated-view (r/adapt-react-class (.-View animated)))
(def animated-text (r/adapt-react-class (.-Text animated)))
(defn icon (defn icon
([n] (icon n {})) ([n] (icon n {}))

View File

@ -12,3 +12,6 @@
(def content-type-status "status") (def content-type-status "status")
(def max-chat-name-length 20) (def max-chat-name-length 20)
(def response-input-hiding-duration 200)
(def response-suggesstion-resize-duration 100)

View File

@ -1,5 +1,7 @@
(ns status-im.db (ns status-im.db
(:require [schema.core :as s :include-macros true])) (:require [schema.core :as s :include-macros true]
[status-im.components.react :refer [animated]]
[status-im.components.animation :as anim]))
;; schema of app-db ;; schema of app-db
(def schema {:greeting s/Str}) (def schema {:greeting s/Str})
@ -29,7 +31,10 @@
:email "myemail@gmail.com" :email "myemail@gmail.com"
:status "Hi, this is my status" :status "Hi, this is my status"
:current-tag nil :current-tag nil
:disable-group-creation false}) :disable-group-creation false
:animations {;; mutable data
:response-suggestions-height (anim/create-value 0)
:response-input-is-hiding? false}})
(def protocol-initialized-path [:protocol-initialized]) (def protocol-initialized-path [:protocol-initialized])
(defn chat-input-text-path [chat-id] (defn chat-input-text-path [chat-id]

View File

@ -3,6 +3,7 @@
[clojure.walk :refer [stringify-keys keywordize-keys]] [clojure.walk :refer [stringify-keys keywordize-keys]]
[re-frame.core :refer [subscribe dispatch]] [re-frame.core :refer [subscribe dispatch]]
[status-im.db :as db] [status-im.db :as db]
[status-im.components.animation :as anim]
[status-im.components.styles :refer [color-blue color-dark-mint]])) [status-im.components.styles :refer [color-blue color-dark-mint]]))
;; todo delete ;; todo delete