1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
import { h, Html } from 'lib/rx'
import * as rx from 'lib/rx'
import * as layout from 'ui/layout'
import * as request from 'request'
import * as login from 'pages/login'
import * as maps from 'pages/maps'
import * as notFound from 'pages/notFound'
import * as route from 'route'
import * as pagesLayout from 'pages/layout'
import * as map from 'pages/map'
import * as L from 'lib/loadable'
import { User } from 'models/user'
// Push internal route when clicking on link
document.addEventListener('click', (event: Event) => {
if (event.target !== null) {
const element = event.target as HTMLElement
const href = element.getAttribute('href')
if (href !== null) {
const r = route.get(href)
if (r !== undefined) {
event.preventDefault()
route.push(r)
}
}
}
})
rx.mount(
document.body,
rx.withState<route.Route | undefined>(route.get(window.location.pathname), routeVar =>
rx.withState<L.Loadable<User>>(L.init, userLoadableVar => {
window.onpopstate = (event: Event) => {
routeVar.update(_ => route.get(window.location.pathname))
}
return rx.map2([routeVar, userLoadableVar], (route, userLoadable) =>
view({
route,
userLoadable,
updateUser: userLoadable => userLoadableVar.update(_ => userLoadable)
})
)
})
)
)
interface ViewParams {
route: route.Route | undefined
userLoadable: L.Loadable<User>
updateUser: (userLoadable: L.Loadable<User>) => void
}
function view({ route, userLoadable, updateUser }: ViewParams): Html {
if (route?.state == 'login') {
return login.view({ updateUser: (user: User) => updateUser(L.loaded(user)) })
} else {
if (userLoadable == L.init) {
request
.get<User>('/api/user')
.then(user => updateUser(L.loaded(user)))
.catch(({ message }) => updateUser(L.failure(message)))
}
return layout.loadable(userLoadable, user =>
pagesLayout.view(user, viewLoggedIn(route))
)
}
}
function viewLoggedIn(route?: route.Route): Html {
if (route?.state == 'maps') {
return maps.view()
} else if (route?.state == 'map') {
return map.view(route.id)
} else {
return notFound.view()
}
}
|