summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2020-03-16 15:56:20 +0100
committerYorhel <git@yorhel.nl>2020-03-16 15:56:23 +0100
commit0e788f5667cb565326ff11dcd863a9a2fe434f6c (patch)
treefa3d3f6231a0532db5bf4788657bbf2f55054b99
parent1060de04e9e54d7e40c5ad96c0012acc0e67dc5d (diff)
imgflag: Add short mouse-over descriptions to the vote options
These need to be refined, not sure they're all that great at the moment.
-rw-r--r--data/style.css29
-rw-r--r--elm/ImageFlagging.elm74
2 files changed, 80 insertions, 23 deletions
diff --git a/data/style.css b/data/style.css
index 5168515c..7bfd84f5 100644
--- a/data/style.css
+++ b/data/style.css
@@ -1077,17 +1077,26 @@ p.filselect i { font-style: normal }
/****** Image flagging *******/
+/* divs:
+ * 1: header
+ * 2: image
+ * 3: metadata
+ * 4: vote box */
.imageflag { width: 810px; margin: auto }
-.imageflag div:nth-child(1) { display: flex; justify-content: space-between; height: 20px }
-.imageflag div:nth-child(1) span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding: 0px 20px }
-.imageflag div:nth-child(2) { border: 1px solid $border$; padding: 5px; display: flex; justify-content: center; align-items: center; background: #000 }
-.imageflag div:nth-child(2) a { border: none; display: inline-block; width: 100%; height: 100%; background-repeat: no-repeat; background-position: center }
-.imageflag div:nth-child(3) { display: flex; justify-content: space-between; }
-.imageflag ul.imgvoteopt { display: flex; align-items: center; list-style-type: none; margin: 5px 0 }
-.imageflag ul.imgvoteopt span { font-weight: bold; padding-right: 5px }
-.imageflag ul.imgvoteopt li:nth-child(4) { flex-grow: 1 }
-.imageflag ul.imgvoteopt li label { display: inline-block; border: 1px solid $secborder$; padding: 4px 5px; min-width: 90px; white-space: nowrap; margin: 2px }
-.imageflag ul.imgvoteopt li.sel label { background-color: $secbg$ }
+.imageflag > div:nth-child(1) { display: flex; justify-content: space-between; height: 20px }
+.imageflag > div:nth-child(1) span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; padding: 0px 20px }
+.imageflag > div:nth-child(2) { border: 1px solid $border$; padding: 5px; display: flex; justify-content: center; align-items: center; background: #000 }
+.imageflag > div:nth-child(2) a { border: none; display: inline-block; width: 100%; height: 100%; background-repeat: no-repeat; background-position: center }
+.imageflag > div:nth-child(3) { display: flex; justify-content: space-between; }
+.imageflag > div:nth-child(4) { display: flex }
+.imageflag > div:nth-child(4) > div { flex-grow: 1 }
+.imageflag > div:nth-child(4) ul { display: flex; align-items: center; list-style-type: none; margin: 5px 0 }
+.imageflag > div:nth-child(4) > div:nth-child(2) ul { justify-content: right }
+.imageflag > div:nth-child(4) ul span { font-weight: bold; padding-right: 5px }
+.imageflag > div:nth-child(4) ul li label { display: inline-block; border: 1px solid $secborder$; padding: 4px 5px; min-width: 90px; white-space: nowrap; margin: 2px }
+.imageflag > div:nth-child(4) ul li.sel label,
+.imageflag > div:nth-child(4) ul li label:hover { background-color: $secbg$ }
+.imageflag > div:nth-child(4) p { height: 80px; padding-left: 20px }
/****** Icons *******/
diff --git a/elm/ImageFlagging.elm b/elm/ImageFlagging.elm
index b45cbde9..6c9a5816 100644
--- a/elm/ImageFlagging.elm
+++ b/elm/ImageFlagging.elm
@@ -32,6 +32,7 @@ type alias Model =
{ warn : Bool
, images : Array.Array GApi.ApiImageResult
, index : Int
+ , desc : (Maybe Int, Maybe Int)
, changes : Dict.Dict String GIV.SendVotes
, saved : Bool
, saveTimer : Bool
@@ -44,6 +45,7 @@ init _ =
{ warn = True
, images = Array.empty
, index = 0
+ , desc = (Nothing, Nothing)
, changes = Dict.empty
, saved = False
, saveTimer = False
@@ -54,6 +56,7 @@ init _ =
type Msg
= SkipWarn
+ | Desc (Maybe Int) (Maybe Int)
| Load GApi.Response
| Vote (Maybe Int) (Maybe Int) Bool
| Save
@@ -79,9 +82,13 @@ update msg model =
if not m.saveTimer && not (Dict.isEmpty m.changes) && m.saveState /= Api.Loading
then ({ m | saveTimer = True }, Cmd.batch [ c, Task.perform (always Save) (Process.sleep 5000) ])
else (m,c)
+ -- Set desc to current image
+ desc (m,c) =
+ ({ m | desc = Maybe.withDefault (Nothing,Nothing) <| Maybe.map (\i -> (i.my_sexual, i.my_violence)) <| Array.get m.index m.images}, c)
in
case msg of
SkipWarn -> load ({ model | warn = False }, Cmd.none)
+ Desc s v -> ({ model | desc = (s,v) }, Cmd.none)
Load (GApi.ImageResult l) ->
let nm = { model | loadState = Api.Normal, images = Array.append model.images (Array.fromList l) }
@@ -97,7 +104,7 @@ update msg model =
let m = { model | saved = False, images = Array.set model.index { i | my_sexual = s, my_violence = v } model.images }
in case (s,v) of
-- Complete vote, mark it as a change and go to next image
- (Just xs, Just xv) -> save <| load
+ (Just xs, Just xv) -> desc <| save <| load
({ m | index = m.index + (if isLast model then 1 else 0)
, changes = Dict.insert i.id { id = i.id, sexual = xs, violence = xv } m.changes
}, Cmd.none)
@@ -107,8 +114,8 @@ update msg model =
Save -> ({ model | saveTimer = False, saveState = Api.Loading, changes = Dict.empty }, GIV.send { votes = Dict.values model.changes } Saved)
Saved r -> save ({ model | saved = True, saveState = if r == GApi.Success then Api.Normal else Api.Error r }, Cmd.none)
- Prev -> ({ model | saved = False, index = model.index - (if model.index == 0 then 0 else 1) }, Cmd.none)
- Next -> ({ model | saved = False, index = model.index + (if isLast model then 0 else 1) }, Cmd.none)
+ Prev -> desc ({ model | saved = False, index = model.index - (if model.index == 0 then 0 else 1) }, Cmd.none)
+ Next -> desc ({ model | saved = False, index = model.index + (if isLast model then 0 else 1) }, Cmd.none)
view : Model -> Html Msg
@@ -123,6 +130,12 @@ view model =
(Just a, Just s) -> Ffi.fmtFloat a 2 ++ " σ " ++ Ffi.fmtFloat s 2
_ -> "-"
+ but i name s v lbl =
+ let sel = i.my_sexual == s && i.my_violence == v
+ in li [ classList [("sel", sel)] ]
+ [ label [ onMouseOver (Desc s v), onMouseOut (Desc i.my_sexual i.my_violence) ] [ inputRadio name sel (Vote s v), text lbl ]
+ ]
+
imgView i =
let entry = i.entry_type ++ String.fromInt i.entry_id
in
@@ -160,16 +173,51 @@ view model =
, a [ href i.url ] [ text <| String.fromInt i.width ++ "x" ++ String.fromInt i.height ]
]
]
- -- TODO: Mouse-over quick explanations
- , ul [ class "imgvoteopt" ]
- [ li [] [ span [] [ text "Sexual" ] ]
- , li [ classList [("sel", i.my_sexual == Just 0)] ] [ label [] [ inputRadio "sexual" (i.my_sexual == Just 0) (Vote (Just 0) i.my_violence), text " Safe" ] ]
- , li [ classList [("sel", i.my_sexual == Just 1)] ] [ label [] [ inputRadio "sexual" (i.my_sexual == Just 1) (Vote (Just 1) i.my_violence), text " Suggestive" ] ]
- , li [ classList [("sel", i.my_sexual == Just 2)] ] [ label [] [ inputRadio "sexual" (i.my_sexual == Just 2) (Vote (Just 2) i.my_violence), text " Explicit" ] ]
- , li [] [ span [] [ text "Violence" ] ]
- , li [ classList [("sel", i.my_violence == Just 0)] ] [ label [] [ inputRadio "violence" (i.my_violence == Just 0) (Vote i.my_sexual (Just 0)), text " Tame" ] ]
- , li [ classList [("sel", i.my_violence == Just 1)] ] [ label [] [ inputRadio "violence" (i.my_violence == Just 1) (Vote i.my_sexual (Just 1)), text " Violent" ] ]
- , li [ classList [("sel", i.my_violence == Just 2)] ] [ label [] [ inputRadio "violence" (i.my_violence == Just 2) (Vote i.my_sexual (Just 2)), text " Brutal" ] ]
+ , div []
+ [ div []
+ [ ul []
+ [ li [] [ span [] [ text "Sexual" ] ]
+ , but i "sexual" (Just 0) i.my_violence " Safe"
+ , but i "sexual" (Just 1) i.my_violence " Suggestive"
+ , but i "sexual" (Just 2) i.my_violence " Explicit"
+ ]
+ , p [] <|
+ case Tuple.first model.desc of
+ Just 0 -> [ text "- No nudity", br [] []
+ , text "- No (implied) sexual actions", br [] []
+ , text "- No suggestive clothing or visible underwear", br [] []
+ , text "- No sex toys" ]
+ Just 1 -> [ text "- Visible underwear or skimpy clothing", br [] []
+ , text "- Erotic posing", br [] []
+ , text "- Sex toys (but not visibly being used)", br [] []
+ , text "- No visible genitals or female nipples" ]
+ Just 2 -> [ text "- Visible genitals or female nipples", br [] []
+ , text "- Penetrative sex (regardless of clothing)", br [] []
+ , text "- Visible use of sex toys" ]
+ _ -> []
+ ]
+ , div []
+ [ ul []
+ [ li [] [ span [] [ text "Violence" ] ]
+ , but i "violence" i.my_sexual (Just 0) " Tame"
+ , but i "violence" i.my_sexual (Just 1) " Violent"
+ , but i "violence" i.my_sexual (Just 2) " Brutal"
+ ]
+ , p [] <|
+ case Tuple.second model.desc of
+ Just 0 -> [ text "- No visible violence", br [] []
+ , text "- Tame slapstick comedy", br [] []
+ , text "- Weapons, but not used to harm anyone", br [] []
+ , text "- Only very minor visible blood or bruises", br [] [] ]
+ Just 1 -> [ text "- Visible blood", br [] []
+ , text "- Non-comedic fight scenes", br [] []
+ , text "- Physically harmful activities" ]
+ Just 2 -> [ text "- Excessive amounts of blood", br [] []
+ , text "- Cut off limbs", br [] []
+ , text "- Sliced-open bodies", br [] []
+ , text "- Harmful activities leading to death" ]
+ _ -> []
+ ]
]
-- TODO: list of users who voted on this image
]