From edff1992b18a62f4ada09ba4f20cd2c29cd4e634 Mon Sep 17 00:00:00 2001
From: Ansh <anshnanda10@gmail.com>
Date: Mon, 3 Jul 2023 11:17:12 -0700
Subject: Add permission checks before saving image (#945)

* catch permission errors when saving image to album

* Save photos to media library alone (not an album)

---------

Co-authored-by: Paul Frazee <pfrazee@gmail.com>
---
 src/view/com/lightbox/Lightbox.tsx | 39 +++++++++++++++++++++++++++-----------
 1 file changed, 28 insertions(+), 11 deletions(-)

(limited to 'src/view/com/lightbox/Lightbox.tsx')

diff --git a/src/view/com/lightbox/Lightbox.tsx b/src/view/com/lightbox/Lightbox.tsx
index d1fd701cf..b496e0d95 100644
--- a/src/view/com/lightbox/Lightbox.tsx
+++ b/src/view/com/lightbox/Lightbox.tsx
@@ -5,21 +5,47 @@ import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'
 import ImageView from './ImageViewing'
 import {useStores} from 'state/index'
 import * as models from 'state/models/ui/shell'
-import {shareImageModal, saveImageToAlbum} from 'lib/media/manip'
+import {shareImageModal, saveImageToMediaLibrary} from 'lib/media/manip'
 import * as Toast from '../util/Toast'
 import {Text} from '../util/text/Text'
 import {s, colors} from 'lib/styles'
 import {Button} from '../util/forms/Button'
 import {isIOS} from 'platform/detection'
+import * as MediaLibrary from 'expo-media-library'
 
 export const Lightbox = observer(function Lightbox() {
   const store = useStores()
   const [isAltExpanded, setAltExpanded] = React.useState(false)
+  const [permissionResponse, requestPermission] = MediaLibrary.usePermissions()
 
   const onClose = React.useCallback(() => {
     store.shell.closeLightbox()
   }, [store])
 
+  const saveImageToAlbumWithToasts = React.useCallback(
+    async (uri: string) => {
+      if (!permissionResponse || permissionResponse.granted === false) {
+        Toast.show('Permission to access camera roll is required.')
+        if (permissionResponse?.canAskAgain) {
+          requestPermission()
+        } else {
+          Toast.show(
+            'Permission to access camera roll was denied. Please enable it in your system settings.',
+          )
+        }
+        return
+      }
+
+      try {
+        await saveImageToMediaLibrary({uri})
+        Toast.show('Saved to your camera roll.')
+      } catch (e: any) {
+        Toast.show(`Failed to save image: ${String(e)}`)
+      }
+    },
+    [permissionResponse, requestPermission],
+  )
+
   const LightboxFooter = React.useCallback(
     ({imageIndex}: {imageIndex: number}) => {
       const lightbox = store.shell.activeLightbox
@@ -74,7 +100,7 @@ export const Lightbox = observer(function Lightbox() {
         </View>
       )
     },
-    [store.shell.activeLightbox, isAltExpanded, setAltExpanded],
+    [store.shell.activeLightbox, isAltExpanded, saveImageToAlbumWithToasts],
   )
 
   if (!store.shell.activeLightbox) {
@@ -106,15 +132,6 @@ export const Lightbox = observer(function Lightbox() {
   }
 })
 
-async function saveImageToAlbumWithToasts(uri: string) {
-  try {
-    await saveImageToAlbum({uri, album: 'Bluesky'})
-    Toast.show('Saved to the "Bluesky" album.')
-  } catch (e: any) {
-    Toast.show(`Failed to save image: ${String(e)}`)
-  }
-}
-
 const styles = StyleSheet.create({
   footer: {
     paddingTop: 16,
-- 
cgit 1.4.1

