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