Subheader generation refactored for better performance

Signed-off-by: Volodymyr Kozieiev <vkjr.sp@gmail.com>
This commit is contained in:
Volodymyr Kozieiev 2020-08-19 17:04:03 +03:00
parent f17b401bbc
commit 6bef1182c6
No known key found for this signature in database
GPG Key ID: 82B04968DF4C0535
1 changed files with 43 additions and 37 deletions

View File

@ -20,53 +20,59 @@
(letsubs [contact-name [:contacts/contact-name-by-identity from]] (letsubs [contact-name [:contacts/contact-name-by-identity from]]
contact-name)) contact-name))
(defn render-subheader-inline [acc {:keys [type destination literal children]}] ;; if truncated subheader text is too short we won't get ellipsize at the end of text
(case type (def max-subheader-length 100)
"paragraph"
(conj acc (reduce
(fn [acc e] (render-subheader-inline acc e))
[react/text-class " "]
children))
"blockquote" (defn truncate-literal [literal]
(conj acc (.substring literal 0 (dec (.-length literal)))) (let [size (min max-subheader-length (.-length literal))]
{:components (.substring literal 0 size)
:length size}))
"codeblock" (defn add-parsed-to-subheader [acc {:keys [type destination literal children]}]
(conj acc (.substring literal 0 (dec (.-length literal)))) (let [result (case type
"paragraph"
(reduce
(fn [{:keys [_ length] :as acc-paragraph} parsed-child]
(if (>= length max-subheader-length)
(reduced acc-paragraph)
(add-parsed-to-subheader acc-paragraph parsed-child)))
{:components [react/text-class]
:length 0}
children)
"mention" "mention"
(conj acc [react/text-class {:components [react/text-class [mention-element literal]]
[mention-element literal]]) :length 4} ;; we can't predict name length so take the smallest possible
"status-tag" "status-tag"
(conj acc [react/text-class (truncate-literal (str "#" literal))
"#"
literal])
"link" "link"
(conj acc destination) (truncate-literal destination)
(conj acc literal))) (truncate-literal literal))]
{:components (conj (:components acc) (:components result))
:length (+ (:length acc) (:length result))}))
(def max-length 40) (def subheader-wrapper
[react/text-class {:style styles/last-message-text
:number-of-lines 1
:ellipsize-mode :tail
:accessibility-label :chat-message-text}])
(defn render-subheader (defn render-subheader
"Render the chat subheader markdown inline, to a maximum of max-length characters" "Render the preview of a last message to a maximum of max-subheader-length characters"
[parsed-text] [parsed-text]
(:elements (let [result
(reduce (reduce
(fn [{:keys [elements l] :as acc} {:keys [literal] :as e}] (fn [{:keys [_ length] :as acc-text} new-text-chunk]
(if (> l max-length) (if (>= length max-subheader-length)
(reduced acc) (reduced acc-text)
{:elements (render-subheader-inline elements e) (add-parsed-to-subheader acc-text new-text-chunk)))
:l (+ l (count literal))})) {:components subheader-wrapper
{:length 0 :length 0}
:elements parsed-text)]
[react/text-class {:style styles/last-message-text (:components result)))
:number-of-lines 1
:ellipsize-mode :tail
:accessibility-label :chat-message-text}]}
parsed-text)))
(defn message-content-text [{:keys [content content-type]}] (defn message-content-text [{:keys [content content-type]}]
[:<> [:<>