Skip to content

Commit 96e4cc2

Browse files
committed
fix: android crash during sharing larger media
1 parent 89edf83 commit 96e4cc2

File tree

3 files changed

+37
-26
lines changed

3 files changed

+37
-26
lines changed

package/native-package/src/optionalDependencies/shareImage.ts

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,9 @@ try {
88
console.log('react-native-share is not installed');
99
}
1010

11-
let RNBlobUtil;
12-
13-
try {
14-
RNBlobUtil = require('react-native-blob-util').default;
15-
} catch (e) {
16-
console.log('react-native-blob-util is not installed');
17-
}
18-
1911
export const shareImage = RNShare
2012
? async ({ type, url }) => {
2113
try {
22-
const base64Image = await RNBlobUtil.fs.readFile(url, 'base64');
23-
const base64Url = `data:${type};base64,${base64Image}`;
2414
await RNShare.open({
2515
activityItemSources:
2616
Platform.OS === 'ios'
@@ -45,7 +35,7 @@ export const shareImage = RNShare
4535
excludedActivityTypes: [] as unknown as string,
4636
failOnCancel: false,
4737
type,
48-
url: Platform.OS === 'android' ? base64Url : undefined,
38+
url: Platform.OS === 'android' ? `file://${url}` : undefined,
4939
});
5040
return true;
5141
} catch (error) {

package/src/components/ImageGallery/ImageGallery.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ export const ImageGallery = (props: Props) => {
528528
<Animated.View
529529
accessibilityLabel='Image Gallery'
530530
pointerEvents={'auto'}
531-
style={[StyleSheet.absoluteFillObject, showScreenStyle]}
531+
style={[StyleSheet.absoluteFillObject, showScreenStyle, { paddingVertical: 30 }]}
532532
>
533533
<Animated.View style={[StyleSheet.absoluteFillObject, containerBackground]} />
534534
<GestureDetector gesture={Gesture.Simultaneous(singleTap, doubleTap, pinch, pan)}>

package/src/components/ImageGallery/components/ImageGalleryFooter.tsx

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
1-
import React, { useState } from 'react';
2-
import { SafeAreaView, StyleSheet, Text, TouchableOpacity, View, ViewStyle } from 'react-native';
1+
import React, { useRef, useState } from 'react';
2+
import {
3+
ActivityIndicator,
4+
SafeAreaView,
5+
StyleSheet,
6+
Text,
7+
TouchableOpacity,
8+
View,
9+
ViewStyle,
10+
} from 'react-native';
311
import Animated, {
412
Extrapolation,
513
interpolate,
@@ -100,7 +108,8 @@ export const ImageGalleryFooterWithContext = (props: ImageGalleryFooterPropsWith
100108
} = props;
101109

102110
const [height, setHeight] = useState(200);
103-
const [shareMenuOpen, setShareMenuOpen] = useState(false);
111+
const [savingInProgress, setSavingInProgress] = useState(false);
112+
const shareIsInProgressRef = useRef<boolean>(false);
104113
const {
105114
theme: {
106115
colors: { black, white },
@@ -124,25 +133,31 @@ export const ImageGalleryFooterWithContext = (props: ImageGalleryFooterPropsWith
124133
);
125134

126135
const share = async () => {
127-
setShareMenuOpen(true);
136+
if (shareIsInProgressRef.current) {
137+
return;
138+
}
139+
shareIsInProgressRef.current = true;
128140
try {
129141
if (!NativeHandlers.shareImage || !NativeHandlers.deleteFile) {
130142
return;
131143
}
132144
const extension = photo.mime_type?.split('/')[1] || 'jpg';
145+
setSavingInProgress(true);
133146
const localFile = await NativeHandlers.saveFile({
134147
fileName: `${photo.user?.id || 'ChatPhoto'}-${
135148
photo.messageId
136149
}-${selectedIndex}.${extension}`,
137150
fromUrl: photo.uri,
138151
});
152+
setSavingInProgress(false);
139153
// `image/jpeg` is added for the case where the mime_type isn't available for a file/image
140154
await NativeHandlers.shareImage({ type: photo.mime_type || 'image/jpeg', url: localFile });
141155
await NativeHandlers.deleteFile({ uri: localFile });
142156
} catch (error) {
157+
setSavingInProgress(false);
143158
console.log(error);
144159
}
145-
setShareMenuOpen(false);
160+
shareIsInProgressRef.current = false;
146161
};
147162

148163
return (
@@ -168,12 +183,12 @@ export const ImageGalleryFooterWithContext = (props: ImageGalleryFooterPropsWith
168183
) : null}
169184
<View style={[styles.innerContainer, { backgroundColor: white }, innerContainer]}>
170185
{leftElement ? (
171-
leftElement({ openGridView, photo, share, shareMenuOpen })
186+
leftElement({ openGridView, photo, share, shareMenuOpen: savingInProgress })
172187
) : (
173-
<ShareButton share={share} ShareIcon={ShareIcon} shareMenuOpen={shareMenuOpen} />
188+
<ShareButton savingInProgress={savingInProgress} share={share} ShareIcon={ShareIcon} />
174189
)}
175190
{centerElement ? (
176-
centerElement({ openGridView, photo, share, shareMenuOpen })
191+
centerElement({ openGridView, photo, share, shareMenuOpen: savingInProgress })
177192
) : (
178193
<View style={[styles.centerContainer, centerContainer]}>
179194
<Text style={[styles.imageCountText, { color: black }, imageCountText]}>
@@ -185,7 +200,7 @@ export const ImageGalleryFooterWithContext = (props: ImageGalleryFooterPropsWith
185200
</View>
186201
)}
187202
{rightElement ? (
188-
rightElement({ openGridView, photo, share, shareMenuOpen })
203+
rightElement({ openGridView, photo, share, shareMenuOpen: savingInProgress })
189204
) : (
190205
<TouchableOpacity onPress={openGridView}>
191206
<View style={[styles.rightContainer, rightContainer]}>
@@ -201,11 +216,11 @@ export const ImageGalleryFooterWithContext = (props: ImageGalleryFooterPropsWith
201216

202217
type ShareButtonProps = {
203218
share: () => Promise<void>;
204-
shareMenuOpen: boolean;
219+
savingInProgress: boolean;
205220
ShareIcon?: React.ReactElement;
206221
};
207222

208-
const ShareButton = ({ share, ShareIcon, shareMenuOpen }: ShareButtonProps) => {
223+
const ShareButton = ({ share, ShareIcon, savingInProgress }: ShareButtonProps) => {
209224
const {
210225
theme: {
211226
colors: { black },
@@ -221,9 +236,15 @@ const ShareButton = ({ share, ShareIcon, shareMenuOpen }: ShareButtonProps) => {
221236
}
222237

223238
return (
224-
<TouchableOpacity accessibilityLabel='Share Button' disabled={shareMenuOpen} onPress={share}>
239+
<TouchableOpacity accessibilityLabel='Share Button' onPress={share}>
225240
<View style={[styles.leftContainer, leftContainer]}>
226-
{ShareIcon ? ShareIcon : <ShareIconDefault pathFill={black} />}
241+
{savingInProgress ? (
242+
<ActivityIndicator size='small' />
243+
) : ShareIcon ? (
244+
ShareIcon
245+
) : (
246+
<ShareIconDefault pathFill={black} />
247+
)}
227248
</View>
228249
</TouchableOpacity>
229250
);
@@ -307,7 +328,7 @@ const styles = StyleSheet.create({
307328
marginRight: 8,
308329
},
309330
wrapper: {
310-
bottom: 0,
331+
bottom: 30,
311332
left: 0,
312333
position: 'absolute',
313334
right: 0,

0 commit comments

Comments
 (0)