Skip to content

Commit 779ed18

Browse files
committed
Add :display-uuids-as setting
1 parent 2126148 commit 779ed18

File tree

8 files changed

+171
-15
lines changed

8 files changed

+171
-15
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
# Change Log
22
All notable changes to this project will be documented in this file. This change log follows the conventions of [keepachangelog.com](http://keepachangelog.com/).
33

4+
## 1.10.0 (2021-04-05)
5+
6+
#### Added
7+
8+
- "display-uuid-as" setting.
9+
UUIDs can be displayed as an identicon, or as the last 4 characters.
10+
411
## 1.9.10 (2024-10-23)
512

613
#### Changed

deps.edn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@
1111
cljsjs/highlight {:mvn/version "10.3.1-0"}
1212
org.clojure/tools.logging {:mvn/version "1.2.4"}
1313
mvxcvi/arrangement {:mvn/version "2.1.0"}}}
14+
;; Removed :npm-deps {identicon.js ...}

src/day8/re_frame_10x/components/cljs_devtools.cljs

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
[day8.re-frame-10x.panels.app-db.subs :as app-db.subs]
2424
[day8.re-frame-10x.tools.datafy :as tools.datafy]
2525
[day8.re-frame-10x.tools.reader.edn :as reader.edn]
26-
[day8.re-frame-10x.panels.settings.subs :as settings.subs]))
26+
[day8.re-frame-10x.panels.settings.subs :as settings.subs]
27+
[day8.re-frame-10x.tools.identicon :as identicon]))
2728

2829
(def initial-config @devtools.prefs/initial-config)
2930

@@ -184,6 +185,17 @@
184185
(reduce (fn [acc [property value]]
185186
(assoc acc (keyword property) value)) {})))
186187

188+
(defn uuid-string? [jsonml]
189+
(and (string? jsonml)
190+
(.startsWith jsonml "#uuid ")))
191+
192+
(defn uuid->hiccup [jsonml]
193+
[:span {:style {:display "inline-flex" :align-items "center"}
194+
:title (pr-str jsonml)}
195+
"#uuid " [identicon/svg jsonml]])
196+
197+
clojure.string/trim
198+
187199
(defn jsonml->hiccup
188200
"JSONML is the format used by Chrome's Custom Object Formatters.
189201
The spec is at https://docs.google.com/document/d/1FTascZXT9cxfetuPRT2eXPQKXui4nWFivUnS_335T3U/preview.
@@ -192,10 +204,18 @@
192204
be found at https://cs.chromium.org/chromium/src/third_party/WebKit/Source/devtools/front_end/object_ui/CustomPreviewComponent.js
193205
"
194206
[jsonml path]
195-
(if (number? jsonml)
196-
jsonml
207+
(cond
208+
(number? jsonml) jsonml
209+
(uuid-string? jsonml) (case @(rf/subscribe [::settings.subs/display-uuids-as])
210+
:last-4-chars (str "#uuid " (.substring jsonml
211+
(- (count jsonml) 5)
212+
(- (count jsonml) 1)))
213+
:identicons [uuid->hiccup jsonml]
214+
jsonml)
215+
(string? jsonml) jsonml ;; Handle non-UUID strings
216+
:else
197217
(let [[tag-name attributes & children] jsonml
198-
tagnames #{"div" "span" "ol" "li" "table" "tr" "td"}]
218+
tagnames #{"div" "span" "ol" "li" "table" "tr" "td"}]
199219
(cond
200220
(contains? tagnames tag-name) (into
201221
[(keyword tag-name) {:style (-> (js->clj attributes)
@@ -204,11 +224,11 @@
204224
(map-indexed (fn [i child] (jsonml->hiccup child (conj path i))))
205225
children)
206226

207-
(= tag-name "object") [data-structure jsonml path]
227+
(= tag-name "object") [data-structure jsonml path]
208228
(= tag-name "annotation") (into [:span {}]
209229
(map-indexed (fn [i child] (jsonml->hiccup child (conj path i))))
210230
children)
211-
:else jsonml))))
231+
:else jsonml))))
212232

213233
(defn jsonml->hiccup-with-path-annotations
214234
"JSONML is the format used by Chrome's Custom Object Formatters.
@@ -221,8 +241,16 @@
221241
:as opts}]
222242
;; indexed-path is updated on every html element such as `tagnames`
223243
;; while devtools-path is updated only when we encounter an element that contains the `:path` attribute.
224-
(if (number? jsonml)
225-
jsonml
244+
(cond
245+
(number? jsonml) jsonml
246+
(uuid-string? jsonml) (case @(rf/subscribe [::settings.subs/display-uuids-as])
247+
:last-4-chars (str "#uuid " (.substring jsonml
248+
(- (count jsonml) 5)
249+
(- (count jsonml) 1)))
250+
:identicons [uuid->hiccup jsonml]
251+
jsonml)
252+
(string? jsonml) jsonml
253+
:else
226254
(let [[tag-name attributes & children] jsonml
227255
tagnames #{"div" "span" "ol" "li" "table" "tr" "td"}]
228256
(cond

src/day8/re_frame_10x/events.cljs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,15 @@
5454
(rf/inject-cofx ::local-storage/load {:key "ns-aliases"
5555
:or (sortable-uuid-map [{:ns-full "long-namespace" :ns-alias "ln"}])})
5656
(rf/inject-cofx ::local-storage/load {:key "alias-namespaces?"})
57+
(rf/inject-cofx ::local-storage/load {:key "display-uuids-as"})
5758
rf/unwrap]
5859
(fn [{::local-storage/keys [stored fallback]} project-config]
5960
(let [{:keys [panel-width-ratio show-panel selected-tab filter-items app-db-json-ml-expansions
6061
external-window? external-window-dimensions show-epoch-traces? using-trace?
6162
ignored-events low-level-trace filtered-view-trace retained-epochs app-db-paths
6263
app-db-follows-events? ambiance syntax-color-scheme categories data-path-annotations?
6364
show-event-history open-new-inspectors? handle-keys? key-bindings log-outputs log-pretty?
64-
expansion-limit ns-aliases alias-namespaces? trace-when
65+
expansion-limit ns-aliases alias-namespaces? trace-when display-uuids-as
6566
debug?]}
6667
(merge fallback project-config stored)]
6768
{:fx [(when (or using-trace? (= :always trace-when))
@@ -98,7 +99,8 @@
9899
[:dispatch [::settings.events/log-pretty? log-pretty?]]
99100
[:dispatch [::settings.events/expansion-limit expansion-limit]]
100101
[:dispatch [::settings.events/ns-aliases ns-aliases]]
101-
[:dispatch [::settings.events/alias-namespaces? alias-namespaces?]]]})))
102+
[:dispatch [::settings.events/alias-namespaces? alias-namespaces?]]
103+
[:dispatch [::settings.events/display-uuids-as display-uuids-as]]]})))
102104

103105
;; Global
104106

src/day8/re_frame_10x/panels/settings/events.cljs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,3 +322,8 @@
322322
(cond
323323
(and (not= :never trace-when) (= :never k)) {::trace/disable {:key ::cb}}
324324
(and (= :never trace-when) (not= :never k)) {::trace/enable {:key ::cb}}))))
325+
326+
(rf/reg-event-db
327+
::display-uuids-as
328+
[(rf/path [:settings :display-uuids-as]) rf/trim-v (local-storage/save "display-uuids-as")]
329+
(fn [_ [method]] method))

src/day8/re_frame_10x/panels/settings/subs.cljs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,3 +193,8 @@
193193
::trace-when
194194
:<- [::root]
195195
:-> :trace-when)
196+
197+
(rf/reg-sub
198+
::display-uuids-as
199+
:<- [::root]
200+
:-> :display-uuids-as)

src/day8/re_frame_10x/panels/settings/views.cljs

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
[day8.re-frame-10x.material :as material]
1515
[day8.re-frame-10x.styles :as styles]
1616
[day8.re-frame-10x.tools.datafy :as tools.datafy]
17-
[day8.re-frame-10x.fx.log :as log]))
17+
[day8.re-frame-10x.fx.log :as log]
18+
[day8.re-frame-10x.tools.identicon :as identicon]))
1819

1920
(def comp-section-width "400px")
2021
(def instruction--section-width "190px")
@@ -121,7 +122,7 @@
121122

122123
[rc/line]
123124

124-
(let [trace-when @(rf/subscribe [::settings.subs/trace-when])
125+
(let [trace-when @(rf/subscribe [::settings.subs/trace-when])
125126
set-trace-when #(rf/dispatch [::settings.events/trace-when %])]
126127
[settings-box
127128
[[rc/v-box
@@ -264,9 +265,9 @@
264265
:on-change #(rf/dispatch [::settings.events/handle-keys? %])]]
265266
[[:p "Should 10x respond to key-press events?"]]
266267
settings-box-81])
267-
(let [ready? @(rf/subscribe [::settings.subs/ready-to-bind-key])
268+
(let [ready? @(rf/subscribe [::settings.subs/ready-to-bind-key])
268269
panel-key (rf/subscribe [::settings.subs/key-bindings :show-panel])
269-
ambiance @(rf/subscribe [::settings.subs/ambiance])]
270+
ambiance @(rf/subscribe [::settings.subs/ambiance])]
270271
[settings-box
271272
[[rc/button
272273
:class (styles/button ambiance)
@@ -332,7 +333,7 @@
332333
[:code @(rf/subscribe [::settings.subs/expansion-limit])] " nodes."]]
333334
settings-box-81]
334335
[rc/line]
335-
(let [ambiance @(rf/subscribe [::settings.subs/ambiance])
336+
(let [ambiance @(rf/subscribe [::settings.subs/ambiance])
336337
alias-namespaces? @(rf/subscribe [::settings.subs/alias-namespaces?])]
337338
[settings-box
338339
[[rc/h-box
@@ -378,6 +379,39 @@
378379
[:p "Display " [:code "::" (str ns-alias) "/x"] " when printing " [:code ":" (str ns-full) "/x"]]
379380
"")]
380381
settings-box-131])
382+
383+
[rc/line]
384+
(let [method @(rf/subscribe [::settings.subs/display-uuids-as])
385+
set-method #(rf/dispatch [::settings.events/display-uuids-as %])
386+
example-uuid (random-uuid)]
387+
[settings-box
388+
[[rc/v-box
389+
:children
390+
[[rc/label :label "Display UUIDs as:"]
391+
[inputs/radio-button
392+
{:label "Plaintext"
393+
:model method
394+
:value nil
395+
:on-change set-method}]
396+
[inputs/radio-button
397+
{:label "Identicons"
398+
:model method
399+
:value :identicons
400+
:on-change set-method}]
401+
[inputs/radio-button
402+
{:label "Last 4 chars"
403+
:model method
404+
:value :last-4-chars
405+
:on-change set-method}]]]]
406+
[[:p "Display " [:code (pr-str example-uuid)] " as "
407+
(case method
408+
:last-4-chars (str "#uuid " (.slice (str example-uuid) -4))
409+
:identicons [:span {:style {:display "inline-flex" :align-items "center"}
410+
:title (pr-str example-uuid)}
411+
"#uuid " [identicon/svg (str "#uuid " example-uuid)]]
412+
example-uuid)]]
413+
settings-box-81])
414+
381415
[rc/line]
382416
(let [ambiance @(rf/subscribe [::settings.subs/ambiance])]
383417
[settings-box
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
(ns day8.re-frame-10x.tools.identicon
2+
(:require [clojure.string :as str]))
3+
4+
;; Ported from identicon.js by Don Park - https://github.com/donpark/identicon
5+
;; Stripped down for SVG only and converted to ClojureScript.
6+
7+
(defn- build-grid [hash]
8+
;; Original used 16 bytes from hash, we use the single 32-bit integer hash
9+
;; Use bits from the hash to fill a 5x5 grid, mirroring the first 2 columns to the last 2
10+
(let [;; Use lower bits for the grid pattern
11+
grid-pattern (bit-and hash 0xFFFFF) ;; Use 20 bits for 5x5 grid decisions
12+
grid (volatile! (vec (repeat 25 false)))]
13+
(dotimes [i 15] ;; Fill first 3 columns (15 cells)
14+
(when (pos? (bit-and grid-pattern (bit-shift-left 1 i)))
15+
(let [row (quot i 3)
16+
col (rem i 3)]
17+
(vswap! grid assoc (+ (* row 5) col) true))))
18+
;; Mirror columns 0 and 1 to 4 and 3
19+
(dotimes [row 5]
20+
(vswap! grid assoc (+ (* row 5) 4) (get @grid (+ (* row 5) 0))) ;; col 4 = col 0
21+
(vswap! grid assoc (+ (* row 5) 3) (get @grid (+ (* row 5) 1)))) ;; col 3 = col 1
22+
@grid))
23+
24+
(defn- foreground-color [hash]
25+
;; Use higher bits for color, ensure it's not too light.
26+
;; Original used first 4 bytes of hash for HSL. We adapt for our single hash int.
27+
;; Simple approach: use hash modulo 360 for hue, fixed saturation/lightness.
28+
(let [hue (mod (bit-shift-right hash 20) 360) ;; Use some higher bits for hue
29+
saturation 65
30+
lightness 40]
31+
(str "hsl(" hue "," saturation "%," lightness "%)")))
32+
33+
(defn svg
34+
"Generates identicon SVG data as Hiccup.
35+
Takes a string value and an options map.
36+
Options:
37+
:size - width/height of the SVG (default 100)
38+
:background - vector [r g b a] 0-255 (default [240 240 240 255])
39+
:margin - decimal percentage margin (default 0.08)"
40+
[value & {:keys [size background margin]
41+
:or {size 14, background "white", margin 0}}]
42+
(when-not (str/blank? value)
43+
(let [hash (hash-string value)
44+
fg-color (foreground-color hash)
45+
grid (build-grid hash)
46+
cell-size (/ size 5.0)
47+
base-margin (* size margin)
48+
cell-margin (/ base-margin 2.0)
49+
final-size (+ size base-margin)]
50+
(into [:svg {:width final-size
51+
:height final-size
52+
:viewBox (str "0 0 " final-size " " final-size)
53+
:xmlns "http://www.w3.org/2000/svg"
54+
:style {:background background}}
55+
[:text {:x 0
56+
:y 0
57+
:text-anchor "middle"
58+
:alignment-baseline "middle"
59+
:fill "rgba(0,0,0,0)"
60+
:style {:user-select :text}}
61+
(subs value 5)]]
62+
(for [row (range 5)
63+
col (range 5)
64+
:let [idx (+ (* row 5) col)]
65+
:when (get grid idx)]
66+
[:rect {:x (+ cell-margin (* col cell-size))
67+
:y (+ cell-margin (* row cell-size))
68+
:width cell-size
69+
:height cell-size
70+
:fill fg-color}])))))
71+
72+
;; Example usage (for testing in REPL):
73+
;; (render-svg "hello" {:size 50})
74+
;; (render-svg "test" {:size 30 :margin 0.1 :background [255 0 0 128]})

0 commit comments

Comments
 (0)