[Fixes: #10801] Send chat messages in order
Chat messages are now sent in order using a different endpoint `sendChatMessages`. Text should always be displayed after images. This is not implementing a Caption field, that would require either a protocol change or leverage the `text` in the message. It applies for both normal chats and timelines. Move also all inputs under `chat/inputs` so we avoid re-renders as `chats` has changed. Signed-off-by: Andrea Maria Piana <andrea.maria.piana@gmail.com>
This commit is contained in:
parent
fd5be21207
commit
f04042c643
|
@ -99,7 +99,7 @@
|
|||
{:events [:chat.ui/image-captured]}
|
||||
[{:keys [db]} uri]
|
||||
(let [current-chat-id (:current-chat-id db)
|
||||
images (get-in db [:chats current-chat-id :metadata :sending-image])]
|
||||
images (get-in db [:chat/inputs current-chat-id :metadata :sending-image])]
|
||||
(when (and (< (count images) config/max-images-batch)
|
||||
(not (get images uri)))
|
||||
{::image-selected uri})))
|
||||
|
@ -118,7 +118,7 @@
|
|||
{:events [:chat.ui/clear-sending-images]}
|
||||
[{:keys [db]}]
|
||||
(let [current-chat-id (:current-chat-id db)]
|
||||
{:db (update-in db [:chats current-chat-id :metadata] assoc :sending-image {})}))
|
||||
{:db (update-in db [:chat/inputs current-chat-id :metadata] assoc :sending-image {})}))
|
||||
|
||||
(fx/defn cancel-sending-image
|
||||
{:events [:chat.ui/cancel-sending-image]}
|
||||
|
@ -129,19 +129,19 @@
|
|||
{:events [:chat.ui/image-selected]}
|
||||
[{:keys [db]} original uri]
|
||||
(let [current-chat-id (:current-chat-id db)]
|
||||
{:db (update-in db [:chats current-chat-id :metadata :sending-image original] merge {:uri uri})}))
|
||||
{:db (update-in db [:chat/inputs current-chat-id :metadata :sending-image original] merge {:uri uri})}))
|
||||
|
||||
(fx/defn image-unselected
|
||||
{:events [:chat.ui/image-unselected]}
|
||||
[{:keys [db]} original]
|
||||
(let [current-chat-id (:current-chat-id db)]
|
||||
{:db (update-in db [:chats current-chat-id :metadata :sending-image] dissoc original)}))
|
||||
{:db (update-in db [:chat/inputs current-chat-id :metadata :sending-image] dissoc original)}))
|
||||
|
||||
(fx/defn chat-open-image-picker
|
||||
{:events [:chat.ui/open-image-picker]}
|
||||
[{:keys [db]}]
|
||||
(let [current-chat-id (:current-chat-id db)
|
||||
images (get-in db [:chats current-chat-id :metadata :sending-image])]
|
||||
images (get-in db [:chat/inputs current-chat-id :metadata :sending-image])]
|
||||
(when (< (count images) config/max-images-batch)
|
||||
{::chat-open-image-picker nil})))
|
||||
|
||||
|
@ -149,7 +149,7 @@
|
|||
{:events [:chat.ui/show-image-picker-camera]}
|
||||
[{:keys [db]}]
|
||||
(let [current-chat-id (:current-chat-id db)
|
||||
images (get-in db [:chats current-chat-id :metadata :sending-image])]
|
||||
images (get-in db [:chat/inputs current-chat-id :metadata :sending-image])]
|
||||
(when (< (count images) config/max-images-batch)
|
||||
{::chat-open-image-picker-camera nil})))
|
||||
|
||||
|
@ -157,9 +157,9 @@
|
|||
{:events [:chat.ui/camera-roll-pick]}
|
||||
[{:keys [db]} uri]
|
||||
(let [current-chat-id (:current-chat-id db)
|
||||
images (get-in db [:chats current-chat-id :metadata :sending-image])]
|
||||
images (get-in db [:chat/inputs current-chat-id :metadata :sending-image])]
|
||||
(if (get-in db [:chats current-chat-id :timeline?])
|
||||
{:db (assoc-in db [:chats current-chat-id :metadata :sending-image] {})
|
||||
{:db (assoc-in db [:chat/inputs current-chat-id :metadata :sending-image] {})
|
||||
::image-selected uri}
|
||||
(when (and (< (count images) config/max-images-batch)
|
||||
(not (get images uri)))
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
;; keyboard's cursor position to be changed before the next input.
|
||||
(mentions/reset-text-input-cursor text-input-ref cursor)
|
||||
;; NOTE(roman): on-text-input event is not dispatched when we change input
|
||||
;; programmatically, so we have to call `on-text-input` manually
|
||||
;; programmatically, so we have to call `on-text-input` manually
|
||||
(mentions/on-text-input
|
||||
(let [match-len (count match)
|
||||
searched-text-len (count searched-text)
|
||||
|
@ -99,51 +99,60 @@
|
|||
(let [current-chat-id (:current-chat-id db)]
|
||||
(fx/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:chats current-chat-id :metadata :responding-to-message]
|
||||
(assoc-in [:chat/inputs current-chat-id :metadata :responding-to-message]
|
||||
message)
|
||||
(update-in [:chats current-chat-id :metadata]
|
||||
(update-in [:chat/inputs current-chat-id :metadata]
|
||||
dissoc :sending-image))})))
|
||||
|
||||
(fx/defn cancel-message-reply
|
||||
"Cancels stage message reply"
|
||||
[{:keys [db]}]
|
||||
(let [current-chat-id (:current-chat-id db)]
|
||||
{:db (assoc-in db [:chats current-chat-id :metadata :responding-to-message] nil)}))
|
||||
{:db (assoc-in db [:chat/inputs current-chat-id :metadata :responding-to-message] nil)}))
|
||||
|
||||
(fx/defn send-plain-text-message
|
||||
"when not empty, proceed by sending text message"
|
||||
[{:keys [db] :as cofx} input-text current-chat-id]
|
||||
(defn build-text-message
|
||||
[{:keys [db]} input-text current-chat-id]
|
||||
(when-not (string/blank? input-text)
|
||||
(let [{:keys [message-id]}
|
||||
(get-in db [:chats current-chat-id :metadata :responding-to-message])
|
||||
(get-in db [:chat/inputs current-chat-id :metadata :responding-to-message])
|
||||
preferred-name (get-in db [:multiaccount :preferred-name])
|
||||
emoji? (message-content/emoji-only-content? {:text input-text
|
||||
:response-to message-id})]
|
||||
(fx/merge cofx
|
||||
{:db (assoc-in db [:chats current-chat-id :metadata :responding-to-message] nil)}
|
||||
(chat.message/send-message {:chat-id current-chat-id
|
||||
:content-type (if emoji?
|
||||
constants/content-type-emoji
|
||||
constants/content-type-text)
|
||||
:text input-text
|
||||
:response-to message-id
|
||||
:ens-name preferred-name})
|
||||
(set-chat-input-text nil)
|
||||
(process-cooldown)))))
|
||||
{:chat-id current-chat-id
|
||||
:content-type (if emoji?
|
||||
constants/content-type-emoji
|
||||
constants/content-type-text)
|
||||
:text input-text
|
||||
:response-to message-id
|
||||
:ens-name preferred-name})))
|
||||
|
||||
(fx/defn send-image
|
||||
[{{:keys [current-chat-id] :as db} :db :as cofx} chat-id]
|
||||
(let [images (get-in db [:chats current-chat-id :metadata :sending-image])]
|
||||
(defn build-image-messages
|
||||
[{{:keys [current-chat-id] :as db} :db} chat-id]
|
||||
(let [images (get-in db [:chat/inputs current-chat-id :metadata :sending-image])]
|
||||
(mapv (fn [[_ {:keys [uri]}]]
|
||||
{:chat-id chat-id
|
||||
:content-type constants/content-type-image
|
||||
:image-path (utils/safe-replace uri #"file://" "")
|
||||
:text (i18n/label :t/update-to-see-image)})
|
||||
images)))
|
||||
|
||||
(fx/defn clean-input [{:keys [db] :as cofx}]
|
||||
(let [current-chat-id (:current-chat-id db)]
|
||||
(fx/merge cofx
|
||||
;; NOTE(Ferossgp): Ideally here and for all other types of message we should dissoc on success only
|
||||
{:db (update-in db [:chats current-chat-id :metadata] dissoc :sending-image)}
|
||||
(chat.message/send-messages
|
||||
(map (fn [[_ {:keys [uri]}]]
|
||||
{:chat-id chat-id
|
||||
:content-type constants/content-type-image
|
||||
:image-path (utils/safe-replace uri #"file://" "")
|
||||
:text (i18n/label :t/update-to-see-image)})
|
||||
images)))))
|
||||
{:db (-> db
|
||||
(assoc-in [:chat/inputs current-chat-id :metadata :sending-image] nil)
|
||||
(assoc-in [:chat/inputs current-chat-id :metadata :responding-to-message] nil))}
|
||||
(set-chat-input-text nil))))
|
||||
|
||||
(fx/defn send-messages [{:keys [db] :as cofx} input-text current-chat-id]
|
||||
(let [image-messages (build-image-messages cofx current-chat-id)
|
||||
text-message (build-text-message cofx input-text current-chat-id)
|
||||
messages (keep identity (conj image-messages text-message))]
|
||||
(when (seq messages)
|
||||
(fx/merge cofx
|
||||
(clean-input cofx)
|
||||
(process-cooldown)
|
||||
(chat.message/send-messages messages)))))
|
||||
|
||||
(fx/defn send-my-status-message
|
||||
"when not empty, proceed by sending text message with public key topic"
|
||||
|
@ -151,9 +160,7 @@
|
|||
[{{:keys [current-chat-id] :as db} :db :as cofx}]
|
||||
(let [{:keys [input-text]} (get-in db [:chat/inputs current-chat-id])
|
||||
chat-id (chat/profile-chat-topic (get-in db [:multiaccount :public-key]))]
|
||||
(fx/merge cofx
|
||||
(send-image chat-id)
|
||||
(send-plain-text-message input-text chat-id))))
|
||||
(send-messages cofx input-text chat-id)))
|
||||
|
||||
(fx/defn send-audio-message
|
||||
[cofx audio-path duration current-chat-id]
|
||||
|
@ -179,7 +186,6 @@
|
|||
(let [{:keys [input-text]} (get-in db [:chat/inputs current-chat-id])
|
||||
input-text-with-mentions (mentions/check-mentions cofx input-text)]
|
||||
(fx/merge cofx
|
||||
(send-image current-chat-id)
|
||||
(send-plain-text-message input-text-with-mentions current-chat-id)
|
||||
(send-messages input-text-with-mentions current-chat-id)
|
||||
(mentions/clear-mentions)
|
||||
(mentions/clear-cursor))))
|
||||
|
|
|
@ -43,16 +43,17 @@
|
|||
(let [last-element-clock-value (:clock-value (.-item last-element))
|
||||
chat-id (:chat-id (.-item last-element))]
|
||||
(when (and last-element-clock-value
|
||||
(get-in db [:chats chat-id :messages-initialized?]))
|
||||
(get-in db [:pagination-info chat-id :messages-initialized?]))
|
||||
(let [new-messages (reduce-kv (fn [acc message-id {:keys [clock-value] :as v}]
|
||||
(if (<= last-element-clock-value clock-value)
|
||||
(assoc acc message-id v)
|
||||
acc))
|
||||
{}
|
||||
(get-in db [:chats chat-id :messages]))]
|
||||
(get-in db [:messages chat-id]))]
|
||||
{:db (-> db
|
||||
(assoc-in [:messages chat-id] new-messages)
|
||||
(assoc-in [:pagination-info chat-id] {:all-loaded? false
|
||||
:messages-initialized? true
|
||||
:cursor (clock-value->cursor last-element-clock-value)})
|
||||
(assoc-in [:message-lists chat-id] (message-list/add-many nil (vals new-messages))))}))))))
|
||||
|
||||
|
|
|
@ -505,7 +505,7 @@
|
|||
[:chats chat-id :mentions]
|
||||
assoc
|
||||
:at-idxs new-at-idxs)
|
||||
(assoc-in [:chats/input-with-mentions chat-id] calculated-input))}))
|
||||
(assoc-in [:chat/inputs-with-mentions chat-id] calculated-input))}))
|
||||
|
||||
(fx/defn calculate-suggestions
|
||||
{:events [::calculate-suggestions]}
|
||||
|
@ -521,7 +521,7 @@
|
|||
{:db (-> db
|
||||
(assoc-in [:chats/mention-suggestions chat-id] nil)
|
||||
(assoc-in [:chats chat-id :mentions :at-idxs] nil)
|
||||
(assoc-in [:chats/input-with-mentions chat-id] [[:text text]]))}
|
||||
(assoc-in [:chat/inputs-with-mentions chat-id] [[:text text]]))}
|
||||
(let [new-at-idxs (check-idx-for-mentions
|
||||
text
|
||||
at-idxs
|
||||
|
@ -551,7 +551,7 @@
|
|||
:at-sign-idx at-sign-idx
|
||||
:at-idxs new-at-idxs
|
||||
:mention-end end)
|
||||
(assoc-in [:chats/input-with-mentions chat-id] calculated-input)
|
||||
(assoc-in [:chat/inputs-with-mentions chat-id] calculated-input)
|
||||
(assoc-in [:chats/mention-suggestions chat-id] mentions))}))))
|
||||
|
||||
(defn new-input-text-with-mention
|
||||
|
@ -586,7 +586,7 @@
|
|||
cofx
|
||||
{:db (-> db
|
||||
(update-in [:chats chat-id] dissoc :mentions)
|
||||
(update :chats/input-with-mentions dissoc chat-id))}
|
||||
(update :chat/inputs-with-mentions dissoc chat-id))}
|
||||
(clear-suggestions))))
|
||||
|
||||
(fx/defn clear-cursor
|
||||
|
|
|
@ -164,7 +164,7 @@
|
|||
(fx/merge cofx
|
||||
;;If its a profile updates we want to add this message to the timeline as well
|
||||
#(when (get-in cofx [:db :chats chat-id :profile-public-key])
|
||||
{:dispatch [::receive-one (assoc message :chat-id chat-model/timeline-chat-id)]})
|
||||
{:dispatch-n [[::receive-one (assoc message :chat-id chat-model/timeline-chat-id)]]})
|
||||
#(let [message-with-chat-id (assoc message :chat-id chat-id)]
|
||||
(when-not (earlier-than-deleted-at? cofx message-with-chat-id)
|
||||
(if (message-loaded? cofx message-with-chat-id)
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
"wakuext_enableInstallation" {}
|
||||
"wakuext_disableInstallation" {}
|
||||
"wakuext_sendChatMessage" {}
|
||||
"wakuext_sendChatMessages" {}
|
||||
"wakuext_confirmJoiningGroup" {}
|
||||
"wakuext_addAdminsToGroupChat" {}
|
||||
"wakuext_addMembersToGroupChat" {}
|
||||
|
|
|
@ -124,7 +124,7 @@
|
|||
(reg-root-key-sub :group-chat/invitations :group-chat/invitations)
|
||||
(reg-root-key-sub :chats/mention-suggestions :chats/mention-suggestions)
|
||||
(reg-root-key-sub :chats/cursor :chats/cursor)
|
||||
(reg-root-key-sub :chats/input-with-mentions :chats/input-with-mentions)
|
||||
(reg-root-key-sub :chat/inputs-with-mentions :chat/inputs-with-mentions)
|
||||
(reg-root-key-sub :inactive-chat-id :inactive-chat-id)
|
||||
;;browser
|
||||
(reg-root-key-sub :browsers :browser/browsers)
|
||||
|
@ -651,11 +651,17 @@
|
|||
(get chats current-chat-id)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/current-chat-input-text
|
||||
:chats/current-chat-inputs
|
||||
:<- [:chats/current-chat-id]
|
||||
:<- [:chat/inputs]
|
||||
(fn [[chat-id inputs]]
|
||||
(get-in inputs [chat-id :input-text])))
|
||||
(get inputs chat-id)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/current-chat-input-text
|
||||
:<- [:chats/current-chat-inputs]
|
||||
(fn [input]
|
||||
(:input-text input)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/current-chat-membership
|
||||
|
@ -835,15 +841,15 @@
|
|||
|
||||
(re-frame/reg-sub
|
||||
:chats/reply-message
|
||||
:<- [:chats/current-chat]
|
||||
:<- [:chats/current-chat-inputs]
|
||||
(fn [{:keys [metadata]}]
|
||||
(:responding-to-message metadata)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:chats/sending-image
|
||||
:<- [:chats/current-raw-chat]
|
||||
:<- [:chats/current-chat-inputs]
|
||||
(fn [{:keys [metadata]}]
|
||||
(get-in metadata [:sending-image])))
|
||||
(:sending-image metadata)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:public-chat.new/topic-error-message
|
||||
|
@ -977,7 +983,7 @@
|
|||
(re-frame/reg-sub
|
||||
:chat/input-with-mentions
|
||||
:<- [:chats/current-chat-id]
|
||||
:<- [:chats/input-with-mentions]
|
||||
:<- [:chat/inputs-with-mentions]
|
||||
(fn [[chat-id cursor]]
|
||||
(get cursor chat-id)))
|
||||
|
||||
|
|
|
@ -14,22 +14,23 @@
|
|||
audio-duration-ms
|
||||
sticker
|
||||
content-type]}]
|
||||
{:method (json-rpc/call-ext-method "sendChatMessage")
|
||||
:params [{:chatId chat-id
|
||||
:text text
|
||||
:responseTo response-to
|
||||
:ensName ens-name
|
||||
:imagePath image-path
|
||||
:audioPath audio-path
|
||||
:audioDurationMs audio-duration-ms
|
||||
:sticker sticker
|
||||
:contentType content-type}]
|
||||
:on-success
|
||||
#(re-frame/dispatch [:transport/message-sent % 1])
|
||||
:on-failure #(log/error "failed to send a message" %)})
|
||||
{:chatId chat-id
|
||||
:text text
|
||||
:responseTo response-to
|
||||
:ensName ens-name
|
||||
:imagePath image-path
|
||||
:audioPath audio-path
|
||||
:audioDurationMs audio-duration-ms
|
||||
:sticker sticker
|
||||
:contentType content-type})
|
||||
|
||||
(fx/defn send-chat-messages [cofx messages]
|
||||
{::json-rpc/call (mapv build-message messages)})
|
||||
{::json-rpc/call
|
||||
[{:method (json-rpc/call-ext-method "sendChatMessages")
|
||||
:params [(mapv build-message messages)]
|
||||
:on-success
|
||||
#(re-frame/dispatch [:transport/message-sent % 1])
|
||||
:on-failure #(log/error "failed to send a message" %)}]})
|
||||
|
||||
(fx/defn send-reaction [cofx {:keys [message-id chat-id emoji-id]}]
|
||||
{::json-rpc/call [{:method (json-rpc/call-ext-method
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
(def ^:private mergeable-keys
|
||||
#{:filters/load-filters
|
||||
:pairing/set-installation-metadata
|
||||
:dispatch-n
|
||||
:status-im.ens.core/verify-names
|
||||
:shh/send-direct-message
|
||||
:shh/remove-filter
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"_comment": "DO NOT EDIT THIS FILE BY HAND. USE 'scripts/update-status-go.sh <tag>' instead",
|
||||
"owner": "status-im",
|
||||
"repo": "status-go",
|
||||
"version": "v0.64.2",
|
||||
"commit-sha1": "0304b3fa46a6a222b0e346d4a2d1472b965eb78c",
|
||||
"src-sha256": "0jmwvapv1k3g45gv5xzwshsf2b96b897xs5wyp69sdz9p2nnl18z"
|
||||
"version": "v0.64.3",
|
||||
"commit-sha1": "14f4c40404d4d3b1a4e9f739b156f8c8b2eeded6",
|
||||
"src-sha256": "0h1mbn4xb4r7fwniyjgi3hj5bwj8kyj8jfi47l33rg8i6mnvd3w9"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue