mobile: handle uploading multiple files

This commit is contained in:
ammarahm-ed
2023-08-14 15:02:51 +05:00
committed by Abdullah Atta
parent 4b693b301f
commit 4ba90510ea
2 changed files with 87 additions and 79 deletions

View File

@@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import React, { useState } from "react";
import { Image, TouchableOpacity, View } from "react-native";
import { Image, ScrollView, TouchableOpacity, View } from "react-native";
import { ImagePickerResponse } from "react-native-image-picker";
import { useThemeColors } from "../../../../../../packages/theme/dist";
import { presentSheet } from "../../../services/event-manager";
@@ -38,10 +38,6 @@ export default function AttachImage({
}) {
const { colors } = useThemeColors();
const [compress, setCompress] = useState(true);
const image = response.assets?.[0];
const width = image?.width || 0;
const height = image?.height || 0;
const ratio = width / height;
return (
<View
@@ -50,30 +46,40 @@ export default function AttachImage({
paddingHorizontal: 12
}}
>
{image ? (
<View
style={{
width: "100%",
borderRadius: 10,
backgroundColor: "black",
alignItems: "center",
justifyContent: "center",
marginBottom: 10
}}
>
<Image
source={{
uri: image.uri
}}
resizeMode="contain"
style={{
width: 300 * ratio,
height: (300 * ratio) / ratio,
backgroundColor: "black"
}}
/>
</View>
) : null}
<View
style={{
backgroundColor: colors.secondary.background,
marginBottom: 12,
height: 140,
width: "100%",
borderRadius: 10,
padding: 5,
paddingHorizontal: 12
}}
>
<Paragraph style={{ color: colors.primary.paragraph, marginBottom: 6 }}>
Attaching {response.assets?.length} image(s):
</Paragraph>
<ScrollView horizontal>
{response.assets?.map((item) => (
<TouchableOpacity key={item.fileName} activeOpacity={0.9}>
<Image
source={{
uri: item.uri
}}
style={{
width: 100,
height: 100,
borderRadius: 5,
backgroundColor: "black",
marginRight: 6
}}
resizeMode="cover"
/>
</TouchableOpacity>
))}
</ScrollView>
</View>
<TouchableOpacity
activeOpacity={1}
@@ -135,7 +141,7 @@ export default function AttachImage({
)}
<Button
title="Add image"
title="Add images to note"
type="accent"
width="100%"
onPress={() => {

View File

@@ -169,7 +169,7 @@ const gallery = async (options) => {
{
includeBase64: true,
mediaType: "photo",
selectionLimit: 1
selectionLimit: 10
},
(response) => handleImageResponse(response, options)
);
@@ -218,60 +218,62 @@ const handleImageResponse = async (response, options) => {
return;
}
let image = response.assets[0];
const result = await AttachImage.present(response);
const compress = await AttachImage.present(response);
if (!result) return;
const compress = result.compress;
const isPng = /(png)/g.test(image.type);
const isJpeg = /(jpeg|jpg)/g.test(image.type);
for (let image of response.assets) {
const isPng = /(png)/g.test(image.type);
const isJpeg = /(jpeg|jpg)/g.test(image.type);
if (compress && (isPng || isJpeg)) {
image.uri = await compressToFile(
Platform.OS === "ios" ? "file://" + image.uri : image.uri,
isPng ? "PNG" : "JPEG"
);
const stat = await RNFetchBlob.fs.stat(image.uri.replace("file://", ""));
image.fileSize = stat.size;
}
if (image.fileSize > IMAGE_SIZE_LIMIT) {
ToastManager.show({
title: "File too large",
message: "The maximum allowed size per image is 50 MB",
type: "error"
});
return;
}
let b64 = `data:${image.type};base64, ` + image.base64;
const uri = decodeURI(image.uri);
const hash = await Sodium.hashFile({
uri: uri,
type: "url"
});
let fileName = image.originalFileName || image.fileName;
editorController.current?.commands.insertImage({
hash: hash,
mime: image.type,
title: fileName,
dataurl: b64,
size: image.fileSize,
filename: fileName
});
if (!(await attachFile(uri, hash, image.type, fileName, options))) return;
if (isPng || isJpeg) {
b64 =
`data:${image.type};base64, ` +
(await compressToBase64(
if (compress && (isPng || isJpeg)) {
image.uri = await compressToFile(
Platform.OS === "ios" ? "file://" + image.uri : image.uri,
isPng ? "PNG" : "JPEG"
));
}
);
const stat = await RNFetchBlob.fs.stat(image.uri.replace("file://", ""));
image.fileSize = stat.size;
}
if (Platform.OS === "ios") await RNFetchBlob.fs.unlink(uri);
if (image.fileSize > IMAGE_SIZE_LIMIT) {
ToastEvent.show({
title: "File too large",
message: "The maximum allowed size per image is 50 MB",
type: "error"
});
return;
}
let b64 = `data:${image.type};base64, ` + image.base64;
const uri = decodeURI(image.uri);
const hash = await Sodium.hashFile({
uri: uri,
type: "url"
});
let fileName = image.originalFileName || image.fileName;
if (!(await attachFile(uri, hash, image.type, fileName, options))) return;
if (isPng || isJpeg) {
b64 =
`data:${image.type};base64, ` +
(await compressToBase64(
Platform.OS === "ios" ? "file://" + image.uri : image.uri,
isPng ? "PNG" : "JPEG"
));
}
if (Platform.OS === "ios") await RNFetchBlob.fs.unlink(uri);
editorController.current?.commands.insertImage({
hash: hash,
mime: image.type,
title: fileName,
dataurl: b64,
size: image.fileSize,
filename: fileName
});
}
};
export async function attachFile(uri, hash, type, filename, options) {