Merge pull request #331 from status-im/bug/#286

Password Request (#286)

Former-commit-id: a0d4da62ee
This commit is contained in:
adrian-tiberius 2016-10-10 17:53:51 +03:00 committed by GitHub
commit f7b88f6d6e
17 changed files with 293 additions and 169 deletions

View File

@ -59,11 +59,11 @@ function startsWith(str1, str2) {
function phoneSuggestions(params) {
var ph, suggestions;
if (!params.value || params.value == "") {
if (!params.phone || params.phone == "") {
ph = phones;
} else {
ph = phones.filter(function (phone) {
return startsWith(phone.number, params.value);
return startsWith(phone.number, params.phone);
});
}
@ -104,7 +104,7 @@ var phoneConfig = {
validator: function (params) {
return {
validationHandler: "phone",
parameters: [params.value]
parameters: [params.phone]
};
},
params: [{
@ -116,7 +116,7 @@ var phoneConfig = {
handler: function (params) {
return {
event: "sign-up",
params: [params.value]
params: [params.phone, params]
};
}
};
@ -155,11 +155,11 @@ status.response({
handler: function (params) {
return {
event: "confirm-sign-up",
params: [params.value]
params: [params.code]
};
},
validator: function (params) {
if(!/^[\d]{4}$/.test(params.value)){
if (!/^[\d]{4}$/.test(params.code)) {
var error = status.components.validationMessage(
"Confirmation code",
"Wrong format"
@ -173,32 +173,56 @@ status.response({
status.response({
name: "password",
color: "#7099e6",
description: "Password Request",
icon: "icon_lock_white",
description: "Password",
icon: "lock_white",
params: [{
name: "password",
type: status.types.PASSWORD,
placeholder: "Type your password"
}, {
name: "password-confirmation",
type: status.types.PASSWORD,
placeholder: "Please re-enter password to confirm"
}],
handler: function (params) {
return {
event: "save-password",
params: [params.value]
params: [params.password]
};
},
validator: function (params) {
if(!params.value || params.value.length < 6){
return {
errors: [
validator: function (params, context) {
var errorMessages = [];
var currentParameter = context["current-parameter"];
if (
currentParameter == "password" &&
params.password.length < 6
) {
errorMessages.push("Password should be not less then 6 symbols.");
}
if (currentParameter == "password-confirmation" &&
params.password != params["password-confirmation"]) {
errorMessages.push("Password confirmation doesn't match password.");
}
if (errorMessages.length) {
var errors = [];
for (var idx in errorMessages) {
errors.push(
status.components.validationMessage(
"Password",
"Password should be not less then 6 symbols."
errorMessages[idx]
)
]
};
);
}
return {errors: errors};
}
return {params: params, context: context};
},
preview: function (params) {
preview: function (params, context) {
var style = {
marginTop: 5,
marginHorizontal: 0,
@ -206,7 +230,7 @@ status.response({
color: "black"
};
if(params.platform == "ios"){
if (context.platform == "ios") {
style.fontSize = 8;
style.marginTop = 10;
style.marginBottom = 2;

View File

@ -61,7 +61,7 @@ function call(pathStr, paramsStr) {
return null;
}
res = fn(params);
res = fn(params.parameters, params.context);
return JSON.stringify(res);
}

View File

@ -22,14 +22,14 @@
(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])
(let [{:keys [command content params]} (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-by-command command content)}]
params {:parameters (or params {})}]
(status/call-jail current-chat-id
path
params
@ -55,21 +55,25 @@
(after #(dispatch [:clear-validation-errors]))]
(fn [{:keys [current-chat-id] :as db} [_ content]]
(let [starts-as-command? (str/starts-with? content command-prefix)
command? (= :command (current-command db :type))]
command? (= :command (current-command db :type))
{:keys [parameter-idx command]} (commands/get-command-input db)
parameter-name (-> command :params (get parameter-idx) :name)]
(as-> db db
(commands/set-chat-command-content db content)
(commands/set-command-parameter db parameter-name 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 id]} staged-command
[{:keys [staged-command] :as db} [_ chat-id]]
(let [{:keys [command id]} staged-command
{:keys [name type]} command
parameters (:params (commands/get-command-input db))
path [(if (= :command type) :commands :responses)
name
:preview]
params {:value content
:platform platform/platform}]
params {:parameters parameters
:context {:platform platform/platform}}]
(status/call-jail chat-id
path
params
@ -84,7 +88,7 @@
(register-handler ::validate!
(u/side-effect!
(fn [_ [_ {:keys [chat-id]} {:keys [error result]}]]
(fn [_ [_ {:keys [chat-id handler]} {:keys [error result]}]]
;; todo handle error
(when-not error
(let [{:keys [errors validationHandler parameters]} result]
@ -97,42 +101,28 @@
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
:command data}]
(status/call-jail chat-id
path
params
#(dispatch [::validate! data %]))))
:else (if handler
(handler)
(dispatch [::finish-command-staging chat-id]))))))))
(register-handler :stage-command
(after start-validate!)
(fn [{:keys [current-chat-id current-account-id] :as db}]
(let [{:keys [command content]} (command-input db)
content' (content-by-command command content)]
(-> db
(assoc ::command {:content content'
(let [command-input (commands/get-command-input db)
command (commands/get-chat-command db)]
(dispatch [::start-command-validation! {:command-input command-input
:command command
:chat-id current-chat-id
:address current-account-id})
(assoc-in [:disable-staging current-chat-id] true)))))
:address current-account-id}])
(assoc-in db [: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-message-id]} (command-input db)
content' (content-by-command command content)
{:keys [command content to-message-id params]} (command-input db)
command-info {:command command
:content content'
:params params
:to-message to-message-id
:created-at (time/now-ms)
:id (random/id)}]
@ -210,3 +200,65 @@
(register-handler :invoke-commands-suggestions!
(u/side-effect!
invoke-suggestions-handler!))
(register-handler :send-command!
(u/side-effect!
(fn [{:keys [current-chat-id current-account-id] :as db}]
(let [{:keys [params] :as command} (commands/get-chat-command db)
{:keys [parameter-idx]} (commands/get-command-input db)
last-parameter? (= (inc parameter-idx) (count params))
parameters {:command command :input command-input}
{:keys [command content]} (command-input db)
content' (content-by-command command content)]
(dispatch [:set-command-parameter
{:value content'
:parameter (params parameter-idx)}])
(if last-parameter?
(dispatch [:check-suggestions-trigger! parameters])
(dispatch [::start-command-validation!
{:chat-id current-chat-id
:address current-account-id
:handler #(dispatch [:next-command-parameter])}]))))))
(register-handler ::start-command-validation!
(u/side-effect!
(fn [db [_ {:keys [command-input chat-id] :as data}]]
(let [command-input' (or command-input (commands/get-command-input db))
{:keys [parameter-idx params command]} command-input'
{:keys [name type]} command
current-parameter (-> command
:params
(get parameter-idx)
:name)
context {:current-parameter current-parameter}
path [(if (= :command type) :commands :responses)
name
:validator]
parameters {:context context
:parameters params}]
(status/call-jail chat-id
path
parameters
#(dispatch [::validate! data %]))))))
(register-handler :set-command-parameter
(fn [db [_ {:keys [value parameter]}]]
(let [name (:name parameter)]
(commands/set-command-parameter db name value))))
(register-handler :next-command-parameter
(fn [{:keys [current-chat-id] :as db}]
(-> db
(update-in [:chats current-chat-id :command-input :parameter-idx] inc)
(commands/set-chat-command-content nil))))
(register-handler :check-suggestions-trigger!
(u/side-effect!
(fn [_ [_ {:keys [command]}]]
(let [suggestions-trigger (keyword (:suggestions-trigger command))]
(if (= :on-send suggestions-trigger)
(dispatch [:invoke-commands-suggestions!])
(dispatch [:stage-command]))))))

View File

@ -16,9 +16,9 @@
[taoensso.timbre :refer-macros [debug]]))
(defn prepare-command
[identity chat-id {:keys [preview preview-string content command to-message]}]
[identity chat-id {:keys [preview preview-string params command to-message]}]
(let [content {:command (command :name)
:content content}]
:params params}]
{:message-id (random/id)
:from identity
:to chat-id
@ -54,7 +54,7 @@
(u/side-effect!
(fn [_ [_ {:keys [commands message] :as params}]]
(doseq [{:keys [command] :as message} commands]
(let [params' (assoc params :command message)]
(let [params' (assoc params :staged-command message)]
(if (:sending message)
(dispatch [:navigate-to :confirm])
(if (:has-handler command)
@ -70,11 +70,12 @@
(register-handler :prepare-command!
(u/side-effect!
(fn [{:keys [current-public-key] :as db} [_ {:keys [chat-id command] :as params}]]
(let [command' (->> command
(fn [{:keys [current-public-key] :as db}
[_ {:keys [chat-id staged-command] :as params}]]
(let [command' (->> staged-command
(prepare-command current-public-key chat-id)
(cu/check-author-direction db chat-id))]
(dispatch [::clear-command chat-id (:id command)])
(dispatch [::clear-command chat-id (:id staged-command)])
(dispatch [::send-command! (assoc params :command command')])))))
(register-handler ::clear-command
@ -97,7 +98,7 @@
(register-handler ::save-command!
(u/side-effect!
(fn [{:keys [current-public-key]} [_ {:keys [command chat-id]}]]
(fn [_ [_ {:keys [command chat-id]}]]
(messages/save
chat-id
(dissoc command :rendered-preview :to-message :has-handler)))))
@ -111,15 +112,15 @@
(register-handler ::invoke-command-handlers!
(u/side-effect!
(fn [db [_ {:keys [chat-id address] :as parameters}]]
(let [{:keys [command content]} (:command parameters)
(fn [db [_ {:keys [chat-id address staged-command] :as parameters}]]
(let [{:keys [command params]} staged-command
{:keys [type name]} command
path [(if (= :command type) :commands :responses)
name
:handler]
to (get-in db [:contacts chat-id :address])
params {:value content
:command {:from address
params {:parameters params
:context {:from address
:to to}}]
(status/call-jail chat-id
path

View File

@ -28,9 +28,10 @@
:borderRadius 16
:backgroundColor color-white})
(def command-icon
{:width 9
:height 15})
(defn command-icon [color]
{:width 13
:height 13
:tint-color color})
(def info-container
{:flex 1

View File

@ -170,6 +170,19 @@
(let [chat-id (subscribe [:get-current-chat-id])]
(reaction (get-in @db [:chats @chat-id :requests])))))
(register-sub :get-requests-map
(fn [db]
(let [chat-id (subscribe [:get-current-chat-id])]
(reaction (->> (get-in @db [:chats @chat-id :requests])
(map #(vector (:message-id %) %))
(into {}))))))
(register-sub :get-current-request
(fn []
(let [requests (subscribe [:get-requests-map])
message-id (subscribe [:get-chat-command-to-message-id])]
(reaction (@requests @message-id)))))
(register-sub :get-response
(fn [db [_ n]]
(let [chat-id (subscribe [:get-current-chat-id])]

View File

@ -22,10 +22,6 @@
(validator message)
(pos? (count message))))
(defn try-send [message validator]
(when (valid? message validator)
(send-command)))
(defview command-icon [command]
[icon-width [:get :command-icon-width]]
[view st/command-container

View File

@ -7,6 +7,7 @@
[status-im.components.react :refer [view
text
image
icon
animated-view
touchable-highlight]]
[status-im.components.animation :as anim]
@ -17,7 +18,6 @@
[status-im.models.commands :refer [parse-command-message-content
parse-command-request]]
[status-im.resources :as res]
[status-im.utils.datetime :as time]
[status-im.constants :refer [text-content-type
content-type-status
content-type-command
@ -69,23 +69,25 @@
(defview message-content-command [content preview]
[commands [:get-commands-and-responses]]
(let [{:keys [command content]} (parse-command-message-content commands content)
{:keys [name icon type]} command]
(let [{:keys [command params]} (parse-command-message-content commands content)
{:keys [name type]
icon-path :icon} command]
[view st/content-command-view
[view st/command-container
[view (pill-st/pill command)
[text {:style pill-st/pill-text
:font :default}
(str (if (= :command type) "!" "?") name)]]]
(when icon
(when icon-path
[view st/command-image-view
[image {:source {:uri icon}
:style st/command-image}]])
[icon icon-path st/command-image]])
(if preview
preview
[text {:style st/command-text
:font :default}
(str content)])]))
(if (= 1 (count params))
(first (vals params))
(str params))])]))
(defn set-chat-command [message-id command]
(dispatch [:set-response-chat-command message-id (keyword (:name command))]))

View File

@ -30,9 +30,7 @@
(defn on-press-commands-handler
[{:keys [suggestions-trigger]}]
(if (= :on-send (keyword suggestions-trigger))
#(dispatch [:invoke-commands-suggestions!])
command/send-command))
#(dispatch [:send-command!]))
(defn command-input-options [command icon-width disable?]
{:style (st-response/command-input icon-width disable?)
@ -102,7 +100,8 @@
[message-input input-options set-layout-size])]
;; TODO emoticons: not implemented
[plain-message/smile-button height]
(when (or @command? @valid-plain-message?)
(when (or (and @command? (not (str/blank? @input-command)))
@valid-plain-message?)
(let [on-press (if @command?
(on-press-commands-handler @command)
plain-message/send)]

View File

@ -7,6 +7,7 @@
[status-im.components.react :refer [view
animated-view
icon
image
text
text-input
touchable-highlight
@ -20,24 +21,35 @@
[status-im.chat.constants :as c]
[status-im.chat.views.command-validation :as cv]
[status-im.utils.platform :refer [ios?]]
[status-im.components.webview-bridge :refer [webview-bridge]]))
[status-im.components.webview-bridge :refer [webview-bridge]]
[status-im.i18n :refer [label]]
[status-im.utils.datetime :as dt]))
(defn drag-icon []
[view st/drag-container
[icon :drag_white st/drag-icon]])
(defn command-icon []
(defn command-icon [{icon-path :icon
color :color}]
[view st/command-icon-container
;; TODO stub data: command icon
[icon :dollar_green st/command-icon]])
(when icon-path
[icon icon-path (st/command-icon color)])])
(defn info-container [command]
(defview info-container
[command]
[{:keys [name chat-id]} [:get-current-chat]
{:keys [added]} [:get-current-request]]
[view st/info-container
[text {:style st/command-name}
(:description command)]
(str (:description command) " " (label :t/request))]
(when added
[text {:style st/message-info}
;; TODO stub data: request message info
"By ???, MMM 1st at HH:mm"]])
(str "By " (or name chat-id) ", "
(dt/format-date "MMM" added)
" "
(dt/get-ordinal-date added)
" at "
(dt/format-date "HH:mm" added))])])
(defn request-info [response-height]
(let [layout-height (subscribe [:get :layout-height])
@ -51,7 +63,7 @@
{:style (st/request-info (:color @command))})
[drag-icon]
[view st/inner-container
[command-icon nil]
[command-icon @command]
[info-container @command]
[touchable-highlight {:on-press #(dispatch [:start-cancel-command])}
[view st/cancel-container

View File

@ -12,8 +12,9 @@
(defn cancel-command-input [staged-command]
(dispatch [:unstage-command staged-command]))
(defn simple-command-staged-view [staged-command]
(let [{:keys [type name] :as command} (:command staged-command)]
(defn simple-command-staged-view
[{:keys [command params] :as staged-command}]
(let [{:keys [type name]} command]
[view st/staged-command-container
[view st/staged-command-background
[view {:flex-direction :row}
@ -30,4 +31,6 @@
(if-let [preview (:preview staged-command)]
preview
[text {:style st/staged-command-content}
(:content staged-command)])]]))
(if (= 1 (count params))
(first (vals params))
(str params))])]]))

View File

@ -7,7 +7,8 @@
[status-im.commands.utils :refer [generate-hiccup reg-handler]]
[clojure.string :as s]
[status-im.components.react :as r]
[status-im.constants :refer [console-chat-id]]))
[status-im.constants :refer [console-chat-id]]
[taoensso.timbre :as log]))
(defn init-render-command!
[_ [chat-id command message-id data]]
@ -78,7 +79,7 @@
(fn [_ params]
(when (:error (last params))
(show-popup "Error" (s/join "\n" [message params]))
(println message params))))
(log/debug message params))))
(reg-handler :init-render-command! init-render-command!)
(reg-handler ::render-command render-command)

View File

@ -8,7 +8,8 @@
[status-im.components.status :as status]
[status-im.utils.types :refer [json->clj]]
[status-im.commands.utils :refer [reg-handler]]
[status-im.constants :refer [console-chat-id wallet-chat-id]]))
[status-im.constants :refer [console-chat-id wallet-chat-id]]
[taoensso.timbre :as log]))
(def commands-js "commands.js")
@ -95,7 +96,7 @@
(name reason)
details])]
(show-popup "Error" m)
(println m))))
(log/debug m))))
(reg-handler :load-commands! (u/side-effect! load-commands!))
(reg-handler ::fetch-commands! (u/side-effect! fetch-commands!))

View File

@ -47,10 +47,12 @@
(defn call-jail [chat-id path params callback]
(when status
(println :call chat-id (cljs->json path) (cljs->json params))
(log/debug :chat-id chat-id)
(log/debug :path path)
(log/debug :params params)
(let [cb (fn [r]
(let [r' (t/json->clj r)]
(println r')
(log/debug r')
(callback r')))]
(.callJail status chat-id (cljs->json path) (cljs->json params) cb))))

View File

@ -9,9 +9,6 @@
[type {:keys [current-chat-id] :as db} command-key]
((or (get-in db [:chats current-chat-id type]) {}) command-key))
(defn find-command [commands command-key]
(first (filter #(= command-key (:command %)) commands)))
(defn get-chat-command-content
[{:keys [current-chat-id] :as db}]
(get-in db (db/chat-command-content-path current-chat-id)))
@ -20,10 +17,17 @@
[{:keys [current-chat-id] :as db} content]
(assoc-in db [:chats current-chat-id :command-input :content] content))
(defn set-command-parameter
[{:keys [current-chat-id] :as db} name value]
(assoc-in db [:chats current-chat-id :command-input :params name] value))
(defn get-chat-command
[{:keys [current-chat-id] :as db}]
(get-in db (db/chat-command-path current-chat-id)))
(defn get-command-input [{:keys [current-chat-id] :as db}]
(get-in db [:chats current-chat-id :command-input]))
(defn set-command-input
([db type command-key]
(set-command-input db type nil command-key))
@ -32,6 +36,7 @@
{:content nil
:command (get-response-or-command type db command-key)
:parameter-idx 0
:params nil
:to-message-id message-id})))
(defn get-chat-command-to-message-id
@ -60,11 +65,6 @@
(get-in db (db/chat-command-request-path current-chat-id
(get-chat-command-to-message-id db))))
(defn set-chat-command-request
[{:keys [current-chat-id] :as db} message-id handler]
(update-in db (db/chat-command-requests-path current-chat-id)
#(assoc % message-id handler)))
(defn parse-command-message-content [commands content]
(update content :command #((keyword %) commands)))

View File

@ -133,6 +133,7 @@
:request-command-description "Send request"
:keypair-password-command-description ""
:help-command-description "Help"
:request "Request"
;new-group
:group-chat-name "Chat name"

View File

@ -1,6 +1,6 @@
(ns status-im.utils.datetime
(:require [cljs-time.core :as t :refer [date-time now plus days hours before?]]
[cljs-time.coerce :refer [from-long to-long]]
[cljs-time.coerce :refer [from-long to-long from-date]]
[cljs-time.format :refer [formatters
formatter
unparse]]
@ -59,3 +59,19 @@
(defn now-ms []
(to-long (now)))
(defn format-date [format date]
(let [local (plus (from-date date) time-zone-offset)]
(unparse (formatter format) local)))
(defn get-ordinal-date [date]
(let [local (plus (from-date date) time-zone-offset)
day (js/parseInt (unparse (formatter "d") local))
s {0 "th"
1 "st"
2 "nd"
3 "rd"}
m (mod day 100)]
(str day (or (s (mod (- m 20) 10))
(s m)
(s 0)))))