mirror of
https://github.com/status-im/status-mobile.git
synced 2025-01-12 09:44:13 +00:00
[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",
|
"web3",
|
||||||
"eccjs",
|
"eccjs",
|
||||||
"chance",
|
"chance",
|
||||||
"react-native-autolink",
|
|
||||||
"instabug-reactnative",
|
"instabug-reactnative",
|
||||||
"nfc-react-native",
|
"nfc-react-native",
|
||||||
"react-native-http-bridge",
|
"react-native-http-bridge",
|
||||||
|
14
package-lock.json
generated
14
package-lock.json
generated
@ -401,11 +401,6 @@
|
|||||||
"resolved": "https://registry.npmjs.org/atob/-/atob-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/atob/-/atob-2.0.3.tgz",
|
||||||
"integrity": "sha1-GcenYEc3dEaPILLS0DNyrX1Mv10="
|
"integrity": "sha1-GcenYEc3dEaPILLS0DNyrX1Mv10="
|
||||||
},
|
},
|
||||||
"autolinker": {
|
|
||||||
"version": "1.6.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/autolinker/-/autolinker-1.6.0.tgz",
|
|
||||||
"integrity": "sha1-utN2t62OQV8i8QL8Dzf2QOZPHL8="
|
|
||||||
},
|
|
||||||
"aws-sign2": {
|
"aws-sign2": {
|
||||||
"version": "0.7.0",
|
"version": "0.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
|
||||||
@ -6882,15 +6877,6 @@
|
|||||||
"prop-types": "15.6.0"
|
"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": {
|
"react-native-background-timer": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-native-background-timer/-/react-native-background-timer-2.0.0.tgz",
|
"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-dom": "16.2.0",
|
||||||
"react-native": "0.51.0",
|
"react-native": "0.51.0",
|
||||||
"react-native-action-button": "2.8.1",
|
"react-native-action-button": "2.8.1",
|
||||||
"react-native-autolink": "1.1.1",
|
|
||||||
"react-native-background-timer": "2.0.0",
|
"react-native-background-timer": "2.0.0",
|
||||||
"react-native-camera": "0.10.0",
|
"react-native-camera": "0.10.0",
|
||||||
"react-native-config": "0.9.0",
|
"react-native-config": "0.9.0",
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
(ns status-im.react-native.js-dependencies)
|
(ns status-im.react-native.js-dependencies)
|
||||||
|
|
||||||
(def action-button (js/require "react-native-action-button"))
|
(def action-button (js/require "react-native-action-button"))
|
||||||
(def autolink (js/require "react-native-autolink"))
|
|
||||||
(def camera (js/require "react-native-camera"))
|
(def camera (js/require "react-native-camera"))
|
||||||
(def config (js/require "react-native-config"))
|
(def config (js/require "react-native-config"))
|
||||||
(def dialogs (js/require "react-native-dialogs"))
|
(def dialogs (js/require "react-native-dialogs"))
|
||||||
|
@ -14,10 +14,12 @@
|
|||||||
[status-im.chat.views.message.request-message :as request-message]
|
[status-im.chat.views.message.request-message :as request-message]
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]
|
[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.identicon :as identicon]
|
||||||
[status-im.utils.gfycat.core :as gfycat]
|
[status-im.utils.gfycat.core :as gfycat]
|
||||||
[status-im.utils.platform :as platform]
|
[status-im.utils.platform :as platform]
|
||||||
[status-im.i18n :as i18n]
|
[status-im.i18n :as i18n]
|
||||||
|
[status-im.ui.components.colors :as colors]
|
||||||
[clojure.string :as string]
|
[clojure.string :as string]
|
||||||
[status-im.chat.events.console :as console]
|
[status-im.chat.events.console :as console]
|
||||||
[taoensso.timbre :as log]))
|
[taoensso.timbre :as log]))
|
||||||
@ -65,7 +67,7 @@
|
|||||||
|
|
||||||
(defview message-content-command
|
(defview message-content-command
|
||||||
[{:keys [content params] :as message}]
|
[{:keys [content params] :as message}]
|
||||||
(letsubs [command [:get-command (:content-command-ref content)]]
|
(letsubs [command [:get-command (:content-command-ref content)]]
|
||||||
(let [preview (:preview content)
|
(let [preview (:preview content)
|
||||||
{:keys [type color] icon-path :icon} command]
|
{:keys [type color] icon-path :icon} command]
|
||||||
[react/view style/content-command-view
|
[react/view style/content-command-view
|
||||||
@ -96,7 +98,49 @@
|
|||||||
{"\\*[^*]+\\*" {:font-weight :bold}
|
{"\\*[^*]+\\*" {:font-weight :bold}
|
||||||
"~[^~]+~" {:font-style :italic}})
|
"~[^~]+~" {: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]
|
(defn get-style [string]
|
||||||
(->> replacements
|
(->> replacements
|
||||||
@ -108,37 +152,29 @@
|
|||||||
replacements))
|
replacements))
|
||||||
|
|
||||||
;; todo rewrite this, naive implementation
|
;; todo rewrite this, naive implementation
|
||||||
(defn- parse-text [string]
|
(defn- parse-text [string url-on-press]
|
||||||
(if (string? string)
|
(parse-str-regx string
|
||||||
(let [general-text (string/split string regx)
|
regx-styled
|
||||||
general-text' (if (zero? (count general-text))
|
(fn [text-seq]
|
||||||
[nil]
|
(map-indexed (fn [idx string]
|
||||||
general-text)
|
(let [style (get-style string)]
|
||||||
styled-text (vec (map-indexed (fn [idx string]
|
[react/text
|
||||||
(let [style (get-style string)]
|
{:key (str idx "_" string)
|
||||||
[react/text
|
:style style}
|
||||||
{:key (str idx "_" string)
|
(subs string 1 (dec (count string)))]))
|
||||||
:style style}
|
text-seq))
|
||||||
(subs string 1 (dec (count string)))]))
|
(fn [text-seq]
|
||||||
(re-seq regx string)))
|
(map-indexed (fn [idx string]
|
||||||
styled-text' (if (> (count general-text)
|
(apply react/text
|
||||||
(count styled-text))
|
{:key (str idx "_" string)}
|
||||||
(conj styled-text nil)
|
(autolink string url-on-press)))
|
||||||
styled-text)]
|
text-seq))))
|
||||||
(mapcat vector general-text' styled-text'))
|
|
||||||
(str string)))
|
|
||||||
|
|
||||||
(defn text-message
|
(defn text-message
|
||||||
[{:keys [content] :as message}]
|
[{:keys [content] :as message}]
|
||||||
[message-view message
|
[message-view message
|
||||||
(let [parsed-text (parse-text content)
|
(let [parsed-text (parse-text content #(re-frame/dispatch [:browse-link-from-message %]))]
|
||||||
simple-text? (and (= (count parsed-text) 2)
|
[react/text {:style (style/text-message message)} parsed-text])])
|
||||||
(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]))])
|
|
||||||
|
|
||||||
(defmulti message-content (fn [_ message _] (message :content-type)))
|
(defmulti message-content (fn [_ message _] (message :content-type)))
|
||||||
|
|
||||||
|
@ -160,15 +160,6 @@
|
|||||||
(let [clipboard-contents (.getString (.-Clipboard js-dependencies/react-native))]
|
(let [clipboard-contents (.getString (.-Clipboard js-dependencies/react-native))]
|
||||||
(.then clipboard-contents #(clbk %))))
|
(.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
|
;; HTTP Bridge
|
||||||
|
|
||||||
(def http-bridge js-dependencies/http-bridge)
|
(def http-bridge js-dependencies/http-bridge)
|
||||||
|
@ -3,11 +3,19 @@
|
|||||||
|
|
||||||
(defn truncate-str
|
(defn truncate-str
|
||||||
"Given string and max threshold, trims the string to threshold length with `...`
|
"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
|
appended to end or in the middle if length of the string exceeds max threshold,
|
||||||
string if threshold is not exceeded"
|
returns the same string if threshold is not exceeded"
|
||||||
[s threshold]
|
[s threshold & [middle?]]
|
||||||
(if (and s (< threshold (count s)))
|
(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))
|
s))
|
||||||
|
|
||||||
(defn clean-text [s]
|
(defn clean-text [s]
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
(ns status-im.react-native.js-dependencies)
|
(ns status-im.react-native.js-dependencies)
|
||||||
|
|
||||||
(def action-button #js {:default #js {:Item #js {}}})
|
(def action-button #js {:default #js {:Item #js {}}})
|
||||||
(def autolink #js {:default #js {}})
|
|
||||||
(def config #js {:default #js {}})
|
(def config #js {:default #js {}})
|
||||||
(def camera #js {:constants #js {}})
|
(def camera #js {:constants #js {}})
|
||||||
(def dialogs #js {})
|
(def dialogs #js {})
|
||||||
|
20
test/cljs/status_im/test/chat/views/message.cljs
Normal file
20
test/cljs/status_im/test/chat/views/message.cljs
Normal file
@ -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.profile.events]
|
||||||
[status-im.test.bots.events]
|
[status-im.test.bots.events]
|
||||||
[status-im.test.chat.models.input]
|
[status-im.test.chat.models.input]
|
||||||
|
[status-im.test.chat.views.message]
|
||||||
[status-im.test.i18n]
|
[status-im.test.i18n]
|
||||||
[status-im.test.protocol.web3.inbox]
|
[status-im.test.protocol.web3.inbox]
|
||||||
[status-im.test.utils.utils]
|
[status-im.test.utils.utils]
|
||||||
@ -43,6 +44,7 @@
|
|||||||
'status-im.test.wallet.transactions.subs
|
'status-im.test.wallet.transactions.subs
|
||||||
'status-im.test.wallet.transactions.views
|
'status-im.test.wallet.transactions.views
|
||||||
'status-im.test.chat.models.input
|
'status-im.test.chat.models.input
|
||||||
|
'status-im.test.chat.views.message
|
||||||
'status-im.test.i18n
|
'status-im.test.i18n
|
||||||
'status-im.test.protocol.web3.inbox
|
'status-im.test.protocol.web3.inbox
|
||||||
'status-im.test.utils.utils
|
'status-im.test.utils.utils
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
(deftest truncate-str-test
|
(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) "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" 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
|
(is (= (u/truncate-str "Long string" 20) "Long string"))) ; threshold is more then string length
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user