From 412b162226496b049b22c2ab42717b37b9899239 Mon Sep 17 00:00:00 2001 From: Roman Volosovskyi Date: Wed, 24 Apr 2019 22:32:06 +0300 Subject: [PATCH] Allow to fetch more history in chats (up to 30 days) --- src/status_im/chat/db.cljs | 36 ++++++++++++++++-------- src/status_im/chat/subs.cljs | 21 ++++++++++++-- src/status_im/events.cljs | 18 ++++++++++++ src/status_im/ui/screens/chat/views.cljs | 21 +++++++++----- 4 files changed, 76 insertions(+), 20 deletions(-) diff --git a/src/status_im/chat/db.cljs b/src/status_im/chat/db.cljs index d8d6c4f8c8a2..dec843443958 100644 --- a/src/status_im/chat/db.cljs +++ b/src/status_im/chat/db.cljs @@ -6,7 +6,8 @@ [status-im.chat.commands.input :as commands.input] [status-im.group-chats.db :as group-chats.db] [status-im.utils.gfycat.core :as gfycat] - [status-im.transport.partitioned-topic :as topic])) + [status-im.transport.partitioned-topic :as topic] + [status-im.mailserver.core :as mailserver])) (defn group-chat-name [{:keys [public? name]}] @@ -86,10 +87,14 @@ (defn datemark? [{:keys [type]}] (= type :datemark)) +(defn gap? [{:keys [type]}] + (= type :gap)) + (defn transform-message [messages message-statuses referenced-messages] (fn [{:keys [message-id timestamp-str] :as reference}] - (if (datemark? reference) + (if (or (datemark? reference) + (gap? reference)) reference (let [{:keys [content] :as message} (get messages message-id) {:keys [response-to response-to-v2]} content @@ -141,18 +146,30 @@ (defn messages-with-datemarks-and-statuses "Converts message groups into sequence of messages interspersed with datemarks, with correct user statuses associated into message" - [message-groups messages message-statuses referenced-messages messages-gaps] + [message-groups messages message-statuses referenced-messages messages-gaps + {:keys [highest-request-to lowest-request-from]} all-loaded?] (transduce (comp (mapcat add-datemark) (map (transform-message messages message-statuses referenced-messages))) - (completing - (fn [{:keys [messages datemark-reference previous-message gaps]} - message] + (fn + ([] + (let [acc {:messages (list) + :previous-message nil + :gaps messages-gaps}] + (if (and + all-loaded? + (< (- highest-request-to lowest-request-from) + mailserver/max-gaps-range)) + (update acc :messages conj {:type :gap + :value (str :first-gap) + :first-gap? true}) + acc))) + ([{:keys [messages datemark-reference previous-message gaps]} message] (let [new-datemark? (datemark? message) {:keys [gaps-number gap]} (check-gap gaps previous-message message) - add-gap? (pos? gaps-number)] + add-gap? (pos? gaps-number)] {:messages (cond-> messages add-gap? @@ -172,13 +189,10 @@ :gaps (if add-gap? (drop gaps-number gaps) gaps)})) - (fn [{:keys [messages gaps]}] + ([{:keys [messages gaps]}] (cond-> messages (seq gaps) (add-gap {:ids (map :id gaps)})))) - {:messages (list) - :previous-message nil - :gaps messages-gaps} message-groups)) (defn- set-previous-message-info [stream] diff --git a/src/status_im/chat/subs.cljs b/src/status_im/chat/subs.cljs index d286b8842e19..c746fe3c99f9 100644 --- a/src/status_im/chat/subs.cljs +++ b/src/status_im/chat/subs.cljs @@ -178,6 +178,19 @@ (fn [[gaps chat-id]] (sort-by :from (vals (get gaps chat-id))))) +(re-frame/reg-sub + :chats/range + :<- [:get-in [:mailserver/ranges]] + :<- [:chats/current-chat-id] + (fn [[ranges chat-id]] + (get ranges chat-id))) + +(re-frame/reg-sub + :chats/all-loaded? + :<- [:chats/current-chat] + (fn [chat] + (:all-loaded? chat))) + (re-frame/reg-sub :chats/current-chat-messages-stream :<- [:chats/current-chat-messages] @@ -185,9 +198,13 @@ :<- [:chats/current-chat-message-statuses] :<- [:chats/current-chat-referenced-messages] :<- [:chats/messages-gaps] - (fn [[messages message-groups message-statuses referenced-messages messages-gaps]] + :<- [:chats/range] + :<- [:chats/all-loaded?] + (fn [[messages message-groups message-statuses referenced-messages + messages-gaps range all-loaded?]] (-> (chat.db/sort-message-groups message-groups messages) - (chat.db/messages-with-datemarks-and-statuses messages message-statuses referenced-messages messages-gaps) + (chat.db/messages-with-datemarks-and-statuses + messages message-statuses referenced-messages messages-gaps range all-loaded?) chat.db/messages-stream))) (re-frame/reg-sub diff --git a/src/status_im/events.cljs b/src/status_im/events.cljs index 4c5f0b07fa2e..2b5900e5f028 100644 --- a/src/status_im/events.cljs +++ b/src/status_im/events.cljs @@ -758,6 +758,24 @@ :topic topic :chat-id chat-id})))) +(handlers/register-handler-fx + :chat.ui/fetch-more + (fn [{:keys [db] :as cofx}] + (let [chat-id (:current-chat-id db) + + {:keys [lowest-request-from]} + (get-in db [:mailserver/ranges chat-id]) + + topic (chat.db/topic-by-current-chat db) + gaps [{:id :first-gap + :to lowest-request-from + :from (- lowest-request-from mailserver/one-day)}]] + (mailserver/fill-the-gap + cofx + {:gaps gaps + :topic topic + :chat-id chat-id})))) + (handlers/register-handler-fx :chat.ui/remove-chat-pressed (fn [_ [_ chat-id]] diff --git a/src/status_im/ui/screens/chat/views.cljs b/src/status_im/ui/screens/chat/views.cljs index 211ff091cbd8..a602e22a62eb 100644 --- a/src/status_im/ui/screens/chat/views.cljs +++ b/src/status_im/ui/screens/chat/views.cljs @@ -71,7 +71,7 @@ [message-datemark/chat-datemark-mobile value]) (defview gap - [ids idx list-ref in-progress? connected?] + [ids idx list-ref in-progress? connected? first-gap?] [react/view {:align-self :stretch :margin-top 24 :margin-bottom 24 @@ -89,7 +89,9 @@ (.scrollToIndex @list-ref #js {:index (max 0 (dec idx)) :viewOffset 20 :viewPosition 0.5})) - (re-frame/dispatch [:chat.ui/fill-gaps ids])))} + (if first-gap? + (re-frame/dispatch [:chat.ui/fetch-more]) + (re-frame/dispatch [:chat.ui/fill-gaps ids]))))} [react/view {:flex 1 :align-items :center :justify-content :center} @@ -99,16 +101,21 @@ {:style {:color (if connected? colors/blue colors/gray)}} - (i18n/label :t/fetch-messages)])]]]) + (if first-gap? + "Load more messages" + (i18n/label :t/fetch-messages))])]]]) -(defview gap-wrapper [{:keys [ids]} idx list-ref] - (letsubs [in-progress? [:chats/fetching-gap-in-progress? ids] +(defview gap-wrapper [{:keys [gaps first-gap?]} idx list-ref] + (letsubs [in-progress? [:chats/fetching-gap-in-progress? + (if first-gap? + [:first-gap] + (:ids gaps))] connected? [:mailserver/connected?]] - [gap ids idx list-ref in-progress? connected?])) + [gap (:ids gaps) idx list-ref in-progress? connected? first-gap?])) (defmethod message-row :gap [{:keys [row idx list-ref]}] - [gap-wrapper (:gaps row) idx list-ref]) + [gap-wrapper row idx list-ref]) (defmethod message-row :default [{:keys [group-chat current-public-key modal? row]}]