2016-05-19 18:31:56 +02:00
|
|
|
(ns status-im.utils.utils
|
2016-10-19 15:22:05 +03:00
|
|
|
(:require [status-im.constants :as const]
|
2017-05-13 00:44:17 +02:00
|
|
|
[status-im.i18n :refer [label]]
|
2016-11-21 15:45:44 +03:00
|
|
|
[reagent.core :as r]
|
2017-07-16 12:04:35 +03:00
|
|
|
[clojure.string :as str]
|
|
|
|
[taoensso.timbre :as log]
|
|
|
|
[status-im.react-native.js-dependencies :as rn-dependencies]))
|
2016-03-27 17:59:03 +03:00
|
|
|
|
2016-09-16 18:30:19 +03:00
|
|
|
(defn show-popup [title content]
|
2017-07-16 12:04:35 +03:00
|
|
|
(.alert (.-Alert rn-dependencies/react-native)
|
2016-09-16 18:30:19 +03:00
|
|
|
title
|
|
|
|
content))
|
2016-03-27 17:59:03 +03:00
|
|
|
|
2017-05-13 00:44:17 +02:00
|
|
|
(defn show-confirmation
|
|
|
|
([title content on-accept]
|
|
|
|
(show-confirmation title content nil on-accept))
|
|
|
|
([title content s on-accept]
|
|
|
|
(show-confirmation title content s on-accept nil))
|
|
|
|
([title content s on-accept on-cancel]
|
2017-07-16 12:04:35 +03:00
|
|
|
(.alert (.-Alert rn-dependencies/react-native)
|
2017-05-13 00:44:17 +02:00
|
|
|
title
|
|
|
|
content
|
2017-07-20 13:59:57 +02:00
|
|
|
;; Styles are only relevant on iOS. On Android first button is 'neutral' and second is 'positive'
|
2017-05-13 00:44:17 +02:00
|
|
|
(clj->js
|
2017-07-20 13:59:57 +02:00
|
|
|
(vector (merge {:text (label :t/cancel) :style "cancel"}
|
|
|
|
(when on-cancel {:onPress on-cancel}))
|
|
|
|
{:text (or s "OK") :onPress on-accept :style "destructive"})))))
|
2017-05-13 00:44:17 +02:00
|
|
|
|
2016-03-27 17:59:03 +03:00
|
|
|
(defn http-post
|
|
|
|
([action data on-success]
|
|
|
|
(http-post action data on-success nil))
|
|
|
|
([action data on-success on-error]
|
|
|
|
(-> (.fetch js/window
|
2016-03-28 15:14:57 +03:00
|
|
|
(str const/server-address action)
|
2016-03-27 17:59:03 +03:00
|
|
|
(clj->js {:method "POST"
|
|
|
|
:headers {:accept "application/json"
|
|
|
|
:content-type "application/json"}
|
|
|
|
:body (.stringify js/JSON (clj->js data))}))
|
|
|
|
(.then (fn [response]
|
2017-07-16 12:04:35 +03:00
|
|
|
(log/debug response)
|
2016-03-27 17:59:03 +03:00
|
|
|
(.text response)))
|
|
|
|
(.then (fn [text]
|
|
|
|
(let [json (.parse js/JSON text)
|
|
|
|
obj (js->clj json :keywordize-keys true)]
|
|
|
|
(on-success obj))))
|
|
|
|
(.catch (or on-error
|
|
|
|
(fn [error]
|
2016-09-16 18:30:19 +03:00
|
|
|
(show-popup "Error" (str error))))))))
|
2016-04-14 12:49:50 +03:00
|
|
|
|
|
|
|
(defn http-get
|
2016-06-08 15:14:35 +03:00
|
|
|
([url on-success on-error]
|
2017-07-20 13:59:57 +02:00
|
|
|
(http-get url nil on-success on-error))
|
2017-03-08 15:53:21 +02:00
|
|
|
([url valid-response? on-success on-error]
|
2017-05-16 16:24:51 +03:00
|
|
|
(-> (.fetch js/window url (clj->js {:method "GET"
|
|
|
|
:headers {"Cache-Control" "no-cache"}}))
|
2016-04-14 12:49:50 +03:00
|
|
|
(.then (fn [response]
|
2017-07-16 12:04:35 +03:00
|
|
|
(log/debug response)
|
2017-03-08 15:53:21 +02:00
|
|
|
(let [ok? (.-ok response)
|
|
|
|
ok?' (if valid-response?
|
|
|
|
(and ok? (valid-response? response))
|
|
|
|
ok?)]
|
2017-04-13 12:37:03 +03:00
|
|
|
[(.-_bodyText response) ok?'])))
|
2017-03-07 12:36:13 +02:00
|
|
|
(.then (fn [[response ok?]]
|
|
|
|
(cond
|
|
|
|
ok? (on-success response)
|
|
|
|
|
|
|
|
(and on-error (not ok?))
|
|
|
|
(on-error response)
|
|
|
|
|
|
|
|
:else false)))
|
2016-04-14 12:49:50 +03:00
|
|
|
(.catch (or on-error
|
|
|
|
(fn [error]
|
2016-09-16 18:30:19 +03:00
|
|
|
(show-popup "Error" (str error))))))))
|
2016-05-20 16:36:00 +03:00
|
|
|
|
2017-07-20 13:59:57 +02:00
|
|
|
(defn truncate-str
|
|
|
|
"Given string and max threshold, trims the string to threshold length with `...`
|
|
|
|
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)) "...")
|
2016-05-20 16:36:00 +03:00
|
|
|
s))
|
2016-08-04 18:36:13 +03:00
|
|
|
|
2016-11-21 15:45:44 +03:00
|
|
|
(defn clean-text [s]
|
|
|
|
(-> s
|
2016-11-30 21:30:57 +03:00
|
|
|
(str/replace #"\n" "")
|
2016-11-21 15:45:44 +03:00
|
|
|
(str/replace #"\r" "")
|
|
|
|
(str/trim)))
|
|
|
|
|
2016-08-04 18:36:13 +03:00
|
|
|
(defn first-index
|
2017-07-20 13:59:57 +02:00
|
|
|
"Returns first index in coll where predicate on coll element is truthy"
|
|
|
|
[pred coll]
|
|
|
|
(->> coll
|
|
|
|
(keep-indexed (fn [idx e]
|
|
|
|
(when (pred e)
|
|
|
|
idx)))
|
|
|
|
first))
|
2016-10-19 15:22:05 +03:00
|
|
|
|
2017-07-01 18:19:31 +08:00
|
|
|
(defn hash-tag? [s]
|
|
|
|
(= \# (first s)))
|
2017-07-23 23:24:27 +02:00
|
|
|
|
|
|
|
(defn wrap-call-once!
|
|
|
|
"Returns a version of provided function that will be called only the first time wrapping function is called. Returns nil."
|
|
|
|
[f]
|
|
|
|
(let [called? (volatile! false)]
|
|
|
|
(fn [& args]
|
|
|
|
(when-not @called?
|
|
|
|
(vreset! called? true)
|
|
|
|
(apply f args)
|
|
|
|
nil))))
|
2017-07-20 13:59:57 +02:00
|
|
|
|
|
|
|
(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))
|
|
|
|
|
2017-07-17 00:23:53 +02:00
|
|
|
(defn default-alert-handler
|
|
|
|
[error fatal?]
|
|
|
|
(show-popup "Error" (.-message error)))
|
|
|
|
|
|
|
|
(defn register-exception-handler
|
|
|
|
"Register a function that will be called for each exception thrown.
|
|
|
|
When `dev?` is true, always register; otherwise only register when goog.DEBUG is false.
|
|
|
|
Default function shows error details in an alert box."
|
|
|
|
([] (register-exception-handler default-alert-handler))
|
|
|
|
([f] (register-exception-handler true f))
|
|
|
|
([dev? f]
|
2017-08-01 11:48:54 +03:00
|
|
|
(if (and dev? (not js/goog.DEBUG))
|
2017-07-17 00:23:53 +02:00
|
|
|
(.setGlobalHandler js/ErrorUtils f dev?))))
|