diff of 7b1733f3dc65cd117bd0cd4d3c73a6c7dbed2cbf

7b1733f3dc65cd117bd0cd4d3c73a6c7dbed2cbf
diff --git a/elm-frontti/src/Ajax_cmds.elm b/elm-frontti/src/Ajax_cmds.elm
index e560464..930b36f 100644
--- a/elm-frontti/src/Ajax_cmds.elm
+++ b/elm-frontti/src/Ajax_cmds.elm
@@ -174,3 +174,9 @@ getFeedMeta =
     Http.get
         { url = "/api/user/feeds/meta"
         , expect = Http.expectJson FeedMetaReceived Feeds.metadataDecoder}
+
+postExcerpt excerpt feed_id =
+    Http.post
+        { url = " /api/posts/excerpt/" ++ feed_id
+        , body = Http.stringBody "text/plain" excerpt
+        , expect = Http.expectJson NewPostGenerated Json.int}
diff --git a/elm-frontti/src/FeedView.elm b/elm-frontti/src/FeedView.elm
index 28b445d..123b051 100644
--- a/elm-frontti/src/FeedView.elm
+++ b/elm-frontti/src/FeedView.elm
@@ -7,23 +7,33 @@ import Time
 import Message exposing (..)
 import Html exposing (..)
 import Html.Attributes exposing (..)
-import Html.Events exposing (onInput, onClick)
+import Html.Events exposing (onInput, onClick, on) 
 import Button exposing (murja_button)
 import UUID
 import Article_view exposing (formatDateTime)
 import FeedManager exposing (feedmanager)
 import Tab exposing (TabEntry, tabs)
-
 import Random
 
 feed_item loginstate settings zone item =
     let time_format = settings.time_format
-        article = itemToArticle item in 
-    case item.feed_id of
-        Just feed_id ->
-            li [] [ Article_view.articleView settings loginstate zone article ]
-        Nothing ->
-            li [] [ text "Unknown feed" ]
+        article = itemToArticle item in
+    li [ class "feed-item" ]
+       ( case item.feed_id of
+             Just feed_id ->
+                 [ div [] [ murja_button [ onClick <| SelectExcerpt item.id ] [ text "Write a post about this"]]
+                 , node "dialog" [ id <| "excerpt-dialog-" ++ (UUID.toString item.id) ]
+                     (let textarea_id = "excerpt-dialog-" ++ (UUID.toString item.id) ++ "-textarea" in 
+                     [ div [ class "dialog" ]
+                           [ header [ class "previouslyHeader" ] [ button [ onClick ClosePreviousPostsModel ] [ text "X"]]
+                           , h3 [] [ text "Select an excerpt"]
+                           , textarea [ rows 30
+                                      , cols 60
+                                      , id textarea_id ] [ text item.description ]
+                           , murja_button [ onClick <| CreateExcerptPost textarea_id item.id ] [ text "Create a post" ]]])
+                 , Article_view.articleView settings loginstate zone article ]
+             Nothing ->
+                 [ text "Unknown feed" ])
 
 correctlySortedFeedItemList loginstate settings zone items = 
     (  items
diff --git a/elm-frontti/src/Main.elm b/elm-frontti/src/Main.elm
index 95192bb..1f5432a 100644
--- a/elm-frontti/src/Main.elm
+++ b/elm-frontti/src/Main.elm
@@ -66,7 +66,8 @@ main =
 subscriptions : Model -> Sub Msg
 subscriptions _ = Sub.batch 
                   [ tags ReceivedTag
-                  , aceStateUpdate AceStateUpdate]
+                  , aceStateUpdate AceStateUpdate
+                  , excerptCreated ExcerptCreated]
 
 initialModel url key viewstate = Model viewstate Nothing False False [] Nothing LoggedOut key url Nothing Time.utc [] [] Nothing PerFeed Nothing
     
@@ -137,6 +138,9 @@ port closePreviousPostsModal: (() -> Cmd msg)
 port showPreviousPostPreviewModal: (() -> Cmd msg)
 port tags : (String -> msg) -> Sub msg
 port aceStateUpdate : (String -> msg) -> Sub msg
+port showModal: String -> Cmd msg
+port createExcerpt: (String, String) -> Cmd msg
+port excerptCreated: ((String, String) -> msg) -> Sub msg 
 
 toggleHidden article =
     { article | hidden = not article.hidden}
@@ -696,7 +700,15 @@ update msg model =
                     , Cmd.none)
                 Err error -> ( { model | view_state = ShowError (errToString error) }
                              , Cmd.none)
-
+        SelectExcerpt article_uuid ->
+            ( model
+            , showModal <| "excerpt-dialog-" ++ (UUID.toString article_uuid))
+        CreateExcerptPost textarea_id feed_id ->
+            ( model
+            , createExcerpt (textarea_id, UUID.toString feed_id))
+        ExcerptCreated (excerpt, feed_id) ->
+            ( model
+            , postExcerpt excerpt feed_id)
                     
 doGoHome_ model other_cmds =
     (model, Cmd.batch (List.append [ getSettings
diff --git a/elm-frontti/src/Message.elm b/elm-frontti/src/Message.elm
index cef9632..ecec903 100644
--- a/elm-frontti/src/Message.elm
+++ b/elm-frontti/src/Message.elm
@@ -212,6 +212,9 @@ type Msg
   | DeleteFeed UUID
   | FeedDeleted (Result Http.Error ())
   | FeedMetaReceived (Result Http.Error Feeds.FeedMetadata)
+  | SelectExcerpt UUID
+  | CreateExcerptPost String UUID 
+  | ExcerptCreated (String, String)
 
 -- ports
 port reallySetupAce : String -> Cmd msg
diff --git a/resources/css/murja.css b/resources/css/murja.css
index 9f4dea9..6c79657 100644
--- a/resources/css/murja.css
+++ b/resources/css/murja.css
@@ -90,7 +90,7 @@ html, body {
 body, dialog {
     background-color: #000000;
     font-family: 'Helvetica Neue', Verdana, Helvetica, Arial, sans-serif;
-    color: #00CC00;
+    color: #FFF;
 }
 
 .meta {
@@ -192,8 +192,19 @@ textarea {
     float: right;
 }
 
+a.tag:visited {
+    color: purple;
+}
+a.tag {
+    color: blue;
+}
+
+a:visited {
+    color: #B0B;
+}
+
 a {
-    color: #0DF;
+    color: #06F;
 }
 
 a:hover {
@@ -210,7 +221,7 @@ a:hover {
 
 header {
     font-size: 3em;
-    color: #00CC00;
+    color: #FFF;
     display: table;
     margin: 0 auto;
     max-widht: 70%;
@@ -236,9 +247,9 @@ header {
 
 .murja-button
 {
-    border: 5px solid #00CC00;
+    border: 5px solid #FFF;
     background-color: #000;
-    color: #0C0;
+    color: #FFF;
     margin: 5px;
     border-radius: 15px;
 
@@ -281,7 +292,7 @@ header {
 }
 
 .tags {
-    background-color: #444;
+    background-color: #A0A0A0;
     font-size: 1.3em;
 }
 
@@ -313,7 +324,8 @@ header {
 }
 
 .feed-item {
-    margin-left: 2em;
+    display: flex;
+    flex-direction: row;
 }
 
 .tabs {
@@ -364,6 +376,23 @@ header {
     flex: 3;
 }
 
+.dialog {
+    width: 60%;
+    height: 60%;
+}
+
+.excerpt {
+    float: right;
+    background-color: #999;
+    color: #000;
+    border: 2px solid #FFF;
+    width: 40%;
+}
+
+.excerpt header {
+    font-size: unset;
+}
+
 @media only screen and (max-device-width:480px)
 {
     body {
diff --git a/resources/js/murja-helper.js b/resources/js/murja-helper.js
index dd655e1..85aa286 100644
--- a/resources/js/murja-helper.js
+++ b/resources/js/murja-helper.js
@@ -22,7 +22,7 @@ app.ports.reallySetupAce.subscribe( (content) => {
     editor.session.setValue(content);
     editor.on('change', event => {
      	let value = editor.getSession().getValue();
-	     app.ports.aceStateUpdate.send(value);
+	app.ports.aceStateUpdate.send(value);
     });
 });
 
@@ -52,9 +52,29 @@ app.ports.showPreviousPostPreviewModal.subscribe(_ => {
     document.getElementById('previewPreviouslyModal').showModal();
 });
 
+app.ports.showModal.subscribe(id => {
+    document.getElementById(id).showModal();
+});
 
 app.ports.closePreviousPostsModal.subscribe(_ => {
     document.querySelectorAll('dialog').forEach(dialog => {
 	dialog.close();
     });
 });
+
+app.ports.createExcerpt.subscribe(([textarea_id, feed_id]) => {
+    let txt = document.getElementById(textarea_id)
+    
+    if ( !txt ) {
+	alert(`Didn't find textarea with id ${textarea_id}`);
+	return;
+    }
+
+    let start = txt.selectionStart;
+    let finish = txt.selectionEnd;
+    
+    let selectedText = txt.value.substring(start, finish);
+    app.ports.excerptCreated.send([selectedText, feed_id]);
+});
+
+    
diff --git a/resources/sql/reader-fns.sql b/resources/sql/reader-fns.sql
index a8b0ddb..aceb8b1 100644
--- a/resources/sql/reader-fns.sql
+++ b/resources/sql/reader-fns.sql
@@ -47,3 +47,10 @@ WHERE fs.id = fi.feed
       AND fi.feed = $2
       AND fs.owner = $3
 RETURNING *;
+
+-- name: get-feed-name-and-url
+-- returns: :array-hash
+SELECT fs.name, fs.url
+FROM blog.feed_subscription fs
+JOIN blog.feed_item fi ON fi.feed = fs.id
+WHERE fi.id = $1 AND fs.owner = $2;
diff --git a/src/routes/post-routes.lisp b/src/routes/post-routes.lisp
index f99eb27..d4bb827 100644
--- a/src/routes/post-routes.lisp
+++ b/src/routes/post-routes.lisp
@@ -86,6 +86,33 @@
   (let ((creator-id (gethash "id" *user*)))
     (prin1-to-string (caar (murja.posts.post-db:insert-post "New title" "New post" creator-id "[]" t nil)))))
 
+(defconstant *excerpt-html-template*
+" <blockquote class=\"excerpt\">
+  <header>
+    <a href=~s> ~s says...</a>
+  </header>
+  ~a 
+</blockquote> ")
+
+(defroute create-excerpt ("/api/posts/excerpt/:feed-item-id" :method :post
+					       :decorators (@json
+							    @transaction
+							    @authenticated
+							    (@can? "create-post"))) ()
+  (let* ((creator-id (gethash "id" *user*))
+	 (name-and-url (first
+			(coerce
+			 (murja.rss.reader-db:get-feed-name-and-url feed-item-id creator-id)
+			 'list)))
+	 (name (gethash "name" name-and-url))
+	 (url (gethash "url" name-and-url))
+	 (excerpt (hunchentoot:raw-post-data :force-text t)))
+    (prin1-to-string (caar (murja.posts.post-db:insert-post "New title"
+							    (format nil *excerpt-html-template*
+								    url name excerpt)
+							    creator-id "[]" t nil)))))
+  
+
 (defroute search-prev ("/api/posts/search-previously" :method :post
 						      :decorators (@json
 								   @transaction
diff --git a/src/rss/reader-db.lisp b/src/rss/reader-db.lisp
index c4f74b1..1f4399f 100644
--- a/src/rss/reader-db.lisp
+++ b/src/rss/reader-db.lisp
@@ -3,7 +3,7 @@
   (:import-from :halisql :defqueries)
   (:import-from :lisp-fixup :partial :compose)
   (:import-from :cl-date-time-parser :parse-date-time)
-  (:export :*updates* :get-user-feeds :subscribe-to-feed :mark-as-read :delete-feed))
+  (:export :get-feed-name-and-url :*updates* :get-user-feeds :subscribe-to-feed :mark-as-read :delete-feed))
 	
 (in-package :murja.rss.reader-db)