summaryrefslogtreecommitdiff
path: root/desk/web/blog
diff options
context:
space:
mode:
Diffstat (limited to 'desk/web/blog')
-rw-r--r--desk/web/blog/post-header.hoon118
-rw-r--r--desk/web/blog/post-list.hoon159
-rw-r--r--desk/web/blog/post.hoon344
-rw-r--r--desk/web/blog/router.hoon198
-rw-r--r--desk/web/blog/title.hoon11
5 files changed, 830 insertions, 0 deletions
diff --git a/desk/web/blog/post-header.hoon b/desk/web/blog/post-header.hoon
new file mode 100644
index 0000000..3bee975
--- /dev/null
+++ b/desk/web/blog/post-header.hoon
@@ -0,0 +1,118 @@
+/- tp=trill-post
+/+ sr=sortug, lib=boke, wall
+=< html
+|%
+++ css ^~ %- trip
+'''
+ #post-header{
+ -webkit-locale: "en";
+ text-size-adjust: 100%;
+ color: rgb(0, 0, 0);
+ font-size: 16px;
+ font-weight: 400;
+ text-rendering: optimizelegibility;
+ -webkit-font-smoothing: antialiased;
+ line-height: 1.618;
+ text-shadow: rgb(0, 0, 0) 0px 0px 0px;
+ align-items: center;
+ border-bottom-color: rgb(223, 223, 223);
+ border-bottom-style: dotted;
+ border-bottom-width: 1px;
+ box-sizing: border-box;
+ margin-left: 0px;
+ margin-right: 0px;
+ padding-bottom: 30px;
+ padding-left: 32px;
+ padding-right: 32px;
+ padding-top: 30px;
+ text-align: center;
+
+ & h2{
+ font-size: 2.1rem;
+ text-transform: uppercase;
+ }
+
+ & #post-meta, .comment-meta, .entry-footer {
+ font-size: 90%;
+ font-style: italic;
+ color: #969696;
+ }
+ @media (min-width: 768px){
+ & .col-md-4 {
+ -ms-flex: 0 0 33.333333%;
+ flex: 0 0 33.333333%;
+ max-width: 33.333333%;
+ }
+ }
+ & .breadcrumbs {
+ list-style: none;
+ display: inline-block;
+ margin: 0;
+ padding: 0;
+ border: none;
+ background: transparent;
+ text-indent: 0;
+
+ }
+ & .breadcrumbs li {
+ display: inline-block;
+ margin: 0 0.3rem;
+ padding: 0;
+ border: none;
+ background: transparent;
+ text-indent: 0;
+ }
+ & .tags{
+ display: block;
+ text-transform: capitalize;
+ }
+
+ }
+'''
+++ html
+|= [t=thread:tp who=@p] ^- manx
+=/ url (trip (spat path.t)) :: TODO check for relative/absolute path
+=/ date (date-to-tape:string:sr id.pid.t "-")
+
+=+ [[a y] m [d h mm s f]]=(yore id.pid.t)
+=/ ys %- trip (ud-to-cord:string:sr y)
+=/ ming (get-name:lib ship.pid.t)
+=/ nam
+ ?. .=(ship.pid.t ~docteg-mothep) ming
+ "Spandrell" :: TODO should use the user component here
+
+=/ ttags (tags:wall ~(tap in tags.t))
+::
+;div#post-header
+ ;style:"{css}"
+ ;h2:"{(trip title.t)}"
+ ;div#post-meta
+ ;span
+ ; Posted by {nam} on
+ ;ul.breadcrumbs
+ ;li
+ ;a/"/{ys}":"{ys}"
+ ==
+ ; /
+ ;li
+ ;a/"/{ys}/{<m.m>}":"{<m.m>}"
+ ==
+ ; /
+ ;li
+ ;a/"/{ys}/{<m.m>}/{<d.d>}":"{<d.d>}"
+ ==
+ ==
+ ==
+ ;+ ?: .=(0 (lent ttags)) ;span:""
+ ;div.tags
+ ;* %+ mapi:sr ttags
+ |= [i=@ t=@t] ^- manx
+ =/ tt (trip t)
+ =/ path "/blog?t={tt}"
+ =/ show
+ ?. .=(i (dec (lent ttags))) "{tt}, " tt
+ ;a/"{path}":"{show}"
+ ==
+ ==
+==
+--
diff --git a/desk/web/blog/post-list.hoon b/desk/web/blog/post-list.hoon
new file mode 100644
index 0000000..35a3590
--- /dev/null
+++ b/desk/web/blog/post-list.hoon
@@ -0,0 +1,159 @@
+/- tp=trill-post
+/+ sr=sortug, plib=trill-utils, lib=boke, kaji
+/= content /web/components/post-text
+|%
+++ abbreviated-post
+|= [cm=content-map:tp button=manx] ^- (list manx)
+ =/ abbreviated (abbreviate-post:plib cm 1.000)
+ =/ blocks (latest-contents:plib cm)
+ ?: .=(blocks abbreviated) %+ turn blocks block:content
+ %+ snoc (turn abbreviated block:content) button
+
+++ post-snippet
+|= t=thread:tp ^- manx
+ =/ url (trip (spat path.t)) :: TODO check for relative/absolute path
+ =+ [[a y] m [d h mm s f]]=(yore id.pid.t)
+ =/ ys %- trip (ud-to-cord:string:sr y)
+ :: =/ author (scot %p p.author.p)
+ =/ count (lent replies.t)
+ =/ comment-count ?: .=(count 0) "No" "{<count>}"
+ ::
+ =/ continue-button
+ ;div.continue-button-wrapper
+ ;a.continue-button/"{url}":"Continue"
+ ==
+ =/ comment-div
+ ;span
+ ;a/"{url}#comments":"{comment-count} comments"
+ ==
+ =/ tag-links
+ %+ mapi:sr ~(tap in tags.t)
+ |= [i=@ tg=@t] ^- manx
+ =/ tt (trip tg)
+ =/ path "/blog?t={tt}"
+ =/ show ?: .=(i (dec ~(wyt in tags.t))) tt "{tt}, "
+ ;a/"{path}":"{show}"
+
+::
+;article
+ ;header
+ ;h2
+ ;a/"{url}":"{(trip title.t)}"
+ ==
+ ==
+ ;main
+ ;* %+ turn snip.t block:content
+ ;+ continue-button
+ ==
+ ;div.post-metadata
+ ;span
+ ; Posted on
+ ;a/"{ys}":"{ys}"
+ ;a/"{ys}/{<m.m>}":"/{<m.m>}"
+ ;a/"{ys}/{<m.m>}/{<d.d>}":"/{<d.d>}"
+ ==
+ :: ;span
+ :: ; by
+ :: ;a/"by/{author}":"{author}"
+ :: ==
+ ==
+ ;+ ?: .=(0 ~(wyt in tags.t)) ;footer ;+ comment-div ==
+ ;footer
+ ; Tagged as
+ ;span.tags-links
+ ;* tag-links
+ ==
+ ;+ comment-div
+ ==
+==
+++ css ^~ %- trip
+'''
+#post-list{
+ :: top: 0;
+ margin: auto;
+
+ & article{
+ margin: 0 0 1.5em;
+ margin-top: 40px;
+ border-bottom: 1px dotted #dfdfdf;
+ padding: 0 2rem;
+ padding-bottom: 40px;
+
+ & header h2{
+ font-size: 1.8rem;
+ text-align: center;
+ letter-spacing: 1px;
+ text-transform: uppercase;
+ line-height: 1.4em;
+ font-weight: 500;
+ }
+ & .post-metadata, article footer{
+ font-size: 90%;
+ font-style: italic;
+ color: #969696;
+ }
+
+ & main{
+ margin: 1.5em 0 0;
+ }
+ }
+ & .tags-links{
+ text-transform: capitalize;
+ margin-right: 1ch;
+ }
+
+ & .continue-button-wrapper{
+ margin-top: 1.5rem;
+ margin-bottom: 1.5rem;
+ }
+ & .continue-button{
+ font-family: 'Montserrat', sans-serif;
+ text-transform: uppercase;
+ letter-spacing: 1px;
+ font-size: 13px;
+ -webkit-transition: all .4s ease;
+ -o-transition: all .4s ease;
+ transition: all .4s ease;
+ padding: 0.5rem, 0rem, 0.5rem, 1.25rem;
+ line-height: 1.5;
+ border-radius: 0.2rem;
+ }
+ & .cursor{
+ text-align: center;
+ margin: 1rem;
+ }
+}
+@media (max-width: 800px){
+ #post-list{
+ & article{
+ padding: 0;
+ line-height: 1.7rem;
+ }
+ }
+}
+
+
+'''
+++ test
+|= [p=post:tp children=full-graph:tp] ^- manx
+=/ pid [author.p id.p]
+=/ pat /blog/snip/(scot %uw (jam pid))
+(fetch:kaji pat)
+++ cursor
+|= [cursor=(unit @da) label=tape]
+?~ cursor ;div;
+=/ path "/blog/f?cursor={(scow:parsing:sr %uw u.cursor)}"
+;div.cursor(kaji "iscroll", path path, cont "#post-list", where "bottom")
+ ;button:"{label} posts"
+==
+++ html
+|= [p=tpage:tp =marl]
+^- manx
+;div#post-list.blog
+ ;style:"{css}"
+ ;* marl
+ :: ;+ (cursor newer.p "Newer")
+ ;* (turn p.p post-snippet)
+ ;+ (cursor older.p "Older")
+==
+--
diff --git a/desk/web/blog/post.hoon b/desk/web/blog/post.hoon
new file mode 100644
index 0000000..0366fc9
--- /dev/null
+++ b/desk/web/blog/post.hoon
@@ -0,0 +1,344 @@
+/- tp=trill-post
+/+ plib=trill-utils, sr=sortug, kaji, lib=boke, const=constants
+/= post-text /web/components/post-text
+/= post-header /web/blog/post-header
+|_ [[t=thread:tp =post:tp children=full-graph:tp] =bowl:gall is-mobile=?]
+++ css ^~ %- trip
+'''
+#post-text{
+ -webkit-locale: "en";
+ text-size-adjust: 100%;
+ color: rgb(0, 0, 0);
+ line-height: 1.618;
+ text-shadow: rgb(0, 0, 0) 0px 0px 0px;
+ border-bottom-color: rgb(223, 223, 223);
+ border-bottom-style: dotted;
+ border-bottom-width: 1px;
+ box-sizing: border-box;
+ display: block;
+ margin-bottom: 24px;
+ margin-left: 0px;
+ margin-right: 0px;
+ margin-top: 0px;
+ padding-bottom: 40px;
+ padding-left: 32px;
+ padding-right: 32px;
+ padding-top: 4px;
+}
+@media (max-width: 800px){
+ #post-text{
+ padding: 0;
+ line-height: 1.2;
+ }
+}
+#comments{
+ -webkit-locale: "en";
+ text-size-adjust: 100%;
+ color: rgb(0, 0, 0);
+ line-height: 1.618;
+ text-align: left;
+ text-shadow: rgb(0, 0, 0) 0px 0px 0px;
+ box-sizing: border-box;
+ display: block;
+ margin-bottom: 32px;
+ padding-bottom: 0px;
+ padding-left: 16px;
+ padding-right: 16px;
+ padding-top: 0px;
+}
+#comments h3{
+ -webkit-locale: "en";
+ text-size-adjust: 100%;
+ color: rgb(0, 0, 0);
+ text-align: left;
+ text-shadow: rgb(0, 0, 0) 0px 0px 0px;
+ font-size: 18.72px;
+ font-weight: 400;
+ box-sizing: border-box;
+ display: block;
+ line-height: 1.2;
+ margin-block-end: 9.36px;
+ margin-block-start: 9.36px;
+ margin-bottom: 9.36px;
+ margin-inline-end: 0px;
+ margin-inline-start: 0px;
+ margin-left: 0px;
+ margin-right: 0px;
+ margin-top: 9.36px;
+}
+.comment-list{
+ -webkit-locale: "en";
+ text-size-adjust: 100%;
+ color: rgb(0, 0, 0);
+ line-height: 1.618;
+ text-align: left;
+ text-shadow: rgb(0, 0, 0) 0px 0px 0px;
+ box-sizing: border-box;
+ display: block;
+ list-style-image: none;
+ list-style-position: outside;
+ list-style-type: none;
+ margin-block-end: 24px;
+ margin-block-start: 0px;
+ margin-bottom: 24px;
+ margin-inline-end: 0px;
+ margin-inline-start: 0px;
+ margin-left: 0px;
+ margin-right: 0px;
+ margin-top: 0px;
+ padding-inline-start: 0px;
+ padding-left: 0px;
+}
+.comment-list li{
+ position: relative;
+ -webkit-locale: "en";
+ text-size-adjust: 100%;
+ color: rgb(0, 0, 0);
+ line-height: 1.618;
+ text-shadow: rgb(0, 0, 0) 0px 0px 0px;
+ list-style-image: none;
+ list-style-position: outside;
+ list-style-type: none;
+ border-left-color: rgb(223, 223, 223);
+ border-left-style: solid;
+ border-left-width: 1px;
+ box-sizing: border-box;
+ display: list-item;
+ padding-bottom: 16px;
+ padding-left: 10px;
+ padding-right: 0px;
+ padding-top: 16px;
+ text-align: left;
+}
+.comment-author{
+ font-weight: 700;
+ color: var(--text);
+ font-style: normal;
+ font-size: 1rem;
+ margin-right: 1rem;
+}
+.comment-content{
+ font-size: 90%;
+}
+#reply-title{
+ display: inline;
+}
+.reply-prompt{
+ color: var(--hong);
+ font-size: 0.9rem;
+}
+.nested{
+ padding-left: 1rem;
+}
+#reply-box{
+ & textarea{
+ width: 100%;
+ }
+ .author-data{
+ display: flex;
+ justify-content: space-between;
+
+ & .name{
+ margin-left: 1rem;
+ }
+ }
+}
+/* desktop */
+@media (min-width: 800px){
+ #reply-box{
+ width: 40%;
+ }
+}
+/* mobile */
+@media (max-width: 800px){
+ #reply-box{
+ width: 100%;
+ }
+}
+.collapse-button, .uncollapse-button{
+ width: 15px;
+ position: absolute;
+ left: -10px;
+ top: 21px;
+}
+'''
+++ script ^~ %- trip
+'''
+function scanTweets(){
+ const nodes = document.querySelectorAll(".parsed-twatter");
+ for (let n of nodes){
+ const status = n.getAttribute("status");
+ twttr.widgets.createTweet(status, n.parentElement, {
+ conversation: true
+ })
+ }
+}
+window.addEventListener('load', () => {
+ scanTweets();
+})
+'''
+++ post-content
+^- manx
+;div#post-text
+ ;style:"{css}"
+ ;* (content:post-text contents.post)
+==
+++ comments
+=/ =pid:tp [author.post id.post]
+=/ board-path (trip (spat (board-path:lib t)))
+=/ l (lent replies.t)
+=/ length ?: .=(0 l) "No" "{<l>}"
+=/ js "$store.replying_to.show('main')"
+^- manx
+;div#comments
+ ;a/"{board-path}":"Switch to Board View"
+ ;h3:"{length} comments"
+ ;div#big-reply
+ ;span.fl
+ =kaji "scry"
+ =path "/blog/f/reply/{(enc:kaji [pid pid])}"
+ =swap "add"
+ =cont "#big-reply"
+ ; Leave a reply
+ ==
+ ==
+ ;+ comment-list
+==
+++ comment-list ^- manx
+=/ cs (tap:form:tp children)
+;div#comments-wrapper
+ ;ul#comments-top.comment-list
+ =id "children{(scow %ud id.post)}"
+ ;* (turn (flop cs) comment)
+ ==
+==
+
+++ comment
+=| nested=@ud
+|= [=pid:tp [p=post:tp c=full-graph:tp]]
+^- manx
+=/ author (get-name:lib -.pid)
+=/ full-time (datetime-to-tape:string:sr id.pid "/")
+=/ time ?. is-mobile full-time
+ (post-date-ago:lib id.pid now.bowl %tam)
+
+=/ id=tape (enc:kaji pid)
+=/ js=tape "$store.replying_to.show('{id}')"
+=/ post-meta (enc:kaji [[author.post id.post] pid])
+=/ permalink ""
+;li
+ =id "comment-{id}"
+ ;img.collapse-button
+ =src "https://s3.spandrell.ch/assets/board/ui/collapse.svg"
+ =kaji "toggle"
+ =targ ".comment-proper/.uncollapse-button/.collapse-button"
+ ;
+ ==
+ ;img.uncollapse-button
+ =src "https://s3.spandrell.ch/assets/board/ui/uncollapse.svg"
+ =kaji "toggle"
+ =targ ".comment-proper/.uncollapse-button/.collapse-button"
+ =hidden ""
+ ;
+ ==
+ ;div.comment
+ ;div.comment-meta
+ ;div.row
+ ;a.comment-author/"/u/{author}":"{author}"
+ ; |
+ ;a.comment-time
+ =title "{time}"
+ =href permalink
+ ; {time}
+ ==
+ ;* ?. (is-admin:lib src.bowl) ~
+ ;= ;span:"|"
+ ;a
+ =kaji "poke"
+ =action "del-comment"
+ =name "pid"
+ =payload id
+ ; Nuke
+ ==
+ ==
+ ==
+ ==
+ ;div.comment-proper
+ ;div.comment-content
+ ;* (content:post-text contents.p)
+ ==
+ ;span.fl.reply-prompt
+ =id id
+ =kaji "scry"
+ =path "/blog/f/reply/{post-meta}"
+ =swap "swap"
+ =targ ".reply-box"
+ ; reply
+ ==
+ ;div.reply-box;
+ ;+ (grandchildren [p c] +(nested))
+ ==
+ ==
+==
+++ shit
+=| nested=@ud
+|= a=@ud %lol
+
+++ grandchildren
+|= [p=full-node:tp nested=@ud] ^- manx
+=/ cs (tap:form:tp children.p)
+=/ c (houyi:plib children.p)
+=/ count (scow:parsing:sr %ud c)
+
+?: ?& (gth (lent cs) 0) (gth nested 5) is-mobile ==
+ =/ pids [[author.post id.post] [author.p.p id.p.p]]
+ =/ path "/blog/f/subthread/{(enc:kaji pids)}"
+ ;a
+ =kaji "scry"
+ =path path
+ =swap "swap"
+ =targ "#comments-wrapper"
+ ; Show {count} more comments
+ ==
+=/ id=tape (enc:kaji [author.p.p id.p.p])
+=/ newcomms comment :: need to tisfas it to be able to manipulate the optional variable
+ :: I don't get it
+;ul.comment-list.nested
+ =id "children-{id}"
+ ;* (turn (flop cs) newcomms(nested nested))
+==
+++ comment-subthread
+|= fn=full-node:tp
+=/ cs (tap:form:tp children.fn)
+=/ ocs (tap:form:tp children)
+=/ c (houyi:plib children.fn)
+=/ oc (houyi:plib children)
+=/ count (scow:parsing:sr %ud c)
+=/ total (scow:parsing:sr %ud oc)
+=/ =pid:tp [author.post id.post]
+;div#subthread
+ ;div
+ ;p:"Showing {count} comments of {total}"
+ ;a
+ =kaji "scry"
+ =path "/blog/f/comments/{(enc:kaji pid)}"
+ =swap "swap"
+ =targ "#comments-wrapper"
+ ; Go back to top
+ ==
+ ==
+ ;div#comments-top.comment-list
+ =id "children{(scow %ud id.post)}"
+ ;* (turn (flop cs) comment)
+ ==
+==
+
+
+++ html ^- manx
+ ;div.blog
+ ;+ (post-header t src.bowl)
+ ;+ post-content
+ ;+ comments
+ ;script:"{script}"
+ ==
+--
diff --git a/desk/web/blog/router.hoon b/desk/web/blog/router.hoon
new file mode 100644
index 0000000..32a96c9
--- /dev/null
+++ b/desk/web/blog/router.hoon
@@ -0,0 +1,198 @@
+/- boke, cnt=contact, tp=trill-post
+/+ kaji, fetch-lib=fetch, plib=trill-utils, const=constants, sr=sortug, lib=boke, ui=trill-ui
+/= index /web/index
+/= post-list /web/blog/post-list
+/= post-show /web/blog/post
+/= title /web/blog/title
+/= user /web/components/user
+
+|_ [rl=req-line:kaji s=state:boke =bowl:gall]
++* fetch ~(. fetch-lib [s bowl])
+
+++ eyre-bail (error-response:kaji 404)
+++ manx-bail (error-page:kaji 404)
+::
+++ $ ^- eyre-res:kaji
+ =/ p pat.rl ::?. mob.rl pat.rl [%m pat.rl]
+ ?+ p ~& >>> path-not-found=`path`p eyre-bail
+ ~ (serve-page par.rl)
+ [%snip pid=@ ~] (post-snippet pid.p)
+ ::
+ [%f rest=*] (fragment rest.p)
+ [%b rest=*] (threads rest.p)
+ ==
+++ serve-index
+ :- %page
+:: =/ paginated (get-tag-page:plib feed.s tags.s ~['blog'] [~ ~ page-size])
+ =/ paginated (thread-page-by-tags:fetch ~['blog'] [~ ~ blog-page-size:const] ~)
+ :: =/ paginated ~> %bout (get-tag-page:plib feed.s tags.s ~['blog'] [~ ~ page-size])
+ =/ main=manx (html:post-list paginated ~)
+ (index ~[title main] bowl)
+
+++ serve-page
+|= params=(map @t @t)
+ :- %page ^- manx
+ =/ tags
+ =/ ptags (~(get by params) 't')
+ ?~ ptags ~['blog']
+ =/ parsed (parse-tags:ui u.ptags)
+ ?~ parsed ~['blog'] :: TODO some error here
+ ~(tap in u.parsed)
+ =/ older
+ =/ pcursor (~(get by params) 'cursor') ?~ pcursor ~
+ (slaw:parsing:sr %uw u.pcursor)
+ =/ req [~ older blog-page-size:const]
+ =/ paginated (thread-page-by-tags:fetch tags req ~)
+ =/ tag-title
+ =/ ptags (~(get by params) 't')
+ ?~ ptags ~
+ ;+ ;h3.tag-title:"Posts tagged as {(trip u.ptags)}"
+ =/ main=manx (html:post-list paginated tag-title)
+ (index ~[title main] bowl)
+
+
+
+
+
+++ show
+ :- %page
+ =/ dat (op-by-path:fetch pat.rl)
+ ?~ dat manx-bail
+ =/ main=manx
+ ~(html post-show [u.dat bowl mob.rl])
+ (index ~[main] bowl)
+
+++ threads
+|= p=(pole knot)
+ :- %page
+ =/ dat (op-by-path:fetch p)
+ ?~ dat manx-bail
+ =/ main=manx
+ ~(html post-show [u.dat bowl mob.rl])
+ (index ~[main] bowl)
+:: don't think we're using this now
+++ post-snippet
+ |= [ss=@]
+ :- %html
+ =/ pid (dec:kaji ss pid:tp)
+ ?~ pid manx-bail
+ :: =/ post (get:gorm:tp feed.s u.pid)
+ =/ thread (get:torm:tp threads.s u.pid)
+ ?~ thread manx-bail
+ :: =/ fn (node-to-full:plib u.post feed.s)
+ (post-snippet:post-list u.thread)
+
+
+
+
+
+ :: ?+ pat bail
+ :: [type=@t name=@t cursor=@t ~]
+ :: :: TODO %feed type at some point?
+ :: =/ older (slaw:parsing:sr %uw cursor.pat) ?~ older inline-error
+ :: ?. ?=(?(%b %t) type.pat) inline-error
+ :: ?: ?=(%b type.pat)
+ :: =/ page (board-to-page:lib name.pat tags.s feed.s [~ older board-page-size:cns])
+ :: ?~ page inline-error
+ :: (serve-post-page name.pat u.page .n)
+ :: :: single tag
+ :: =/ page (tag-to-page:lib name.pat tags.s feed.s [~ older board-page-size:cns]) ?~ page inline-error
+ :: (serve-post-page name.pat u.page .y)
+ :: ==
+ :: ++ serve-post-page
+ :: |= [name=@t =page:tp is-tag=?]
+ :: ~& >> serving-page=+.page
+ :: =/ previews ?: ?=(%blog name)
+ :: (turn p.page post-snippet:post-list)
+ :: ::
+ :: =/ contacts (get-contacts:cnt bowl)
+ :: %+ turn p.page |= fn=full-node:tp (thread-preview fn contacts bowl)
+ :: ;div
+ :: ;* %+ snoc previews
+ :: (cursor:cm older.page "Older" name is-tag)
+ :: ==
+ ++ fragment
+ |= p=(pole knot)
+ :- %html
+ ?+ p manx-bail
+ ~ blog-page
+ [%comments uid=@t ~] (blog-comments uid.p)
+ [%subthread uid=@t ~] (subthread uid.p)
+ [%reply uid=@t ~] (reply-box uid.p)
+ ==
+ ++ blog-page
+ =/ params=(map @t @t) par.rl
+ =/ tags
+ =/ ptags (~(get by params) 't')
+ ?~ ptags ~['blog']
+ =/ parsed (parse-tags:ui u.ptags)
+ ?~ parsed ~['blog'] ~(tap in u.parsed)
+ =/ older
+ =/ pcursor (~(get by params) 'cursor') ?~ pcursor ~
+ (slaw:parsing:sr %uw u.pcursor)
+ =/ req=page-req:tp [~ older blog-page-size:const]
+ :: =/ paginated (get-tag-page-2:plib feed.s tags.s tags req)
+ =/ paginated (thread-page-by-tags:fetch tags req ~)
+ (html:post-list paginated ~)
+++ blog-comments
+|= hash=@t
+ =/ op (op-by-hash:fetch hash)
+ ?~ op manx-bail
+ ~(comment-list post-show [u.op bowl mob.rl])
+
+++ subthread
+|= hash=@t
+ =/ both (dec:kaji hash ,[op=pid:tp sub=pid:tp])
+ ?~ both manx-bail
+ =/ op (op-by-pid:fetch op.u.both)
+ ?~ op manx-bail
+ =/ sub-op (fn-by-pid:fetch sub.u.both)
+ ?~ sub-op manx-bail
+ =/ core ~(. post-show [u.op bowl mob.rl])
+
+ (comment-subthread:core u.sub-op)
+
+++ reply-box
+|= hash=@t
+?: .=(%pawn (clan:^title src.bowl))
+;div#reply-box
+ ;p:"You must login with an Urbit ID to comment"
+==
+=/ usr (user src.bowl *whoms:cnt 30) :: TODO
+ ;div
+ ;div#reply-box
+ ;span
+ =id "cancel-reply"
+ =class "fl"
+ =kaji "destroy"
+ =targ "#reply-box"
+ ; Cancel reply
+ ==
+ ;form#reply-form
+ =kaji "poke"
+ =action "add-reply"
+ ;textarea#comment
+ =name "text"
+ =cols "45"
+ =rows "8"
+ =maxlength "6552"
+ =autocomplete "off"
+ ;
+ ==
+ ;div.author-data
+ ;div.as.flex
+ ;span:"Posting as "
+ ;div.flex.ml1
+ ;+ avatar.usr
+ ;+ name.usr
+ ==
+ ==
+ ;input#submit-comment(type "submit", value "Poast");
+ ==
+ ;input(type "hidden", name "parents", value (trip hash));
+ ;input(type "hidden", name "is-blog", value ".y");
+ ;span#error-div;
+ ==
+ ==
+ ==
+--
diff --git a/desk/web/blog/title.hoon b/desk/web/blog/title.hoon
new file mode 100644
index 0000000..7675165
--- /dev/null
+++ b/desk/web/blog/title.hoon
@@ -0,0 +1,11 @@
+=< html
+|%
+++ html ^- manx
+ ;header
+ ;h1
+ ;a/"/":"Bloody Shovel 4"
+ ==
+ ;h4:"Nemo nos Salvabit"
+ :: ;h4:"不當而當亂也"
+ ==
+-- \ No newline at end of file