Skip to content

Commit

Permalink
First cut of diff-text viewer
Browse files Browse the repository at this point in the history
  • Loading branch information
djblue committed Aug 28, 2024
1 parent c9de620 commit d696bd7
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/portal/ui/app.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
[portal.ui.viewer.date-time :as date-time]
[portal.ui.viewer.deref :as deref]
[portal.ui.viewer.diff :as diff]
[portal.ui.viewer.diff-text :as diff-text]
[portal.ui.viewer.duration :as duration]
[portal.ui.viewer.edn :as edn]
[portal.ui.viewer.exception :as ex]
Expand Down Expand Up @@ -489,6 +490,7 @@
csv/viewer
html/viewer
diff/viewer
diff-text/viewer
md/viewer
hiccup/viewer
date-time/viewer
Expand Down
124 changes: 124 additions & 0 deletions src/portal/ui/viewer/diff_text.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
(ns portal.ui.viewer.diff-text
(:require ["diff" :as df]
[clojure.string :as str]
[portal.colors :as c]
[portal.ui.icons :as icons]
[portal.ui.inspector :as ins]
[portal.ui.lazy :as l]
[portal.ui.styled :as d]
[portal.ui.theme :as theme]))

(defn- changed? [^js item]
(or (some-> item .-added)
(some-> item .-removed)))

(defn- inspect-text-diff [value]
(let [theme (theme/use-theme)
add (::c/diff-add theme)
remove (::c/diff-remove theme)
diff (df/diffLines (or (:- value) (first value))
(or (:+ value) (second value)))
opts (ins/use-options)
bg (ins/get-background)]
[:pre
{:style {:margin 0 :white-space :pre-wrap :background bg}}
[d/div
{:style {:height (:padding theme)
:padding-left (:padding theme)
:border-top [1 :solid (::c/border theme)]
:border-left [5 :solid (::c/border theme)]
:border-right [1 :solid (::c/border theme)]
:border-top-left-radius (:border-radius theme)
:border-top-right-radius (:border-radius theme)}}]
[l/lazy-seq
(map-indexed
(fn [index [before item after]]
(let [added (.-added item)
removed (.-removed item)
text (.-value item)
border-color (cond
added add
removed remove
:else (::c/border theme))]
^{:key index}
[d/div
{:style
{:position :relative
:border-left [5 :solid border-color]
:border-right [1 :solid border-color]
:padding [0 (:padding theme)]}}
(when (or removed added)
[d/div {:style {:position :absolute
:top 0
:left 0
:right 0
:bottom 0
:opacity 0.20
:background (cond added add
removed remove)}}])
(if-not (or removed added)
(if (:expanded? opts)
[ins/highlight-words text]
(let [lines (str/split-lines text)]
(if (< (count lines) 6)
[ins/highlight-words text]
[:<>
(when before
[:<>
[ins/highlight-words (str/join "\n" (take 3 lines))]
[d/div {:style {:background (::c/border theme)
:padding (:padding theme)
:text-align :center}}
[icons/ellipsis-h]]])
(when after
[:<>
[d/div {:style {:background (::c/border theme)
:padding (:padding theme)
:text-align :center}}
[icons/ellipsis-h]]
[ins/highlight-words (str/join "\n" (take-last 3 lines))]])])))
(cond (changed? before)
(keep-indexed
(fn [idx ^js item]
(when (or (.-added item) (not (.-removed item)))
^{:key idx}
[d/span {:style {:background (when (.-added item)
(if added
(str add "66")
(str remove "66")))}}
[ins/highlight-words (.-value item)]]))
(df/diffChars (.-value before) text))
(changed? after)
(keep-indexed
(fn [idx ^js item]
(when (or (.-added item) (not (.-removed item)))
^{:key idx}
[d/span {:style {:background (when (.-added item)
(if added
(str add "66")
(str remove "66")))}}
[ins/highlight-words (.-value item)]]))
(df/diffChars (.-value after) text))
:else text))

(when (or removed added) "\n")]))
(partition 3 1 (concat [nil] diff [nil])))]
[d/div
{:style {:height (:padding theme)
:padding-left (:padding theme)
:border-bottom [1 :solid (::c/border theme)]
:border-left [5 :solid (::c/border theme)]
:border-right [1 :solid (::c/border theme)]
:border-bottom-left-radius (:border-radius theme)
:border-bottom-right-radius (:border-radius theme)}}]]))

(defn- text-diff? [value]
(and (coll? value)
(string? (first value))
(string? (second value))))

(def viewer
{:predicate text-diff?
:component inspect-text-diff
:name :portal.viewer/diff-text
:doc "Diff two strings."})

0 comments on commit d696bd7

Please sign in to comment.