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 spacing-char " ")
(def arg-wrapping-char "\"")
(def arg-wrapping-char "\"")
(def input-height 56)
(def input-spacing-top 16)

View File

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

View File

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

View File

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

View File

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

View File

@ -11,72 +11,72 @@
;;;; Handlers
(handlers/register-handler-fx
::received-message
message-model/receive-interceptors
(fn [cofx [message]]
(message-model/receive message cofx)))
::received-message
message-model/receive-interceptors
(fn [cofx [message]]
(message-model/receive message cofx)))
(handlers/register-handler-fx
:chat-received-message/add
message-model/receive-interceptors
(fn [{:keys [db] :as cofx} [{:keys [content] :as message}]]
(when (message-model/add-to-chat? cofx message)
(if (:command content)
:chat-received-message/add
message-model/receive-interceptors
(fn [{:keys [db] :as cofx} [{:keys [content] :as message}]]
(when (message-model/add-to-chat? cofx message)
(if (:command content)
;; 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.
;; note that `request-command-message-data` implicitly wait till jail is ready and
;; calls are made only after that
(commands-events/request-command-message-data
db message
{:data-type :short-preview
:proceed-event-creator (fn [short-preview]
[:request-command-message-data
message
{:data-type :preview
:proceed-event-creator (fn [preview]
[::received-message
(update message :content merge
{:short-preview short-preview
:preview preview})])}])})
(commands-events/request-command-message-data
db message
{:data-type :short-preview
:proceed-event-creator (fn [short-preview]
[:request-command-message-data
message
{:data-type :preview
:proceed-event-creator (fn [preview]
[::received-message
(update message :content merge
{:short-preview short-preview
:preview preview})])}])})
;; 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
(handlers/register-handler-fx
:chat-received-message/bot-response
(fn [{:contacts/keys [contacts]} [_ {:keys [chat-id] :as params} {:keys [result bot-id] :as data}]]
(let [{:keys [returned context]} result
{:keys [markup text-message err]} returned
{:keys [log-messages update-db default-db]} context
content (or err text-message)]
(when update-db
(re-frame/dispatch [:update-bot-db {:bot bot-id
:db update-db}]))
(re-frame/dispatch [:suggestions-handler (assoc params
:bot-id bot-id
:result data
:default-db default-db)])
(doseq [message log-messages]
(let [{:keys [message type]} message]
(when (or (not= type "debug")
js/goog.DEBUG
(get-in contacts [chat-id :debug?]))
(re-frame/dispatch [:chat-received-message/add
{:message-id (random/id)
:content (str type ": " message)
:content-type constants/content-type-log-message
:outgoing false
:clock-value (utils.clocks/send 0)
:chat-id chat-id
:from chat-id
:to "me"}]))))
(when content
(re-frame/dispatch [:chat-received-message/add
{:message-id (random/id)
:content (str content)
:content-type constants/text-content-type
:outgoing false
:clock-value (utils.clocks/send 0)
:chat-id chat-id
:from chat-id
:to "me"}])))))
:chat-received-message/bot-response
(fn [{:contacts/keys [contacts]} [_ {:keys [chat-id] :as params} {:keys [result bot-id] :as data}]]
(let [{:keys [returned context]} result
{:keys [markup text-message err]} returned
{:keys [log-messages update-db default-db]} context
content (or err text-message)]
(when update-db
(re-frame/dispatch [:update-bot-db {:bot bot-id
:db update-db}]))
(re-frame/dispatch [:suggestions-handler (assoc params
:bot-id bot-id
:result data
:default-db default-db)])
(doseq [message log-messages]
(let [{:keys [message type]} message]
(when (or (not= type "debug")
js/goog.DEBUG
(get-in contacts [chat-id :debug?]))
(re-frame/dispatch [:chat-received-message/add
{:message-id (random/id)
:content (str type ": " message)
:content-type constants/content-type-log-message
:outgoing false
:clock-value (utils.clocks/send 0)
:chat-id chat-id
:from chat-id
:to "me"}]))))
(when content
(re-frame/dispatch [:chat-received-message/add
{:message-id (random/id)
:content (str content)
:content-type constants/text-content-type
:outgoing false
:clock-value (utils.clocks/send 0)
:chat-id chat-id
:from chat-id
:to "me"}])))))

View File

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

View File

@ -28,9 +28,9 @@
"Upsert chat when not deleted"
[{:keys [chat-id] :as chat-props} {:keys [db] :as cofx}]
(let [chat (merge
(or (get (:chats db) chat-id)
(create-new-chat chat-id cofx))
chat-props)]
(or (get (:chats db) chat-id)
(create-new-chat chat-id cofx))
chat-props)]
(if (:is-active 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]}]
(let [prepared-message (prepare-message message chat-id current-chat?)]
{:db (cond->
(-> db
(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
(-> db
(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
(not current-chat?)
(update-in [:chats chat-id :unviewed-messages] (fnil conj #{}) message-id))
:data-store/save-message prepared-message}))
@ -55,7 +55,6 @@
(when send-seen?
(transport/send (protocol/map->MessagesSeen {:message-ids #{message-id}}) chat-id cofx)))
(defn- add-received-message
[{:keys [from message-id chat-id content content-type timestamp clock-value to-clock-value] :as message}
{:keys [db now] :as cofx}]
@ -72,35 +71,35 @@
request-command)
new-timestamp (or timestamp now)]
(handlers-macro/merge-fx cofx
(add-message chat-id
(cond-> (assoc message
:timestamp new-timestamp
:show? true)
public-key
(assoc :user-statuses {public-key (if current-chat? :seen :received)})
(add-message chat-id
(cond-> (assoc message
:timestamp new-timestamp
:show? true)
public-key
(assoc :user-statuses {public-key (if current-chat? :seen :received)})
(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
command-request?
(assoc-in [:content :request-command-ref]
(lookup-response-ref access-scope->commands-responses
current-account chat contacts request-command)))
current-chat?)
(send-message-seen chat-id message-id (and public-key
(not public?)
current-chat?
(not (chat-model/bot-only-chat? db chat-id))
(not (= constants/system from)))))))
(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
command-request?
(assoc-in [:content :request-command-ref]
(lookup-response-ref access-scope->commands-responses
current-account chat contacts request-command)))
current-chat?)
(send-message-seen chat-id message-id (and public-key
(not public?)
current-chat?
(not (chat-model/bot-only-chat? db chat-id))
(not (= constants/system from)))))))
(defn receive
[{:keys [chat-id message-id] :as message} {:keys [now] :as 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
:is-active true
:timestamp now})
(add-received-message message)
(requests-events/add-request chat-id message-id)))
:is-active true
:timestamp now})
(add-received-message message)
(requests-events/add-request chat-id message-id)))
(defn system-message [chat-id message-id timestamp content]
{:message-id message-id
@ -213,10 +212,10 @@
message-id (transport.utils/message-id send-record)
message-with-id (assoc message :message-id message-id)]
(handlers-macro/merge-fx cofx
(chat-model/upsert-chat {:chat-id chat-id
:timestamp now})
(add-message chat-id message-with-id true)
(send chat-id message-id send-record))))
(chat-model/upsert-chat {:chat-id chat-id
:timestamp now})
(add-message chat-id message-with-id true)
(send chat-id message-id send-record))))
(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)]
@ -291,9 +290,9 @@
chat (or (get chats chat-id) {:chat-id chat-id})
request (:request handler-data)]
(handlers-macro/merge-fx cofx
(upsert-and-send (prepare-command-message current-public-key chat now request content))
(add-console-responses command handler-data)
(requests-events/request-answered chat-id to-message))))
(upsert-and-send (prepare-command-message current-public-key chat now request content))
(add-console-responses command handler-data)
(requests-events/request-answered chat-id to-message))))
(defn invoke-console-command-handler
[{:keys [db] :as cofx} {:keys [command] :as command-params}]

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -26,19 +26,19 @@
(defn view []
(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}])]
[bottom-info/overlay {:on-click-outside close-message-options-fn}
[bottom-info/container (* styles/item-height 2)
[react/view
[react/view options.styles/title
[react/text {:style options.styles/title-text} (i18n/label :message-not-sent)]]
[action-item {:label :resend-message
:icon :icons/refresh
:on-press #(do
(close-message-options-fn)
(re-frame/dispatch [:resend-message chat-id message-id]))}]
[action-item {:label :delete-message
:icon :icons/delete
:style {:color colors/red}
:on-press #(do
(close-message-options-fn)
(re-frame/dispatch [:delete-message chat-id message-id]))}]]]]))
[bottom-info/overlay {:on-click-outside close-message-options-fn}
[bottom-info/container (* styles/item-height 2)
[react/view
[react/view options.styles/title
[react/text {:style options.styles/title-text} (i18n/label :message-not-sent)]]
[action-item {:label :resend-message
:icon :icons/refresh
:on-press #(do
(close-message-options-fn)
(re-frame/dispatch [:resend-message chat-id message-id]))}]
[action-item {:label :delete-message
:icon :icons/delete
:style {:color colors/red}
:on-press #(do
(close-message-options-fn)
(re-frame/dispatch [:delete-message chat-id message-id]))}]]]]))

View File

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