Bluesky app fork with some witchin' additions 💫

Avoid asking for read access to photo library when saving images on iOS (#9297)

* use saveToLibraryAsync on iOS

* use _(msg``) syntax

authored by samuel.fm and committed by

GitHub c9033dbc 1b0fbd50

+51 -10
+1 -1
src/lib/media/manip.ts
··· 157 157 ) 158 158 } 159 159 } else { 160 - await MediaLibrary.createAssetAsync(imagePath) 160 + await MediaLibrary.saveToLibraryAsync(imagePath) 161 161 } 162 162 } catch (err) { 163 163 logger.error(err instanceof Error ? err : String(err), {
+32
src/lib/media/save-image.ios.ts
··· 1 + import {useCallback} from 'react' 2 + import {msg} from '@lingui/macro' 3 + import {useLingui} from '@lingui/react' 4 + 5 + import {isNative} from '#/platform/detection' 6 + import * as Toast from '#/components/Toast' 7 + import {saveImageToMediaLibrary} from './manip' 8 + 9 + /** 10 + * Same as `saveImageToMediaLibrary`, but also handles permissions and toasts 11 + * 12 + * iOS doesn't not require permissions to save images to the media library, 13 + * so this file is platform-split as it's much simpler than the Android version. 14 + */ 15 + export function useSaveImageToMediaLibrary() { 16 + const {_} = useLingui() 17 + return useCallback( 18 + async (uri: string) => { 19 + if (!isNative) { 20 + throw new Error('useSaveImageToMediaLibrary is native only') 21 + } 22 + 23 + try { 24 + await saveImageToMediaLibrary({uri}) 25 + Toast.show(_(msg`Image saved`)) 26 + } catch (e: any) { 27 + Toast.show(_(msg`Failed to save image: ${String(e)}`), {type: 'error'}) 28 + } 29 + }, 30 + [_], 31 + ) 32 + }
+18 -9
src/lib/media/save-image.ts
··· 1 1 import {useCallback} from 'react' 2 2 import * as MediaLibrary from 'expo-media-library' 3 - import {t} from '@lingui/macro' 3 + import {msg} from '@lingui/macro' 4 + import {useLingui} from '@lingui/react' 4 5 5 6 import {isNative} from '#/platform/detection' 6 - import * as Toast from '#/view/com/util/Toast' 7 + import * as Toast from '#/components/Toast' 7 8 import {saveImageToMediaLibrary} from './manip' 8 9 9 10 /** 10 11 * Same as `saveImageToMediaLibrary`, but also handles permissions and toasts 11 12 */ 12 13 export function useSaveImageToMediaLibrary() { 14 + const {_} = useLingui() 13 15 const [permissionResponse, requestPermission, getPermission] = 14 16 MediaLibrary.usePermissions({ 15 17 granularPermissions: ['photo'], ··· 23 25 async function save() { 24 26 try { 25 27 await saveImageToMediaLibrary({uri}) 26 - Toast.show(t`Image saved`) 28 + 29 + Toast.show(_(msg`Image saved`)) 27 30 } catch (e: any) { 28 - Toast.show(t`Failed to save image: ${String(e)}`, 'xmark') 31 + Toast.show(_(msg`Failed to save image: ${String(e)}`), { 32 + type: 'error', 33 + }) 29 34 } 30 35 } 31 36 ··· 42 47 } else { 43 48 // since we've been explicitly denied, show a toast. 44 49 Toast.show( 45 - t`Images cannot be saved unless permission is granted to access your photo library.`, 46 - 'xmark', 50 + _( 51 + msg`Images cannot be saved unless permission is granted to access your photo library.`, 52 + ), 53 + {type: 'error'}, 47 54 ) 48 55 } 49 56 } else { 50 57 Toast.show( 51 - t`Permission to access your photo library was denied. Please enable it in your system settings.`, 52 - 'xmark', 58 + _( 59 + msg`Permission to access your photo library was denied. Please enable it in your system settings.`, 60 + ), 61 + {type: 'error'}, 53 62 ) 54 63 } 55 64 } 56 65 }, 57 - [permissionResponse, requestPermission, getPermission], 66 + [permissionResponse, requestPermission, getPermission, _], 58 67 ) 59 68 }