Kaynağa Gözat

Interactive list

Innocenty Enikeew 11 yıl önce
ebeveyn
işleme
7d9fffeac8
1 değiştirilmiş dosya ile 111 ekleme ve 52 silme
  1. 111 52
      src/web.lisp

+ 111 - 52
src/web.lisp

@@ -96,8 +96,7 @@
   (list))
 
 (restas:define-route day ("day/:date")
-  (declare (ignore date))
-  (restas:redirect 'index))
+  (list :date date))
 
 (defmethod tag/script (body)
   (who:with-html-output-to-string (out)
@@ -111,7 +110,7 @@
                           :scripts '("moment.min.js"
                                      "bootstrap-datepicker.js"
                                      "bootstrap-datepaginator.min.js"
-                                     "leaflet.js"
+                                     "leaflet-src.js"
                                      "underscore.js"
                                      "backbone.js"
                                      "timeliner.js")
@@ -122,14 +121,18 @@
                                         (:div :id "paginator")))
                             (:div :class "row"
                                   (:div :class "col-sm-6"
-                                        (:ul :id "events" :class "list-group"
-                                             (:li :class "list-group-item"
+                                        (:div :id "events" :class "list-group"
+                                              (:a :class "list-group-item"
                                                   "Loading")))
                                   (:div :class "col-sm-6"
                                         (:div :id "map"))))
                           :inline-scripts
                           (tag/script
-                           (ps ($ (lambda () (chain *timeliner (start)))))))))
+                           (ps ($ (lambda () (chain *timeliner (start (lisp (getf data :date)))))))))))
+
+(defmethod render-route-data ((route (eql 'day)) data)
+  (render-route-data 'index data))
+
 
 (restas:define-route about ("about/")
   (list :title "About Timeliner"
@@ -155,6 +158,7 @@
   (css-lite:css
     (("body") (:padding-top "70px" :padding-bottom "30px"))
     (("#map") (:height "600px" :border-radius "6px"))
+    (("#events") (:height "600px" :overflow-y "scroll"))
     (("#paginator") (:margin-bottom "10px"))))
 
 (restas:define-route static/css ("css/:file" :content-type "text/css")
@@ -170,12 +174,14 @@
            *models (create)
            *collections (create)
            *views (create)
-           :start (lambda ()
+           dispatcher (chain _ (clone (@ *backbone *events)))
+           :start (lambda (date)
                     (var router (new ((@ *timeliner *router))))
                     (var events (new ((@ *timeliner *collections *events))))
                     (setf (@ events url) (lisp (restas:genurl 'api/events)))
                     (new ((@ *timeliner *views *paginator)
-                          (create :el "#paginator")))
+                          (create :el "#paginator"
+                                  :date date)))
                     (new ((@ *timeliner *views *events)
                           (create
                            :el "#events"
@@ -187,7 +193,6 @@
                     (chain router (on "route:home"
                                       (lambda ()
                                         (var today (chain (moment)
-                                                          (start-of "day")
                                                           (format "YYYY-MM-DD")))
                                         (chain router (navigate
                                                        (concatenate 'string "day/" today)
@@ -202,7 +207,7 @@
                                                                        (moment day "YYYY-MM-DD")
                                                                        (value-of)))))))))
                     (chain *backbone history (start (create push-state t)))
-                    (setf (@ window app) router))))
+                    (setf (@ *timeliner router) router))))
     ;; * Router
     (setf (@ *timeliner *router)
           (chain *backbone *router
@@ -231,18 +236,37 @@
           (chain *backbone *view
                  (extend
                   (create
-                   tag-name "li"
+                   tag-name "a"
                    class-name "list-group-item"
-                   :render (lambda ()
-                             (chain this $el (attr :data-type (chain this model (get :type))))
-                             (chain this $el (html
-                                              (who-ps-html
-                                               (:strong (chain (moment
-                                                                (chain this model (get :ts)))
-                                                               (format "lll")))
-                                               (:br)
-                                               (chain this model (get :title)))))
-                             this)))))
+                   :events (create
+                            "click" "select")
+                   icon-class (lambda ()
+                                (case (chain this model (get :type))
+                                  (:place "glyphicon glyphicon-map-marker")
+                                  (:finance "glyphicon glyphicon-usd")))
+                   render (lambda ()
+                            (chain this $el (attr (create
+                                                   :href "#"
+                                                   :data-type (chain this model (get :type)))))
+                            (chain this $el (html
+                                             (who-ps-html
+                                              (:span :class "label label-info pull-right"
+                                                     (:span :class "glyphicon glyphicon-time")
+                                                     " "
+                                                     (chain (moment
+                                                             (chain this model (get :ts)))
+                                                            (format "HH:mm")))
+                                              (:span :class (chain this (icon-class)))
+                                              " "
+                                              (chain this model (get :title)))))
+                            this)
+                   select (lambda (e)
+                            (chain e (prevent-default))
+                            (chain this $el
+                                   (siblings) (remove-class "active") (end)
+                                   (add-class "active"))
+                            (chain *timeliner dispatcher
+                                   (trigger "event:selected" (@ this model))))))))
     ;; ** Events
     (setf
      (@ *timeliner *views *events)
@@ -268,13 +292,18 @@
                  (extend
                   (create
                    :events (create selected-date-changed "changed")
-                   :initialize (lambda () (chain this $el (datepaginator)))
+                   :initialize (lambda (opts)
+                                 (chain this $el (datepaginator))
+                                 (when (@ opts date)
+                                   (chain this $el (datepaginator "setSelectedDate"
+                                                                  (list (@ opts date)
+                                                                        "YYYY-MM-DD")))))
                    :changed (lambda (e date)
-                              (chain
-                               app
-                               (navigate
-                                (concatenate 'string "day/" (chain date (format "YYYY-MM-DD")))
-                                (create :trigger t))))))))
+                              (chain *timeliner router
+                                     (navigate
+                                      (concatenate 'string "day/"
+                                                   (chain date (format "YYYY-MM-DD")))
+                                      (create :trigger t))))))))
     ;; ** Map
     (setf (@ *timeliner *views *map)
           (chain
@@ -285,38 +314,68 @@
                           (var tile-layer
                                (chain *L (tile-layer "http://{s}.tiles.mapbox.com/v3/{id}/{z}/{x}/{y}.png"
                                                      (create :id "enikesha.icd0bj4k" max-Zoom 18))))
-                          (var events-layer (chain *L (feature-group)))
+                          (setf (@ this events-layer) (chain *L (feature-group)))
+                          (setf (@ this path-layer) (chain *L (polyline (list)
+                                                                        (create
+                                                                         :weight 4
+                                                                         :color "#f30"))))
                           (setf (@ this map)
                                 (chain *L (map (@ this el)
                                                (create
                                                 :center '(59.94 30.33)
                                                 :zoom 10
-                                                :layers (list tile-layer events-layer)))))
-                          (setf (@ this events-layer) events-layer)
+                                                :layers (list tile-layer
+                                                              (@ this path-layer)
+                                                              (@ this events-layer))))))
                           (chain this (listen-to (@ this collection) "reset"
-                                                 (@ this render))))
+                                                 (@ this render)))
+                          (chain this (listen-to (@ *timeliner dispatcher) "event:selected"
+                                                 (@ this highlight))))
              render (lambda ()
-                      (var new-layer
-                           (chain *L (feature-group
-                                      (chain _ (filter
-                                                (chain this collection
-                                                       (map
-                                                        (lambda (e)
-                                                          (var loc (chain e (get "loc")))
-                                                          (var coords (when loc (@ loc coordinates)))
-                                                          (when coords
-                                                            (chain *L (circle-marker
-                                                                       (list (@ coords 1)
-                                                                             (@ coords 0))))))))
-                                                (lambda (e) e))))))
-                      (chain this map (remove-layer (@ this events-layer)))
-                      (when (chain new-layer (get-layers) length)
-                        (chain this map
-                               (add-layer new-layer)
-                               (fit-bounds (chain new-layer (get-bounds))
-                                           (create :padding '(50 50)))))
-                      (setf (@ this events-layer) new-layer)
-                      this)))))))
+                      (chain this events-layer (clear-layers))
+                      (chain this path-layer (splice-lat-lngs 0))
+                      (chain this collection
+                             (each (lambda (e)
+                                     (var loc (chain e (get "loc")))
+                                     (when loc
+                                       (var marker (chain *L (circle-marker
+                                                              (list (@ loc coordinates 1)
+                                                                    (@ loc coordinates 0))
+                                                              (create
+                                                               :radius 4
+                                                               :weight 1
+                                                               :color "#000"
+                                                               fill-color "#F00"
+                                                               fill-opacity 1))))
+                                       (chain e (set "_layer" marker))
+                                       (chain this path-layer (add-lat-lng
+                                                               (chain marker (get-lat-lng))))
+                                       (chain this events-layer (add-layer marker))))
+                                   this))
+                      (when (@ this collection length)
+                        (set-timeout
+                         (chain _ (bind (lambda ()
+                                          (chain this map (fit-bounds
+                                                           (chain this events-layer (get-bounds))
+                                                           (create :padding '(50 50)))))
+                                        this))
+                         200))
+                      this)
+             highlight (lambda (event)
+                         (var layer (chain event (get "_layer")))
+                         (chain this events-layer
+                                (set-style (create fill-color "#F00")))
+                         (if layer
+                             (progn
+                               (chain layer (set-style (create fill-color "#03F")))
+                               (when (and (not (@ *L *browser ie))
+                                          (not (@ *L *browser opera)))
+                                 (chain layer (bring-to-front)))
+                               (chain this map (set-view (chain layer (get-lat-lng))
+                                                         16)))
+                             (chain this map (fit-bounds
+                                              (chain this events-layer (get-bounds))
+                                              (create :padding '(50 50))))))))))))
 
 (restas:define-route static/js ("js/:file" :content-type "application/x-javascript")
   (cond