it works!

This commit is contained in:
fiatjaf 2023-03-23 21:04:53 -03:00
parent fa7c9b632a
commit 570ee55359
No known key found for this signature in database
GPG Key ID: BAD43C4BE5C1A3A1

View File

@ -1,3 +1,4 @@
import cats.data.*
import cats.effect.* import cats.effect.*
import cats.effect.syntax.all.* import cats.effect.syntax.all.*
import cats.syntax.all.* import cats.syntax.all.*
@ -9,64 +10,92 @@ import calico.html.io.{*, given}
import calico.syntax.* import calico.syntax.*
import snow.* import snow.*
object Store {
def apply(window: Window[IO]): Resource[IO, Store] = {
val key = "nak-input"
for {
inputRef <- SignallingRef[IO].of("").toResource
_ <- Resource.eval {
OptionT(window.localStorage.getItem(key))
.foreachF(inputRef.set(_))
}
_ <- window.localStorage
.events(window)
.foreach {
case Storage.Event.Updated(`key`, _, value, _) =>
inputRef.set(value)
case _ => IO.unit
}
.compile
.drain
.background
_ <- inputRef.discrete
.foreach(input => IO.cede *> window.localStorage.setItem(key, input))
.compile
.drain
.background
} yield new Store(inputRef)
}
}
case class Store(input: SignallingRef[IO, String])
object Main extends IOWebApp { object Main extends IOWebApp {
def render: Resource[IO, HtmlDivElement[IO]] = { def render: Resource[IO, HtmlDivElement[IO]] = Store(window).flatMap {
div( store =>
cls := "flex w-full h-full flex-col items-center justify-center",
h1(cls := "px-1 py-2 text-lg", "nostr army knife"),
div( div(
cls := "flex justify-center my-3" cls := "flex w-full h-full flex-col items-center justify-center",
// button(cls := buttonCls, "generate event", onClick --> (_.foreach(_ => ))), h1(cls := "px-1 py-2 text-lg", "nostr army knife"),
), div(
input() cls := "flex justify-center my-3"
) // button(cls := buttonCls, "generate event", onClick --> (_.foreach(_ => ))),
),
input(store),
result(store)
)
} }
def input(): Resource[IO, HtmlDivElement[IO]] = def input(store: Store): Resource[IO, HtmlDivElement[IO]] =
SignallingRef[IO] div(
.of("") cls := "w-full",
.toResource div(
.flatMap { input => cls := "w-full flex justify-center",
div( textArea.withSelf { self =>
cls := "w-full", (
div( cls := "w-2/3 max-h-96 p-3",
cls := "w-full flex justify-center", styleAttr := "min-height: 200px",
textArea.withSelf { self => placeholder := "paste something nostric",
( onInput --> (_.foreach(_ =>
cls := "w-2/3 max-h-96 p-3", self.value.get.flatMap(store.input.set)
styleAttr := "min-height: 200px", )),
placeholder := "paste something nostric", value <-- store.input
onInput --> (_.foreach(_ => self.value.get.flatMap(input.set))),
value <-- input
)
}
) )
) }
} )
)
def result(): Resource[IO, HtmlDivElement[IO]] = def result(store: Store): Resource[IO, HtmlDivElement[IO]] =
SignallingRef[IO] div(
.of("") cls := "w-full flex justify-center",
.toResource store.input.map { input =>
.flatMap { input => if input.trim() == "" then ""
div( else
cls := "w-full flex justify-center", decode[Event](input) match {
input.map(inp => case Right(event) => event.toString
if inp.trim() == "" then "" case Left(err: io.circe.DecodingFailure) =>
else err.pathToRootString match {
decode[Event](inp) match { case Some(path) => s"field $path is missing or wrong"
case Right(event) => event.toString case None => s"decoding ${err.pathToRootString}"
case Left(err: io.circe.DecodingFailure) =>
err.pathToRootString match {
case Some(path) => s"field $path is missing or wrong"
case None => s"decoding ${err.pathToRootString}"
}
case Left(err: io.circe.ParsingFailure) =>
"not valid JSON"
} }
) case Left(err: io.circe.ParsingFailure) =>
) "not valid JSON"
}
} }
)
val buttonCls = val buttonCls =
"bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 mx-2 px-4 rounded" "bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 mx-2 px-4 rounded"