|
|
@@ -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
|