diff options
Diffstat (limited to 'desk/web/thread.hoon')
-rw-r--r-- | desk/web/thread.hoon | 478 |
1 files changed, 478 insertions, 0 deletions
diff --git a/desk/web/thread.hoon b/desk/web/thread.hoon new file mode 100644 index 0000000..e88185d --- /dev/null +++ b/desk/web/thread.hoon @@ -0,0 +1,478 @@ +/- boke, tp=trill-post, cons=contact +/+ sr=sortug, plib=trill-utils, sigil=sigil-sigil, lib=boke, kaji, constants +/= post-content /web/components/post-text +|_ [fn=full-node:tp children=(list post:tp) page=@ud contacts=whoms:cons =bowl:gall] +++ thread-css ^~ %- trip +''' +body>main{ + width: 100%!important; +} +@media (max-width: 800px){ + body>main{ + padding: 0!important; + } +} +#board-thread{ + max-width: 1280px; + margin: auto; + +/* base styles */ + & header{ + & img{ + width: 20px; + margin-left: 1rem; + } + } + + & p{ + font-size: 1.1rem; + } + & .reply{ + display: grid; + border: 1px solid silver; + + & .author{ + margin-right: 1rem; + + & .avatar{ + max-height: 100px; + max-width: 88px; + } + & .name{ + font-weight: 500; + color: var(--hong); + text-align: center; + word-break: break-word; + } + } + + & .metadata { + & p{ + margin: -5px 0 0 0; + font-size: 14px; + } + & .buttons{ + display: flex; + img{ + height: 20px; + width: 20px; + margin: 5px 5px; + cursor: pointer; + } + } + + } + + & .content{ + text-align: left: + word-wrap: break-word; + + & p{ + padding: 0.5rem; + font-weight: 400; + overflow: hidden; + word-break: break-word; + white-space: normal; + margin: 1rem 0; + } + & blockquote{ + margin: 1rem 2rem 1rem 1rem; + padding: 0.4rem; + border: 1px solid grey; + border-radius: 2%; + } + } + } + & footer{ + width: 100%; + .tags{ + padding: 0; + font-size: 0.9rem; + flex-wrap: wrap; + + a{ + margin-left: 0.1rem; + } + } + } + + + /* desktop */ + + @media (min-width: 1000px){ + #posts{ + display: flex; + } + #replies{ + width: 83.33%; + } + } + @media(min-width: 800px){ + + & #sidebar{ + position: sticky; + top: 4rem; + right: 0; + align-self: flex-start; + } + + & #posts{ + + & .reply{ + padding: 1rem; + margin: 1rem; + grid-template-columns: 10% 90%; + grid-template-rows: 40px auto; + + & .author{ + grid-column-start: 1; + grid-column-end: 2; + grid-row-start: 1; + grid-row-end: 3; + } + + & .metadata{ + display: flex; + justify-content: space-between; + border-bottom: 1px solid grey; /* TODO darkmode */ + grid-column-start: 2; + grid-column-end: 3; + grid-row-start: 1; + grid-row-end: 2; + } + + & .content{ + grid-column-start: 2; + grid-column-end: 3; + grid-row-start: 2; + grid-row-end: 3; + + & img{ + margin: 0 auto; + } + } + } + } + } + /* mobile */ + @media(max-width: 800px){ + + + & #posts{ + display: block; + width: 100%; + + & .reply{ + padding-top: 10px; + grid-template-columns: 100px auto; + grid-template-rows: 80px auto; + + & .author{ + grid-column-start; 1; + grid-column-end: 2; + grid-row-start: 1; + grid-row-end: 2; + + & .avatar{ + height: 60px; + width: 60px; + display: block; + margin: 0 auto; + } + } + & .metadata{ + grid-column-start: 2; + grid-column-end: 3; + grid-row-start: 1; + grid-row-end: 2; + padding: 0; + border-bottom: 1px solid grey; + + & .buttons{ + width: 100%; + justify-content: space-between; + margin-top: 0.5rem; + } + } + & .content{ + grid-column-start: 1; + grid-column-end: 3; + grid-row-start: 2; + grid-row-end: 3; + + } + } + } + } + + + + + & #sidebar{ + padding-top: 2rem 0.5rem 0.5rem 0.5rem; + + & div{ + margin: 1rem 0; + } + + & #search-box{ + margin-top: 0.25rem; + + & input{ + width: 100%!important; + border: 1px solid var(--text-color); + } + } + } +} + +.reply-box{ + & .replying-to{ + display: flex; + + & .name{ + margin-left: 1rem; + } + } + & textarea{ + resize: none; + display: block; + outline: none; + width: 100%; + } + & input[type=submit]{ + margin-top: 0.5rem; + float:right; + } +} +''' +++ thread-js ^~ %- trip +''' +const buttons = document.querySelectorAll(".buttons"); +console.log(buttons, "buttons") +buttons.forEach(el => { + const parent = el.closest(".reply"); + const cb = el.querySelector(".copy-button") + cb.addEventListener("click", () => { + const path = `https://spandrell.ch/board/p/${parent.id}` + navigator.clipboard.writeText(path).then(res => { + console.log(res, "write to clipboard") + }).catch(er => { + console.log(er, "couldn't write to clipboard") + }) + }) + const db = el.querySelector(".down-button") + db.addEventListener("click", () => { + parent.querySelector("footer").scrollIntoView(); + }) +}); + +''' +++ $ ^- manx +=/ index (mul (dec page) board-page-size:constants) +=/ childlist (slice:sr children board-page-size:constants index) +;div#board-thread + ;style:"{thread-css}" + ;header.fxc + ;h1:"{(trip title.p.fn)}" + ;+ %+ hide-if:kaji ?|((is-admin:lib src.bowl) .=(author.p.fn src.bowl)) + edit-button + == + ;div#posts + ;div#replies + ;* %+ mapi:sr childlist thread-child + == + ;+ sidebar + == + ;script:"{thread-js}" +== +++ edit-button +=/ pid-string (enc:kaji [author.p.fn id.p.fn]) +;a/"/board/edit/{pid-string}" + ;img@"https://s3.spandrell.ch/assets/board/ui/edit.svg"; +== + +++ thread-child +|= [post-index=@ud =post:tp] ^- manx +=/ base-index (mul (dec page) board-page-size:constants) +=/ pind (add base-index +(post-index)) +=/ usr (user author.post) +=/ pid-string (enc:kaji [author.post id.post]) +=/ jammed-parents %- enc:kaji [op=[author.p.fn id.p.fn] parent=[author.post id.post]] +;div.reply(id pid-string) + ;div.author + ;+ avatar.usr + ;+ name.usr + == + ;div.metadata + ;+ (date post pind) + ;+ (buttons post) + == + ;div.content + ;* (post-content contents.post) + ;+ (footer post) + == + ;+ (reply-box name.usr jammed-parents) +== +++ user +|= u=@p ^- [avatar=manx name=manx] +=/ ming (get-name:lib u) +=/ sig sigil(size 80) +=/ sigl ?: ?=(%ship -.ming) (sig u) +=/ random (random-avatar:lib (jam u)) +;img.avatar@"{random}"; +=/ nam ;div.name:"{ming}" +=/ prof (~(get by contacts) [%.y u]) +?~ prof [sigl nam] +=/ avatar + =/ avatar-data (~(get by info.u.prof) %avatar) + ?~ avatar-data sigl + ?. ?=(%look -.u.avatar-data) sigl + ;img.avatar@"{(trip +.u.avatar-data)}"; +=/ name + =/ name-data (~(get by info.u.prof) %nickname) + ?~ name-data nam + ?. ?=(%text -.u.name-data) nam + ;div.name:"{(trip +.u.name-data)}" + +[avatar name] +++ date +|= [=post:tp post-index=@ud] +=/ date-string (datetime-to-tape:string:sr id.post "-") +=/ posted ;span.posted-date:"{date-string}" +=/ last-edit=time key:head:(pop:corm:tp contents.post) +=/ =marl ?: .=(last-edit id.post) posted^~ +:~ posted + ;span.updated-date:"{(datetime-to-tape:string:sr last-edit "-")}" +== +;div.date + ;p + ;* marl + == + ;p + ;span:"Post #{(scow:parsing:sr %ud post-index)}" + ;span.engagement:"" + == +== +++ buttons +|= =post:tp +:: =/ votes %+ roll ~(tap by reacts.engagement.post) |= [[s=@p [r=@t *]] acc=@] +:: ?: ?|(=(r "thumbsup") =(r "👍")) +;div.buttons + ;+ %+ hide-if:kaji ?|((is-admin:lib src.bowl) .=(author.post src.bowl)) + ;img@"https://s3.spandrell.ch/assets/board/ui/edit.svg"; + ;img.copy-button@"https://s3.spandrell.ch/assets/board/ui/copy.svg"; + ;img + =src "https://s3.spandrell.ch/assets/board/ui/upvote.svg" + ; + == + ;img@"https://s3.spandrell.ch/assets/board/ui/downvote.svg" + ; + == + ;img.down-button@"https://s3.spandrell.ch/assets/board/ui/down.svg"; + ;img@"https://s3.spandrell.ch/assets/board/ui/reply.svg" + =kaji "toggle" + =targ ".reply-box" + =modal "1" + ; + == + ;img.collapse-button + =src "https://s3.spandrell.ch/assets/board/ui/collapse.svg" + =kaji "toggle" + =targ ".content/.avatar/.uncollapse-button/.collapse-button" + ; + == + ;img.uncollapse-button + =src "https://s3.spandrell.ch/assets/board/ui/uncollapse.svg" + =kaji "toggle" + =targ ".content/.avatar/.uncollapse-button/.collapse-button" + =hidden "" + ; + == +== +++ reply-box +|= [author=manx jammed-parents=tape] ^- manx +:: %- serve-modal:kaji :_ ~ +;div.reply-box + =hidden "" + ;div.replying-to + ;div:"Replying to" + ;+ author + == + ;form + =kaji "poke" + =action "add-post" + ;textarea + =name "text" + =rows "10" + ; + == + ;input(type "hidden", name "parents", value jammed-parents); + ;input(type "submit", value "Send"); + :: == + == +== +++ footer +|= =post:tp +=/ count ~(wyt in tags.post) +=/ tags ?. (gth count 0) ;span:"" +=/ tag-links +%+ mapi:sr ~(tap in tags.post) + |= [i=@ t=@t] ^- manx + ?. .=(i (dec count)) + ;a/"/tags/{(trip t)}":"{(trip t)}, " + ;a/"/tags/{(trip t)}":"{(trip t)} " +;div.tags.flex + ; Tags: + ;* tag-links +== +;footer + ;+ tags +== +:: +++ sidebar +=/ from +((mul (dec page) board-page-size:constants)) +=/ to + =/ added (add from board-page-size:constants) + ?: (gth added (lent children)) (lent children) added +=/ froms (number:string:sr from) +=/ tos (number:string:sr to) +=/ post-count (number:string:sr (lent children)) +=/ max-page +((div (lent children) board-page-size:constants)) +=/ page-count %- number:string:sr max-page +=/ prev-page %- number:string:sr ?: .=(page 1) 1 (dec page) +=/ curr-page (number:string:sr page) +=/ next-page %- number:string:sr ?: .=(page max-page) page +(page) +;div#sidebar + ;button:"Back to Board" + ;div#search-box + ;form.flex + ;input(name "thread-search", placeholder "Search on Thread"); + ;button + ;img@"https://s3.spandrell.ch/assets/board/ui/search.svg"; + == + == + == + ;div#stats + ;p:"{post-count} Posts - {page-count} Pages" + ;p:"Showing posts {froms} to {tos}" + == + ;div#page-nav + ;a.button/"1":"1" + ;a.button/"{prev-page}" + ;img@"https://s3.spandrell.ch/assets/board/ui/left.svg"; + == + ;a.button:"{curr-page}" + ;a.button/"{next-page}" + ;img@"https://s3.spandrell.ch/assets/board/ui/right.svg"; + == + ;a.button/"{page-count}":"{page-count}" + == + ;button + =kaji "toggle" + =targ ".reply-box" + =modal "1" + ; Reply + == +== +-- |