Repository: NMF-earth/nmf-app (language: typescript)

Issue:
Present PermissionsRequest in Notification screen
#### Summary
Show `PermissionsRequest` component in Notification screen instead of opening settings with Linking.

_NB: First to submit a valid PR, first to merge. Except if you already have merged some good code in this repo, I won’t assign any issue due to spam and beginners unable to complete a PR without a lot of help from my side._


Discussion hints:
As far as I'm concerned you can't show the permission pop up twice to a user once they've rejected.
I also agree that just sending users to settings might not be a good UX, rather showing a popup saying :
`you've rejected before if you want you can go to settings and give permission manually` (sth like that) & then two buttons `yes`/`no` sth
@BatDroid indeed, you are right, you can only ask once with the native popup/dialog/prompt.
The idea is to do the same as in the `BarCodeScanScreen`. When user open for the notification screen for the first time, he should see the native dialog with empty screen behind, like line 102 of `BarCodeScanScreen` : 
```
  if (hasPermission === null) {
    return <View style={styles.container}></View>;
  }
```
And then if user has denied the authorization in the dialog show the component:
```
  if (!hasPermission) {
    return <PermissionsRequest type="notification" />;
  }
```
otherwise, show normal render. 

Pull request: (#339) Present PermissionsRequest in Notification screen
✅ I have read the [contributing file](https://github.com/NMF-earth/nmf-app/blob/main/contributing.md)

## Summary

Closes #339 

## Changelog

- Update snapshots
- Check for permissions on useEffect in Notifications screen
- Use PermissionsRequest component to require permissions in Notifications screen
- Add necessary translations

## Demo

![image](https://user-images.githubusercontent.com/39802870/139155519-63c26c98-460a-4fe9-bd67-dcb9e04e3330.png)



Test command: NODE_OPTIONS='--experimental-vm-modules --max-old-space-size=4096' npx --no-install jest app/components/PermissionsRequest/__tests__/PermissionsRequest.test.tsx app/screens/Notifications/__tests__/NotificationsScreen.tests.tsx --passWithNoTests 2>&1

Fix patch:
diff --git a/app/components/PermissionsRequest/translations/en.json b/app/components/PermissionsRequest/translations/en.json
index ae6002d8..5210dddb 100644
--- a/app/components/PermissionsRequest/translations/en.json
+++ b/app/components/PermissionsRequest/translations/en.json
@@ -2,6 +2,6 @@
   "PERMISSIONS_REQUEST_COMPONENT_OPEN_SETTINGS": "Open settings",
   "PERMISSIONS_REQUEST_COMPONENT_CAMERA_TITLE": "No access to camera",
   "PERMISSIONS_REQUEST_COMPONENT_CAMERA_SUBTITLE": "Please give NMF.earth app access to camera in your phone settings to use this feature.",
-  "PERMISSIONS_REQUEST_COMPONENT_NOTIFICATION_TITLE": "",
-  "PERMISSIONS_REQUEST_COMPONENT_NOTIFICATION_SUBTITLE": ""
+  "PERMISSIONS_REQUEST_COMPONENT_NOTIFICATION_TITLE": "No permission to send notifications",
+  "PERMISSIONS_REQUEST_COMPONENT_NOTIFICATION_SUBTITLE": "Please give NMF.earth app permission to send you notifications in your phone settings to use this feature."
 }
diff --git a/app/screens/Notifications/NotificationsScreen.tsx b/app/screens/Notifications/NotificationsScreen.tsx
index b772d818..63c75c78 100644
--- a/app/screens/Notifications/NotificationsScreen.tsx
+++ b/app/screens/Notifications/NotificationsScreen.tsx
@@ -1,10 +1,10 @@
-import React, { useCallback, useState } from "react";
+import React, { useCallback, useState, useEffect } from "react";
 import { View, Switch, Alert, Linking } from "react-native";
 import * as Notifications from "expo-notifications";
 import { useDispatch, useSelector } from "react-redux";
 
 import { NavStatelessComponent } from "interfaces";
-import { Text } from "components";
+import { PermissionsRequest, Text } from "components";
 import { userPreferences } from "ducks";
 import { t } from "utils";
 
@@ -29,31 +29,46 @@ const NotificationsScreen: NavStatelessComponent = () => {
   const [activated, setActivated] = useState(
     useSelector(userPreferences.selectors.getActivateNotifications)
   );
+  const [hasPermission, setHasPermission] = useState(null);
 
   const onValueChange = useCallback(
     async (value: boolean) => {
       try {
-        const permission = await Notifications.requestPermissionsAsync();
+        if (!hasPermission) {
+          Linking.openSettings();
+          return;
+        }
 
-        if (permission.granted && value) {
+        if (value) {
           await Notifications.scheduleNotificationAsync(notification);
         } else {
           await Notifications.cancelAllScheduledNotificationsAsync();
-
-          if (!permission.granted) {
-            Linking.openSettings();
-          }
         }
 
-        setActivated(permission.granted && value);
-        dispatch(userPreferences.actions.toggleNotifications(permission.granted && value));
+        setActivated(value);
+        dispatch(userPreferences.actions.toggleNotifications(value));
       } catch (e) {
         Alert.alert("Error", e);
       }
     },
-    [dispatch]
+    [dispatch, hasPermission]
   );
 
+  useEffect(() => {
+    (async () => {
+      const { status } = await Notifications.requestPermissionsAsync();
+      setHasPermission(status === "granted");
+    })();
+  }, []);
+
+  if (hasPermission === null) {
+    return <View style={styles.container} />;
+  }
+
+  if (!hasPermission) {
+    return <PermissionsRequest type="notification" />;
+  }
+
   return (
     <View style={styles.container}>
       <Text.Primary style={styles.intro}>{t("NOTIFICATIONS_SCREEN_INTRO")}</Text.Primary>
diff --git a/scripts/poeditor/en.json b/scripts/poeditor/en.json
index dd1e4570..76207d46 100644
--- a/scripts/poeditor/en.json
+++ b/scripts/poeditor/en.json
@@ -217,6 +217,6 @@
 	"PERMISSIONS_REQUEST_COMPONENT_OPEN_SETTINGS": "Open settings",
 	"PERMISSIONS_REQUEST_COMPONENT_CAMERA_TITLE": "No access to camera",
 	"PERMISSIONS_REQUEST_COMPONENT_CAMERA_SUBTITLE": "Please give NMF.earth app access to camera in your phone settings to use this feature.",
-	"PERMISSIONS_REQUEST_COMPONENT_NOTIFICATION_TITLE": "",
-	"PERMISSIONS_REQUEST_COMPONENT_NOTIFICATION_SUBTITLE": ""
+	"PERMISSIONS_REQUEST_COMPONENT_NOTIFICATION_TITLE": "No permission to send notifications",
+	"PERMISSIONS_REQUEST_COMPONENT_NOTIFICATION_SUBTITLE": "Please give NMF.earth app permission to send you notifications in your phone settings to use this feature."
 }
\ No newline at end of file


Test patch:
diff --git a/app/components/PermissionsRequest/__tests__/__snapshots__/PermissionsRequest.test.tsx.snap b/app/components/PermissionsRequest/__tests__/__snapshots__/PermissionsRequest.test.tsx.snap
index 25b50ab3..bdbde928 100644
--- a/app/components/PermissionsRequest/__tests__/__snapshots__/PermissionsRequest.test.tsx.snap
+++ b/app/components/PermissionsRequest/__tests__/__snapshots__/PermissionsRequest.test.tsx.snap
@@ -85,12 +85,12 @@ exports[`renders correctly PermissionsRequest if notification 1`] = `
     <Text.H2
       center={true}
     >
-      
+      No permission to send notifications
     </Text.H2>
     <Text.Primary
       center={true}
     >
-      
+      Please give NMF.earth app permission to send you notifications in your phone settings to use this feature.
     </Text.Primary>
   </View>
   <Button.Secondary
diff --git a/app/screens/Notifications/__tests__/__snapshots__/NotificationsScreen.tests.tsx.snap b/app/screens/Notifications/__tests__/__snapshots__/NotificationsScreen.tests.tsx.snap
index 1e5f798c..aadab118 100644
--- a/app/screens/Notifications/__tests__/__snapshots__/NotificationsScreen.tests.tsx.snap
+++ b/app/screens/Notifications/__tests__/__snapshots__/NotificationsScreen.tests.tsx.snap
@@ -9,44 +9,5 @@ exports[`NotificationsScreen renders correctly 1`] = `
       "paddingHorizontal": 16,
     }
   }
->
-  <Text.Primary
-    style={
-      Object {
-        "paddingTop": 30,
-      }
-    }
-  >
-    Receive a notification every Sunday at 9 p.m to remind you to add your weekly emissions.
-  </Text.Primary>
-  <View
-    style={
-      Object {
-        "alignItems": "center",
-        "flexDirection": "row",
-        "justifyContent": "space-between",
-        "marginTop": 22,
-      }
-    }
-  >
-    <Text.Secondary
-      bold={true}
-    >
-      Activated
-    </Text.Secondary>
-    <RCTSwitch
-      accessibilityRole="switch"
-      onChange={[Function]}
-      onResponderTerminationRequest={[Function]}
-      onStartShouldSetResponder={[Function]}
-      style={
-        Object {
-          "height": 31,
-          "width": 51,
-        }
-      }
-      value={false}
-    />
-  </View>
-</View>
+/>
 `;