reformat status-im.chat.* namespaces

This commit is contained in:
Roman Volosovskyi 2018-05-07 12:14:54 +03:00
parent 4f979fba43
commit 34ae92ac9f
No known key found for this signature in database
GPG Key ID: 0238A4B5ECEE70DE
23 changed files with 826 additions and 832 deletions

View File

@ -2,7 +2,7 @@
(def command-char "/") (def command-char "/")
(def spacing-char " ") (def spacing-char " ")
(def arg-wrapping-char "\"") (def arg-wrapping-char "\"")
(def input-height 56) (def input-height 56)
(def input-spacing-top 16) (def input-spacing-top 16)

View File

@ -22,7 +22,7 @@
[status-im.transport.message.v1.group-chat :as group-chat] [status-im.transport.message.v1.group-chat :as group-chat]
status-im.chat.events.commands status-im.chat.events.commands
status-im.chat.events.requests status-im.chat.events.requests
status-im.chat.events.send-message status-im.chat.events.send-message
status-im.chat.events.receive-message status-im.chat.events.receive-message
status-im.chat.events.console status-im.chat.events.console
status-im.chat.events.webview-bridge)) status-im.chat.events.webview-bridge))
@ -30,103 +30,103 @@
;;;; Effects ;;;; Effects
(re-frame/reg-fx (re-frame/reg-fx
:browse :browse
(fn [link] (fn [link]
(list-selection/browse link))) (list-selection/browse link)))
;;;; Handlers ;;;; Handlers
(handlers/register-handler-db (handlers/register-handler-db
:set-chat-ui-props :set-chat-ui-props
[re-frame/trim-v] [re-frame/trim-v]
(fn [db [kvs]] (fn [db [kvs]]
(models/set-chat-ui-props db kvs))) (models/set-chat-ui-props db kvs)))
(handlers/register-handler-db (handlers/register-handler-db
:toggle-chat-ui-props :toggle-chat-ui-props
[re-frame/trim-v] [re-frame/trim-v]
(fn [db [ui-element]] (fn [db [ui-element]]
(models/toggle-chat-ui-prop db ui-element))) (models/toggle-chat-ui-prop db ui-element)))
(handlers/register-handler-db (handlers/register-handler-db
:show-message-details :show-message-details
[re-frame/trim-v] [re-frame/trim-v]
(fn [db [details]] (fn [db [details]]
(models/set-chat-ui-props db {:show-bottom-info? true (models/set-chat-ui-props db {:show-bottom-info? true
:bottom-info details}))) :bottom-info details})))
(handlers/register-handler-db (handlers/register-handler-db
:show-message-options :show-message-options
[re-frame/trim-v] [re-frame/trim-v]
(fn [db [options]] (fn [db [options]]
(models/set-chat-ui-props db {:show-message-options? true (models/set-chat-ui-props db {:show-message-options? true
:message-options options}))) :message-options options})))
(def index-messages (partial into {} (map (juxt :message-id identity)))) (def index-messages (partial into {} (map (juxt :message-id identity))))
(handlers/register-handler-fx (handlers/register-handler-fx
:load-more-messages :load-more-messages
[(re-frame/inject-cofx :data-store/get-messages)] [(re-frame/inject-cofx :data-store/get-messages)]
(fn [{{:keys [current-chat-id] :as db} :db get-stored-messages :get-stored-messages} _] (fn [{{:keys [current-chat-id] :as db} :db get-stored-messages :get-stored-messages} _]
(when-not (get-in db [:chats current-chat-id :all-loaded?]) (when-not (get-in db [:chats current-chat-id :all-loaded?])
(let [loaded-count (count (get-in db [:chats current-chat-id :messages])) (let [loaded-count (count (get-in db [:chats current-chat-id :messages]))
new-messages (index-messages (get-stored-messages current-chat-id loaded-count))] new-messages (index-messages (get-stored-messages current-chat-id loaded-count))]
{:db (-> db {:db (-> db
(update-in [:chats current-chat-id :messages] merge new-messages) (update-in [:chats current-chat-id :messages] merge new-messages)
(update-in [:chats current-chat-id :not-loaded-message-ids] #(apply disj % (keys new-messages))) (update-in [:chats current-chat-id :not-loaded-message-ids] #(apply disj % (keys new-messages)))
(assoc-in [:chats current-chat-id :all-loaded?] (assoc-in [:chats current-chat-id :all-loaded?]
(> constants/default-number-of-messages (count new-messages))))})))) (> constants/default-number-of-messages (count new-messages))))}))))
(handlers/register-handler-db (handlers/register-handler-db
:message-appeared :message-appeared
[re-frame/trim-v] [re-frame/trim-v]
(fn [db [{:keys [chat-id message-id]}]] (fn [db [{:keys [chat-id message-id]}]]
(update-in db [:chats chat-id :messages message-id] assoc :appearing? false))) (update-in db [:chats chat-id :messages message-id] assoc :appearing? false)))
(handlers/register-handler-fx (handlers/register-handler-fx
:update-message-status :update-message-status
[re-frame/trim-v] [re-frame/trim-v]
(fn [{:keys [db]} [chat-id message-id user-id status]] (fn [{:keys [db]} [chat-id message-id user-id status]]
(let [msg-path [:chats chat-id :messages message-id] (let [msg-path [:chats chat-id :messages message-id]
new-db (update-in db (conj msg-path :user-statuses) assoc user-id status)] new-db (update-in db (conj msg-path :user-statuses) assoc user-id status)]
{:db new-db {:db new-db
:data-store/update-message (-> (get-in new-db msg-path) (select-keys [:message-id :user-statuses]))}))) :data-store/update-message (-> (get-in new-db msg-path) (select-keys [:message-id :user-statuses]))})))
(handlers/register-handler-fx (handlers/register-handler-fx
:transport/set-message-envelope-hash :transport/set-message-envelope-hash
[re-frame/trim-v] [re-frame/trim-v]
;; message-type is used for tracking ;; message-type is used for tracking
(fn [{:keys [db]} [chat-id message-id message-type envelope-hash]] (fn [{:keys [db]} [chat-id message-id message-type envelope-hash]]
{:db (assoc-in db [:transport/message-envelopes envelope-hash] {:chat-id chat-id {:db (assoc-in db [:transport/message-envelopes envelope-hash] {:chat-id chat-id
:message-id message-id})})) :message-id message-id})}))
(handlers/register-handler-fx (handlers/register-handler-fx
:signals/envelope-status :signals/envelope-status
[re-frame/trim-v] [re-frame/trim-v]
(fn [{:keys [db] :as cofx} [envelope-hash status]] (fn [{:keys [db] :as cofx} [envelope-hash status]]
(let [{:keys [chat-id message-id]} (get-in db [:transport/message-envelopes envelope-hash]) (let [{:keys [chat-id message-id]} (get-in db [:transport/message-envelopes envelope-hash])
message (get-in db [:chats chat-id :messages message-id])] message (get-in db [:chats chat-id :messages message-id])]
(models.message/update-message-status message status cofx)))) (models.message/update-message-status message status cofx))))
;; Change status of messages which are still in "sending" status to "not-sent" ;; Change status of messages which are still in "sending" status to "not-sent"
;; (If signal from status-go has not been received) ;; (If signal from status-go has not been received)
(handlers/register-handler-fx (handlers/register-handler-fx
:process-pending-messages :process-pending-messages
[re-frame/trim-v] [re-frame/trim-v]
(fn [{:keys [db]} []] (fn [{:keys [db]} []]
(let [pending-messages (->> db (let [pending-messages (->> db
:chats :chats
vals vals
(mapcat (comp vals :messages)) (mapcat (comp vals :messages))
(filter (fn [{:keys [from user-statuses]}] (= :sending (get user-statuses from))))) (filter (fn [{:keys [from user-statuses]}] (= :sending (get user-statuses from)))))
updated-messages (map (fn [{:keys [from] :as message}] updated-messages (map (fn [{:keys [from] :as message}]
(assoc-in message [:user-statuses from] :not-sent)) (assoc-in message [:user-statuses from] :not-sent))
pending-messages)] pending-messages)]
{:data-store/update-messages updated-messages {:data-store/update-messages updated-messages
:db (reduce (fn [m {:keys [chat-id message-id from]}] :db (reduce (fn [m {:keys [chat-id message-id from]}]
(assoc-in m [:chats chat-id :messages message-id :user-statuses from] :not-sent)) (assoc-in m [:chats chat-id :messages message-id :user-statuses from] :not-sent))
db db
pending-messages)}))) pending-messages)})))
(defn init-console-chat (defn init-console-chat
[{:keys [db] :as cofx}] [{:keys [db] :as cofx}]
@ -159,50 +159,50 @@
contacts-to-add (select-keys new-contacts (set/difference (set (keys new-contacts)) contacts-to-add (select-keys new-contacts (set/difference (set (keys new-contacts))
(set (keys existing-contacts))))] (set (keys existing-contacts))))]
(handlers-macro/merge-fx cofx (handlers-macro/merge-fx cofx
{:db (update db :contacts/contacts merge contacts-to-add) {:db (update db :contacts/contacts merge contacts-to-add)
:data-store/save-contacts (vals contacts-to-add)} :data-store/save-contacts (vals contacts-to-add)}
(events.loading/load-commands)))) (events.loading/load-commands))))
(handlers/register-handler-fx (handlers/register-handler-fx
:initialize-chats :initialize-chats
[(re-frame/inject-cofx :get-default-contacts-and-groups) [(re-frame/inject-cofx :get-default-contacts-and-groups)
(re-frame/inject-cofx :data-store/all-chats) (re-frame/inject-cofx :data-store/all-chats)
(re-frame/inject-cofx :data-store/get-messages) (re-frame/inject-cofx :data-store/get-messages)
(re-frame/inject-cofx :data-store/unviewed-messages) (re-frame/inject-cofx :data-store/unviewed-messages)
(re-frame/inject-cofx :data-store/message-ids) (re-frame/inject-cofx :data-store/message-ids)
(re-frame/inject-cofx :data-store/get-unanswered-requests) (re-frame/inject-cofx :data-store/get-unanswered-requests)
(re-frame/inject-cofx :data-store/get-local-storage-data)] (re-frame/inject-cofx :data-store/get-local-storage-data)]
(fn [{:keys [db (fn [{:keys [db
all-stored-chats all-stored-chats
stored-unanswered-requests stored-unanswered-requests
get-stored-messages get-stored-messages
stored-unviewed-messages stored-unviewed-messages
stored-message-ids] :as cofx} _] stored-message-ids] :as cofx} _]
(let [chat->message-id->request (reduce (fn [acc {:keys [chat-id message-id] :as request}] (let [chat->message-id->request (reduce (fn [acc {:keys [chat-id message-id] :as request}]
(assoc-in acc [chat-id message-id] request)) (assoc-in acc [chat-id message-id] request))
{} {}
stored-unanswered-requests) stored-unanswered-requests)
chats (reduce (fn [acc {:keys [chat-id] :as chat}] chats (reduce (fn [acc {:keys [chat-id] :as chat}]
(let [chat-messages (index-messages (get-stored-messages chat-id))] (let [chat-messages (index-messages (get-stored-messages chat-id))]
(assoc acc chat-id (assoc acc chat-id
(assoc chat (assoc chat
:unviewed-messages (get stored-unviewed-messages chat-id) :unviewed-messages (get stored-unviewed-messages chat-id)
:requests (get chat->message-id->request chat-id) :requests (get chat->message-id->request chat-id)
:messages chat-messages :messages chat-messages
:not-loaded-message-ids (set/difference (get stored-message-ids chat-id) :not-loaded-message-ids (set/difference (get stored-message-ids chat-id)
(-> chat-messages keys set)))))) (-> chat-messages keys set))))))
{} {}
all-stored-chats)] all-stored-chats)]
(handlers-macro/merge-fx cofx (handlers-macro/merge-fx cofx
{:db (assoc db :chats chats)} {:db (assoc db :chats chats)}
(init-console-chat) (init-console-chat)
(group.events/add-default-groups) (group.events/add-default-groups)
(add-default-contacts))))) (add-default-contacts)))))
(handlers/register-handler-fx (handlers/register-handler-fx
:browse-link-from-message :browse-link-from-message
(fn [_ [_ link]] (fn [_ [_ link]]
{:browse link})) {:browse link}))
(defn- persist-seen-messages (defn- persist-seen-messages
[chat-id unseen-messages-ids {:keys [db]}] [chat-id unseen-messages-ids {:keys [db]}]
@ -256,37 +256,37 @@
"Takes chat-id and coeffects map, returns effects necessary when navigating to chat" "Takes chat-id and coeffects map, returns effects necessary when navigating to chat"
[chat-id {:keys [db] :as cofx}] [chat-id {:keys [db] :as cofx}]
(handlers-macro/merge-fx cofx (handlers-macro/merge-fx cofx
{:db (-> (assoc db :current-chat-id chat-id) {:db (-> (assoc db :current-chat-id chat-id)
(models/set-chat-ui-props {:validation-messages nil}))} (models/set-chat-ui-props {:validation-messages nil}))}
(fire-off-chat-loaded-event chat-id) (fire-off-chat-loaded-event chat-id)
(mark-messages-seen chat-id))) (mark-messages-seen chat-id)))
(handlers/register-handler-fx (handlers/register-handler-fx
:add-chat-loaded-event :add-chat-loaded-event
[re-frame/trim-v] [re-frame/trim-v]
(fn [{:keys [db] :as cofx} [chat-id event]] (fn [{:keys [db] :as cofx} [chat-id event]]
(if (get (:chats db) chat-id) (if (get (:chats db) chat-id)
{:db (assoc-in db [:chats chat-id :chat-loaded-event] event)} {:db (assoc-in db [:chats chat-id :chat-loaded-event] event)}
(-> (models/upsert-chat {:chat-id chat-id} cofx) ; chat not created yet, we have to create it (-> (models/upsert-chat {:chat-id chat-id} cofx) ; chat not created yet, we have to create it
(assoc-in [:db :chats chat-id :chat-loaded-event] event))))) (assoc-in [:db :chats chat-id :chat-loaded-event] event)))))
(defn- navigate-to-chat (defn- navigate-to-chat
"Takes coeffects map and chat-id, returns effects necessary for navigation and preloading data" "Takes coeffects map and chat-id, returns effects necessary for navigation and preloading data"
[chat-id {:keys [navigation-replace?]} {:keys [db] :as cofx}] [chat-id {:keys [navigation-replace?]} {:keys [db] :as cofx}]
(if navigation-replace? (if navigation-replace?
(handlers-macro/merge-fx cofx (handlers-macro/merge-fx cofx
(navigation/replace-view :chat) (navigation/replace-view :chat)
(preload-chat-data chat-id)) (preload-chat-data chat-id))
(handlers-macro/merge-fx cofx (handlers-macro/merge-fx cofx
;; TODO janherich - refactor `navigate-to` so it can be used with `merge-fx` macro ;; TODO janherich - refactor `navigate-to` so it can be used with `merge-fx` macro
{:db (navigation/navigate-to db :chat)} {:db (navigation/navigate-to db :chat)}
(preload-chat-data chat-id)))) (preload-chat-data chat-id))))
(handlers/register-handler-fx (handlers/register-handler-fx
:navigate-to-chat :navigate-to-chat
[re-frame/trim-v] [re-frame/trim-v]
(fn [cofx [chat-id opts]] (fn [cofx [chat-id opts]]
(navigate-to-chat chat-id opts cofx))) (navigate-to-chat chat-id opts cofx)))
(defn start-chat (defn start-chat
"Start a chat, making sure it exists" "Start a chat, making sure it exists"
@ -294,22 +294,22 @@
; don't allow to open chat with yourself ; don't allow to open chat with yourself
(when (not= (:current-public-key db) chat-id) (when (not= (:current-public-key db) chat-id)
(handlers-macro/merge-fx cofx (handlers-macro/merge-fx cofx
(models/upsert-chat {:chat-id chat-id (models/upsert-chat {:chat-id chat-id
:is-active true}) :is-active true})
(navigate-to-chat chat-id opts)))) (navigate-to-chat chat-id opts))))
(handlers/register-handler-fx (handlers/register-handler-fx
:start-chat :start-chat
[re-frame/trim-v] [re-frame/trim-v]
(fn [cofx [contact-id opts]] (fn [cofx [contact-id opts]]
(start-chat contact-id opts cofx))) (start-chat contact-id opts cofx)))
;; TODO(janherich): remove this unnecessary event in the future (only model function `update-chat` will stay) ;; TODO(janherich): remove this unnecessary event in the future (only model function `update-chat` will stay)
(handlers/register-handler-fx (handlers/register-handler-fx
:update-chat! :update-chat!
[re-frame/trim-v] [re-frame/trim-v]
(fn [cofx [chat]] (fn [cofx [chat]]
(models/upsert-chat chat cofx))) (models/upsert-chat chat cofx)))
(defn- remove-transport [chat-id {:keys [db] :as cofx}] (defn- remove-transport [chat-id {:keys [db] :as cofx}]
(let [{:keys [group-chat public?]} (get-in db [:chats chat-id])] (let [{:keys [group-chat public?]} (get-in db [:chats chat-id])]
@ -319,49 +319,49 @@
(handlers-macro/merge-fx cofx (transport/unsubscribe-from-chat chat-id))))) (handlers-macro/merge-fx cofx (transport/unsubscribe-from-chat chat-id)))))
(handlers/register-handler-fx (handlers/register-handler-fx
:leave-chat-and-navigate-home :leave-chat-and-navigate-home
[re-frame/trim-v] [re-frame/trim-v]
(fn [cofx [chat-id]] (fn [cofx [chat-id]]
(handlers-macro/merge-fx cofx (handlers-macro/merge-fx cofx
(models/remove-chat chat-id) (models/remove-chat chat-id)
(navigation/replace-view :home) (navigation/replace-view :home)
(remove-transport chat-id)))) (remove-transport chat-id))))
(handlers/register-handler-fx (handlers/register-handler-fx
:leave-group-chat? :leave-group-chat?
[re-frame/trim-v] [re-frame/trim-v]
(fn [_ [chat-id]] (fn [_ [chat-id]]
{:show-confirmation {:title (i18n/label :t/leave-confirmation) {:show-confirmation {:title (i18n/label :t/leave-confirmation)
:content (i18n/label :t/leave-group-chat-confirmation) :content (i18n/label :t/leave-group-chat-confirmation)
:confirm-button-text (i18n/label :t/leave) :confirm-button-text (i18n/label :t/leave)
:on-accept #(re-frame/dispatch [:leave-chat-and-navigate-home chat-id])}})) :on-accept #(re-frame/dispatch [:leave-chat-and-navigate-home chat-id])}}))
(handlers/register-handler-fx (handlers/register-handler-fx
:remove-chat-and-navigate-home :remove-chat-and-navigate-home
[re-frame/trim-v] [re-frame/trim-v]
(fn [cofx [chat-id]] (fn [cofx [chat-id]]
(handlers-macro/merge-fx cofx (handlers-macro/merge-fx cofx
(models/remove-chat chat-id) (models/remove-chat chat-id)
(navigation/replace-view :home)))) (navigation/replace-view :home))))
(handlers/register-handler-fx (handlers/register-handler-fx
:remove-chat-and-navigate-home? :remove-chat-and-navigate-home?
[re-frame/trim-v] [re-frame/trim-v]
(fn [_ [chat-id group?]] (fn [_ [chat-id group?]]
{:show-confirmation {:title (i18n/label :t/delete-confirmation) {:show-confirmation {:title (i18n/label :t/delete-confirmation)
:content (i18n/label (if group? :t/delete-group-chat-confirmation :t/delete-chat-confirmation)) :content (i18n/label (if group? :t/delete-group-chat-confirmation :t/delete-chat-confirmation))
:confirm-button-text (i18n/label :t/delete) :confirm-button-text (i18n/label :t/delete)
:on-accept #(re-frame/dispatch [:remove-chat-and-navigate-home chat-id])}})) :on-accept #(re-frame/dispatch [:remove-chat-and-navigate-home chat-id])}}))
(handlers/register-handler-fx (handlers/register-handler-fx
:create-new-public-chat :create-new-public-chat
[re-frame/trim-v] [re-frame/trim-v]
(fn [{:keys [db now] :as cofx} [topic]] (fn [{:keys [db now] :as cofx} [topic]]
(handlers-macro/merge-fx cofx (handlers-macro/merge-fx cofx
(models/add-public-chat topic) (models/add-public-chat topic)
(navigation/navigate-to-clean :home) (navigation/navigate-to-clean :home)
(navigate-to-chat topic {}) (navigate-to-chat topic {})
(public-chat/join-public-chat topic)))) (public-chat/join-public-chat topic))))
(defn- group-name-from-contacts [selected-contacts all-contacts username] (defn- group-name-from-contacts [selected-contacts all-contacts username]
(->> selected-contacts (->> selected-contacts
@ -370,38 +370,38 @@
(string/join ", "))) (string/join ", ")))
(handlers/register-handler-fx (handlers/register-handler-fx
:create-new-group-chat-and-open :create-new-group-chat-and-open
[re-frame/trim-v (re-frame/inject-cofx :random-id)] [re-frame/trim-v (re-frame/inject-cofx :random-id)]
(fn [{:keys [db now random-id] :as cofx} [group-name]] (fn [{:keys [db now random-id] :as cofx} [group-name]]
(let [selected-contacts (:group/selected-contacts db) (let [selected-contacts (:group/selected-contacts db)
chat-name (if-not (string/blank? group-name) chat-name (if-not (string/blank? group-name)
group-name group-name
(group-name-from-contacts selected-contacts (group-name-from-contacts selected-contacts
(:contacts/contacts db) (:contacts/contacts db)
(:username db)))] (:username db)))]
(handlers-macro/merge-fx cofx (handlers-macro/merge-fx cofx
{:db (assoc db :group/selected-contacts #{})} {:db (assoc db :group/selected-contacts #{})}
(models/add-group-chat random-id chat-name (:current-public-key db) selected-contacts) (models/add-group-chat random-id chat-name (:current-public-key db) selected-contacts)
(navigation/navigate-to-clean :home) (navigation/navigate-to-clean :home)
(navigate-to-chat random-id {}) (navigate-to-chat random-id {})
(transport.message/send (group-chat/GroupAdminUpdate. chat-name selected-contacts) random-id))))) (transport.message/send (group-chat/GroupAdminUpdate. chat-name selected-contacts) random-id)))))
(handlers/register-handler-fx (handlers/register-handler-fx
:show-profile :show-profile
[re-frame/trim-v] [re-frame/trim-v]
(fn [{:keys [db] :as cofx} [identity]] (fn [{:keys [db] :as cofx} [identity]]
(handlers-macro/merge-fx cofx (handlers-macro/merge-fx cofx
{:db (assoc db :contacts/identity identity)} {:db (assoc db :contacts/identity identity)}
(navigation/navigate-forget :profile)))) (navigation/navigate-forget :profile))))
(handlers/register-handler-fx (handlers/register-handler-fx
:resend-message :resend-message
[re-frame/trim-v] [re-frame/trim-v]
(fn [cofx [chat-id message-id]] (fn [cofx [chat-id message-id]]
(models.message/resend-message chat-id message-id cofx))) (models.message/resend-message chat-id message-id cofx)))
(handlers/register-handler-fx (handlers/register-handler-fx
:delete-message :delete-message
[re-frame/trim-v] [re-frame/trim-v]
(fn [cofx [chat-id message-id]] (fn [cofx [chat-id message-id]]
(models.message/delete-message chat-id message-id cofx))) (models.message/delete-message chat-id message-id cofx)))

View File

@ -47,24 +47,24 @@
;;;; Handlers ;;;; Handlers
(handlers/register-handler-fx (handlers/register-handler-fx
::jail-command-data-response ::jail-command-data-response
[re-frame/trim-v] [re-frame/trim-v]
(fn [{:keys [db]} [{{:keys [returned]} :result} {:keys [chat-id]} {:keys [proceed-event-creator]}]] (fn [{:keys [db]} [{{:keys [returned]} :result} {:keys [chat-id]} {:keys [proceed-event-creator]}]]
(when proceed-event-creator (when proceed-event-creator
{:dispatch (proceed-event-creator returned)}))) {:dispatch (proceed-event-creator returned)})))
(handlers/register-handler-fx (handlers/register-handler-fx
:request-command-message-data :request-command-message-data
[re-frame/trim-v (re-frame/inject-cofx :data-store/get-local-storage-data)] [re-frame/trim-v (re-frame/inject-cofx :data-store/get-local-storage-data)]
(fn [{:keys [db]} [message opts]] (fn [{:keys [db]} [message opts]]
(request-command-message-data db message opts))) (request-command-message-data db message opts)))
(handlers/register-handler-fx (handlers/register-handler-fx
:execute-command-immediately :execute-command-immediately
[re-frame/trim-v] [re-frame/trim-v]
(fn [_ [{command-name :name}]] (fn [_ [{command-name :name}]]
(case (keyword command-name) (case (keyword command-name)
:grant-permissions :grant-permissions
{:dispatch [:request-permissions {:permissions [:read-external-storage] {:dispatch [:request-permissions {:permissions [:read-external-storage]
:on-allowed #(re-frame/dispatch [:initialize-geth])}]} :on-allowed #(re-frame/dispatch [:initialize-geth])}]}
(log/debug "ignoring command: " command-name)))) (log/debug "ignoring command: " command-name))))

View File

@ -59,16 +59,16 @@
(fn [{:keys [db random-id now] :as cofx} {:keys [params]}] (fn [{:keys [db random-id now] :as cofx} {:keys [params]}]
(let [debug? (= "On" (:mode params))] (let [debug? (= "On" (:mode params))]
(handlers-macro/merge-fx cofx (handlers-macro/merge-fx cofx
{:dispatch-n (if debug? {:dispatch-n (if debug?
[[:initialize-debugging {:force-start? true}] [[:initialize-debugging {:force-start? true}]
[:chat-received-message/add [:chat-received-message/add
(console-chat/console-message (console-chat/console-message
{:message-id random-id {:message-id random-id
:content (i18n/label :t/debug-enabled) :content (i18n/label :t/debug-enabled)
:content-type constants/text-content-type})]] :content-type constants/text-content-type})]]
[[:stop-debugging]])} [[:stop-debugging]])}
(account.utils/account-update {:debug? debug? (account.utils/account-update {:debug? debug?
:last-updated now}))))}) :last-updated now}))))})
(def commands-names (set (keys console-commands->fx))) (def commands-names (set (keys console-commands->fx)))

View File

@ -18,30 +18,30 @@
;;;; Effects ;;;; Effects
(re-frame/reg-fx (re-frame/reg-fx
::focus-rn-component ::focus-rn-component
(fn [ref] (fn [ref]
(try (try
(.focus ref) (.focus ref)
(catch :default e (catch :default e
(log/debug "Cannot focus the reference"))))) (log/debug "Cannot focus the reference")))))
(re-frame/reg-fx (re-frame/reg-fx
::blur-rn-component ::blur-rn-component
(fn [ref] (fn [ref]
(try (try
(.blur ref) (.blur ref)
(catch :default e (catch :default e
(log/debug "Cannot blur the reference"))))) (log/debug "Cannot blur the reference")))))
(re-frame/reg-fx (re-frame/reg-fx
::dismiss-keyboard ::dismiss-keyboard
(fn [_] (fn [_]
(react-comp/dismiss-keyboard!))) (react-comp/dismiss-keyboard!)))
(re-frame/reg-fx (re-frame/reg-fx
::set-native-props ::set-native-props
(fn [{:keys [ref props]}] (fn [{:keys [ref props]}]
(.setNativeProps ref (clj->js props)))) (.setNativeProps ref (clj->js props))))
;;;; Helper functions ;;;; Helper functions
@ -204,11 +204,11 @@
sequential-params sequential-params
(as-> fx' (as-> fx'
(cond-> (update fx' :db (cond-> (update fx' :db
set-chat-seq-arg-input-text set-chat-seq-arg-input-text
(string/join constants/spacing-char prefill)) (string/join constants/spacing-char prefill))
(not prevent-auto-focus?) (not prevent-auto-focus?)
(merge fx' (chat-input-focus (:db fx') :seq-input-ref))))))) (merge fx' (chat-input-focus (:db fx') :seq-input-ref)))))))
(defn set-contact-as-command-argument (defn set-contact-as-command-argument
"Sets contact as command argument for active chat" "Sets contact as command argument for active chat"
@ -222,18 +222,18 @@
:path [:public (keyword bot-db-key)] :path [:public (keyword bot-db-key)]
:value contact}) :value contact})
(as-> fx (as-> fx
(let [{:keys [current-chat-id] (let [{:keys [current-chat-id]
:as new-db} (:db fx) :as new-db} (:db fx)
arg-position (input-model/argument-position new-db) arg-position (input-model/argument-position new-db)
input-text (get-in new-db [:chats current-chat-id :input-text]) input-text (get-in new-db [:chats current-chat-id :input-text])
command-args (cond-> (input-model/split-command-args input-text) command-args (cond-> (input-model/split-command-args input-text)
(input-model/text-ends-with-space? input-text) (conj "")) (input-model/text-ends-with-space? input-text) (conj ""))
new-selection (->> command-args new-selection (->> command-args
(take (+ 3 arg-position)) (take (+ 3 arg-position))
(input-model/join-command-args) (input-model/join-command-args)
count count
(min (count input-text)))] (min (count input-text)))]
(merge fx (update-text-selection new-db new-selection))))))) (merge fx (update-text-selection new-db new-selection)))))))
;; function creating "message shaped" data from command, because that's what `request-command-message-data` expects ;; function creating "message shaped" data from command, because that's what `request-command-message-data` expects
(defn- command->message (defn- command->message
@ -282,69 +282,69 @@
;;;; Handlers ;;;; Handlers
(handlers/register-handler-fx (handlers/register-handler-fx
:set-chat-input-text :set-chat-input-text
[re-frame/trim-v] [re-frame/trim-v]
(fn [{:keys [db]} [text]] (fn [{:keys [db]} [text]]
(let [new-db (set-chat-input-text db text) (let [new-db (set-chat-input-text db text)
fx (call-on-message-input-change new-db)] fx (call-on-message-input-change new-db)]
(if-let [{:keys [command]} (input-model/selected-chat-command new-db)] (if-let [{:keys [command]} (input-model/selected-chat-command new-db)]
(merge fx (load-chat-parameter-box new-db command)) (merge fx (load-chat-parameter-box new-db command))
fx)))) fx))))
(handlers/register-handler-fx (handlers/register-handler-fx
:select-chat-input-command :select-chat-input-command
[re-frame/trim-v] [re-frame/trim-v]
(fn [cofx [command metadata prevent-auto-focus?]] (fn [cofx [command metadata prevent-auto-focus?]]
(select-chat-input-command command metadata prevent-auto-focus? cofx))) (select-chat-input-command command metadata prevent-auto-focus? cofx)))
(handlers/register-handler-db (handlers/register-handler-db
:set-command-argument :set-command-argument
[re-frame/trim-v] [re-frame/trim-v]
(fn [db [[index arg move-to-next?]]] (fn [db [[index arg move-to-next?]]]
(set-command-argument db index arg move-to-next?))) (set-command-argument db index arg move-to-next?)))
(handlers/register-handler-fx (handlers/register-handler-fx
:chat-input-focus :chat-input-focus
[re-frame/trim-v] [re-frame/trim-v]
(fn [{:keys [db]} [ref]] (fn [{:keys [db]} [ref]]
(chat-input-focus db ref))) (chat-input-focus db ref)))
(handlers/register-handler-fx (handlers/register-handler-fx
:chat-input-blur :chat-input-blur
[re-frame/trim-v] [re-frame/trim-v]
(fn [{{:keys [current-chat-id chat-ui-props]} :db} [ref]] (fn [{{:keys [current-chat-id chat-ui-props]} :db} [ref]]
(when-let [cmp-ref (get-in chat-ui-props [current-chat-id ref])] (when-let [cmp-ref (get-in chat-ui-props [current-chat-id ref])]
{::blur-rn-component cmp-ref}))) {::blur-rn-component cmp-ref})))
(handlers/register-handler-fx (handlers/register-handler-fx
::proceed-validation ::proceed-validation
[re-frame/trim-v] [re-frame/trim-v]
(fn [_ [{:keys [markup parameters]} proceed-events]] (fn [_ [{:keys [markup parameters]} proceed-events]]
(let [error-events-creator (fn [validator-result] (let [error-events-creator (fn [validator-result]
[[:set-chat-ui-props {:validation-messages validator-result [[:set-chat-ui-props {:validation-messages validator-result
:sending-in-progress? false}]]) :sending-in-progress? false}]])
events (if markup events (if markup
(error-events-creator markup) (error-events-creator markup)
proceed-events)] proceed-events)]
{:dispatch-n events}))) {:dispatch-n events})))
(handlers/register-handler-fx (handlers/register-handler-fx
::send-command ::send-command
message-model/send-interceptors message-model/send-interceptors
(fn [{:keys [db] :as cofx} [command-message]] (fn [{:keys [db] :as cofx} [command-message]]
(let [{:keys [current-chat-id current-public-key]} db (let [{:keys [current-chat-id current-public-key]} db
new-db (-> (model/set-chat-ui-props db {:sending-in-progress? false}) new-db (-> (model/set-chat-ui-props db {:sending-in-progress? false})
(clear-seq-arguments) (clear-seq-arguments)
(set-chat-input-metadata nil) (set-chat-input-metadata nil)
(set-chat-input-text nil)) (set-chat-input-text nil))
address (get-in db [:account/account :address])] address (get-in db [:account/account :address])]
(merge {:db new-db} (merge {:db new-db}
(message-model/process-command (assoc cofx :db new-db) (message-model/process-command (assoc cofx :db new-db)
{:message (get-in db [:chats current-chat-id :input-text]) {:message (get-in db [:chats current-chat-id :input-text])
:command command-message :command command-message
:chat-id current-chat-id :chat-id current-chat-id
:identity current-public-key :identity current-public-key
:address address}))))) :address address})))))
(defn command-complete? (defn command-complete?
[chat-command] [chat-command]
@ -376,96 +376,95 @@
:chat-id current-chat-id :chat-id current-chat-id
:identity current-public-key}))) :identity current-public-key})))
(handlers/register-handler-fx (handlers/register-handler-fx
:send-current-message :send-current-message
message-model/send-interceptors message-model/send-interceptors
(fn [{{:keys [current-chat-id current-public-key] :as db} :db message-id :random-id current-time :now (fn [{{:keys [current-chat-id current-public-key] :as db} :db message-id :random-id current-time :now
:as cofx} _] :as cofx} _]
(when-not (get-in db [:chat-ui-props current-chat-id :sending-in-progress?]) (when-not (get-in db [:chat-ui-props current-chat-id :sending-in-progress?])
(let [input-text (get-in db [:chats current-chat-id :input-text]) (let [input-text (get-in db [:chats current-chat-id :input-text])
chat-command (-> (input-model/selected-chat-command db) chat-command (-> (input-model/selected-chat-command db)
(as-> selected-command (as-> selected-command
(if (get-in selected-command [:command :sequential-params]) (if (get-in selected-command [:command :sequential-params])
(assoc selected-command :args (assoc selected-command :args
(get-in db [:chats current-chat-id :seq-arguments])) (get-in db [:chats current-chat-id :seq-arguments]))
(update selected-command :args (partial remove string/blank?)))))] (update selected-command :args (partial remove string/blank?)))))]
(if (:command chat-command) (if (:command chat-command)
;; Returns true if current input contains command ;; Returns true if current input contains command
(if (command-complete? chat-command) (if (command-complete? chat-command)
(command-complete-fx db chat-command message-id current-time) (command-complete-fx db chat-command message-id current-time)
(command-not-complete-fx db input-text)) (command-not-complete-fx db input-text))
(plain-text-message-fx db cofx input-text current-chat-id current-public-key)))))) (plain-text-message-fx db cofx input-text current-chat-id current-public-key))))))
(handlers/register-handler-db (handlers/register-handler-db
::update-seq-arguments ::update-seq-arguments
[re-frame/trim-v] [re-frame/trim-v]
(fn [{:keys [current-chat-id chats] :as db} [chat-id]] (fn [{:keys [current-chat-id chats] :as db} [chat-id]]
(let [chat-id (or chat-id current-chat-id) (let [chat-id (or chat-id current-chat-id)
text (get-in chats [chat-id :seq-argument-input-text])] text (get-in chats [chat-id :seq-argument-input-text])]
(-> db (-> db
(update-in [:chats chat-id :seq-arguments] #(into [] (conj % text))) (update-in [:chats chat-id :seq-arguments] #(into [] (conj % text)))
(assoc-in [:chats chat-id :seq-argument-input-text] nil))))) (assoc-in [:chats chat-id :seq-argument-input-text] nil)))))
(handlers/register-handler-fx (handlers/register-handler-fx
:send-seq-argument :send-seq-argument
(fn [{{:keys [current-chat-id chats] :as db} :db} _] (fn [{{:keys [current-chat-id chats] :as db} :db} _]
(let [text (get-in chats [current-chat-id :seq-argument-input-text]) (let [text (get-in chats [current-chat-id :seq-argument-input-text])
seq-arguments (get-in chats [current-chat-id :seq-arguments]) seq-arguments (get-in chats [current-chat-id :seq-arguments])
command (-> (input-model/selected-chat-command db) command (-> (input-model/selected-chat-command db)
(assoc :args (into [] (conj seq-arguments text))))] (assoc :args (into [] (conj seq-arguments text))))]
(commands-events/request-command-message-data db (command->message db command) (commands-events/request-command-message-data db (command->message db command)
{:data-type :validator {:data-type :validator
:proceed-event-creator (fn [validation-response] :proceed-event-creator (fn [validation-response]
[::proceed-validation [::proceed-validation
validation-response validation-response
[[::update-seq-arguments current-chat-id] [[::update-seq-arguments current-chat-id]
[:send-current-message]]])})))) [:send-current-message]]])}))))
(handlers/register-handler-db (handlers/register-handler-db
:set-chat-seq-arg-input-text :set-chat-seq-arg-input-text
[re-frame/trim-v] [re-frame/trim-v]
(fn [db [text]] (fn [db [text]]
(set-chat-seq-arg-input-text db text))) (set-chat-seq-arg-input-text db text)))
(handlers/register-handler-fx (handlers/register-handler-fx
:update-text-selection :update-text-selection
[re-frame/trim-v] [re-frame/trim-v]
(fn [{:keys [db]} [selection]] (fn [{:keys [db]} [selection]]
(update-text-selection db selection))) (update-text-selection db selection)))
(handlers/register-handler-fx (handlers/register-handler-fx
:select-prev-argument :select-prev-argument
(fn [{{:keys [chat-ui-props current-chat-id] :as db} :db} _] (fn [{{:keys [chat-ui-props current-chat-id] :as db} :db} _]
(let [command (input-model/selected-chat-command db)] (let [command (input-model/selected-chat-command db)]
(if (get-in command [:command :sequential-params]) (if (get-in command [:command :sequential-params])
(-> db (-> db
(set-command-argument 0 "" false) (set-command-argument 0 "" false)
(set-chat-seq-arg-input-text "") (set-chat-seq-arg-input-text "")
(load-chat-parameter-box (:command command))) (load-chat-parameter-box (:command command)))
(let [arg-pos (input-model/argument-position db)] (let [arg-pos (input-model/argument-position db)]
(when (pos? arg-pos) (when (pos? arg-pos)
(let [input-text (get-in db [:chats current-chat-id :input-text]) (let [input-text (get-in db [:chats current-chat-id :input-text])
new-sel (->> (input-model/split-command-args input-text) new-sel (->> (input-model/split-command-args input-text)
(take (inc arg-pos)) (take (inc arg-pos))
(input-model/join-command-args) (input-model/join-command-args)
(count)) (count))
ref (get-in chat-ui-props [current-chat-id :input-ref])] ref (get-in chat-ui-props [current-chat-id :input-ref])]
(-> db (-> db
(update-text-selection new-sel) (update-text-selection new-sel)
(assoc ::set-native-props (assoc ::set-native-props
{:ref ref {:ref ref
:props {:selection {:start new-sel :end new-sel}}}))))))))) :props {:selection {:start new-sel :end new-sel}}})))))))))
(handlers/register-handler-fx (handlers/register-handler-fx
:set-contact-as-command-argument :set-contact-as-command-argument
[re-frame/trim-v] [re-frame/trim-v]
(fn [{:keys [db]} [params]] (fn [{:keys [db]} [params]]
(set-contact-as-command-argument db params))) (set-contact-as-command-argument db params)))
(handlers/register-handler-db (handlers/register-handler-db
:show-suggestions :show-suggestions
(fn [db _] (fn [db _]
(-> db (-> db
(model/toggle-chat-ui-prop :show-suggestions?) (model/toggle-chat-ui-prop :show-suggestions?)
(model/set-chat-ui-props {:validation-messages nil})))) (model/set-chat-ui-props {:validation-messages nil}))))

View File

@ -11,72 +11,72 @@
;;;; Handlers ;;;; Handlers
(handlers/register-handler-fx (handlers/register-handler-fx
::received-message ::received-message
message-model/receive-interceptors message-model/receive-interceptors
(fn [cofx [message]] (fn [cofx [message]]
(message-model/receive message cofx))) (message-model/receive message cofx)))
(handlers/register-handler-fx (handlers/register-handler-fx
:chat-received-message/add :chat-received-message/add
message-model/receive-interceptors message-model/receive-interceptors
(fn [{:keys [db] :as cofx} [{:keys [content] :as message}]] (fn [{:keys [db] :as cofx} [{:keys [content] :as message}]]
(when (message-model/add-to-chat? cofx message) (when (message-model/add-to-chat? cofx message)
(if (:command content) (if (:command content)
;; we are dealing with received command message, we can't add it right away, ;; we are dealing with received command message, we can't add it right away,
;; we first need to fetch short-preview + preview and add it only after we already have those. ;; we first need to fetch short-preview + preview and add it only after we already have those.
;; note that `request-command-message-data` implicitly wait till jail is ready and ;; note that `request-command-message-data` implicitly wait till jail is ready and
;; calls are made only after that ;; calls are made only after that
(commands-events/request-command-message-data (commands-events/request-command-message-data
db message db message
{:data-type :short-preview {:data-type :short-preview
:proceed-event-creator (fn [short-preview] :proceed-event-creator (fn [short-preview]
[:request-command-message-data [:request-command-message-data
message message
{:data-type :preview {:data-type :preview
:proceed-event-creator (fn [preview] :proceed-event-creator (fn [preview]
[::received-message [::received-message
(update message :content merge (update message :content merge
{:short-preview short-preview {:short-preview short-preview
:preview preview})])}])}) :preview preview})])}])})
;; regular non command message, we can add it right away ;; regular non command message, we can add it right away
(message-model/receive message cofx))))) (message-model/receive message cofx)))))
;; TODO(alwx): refactor this when status-im.commands.handlers.jail is refactored ;; TODO(alwx): refactor this when status-im.commands.handlers.jail is refactored
(handlers/register-handler-fx (handlers/register-handler-fx
:chat-received-message/bot-response :chat-received-message/bot-response
(fn [{:contacts/keys [contacts]} [_ {:keys [chat-id] :as params} {:keys [result bot-id] :as data}]] (fn [{:contacts/keys [contacts]} [_ {:keys [chat-id] :as params} {:keys [result bot-id] :as data}]]
(let [{:keys [returned context]} result (let [{:keys [returned context]} result
{:keys [markup text-message err]} returned {:keys [markup text-message err]} returned
{:keys [log-messages update-db default-db]} context {:keys [log-messages update-db default-db]} context
content (or err text-message)] content (or err text-message)]
(when update-db (when update-db
(re-frame/dispatch [:update-bot-db {:bot bot-id (re-frame/dispatch [:update-bot-db {:bot bot-id
:db update-db}])) :db update-db}]))
(re-frame/dispatch [:suggestions-handler (assoc params (re-frame/dispatch [:suggestions-handler (assoc params
:bot-id bot-id :bot-id bot-id
:result data :result data
:default-db default-db)]) :default-db default-db)])
(doseq [message log-messages] (doseq [message log-messages]
(let [{:keys [message type]} message] (let [{:keys [message type]} message]
(when (or (not= type "debug") (when (or (not= type "debug")
js/goog.DEBUG js/goog.DEBUG
(get-in contacts [chat-id :debug?])) (get-in contacts [chat-id :debug?]))
(re-frame/dispatch [:chat-received-message/add (re-frame/dispatch [:chat-received-message/add
{:message-id (random/id) {:message-id (random/id)
:content (str type ": " message) :content (str type ": " message)
:content-type constants/content-type-log-message :content-type constants/content-type-log-message
:outgoing false :outgoing false
:clock-value (utils.clocks/send 0) :clock-value (utils.clocks/send 0)
:chat-id chat-id :chat-id chat-id
:from chat-id :from chat-id
:to "me"}])))) :to "me"}]))))
(when content (when content
(re-frame/dispatch [:chat-received-message/add (re-frame/dispatch [:chat-received-message/add
{:message-id (random/id) {:message-id (random/id)
:content (str content) :content (str content)
:content-type constants/text-content-type :content-type constants/text-content-type
:outgoing false :outgoing false
:clock-value (utils.clocks/send 0) :clock-value (utils.clocks/send 0)
:chat-id chat-id :chat-id chat-id
:from chat-id :from chat-id
:to "me"}]))))) :to "me"}])))))

View File

@ -7,25 +7,25 @@
[status-im.utils.types :as types])) [status-im.utils.types :as types]))
(re-frame/reg-fx (re-frame/reg-fx
:send-notification :send-notification
(fn [{:keys [message payload tokens]}] (fn [{:keys [message payload tokens]}]
(let [payload-json (types/clj->json payload) (let [payload-json (types/clj->json payload)
tokens-json (types/clj->json tokens)] tokens-json (types/clj->json tokens)]
(log/debug "send-notification message: " message " payload-json: " payload-json " tokens-json: " tokens-json) (log/debug "send-notification message: " message " payload-json: " payload-json " tokens-json: " tokens-json)
(status/notify-users {:message message :payload payload-json :tokens tokens-json} #(log/debug "send-notification cb result: " %))))) (status/notify-users {:message message :payload payload-json :tokens tokens-json} #(log/debug "send-notification cb result: " %)))))
;;;; Handlers ;;;; Handlers
(handlers/register-handler-fx (handlers/register-handler-fx
:chat-send-message/send-command :chat-send-message/send-command
message-model/send-interceptors message-model/send-interceptors
(fn [cofx [_ params]] (fn [cofx [_ params]]
(message-model/send-command cofx params))) (message-model/send-command cofx params)))
(handlers/register-handler-fx (handlers/register-handler-fx
:chat-send-message/from-jail :chat-send-message/from-jail
[re-frame/trim-v] [re-frame/trim-v]
(fn [cofx [{:keys [chat-id message]}]] (fn [cofx [{:keys [chat-id message]}]]
(let [parsed-message (types/json->clj message)] (let [parsed-message (types/json->clj message)]
(message-model/handle-message-from-bot cofx {:message parsed-message (message-model/handle-message-from-bot cofx {:message parsed-message
:chat-id chat-id})))) :chat-id chat-id}))))

View File

@ -28,9 +28,9 @@
"Upsert chat when not deleted" "Upsert chat when not deleted"
[{:keys [chat-id] :as chat-props} {:keys [db] :as cofx}] [{:keys [chat-id] :as chat-props} {:keys [db] :as cofx}]
(let [chat (merge (let [chat (merge
(or (get (:chats db) chat-id) (or (get (:chats db) chat-id)
(create-new-chat chat-id cofx)) (create-new-chat chat-id cofx))
chat-props)] chat-props)]
(if (:is-active chat) (if (:is-active chat)
{:db (update-in db [:chats chat-id] merge chat) {:db (update-in db [:chats chat-id] merge chat)

View File

@ -40,9 +40,9 @@
[chat-id {:keys [message-id clock-value content] :as message} current-chat? {:keys [db]}] [chat-id {:keys [message-id clock-value content] :as message} current-chat? {:keys [db]}]
(let [prepared-message (prepare-message message chat-id current-chat?)] (let [prepared-message (prepare-message message chat-id current-chat?)]
{:db (cond-> {:db (cond->
(-> db (-> db
(update-in [:chats chat-id :messages] assoc message-id prepared-message) (update-in [:chats chat-id :messages] assoc message-id prepared-message)
(update-in [:chats chat-id :last-clock-value] (partial utils.clocks/receive clock-value))) ; this will increase last-clock-value twice when sending our own messages (update-in [:chats chat-id :last-clock-value] (partial utils.clocks/receive clock-value))) ; this will increase last-clock-value twice when sending our own messages
(not current-chat?) (not current-chat?)
(update-in [:chats chat-id :unviewed-messages] (fnil conj #{}) message-id)) (update-in [:chats chat-id :unviewed-messages] (fnil conj #{}) message-id))
:data-store/save-message prepared-message})) :data-store/save-message prepared-message}))
@ -55,7 +55,6 @@
(when send-seen? (when send-seen?
(transport/send (protocol/map->MessagesSeen {:message-ids #{message-id}}) chat-id cofx))) (transport/send (protocol/map->MessagesSeen {:message-ids #{message-id}}) chat-id cofx)))
(defn- add-received-message (defn- add-received-message
[{:keys [from message-id chat-id content content-type timestamp clock-value to-clock-value] :as message} [{:keys [from message-id chat-id content content-type timestamp clock-value to-clock-value] :as message}
{:keys [db now] :as cofx}] {:keys [db now] :as cofx}]
@ -72,35 +71,35 @@
request-command) request-command)
new-timestamp (or timestamp now)] new-timestamp (or timestamp now)]
(handlers-macro/merge-fx cofx (handlers-macro/merge-fx cofx
(add-message chat-id (add-message chat-id
(cond-> (assoc message (cond-> (assoc message
:timestamp new-timestamp :timestamp new-timestamp
:show? true) :show? true)
public-key public-key
(assoc :user-statuses {public-key (if current-chat? :seen :received)}) (assoc :user-statuses {public-key (if current-chat? :seen :received)})
(not clock-value) (not clock-value)
(assoc :clock-value (utils.clocks/send last-clock-value)) ; TODO (cammeelos): for backward compatibility, we use received time to be removed when not an issue anymore (assoc :clock-value (utils.clocks/send last-clock-value)) ; TODO (cammeelos): for backward compatibility, we use received time to be removed when not an issue anymore
command-request? command-request?
(assoc-in [:content :request-command-ref] (assoc-in [:content :request-command-ref]
(lookup-response-ref access-scope->commands-responses (lookup-response-ref access-scope->commands-responses
current-account chat contacts request-command))) current-account chat contacts request-command)))
current-chat?) current-chat?)
(send-message-seen chat-id message-id (and public-key (send-message-seen chat-id message-id (and public-key
(not public?) (not public?)
current-chat? current-chat?
(not (chat-model/bot-only-chat? db chat-id)) (not (chat-model/bot-only-chat? db chat-id))
(not (= constants/system from))))))) (not (= constants/system from)))))))
(defn receive (defn receive
[{:keys [chat-id message-id] :as message} {:keys [now] :as cofx}] [{:keys [chat-id message-id] :as message} {:keys [now] :as cofx}]
(handlers-macro/merge-fx cofx (handlers-macro/merge-fx cofx
(chat-model/upsert-chat {:chat-id chat-id (chat-model/upsert-chat {:chat-id chat-id
; We activate a chat again on new messages ; We activate a chat again on new messages
:is-active true :is-active true
:timestamp now}) :timestamp now})
(add-received-message message) (add-received-message message)
(requests-events/add-request chat-id message-id))) (requests-events/add-request chat-id message-id)))
(defn system-message [chat-id message-id timestamp content] (defn system-message [chat-id message-id timestamp content]
{:message-id message-id {:message-id message-id
@ -213,10 +212,10 @@
message-id (transport.utils/message-id send-record) message-id (transport.utils/message-id send-record)
message-with-id (assoc message :message-id message-id)] message-with-id (assoc message :message-id message-id)]
(handlers-macro/merge-fx cofx (handlers-macro/merge-fx cofx
(chat-model/upsert-chat {:chat-id chat-id (chat-model/upsert-chat {:chat-id chat-id
:timestamp now}) :timestamp now})
(add-message chat-id message-with-id true) (add-message chat-id message-with-id true)
(send chat-id message-id send-record)))) (send chat-id message-id send-record))))
(defn update-message-status [{:keys [chat-id message-id from] :as message} status {:keys [db]}] (defn update-message-status [{:keys [chat-id message-id from] :as message} status {:keys [db]}]
(let [updated-message (assoc-in message [:user-statuses from] status)] (let [updated-message (assoc-in message [:user-statuses from] status)]
@ -291,9 +290,9 @@
chat (or (get chats chat-id) {:chat-id chat-id}) chat (or (get chats chat-id) {:chat-id chat-id})
request (:request handler-data)] request (:request handler-data)]
(handlers-macro/merge-fx cofx (handlers-macro/merge-fx cofx
(upsert-and-send (prepare-command-message current-public-key chat now request content)) (upsert-and-send (prepare-command-message current-public-key chat now request content))
(add-console-responses command handler-data) (add-console-responses command handler-data)
(requests-events/request-answered chat-id to-message)))) (requests-events/request-answered chat-id to-message))))
(defn invoke-console-command-handler (defn invoke-console-command-handler
[{:keys [db] :as cofx} {:keys [command] :as command-params}] [{:keys [db] :as cofx} {:keys [command] :as command-params}]

View File

@ -84,19 +84,19 @@
timeout (if platform/android? 50 0)] timeout (if platform/android? 50 0)]
{:component-did-mount (fn [_] {:component-did-mount (fn [_]
(animation/start (animation/start
(animation/anim-sequence (animation/anim-sequence
[(animation/anim-delay timeout) [(animation/anim-delay timeout)
(animation/spring opacity {:toValue 1 (animation/spring opacity {:toValue 1
:duration duration})])))} :duration duration})])))}
[react/with-activity-indicator [react/with-activity-indicator
{:style style/message-view-preview {:style style/message-view-preview
:preview [react/view style/message-view-preview]} :preview [react/view style/message-view-preview]}
[react/touchable-without-feedback [react/touchable-without-feedback
{:on-press (fn [_] {:on-press (fn [_]
(re-frame/dispatch [:set-chat-ui-props {:messages-focused? true}]) (re-frame/dispatch [:set-chat-ui-props {:messages-focused? true}])
(react/dismiss-keyboard!))} (react/dismiss-keyboard!))}
[react/animated-view {:style (style/message-view-animated opacity)} [react/animated-view {:style (style/message-view-animated opacity)}
message-view]]])) message-view]]]))
(defview messages-view [group-chat] (defview messages-view [group-chat]
(letsubs [messages [:get-current-chat-messages] (letsubs [messages [:get-current-chat-messages]

View File

@ -5,7 +5,6 @@
[status-im.ui.components.colors :as colors] [status-im.ui.components.colors :as colors]
[status-im.constants :as constants])) [status-im.constants :as constants]))
(defstyle style-message-text (defstyle style-message-text
{:font-size 15 {:font-size 15
:color styles/text1-color :color styles/text1-color
@ -104,15 +103,15 @@
(def not-sent-view (def not-sent-view
(assoc delivery-view :opacity 1 (assoc delivery-view :opacity 1
:margin-bottom 2 :margin-bottom 2
:padding-top 2)) :padding-top 2))
(def not-sent-text (def not-sent-text
(assoc delivery-text :color styles/color-red (assoc delivery-text :color styles/color-red
:opacity 1 :opacity 1
:font-size 12 :font-size 12
:text-align :right :text-align :right
:padding-top 4)) :padding-top 4))
(def not-sent-icon (def not-sent-icon
{:padding-top 3 {:padding-top 3
@ -141,7 +140,7 @@
:padding-bottom 8 :padding-bottom 8
:border-radius 8} :border-radius 8}
(when-not (= content-type constants/content-type-emoji) (when-not (= content-type constants/content-type-emoji)
{:background-color styles/color-white}) {:background-color styles/color-white})
(when (= content-type constants/content-type-command) (when (= content-type constants/content-type-command)
{:padding-top 10 {:padding-top 10
:padding-bottom 14}))) :padding-bottom 14})))

View File

@ -5,12 +5,12 @@
[status-im.constants :as constants])) [status-im.constants :as constants]))
(defstyle row (defstyle row
{:flex-direction :row {:flex-direction :row
:background-color :white :background-color :white
:align-items :center :align-items :center
:padding-horizontal 16 :padding-horizontal 16
:ios {:height 36} :ios {:height 36}
:android {:height 36}}) :android {:height 36}})
(def title (def title
{:padding-horizontal 16 {:padding-horizontal 16

View File

@ -3,7 +3,6 @@
(:require [status-im.ui.components.styles :as component.styles] (:require [status-im.ui.components.styles :as component.styles]
[status-im.ui.components.colors :as colors])) [status-im.ui.components.colors :as colors]))
(def scroll-root (def scroll-root
{:flex 1}) {:flex 1})

View File

@ -18,38 +18,38 @@
(reg-sub :chat-ui-props :chat-ui-props) (reg-sub :chat-ui-props :chat-ui-props)
(reg-sub (reg-sub
:get-current-chat-ui-props :get-current-chat-ui-props
:<- [:chat-ui-props] :<- [:chat-ui-props]
:<- [:get-current-chat-id] :<- [:get-current-chat-id]
(fn [[chat-ui-props id]] (fn [[chat-ui-props id]]
(get chat-ui-props id))) (get chat-ui-props id)))
(reg-sub (reg-sub
:get-current-chat-ui-prop :get-current-chat-ui-prop
:<- [:get-current-chat-ui-props] :<- [:get-current-chat-ui-props]
(fn [ui-props [_ prop]] (fn [ui-props [_ prop]]
(get ui-props prop))) (get ui-props prop)))
(reg-sub (reg-sub
:validation-messages :validation-messages
:<- [:get-current-chat-ui-props] :<- [:get-current-chat-ui-props]
(fn [ui-props] (fn [ui-props]
(some-> ui-props :validation-messages commands-utils/generate-hiccup))) (some-> ui-props :validation-messages commands-utils/generate-hiccup)))
(reg-sub (reg-sub
:result-box-markup :result-box-markup
:<- [:get-current-chat-ui-props] :<- [:get-current-chat-ui-props]
(fn [ui-props] (fn [ui-props]
(some-> ui-props :result-box :markup commands-utils/generate-hiccup))) (some-> ui-props :result-box :markup commands-utils/generate-hiccup)))
(reg-sub (reg-sub
:chat-input-margin :chat-input-margin
:<- [:get :keyboard-height] :<- [:get :keyboard-height]
(fn [kb-height] (fn [kb-height]
(cond (cond
(and platform/iphone-x? (> kb-height 0)) (- kb-height 34) (and platform/iphone-x? (> kb-height 0)) (- kb-height 34)
platform/ios? kb-height platform/ios? kb-height
:default 0))) :default 0)))
(defn- active-chat? [dev-mode? [_ chat]] (defn- active-chat? [dev-mode? [_ chat]]
(and (:is-active chat) (and (:is-active chat)
@ -60,29 +60,29 @@
(into {} (filter (partial active-chat? dev-mode?) chats))) (into {} (filter (partial active-chat? dev-mode?) chats)))
(reg-sub (reg-sub
:get-active-chats :get-active-chats
:<- [:get-chats] :<- [:get-chats]
:<- [:get-current-account] :<- [:get-current-account]
active-chats) active-chats)
(reg-sub (reg-sub
:get-chat :get-chat
:<- [:get-active-chats] :<- [:get-active-chats]
(fn [chats [_ chat-id]] (fn [chats [_ chat-id]]
(get chats chat-id))) (get chats chat-id)))
(reg-sub (reg-sub
:get-current-chat :get-current-chat
:<- [:get-active-chats] :<- [:get-active-chats]
:<- [:get-current-chat-id] :<- [:get-current-chat-id]
(fn [[chats current-chat-id]] (fn [[chats current-chat-id]]
(get chats current-chat-id))) (get chats current-chat-id)))
(reg-sub (reg-sub
:get-current-chat-message :get-current-chat-message
:<- [:get-current-chat] :<- [:get-current-chat]
(fn [{:keys [messages]} [_ message-id]] (fn [{:keys [messages]} [_ message-id]]
(get messages message-id))) (get messages message-id)))
(defn- intersperse-datemark (defn- intersperse-datemark
"Reduce step which expects the input list of messages to be sorted by clock value. "Reduce step which expects the input list of messages to be sorted by clock value.
@ -122,11 +122,11 @@
[id->messages] [id->messages]
(->> id->messages (->> id->messages
vals vals
(filter :show?) (filter :show?)
(sort-by (juxt (comp unchecked-negate :clock-value) :message-id)))) (sort-by (juxt (comp unchecked-negate :clock-value) :message-id))))
(defn- add-datemark [{:keys [timestamp] :as msg}] (defn- add-datemark [{:keys [timestamp] :as msg}]
(assoc msg :datemark (time/day-relative timestamp))) (assoc msg :datemark (time/day-relative timestamp)))
(defn- add-timestamp [{:keys [timestamp] :as msg}] (defn- add-timestamp [{:keys [timestamp] :as msg}]
(assoc msg :timestamp-str (time/timestamp->time timestamp))) (assoc msg :timestamp-str (time/timestamp->time timestamp)))
@ -137,8 +137,8 @@
[messages] [messages]
(when (seq messages) (when (seq messages)
(let [messages-with-datemarks (transduce (comp (let [messages-with-datemarks (transduce (comp
(map add-datemark) (map add-datemark)
(map add-timestamp)) (map add-timestamp))
(completing intersperse-datemark :acc) (completing intersperse-datemark :acc)
{:acc []} {:acc []}
messages)] messages)]
@ -203,35 +203,35 @@
:stream)))) :stream))))
(reg-sub (reg-sub
:get-ordered-chat-messages :get-ordered-chat-messages
(fn [[_ chat-id]] (fn [[_ chat-id]]
(subscribe [:get-chat chat-id])) (subscribe [:get-chat chat-id]))
(fn [{:keys [messages]}] (fn [{:keys [messages]}]
(sort-messages messages))) (sort-messages messages)))
(reg-sub (reg-sub
:get-current-chat-messages :get-current-chat-messages
:<- [:get-current-chat] :<- [:get-current-chat]
(fn [{:keys [messages]}] (fn [{:keys [messages]}]
(-> messages sort-messages intersperse-datemarks messages-stream))) (-> messages sort-messages intersperse-datemarks messages-stream)))
(reg-sub (reg-sub
:get-commands-for-chat :get-commands-for-chat
:<- [:get-commands-responses-by-access-scope] :<- [:get-commands-responses-by-access-scope]
:<- [:get-current-account] :<- [:get-current-account]
:<- [:get-current-chat] :<- [:get-current-chat]
:<- [:get-contacts] :<- [:get-contacts]
(fn [[commands-responses account chat contacts]] (fn [[commands-responses account chat contacts]]
(commands-model/commands-responses :command commands-responses account chat contacts))) (commands-model/commands-responses :command commands-responses account chat contacts)))
(reg-sub (reg-sub
:get-responses-for-chat :get-responses-for-chat
:<- [:get-commands-responses-by-access-scope] :<- [:get-commands-responses-by-access-scope]
:<- [:get-current-account] :<- [:get-current-account]
:<- [:get-current-chat] :<- [:get-current-chat]
:<- [:get-contacts] :<- [:get-contacts]
(fn [[commands-responses account {:keys [requests] :as chat} contacts]] (fn [[commands-responses account {:keys [requests] :as chat} contacts]]
(commands-model/requested-responses commands-responses account chat contacts (vals requests)))) (commands-model/requested-responses commands-responses account chat contacts (vals requests))))
(def ^:private map->sorted-seq (comp (partial map second) (partial sort-by first))) (def ^:private map->sorted-seq (comp (partial map second) (partial sort-by first)))
@ -243,149 +243,149 @@
(string/includes? (commands-model/command-name item) input-text)))))) (string/includes? (commands-model/command-name item) input-text))))))
(reg-sub (reg-sub
:get-available-commands :get-available-commands
:<- [:get-commands-for-chat] :<- [:get-commands-for-chat]
:<- [:get-current-chat] :<- [:get-current-chat]
available-commands-responses) available-commands-responses)
(reg-sub (reg-sub
:get-available-responses :get-available-responses
:<- [:get-responses-for-chat] :<- [:get-responses-for-chat]
:<- [:get-current-chat] :<- [:get-current-chat]
available-commands-responses) available-commands-responses)
(reg-sub (reg-sub
:get-available-commands-responses :get-available-commands-responses
:<- [:get-commands-for-chat] :<- [:get-commands-for-chat]
:<- [:get-responses-for-chat] :<- [:get-responses-for-chat]
(fn [[commands responses]] (fn [[commands responses]]
(map->sorted-seq (merge commands responses)))) (map->sorted-seq (merge commands responses))))
(reg-sub (reg-sub
:selected-chat-command :selected-chat-command
:<- [:get-current-chat] :<- [:get-current-chat]
:<- [:get-commands-for-chat] :<- [:get-commands-for-chat]
:<- [:get-responses-for-chat] :<- [:get-responses-for-chat]
(fn [[chat commands responses]] (fn [[chat commands responses]]
(input-model/selected-chat-command chat commands responses))) (input-model/selected-chat-command chat commands responses)))
(reg-sub (reg-sub
:chat-input-placeholder :chat-input-placeholder
:<- [:get-current-chat] :<- [:get-current-chat]
:<- [:selected-chat-command] :<- [:selected-chat-command]
(fn [[{:keys [input-text]} command]] (fn [[{:keys [input-text]} command]]
(when (and (string/ends-with? (or input-text "") chat-constants/spacing-char) (when (and (string/ends-with? (or input-text "") chat-constants/spacing-char)
(not (get-in command [:command :sequential-params]))) (not (get-in command [:command :sequential-params])))
(let [input (string/trim (or input-text "")) (let [input (string/trim (or input-text ""))
real-args (remove string/blank? (:args command))] real-args (remove string/blank? (:args command))]
(cond (cond
(and command (empty? real-args)) (and command (empty? real-args))
(get-in command [:command :params 0 :placeholder]) (get-in command [:command :params 0 :placeholder])
(and command (and command
(= (count real-args) 1) (= (count real-args) 1)
(input-model/text-ends-with-space? input)) (input-model/text-ends-with-space? input))
(get-in command [:command :params 1 :placeholder])))))) (get-in command [:command :params 1 :placeholder]))))))
(reg-sub (reg-sub
:current-chat-argument-position :current-chat-argument-position
:<- [:selected-chat-command] :<- [:selected-chat-command]
:<- [:get-current-chat] :<- [:get-current-chat]
:<- [:get-current-chat-ui-prop :selection] :<- [:get-current-chat-ui-prop :selection]
(fn [[command {:keys [input-text seq-arguments]} selection]] (fn [[command {:keys [input-text seq-arguments]} selection]]
(input-model/current-chat-argument-position command input-text selection seq-arguments))) (input-model/current-chat-argument-position command input-text selection seq-arguments)))
(reg-sub (reg-sub
:chat-parameter-box :chat-parameter-box
:<- [:get-current-chat] :<- [:get-current-chat]
:<- [:selected-chat-command] :<- [:selected-chat-command]
:<- [:current-chat-argument-position] :<- [:current-chat-argument-position]
(fn [[current-chat selected-chat-command argument-position]] (fn [[current-chat selected-chat-command argument-position]]
(cond (cond
(and selected-chat-command (and selected-chat-command
(not= argument-position input-model/*no-argument-error*)) (not= argument-position input-model/*no-argument-error*))
(get-in current-chat [:parameter-boxes (get-in current-chat [:parameter-boxes
(get-in selected-chat-command [:command :name]) (get-in selected-chat-command [:command :name])
argument-position]) argument-position])
(not selected-chat-command) (not selected-chat-command)
(get-in current-chat [:parameter-boxes :message]) (get-in current-chat [:parameter-boxes :message])
:default :default
nil))) nil)))
(reg-sub (reg-sub
:show-parameter-box? :show-parameter-box?
:<- [:chat-parameter-box] :<- [:chat-parameter-box]
:<- [:show-suggestions?] :<- [:show-suggestions?]
:<- [:get-current-chat] :<- [:get-current-chat]
:<- [:validation-messages] :<- [:validation-messages]
(fn [[chat-parameter-box show-suggestions? {:keys [input-text]} validation-messages]] (fn [[chat-parameter-box show-suggestions? {:keys [input-text]} validation-messages]]
(and (get chat-parameter-box :markup) (and (get chat-parameter-box :markup)
(not validation-messages) (not validation-messages)
(not show-suggestions?)))) (not show-suggestions?))))
(reg-sub (reg-sub
:command-completion :command-completion
:<- [:selected-chat-command] :<- [:selected-chat-command]
input-model/command-completion) input-model/command-completion)
(reg-sub (reg-sub
:show-suggestions-view? :show-suggestions-view?
:<- [:get-current-chat-ui-prop :show-suggestions?] :<- [:get-current-chat-ui-prop :show-suggestions?]
:<- [:get-current-chat] :<- [:get-current-chat]
:<- [:selected-chat-command] :<- [:selected-chat-command]
:<- [:get-available-commands-responses] :<- [:get-available-commands-responses]
(fn [[show-suggestions? {:keys [input-text]} selected-command commands-responses]] (fn [[show-suggestions? {:keys [input-text]} selected-command commands-responses]]
(and (or show-suggestions? (input-model/starts-as-command? (string/trim (or input-text "")))) (and (or show-suggestions? (input-model/starts-as-command? (string/trim (or input-text ""))))
(seq commands-responses)))) (seq commands-responses))))
(reg-sub (reg-sub
:show-suggestions? :show-suggestions?
:<- [:show-suggestions-view?] :<- [:show-suggestions-view?]
:<- [:selected-chat-command] :<- [:selected-chat-command]
(fn [[show-suggestions-box? selected-command]] (fn [[show-suggestions-box? selected-command]]
(and show-suggestions-box? (not (:command selected-command))))) (and show-suggestions-box? (not (:command selected-command)))))
(reg-sub (reg-sub
:is-request-answered? :is-request-answered?
:<- [:get-current-chat] :<- [:get-current-chat]
(fn [{:keys [requests]} [_ message-id]] (fn [{:keys [requests]} [_ message-id]]
(not= "open" (get-in requests [message-id :status])))) (not= "open" (get-in requests [message-id :status]))))
(reg-sub (reg-sub
:unviewed-messages-count :unviewed-messages-count
(fn [[_ chat-id]] (fn [[_ chat-id]]
(subscribe [:get-chat chat-id])) (subscribe [:get-chat chat-id]))
(fn [{:keys [unviewed-messages]}] (fn [{:keys [unviewed-messages]}]
(count unviewed-messages))) (count unviewed-messages)))
(reg-sub (reg-sub
:web-view-extra-js :web-view-extra-js
:<- [:get-current-chat] :<- [:get-current-chat]
(fn [current-chat] (fn [current-chat]
(:web-view-extra-js current-chat))) (:web-view-extra-js current-chat)))
(reg-sub (reg-sub
:get-photo-path :get-photo-path
:<- [:get-contacts] :<- [:get-contacts]
(fn [contacts [_ id]] (fn [contacts [_ id]]
(:photo-path (contacts id)))) (:photo-path (contacts id))))
(reg-sub (reg-sub
:get-last-message :get-last-message
(fn [[_ chat-id]] (fn [[_ chat-id]]
(subscribe [:get-ordered-chat-messages chat-id])) (subscribe [:get-ordered-chat-messages chat-id]))
first) first)
(reg-sub (reg-sub
:chat-animations :chat-animations
(fn [db [_ key type]] (fn [db [_ key type]]
(let [chat-id (subscribe [:get-current-chat-id])] (let [chat-id (subscribe [:get-current-chat-id])]
(get-in db [:chat-animations @chat-id key type])))) (get-in db [:chat-animations @chat-id key type]))))
(reg-sub (reg-sub
:get-chats-unread-messages-number :get-chats-unread-messages-number
:<- [:get-active-chats] :<- [:get-active-chats]
(fn [chats _] (fn [chats _]
(apply + (map #(count (:unviewed-messages %)) (vals chats))))) (apply + (map #(count (:unviewed-messages %)) (vals chats)))))

View File

@ -9,10 +9,9 @@
(fn [contact] (fn [contact]
[contact-view {:contact contact [contact-view {:contact contact
:on-press #(re-frame/dispatch :on-press #(re-frame/dispatch
[:set-contact-as-command-argument {:arg-index arg-index [:set-contact-as-command-argument {:arg-index arg-index
:bot-db-key bot-db-key :bot-db-key bot-db-key
:contact contact}])}])) :contact contact}])}]))
(defview choose-contact-view [{title :title (defview choose-contact-view [{title :title
arg-index :index arg-index :index

View File

@ -14,9 +14,9 @@
(defn- container-animation-logic [{:keys [to-value val]}] (defn- container-animation-logic [{:keys [to-value val]}]
(fn [_] (fn [_]
(anim/start (anim/start
(anim/spring val {:toValue to-value (anim/spring val {:toValue to-value
:friction 6 :friction 6
:tension 40})))) :tension 40}))))
(defn overlay [{:keys [on-click-outside]} items] (defn overlay [{:keys [on-click-outside]} items]
[react/view styles/bottom-info-overlay [react/view styles/bottom-info-overlay
@ -31,13 +31,13 @@
:val anim-value} :val anim-value}
on-update (container-animation-logic context)] on-update (container-animation-logic context)]
(reagent/create-class (reagent/create-class
{:component-did-update {:component-did-update
on-update on-update
:display-name "container" :display-name "container"
:reagent-render :reagent-render
(fn [height & children] (fn [height & children]
[react/animated-view {:style (styles/bottom-info-container height)} [react/animated-view {:style (styles/bottom-info-container height)}
(into [react/view] children)])}))) (into [react/view] children)])})))
(defn- message-status-row [{:keys [photo-path name]} {:keys [whisper-identity status]}] (defn- message-status-row [{:keys [photo-path name]} {:keys [whisper-identity status]}]
[react/view styles/bottom-info-row [react/view styles/bottom-info-row
@ -62,20 +62,20 @@
(let [bottom-info (re-frame/subscribe [:get-current-chat-ui-prop :bottom-info]) (let [bottom-info (re-frame/subscribe [:get-current-chat-ui-prop :bottom-info])
contacts (re-frame/subscribe [:get-contacts])] contacts (re-frame/subscribe [:get-contacts])]
(reagent/create-class (reagent/create-class
{:display-name "bottom-info-view" {:display-name "bottom-info-view"
:reagent-render :reagent-render
(fn [] (fn []
(let [{:keys [user-statuses message-status participants]} @bottom-info (let [{:keys [user-statuses message-status participants]} @bottom-info
participants (->> participants participants (->> participants
(map (fn [{:keys [identity]}] (map (fn [{:keys [identity]}]
[identity {:whisper-identity identity [identity {:whisper-identity identity
:status message-status}])) :status message-status}]))
(into {})) (into {}))
statuses (vals (merge participants user-statuses))] statuses (vals (merge participants user-statuses))]
[overlay {:on-click-outside #(re-frame/dispatch [:set-chat-ui-props {:show-bottom-info? false}])} [overlay {:on-click-outside #(re-frame/dispatch [:set-chat-ui-props {:show-bottom-info? false}])}
[container (* styles/item-height (count statuses)) [container (* styles/item-height (count statuses))
[list/flat-list {:contentContainerStyle styles/bottom-info-list-container [list/flat-list {:contentContainerStyle styles/bottom-info-list-container
:data statuses :data statuses
:key-fn :address :key-fn :address
:render-fn (render-status @contacts) :render-fn (render-status @contacts)
:enableEmptySections true}]]]))}))) :enableEmptySections true}]]]))})))

View File

@ -12,9 +12,9 @@
(defn expandable-view-on-update [anim-value animation-height] (defn expandable-view-on-update [anim-value animation-height]
(when animation-height (when animation-height
(animation/start (animation/start
(animation/spring anim-value {:toValue animation-height (animation/spring anim-value {:toValue animation-height
:friction 10 :friction 10
:tension 60})))) :tension 60}))))
(defview expandable-view [{:keys [key]} & elements] (defview expandable-view [{:keys [key]} & elements]
(letsubs [anim-value (animation/create-value 0) (letsubs [anim-value (animation/create-value 0)
@ -35,5 +35,5 @@
(into [react/scroll-view {:keyboard-should-persist-taps :always (into [react/scroll-view {:keyboard-should-persist-taps :always
:on-content-size-change #(expandable-view-on-update anim-value %2) :on-content-size-change #(expandable-view-on-update anim-value %2)
:bounces false}] :bounces false}]
(when (or input-focused? (not messages-focused?)) (when (or input-focused? (not messages-focused?))
elements))]]))) elements))]])))

View File

@ -19,13 +19,13 @@
;; TODO(pacamara) Symptomatic fix, root cause is react-native onLayout returning ;; TODO(pacamara) Symptomatic fix, root cause is react-native onLayout returning
;; inconsistent height values, more investigation needed ;; inconsistent height values, more investigation needed
(defn android-blank-line-extra-height [input-text] (defn android-blank-line-extra-height [input-text]
(if (and platform/android? input-text (string/ends-with? input-text "\n")) (if (and platform/android? input-text (string/ends-with? input-text "\n"))
(/ style/min-input-height 2) (/ style/min-input-height 2)
0)) 0))
(defview basic-text-input [{:keys [set-layout-height-fn set-container-width-fn height single-line-input?]}] (defview basic-text-input [{:keys [set-layout-height-fn set-container-width-fn height single-line-input?]}]
(letsubs [{:keys [input-text]} [:get-current-chat] (letsubs [{:keys [input-text]} [:get-current-chat]
input-focused? [:get-current-chat-ui-prop :input-focused?] input-focused? [:get-current-chat-ui-prop :input-focused?]
input-ref (atom nil)] input-ref (atom nil)]
[react/text-input [react/text-input
@ -38,7 +38,7 @@
:editable true :editable true
:blur-on-submit false :blur-on-submit false
:on-focus #(re-frame/dispatch [:set-chat-ui-props {:input-focused? true :on-focus #(re-frame/dispatch [:set-chat-ui-props {:input-focused? true
:messages-focused? false}]) :messages-focused? false}])
:on-blur #(re-frame/dispatch [:set-chat-ui-props {:input-focused? false}]) :on-blur #(re-frame/dispatch [:set-chat-ui-props {:input-focused? false}])
:on-submit-editing (fn [_] :on-submit-editing (fn [_]
(if single-line-input? (if single-line-input?
@ -94,8 +94,8 @@
(fn [_] (fn [_]
(let [to-value (if @placeholder 1 0)] (let [to-value (if @placeholder 1 0)]
(animation/start (animation/start
(animation/timing opacity-value {:toValue to-value (animation/timing opacity-value {:toValue to-value
:duration 300}))))) :duration 300})))))
(defview input-helper [{:keys [width]}] (defview input-helper [{:keys [width]}]
(letsubs [placeholder [:chat-input-placeholder] (letsubs [placeholder [:chat-input-placeholder]
@ -107,7 +107,6 @@
[react/text {:style (style/input-helper-text width)} [react/text {:style (style/input-helper-text width)}
placeholder]])) placeholder]]))
(defn get-options [type] (defn get-options [type]
(case (keyword type) (case (keyword type)
:phone {:keyboard-type "phone-pad"} :phone {:keyboard-type "phone-pad"}
@ -124,7 +123,7 @@
[react/text-input (merge {:ref #(re-frame/dispatch [:set-chat-ui-props {:seq-input-ref %}]) [react/text-input (merge {:ref #(re-frame/dispatch [:set-chat-ui-props {:seq-input-ref %}])
:style (style/seq-input-text command-width container-width) :style (style/seq-input-text command-width container-width)
:default-value (or seq-arg-input-text "") :default-value (or seq-arg-input-text "")
:on-change-text #(do (re-frame/dispatch [:set-chat-seq-arg-input-text %]) :on-change-text #(do (re-frame/dispatch [:set-chat-seq-arg-input-text %])
(re-frame/dispatch [:set-chat-ui-props {:validation-messages nil}])) (re-frame/dispatch [:set-chat-ui-props {:validation-messages nil}]))
:placeholder placeholder :placeholder placeholder
:accessibility-label :chat-request-input :accessibility-label :chat-request-input
@ -135,8 +134,8 @@
(get-in command [:command :hide-send-button])) (get-in command [:command :hide-send-button]))
(re-frame/dispatch [:send-seq-argument])) (re-frame/dispatch [:send-seq-argument]))
(utils/set-timeout (utils/set-timeout
#(re-frame/dispatch [:chat-input-focus :seq-input-ref]) #(re-frame/dispatch [:chat-input-focus :seq-input-ref])
100))} 100))}
(get-options type))])))) (get-options type))]))))
(defview input-view [{:keys [single-line-input?]}] (defview input-view [{:keys [single-line-input?]}]

View File

@ -12,8 +12,8 @@
(fn [_] (fn [_]
(let [to-spin-value (if (some #{:complete :no-command} [@command-completion]) 1 0)] (let [to-spin-value (if (some #{:complete :no-command} [@command-completion]) 1 0)]
(animation/start (animation/start
(animation/timing spin-value {:toValue to-spin-value (animation/timing spin-value {:toValue to-spin-value
:duration 300}))))) :duration 300})))))
(defview send-button-view [] (defview send-button-view []
(letsubs [command-completion [:command-completion] (letsubs [command-completion [:command-completion]

View File

@ -1,6 +1,6 @@
(ns status-im.chat.views.message.datemark (ns status-im.chat.views.message.datemark
(:require [status-im.ui.components.react :as react] (:require [status-im.ui.components.react :as react]
[clojure.string :as str] [clojure.string :as str]
[status-im.chat.styles.message.datemark :as st])) [status-im.chat.styles.message.datemark :as st]))
(defn chat-datemark [value] (defn chat-datemark [value]

View File

@ -270,8 +270,8 @@
:destructive? true :destructive? true
:action #(re-frame/dispatch [:delete-message chat-id message-id])}]}) :action #(re-frame/dispatch [:delete-message chat-id message-id])}]})
(re-frame/dispatch (re-frame/dispatch
[:show-message-options {:chat-id chat-id [:show-message-options {:chat-id chat-id
:message-id message-id}])))} :message-id message-id}])))}
[react/view style/not-sent-view [react/view style/not-sent-view
[react/text {:style style/not-sent-text} [react/text {:style style/not-sent-text}
(i18n/message-status-label :not-sent)] (i18n/message-status-label :not-sent)]
@ -318,7 +318,7 @@
(when first-in-group? (when first-in-group?
[message-author-name from username]) [message-author-name from username])
[react/view {:style (style/timestamp-content-wrapper message)} [react/view {:style (style/timestamp-content-wrapper message)}
content]]] content]]]
[react/view style/delivery-status [react/view style/delivery-status
[message-delivery-status message]]]) [message-delivery-status message]]])
@ -327,11 +327,11 @@
(let [to-value @to-value] (let [to-value @to-value]
(when (pos? to-value) (when (pos? to-value)
(animation/start (animation/start
(animation/timing val {:toValue to-value (animation/timing val {:toValue to-value
:duration 250}) :duration 250})
(fn [arg] (fn [arg]
(when (.-finished arg) (when (.-finished arg)
(callback)))))))) (callback))))))))
(defn message-container [message & children] (defn message-container [message & children]
(if (:appearing? message) (if (:appearing? message)
@ -343,28 +343,28 @@
:callback anim-callback} :callback anim-callback}
on-update (message-container-animation-logic context)] on-update (message-container-animation-logic context)]
(reagent/create-class (reagent/create-class
{:component-did-update {:component-did-update
on-update on-update
:display-name :display-name
"message-container" "message-container"
:reagent-render :reagent-render
(fn [_ & children] (fn [_ & children]
@layout-height @layout-height
[react/animated-view {:style (style/message-animated-container anim-value)} [react/animated-view {:style (style/message-animated-container anim-value)}
(into [react/view {:style (style/message-container window-width) (into [react/view {:style (style/message-container window-width)
:onLayout (fn [event] :onLayout (fn [event]
(let [height (.. event -nativeEvent -layout -height)] (let [height (.. event -nativeEvent -layout -height)]
(reset! layout-height height)))}] (reset! layout-height height)))}]
children)])})) children)])}))
(into [react/view] children))) (into [react/view] children)))
(defn chat-message [{:keys [outgoing group-chat current-public-key content-type content] :as message}] (defn chat-message [{:keys [outgoing group-chat current-public-key content-type content] :as message}]
[message-container message [message-container message
[react/touchable-highlight {:on-press (fn [_] [react/touchable-highlight {:on-press (fn [_]
(re-frame/dispatch [:set-chat-ui-props {:messages-focused? true}]) (re-frame/dispatch [:set-chat-ui-props {:messages-focused? true}])
(react/dismiss-keyboard!)) (react/dismiss-keyboard!))
:on-long-press #(when (= content-type constants/text-content-type) :on-long-press #(when (= content-type constants/text-content-type)
(list-selection/share content (i18n/label :t/message)))} (list-selection/share content (i18n/label :t/message)))}
[react/view {:accessibility-label :chat-item} [react/view {:accessibility-label :chat-item}
(let [incoming-group (and group-chat (not outgoing))] (let [incoming-group (and group-chat (not outgoing))]
[message-content message-body (merge message [message-content message-body (merge message

View File

@ -26,19 +26,19 @@
(defn view [] (defn view []
(let [{:keys [chat-id message-id]} @(re-frame/subscribe [:get-current-chat-ui-prop :message-options]) (let [{:keys [chat-id message-id]} @(re-frame/subscribe [:get-current-chat-ui-prop :message-options])
close-message-options-fn #(re-frame/dispatch [:set-chat-ui-props {:show-message-options? false}])] close-message-options-fn #(re-frame/dispatch [:set-chat-ui-props {:show-message-options? false}])]
[bottom-info/overlay {:on-click-outside close-message-options-fn} [bottom-info/overlay {:on-click-outside close-message-options-fn}
[bottom-info/container (* styles/item-height 2) [bottom-info/container (* styles/item-height 2)
[react/view [react/view
[react/view options.styles/title [react/view options.styles/title
[react/text {:style options.styles/title-text} (i18n/label :message-not-sent)]] [react/text {:style options.styles/title-text} (i18n/label :message-not-sent)]]
[action-item {:label :resend-message [action-item {:label :resend-message
:icon :icons/refresh :icon :icons/refresh
:on-press #(do :on-press #(do
(close-message-options-fn) (close-message-options-fn)
(re-frame/dispatch [:resend-message chat-id message-id]))}] (re-frame/dispatch [:resend-message chat-id message-id]))}]
[action-item {:label :delete-message [action-item {:label :delete-message
:icon :icons/delete :icon :icons/delete
:style {:color colors/red} :style {:color colors/red}
:on-press #(do :on-press #(do
(close-message-options-fn) (close-message-options-fn)
(re-frame/dispatch [:delete-message chat-id message-id]))}]]]])) (re-frame/dispatch [:delete-message chat-id message-id]))}]]]]))

View File

@ -25,23 +25,23 @@
(defn button-animation [val to-value loop? answered?] (defn button-animation [val to-value loop? answered?]
(anim/anim-sequence (anim/anim-sequence
[(anim/anim-delay [(anim/anim-delay
(if (and @loop? (not @answered?)) (if (and @loop? (not @answered?))
request-message-icon-scale-delay request-message-icon-scale-delay
0)) 0))
(anim/spring val {:toValue to-value (anim/spring val {:toValue to-value
:useNativeDriver true})])) :useNativeDriver true})]))
(defn request-button-animation-logic (defn request-button-animation-logic
[{:keys [to-value val loop? answered?] :as context}] [{:keys [to-value val loop? answered?] :as context}]
(anim/start (anim/start
(button-animation val to-value loop? answered?) (button-animation val to-value loop? answered?)
#(if (and @loop? (not @answered?)) #(if (and @loop? (not @answered?))
(let [new-value (if (= to-value min-scale) max-scale min-scale) (let [new-value (if (= to-value min-scale) max-scale min-scale)
context' (assoc context :to-value new-value)] context' (assoc context :to-value new-value)]
(request-button-animation-logic context')) (request-button-animation-logic context'))
(anim/start (anim/start
(button-animation val min-scale loop? answered?))))) (button-animation val min-scale loop? answered?)))))
(defn request-button-label (defn request-button-label
"The request button label will be in the form of `request-the-command-name`" "The request button label will be in the form of `request-the-command-name`"
@ -57,29 +57,29 @@
:answered? answered? :answered? answered?
:loop? loop?}] :loop? loop?}]
(r/create-class (r/create-class
{:display-name "request-button" {:display-name "request-button"
:component-did-mount :component-did-mount
(if @answered? (fn []) #(request-button-animation-logic context)) (if @answered? (fn []) #(request-button-animation-logic context))
:component-will-unmount :component-will-unmount
#(reset! loop? false) #(reset! loop? false)
:reagent-render :reagent-render
(fn [message-id {command-icon :icon :as command} on-press-handler] (fn [message-id {command-icon :icon :as command} on-press-handler]
(when command (when command
[touchable-highlight [touchable-highlight
{:on-press on-press-handler {:on-press on-press-handler
:style (st/command-request-image-touchable) :style (st/command-request-image-touchable)
:accessibility-label (request-button-label (:name command))} :accessibility-label (request-button-label (:name command))}
[animated-view {:style (st/command-request-image-view command scale-anim-val)} [animated-view {:style (st/command-request-image-view command scale-anim-val)}
(when command-icon (when command-icon
[icon command-icon st/command-request-image])]]))}))) [icon command-icon st/command-request-image])]]))})))
(defview message-content-command-request (defview message-content-command-request
[{:keys [message-id content] :as message}] [{:keys [message-id content] :as message}]
(letsubs [command [:get-command (:request-command-ref content)] (letsubs [command [:get-command (:request-command-ref content)]
answered? [:is-request-answered? message-id] answered? [:is-request-answered? message-id]
status-initialized? [:get :status-module-initialized?]] status-initialized? [:get :status-module-initialized?]]
(let [{:keys [prefill prefill-bot-db prefillBotDb params preview] (let [{:keys [prefill prefill-bot-db prefillBotDb params preview]
text-content :text} content text-content :text} content
command (if (and params command) command (if (and params command)
(merge command {:prefill prefill (merge command {:prefill prefill
:prefill-bot-db (or prefill-bot-db prefillBotDb)}) :prefill-bot-db (or prefill-bot-db prefillBotDb)})
@ -92,7 +92,7 @@
[touchable-highlight [touchable-highlight
{:on-press on-press-handler} {:on-press on-press-handler}
[view st/command-request-message-view [view st/command-request-message-view
(if (:markup preview) (if (:markup preview)
[view (commands-utils/generate-hiccup (:markup preview))] [view (commands-utils/generate-hiccup (:markup preview))]
[text {:style st/style-message-text [text {:style st/style-message-text
:font :default} :font :default}