You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

187 lines
6.2 KiB

package outwatchapp
import scala.concurrent.duration._
import colibri.ext.monix._
import com.softwaremill.macwire._
import io.odin.consoleLogger
import monix.bio.Task
import monix.eval.Coeval
import monix.reactive.Observable
import monix.{eval => me}
import org.scalajs.dom.raw.Element
import outwatch._
import outwatch.dsl._
import outwatch.router._
import outwatchapp.components.ChartjsDemo
import outwatchapp.components.CounterDemo
import outwatchapp.components.DatatablesDemo
import outwatchapp.components.FusejsDemo
import outwatchapp.components.RequestDemo
import outwatchapp.pages.HomePage
import outwatchapp.ui.components.todo.TodoListStore
import outwatchapp.util.IOUtils
import outwatchapp.util.reactive.WebSocket
import outwatchapp.util.reactive.WebWorker
import outwatchapp.util.reactive.WebsocketData
import outwatchapp.util.reactive.WorkerData
import outwatchapp.util.reactive.ReconnectingWebSocket
import cats.syntax.eq._
import monix.execution.Ack
import monix.reactive.Observer
class MainApp(el: Element)(implicit
backend: AppTypes.Backend,
store: RouterStore[Page]
) {
import MainApp._
def run: Task[Unit] = for {
resolver <- resolver
_ <- OutWatch.renderInto[Task](el, Router(resolver))
} yield ()
def producer(data: Long, ws: Observer[WebsocketData]): me.Task[Unit] =
me.Task.deferFuture(ws.onNext(WebsocketData(data))).flatMap {
case Ack.Continue => producer(data + 1, ws)
// .delayExecution(3.seconds)
case Ack.Stop => me.Task.unit
}
def resolver: Task[PartialFunction[Page, VDomModifier]] =
Task.deferAction(implicit s =>
for {
counterDemo <- CounterDemo()
chartDemo <- ChartjsDemo()
todoStore <- TodoListStore(consoleLogger[Task]())
requestDemo <- RequestDemo(todoStore)
demoWorker <- WebWorker[WorkerData]("/worker.js")
dtDemo <- DatatablesDemo()
_ <- IOUtils
.toIO(
Observable
.interval(1.second)
.take(2)
.doOnNextF(i => Coeval(println(s"Producer emitted $i")))
.doOnNextF(i =>
me.Task.deferFuture(demoWorker.onNext(WorkerData(i))).void
)
.completedL >>
me.Task.deferFuture(demoWorker.onNext(WorkerData(999)))
// .delayExecution(6.seconds)
)
.startAndForget
_ <-
ReconnectingWebSocket[WebsocketData]("ws://localhost:6789").flatMap {
case (source, sink) =>
IOUtils
.toIO(
me.Task.parZip2(
// Observable
// .interval(3.seconds)
// .doOnNext(_ => me.Task(println("Sending websocket data")))
// .doOnNext(i =>
// me.Task.deferFuture(
// ws.onNext(WebsocketData(i))
// ) >> me.Task.unit
// )
// .completedL,
producer(0, sink.value),
source.value
.doOnNext(data => me.Task(println(s"Received : $data")))
.completedL
)
)
}
// .onErrorRestartIf {
// case e: Exception =>
// e.getMessage() === "Websocket closed"
// case _ => false
// }
// .onErrorRestartLoop(Backoff(3, 1.second)) { (err, state, retry) =>
// val Backoff(maxRetries, delay) = state
// if (maxRetries > 0)
// retry(Backoff(maxRetries - 1, delay * 2)).delayExecution(delay)
// else
// // No retries left, rethrow the error
// Task.raiseError(err)
// }
.startAndForget
// .start
// .startAndForget
// _ <- SweetAlertDemo.dumbNotif
// _ <- Task(println(s"Notif result: $notifRes"))
} yield {
case Page.Home => wire[HomePage].render
case Page.SomePage =>
div(
div(cls := "title", "SomePage"),
// RequestDemo(todoStore),
// Observable
// .interval(1.second)
// .doOnNextF(i => Coeval(println(s"Producer emitted $i")))
// .doOnNextF(i =>
// Coeval(demoWorker.onNext(WorkerData(i))) >> Coeval.unit
// )
// .take(2)
// .map(_ => div()),
demoWorker.map(_.toString).map(v => p(cls := "text-white", v)),
requestDemo,
div(cls := "slider")
)
case Page.UserHome(id) =>
div(
// cls := "text-white",
div(cls := "title", "UserHome"),
s"User id: $id",
div(FusejsDemo.y.map(_.item.toString).mkString(" ")),
// ExampleDataTable.value(
// onDomMount.asHtml.foreachSync(el =>
// Coeval(DatatablesDemo.init(el)) >> Coeval.unit
// )
// )
dtDemo
)
case Page.NotFound =>
Task(
div(
cls := "page-header error-page header-filter",
div(
cls := "page-header-image"
// style := js.Dictionary(
// "background-image" -> "url('../assets/img/braden-collum.jpg')"
// )
),
div(
cls := "container",
cls := "text-center",
div(
cls := "row",
div(
cls := "col-md-12",
h1(
fontSize := "12em",
color := "#fff",
letterSpacing := "14px",
fontWeight := 700,
cls := "title",
"404"
),
h2(cls := "description", "Page not found :("),
h4(
cls := "description",
"Ooooups! Looks like you got lost."
)
)
)
)
)
)
}
)
}
object MainApp {
final case class Backoff(maxRetries: Long, delay: FiniteDuration)
}