@@ -5,23 +5,24 @@ import { TouchableWithoutFeedback } from "react-native-gesture-handler";
55import Animated , { Easing , runOnJS , interpolate , interpolateColor , useAnimatedStyle , useSharedValue , withTiming , LinearTransition , FadeInLeft } from "react-native-reanimated" ;
66import { 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" ;
99import { BlurView } from "expo-blur" ;
1010import { Image } from "expo-image" ;
1111import * 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
1414import { IS_ANDROID } from "@/constants" ;
1515import { useColors } from "@/hooks/use-colors" ;
1616import { useCreateShots } from "@/hooks/use-create-shots" ;
1717import { useIsLogin } from "@/hooks/use-is-login" ;
1818import { useRootNavigation } from "@/hooks/use-navigation" ;
19+ import { usePickImages } from "@/hooks/use-pick-images" ;
1920import type { Photo } from "@/pages/TakePhoto" ;
2021
2122import { XTouch } from "./XTouch" ;
2223
2324export 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