Skip to content

Commit fbe9bf2

Browse files
committed
fix: Addressed the swipe issue in CreateShortsButton on Android
1 parent e98ed81 commit fbe9bf2

2 files changed

Lines changed: 164 additions & 143 deletions

File tree

.changeset/long-eels-shout.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"xlog": patch
3+
---
4+
5+
Addressed the swipe issue in "CreateShortsButton" on Android.

src/components/CreateShortsButton.tsx

Lines changed: 159 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
import { useState, type FC, useRef } from "react";
22
import type { ScrollView as RNScrollVIew } from "react-native";
3-
import { InteractionManager, StyleSheet } from "react-native";
4-
import { TouchableWithoutFeedback } from "react-native-gesture-handler";
3+
import { StyleSheet } from "react-native";
4+
import { PanGestureHandler, TouchableWithoutFeedback } from "react-native-gesture-handler";
55
import Animated, { Easing, runOnJS, interpolate, interpolateColor, useAnimatedStyle, useSharedValue, withTiming, LinearTransition, FadeInLeft } from "react-native-reanimated";
66
import { Camera, useCameraPermission, useCameraDevice } from "react-native-vision-camera";
77

8-
import { Album, Image as ImageIcon, Maximize2, Plus, X } from "@tamagui/lucide-icons";
8+
import { Image as ImageIcon, Maximize2, Plus, X } from "@tamagui/lucide-icons";
99
import { BlurView } from "expo-blur";
1010
import { Image } from "expo-image";
1111
import * as MediaLibrary from "expo-media-library";
1212
import { Button, ScrollView, Stack, Text, View, XStack, YStack, useWindowDimensions } from "tamagui";
1313

1414
import { IS_ANDROID } from "@/constants";
1515
import { useColors } from "@/hooks/use-colors";
16-
import { useCreateShots } from "@/hooks/use-create-shots";
1716
import { useIsLogin } from "@/hooks/use-is-login";
1817
import { useRootNavigation } from "@/hooks/use-navigation";
1918
import { usePickImages } from "@/hooks/use-pick-images";
@@ -195,150 +194,167 @@ export const CreateShortsButton: FC = () => {
195194
};
196195

197196
return (
198-
<Stack width={buttonSize} height={buttonSize} marginHorizontal={15} overflow="visible" zIndex={999}>
199-
<Animated.View
200-
style={[{
201-
borderRadius: 10,
202-
alignSelf: "center",
203-
position: "absolute",
204-
alignItems: "center",
205-
justifyContent: "center",
206-
overflow: "hidden",
207-
flex: 1,
208-
}, containerAnimStyle]}
209-
>
210-
<Animated.View style={[actionsContainerAnimStyle, { width: targetWidth, height: targetHeight, position: "absolute", borderRadius: 10, padding: 12 }]}>
211-
<BlurView tint="dark" intensity={IS_ANDROID ? 10 : 30} style={StyleSheet.absoluteFillObject}/>
212-
<XStack flex={1} gap={6}>
213-
<XStack flex={1} >
214-
<ScrollView ref={scrollViewRef} flex={1}>
215-
<XStack flexWrap="wrap" justifyContent="space-between">
216-
<Animated.View layout={LinearTransition.duration(150)} entering={FadeInLeft.duration(150)}>
217-
<TouchableWithoutFeedback
218-
style={{ marginBottom: 4 }}
219-
onPress={selectImageFromAlbum}
220-
>
221-
<View width={photoSize} height={photoSize} backgroundColor={"$primary"} borderRadius={10} alignItems="center" justifyContent="center">
222-
<ImageIcon size={"$3"}/>
223-
</View>
224-
</TouchableWithoutFeedback>
225-
</Animated.View>
226-
{
227-
mediaPermissionResponse?.granted && photos.map((item) => {
228-
const isSelected = selectedPhotos.some(photo => photo.uri === item.uri);
229-
230-
return (
231-
<Animated.View key={item.uri} layout={LinearTransition.duration(150)} entering={FadeInLeft.duration(150)}>
232-
<TouchableWithoutFeedback
233-
style={{ marginBottom: 4 }}
234-
onPress={() => {
235-
if (isSelected) {
236-
setSelectedPhotos(selectedPhotos.filter(({ uri }) => uri !== item.uri));
237-
return;
238-
}
239-
240-
setSelectedPhotos([...selectedPhotos, item]);
241-
}}
242-
>
243-
<View width={photoSize} height={photoSize}>
244-
<Image source={{ uri: item.uri }} style={{ width: "100%", height: "100%", borderRadius: 10 }}/>
197+
<PanGestureHandler>
198+
<Stack width={buttonSize} height={buttonSize} marginHorizontal={15} overflow="visible" zIndex={999}>
199+
<Animated.View
200+
style={[{
201+
borderRadius: 10,
202+
alignSelf: "center",
203+
position: "absolute",
204+
alignItems: "center",
205+
justifyContent: "center",
206+
overflow: "hidden",
207+
flex: 1,
208+
}, containerAnimStyle]}
209+
>
210+
<Animated.View
211+
style={[
212+
actionsContainerAnimStyle, {
213+
width: targetWidth,
214+
height: targetHeight,
215+
position: "absolute",
216+
borderRadius: 10,
217+
padding: 12,
218+
}]
219+
}
220+
>
221+
<BlurView
222+
tint="dark"
223+
intensity={30}
224+
experimentalBlurMethod="dimezisBlurView"
225+
style={StyleSheet.absoluteFillObject}
226+
/>
227+
<XStack flex={1} gap={6}>
228+
<XStack flex={1} >
229+
<ScrollView ref={scrollViewRef} flex={1}>
230+
<XStack flexWrap="wrap" justifyContent="space-between">
231+
<Animated.View layout={LinearTransition.duration(150)} entering={FadeInLeft.duration(150)}>
232+
<TouchableWithoutFeedback
233+
style={{ marginBottom: 4 }}
234+
onPress={selectImageFromAlbum}
235+
>
236+
<View width={photoSize} height={photoSize} backgroundColor={"$primary"} borderRadius={10} alignItems="center" justifyContent="center">
237+
<ImageIcon size={"$3"}/>
238+
</View>
239+
</TouchableWithoutFeedback>
240+
</Animated.View>
241+
{
242+
mediaPermissionResponse?.granted && photos.map((item) => {
243+
const isSelected = selectedPhotos.some(photo => photo.uri === item.uri);
244+
245+
return (
246+
<Animated.View key={item.uri} layout={LinearTransition.duration(150)} entering={FadeInLeft.duration(150)}>
247+
<TouchableWithoutFeedback
248+
style={{ marginBottom: 4 }}
249+
onPress={() => {
250+
if (isSelected) {
251+
setSelectedPhotos(selectedPhotos.filter(({ uri }) => uri !== item.uri));
252+
return;
253+
}
254+
255+
setSelectedPhotos([...selectedPhotos, item]);
256+
}}
257+
>
258+
<View width={photoSize} height={photoSize}>
259+
<Image source={{ uri: item.uri }} style={{ width: "100%", height: "100%", borderRadius: 10 }}/>
260+
<Stack
261+
position="absolute"
262+
right="$2"
263+
bottom="$2"
264+
width={15}
265+
height={15}
266+
borderRadius={50}
267+
alignItems="center"
268+
justifyContent="center"
269+
borderWidth={1}
270+
borderColor={"white"}
271+
>
272+
{isSelected && <Stack width={10} height={10} borderRadius={50} backgroundColor={"$primary"}/>}
273+
</Stack>
274+
</View>
275+
</TouchableWithoutFeedback>
276+
</Animated.View>
277+
);
278+
})
279+
}
280+
</XStack>
281+
</ScrollView>
282+
</XStack>
283+
<YStack flex={1} gap={8} borderRadius={10}>
284+
<Stack flex={1} borderRadius={10} overflow="hidden">
285+
{hasPermission && (
286+
device
287+
? (
288+
<Stack flex={1}>
289+
{device && (
290+
<Camera
291+
ref={cameraRef}
292+
device={device}
293+
isActive={expanded}
294+
photo={true}
295+
video={false}
296+
audio={false}
297+
style={{ flex: 1 }}
298+
/>
299+
)}
300+
<XTouch onPress={handleOpenCamera} enableHaptics containerStyle={{
301+
position: "absolute",
302+
right: 12,
303+
top: 12,
304+
}}>
305+
<Maximize2 color="white" size={25}/>
306+
</XTouch>
307+
308+
<XTouch onPress={takePhoto} enableHaptics containerStyle={{
309+
position: "absolute",
310+
left: "50%",
311+
bottom: 12,
312+
transform: [{ translateX: -15 }],
313+
}}>
314+
<Stack borderRadius={50} borderWidth={1} borderColor={"white"} width={30} height={30} alignItems="center" justifyContent="center">
245315
<Stack
246-
position="absolute"
247-
right="$2"
248-
bottom="$2"
249-
width={15}
250-
height={15}
251316
borderRadius={50}
252-
alignItems="center"
253-
justifyContent="center"
254-
borderWidth={1}
255-
borderColor={"white"}
256-
>
257-
{isSelected && <Stack width={10} height={10} borderRadius={50} backgroundColor={"$primary"}/>}
258-
</Stack>
259-
</View>
260-
</TouchableWithoutFeedback>
261-
</Animated.View>
262-
);
263-
})
264-
}
265-
</XStack>
266-
</ScrollView>
267-
</XStack>
268-
<YStack flex={1} gap={8} borderRadius={10}>
269-
<Stack flex={1} borderRadius={10} overflow="hidden">
270-
{hasPermission && (
271-
device
272-
? (
273-
<Stack flex={1}>
274-
{device && (
275-
<Camera
276-
ref={cameraRef}
277-
device={device}
278-
isActive={expanded}
279-
photo={true}
280-
video={false}
281-
audio={false}
282-
style={{ flex: 1 }}
283-
/>
284-
)}
285-
<XTouch onPress={handleOpenCamera} enableHaptics containerStyle={{
286-
position: "absolute",
287-
right: 12,
288-
top: 12,
289-
}}>
290-
<Maximize2 color="white" size={25}/>
291-
</XTouch>
292-
293-
<XTouch onPress={takePhoto} enableHaptics containerStyle={{
294-
position: "absolute",
295-
left: "50%",
296-
bottom: 12,
297-
transform: [{ translateX: -15 }],
298-
}}>
299-
<Stack borderRadius={50} borderWidth={1} borderColor={"white"} width={30} height={30} alignItems="center" justifyContent="center">
300-
<Stack
301-
borderRadius={50}
302-
backgroundColor={"white"}
303-
width={25}
304-
height={25}
305-
/>
306-
</Stack>
307-
</XTouch>
308-
</Stack>
309-
)
310-
: (
311-
<View flex={1} alignItems="center" justifyContent="center">
312-
<Text textAlign="center" fontSize={"$1"}>
317+
backgroundColor={"white"}
318+
width={25}
319+
height={25}
320+
/>
321+
</Stack>
322+
</XTouch>
323+
</Stack>
324+
)
325+
: (
326+
<View flex={1} alignItems="center" justifyContent="center">
327+
<Text textAlign="center" fontSize={"$1"}>
313328
Please use physical device, this feature is not supported on simulator.
314-
</Text>
315-
</View>
316-
)
317-
)}
318-
</Stack>
319-
<XStack alignItems="center" justifyContent="space-between" width={"100%"} gap={8}>
320-
<Button
321-
flex={1}
322-
disabled={selectedPhotos.length === 0}
323-
backgroundColor={selectedPhotos.length === 0 ? "$backgroundHover" : "$primary"}
324-
onPress={onHandleNext}
325-
>
329+
</Text>
330+
</View>
331+
)
332+
)}
333+
</Stack>
334+
<XStack alignItems="center" justifyContent="space-between" width={"100%"} gap={8}>
335+
<Button
336+
flex={1}
337+
disabled={selectedPhotos.length === 0}
338+
backgroundColor={selectedPhotos.length === 0 ? "$backgroundHover" : "$primary"}
339+
onPress={onHandleNext}
340+
>
326341
Next
327-
</Button>
328-
<Button onPress={toggle} backgroundColor={"$backgroundHover"} icon={<X size={22}/>} padding={12}/>
329-
</XStack>
330-
</YStack>
331-
</XStack>
332-
</Animated.View>
342+
</Button>
343+
<Button onPress={toggle} backgroundColor={"$backgroundHover"} icon={<X size={22}/>} padding={12}/>
344+
</XStack>
345+
</YStack>
346+
</XStack>
347+
</Animated.View>
333348

334-
<Animated.View style={[buttonAnimStyle, { flex: 1, justifyContent: "center", alignItems: "center" }]}>
335-
<TouchableWithoutFeedback onPress={handleOnPress}>
336-
<Stack flex={1} alignItems="center" justifyContent="center">
337-
<Plus color="white"/>
338-
</Stack>
339-
</TouchableWithoutFeedback>
349+
<Animated.View style={[buttonAnimStyle, { flex: 1, justifyContent: "center", alignItems: "center" }]}>
350+
<TouchableWithoutFeedback onPress={handleOnPress}>
351+
<Stack flex={1} alignItems="center" justifyContent="center">
352+
<Plus color="white"/>
353+
</Stack>
354+
</TouchableWithoutFeedback>
355+
</Animated.View>
340356
</Animated.View>
341-
</Animated.View>
342-
</Stack>
357+
</Stack>
358+
</PanGestureHandler>
343359
);
344360
};

0 commit comments

Comments
 (0)