keep parse result on Store.

This commit is contained in:
fiatjaf 2023-03-24 22:12:11 -03:00
parent b9fc27ea2f
commit 8961eddc43
No known key found for this signature in database
GPG Key ID: BAD43C4BE5C1A3A1
3 changed files with 62 additions and 57 deletions

View File

@ -1,4 +1,3 @@
import cats.data.*
import cats.effect.*
import cats.effect.syntax.all.*
import cats.syntax.all.*
@ -15,40 +14,6 @@ import snow.*
import Utils.*
import Components.*
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 {
def render: Resource[IO, HtmlDivElement[IO]] = Store(window).flatMap {
store =>
@ -120,23 +85,18 @@ object Main extends IOWebApp {
def result(store: Store): Resource[IO, HtmlDivElement[IO]] =
div(
cls := "w-full flex my-5",
store.input.map { input =>
if input.trim() == "" then div("")
else
Parser.parseInput(input) match {
case Left(msg) => div(msg)
case Right(event: Event) =>
renderEvent(event)
case Right(pp: ProfilePointer) => renderProfilePointer(pp)
case Right(evp: EventPointer) => renderEventPointer(evp)
case Right(sk: PrivateKey) =>
renderProfilePointer(
ProfilePointer(pubkey = sk.publicKey.xonly),
Some(sk)
)
case Right(addr: AddressPointer) => renderAddressPointer(addr)
}
store.result.map {
case Left(msg) => div(msg)
case Right(event: Event) =>
renderEvent(event)
case Right(pp: ProfilePointer) => renderProfilePointer(pp)
case Right(evp: EventPointer) => renderEventPointer(evp)
case Right(sk: PrivateKey) =>
renderProfilePointer(
ProfilePointer(pubkey = sk.publicKey.xonly),
Some(sk)
)
case Right(addr: AddressPointer) => renderAddressPointer(addr)
}
)
}

View File

@ -3,13 +3,13 @@ import cats.syntax.all.*
import scoin.*
import snow.*
import Components.*
type Result = Either[
String,
Event | PrivateKey | AddressPointer | EventPointer | ProfilePointer
]
object Parser {
def parseInput(input: String): Either[
String,
Event | PrivateKey | AddressPointer | EventPointer | ProfilePointer
] =
def parseInput(input: String): Result =
NIP19.decode(input) match {
case Right(pp: ProfilePointer) => Right(pp)
case Right(evp: EventPointer) => Right(evp)

View File

@ -0,0 +1,45 @@
import cats.data.*
import cats.effect.*
import cats.effect.syntax.all.*
import cats.syntax.all.*
import fs2.concurrent.*
import fs2.dom.{Event => _, *}
case class Store(
input: SignallingRef[IO, String],
result: SignallingRef[IO, Result]
)
object Store {
def apply(window: Window[IO]): Resource[IO, Store] = {
val key = "nak-input"
for {
input <- SignallingRef[IO].of("").toResource
result <- SignallingRef[IO, Result](Left("")).toResource
_ <- Resource.eval {
OptionT(window.localStorage.getItem(key))
.foreachF(input.set(_))
}
_ <- window.localStorage
.events(window)
.foreach {
case Storage.Event.Updated(`key`, _, value, _) =>
input.set(value)
case _ => IO.unit
}
.compile
.drain
.background
_ <- input.discrete
.evalTap(input => IO.cede *> window.localStorage.setItem(key, input))
.evalTap(input => result.set(Parser.parseInput(input)))
.compile
.drain
.background
} yield Store(input, result)
}
}