svg.escobar.life

A simple SVG markup editor for the web

View.elm (3753B)

  1 module View exposing (view)
  2 
  3 import Types exposing (..)
  4 import Editor exposing (editor)
  5 
  6 import Html exposing ( Html
  7                      , Attribute
  8                      , div
  9                      , img
 10                      , button
 11                      , a
 12                      , span
 13                      , text
 14                      , h1
 15                      , header
 16                      )
 17 import Html.Events exposing (onClick, on)
 18 import Html.Attributes exposing ( id
 19                                 , class
 20                                 , src
 21                                 , href
 22                                 , target
 23                                 , rel
 24                                 , alt
 25                                 , attribute
 26                                 , name
 27                                 )
 28 import Html.Lazy exposing (lazy)
 29 import Accessibility.Landmark exposing (application, region)
 30 import Accessibility.Role exposing (alert)
 31 import Accessibility.Key exposing (onKeyDown, enter)
 32 import Accessibility.Widget exposing (label)
 33 import Browser exposing (Document)
 34 import Json.Decode
 35 import Regex exposing (Regex, Match, replace)
 36 
 37 
 38 view : Model -> Document Msg
 39 view model =
 40   { title = "SVG Editor"
 41   , body =
 42       case model.load of
 43         Loading -> 
 44           []
 45 
 46         Loaded -> 
 47           [ lazy container model ]
 48   }
 49 
 50 container : Model -> Html Msg
 51 container model =
 52   div 
 53     (
 54       [ id "container", application, label "SVG Editor" ]
 55       ++ 
 56       (if valid model.status then [] else [class "error"])
 57       ++
 58       (if model.darkModeOn then [ class "dark" ] else [])
 59     )
 60     [ display model
 61     , lazy editor model
 62     ]
 63 
 64 display : Model -> Html Msg
 65 display model =
 66   div 
 67     (
 68       [ id "display"
 69       , region
 70       , class (if model.darkModeOn then "dark" else "light") 
 71       , label "Picture preview"
 72       ] 
 73       ++ 
 74       -- Alert users when the image is invalid
 75       (if valid model.status then [] else [ alert ])
 76     )
 77     [ img 
 78       [ id "image", src (uri model), loaded model, alt "Input picture" ] 
 79       []
 80     , errorIcon
 81     , button 
 82         [ onClick Download
 83         , label "Download file"
 84         ] 
 85         [ span [] [ text "Download" ] ]
 86     , button 
 87         [ onClick (Upload Requested)
 88         , label "Upload file"
 89         ] 
 90         [ span [] [ text "Upload" ] ]
 91     , button 
 92         [ onClick ToggleDarkMode
 93         , label "Toggle dark mode"
 94         ] 
 95         [ span [] [ text (if model.darkModeOn then "Lighter" else "Darker") ] ]
 96     ]
 97 
 98 uri : Model -> String
 99 uri model =
100   "data:image/svg+xml;utf8," 
101   ++ 
102   (replace model.uriEncoder percentEscape model.image)
103 
104 percentEscape : Match -> String
105 percentEscape m =
106   case m.match of
107     "!" -> "%21"
108     "#" -> "%23"
109     "$" -> "%24"
110     "%" -> "%25"
111     "&" -> "%26"
112     "'" -> "%27"
113     "(" -> "%28"
114     ")" -> "%29"
115     "*" -> "%2A"
116     "+" -> "%2B"
117     "," -> "%2C"
118     "/" -> "%2F"
119     ":" -> "%3A"
120     ";" -> "%3B"
121     "=" -> "%3D"
122     "?" -> "%3F"
123     "@" -> "%40"
124     "[" -> "%5B"
125     "]" -> "%5D"
126     str -> str
127 
128 onError : msg -> Attribute msg
129 onError f = 
130   on "error" (Json.Decode.succeed f)
131 
132 onLoad : msg -> Attribute msg
133 onLoad f = 
134   on "load" (Json.Decode.succeed f)
135 
136 loaded : Model -> Attribute Msg
137 loaded model =
138   if valid model.status 
139     then onError (Validation Invalid) 
140     else onLoad (Validation Valid)
141 
142 valid : Status -> Bool
143 valid status =
144   case status of
145     Valid -> 
146       True
147 
148     Invalid -> 
149       False
150 
151 errorIcon : Html Msg
152 errorIcon = 
153   img 
154     [ id "error", src "assets/error.svg", alt "Something Went Wrong" ] 
155     []
156