-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathModel.elm
108 lines (90 loc) · 3.76 KB
/
Model.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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
module Model exposing (Version, History, Identifier, ObjectClass (..), Response, Model, Msg (..), Selected
, history, versions, LockerState (..), NavigationDirection (..), getNextVersion
, getPreviousVersion, getDistance, canNavigate, TimelineZoom(..))
import Date exposing (Date, toTime)
import Date.Extra.Compare exposing (Compare2(..), is)
import Either exposing (Either)
import Http
import Json.Encode exposing (Value)
import Maybe exposing (map, map2, map3, withDefault)
import Maybe.Extra exposing (join)
import Navigation exposing (Location)
import List exposing (head)
import List.Extra exposing ((!!), last)
type alias Response =
{ stamp : Date.Date
, history : List History
}
type alias Model =
{ resource : String
, response : Either String Response
, selected : Int
, displayedVersions : (Maybe Version, Maybe Version)
, navigationLocks : (LockerState, LockerState)
, versionDateDetail : Maybe Date
, timelineWidgetZoom : TimelineZoom
, timelineWidgetZoomDate : Maybe Date
}
type Msg
= UrlChange Location
| Fetched String (Result Http.Error Response)
| StartSearch String
| Select Int
| NavigateDiff NavigationDirection
| NavigateDiffToVersion Version
| FlipNavLock NavigationDirection
| FlipShowVersionDateDetail (Maybe Date)
| ZoomTimelineWidget TimelineZoom (Maybe Date)
type Selected
= Selected
| NotSelected
-- The supported object classes
type ObjectClass
= InetNum
| AutNum
| Entity
| Domain
type alias Identifier =
{ objectClass : ObjectClass
, handle : String
}
-- The history of one object
type alias History =
{ identifier : Identifier
, versions : List Version
}
-- One version of one object
type alias Version =
{ from : Date
, until : Maybe Date
, object : Value
}
type NavigationDirection = Fwd | Bkwd
type LockerState = Locked | Unlocked
type TimelineZoom = Lifetime | Year | Month
-- Utility methods
history : Model -> Maybe History
history model = Maybe.andThen (flip (!!) model.selected) <| Maybe.map .history <| Either.toMaybe model.response
versions : Model -> Maybe (List Version)
versions = Maybe.map .versions << history
getNextVersion : Version -> List Version -> Maybe Version
getNextVersion current = List.Extra.last << List.Extra.takeWhile (\v -> is After v.from current.from)
getPreviousVersion : Version -> List Version -> Maybe Version
getPreviousVersion current = List.head << List.Extra.dropWhile (\v -> is SameOrAfter v.from current.from)
getDistance : Version -> Version -> List Version -> Maybe Int
getDistance v1 v2 vs = Maybe.map2 (-) (List.Extra.elemIndex v1 vs) (List.Extra.elemIndex v2 vs)
canNavigate : List Version -> (Maybe Version, Maybe Version) -> NavigationDirection -> (LockerState, LockerState) -> Bool
canNavigate vs (leftVersion, rightVersion) dir (bkwdState, fwdState) =
let displayedVersions = Maybe.Extra.values [leftVersion, rightVersion]
finalVersion = if dir == Fwd then head vs else last vs
displayed = (if dir == Fwd then last else head) displayedVersions
isOnlyDirectionLocked = case dir of
Fwd -> fwdState == Locked && bkwdState == Unlocked
Bkwd -> bkwdState == Locked && fwdState == Unlocked
isNotOnEdge = withDefault False <| map ((flip (>)) 0) <| map abs <| join <|
map3 (getDistance) finalVersion displayed (Just vs)
leftAndRightAreNotAdjacent = withDefault False <| map ((flip (>)) 1) <| map abs <| join <|
map3 (getDistance) leftVersion rightVersion (Just vs)
in if isOnlyDirectionLocked
then leftAndRightAreNotAdjacent || isNotOnEdge
else isNotOnEdge