Skip to content

Commit 410566b

Browse files
committed
SelectOpts for better clipboard and file selector options for image compression and OPFS
1 parent 4ca33c6 commit 410566b

File tree

8 files changed

+78
-40
lines changed

8 files changed

+78
-40
lines changed

ghcjs/delivery-calculator/src/App/Jsm.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ fetchBlobUris st = do
1313
vars <-
1414
forM blobUris $ \uri -> do
1515
var <- newEmptyMVar
16-
Jsm.fetchUrlAsRfc2397 (Just 400000) uri
16+
Jsm.fetchUrlAsRfc2397 uri
1717
$ liftIO
1818
. putMVar var
1919
. fmap (uri,)

ghcjs/delivery-calculator/src/App/Types.hs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,25 @@ newAsset = do
176176
either throw pure . decodeUtf8Strict . unTagged . htmlUid =<< newUid
177177
photo <-
178178
fmap
179-
( (#fieldPairValue . #fieldOpfsName .~ Just opfs)
180-
. (#fieldPairValue . #fieldType .~ FieldTypeImage)
181-
. (#fieldPairValue . #fieldOpts . #fieldOptsTruncateLimit .~ Nothing)
179+
( ( #fieldPairValue
180+
. #fieldSelectOpts
181+
. #selectOptsOpfsName
182+
.~ Just opfs
183+
)
184+
. ( #fieldPairValue
185+
. #fieldSelectOpts
186+
. #selectOptsMaxSizeKb
187+
.~ Just 400000
188+
)
189+
. ( #fieldPairValue
190+
. #fieldType
191+
.~ FieldTypeImage
192+
)
193+
. ( #fieldPairValue
194+
. #fieldOpts
195+
. #fieldOptsTruncateLimit
196+
.~ Nothing
197+
)
182198
)
183199
. newFieldPair "Photo"
184200
$ DynamicFieldText mempty

ghcjs/delivery-calculator/src/Main.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ opfsRead sink st =
434434
. ix fieldIdx
435435
. #fieldPairValue
436436
when (field ^. #fieldType == FieldTypeImage)
437-
$ whenJust (field ^. #fieldOpfsName)
437+
$ whenJust (field ^. #fieldSelectOpts . #selectOptsOpfsName)
438438
$ \opfsName -> Jsm.opfsRead opfsName . flip whenJust $ \uri ->
439439
liftIO
440440
. sink

ghcjs/miso-functora/js/main.js

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export async function insertStorage(key, value) {
3030
return await Preferences.set({ key: key, value: value });
3131
}
3232

33-
export async function compressImage(maxSizeKb, prevImage) {
33+
export async function compressImage(prevImage, maxSizeKb) {
3434
let opts = { quality: 1 };
3535
if (maxSizeKb) {
3636
opts = {
@@ -50,12 +50,12 @@ export async function compressImage(maxSizeKb, prevImage) {
5050
return nextImage;
5151
}
5252

53-
export async function selectClipboard(opfsName = null) {
53+
export async function selectClipboard(opts = {}) {
5454
const { value } = await Clipboard.read();
55-
return await selectDataUrl(value, opfsName);
55+
return await resolveDataUrl(value, opts);
5656
}
5757

58-
export async function selectFile(file, opfsName = null) {
58+
export async function selectFile(file, opts = {}) {
5959
const value = await new Promise((resolve, reject) => {
6060
var fr = new FileReader();
6161
fr.onload = () => {
@@ -64,18 +64,22 @@ export async function selectFile(file, opfsName = null) {
6464
fr.onerror = reject;
6565
fr.readAsDataURL(file);
6666
});
67-
return await selectDataUrl(value, opfsName);
67+
return await resolveDataUrl(value, opts);
6868
}
6969

70-
export async function selectDataUrl(value, opfsName = null) {
70+
export async function resolveDataUrl(value, opts = {}) {
7171
try {
7272
const { buffer: u8a, typeFull: mime } = dataUriToBuffer(value);
7373
let blob = new Blob([u8a], { type: mime });
7474
if (mime.startsWith("image")) {
75-
blob = await compressImage(null, blob);
75+
let maxSizeKb = null;
76+
if (opts.maxSizeKb) {
77+
maxSizeKb = opts.maxSizeKb;
78+
}
79+
blob = await compressImage(blob, maxSizeKb);
7680
}
77-
if (opfsName) {
78-
await opfsWrite(value, opfsName);
81+
if (opts.opfsName) {
82+
await opfsWrite(value, opts.opfsName);
7983
}
8084
return URL.createObjectURL(blob);
8185
} catch (e) {
@@ -102,7 +106,7 @@ export async function opfsRead(opfsName) {
102106
const handle = await root.getFileHandle(opfsName);
103107
const file = await handle.getFile();
104108
const uri = await file.text();
105-
const res = await selectDataUrl(uri);
109+
const res = await resolveDataUrl(uri);
106110
return res;
107111
} catch (e) {
108112
alert("OPFS read failure: " + e.toString() + " file: " + opfsName);
@@ -200,17 +204,16 @@ export function isNativePlatform() {
200204
return Capacitor.isNativePlatform();
201205
}
202206

203-
export async function fetchUrlAsRfc2397(maxSizeKb, url) {
207+
export async function fetchUrlAsRfc2397(url) {
204208
const imgResp = await fetch(url);
205209
const imgBlob = await imgResp.blob();
206-
const imgComp = await compressImage(maxSizeKb, imgBlob);
207210
const rfc2397 = await new Promise((resolve, reject) => {
208211
var fr = new FileReader();
209212
fr.onload = () => {
210213
resolve(fr.result);
211214
};
212215
fr.onerror = reject;
213-
fr.readAsDataURL(imgComp);
216+
fr.readAsDataURL(imgBlob);
214217
});
215218
const utf8Encode = new TextEncoder();
216219
const ab = utf8Encode.encode(rfc2397).buffer;

ghcjs/miso-functora/js/main.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ghcjs/miso-functora/src/Functora/Miso/Jsm/Generic.hs

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ module Functora.Miso.Jsm.Generic
77
openBrowserPage,
88
enterOrEscapeBlur,
99
insertStorage,
10+
SelectOpts (..),
11+
defSelectOpts,
1012
selectStorage,
1113
selectBarcode,
1214
selectClipboard,
@@ -152,17 +154,17 @@ selectBarcode after =
152154
$ after
153155
. fmap strip
154156

155-
selectClipboard :: Maybe Unicode -> (Maybe Unicode -> JSM ()) -> JSM ()
156-
selectClipboard opfsName after = do
157-
jopfsName <- JS.toJSVal opfsName
158-
genericPromise @[JS.JSVal] @Unicode "selectClipboard" [jopfsName]
157+
selectClipboard :: SelectOpts -> (Maybe Unicode -> JSM ()) -> JSM ()
158+
selectClipboard opts after = do
159+
jopts <- JS.toJSVal $ toJSON opts
160+
genericPromise @[JS.JSVal] @Unicode "selectClipboard" [jopts]
159161
$ after
160162
. fmap strip
161163

162-
selectFile :: Maybe Unicode -> JS.JSVal -> (Maybe Unicode -> JSM ()) -> JSM ()
163-
selectFile opfsName file after = do
164-
jopfsName <- JS.toJSVal opfsName
165-
genericPromise @[JS.JSVal] @Unicode "selectFile" [file, jopfsName]
164+
selectFile :: SelectOpts -> JS.JSVal -> (Maybe Unicode -> JSM ()) -> JSM ()
165+
selectFile opts file after = do
166+
jopts <- JS.toJSVal $ toJSON opts
167+
genericPromise @[JS.JSVal] @Unicode "selectFile" [file, jopts]
166168
$ after
167169
. fmap strip
168170

@@ -251,11 +253,10 @@ saveFileThen onSuccess name mime bs = do
251253
Just str -> onSuccess str
252254

253255
fetchUrlAsRfc2397 ::
254-
Maybe Int ->
255256
Unicode ->
256257
(Maybe ByteString -> JSM ()) ->
257258
JSM ()
258-
fetchUrlAsRfc2397 maxSizeKb url after = do
259+
fetchUrlAsRfc2397 url after = do
259260
success <- JS.function $ \_ _ ->
260261
handleAny
261262
( \e -> do
@@ -280,10 +281,6 @@ fetchUrlAsRfc2397 maxSizeKb url after = do
280281
alert $ "Failure, " <> inspect msg <> "!"
281282
after Nothing
282283
pkg <- getPkg
283-
argv <-
284-
sequence
285-
[ JS.toJSVal maxSizeKb,
286-
JS.toJSVal url
287-
]
284+
argv <- sequence [JS.toJSVal url]
288285
prom <- pkg ^. JS.jsf ("fetchUrlAsRfc2397" :: Unicode) (argv :: [JS.JSVal])
289286
void $ prom ^. JS.js2 @Unicode "then" success failure

ghcjs/miso-functora/src/Functora/Miso/Types.hs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ module Functora.Miso.Types
5858
themeCssFile,
5959
noopAll,
6060
noop,
61+
SelectOpts (..),
62+
defSelectOpts,
6163
module X,
6264
)
6365
where
@@ -128,7 +130,7 @@ data Field a f = Field
128130
{ fieldType :: FieldType,
129131
fieldInput :: f Unicode,
130132
fieldOutput :: a,
131-
fieldOpfsName :: Maybe Unicode,
133+
fieldSelectOpts :: SelectOpts,
132134
fieldModalState :: OpenedOrClosed,
133135
fieldFocusState :: FocusedOrBlurred,
134136
fieldRequired :: Bool,
@@ -184,7 +186,7 @@ newField typ output newInput = do
184186
{ fieldType = typ,
185187
fieldInput = input,
186188
fieldOutput = output,
187-
fieldOpfsName = Nothing,
189+
fieldSelectOpts = defSelectOpts,
188190
fieldModalState = Closed,
189191
fieldFocusState = Blurred,
190192
fieldRequired = False,
@@ -197,7 +199,7 @@ newFieldId typ viewer output =
197199
{ fieldType = typ,
198200
fieldInput = Identity $ viewer output,
199201
fieldOutput = output,
200-
fieldOpfsName = Nothing,
202+
fieldSelectOpts = defSelectOpts,
201203
fieldModalState = Closed,
202204
fieldFocusState = Blurred,
203205
fieldRequired = False,
@@ -617,3 +619,17 @@ noop action event =
617619
. action
618620
. EffectUpdate
619621
$ pure ()
622+
623+
data SelectOpts = SelectOpts
624+
{ selectOptsOpfsName :: Maybe Unicode,
625+
selectOptsMaxSizeKb :: Maybe Int
626+
}
627+
deriving stock (Eq, Ord, Show, Data, Generic)
628+
deriving (Binary, ToJSON, FromJSON) via GenericType SelectOpts
629+
630+
defSelectOpts :: SelectOpts
631+
defSelectOpts =
632+
SelectOpts
633+
{ selectOptsOpfsName = Nothing,
634+
selectOptsMaxSizeKb = Nothing
635+
}

ghcjs/miso-functora/src/Functora/Miso/Widgets/Field.hs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,11 @@ field full@Full {fullArgs = args, fullParser = parser, fullViewer = viewer} opts
343343
else do
344344
file <- el JS.! ("files" :: Unicode) JS.!! 0
345345
Jsm.selectFile
346-
(st ^? cloneTraversal optic . #fieldOpfsName . _Just)
346+
( fromMaybe defSelectOpts
347+
$ st
348+
^? cloneTraversal optic
349+
. #fieldSelectOpts
350+
)
347351
file
348352
$ \case
349353
Nothing -> Jsm.popupText @Unicode "File is not selected!"
@@ -455,8 +459,10 @@ fieldIcon full opts = \case
455459
PasteWidget attrs ->
456460
fieldIconSimple opts Icon.IconPaste attrs
457461
. insertAction full
458-
$ Jsm.selectClipboard
459-
(st ^? cloneTraversal optic . #fieldOpfsName . _Just)
462+
. Jsm.selectClipboard
463+
$ fromMaybe
464+
defSelectOpts
465+
(st ^? cloneTraversal optic . #fieldSelectOpts)
460466
ScanQrWidget ->
461467
fieldIconSimple opts Icon.IconQrCode mempty
462468
$ insertAction full Jsm.selectBarcode

0 commit comments

Comments
 (0)