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.
107 lines
2.5 KiB
107 lines
2.5 KiB
package nova.monadic_sfx.ui.components.router
|
|
|
|
import enumeratum._
|
|
import io.circe.Encoder
|
|
import io.circe.generic.JsonCodec
|
|
import io.odin.Logger
|
|
import monix.bio.Task
|
|
import nova.monadic_sfx.util.IOUtils
|
|
import nova.monadic_sfx.util.reactive.Reducer
|
|
import nova.monadic_sfx.util.reactive.Store
|
|
import scalafx.scene.Parent
|
|
import scalafx.scene.control.Label
|
|
|
|
object FXRouter {
|
|
|
|
final case class State[P](page: P)
|
|
|
|
@JsonCodec
|
|
sealed abstract class Action[T]
|
|
// final case object Init extends Action
|
|
final case class Replace[T](p: T) extends Action[T]
|
|
|
|
type FXStore[P] = Store[Action[P], State[P]]
|
|
|
|
// def resolver2 = resolver.lift.andThen(_.getOrElse(notFound))
|
|
|
|
// def resolver: PartialFunction[P <: Enum[P]][P, Parent] = {
|
|
// case Home => new TextField
|
|
// }
|
|
|
|
}
|
|
|
|
class FXRouter[P <: EnumEntry](
|
|
)(implicit E: Encoder[P]) {
|
|
import FXRouter._
|
|
|
|
def store(initialPage: P, logger: Logger[Task]) =
|
|
Task.deferAction(implicit s =>
|
|
Store.createL[Action[P], State[P]](
|
|
Replace(initialPage),
|
|
State(initialPage),
|
|
Reducer.withOptionalEffects[Task, Action[P], State[P]](reducer _)
|
|
// Seq(actionLoggerMiddleware(logger, "RouterStore"))
|
|
)
|
|
)
|
|
|
|
def reducer(
|
|
state: State[P],
|
|
action: Action[P]
|
|
): (State[P], Option[Task[Action[P]]]) =
|
|
action match {
|
|
// case Init => (state, None)
|
|
case Replace(p) =>
|
|
(state.copy(page = p), None)
|
|
}
|
|
|
|
def render(
|
|
resolver: P => Task[Parent]
|
|
)(implicit store: FXStore[P]) =
|
|
store.mapEval { case (_, FXRouter.State(p)) => IOUtils.toTask(resolver(p)) }
|
|
|
|
def link(
|
|
page: P,
|
|
store: FXStore[P]
|
|
) = {
|
|
store.onNext(Replace(page))
|
|
}
|
|
}
|
|
|
|
object BrainNotWorking {
|
|
|
|
@JsonCodec
|
|
sealed trait Page extends EnumEntry
|
|
object Page extends Enum[Page] {
|
|
val values = findValues
|
|
final case object Home extends Page
|
|
final case class UserHome(id: Int) extends Page
|
|
}
|
|
|
|
def resolver: PartialFunction[Page, Task[Parent]] = {
|
|
case Page.Home =>
|
|
Task(new Label {
|
|
text = "HomePage"
|
|
})
|
|
case Page.UserHome(id0) =>
|
|
Task(new Label {
|
|
text = s"User Home, Id = $id0"
|
|
})
|
|
}
|
|
|
|
val router = new FXRouter[Page]
|
|
}
|
|
|
|
// case class State()
|
|
// object RouterStore {
|
|
|
|
// sealed trait Action
|
|
// case object Init extends Action
|
|
|
|
// def reducer(state: State, action: Action) =
|
|
// action match {
|
|
// case Init => state
|
|
|
|
// }
|
|
// def apply() =
|
|
// Store.createL[Action, State](Init, State(), Reducer(reducer _), Seq.empty)
|
|
// }
|