module Lib.ExtLinks exposing (..)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Regex
import Lib.Html exposing (..)
import Gen.ReleaseEdit as GRE
import Gen.ExtLinks as GEL
-- Takes a printf-style string with a single %s or %d formatting code and a parameter to format.
-- Supports 0-padding with '%0d' formatting codes, where <= 99.
-- Returns (prefix, formatted_param, suffix)
-- (This is super ugly and probably better written with elm/parser, but it gets the job done)
splitPrintf : String -> String -> (String, String, String)
splitPrintf s p =
case String.split "%" s of
[ pre, suf ] ->
case String.uncons suf of
Just ('s', suf1) -> (pre, p, suf1)
Just ('d', suf1) -> (pre, p, suf1)
Just ('0', suf1) ->
case String.uncons suf1 of
Just (c2, suf2) ->
case String.uncons suf2 of
Just ('d', suf3) -> (pre, String.padLeft (Char.toCode c2 - 48) '0' p, suf3)
Just (c3, suf3) ->
case String.uncons suf3 of
Just ('d', suf4) -> (pre, String.padLeft (10*(Char.toCode c2 - 48) + Char.toCode c3 - 48) '0' p, suf4)
_ -> (pre, "%", suf)
_ -> (pre, "%", suf)
_ -> (pre, "%", suf)
_ -> (pre, "%", suf)
_ -> (s, "", "")
type Rec a
= Unrecognized
| Duplicate
| Add (GEL.Site a, String) -- Site, value
type alias Model a =
{ links : a
, sites : List (GEL.Site a)
, input : String
, rec : Rec a
, lst : Bool
}
type Msg a
= Del (Int -> a -> a) Int
| Input String
| Enter
| Expand
new : a -> List (GEL.Site a) -> Model a
new l s =
{ links = l
, sites = s
, input = ""
, rec = Unrecognized
, lst = False
}
update : Msg a -> Model a -> Model a
update msg model =
let
match s m = (s, List.map (Maybe.withDefault "") m.submatches |> List.filter (\a -> a /= "") |> List.head |> Maybe.withDefault "")
fmtval s v = let (_, val, _) = splitPrintf s.fmt v in val
dup s val = List.filter (\l -> fmtval s l == fmtval s val) (s.links model.links) |> List.isEmpty |> not
find i =
case List.concatMap (\s -> List.map (match s) (Regex.find s.regex i)) model.sites |> List.head of
Nothing -> Unrecognized
Just (s, val) -> if dup s val then Duplicate else Add (s, val)
add s val = { model | input = "", rec = Unrecognized, links = s.add val model.links }
in case msg of
Del f i -> { model | links = f i model.links }
Input i ->
case find (String.trim i) of
Add (s, val) ->
if s.multi || List.isEmpty (s.links model.links)
then add s val
else { model | input = i, rec = Add (s, val) }
x -> { model | input = i, rec = x }
Enter ->
case model.rec of
Add (s, val) -> add s val
_ -> model
Expand -> { model | lst = not model.lst }
view : Model a -> Html (Msg a)
view model =
let msg st s = span [] [ br [] [], b [ class "grayedout" ] [ text ">>> " ], if st then b [ class "standout" ] [ text s ] else text s ]
in
Html.form [ onSubmit Enter ]
[ table [] <| List.concatMap (\s ->
List.indexedMap (\i l ->
let (pre, val, suf) = splitPrintf s.fmt l
in tr []
[ td [] [ a [ href <| pre ++ val ++ suf, target "_blank" ] [ text s.name ] ]
, td [] [ b [ class "grayedout" ] [ text pre ], text val, b [ class "grayedout" ] [ text suf ] ]
, td [] [ inputButton "remove" (Del s.del i) [] ]
]
) (s.links model.links)
) model.sites
, inputText "" model.input Input [style "width" "500px", placeholder "Add URL..."]
, case (model.input, model.rec) of
("", _) -> text ""
(_, Unrecognized) -> msg True "Invalid or unrecognized URL."
(_, Duplicate) -> msg True "URL is already listed."
(_, Add (s, _)) -> span [] [ inputButton "Edit" Enter [], msg False <| "URL recognized as: " ++ s.name ]
, div [ style "margin-top" "5px" ]
[ span [ onClickD Expand, style "cursor" "pointer" ] [ text <| if model.lst then "▾ " else "▸ ", text "Recognized sites: " ]
, if model.lst
then table [] <| List.map (\s ->
tr []
[ td [] [ text s.name ]
, td [] <| List.indexedMap (\i l -> if modBy 2 i == 0 then b [ class "grayedout" ] [ text l ] else text l) s.patt
]
) model.sites
else text <| String.join ", " (List.map (\s -> s.name) model.sites) ++ "."
]
]