Response suggestions animation
This commit is contained in:
parent
a495fa7961
commit
b9fcad3df5
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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)))))
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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]])
|
||||||
|
|
|
@ -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}]]]))
|
|
||||||
|
|
|
@ -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]))
|
||||||
|
|
||||||
|
|
|
@ -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))
|
|
@ -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 {}))
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue