Enable router to get initial pathname on load

Also makes router parameterized so that users can
have their own custom adt.
This commit is contained in:
Zak Patterson 2019-02-04 17:14:34 -05:00
parent ce39b200c2
commit 7dd1bf758a
2 changed files with 22 additions and 13 deletions

View File

@ -6,26 +6,35 @@ import org.scalajs.dom.window
import outwatch.dom._, dsl._ import outwatch.dom._, dsl._
import outwatch.util.Store import outwatch.util.Store
sealed trait Action sealed trait Action
final case class Replace(path: Path) extends Action final case class Replace(path: Path) extends Action
final case class RouterState(path: Path) final case class RouterState[P](page: P)
object AppRouter { class AppRouter[F[_]: LiftIO, P](f: Path => P) {
def routerReducer(state: RouterState, action: Action): RouterState = action match { def routerReducer(state: RouterState[P], action: Action): RouterState[P] = action match {
case Replace(path) => case Replace(path) =>
println(s"Going to $path")
Path.unapplySeq(path).foreach(p => window.history.replaceState("", "", p.mkString("/"))) Path.unapplySeq(path).foreach(p => window.history.replaceState("", "", p.mkString("/")))
state.copy(path = path) state.copy(page = f(path))
case _ => state case _ => state
} }
def store[F[_]: LiftIO](implicit S : Scheduler): F[RouterStore] = def store(implicit S : Scheduler): F[RouterStore[P]] = {
Store.create[RouterState, Action]( val startingPath = Path(window.location.pathname)
RouterState(Root),
Store.create[RouterState[P], Action](
RouterState(f(startingPath)),
Store.Reducer.justState(routerReducer _) Store.Reducer.justState(routerReducer _)
).to[F] ).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)))
} }

View File

@ -3,7 +3,7 @@ package outwatch
import outwatch.dom.VDomModifier import outwatch.dom.VDomModifier
package object router { 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]
} }