commit
a479ae3e15
|
@ -128,7 +128,12 @@ public class GethModule extends ReactContextBaseJavaModule implements LifecycleE
|
||||||
}
|
}
|
||||||
|
|
||||||
@ReactMethod
|
@ReactMethod
|
||||||
public void startNode(Callback callback) {
|
public void startNode(Callback callback, Callback onAlreadyRunning) {
|
||||||
|
|
||||||
|
if(GethService.isRunning()){
|
||||||
|
onAlreadyRunning.invoke();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Activity currentActivity = getCurrentActivity();
|
Activity currentActivity = getCurrentActivity();
|
||||||
|
|
||||||
|
|
|
@ -213,7 +213,7 @@ public class GethService extends Service {
|
||||||
String address = data.getString("address");
|
String address = data.getString("address");
|
||||||
String password = data.getString("password");
|
String password = data.getString("password");
|
||||||
// TODO: remove third argument
|
// TODO: remove third argument
|
||||||
String result = Statusgo.Login(address, password);
|
String result = Statusgo.UnlockAccount(address, password, 0);
|
||||||
Log.d(TAG, "Unlocked account: " + result);
|
Log.d(TAG, "Unlocked account: " + result);
|
||||||
|
|
||||||
Bundle replyData = new Bundle();
|
Bundle replyData = new Bundle();
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
[prismatic/schema "1.0.4"]
|
[prismatic/schema "1.0.4"]
|
||||||
^{:voom {:repo "git@github.com:status-im/status-lib.git"
|
^{:voom {:repo "git@github.com:status-im/status-lib.git"
|
||||||
:branch "master"}}
|
:branch "master"}}
|
||||||
[status-im/protocol "0.1.1-20160630_153846-gbf92f5f"]
|
[status-im/protocol "0.1.1-20160706_085008-ge61756a"]
|
||||||
[natal-shell "0.1.6"]
|
[natal-shell "0.1.6"]
|
||||||
[com.andrewmcveigh/cljs-time "0.4.0"]]
|
[com.andrewmcveigh/cljs-time "0.4.0"]]
|
||||||
:plugins [[lein-cljsbuild "1.1.1"]
|
:plugins [[lein-cljsbuild "1.1.1"]
|
||||||
|
|
|
@ -3,7 +3,7 @@ status.command({
|
||||||
description: "Send location",
|
description: "Send location",
|
||||||
color: "#9a5dcf",
|
color: "#9a5dcf",
|
||||||
preview: function (params) {
|
preview: function (params) {
|
||||||
var text = status.components.text(
|
var text = status.components.text(
|
||||||
{
|
{
|
||||||
style: {
|
style: {
|
||||||
marginTop: 5,
|
marginTop: 5,
|
||||||
|
@ -138,6 +138,12 @@ status.response({
|
||||||
name: "phone",
|
name: "phone",
|
||||||
description: "Send phone number",
|
description: "Send phone number",
|
||||||
color: "#5fc48d",
|
color: "#5fc48d",
|
||||||
|
validator: function (params) {
|
||||||
|
return {
|
||||||
|
validationHandler: "phone",
|
||||||
|
parameters: [params.value]
|
||||||
|
};
|
||||||
|
},
|
||||||
params: [{
|
params: [{
|
||||||
name: "phone",
|
name: "phone",
|
||||||
type: status.types.PHONE,
|
type: status.types.PHONE,
|
||||||
|
@ -156,6 +162,16 @@ status.command({
|
||||||
name: "help",
|
name: "help",
|
||||||
description: "Help",
|
description: "Help",
|
||||||
color: "#7099e6",
|
color: "#7099e6",
|
||||||
|
/* Validator example
|
||||||
|
validator: function (params) {
|
||||||
|
if (params.value != "3") {
|
||||||
|
var error = status.components.view(
|
||||||
|
{backgroundColor: "red"},
|
||||||
|
[status.components.text({}, "ooops :(")]
|
||||||
|
);
|
||||||
|
return {errors: [error]}
|
||||||
|
}
|
||||||
|
},*/
|
||||||
params: [{
|
params: [{
|
||||||
name: "query",
|
name: "query",
|
||||||
type: status.types.TEXT
|
type: status.types.TEXT
|
||||||
|
|
|
@ -22,6 +22,7 @@ Command.prototype.create = function (com) {
|
||||||
this.name = com.name;
|
this.name = com.name;
|
||||||
this.description = com.description;
|
this.description = com.description;
|
||||||
this.handler = com.handler;
|
this.handler = com.handler;
|
||||||
|
this.validator = com.validator;
|
||||||
this.color = com.color;
|
this.color = com.color;
|
||||||
this.icon = com.icon;
|
this.icon = com.icon;
|
||||||
this.params = com.params || [];
|
this.params = com.params || [];
|
||||||
|
@ -83,13 +84,13 @@ function scrollView(options, elements) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var status = {
|
var status = {
|
||||||
command: function (n, d, h) {
|
command: function (h) {
|
||||||
var command = new Command();
|
var command = new Command();
|
||||||
return command.create(n, d, h);
|
return command.create(h);
|
||||||
},
|
},
|
||||||
response: function (n, d, h) {
|
response: function (h) {
|
||||||
var response = new Response();
|
var response = new Response();
|
||||||
return response.create(n, d, h);
|
return response.create(h);
|
||||||
},
|
},
|
||||||
types: {
|
types: {
|
||||||
TEXT: 'text',
|
TEXT: 'text',
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
(:require-macros [status-im.utils.views :refer [defview]])
|
(:require-macros [status-im.utils.views :refer [defview]])
|
||||||
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
|
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
|
||||||
[status-im.components.react :refer [view
|
[status-im.components.react :refer [view
|
||||||
text
|
text-class
|
||||||
text-input
|
text-input
|
||||||
image
|
image
|
||||||
linear-gradient
|
linear-gradient
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
(def toolbar-title
|
(def toolbar-title
|
||||||
[view toolbar-title-container
|
[view toolbar-title-container
|
||||||
[text {:style (merge toolbar-title-text {:color color-white})}
|
[text-class {:style (merge toolbar-title-text {:color color-white})}
|
||||||
(label :t/login)]])
|
(label :t/login)]])
|
||||||
|
|
||||||
(defview address-input [address]
|
(defview address-input [address]
|
||||||
|
@ -83,9 +83,9 @@
|
||||||
[view st/recover-text-container
|
[view st/recover-text-container
|
||||||
[touchable-highlight
|
[touchable-highlight
|
||||||
{:on-press #()}
|
{:on-press #()}
|
||||||
[text {:style st/recover-text} (label :t/recover-access)]]]
|
[text-class {:style st/recover-text} (label :t/recover-access)]]]
|
||||||
[view st/connect-button-container
|
[view st/connect-button-container
|
||||||
[touchable-highlight
|
[touchable-highlight
|
||||||
{:on-press #(dispatch [:login-account address password])}
|
{:on-press #(dispatch [:login-account address password])}
|
||||||
[view st/connect-button
|
[view st/connect-button
|
||||||
[text {:style st/connect-button-text} (label :t/connect)]]]]]])
|
[text-class {:style st/connect-button-text} (label :t/connect)]]]]]])
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
|
|
||||||
(defn app-root []
|
(defn app-root []
|
||||||
(let [signed-up (subscribe [:get :signed-up])
|
(let [signed-up (subscribe [:get :signed-up])
|
||||||
|
_ (log/debug "signed up: " @signed-up)
|
||||||
view-id (subscribe [:get :view-id])
|
view-id (subscribe [:get :view-id])
|
||||||
account (subscribe [:get :user-identity])
|
account (subscribe [:get :user-identity])
|
||||||
keyboard-height (subscribe [:get :keyboard-height])]
|
keyboard-height (subscribe [:get :keyboard-height])]
|
||||||
|
@ -59,15 +60,21 @@
|
||||||
"keyboardDidShow"
|
"keyboardDidShow"
|
||||||
(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])))))
|
||||||
(.addListener device-event-emitter
|
(.addListener device-event-emitter
|
||||||
"keyboardDidHide"
|
"keyboardDidHide"
|
||||||
(when-not (= 0 keyboard-height)
|
(when-not (= 0 @keyboard-height)
|
||||||
#(dispatch [:set :keyboard-height 0]))))
|
#(dispatch [:set :keyboard-height 0]))))
|
||||||
:render
|
:render
|
||||||
(fn []
|
(fn []
|
||||||
(let [startup-view (if @account @view-id (if (contains? #{:login :chat} @view-id) @view-id :accounts))]
|
(let [startup-view (if @account
|
||||||
|
(if @signed-up
|
||||||
|
@view-id
|
||||||
|
:chat)
|
||||||
|
(if (contains? #{:login :chat} @view-id)
|
||||||
|
@view-id
|
||||||
|
:accounts))]
|
||||||
(log/debug startup-view)
|
(log/debug startup-view)
|
||||||
(case (if true startup-view :chat)
|
(case (if true startup-view :chat)
|
||||||
:discovery [main-tabs]
|
:discovery [main-tabs]
|
||||||
|
|
|
@ -21,10 +21,13 @@
|
||||||
[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]
|
||||||
[status-im.components.react :refer [geth]]
|
[status-im.components.react :refer [geth]]
|
||||||
[status-im.utils.logging :as log]
|
|
||||||
[status-im.components.jail :as j]
|
[status-im.components.jail :as j]
|
||||||
[status-im.utils.types :refer [json->clj]]
|
[status-im.utils.types :refer [json->clj]]
|
||||||
[status-im.commands.utils :refer [generate-hiccup]]))
|
[status-im.commands.utils :refer [generate-hiccup]]
|
||||||
|
status-im.chat.handlers.commands
|
||||||
|
status-im.chat.handlers.animation
|
||||||
|
status-im.chat.handlers.requests
|
||||||
|
status-im.chat.handlers.unviewed-messages))
|
||||||
|
|
||||||
(register-handler :set-show-actions
|
(register-handler :set-show-actions
|
||||||
(fn [db [_ show-actions]]
|
(fn [db [_ show-actions]]
|
||||||
|
@ -53,81 +56,15 @@
|
||||||
(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 invoke-suggestions-handler!
|
|
||||||
[{:keys [current-chat-id canceled-command] :as db} _]
|
|
||||||
(when-not canceled-command
|
|
||||||
(let [{:keys [command content]} (get-in db [:chats current-chat-id :command-input])
|
|
||||||
{:keys [name type]} command
|
|
||||||
path [(if (= :command type) :commands :responses)
|
|
||||||
name
|
|
||||||
:params
|
|
||||||
0
|
|
||||||
:suggestions]
|
|
||||||
params {:value content}]
|
|
||||||
(j/call current-chat-id
|
|
||||||
path
|
|
||||||
params
|
|
||||||
#(dispatch [:suggestions-handler {:command command
|
|
||||||
:content content
|
|
||||||
:chat-id current-chat-id} %])))))
|
|
||||||
|
|
||||||
(register-handler :start-cancel-command
|
(register-handler :start-cancel-command
|
||||||
(u/side-effect!
|
(u/side-effect!
|
||||||
(fn [db _]
|
(fn [db _]
|
||||||
(dispatch [:animate-cancel-command]))))
|
(dispatch [:animate-cancel-command]))))
|
||||||
|
|
||||||
(def command-prefix "c ")
|
|
||||||
|
|
||||||
(defn cancel-command!
|
|
||||||
[{:keys [canceled-command]}]
|
|
||||||
(when canceled-command
|
|
||||||
(dispatch [:start-cancel-command])))
|
|
||||||
|
|
||||||
(register-handler :set-chat-command-content
|
|
||||||
[(after invoke-suggestions-handler!)
|
|
||||||
(after cancel-command!)]
|
|
||||||
(fn [{:keys [current-chat-id] :as db} [_ content]]
|
|
||||||
(let [starts-as-command? (str/starts-with? content command-prefix)
|
|
||||||
path [:chats current-chat-id :command-input :command :type]
|
|
||||||
command? (= :command (get-in db path))]
|
|
||||||
(as-> db db
|
|
||||||
(commands/set-chat-command-content db content)
|
|
||||||
(assoc-in db [:chats current-chat-id :input-text] nil)
|
|
||||||
(assoc db :canceled-command (and command? (not starts-as-command?)))))))
|
|
||||||
|
|
||||||
(defn update-input-text
|
(defn update-input-text
|
||||||
[{:keys [current-chat-id] :as db} text]
|
[{:keys [current-chat-id] :as db} text]
|
||||||
(assoc-in db [:chats current-chat-id :input-text] text))
|
(assoc-in db [:chats current-chat-id :input-text] text))
|
||||||
|
|
||||||
(defn invoke-command-preview!
|
|
||||||
[{:keys [current-chat-id staged-command]} _]
|
|
||||||
(let [{:keys [command content]} staged-command
|
|
||||||
{:keys [name type]} command
|
|
||||||
path [(if (= :command type) :commands :responses)
|
|
||||||
name
|
|
||||||
:preview]
|
|
||||||
params {:value content}]
|
|
||||||
(j/call current-chat-id
|
|
||||||
path
|
|
||||||
params
|
|
||||||
#(dispatch [:command-preview current-chat-id %]))))
|
|
||||||
|
|
||||||
(register-handler :stage-command
|
|
||||||
(after invoke-command-preview!)
|
|
||||||
(fn [{:keys [current-chat-id] :as db} _]
|
|
||||||
(let [db (update-input-text db nil)
|
|
||||||
{:keys [command content to-msg-id]}
|
|
||||||
(get-in db [:chats current-chat-id :command-input])
|
|
||||||
content' (if (= :command (:type command))
|
|
||||||
(subs content 2)
|
|
||||||
content)
|
|
||||||
command-info {:command command
|
|
||||||
:content content'
|
|
||||||
:to-message to-msg-id}]
|
|
||||||
(-> db
|
|
||||||
(commands/stage-command command-info)
|
|
||||||
(assoc :staged-command command-info)))))
|
|
||||||
|
|
||||||
(register-handler :set-message-input []
|
(register-handler :set-message-input []
|
||||||
(fn [db [_ input]]
|
(fn [db [_ input]]
|
||||||
(assoc db :message-input input)))
|
(assoc db :message-input input)))
|
||||||
|
@ -138,15 +75,6 @@
|
||||||
(when-let [message-input (:message-input db)]
|
(when-let [message-input (:message-input db)]
|
||||||
(.blur message-input)))))
|
(.blur message-input)))))
|
||||||
|
|
||||||
(register-handler :set-response-chat-command
|
|
||||||
[(after invoke-suggestions-handler!)
|
|
||||||
(after #(dispatch [:command-edit-mode]))
|
|
||||||
(after #(dispatch [:set-chat-input-text ""]))]
|
|
||||||
(fn [db [_ to-msg-id command-key]]
|
|
||||||
(-> db
|
|
||||||
(commands/set-response-chat-command to-msg-id command-key)
|
|
||||||
(assoc :canceled-command false))))
|
|
||||||
|
|
||||||
(defn update-text
|
(defn update-text
|
||||||
[{:keys [current-chat-id] :as db} [_ text]]
|
[{:keys [current-chat-id] :as db} [_ text]]
|
||||||
(let [suggestions (get-in db [:command-suggestions current-chat-id])]
|
(let [suggestions (get-in db [:command-suggestions current-chat-id])]
|
||||||
|
@ -215,20 +143,26 @@
|
||||||
(fn [db [_ {:keys [chat-id msg-id]}]]
|
(fn [db [_ {:keys [chat-id msg-id]}]]
|
||||||
(set-message-shown db chat-id msg-id)))
|
(set-message-shown db chat-id msg-id)))
|
||||||
|
|
||||||
|
(defn default-delivery-status [chat-id]
|
||||||
|
(if (console? chat-id)
|
||||||
|
:seen
|
||||||
|
:pending))
|
||||||
|
|
||||||
(defn prepare-message
|
(defn prepare-message
|
||||||
[{:keys [identity current-chat-id] :as db} _]
|
[{:keys [identity current-chat-id] :as db} _]
|
||||||
(let [text (get-in db [:chats current-chat-id :input-text])
|
(let [text (get-in db [:chats current-chat-id :input-text])
|
||||||
[command] (suggestions/check-suggestion db (str text " "))
|
[command] (suggestions/check-suggestion db (str text " "))
|
||||||
message (check-author-direction
|
message (check-author-direction
|
||||||
db current-chat-id
|
db current-chat-id
|
||||||
{:msg-id (random/id)
|
{:msg-id (random/id)
|
||||||
:chat-id current-chat-id
|
:chat-id current-chat-id
|
||||||
:content text
|
:content text
|
||||||
:to current-chat-id
|
:to current-chat-id
|
||||||
:from identity
|
:from identity
|
||||||
:content-type text-content-type
|
:content-type text-content-type
|
||||||
:outgoing true
|
:delivery-status (default-delivery-status current-chat-id)
|
||||||
:timestamp (time/now-ms)})]
|
:outgoing true
|
||||||
|
:timestamp (time/now-ms)})]
|
||||||
(if command
|
(if command
|
||||||
(commands/set-chat-command db command)
|
(commands/set-chat-command db command)
|
||||||
(assoc db :new-message (when-not (str/blank? text) message)))))
|
(assoc db :new-message (when-not (str/blank? text) message)))))
|
||||||
|
@ -242,6 +176,7 @@
|
||||||
:to chat-id
|
:to chat-id
|
||||||
:content content
|
:content content
|
||||||
:content-type content-type-command
|
:content-type content-type-command
|
||||||
|
:delivery-status (default-delivery-status chat-id)
|
||||||
:outgoing true
|
:outgoing true
|
||||||
:preview preview-string
|
:preview preview-string
|
||||||
:rendered-preview preview
|
:rendered-preview preview
|
||||||
|
@ -283,12 +218,10 @@
|
||||||
[{:keys [new-message current-chat-id] :as db} _]
|
[{:keys [new-message current-chat-id] :as db} _]
|
||||||
(when (and new-message (not-console? current-chat-id))
|
(when (and new-message (not-console? current-chat-id))
|
||||||
(let [{:keys [group-chat]} (get-in db [:chats current-chat-id])
|
(let [{:keys [group-chat]} (get-in db [:chats current-chat-id])
|
||||||
content (:content new-message)]
|
message (select-keys new-message [:content :msg-id])]
|
||||||
(if group-chat
|
(if group-chat
|
||||||
(api/send-group-user-msg {:group-id current-chat-id
|
(api/send-group-user-msg (assoc message :group-id current-chat-id))
|
||||||
:content content})
|
(api/send-user-msg (assoc message :to current-chat-id))))))
|
||||||
(api/send-user-msg {:to current-chat-id
|
|
||||||
:content content})))))
|
|
||||||
|
|
||||||
(defn save-message-to-realm!
|
(defn save-message-to-realm!
|
||||||
[{:keys [new-message current-chat-id]} _]
|
[{:keys [new-message current-chat-id]} _]
|
||||||
|
@ -322,13 +255,6 @@
|
||||||
params
|
params
|
||||||
#(dispatch [:command-handler! com %])))))
|
#(dispatch [:command-handler! com %])))))
|
||||||
|
|
||||||
(defn handle-commands
|
|
||||||
[{:keys [new-commands]}]
|
|
||||||
(doseq [{{content :content} :content
|
|
||||||
handler :handler} new-commands]
|
|
||||||
(when handler
|
|
||||||
(handler content))))
|
|
||||||
|
|
||||||
(register-handler :send-chat-msg
|
(register-handler :send-chat-msg
|
||||||
(-> prepare-message
|
(-> prepare-message
|
||||||
((enrich prepare-staged-commans))
|
((enrich prepare-staged-commans))
|
||||||
|
@ -341,21 +267,7 @@
|
||||||
((after save-commands-to-realm!))
|
((after save-commands-to-realm!))
|
||||||
((after dispatch-responded-requests!))
|
((after dispatch-responded-requests!))
|
||||||
;; todo maybe it is better to track if it was handled or not
|
;; todo maybe it is better to track if it was handled or not
|
||||||
((after invoke-commands-handlers!))
|
((after invoke-commands-handlers!))))
|
||||||
((after handle-commands))))
|
|
||||||
|
|
||||||
(register-handler :unstage-command
|
|
||||||
(fn [db [_ staged-command]]
|
|
||||||
(commands/unstage-command db staged-command)))
|
|
||||||
|
|
||||||
(register-handler :set-chat-command
|
|
||||||
[(after invoke-suggestions-handler!)
|
|
||||||
(after #(dispatch [:command-edit-mode]))]
|
|
||||||
(fn [{:keys [current-chat-id] :as db} [_ command-key]]
|
|
||||||
(-> db
|
|
||||||
(commands/set-chat-command command-key)
|
|
||||||
(assoc-in [:chats current-chat-id :command-input :content] "c ")
|
|
||||||
(assoc :disable-input true))))
|
|
||||||
|
|
||||||
(register-handler :init-console-chat
|
(register-handler :init-console-chat
|
||||||
(fn [db [_]]
|
(fn [db [_]]
|
||||||
|
@ -426,6 +338,7 @@
|
||||||
(assoc db :loaded-chats (chats/chats-list)))
|
(assoc db :loaded-chats (chats/chats-list)))
|
||||||
|
|
||||||
(register-handler :initialize-chats
|
(register-handler :initialize-chats
|
||||||
|
(after #(dispatch [:load-unviewed-messages!]))
|
||||||
((enrich initialize-chats) load-chats!))
|
((enrich initialize-chats) load-chats!))
|
||||||
|
|
||||||
(defn store-message!
|
(defn store-message!
|
||||||
|
@ -434,20 +347,27 @@
|
||||||
|
|
||||||
(defn dispatch-request!
|
(defn dispatch-request!
|
||||||
[{:keys [new-message]} [_ {chat-id :from}]]
|
[{:keys [new-message]} [_ {chat-id :from}]]
|
||||||
(log/debug "Dispatching request: " new-message)
|
|
||||||
(when (= (:content-type new-message) content-type-command-request)
|
(when (= (:content-type new-message) content-type-command-request)
|
||||||
(dispatch [:add-request chat-id new-message])))
|
(dispatch [:add-request chat-id new-message])))
|
||||||
|
|
||||||
(defn receive-message
|
(defn receive-message
|
||||||
[db [_ {chat-id :from :as message}]]
|
[db [_ {chat-id :from :as message}]]
|
||||||
(let [message' (check-author-direction db chat-id message)]
|
(let [message' (-> db
|
||||||
|
(check-author-direction chat-id message)
|
||||||
|
(assoc :delivery-status :pending))]
|
||||||
(-> db
|
(-> db
|
||||||
(add-message-to-db chat-id message')
|
(add-message-to-db chat-id message')
|
||||||
(assoc :new-message message'))))
|
(assoc :new-message message'))))
|
||||||
|
|
||||||
|
(defn dispatch-unviewed-message!
|
||||||
|
[{:keys [new-message]} [_ {chat-id :from}]]
|
||||||
|
(let [{:keys [msg-id]} new-message]
|
||||||
|
(dispatch [:add-unviewed-message chat-id msg-id])))
|
||||||
|
|
||||||
(register-handler :received-msg
|
(register-handler :received-msg
|
||||||
[(after store-message!)
|
[(after store-message!)
|
||||||
(after dispatch-request!)]
|
(after dispatch-request!)
|
||||||
|
(after dispatch-unviewed-message!)]
|
||||||
receive-message)
|
receive-message)
|
||||||
|
|
||||||
(register-handler :group-received-msg
|
(register-handler :group-received-msg
|
||||||
|
@ -553,6 +473,7 @@
|
||||||
(assoc-in db [:edit-mode current-chat-id] mode)))
|
(assoc-in db [:edit-mode current-chat-id] mode)))
|
||||||
|
|
||||||
(register-handler :command-edit-mode
|
(register-handler :command-edit-mode
|
||||||
|
(after #(dispatch [:clear-validation-errors]))
|
||||||
(edit-mode-handler :command))
|
(edit-mode-handler :command))
|
||||||
|
|
||||||
(register-handler :text-edit-mode
|
(register-handler :text-edit-mode
|
||||||
|
@ -571,6 +492,16 @@
|
||||||
(let [suggestions (get-in db [:command-suggestions current-chat-id])
|
(let [suggestions (get-in db [:command-suggestions current-chat-id])
|
||||||
mode (get-in db [:edit-mode current-chat-id])]
|
mode (get-in db [:edit-mode current-chat-id])]
|
||||||
(when (and (= :text mode)) (seq suggestions)
|
(when (and (= :text mode)) (seq suggestions)
|
||||||
(dispatch [:fix-commands-suggestions-height])))))]
|
(dispatch [:fix-commands-suggestions-height])))))]
|
||||||
(fn [db [_ h]]
|
(fn [db [_ h]]
|
||||||
(assoc db :layout-height h)))
|
(assoc db :layout-height h)))
|
||||||
|
|
||||||
|
|
||||||
|
(register-handler :send-seen!
|
||||||
|
(after (fn [_ [_ chat-id message-id]]
|
||||||
|
(when-not (console? chat-id))
|
||||||
|
(dispatch [:msg-seen chat-id message-id])))
|
||||||
|
(u/side-effect!
|
||||||
|
(fn [_ [_ chat-id message-id]]
|
||||||
|
(when-not (console? chat-id)
|
||||||
|
(api/send-seen chat-id message-id)))))
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
[status-im.utils.handlers :refer [register-handler]]
|
[status-im.utils.handlers :refer [register-handler]]
|
||||||
[status-im.handlers.content-suggestions :refer [get-content-suggestions]]
|
[status-im.handlers.content-suggestions :refer [get-content-suggestions]]
|
||||||
[status-im.chat.constants :refer [input-height request-info-height
|
[status-im.chat.constants :refer [input-height request-info-height
|
||||||
|
suggestions-header-height
|
||||||
minimum-command-suggestions-height
|
minimum-command-suggestions-height
|
||||||
response-height-normal minimum-suggestion-height]]
|
response-height-normal minimum-suggestion-height]]
|
||||||
[status-im.constants :refer [response-input-hiding-duration]]))
|
[status-im.constants :refer [response-input-hiding-duration]]))
|
||||||
|
@ -15,45 +16,54 @@
|
||||||
([name middleware handler]
|
([name middleware handler]
|
||||||
(register-handler name [(path :animations) middleware] handler)))
|
(register-handler name [(path :animations) middleware] handler)))
|
||||||
|
|
||||||
(animation-handler :animate-cancel-command
|
(register-handler :animate-cancel-command
|
||||||
(after #(dispatch [:text-edit-mode]))
|
(after #(dispatch [:text-edit-mode]))
|
||||||
(fn [db _]
|
(fn [{:keys [current-chat-id] :as db} _]
|
||||||
(assoc db :to-response-height input-height)))
|
(assoc-in db [:animations :to-response-height current-chat-id] input-height)))
|
||||||
|
|
||||||
(def response-height (+ input-height response-height-normal))
|
(def response-height (+ input-height response-height-normal))
|
||||||
|
|
||||||
(defn update-response-height [db]
|
(defn update-response-height
|
||||||
(assoc-in db [:animations :to-response-height] response-height))
|
[{:keys [current-chat-id] :as db}]
|
||||||
|
(assoc-in db [:animations :to-response-height current-chat-id] response-height))
|
||||||
|
|
||||||
(register-handler :animate-command-suggestions
|
(register-handler :animate-command-suggestions
|
||||||
(fn [{:keys [current-chat-id] :as db} _]
|
(fn [{chat-id :current-chat-id :as db} _]
|
||||||
(let [suggestions? (seq (get-in db [:command-suggestions current-chat-id]))
|
(let [suggestions? (seq (get-in db [:command-suggestions chat-id]))
|
||||||
current (get-in db [:animations :command-suggestions-height])
|
current (get-in db [:animations :command-suggestions-height chat-id])
|
||||||
height (if suggestions? middle-height input-height)
|
height (if suggestions? middle-height input-height)
|
||||||
changed? (if (and suggestions?
|
changed? (if (and suggestions?
|
||||||
(not (nil? current))
|
(not (nil? current))
|
||||||
(not= input-height current))
|
(not= input-height current))
|
||||||
identity inc)]
|
identity inc)]
|
||||||
(-> db
|
(-> db
|
||||||
(update :animations assoc :command-suggestions-height height)
|
(assoc-in [:animations :command-suggestions-height chat-id] height)
|
||||||
(update-in [:animations :commands-height-changed] changed?)))))
|
(update-in [:animations :commands-height-changed] changed?)))))
|
||||||
|
|
||||||
(defn get-minimum-height
|
(defn get-minimum-height
|
||||||
[{:keys [current-chat-id] :as db}]
|
[{:keys [current-chat-id] :as db}]
|
||||||
(let [path [:chats current-chat-id :command-input :command :type]
|
(let [path [:chats current-chat-id :command-input :command :type]
|
||||||
type (get-in db path)]
|
type (get-in db path)
|
||||||
(if (= :response type)
|
errors (get-in db [:validation-errors current-chat-id])
|
||||||
minimum-suggestion-height
|
custom-errors (get-in db [:custom-validation-errors current-chat-id])
|
||||||
input-height)))
|
validation-height (if (or (seq errors) (seq custom-errors))
|
||||||
|
request-info-height
|
||||||
|
0)]
|
||||||
|
(+ validation-height
|
||||||
|
(if (= :response type)
|
||||||
|
minimum-suggestion-height
|
||||||
|
(if (zero? validation-height)
|
||||||
|
input-height
|
||||||
|
(+ input-height suggestions-header-height))))))
|
||||||
|
|
||||||
(register-handler :animate-show-response
|
(register-handler :animate-show-response
|
||||||
[(after #(dispatch [:command-edit-mode]))]
|
;[(after #(dispatch [:command-edit-mode]))]
|
||||||
(fn [{:keys [current-chat-id] :as db}]
|
(fn [{:keys [current-chat-id] :as db}]
|
||||||
(let [suggestions? (seq (get-in db [:suggestions current-chat-id]))
|
(let [suggestions? (seq (get-in db [:suggestions current-chat-id]))
|
||||||
height (if suggestions?
|
height (if suggestions?
|
||||||
middle-height
|
middle-height
|
||||||
(get-minimum-height db))]
|
(get-minimum-height db))]
|
||||||
(assoc-in db [:animations :to-response-height] height))))
|
(assoc-in db [:animations :to-response-height current-chat-id] height))))
|
||||||
|
|
||||||
(defn fix-height
|
(defn fix-height
|
||||||
[height-key height-signal-key suggestions-key minimum]
|
[height-key height-signal-key suggestions-key minimum]
|
||||||
|
@ -64,7 +74,7 @@
|
||||||
under-middle-position? (<= current middle-height)
|
under-middle-position? (<= current middle-height)
|
||||||
over-middle-position? (not under-middle-position?)
|
over-middle-position? (not under-middle-position?)
|
||||||
suggestions (get-in db [suggestions-key current-chat-id])
|
suggestions (get-in db [suggestions-key current-chat-id])
|
||||||
old-fixed (get-in db [:animations height-key])
|
old-fixed (get-in db [:animations height-key current-chat-id])
|
||||||
|
|
||||||
new-fixed (cond (not suggestions)
|
new-fixed (cond (not suggestions)
|
||||||
(minimum db)
|
(minimum db)
|
||||||
|
@ -89,7 +99,7 @@
|
||||||
(and under-middle-position? moving-down?)
|
(and under-middle-position? moving-down?)
|
||||||
(minimum db))]
|
(minimum db))]
|
||||||
(-> db
|
(-> db
|
||||||
(assoc-in [:animations height-key] new-fixed)
|
(assoc-in [:animations height-key current-chat-id] new-fixed)
|
||||||
(update-in [:animations height-signal-key] inc)))))
|
(update-in [:animations height-signal-key] inc)))))
|
||||||
|
|
||||||
(defn commands-min-height
|
(defn commands-min-height
|
||||||
|
|
|
@ -0,0 +1,188 @@
|
||||||
|
(ns status-im.chat.handlers.commands
|
||||||
|
(:require [re-frame.core :refer [enrich after dispatch]]
|
||||||
|
[status-im.utils.handlers :refer [register-handler] :as u]
|
||||||
|
[status-im.components.jail :as j]
|
||||||
|
[status-im.models.commands :as commands]
|
||||||
|
[clojure.string :as str]
|
||||||
|
[status-im.commands.utils :as cu]
|
||||||
|
[status-im.utils.phone-number :as pn]
|
||||||
|
[status-im.i18n :as i18n]))
|
||||||
|
|
||||||
|
(def command-prefix "c ")
|
||||||
|
|
||||||
|
(defn invoke-suggestions-handler!
|
||||||
|
[{:keys [current-chat-id canceled-command] :as db} _]
|
||||||
|
(when-not canceled-command
|
||||||
|
(let [{:keys [command content]} (get-in db [:chats current-chat-id :command-input])
|
||||||
|
{:keys [name type]} command
|
||||||
|
path [(if (= :command type) :commands :responses)
|
||||||
|
name
|
||||||
|
:params
|
||||||
|
0
|
||||||
|
:suggestions]
|
||||||
|
params {:value content}]
|
||||||
|
(j/call current-chat-id
|
||||||
|
path
|
||||||
|
params
|
||||||
|
#(dispatch [:suggestions-handler {:command command
|
||||||
|
:content content
|
||||||
|
:chat-id current-chat-id} %])))))
|
||||||
|
|
||||||
|
(defn cancel-command!
|
||||||
|
[{:keys [canceled-command]}]
|
||||||
|
(when canceled-command
|
||||||
|
(dispatch [:start-cancel-command])))
|
||||||
|
|
||||||
|
(register-handler :set-chat-command-content
|
||||||
|
[(after invoke-suggestions-handler!)
|
||||||
|
(after cancel-command!)
|
||||||
|
(after #(dispatch [:clear-validation-errors]))]
|
||||||
|
(fn [{:keys [current-chat-id] :as db} [_ content]]
|
||||||
|
(let [starts-as-command? (str/starts-with? content command-prefix)
|
||||||
|
path [:chats current-chat-id :command-input :command :type]
|
||||||
|
command? (= :command (get-in db path))]
|
||||||
|
(as-> db db
|
||||||
|
(commands/set-chat-command-content db content)
|
||||||
|
(assoc-in db [:chats current-chat-id :input-text] nil)
|
||||||
|
(assoc db :canceled-command (and command? (not starts-as-command?)))))))
|
||||||
|
|
||||||
|
(defn invoke-command-preview!
|
||||||
|
[{:keys [staged-command]} [_ chat-id]]
|
||||||
|
(let [{:keys [command content]} staged-command
|
||||||
|
{:keys [name type]} command
|
||||||
|
path [(if (= :command type) :commands :responses)
|
||||||
|
name
|
||||||
|
:preview]
|
||||||
|
params {:value content}]
|
||||||
|
(j/call chat-id
|
||||||
|
path
|
||||||
|
params
|
||||||
|
#(dispatch [:command-preview chat-id %]))))
|
||||||
|
|
||||||
|
(defn content-by-command
|
||||||
|
[{:keys [type]} content]
|
||||||
|
(if (= :command type)
|
||||||
|
(subs content 2)
|
||||||
|
content))
|
||||||
|
|
||||||
|
(defn command-input
|
||||||
|
([{:keys [current-chat-id] :as db}]
|
||||||
|
(command-input db current-chat-id))
|
||||||
|
([db chat-id]
|
||||||
|
(get-in db [:chats chat-id :command-input])))
|
||||||
|
|
||||||
|
|
||||||
|
(register-handler ::validate!
|
||||||
|
(u/side-effect!
|
||||||
|
(fn [_ [_ {:keys [chat-id]} {:keys [error result]}]]
|
||||||
|
;; todo handle error
|
||||||
|
(when-not error
|
||||||
|
(let [{:keys [errors validationHandler parameters]} result]
|
||||||
|
(cond errors
|
||||||
|
(dispatch [::add-validation-errors chat-id errors])
|
||||||
|
|
||||||
|
validationHandler
|
||||||
|
(dispatch [::validation-handler!
|
||||||
|
chat-id
|
||||||
|
validationHandler
|
||||||
|
parameters])
|
||||||
|
|
||||||
|
:else (dispatch [::finish-command-staging chat-id])))))))
|
||||||
|
|
||||||
|
(defn start-validate! [db]
|
||||||
|
(let [{:keys [content command chat-id] :as data} (::command db)
|
||||||
|
{:keys [name type]} command
|
||||||
|
path [(if (= :command type) :commands :responses)
|
||||||
|
name
|
||||||
|
:validator]
|
||||||
|
params {:value content}]
|
||||||
|
(j/call chat-id
|
||||||
|
path
|
||||||
|
params
|
||||||
|
#(dispatch [::validate! data %]))))
|
||||||
|
|
||||||
|
(register-handler :stage-command
|
||||||
|
(after start-validate!)
|
||||||
|
(fn [{:keys [current-chat-id] :as db}]
|
||||||
|
(let [{:keys [command content]} (command-input db)
|
||||||
|
content' (content-by-command command content)]
|
||||||
|
(-> db
|
||||||
|
(assoc ::command {:content content'
|
||||||
|
:command command
|
||||||
|
:chat-id current-chat-id})
|
||||||
|
(assoc-in [:disable-staging current-chat-id] true)))))
|
||||||
|
|
||||||
|
(register-handler ::finish-command-staging
|
||||||
|
[(after #(dispatch [:start-cancel-command]))
|
||||||
|
(after invoke-command-preview!)]
|
||||||
|
(fn [db [_ chat-id]]
|
||||||
|
(let [db (assoc-in db [:chats chat-id :input-text] nil)
|
||||||
|
{:keys [command content to-msg-id]} (command-input db)
|
||||||
|
content' (content-by-command command content)
|
||||||
|
command-info {:command command
|
||||||
|
:content content'
|
||||||
|
:to-message to-msg-id}]
|
||||||
|
(-> db
|
||||||
|
(commands/stage-command command-info)
|
||||||
|
(assoc :staged-command command-info)
|
||||||
|
(assoc-in [:disable-staging chat-id] true)))))
|
||||||
|
|
||||||
|
(register-handler :unstage-command
|
||||||
|
(fn [db [_ staged-command]]
|
||||||
|
(commands/unstage-command db staged-command)))
|
||||||
|
|
||||||
|
(defn set-chat-command
|
||||||
|
[{:keys [current-chat-id] :as db} [_ command-key]]
|
||||||
|
(-> db
|
||||||
|
(commands/set-chat-command command-key)
|
||||||
|
(assoc-in [:chats current-chat-id :command-input :content] command-prefix)
|
||||||
|
(assoc :disable-input true)))
|
||||||
|
|
||||||
|
(register-handler :set-chat-command
|
||||||
|
[(after invoke-suggestions-handler!)
|
||||||
|
(after #(dispatch [:command-edit-mode]))]
|
||||||
|
set-chat-command)
|
||||||
|
|
||||||
|
(defn set-response-command [db [_ to-msg-id command-key]]
|
||||||
|
(-> db
|
||||||
|
(commands/set-response-chat-command to-msg-id command-key)
|
||||||
|
(assoc :canceled-command false)))
|
||||||
|
|
||||||
|
(register-handler :set-response-chat-command
|
||||||
|
[(after invoke-suggestions-handler!)
|
||||||
|
(after #(dispatch [:command-edit-mode]))
|
||||||
|
(after #(dispatch [:set-chat-input-text ""]))]
|
||||||
|
set-response-command)
|
||||||
|
|
||||||
|
(register-handler ::add-validation-errors
|
||||||
|
(fn [db [_ chat-id errors]]
|
||||||
|
(assoc-in db [:custom-validation-errors chat-id]
|
||||||
|
(map cu/generate-hiccup errors))))
|
||||||
|
|
||||||
|
(register-handler :clear-validation-errors
|
||||||
|
(fn [db]
|
||||||
|
(dissoc db :validation-errors :custom-validation-errors)))
|
||||||
|
|
||||||
|
(def validation-handlers
|
||||||
|
{:phone (fn [chat-id [number]]
|
||||||
|
(if (pn/valid-mobile-number? number)
|
||||||
|
(dispatch [::finish-command-staging chat-id])
|
||||||
|
(dispatch [::set-validation-error
|
||||||
|
chat-id
|
||||||
|
{:title (i18n/label :t/phone-number)
|
||||||
|
:description (i18n/label :t/invalid-phone)}])))})
|
||||||
|
|
||||||
|
(defn validator [name]
|
||||||
|
(validation-handlers (keyword name)))
|
||||||
|
|
||||||
|
(register-handler ::validation-handler!
|
||||||
|
(u/side-effect!
|
||||||
|
(fn [_ [_ chat-id name params]]
|
||||||
|
(when-let [handler (validator name)]
|
||||||
|
(handler chat-id params)))))
|
||||||
|
|
||||||
|
|
||||||
|
(register-handler ::set-validation-error
|
||||||
|
(after #(dispatch [:fix-response-height]))
|
||||||
|
(fn [db [_ chat-id error]]
|
||||||
|
(assoc-in db [:validation-errors chat-id] [error])))
|
|
@ -0,0 +1,44 @@
|
||||||
|
(ns status-im.chat.handlers.unviewed-messages
|
||||||
|
(:require [re-frame.core :refer [after enrich path dispatch]]
|
||||||
|
[status-im.utils.handlers :refer [register-handler]]
|
||||||
|
[status-im.persistence.realm.core :as realm]))
|
||||||
|
|
||||||
|
(defn delivered-messages []
|
||||||
|
(-> (realm/get-by-fields
|
||||||
|
:account :msgs
|
||||||
|
{:delivery-status :delivered
|
||||||
|
:outgoing false})
|
||||||
|
(realm/collection->map)))
|
||||||
|
|
||||||
|
(defn set-unviewed-messages [db]
|
||||||
|
(let [messages (->> (::raw-unviewed-messages db)
|
||||||
|
(group-by :chat-id)
|
||||||
|
(map (fn [[id messages]]
|
||||||
|
[id {:messages-ids (map :msg-id messages)
|
||||||
|
:count (count messages)}]))
|
||||||
|
(into {}))]
|
||||||
|
(-> db
|
||||||
|
(assoc :unviewed-messages messages)
|
||||||
|
(dissoc ::raw-unviewed-messages))))
|
||||||
|
|
||||||
|
(defn load-messages! [db]
|
||||||
|
(let [messages (delivered-messages)]
|
||||||
|
(assoc db ::raw-unviewed-messages messages)))
|
||||||
|
|
||||||
|
(register-handler ::set-unviewed-messages set-unviewed-messages)
|
||||||
|
|
||||||
|
(register-handler :load-unviewed-messages!
|
||||||
|
(after #(dispatch [::set-unviewed-messages]))
|
||||||
|
load-messages!)
|
||||||
|
|
||||||
|
(register-handler :add-unviewed-message
|
||||||
|
(path :unviewed-messages)
|
||||||
|
(fn [db [_ chat-id message-id]]
|
||||||
|
(-> db
|
||||||
|
(update-in [chat-id :messages-ids] conj message-id)
|
||||||
|
(update-in [chat-id :count] inc))))
|
||||||
|
|
||||||
|
(register-handler :remove-unviewed-messages
|
||||||
|
(path :unviewed-messages)
|
||||||
|
(fn [db [_ chat-id]]
|
||||||
|
(dissoc db chat-id)))
|
|
@ -0,0 +1,17 @@
|
||||||
|
(ns status-im.chat.styles.command-validation
|
||||||
|
(:require [status-im.components.styles :as st]
|
||||||
|
[status-im.chat.constants :as constants]))
|
||||||
|
|
||||||
|
(def messages-container
|
||||||
|
{:background-color :red
|
||||||
|
:height constants/request-info-height
|
||||||
|
:padding-left 16
|
||||||
|
:padding-top 14})
|
||||||
|
|
||||||
|
(def title
|
||||||
|
{:color :white
|
||||||
|
:font-size 12
|
||||||
|
:font-family st/font})
|
||||||
|
|
||||||
|
(def description
|
||||||
|
(assoc title :opacity 0.69))
|
|
@ -172,3 +172,29 @@
|
||||||
(fn [_ [_ message-id]]
|
(fn [_ [_ message-id]]
|
||||||
(let [requests (subscribe [:get-requests])]
|
(let [requests (subscribe [:get-requests])]
|
||||||
(reaction (not (some #(= message-id (:message-id %)) @requests))))))
|
(reaction (not (some #(= message-id (:message-id %)) @requests))))))
|
||||||
|
|
||||||
|
(register-sub :validation-errors
|
||||||
|
(fn [db]
|
||||||
|
(let [current-chat-id (subscribe [:get-current-chat-id])]
|
||||||
|
(reaction (get-in @db [:validation-errors @current-chat-id])))))
|
||||||
|
|
||||||
|
(register-sub :custom-validation-errors
|
||||||
|
(fn [db]
|
||||||
|
(let [current-chat-id (subscribe [:get-current-chat-id])]
|
||||||
|
(reaction (get-in @db [:custom-validation-errors @current-chat-id])))))
|
||||||
|
|
||||||
|
(register-sub :unviewed-messages-count
|
||||||
|
(fn [db [_ chat-id]]
|
||||||
|
(reaction (get-in @db [:unviewed-messages chat-id :count]))))
|
||||||
|
|
||||||
|
(register-sub :command-suggestions-height
|
||||||
|
(fn [db]
|
||||||
|
(let [chat-id (subscribe [:get-current-chat-id])]
|
||||||
|
(reaction
|
||||||
|
(get-in @db [:animations :command-suggestions-height @chat-id])))))
|
||||||
|
|
||||||
|
(register-sub :response-height
|
||||||
|
(fn [db]
|
||||||
|
(let [chat-id (subscribe [:get-current-chat-id])]
|
||||||
|
(reaction
|
||||||
|
(get-in @db [:animations :to-response-height @chat-id])))))
|
||||||
|
|
|
@ -15,8 +15,7 @@
|
||||||
(dispatch [:set-chat-command-content message]))
|
(dispatch [:set-chat-command-content message]))
|
||||||
|
|
||||||
(defn send-command []
|
(defn send-command []
|
||||||
(dispatch [:stage-command])
|
(dispatch [:stage-command]))
|
||||||
(cancel-command-input))
|
|
||||||
|
|
||||||
(defn valid? [message validator]
|
(defn valid? [message validator]
|
||||||
(if validator
|
(if validator
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
(ns status-im.chat.views.command-validation
|
||||||
|
(:require-macros [status-im.utils.views :refer [defview]])
|
||||||
|
(:require [status-im.components.react :as c]
|
||||||
|
[status-im.chat.styles.command-validation :as st]
|
||||||
|
[status-im.utils.listview :as lw]))
|
||||||
|
|
||||||
|
(defn message [{:keys [title description]}]
|
||||||
|
(c/list-item
|
||||||
|
[c/view
|
||||||
|
[c/text st/title title]
|
||||||
|
[c/text st/description description]]))
|
||||||
|
|
||||||
|
(defn messages-list [errors]
|
||||||
|
[c/list-view {:renderRow message
|
||||||
|
:keyboardShouldPersistTaps true
|
||||||
|
:dataSource (lw/to-datasource errors)
|
||||||
|
:style st/messages-container}])
|
||||||
|
|
||||||
|
(defview validation-messages []
|
||||||
|
[validation-messages [:validation-errors]
|
||||||
|
custom-errors [:custom-validation-errors]
|
||||||
|
command? [:command?]]
|
||||||
|
[c/view
|
||||||
|
(cond (seq custom-errors)
|
||||||
|
(vec (concat [c/view] custom-errors))
|
||||||
|
|
||||||
|
(seq validation-messages)
|
||||||
|
[messages-list validation-messages]
|
||||||
|
|
||||||
|
:else nil)])
|
|
@ -120,20 +120,23 @@
|
||||||
[message-content-audio {:content content
|
[message-content-audio {:content content
|
||||||
:content-type content-type}]]])
|
:content-type content-type}]]])
|
||||||
|
|
||||||
(defn message-delivery-status [{:keys [delivery-status]}]
|
(defview message-delivery-status
|
||||||
|
[{:keys [delivery-status msg-id to] :as m}]
|
||||||
|
[status [:get-in [:message-status to msg-id]]]
|
||||||
[view st/delivery-view
|
[view st/delivery-view
|
||||||
[image {:source (case delivery-status
|
[image {:source (case (or status delivery-status)
|
||||||
:delivered {:uri :icon_ok_small}
|
|
||||||
:seen {:uri :icon_ok_small}
|
:seen {:uri :icon_ok_small}
|
||||||
:seen-by-everyone {:uri :icon_ok_small}
|
:seen-by-everyone {:uri :icon_ok_small}
|
||||||
:failed res/delivery-failed-icon)
|
:failed res/delivery-failed-icon
|
||||||
|
nil)
|
||||||
:style st/delivery-image}]
|
:style st/delivery-image}]
|
||||||
[text {:style st/delivery-text}
|
[text {:style st/delivery-text}
|
||||||
(case delivery-status
|
(case (or status delivery-status)
|
||||||
:delivered "Delivered"
|
:delivered "Sent"
|
||||||
:seen "Seen"
|
:seen "Seen"
|
||||||
:seen-by-everyone "Seen by everyone"
|
:seen-by-everyone "Seen by everyone"
|
||||||
:failed "Failed")]])
|
:failed "Failed"
|
||||||
|
"Pending")]])
|
||||||
|
|
||||||
(defn member-photo [{:keys [photo-path]}]
|
(defn member-photo [{:keys [photo-path]}]
|
||||||
[view st/photo-view
|
[view st/photo-view
|
||||||
|
@ -159,12 +162,11 @@
|
||||||
[message-delivery-status {:delivery-status delivery-status}])]]]))
|
[message-delivery-status {:delivery-status delivery-status}])]]]))
|
||||||
|
|
||||||
(defn message-body
|
(defn message-body
|
||||||
[{:keys [outgoing] :as message} content]
|
[{:keys [outgoing delivery-status] :as message} content]
|
||||||
(let [delivery-status :seen]
|
[view (st/message-body message)
|
||||||
[view (st/message-body message)
|
content
|
||||||
content
|
(when outgoing
|
||||||
(when (and outgoing delivery-status)
|
[message-delivery-status message])])
|
||||||
[message-delivery-status {:delivery-status delivery-status}])]))
|
|
||||||
|
|
||||||
(defn message-container-animation-logic [{:keys [to-value val callback]}]
|
(defn message-container-animation-logic [{:keys [to-value val callback]}]
|
||||||
(fn [_]
|
(fn [_]
|
||||||
|
@ -203,17 +205,28 @@
|
||||||
(into [view] children)))
|
(into [view] children)))
|
||||||
|
|
||||||
(defn chat-message
|
(defn chat-message
|
||||||
[{:keys [outgoing delivery-status timestamp new-day group-chat]
|
[{:keys [outgoing delivery-status timestamp new-day group-chat msg-id chat-id]
|
||||||
:as message}]
|
:as message}]
|
||||||
[message-container message
|
(let [status (subscribe [:get-in [:message-status chat-id msg-id]])]
|
||||||
;; TODO there is no new-day info in message
|
(r/create-class
|
||||||
(when new-day
|
{:component-did-mount
|
||||||
[message-date timestamp])
|
(fn []
|
||||||
[view
|
(when (and (not outgoing)
|
||||||
(let [incoming-group (and group-chat (not outgoing))]
|
(not= :seen delivery-status)
|
||||||
[message-content
|
(not= :seen @status))
|
||||||
(if incoming-group
|
(dispatch [:send-seen! chat-id msg-id])))
|
||||||
incoming-group-message-body
|
:reagent-render
|
||||||
message-body)
|
(fn [{:keys [outgoing delivery-status timestamp new-day group-chat]
|
||||||
(merge message {:delivery-status (keyword delivery-status)
|
:as message}]
|
||||||
:incoming-group incoming-group})])]])
|
[message-container message
|
||||||
|
;; TODO there is no new-day info in message
|
||||||
|
(when new-day
|
||||||
|
[message-date timestamp])
|
||||||
|
[view
|
||||||
|
(let [incoming-group (and group-chat (not outgoing))]
|
||||||
|
[message-content
|
||||||
|
(if incoming-group
|
||||||
|
incoming-group-message-body
|
||||||
|
message-body)
|
||||||
|
(merge message {:delivery-status (keyword delivery-status)
|
||||||
|
:incoming-group incoming-group})])]])})))
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
(:require-macros [status-im.utils.views :refer [defview]])
|
(:require-macros [status-im.utils.views :refer [defview]])
|
||||||
(:require [re-frame.core :refer [subscribe]]
|
(:require [re-frame.core :refer [subscribe]]
|
||||||
[status-im.components.react :refer [view
|
[status-im.components.react :refer [view
|
||||||
|
text
|
||||||
animated-view
|
animated-view
|
||||||
icon
|
icon
|
||||||
touchable-highlight
|
touchable-highlight
|
||||||
|
@ -48,20 +49,19 @@
|
||||||
input-options)
|
input-options)
|
||||||
(if command? input-command input-message)])
|
(if command? input-command input-message)])
|
||||||
|
|
||||||
(defview plain-message-input-view [{:keys [input-options validator]}]
|
(defview plain-message-input-view [{:keys [input-options]}]
|
||||||
[command? [:command?]
|
[command? [:command?]
|
||||||
{:keys [type] :as command} [:get-chat-command]
|
{:keys [type] :as command} [:get-chat-command]
|
||||||
input-command [:get-chat-command-content]
|
input-command [:get-chat-command-content]
|
||||||
valid-plain-message? [:valid-plain-message?]
|
valid-plain-message? [:valid-plain-message?]]
|
||||||
valid-command? [:valid-command? validator]]
|
|
||||||
[view st/input-container
|
[view st/input-container
|
||||||
[view st/input-view
|
[view st/input-view
|
||||||
[plain-message/commands-button]
|
[plain-message/commands-button]
|
||||||
[message-input-container
|
[message-input-container
|
||||||
[message-input input-options validator]]
|
[message-input input-options]]
|
||||||
;; TODO emoticons: not implemented
|
;; TODO emoticons: not implemented
|
||||||
[plain-message/smile-button]
|
[plain-message/smile-button]
|
||||||
(when (if command? valid-command? valid-plain-message?)
|
(when (or command? valid-plain-message?)
|
||||||
(let [on-press (if command?
|
(let [on-press (if command?
|
||||||
command/send-command
|
command/send-command
|
||||||
plain-message/send)]
|
plain-message/send)]
|
||||||
|
|
|
@ -18,8 +18,7 @@
|
||||||
|
|
||||||
(defn get-options [{:keys [type placeholder]} command-type]
|
(defn get-options [{:keys [type placeholder]} command-type]
|
||||||
(let [options (case (keyword type)
|
(let [options (case (keyword type)
|
||||||
:phone {:input-options {:keyboardType :phone-pad}
|
:phone {:input-options {:keyboardType :phone-pad}}
|
||||||
:validator valid-mobile-number?}
|
|
||||||
:password {:input-options {:secureTextEntry true}}
|
:password {:input-options {:secureTextEntry true}}
|
||||||
:number {:input-options {:keyboardType :numeric}}
|
:number {:input-options {:keyboardType :numeric}}
|
||||||
;; todo maybe nil is fine for now :)
|
;; todo maybe nil is fine for now :)
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
[status-im.chat.styles.dragdown :as ddst]
|
[status-im.chat.styles.dragdown :as ddst]
|
||||||
[status-im.components.animation :as anim]
|
[status-im.components.animation :as anim]
|
||||||
[status-im.chat.suggestions-responder :as resp]
|
[status-im.chat.suggestions-responder :as resp]
|
||||||
[status-im.chat.constants :as c]))
|
[status-im.chat.constants :as c]
|
||||||
|
[status-im.chat.views.command-validation :as cv]))
|
||||||
|
|
||||||
(defn drag-icon []
|
(defn drag-icon []
|
||||||
[view st/drag-container
|
[view st/drag-container
|
||||||
|
@ -58,14 +59,14 @@
|
||||||
[icon :drag_down ddst/drag-down-icon]]))))
|
[icon :drag_down ddst/drag-down-icon]]))))
|
||||||
|
|
||||||
(defn container-animation-logic [{:keys [to-value val]}]
|
(defn container-animation-logic [{:keys [to-value val]}]
|
||||||
(let [to-value @to-value]
|
(when-let [to-value @to-value]
|
||||||
(when-not (= to-value (.-_value val))
|
(when-not (= to-value (.-_value val))
|
||||||
(anim/start (anim/spring val {:toValue to-value})))))
|
(anim/start (anim/spring val {:toValue to-value})))))
|
||||||
|
|
||||||
(defn container [response-height & children]
|
(defn container [response-height & children]
|
||||||
(let [;; todo to-response-height, cur-response-height must be specific
|
(let [;; todo to-response-height, cur-response-height must be specific
|
||||||
;; for each chat
|
;; for each chat
|
||||||
to-response-height (subscribe [:animations :to-response-height])
|
to-response-height (subscribe [:response-height])
|
||||||
changed (subscribe [:animations :response-height-changed])
|
changed (subscribe [:animations :response-height-changed])
|
||||||
context {:to-value to-response-height
|
context {:to-value to-response-height
|
||||||
:val response-height}
|
:val response-height}
|
||||||
|
@ -83,8 +84,7 @@
|
||||||
|
|
||||||
(defview placeholder []
|
(defview placeholder []
|
||||||
[suggestions [:get-content-suggestions]]
|
[suggestions [:get-content-suggestions]]
|
||||||
(when (seq suggestions)
|
[view st/input-placeholder])
|
||||||
[view st/input-placeholder]))
|
|
||||||
|
|
||||||
(defview response-suggestions-view []
|
(defview response-suggestions-view []
|
||||||
[suggestions [:get-content-suggestions]]
|
[suggestions [:get-content-suggestions]]
|
||||||
|
@ -95,4 +95,5 @@
|
||||||
[container response-height
|
[container response-height
|
||||||
[request-info response-height]
|
[request-info response-height]
|
||||||
[response-suggestions-view]
|
[response-suggestions-view]
|
||||||
|
[cv/validation-messages]
|
||||||
[placeholder]]))
|
[placeholder]]))
|
||||||
|
|
|
@ -104,7 +104,7 @@
|
||||||
(defn container [h & elements]
|
(defn container [h & elements]
|
||||||
(let [;; todo to-response-height, cur-response-height must be specific
|
(let [;; todo to-response-height, cur-response-height must be specific
|
||||||
;; for each chat
|
;; for each chat
|
||||||
to-response-height (subscribe [:animations :command-suggestions-height])
|
to-response-height (subscribe [:command-suggestions-height])
|
||||||
changed (subscribe [:animations :commands-height-changed])
|
changed (subscribe [:animations :commands-height-changed])
|
||||||
context {:to-value to-response-height
|
context {:to-value to-response-height
|
||||||
:val h}
|
:val h}
|
||||||
|
|
|
@ -6,9 +6,10 @@
|
||||||
[status-im.utils.utils :refer [truncate-str]]
|
[status-im.utils.utils :refer [truncate-str]]
|
||||||
[status-im.utils.datetime :as time]))
|
[status-im.utils.datetime :as time]))
|
||||||
|
|
||||||
(defn chat-list-item-inner-view
|
(defview chat-list-item-inner-view
|
||||||
[{:keys [chat-id name color new-messages-count
|
[{:keys [chat-id name color new-messages-count
|
||||||
online group-chat contacts] :as chat}]
|
online group-chat contacts] :as chat}]
|
||||||
|
[unviewed-messages [:unviewed-messages-count chat-id]]
|
||||||
(let [last-message (first (:messages chat))]
|
(let [last-message (first (:messages chat))]
|
||||||
[view st/chat-container
|
[view st/chat-container
|
||||||
[view st/chat-icon-container
|
[view st/chat-icon-container
|
||||||
|
@ -43,6 +44,6 @@
|
||||||
(when (:timestamp last-message)
|
(when (:timestamp last-message)
|
||||||
[text {:style st/datetime-text}
|
[text {:style st/datetime-text}
|
||||||
(time/to-short-str (:timestamp last-message))])])
|
(time/to-short-str (:timestamp last-message))])])
|
||||||
(when (pos? new-messages-count)
|
(when (pos? unviewed-messages)
|
||||||
[view st/new-messages-container
|
[view st/new-messages-container
|
||||||
[text {:style st/new-messages-text} new-messages-count]])]]))
|
[text {:style st/new-messages-text} unviewed-messages]])]]))
|
||||||
|
|
|
@ -17,7 +17,11 @@
|
||||||
|
|
||||||
(def app-registry (get-react-property "AppRegistry"))
|
(def app-registry (get-react-property "AppRegistry"))
|
||||||
(def navigator (get-class "Navigator"))
|
(def navigator (get-class "Navigator"))
|
||||||
(def text (get-class "Text"))
|
(def text-class (get-class "Text"))
|
||||||
|
(defn text
|
||||||
|
([s] [text-class s])
|
||||||
|
([{:keys [style] :as opts} s]
|
||||||
|
[text-class (if style opts {:style opts}) s]))
|
||||||
(def view (get-class "View"))
|
(def view (get-class "View"))
|
||||||
(def image (get-class "Image"))
|
(def image (get-class "Image"))
|
||||||
(def touchable-highlight-class (get-class "TouchableHighlight"))
|
(def touchable-highlight-class (get-class "TouchableHighlight"))
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
(.isAddress js/Web3.prototype s))
|
(.isAddress js/Web3.prototype s))
|
||||||
|
|
||||||
(defn unique-identity? [identity]
|
(defn unique-identity? [identity]
|
||||||
(println identity)
|
|
||||||
(not (realm/exists? :account :contacts :whisper-identity identity)))
|
(not (realm/exists? :account :contacts :whisper-identity identity)))
|
||||||
|
|
||||||
(defn valid-length? [identity]
|
(defn valid-length? [identity]
|
||||||
|
|
|
@ -40,8 +40,7 @@
|
||||||
:whisper-identity ""
|
:whisper-identity ""
|
||||||
:phone-number ""}
|
:phone-number ""}
|
||||||
:disable-group-creation false
|
:disable-group-creation false
|
||||||
:animations {:to-response-height 0.1
|
:animations {;; todo clear this
|
||||||
;; todo clear this
|
|
||||||
:tabs-bar-value (anim/create-value 0)}})
|
:tabs-bar-value (anim/create-value 0)}})
|
||||||
|
|
||||||
(def protocol-initialized-path [:protocol-initialized])
|
(def protocol-initialized-path [:protocol-initialized])
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
[status-im.utils.handlers :refer [register-handler] :as u]
|
[status-im.utils.handlers :refer [register-handler] :as u]
|
||||||
[status-im.models.protocol :as protocol]
|
[status-im.models.protocol :as protocol]
|
||||||
status-im.chat.handlers
|
status-im.chat.handlers
|
||||||
status-im.chat.handlers.animation
|
|
||||||
status-im.group-settings.handlers
|
status-im.group-settings.handlers
|
||||||
status-im.navigation.handlers
|
status-im.navigation.handlers
|
||||||
status-im.contacts.handlers
|
status-im.contacts.handlers
|
||||||
|
@ -23,8 +22,7 @@
|
||||||
status-im.commands.handlers.jail
|
status-im.commands.handlers.jail
|
||||||
status-im.qr-scanner.handlers
|
status-im.qr-scanner.handlers
|
||||||
status-im.accounts.handlers
|
status-im.accounts.handlers
|
||||||
status-im.protocol.handlers
|
status-im.protocol.handlers))
|
||||||
status-im.chat.handlers.requests))
|
|
||||||
|
|
||||||
;; -- Middleware ------------------------------------------------------------
|
;; -- Middleware ------------------------------------------------------------
|
||||||
;;
|
;;
|
||||||
|
@ -108,7 +106,9 @@
|
||||||
(u/side-effect!
|
(u/side-effect!
|
||||||
(fn [db _]
|
(fn [db _]
|
||||||
(log/debug "Starting node")
|
(log/debug "Starting node")
|
||||||
(.startNode geth (fn [result] (node-started db result))))))
|
(.startNode geth
|
||||||
|
(fn [result] (node-started db result))
|
||||||
|
#(log/debug "Geth already initialized")))))
|
||||||
|
|
||||||
(register-handler :crypt-initialized
|
(register-handler :crypt-initialized
|
||||||
(u/side-effect!
|
(u/side-effect!
|
||||||
|
|
|
@ -1,11 +1,5 @@
|
||||||
(ns status-im.models.commands
|
(ns status-im.models.commands
|
||||||
(:require [clojure.string :refer [join split]]
|
(:require [status-im.db :as db]))
|
||||||
[clojure.walk :refer [stringify-keys keywordize-keys]]
|
|
||||||
[re-frame.core :refer [subscribe dispatch]]
|
|
||||||
[status-im.db :as db]
|
|
||||||
[status-im.components.animation :as anim]
|
|
||||||
[status-im.components.styles :refer [color-blue color-dark-mint]]
|
|
||||||
[status-im.i18n :refer [label]]))
|
|
||||||
|
|
||||||
(defn get-commands [{:keys [current-chat-id] :as db}]
|
(defn get-commands [{:keys [current-chat-id] :as db}]
|
||||||
(or (get-in db [:chats current-chat-id :commands]) {}))
|
(or (get-in db [:chats current-chat-id :commands]) {}))
|
||||||
|
|
|
@ -26,7 +26,8 @@
|
||||||
|
|
||||||
(defn save-message
|
(defn save-message
|
||||||
;; todo remove chat-id parameter
|
;; todo remove chat-id parameter
|
||||||
[chat-id {:keys [msg-id content]
|
[chat-id {:keys [delivery-status msg-id content]
|
||||||
|
:or {delivery-status :pending}
|
||||||
:as message}]
|
:as message}]
|
||||||
(when-not (r/exists? :account :msgs :msg-id msg-id)
|
(when-not (r/exists? :account :msgs :msg-id msg-id)
|
||||||
(r/write :account
|
(r/write :account
|
||||||
|
@ -38,8 +39,8 @@
|
||||||
message
|
message
|
||||||
{:chat-id chat-id
|
{:chat-id chat-id
|
||||||
:content content'
|
:content content'
|
||||||
:timestamp (timestamp)
|
:delivery-status delivery-status
|
||||||
:delivery-status nil})]
|
:timestamp (timestamp)})]
|
||||||
(r/create :account :msgs message' true))))))
|
(r/create :account :msgs message' true))))))
|
||||||
|
|
||||||
(defn command-type? [type]
|
(defn command-type? [type]
|
||||||
|
|
|
@ -4,13 +4,13 @@
|
||||||
(:require [status-im.utils.handlers :as u]
|
(:require [status-im.utils.handlers :as u]
|
||||||
[status-im.utils.logging :as log]
|
[status-im.utils.logging :as log]
|
||||||
[status-im.protocol.api :as api]
|
[status-im.protocol.api :as api]
|
||||||
[re-frame.core :refer [dispatch debug]]
|
[re-frame.core :refer [dispatch after]]
|
||||||
[status-im.utils.handlers :refer [register-handler]]
|
[status-im.utils.handlers :refer [register-handler]]
|
||||||
[status-im.models.contacts :as contacts]
|
[status-im.models.contacts :as contacts]
|
||||||
[status-im.protocol.api :refer [init-protocol]]
|
[status-im.protocol.api :refer [init-protocol]]
|
||||||
[status-im.protocol.protocol-handler :refer [make-handler]]
|
[status-im.protocol.protocol-handler :refer [make-handler]]
|
||||||
[status-im.models.protocol :refer [update-identity
|
[status-im.models.protocol :refer [update-identity
|
||||||
set-initialized]]
|
set-initialized]]
|
||||||
[status-im.constants :refer [text-content-type]]
|
[status-im.constants :refer [text-content-type]]
|
||||||
[status-im.models.messages :as messages]
|
[status-im.models.messages :as messages]
|
||||||
[status-im.models.chats :as chats]
|
[status-im.models.chats :as chats]
|
||||||
|
@ -18,8 +18,8 @@
|
||||||
|
|
||||||
(register-handler :initialize-protocol
|
(register-handler :initialize-protocol
|
||||||
(u/side-effect!
|
(u/side-effect!
|
||||||
(fn [db [_ account]]
|
(fn [{:keys [user-identity] :as db} [_ account]]
|
||||||
(init-protocol account (make-handler db)))))
|
(init-protocol (or account user-identity) (make-handler db)))))
|
||||||
|
|
||||||
(register-handler :protocol-initialized
|
(register-handler :protocol-initialized
|
||||||
(fn [db [_ identity]]
|
(fn [db [_ identity]]
|
||||||
|
@ -102,16 +102,28 @@
|
||||||
(log/debug action msg-id from group-id identity)
|
(log/debug action msg-id from group-id identity)
|
||||||
(participant-invited-to-group-msg group-id identity from msg-id))))
|
(participant-invited-to-group-msg group-id identity from msg-id))))
|
||||||
|
|
||||||
|
(defn update-message! [status]
|
||||||
|
(fn [_ [_ _ msg-id]]
|
||||||
|
(messages/update-message! {:msg-id msg-id
|
||||||
|
:delivery-status status})))
|
||||||
|
|
||||||
|
(defn update-message-status [status]
|
||||||
|
(fn [db [_ from msg-id]]
|
||||||
|
(let [current-status (get-in db [:message-status from msg-id])]
|
||||||
|
(if-not (= :seen current-status)
|
||||||
|
(assoc-in db [:message-status from msg-id] status)
|
||||||
|
db))))
|
||||||
|
|
||||||
(register-handler :acked-msg
|
(register-handler :acked-msg
|
||||||
(u/side-effect!
|
(after (update-message! :delivered))
|
||||||
(fn [_ [action from msg-id]]
|
(update-message-status :delivered))
|
||||||
(log/debug action from msg-id)
|
|
||||||
(messages/update-message! {:msg-id msg-id
|
|
||||||
:delivery-status :delivered}))))
|
|
||||||
|
|
||||||
(register-handler :msg-delivery-failed
|
(register-handler :msg-delivery-failed
|
||||||
(u/side-effect!
|
(after (update-message! :failed))
|
||||||
(fn [_ [action msg-id]]
|
(update-message-status :failed))
|
||||||
(log/debug action msg-id)
|
|
||||||
(messages/update-message! {:msg-id msg-id
|
(register-handler :msg-seen
|
||||||
:delivery-status :failed}))))
|
[(after (update-message! :seen))
|
||||||
|
(after (fn [_ [_ chat-id]]
|
||||||
|
(dispatch [:remove-unviewed-messages chat-id])))]
|
||||||
|
(update-message-status :seen))
|
||||||
|
|
|
@ -22,8 +22,10 @@
|
||||||
(dispatch [:received-msg (assoc payload :from from :to to)]))
|
(dispatch [:received-msg (assoc payload :from from :to to)]))
|
||||||
:msg-acked (let [{:keys [msg-id from]} event]
|
:msg-acked (let [{:keys [msg-id from]} event]
|
||||||
(dispatch [:acked-msg from msg-id]))
|
(dispatch [:acked-msg from msg-id]))
|
||||||
:delivery-failed (let [{:keys [msg-id]} event]
|
:msg-seen (let [{:keys [msg-id from]} event]
|
||||||
(dispatch [:msg-delivery-failed msg-id]))
|
(dispatch [:msg-seen from msg-id]))
|
||||||
|
:delivery-failed (let [{:keys [msg-id from]} event]
|
||||||
|
(dispatch [:msg-delivery-failed from msg-id]))
|
||||||
:new-group-chat (let [{:keys [from group-id identities group-name]} event]
|
:new-group-chat (let [{:keys [from group-id identities group-name]} event]
|
||||||
(dispatch [:group-chat-invite-received from group-id identities group-name]))
|
(dispatch [:group-chat-invite-received from group-id identities group-name]))
|
||||||
:new-group-msg (let [{from :from
|
:new-group-msg (let [{from :from
|
||||||
|
|
|
@ -140,4 +140,6 @@
|
||||||
;users
|
;users
|
||||||
:add-account "Add account"
|
:add-account "Add account"
|
||||||
|
|
||||||
|
;validation
|
||||||
|
:invalid-phone "Invalid phone number"
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue