Finish adding expo
This commit is contained in:
@@ -16,7 +16,7 @@ export function init(store: RootStoreModel) {
|
||||
// this method is a copy of segment's own lifecycle event tracking
|
||||
// we handle it manually to ensure that it never fires while the app is backgrounded
|
||||
// -prf
|
||||
segmentClient.onContextLoaded(() => {
|
||||
segmentClient.isReady.onChange(() => {
|
||||
if (AppState.currentState !== 'active') {
|
||||
store.log.debug('Prevented a metrics ping while the app was backgrounded')
|
||||
return
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import {Alert} from 'react-native'
|
||||
import {Camera} from 'expo-camera'
|
||||
import * as MediaLibrary from 'expo-media-library'
|
||||
import {Linking} from 'react-native'
|
||||
|
||||
const openSettings = () => {
|
||||
Linking.openURL('app-settings:')
|
||||
}
|
||||
|
||||
const openPermissionAlert = (perm: string) => {
|
||||
Alert.alert(
|
||||
'Permission needed',
|
||||
`Bluesky does not have permission to access your ${perm}.`,
|
||||
[
|
||||
{
|
||||
text: 'Cancel',
|
||||
style: 'cancel',
|
||||
},
|
||||
{text: 'Open Settings', onPress: () => openSettings()},
|
||||
],
|
||||
)
|
||||
}
|
||||
|
||||
export function usePhotoLibraryPermission() {
|
||||
const [mediaLibraryPermissions] = MediaLibrary.usePermissions()
|
||||
const requestPhotoAccessIfNeeded = async () => {
|
||||
if (mediaLibraryPermissions?.status === 'granted') {
|
||||
return true
|
||||
} else {
|
||||
openPermissionAlert('photo library')
|
||||
return false
|
||||
}
|
||||
}
|
||||
return {requestPhotoAccessIfNeeded}
|
||||
}
|
||||
|
||||
export function useCameraPermission() {
|
||||
const [cameraPermissionStatus] = Camera.useCameraPermissions()
|
||||
|
||||
const requestCameraAccessIfNeeded = async () => {
|
||||
if (cameraPermissionStatus.granted) {
|
||||
return true
|
||||
} else {
|
||||
openPermissionAlert('camera')
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return {requestCameraAccessIfNeeded}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
import {Alert} from 'react-native'
|
||||
import {
|
||||
check,
|
||||
openSettings,
|
||||
Permission,
|
||||
PermissionStatus,
|
||||
PERMISSIONS,
|
||||
RESULTS,
|
||||
} from 'react-native-permissions'
|
||||
|
||||
export const PHOTO_LIBRARY = PERMISSIONS.IOS.PHOTO_LIBRARY
|
||||
export const CAMERA = PERMISSIONS.IOS.CAMERA
|
||||
|
||||
/**
|
||||
* Returns `true` if the user has granted permission or hasn't made
|
||||
* a decision yet. Returns `false` if unavailable or not granted.
|
||||
*/
|
||||
export async function hasAccess(perm: Permission): Promise<boolean> {
|
||||
const status = await check(perm)
|
||||
return isntANo(status)
|
||||
}
|
||||
|
||||
export async function requestAccessIfNeeded(
|
||||
perm: Permission,
|
||||
): Promise<boolean> {
|
||||
if (await hasAccess(perm)) {
|
||||
return true
|
||||
}
|
||||
let permDescription
|
||||
if (perm === PHOTO_LIBRARY) {
|
||||
permDescription = 'photo library'
|
||||
} else if (perm === CAMERA) {
|
||||
permDescription = 'camera'
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
Alert.alert(
|
||||
'Permission needed',
|
||||
`Bluesky does not have permission to access your ${permDescription}.`,
|
||||
[
|
||||
{
|
||||
text: 'Cancel',
|
||||
style: 'cancel',
|
||||
},
|
||||
{text: 'Open Settings', onPress: () => openSettings()},
|
||||
],
|
||||
)
|
||||
return false
|
||||
}
|
||||
|
||||
export async function requestPhotoAccessIfNeeded() {
|
||||
return requestAccessIfNeeded(PHOTO_LIBRARY)
|
||||
}
|
||||
|
||||
export async function requestCameraAccessIfNeeded() {
|
||||
return requestAccessIfNeeded(CAMERA)
|
||||
}
|
||||
|
||||
function isntANo(status: PermissionStatus): boolean {
|
||||
return status !== RESULTS.UNAVAILABLE && status !== RESULTS.BLOCKED
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
At the moment, Web doesn't have any equivalence for these.
|
||||
*/
|
||||
|
||||
export const PHOTO_LIBRARY = ''
|
||||
export const CAMERA = ''
|
||||
|
||||
export async function hasAccess(_perm: any): Promise<boolean> {
|
||||
return true
|
||||
}
|
||||
|
||||
export async function requestAccessIfNeeded(_perm: any): Promise<boolean> {
|
||||
return true
|
||||
}
|
||||
|
||||
export async function requestPhotoAccessIfNeeded() {
|
||||
return requestAccessIfNeeded(PHOTO_LIBRARY)
|
||||
}
|
||||
|
||||
export async function requestCameraAccessIfNeeded() {
|
||||
return requestAccessIfNeeded(CAMERA)
|
||||
}
|
||||
@@ -18,9 +18,9 @@ import {compressIfNeeded} from 'lib/media/manip'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {useStores} from 'state/index'
|
||||
import {
|
||||
requestPhotoAccessIfNeeded,
|
||||
requestCameraAccessIfNeeded,
|
||||
} from 'lib/permissions'
|
||||
usePhotoLibraryPermission,
|
||||
useCameraPermission,
|
||||
} from 'lib/hooks/usePermissions'
|
||||
import {
|
||||
POST_IMG_MAX_WIDTH,
|
||||
POST_IMG_MAX_HEIGHT,
|
||||
@@ -38,6 +38,8 @@ export const PhotoCarouselPicker = ({
|
||||
const pal = usePalette('default')
|
||||
const store = useStores()
|
||||
const [isSetup, setIsSetup] = React.useState<boolean>(false)
|
||||
const {requestCameraAccessIfNeeded} = useCameraPermission()
|
||||
const {requestPhotoAccessIfNeeded} = usePhotoLibraryPermission()
|
||||
|
||||
const localPhotos = React.useMemo<UserLocalPhotosModel>(
|
||||
() => new UserLocalPhotosModel(store),
|
||||
@@ -68,7 +70,7 @@ export const PhotoCarouselPicker = ({
|
||||
// ignore
|
||||
store.log.warn('Error using camera', err)
|
||||
}
|
||||
}, [store, selectedPhotos, onSelectPhotos])
|
||||
}, [store, selectedPhotos, onSelectPhotos, requestCameraAccessIfNeeded])
|
||||
|
||||
const handleSelectPhoto = useCallback(
|
||||
async (item: PhotoIdentifier) => {
|
||||
@@ -116,7 +118,7 @@ export const PhotoCarouselPicker = ({
|
||||
)
|
||||
}
|
||||
onSelectPhotos([...selectedPhotos, ...result])
|
||||
}, [track, store, selectedPhotos, onSelectPhotos])
|
||||
}, [track, store, selectedPhotos, onSelectPhotos, requestPhotoAccessIfNeeded])
|
||||
|
||||
return (
|
||||
<ScrollView
|
||||
|
||||
@@ -11,9 +11,9 @@ import {
|
||||
PickedMedia,
|
||||
} from '../../../lib/media/picker'
|
||||
import {
|
||||
requestPhotoAccessIfNeeded,
|
||||
requestCameraAccessIfNeeded,
|
||||
} from 'lib/permissions'
|
||||
usePhotoLibraryPermission,
|
||||
useCameraPermission,
|
||||
} from 'lib/hooks/usePermissions'
|
||||
import {useStores} from 'state/index'
|
||||
import {colors, gradients} from 'lib/styles'
|
||||
import {DropdownButton} from './forms/DropdownButton'
|
||||
@@ -36,6 +36,8 @@ export function UserAvatar({
|
||||
const store = useStores()
|
||||
const pal = usePalette('default')
|
||||
const initials = getInitials(displayName || handle)
|
||||
const {requestCameraAccessIfNeeded} = useCameraPermission()
|
||||
const {requestPhotoAccessIfNeeded} = usePhotoLibraryPermission()
|
||||
|
||||
const renderSvg = (svgSize: number, svgInitials: string) => (
|
||||
<Svg width={svgSize} height={svgSize} viewBox="0 0 100 100">
|
||||
|
||||
@@ -13,9 +13,9 @@ import {
|
||||
} from '../../../lib/media/picker'
|
||||
import {useStores} from 'state/index'
|
||||
import {
|
||||
requestPhotoAccessIfNeeded,
|
||||
requestCameraAccessIfNeeded,
|
||||
} from 'lib/permissions'
|
||||
usePhotoLibraryPermission,
|
||||
useCameraPermission,
|
||||
} from 'lib/hooks/usePermissions'
|
||||
import {DropdownButton} from './forms/DropdownButton'
|
||||
import {usePalette} from 'lib/hooks/usePalette'
|
||||
import {isWeb} from 'platform/detection'
|
||||
@@ -29,6 +29,9 @@ export function UserBanner({
|
||||
}) {
|
||||
const store = useStores()
|
||||
const pal = usePalette('default')
|
||||
const {requestCameraAccessIfNeeded} = useCameraPermission()
|
||||
const {requestPhotoAccessIfNeeded} = usePhotoLibraryPermission()
|
||||
|
||||
const dropdownItems = [
|
||||
!isWeb && {
|
||||
label: 'Camera',
|
||||
|
||||
Reference in New Issue
Block a user