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.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)))
}

View File

@ -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]
}