Merge pull request #558 from status-im/feature/#547

Emoji picker (#547)
This commit is contained in:
Roman Volosovskyi 2016-12-21 11:07:41 +02:00 committed by GitHub
commit c9366c1d2b
13 changed files with 104 additions and 30 deletions

View File

@ -34,7 +34,8 @@
"eccjs",
"chance",
"react-native-swiper",
"react-native-share"
"react-native-share",
"react-native-emoji-picker"
],
"imageDirs": [
"images"

View File

@ -50,6 +50,7 @@
"react-native-crypto": "^2.0.1",
"react-native-dialogs": "0.0.16",
"react-native-drawer-layout": "^1.1.0",
"react-native-emoji-picker": "^0.2.2",
"react-native-fs": "^1.5.1",
"react-native-http": "github:tradle/react-native-http#834492d",
"react-native-i18n": "0.0.8",

View File

@ -77,7 +77,8 @@
(fn [e]
(let [h (.. e -endCoordinates -height)]
(when-not (= h @keyboard-height)
(dispatch [:set :keyboard-height h])))))
(dispatch [:set :keyboard-height h])
(dispatch [:set :keyboard-max-height h])))))
(.addListener keyboard
"keyboardDidHide"
#(when-not (= 0 @keyboard-height)

View File

@ -12,3 +12,5 @@
(def suggestions-header-height 22)
(def minimum-command-suggestions-height
(+ input-height suggestions-header-height))
(def emoji-container-height 250)

View File

@ -2,7 +2,7 @@
(:require-macros [cljs.core.async.macros :as am])
(:require [re-frame.core :refer [enrich after debug dispatch]]
[status-im.models.commands :as commands]
[clojure.string :as str]
[clojure.string :as string]
[status-im.components.styles :refer [default-chat-color]]
[status-im.chat.suggestions :as suggestions]
[status-im.protocol.core :as protocol]
@ -46,6 +46,10 @@
(fn [db [_ ui-element value]]
(assoc-in db [:chat-ui-props ui-element] value)))
(register-handler :toggle-chat-ui-props
(fn [{:keys [chat-ui-props] :as db} [_ ui-element]]
(assoc-in db [:chat-ui-props ui-element] (not (ui-element chat-ui-props)))))
(register-handler :set-show-info
(fn [db [_ show-info]]
(assoc db :show-info show-info)))
@ -54,6 +58,7 @@
(u/side-effect!
(fn [_ [_ details]]
(dispatch [:set-chat-ui-props :show-bottom-info? true])
(dispatch [:set-chat-ui-props :show-emoji? false])
(dispatch [:set-chat-ui-props :bottom-info details]))))
(register-handler :load-more-messages
@ -78,7 +83,7 @@
(defn safe-trim [s]
(when (string? s)
(str/trim s)))
(string/trim s)))
(register-handler :cancel-command
(fn [{:keys [current-chat-id] :as db} _]
@ -165,11 +170,16 @@
(u/side-effect!
(fn [{:keys [current-chat-id] :as db} [_ text]]
(let [{:keys [dapp?] :as contact} (get-in db [:contacts current-chat-id])]
(log/debug "SET CHAT INPUT TEXT: " current-chat-id text contact dapp?)
(if (console? current-chat-id)
(dispatch [::check-input-for-commands text])
(dispatch [::check-suggestions current-chat-id text]))))))
(register-handler :add-to-chat-input-text
(u/side-effect!
(fn [{:keys [chats current-chat-id] :as db} [_ text-to-add]]
(let [input-text (get-in chats [current-chat-id :input-text])]
(dispatch [:set-chat-input-text (str input-text text-to-add)])))))
(def possible-commands
{[:confirmation-code :responses] #(re-matches #"^[\d]{4}$" %)
[:phone :commands] valid-mobile-number?})

View File

@ -25,6 +25,7 @@
[status-im.chat.views.new-message :refer [chat-message-input-view]]
[status-im.chat.views.staged-commands :refer [staged-commands-view]]
[status-im.chat.views.actions :refer [actions-view]]
[status-im.chat.views.emoji :refer [emoji-view]]
[status-im.chat.views.bottom-info :refer [bottom-info-view]]
[status-im.chat.views.toolbar-content :refer [toolbar-content-view]]
[status-im.chat.views.suggestions :refer [suggestion-container]]
@ -187,6 +188,7 @@
[group-chat [:chat :group-chat]
show-actions? [:chat-ui-props :show-actions?]
show-bottom-info? [:chat-ui-props :show-bottom-info?]
show-emoji? [:chat-ui-props :show-emoji?]
command? [:command?]
staged-commands [:get-chat-staged-commands]
layout-height [:get :layout-height]]
@ -206,6 +208,8 @@
(when-not command?
[suggestion-container])
[response-view]
(when show-emoji?
[emoji-view])
[chat-message-input-view]
(when show-actions?
[actions-view])

View File

@ -0,0 +1,23 @@
(ns status-im.chat.styles.emoji
(:require [status-im.components.styles :refer [color-white]]
[status-im.chat.constants :refer [emoji-container-height]]
[taoensso.timbre :as log]))
(def container-height emoji-container-height)
(defn container [height]
{:flexDirection :column
:position :absolute
:left 0
:right 0
:bottom 0
:height (or height emoji-container-height)
:backgroundColor color-white
:elevation 5})
(def emoji-container
{:flex 1})
(def emoji-picker
{:flex 1
:background-color color-white})

View File

@ -272,13 +272,16 @@
(register-sub :input-margin
(fn []
(let [kb-height (subscribe [:get :keyboard-height])
focused (subscribe [:get :focused])
mode (subscribe [:kb-mode])]
(let [kb-height (subscribe [:get :keyboard-height])
focused (subscribe [:get :focused])
mode (subscribe [:kb-mode])
kb-max (subscribe [:get :keyboard-max-height])
show-emoji? (subscribe [:chat-ui-props :show-emoji?])]
(reaction
(cond ios? @kb-height
(and @focused (= :pan @mode) (pos? @kb-height)) 20
:else 0)))))
(cond @show-emoji? (or @kb-max c/emoji-container-height)
ios? @kb-height
(and @focused (= :pan @mode) (pos? @kb-height)) 20
:else 0)))))
(register-sub :max-layout-height
(fn [db [_ status-bar]]

View File

@ -0,0 +1,21 @@
(ns status-im.chat.views.emoji
(: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
text
icon
emoji-picker]]
[status-im.chat.styles.emoji :as st]
[status-im.components.animation :as anim]
[status-im.chat.suggestions-responder :as resp]
[status-im.chat.constants :as c]
[status-im.i18n :refer [label]]))
(defview emoji-view []
[keyboard-max-height [:get :keyboard-max-height]]
[view {:style (st/container keyboard-max-height)}
[view st/emoji-container
[emoji-picker {:style st/emoji-picker
:hideClearButton true
:onEmojiSelected #(dispatch [:add-to-chat-input-text %])}]]])

View File

@ -47,12 +47,13 @@
:auto-focus false
:blur-on-submit true
:multiline true
:on-change #(let [size (-> (.-nativeEvent %)
:on-content-size-change #(let [size (-> (.-nativeEvent %)
(.-contentSize)
(.-height))]
(set-layout-size size))
(set-layout-size size))
:accessibility-label :input
:on-focus #(dispatch [:set :focused true])
:on-focus #(do (dispatch [:set :focused true])
(dispatch [:set-chat-ui-props :show-emoji? false]))
:on-blur #(do (dispatch [:set :focused false])
(set-layout-size 0))
:default-value (or input-message "")}
@ -75,7 +76,7 @@
(defn plain-message-get-initial-state [_]
{:height 0})
(defn plain-message-render [_]
(defn plain-message-input-view [_]
(let [command? (subscribe [:command?])
command (subscribe [:get-chat-command])
input-command (subscribe [:get-chat-command-content])
@ -84,7 +85,9 @@
component (r/current-component)
set-layout-size #(r/set-state component {:height %})]
(r/create-class
{:component-will-update
{:get-initial-state
plain-message-get-initial-state
:component-will-update
(fn [_]
(when (or (and @command? (str/blank? @input-command))
(and (not @command?) (not @input-message)))
@ -99,20 +102,14 @@
(if @command?
[command-input input-options @command]
[message-input input-options set-layout-size])]
;; TODO emoticons: not implemented
[plain-message/smile-button height]
(when (or (and @command? (not (str/blank? @input-command)))
@valid-plain-message?)
(let [on-press (if @command?
(on-press-commands-handler @command)
plain-message/send)]
[send-button {:on-press #(on-press %)
:accessibility-label :send-message}]))
[send-button {:on-press #(do (dispatch [:set-chat-ui-props :show-emoji? false])
(on-press %))}]))
(when (and @command? (= :command (:type @command)))
[command/command-icon @command])]]))})))
(defn plain-message-input-view [_]
(r/create-class {:get-initial-state plain-message-get-initial-state
:reagent-render plain-message-render}))

View File

@ -6,7 +6,8 @@
animated-view
icon
text
touchable-highlight]]
touchable-highlight
dismiss-keyboard!]]
[status-im.components.animation :as anim]
[status-im.chat.styles.plain-message :as st]
[status-im.constants :refer [response-input-hiding-duration]]))
@ -56,7 +57,8 @@
on-update
:reagent-render
(fn [height on-press]
[touchable-highlight {:on-press #(do (dispatch [:switch-command-suggestions!])
[touchable-highlight {:on-press #(do (dispatch [:set-chat-ui-props :show-emoji? false])
(dispatch [:switch-command-suggestions!])
(on-press))
:disabled @command?}
[animated-view {:style (st/message-input-button-touchable container-width height)}
@ -97,9 +99,8 @@
on-update
:reagent-render
(fn []
[touchable-highlight {:on-press (fn []
;; TODO emoticons: not implemented
)
[touchable-highlight {:on-press #(do (dispatch [:toggle-chat-ui-props :show-emoji?])
(dismiss-keyboard!))
:disabled @command?}
[animated-view {:style (st/message-input-button-touchable container-width height)}
[animated-view {:style (st/message-input-button buttons-scale 16)}

View File

@ -123,3 +123,12 @@
(defn copy-to-clipboard [text]
(.setString (.-Clipboard react-native) text))
;; Emoji
(def emoji-picker-class (js/require "react-native-emoji-picker"))
(def emoji-picker
(let [emoji-picker (.-default emoji-picker-class)]
(r/adapt-react-class emoji-picker)))

View File

@ -64,7 +64,8 @@
(fn [e]
(let [h (.. e -endCoordinates -height)]
(when-not (= h @keyboard-height)
(dispatch [:set :keyboard-height h])))))
(dispatch [:set :keyboard-height h])
(dispatch [:set :keyboard-max-height h])))))
(.addListener keyboard
"keyboardWillHide"
#(when-not (= 0 @keyboard-height)