diff --git a/src/day8/re_frame/trace.cljs b/src/day8/re_frame/trace.cljs index 96d99fb..906e733 100644 --- a/src/day8/re_frame/trace.cljs +++ b/src/day8/re_frame/trace.cljs @@ -236,29 +236,30 @@ (:filter-type item) ": " [:span.filter-item-string (:query item)] [:span.icon-button [components/icon-remove]]]]) @filter-items)]] - [:div.panel-content-scrollable - [:table - {:cell-spacing "0" :width "100%"} - [:thead>tr - [:th [:button.text-button - {:style {:cursor "pointer"} - :on-click (fn [ev] - ;; Always reset expansions - (swap! trace-detail-expansions assoc :overrides {}) - ;; Then toggle :show-all? - (swap! trace-detail-expansions update :show-all? not))} - (if (:show-all? @trace-detail-expansions) "-" "+")]] - [:th "operations"] - [:th - (when (pos? (count @filter-items)) - (str (count showing-traces) " of ")) - (when (pos? (count @traces)) - (str (count @traces))) - " events " - (when (pos? (count @traces)) - [:span "(" [:button.text-button {:on-click #(do (trace/reset-tracing!) (reset! traces []))} "clear"] ")"])] - [:th "meta"]] - [:tbody (render-traces showing-traces trace-detail-expansions)]]]])))) + [components/autoscroll-list {:class "panel-content-scrollable" :scroll? true} + [:table + {:style {:margin-bottom 10} + :cell-spacing "0" :width "100%"} + [:thead>tr + [:th [:button.text-button + {:style {:cursor "pointer"} + :on-click (fn [ev] + ;; Always reset expansions + (swap! trace-detail-expansions assoc :overrides {}) + ;; Then toggle :show-all? + (swap! trace-detail-expansions update :show-all? not))} + (if (:show-all? @trace-detail-expansions) "-" "+")]] + [:th "operations"] + [:th + (when (pos? (count @filter-items)) + (str (count showing-traces) " of ")) + (when (pos? (count @traces)) + (str (count @traces))) + " events " + (when (pos? (count @traces)) + [:span "(" [:button.text-button {:on-click #(do (trace/reset-tracing!) (reset! traces []))} "clear"] ")"])] + [:th "meta"]] + [:tbody (render-traces showing-traces trace-detail-expansions)]]]])))) (defn resizer-style [draggable-area] {:position "absolute" :z-index 2 :opacity 0 diff --git a/src/day8/re_frame/trace/components.cljs b/src/day8/re_frame/trace/components.cljs index 97a33d6..c25dd56 100644 --- a/src/day8/re_frame/trace/components.cljs +++ b/src/day8/re_frame/trace/components.cljs @@ -1,4 +1,6 @@ -(ns day8.re-frame.trace.components) +(ns day8.re-frame.trace.components + (:require [reagent.core :as r] + [goog.fx.dom :as fx])) (defn icon-add [] [:svg.icon.icon-add @@ -13,3 +15,36 @@ [:title "remove"] [:path {:d "M31.708 25.708c-0-0-0-0-0-0l-9.708-9.708 9.708-9.708c0-0 0-0 0-0 0.105-0.105 0.18-0.227 0.229-0.357 0.133-0.356 0.057-0.771-0.229-1.057l-4.586-4.586c-0.286-0.286-0.702-0.361-1.057-0.229-0.13 0.048-0.252 0.124-0.357 0.228 0 0-0 0-0 0l-9.708 9.708-9.708-9.708c-0-0-0-0-0-0-0.105-0.104-0.227-0.18-0.357-0.228-0.356-0.133-0.771-0.057-1.057 0.229l-4.586 4.586c-0.286 0.286-0.361 0.702-0.229 1.057 0.049 0.13 0.124 0.252 0.229 0.357 0 0 0 0 0 0l9.708 9.708-9.708 9.708c-0 0-0 0-0 0-0.104 0.105-0.18 0.227-0.229 0.357-0.133 0.355-0.057 0.771 0.229 1.057l4.586 4.586c0.286 0.286 0.702 0.361 1.057 0.229 0.13-0.049 0.252-0.124 0.357-0.229 0-0 0-0 0-0l9.708-9.708 9.708 9.708c0 0 0 0 0 0 0.105 0.105 0.227 0.18 0.357 0.229 0.356 0.133 0.771 0.057 1.057-0.229l4.586-4.586c0.286-0.286 0.362-0.702 0.229-1.057-0.049-0.13-0.124-0.252-0.229-0.357z"}]]) + +(defn scroll! [el start end time] + (.play (fx/Scroll. el (clj->js start) (clj->js end) time))) + +(defn scrolled-to-end? [el tolerance] + ;; at-end?: element.scrollHeight - element.scrollTop === element.clientHeight + (> tolerance (- (.-scrollHeight el) (.-scrollTop el) (.-clientHeight el)))) + +(defn autoscroll-list [{:keys [class scroll?]} child] + "Reagent component that enables scrolling for the elements of its child dom-node. + Scrolling is only enabled if the list is scrolled to the end. + Scrolling can be set as option for debugging purposes. + Thanks to Martin Klepsch! Original code can be found here: + https://gist.github.com/martinklepsch/440e6fd96714fac8c66d892e0be2aaa0" + (let [node (r/atom nil) + should-scroll (r/atom true)] + (r/create-class + {:display-name "autoscroll-list" + :component-did-mount + (fn [_] + (scroll! @node [0 (.-scrollTop @node)] [0 (.-scrollHeight @node)] 0)) + :component-will-update + (fn [_] + (reset! should-scroll (scrolled-to-end? @node 100))) + :component-did-update + (fn [_] + (when (and scroll? @should-scroll) + (scroll! @node [0 (.-scrollTop @node)] [0 (.-scrollHeight @node)] 1600))) + :reagent-render + (fn [{:keys [class]} child] + [:div {:class class :ref (fn [dom-node] + (reset! node dom-node))} + child])}))) \ No newline at end of file diff --git a/src/day8/re_frame/trace/styles.cljs b/src/day8/re_frame/trace/styles.cljs index 582e525..b17a848 100644 --- a/src/day8/re_frame/trace/styles.cljs +++ b/src/day8/re_frame/trace/styles.cljs @@ -95,12 +95,12 @@ flex: 1; } #--re-frame-trace-- .panel-content-scrollable { - margin: 10px 0 0 10px; - flex: 1 0 auto; - height: 100%; + margin: 0 0 10px 5px; overflow: auto; + flex: 1 1 auto; } #--re-frame-trace-- .filter-control { margin: 10px 0 0 10px; + flex: none; } ")