summaryrefslogtreecommitdiff
path: root/desk/web/chat/chat.hoon
diff options
context:
space:
mode:
Diffstat (limited to 'desk/web/chat/chat.hoon')
-rw-r--r--desk/web/chat/chat.hoon317
1 files changed, 317 insertions, 0 deletions
diff --git a/desk/web/chat/chat.hoon b/desk/web/chat/chat.hoon
new file mode 100644
index 0000000..92c451a
--- /dev/null
+++ b/desk/web/chat/chat.hoon
@@ -0,0 +1,317 @@
+/- c=tlon-channels, contact
+/+ sr=sortug, kaji, sigil=sigil-sigil, lib=boke
+/= user /web/components/user
+|_ [=whoms:contact =bowl:gall]
+::
++$ mane $@(@tas [@tas @tas]) :: XML name+space
++$ manx $~([[%$ ~] ~] [g=marx c=marl]) :: dynamic XML node
++$ marl (list manx) :: XML node list
++$ mars [t=[n=%$ a=[i=[n=%$ v=tape] t=~]] c=~] :: XML cdata
++$ mart (list [n=mane v=tape]) :: XML attributes
++$ marx $~([%$ ~] [n=mane a=mart]) :: dynamic XML tag
+++ md
+'''
+# H1
+
+## H2
+
+### H3
+
+#### H4
+
+##### H5
+
+###### H6
+
+This is a paragraph with _italics_, *bold* and
+`inline code`. Sentences can be hard wrapped.
+
+
+- unordered
+- list
+
++ ordered
++ list
+
+[link](https://urbit.org)
+
+![image](https://media.urbit.org/guides/additional/dist/wut.svg)
+
+```
+fenced codeblock
+(note language spec not supported)
+```
+
+horizontal rule:
+---
+
+> block quotes
+ may be hard-wrapped if indented
+
+Backslash at end\
+of line adds linebreak
+
+Udon syntax may be prefixed with \*backslashes\* to escape.
+
+Hoon atom literals like ~sampel-palnet and ~.foo will
+be rendered as inline code.
+
+'''
+++ css ^~ %- trip
+'''
+#chat-box{
+ height: 100%;
+ width: 100%;
+ border: 1px solid var(--text-color);
+ display: flex;
+ flex-direction: column;
+
+ input[type=text]{
+ outline: none;
+ }
+
+ header{
+ border-bottom: 1px solid var(--text-color);
+ display: flex;
+ padding: 0.5rem;
+
+ h3{
+ margin: 0;
+ }
+ }
+}
+#chat-container{
+ flex-grow: 1;
+ overflow-y: scroll;
+ word-break: break-all;
+ padding: 0.5rem;
+
+
+ .chat-msg {
+ display: flex;
+ min-height: 4rem;
+
+ .left {
+ margin-right: 1rem;
+
+ & .avatar{
+ width: 32px;
+ height: 32px;
+ }
+ }
+ .right {
+ width: 100%;
+ .metadata {
+ display: flex;
+ color: rgb(100, 100, 100);
+ font-size: 0.8rem;
+
+ .name{
+ font-family: "Anonymous Pro";
+ margin-right: 0.5rem;
+ }
+ }
+ .chat-content{
+ font-family: Inter;
+ }
+ }
+ }
+}
+#chat-container .chat-content img{
+ max-width: 80%;
+ display: block;
+ margin: 0 auto;
+}
+#chat-composer{
+ display: flex;
+}
+#text-input{
+ flex-grow: 1;
+}
+.row{
+ display: flex;
+}
+.f1{
+ display: flex;
+ justify-content: space-between;
+}
+
+@media (min-width: 800px){
+ header{
+ padding: 0.5rem 2rem;
+
+ }
+
+}
+@media (max-width: 800px){
+
+ header{
+ & .chat-name{
+ text-align: end;
+ }
+ }
+
+}
+
+'''
+++ script
+|= sub-path=tape
+^~ %+ weld %- trip
+'''
+document.addEventListener('DOMContentLoaded', (event) => {
+ const room = document.getElementById("chat-container");
+ if (room) room.scrollTop = room.scrollHeight
+})
+
+document.addEventListener('kaji-fact', (event) => {
+ const room = document.getElementById("chat-container");
+ if (room) setTimeout(() => room.scrollTop = room.scrollHeight, 50)
+})
+
+'''
+"""
+subscribe('{sub-path}');
+"""
+++ main
+|= page=paged-posts:c
+=/ sip our.bowl
+=/ name 'chat'
+=/ sub-path "/chat/{(scow %p sip)}/{(trip name)}"
+^- manx
+ =/ chat-list (tap:on-posts:c posts.page)
+ ;div#chat-box
+ ;style:"{css}"
+ ;script:"{(script sub-path)}"
+ ;header.f1
+ ;h3: Bloody Shovel Public Chat
+ ;div.chat-name:"~tasdev-docteg-mothep/bloody-shovel-public/chat"
+ ==
+ ;div#chat-container
+ ;* %+ turn chat-list |= [=time up=(unit post:c)]
+ ?~ up ;span;
+ (post-div +<.u.up)
+ ==
+ ;form
+ =id "chat-composer"
+ =kaji "poke"
+ =action "add-chat"
+ =wipe "yes"
+ ;input#text-input(type "text", name "input", autocomplete "off");
+ ;input(type "submit", value "Submit");
+ ==
+ ==
+++ post-div
+|= =memo:c ^- manx
+:: =/ =memo:c +<.post
+:: seal is engagement, essay is the post
+=/ usr (user author.memo whoms 32)
+;div.chat-msg
+ ;div.left
+ ;+ avatar.usr
+ ==
+ ;div.right
+ ;div.metadata
+ ;+ name.usr
+ ;div.time:"{(time-to-tape:string:sr sent.memo)}"
+ ==
+ ;div.chat-content
+ ;* %+ turn content.memo |= =verse:c
+ ?: ?=(%block -.verse) (block +.verse)
+ ;div.inline
+ ;* %+ turn p.verse tinline
+ ==
+ ==
+ ==
+==
+:: chat:tlon -> manx
+++ block |= b=block:c
+ ?- -.b
+ %image
+ ;img
+ =src "{(trip src.b)}"
+ :: =width "{(scow %ud width.b)}"
+ :: =height "{(scow %ud height.b)}"
+ =alt "{(trip alt.b)}"
+ ;
+ ==
+ %cite ;p:"oops"
+ %header (heading-to-manx +.b)
+ %listing (listing-to-manx +.b)
+ %code ;code
+ =lang "{(trip code.b)}"
+ ; (trip lang.b)
+ ==
+ %rule ;p:""
+ ==
+:: ::
+++ listing-to-manx
+ |= l=listing:c ^- manx
+ ?: ?=(%item -.l)
+ ;li
+ ;* %+ turn p.l tinline
+ ==
+ ::
+ :: =/ inl (tinline r.l) :: ???
+ ?: ?=(%ordered p.l)
+ ;ol
+ ;* %+ turn q.l listing-to-manx
+ ==
+ ?: ?=(%unordered p.l)
+ ;ul
+ ;* %+ turn q.l listing-to-manx
+ ==
+ :: %tasklist
+ ;div.task-list
+ ;* %+ turn q.l listing-to-manx
+ ==
+++ heading-to-manx
+|= [p=?(%h1 %h2 %h3 %h4 %h5 %h6) q=(list inline:c)] ^- manx
+ =/ tp (turn q tinline)
+ ?- p
+ %h1 ;h1
+ ;* tp
+ ==
+ %h2 ;h2
+ ;* tp
+ ==
+ %h3 ;h3
+ ;* tp
+ ==
+ %h4 ;h4
+ ;* tp
+ ==
+ %h5 ;h5
+ ;* tp
+ ==
+ %h6 ;h6
+ ;* tp
+ ==
+ ==
+:: ::
+++ tinline |= i=inline:c
+ ?@ i ;span:"{(trip i)}"
+ ?- -.i
+ %italics ;i
+ ;* (turn p.i tinline)
+ ==
+ %bold ;em:""
+ %strike ;span.strike:""
+ %blockquote ;blockquote
+ ;* (turn p.i tinline)
+ ==
+ ::
+ %inline-code ;code:"{(trip p.i)}"
+ %code ;code:"{(trip p.i)}"
+ %ship ;span.ship:"{(trip (scot %p p.i))}"
+ %block ;span.ref:"Reference to {(scow %ud p.i)} {(trip q.i)}"
+ %tag ;span.tag:"{(trip p.i)}"
+ %link ;a/"{(trip p.i)}"(target "_blank"):"{(trip q.i)}"
+ %task ;span.task
+ ; Done: {(bool-string p.i)}
+ ;* (turn q.i tinline)
+ ==
+ %break ;br;
+ ==
+++ bool-string
+ |= a=? ^- tape ?:(a "yes" "no")
+--