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
|
-- Utility module and UI widget for handling release dates.
--
-- Release dates are integers with the following format: 0 or yyyymmdd
-- Special values
-- 0 -> unknown
-- 99999999 -> TBA
-- yyyy9999 -> year known, month & day unknown
-- yyyymm99 -> year & month known, day unknown
--
-- I'm not a big fan of the UI widget. It's functional, but could be much more
-- convenient and intuitive.
module Lib.RDate exposing (..)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Date
import Lib.Html exposing (..)
import Lib.Ffi exposing (curYear)
type alias RDate = Int
type alias RDateComp =
{ y : Int
, m : Int
, d : Int
}
expand : RDate -> RDateComp
expand r =
{ y = r // 10000
, m = modBy 100 (r // 100)
, d = modBy 100 r
}
compact : RDateComp -> RDate
compact r = r.y * 10000 + r.m * 100 + r.d
normalize : RDateComp -> RDateComp
normalize r =
if r.y == 0 then { y = 0, m = 0, d = 0 }
else if r.y == 9999 then { y = 9999, m = 99, d = 99 }
else if r.m == 99 then { y = r.y, m = 99, d = 99 }
else r
type Msg
= Year String
| Month String
| Day String
update : Msg -> RDate -> RDate
update msg ro =
let r = expand ro
in compact <| normalize <| case msg of
Year s -> { r | y = Maybe.withDefault r.y <| String.toInt s }
Month s -> { r | m = Maybe.withDefault r.m <| String.toInt s }
Day s -> { r | d = Maybe.withDefault r.d <| String.toInt s }
view : RDate -> Bool -> Html Msg
view ro permitUnknown =
let r = expand ro
range s = List.range s >> List.map (\n -> (String.fromInt n, String.fromInt n))
yl = (if permitUnknown then [("0", "Unknown")] else [])
++ List.reverse (range 1980 (curYear + 5))
++ [("9999", "TBA")]
ml = ("99", "- month -") :: (range 1 12)
maxDay = Date.fromCalendarDate r.y (Date.numberToMonth r.m) 1 |> Date.add Date.Months 1 |> Date.add Date.Days -1 |> Date.day
dl = ("99", "- day -") :: (range 1 maxDay)
in div []
[ inputSelect [class "form-control--inline", onInput Year] (String.fromInt r.y) yl
, if r.y == 0 || r.y == 9999
then text ""
else inputSelect [class "form-control--inline", onInput Month] (String.fromInt r.m) ml
, if r.m == 0 || r.m == 99
then text ""
else inputSelect [class "form-control--inline", onInput Day] (String.fromInt r.d) dl
]
|