diff --git a/.re-natal b/.re-natal
index 76261cfccd..7c0d7e5cca 100644
--- a/.re-natal
+++ b/.re-natal
@@ -38,7 +38,6 @@
"web3",
"eccjs",
"chance",
- "react-native-emoji-picker",
"react-native-autolink",
"instabug-reactnative",
"nfc-react-native",
diff --git a/package.json b/package.json
index 869df56bb3..42bfe57560 100644
--- a/package.json
+++ b/package.json
@@ -53,7 +53,6 @@
"react-native-config": "0.9.0",
"react-native-crypto": "2.1.1",
"react-native-dialogs": "0.0.20",
- "react-native-emoji-picker": "git+https://github.com/status-im/react-native-emoji-picker.git",
"react-native-fcm": "10.0.3",
"react-native-fs": "2.8.1",
"react-native-http": "github:tradle/react-native-http#834492d",
diff --git a/react-native/src/status_im/react_native/js_dependencies.cljs b/react-native/src/status_im/react_native/js_dependencies.cljs
index 66efbb4b1e..3441e95f30 100644
--- a/react-native/src/status_im/react_native/js_dependencies.cljs
+++ b/react-native/src/status_im/react_native/js_dependencies.cljs
@@ -6,7 +6,6 @@
(def config (js/require "react-native-config"))
(def dialogs (js/require "react-native-dialogs"))
(def dismiss-keyboard (js/require "dismissKeyboard"))
-(def emoji-picker (js/require "react-native-emoji-picker"))
(def fs (js/require "react-native-fs"))
(def http-bridge (js/require "react-native-http-bridge"))
;; i18n is now exported in default object of the module
diff --git a/resources/icons/commands_list.svg b/resources/icons/commands_list.svg
deleted file mode 100644
index a2832a539e..0000000000
--- a/resources/icons/commands_list.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/resources/icons/input_commands.svg b/resources/icons/input_commands.svg
new file mode 100644
index 0000000000..7188dbdfe8
--- /dev/null
+++ b/resources/icons/input_commands.svg
@@ -0,0 +1,3 @@
+
diff --git a/resources/icons/input_send.svg b/resources/icons/input_send.svg
new file mode 100644
index 0000000000..309b13351f
--- /dev/null
+++ b/resources/icons/input_send.svg
@@ -0,0 +1,3 @@
+
diff --git a/resources/icons/smile.svg b/resources/icons/smile.svg
deleted file mode 100644
index 6b219e3c4b..0000000000
--- a/resources/icons/smile.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
diff --git a/resources/js/bots/console/bot.js b/resources/js/bots/console/bot.js
index ee8998b0a8..e72c03383d 100644
--- a/resources/js/bots/console/bot.js
+++ b/resources/js/bots/console/bot.js
@@ -1,17 +1,11 @@
-function jsSuggestionsContainerStyle(suggestionsCount) {
- return {
- marginVertical: 1,
- marginHorizontal: 0,
- keyboardShouldPersistTaps: "always",
- //height: Math.min(150, (56 * suggestionsCount)),
- backgroundColor: "white",
- borderRadius: 5,
- keyboardShouldPersistTaps: "always"
- };
-}
+var jsSuggestionsContainerStyle = {
+ keyboardShouldPersistTaps: "always",
+ backgroundColor: "white",
+ flexGrow: 1,
+ bounces: false
+};
var jsSuggestionContainerStyle = {
- paddingLeft: 16,
backgroundColor: "white"
};
@@ -22,22 +16,34 @@ var jsSubContainerStyle = {
borderBottomColor: "#0000001f"
};
+function jsSuggestionSubContainerStyle(isLast) {
+ var borderBottomWidth = (isLast ? 0 : 1);
+
+ return {
+ paddingTop: 14,
+ paddingBottom: 14,
+ paddingRight: 14,
+ marginLeft: 14,
+ borderBottomWidth: borderBottomWidth,
+ borderBottomColor: "#e8ebec"
+ };
+}
+
var jsValueStyle = {
- fontSize: 14,
+ fontSize: 15,
fontFamily: "font",
color: "#000000de"
};
var jsBoldValueStyle = {
- fontSize: 14,
+ fontSize: 15,
fontFamily: "font",
color: "#000000de",
fontWeight: "bold"
};
var jsDescriptionStyle = {
- marginTop: 1.5,
- paddingBottom: 9,
+ marginTop: 2,
fontSize: 14,
fontFamily: "font",
color: "#838c93de"
@@ -324,7 +330,7 @@ function jsSuggestions(params, context) {
suggestion.title = createMarkupText(suggestion.title);
}
var suggestionMarkup = status.components.view(jsSuggestionContainerStyle,
- [status.components.view(jsSubContainerStyle,
+ [status.components.view(jsSuggestionSubContainerStyle(i == suggestions.length - 1),
[
status.components.text({style: jsValueStyle},
suggestion.title),
@@ -342,9 +348,7 @@ function jsSuggestions(params, context) {
}
if (sugestionsMarkup.length > 0) {
- var view = status.components.scrollView(jsSuggestionsContainerStyle(sugestionsMarkup.length),
- sugestionsMarkup
- );
+ var view = status.components.scrollView(jsSuggestionsContainerStyle, sugestionsMarkup);
return {markup: view};
} else {
return {markup: null};
@@ -371,39 +375,41 @@ function jsHandler(params, context) {
return result;
}
-function suggestionsContainerStyle(suggestionsCount) {
- return {
- marginVertical: 1,
- marginHorizontal: 0,
- keyboardShouldPersistTaps: "always",
- height: Math.min(150, (56 * suggestionsCount)),
- backgroundColor: "white",
- borderRadius: 5,
- flexGrow: 1
- };
+var suggestionsContainerStyle = {
+ keyboardShouldPersistTaps: "always",
+ backgroundColor: "white",
+ flexGrow: 1,
+ bounces: false
}
var suggestionContainerStyle = {
- paddingLeft: 16,
backgroundColor: "white"
};
-var suggestionSubContainerStyle = {
- height: 56,
- borderBottomWidth: 1,
- borderBottomColor: "#0000001f"
-};
+function suggestionSubContainerStyle(isTwoLineEntry, isLast) {
+ var height = (isTwoLineEntry ? 64 : 48);
+ var borderBottomWidth = (isLast ? 0 : 1);
+
+ return {
+ paddingTop: 14,
+ paddingBottom: 14,
+ paddingRight: 14,
+ marginLeft: 14,
+ height: height,
+ borderBottomWidth: borderBottomWidth,
+ borderBottomColor: "#e8ebec"
+ };
+}
var valueStyle = {
- marginTop: 9,
- fontSize: 14,
+ fontSize: 15,
fontFamily: "font",
color: "#000000de"
};
var descriptionStyle = {
- marginTop: 1.5,
- fontSize: 14,
+ marginTop: 2,
+ fontSize: 13,
fontFamily: "font",
color: "#838c93de"
};
@@ -443,13 +449,15 @@ function getFaucets(networkId) {
var faucets = getFaucets(status.ethereumNetworkId);
function faucetSuggestions(params) {
- var suggestions = faucets.map(function (entry) {
+ var subContainerStyle = suggestionSubContainerStyle(true, false);
+
+ var suggestions = faucets.map(function (entry, index) {
return status.components.touchable(
- {onPress: status.components.dispatch([status.events.SET_COMMAND_ARGUMENT, [0, entry.url, false]])},
+ {onPress: status.components.dispatch([status.events.SET_COMMAND_ARGUMENT, [0, entry.url, true]])},
status.components.view(
suggestionContainerStyle,
[status.components.view(
- suggestionSubContainerStyle,
+ (index == faucets.length - 1 ? suggestionSubContainerStyle(true, true) : subContainerStyle),
[
status.components.text(
{style: valueStyle},
@@ -466,11 +474,13 @@ function faucetSuggestions(params) {
});
var view = status.components.scrollView(
- suggestionsContainerStyle(faucets.length),
+ suggestionsContainerStyle,
suggestions
);
- return {markup: view};
+ var entryHeight = subContainerStyle.height + subContainerStyle.borderBottomWidth;
+
+ return {markup: view, height: entryHeight * faucets.length};
}
var faucetCommandConfig ={
@@ -523,13 +533,16 @@ if (faucets.length > 0) {
}
function debugSuggestions(params) {
- var suggestions = ["On", "Off"].map(function (entry) {
+ var values = ["On", "Off"];
+ var subContainerStyle = suggestionSubContainerStyle(false, false);
+
+ var suggestions = values.map(function (entry, index) {
return status.components.touchable(
- {onPress: status.components.dispatch([status.events.SET_COMMAND_ARGUMENT, [0, entry, false]])},
+ {onPress: status.components.dispatch([status.events.SET_COMMAND_ARGUMENT, [0, entry, true]])},
status.components.view(
suggestionContainerStyle,
[status.components.view(
- suggestionSubContainerStyle,
+ (index == values.length - 1 ? suggestionSubContainerStyle(false, true) : subContainerStyle),
[
status.components.text(
{style: valueStyle},
@@ -542,11 +555,13 @@ function debugSuggestions(params) {
});
var view = status.components.scrollView(
- suggestionsContainerStyle(faucets.length),
+ suggestionsContainerStyle,
suggestions
);
- return {markup: view};
+ var entryHeight = subContainerStyle.height + subContainerStyle.borderBottomWidth;
+
+ return {markup: view, height: entryHeight * values.length};
}
status.command({
diff --git a/src/status_im/chat/events.cljs b/src/status_im/chat/events.cljs
index 0581ad25ca..5076d9fbfe 100644
--- a/src/status_im/chat/events.cljs
+++ b/src/status_im/chat/events.cljs
@@ -132,7 +132,6 @@
[re-frame/trim-v]
(fn [db [details]]
(model/set-chat-ui-props db {:show-bottom-info? true
- :show-emoji? false
:bottom-info details})))
(def index-messages (partial into {} (map (juxt :message-id identity))))
diff --git a/src/status_im/chat/events/input.cljs b/src/status_im/chat/events/input.cljs
index 61a5e1e4cd..0ab840022f 100644
--- a/src/status_im/chat/events/input.cljs
+++ b/src/status_im/chat/events/input.cljs
@@ -186,7 +186,6 @@
(bots-events/clear-bot-db owner-id)
clear-seq-arguments
(model/set-chat-ui-props {:show-suggestions? false
- :show-emoji? false
:result-box nil
:validation-messages nil
:prev-command name})
diff --git a/src/status_im/chat/screen.cljs b/src/status_im/chat/screen.cljs
index f684759a26..6c3dc4a387 100644
--- a/src/status_im/chat/screen.cljs
+++ b/src/status_im/chat/screen.cljs
@@ -97,9 +97,8 @@
(defview chat []
(letsubs [{:keys [group-chat input-text]} [:get-current-chat]
show-bottom-info? [:get-current-chat-ui-prop :show-bottom-info?]
- show-emoji? [:get-current-chat-ui-prop :show-emoji?]
+ layout-height [:get :layout-height]
current-view [:get :view-id]]
- {:component-will-unmount #(re-frame/dispatch [:set-chat-ui-props {:show-emoji? false}])}
[react/view {:style style/chat-view}
[chat-toolbar]
(when (= :chat current-view)
diff --git a/src/status_im/chat/styles/animations.cljs b/src/status_im/chat/styles/animations.cljs
index 3072eececf..2d6447cfa3 100644
--- a/src/status_im/chat/styles/animations.cljs
+++ b/src/status_im/chat/styles/animations.cljs
@@ -4,16 +4,6 @@
(def color-root-border "rgba(192, 198, 202, 0.28)")
(def header-draggable-icon "rgba(73, 84, 93, 0.23)")
-(defn result-box-overlay [max-height opacity-anim-value]
- {:background-color common/color-black
- :position :absolute
- :opacity opacity-anim-value
- :height max-height
- :elevation 2
- :bottom 0
- :left 0
- :right 0})
-
(def overlap-container
{:position :absolute
:left 0
@@ -23,14 +13,14 @@
(defn expandable-container [anim-value bottom]
{:background-color common/color-white
- :border-top-color color-root-border
- :border-top-width 1
- :elevation 2
:height anim-value
:left 0
:right 0
:bottom bottom
- :position :absolute})
+ :position :absolute
+ :border-top-color color-root-border
+ :border-top-width 1
+ :elevation 2})
(def header-container
{:min-height 19
diff --git a/src/status_im/chat/styles/input/emoji.cljs b/src/status_im/chat/styles/input/emoji.cljs
deleted file mode 100644
index 42cb7232a5..0000000000
--- a/src/status_im/chat/styles/input/emoji.cljs
+++ /dev/null
@@ -1,16 +0,0 @@
-(ns status-im.chat.styles.input.emoji
- (:require [status-im.ui.components.styles :as common]))
-
-(def container-height 250)
-
-(defn container [height]
- {:flex-direction :column
- :height (or height container-height)
- :background-color common/color-white})
-
-(def emoji-container
- {:flex 1})
-
-(def emoji-picker
- {:flex 1
- :background-color common/color-white})
diff --git a/src/status_im/chat/styles/input/input.cljs b/src/status_im/chat/styles/input/input.cljs
index 66cbb5a4c8..691a82d921 100644
--- a/src/status_im/chat/styles/input/input.cljs
+++ b/src/status_im/chat/styles/input/input.cljs
@@ -1,69 +1,52 @@
(ns status-im.chat.styles.input.input
(:require-macros [status-im.utils.styles :refer [defstyle defnstyle]])
(:require [status-im.ui.components.styles :as common]
- [status-im.utils.platform :as platform]
- [taoensso.timbre :as log]))
+ [status-im.ui.components.colors :as colors]
+ [status-im.utils.platform :as platform]))
-(def color-root-border "#e8eaeb")
-(def color-input "#edf1f3")
-(def color-input-helper-text "rgb(182, 189, 194)")
-(def color-input-helper-placeholder "rgb(182, 189, 194)")
-(def color-command "#70777d")
-(def color-send "rgb(98, 143, 227)")
-
-(def min-input-height 38)
+(def min-input-height 36)
+(def padding-vertical 8)
+(def border-height 1)
(def max-input-height (* 4 min-input-height))
(defnstyle root [margin-bottom]
- {:flex-direction :column
- :elevation 2
- :margin-bottom margin-bottom
- :border-top-width 1
- :border-top-color color-root-border})
-
-(defn container [container-anim-margin bottom-anim-margin]
{:background-color common/color-white
+ :margin-bottom margin-bottom
:flex-direction :column
- :padding-left container-anim-margin
- :padding-right container-anim-margin
- :padding-top 8
- :padding-bottom bottom-anim-margin})
-
-(defstyle input-container-view
- {:ios {:z-index 1}})
+ :border-top-width border-height
+ :border-top-color colors/light-gray
+ :elevation 2})
(def input-container
- {:flex-direction :row
- :align-items :flex-end})
+ {:flex-direction :row
+ :align-items :flex-end
+ :padding-left 14
+ :padding-right 14})
-(defn input-root [content-height anim-margin]
+(def input-root
+ {:padding-top padding-vertical
+ :padding-bottom padding-vertical
+ :flex 1})
+
+(defn input-animated [content-height]
{:align-items :flex-start
- :background-color color-input
:flex-direction :row
:flex-grow 1
- :height (min (max min-input-height content-height) max-input-height)
- :margin-top anim-margin
- :padding-left 10
- :padding-right 10
- :border-radius 8})
-
-(defnstyle input-touch-handler-view [container-width]
- {:position :absolute
- :width container-width
- :height min-input-height})
+ :height (min (max min-input-height content-height) max-input-height)})
(defnstyle input-view [content-height single-line-input?]
{:flex 1
- :font-size 14
+ :font-size 15
:padding-top 9
:padding-bottom 5
+ :padding-right 12
:height (if single-line-input?
min-input-height
(+ (min (max min-input-height content-height) max-input-height)))
:android {:padding-top 3}})
(def invisible-input-text
- {:font-size 14
+ {:font-size 15
:position :absolute
:left 0
:background-color :transparent
@@ -72,7 +55,7 @@
(defnstyle invisible-input-text-height [container-width]
{:width container-width
:flex 1
- :font-size 14
+ :font-size 15
:padding-top 5
:padding-bottom 5
:android {:padding-top 3}
@@ -81,45 +64,44 @@
:background-color :transparent
:color :transparent})
+(defnstyle input-helper-view [left opacity]
+ {:opacity opacity
+ :position :absolute
+ :height min-input-height
+ :android {:left (+ 4 left)}
+ :ios {:left left}})
+
(defnstyle input-helper-text [left]
- {:color color-input-helper-text
- :font-size 14
- :position :absolute
+ {:color colors/gray
+ :font-size 15
:text-align-vertical :center
- :height min-input-height
- :align-items :center
- :android {:left (+ 15 left)
- :top -1}
- :ios {:line-height min-input-height
- :left (+ 10 left)}})
+ :flex 1
+ :android {:top -1}
+ :ios {:line-height min-input-height}})
(defnstyle seq-input-text [left container-width]
{:min-width (- container-width left)
- :font-size 14
+ :font-size 15
:position :absolute
:text-align-vertical :center
- :height min-input-height
:align-items :center
- :android {:left (+ 10 left)
- :top 0.5}
+ :android {:left (+ 2 left)
+ :height (+ 2 min-input-height)
+ :top 0.5}
:ios {:line-height min-input-height
- :left (+ 9 left)}})
+ :height min-input-height
+ :left left}})
-(def input-emoji-icon
- {:margin-top 7
- :height 24
- :width 24})
+(def input-commands-icon
+ {:margin-bottom 14
+ :height 24
+ :width 24})
(def input-clear-container
- {:width 24
- :height 24
- :margin-top 7
- :align-items :center})
-
-(def input-clear-icon
- {:width 24
- :height 24
- :margin-top 0})
+ {:width 24
+ :height 24
+ :margin-top 7
+ :align-items :center})
(def commands-root
{:flex-direction :row
@@ -133,30 +115,3 @@
(def commands-list-icon
{:height 24
:width 24})
-
-(def close-commands-list-icon
- {:height 24
- :width 24})
-
-(def send-message-container
- {:background-color color-send
- :width 38
- :height 38
- :border-radius 19
- :padding 7
- :margin-left 8})
-
-(def send-message-icon
- {:height 24
- :width 24})
-
-(def commands
- {:flex-direction :row
- :margin-right 16})
-
-(defn command [first?]
- {:color color-command
- :font-size 14
- :margin-left (if first? 10 16)
- :padding-top 8
- :padding-bottom 8})
diff --git a/src/status_im/chat/styles/input/input_actions.cljs b/src/status_im/chat/styles/input/input_actions.cljs
deleted file mode 100644
index aaf40e894d..0000000000
--- a/src/status_im/chat/styles/input/input_actions.cljs
+++ /dev/null
@@ -1,27 +0,0 @@
-(ns status-im.chat.styles.input.input-actions
- (:require-macros [status-im.utils.styles :refer [defnstyle]])
- (:require [status-im.ui.components.styles :as common]))
-
-(def actions-container
- {:flex-direction :row
- :margin-left 10})
-
-(defn action-view [enabled?]
- {:width 38
- :height 38
- :opacity (if enabled? 1 0.5)
- :justify-content :center
- :align-items :center})
-
-(def action-view-icon
- {:width 24
- :height 24})
-
-(def action-view-icon-tinted
- {:width 24
- :height 24
- :tint-color "black"})
-
-(def action-view-fullscreen-expand-icon
- {:width 16
- :height 16})
\ No newline at end of file
diff --git a/src/status_im/chat/styles/input/parameter_box.cljs b/src/status_im/chat/styles/input/parameter_box.cljs
new file mode 100644
index 0000000000..e3c7d6c6d6
--- /dev/null
+++ b/src/status_im/chat/styles/input/parameter_box.cljs
@@ -0,0 +1,9 @@
+(ns status-im.chat.styles.input.parameter-box
+ (:require [status-im.ui.components.styles :as common]
+ [status-im.ui.components.colors :as colors]))
+
+(def root
+ {:background-color common/color-white
+ :border-top-color colors/light-gray
+ :border-top-width 1})
+
diff --git a/src/status_im/chat/styles/input/result_box.cljs b/src/status_im/chat/styles/input/result_box.cljs
index 93e5427dc9..4165a5366d 100644
--- a/src/status_im/chat/styles/input/result_box.cljs
+++ b/src/status_im/chat/styles/input/result_box.cljs
@@ -1,11 +1,10 @@
(ns status-im.chat.styles.input.result-box
- (:require [status-im.ui.components.styles :as common]))
-
-(def color-root-border "rgba(192, 198, 202, 0.5)")
+ (:require [status-im.ui.components.styles :as common]
+ [status-im.ui.components.colors :as colors]))
(defn root [height bottom]
{:background-color common/color-white
- :border-top-color color-root-border
+ :border-top-color colors/light-gray
:border-top-width 1
:flex-direction :column
:height height
diff --git a/src/status_im/chat/styles/input/send_button.cljs b/src/status_im/chat/styles/input/send_button.cljs
new file mode 100644
index 0000000000..c3989fbf68
--- /dev/null
+++ b/src/status_im/chat/styles/input/send_button.cljs
@@ -0,0 +1,16 @@
+(ns status-im.chat.styles.input.send-button
+ (:require [status-im.ui.components.colors :as colors]))
+
+(defn send-message-container [rotation]
+ {:background-color colors/blue
+ :width 30
+ :height 30
+ :border-radius 15
+ :padding 4
+ :margin-left 8
+ :margin-bottom 11
+ :transform [{:rotate rotation}]})
+
+(def send-message-icon
+ {:height 22
+ :width 22})
\ No newline at end of file
diff --git a/src/status_im/chat/styles/input/suggestions.cljs b/src/status_im/chat/styles/input/suggestions.cljs
index ed38e09496..e34438d35a 100644
--- a/src/status_im/chat/styles/input/suggestions.cljs
+++ b/src/status_im/chat/styles/input/suggestions.cljs
@@ -1,46 +1,32 @@
(ns status-im.chat.styles.input.suggestions
(:require-macros [status-im.utils.styles :refer [defnstyle]])
(:require [status-im.ui.components.styles :as common]
+ [status-im.ui.components.colors :as colors]
[status-im.utils.platform :as platform]))
-(def color-item-title-text "rgb(147, 155, 161)")
-(def color-item-suggestion-name "rgb(98, 143, 227)")
-(def color-item-border "#e8eaeb")
+(def item-height 52)
+(def border-height 1)
-(defn item-title-container [top-padding?]
- {:margin-left 16
- :align-items :center
- :flex-direction :row
- :height 44})
+(def root
+ {:background-color common/color-white
+ :border-top-color colors/light-gray
+ :border-top-width 1})
-(def item-title-text
- {:font-size 14
- :color color-item-title-text})
-
-(defnstyle item-suggestion-container [last?]
- {:flex-direction :row
- :align-items :center
- :height 56
- :margin-left 16
- :ios {:border-bottom-color color-item-border
- :border-bottom-width (if last? 0 1)}})
+(defn item-suggestion-container [last?]
+ {:flex-direction :row
+ :align-items :center
+ :height item-height
+ :margin-left 14
+ :padding-right 14
+ :border-bottom-color colors/light-gray
+ :border-bottom-width (if last? 0 border-height)})
(def item-suggestion-name
- {:background-color color-item-suggestion-name
- :height 28
- :flex-direction :row
- :align-items :center
- :border-radius 4
- :padding-left 7
- :padding-right 7})
-
-(def item-suggestion-name-text
- {:color common/color-white
- :font-size 14})
+ {:color common/color-black
+ :font-size 15})
(def item-suggestion-description
- {:flex 1
- :font-size 14
- :margin-left 16
- :margin-right 16
- :color color-item-title-text})
+ {:flex 1
+ :font-size 15
+ :margin-left 10
+ :color colors/gray})
diff --git a/src/status_im/chat/subs.cljs b/src/status_im/chat/subs.cljs
index 5ad243b0ff..60130d862a 100644
--- a/src/status_im/chat/subs.cljs
+++ b/src/status_im/chat/subs.cljs
@@ -1,14 +1,15 @@
(ns status-im.chat.subs
- (:require [re-frame.core :refer [reg-sub subscribe]]
+ (:require [clojure.string :as string]
+ [re-frame.core :refer [reg-sub subscribe]]
[status-im.constants :as constants]
+ [status-im.chat.constants :as chat-constants]
[status-im.chat.models.input :as input-model]
[status-im.chat.models.commands :as commands-model]
[status-im.chat.views.input.utils :as input-utils]
[status-im.commands.utils :as commands-utils]
[status-im.utils.datetime :as time]
[status-im.utils.platform :as platform]
- [status-im.i18n :as i18n]
- [clojure.string :as string]))
+ [status-im.i18n :as i18n]))
(reg-sub :get-chats :chats)
@@ -169,7 +170,9 @@
(defn- available-commands-responses [[commands-responses {:keys [input-text]}]]
(->> commands-responses
map->sorted-seq
- (filter #(string/includes? (commands-model/command-name %) (or input-text "")))))
+ (filter (fn [item]
+ (when (input-model/starts-as-command? input-text)
+ (string/includes? (commands-model/command-name item) input-text))))))
(reg-sub
:get-available-commands
@@ -198,6 +201,24 @@
(fn [[chat commands responses]]
(input-model/selected-chat-command chat commands responses)))
+(reg-sub
+ :chat-input-placeholder
+ :<- [:chat :input-text]
+ :<- [:selected-chat-command]
+ (fn [[input-text command]]
+ (when (and (string/ends-with? (or input-text "") chat-constants/spacing-char)
+ (not (get-in command [:command :sequential-params])))
+ (let [input (string/trim (or input-text ""))
+ real-args (remove string/blank? (:args command))]
+ (cond
+ (and command (empty? real-args))
+ (get-in command [:command :params 0 :placeholder])
+
+ (and command
+ (= (count real-args) 1)
+ (input-model/text-ends-with-space? input))
+ (get-in command [:command :params 1 :placeholder]))))))
+
(reg-sub
:current-chat-argument-position
:<- [:selected-chat-command]
@@ -242,16 +263,22 @@
input-model/command-completion)
(reg-sub
- :show-suggestions?
+ :show-suggestions-view?
:<- [:get-current-chat-ui-prop :show-suggestions?]
:<- [:get-current-chat]
:<- [:selected-chat-command]
:<- [:get-available-commands-responses]
(fn [[show-suggestions? {:keys [input-text]} selected-command commands-responses]]
(and (or show-suggestions? (input-model/starts-as-command? (string/trim (or input-text ""))))
- (not (:command selected-command))
(seq commands-responses))))
+(reg-sub
+ :show-suggestions?
+ :<- [:show-suggestions-view?]
+ :<- [:selected-chat-command]
+ (fn [[show-suggestions-box? selected-command]]
+ (and show-suggestions-box? (not (:command selected-command)))))
+
(reg-sub
:is-request-answered?
:<- [:get-current-chat]
diff --git a/src/status_im/chat/views/api/choose_contact.cljs b/src/status_im/chat/views/api/choose_contact.cljs
index 5e367aee0e..cc9abac56f 100644
--- a/src/status_im/chat/views/api/choose_contact.cljs
+++ b/src/status_im/chat/views/api/choose_contact.cljs
@@ -1,5 +1,5 @@
(ns status-im.chat.views.api.choose-contact
- (:require-macros [status-im.utils.views :refer [defview]])
+ (:require-macros [status-im.utils.views :refer [defview letsubs]])
(:require [re-frame.core :as re-frame]
[status-im.ui.components.contact.contact :refer [contact-view]]
[status-im.ui.components.list.views :as list]
@@ -17,17 +17,17 @@
(defview choose-contact-view [{title :title
arg-index :index
bot-db-key :bot-db-key}]
- [contacts [:people-in-current-chat]]
- [react/view {:flex 1}
- [react/text {:style {:font-size 14
- :color "rgb(147, 155, 161)"
- :padding-top 12
- :padding-left 16
- :padding-right 16
- :padding-bottom 12}}
- title]
- [list/flat-list {:data contacts
- :render-fn (render-contact arg-index bot-db-key)
- :enableEmptySections true
- :keyboardShouldPersistTaps :always
- :bounces false}]])
+ (letsubs [contacts [:people-in-current-chat]]
+ [react/view
+ [react/text {:style {:font-size 14
+ :color "rgb(147, 155, 161)"
+ :padding-top 12
+ :padding-left 16
+ :padding-right 16
+ :padding-bottom 12}}
+ title]
+ [list/flat-list {:data contacts
+ :render-fn (render-contact arg-index bot-db-key)
+ :enableEmptySections true
+ :keyboardShouldPersistTaps :always
+ :bounces false}]]))
diff --git a/src/status_im/chat/views/input/animations/expandable.cljs b/src/status_im/chat/views/input/animations/expandable.cljs
index 9b032ca09a..33a8e452ef 100644
--- a/src/status_im/chat/views/input/animations/expandable.cljs
+++ b/src/status_im/chat/views/input/animations/expandable.cljs
@@ -1,92 +1,92 @@
(ns status-im.chat.views.input.animations.expandable
(:require-macros [status-im.utils.views :refer [defview letsubs]])
- (:require [reagent.core :as r]
- [reagent.impl.component :as rc]
- [re-frame.core :refer [dispatch subscribe]]
- [status-im.ui.components.animation :as anim]
+ (:require [reagent.core :as reagent]
+ [re-frame.core :as re-frame]
+ [status-im.ui.components.animation :as animation]
[status-im.ui.components.drag-drop :as drag]
- [status-im.ui.components.react :refer [view
- animated-view]]
- [status-im.chat.views.input.animations.responder :as resp]
+ [status-im.ui.components.react :as react]
+ [status-im.chat.views.input.animations.responder :as responder]
[status-im.chat.views.input.utils :as input-utils]
[status-im.chat.styles.animations :as style]
- [taoensso.timbre :as log]
- [status-im.utils.platform :as p]))
+ [status-im.chat.styles.input.input :as input-style]))
(defn header [key container-height custom-header]
- (let [set-container-height (subscribe [:chat-animations key :height])
- max-container-height (subscribe [:get-max-container-area-height])
- pan-responder (resp/pan-responder container-height
- max-container-height
- :fix-expandable-height
- key)]
+ (let [set-container-height (re-frame/subscribe [:chat-animations key :height])
+ max-container-height (re-frame/subscribe [:get-max-container-area-height])
+ pan-responder (responder/pan-responder container-height
+ max-container-height
+ :fix-expandable-height
+ key)]
(fn [_]
- [view (merge (drag/pan-handlers pan-responder)
- {:style style/header-container})
- [view style/header-icon]
+ [react/view (merge (drag/pan-handlers pan-responder)
+ {:style style/header-container})
+ [react/view style/header-icon]
(when (and custom-header
(or (= @set-container-height :max)
(> @set-container-height (:min-height style/header-container))))
[custom-header])])))
(defn expandable-view-on-update [{:keys [anim-value to-changed-height max-height chat-input-margin height]}]
- (let [to-default-height (subscribe [:get-default-container-area-height])
- layout-height (subscribe [:get :layout-height])]
- (fn [_]
- (let [to-change-height (if (= @to-changed-height :max)
- (input-utils/max-container-area-height @chat-input-margin @layout-height)
- @to-changed-height)
- to-value (min (or @to-changed-height (or height @to-default-height))
- @max-height)]
- (dispatch [:set :expandable-view-height-to-value to-value])
- (anim/start
- (anim/spring anim-value {:toValue to-value
- :friction 10
- :tension 60}))))))
+ (let [to-default-height (re-frame/subscribe [:get-default-container-area-height])
+ layout-height (re-frame/subscribe [:get :layout-height])]
+ (fn [component]
+ ;; we're going to change the height here
-(defview overlay-view []
- (letsubs [max-height [:get-max-container-area-height]
- layout-height [:get :layout-height]
- view-height-to [:get :expandable-view-height-to-value]]
- (let [related-height (/ view-height-to max-height)]
- (when (> related-height 0.6)
- [animated-view {:style (style/result-box-overlay layout-height (- related-height (/ 0.4 related-height)))}]))))
+ ;; by default the height can be modified by dispatching :set-expandable-height,
+ ;; but there is also a way to make the height adjusted automatically — in this
+ ;; case you just need to set :dynamic-height? to true
+ (let [{:keys [dynamic-height?] dynamic-height :height} (reagent/props component)
+ to-changed-height (if dynamic-height?
+ dynamic-height
+ @to-changed-height)
+ to-change-height (if (= to-changed-height :max)
+ (input-utils/max-container-area-height @chat-input-margin @layout-height)
+ to-changed-height)
+ to-value (min (or to-change-height (or height @to-default-height))
+ @max-height)]
+ (re-frame/dispatch [:set :expandable-view-height-to-value to-value])
+ (animation/start
+ (animation/spring anim-value {:toValue to-value
+ :friction 10
+ :tension 60}))))))
(defn expandable-view [{:keys [key height hide-overlay?]} & _]
- (let [anim-value (anim/create-value 0)
- input-height (subscribe [:get-current-chat-ui-prop :input-height])
- max-height (subscribe [:get-max-container-area-height])
- fullscreen? (subscribe [:get-current-chat-ui-prop :fullscreen?])
- chat-input-margin (subscribe [:chat-input-margin])
- to-changed-height (subscribe [:chat-animations key :height])
- changes-counter (subscribe [:chat-animations key :changes-counter])
- on-update (expandable-view-on-update {:anim-value anim-value
- :to-changed-height to-changed-height
- :max-height max-height
- :chat-input-margin chat-input-margin
- :height height})]
- (r/create-class
+ (let [anim-value (animation/create-value 0)
+ input-height (re-frame/subscribe [:get-current-chat-ui-prop :input-height])
+ max-height (re-frame/subscribe [:get-max-container-area-height])
+ fullscreen? (re-frame/subscribe [:get-current-chat-ui-prop :fullscreen?])
+ chat-input-margin (re-frame/subscribe [:chat-input-margin])
+ to-changed-height (re-frame/subscribe [:chat-animations key :height])
+ changes-counter (re-frame/subscribe [:chat-animations key :changes-counter])
+ on-update (expandable-view-on-update {:anim-value anim-value
+ :to-changed-height to-changed-height
+ :max-height max-height
+ :chat-input-margin chat-input-margin
+ :height height})]
+ (reagent/create-class
{:component-did-mount
on-update
:component-did-update
on-update
:component-will-unmount
(fn []
- (dispatch [:set-chat-ui-props {:fullscreen? false}])
+ (re-frame/dispatch [:set-chat-ui-props {:fullscreen? false}])
(if height
- (dispatch [:set-expandable-height key height])
- (dispatch [:choose-predefined-expandable-height key :default])))
- :display-name "expandable-view"
+ (re-frame/dispatch [:set-expandable-height key height])
+ (re-frame/dispatch [:choose-predefined-expandable-height key :default])))
+ :display-name
+ "expandable-view"
:reagent-render
(fn [{:keys [draggable? custom-header]} & elements]
@to-changed-height @changes-counter @max-height
- (let [bottom (+ @input-height @chat-input-margin)
- height (if @fullscreen? @max-height anim-value)]
- [view style/overlap-container
- (when (and (not hide-overlay?)
- (not @fullscreen?))
- [overlay-view])
- (into [animated-view {:style (style/expandable-container height bottom)}
+ (let [input-height (or @input-height (+ input-style/padding-vertical
+ input-style/min-input-height
+ input-style/padding-vertical
+ input-style/border-height))
+ bottom (+ input-height @chat-input-margin)
+ height (if @fullscreen? @max-height anim-value)]
+ [react/view style/overlap-container
+ (into [react/animated-view {:style (style/expandable-container height bottom)}
(when (and draggable?
(not @fullscreen?))
[header key anim-value custom-header])]
diff --git a/src/status_im/chat/views/input/emoji.cljs b/src/status_im/chat/views/input/emoji.cljs
deleted file mode 100644
index e0abdb5149..0000000000
--- a/src/status_im/chat/views/input/emoji.cljs
+++ /dev/null
@@ -1,17 +0,0 @@
-(ns status-im.chat.views.input.emoji
- (:require-macros [status-im.utils.views :refer [defview]])
- (:require [re-frame.core :refer [subscribe dispatch]]
- [status-im.ui.components.react :refer [view
- text
- icon
- emoji-picker]]
- [status-im.chat.styles.input.emoji :as style]
- [status-im.i18n :refer [label]]))
-
-(defview emoji-view []
- [keyboard-max-height [:get :keyboard-max-height]]
- [view {:style (style/container keyboard-max-height)}
- [view style/emoji-container
- [emoji-picker {:style style/emoji-picker
- :hideClearButton true
- :onEmojiSelected #(dispatch [:add-to-chat-input-text %])}]]])
diff --git a/src/status_im/chat/views/input/input.cljs b/src/status_im/chat/views/input/input.cljs
index 40635794fe..8950fe3a83 100644
--- a/src/status_im/chat/views/input/input.cljs
+++ b/src/status_im/chat/views/input/input.cljs
@@ -1,138 +1,104 @@
(ns status-im.chat.views.input.input
(:require-macros [status-im.utils.views :refer [defview letsubs]])
- (:require [clojure.string :as str]
- [reagent.core :as r]
- [re-frame.core :refer [subscribe dispatch]]
- [taoensso.timbre :as log]
- [status-im.chat.constants :as const]
- [status-im.chat.models.input :as input-model]
- [status-im.chat.models.commands :as commands-model]
- [status-im.chat.styles.input.input :as style]
- [status-im.chat.views.input.emoji :as emoji]
+ (:require [clojure.string :as string]
+ [reagent.core :as reagent]
+ [re-frame.core :as re-frame]
+ [status-im.chat.constants :as constants]
+ [status-im.chat.styles.input.input :as style]
[status-im.chat.views.input.parameter-box :as parameter-box]
- [status-im.chat.views.input.input-actions :as input-actions]
[status-im.chat.views.input.result-box :as result-box]
+ [status-im.chat.views.input.send-button :as send-button]
[status-im.chat.views.input.suggestions :as suggestions]
[status-im.chat.views.input.validation-messages :as validation-messages]
- [status-im.ui.components.animation :as anim]
+ [status-im.ui.components.animation :as animation]
+ [status-im.ui.components.colors :as colors]
[status-im.ui.components.react :as react]
[status-im.ui.components.icons.vector-icons :as vi]
- [status-im.i18n :as i18n]
- [status-im.utils.platform :as platform]
[status-im.utils.utils :as utils]))
-(defn command-view [first? command]
- [react/touchable-highlight {:on-press #(dispatch [:select-chat-input-command command nil])}
- [react/view
- [react/text {:style (style/command first?)
- :font :roboto-mono}
- (commands-model/command-name command)]]])
+(defview basic-text-input [{:keys [set-layout-height-fn set-container-width-fn height single-line-input?]}]
+ (letsubs [input-text [:chat :input-text]
+ command [:selected-chat-command]
+ input-focused? [:get-current-chat-ui-prop :input-focused?]
+ input-ref (atom nil)]
+ [react/text-input
+ {:ref #(when %
+ (re-frame/dispatch [:set-chat-ui-props {:input-ref %}])
+ (reset! input-ref %))
+ :accessibility-label :chat-message-input
+ :multiline (not single-line-input?)
+ :default-value (or input-text "")
+ :editable true
+ :blur-on-submit false
+ :on-focus #(re-frame/dispatch [:set-chat-ui-props {:input-focused? true}])
+ :on-blur #(re-frame/dispatch [:set-chat-ui-props {:input-focused? false}])
+ :on-submit-editing (fn [e]
+ (if single-line-input?
+ (re-frame/dispatch [:send-current-message])
+ (.setNativeProps @input-ref (clj->js {:text (str input-text "\n")}))))
+ :on-layout (fn [e]
+ (set-container-width-fn (.-width (.-layout (.-nativeEvent e)))))
+ :on-change (fn [e]
+ (let [native-event (.-nativeEvent e)
+ text (.-text native-event)
+ content-size (.. native-event -contentSize)]
+ (when (and (not single-line-input?)
+ content-size)
+ (set-layout-height-fn (.-height content-size)))
+ (when (not= text input-text)
+ (re-frame/dispatch [:set-chat-input-text text])
+ (when command
+ (re-frame/dispatch [:load-chat-parameter-box (:command command)]))
+ (re-frame/dispatch [:update-input-data]))))
+ :on-content-size-change (when (and (not input-focused?)
+ (not single-line-input?))
+ #(let [h (-> (.-nativeEvent %)
+ (.-contentSize)
+ (.-height))]
+ (set-layout-height-fn h)))
+ :on-selection-change #(let [s (-> (.-nativeEvent %)
+ (.-selection))
+ end (.-end s)]
+ (re-frame/dispatch [:update-text-selection end]))
+ :style (style/input-view height single-line-input?)
+ :placeholder-text-color colors/gray
+ :auto-capitalize :sentences}]))
-(defview commands-view []
- [all-commands-responses [:get-available-commands-responses]
- show-suggestions? [:show-suggestions?]]
- [react/view style/commands-root
- [react/view style/command-list-icon-container
- [react/touchable-highlight {:on-press #(dispatch [:show-suggestions])}
- [react/view style/commands-list-icon
- (if show-suggestions?
- [vi/icon :icons/close]
- [vi/icon :icons/commands-list])]]]
- [react/scroll-view {:horizontal true
- :showsHorizontalScrollIndicator false
- :keyboardShouldPersistTaps :always}
- [react/view style/commands
- (for [[index command] (map-indexed vector all-commands-responses)]
- ^{:key (str "command-" index)}
- [command-view (= index 0) command])]]])
-
-(defn- basic-text-input [_]
- (let [input-text (subscribe [:chat :input-text])
- command (subscribe [:selected-chat-command])
- input-focused? (subscribe [:get-current-chat-ui-prop :input-focused?])
- input-ref (atom nil)]
- (fn [{:keys [set-layout-height-fn set-container-width-fn height single-line-input?]}]
- [react/text-input
- {:ref #(when %
- (dispatch [:set-chat-ui-props {:input-ref %}])
- (reset! input-ref %))
- :accessibility-label :chat-message-input
- :multiline (not single-line-input?)
- :default-value (or @input-text "")
- :editable true
- :blur-on-submit false
- :on-focus #(dispatch [:set-chat-ui-props {:input-focused? true
- :show-emoji? false}])
- :on-blur #(dispatch [:set-chat-ui-props {:input-focused? false}])
- :on-submit-editing (fn [e]
- (if single-line-input?
- (dispatch [:send-current-message])
- (.setNativeProps @input-ref (clj->js {:text (str @input-text "\n")}))))
- :on-layout (fn [e]
- (set-container-width-fn (.-width (.-layout (.-nativeEvent e)))))
- :on-change (fn [e]
- (let [native-event (.-nativeEvent e)
- text (.-text native-event)
- content-size (.. native-event -contentSize)]
- (when (and (not single-line-input?)
- content-size)
- (set-layout-height-fn (.-height content-size)))
- (when (not= text @input-text)
- (dispatch [:set-chat-input-text text])
- (when @command
- (dispatch [:load-chat-parameter-box (:command @command)]))
- (dispatch [:update-input-data]))))
- :on-content-size-change (when (and (not @input-focused?)
- (not single-line-input?))
- #(let [h (-> (.-nativeEvent %)
- (.-contentSize)
- (.-height))]
- (set-layout-height-fn h)))
- :on-selection-change #(let [s (-> (.-nativeEvent %)
- (.-selection))
- end (.-end s)]
- (dispatch [:update-text-selection end]))
- :style (style/input-view height single-line-input?)
- :placeholder-text-color style/color-input-helper-placeholder
- :auto-capitalize :sentences}])))
-
-(defn- invisible-input [{:keys [set-layout-width-fn value]}]
- (let [input-text (subscribe [:chat :input-text])]
+(defview invisible-input [{:keys [set-layout-width-fn value]}]
+ (letsubs [input-text [:chat :input-text]]
[react/text {:style style/invisible-input-text
:on-layout #(let [w (-> (.-nativeEvent %)
(.-layout)
(.-width))]
(set-layout-width-fn w))}
- (or @input-text "")]))
+ (or input-text "")]))
-(defn- invisible-input-height [{:keys [set-layout-height-fn container-width]}]
- (let [input-text (subscribe [:chat :input-text])]
+(defview invisible-input-height [{:keys [set-layout-height-fn container-width]}]
+ (letsubs [input-text [:chat :input-text]]
[react/text {:style (style/invisible-input-text-height container-width)
:on-layout #(let [h (-> (.-nativeEvent %)
(.-layout)
(.-height))]
(set-layout-height-fn h))}
- (or @input-text "")]))
+ (or input-text "")]))
-(defn- input-helper [_]
- (let [input-text (subscribe [:chat :input-text])]
- (fn [{:keys [command width]}]
- (when-not (get-in command [:command :sequential-params])
- (let [input (str/trim (or @input-text ""))
- real-args (remove str/blank? (:args command))]
- (when-let [placeholder (cond
- (= const/command-char input)
- (i18n/label :t/type-a-command)
+(defn- input-helper-view-on-update [{:keys [opacity-value placeholder]}]
+ (fn [_]
+ (let [to-value (if @placeholder 1 0)]
+ (animation/start
+ (animation/timing opacity-value {:toValue to-value
+ :duration 300})))))
- (and command (empty? real-args))
- (get-in command [:command :params 0 :placeholder])
+(defview input-helper [{:keys [width]}]
+ (letsubs [placeholder [:chat-input-placeholder]
+ opacity-value (animation/create-value 0)
+ on-update (input-helper-view-on-update {:opacity-value opacity-value
+ :placeholder placeholder})]
+ {:component-did-update on-update}
+ [react/animated-view {:style (style/input-helper-view width opacity-value)}
+ [react/text {:style (style/input-helper-text width)}
+ placeholder]]))
- (and command
- (= (count real-args) 1)
- (input-model/text-ends-with-space? input))
- (get-in command [:command :params 1 :placeholder]))]
- [react/text {:style (style/input-helper-text width)}
- placeholder]))))))
(defn get-options [type]
(case (keyword type)
@@ -141,149 +107,80 @@
:number {:keyboard-type "numeric"}
nil))
-(defn- seq-input [_]
- (let [command (subscribe [:selected-chat-command])
- arg-pos (subscribe [:current-chat-argument-position])
- seq-arg-input-text (subscribe [:chat :seq-argument-input-text])]
- (fn [{:keys [command-width container-width]}]
- (when (get-in @command [:command :sequential-params])
- (let [{:keys [placeholder hidden type]} (get-in @command [:command :params @arg-pos])]
- [react/text-input (merge {:ref #(dispatch [:set-chat-ui-props {:seq-input-ref %}])
- :style (style/seq-input-text command-width container-width)
- :default-value (or @seq-arg-input-text "")
- :on-change-text #(do (dispatch [:set-chat-seq-arg-input-text %])
- (dispatch [:load-chat-parameter-box (:command @command)])
- (dispatch [:set-chat-ui-props {:validation-messages nil}]))
- :placeholder placeholder
- :accessibility-label :chat-request-input
- :blur-on-submit false
- :editable true
- :on-focus #(dispatch [:set-chat-ui-props {:show-emoji? false}])
- :on-submit-editing (fn []
- (when-not (or (str/blank? @seq-arg-input-text)
- (get-in @command [:command :hide-send-button]))
- (dispatch [:send-seq-argument]))
- (utils/set-timeout
- #(dispatch [:chat-input-focus :seq-input-ref])
- 100))}
- (get-options type))])))))
+(defview seq-input [{:keys [command-width container-width]}]
+ (letsubs [command [:selected-chat-command]
+ arg-pos [:current-chat-argument-position]
+ seq-arg-input-text [:chat :seq-argument-input-text]]
+ (when (get-in command [:command :sequential-params])
+ (let [{:keys [placeholder hidden type]} (get-in command [:command :params arg-pos])]
+ [react/text-input (merge {:ref #(re-frame/dispatch [:set-chat-ui-props {:seq-input-ref %}])
+ :style (style/seq-input-text command-width container-width)
+ :default-value (or seq-arg-input-text "")
+ :on-change-text #(do (re-frame/dispatch [:set-chat-seq-arg-input-text %])
+ (re-frame/dispatch [:load-chat-parameter-box (:command command)])
+ (re-frame/dispatch [:set-chat-ui-props {:validation-messages nil}]))
+ :placeholder placeholder
+ :accessibility-label :chat-request-input
+ :blur-on-submit false
+ :editable true
+ :on-submit-editing (fn []
+ (when-not (or (string/blank? seq-arg-input-text)
+ (get-in @command [:command :hide-send-button]))
+ (re-frame/dispatch [:send-seq-argument]))
+ (utils/set-timeout
+ #(re-frame/dispatch [:chat-input-focus :seq-input-ref])
+ 100))}
+ (get-options type))]))))
-(defn input-view [_]
- (let [component (r/current-component)
- set-layout-width-fn #(r/set-state component {:width %})
- set-layout-height-fn #(r/set-state component {:height %})
- set-container-width-fn #(r/set-state component {:container-width %})
- command (subscribe [:selected-chat-command])]
- (r/create-class
- {:display-name "input-view"
- :reagent-render
- (fn [{:keys [anim-margin single-line-input?]}]
- (let [{:keys [width height container-width]} (r/state component)
- command @command]
- [react/animated-view {:style (style/input-root height anim-margin)}
- [invisible-input {:set-layout-width-fn set-layout-width-fn}]
- [invisible-input-height {:set-layout-height-fn set-layout-height-fn
- :container-width container-width}]
- [basic-text-input {:set-layout-height-fn set-layout-height-fn
- :set-container-width-fn set-container-width-fn
- :height height
- :single-line-input? single-line-input?}]
- [input-helper {:command command
- :width width}]
- [seq-input {:command-width width
- :container-width container-width}]
- (if-not command
- [react/touchable-highlight
- {:on-press #(do (dispatch [:toggle-chat-ui-props :show-emoji?])
- (react/dismiss-keyboard!))}
- [react/view
- [vi/icon :icons/smile {:container-style style/input-emoji-icon}]]]
- (when-not single-line-input?
- [react/touchable-highlight
- {:on-press #(do (dispatch [:set-chat-input-text nil])
- (dispatch [:set-chat-input-metadata nil])
- (dispatch [:set-chat-ui-props {:result-box nil
- :validation-messages nil}])
- (dispatch [:clear-seq-arguments]))}
- [react/view style/input-clear-container
- [vi/icon :icons/close]]]))]))})))
+(defview input-view [{:keys [single-line-input?]}]
+ (letsubs [command [:selected-chat-command]]
+ (let [component (reagent/current-component)
+ set-layout-width-fn #(reagent/set-state component {:width %})
+ set-layout-height-fn #(reagent/set-state component {:height %})
+ set-container-width-fn #(reagent/set-state component {:container-width %})
+ {:keys [width height container-width]} (reagent/state component)]
+ [react/view {:style style/input-root}
+ [react/animated-view {:style (style/input-animated height)}
+ [invisible-input {:set-layout-width-fn set-layout-width-fn}]
+ [invisible-input-height {:set-layout-height-fn set-layout-height-fn
+ :container-width container-width}]
+ [basic-text-input {:set-layout-height-fn set-layout-height-fn
+ :set-container-width-fn set-container-width-fn
+ :height height
+ :single-line-input? single-line-input?}]
+ [input-helper {:width width}]
+ [seq-input {:command-width width
+ :container-width container-width}]]])))
-(defview input-container [{:keys [anim-margin]}]
- (letsubs [command-completion [:command-completion]
- selected-command [:selected-chat-command]
- input-text [:chat :input-text]
- seq-arg-input-text [:chat :seq-argument-input-text]
- result-box [:get-current-chat-ui-prop :result-box]]
- (let [single-line-input? (:singleLineInput result-box)
- {:keys [hide-send-button sequential-params]} (:command selected-command)]
- [react/view style/input-container
- [input-view {:anim-margin anim-margin
- :single-line-input? single-line-input?}]
- (if (:actions result-box)
- [input-actions/input-actions-view]
- (when (and (not (str/blank? input-text))
- (or (not selected-command)
- (some #{:complete :less-than-needed} [command-completion]))
- (not hide-send-button))
- [react/touchable-highlight {:on-press #(if sequential-params
- (do
- (when-not (str/blank? seq-arg-input-text)
- (dispatch [:send-seq-argument]))
- (utils/set-timeout
- (fn [] (dispatch [:chat-input-focus :seq-input-ref]))
- 100))
- (dispatch [:send-current-message]))}
- [react/view {:style style/send-message-container
- :accessibility-label :send-message-button}
- [react/icon :arrow_top style/send-message-icon]]]))])))
+(defn commands-button []
+ [react/touchable-highlight
+ {:on-press #(do (re-frame/dispatch [:set-chat-input-text constants/command-char])
+ (react/dismiss-keyboard!))}
+ [react/view
+ [vi/icon :icons/input-commands {:container-style style/input-commands-icon
+ :color :dark}]]])
+
+(defview input-container []
+ (letsubs [margin [:chat-input-margin]
+ input-text [:chat :input-text]
+ result-box [:get-current-chat-ui-prop :result-box]]
+ (let [single-line-input? (:singleLineInput result-box)]
+ [react/view {:style (style/root margin)
+ :on-layout #(let [h (-> (.-nativeEvent %)
+ (.-layout)
+ (.-height))]
+ (when (> h 0)
+ (re-frame/dispatch [:set-chat-ui-props {:input-height h}])))}
+ [react/view {:style style/input-container}
+ [input-view {:single-line-input? single-line-input?}]
+ (when (string/blank? input-text)
+ [commands-button])
+ [send-button/send-button-view]]])))
(defn container []
- (let [margin (subscribe [:chat-input-margin])
- show-emoji? (subscribe [:get-current-chat-ui-prop :show-emoji?])
- input-text (subscribe [:chat :input-text])
- anim-margin (anim/create-value 10)
- container-anim-margin (anim/create-value 16)
- bottom-anim-margin (anim/create-value 14)]
- (r/create-class
- {:display-name "input-container"
- :component-did-mount
- (fn []
- (when-not (str/blank? @input-text)
- (.setValue anim-margin 0)
- (.setValue container-anim-margin 8)
- (.setValue bottom-anim-margin 8)))
- :component-did-update
- (fn [component]
- (let [{:keys [text-empty?]} (reagent.core/props component)]
- (let [to-anim-value (if text-empty? 10 0)
- to-container-anim-value (if text-empty? 16 8)
- to-bottom-anim-value (if text-empty? 14 8)]
- (anim/start
- (anim/timing anim-margin {:toValue to-anim-value
- :duration 100}))
- (anim/start
- (anim/timing container-anim-margin {:toValue to-container-anim-value
- :duration 100}))
- (anim/start
- (anim/timing bottom-anim-margin {:toValue to-bottom-anim-value
- :duration 100})))))
-
- :reagent-render
- (fn []
- [react/view style/input-container-view
- [parameter-box/parameter-box-view]
- [result-box/result-box-view]
- [suggestions/suggestions-view]
- [validation-messages/validation-messages-view]
- [react/view {:style (style/root @margin)
- :on-layout #(let [h (-> (.-nativeEvent %)
- (.-layout)
- (.-height))]
- (when (> h 0)
- (dispatch [:set-chat-ui-props {:input-height h}])))}
- [react/animated-view {:style (style/container container-anim-margin bottom-anim-margin)}
- (when (str/blank? @input-text)
- [commands-view])
- [input-container {:anim-margin anim-margin}]]
- (when @show-emoji?
- [emoji/emoji-view])]])})))
+ [react/view
+ [parameter-box/parameter-box-view]
+ [result-box/result-box-view]
+ [suggestions/suggestions-view]
+ [validation-messages/validation-messages-view]
+ [input-container]])
diff --git a/src/status_im/chat/views/input/input_actions.cljs b/src/status_im/chat/views/input/input_actions.cljs
deleted file mode 100644
index e2802674d8..0000000000
--- a/src/status_im/chat/views/input/input_actions.cljs
+++ /dev/null
@@ -1,25 +0,0 @@
-(ns status-im.chat.views.input.input-actions
- (:require [re-frame.core :as re-frame]
- [taoensso.timbre :as log]
- [status-im.ui.components.react :as react]
- [status-im.chat.styles.input.input-actions :as style]))
-
-(defmulti action-view (fn [{:keys [type]}] (keyword type)))
-
-(defmethod action-view :default
- [{:keys [image executeJs]}]
- [react/touchable-highlight
- {:on-press #(re-frame/dispatch [:chat-webview-bridge/send-to-bridge
- {:event "actions-execute-js"
- :js executeJs}])}
- [react/view (style/action-view true)
- [react/icon (str "action_" image) style/action-view-icon]]])
-
-(defn input-actions-view []
- (let [result-box (re-frame/subscribe [:get-current-chat-ui-prop :result-box])]
- (fn []
- (let [{:keys [actions]} @result-box]
- [react/view style/actions-container
- (for [{:keys [type] :as action} actions]
- ^{:key type}
- [action-view action])]))))
\ No newline at end of file
diff --git a/src/status_im/chat/views/input/parameter_box.cljs b/src/status_im/chat/views/input/parameter_box.cljs
index 7f813229ae..8624d0a773 100644
--- a/src/status_im/chat/views/input/parameter_box.cljs
+++ b/src/status_im/chat/views/input/parameter_box.cljs
@@ -1,23 +1,32 @@
(ns status-im.chat.views.input.parameter-box
- (:require-macros [status-im.utils.views :refer [defview]])
+ (:require-macros [status-im.utils.views :refer [defview letsubs]])
(:require [re-frame.core :refer [subscribe dispatch]]
- [status-im.chat.views.input.animations.expandable :refer [expandable-view]]
+ [status-im.chat.views.input.animations.expandable :as expandable]
[status-im.chat.views.input.box-header :as box-header]
+ [status-im.chat.styles.input.parameter-box :as style]
[status-im.commands.utils :as command-utils]
+ [status-im.ui.components.react :as react]
[taoensso.timbre :as log]))
(defview parameter-box-container []
[{:keys [markup]} [:chat-parameter-box]
bot-id-bot-db [:current-bot-db]]
(when markup
- (command-utils/generate-hiccup markup (first bot-id-bot-db) (second bot-id-bot-db))))
+ [react/view style/root
+ (command-utils/generate-hiccup markup (first bot-id-bot-db) (second bot-id-bot-db))]))
(defview parameter-box-view []
- [show-parameter-box? [:show-parameter-box?]
- {:keys [title]} [:chat-parameter-box]]
- (when show-parameter-box?
- [expandable-view {:key :parameter-box
- :draggable? true
- :custom-header (when title
- (box-header/get-header :parameter-box))}
- [parameter-box-container]]))
+ (letsubs [show-parameter-box? [:show-parameter-box?]
+ parameter-box [:chat-parameter-box]]
+ (let [{:keys [title height]} parameter-box
+ draggable? (not height)]
+ (when show-parameter-box?
+ [expandable/expandable-view
+ {:key :parameter-box
+ :draggable? draggable?
+ :custom-header (when title
+ (box-header/get-header :parameter-box))
+ :height (when-not draggable?
+ (+ height (:border-top-width style/root)))
+ :dynamic-height? (not draggable?)}
+ [parameter-box-container]]))))
diff --git a/src/status_im/chat/views/input/send_button.cljs b/src/status_im/chat/views/input/send_button.cljs
new file mode 100644
index 0000000000..e2c729d173
--- /dev/null
+++ b/src/status_im/chat/views/input/send_button.cljs
@@ -0,0 +1,47 @@
+(ns status-im.chat.views.input.send-button
+ (:require-macros [status-im.utils.views :refer [defview letsubs]])
+ (:require [clojure.string :as string]
+ [reagent.core :as reagent]
+ [re-frame.core :as re-frame]
+ [status-im.chat.styles.input.send-button :as style]
+ [status-im.ui.components.animation :as animation]
+ [status-im.ui.components.react :as react]
+ [status-im.ui.components.icons.vector-icons :as vi]
+ [status-im.utils.utils :as utils]))
+
+(defn send-button-view-on-update [{:keys [spin-value opacity-value command-completion]}]
+ (fn [_]
+ (let [to-spin-value (if (some #{:complete :no-command} [@command-completion]) 1 0)]
+ (animation/start
+ (animation/timing spin-value {:toValue to-spin-value
+ :duration 300})))))
+
+(defview send-button-view []
+ (letsubs [command-completion [:command-completion]
+ selected-command [:selected-chat-command]
+ input-text [:chat :input-text]
+ seq-arg-input-text [:chat :seq-argument-input-text]
+ spin-value (animation/create-value 1)
+ on-update (send-button-view-on-update {:spin-value spin-value
+ :command-completion command-completion})]
+ {:component-did-update on-update}
+ (let [{:keys [hide-send-button sequential-params]} (:command selected-command)]
+ (when (and (not (string/blank? input-text))
+ (or (not selected-command)
+ (some #{:complete :less-than-needed} [command-completion]))
+ (not hide-send-button))
+ [react/touchable-highlight {:on-press #(if sequential-params
+ (do
+ (when-not (string/blank? seq-arg-input-text)
+ (re-frame/dispatch [:send-seq-argument]))
+ (utils/set-timeout
+ (fn [] (re-frame/dispatch [:chat-input-focus :seq-input-ref]))
+ 100))
+ (re-frame/dispatch [:send-current-message]))}
+ (let [spin (.interpolate spin-value (clj->js {:inputRange [0 1]
+ :outputRange ["0deg" "90deg"]}))]
+ [react/animated-view
+ {:style (style/send-message-container spin)
+ :accessibility-label :send-message-button}
+ [vi/icon :icons/input-send {:container-style style/send-message-icon
+ :color :white}]])]))))
\ No newline at end of file
diff --git a/src/status_im/chat/views/input/suggestions.cljs b/src/status_im/chat/views/input/suggestions.cljs
index 7c999efbc6..a52ce93b1d 100644
--- a/src/status_im/chat/views/input/suggestions.cljs
+++ b/src/status_im/chat/views/input/suggestions.cljs
@@ -1,18 +1,18 @@
(ns status-im.chat.views.input.suggestions
- (:require-macros [status-im.utils.views :refer [defview]])
+ (:require-macros [status-im.utils.views :refer [defview letsubs]])
(:require [re-frame.core :as re-frame]
[status-im.ui.components.react :as react]
[status-im.chat.styles.input.suggestions :as style]
[status-im.chat.views.input.animations.expandable :as expandable]
- [status-im.chat.models.commands :as commands-model]
- [status-im.i18n :as i18n]))
+ [status-im.chat.models.commands :as commands-model]
+ [status-im.i18n :as i18n]
+ [taoensso.timbre :as log]))
(defn suggestion-item [{:keys [on-press name description last?]}]
[react/touchable-highlight {:on-press on-press}
[react/view (style/item-suggestion-container last?)
- [react/view {:style style/item-suggestion-name}
- [react/text {:style style/item-suggestion-name-text
- :font :roboto-mono} name]]
+ [react/text {:style style/item-suggestion-name}
+ name]
[react/text {:style style/item-suggestion-description
:number-of-lines 2}
description]]])
@@ -34,30 +34,25 @@
:description description
:last? last?}])
-(defn item-title [top-padding? title]
- [react/view (style/item-title-container top-padding?)
- [react/text {:style style/item-title-text}
- title]])
-
(defview suggestions-view []
- [show-suggestions? [:show-suggestions?]
- responses [:get-available-responses]
- commands [:get-available-commands]]
- (when show-suggestions?
- [expandable/expandable-view {:key :suggestions
- :draggable? false
- :height 212}
- [react/view {:flex 1}
- [react/scroll-view {:keyboardShouldPersistTaps :always}
- (when (seq responses)
- [react/view
- [item-title false (i18n/label :t/suggestions-requests)]
- (for [[i response] (map-indexed vector responses)]
- ^{:key i}
- [response-item response (= i (dec (count responses)))])])
- (when (seq commands)
- [react/view
- [item-title (seq responses) (i18n/label :t/suggestions-commands)]
- (for [[i command] (map-indexed vector commands)]
- ^{:key i}
- [command-item command (= i (dec (count commands)))])])]]]))
+ (letsubs [show-suggestions-view? [:show-suggestions-view?]
+ responses [:get-available-responses]
+ commands [:get-available-commands]]
+ (let [number-of-entries (+ (count responses) (count commands))]
+ [expandable/expandable-view {:key :suggestions
+ :draggable? false
+ :height (* number-of-entries
+ (+ style/item-height
+ style/border-height))
+ :dynamic-height? true}
+ [react/view
+ [react/scroll-view {:keyboard-should-persist-taps :always
+ :bounces false}
+ (when (seq responses)
+ (for [[i response] (map-indexed vector responses)]
+ ^{:key i}
+ [response-item response (= i (dec (count responses)))]))
+ (when (seq commands)
+ (for [[i command] (map-indexed vector commands)]
+ ^{:key i}
+ [command-item command (= i (dec (count commands)))]))]]])))
diff --git a/src/status_im/chat/views/message/message.cljs b/src/status_im/chat/views/message/message.cljs
index e97f47ec4b..224443131a 100644
--- a/src/status_im/chat/views/message/message.cljs
+++ b/src/status_im/chat/views/message/message.cljs
@@ -305,8 +305,6 @@
(fn [{:keys [outgoing group-chat content-type content] :as message}]
[message-container message
[react/touchable-highlight {:on-press #(when platform/ios?
- (re-frame/dispatch [:set-chat-ui-props
- {:show-emoji? false}])
(react/dismiss-keyboard!))
:on-long-press #(when (= content-type constants/text-content-type)
(list-selection/share content (i18n/label :t/message)))}
diff --git a/src/status_im/i18n.cljs b/src/status_im/i18n.cljs
index 0820877a0a..a0719b1385 100644
--- a/src/status_im/i18n.cljs
+++ b/src/status_im/i18n.cljs
@@ -206,7 +206,7 @@
:transactions-filter-type :next :recent
:open-on-etherscan :share :status :from
:wrong-password :search-chats :transactions-sign-later :in-contacts
- :transactions-sign :sharing-share :type-a-message :type-a-command
+ :transactions-sign :sharing-share :type-a-message
:usd-currency :existing-networks :node-unavailable :url :shake-your-phone
:add-network :unknown-status-go-error :contacts-group-new-chat :and-you
:wallets :clear-history :wallet-choose-from-contacts
diff --git a/src/status_im/ui/components/colors.cljs b/src/status_im/ui/components/colors.cljs
index 79c21735bb..cb41b5a66c 100644
--- a/src/status_im/ui/components/colors.cljs
+++ b/src/status_im/ui/components/colors.cljs
@@ -11,5 +11,5 @@
(def gray-lighter "#eef2f5") ;; Used as a background or shadow
(def blue "#4360df") ;; Used as main wallet color
(def red "#ff2d55") ;; Used to highlight errors or "dangerous" actions
-(def light-gray "#eef2f5") ;; Used as a background or shadow
+(def light-gray "#e8ebec") ;; Used as a background or shadow
(def text-light-gray "#212121") ;; Used for labels (home items)
diff --git a/src/status_im/ui/components/icons/vector_icons.cljs b/src/status_im/ui/components/icons/vector_icons.cljs
index 1da1a32c8a..9f22eb890e 100644
--- a/src/status_im/ui/components/icons/vector_icons.cljs
+++ b/src/status_im/ui/components/icons/vector_icons.cljs
@@ -62,8 +62,8 @@
:icons/public (slurp/slurp-svg "./resources/icons/public.svg")
:icons/public-chat (slurp/slurp-svg "./resources/icons/public_chat.svg")
:icons/qr (slurp/slurp-svg "./resources/icons/QR.svg")
- :icons/smile (slurp/slurp-svg "./resources/icons/smile.svg")
- :icons/commands-list (slurp/slurp-svg "./resources/icons/commands_list.svg")
+ :icons/input-commands (slurp/slurp-svg "./resources/icons/input_commands.svg")
+ :icons/input-send (slurp/slurp-svg "./resources/icons/input_send.svg")
:icons/back (slurp/slurp-svg "./resources/icons/back.svg")
:icons/forward (slurp/slurp-svg "./resources/icons/forward.svg")
:icons/dropdown-up (slurp/slurp-svg "./resources/icons/dropdown_up.svg")
diff --git a/src/status_im/ui/components/react.cljs b/src/status_im/ui/components/react.cljs
index 5937f2d4e9..ddcffd33f3 100644
--- a/src/status_im/ui/components/react.cljs
+++ b/src/status_im/ui/components/react.cljs
@@ -161,14 +161,6 @@
(.then clipboard-contents #(clbk %))))
-;; Emoji
-
-(def emoji-picker-class js-dependencies/emoji-picker)
-
-(def emoji-picker
- (let [emoji-picker (.-default emoji-picker-class)]
- (reagent/adapt-react-class emoji-picker)))
-
;; Autolink
(def autolink-class (reagent/adapt-react-class (.-default js-dependencies/autolink)))