Skip to content

Commit

Permalink
Merge pull request #5 from arthyn/hm/alt-rendering
Browse files Browse the repository at this point in the history
feature: alt rendering and caching
  • Loading branch information
arthyn authored Oct 13, 2024
2 parents 2cfa02c + 8fda889 commit 9591eef
Show file tree
Hide file tree
Showing 38 changed files with 4,122 additions and 6,802 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
dist
34 changes: 1 addition & 33 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,3 @@
# scratch

A small app for saving text, similar to pastebin. Also an experimental
testbed for a new supercharged [Sail](https://developers.urbit.org/guides/additional/sail)
framework.

## thoughts (revised)
We need a way for new Hoon devs to be able to create robust UI without
needing to learn Javascript. "Server rendered" apps are fine for most use
cases. There have even been advances to make many of the drawbacks
non-existent. The main libraries that address this are [Hotwire](https://hotwired.dev/),
[htmx](https://htmx.org/), and [AlpineJS](https://alpinejs.dev/).

## first stage - complete
- using [twind](https://twind.style/) instead ~~port [TailwindCSS](https://tailwindcss.com/) to Hoon and create a library
that integrates easily with Sail and the new framework~~
- using [shoelace](https://shoelace.style/) since it's already web components so easy to use in sail ~~begin implementing basic components as "primitives" possibly using
something like [Radix UI](https://www.radix-ui.com/) or hand rolled
with~~
- built a small gate to work with alpine bindings since they use special chars will pursue more now ~~build gates or Sail hooks of some kind to integrate with one of the
"dynamic" HTML libraries listed above~~
- done! ~~build first version of the app using the above~~

## second stage
- begin wrapping functionality into gates or custom Sail tags and abstracting
functionality into components
- explore common patterns of urbit app interactions and create helpers to
facilitate easier/quicker methods
- test out urbit interface framework being developed here: https://github.com/h5gq3/todos
- rewrite app given new abstractions

## third stage
- writeup docs for everything generated in the second stage
- create more complex app to show-off what's possible and explore further
necessary abstractions
A small app for saving text, similar to pastebin or github gists
50 changes: 39 additions & 11 deletions desk/app/scratch.hoon
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/- *scratch
/+ rudder, tonic, default-agent, verb, dbug
/+ rudder, tonic, server, default-agent, verb, dbug
::
/~ pages
(page:rudder pile action)
Expand All @@ -12,7 +12,8 @@
+$ card card:agent:gall
--
::
=| state-1
=/ verbose &
=| state-2
=* state -
=<
%+ verb &
Expand Down Expand Up @@ -71,23 +72,48 @@
++ cor .
++ emit |=(=card cor(cards [card cards]))
++ give |=(=gift:agent:gall (emit %give gift))
++ log
|= msg=(trap tape)
?. verbose same
(slog leaf+"%{(trip dap.bowl)} {(msg)}" ~)
++ init
^+ cor
cor
++ load
|= =vase
=/ old !<(state-1 vase)
=. state old
cor
|^
=+ !<(old=versioned-state vase)
=? old ?=(%1 -.old) (state-1-to-2 old)
?> ?=(%2 -.old)
cor(state old)
++ state-1-to-2
|= old=state-1
^- state-2
:- %2
^- ^pile
%- ~(run by pile.old)
|= =file:v1:^old
[text.file %plain]
--
::
++ poke
|= [=mark =vase]
^+ cor
?+ mark ~|(bad-poke/mark !!)
%save
%- (log |.("save poke"))
?> =(src our):bowl
=+ !<(=save vase)
sc-abet:(sc-save:(sc-abed:sc-core p.save) q.save)
%- (log |.("saving {<save>}"))
=. cor sc-abet:(sc-save:(sc-abed:sc-core p.save) q.save)
=/ view (~(got by pages) %view)
=/ url=path /scratch/view/[p.save]
=/ =request:http [%'GET' (spat url) ~ ~]
=/ =order:rudder [%order | | [%ipv4 *@if] request]
=* page ~(. view bowl order pile)
=/ =cache-entry:eyre
[| [%payload (paint:rudder (build:page [~ url] ~ ~))]]
(emit (store:rudder (spat url) `cache-entry))
::
%delete
?> =(src our):bowl
Expand All @@ -110,7 +136,7 @@
=^ caz pile
?- action.act
%save
[[%saved cards] pile]:(poke %save !>([key.act text.act]))
[[%saved cards] pile]:(poke %save !>([key.act [text view]:act]))
%delete
[[%deleted cards] pile]:(poke %delete !>(key.act))
==
Expand All @@ -125,20 +151,22 @@
|= trail
^- (unit place)
?~ site=(decap:rudder base site) ~
?- u.site
=/ =(pole knot) u.site
?- pole
~ `[%page & %index]
[~ ~] `[%away (snip ^site)]
[%index ~] `[%away (snip ^site)]
[%view @ ~] `[%page | %view]
:: favicon
[%icon ~] `[%page | %icon]
::
[@ ~]
?: (~(has in have) i.u.site)
`[%page & i.u.site]
[part=@ ~]
?: (~(has in have) part.pole)
`[%page & part.pole]
`[%page & %index]
::
[@ ~ ~] `[%away (snip ^site)]
[%'~' rest=*] `[%page | %serve]
* ~
==
::
Expand Down
31 changes: 0 additions & 31 deletions desk/app/scratch/icon.hoon

This file was deleted.

78 changes: 46 additions & 32 deletions desk/app/scratch/index.hoon
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
/- *scratch, *docket
/- s=scratch, *docket
/+ *ui
/+ rudder, agentio
::
^- (page:rudder pile action)
^- (page:rudder pile:s action:s)
::
|_ $: =bowl:gall
=order:rudder
=pile
=pile:s
==
+* io ~(. agentio bowl)
++ argue
|= [headers=header-list:http body=(unit octs)]
^- $@(brief:rudder action)
^- $@(brief:rudder action:s)
=/ args=(map @t @t)
?~(body ~ (frisk:rudder q.u.body))
?~ key=(~(get by args) 'key') ~
?~ text=(~(get by args) 'text') ~
?~ act=(~(get by args) 'action') ~
=/ view=@t (~(gut by args) 'view' 'plain')
?~ display=(rush view (perk %plain %md %html ~)) ~
?: =(u.act 'save')
[%file u.key u.text %save]
[%file u.key u.text u.display %save]
?: =(u.act 'delete')
[%file u.key u.text %delete]
[%file u.key u.text u.display %delete]
~
++ final
|= [trail:rudder rsp=(response:rudder action)]
|= [trail:rudder rsp=(response:rudder action:s)]
^- reply:rudder
?- -.rsp
%.n (build [~ /] ~ `[| `@t`msg.rsp])
Expand All @@ -43,15 +45,17 @@
==
=/ saved ?~(msg | =(txt.u.msg 'saved'))
=/ empty (lte (lent site.trail) 1)
=/ =key
=/ =key:s
?: !empty (snag 1 site.trail)
(crip (scag 5 (flop (trip (scot %uv eny.bowl)))))
=/ file=(unit file) (~(get by pile) key)
=/ file=(unit file:s) (~(get by pile) key)
=/ base (spud /[dap.bowl])
=/ text ?~(file "" (trip text.u.file))
=/ norm (scan text (star ;~(pose (cold '\\`' (just '`')) next)))
=/ norm=tape (scan text (star ;~(pose (cold '\\`' (just '`')) next)))
=/ view=view:s ?~(file %plain view.u.file)
=/ display=tape (trip view)
^- reply:rudder
|^ [%page page]
|^ [%page page |]
++ page
%^ template q.byk.bowl ?:(empty "new note | scratch" "{(trip key)} | scratch")
:~ ;script: {data}
Expand All @@ -65,22 +69,17 @@
;+ list
==
;section.flex-1.h-full.p-4.pl-2
;form.flex.flex-col.h-full.space-y-6(method "post", x-data "\{ og: window.scratch.text, text: window.scratch.text }")
;form.flex.flex-col.h-full.space-y-6(method "post", x-data "\{ og: window.scratch.text, text: window.scratch.text, view: window.scratch.view, ogview: window.scratch.view }")
;div(class "flex-1 h-full")
;+ %: mx
%sl-textarea
'${tws({ base: "h-full", textarea: "h-full font-mono" })}'
~[[%name "text"] [%x-model "text"]]
~
==
;sl-textarea(class "part-[base]:h-full part-[textarea]:h-full font-mono", x-model "text", name "text");
==
;div(class "flex flex-col md:flex-row justify-between gap-4")
;+ %: mx
%sl-input
'flex-1'
%+ welp ?:(empty ~ ~[[%readonly ""]])
:~ [%name "key"]
[%size "small"]
[%class "flex-1"]
[%value (trip key)]
[%required ""]
[%pattern "[\\w.~\\-]*"]
Expand All @@ -94,19 +93,17 @@
;span: saved
==
==
;div.flex.justify-end.items-center.gap-2.self-start
;div.flex.justify-end.items-start.gap-2.self-start
;* actions
;+ %: mx
%sl-button
''
~[[%':disabled' "og === text"] [%variant "primary"] [%size "small"] [%type "submit"] [%name "action"] [%value "save"]]
~[[%':disabled' "og === text && ogview === view"] [%variant "primary"] [%size "small"] [%type "submit"] [%name "action"] [%value "save"]]
;sl-icon(slot "prefix", name "file-earmark-check", class "text-lg");
; save
==
;+ %: mx
%sl-button
'md:hidden'
~[[%'@click' "$refs.drawer.show()"] [%variant "secondary"] [%outline ""] [%size "small"] [%type "button"]]
~[[%class "md:hidden"] [%'@click' "$refs.drawer.show()"] [%variant "secondary"] [%outline ""] [%size "small"] [%type "button"]]
;+ ;sl-icon(name "list", class "text-lg", slot "prefix");
==
==
Expand All @@ -116,7 +113,6 @@
;div(slot "footer")
;+ %: mx
%sl-button
''
~[[%'@click' "$refs.delete.hide()"] [%variant "text"] [%size "small"] [%type "button"]]
; cancel
==
Expand All @@ -132,13 +128,13 @@
==
::
++ data
"window.scratch = \{ text: `{norm}` }"
"window.scratch = \{ text: `{norm}`, view: `{display}` }"
::
++ list
;div.flex-1.overflow-y-auto
;* %+ turn
~(tap by pile)
|= [key=@t text=@t]
|= [=key:s =text:s =view:s]
=/ text (trip text)
;a(href "{base}/{(trip key)}", class "flex flex-col p-2 rounded-md border-2 border-transparent hover:border-sky-500 hover:border-opacity-80 transition-colors {?:(=(key ^key) "bg-gray-700" "")}")
;strong: {(trip key)}
Expand All @@ -157,24 +153,42 @@
;span.flex-none.text-gray-500.font-mono.text-sm: {<major.v>}.{<minor.v>}.{<patch.v>}
==
::
++ display-dropdown
%: mx
%sl-select
:~ [%size "small"]
[%name "view"]
[%value "plain"]
[%x-model "view"]
[%x-ref "view"]
[%'@sl-change' "$refs.view._x_model.set($event.target.value)"]
==
;= ;sl-option(value "plain"): plain
;sl-option(value "md"): markdown
;sl-option(value "html"): html
;span(slot "help-text"): view mode
==
==
++ actions
^- marl
?: empty ~
:~ %: mx
?: empty ~[display-dropdown]
:~ display-dropdown
;sl-button(variant "neutral", outline "", size "small", title "View", aria-label "View", href "/scratch/view/{(trip key)}", target "_blank")
;sl-icon(slot "prefix", name "eye", class "text-lg");
==
%: mx
%sl-button
''
:~ [%variant "neutral"]
[%outline ""]
[%size "small"]
[%title "Copy URL"]
[%aria-label "Copy URL"]
[%'@click' "copy(window.location.toString().replace('/scratch', '/scratch/view'))"]
[%'@click' "copy(window.location.toString().replace('/scratch', '/scratch/view').replace('?rmsg=saved', ''))"]
==
;+ ;sl-icon(slot "prefix", name "stickies", class "text-lg");
==
%: mx
%sl-button
''
~[[%'@click' "$refs.delete.show()"] [%variant "danger"] [%outline ""] [%size "small"] [%aria-label "Delete"]]
;+ ;sl-icon(slot "prefix", name "trash", class "text-lg");
==
Expand Down
Loading

0 comments on commit 9591eef

Please sign in to comment.