|
@ -12,14 +12,17 @@ import nova.monadic_sfx.util.reactive.store.Middlewares |
|
|
import nova.monadic_sfx.util.reactive.store.Reducer |
|
|
import nova.monadic_sfx.util.reactive.store.Reducer |
|
|
import nova.monadic_sfx.util.reactive.store.Store |
|
|
import nova.monadic_sfx.util.reactive.store.Store |
|
|
import scalafx.scene.Parent |
|
|
import scalafx.scene.Parent |
|
|
|
|
|
import monix.reactive.Observable |
|
|
|
|
|
import nova.monadic_sfx.util.controls.JFXSpinner |
|
|
|
|
|
import scala.concurrent.duration._ |
|
|
|
|
|
import monix.eval.Coeval |
|
|
|
|
|
|
|
|
object FXRouter { |
|
|
object FXRouter { |
|
|
|
|
|
|
|
|
final case class State[P](page: P) |
|
|
final case class State[P](page: P) |
|
|
|
|
|
|
|
|
// @JsonCodec |
|
|
|
|
|
sealed abstract class Action[+T] |
|
|
sealed abstract class Action[+T] |
|
|
final case class Replace[T](p: T) extends Action[T] |
|
|
|
|
|
|
|
|
final case class Replace[T](page: T) extends Action[T] |
|
|
|
|
|
|
|
|
object Action { |
|
|
object Action { |
|
|
implicit def codec[T: Encoder: Decoder]: Codec[Action[T]] = deriveCodec |
|
|
implicit def codec[T: Encoder: Decoder]: Codec[Action[T]] = deriveCodec |
|
@ -29,8 +32,7 @@ object FXRouter { |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
class FXRouter[P]( |
|
|
|
|
|
)(implicit E: Encoder[P], D: Decoder[P]) { |
|
|
|
|
|
|
|
|
class FXRouter[P]()(implicit E: Encoder[P], D: Decoder[P]) { |
|
|
import FXRouter._ |
|
|
import FXRouter._ |
|
|
|
|
|
|
|
|
def store(initialPage: P, logger: Logger[Task]): Task[FXStore[P]] = |
|
|
def store(initialPage: P, logger: Logger[Task]): Task[FXStore[P]] = |
|
@ -60,9 +62,26 @@ class FXRouter[P]( |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
def render( |
|
|
def render( |
|
|
resolver: P => Task[Parent] |
|
|
|
|
|
|
|
|
resolver: P => Task[Parent], |
|
|
|
|
|
transitionDelay: FiniteDuration = 500.millis |
|
|
)(implicit store: FXStore[P]) = |
|
|
)(implicit store: FXStore[P]) = |
|
|
store.mapEval { case (_, FXRouter.State(p)) => IOUtils.toTask(resolver(p)) } |
|
|
|
|
|
|
|
|
store |
|
|
|
|
|
.flatMap { |
|
|
|
|
|
case (_, FXRouter.State(p)) => |
|
|
|
|
|
Observable.from(Coeval(new JFXSpinner)) ++ Observable.from( |
|
|
|
|
|
IOUtils.toTask( |
|
|
|
|
|
Task |
|
|
|
|
|
.racePair( |
|
|
|
|
|
Task.sleep(transitionDelay), |
|
|
|
|
|
resolver(p) |
|
|
|
|
|
) |
|
|
|
|
|
.flatMap { |
|
|
|
|
|
case Left(_ -> fib) => fib.join |
|
|
|
|
|
case Right(fib -> res) => fib.join >> Task.pure(res) |
|
|
|
|
|
} |
|
|
|
|
|
) |
|
|
|
|
|
) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
def link( |
|
|
def link( |
|
|
page: P, |
|
|
page: P, |
|
|