/
GithubEventSignal.elm
88 lines (69 loc) · 2.34 KB
/
GithubEventSignal.elm
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
module GithubEventSignal(SingleEvent(..), eventsOneByOne, fetchOnce) where
import Http
import GithubEvent exposing (Event)
import Time
import Task exposing (Task, andThen)
type SingleEvent = NothingYet | SoThisHappened Event
--- port
fetchOnce: Signal (Task Http.Error ())
fetchOnce =
Signal.constant fetchPageOfEvents
|> Signal.map (\task -> task `andThen` Signal.send newEvents.address)
-- wiring
newEvents : Signal.Mailbox (List Event)
newEvents = Signal.mailbox []
-- signal
eventsOneByOne : Signal SingleEvent
eventsOneByOne =
newEvents.signal
|> Signal.map (\e -> SomeNewEvents (List.reverse e))
|> Signal.merge everyFewSeconds
|> Signal.foldp splitEvents (SplitEvents [] [])
|> Signal.map singleEvents
|> Signal.filterMap (\a -> Maybe.map SoThisHappened a) NothingYet
-- private
type InnerStuff =
Heartbeat
| SomeNewEvents (List Event)
everyFewSeconds : Signal InnerStuff
everyFewSeconds = Signal.map (\_ -> Heartbeat) (Time.every 3000)
type alias SplitEvents =
{
seenEvents : List Event,
queuedEvents : List Event
}
splitEvents: InnerStuff -> SplitEvents -> SplitEvents
splitEvents action before =
case action of
Heartbeat -> moveOneOver before
SomeNewEvents events -> queueEvents before events
singleEvents: SplitEvents -> Maybe Event
singleEvents splitEvents =
case splitEvents.queuedEvents of
[] -> Nothing
head :: _ -> Just head
type alias SomeEventModel =
{
seen: List Event,
unseen: List Event
}
moveOneOver : SplitEvents -> SplitEvents
moveOneOver before =
case before.queuedEvents of
[] -> before
head :: tail -> { seenEvents = head :: before.seenEvents, queuedEvents = tail }
queueEvents : SplitEvents -> List Event -> SplitEvents
queueEvents before moreEvents =
{ seenEvents = before.seenEvents, queuedEvents = before.queuedEvents ++ moreEvents }
-- todo: record "suchthat" syntax
-- Fetchy Fetchy
fetchPageOfEvents : Task Http.Error (List Event)
fetchPageOfEvents =
let
pageNo = 1
parameters = [("page", toString pageNo)]
in
Http.get GithubEvent.listDecoder (github "satellite-of-love" "Hungover" pageNo)
github : String -> String -> Int -> String
github owner repo pageNo = Http.url ("https://api.github.com/repos/" ++ owner ++ "/" ++ repo ++ "/events") <|
[("pageNo", (toString pageNo))]