[Fix #3252] Remove dependency on react-native-autolink
Signed-off-by: Julien Eluard <julien.eluard@gmail.com>
This commit is contained in:
parent
6bde9828cb
commit
c1900a24ec
|
@ -37,7 +37,6 @@
|
|||
"web3",
|
||||
"eccjs",
|
||||
"chance",
|
||||
"react-native-autolink",
|
||||
"instabug-reactnative",
|
||||
"nfc-react-native",
|
||||
"react-native-http-bridge",
|
||||
|
|
|
@ -401,11 +401,6 @@
|
|||
"resolved": "https://registry.npmjs.org/atob/-/atob-2.0.3.tgz",
|
||||
"integrity": "sha1-GcenYEc3dEaPILLS0DNyrX1Mv10="
|
||||
},
|
||||
"autolinker": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/autolinker/-/autolinker-1.6.0.tgz",
|
||||
"integrity": "sha1-utN2t62OQV8i8QL8Dzf2QOZPHL8="
|
||||
},
|
||||
"aws-sign2": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
|
||||
|
@ -6882,15 +6877,6 @@
|
|||
"prop-types": "15.6.0"
|
||||
}
|
||||
},
|
||||
"react-native-autolink": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-autolink/-/react-native-autolink-1.1.1.tgz",
|
||||
"integrity": "sha512-h11oWD1x0Z1ar0W493tpXJ8hMofpcm21xg3wPFIy5r4CvsRlWNMBp9iG+4jeYqCNAQcDHHeu5yO+NJVaWffXZg==",
|
||||
"requires": {
|
||||
"autolinker": "1.6.0",
|
||||
"prop-types": "15.6.0"
|
||||
}
|
||||
},
|
||||
"react-native-background-timer": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-background-timer/-/react-native-background-timer-2.0.0.tgz",
|
||||
|
|
|
@ -47,7 +47,6 @@
|
|||
"react-dom": "16.2.0",
|
||||
"react-native": "0.51.0",
|
||||
"react-native-action-button": "2.8.1",
|
||||
"react-native-autolink": "1.1.1",
|
||||
"react-native-background-timer": "2.0.0",
|
||||
"react-native-camera": "0.10.0",
|
||||
"react-native-config": "0.9.0",
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
(ns status-im.react-native.js-dependencies)
|
||||
|
||||
(def action-button (js/require "react-native-action-button"))
|
||||
(def autolink (js/require "react-native-autolink"))
|
||||
(def camera (js/require "react-native-camera"))
|
||||
(def config (js/require "react-native-config"))
|
||||
(def dialogs (js/require "react-native-dialogs"))
|
||||
|
|
|
@ -14,10 +14,12 @@
|
|||
[status-im.chat.views.message.request-message :as request-message]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]
|
||||
[status-im.utils.core :as utils]
|
||||
[status-im.utils.identicon :as identicon]
|
||||
[status-im.utils.gfycat.core :as gfycat]
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[clojure.string :as string]
|
||||
[status-im.chat.events.console :as console]
|
||||
[taoensso.timbre :as log]))
|
||||
|
@ -96,7 +98,49 @@
|
|||
{"\\*[^*]+\\*" {:font-weight :bold}
|
||||
"~[^~]+~" {:font-style :italic}})
|
||||
|
||||
(def regx (re-pattern (string/join "|" (map first replacements))))
|
||||
(def regx-styled (re-pattern (string/join "|" (map first replacements))))
|
||||
|
||||
(def regx-url #"(?i)(?:[a-z][\w-]+:(?:/{1,3}|[a-z0-9%])|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{1,4}/?)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:\'\".,<>?«»“”‘’]){0,}")
|
||||
|
||||
(defn- parse-str-regx [string regx matched-fn unmatched-fn]
|
||||
(if (string? string)
|
||||
(let [unmatched-text (as-> (->> (string/split string regx)
|
||||
(remove empty?)
|
||||
vec) $
|
||||
(if (zero? (count $))
|
||||
[nil]
|
||||
(unmatched-fn $)))
|
||||
matched-text (as-> (->> string
|
||||
(re-seq regx)
|
||||
matched-fn
|
||||
vec) $
|
||||
(if (> (count unmatched-text)
|
||||
(count $))
|
||||
(conj $ nil)
|
||||
$))]
|
||||
(mapcat vector unmatched-text matched-text))
|
||||
(str string)))
|
||||
|
||||
(defn parse-url [string]
|
||||
(parse-str-regx string
|
||||
regx-url
|
||||
(fn [text-seq]
|
||||
(map (fn [[text]] {:text text :url? true}) text-seq))
|
||||
(fn [text-seq]
|
||||
(map (fn [text] {:text text :url? false}) text-seq))))
|
||||
|
||||
(defn- autolink [string on-press]
|
||||
(->> (parse-url string)
|
||||
(map-indexed (fn [idx {:keys [text url?]}]
|
||||
(if url?
|
||||
(let [[url _ _ _ text] (re-matches #"(?i)^((\w+://)?(www\d{0,3}[.])?)?(.*)$" text)]
|
||||
[react/text
|
||||
{:key idx
|
||||
:style {:color colors/blue}
|
||||
:on-press #(on-press url)}
|
||||
(utils/truncate-str text 32 true)])
|
||||
text)))
|
||||
vec))
|
||||
|
||||
(defn get-style [string]
|
||||
(->> replacements
|
||||
|
@ -108,37 +152,29 @@
|
|||
replacements))
|
||||
|
||||
;; todo rewrite this, naive implementation
|
||||
(defn- parse-text [string]
|
||||
(if (string? string)
|
||||
(let [general-text (string/split string regx)
|
||||
general-text' (if (zero? (count general-text))
|
||||
[nil]
|
||||
general-text)
|
||||
styled-text (vec (map-indexed (fn [idx string]
|
||||
(defn- parse-text [string url-on-press]
|
||||
(parse-str-regx string
|
||||
regx-styled
|
||||
(fn [text-seq]
|
||||
(map-indexed (fn [idx string]
|
||||
(let [style (get-style string)]
|
||||
[react/text
|
||||
{:key (str idx "_" string)
|
||||
:style style}
|
||||
(subs string 1 (dec (count string)))]))
|
||||
(re-seq regx string)))
|
||||
styled-text' (if (> (count general-text)
|
||||
(count styled-text))
|
||||
(conj styled-text nil)
|
||||
styled-text)]
|
||||
(mapcat vector general-text' styled-text'))
|
||||
(str string)))
|
||||
text-seq))
|
||||
(fn [text-seq]
|
||||
(map-indexed (fn [idx string]
|
||||
(apply react/text
|
||||
{:key (str idx "_" string)}
|
||||
(autolink string url-on-press)))
|
||||
text-seq))))
|
||||
|
||||
(defn text-message
|
||||
[{:keys [content] :as message}]
|
||||
[message-view message
|
||||
(let [parsed-text (parse-text content)
|
||||
simple-text? (and (= (count parsed-text) 2)
|
||||
(nil? (second parsed-text)))]
|
||||
(if simple-text?
|
||||
[react/autolink {:style (style/text-message message)
|
||||
:text (apply str parsed-text)
|
||||
:onPress #(re-frame/dispatch [:browse-link-from-message %])}]
|
||||
[react/text {:style (style/text-message message)} parsed-text]))])
|
||||
(let [parsed-text (parse-text content #(re-frame/dispatch [:browse-link-from-message %]))]
|
||||
[react/text {:style (style/text-message message)} parsed-text])])
|
||||
|
||||
(defmulti message-content (fn [_ message _] (message :content-type)))
|
||||
|
||||
|
|
|
@ -160,15 +160,6 @@
|
|||
(let [clipboard-contents (.getString (.-Clipboard js-dependencies/react-native))]
|
||||
(.then clipboard-contents #(clbk %))))
|
||||
|
||||
|
||||
;; Autolink
|
||||
|
||||
(def autolink-class (reagent/adapt-react-class (.-default js-dependencies/autolink)))
|
||||
|
||||
(defn autolink [opts]
|
||||
(reagent/as-element
|
||||
[autolink-class (add-font-style :style opts)]))
|
||||
|
||||
;; HTTP Bridge
|
||||
|
||||
(def http-bridge js-dependencies/http-bridge)
|
||||
|
|
|
@ -3,11 +3,19 @@
|
|||
|
||||
(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]
|
||||
appended to end or in the middle if length of the string exceeds max threshold,
|
||||
returns the same string if threshold is not exceeded"
|
||||
[s threshold & [middle?]]
|
||||
(if (and s (< threshold (count s)))
|
||||
(str (subs s 0 (- threshold 3)) "...")
|
||||
(if middle?
|
||||
(let [str-len (count s)
|
||||
max-len (- threshold 3)
|
||||
start-len (Math/ceil (/ max-len 2))
|
||||
end-len (Math/floor (/ max-len 2))
|
||||
start (subs s 0 start-len)
|
||||
end (subs s (- str-len end-len) str-len)]
|
||||
(str start "..." end))
|
||||
(str (subs s 0 (- threshold 3)) "..."))
|
||||
s))
|
||||
|
||||
(defn clean-text [s]
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
(ns status-im.react-native.js-dependencies)
|
||||
|
||||
(def action-button #js {:default #js {:Item #js {}}})
|
||||
(def autolink #js {:default #js {}})
|
||||
(def config #js {:default #js {}})
|
||||
(def camera #js {:constants #js {}})
|
||||
(def dialogs #js {})
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
(ns status-im.test.chat.views.message
|
||||
(:require [cljs.test :refer [deftest is]]
|
||||
[status-im.chat.views.message.message :as message]))
|
||||
|
||||
(deftest parse-url
|
||||
(is (= (lazy-seq [nil {:text "www.google.com" :url? true}])
|
||||
(message/parse-url "www.google.com")))
|
||||
(is (= (lazy-seq [nil {:text "status.im" :url? true}])
|
||||
(message/parse-url "status.im")))
|
||||
(is (= (lazy-seq [{:text "$33.90" :url? false} nil])
|
||||
(message/parse-url "$33.90")))
|
||||
(is (= (lazy-seq [nil {:text "https://www.google.com/?gfe_rd=cr&dcr=0&ei=P9-CWuyBGaro8AeqkYGQDQ&gws_rd=cr&fg=1" :url? true}])
|
||||
(message/parse-url "https://www.google.com/?gfe_rd=cr&dcr=0&ei=P9-CWuyBGaro8AeqkYGQDQ&gws_rd=cr&fg=1")))
|
||||
(is (= (lazy-seq [{:text "Status - " :url? false}
|
||||
{:text "https://github.com/status-im/status-react" :url? true}
|
||||
{:text " a Mobile Ethereum Operating System" :url? false}
|
||||
nil])
|
||||
(message/parse-url "Status - https://github.com/status-im/status-react a Mobile Ethereum Operating System")))
|
||||
(is (= (lazy-seq [{:text "Browse, chat and make payments securely on the decentralized web." :url? false} nil])
|
||||
(message/parse-url "Browse, chat and make payments securely on the decentralized web."))))
|
|
@ -9,6 +9,7 @@
|
|||
[status-im.test.profile.events]
|
||||
[status-im.test.bots.events]
|
||||
[status-im.test.chat.models.input]
|
||||
[status-im.test.chat.views.message]
|
||||
[status-im.test.i18n]
|
||||
[status-im.test.protocol.web3.inbox]
|
||||
[status-im.test.utils.utils]
|
||||
|
@ -43,6 +44,7 @@
|
|||
'status-im.test.wallet.transactions.subs
|
||||
'status-im.test.wallet.transactions.views
|
||||
'status-im.test.chat.models.input
|
||||
'status-im.test.chat.views.message
|
||||
'status-im.test.i18n
|
||||
'status-im.test.protocol.web3.inbox
|
||||
'status-im.test.utils.utils
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
(deftest truncate-str-test
|
||||
(is (= (u/truncate-str "Long string" 7) "Long...")) ; threshold is less then string length
|
||||
(is (= (u/truncate-str "Long string" 7 true) "Lo...ng")) ; threshold is less then string length (truncate middle)
|
||||
(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
|
||||
|
||||
|
|
Loading…
Reference in New Issue