Skip to content

Commit cb370a7

Browse files
committed
saving and sharing xlsx files with embedded images wip
1 parent 8ef5848 commit cb370a7

File tree

10 files changed

+113
-34
lines changed

10 files changed

+113
-34
lines changed

ghcjs/delivery-calculator/package-lock.json

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ghcjs/delivery-calculator/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"@capacitor/browser": "^6.0.1",
1313
"@capacitor/clipboard": "^6.0.1",
1414
"@capacitor/core": "^6.0.0",
15+
"@capacitor/filesystem": "^6.0.1",
1516
"@capacitor/preferences": "^6.0.1",
1617
"@capacitor/share": "^6.0.1",
1718
"@capacitor/toast": "^6.0.2",

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ module App.Xlsx
44
where
55

66
import Codec.Xlsx
7+
import qualified Data.ByteString.Base64.Lazy as B64
78
import qualified Data.ByteString.Lazy as BL
89
import Functora.Miso.Prelude
910
import Lens.Micro
@@ -18,3 +19,32 @@ newXlsx =
1819
def
1920
& cellValueAt (1, 2) ?~ CellDouble 42.0
2021
& cellValueAt (3, 2) ?~ CellText "foo"
22+
& #wsDrawing ?~ drawing
23+
24+
drawing :: Drawing
25+
drawing = Drawing [anchor1]
26+
where
27+
obj =
28+
picture
29+
(DrawingElementId 0)
30+
FileInfo
31+
{ fiFilename = "img.jpg",
32+
fiContentType = "image/jpg",
33+
fiContents = img
34+
}
35+
anchor1 =
36+
Anchor
37+
{ anchAnchoring =
38+
TwoCellAnchor
39+
{ tcaFrom = unqMarker (1, 0) (1, 0),
40+
tcaTo = unqMarker (5, 0) (13, 0),
41+
tcaEditAs = EditAsTwoCell
42+
},
43+
anchObject = obj,
44+
anchClientData = def
45+
}
46+
47+
img :: BL.ByteString
48+
img =
49+
B64.decodeLenient
50+
"/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAP//////////////////////////////////////////////////////////////////////////////////////2wBDAf//////////////////////////////////////////////////////////////////////////////////////wAARCADqATkDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAECA//EACQQAQEBAAIBBAMBAQEBAAAAAAABESExQQISUXFhgZGxocHw/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAH/xAAWEQEBAQAAAAAAAAAAAAAAAAAAEQH/2gAMAwEAAhEDEQA/AMriLyCKgg1gQwCgs4FTMOdutepjQak+FzMSVqgxZdRdPPIIvH5WzzGdBriphtTeAXg2ZjKA1pqKDUGZca3foBek8gFv8Ie3fKdA1qb8s7hoL6eLVt51FsAnql3Ut1M7AWbflLMDkEMX/F6/YjK/pADFQAUNA6alYagKk72m/j9p4Bq2fDDSYKLNXPNLoHE/NT6RYC31cJxZ3yWVM+aBYi/S2ZgiAsnYJx5D21vPmqrm3PTfpQQwyAC8JZvSKDni41ZrMuUVVl+Uz9w9v/1QWrZsZ5nFPHYH+JZyureQSF5M+fJ0CAfwRAVRBQA1DAWVUayoJUWoDpsxntPsueBV4+VxhdyAtv8AjOLGpIDMLbeGvbF4iozJfr/WukAVABAXAQXEAAASzVAZdO2WNordm+emFl7XcQSNZiFtv0C9w90nhJf4mA1u+GcJFwIyAqL/AOovwgGNfSRqdIrNa29M0gKCAojU9PAMjWXpckEJFNFEAAXEUBABYz6rZ0ureQc9vyt9XxDF2QAXtABcQAs0AZywkvluJbyipifas52DcyxjlZweAO0xri/hc+wZOEKIu6nSyeToVZyWXwvCg53gW81QQ7aTNAn5dGZJPs1UXURQAUEMCXQLZE93PRZ5hPTgNMrbIzKCm52LZwCs+2M8w2g3sjPuZAXb4IsMAUACzVUGM4/K+md6vEXUUyM5PDR0IxYe6ramih0VNBrS4xoqN8Q1BFQk3yqyAsioioAAKgDSJL4/jQIn5igLrPqtOuf6oOaxbMoAltUAhhIoJiiggrPu+AaOIxtAX3JbaAIaLwi4t9X4T3fg2AFtqcrUUarP20zUDAmqoE0WRBZPNVUVEAAAAVAC8kvih2DSKxOdBqs7Z0l0gI0mKAC4AuHE7ZtBriM+744QAAAAABAFsveIttBICyaikvy1+r/Cen5rWQHIBQa4rIDRqSl5qDWqziqgAAAATA7BpGdqXb2C2+J/UgAtRQBSQtkBWb6vhLbQAAAAAEBRAAAAAUbm+GZNdPxAP+ql2Tjwx7/wIgZ8iKvBk+CJoCXii9gaqZ/qqihAAAEVABGkBFUwBftNkZ3QW34QAAABFAQAVAAAAAARVkl8gs/43sk1jL45LvHArepk+E9XTG35oLqsmIKmLAEygKg0y1AFQBUXwgAAAoBC34S3UAAABAVAAAAAABAUQAVABdRQa1PcYyit2z58M8C4ouM2NXpOEGeWtNZUatiAIoAKIoCoAoG4C9MW6dgIoAIAAAAAAACKWAgL0CAAAALiANCKioNLgM1CrLihmTafkt1EF3SZ5ZVUW4mnIKvAi5fhEURVDWVQBRAAAAAAAAQFRVyAyulgAqCKlF8IqLsEgC9mGoC+IusqCrv5ZEUVOk1RuJfwSLOOkGFi4XPCoYYrNiKauosBGi9ICstM1UAAAAAAFQ0VcTBAXUGgIqGoKhKAzRRUQUAwxoSrGRpkQA/qiosOL9oJptMRRVZa0VUqSiChE6BqMgCwqKqIogAIAqKCKgKoogg0lBFuIKgAAAKNRlf2gqsftsEtZWoAAqAACKoMqAAeSoqp39kL2AqLOlE8rEBFQARYALhigrNC9gGmooLp4TweEQFFBFAECgIoAu0ifIAqAAA//9k="

ghcjs/delivery-calculator/trapeze.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ platforms:
99
target: manifest/application/activity
1010
attrs:
1111
android:label: "@string/app_name"
12+
- file: AndroidManifest.xml
13+
target: manifest
14+
merge: |
15+
<manifest>
16+
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
17+
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
18+
</manifest>
1219
gradle:
1320
- file: variables.gradle
1421
target:

ghcjs/miso-widgets/js/main.js

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { defineCustomElements } from "@ionic/pwa-elements/loader";
2+
import { Filesystem, Directory } from "@capacitor/filesystem";
23
import { WebviewPrint } from "capacitor-webview-print";
34
import { Preferences } from "@capacitor/preferences";
45
import { Clipboard } from "@capacitor/clipboard";
@@ -65,16 +66,34 @@ export async function selectBarcode() {
6566
return ScanResult;
6667
}
6768

68-
export async function saveFile(name, mime, bytes) {
69-
return saveAs(new Blob([Uint8Array.from(bytes)], { type: mime }), name);
69+
export async function saveFile(name, mime, bs) {
70+
const u8a = Uint8Array.from(bs);
71+
if (Capacitor.isNativePlatform()) {
72+
const b64 = btoa(String.fromCharCode.apply(null, u8a));
73+
const { uri } = await Filesystem.writeFile({
74+
path: name,
75+
data: b64,
76+
directory: Directory.Documents,
77+
});
78+
return uri;
79+
} else {
80+
const blob = new Blob([u8a, { type: mime }]);
81+
await saveAs(blob, name);
82+
return null;
83+
}
7084
}
7185

72-
export function newUint8Array(buf, off, len) {
73-
return new Uint8Array(buf, off, len);
86+
export async function shareFiles(files) {
87+
if (Capacitor.isNativePlatform()) {
88+
const { value } = await Share.share({ files: files });
89+
return value;
90+
} else {
91+
return null;
92+
}
7493
}
7594

76-
export function emptyUint8Array() {
77-
return new Uint8Array(0);
95+
export function isNativePlatform() {
96+
return Capacitor.isNativePlatform();
7897
}
7998

8099
defineCustomElements(window);

ghcjs/miso-widgets/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-widgets/package-lock.json

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ghcjs/miso-widgets/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"@capacitor/browser": "^6.0.1",
1313
"@capacitor/clipboard": "^6.0.1",
1414
"@capacitor/core": "^6.0.0",
15+
"@capacitor/filesystem": "^6.0.1",
1516
"@capacitor/ios": "^6.0.0",
1617
"@capacitor/preferences": "^6.0.1",
1718
"@capacitor/share": "^6.0.1",

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

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ insertStorage key raw = do
119119

120120
selectStorage :: (FromJSON a) => Unicode -> (Maybe a -> JSM ()) -> JSM ()
121121
selectStorage key after =
122-
genericPromise "selectStorage" (Just key) $ \case
122+
genericPromise @[Unicode] @Unicode "selectStorage" [key] $ \case
123123
Nothing ->
124124
after Nothing
125125
Just str ->
@@ -134,31 +134,36 @@ selectStorage key after =
134134

135135
selectBarcode :: (Maybe Unicode -> JSM ()) -> JSM ()
136136
selectBarcode after =
137-
genericPromise "selectBarcode" Nothing $ after . fmap strip
137+
genericPromise @[Unicode] @Unicode "selectBarcode" mempty
138+
$ after
139+
. fmap strip
138140

139141
selectClipboard :: (Maybe Unicode -> JSM ()) -> JSM ()
140142
selectClipboard after =
141-
genericPromise "selectClipboard" Nothing $ after . fmap strip
143+
genericPromise @[Unicode] @Unicode "selectClipboard" mempty
144+
$ after
145+
. fmap strip
142146

143147
genericPromise ::
148+
forall args res.
149+
( JS.MakeArgs args,
150+
JS.FromJSVal res
151+
) =>
144152
Unicode ->
145-
Maybe Unicode ->
146-
(Maybe Unicode -> JSM ()) ->
153+
args ->
154+
(Maybe res -> JSM ()) ->
147155
JSM ()
148-
genericPromise fun marg after = do
156+
genericPromise fun argv after = do
149157
success <- JS.function $ \_ _ ->
150158
handleAny (\e -> consoleLog e >> after Nothing) . \case
151159
[val] -> do
152160
valExist <- ghcjsPure $ JS.isTruthy val
153161
if not valExist
154162
then after Nothing
155163
else do
156-
raw <-
157-
JS.fromJSVal @Unicode val
158-
res <-
159-
maybe (throwString @String "Failure, bad type!") pure raw
160-
after
161-
$ Just res
164+
mres <- JS.fromJSVal @res val
165+
res <- maybe (throwString @String "Failure, bad result!") pure mres
166+
after $ Just res
162167
_ ->
163168
throwString @String "Failure, bad argv!"
164169
failure <-
@@ -167,13 +172,8 @@ genericPromise fun marg after = do
167172
consoleLog @Unicode $ "Failure, " <> inspect msg <> "!"
168173
after Nothing
169174
pkg <- getPkg
170-
prom <-
171-
case marg of
172-
Nothing -> pkg ^. JS.js0 fun
173-
Just arg -> pkg ^. JS.js1 fun arg
174-
void
175-
$ prom
176-
^. JS.js2 @Unicode "then" success failure
175+
prom <- pkg ^. JS.jsf fun argv
176+
void $ prom ^. JS.js2 @Unicode "then" success failure
177177

178178
printCurrentPage :: Unicode -> JSM ()
179179
printCurrentPage name = do
@@ -182,11 +182,12 @@ printCurrentPage name = do
182182

183183
saveFile :: forall a. (From a [Word8]) => Unicode -> Unicode -> a -> JSM ()
184184
saveFile name mime bs = do
185-
pkg <- getPkg
186-
void
187-
$ pkg
188-
^. JS.js3
189-
("saveFile" :: Unicode)
190-
name
191-
mime
192-
(from @a @[Word8] bs)
185+
argv <-
186+
sequence
187+
[ JS.toJSVal name,
188+
JS.toJSVal mime,
189+
JS.toJSVal $ from @a @[Word8] bs
190+
]
191+
genericPromise @[JS.JSVal] @Unicode "saveFile" argv $ \case
192+
Nothing -> pure ()
193+
Just str -> popupText str

pub/xlsx/src/Codec/Xlsx/Writer.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,7 @@ data FileData = FileData
448448
fdRelType :: Text,
449449
fdContents :: L.ByteString
450450
}
451+
deriving (Eq, Ord, Show, Generic)
451452

452453
type ReferencedFileData = (RefId, FileData)
453454

0 commit comments

Comments
 (0)