Generating message preview on the fly, localization of request data and previews (#645, #754)

This commit is contained in:
alwx 2017-01-23 18:57:40 +03:00 committed by Roman Volosovskyi
parent e73f0940b3
commit 78e70571df
19 changed files with 136 additions and 123 deletions

View File

@ -825,7 +825,7 @@ var send = {
style: amountStyle,
font: "light"
},
params.amount
status.localizeNumber(params.amount, context.delimiter, context.separator)
)]);
var currency = status.components.view(
@ -877,12 +877,6 @@ status.command({
name: "amount",
type: status.types.NUMBER
}],
preview: function (params) {
return status.components.text(
{},
params.amount + " ETH"
);
},
handler: function (params) {
return {
event: "request",
@ -891,11 +885,15 @@ status.command({
command: "send",
params: {
amount: params.amount
},
content: I18n.t('request_requesting') + params.amount + "ETH"
}
}
};
},
preview: function (params, context) {
return I18n.t('request_requesting')
+ status.localizeNumber(params.amount, context.delimiter, context.separator)
+ " ETH";
},
validator: function(params) {
try {
var val = web3.toWei(params.amount, "ether");

View File

@ -167,6 +167,11 @@ var status = {
autorun: function (commandName) {
_status_catalog.autorun = commandName;
},
localizeNumber: function (num, del, sep) {
return I18n.toNumber(
num.replace(",", "."),
{precision: 10, strip_insignificant_zeros: true, delimiter: del, separator: sep});
},
types: {
TEXT: 'text',
NUMBER: 'number',

View File

@ -1,11 +1,3 @@
I18n.translations = {
en: {
browse_title: 'Browser',
browse_description: 'Launch the browser'
}
};
function wallet(params, context) {
var url = 'https://status.im/dapps/wallet';

View File

@ -297,7 +297,12 @@
(defn load-messages!
([db] (load-messages! db nil))
([{:keys [current-chat-id] :as db} _]
(assoc db :messages (messages/get-by-chat-id current-chat-id))))
(let [messages (messages/get-by-chat-id current-chat-id)]
(doseq [{:keys [content] :as message} messages]
(when (and (:command content)
(not (:content content)))
(dispatch [:request-command-preview (assoc message :chat-id current-chat-id)])))
(assoc db :messages messages))))
(defn init-chat
([db] (init-chat db nil))

View File

@ -10,7 +10,8 @@
[status-im.i18n :as i18n]
[status-im.utils.datetime :as time]
[status-im.utils.random :as random]
[status-im.utils.platform :as platform]))
[status-im.utils.platform :as platform]
[taoensso.timbre :as log]))
(defn content-by-command
[{:keys [type]} content]
@ -82,30 +83,12 @@
(str cu/command-prefix content)
content)])))))
(defn invoke-command-preview!
[db command-message [_ command-input chat-id]]
(let [{:keys [command]} command-message
{:keys [name type]} command
parameters (:params (or command-input (commands/get-command-input db)))
path [(if (= :command type) :commands :responses)
name
:preview]
params {:parameters parameters
:context {:platform platform/platform}}]
(if (and (console? chat-id) (= name "js"))
(dispatch [:send-chat-message command-message])
(status/call-jail chat-id
path
params
#(dispatch [:command-preview command-message %])))))
(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 [_ [_ command-input {:keys [chat-id handler]} {:keys [error result]}]]
@ -146,14 +129,21 @@
(fn [db [_ command-input chat-id :as parameters]]
(let [db (assoc-in db [:chats chat-id :input-text] nil)
{:keys [command to-message-id params]} (or command-input (command-input db))
message-id (random/id)
command-info {:command command
:params params
:to-message to-message-id
:created-at (time/now-ms)
:id (random/id)
:chat-id chat-id}]
:id message-id
:chat-id chat-id}
request-data {:message-id message-id
:chat-id chat-id
:content {:command (:name command)
:params params
:type (:type command)}
:on-requested #(dispatch [:send-chat-message command-info])}]
(dispatch [:set-in [:command->chat (:id command-info)] chat-id])
(invoke-command-preview! db command-info parameters)))))
(dispatch [:request-command-preview request-data])))))
(defn set-chat-command
[{:keys [current-chat-id] :as db} [_ command-key type]]
@ -274,6 +264,23 @@
parameters
#(dispatch [::validate! command-input data %]))))))
(register-handler :request-command-preview
(u/side-effect!
(fn [_ [_ {{:keys [command params content-command type]} :content
:keys [message-id chat-id on-requested] :as message}]]
(let [path [(if (= :response (keyword type)) :responses :commands)
(if content-command content-command command)
:preview]
params {:parameters params
:context (merge {:platform platform/platform} i18n/delimeters)}
callback #(do (when-let [result (get-in % [:result :returned])]
(dispatch [:set-in [:message-data :preview message-id]
(if (string? result)
result
(cu/generate-hiccup result))]))
(when on-requested (on-requested %)))]
(status/call-jail chat-id path params callback)))))
(register-handler :set-command-parameter
(fn [db [_ {:keys [value parameter]}]]
(let [name (:name parameter)]
@ -292,3 +299,7 @@
(do
(dispatch [:set-chat-ui-props :sending-disabled? true])
(dispatch [:validate-command])))))))
(defn fib-lazy
([] (fib-lazy 0 1))
([x1 x2] (cons x1 (lazy-seq (fib-lazy x2 (+ x1 x2))))))

View File

@ -43,7 +43,7 @@
(messages/update {:message-id message-id
:message-status status})))
(fn [db [_ message-id status]]
(assoc-in db [:message-statuses message-id] {:status status})))
(assoc-in db [:message-data :statuses message-id] {:status status})))
(register-handler :console-respond-command
(u/side-effect!

View File

@ -13,16 +13,8 @@
[status-im.data-store.chats :as chats]
[status-im.utils.scheduler :as s]))
(defn check-preview [{:keys [content] :as message}]
(if-let [preview (:preview content)]
(let [rendered-preview (generate-hiccup (read-string preview))]
(assoc message
:preview preview
:rendered-preview rendered-preview))
message))
(defn store-message [{chat-id :chat-id :as message}]
(messages/save chat-id (dissoc message :rendered-preview :new?)))
(messages/save chat-id (dissoc message :new?)))
(defn get-current-identity
[{:keys [current-account-id accounts]}]
@ -49,15 +41,15 @@
(or (not exists?) active?))
(let [group-chat? (not (nil? group-id))
previous-message (messages/get-last-message chat-id')
message' (assoc (->> message
(cu/check-author-direction previous-message)
(check-preview))
message' (assoc (cu/check-author-direction previous-message message)
:chat-id chat-id'
:timestamp (or timestamp (random/timestamp))
:clock-value clock-value)]
(store-message message')
(dispatch [:upsert-chat! {:chat-id chat-id'
:group-chat group-chat?}])
(when (get-in message [:content :command])
(dispatch [:request-command-preview message]))
(dispatch [::add-message chat-id' message'])
(when (= (:content-type message') content-type-command-request)
(dispatch [:add-request chat-id' message']))

View File

@ -29,16 +29,14 @@
:from identity
:to chat-id
:timestamp (time/now-ms)
:content (assoc content :preview preview-string
:handler-data handler-data
:type (name (:type command)))
:content (assoc content :handler-data handler-data
:type (name (:type command))
:content-command (:name command))
:content-type (or content-type
(if request
content-type-command-request
content-type-command))
:outgoing true
:preview preview-string
:rendered-preview preview
:to-message to-message
:type (:type command)
:has-handler (:has-handler command)
@ -142,7 +140,7 @@
(fn [_ [_ chat-id {:keys [command]} hidden-params]]
(let [command (-> command
(update-in [:content :params] #(apply dissoc % hidden-params))
(dissoc :rendered-preview :to-message :has-handler))]
(dissoc :to-message :has-handler))]
(messages/save chat-id command)))))
(register-handler ::dispatch-responded-requests!
@ -288,7 +286,7 @@
(register-handler ::send-command-protocol!
(u/side-effect!
(fn [{:keys [web3 current-public-key chats network-status] :as db}
[_ {:keys [chat-id command]}]]
[_ {:keys [chat-id command command-message]}]]
(log/debug "sending command: " command)
(when (cu/not-console? chat-id)
(let [{:keys [public-key private-key]} (chats chat-id)

View File

@ -36,7 +36,8 @@
get-contact-translated]]
[status-im.chat.utils :as cu]
[clojure.string :as str]
[status-im.chat.handlers.console :as console]))
[status-im.chat.handlers.console :as console]
[taoensso.timbre :as log]))
(def window-width (:width (get-dimensions "window")))
@ -112,13 +113,14 @@
(str params))]))
(defview message-content-command
[{:keys [content content-type rendered-preview chat-id to from outgoing] :as message}]
[{:keys [message-id content content-type chat-id to from outgoing] :as message}]
[commands [(if (= (:type content) "response")
:get-responses
:get-commands)
chat-id]
current-chat-id [:get-current-chat-id]
contact-chat [:get-in [:chats (if outgoing to from)]]]
contact-chat [:get-in [:chats (if outgoing to from)]]
preview [:get-in [:message-data :preview message-id]]]
(let [{:keys [command params]} (parse-command-message-content commands content)
{:keys [name type]
icon-path :icon} command]
@ -135,7 +137,7 @@
:content-type content-type
:params params
:outgoing? outgoing
:preview rendered-preview
:preview preview
:contact-chat contact-chat
:contact-address (if outgoing to from)
:current-chat-id current-chat-id}]]))
@ -237,8 +239,8 @@
:content-type content-type}]]])
(defview group-message-delivery-status [{:keys [message-id group-id message-status user-statuses] :as msg}]
[app-db-message-user-statuses [:get-in [:message-user-statuses message-id]]
app-db-message-status-value [:get-in [:message-statuses message-id :status]]
[app-db-message-user-statuses [:get-in [:message-data :user-statuses message-id]]
app-db-message-status-value [:get-in [:message-data :statuses message-id :status]]
chat [:get-chat-by-id group-id]
contacts [:get-contacts]]
(let [status (or message-status app-db-message-status-value :sending)
@ -281,7 +283,7 @@
(defview message-delivery-status
[{:keys [message-id chat-id message-status user-statuses content]}]
[app-db-message-status-value [:get-in [:message-statuses message-id :status]]]
[app-db-message-status-value [:get-in [:message-data :statuses message-id :status]]]
(let [delivery-status (get-in user-statuses [chat-id :status])
command-name (keyword (:command content))
status (cond (and (not (console/commands-with-delivery-status command-name))
@ -372,11 +374,18 @@
children)])}))
(into [view] children)))
(defn chat-message [{:keys [outgoing message-id chat-id user-statuses from]}]
(defn chat-message [{:keys [outgoing message-id chat-id user-statuses from content] :as message}]
(let [my-identity (subscribe [:get :current-public-key])
status (subscribe [:get-in [:message-user-statuses message-id my-identity]])]
status (subscribe [:get-in [:message-data :user-statuses message-id my-identity]])
preview (subscribe [:get-in [:message-data :preview message-id]])]
(r/create-class
{:component-did-mount
{:component-will-mount
(fn []
(when (and (get-in message [:content :command])
(not @preview))
(dispatch [:request-command-preview message])))
:component-did-mount
(fn []
(when (and (not outgoing)
(not= :seen (keyword @status))

View File

@ -76,7 +76,8 @@
(let [top-offset (r/atom {:specified? false})
commands-atom (subscribe [:get-responses])
answered? (subscribe [:is-request-answered? message-id])
status-initialized? (subscribe [:get :status-module-initialized?])]
status-initialized? (subscribe [:get :status-module-initialized?])
preview (subscribe [:get-in [:message-data :preview message-id]])]
(fn [{:keys [message-id content from incoming-group]}]
(let [commands @commands-atom
params (:params content)
@ -93,6 +94,9 @@
[text {:style st/command-request-from-text
:font :default}
from])
(if (and @preview
(not (string? @preview)))
[view @preview]
[text {:style st/style-message-text
:on-layout #(reset! top-offset {:specified? true
:value (-> (.-nativeEvent %)
@ -100,7 +104,7 @@
(.-height)
(> 25))})
:font :default}
content]]]
(or @preview content)])]]
(when (:request-text command)
[view st/command-request-text-view
[text {:style st/style-sub-text

View File

@ -12,13 +12,14 @@
[status-im.utils.gfycat.core :refer [generate-gfy]]
[status-im.constants :refer [console-chat-id
content-type-command
content-type-command-request] :as c]))
content-type-command-request] :as c]
[taoensso.timbre :as log]))
(defmulti message-content (fn [{:keys [content-type]}] content-type))
(defn command-content
[{{:keys [command params]} :content}]
(let [kw (keyword (str "t/command-text-" (name command)))]
[{{:keys [command content-command params]} :content}]
(let [kw (keyword (str "t/command-text-" (name (or content-command command))))]
(label kw params)))
(defmethod message-content content-type-command
@ -30,8 +31,8 @@
(command-content message))
(defmethod message-content content-type-command-request
[{{:keys [content]} :content}]
content)
[message]
(command-content message))
(defmethod message-content :default
[{:keys [content]}]
@ -48,7 +49,7 @@
(defview message-status [{:keys [chat-id contacts]}
{:keys [message-id message-status user-statuses message-type outgoing] :as msg}]
[app-db-message-status-value [:get-in [:message-statuses message-id :status]]]
[app-db-message-status-value [:get-in [:message-data :statuses message-id :status]]]
(let [delivery-status (get-in user-statuses [chat-id :status])]
(when (and outgoing
(or (some #(= (keyword %) :seen) [delivery-status

View File

@ -67,16 +67,6 @@
;; todo show error?
nil)))
(defn command-preview
[_ [command-message {:keys [result]}]]
(let [result' (:returned result)]
(dispatch [:send-chat-message
(if result'
(assoc command-message
:preview (generate-hiccup result')
:preview-string (str result'))
command-message)])))
(defn print-error-message! [message]
(fn [_ params]
(when (:error (last params))
@ -100,10 +90,6 @@
suggestions-handler!)
(reg-handler :suggestions-event! (u/side-effect! suggestions-events-handler!))
(reg-handler :command-preview
(after (print-error-message! "Error on command preview"))
(u/side-effect! command-preview))
(reg-handler :set-local-storage
(fn [{:keys [current-chat-id] :as db} [{:keys [data] :as event}]]
(log/debug "Got event: " event)

View File

@ -131,9 +131,9 @@
(when status
(call-module
#(do
(log/debug :chat-id chat-id)
(log/debug :path path)
(log/debug :params params)
(log/debug :call-jail :chat-id chat-id)
(log/debug :call-jail :path path)
(log/debug :call-jail :params params)
(let [params' (update params :context assoc
:debug js/goog.DEBUG
:locale i/i18n.locale)

View File

@ -53,13 +53,9 @@
(mapv #(clojure.core/update % :user-statuses user-statuses-to-map))
(into '())
reverse
(keep (fn [{:keys [content-type preview] :as message}]
(keep (fn [{:keys [content-type] :as message}]
(if (command-type? content-type)
(-> message
(clojure.core/update :content str-to-map)
(assoc :rendered-preview
(when preview
(generate-hiccup (read-string preview)))))
(clojure.core/update message :content str-to-map)
message)))))
(defn get-count-by-chat-id
@ -76,11 +72,7 @@
reverse
(keep (fn [{:keys [content-type preview] :as message}]
(if (command-type? content-type)
(-> message
(clojure.core/update :content str-to-map)
(assoc :rendered-preview
(when preview
(generate-hiccup (read-string preview)))))
(clojure.core/update message :content str-to-map)
message))))))
(defn get-last-message

View File

@ -33,7 +33,9 @@
[status-im.translations.zh-hant :as zh-hant]
[status-im.translations.zh-wuu :as zh-wuu]
[status-im.translations.zh-yue :as zh-yue]
[status-im.utils.js-resources :refer [default-contacts]]))
[status-im.utils.js-resources :refer [default-contacts]]
[taoensso.timbre :as log]
[clojure.string :as str]))
(def i18n (js/require "react-native-i18n"))
(set! (.-fallbacks i18n) true)
@ -73,11 +75,29 @@
:zh-wuu zh-wuu/translations
:zh-yue zh-yue/translations}))
(def delimeters
"This function is a hack: mobile Safari doesn't support toLocaleString(), so we need to pass
this map to WKWebView to make number formatting work."
(let [n (.toLocaleString (js/Number 1000.1))]
{:delimiter (subs n 1 2)
:separator (subs n 5 6)}))
(defn label-number [number]
(when number
(let [{:keys [delimiter separator]} delimeters]
(.toNumber i18n
(str/replace number #"," ".")
(clj->js {:precision 10
:strip_insignificant_zeros true
:delimiter delimiter
:separator separator})))))
(defn label
([path] (label path {}))
([path options]
(if (exists? i18n.t)
(.t i18n (name path) (clj->js options))
(let [options (update options :amount label-number)]
(.t i18n (name path) (clj->js options)))
(name path))))
(defn label-pluralize [count path & options]

View File

@ -310,8 +310,8 @@
(let [message-id' (or ack-of-message message-id)
group? (boolean group-id)
status-path (if (and group? (not= status :sent))
[:message-user-statuses message-id' from]
[:message-statuses message-id'])
[:message-data :user-statuses message-id' from]
[:message-data :statuses message-id'])
{current-status :status} (get-in db status-path)]
(if-not (= :seen current-status)
(assoc-in db status-path {:whisper-identity from

View File

@ -20,7 +20,6 @@
[status-im.i18n :refer [label label-pluralize]]
[clojure.string :as s]))
(defview confirm []
[transactions [:transactions]
{:keys [password]} [:get :confirm-transactions]

View File

@ -10,7 +10,7 @@
touchable-opacity]]
[status-im.components.styles :refer [icon-close]]
[status-im.transactions.styles :as st]
[status-im.i18n :refer [label label-pluralize]]))
[status-im.i18n :refer [label label-pluralize label-number]]))
(defn title-bar [title id]
[view st/title-bar
@ -35,10 +35,10 @@
(defview transaction-page [{:keys [id from to value] :as transaction}]
[{:keys [name] :as contact} [:contact-by-address to]]
(let [eth-value (.fromWei js/Web3.prototype value "ether")
title (str eth-value " ETH to " (or name to))
title (str (label-number eth-value) " ETH to " (or name to))
transactions-info [[(label :t/status) (label :t/pending-confirmation)]
[(label :t/recipient) (or name to)]
[(label :t/value) (str eth-value " ETH")]]]
[(label :t/value) (str (label-number eth-value) " ETH")]]]
[view {:style st/transaction-page
:key id}
[title-bar title id]

View File

@ -178,6 +178,7 @@
:command-text-send "Transaction: {{amount}} ETH"
:command-text-help "Help"
:command-text-faucet "Faucet: {{url}}"
:command-text-request "Request: {{amount}} ETH"
;new-group
:group-chat-name "Chat name"