Skip to content

Commit e98ed81

Browse files
committed
feat: Support to pick images from album directly in the CreateShortsButton.
1 parent 933f3cb commit e98ed81

2 files changed

Lines changed: 81 additions & 39 deletions

File tree

.changeset/itchy-snakes-clap.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+
Support to pick images from album directly in the "CreateShortsButton".

src/components/CreateShortsButton.tsx

Lines changed: 76 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,24 @@ import { 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 { Maximize2, Plus, X } from "@tamagui/lucide-icons";
8+
import { Album, 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";
12-
import { Button, ScrollView, Stack, View, XStack, YStack, useWindowDimensions } from "tamagui";
12+
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";
1616
import { useCreateShots } from "@/hooks/use-create-shots";
1717
import { useIsLogin } from "@/hooks/use-is-login";
1818
import { useRootNavigation } from "@/hooks/use-navigation";
19+
import { usePickImages } from "@/hooks/use-pick-images";
1920
import type { Photo } from "@/pages/TakePhoto";
2021

2122
import { XTouch } from "./XTouch";
2223

2324
export const CreateShortsButton: FC = () => {
24-
const { createShots } = useCreateShots();
25+
const { pickImages } = usePickImages();
2526
const navigation = useRootNavigation();
2627
const isLogin = useIsLogin();
2728
const { width } = useWindowDimensions();
@@ -137,6 +138,7 @@ export const CreateShortsButton: FC = () => {
137138
const isOpenAnimValue = useSharedValue(0);
138139
const targetWidth = width * 0.96;
139140
const targetHeight = 300;
141+
const photoSize = targetWidth / 4 * 0.9;
140142

141143
const containerAnimStyle = useAnimatedStyle(() => {
142144
const animValue = Math.max(0, isOpenAnimValue.value);
@@ -176,6 +178,22 @@ export const CreateShortsButton: FC = () => {
176178
});
177179
};
178180

181+
const selectImageFromAlbum = () => {
182+
pickImages().then((result) => {
183+
if (result) {
184+
setPhotos(photos => [
185+
...result,
186+
...photos,
187+
]);
188+
189+
setSelectedPhotos(selectedPhotos => [
190+
...result,
191+
...selectedPhotos,
192+
]);
193+
}
194+
});
195+
};
196+
179197
return (
180198
<Stack width={buttonSize} height={buttonSize} marginHorizontal={15} overflow="visible" zIndex={999}>
181199
<Animated.View
@@ -195,9 +213,18 @@ export const CreateShortsButton: FC = () => {
195213
<XStack flex={1} >
196214
<ScrollView ref={scrollViewRef} flex={1}>
197215
<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>
198226
{
199227
mediaPermissionResponse?.granted && photos.map((item) => {
200-
const photoSize = targetWidth / 4 * 0.9;
201228
const isSelected = selectedPhotos.some(photo => photo.uri === item.uri);
202229

203230
return (
@@ -241,42 +268,52 @@ export const CreateShortsButton: FC = () => {
241268
<YStack flex={1} gap={8} borderRadius={10}>
242269
<Stack flex={1} borderRadius={10} overflow="hidden">
243270
{hasPermission && (
244-
<Stack flex={1}>
245-
{device && (
246-
<Camera
247-
ref={cameraRef}
248-
device={device}
249-
isActive={expanded}
250-
photo={true}
251-
video={false}
252-
audio={false}
253-
style={{ flex: 1 }}
254-
/>
255-
)}
256-
<XTouch onPress={handleOpenCamera} enableHaptics containerStyle={{
257-
position: "absolute",
258-
right: 12,
259-
top: 12,
260-
}}>
261-
<Maximize2 color="white" size={25}/>
262-
</XTouch>
263-
264-
<XTouch onPress={takePhoto} enableHaptics containerStyle={{
265-
position: "absolute",
266-
left: "50%",
267-
bottom: 12,
268-
transform: [{ translateX: -15 }],
269-
}}>
270-
<Stack borderRadius={50} borderWidth={1} borderColor={"white"} width={30} height={30} alignItems="center" justifyContent="center">
271-
<Stack
272-
borderRadius={50}
273-
backgroundColor={"white"}
274-
width={25}
275-
height={25}
276-
/>
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>
277308
</Stack>
278-
</XTouch>
279-
</Stack>
309+
)
310+
: (
311+
<View flex={1} alignItems="center" justifyContent="center">
312+
<Text textAlign="center" fontSize={"$1"}>
313+
Please use physical device, this feature is not supported on simulator.
314+
</Text>
315+
</View>
316+
)
280317
)}
281318
</Stack>
282319
<XStack alignItems="center" justifyContent="space-between" width={"100%"} gap={8}>

0 commit comments

Comments
 (0)