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

  1. package nova.monadic_sfx.ui.components.router
  2. import enumeratum._
  3. import io.circe.Encoder
  4. import io.circe.generic.JsonCodec
  5. import io.odin.Logger
  6. import monix.bio.Task
  7. import nova.monadic_sfx.util.IOUtils
  8. import nova.monadic_sfx.util.reactive.Reducer
  9. import nova.monadic_sfx.util.reactive.Store
  10. import scalafx.scene.Parent
  11. import scalafx.scene.control.Label
  12. object FXRouter {
  13. final case class State[P](page: P)
  14. @JsonCodec
  15. sealed abstract class Action[T]
  16. // final case object Init extends Action
  17. final case class Replace[T](p: T) extends Action[T]
  18. type FXStore[P] = Store[Action[P], State[P]]
  19. // def resolver2 = resolver.lift.andThen(_.getOrElse(notFound))
  20. // def resolver: PartialFunction[P <: Enum[P]][P, Parent] = {
  21. // case Home => new TextField
  22. // }
  23. }
  24. class FXRouter[P <: EnumEntry](
  25. )(implicit E: Encoder[P]) {
  26. import FXRouter._
  27. def store(initialPage: P, logger: Logger[Task]) =
  28. Task.deferAction(implicit s =>
  29. Store.createL[Action[P], State[P]](
  30. Replace(initialPage),
  31. State(initialPage),
  32. Reducer.withOptionalEffects[Task, Action[P], State[P]](reducer _)
  33. // Seq(actionLoggerMiddleware(logger, "RouterStore"))
  34. )
  35. )
  36. def reducer(
  37. state: State[P],
  38. action: Action[P]
  39. ): (State[P], Option[Task[Action[P]]]) =
  40. action match {
  41. // case Init => (state, None)
  42. case Replace(p) =>
  43. (state.copy(page = p), None)
  44. }
  45. def render(
  46. resolver: P => Task[Parent]
  47. )(implicit store: FXStore[P]) =
  48. store.mapEval { case (_, FXRouter.State(p)) => IOUtils.toTask(resolver(p)) }
  49. def link(
  50. page: P,
  51. store: FXStore[P]
  52. ) = {
  53. store.onNext(Replace(page))
  54. }
  55. }
  56. object BrainNotWorking {
  57. @JsonCodec
  58. sealed trait Page extends EnumEntry
  59. object Page extends Enum[Page] {
  60. val values = findValues
  61. final case object Home extends Page
  62. final case class UserHome(id: Int) extends Page
  63. }
  64. def resolver: PartialFunction[Page, Task[Parent]] = {
  65. case Page.Home =>
  66. Task(new Label {
  67. text = "HomePage"
  68. })
  69. case Page.UserHome(id0) =>
  70. Task(new Label {
  71. text = s"User Home, Id = $id0"
  72. })
  73. }
  74. val router = new FXRouter[Page]
  75. }
  76. // case class State()
  77. // object RouterStore {
  78. // sealed trait Action
  79. // case object Init extends Action
  80. // def reducer(state: State, action: Action) =
  81. // action match {
  82. // case Init => state
  83. // }
  84. // def apply() =
  85. // Store.createL[Action, State](Init, State(), Reducer(reducer _), Seq.empty)
  86. // }