-
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
-
163
-
164
-
165
-
166
-
167
-
168
-
169
-
170
-
171
-
172
-
173
-
174
-
175
-
176
-
177
-
178
-
179
-
180
-
181
-
182
-
183
-
184
-
185
-
186
-
187
-
188
-
189
-
190
-
191
-
192
-
193
-
194
-
195
-
196
-
197
-
198
-
199
-
200
-
201
-
202
-
203
-
204
-
205
-
206
-
207
-
208
-
209
-
210
-
211
-
212
-
213
-
214
-
215
-
216
-
217
-
218
-
219
-
220
-
221
-
222
-
223
-
224
-
225
-
226
-
227
-
228
-
229
-
230
-
231
-
232
-
233
-
234
-
235
-
236
-
237
-
238
-
239
-
240
-
241
-
242
-
243
-
244
-
245
-
246
-
247
-
248
-
249
-
250
-
251
-
252
-
253
-
254
-
255
-
256
-
257
-
258
-
259
-- Copyright 2026 Shota FUJI
--
-- This Source Code Form is subject to the terms of the Mozilla Public
-- License, v. 2.0. If a copy of the MPL was not distributed with this
-- file, You can obtain one at https://mozilla.org/MPL/2.0/.
--
-- SPDX-License-Identifier: MPL-2.0
module Main exposing (main)
import Browser
import Browser.Navigation exposing (Key)
import Html exposing (a, hr, node, p, span, text)
import Html.Attributes exposing (attribute, href)
import Html.LivingStandard exposing (..)
import Json.Decode
import Parameters
import Parameters.App
import Parameters.Parser
import Preferences exposing (FieldHighlight(..))
import Preferences.App
import Template exposing (template)
import Url exposing (Url)
import Url.SearchParams
main : Program Flags Model Msg
main =
Browser.application
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
, onUrlRequest = UrlRequested
, onUrlChange = UrlChanged
}
-- FLAGS
type alias Flags =
{ preferences : Json.Decode.Value
}
-- MODEL
type alias Model =
{ url : Url
, key : Key
, parameters : Parameters.App.Model
, preferences : Preferences.App.Model
}
init : Flags -> Url -> Key -> ( Model, Cmd Msg )
init flags url key =
let
parameters =
case Maybe.map Url.SearchParams.parse url.query of
Just dict ->
-- TODO: Handle and present errors to a user
Parameters.Parser.parse dict
|> Result.withDefault Parameters.default
Nothing ->
Parameters.default
( parametersModel, parametersCmd ) =
Parameters.App.init url key parameters
in
( { url = url
, key = key
, parameters = parametersModel
, preferences = Preferences.App.init flags.preferences
}
, Cmd.map ParametersMsg parametersCmd
)
-- UPDATE
type Msg
= NoOp
| ParametersMsg Parameters.App.Msg
| PreferencesMsg Preferences.App.Msg
| UrlRequested Browser.UrlRequest
| UrlChanged Url
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
NoOp ->
( model, Cmd.none )
ParametersMsg subMsg ->
Parameters.App.update subMsg model.parameters
|> Tuple.mapFirst (\p -> { model | parameters = p })
|> Tuple.mapSecond (Cmd.map ParametersMsg)
PreferencesMsg subMsg ->
Preferences.App.update subMsg model.preferences
|> Tuple.mapFirst (\p -> { model | preferences = p })
|> Tuple.mapSecond (Cmd.map PreferencesMsg)
UrlRequested (Browser.Internal url) ->
if String.endsWith ".txt" url.path then
( model, Browser.Navigation.load (Url.toString url) )
else
( model, Browser.Navigation.replaceUrl model.key (Url.toString url) )
UrlRequested (Browser.External href) ->
( model, Browser.Navigation.load href )
UrlChanged url ->
( { model | url = url }, Cmd.none )
-- VIEW
view : Model -> Browser.Document Msg
view model =
let
highlighting =
case model.preferences.preferences.fieldHighlight of
HighlightOnPreview ->
model.parameters.highlighting
DoNotHighlight ->
Nothing
in
{ title = ""
, body =
[ node "x-app-layout"
[]
[ node "x-preview"
[ slot "preview"
, attribute "print-theme"
(case model.parameters.parameters.rendering.colorSchema of
Parameters.BlackOnWhite ->
"black-on-white"
Parameters.WhiteOnBlack ->
"white-on-black"
)
, attribute "preview-theme"
(case model.preferences.preferences.previewTheme of
Preferences.SystemTheme ->
"system"
Preferences.PrintTheme ->
"print"
)
]
[ template
model.url
model.parameters.parameters
highlighting
[]
]
, node "x-panel"
[ slot "parameters" ]
[ node "x-parameters"
[]
(node "x-field-group"
[]
[ span [ slot "title" ] [ text "About" ]
, node "x-field"
[]
[ span [ slot "title" ] [ text "This Software" ]
, p [ slot "description" ]
[ text "This application lets you build a leather craft template for basic watch straps."
]
]
, node "x-field"
[]
[ span [ slot "title" ] [ text "The Template" ]
, p [ slot "description" ]
[ text "The template this application outputs is for two-parts leather wrist warch strap. "
, text "It assumes you use a lining leather and a clasp / buckle. "
]
, p [ slot "description" ]
[ text "The output is provided as-is. How to use the template is completely on your own."
]
]
, node "x-field"
[]
[ span [ slot "title" ] [ text "Author" ]
, p [ slot "description" ]
[ text "© Shota FUJI, licensed under the "
, a [ href "/licenses/MPL-2.0.txt" ] [ text "Mozilla Public License version 2.0" ]
, text "."
]
]
]
:: hr [] []
:: (Parameters.App.view model.parameters |> List.map (Html.map ParametersMsg))
++ hr [] []
:: (Preferences.App.panelItems model.preferences |> List.map (Html.map PreferencesMsg))
++ [ hr [] []
, node "x-field-group"
[]
[ span [ slot "title" ] [ text "Legal" ]
, node "x-field"
[]
[ span [ slot "title" ] [ text "Third-party Fonts" ]
, p [ slot "description" ] [ text "This application uses these fonts:" ]
, Html.ul
[ slot "description" ]
[ Html.li []
[ a [ href "https://github.com/jpt/barlow" ] [ text "Barlow" ]
, text " (Copyright 2017 The Barlow Project Authors (https://github.com/jpt/barlow), licensed under "
, a [ href "/licenses/OFL-1.1-no-RFN.txt" ] [ text "SIL Open Font License, Version 1.1" ]
, text ")"
]
, Html.li []
[ a [ href "https://rsms.me/inter/" ] [ text "Inter UI" ]
, text " (Copyright (c) 2016 The Inter Project Authors (https://github.com/rsms/inter), licensed under "
, a [ href "/licenses/OFL-1.1-no-RFN.txt" ] [ text "SIL Open Font License, Version 1.1" ]
, text ")"
]
]
]
, node "x-field"
[]
[ span [ slot "title" ] [ text "Third-party Softwares" ]
, p [ slot "description" ]
[ text "See "
, a [ href "/licenses/third-party.txt" ] [ text "third-party.txt" ]
, text " for list of third-party softwares and its license text."
]
]
]
]
)
]
]
]
}
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions _ =
Sub.none