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