From 7dd1bf758a280858a62aadf5cace317654bc885f Mon Sep 17 00:00:00 2001 From: Zak Patterson Date: Mon, 4 Feb 2019 17:14:34 -0500 Subject: [PATCH] Enable router to get initial pathname on load Also makes router parameterized so that users can have their own custom adt. --- .../main/scala/outwatch/router/Router.scala | 31 ++++++++++++------- .../main/scala/outwatch/router/package.scala | 4 +-- 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/outwatch-router/src/main/scala/outwatch/router/Router.scala b/outwatch-router/src/main/scala/outwatch/router/Router.scala index e6d91ed..1a6af97 100644 --- a/outwatch-router/src/main/scala/outwatch/router/Router.scala +++ b/outwatch-router/src/main/scala/outwatch/router/Router.scala @@ -6,26 +6,35 @@ import org.scalajs.dom.window import outwatch.dom._, dsl._ import outwatch.util.Store - sealed trait Action final case class Replace(path: Path) extends Action -final case class RouterState(path: Path) +final case class RouterState[P](page: P) -object AppRouter { - def routerReducer(state: RouterState, action: Action): RouterState = action match { +class AppRouter[F[_]: LiftIO, P](f: Path => P) { + def routerReducer(state: RouterState[P], action: Action): RouterState[P] = action match { case Replace(path) => + println(s"Going to $path") Path.unapplySeq(path).foreach(p => window.history.replaceState("", "", p.mkString("/"))) - state.copy(path = path) + state.copy(page = f(path)) case _ => state } - def store[F[_]: LiftIO](implicit S : Scheduler): F[RouterStore] = - Store.create[RouterState, Action]( - RouterState(Root), + def store(implicit S : Scheduler): F[RouterStore[P]] = { + val startingPath = Path(window.location.pathname) + + Store.create[RouterState[P], Action]( + RouterState(f(startingPath)), Store.Reducer.justState(routerReducer _) ).to[F] - - def render(resolver: RouterResolve)(implicit store: RouterStore): VDomModifier = - div(store.map(state => resolver(state.path))) + } +} + + +object AppRouter{ + def render[P](resolver: RouterResolve[P])(implicit store: RouterStore[P]): VDomModifier = + div(store.map(state => resolver(state.page))) + + def create[F[_]: LiftIO, P](notFound: P)(f: PartialFunction[Path, P]): AppRouter[F, P] = + new AppRouter[F, P](f.lift.andThen(_.getOrElse(notFound))) } diff --git a/outwatch-router/src/main/scala/outwatch/router/package.scala b/outwatch-router/src/main/scala/outwatch/router/package.scala index 362b185..2857f31 100644 --- a/outwatch-router/src/main/scala/outwatch/router/package.scala +++ b/outwatch-router/src/main/scala/outwatch/router/package.scala @@ -3,7 +3,7 @@ package outwatch import outwatch.dom.VDomModifier package object router { - type RouterStore = ProHandler[Action, RouterState] + type RouterStore[P] = ProHandler[Action, RouterState[P]] - type RouterResolve = PartialFunction[Path, VDomModifier] + type RouterResolve[P] = PartialFunction[P, VDomModifier] }