expo-document-picker 11.5.2 → 11.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/android/build.gradle +2 -2
- package/build/ExpoDocumentPicker.web.d.ts.map +1 -1
- package/build/ExpoDocumentPicker.web.js +34 -24
- package/build/ExpoDocumentPicker.web.js.map +1 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -30
- package/build/index.js.map +1 -1
- package/build/types.d.ts +0 -31
- package/build/types.d.ts.map +1 -1
- package/build/types.js.map +1 -1
- package/ios/DocumentPickerModule.swift +48 -2
- package/ios/DocumentPickerOptions.swift +1 -56
- package/package.json +2 -2
- package/src/ExpoDocumentPicker.web.ts +37 -25
- package/src/index.ts +1 -36
- package/src/types.ts +0 -31
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,18 @@
|
|
|
10
10
|
|
|
11
11
|
### 💡 Others
|
|
12
12
|
|
|
13
|
+
## 11.5.4 — 2023-07-19
|
|
14
|
+
|
|
15
|
+
### 🐛 Bug fixes
|
|
16
|
+
|
|
17
|
+
- Fix `type` on `DocumentPickerOptions` on iOS. ([#23497](https://github.com/expo/expo/pull/23497) by [@aleqsio](https://github.com/aleqsio))
|
|
18
|
+
|
|
19
|
+
## 11.5.3 — 2023-07-10
|
|
20
|
+
|
|
21
|
+
### 💡 Others
|
|
22
|
+
|
|
23
|
+
- Remove deprecated fields and warning on `getDocumentAsync`. ([#23135](https://github.com/expo/expo/pull/23135) by [@alanjhughes](https://github.com/alanjhughes))
|
|
24
|
+
|
|
13
25
|
## 11.5.2 — 2023-06-28
|
|
14
26
|
|
|
15
27
|
_This version does not introduce any user-facing changes._
|
package/android/build.gradle
CHANGED
|
@@ -3,7 +3,7 @@ apply plugin: 'kotlin-android'
|
|
|
3
3
|
apply plugin: 'maven-publish'
|
|
4
4
|
|
|
5
5
|
group = 'host.exp.exponent'
|
|
6
|
-
version = '11.5.
|
|
6
|
+
version = '11.5.4'
|
|
7
7
|
|
|
8
8
|
buildscript {
|
|
9
9
|
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
@@ -67,7 +67,7 @@ android {
|
|
|
67
67
|
minSdkVersion safeExtGet("minSdkVersion", 21)
|
|
68
68
|
targetSdkVersion safeExtGet("targetSdkVersion", 33)
|
|
69
69
|
versionCode 17
|
|
70
|
-
versionName '11.5.
|
|
70
|
+
versionName '11.5.4'
|
|
71
71
|
}
|
|
72
72
|
lintOptions {
|
|
73
73
|
abortOnError false
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoDocumentPicker.web.d.ts","sourceRoot":"","sources":["../src/ExpoDocumentPicker.web.ts"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"ExpoDocumentPicker.web.d.ts","sourceRoot":"","sources":["../src/ExpoDocumentPicker.web.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;;;0CAUtF,qBAAqB,GAAG,QAAQ,oBAAoB,CAAC;;AAR1D,wBAiDE"}
|
|
@@ -18,31 +18,19 @@ export default {
|
|
|
18
18
|
}
|
|
19
19
|
document.body.appendChild(input);
|
|
20
20
|
return new Promise((resolve, reject) => {
|
|
21
|
-
input.addEventListener('change', () => {
|
|
21
|
+
input.addEventListener('change', async () => {
|
|
22
22
|
if (input.files) {
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
uri,
|
|
35
|
-
mimeType,
|
|
36
|
-
assets: [],
|
|
37
|
-
name: targetFile.name,
|
|
38
|
-
file: targetFile,
|
|
39
|
-
lastModified: targetFile.lastModified,
|
|
40
|
-
size: targetFile.size,
|
|
41
|
-
output: input.files,
|
|
42
|
-
});
|
|
43
|
-
};
|
|
44
|
-
// Read in the image file as a binary string.
|
|
45
|
-
reader.readAsDataURL(targetFile);
|
|
23
|
+
const results = [];
|
|
24
|
+
for (let i = 0; i < input.files.length; i++) {
|
|
25
|
+
results.push(readFileAsync(input.files[i]));
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
const assets = await Promise.all(results);
|
|
29
|
+
resolve({ canceled: false, assets, output: input.files });
|
|
30
|
+
}
|
|
31
|
+
catch (e) {
|
|
32
|
+
reject(e);
|
|
33
|
+
}
|
|
46
34
|
}
|
|
47
35
|
else {
|
|
48
36
|
resolve({ canceled: true, assets: null });
|
|
@@ -54,4 +42,26 @@ export default {
|
|
|
54
42
|
});
|
|
55
43
|
},
|
|
56
44
|
};
|
|
45
|
+
function readFileAsync(targetFile) {
|
|
46
|
+
return new Promise((resolve, reject) => {
|
|
47
|
+
const mimeType = targetFile.type;
|
|
48
|
+
const reader = new FileReader();
|
|
49
|
+
reader.onerror = () => {
|
|
50
|
+
reject(new Error(`Failed to read the selected media because the operation failed.`));
|
|
51
|
+
};
|
|
52
|
+
reader.onload = ({ target }) => {
|
|
53
|
+
const uri = target.result;
|
|
54
|
+
resolve({
|
|
55
|
+
uri,
|
|
56
|
+
mimeType,
|
|
57
|
+
name: targetFile.name,
|
|
58
|
+
lastModified: targetFile.lastModified,
|
|
59
|
+
size: targetFile.size,
|
|
60
|
+
file: targetFile,
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
// Read in the image file as a binary string.
|
|
64
|
+
reader.readAsDataURL(targetFile);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
57
67
|
//# sourceMappingURL=ExpoDocumentPicker.web.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoDocumentPicker.web.js","sourceRoot":"","sources":["../src/ExpoDocumentPicker.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAI7C,eAAe;IACb,IAAI,IAAI;QACN,OAAO,oBAAoB,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,EACrB,IAAI,GAAG,KAAK,EACZ,QAAQ,GAAG,KAAK,GACM;QACtB,YAAY;QACZ,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE;YAC5B,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;SACzC;QAED,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAC9C,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;QAC7B,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC1E,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAChD,IAAI,QAAQ,EAAE;YACZ,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;SAC5C;QAED,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAEjC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,KAAK,CAAC,gBAAgB,CAAC,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"ExpoDocumentPicker.web.js","sourceRoot":"","sources":["../src/ExpoDocumentPicker.web.ts"],"names":[],"mappings":"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","sourcesContent":["import { Platform } from 'expo-modules-core';\n\nimport { DocumentPickerAsset, DocumentPickerOptions, DocumentPickerResult } from './types';\n\nexport default {\n get name(): string {\n return 'ExpoDocumentPicker';\n },\n\n async getDocumentAsync({\n type = '*/*',\n multiple = false,\n }: DocumentPickerOptions): Promise<DocumentPickerResult> {\n // SSR guard\n if (!Platform.isDOMAvailable) {\n return { canceled: true, assets: null };\n }\n\n const input = document.createElement('input');\n input.style.display = 'none';\n input.setAttribute('type', 'file');\n input.setAttribute('accept', Array.isArray(type) ? type.join(',') : type);\n input.setAttribute('id', String(Math.random()));\n if (multiple) {\n input.setAttribute('multiple', 'multiple');\n }\n\n document.body.appendChild(input);\n\n return new Promise((resolve, reject) => {\n input.addEventListener('change', async () => {\n if (input.files) {\n const results: Promise<DocumentPickerAsset>[] = [];\n for (let i = 0; i < input.files.length; i++) {\n results.push(readFileAsync(input.files[i]));\n }\n try {\n const assets = await Promise.all(results);\n resolve({ canceled: false, assets, output: input.files });\n } catch (e) {\n reject(e);\n }\n } else {\n resolve({ canceled: true, assets: null });\n }\n\n document.body.removeChild(input);\n });\n\n const event = new MouseEvent('click');\n input.dispatchEvent(event);\n });\n },\n};\n\nfunction readFileAsync(targetFile: File): Promise<DocumentPickerAsset> {\n return new Promise((resolve, reject) => {\n const mimeType = targetFile.type;\n\n const reader = new FileReader();\n reader.onerror = () => {\n reject(new Error(`Failed to read the selected media because the operation failed.`));\n };\n reader.onload = ({ target }) => {\n const uri = (target as any).result;\n resolve({\n uri,\n mimeType,\n name: targetFile.name,\n lastModified: targetFile.lastModified,\n size: targetFile.size,\n file: targetFile,\n });\n };\n\n // Read in the image file as a binary string.\n reader.readAsDataURL(targetFile);\n });\n}\n"]}
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAGtE;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CAAC,EACrC,IAAY,EACZ,oBAA2B,EAC3B,QAAgB,GACjB,GAAE,qBAA0B,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAS5D;AAED,cAAc,SAAS,CAAC"}
|
package/build/index.js
CHANGED
|
@@ -1,32 +1,4 @@
|
|
|
1
1
|
import ExpoDocumentPicker from './ExpoDocumentPicker';
|
|
2
|
-
const DEPRECATED_RESULT_KEYS = [
|
|
3
|
-
'name',
|
|
4
|
-
'size',
|
|
5
|
-
'uri',
|
|
6
|
-
'mimeType',
|
|
7
|
-
'lastModified',
|
|
8
|
-
'file',
|
|
9
|
-
'output',
|
|
10
|
-
];
|
|
11
|
-
function mergeDeprecatedResult(result) {
|
|
12
|
-
const firstAsset = result.assets?.[0];
|
|
13
|
-
const deprecatedResult = {
|
|
14
|
-
...result,
|
|
15
|
-
get type() {
|
|
16
|
-
console.warn('Key "type" in the document picker result is deprecated and will be removed in SDK 49, use "canceled" instead');
|
|
17
|
-
return this.canceled ? 'cancel' : 'success';
|
|
18
|
-
},
|
|
19
|
-
};
|
|
20
|
-
for (const key of DEPRECATED_RESULT_KEYS) {
|
|
21
|
-
Object.defineProperty(deprecatedResult, key, {
|
|
22
|
-
get() {
|
|
23
|
-
console.warn(`Key "${key}" in the document picker result is deprecated and will be removed in SDK 49, you can access selected assets through the "assets" array instead`);
|
|
24
|
-
return firstAsset?.[key];
|
|
25
|
-
},
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
return deprecatedResult;
|
|
29
|
-
}
|
|
30
2
|
// @needsAudit
|
|
31
3
|
/**
|
|
32
4
|
* Display the system UI for choosing a document. By default, the chosen file is copied to [the app's internal cache directory](filesystem.md#filesystemcachedirectory).
|
|
@@ -43,12 +15,11 @@ export async function getDocumentAsync({ type = '*/*', copyToCacheDirectory = tr
|
|
|
43
15
|
if (typeof type === 'string') {
|
|
44
16
|
type = [type];
|
|
45
17
|
}
|
|
46
|
-
|
|
18
|
+
return await ExpoDocumentPicker.getDocumentAsync({
|
|
47
19
|
type,
|
|
48
20
|
copyToCacheDirectory,
|
|
49
21
|
multiple,
|
|
50
22
|
});
|
|
51
|
-
return mergeDeprecatedResult(result);
|
|
52
23
|
}
|
|
53
24
|
export * from './types';
|
|
54
25
|
//# sourceMappingURL=index.js.map
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,MAAM,sBAAsB,CAAC;AAGtD,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,MAAM,sBAAsB,CAAC;AAGtD,cAAc;AACd;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,EACrC,IAAI,GAAG,KAAK,EACZ,oBAAoB,GAAG,IAAI,EAC3B,QAAQ,GAAG,KAAK,MACS,EAAE;IAC3B,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;QAC5B,IAAI,GAAG,CAAC,IAAI,CAAa,CAAC;KAC3B;IACD,OAAO,MAAM,kBAAkB,CAAC,gBAAgB,CAAC;QAC/C,IAAI;QACJ,oBAAoB;QACpB,QAAQ;KACT,CAAC,CAAC;AACL,CAAC;AAED,cAAc,SAAS,CAAC","sourcesContent":["import ExpoDocumentPicker from './ExpoDocumentPicker';\nimport { DocumentPickerOptions, DocumentPickerResult } from './types';\n\n// @needsAudit\n/**\n * Display the system UI for choosing a document. By default, the chosen file is copied to [the app's internal cache directory](filesystem.md#filesystemcachedirectory).\n * > **Notes for Web:** The system UI can only be shown after user activation (e.g. a `Button` press).\n * > Therefore, calling `getDocumentAsync` in `componentDidMount`, for example, will **not** work as\n * > intended. The `cancel` event will not be returned in the browser due to platform restrictions and\n * > inconsistencies across browsers.\n *\n * @return On success returns a promise that fulfils with [`DocumentResult`](#documentresult) object.\n *\n * If the user cancelled the document picking, the promise resolves to `{ type: 'cancel' }`.\n */\nexport async function getDocumentAsync({\n type = '*/*',\n copyToCacheDirectory = true,\n multiple = false,\n}: DocumentPickerOptions = {}): Promise<DocumentPickerResult> {\n if (typeof type === 'string') {\n type = [type] as string[];\n }\n return await ExpoDocumentPicker.getDocumentAsync({\n type,\n copyToCacheDirectory,\n multiple,\n });\n}\n\nexport * from './types';\n"]}
|
package/build/types.d.ts
CHANGED
|
@@ -47,11 +47,6 @@ export type DocumentPickerAsset = {
|
|
|
47
47
|
* @platform web
|
|
48
48
|
*/
|
|
49
49
|
file?: File;
|
|
50
|
-
/**
|
|
51
|
-
* `FileList` object for the parity with web File API.
|
|
52
|
-
* @platform web
|
|
53
|
-
*/
|
|
54
|
-
output?: FileList | null;
|
|
55
50
|
};
|
|
56
51
|
export type DocumentPickerResult = {
|
|
57
52
|
/**
|
|
@@ -59,36 +54,10 @@ export type DocumentPickerResult = {
|
|
|
59
54
|
* always be `false`.
|
|
60
55
|
*/
|
|
61
56
|
canceled: boolean;
|
|
62
|
-
type?: string;
|
|
63
|
-
/**
|
|
64
|
-
* Document original name.
|
|
65
|
-
*/
|
|
66
|
-
name?: string;
|
|
67
|
-
/**
|
|
68
|
-
* Document size in bytes.
|
|
69
|
-
*/
|
|
70
|
-
size?: number;
|
|
71
57
|
/**
|
|
72
58
|
* An array of picked assets or `null` when the request was canceled.
|
|
73
59
|
*/
|
|
74
60
|
assets: DocumentPickerAsset[] | null;
|
|
75
|
-
/**
|
|
76
|
-
* An URI to the local document file.
|
|
77
|
-
*/
|
|
78
|
-
uri?: string;
|
|
79
|
-
/**
|
|
80
|
-
* Document MIME type.
|
|
81
|
-
*/
|
|
82
|
-
mimeType?: string;
|
|
83
|
-
/**
|
|
84
|
-
* Timestamp of last document modification.
|
|
85
|
-
*/
|
|
86
|
-
lastModified?: number;
|
|
87
|
-
/**
|
|
88
|
-
* `File` object for the parity with web File API.
|
|
89
|
-
* @platform web
|
|
90
|
-
*/
|
|
91
|
-
file?: File;
|
|
92
61
|
/**
|
|
93
62
|
* `FileList` object for the parity with web File API.
|
|
94
63
|
* @platform web
|
package/build/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,qBAAqB,GAAG;IAClC;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB;;;;;;OAMG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,IAAI,CAAC,EAAE,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,qBAAqB,GAAG;IAClC;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB;;;;;;OAMG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,IAAI,CAAC,EAAE,IAAI,CAAC;CACb,CAAC;AAGF,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;OAGG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB;;OAEG;IACH,MAAM,EAAE,mBAAmB,EAAE,GAAG,IAAI,CAAC;IACrC;;;OAGG;IACH,MAAM,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;CAC1B,GAAG,CAAC,2BAA2B,GAAG,4BAA4B,CAAC,CAAC;AAEjE;;GAEG;AACH,MAAM,MAAM,2BAA2B,GAAG;IACxC,QAAQ,EAAE,KAAK,CAAC;IAChB,MAAM,EAAE,mBAAmB,EAAE,CAAC;CAC/B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACzC,QAAQ,EAAE,IAAI,CAAC;IACf,MAAM,EAAE,IAAI,CAAC;CACd,CAAC"}
|
package/build/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["// @needsAudit\nexport type DocumentPickerOptions = {\n /**\n * The [MIME type(s)](https://en.wikipedia.org/wiki/Media_type) of the documents that are available\n * to be picked. It also supports wildcards like `'image/*'` to choose any image. To allow any type\n * of document you can use `'*/*'`.\n * @default '*/*'\n */\n type?: string | string[];\n /**\n * If `true`, the picked file is copied to [`FileSystem.CacheDirectory`](./filesystem#filesystemcachedirectory),\n * which allows other Expo APIs to read the file immediately. This may impact performance for\n * large files, so you should consider setting this to `false` if you expect users to pick\n * particularly large files and your app does not need immediate read access.\n * @default true\n */\n copyToCacheDirectory?: boolean;\n /**\n * Allows multiple files to be selected from the system UI.\n * @default false\n *\n */\n multiple?: boolean;\n};\n\nexport type DocumentPickerAsset = {\n /**\n * Document original name.\n */\n name: string;\n /**\n * Document size in bytes.\n */\n size?: number;\n /**\n * An URI to the local document file.\n */\n uri: string;\n /**\n * Document MIME type.\n */\n mimeType?: string;\n /**\n * Timestamp of last document modification.\n */\n lastModified?: number;\n /**\n * `File` object for the parity with web File API.\n * @platform web\n */\n file?: File;\n
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["// @needsAudit\nexport type DocumentPickerOptions = {\n /**\n * The [MIME type(s)](https://en.wikipedia.org/wiki/Media_type) of the documents that are available\n * to be picked. It also supports wildcards like `'image/*'` to choose any image. To allow any type\n * of document you can use `'*/*'`.\n * @default '*/*'\n */\n type?: string | string[];\n /**\n * If `true`, the picked file is copied to [`FileSystem.CacheDirectory`](./filesystem#filesystemcachedirectory),\n * which allows other Expo APIs to read the file immediately. This may impact performance for\n * large files, so you should consider setting this to `false` if you expect users to pick\n * particularly large files and your app does not need immediate read access.\n * @default true\n */\n copyToCacheDirectory?: boolean;\n /**\n * Allows multiple files to be selected from the system UI.\n * @default false\n *\n */\n multiple?: boolean;\n};\n\nexport type DocumentPickerAsset = {\n /**\n * Document original name.\n */\n name: string;\n /**\n * Document size in bytes.\n */\n size?: number;\n /**\n * An URI to the local document file.\n */\n uri: string;\n /**\n * Document MIME type.\n */\n mimeType?: string;\n /**\n * Timestamp of last document modification.\n */\n lastModified?: number;\n /**\n * `File` object for the parity with web File API.\n * @platform web\n */\n file?: File;\n};\n\n// @needsAudit @docsMissing\nexport type DocumentPickerResult = {\n /**\n * Boolean flag which shows if request was canceled. If asset data have been returned this should\n * always be `false`.\n */\n canceled: boolean;\n /**\n * An array of picked assets or `null` when the request was canceled.\n */\n assets: DocumentPickerAsset[] | null;\n /**\n * `FileList` object for the parity with web File API.\n * @platform web\n */\n output?: FileList | null;\n} & (DocumentPickerSuccessResult | DocumentPickerCanceledResult);\n\n/**\n * @hidden\n */\nexport type DocumentPickerSuccessResult = {\n canceled: false;\n assets: DocumentPickerAsset[];\n};\n\n/**\n * @hidden\n */\nexport type DocumentPickerCanceledResult = {\n canceled: true;\n assets: null;\n};\n"]}
|
|
@@ -156,15 +156,61 @@ public class DocumentPickerModule: Module, PickingResultHandler {
|
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
+
@available(iOS 14.0, *)
|
|
160
|
+
private func toUTType(mimeType: String) -> UTType? {
|
|
161
|
+
switch mimeType {
|
|
162
|
+
case "*/*":
|
|
163
|
+
return UTType.item
|
|
164
|
+
case "image/*":
|
|
165
|
+
return UTType.image
|
|
166
|
+
case "video/*":
|
|
167
|
+
return UTType.video
|
|
168
|
+
case "audio/*":
|
|
169
|
+
return UTType.audio
|
|
170
|
+
case "text/*":
|
|
171
|
+
return UTType.text
|
|
172
|
+
default:
|
|
173
|
+
return UTType(mimeType: mimeType)
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
private func toUTI(mimeType: String) -> String {
|
|
178
|
+
var uti: CFString
|
|
179
|
+
|
|
180
|
+
switch mimeType {
|
|
181
|
+
case "*/*":
|
|
182
|
+
uti = kUTTypeItem
|
|
183
|
+
case "image/*":
|
|
184
|
+
uti = kUTTypeImage
|
|
185
|
+
case "video/*":
|
|
186
|
+
uti = kUTTypeVideo
|
|
187
|
+
case "audio/*":
|
|
188
|
+
uti = kUTTypeAudio
|
|
189
|
+
case "text/*":
|
|
190
|
+
uti = kUTTypeText
|
|
191
|
+
default:
|
|
192
|
+
if let ref = UTTypeCreatePreferredIdentifierForTag(
|
|
193
|
+
kUTTagClassMIMEType,
|
|
194
|
+
mimeType as CFString,
|
|
195
|
+
nil
|
|
196
|
+
)?.takeRetainedValue() {
|
|
197
|
+
uti = ref
|
|
198
|
+
} else {
|
|
199
|
+
uti = kUTTypeItem
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return uti as String
|
|
203
|
+
}
|
|
204
|
+
|
|
159
205
|
private func createDocumentPicker(with options: DocumentPickerOptions) -> UIDocumentPickerViewController {
|
|
160
206
|
if #available(iOS 14.0, *) {
|
|
161
|
-
let utTypes = options.type.compactMap { $0
|
|
207
|
+
let utTypes = options.type.compactMap { toUTType(mimeType: $0) }
|
|
162
208
|
return UIDocumentPickerViewController(
|
|
163
209
|
forOpeningContentTypes: utTypes,
|
|
164
210
|
asCopy: true
|
|
165
211
|
)
|
|
166
212
|
} else {
|
|
167
|
-
let utiTypes = options.type.map { $0
|
|
213
|
+
let utiTypes = options.type.map { toUTI(mimeType: $0) }
|
|
168
214
|
return UIDocumentPickerViewController(
|
|
169
215
|
documentTypes: utiTypes,
|
|
170
216
|
in: .import
|
|
@@ -6,63 +6,8 @@ struct DocumentPickerOptions: Record {
|
|
|
6
6
|
var copyToCacheDirectory: Bool
|
|
7
7
|
|
|
8
8
|
@Field
|
|
9
|
-
var type: [
|
|
9
|
+
var type: [String]
|
|
10
10
|
|
|
11
11
|
@Field
|
|
12
12
|
var multiple: Bool
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
internal enum MimeType: String, Enumerable {
|
|
16
|
-
case item = "*/*"
|
|
17
|
-
case image = "image/*"
|
|
18
|
-
case video = "video/*"
|
|
19
|
-
case audio = "audio/*"
|
|
20
|
-
case text = "text/*"
|
|
21
|
-
|
|
22
|
-
@available(iOS 14.0, *)
|
|
23
|
-
func toUTType() -> UTType? {
|
|
24
|
-
switch self {
|
|
25
|
-
case .item:
|
|
26
|
-
return UTType.item
|
|
27
|
-
case .image:
|
|
28
|
-
return UTType.image
|
|
29
|
-
case .video:
|
|
30
|
-
return UTType.video
|
|
31
|
-
case .audio:
|
|
32
|
-
return UTType.audio
|
|
33
|
-
case .text:
|
|
34
|
-
return UTType.text
|
|
35
|
-
default:
|
|
36
|
-
return UTType(mimeType: self.rawValue)
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
func toUTI() -> String {
|
|
41
|
-
var uti: CFString
|
|
42
|
-
|
|
43
|
-
switch self {
|
|
44
|
-
case .item:
|
|
45
|
-
uti = kUTTypeItem
|
|
46
|
-
case .image:
|
|
47
|
-
uti = kUTTypeImage
|
|
48
|
-
case .video:
|
|
49
|
-
uti = kUTTypeVideo
|
|
50
|
-
case .audio:
|
|
51
|
-
uti = kUTTypeAudio
|
|
52
|
-
case .text:
|
|
53
|
-
uti = kUTTypeText
|
|
54
|
-
default:
|
|
55
|
-
if let ref = UTTypeCreatePreferredIdentifierForTag(
|
|
56
|
-
kUTTagClassMIMEType,
|
|
57
|
-
self.rawValue as CFString,
|
|
58
|
-
nil
|
|
59
|
-
)?.takeRetainedValue() {
|
|
60
|
-
uti = ref
|
|
61
|
-
} else {
|
|
62
|
-
uti = kUTTypeItem
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
return uti as String
|
|
67
|
-
}
|
|
68
|
-
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-document-picker",
|
|
3
|
-
"version": "11.5.
|
|
3
|
+
"version": "11.5.4",
|
|
4
4
|
"description": "Provides access to the system's UI for selecting documents from the available providers on the user's device.",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -40,5 +40,5 @@
|
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"expo": "*"
|
|
42
42
|
},
|
|
43
|
-
"gitHead": "
|
|
43
|
+
"gitHead": "c549faa0676cee6ce886846d5332f0f8e5674e5c"
|
|
44
44
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Platform } from 'expo-modules-core';
|
|
2
2
|
|
|
3
|
-
import { DocumentPickerOptions, DocumentPickerResult } from './types';
|
|
3
|
+
import { DocumentPickerAsset, DocumentPickerOptions, DocumentPickerResult } from './types';
|
|
4
4
|
|
|
5
5
|
export default {
|
|
6
6
|
get name(): string {
|
|
@@ -28,31 +28,18 @@ export default {
|
|
|
28
28
|
document.body.appendChild(input);
|
|
29
29
|
|
|
30
30
|
return new Promise((resolve, reject) => {
|
|
31
|
-
input.addEventListener('change', () => {
|
|
31
|
+
input.addEventListener('change', async () => {
|
|
32
32
|
if (input.files) {
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
type: 'success',
|
|
44
|
-
uri,
|
|
45
|
-
mimeType,
|
|
46
|
-
assets: [],
|
|
47
|
-
name: targetFile.name,
|
|
48
|
-
file: targetFile,
|
|
49
|
-
lastModified: targetFile.lastModified,
|
|
50
|
-
size: targetFile.size,
|
|
51
|
-
output: input.files,
|
|
52
|
-
});
|
|
53
|
-
};
|
|
54
|
-
// Read in the image file as a binary string.
|
|
55
|
-
reader.readAsDataURL(targetFile);
|
|
33
|
+
const results: Promise<DocumentPickerAsset>[] = [];
|
|
34
|
+
for (let i = 0; i < input.files.length; i++) {
|
|
35
|
+
results.push(readFileAsync(input.files[i]));
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
const assets = await Promise.all(results);
|
|
39
|
+
resolve({ canceled: false, assets, output: input.files });
|
|
40
|
+
} catch (e) {
|
|
41
|
+
reject(e);
|
|
42
|
+
}
|
|
56
43
|
} else {
|
|
57
44
|
resolve({ canceled: true, assets: null });
|
|
58
45
|
}
|
|
@@ -65,3 +52,28 @@ export default {
|
|
|
65
52
|
});
|
|
66
53
|
},
|
|
67
54
|
};
|
|
55
|
+
|
|
56
|
+
function readFileAsync(targetFile: File): Promise<DocumentPickerAsset> {
|
|
57
|
+
return new Promise((resolve, reject) => {
|
|
58
|
+
const mimeType = targetFile.type;
|
|
59
|
+
|
|
60
|
+
const reader = new FileReader();
|
|
61
|
+
reader.onerror = () => {
|
|
62
|
+
reject(new Error(`Failed to read the selected media because the operation failed.`));
|
|
63
|
+
};
|
|
64
|
+
reader.onload = ({ target }) => {
|
|
65
|
+
const uri = (target as any).result;
|
|
66
|
+
resolve({
|
|
67
|
+
uri,
|
|
68
|
+
mimeType,
|
|
69
|
+
name: targetFile.name,
|
|
70
|
+
lastModified: targetFile.lastModified,
|
|
71
|
+
size: targetFile.size,
|
|
72
|
+
file: targetFile,
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// Read in the image file as a binary string.
|
|
77
|
+
reader.readAsDataURL(targetFile);
|
|
78
|
+
});
|
|
79
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,40 +1,6 @@
|
|
|
1
1
|
import ExpoDocumentPicker from './ExpoDocumentPicker';
|
|
2
2
|
import { DocumentPickerOptions, DocumentPickerResult } from './types';
|
|
3
3
|
|
|
4
|
-
const DEPRECATED_RESULT_KEYS = [
|
|
5
|
-
'name',
|
|
6
|
-
'size',
|
|
7
|
-
'uri',
|
|
8
|
-
'mimeType',
|
|
9
|
-
'lastModified',
|
|
10
|
-
'file',
|
|
11
|
-
'output',
|
|
12
|
-
];
|
|
13
|
-
|
|
14
|
-
function mergeDeprecatedResult(result: DocumentPickerResult): DocumentPickerResult {
|
|
15
|
-
const firstAsset = result.assets?.[0];
|
|
16
|
-
const deprecatedResult = {
|
|
17
|
-
...result,
|
|
18
|
-
get type() {
|
|
19
|
-
console.warn(
|
|
20
|
-
'Key "type" in the document picker result is deprecated and will be removed in SDK 49, use "canceled" instead'
|
|
21
|
-
);
|
|
22
|
-
return this.canceled ? 'cancel' : 'success';
|
|
23
|
-
},
|
|
24
|
-
};
|
|
25
|
-
for (const key of DEPRECATED_RESULT_KEYS) {
|
|
26
|
-
Object.defineProperty(deprecatedResult, key, {
|
|
27
|
-
get() {
|
|
28
|
-
console.warn(
|
|
29
|
-
`Key "${key}" in the document picker result is deprecated and will be removed in SDK 49, you can access selected assets through the "assets" array instead`
|
|
30
|
-
);
|
|
31
|
-
return firstAsset?.[key];
|
|
32
|
-
},
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
return deprecatedResult;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
4
|
// @needsAudit
|
|
39
5
|
/**
|
|
40
6
|
* Display the system UI for choosing a document. By default, the chosen file is copied to [the app's internal cache directory](filesystem.md#filesystemcachedirectory).
|
|
@@ -55,12 +21,11 @@ export async function getDocumentAsync({
|
|
|
55
21
|
if (typeof type === 'string') {
|
|
56
22
|
type = [type] as string[];
|
|
57
23
|
}
|
|
58
|
-
|
|
24
|
+
return await ExpoDocumentPicker.getDocumentAsync({
|
|
59
25
|
type,
|
|
60
26
|
copyToCacheDirectory,
|
|
61
27
|
multiple,
|
|
62
28
|
});
|
|
63
|
-
return mergeDeprecatedResult(result);
|
|
64
29
|
}
|
|
65
30
|
|
|
66
31
|
export * from './types';
|
package/src/types.ts
CHANGED
|
@@ -49,11 +49,6 @@ export type DocumentPickerAsset = {
|
|
|
49
49
|
* @platform web
|
|
50
50
|
*/
|
|
51
51
|
file?: File;
|
|
52
|
-
/**
|
|
53
|
-
* `FileList` object for the parity with web File API.
|
|
54
|
-
* @platform web
|
|
55
|
-
*/
|
|
56
|
-
output?: FileList | null;
|
|
57
52
|
};
|
|
58
53
|
|
|
59
54
|
// @needsAudit @docsMissing
|
|
@@ -63,36 +58,10 @@ export type DocumentPickerResult = {
|
|
|
63
58
|
* always be `false`.
|
|
64
59
|
*/
|
|
65
60
|
canceled: boolean;
|
|
66
|
-
type?: string;
|
|
67
|
-
/**
|
|
68
|
-
* Document original name.
|
|
69
|
-
*/
|
|
70
|
-
name?: string;
|
|
71
|
-
/**
|
|
72
|
-
* Document size in bytes.
|
|
73
|
-
*/
|
|
74
|
-
size?: number;
|
|
75
61
|
/**
|
|
76
62
|
* An array of picked assets or `null` when the request was canceled.
|
|
77
63
|
*/
|
|
78
64
|
assets: DocumentPickerAsset[] | null;
|
|
79
|
-
/**
|
|
80
|
-
* An URI to the local document file.
|
|
81
|
-
*/
|
|
82
|
-
uri?: string;
|
|
83
|
-
/**
|
|
84
|
-
* Document MIME type.
|
|
85
|
-
*/
|
|
86
|
-
mimeType?: string;
|
|
87
|
-
/**
|
|
88
|
-
* Timestamp of last document modification.
|
|
89
|
-
*/
|
|
90
|
-
lastModified?: number;
|
|
91
|
-
/**
|
|
92
|
-
* `File` object for the parity with web File API.
|
|
93
|
-
* @platform web
|
|
94
|
-
*/
|
|
95
|
-
file?: File;
|
|
96
65
|
/**
|
|
97
66
|
* `FileList` object for the parity with web File API.
|
|
98
67
|
* @platform web
|