react-native-emoji-picker (#547)

This commit is contained in:
alwx 2016-12-16 17:15:17 +03:00
parent 080f2f508a
commit f3da7e7e76
13 changed files with 104 additions and 30 deletions

View File

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

View File

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

View File

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

View File

@ -12,3 +12,5 @@
(def suggestions-header-height 22) (def suggestions-header-height 22)
(def minimum-command-suggestions-height (def minimum-command-suggestions-height
(+ input-height suggestions-header-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-macros [cljs.core.async.macros :as am])
(:require [re-frame.core :refer [enrich after debug dispatch]] (:require [re-frame.core :refer [enrich after debug dispatch]]
[status-im.models.commands :as commands] [status-im.models.commands :as commands]
[clojure.string :as str] [clojure.string :as string]
[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.core :as protocol] [status-im.protocol.core :as protocol]
@ -46,6 +46,10 @@
(fn [db [_ ui-element value]] (fn [db [_ ui-element value]]
(assoc-in db [:chat-ui-props 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 (register-handler :set-show-info
(fn [db [_ show-info]] (fn [db [_ show-info]]
(assoc db :show-info show-info))) (assoc db :show-info show-info)))
@ -54,6 +58,7 @@
(u/side-effect! (u/side-effect!
(fn [_ [_ details]] (fn [_ [_ details]]
(dispatch [:set-chat-ui-props :show-bottom-info? true]) (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])))) (dispatch [:set-chat-ui-props :bottom-info details]))))
(register-handler :load-more-messages (register-handler :load-more-messages
@ -78,7 +83,7 @@
(defn safe-trim [s] (defn safe-trim [s]
(when (string? s) (when (string? s)
(str/trim s))) (string/trim s)))
(register-handler :cancel-command (register-handler :cancel-command
(fn [{:keys [current-chat-id] :as db} _] (fn [{:keys [current-chat-id] :as db} _]
@ -165,11 +170,16 @@
(u/side-effect! (u/side-effect!
(fn [{:keys [current-chat-id] :as db} [_ text]] (fn [{:keys [current-chat-id] :as db} [_ text]]
(let [{:keys [dapp?] :as contact} (get-in db [:contacts current-chat-id])] (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) (if (console? current-chat-id)
(dispatch [::check-input-for-commands text]) (dispatch [::check-input-for-commands text])
(dispatch [::check-suggestions current-chat-id 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 (def possible-commands
{[:confirmation-code :responses] #(re-matches #"^[\d]{4}$" %) {[:confirmation-code :responses] #(re-matches #"^[\d]{4}$" %)
[:phone :commands] valid-mobile-number?}) [: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.new-message :refer [chat-message-input-view]]
[status-im.chat.views.staged-commands :refer [staged-commands-view]] [status-im.chat.views.staged-commands :refer [staged-commands-view]]
[status-im.chat.views.actions :refer [actions-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.bottom-info :refer [bottom-info-view]]
[status-im.chat.views.toolbar-content :refer [toolbar-content-view]] [status-im.chat.views.toolbar-content :refer [toolbar-content-view]]
[status-im.chat.views.suggestions :refer [suggestion-container]] [status-im.chat.views.suggestions :refer [suggestion-container]]
@ -184,6 +185,7 @@
[group-chat [:chat :group-chat] [group-chat [:chat :group-chat]
show-actions? [:chat-ui-props :show-actions?] show-actions? [:chat-ui-props :show-actions?]
show-bottom-info? [:chat-ui-props :show-bottom-info?] show-bottom-info? [:chat-ui-props :show-bottom-info?]
show-emoji? [:chat-ui-props :show-emoji?]
command? [:command?] command? [:command?]
staged-commands [:get-chat-staged-commands] staged-commands [:get-chat-staged-commands]
layout-height [:get :layout-height]] layout-height [:get :layout-height]]
@ -203,6 +205,8 @@
(when-not command? (when-not command?
[suggestion-container]) [suggestion-container])
[response-view] [response-view]
(when show-emoji?
[emoji-view])
[chat-message-input-view] [chat-message-input-view]
(when show-actions? (when show-actions?
[actions-view]) [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

@ -277,13 +277,16 @@
(register-sub :input-margin (register-sub :input-margin
(fn [] (fn []
(let [kb-height (subscribe [:get :keyboard-height]) (let [kb-height (subscribe [:get :keyboard-height])
focused (subscribe [:get :focused]) focused (subscribe [:get :focused])
mode (subscribe [:kb-mode])] mode (subscribe [:kb-mode])
kb-max (subscribe [:get :keyboard-max-height])
show-emoji? (subscribe [:chat-ui-props :show-emoji?])]
(reaction (reaction
(cond ios? @kb-height (cond @show-emoji? (or @kb-max c/emoji-container-height)
(and @focused (= :pan @mode) (pos? @kb-height)) 20 ios? @kb-height
:else 0))))) (and @focused (= :pan @mode) (pos? @kb-height)) 20
:else 0)))))
(register-sub :max-layout-height (register-sub :max-layout-height
(fn [db [_ status-bar]] (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 :auto-focus false
:blur-on-submit true :blur-on-submit true
:multiline true :multiline true
:on-change #(let [size (-> (.-nativeEvent %) :on-content-size-change #(let [size (-> (.-nativeEvent %)
(.-contentSize) (.-contentSize)
(.-height))] (.-height))]
(set-layout-size size)) (set-layout-size size))
:accessibility-label :input :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]) :on-blur #(do (dispatch [:set :focused false])
(set-layout-size 0)) (set-layout-size 0))
:default-value (or input-message "")} :default-value (or input-message "")}
@ -75,7 +76,7 @@
(defn plain-message-get-initial-state [_] (defn plain-message-get-initial-state [_]
{:height 0}) {:height 0})
(defn plain-message-render [_] (defn plain-message-input-view [_]
(let [command? (subscribe [:command?]) (let [command? (subscribe [:command?])
command (subscribe [:get-chat-command]) command (subscribe [:get-chat-command])
input-command (subscribe [:get-chat-command-content]) input-command (subscribe [:get-chat-command-content])
@ -84,7 +85,9 @@
component (r/current-component) component (r/current-component)
set-layout-size #(r/set-state component {:height %})] set-layout-size #(r/set-state component {:height %})]
(r/create-class (r/create-class
{:component-will-update {:get-initial-state
plain-message-get-initial-state
:component-will-update
(fn [_] (fn [_]
(when (or (and @command? (str/blank? @input-command)) (when (or (and @command? (str/blank? @input-command))
(and (not @command?) (not @input-message))) (and (not @command?) (not @input-message)))
@ -99,20 +102,14 @@
(if @command? (if @command?
[command-input input-options @command] [command-input input-options @command]
[message-input input-options set-layout-size])] [message-input input-options set-layout-size])]
;; TODO emoticons: not implemented
[plain-message/smile-button height] [plain-message/smile-button height]
(when (or (and @command? (not (str/blank? @input-command))) (when (or (and @command? (not (str/blank? @input-command)))
@valid-plain-message?) @valid-plain-message?)
(let [on-press (if @command? (let [on-press (if @command?
(on-press-commands-handler @command) (on-press-commands-handler @command)
plain-message/send)] plain-message/send)]
[send-button {:on-press #(on-press %) [send-button {:on-press #(do (dispatch [:set-chat-ui-props :show-emoji? false])
:accessibility-label :send-message}])) (on-press %))}]))
(when (and @command? (= :command (:type @command))) (when (and @command? (= :command (:type @command)))
[command/command-icon @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 animated-view
icon icon
text text
touchable-highlight]] touchable-highlight
dismiss-keyboard!]]
[status-im.components.animation :as anim] [status-im.components.animation :as anim]
[status-im.chat.styles.plain-message :as st] [status-im.chat.styles.plain-message :as st]
[status-im.constants :refer [response-input-hiding-duration]])) [status-im.constants :refer [response-input-hiding-duration]]))
@ -56,7 +57,8 @@
on-update on-update
:reagent-render :reagent-render
(fn [height on-press] (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)) (on-press))
:disabled @command?} :disabled @command?}
[animated-view {:style (st/message-input-button-touchable container-width height)} [animated-view {:style (st/message-input-button-touchable container-width height)}
@ -97,9 +99,8 @@
on-update on-update
:reagent-render :reagent-render
(fn [] (fn []
[touchable-highlight {:on-press (fn [] [touchable-highlight {:on-press #(do (dispatch [:toggle-chat-ui-props :show-emoji?])
;; TODO emoticons: not implemented (dismiss-keyboard!))
)
:disabled @command?} :disabled @command?}
[animated-view {:style (st/message-input-button-touchable container-width height)} [animated-view {:style (st/message-input-button-touchable container-width height)}
[animated-view {:style (st/message-input-button buttons-scale 16)} [animated-view {:style (st/message-input-button buttons-scale 16)}

View File

@ -123,3 +123,12 @@
(defn copy-to-clipboard [text] (defn copy-to-clipboard [text]
(.setString (.-Clipboard react-native) 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] (fn [e]
(let [h (.. e -endCoordinates -height)] (let [h (.. e -endCoordinates -height)]
(when-not (= h @keyboard-height) (when-not (= h @keyboard-height)
(dispatch [:set :keyboard-height h]))))) (dispatch [:set :keyboard-height h])
(dispatch [:set :keyboard-max-height h])))))
(.addListener keyboard (.addListener keyboard
"keyboardWillHide" "keyboardWillHide"
#(when-not (= 0 @keyboard-height) #(when-not (= 0 @keyboard-height)