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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
module Lib.Image exposing (..)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Process
import Task
import File exposing (File)
import Lib.Html exposing (..)
import Lib.Api as Api
import Lib.Util exposing (imageUrl)
import Gen.Api as GApi
import Gen.Image as GI
import Gen.ImageVote as GIV
type State
= Normal
| Invalid
| NotFound
| Loading
| Error GApi.Response
type alias Image =
{ id : Maybe String
, img : Maybe GApi.ApiImageResult
, imgState : State
, saveState : Api.State
, saveTimer : Bool
}
info : Maybe GApi.ApiImageResult -> Image
info img =
{ id = Maybe.map (\i -> i.id) img
, img = img
, imgState = Normal
, saveState = Api.Normal
, saveTimer = False
}
-- Fetch image info from the ID
new : Bool -> String -> (Image, Cmd Msg)
new valid id =
( { id = if id == "" then Nothing else Just id
, img = Nothing
, imgState = if id == "" then Normal else if valid then Loading else Invalid
, saveState = Api.Normal
, saveTimer = False
}
, if valid && id /= "" then GI.send { id = id } Loaded else Cmd.none
)
-- Upload a new image from a form
upload : Api.ImageType -> File -> (Image, Cmd Msg)
upload t f =
( { id = Nothing
, img = Nothing
, imgState = Loading
, saveState = Api.Normal
, saveTimer = False
}
, Api.postImage t f Loaded)
type Msg
= Loaded GApi.Response
| MySex Int Bool
| MyVio Int Bool
| Save
| Saved GApi.Response
update : Msg -> Image -> (Image, Cmd Msg)
update msg model =
let
save m =
if m.saveTimer || Maybe.withDefault True (Maybe.map (\i -> i.token == Nothing || i.my_sexual == Nothing || i.my_violence == Nothing) m.img)
then (m, Cmd.none)
else ({ m | saveTimer = True }, Task.perform (always Save) (Process.sleep 1000))
in
case msg of
Loaded (GApi.ImageResult [i]) -> ({ model | id = Just i.id, img = Just i, imgState = Normal}, Cmd.none)
Loaded (GApi.ImageResult []) -> ({ model | imgState = NotFound}, Cmd.none)
Loaded e -> ({ model | imgState = Error e }, Cmd.none)
MySex v _ -> save { model | img = Maybe.map (\i -> { i | my_sexual = Just v }) model.img }
MyVio v _ -> save { model | img = Maybe.map (\i -> { i | my_violence = Just v }) model.img }
Save ->
case Maybe.map (\i -> (i.token, i.my_sexual, i.my_violence)) model.img of
Just (Just token, Just sex, Just vio) ->
( { model | saveTimer = False, saveState = Api.Loading }
, GIV.send { votes = [{ id = Maybe.withDefault "" model.id, token = token, sexual = sex, violence = vio, overrule = False }] } Saved)
_ -> (model, Cmd.none)
Saved (GApi.Success) -> ({ model | saveState = Api.Normal}, Cmd.none)
Saved e -> ({ model | saveState = Api.Error e }, Cmd.none)
isValid : Image -> Bool
isValid img = img.imgState == Normal
viewImg : Image -> Html m
viewImg image =
case (image.imgState, image.img) of
(Loading, _) -> div [ class "spinner" ] []
(NotFound, _) -> b [ class "standout" ] [ text "Image not found." ]
(Invalid, _) -> b [ class "standout" ] [ text "Invalid image ID." ]
(Error e, _) -> b [ class "standout" ] [ text <| Api.showResponse e ]
(_, Nothing) -> text "No image."
(_, Just i) ->
label [ class "imghover", style "width" (String.fromInt i.width++"px"), style "height" (String.fromInt i.height++"px") ]
[ div [ class "imghover--visible" ]
[ img [ src (imageUrl i.id) ] []
, a [ href <| "/img/"++i.id ] <|
case (i.sexual_avg, i.violence_avg) of
(Just sex, Just vio) ->
-- XXX: These thresholds are subject to change, maybe just show the numbers here?
[ text <| if sex > 1.3 then "Explicit" else if sex > 0.4 then "Suggestive" else "Tame"
, text " / "
, text <| if vio > 1.3 then "Brutal" else if vio > 0.4 then "Violent" else "Safe"
, text <| " (" ++ String.fromInt i.votecount ++ ")"
]
_ -> [ text "Not flagged" ]
]
]
viewVote : Image -> Maybe (Html Msg)
viewVote model =
let
vote i = table []
[ thead [] [ tr []
[ td [] [ text "Sexual ", if model.saveState == Api.Loading then span [ class "spinner" ] [] else text "" ]
, td [] [ text "Violence" ]
] ]
, tfoot [] <|
case model.saveState of
Api.Error e -> [ tr [] [ td [ colspan 2 ] [ b [ class "standout" ] [ text (Api.showResponse e) ] ] ] ]
_ -> []
, tr []
[ td []
[ label [] [ inputRadio "" (i.my_sexual == Just 0) (MySex 0), text " Safe" ], br [] []
, label [] [ inputRadio "" (i.my_sexual == Just 1) (MySex 1), text " Suggestive" ], br [] []
, label [] [ inputRadio "" (i.my_sexual == Just 2) (MySex 2), text " Explicit" ]
]
, td []
[ label [] [ inputRadio "" (i.my_violence == Just 0) (MyVio 0), text " Tame" ], br [] []
, label [] [ inputRadio "" (i.my_violence == Just 1) (MyVio 1), text " Violent" ], br [] []
, label [] [ inputRadio "" (i.my_violence == Just 2) (MyVio 2), text " Brutal" ]
]
]
]
in case model.img of
Nothing -> Nothing
Just i ->
if i.token == Nothing then Nothing
else Just (vote i)
|