refactor: delete message related code (#14548)
This commit is contained in:
parent
c0c0742687
commit
01660765b7
|
@ -17,4 +17,5 @@
|
|||
;; https://github.com/borkdude/clj-kondo/issues/867
|
||||
:unresolved-symbol {:exclude [PersistentPriorityMap.EMPTY
|
||||
number
|
||||
status-im.test-helpers/restore-app-db]}}}
|
||||
status-im.test-helpers/restore-app-db]}}
|
||||
:config-in-ns {mocks.js-dependencies {:linters {:clojure-lsp/unused-public-var {:level :off}}}}}
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
[taoensso.timbre :as log]
|
||||
[status-im.multiaccounts.model :as multiaccounts.model]
|
||||
[status-im.chat.models.message-list :as message-list]
|
||||
[status-im.chat.models.delete-message :as delete-message]
|
||||
[status-im.chat.models.delete-message-for-me :as delete-for-me]
|
||||
[status-im2.contexts.chat.messages.message.delete-message.events :as delete-message]
|
||||
[status-im2.contexts.chat.messages.message.delete-message-for-me.events :as delete-for-me]
|
||||
[status-im.data-store.chats :as chats-store]
|
||||
[status-im.mailserver.core :as mailserver]
|
||||
[status-im.data-store.contacts :as contacts-store]
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
(:require [clojure.string :as string]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.chat.models :as chat-model]
|
||||
[status-im.chat.models.delete-message :as delete-message]
|
||||
[status-im2.contexts.chat.messages.message.delete-message.events :as delete-message]
|
||||
[status-im.chat.models.loading :as chat.loading]
|
||||
[status-im.chat.models.mentions :as mentions]
|
||||
[status-im.chat.models.message-list :as message-list]
|
||||
|
|
|
@ -186,7 +186,7 @@
|
|||
(array-seq (.-values message-list))
|
||||
[]))
|
||||
|
||||
;;TODO this is too expensive, probably we could mark message somehow and just hide it in the UI
|
||||
;; NOTE(performance): this is too expensive, probably we could mark message somehow and just hide it in the UI
|
||||
(fx/defn rebuild-message-list
|
||||
[{:keys [db]} chat-id]
|
||||
{:db (assoc-in db [:message-lists chat-id]
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
[status-im.utils.utils :as utils]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
;; NOTE(19/12/22 yqrashawn) this namespace has been moved to the
|
||||
;; status-im2.common.json-rpc.events namespace,
|
||||
;; we keep this only for old (status 1.0) code, can be removed with old code later
|
||||
(defn on-error-retry
|
||||
[call-method {:keys [method number-of-retries delay on-error] :as arg}]
|
||||
(if (pos? number-of-retries)
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
[re-frame.core :as re-frame]
|
||||
[quo.design-system.colors :as colors]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.utils.handlers :refer [<sub >evt]]
|
||||
[status-im.utils.handlers :refer [<sub]]
|
||||
[status-im.ui.components.chat-icon.screen :as chat-icon]
|
||||
[status-im.multiaccounts.core :as multiaccounts]
|
||||
[status-im.ui.components.icons.icons :as icons]
|
||||
|
@ -14,10 +14,6 @@
|
|||
[status-im.communities.core :as communities]
|
||||
[quo.components.animated.pressable :as animation]))
|
||||
|
||||
(defn hide-sheet-and-dispatch [event]
|
||||
(>evt [:bottom-sheet/hide])
|
||||
(>evt event))
|
||||
|
||||
(defn request-actions [community-id request-id]
|
||||
[react/view {:flex-direction :row}
|
||||
[animation/pressable {:on-press #(re-frame/dispatch [:communities.ui/accept-request-to-join-pressed community-id request-id])}
|
||||
|
|
|
@ -127,19 +127,6 @@
|
|||
:after :main-icons/next}
|
||||
(i18n/label (if creating-backup? :t/next :t/choose-storage))]}]]))
|
||||
|
||||
(defn keycard-subtitle []
|
||||
[react/view
|
||||
[react/text {:style {:color colors/gray}} (i18n/label :t/empty-keycard-required)]
|
||||
[react/view {:flex-direction :row
|
||||
:align-items :center}
|
||||
[react/text {:style {:color colors/blue}
|
||||
:accessibility-label :learn-more
|
||||
:on-press #(js/alert :press)}
|
||||
(i18n/label :learn-more)]
|
||||
[icons/icon :main-icons/tiny-external {:color colors/blue
|
||||
:width 16
|
||||
:height 16}]]])
|
||||
|
||||
(defn keycard-upsell-banner []
|
||||
[react/view {:background-color (if (colors/dark?) "#2C5955" "#DDF8F4")
|
||||
:border-radius 16 :padding-left 12 :padding-right 50 :margin 16}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
[quo.react]
|
||||
["react-native" :as react-native]
|
||||
[status-im.ui.components.react :as react]
|
||||
[status-im.utils.types :as types]
|
||||
[utils.transforms :as transforms]
|
||||
[oops.core :as oops]))
|
||||
|
||||
(defonce input-texts (atom {}))
|
||||
|
@ -322,7 +322,7 @@
|
|||
(reset! selection-event nil))))
|
||||
on-selection (fn [event]
|
||||
(let [native-event (.-nativeEvent event)
|
||||
native-event (types/js->clj native-event)
|
||||
native-event (transforms/js->clj native-event)
|
||||
{:keys [eventType content selectionStart selectionEnd]} native-event
|
||||
full-text (:input-text (<sub [:chats/current-chat-inputs]))]
|
||||
(on-menu-item-touched {:first-level first-level
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
[quo2.foundations.typography :as typography]
|
||||
[re-frame.core :as re-frame]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.chat.models.delete-message]
|
||||
[status-im.chat.models.delete-message-for-me]
|
||||
[status-im2.contexts.chat.messages.message.delete-message.events]
|
||||
[status-im2.contexts.chat.messages.message.delete-message-for-me.events]
|
||||
[status-im.chat.models.images :as images]
|
||||
[status-im.chat.models.reactions :as models.reactions]
|
||||
[status-im.constants :as constants]
|
||||
|
|
|
@ -1,74 +1,66 @@
|
|||
(ns status-im.utils.datetime
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[cljs-time.core :as t :refer [plus minus days hours before?]]
|
||||
[cljs-time.coerce :refer [from-long]]
|
||||
[cljs-time.format :refer [formatters
|
||||
formatter
|
||||
unparse]]
|
||||
[status-im.i18n.i18n :refer [label label-pluralize]]
|
||||
[status-im.native-module.core :as status]
|
||||
(:require [cljs-time.coerce :as t.coerce]
|
||||
[cljs-time.core :as t]
|
||||
[cljs-time.format :as t.format]
|
||||
[clojure.string :as string]
|
||||
[status-im.goog.i18n :as goog.18n]))
|
||||
[i18n.i18n :as i18n]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.goog.i18n :as goog.18n]
|
||||
[status-im.native-module.core :as status]))
|
||||
|
||||
;;;; Datetime constants
|
||||
|
||||
(defn now []
|
||||
(t/now))
|
||||
(defn now [] (t/now))
|
||||
|
||||
(def one-second 1000)
|
||||
(def minute (* 60 one-second))
|
||||
(defn minutes [m]
|
||||
(* m minute))
|
||||
(defn minutes [m] (* m minute))
|
||||
(def hour (* 60 minute))
|
||||
(def day (* 24 hour))
|
||||
(def week (* 7 day))
|
||||
(defn weeks [w]
|
||||
(* w week))
|
||||
(def units [{:name :t/datetime-second-short :limit 60 :in-second 1}
|
||||
(defn weeks [w] (* w week))
|
||||
(def units
|
||||
[{:name :t/datetime-second-short :limit 60 :in-second 1}
|
||||
{:name :t/datetime-minute-short :limit 3600 :in-second 60}
|
||||
{:name :t/datetime-hour-short :limit 86400 :in-second 3600}
|
||||
{:name :t/datetime-day-short :limit nil :in-second 86400}])
|
||||
|
||||
(def time-zone-offset (hours (- (/ (.getTimezoneOffset ^js (js/Date.)) 60))))
|
||||
(def time-zone-offset (t/hours (- (/ (.getTimezoneOffset ^js (js/Date.)) 60))))
|
||||
|
||||
;;;; Utilities
|
||||
|
||||
(defn- is24Hour-locsym
|
||||
(defn- is-24-hour-locsym
|
||||
"Detects if given locale symbols timeformat generates AM/PM ('a')."
|
||||
[^js locsym]
|
||||
(not (string/includes?
|
||||
(nth (.-TIMEFORMATS locsym) 2)
|
||||
"a")))
|
||||
|
||||
(defn- is24Hour
|
||||
(defn- is-24-hour
|
||||
"Returns is24Hour from device or from given locale symbols. Whenever we get
|
||||
non-nil value use it, else calculate it from the given locale symbol."
|
||||
[^js locsym]
|
||||
(if-some [fromdev (status/is24Hour)]
|
||||
fromdev
|
||||
(is24Hour-locsym locsym)))
|
||||
(is-24-hour-locsym locsym)))
|
||||
|
||||
;;;; Time formats
|
||||
|
||||
(defn- short-time-format
|
||||
[^js locsym]
|
||||
(if (is24Hour locsym)
|
||||
(if (is-24-hour locsym)
|
||||
"HH:mm"
|
||||
"h:mm a"))
|
||||
|
||||
(defn- time-format
|
||||
[^js locsym]
|
||||
(if (is24Hour locsym)
|
||||
(if (is-24-hour locsym)
|
||||
"HH:mm:ss"
|
||||
"h:mm:ss a"))
|
||||
|
||||
;;;; Date formats
|
||||
|
||||
(defn- short-date-format [_] "dd MMM")
|
||||
|
||||
(defn- datetime-within-one-week-format
|
||||
[^js locsym]
|
||||
(if (is24Hour locsym)
|
||||
(if (is-24-hour locsym)
|
||||
"E HH:mm"
|
||||
"E h:mm a"))
|
||||
|
||||
|
@ -78,16 +70,17 @@
|
|||
(nth (.-DATEFORMATS locsym) 2))
|
||||
|
||||
;;;; Datetime formats
|
||||
|
||||
(defn- medium-date-time-format [locsym]
|
||||
(defn- medium-date-time-format
|
||||
[locsym]
|
||||
(str (medium-date-format locsym) ", " (time-format locsym)))
|
||||
|
||||
(defn get-formatter-fn [format]
|
||||
(defn get-formatter-fn
|
||||
[format]
|
||||
(let [formatter (atom nil)]
|
||||
(fn []
|
||||
(or @formatter
|
||||
(reset! formatter
|
||||
(goog.18n/mk-fmt status-im.i18n.i18n/locale format))))))
|
||||
(goog.18n/mk-fmt i18n/locale format))))))
|
||||
|
||||
(def date-time-fmt (get-formatter-fn medium-date-time-format))
|
||||
(def date-fmt (get-formatter-fn medium-date-format))
|
||||
|
@ -96,7 +89,6 @@
|
|||
(def datetime-within-one-week-fmt (get-formatter-fn datetime-within-one-week-format))
|
||||
|
||||
;;;; Utilities
|
||||
|
||||
(defn previous-years?
|
||||
[datetime]
|
||||
(< (t/year datetime) (t/year (t/now))))
|
||||
|
@ -121,37 +113,41 @@
|
|||
(t/within? start end datetime)))
|
||||
|
||||
;;;; Timestamp formatters
|
||||
|
||||
(defn- to-str [ms old-fmt-fn yesterday-fmt-fn today-fmt-fn]
|
||||
(let [date (from-long ms)
|
||||
local (plus date time-zone-offset) ; this is wrong, it uses the current timezone offset, regardless of DST
|
||||
today (minus (t/today-at-midnight) time-zone-offset)
|
||||
yesterday (plus today (days -1))]
|
||||
(defn- to-str
|
||||
[ms old-fmt-fn yesterday-fmt-fn today-fmt-fn]
|
||||
(let [date (t.coerce/from-long ms)
|
||||
local (t/plus date time-zone-offset) ; NOTE(edge-case): this is wrong, it uses the current timezone offset,
|
||||
; regardless of DST
|
||||
today (t/minus (t/today-at-midnight) time-zone-offset)
|
||||
yesterday (t/plus today (t/days -1))]
|
||||
(cond
|
||||
(before? date yesterday) (old-fmt-fn local)
|
||||
(before? date today) (yesterday-fmt-fn local)
|
||||
(t/before? date yesterday) (old-fmt-fn local)
|
||||
(t/before? date today) (yesterday-fmt-fn local)
|
||||
:else (today-fmt-fn local))))
|
||||
|
||||
(defn to-short-str [ms]
|
||||
(defn to-short-str
|
||||
[ms]
|
||||
(to-str ms
|
||||
#(.format ^js (date-fmt) %)
|
||||
#(label :t/datetime-yesterday)
|
||||
#(i18n/label :t/datetime-yesterday)
|
||||
#(.format ^js (time-fmt) %)))
|
||||
|
||||
(defn day-relative [ms]
|
||||
(defn day-relative
|
||||
[ms]
|
||||
(to-str ms
|
||||
#(.format ^js (date-fmt) %)
|
||||
#(label :t/datetime-yesterday)
|
||||
#(label :t/datetime-today)))
|
||||
#(i18n/label :t/datetime-yesterday)
|
||||
#(i18n/label :t/datetime-today)))
|
||||
|
||||
(defn timestamp->relative [ms]
|
||||
(let [datetime (from-long ms)]
|
||||
(defn timestamp->relative
|
||||
[ms]
|
||||
(let [datetime (t.coerce/from-long ms)]
|
||||
(cond
|
||||
(today? datetime)
|
||||
(.format ^js (time-fmt) datetime)
|
||||
|
||||
(within-last-n-days? datetime 1)
|
||||
(str (string/capitalize (label :t/datetime-yesterday))
|
||||
(str (string/capitalize (i18n/label :t/datetime-yesterday))
|
||||
" "
|
||||
(.format ^js (time-fmt) datetime))
|
||||
|
||||
|
@ -164,40 +160,52 @@
|
|||
(previous-years? datetime)
|
||||
(.format ^js (date-fmt) datetime))))
|
||||
|
||||
(defn timestamp->mini-date [ms]
|
||||
(.format ^js (short-date-fmt) (-> ms
|
||||
from-long
|
||||
(plus time-zone-offset))))
|
||||
(defn timestamp->mini-date
|
||||
[ms]
|
||||
(.format ^js (short-date-fmt)
|
||||
(-> ms
|
||||
t.coerce/from-long
|
||||
(t/plus time-zone-offset))))
|
||||
|
||||
(defn timestamp->time [ms]
|
||||
(.format ^js (time-fmt) (-> ms
|
||||
from-long
|
||||
(plus time-zone-offset))))
|
||||
(defn timestamp->time
|
||||
[ms]
|
||||
(.format ^js (time-fmt)
|
||||
(-> ms
|
||||
t.coerce/from-long
|
||||
(t/plus time-zone-offset))))
|
||||
|
||||
(defn timestamp->date-key [ms]
|
||||
(keyword (unparse (formatter "YYYYMMDD") (-> ms
|
||||
from-long
|
||||
(plus time-zone-offset)))))
|
||||
(defn timestamp->date-key
|
||||
[ms]
|
||||
(keyword (t.format/unparse (t.format/formatter "YYYYMMDD")
|
||||
(-> ms
|
||||
t.coerce/from-long
|
||||
(t/plus time-zone-offset)))))
|
||||
|
||||
(defn timestamp->long-date [ms]
|
||||
(.format ^js (date-time-fmt) (-> ms
|
||||
from-long
|
||||
(plus time-zone-offset))))
|
||||
(defn timestamp->long-date
|
||||
[ms]
|
||||
(.format ^js (date-time-fmt)
|
||||
(-> ms
|
||||
t.coerce/from-long
|
||||
(t/plus time-zone-offset))))
|
||||
|
||||
(defn format-time-ago [diff unit]
|
||||
(let [name (label-pluralize diff (:name unit))]
|
||||
(defn format-time-ago
|
||||
[diff unit]
|
||||
(let [name (i18n/label-pluralize diff (:name unit))]
|
||||
(if (= :t/datetime-second-short (:name unit))
|
||||
(label :t/now)
|
||||
(label :t/datetime-ago-format-short {:ago (label :t/datetime-ago)
|
||||
(i18n/label :t/now)
|
||||
(i18n/label :t/datetime-ago-format-short
|
||||
{:ago (i18n/label :t/datetime-ago)
|
||||
:number diff
|
||||
:time-intervals name}))))
|
||||
(defn seconds-ago [time]
|
||||
(defn seconds-ago
|
||||
[time]
|
||||
(let [now (t/now)]
|
||||
(if (<= (.getTime ^js time) (.getTime ^js now))
|
||||
(t/in-seconds (t/interval time now))
|
||||
0)))
|
||||
|
||||
(defn time-ago [time]
|
||||
(defn time-ago
|
||||
[time]
|
||||
(let [diff (seconds-ago time)
|
||||
unit (first (drop-while #(and (>= diff (:limit %))
|
||||
(:limit %))
|
||||
|
@ -207,7 +215,8 @@
|
|||
int
|
||||
(format-time-ago unit))))
|
||||
|
||||
(defn time-ago-long [time]
|
||||
(defn time-ago-long
|
||||
[time]
|
||||
(let [seconds-ago (seconds-ago time)
|
||||
unit (first (drop-while #(and (>= seconds-ago (:limit %))
|
||||
(:limit %))
|
||||
|
@ -216,27 +225,33 @@
|
|||
Math/floor
|
||||
int)
|
||||
|
||||
name (label-pluralize diff (:name unit))]
|
||||
(label :t/datetime-ago-format {:ago (label :t/datetime-ago)
|
||||
name (i18n/label-pluralize diff (:name unit))]
|
||||
(i18n/label :t/datetime-ago-format
|
||||
{:ago (i18n/label :t/datetime-ago)
|
||||
:number diff
|
||||
:time-intervals name})))
|
||||
|
||||
(defn to-date [ms]
|
||||
(from-long ms))
|
||||
(defn to-date
|
||||
[ms]
|
||||
(t.coerce/from-long ms))
|
||||
|
||||
(defn timestamp []
|
||||
(defn timestamp
|
||||
[]
|
||||
(inst-ms (js/Date.)))
|
||||
|
||||
(defn timestamp-sec []
|
||||
(defn timestamp-sec
|
||||
[]
|
||||
(int (/ (timestamp) 1000)))
|
||||
|
||||
(defn timestamp->year-month-day-date [ms]
|
||||
(unparse (:year-month-day formatters) (to-date ms)))
|
||||
(defn timestamp->year-month-day-date
|
||||
[ms]
|
||||
(t.format/unparse (:year-month-day t.format/formatters) (to-date ms)))
|
||||
|
||||
(re-frame/reg-cofx
|
||||
:now
|
||||
(fn [coeffects _]
|
||||
(assoc coeffects :now (timestamp))))
|
||||
|
||||
(defn to-ms [sec]
|
||||
(defn to-ms
|
||||
[sec]
|
||||
(* 1000 sec))
|
||||
|
|
|
@ -23,14 +23,14 @@
|
|||
;; 1970-01-03 00:00:00 UTC
|
||||
(def epoch-plus-3d 172800000)
|
||||
|
||||
(deftest is24Hour-locale-en-test
|
||||
(is (= (#'status-im.utils.datetime/is24Hour-locsym (i18n/locale-symbols "en")) false)))
|
||||
(deftest is-24-hour-locale-en-test
|
||||
(is (= (#'status-im.utils.datetime/is-24-hour-locsym (i18n/locale-symbols "en")) false)))
|
||||
|
||||
(deftest is24Hour-locale-it-test
|
||||
(is (= (#'status-im.utils.datetime/is24Hour-locsym (i18n/locale-symbols "it")) true)))
|
||||
(deftest is-24-hour-locale-it-test
|
||||
(is (= (#'status-im.utils.datetime/is-24-hour-locsym (i18n/locale-symbols "it")) true)))
|
||||
|
||||
(deftest is24Hour-locale-nb-test
|
||||
(is (= (#'status-im.utils.datetime/is24Hour-locsym (i18n/locale-symbols "nb-NO")) true)))
|
||||
(deftest is-24-hour-locale-nb-test
|
||||
(is (= (#'status-im.utils.datetime/is-24-hour-locsym (i18n/locale-symbols "nb-NO")) true)))
|
||||
|
||||
(deftest to-short-str-today-test
|
||||
(with-redefs [t/*ms-fn* (constantly epoch-plus-3d)
|
||||
|
@ -40,14 +40,14 @@
|
|||
|
||||
#_((deftest to-short-str-today-force-24H-test
|
||||
(with-redefs [t/*ms-fn* (constantly epoch-plus-3d)
|
||||
d/is24Hour (constantly true)
|
||||
d/is-24-hour (constantly true)
|
||||
d/time-fmt (i18n-module/mk-fmt "us" d/short-time-format)
|
||||
d/time-zone-offset (t/period :hours 0)]
|
||||
(is (= (d/to-short-str epoch-plus-3d) "00:00"))))
|
||||
|
||||
(deftest to-short-str-today-force-AMPM-test
|
||||
(with-redefs [t/*ms-fn* (constantly epoch-plus-3d)
|
||||
d/is24Hour (constantly false)
|
||||
d/is-24-hour (constantly false)
|
||||
d/time-fmt (i18n-module/mk-fmt "it" d/short-time-format)
|
||||
d/time-zone-offset (t/period :hours 0)]
|
||||
(is (= (d/to-short-str epoch-plus-3d) "12:00 AM")))))
|
||||
|
@ -135,7 +135,7 @@
|
|||
;; Today is Monday, 1975-03-10 15:15:45Z
|
||||
(with-redefs [t/*ms-fn* (constantly 163696545000)
|
||||
d/time-zone-offset (t/period :hours 0)
|
||||
d/is24Hour (constantly false)]
|
||||
d/is-24-hour (constantly false)]
|
||||
(testing "formats previous years"
|
||||
;; 1974-12-31 23:59:59Z
|
||||
(is (= "Dec 31, 1974" (d/timestamp->relative 157766399000)))
|
||||
|
@ -165,14 +165,14 @@
|
|||
|
||||
#_((deftest day-relative-before-yesterday-force-24H-test
|
||||
(with-redefs [t/*ms-fn* (constantly epoch-plus-3d)
|
||||
d/is24Hour (constantly true)
|
||||
d/is-24-hour (constantly true)
|
||||
d/time-zone-offset (t/period :hours 0)
|
||||
d/date-fmt (i18n-module/mk-fmt "us" #'status-im.utils.datetime/medium-date-time-format)]
|
||||
(is (= (d/day-relative epoch) "Jan 1, 1970, 00:00:00"))))
|
||||
|
||||
(deftest day-relative-before-yesterday-force-AMPM-test
|
||||
(with-redefs [t/*ms-fn* (constantly epoch-plus-3d)
|
||||
d/is24Hour (constantly false)
|
||||
d/is-24-hour (constantly false)
|
||||
d/time-zone-offset (t/period :hours 0)
|
||||
d/date-fmt (i18n-module/mk-fmt "it" #'status-im.utils.datetime/medium-date-time-format)]
|
||||
(is (= (d/day-relative epoch) "01 gen 1970, 12:00:00 AM")))))
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
(:refer-clojure :exclude [js->clj])
|
||||
(:require [cljs-bean.core :as clj-bean]))
|
||||
|
||||
;; NOTE(19/12/22 yqrashawn) this namespace has been moved to the utils.transforms namespace,
|
||||
;; we keep this only for old (status 1.0) code, can be removed with old code later
|
||||
|
||||
(defn to-string [s]
|
||||
(if (keyword? s)
|
||||
(name s)
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
(ns status-im2.common.json-rpc.events
|
||||
(:require [clojure.string :as string]
|
||||
[re-frame.core :as re-frame]
|
||||
[react-native.background-timer :as background-timer]
|
||||
[status-im.native-module.core :as status]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.transforms :as transforms]))
|
||||
|
||||
(defn on-error-retry
|
||||
[call-method {:keys [method number-of-retries delay on-error] :as arg}]
|
||||
(if (pos? number-of-retries)
|
||||
(fn [error]
|
||||
(let [updated-delay (if delay
|
||||
(min 2000 (* 2 delay))
|
||||
50)]
|
||||
(log/debug "[on-error-retry]" method
|
||||
"number-of-retries" number-of-retries
|
||||
"delay" delay
|
||||
"error" error)
|
||||
(background-timer/set-timeout #(call-method (-> arg
|
||||
(update :number-of-retries dec)
|
||||
(assoc :delay updated-delay)))
|
||||
updated-delay)))
|
||||
on-error))
|
||||
|
||||
(defn call
|
||||
[{:keys [method params on-success on-error js-response] :as arg}]
|
||||
(let [params (or params [])
|
||||
on-error (or on-error
|
||||
(on-error-retry call arg)
|
||||
#(log/warn :json-rpc/error method :error % :params params))]
|
||||
(status/call-private-rpc
|
||||
(transforms/clj->json {:jsonrpc "2.0"
|
||||
:id 1
|
||||
:method method
|
||||
:params params})
|
||||
(fn [response]
|
||||
(if (string/blank? response)
|
||||
(on-error {:message "Blank response"})
|
||||
(let [response-js (transforms/json->js response)]
|
||||
(if (.-error response-js)
|
||||
(on-error (transforms/js->clj (.-error response-js)))
|
||||
(on-success (if js-response
|
||||
(.-result response-js)
|
||||
(transforms/js->clj (.-result response-js)))))))))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::call
|
||||
(fn [params]
|
||||
(doseq [param params]
|
||||
(call param))))
|
|
@ -1,7 +1,7 @@
|
|||
(ns status-im2.contexts.activity-center.events
|
||||
(:require [re-frame.core :as rf]
|
||||
[status-im.data-store.activities :as data-store.activities]
|
||||
[status-im.ethereum.json-rpc :as json-rpc]
|
||||
[status-im2.common.json-rpc.events :as json-rpc]
|
||||
[status-im.utils.fx :as fx]
|
||||
[status-im2.contexts.activity-center.notification-types :as types]
|
||||
[taoensso.timbre :as log]))
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
[day8.re-frame.test :as rf-test]
|
||||
[re-frame.core :as rf]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.ethereum.json-rpc :as json-rpc]
|
||||
[status-im2.common.json-rpc.events :as json-rpc]
|
||||
status-im.events
|
||||
[status-im.test-helpers :as h]
|
||||
[status-im2.contexts.activity-center.events :as activity-center]
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
(ns status-im.chat.models.delete-message
|
||||
(:require [re-frame.core :as re-frame]
|
||||
(ns status-im2.contexts.chat.messages.message.delete-message.events
|
||||
(:require
|
||||
;; TODO move to status-im2
|
||||
[status-im.chat.models.message-list :as message-list]
|
||||
[status-im.ethereum.json-rpc :as json-rpc]
|
||||
[status-im.utils.datetime :as datetime]
|
||||
[status-im.utils.fx :as fx]
|
||||
[taoensso.encore :as enc]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
[status-im2.common.json-rpc.events :as json-rpc]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- update-db-clear-undo-timer
|
||||
[db chat-id message-id]
|
||||
|
@ -46,7 +47,7 @@
|
|||
(when (get-in db [:messages chat-id message-id])
|
||||
(update-in db [:messages chat-id message-id] assoc :deleted? true)))
|
||||
|
||||
(fx/defn delete
|
||||
(rf/defn delete
|
||||
"Delete message now locally and broadcast after undo time limit timeout"
|
||||
{:events [:chat.ui/delete-message]}
|
||||
[{:keys [db]} {:keys [chat-id message-id]} undo-time-limit-ms]
|
||||
|
@ -55,12 +56,13 @@
|
|||
(message-list/rebuild-message-list
|
||||
{:db (update-db-delete-locally db chat-id message-id undo-time-limit-ms)}
|
||||
chat-id)
|
||||
:utils/dispatch-later [{:dispatch [:chat.ui/delete-message-and-send
|
||||
:utils/dispatch-later
|
||||
[{:dispatch [:chat.ui/delete-message-and-send
|
||||
{:chat-id chat-id
|
||||
:message-id message-id}]
|
||||
:ms undo-time-limit-ms}])))
|
||||
|
||||
(fx/defn undo
|
||||
(rf/defn undo
|
||||
{:events [:chat.ui/undo-delete-message]}
|
||||
[{:keys [db]} {:keys [chat-id message-id]}]
|
||||
(when (get-in db [:messages chat-id message-id])
|
||||
|
@ -68,19 +70,22 @@
|
|||
{:db (update-db-undo-locally db chat-id message-id)}
|
||||
chat-id)))
|
||||
|
||||
(fx/defn delete-and-send
|
||||
(rf/defn delete-and-send
|
||||
{:events [:chat.ui/delete-message-and-send]}
|
||||
[{:keys [db]} {:keys [message-id chat-id]}]
|
||||
(when-let [message (get-in db [:messages chat-id message-id])]
|
||||
(enc/assoc-when
|
||||
{:db (update-db-clear-undo-timer db chat-id message-id)
|
||||
(cond-> {:db (update-db-clear-undo-timer db chat-id message-id)
|
||||
::json-rpc/call [{:method "wakuext_deleteMessageAndSend"
|
||||
:params [message-id]
|
||||
:js-response true
|
||||
:on-error #(log/error "failed to delete message " {:message-id message-id :error %})
|
||||
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])}]}
|
||||
:dispatch (and (get-in db [:pin-messages chat-id message-id])
|
||||
[:pin-message/send-pin-message {:chat-id chat-id :message-id message-id :pinned false}]))))
|
||||
:on-error #(log/error "failed to delete message "
|
||||
{:message-id message-id :error %})
|
||||
:on-success #(rf/dispatch [:sanitize-messages-and-process-response
|
||||
%])}]}
|
||||
(get-in db [:pin-messages chat-id message-id])
|
||||
(assoc :dispatch
|
||||
[:pin-message/send-pin-message
|
||||
{:chat-id chat-id :message-id message-id :pinned false}]))))
|
||||
|
||||
(defn- filter-pending-send-messages
|
||||
"traverse all messages find not yet synced deleted? messages"
|
||||
|
@ -90,19 +95,20 @@
|
|||
(map (fn [message] {:chat-id chat-id :message-id (first message)}))
|
||||
(concat acc)))
|
||||
|
||||
(fx/defn send-all
|
||||
(rf/defn send-all
|
||||
"Get all deleted messages that not yet synced with status-go and send them"
|
||||
{:events [:chat.ui/send-all-deleted-messages]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [pending-send-messages (reduce-kv filter-pending-send-messages [] (:messages db))]
|
||||
(apply fx/merge cofx (map delete-and-send pending-send-messages))))
|
||||
(apply rf/merge cofx (map delete-and-send pending-send-messages))))
|
||||
|
||||
(fx/defn delete-messages-localy
|
||||
(rf/defn delete-messages-localy
|
||||
"Mark messages :deleted? localy in client"
|
||||
{:events [:chat.ui/delete-messages-localy]}
|
||||
[{:keys [db]} messages chat-id]
|
||||
(let [new-db (->> messages
|
||||
(filter #(get-in db [:messages chat-id (:message-id %)]))
|
||||
(reduce #(update-db-delete-locally-without-time-limit %1 chat-id (:message-id %2)) db))]
|
||||
(reduce #(update-db-delete-locally-without-time-limit %1 chat-id (:message-id %2))
|
||||
db))]
|
||||
(when new-db
|
||||
(message-list/rebuild-message-list {:db new-db} chat-id))))
|
|
@ -1,8 +1,8 @@
|
|||
(ns status-im.chat.models.delete-message-test
|
||||
(:require
|
||||
[cljs.test :refer-macros [deftest is testing]]
|
||||
[status-im.chat.models.delete-message :as delete-message]
|
||||
[status-im.utils.datetime :as datetime]))
|
||||
(ns status-im2.contexts.chat.messages.message.delete-message.events-test
|
||||
(:require [cljs.test :refer-macros [deftest is testing]]
|
||||
[status-im.utils.datetime :as datetime]
|
||||
[status-im2.common.json-rpc.events :as json-rpc]
|
||||
[status-im2.contexts.chat.messages.message.delete-message.events :as delete-message]))
|
||||
|
||||
(def mid "message-id")
|
||||
(def cid "chat-id")
|
||||
|
@ -62,7 +62,7 @@
|
|||
(let [expected-db {:messages {cid {mid {:id mid}}}}
|
||||
effects (delete-message/delete-and-send {:db db} message)
|
||||
result-db (:db effects)
|
||||
rpc-calls (:status-im.ethereum.json-rpc/call effects)]
|
||||
rpc-calls (::json-rpc/call effects)]
|
||||
(is (= result-db expected-db))
|
||||
(is (= (count rpc-calls) 1))
|
||||
(is (= (-> rpc-calls
|
|
@ -1,10 +1,12 @@
|
|||
(ns status-im.chat.models.delete-message-for-me
|
||||
(:require [re-frame.core :as re-frame]
|
||||
(ns status-im2.contexts.chat.messages.message.delete-message-for-me.events
|
||||
(:require
|
||||
;; TODO move to status-im2
|
||||
[status-im.chat.models.message-list :as message-list]
|
||||
[status-im.ethereum.json-rpc :as json-rpc]
|
||||
[status-im.utils.datetime :as datetime]
|
||||
[status-im.utils.fx :as fx]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
[status-im2.common.json-rpc.events :as json-rpc]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- update-db-clear-undo-timer
|
||||
[db chat-id message-id]
|
||||
|
@ -39,7 +41,7 @@
|
|||
:deleted-for-me-undoable-till)
|
||||
(update-db-clear-undo-timer db chat-id message-id))))
|
||||
|
||||
(fx/defn delete
|
||||
(rf/defn delete
|
||||
"Delete message for me now locally and broadcast after undo time limit timeout"
|
||||
{:events [:chat.ui/delete-message-for-me]}
|
||||
[{:keys [db]} {:keys [chat-id message-id]} undo-time-limit-ms]
|
||||
|
@ -48,12 +50,13 @@
|
|||
(message-list/rebuild-message-list
|
||||
{:db (update-db-delete-locally db chat-id message-id undo-time-limit-ms)}
|
||||
chat-id)
|
||||
:utils/dispatch-later [{:dispatch [:chat.ui/delete-message-for-me-and-sync
|
||||
:utils/dispatch-later
|
||||
[{:dispatch [:chat.ui/delete-message-for-me-and-sync
|
||||
{:chat-id chat-id
|
||||
:message-id message-id}]
|
||||
:ms undo-time-limit-ms}])))
|
||||
|
||||
(fx/defn undo
|
||||
(rf/defn undo
|
||||
{:events [:chat.ui/undo-delete-message-for-me]}
|
||||
[{:keys [db]} {:keys [chat-id message-id]}]
|
||||
(when (get-in db [:messages chat-id message-id])
|
||||
|
@ -61,7 +64,7 @@
|
|||
{:db (update-db-undo-locally db chat-id message-id)}
|
||||
chat-id)))
|
||||
|
||||
(fx/defn delete-and-sync
|
||||
(rf/defn delete-and-sync
|
||||
{:events [:chat.ui/delete-message-for-me-and-sync]}
|
||||
[{:keys [db]} {:keys [message-id chat-id]}]
|
||||
(when (get-in db [:messages chat-id message-id])
|
||||
|
@ -69,20 +72,22 @@
|
|||
::json-rpc/call [{:method "wakuext_deleteMessageForMeAndSync"
|
||||
:params [chat-id message-id]
|
||||
:js-response true
|
||||
:on-error #(log/error "failed to delete message for me, message id: " {:message-id message-id :error %})
|
||||
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])}]}))
|
||||
:on-error #(log/error "failed to delete message for me, message id: "
|
||||
{:message-id message-id :error %})
|
||||
:on-success #(rf/dispatch [:sanitize-messages-and-process-response %])}]}))
|
||||
|
||||
(defn- filter-pending-sync-messages
|
||||
"traverse all messages find not yet synced deleted-for-me? messages"
|
||||
[acc chat-id messages]
|
||||
(->> messages
|
||||
(filter (fn [[_ {:keys [deleted-for-me? deleted-for-me-undoable-till]}]] (and deleted-for-me? deleted-for-me-undoable-till)))
|
||||
(filter (fn [[_ {:keys [deleted-for-me? deleted-for-me-undoable-till]}]]
|
||||
(and deleted-for-me? deleted-for-me-undoable-till)))
|
||||
(map (fn [message] {:chat-id chat-id :message-id (first message)}))
|
||||
(concat acc)))
|
||||
|
||||
(fx/defn sync-all
|
||||
(rf/defn sync-all
|
||||
"Get all deleted-for-me messages that not yet synced with status-go and sync them"
|
||||
{:events [:chat.ui/sync-all-deleted-for-me-messages]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [pending-sync-messages (reduce-kv filter-pending-sync-messages [] (:messages db))]
|
||||
(apply fx/merge cofx (map delete-and-sync pending-sync-messages))))
|
||||
(apply rf/merge cofx (map delete-and-sync pending-sync-messages))))
|
|
@ -1,8 +1,9 @@
|
|||
(ns status-im.chat.models.delete-message-for-me-test
|
||||
(ns status-im2.contexts.chat.messages.message.delete-message-for-me.events-test
|
||||
(:require [cljs.test :refer-macros [deftest is testing]]
|
||||
[status-im.chat.models.delete-message-for-me :as
|
||||
delete-message-for-me]
|
||||
[status-im.utils.datetime :as datetime]))
|
||||
[status-im.utils.datetime :as datetime]
|
||||
[status-im2.common.json-rpc.events :as json-rpc]
|
||||
[status-im2.contexts.chat.messages.message.delete-message-for-me.events :as
|
||||
delete-message-for-me]))
|
||||
|
||||
(def mid "message-id")
|
||||
(def cid "chat-id")
|
||||
|
@ -45,7 +46,8 @@
|
|||
assoc
|
||||
:deleted-for-me? true
|
||||
:deleted-for-me-undoable-till (- (datetime/timestamp) 1000))
|
||||
result-message (get-in (delete-message-for-me/undo {:db db} message) [:db :messages cid mid])]
|
||||
result-message (get-in (delete-message-for-me/undo {:db db} message)
|
||||
[:db :messages cid mid])]
|
||||
(is (= (:id result-message) mid))
|
||||
(is (nil? (:deleted-for-me-undoable-till result-message)))
|
||||
(is (true? (:deleted-for-me? result-message)))))
|
||||
|
@ -62,7 +64,7 @@
|
|||
(let [expected-db {:messages {cid {mid {:id mid}}}}
|
||||
effects (delete-message-for-me/delete-and-sync {:db db} message)
|
||||
result-db (:db effects)
|
||||
rpc-calls (:status-im.ethereum.json-rpc/call effects)]
|
||||
rpc-calls (::json-rpc/call effects)]
|
||||
(is (= result-db expected-db))
|
||||
(is (= (count rpc-calls) 1))
|
||||
(is (= (-> rpc-calls
|
|
@ -3,6 +3,7 @@
|
|||
[re-frame.interop :as interop]
|
||||
[reagent.impl.batching :as batching]
|
||||
[react-native.core :as rn]
|
||||
[status-im.native-module.core :as status]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.shake :as react-native-shake]
|
||||
[react-native.languages :as react-native-languages]
|
||||
|
@ -23,7 +24,6 @@
|
|||
|
||||
;; TODO (14/11/22 flexsurfer move to status-im2 namespace
|
||||
status-im.events
|
||||
[status-im.native-module.core :as status]
|
||||
[status-im.notifications.local :as notifications]
|
||||
[status-im.async-storage.core :as async-storage]
|
||||
[status-im.utils.universal-links.core :as utils.universal-links]))
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
|
||||
;; TODO (14/11/22 flexsurfer move to status-im2 namespace
|
||||
[quo.theme :as quo.theme]
|
||||
[status-im.multiaccounts.login.core :as multiaccounts.login]
|
||||
[status-im.native-module.core :as status]
|
||||
[status-im.multiaccounts.login.core :as multiaccounts.login]
|
||||
[status-im.utils.keychain.core :as keychain]
|
||||
[status-im2.navigation.events :as navigation]))
|
||||
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
(ns utils.transforms
|
||||
(:refer-clojure :exclude [js->clj])
|
||||
(:require [cljs-bean.core :as clj-bean]))
|
||||
|
||||
(defn js->clj [data] (cljs.core/js->clj data :keywordize-keys true))
|
||||
|
||||
(defn clj->pretty-json
|
||||
[data spaces]
|
||||
(.stringify js/JSON (clj-bean/->js data) nil spaces))
|
||||
|
||||
(defn clj->json [data] (clj->pretty-json data 0))
|
||||
|
||||
(defn json->clj
|
||||
[json]
|
||||
(when-not (= json "undefined")
|
||||
(try (js->clj (.parse js/JSON json))
|
||||
(catch js/Error _ (when (string? json) json)))))
|
||||
|
||||
(defn json->js
|
||||
[json]
|
||||
(when-not (= json "undefined")
|
||||
(try (.parse js/JSON json) (catch js/Error _ (when (string? json) json)))))
|
Loading…
Reference in New Issue