Procházet zdrojové kódy

[RN] Alert the user when they need to manually grant a permission

master
Saúl Ibarra Corretgé před 7 roky
rodič
revize
26f0f7f89c

+ 44
- 0
android/sdk/src/main/java/org/jitsi/meet/sdk/AndroidSettingsModule.java Zobrazit soubor

@@ -0,0 +1,44 @@
1
+/**
2
+ * Adapted from
3
+ * {@link https://github.com/Aleksandern/react-native-android-settings-library}.
4
+ */
5
+
6
+package org.jitsi.meet.sdk;
7
+
8
+import android.content.Context;
9
+import android.content.Intent;
10
+import android.net.Uri;
11
+import android.provider.Settings;
12
+
13
+import com.facebook.react.bridge.ReactApplicationContext;
14
+import com.facebook.react.bridge.ReactContextBaseJavaModule;
15
+import com.facebook.react.bridge.ReactMethod;
16
+
17
+class AndroidSettingsModule extends ReactContextBaseJavaModule {
18
+    /**
19
+     * React Native module name.
20
+     */
21
+    private static final String MODULE_NAME = "AndroidSettings";
22
+
23
+    public AndroidSettingsModule(ReactApplicationContext reactContext) {
24
+        super(reactContext);
25
+    }
26
+
27
+    @Override
28
+    public String getName() {
29
+        return MODULE_NAME;
30
+    }
31
+
32
+    @ReactMethod
33
+    public void open() {
34
+        Context context = getReactApplicationContext();
35
+        Intent intent = new Intent();
36
+
37
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
38
+        intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
39
+        intent.setData(
40
+            Uri.fromParts("package", context.getPackageName(), null));
41
+
42
+        context.startActivity(intent);
43
+    }
44
+}

+ 1
- 0
android/sdk/src/main/java/org/jitsi/meet/sdk/JitsiMeetView.java Zobrazit soubor

@@ -59,6 +59,7 @@ public class JitsiMeetView extends FrameLayout {
59 59
     private static List<NativeModule> createNativeModules(
60 60
             ReactApplicationContext reactContext) {
61 61
         return Arrays.<NativeModule>asList(
62
+            new AndroidSettingsModule(reactContext),
62 63
             new AudioModeModule(reactContext),
63 64
             new ExternalAPIModule(reactContext),
64 65
             new ProximityModule(reactContext)

+ 1
- 0
react/features/app/components/App.native.js Zobrazit soubor

@@ -8,6 +8,7 @@ import '../../mobile/audio-mode';
8 8
 import '../../mobile/background';
9 9
 import '../../mobile/external-api';
10 10
 import '../../mobile/full-screen';
11
+import '../../mobile/permissions';
11 12
 import '../../mobile/proximity';
12 13
 import '../../mobile/wake-lock';
13 14
 

+ 11
- 0
react/features/base/tracks/actionTypes.js Zobrazit soubor

@@ -9,6 +9,17 @@
9 9
  */
10 10
 export const TRACK_ADDED = Symbol('TRACK_ADDED');
11 11
 
12
+/**
13
+ * Action for when a track cannot be created because permissions have not been
14
+ * granted.
15
+ *
16
+ * {
17
+ *     type: TRACK_PERMISSION_ERROR,
18
+ *     trackType: string
19
+ * }
20
+ */
21
+export const TRACK_PERMISSION_ERROR = Symbol('TRACK_PERMISSION_ERROR');
22
+
12 23
 /**
13 24
  * Action for when a track has been removed from the conference,
14 25
  * local or remote.

+ 19
- 9
react/features/base/tracks/actions.js Zobrazit soubor

@@ -7,7 +7,12 @@ import {
7 7
 } from '../media';
8 8
 import { getLocalParticipant } from '../participants';
9 9
 
10
-import { TRACK_ADDED, TRACK_REMOVED, TRACK_UPDATED } from './actionTypes';
10
+import {
11
+    TRACK_ADDED,
12
+    TRACK_PERMISSION_ERROR,
13
+    TRACK_REMOVED,
14
+    TRACK_UPDATED
15
+} from './actionTypes';
11 16
 import { createLocalTracksF } from './functions';
12 17
 
13 18
 /**
@@ -78,14 +83,19 @@ export function createLocalTracksA(options = {}) {
78 83
                 },
79 84
                 /* firePermissionPromptIsShownEvent */ false,
80 85
                 store)
81
-            .then(localTracks => dispatch(_updateLocalTracks(localTracks)));
82
-
83
-            // TODO The function createLocalTracksF logs the rejection reason of
84
-            // JitsiMeetJS.createLocalTracks so there is no real benefit to
85
-            // logging it here as well. Technically though,
86
-            // _updateLocalTracks may cause a rejection so it may be nice to log
87
-            // it. It's not too big of a concern at the time of this writing
88
-            // because React Native warns on unhandled Promise rejections.
86
+            .then(localTracks => dispatch(_updateLocalTracks(localTracks)))
87
+            .catch(({ gum }) => {
88
+                // If permissions are not allowed, alert the user.
89
+                if (gum
90
+                        && gum.error
91
+                        && gum.error.name === 'DOMException'
92
+                        && gum.error.message === 'NotAllowedError') {
93
+                    dispatch({
94
+                        type: TRACK_PERMISSION_ERROR,
95
+                        trackType: device
96
+                    });
97
+                }
98
+            });
89 99
         }
90 100
     };
91 101
 }

+ 47
- 0
react/features/mobile/permissions/functions.js Zobrazit soubor

@@ -0,0 +1,47 @@
1
+import { Alert, Linking, NativeModules } from 'react-native';
2
+
3
+import { Platform } from '../../base/react';
4
+
5
+/**
6
+ * Shows an alert panel which tells the user they have to manually grant some
7
+ * permissions by opening Settings. A button which opens Settings is provided.
8
+ *
9
+ * FIXME: translate.
10
+ *
11
+ * @param {string} trackType - Type of track that failed with a permission
12
+ * error.
13
+ * @returns {void}
14
+ */
15
+export function alertPermissionErrorWithSettings(trackType) {
16
+    const type = trackType === 'video' ? 'Camera' : 'Microphone';
17
+
18
+    Alert.alert(
19
+        'Permissions Error',
20
+        `${type} permission is required, please enable it in Settings.`,
21
+        [
22
+            { text: 'Cancel' },
23
+            {
24
+                onPress: _openSettings,
25
+                text: 'Settings'
26
+            }
27
+        ],
28
+        { cancelable: false });
29
+}
30
+
31
+/**
32
+ * Opens the settings panel for the current platform.
33
+ *
34
+ * @private
35
+ * @returns {void}
36
+ */
37
+function _openSettings() {
38
+    switch (Platform.OS) {
39
+    case 'android':
40
+        NativeModules.AndroidSettings.open();
41
+        break;
42
+
43
+    case 'ios':
44
+        Linking.openURL('app-settings:');
45
+        break;
46
+    }
47
+}

+ 1
- 0
react/features/mobile/permissions/index.js Zobrazit soubor

@@ -0,0 +1 @@
1
+import './middleware';

+ 25
- 0
react/features/mobile/permissions/middleware.js Zobrazit soubor

@@ -0,0 +1,25 @@
1
+/* @flow */
2
+
3
+import { MiddlewareRegistry } from '../../base/redux';
4
+import { TRACK_PERMISSION_ERROR } from '../../base/tracks';
5
+
6
+import { alertPermissionErrorWithSettings } from './functions';
7
+
8
+/**
9
+ * Middleware that captures track permission errors and alerts the user so they
10
+ * can enable the permission themselves.
11
+ *
12
+ * @param {Store} store - The redux store.
13
+ * @returns {Function}
14
+ */
15
+MiddlewareRegistry.register(() => next => action => {
16
+    const result = next(action);
17
+
18
+    switch (action.type) {
19
+    case TRACK_PERMISSION_ERROR:
20
+        alertPermissionErrorWithSettings(action.trackType);
21
+        break;
22
+    }
23
+
24
+    return result;
25
+});

Načítá se…
Zrušit
Uložit