# Media ## Camera - Hide navigation headers when there's a full screen camera - Ensure to flip the camera with `mirror` to emulate social apps - Use liquid glass buttons on cameras - Icons: `arrow.triangle.2.circlepath` (flip), `photo` (gallery), `bolt` (flash) - Eagerly request camera permission - Lazily request media library permission ```tsx import React, { useRef, useState } from "react"; import { View, TouchableOpacity, Text, Alert } from "react-native"; import { CameraView, CameraType, useCameraPermissions } from "expo-camera"; import * as MediaLibrary from "expo-media-library"; import * as ImagePicker from "expo-image-picker"; import * as Haptics from "expo-haptics"; import { SymbolView } from "expo-symbols"; import { PlatformColor } from "react-native"; import { GlassView } from "expo-glass-effect"; import { useSafeAreaInsets } from "react-native-safe-area-context"; function Camera({ onPicture }: { onPicture: (uri: string) => Promise }) { const [permission, requestPermission] = useCameraPermissions(); const cameraRef = useRef(null); const [type, setType] = useState("back"); const { bottom } = useSafeAreaInsets(); if (!permission?.granted) { return ( Camera access is required Grant Permission ); } const takePhoto = async () => { await Haptics.selectionAsync(); if (!cameraRef.current) return; const photo = await cameraRef.current.takePictureAsync({ quality: 0.8 }); await onPicture(photo.uri); }; const selectPhoto = async () => { await Haptics.selectionAsync(); const result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: "images", allowsEditing: false, quality: 0.8, }); if (!result.canceled && result.assets?.[0]) { await onPicture(result.assets[0].uri); } }; return ( setType(t => t === "back" ? "front" : "back")} icon="arrow.triangle.2.circlepath" /> ); } ``` ## Audio Playback Use `expo-audio` not `expo-av`: ```tsx import { useAudioPlayer } from 'expo-audio'; const player = useAudioPlayer({ uri: 'https://stream.nightride.fm/rektory.mp3' });