chat, data, utils: add implementation of simple preview caching
This commit is contained in:
parent
59edcb37ef
commit
f5b0c0c368
|
@ -1,13 +1,15 @@
|
||||||
(ns status-im.chat.handlers.commands
|
(ns status-im.chat.handlers.commands
|
||||||
(:require [re-frame.core :refer [enrich after dispatch]]
|
(:require [cljs.reader :as reader]
|
||||||
|
[clojure.string :as str]
|
||||||
|
[re-frame.core :refer [enrich after dispatch]]
|
||||||
|
[status-im.data-store.messages :as messages]
|
||||||
[status-im.utils.handlers :as handlers]
|
[status-im.utils.handlers :as handlers]
|
||||||
[status-im.components.status :as status]
|
[status-im.components.status :as status]
|
||||||
[status-im.chat.constants :as const]
|
[status-im.chat.constants :as const]
|
||||||
[status-im.commands.utils :as cu]
|
[status-im.commands.utils :as cu]
|
||||||
[status-im.i18n :as i18n]
|
[status-im.i18n :as i18n]
|
||||||
[status-im.utils.platform :as platform]
|
[status-im.utils.platform :as platform]
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]))
|
||||||
[clojure.string :as str]))
|
|
||||||
|
|
||||||
(defn generate-context [{:keys [contacts current-account-id chats] :as db} chat-id to]
|
(defn generate-context [{:keys [contacts current-account-id chats] :as db} chat-id to]
|
||||||
(merge {:platform platform/platform
|
(merge {:platform platform/platform
|
||||||
|
@ -38,11 +40,15 @@
|
||||||
params {:parameters params
|
params {:parameters params
|
||||||
:context (generate-context db chat-id to)}
|
:context (generate-context db chat-id to)}
|
||||||
callback #(let [result (get-in % [:result :returned])
|
callback #(let [result (get-in % [:result :returned])
|
||||||
result (if (:markup result)
|
result' (if (:markup result)
|
||||||
(update result :markup cu/generate-hiccup)
|
(update result :markup cu/generate-hiccup)
|
||||||
result)]
|
result)]
|
||||||
(dispatch [:set-in [:message-data data-type message-id] result])
|
(dispatch [:set-in [:message-data data-type message-id] result'])
|
||||||
(when on-requested (on-requested result)))]
|
(when (= :preview data-type)
|
||||||
|
;; update message in realm with serialized preview
|
||||||
|
(messages/update {:message-id message-id
|
||||||
|
:preview (prn-str result)}))
|
||||||
|
(when on-requested (on-requested result')))]
|
||||||
;chat-id path params callback lock? type
|
;chat-id path params callback lock? type
|
||||||
(status/call-jail {:jail-id jail-id'
|
(status/call-jail {:jail-id jail-id'
|
||||||
:path path
|
:path path
|
||||||
|
@ -64,4 +70,12 @@
|
||||||
(fn [db [_ {:keys [message-id] :as message}]]
|
(fn [db [_ {:keys [message-id] :as message}]]
|
||||||
(let [previews (get-in db [:message-data :preview])]
|
(let [previews (get-in db [:message-data :preview])]
|
||||||
(when-not (contains? previews message-id)
|
(when-not (contains? previews message-id)
|
||||||
(dispatch [:request-command-data message :preview]))))))
|
(let [{serialized-preview :preview} (messages/get-by-id message-id)]
|
||||||
|
;; if preview is already cached in db, do not request it from jail
|
||||||
|
;; and write it directly to message-data path
|
||||||
|
(if serialized-preview
|
||||||
|
(dispatch [:set-in [:message-data :preview message-id]
|
||||||
|
(-> serialized-preview
|
||||||
|
reader/read-string
|
||||||
|
(update :markup cu/generate-hiccup))])
|
||||||
|
(dispatch [:request-command-data message :preview]))))))))
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
(:require [status-im.data-store.realm.messages :as data-store]
|
(:require [status-im.data-store.realm.messages :as data-store]
|
||||||
[clojure.string :refer [join split]]
|
[clojure.string :refer [join split]]
|
||||||
[status-im.utils.random :refer [timestamp]]
|
[status-im.utils.random :refer [timestamp]]
|
||||||
|
[status-im.utils.utils :refer [update-if-present]]
|
||||||
[clojure.walk :refer [stringify-keys keywordize-keys]]
|
[clojure.walk :refer [stringify-keys keywordize-keys]]
|
||||||
[cljs.reader :refer [read-string]]
|
[cljs.reader :refer [read-string]]
|
||||||
[status-im.constants :as c])
|
[status-im.constants :as c])
|
||||||
|
@ -111,10 +112,10 @@
|
||||||
:timestamp (timestamp)})]
|
:timestamp (timestamp)})]
|
||||||
(data-store/save message'))))
|
(data-store/save message'))))
|
||||||
|
|
||||||
(defn update
|
(defn update
|
||||||
[{:keys [message-id] :as message}]
|
[{:keys [message-id] :as message}]
|
||||||
(when (data-store/exists? message-id)
|
(when (data-store/exists? message-id)
|
||||||
(let [message (clojure.core/update message :user-statuses vals)]
|
(let [message (update-if-present message :user-statuses vals)]
|
||||||
(data-store/save message))))
|
(data-store/save message))))
|
||||||
|
|
||||||
(defn delete-by-chat-id [chat-id]
|
(defn delete-by-chat-id [chat-id]
|
||||||
|
|
|
@ -20,11 +20,11 @@
|
||||||
(.alert (.-Alert rn-dependencies/react-native)
|
(.alert (.-Alert rn-dependencies/react-native)
|
||||||
title
|
title
|
||||||
content
|
content
|
||||||
; Styles are only relevant on iOS. On Android first button is 'neutral' and second is 'positive'
|
;; Styles are only relevant on iOS. On Android first button is 'neutral' and second is 'positive'
|
||||||
(clj->js
|
(clj->js
|
||||||
(vector (merge {:text (label :t/cancel) :style "cancel"}
|
(vector (merge {:text (label :t/cancel) :style "cancel"}
|
||||||
(when on-cancel {:onPress on-cancel}))
|
(when on-cancel {:onPress on-cancel}))
|
||||||
{:text (or s "OK") :onPress on-accept :style "destructive"})))))
|
{:text (or s "OK") :onPress on-accept :style "destructive"})))))
|
||||||
|
|
||||||
(defn http-post
|
(defn http-post
|
||||||
([action data on-success]
|
([action data on-success]
|
||||||
|
@ -49,7 +49,7 @@
|
||||||
|
|
||||||
(defn http-get
|
(defn http-get
|
||||||
([url on-success on-error]
|
([url on-success on-error]
|
||||||
(http-get url nil on-success on-error))
|
(http-get url nil on-success on-error))
|
||||||
([url valid-response? on-success on-error]
|
([url valid-response? on-success on-error]
|
||||||
(-> (.fetch js/window url (clj->js {:method "GET"
|
(-> (.fetch js/window url (clj->js {:method "GET"
|
||||||
:headers {"Cache-Control" "no-cache"}}))
|
:headers {"Cache-Control" "no-cache"}}))
|
||||||
|
@ -72,9 +72,13 @@
|
||||||
(fn [error]
|
(fn [error]
|
||||||
(show-popup "Error" (str error))))))))
|
(show-popup "Error" (str error))))))))
|
||||||
|
|
||||||
(defn truncate-str [s max]
|
(defn truncate-str
|
||||||
(if (and (< max (count s)) s)
|
"Given string and max threshold, trims the string to threshold length with `...`
|
||||||
(str (subs s 0 (- max 3)) "...")
|
appended to end if length of the string exceeds max threshold, returns the same
|
||||||
|
string if threshold is not exceeded"
|
||||||
|
[s threshold]
|
||||||
|
(if (and s (< threshold (count s)))
|
||||||
|
(str (subs s 0 (- threshold 3)) "...")
|
||||||
s))
|
s))
|
||||||
|
|
||||||
(defn clean-text [s]
|
(defn clean-text [s]
|
||||||
|
@ -84,14 +88,13 @@
|
||||||
(str/trim)))
|
(str/trim)))
|
||||||
|
|
||||||
(defn first-index
|
(defn first-index
|
||||||
[cond coll]
|
"Returns first index in coll where predicate on coll element is truthy"
|
||||||
(loop [index 0
|
[pred coll]
|
||||||
cond cond
|
(->> coll
|
||||||
coll coll]
|
(keep-indexed (fn [idx e]
|
||||||
(when (seq coll)
|
(when (pred e)
|
||||||
(if (cond (first coll))
|
idx)))
|
||||||
index
|
first))
|
||||||
(recur (inc index) cond (next coll))))))
|
|
||||||
|
|
||||||
(defn hash-tag? [s]
|
(defn hash-tag? [s]
|
||||||
(= \# (first s)))
|
(= \# (first s)))
|
||||||
|
@ -105,3 +108,11 @@
|
||||||
(vreset! called? true)
|
(vreset! called? true)
|
||||||
(apply f args)
|
(apply f args)
|
||||||
nil))))
|
nil))))
|
||||||
|
|
||||||
|
(defn update-if-present
|
||||||
|
"Like regular `clojure.core/update` but returns original map if update key is not present"
|
||||||
|
[m k f & args]
|
||||||
|
(if (contains? m k)
|
||||||
|
(apply update m k f args)
|
||||||
|
m))
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
(ns status-im.test.utils.utils
|
(ns status-im.test.utils.utils
|
||||||
(:require [cljs.test :refer-macros [deftest is]]
|
(:require [cljs.test :refer-macros [deftest is]]
|
||||||
[status-im.utils.utils :as u]))
|
[status-im.utils.utils :as u]))
|
||||||
|
|
||||||
(deftest wrap-as-call-once-test
|
(deftest wrap-as-call-once-test
|
||||||
(let [count (atom 0)]
|
(let [count (atom 0)]
|
||||||
|
@ -9,4 +9,30 @@
|
||||||
(is (nil? (f)))
|
(is (nil? (f)))
|
||||||
(is (= 1 @count))
|
(is (= 1 @count))
|
||||||
(is (nil? (f)))
|
(is (nil? (f)))
|
||||||
(is (= 1 @count))))))
|
(is (= 1 @count))))))
|
||||||
|
|
||||||
|
(deftest truncate-str-test
|
||||||
|
(is (= (u/truncate-str "Long string" 7) "Long...")) ; threshold is less then string length
|
||||||
|
(is (= (u/truncate-str "Long string" 11) "Long string")) ; threshold is the same as string length
|
||||||
|
(is (= (u/truncate-str "Long string" 20) "Long string"))) ; threshold is more then string length
|
||||||
|
|
||||||
|
(deftest clean-text-test
|
||||||
|
(is (= (u/clean-text "Hello! \n\r") "Hello!")
|
||||||
|
(= (u/clean-text "Hello!") "Hello!")))
|
||||||
|
|
||||||
|
(deftest first-index-test
|
||||||
|
(is (= 2 (u/first-index (partial = :test)
|
||||||
|
'(:a :b :test :c :test))))
|
||||||
|
(is (= nil (u/first-index (partial = :test)
|
||||||
|
'(:a :b :c)))))
|
||||||
|
|
||||||
|
(deftest hash-tag?-test
|
||||||
|
(is (u/hash-tag? "#clojure"))
|
||||||
|
(is (not (u/hash-tag? "clojure")))
|
||||||
|
(is (not (u/hash-tag? "clo#jure")))
|
||||||
|
(is (not (u/hash-tag? "clojure#"))))
|
||||||
|
|
||||||
|
(deftest update-if-present-test
|
||||||
|
(is (= {:a 1} (u/update-if-present {:a 0} :a inc)))
|
||||||
|
(is (= {:a 2} (u/update-if-present {:a 0} :a + 2)))
|
||||||
|
(is (= {:a 0} (u/update-if-present {:a 0} :b inc))))
|
||||||
|
|
Loading…
Reference in New Issue