191 lines
4.7 KiB
Plaintext
191 lines
4.7 KiB
Plaintext
// COMPONENT : Jika ingin uoload gambar dan video gunakan component ini
|
|
|
|
import {
|
|
ButtonCustom,
|
|
Spacing,
|
|
StackCustom,
|
|
ViewWrapper
|
|
} from "@/components";
|
|
import AntDesign from "@expo/vector-icons/AntDesign";
|
|
import Feather from "@expo/vector-icons/Feather";
|
|
import FontAwesome6 from "@expo/vector-icons/FontAwesome6";
|
|
import {
|
|
CameraMode,
|
|
CameraType,
|
|
CameraView,
|
|
useCameraPermissions,
|
|
} from "expo-camera";
|
|
import { Image } from "expo-image";
|
|
import { router } from "expo-router";
|
|
import { useRef, useState } from "react";
|
|
import { Button, Pressable, StyleSheet, Text, View } from "react-native";
|
|
|
|
export default function TakePictureProfile2() {
|
|
const [permission, requestPermission] = useCameraPermissions();
|
|
const ref = useRef<CameraView>(null);
|
|
const [uri, setUri] = useState<string | null>(null);
|
|
const [mode, setMode] = useState<CameraMode>("picture");
|
|
const [facing, setFacing] = useState<CameraType>("back");
|
|
const [recording, setRecording] = useState(false);
|
|
|
|
if (!permission?.granted) {
|
|
return (
|
|
<View style={styles.container}>
|
|
<Text style={{ textAlign: "center" }}>
|
|
We need your permission to use the camera
|
|
</Text>
|
|
<Button onPress={requestPermission} title="Grant permission" />
|
|
</View>
|
|
);
|
|
}
|
|
|
|
const takePicture = async () => {
|
|
const photo = await ref.current?.takePictureAsync();
|
|
setUri(photo?.uri || null);
|
|
};
|
|
|
|
const recordVideo = async () => {
|
|
if (recording) {
|
|
setRecording(false);
|
|
ref.current?.stopRecording();
|
|
return;
|
|
}
|
|
setRecording(true);
|
|
const video = await ref.current?.recordAsync();
|
|
console.log({ video });
|
|
};
|
|
|
|
const toggleMode = () => {
|
|
setMode((prev) => (prev === "picture" ? "video" : "picture"));
|
|
};
|
|
|
|
const toggleFacing = () => {
|
|
setFacing((prev) => (prev === "back" ? "front" : "back"));
|
|
};
|
|
|
|
const renderPicture = () => {
|
|
console.log("renderPicture", uri);
|
|
return (
|
|
<View>
|
|
<Image
|
|
source={uri ? uri : null}
|
|
contentFit="contain"
|
|
style={{ width: 340, aspectRatio: 1 }}
|
|
/>
|
|
<Spacing />
|
|
|
|
<StackCustom>
|
|
<ButtonCustom onPress={() => setUri(null)} title="Foto ulang" />
|
|
<ButtonCustom
|
|
onPress={() => {
|
|
console.log("Update foto");
|
|
router.back();
|
|
}}
|
|
title="Update Foto"
|
|
/>
|
|
</StackCustom>
|
|
</View>
|
|
);
|
|
};
|
|
|
|
const renderCameraUI = () => {
|
|
return (
|
|
<View style={styles.cameraOverlay}>
|
|
<View style={styles.shutterContainer}>
|
|
<Pressable onPress={toggleMode}>
|
|
{mode === "picture" ? (
|
|
<AntDesign name="picture" size={32} color="white" />
|
|
) : (
|
|
<Feather name="video" size={32} color="white" />
|
|
)}
|
|
</Pressable>
|
|
|
|
<Pressable onPress={mode === "picture" ? takePicture : recordVideo}>
|
|
{({ pressed }) => (
|
|
<View
|
|
style={[
|
|
styles.shutterBtn,
|
|
{
|
|
opacity: pressed ? 0.5 : 1,
|
|
},
|
|
]}
|
|
>
|
|
<View
|
|
style={[
|
|
styles.shutterBtnInner,
|
|
{
|
|
backgroundColor: mode === "picture" ? "white" : "red",
|
|
},
|
|
]}
|
|
/>
|
|
</View>
|
|
)}
|
|
</Pressable>
|
|
|
|
<Pressable onPress={toggleFacing}>
|
|
<FontAwesome6 name="rotate-left" size={32} color="white" />
|
|
</Pressable>
|
|
</View>
|
|
</View>
|
|
);
|
|
};
|
|
|
|
return (
|
|
<>
|
|
{uri ? (
|
|
<ViewWrapper>
|
|
<View style={styles.container}>{renderPicture()}</View>
|
|
</ViewWrapper>
|
|
) : (
|
|
<>
|
|
<CameraView
|
|
style={styles.camera}
|
|
ref={ref}
|
|
mode={mode}
|
|
facing={facing}
|
|
mute={false}
|
|
responsiveOrientationWhenOrientationLocked
|
|
/>
|
|
{renderCameraUI()}
|
|
</>
|
|
)}
|
|
</>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
justifyContent: "center",
|
|
alignItems: "center",
|
|
},
|
|
camera: {
|
|
flex: 1,
|
|
width: "100%",
|
|
},
|
|
cameraOverlay: {
|
|
...StyleSheet.absoluteFillObject,
|
|
justifyContent: "flex-end",
|
|
padding: 44,
|
|
},
|
|
shutterContainer: {
|
|
flexDirection: "row",
|
|
justifyContent: "space-between",
|
|
alignItems: "center",
|
|
},
|
|
shutterBtn: {
|
|
backgroundColor: "transparent",
|
|
borderWidth: 5,
|
|
borderColor: "white",
|
|
width: 85,
|
|
height: 85,
|
|
borderRadius: 45,
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
},
|
|
shutterBtnInner: {
|
|
width: 70,
|
|
height: 70,
|
|
borderRadius: 50,
|
|
},
|
|
});
|