From d5aefa9b1d81d95fc720552f4ca9bb81762d0e72 Mon Sep 17 00:00:00 2001 From: Saskia Lindner Date: Fri, 25 Aug 2017 11:43:00 +0200 Subject: [PATCH] Pin traces to bottom for autoscrolling --- src/day8/re_frame/trace.cljs | 47 +++++++++++++------------ src/day8/re_frame/trace/components.cljs | 33 ++++++++++++++++- src/day8/re_frame/trace/styles.cljs | 6 ++-- 3 files changed, 59 insertions(+), 27 deletions(-) diff --git a/src/day8/re_frame/trace.cljs b/src/day8/re_frame/trace.cljs index 616f004..f437544 100644 --- a/src/day8/re_frame/trace.cljs +++ b/src/day8/re_frame/trace.cljs @@ -227,29 +227,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..bcaad1b 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,32 @@ [: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?] :as opts} childr] + (let [should-scroll (r/atom true)] + (r/create-class + {:display-name "autoscroll-list" + :component-did-mount + (fn [this] + (let [n (r/dom-node this)] + (scroll! n [0 (.-scrollTop n)] [0 (.-scrollHeight n)] 0))) + :component-will-update + (fn [this] + (let [n (r/dom-node this)] + (reset! should-scroll (scrolled-to-end? n 100)))) + :component-did-update + (fn [this] + (let [scroll? (:scroll? (r/props this)) + n (r/dom-node this)] + (when (and scroll? @should-scroll) + (scroll! n [0 (.-scrollTop n)] [0 (.-scrollHeight n)] 1600)))) + :reagent-render + (fn [{:keys [class]} child] + [:div {:class class} 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..5b37b8a 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: 10px; overflow: auto; + flex: 1 1 auto; } #--re-frame-trace-- .filter-control { margin: 10px 0 0 10px; + flex: none; } ")