-
-
Notifications
You must be signed in to change notification settings - Fork 139
/
Copy pathMain.hs
145 lines (134 loc) · 4.31 KB
/
Main.hs
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TypeFamilies #-}
module Main where
import Data.Aeson
import Data.Aeson.Types
import qualified Data.Map as M
import Data.Maybe
import GHC.Generics
import JavaScript.Web.XMLHttpRequest
import Miso hiding (defaultOptions)
import Miso.String
-- | Model
data Model
= Model
{ info :: Maybe APIInfo
} deriving (Eq, Show)
-- | Action
data Action
= FetchGitHub
| SetGitHub APIInfo
| NoOp
deriving (Show, Eq)
-- | Main entry point
main :: IO ()
main = do
startApp App { model = Model Nothing
, initialAction = NoOp
, mountPoint = Nothing
, ..
}
where
update = updateModel
events = defaultEvents
subs = []
view = viewModel
logLevel = Off
-- | Update your model
updateModel :: Action -> Model -> Effect Action Model
updateModel FetchGitHub m = m <# do
SetGitHub <$> getGitHubAPIInfo
updateModel (SetGitHub apiInfo) m =
noEff m { info = Just apiInfo }
updateModel NoOp m = noEff m
-- | View function, with routing
viewModel :: Model -> View Action
viewModel Model {..} = view
where
view = div_ [ style_ $ M.fromList [
(pack "text-align", pack "center")
, (pack "margin", pack "200px")
]
] [
h1_ [class_ $ pack "title" ] [ text $ pack "Miso XHR Example" ]
, button_ attrs [
text $ pack "Fetch JSON from https://api.github.com via XHR"
]
, case info of
Nothing -> div_ [] [ text $ pack "No data" ]
Just APIInfo{..} ->
table_ [ class_ $ pack "table is-striped" ] [
thead_ [] [
tr_ [] [
th_ [] [ text $ pack "URLs"]
]
]
, tbody_ [] [
tr_ [] [ td_ [] [ text current_user_url ] ]
, tr_ [] [ td_ [] [ text emojis_url ] ]
, tr_ [] [ td_ [] [ text emails_url ] ]
, tr_ [] [ td_ [] [ text events_url ] ]
, tr_ [] [ td_ [] [ text gists_url ] ]
, tr_ [] [ td_ [] [ text feeds_url ] ]
, tr_ [] [ td_ [] [ text followers_url ] ]
, tr_ [] [ td_ [] [ text following_url ] ]
]
]
]
where
attrs = [ onClick FetchGitHub
, class_ $ pack "button is-large is-outlined"
] ++ [ disabled_ True | isJust info ]
data APIInfo
= APIInfo
{ current_user_url :: MisoString
, current_user_authorizations_html_url :: MisoString
, authorizations_url :: MisoString
, code_search_url :: MisoString
, commit_search_url :: MisoString
, emails_url :: MisoString
, emojis_url :: MisoString
, events_url :: MisoString
, feeds_url :: MisoString
, followers_url :: MisoString
, following_url :: MisoString
, gists_url :: MisoString
, hub_url :: MisoString
, issue_search_url :: MisoString
, issues_url :: MisoString
, keys_url :: MisoString
, notifications_url :: MisoString
, organization_repositories_url :: MisoString
, organization_url :: MisoString
, public_gists_url :: MisoString
, rate_limit_url :: MisoString
, repository_url :: MisoString
, repository_search_url :: MisoString
, current_user_repositories_url :: MisoString
, starred_url :: MisoString
, starred_gists_url :: MisoString
, user_url :: MisoString
, user_organizations_url :: MisoString
, user_repositories_url :: MisoString
, user_search_url :: MisoString
} deriving (Show, Eq, Generic)
instance FromJSON APIInfo where
parseJSON = genericParseJSON defaultOptions { fieldLabelModifier = camelTo '_' }
getGitHubAPIInfo :: IO APIInfo
getGitHubAPIInfo = do
Just resp <- contents <$> xhrByteString req
case eitherDecodeStrict resp :: Either String APIInfo of
Left s -> error s
Right j -> pure j
where
req = Request { reqMethod = GET
, reqURI = pack "https://api.github.com"
, reqLogin = Nothing
, reqHeaders = []
, reqWithCredentials = False
, reqData = NoData
}