diff --git a/src-cljs/main.cljs b/src-cljs/main.cljs index c8aada7..2a29ef2 100644 --- a/src-cljs/main.cljs +++ b/src-cljs/main.cljs @@ -1,6 +1,7 @@ (ns NoteHub.main - (:use [jayq.core :only [$ css inner val anim]]) + (:use [jayq.core :only [$ css inner val anim show]]) (:require [fetch.remotes :as remotes] + [goog.dom :as gdom] [clojure.browser.dom :as dom] [clojure.browser.event :as event]) (:require-macros [fetch.macros :as fm])) @@ -8,6 +9,7 @@ ; frequently used selectors (def $draft ($ :#draft)) (def $preview ($ :#preview)) +(def $preview-start-line ($ :#preview-start-line)) (defn scroll-to "scrolls to the given selector" @@ -28,5 +30,6 @@ (fn [e] (do (fm/remote (md-to-html (val $draft)) [result] + (show $preview-start-line) (inner $preview result) - (scroll-to ($ :#preview-start)))))) + (scroll-to $preview-start-line))))) diff --git a/src/NoteHub/storage.clj b/src/NoteHub/storage.clj index 172b7c7..fef47ea 100644 --- a/src/NoteHub/storage.clj +++ b/src/NoteHub/storage.clj @@ -1,11 +1,15 @@ (ns NoteHub.storage - (:refer-clojure :exclude (set get)) (:require [clj-redis.client :as redis])) (def db (redis/init)) -(defn set [k v] - (redis/set db k v)) +(def note "note") -(defn get [k] - (redis/get db k)) +(defn- build-key [[year month day] key] + (print-str year month day key)) + +(defn set-note [date key v] + (redis/hset db note (build-key date key) v)) + +(defn get-note [date key] + (redis/hget db note (build-key date key))) diff --git a/src/NoteHub/views/common.clj b/src/NoteHub/views/common.clj index 213d19a..0ee1510 100644 --- a/src/NoteHub/views/common.clj +++ b/src/NoteHub/views/common.clj @@ -8,7 +8,7 @@ (defn gen-comma-list [& fonts] (apply str (interpose "," fonts))) (def page-width (mixin - :width :900px)) + :width :800px)) (def helvetica-neue (mixin :font-weight 300 @@ -17,6 +17,13 @@ "Arial" "'Lucida Grande'" "sans-serif"))) +(def central-element + (mixin + page-width + :margin-top :5em + :margin-bottom :10em + :margin-left "auto" + :margin-right "auto")) (def global-css (css @@ -43,6 +50,7 @@ (rule "h2" helvetica-neue)) (rule "article" + central-element :font-family :Georgia :font-size :1.2em (rule "& > h1:first-child" @@ -61,7 +69,7 @@ :font-size :1.2em :border :none ; TODO: make this dynamic - :height :600px + :height :500px :margin-bottom :2em) (rule ".hidden" :display :none) @@ -73,15 +81,11 @@ :opacity 0.8 :font-size :1em :background :white) - (rule ".central-body" - page-width - :margin-top :5em - :margin-bottom :10em - :margin-left "auto" - :margin-right "auto") + (rule ".central-element" + central-element) (rule "h1" :font-size :2em) - (rule "#preview-start" + (rule "#preview-start-line" :border-bottom [:1px :dashed :gray] :margin-bottom :5em) (rule "h1, h2, h3, h4" @@ -90,7 +94,7 @@ (defpartial layout [title & content] (html5 [:head - [:title "NoteHub - " title] + [:title "NoteHub — " title] (include-js "https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js") [:link {:href "http://fonts.googleapis.com/css?family=Noticia+Text:400,700" :rel "stylesheet" diff --git a/src/NoteHub/views/pages.clj b/src/NoteHub/views/pages.clj index 564273f..119873f 100644 --- a/src/NoteHub/views/pages.clj +++ b/src/NoteHub/views/pages.clj @@ -1,16 +1,34 @@ (ns NoteHub.views.pages (:require [NoteHub.views.common :as common]) (:use - [NoteHub.storage :rename {get s-get set s-set} :only [set get]] - [noir.response :only [redirect]] + [NoteHub.storage] [clojure.string :rename {replace sreplace} :only [split replace lower-case]] - [noir.core :only [defpage render]] + [clojure.core.incubator :only [-?>]] [hiccup.form] + [noir.response :only [redirect]] + [noir.core :only [defpage render]] + [noir.statuses] [noir.fetch.remotes]) (:import [org.pegdown PegDownProcessor])) +; Fix a maximal title length used in the link (def max-title-length 80) +; Markdown -> HTML mapper +(defremote md-to-html [draft] + (.markdownToHtml (PegDownProcessor.) draft)) + +; Template for the 404 error +(set-page! 404 + (let [message "Page Not Found."] + (common/layout message + [:article + [:h1 message]]))) + +; Routes +; ====== + +; Landing Page (defpage "/" {} (common/layout "Free Markdown Hosting" [:div#hero @@ -19,41 +37,44 @@ [:br] [:a.landing-button {:href "/new"} "New Page"]])) +; New Note Page (defpage "/new" {} (common/layout "New Markdown Note" - [:div.central-body + [:div.central-element (form-to [:post "/post-note"] (text-area {:class "max-width"} :draft) [:div#buttons.hidden (submit-button {:style "float: left" :class "button"} "Publish") [:button#preview-button.button {:type :button :style "float: right"} "Preview"]])] - [:div#preview-start] - [:article#preview.central-body])) - -(defn get-storage-key [year month day title] - (apply str (interpose "-" ["note" year month day (hash [year month day title])]))) - -(defremote md-to-html [draft] - (.markdownToHtml (PegDownProcessor.) draft)) + [:div#preview-start-line.hidden] + [:article#preview])) +; Note URL (defpage "/:year/:month/:day/:title" {:keys [year month day title]} - (let [key (get-storage-key year month day title) - post (s-get key) - title (sreplace (-> post (split #"\n") first) #"[_\*#]" "")] - (common/layout title - [:article.central-body - ; TODO: deal with 404! - (md-to-html post)]))) + (let [date [year month day] + key (hash (conj date title)) + post (get-note date key) + title (-?> post (split #"\n") first (sreplace #"[_\*#]" ""))] + (if post + (common/layout title + [:article + (md-to-html post)]) + (get-page 400)))) +; New Note Posting (defpage [:post "/post-note"] {:keys [draft]} - (let [[year month day] (split (.format (java.text.SimpleDateFormat. "yyyy-MM-dd") (java.util.Date.)) #"-") + (let [[year month day] (split + (.format + (java.text.SimpleDateFormat. "yyyy-MM-dd") + (java.util.Date.)) #"-") untrimmed-line (filter #(or (= \- %) (Character/isLetterOrDigit %)) (-> draft (split #"\n") first (sreplace " " "-") lower-case)) trim (fn [s] (apply str (drop-while #(= \- %) s))) title-uncut (-> untrimmed-line trim reverse trim reverse) title (apply str (take max-title-length title-uncut)) ; TODO: deal with collisions! - key (get-storage-key year month day title)] + date [year month day] + key (hash (conj date title))] (do - (s-set key draft) + (set-note date key draft) (redirect (apply str (interpose "/" ["" year month day title]))))))