@@ -8,6 +8,7 @@ module App.Types
8
8
newSt ,
9
9
Asset (.. ),
10
10
newAsset ,
11
+ verifyAsset ,
11
12
newFieldPair ,
12
13
newFieldPairId ,
13
14
newTotal ,
@@ -56,7 +57,9 @@ import qualified Functora.Prelude as Prelude
56
57
import qualified Functora.Rates as Rates
57
58
import qualified Functora.Web as Web
58
59
import Lens.Micro ((^..) )
60
+ import qualified Network.URI as NetUri
59
61
import qualified Paths_delivery_calculator as Paths
62
+ import qualified Text.Regex as Re
60
63
import qualified Text.URI as URI
61
64
62
65
data Model = Model
@@ -143,7 +146,8 @@ newSt = do
143
146
144
147
data Asset f = Asset
145
148
{ assetFieldPairs :: [FieldPair DynamicField f ],
146
- assetModalState :: OpenedOrClosed
149
+ assetModalState :: OpenedOrClosed ,
150
+ assetMustVerify :: Bool
147
151
}
148
152
deriving stock (Generic )
149
153
@@ -188,12 +192,70 @@ newAsset = do
188
192
required qty,
189
193
comment
190
194
],
191
- assetModalState = Opened
195
+ assetModalState = Opened ,
196
+ assetMustVerify = False
192
197
}
193
198
where
194
199
required :: FieldPair DynamicField Unique -> FieldPair DynamicField Unique
195
200
required = # fieldPairValue . # fieldRequired .~ True
196
201
202
+ verifyAsset :: Asset Unique -> [View Action ]
203
+ verifyAsset asset =
204
+ case assetFieldPairs asset of
205
+ (link : photo : price : qty : _)
206
+ | assetMustVerify asset -> do
207
+ let failures =
208
+ intersperse (text " " )
209
+ $ verifyLink
210
+ (link ^. # fieldPairValue . # fieldInput . # uniqueValue)
211
+ <> verifyPhoto
212
+ (photo ^. # fieldPairValue . # fieldInput . # uniqueValue)
213
+ <> verifyPrice
214
+ (price ^. # fieldPairValue . # fieldOutput)
215
+ <> verifyQty
216
+ (qty ^. # fieldPairValue . # fieldOutput)
217
+ if null failures
218
+ then mempty
219
+ else [blockquote_ mempty failures]
220
+ _ ->
221
+ mempty
222
+
223
+ verifyLink :: Unicode -> [View Action ]
224
+ verifyLink " " = [text " Link is missing!" ]
225
+ verifyLink txt =
226
+ case Re. matchRegex uriRe . from @ Unicode @ String $ uriOnlyChars txt of
227
+ Just [uri, _] ->
228
+ if isJust $ Re. matchRegex marketRe uri
229
+ then mempty
230
+ else [text " Link has unsupported marketplace!" ]
231
+ _ -> [text " Link should have exactly one URL!" ]
232
+
233
+ verifyPhoto :: Unicode -> [View Action ]
234
+ verifyPhoto " " = [text " Photo is missing!" ]
235
+ verifyPhoto txt =
236
+ case Re. matchRegex uriRe str of
237
+ Just [_, _] -> mempty
238
+ _ -> [text " Photo is incorrect!" ]
239
+ where
240
+ str = from @ Unicode @ String $ uriOnlyChars txt
241
+
242
+ verifyPrice :: DynamicField -> [View Action ]
243
+ verifyPrice = \ case
244
+ DynamicFieldNumber x | x > 0 -> mempty
245
+ _ -> [text " Price must be a positive number!" ]
246
+
247
+ verifyQty :: DynamicField -> [View Action ]
248
+ verifyQty = \ case
249
+ DynamicFieldNumber x | x > 0 -> mempty
250
+ _ -> [text " Quantity must be a positive number!" ]
251
+
252
+ uriOnlyChars :: Unicode -> Unicode
253
+ uriOnlyChars =
254
+ omap $ \ x ->
255
+ if NetUri. isAllowedInURI x
256
+ then x
257
+ else ' '
258
+
197
259
newFieldPair ::
198
260
( MonadIO m
199
261
) =>
@@ -511,3 +573,11 @@ apkLink =
511
573
<> " /delivery-calculator-v"
512
574
<> vsn
513
575
<> " .apk"
576
+
577
+ uriRe :: Re. Regex
578
+ uriRe =
579
+ Re. mkRegex " ((https?|ftp)://[^\\ s/$.?#].[^\\ s]*)"
580
+
581
+ marketRe :: Re. Regex
582
+ marketRe =
583
+ Re. mkRegex " (tb\\ .cn|1688\\ .com|dewu\\ .com|taobao\\ .com|tmall\\ .com)"
0 commit comments