summaryrefslogtreecommitdiff
path: root/desk/web/board/index.hoon
diff options
context:
space:
mode:
Diffstat (limited to 'desk/web/board/index.hoon')
-rw-r--r--desk/web/board/index.hoon456
1 files changed, 456 insertions, 0 deletions
diff --git a/desk/web/board/index.hoon b/desk/web/board/index.hoon
new file mode 100644
index 0000000..f70eb03
--- /dev/null
+++ b/desk/web/board/index.hoon
@@ -0,0 +1,456 @@
+/- boke, tp=trill-post, cnt=contact
+/+ sr=sortug, plib=trill-utils, sigil=sigil-sigil, lib=boke, kaji, const=constants, fetch-lib=fetch
+/= thread-preview /web/components/thread-preview
+|_ [s=state:boke =bowl:gall is-mobile=?]
++* fetch ~(. fetch-lib [s bowl])
+++ show-css ^~ %- trip
+'''
+.thread-preview{
+ display: flex;
+ gap: 0.5rem;
+ align-items: center;
+ border-bottom: 1px solid var(--text-color);
+ margin: auto;
+ padding: 0.4rem;
+ color: var(--text-color);
+
+ & .thread-author{
+ width: 10%;
+ & img, & svg {
+ width: 40px;
+ }
+ }
+
+ & .thread-name{
+ width: 60%;
+
+ & h2{
+ margin: 0;
+ color: var(--text-color);
+ }
+
+ & .thread-tags{
+ display: flex;
+ gap: 0.3rem;
+ & .tag{
+ padding: 0.2rem;
+ background-color: var(--huang);
+ opacity: 0.9;
+ font-size: 0.7rem;
+ cursor: pointer;
+ border-radius: 0.7rem;
+ }
+ }
+ }
+
+ & .reply-count{
+ width: 10%;
+ }
+ & .dates{
+ width: 20%;
+ text-align: right;
+ padding-right: 0.5rem;
+ & .last-reply-author{
+ display: flex;
+ gap: 1ch;
+ margin-left: auto;
+ width: fit-content;
+ }
+ }
+
+ &. reply-count{
+ font-size: 0.9rem;
+ }
+}
+@media (max-width: 768px){
+ .thread-preview{
+ & .meta{
+ justify-content: space-between;
+ }
+ & img, & svg{
+ display: none!important;
+ }
+ }
+}
+'''
+++ css ^~ %- trip
+'''
+body > main{
+ width: unset!important;
+}
+.tab:hover{
+ font-weight: 700;
+}
+.tab.active{
+ font-weight: 700;
+}
+#board-index{
+ width: 16%;
+ padding: 0 0.5rem;
+ border-right: 1px solid grey;
+
+ & header{
+ display: flex;
+ height: 60px;
+
+ & #select{
+ color: var(--hong);
+ }
+ & img{
+ width: 30px;
+ }
+ }
+}
+#board-list{
+ padding: 0.5rem;
+ height: calc(100% - 4rem);
+ & .entry.active{
+ border: 1px solid black; /* TODO */
+ }
+ & .entry{
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ margin-bottom: 0.5rem;
+ & img{
+ width: 30px;
+ margin-right: 10px;
+ }
+ & h3{
+ font-size: 30px;
+ margin: 0 10px 0 0;
+ }
+ & h4{
+ margin: 0;
+ }
+ }
+ & .entry:hover{
+ background-color: rgb(100, 100, 100, 0.3);
+ }
+}
+.tabs{
+ align-items: center;
+ justify-content: space-evenly;
+ width: 100%;
+}
+#board-proper{
+ width: 84%; /* TODO third column?*/
+
+ & .title{
+ padding: 1rem 2rem;
+ height: 60px;
+ border-bottom: 1px solid var(--text-color);
+ display: flex;
+ justify-content: space-between;
+
+ & h2{
+ text-transform: uppercase;
+ width: 30%;
+ margin: 0;
+ }
+ }
+ & #thread-list{
+ height: calc(100% - 60px);
+ overflow-y: scroll;
+ }
+ #sorting{
+ display: flex;
+ justify-content: space-evenly;
+ gap: 1rem;
+ align-items: center;
+ border-bottom: 1px solid var(--text-color);
+
+ & .sort-cat{
+ display: flex;
+ align-items: center;
+ cursor: pointer;
+ }
+ }
+}
+
+@media (max-width: 768px){
+ #board-main{
+ display: block;
+ & #board-index{
+ width: 100%;
+ }
+ & #board-proper{
+ display: none;
+ }
+ }
+}
+'''
+++ mobile-css ^~ %- trip
+'''
+@media (max-width: 800px){
+ #board-proper{
+ & .title{
+ padding: 0.5rem;
+ border-bottom: 1px solid var(--text-color);
+ & input{
+ width: 30%;
+ line-height: 2rem;
+ }
+ }
+ & #thread-list{
+ padding: 1rem;
+
+ & .thread-preview{
+ color: var(--text-color);
+ & h2{
+ margin-bottom: 0.2rem;
+ }
+ & .thread-inner{
+ border-bottom: 1px solid black;
+ margin-bottom: 0.5rem;
+ }
+ & .meta{
+ opacity: 0.7;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ }
+ }
+ }
+ }
+}
+.by-author{
+ display: flex;
+ gap: 1ch;
+}
+
+#tag-search{
+ margin-bottom: 1rem;
+}
+'''
+++ big-button-css ^~ %- trip
+'''
+.big-button{
+ display: flex;
+ background-color: var(--hong);
+ margin: auto;
+ position: fixed;
+ bottom: 50px;
+ left: 50%;
+ transform: translateX(-50%);
+ & svg{
+ width: 20px;
+ }
+}
+'''
+++ big-button
+;a.button.big-button/"/board/n"
+ ;style:"{big-button-css}"
+ ;svg
+ =viewBox "0 0 20 20"
+ =enable-background "new 0 0 20 20"
+ ;path
+ =fill "#FFFFFF"
+ =d "M17.561,2.439c-1.442-1.443-2.525-1.227-2.525-1.227L8.984,7.264L2.21,14.037L1.2,18.799l4.763-1.01l6.774-6.771l6.052-6.052C18.788,4.966,19.005,3.883,17.561,2.439z M5.68,17.217l-1.624,0.35c-0.156-0.293-0.345-0.586-0.69-0.932c-0.346-0.346-0.639-0.533-0.932-0.691l0.35-1.623l0.47-0.469c0,0,0.883,0.018,1.881,1.016c0.997,0.996,1.016,1.881,1.016,1.881L5.68,17.217z"
+ ;
+ ==
+ ;
+ ==
+ ;span:"New Thread"
+==
+
+++ recent-post
+|= [* =post:tp]
+:: =/ snippet (abbreviate-post:plib contents.post 100)
+=/ tags=marl %^ foldi:sr ~(tap in tags.post) `marl`~ |= [i=@ud tag=@t acc=marl]
+?: (gth i 3) acc
+:_ acc
+=/ tt (trip tag)
+;a@"/boards/tag/{tt}":"{tt}"
+
+;div.recent-post
+ ;div.author:"{(scow %p author.post)}"
+ ;div.tags
+ ;* tags
+ ==
+==
+++ main
+|= post-list=manx
+^- manx
+;div#board-main.flex.fh
+;style: {css}
+;style:"{show-css}"
+ ;div#board-index.fh
+ ;header
+ ;div.tabs :: Boards/tags/latest
+ ;div.tab.active
+ =kaji "scry"
+ =path "/board/f/boards"
+ =swap "swap"
+ =targ "#board-list"
+ ; Boards
+ ==
+ ;div.tab
+ =kaji "scry"
+ =path "/board/f/tags"
+ =swap "swap"
+ =targ "#board-list"
+ ; Tags
+ ==
+ ==
+ ==
+ ;div#board-list.fsy
+ ;* category-list
+ ==
+ ==
+ ;+ post-list
+==
+++ category-list ^- marl
+ :- ;div.entry
+ =kaji "scry"
+ =swap "swap"
+ =path "/board/f/page/l/l/0"
+ =targ "#board-proper"
+ :: ;img@"https://s3.spandrell.ch/assets/board/boards/{name}.svg";
+ ;h3: 全
+ ;h4: All
+ ==
+ ;* %+ turn ~(tap by categories:const) |= [p=@tas *]
+ =/ name (trip p)
+ ;div.entry
+ =kaji "scry"
+ =swap "swap"
+ =path "/board/f/page/b/{name}/0"
+ =targ "#board-proper"
+ ;img@"https://s3.spandrell.ch/assets/board/boards/{name}.svg";
+ ;h4: {name}
+ ==
+++ make-tag-list
+ |= l=(list [@t @ud]) ^- marl
+ ;= ;+ tag-search-input
+ ;+ ?~ l
+ ;span:"No tags found"
+ ;div#board-list-inner.tags
+ ;* %+ turn l tag-preview
+ ==
+ ==
+++ tag-search-input
+;div#tag-search
+ ;input(type "text", name "query", placeholder "Search tag")
+ =kaji "search"
+ =bounce "1000"
+ =path "/board/f/tag-search"
+ =swap "swap"
+ =targ "#board-list-inner"
+ ;
+ ==
+==
+++ tag-preview
+ |= [t=@t c=@ud] ^- manx
+ =/ name (trip t)
+ =/ count (scow:parsing:sr %ud c)
+ ?. is-mobile
+ ;div.entry
+ =kaji "scry"
+ =swap "swap"
+ =path "/board/f/page/t/{name}/0"
+ =targ "#board-proper"
+ ;h4:"{name} ({count})"
+ ==
+ ;a.entry/"/board/t/{name}"
+ ;h4:"{name} ({count})"
+ ==
+
+++ cursor
+|= [cursor=(unit @da) label=tape =rq search=(unit @t)] ^- manx
+?~ cursor ;div;
+=/ type
+ ?- -.rq
+ %latest "l/l"
+ %board "b/{(trip name.rq)}"
+ %tag "t/{(trip name.rq)}"
+ ==
+=/ path ?~ search
+"/board/f/page/{type}/{(scow:parsing:sr %uw u.cursor)}"
+"/board/f/search/{type}/{(scow:parsing:sr %uw u.cursor)}?query={(trip u.search)}"
+
+;div.cursor(kaji "iscroll", path path, cont "#thread-list", where "bottom")
+ ;button:"{label} posts"
+==
++$ rq $%([%latest ~] [%board name=@t] [%tag name=@t])
+++ post-index
+|= [=tpage:tp =rq contacts=whoms:cnt search=(unit @t) is-mobile=?] ^- manx
+~& > cursors=[newer.tpage older.tpage]
+=/ title ?- -.rq
+ %latest "Latest posts"
+ %board (trip +.rq)
+ %tag "Tag: {(trip +.rq)}" ==
+:: =/ cursor-string ?~ older.page "0" (scow:parsing:sr %uw u.older.page)
+=/ cursor-string ""
+~& page-req=+.page
+:: =/ order "Post date" :: || "Reply date"
+=/ flop-path "/board/f/flop/"
+=/ search-path ?- -.rq
+ %latest "/board/f/search/l/l/{cursor-string}"
+ %board "/board/f/search/b/{(trip +.rq)}/{cursor-string}"
+ %tag "/board/f/search/t/{(trip +.rq)}/{cursor-string}" ==
+=/ sort-path ?- -.rq
+ %latest "/board/f/page/h/l/l/0"
+ %board "/board/f/page/b/{(trip +.rq)}/0"
+ %tag "/board/f/page/t/{(trip +.rq)}/0" ==
+
+;div#board-proper.fh
+ ;style: {mobile-css}
+ ;div.title.f1
+ :: ;button
+ :: =kaji "scry"
+ :: path flop-path
+ :: ; Flop
+ :: ==
+ ;h2:"{title}"
+ ;input(type "text")
+ =placeholder "Search threads"
+ =kaji "search"
+ =name "query"
+ =bounce "1000"
+ =path search-path
+ =swap "swap"
+ =targ "#thread-list"
+ ;
+ ==
+ ==
+ :: ;div#sorting
+ :: =kaji "scry"
+ :: =swap "swap"
+ :: =targ "thread-list"
+
+ :: ;div.sort-cat
+ :: ;span:"Title"
+ :: ;span(path "{sort-path}?sort=title&dir=asc"):"⇑"
+ :: ;span(path "{sort-path}?sort=title&dir=desc"):"⇓"
+ :: ==
+ :: ;div.sort-cat
+ :: ;span:"Author"
+ :: ==
+ :: ;div.sort-cat
+ :: ;span:"Posted"
+ :: ==
+ :: ;div.sort-cat
+ :: ;span:"Last Reply"
+ :: ==
+ :: ;div.sort-cat
+ :: ;span:"Reply Count"
+ :: ==
+ :: ==
+ ;div#thread-list
+ ;* %+ turn p.tpage |= t=thread:tp
+ =/ preview ~(. thread-preview [t contacts bowl])
+ ?: is-mobile mobile:preview wide:preview
+ ;+ (cursor older.tpage "Older" rq search)
+ ==
+ ;+ big-button
+==
+++ previews
+|= [=tpage:tp =rq contacts=whoms:cnt search=(unit @t) is-mobile=?] ^- manx
+;div
+ ;* %+ turn p.tpage |= t=thread:tp
+ =/ preview ~(. thread-preview [t contacts bowl])
+ ?: is-mobile mobile:preview wide:preview
+ ;+ (cursor older.tpage "Older" rq search)
+==
+--