diff --git a/android/app/build.gradle b/android/app/build.gradle
index e112598..d258bfd 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -137,6 +137,7 @@ android {
}
dependencies {
+ compile project(':react-native-app-settings')
compile project(':react-native-contacts')
compile project(':react-native-webview')
compile project(':react-native-vector-icons')
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 9fb7a3f..33833ec 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -3,6 +3,7 @@
+
getPackages() {
return Arrays.asList(
new MainReactPackage(),
+ new OpenAppSettingsPackage(),
new ReactNativeContacts(),
new RNCWebViewPackage(),
new VectorIconsPackage(),
diff --git a/android/settings.gradle b/android/settings.gradle
index 9e1189e..be5e104 100644
--- a/android/settings.gradle
+++ b/android/settings.gradle
@@ -1,4 +1,6 @@
rootProject.name = 'Tagfer'
+include ':react-native-app-settings'
+project(':react-native-app-settings').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-app-settings/android')
include ':react-native-contacts'
project(':react-native-contacts').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-contacts/android')
include ':react-native-webview'
diff --git a/ios/Tagfer.xcodeproj/project.pbxproj b/ios/Tagfer.xcodeproj/project.pbxproj
index 85010ea..55f1323 100644
--- a/ios/Tagfer.xcodeproj/project.pbxproj
+++ b/ios/Tagfer.xcodeproj/project.pbxproj
@@ -5,7 +5,6 @@
};
objectVersion = 46;
objects = {
-
/* Begin PBXBuildFile section */
00703E436FE7412D82B8B2ED /* libRealmReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 35A364E2A9804D0FA6E9C2BD /* libRealmReact.a */; };
00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; };
@@ -56,6 +55,8 @@
CCFF320D8D3B429E98A05055 /* MaterialCommunityIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = AC4E3A77FB9C4C96AC304034 /* MaterialCommunityIcons.ttf */; };
D9DE5DDB1B7D4D3A97259D9B /* Octicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = F025858B6C364BB985AFD241 /* Octicons.ttf */; };
E42DCC4F98F24BC99A74B29B /* SimpleLineIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 05246261280A4D30B02BFE85 /* SimpleLineIcons.ttf */; };
+ 5732A1A6497B4CAD966524D3 /* libReactNativePermissions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 75B79A57F6EF4FE2A21CEE97 /* libReactNativePermissions.a */; };
+ 864F29A547984CC590F11FA6 /* libRNOpenAppSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E2957596074A7C85333B68 /* libRNOpenAppSettings.a */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -419,6 +420,10 @@
DB6CE8411CF34300A2ED791F /* Foundation.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Foundation.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Foundation.ttf"; sourceTree = ""; };
E76DD57CF0E846F0B388335E /* libz.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
F025858B6C364BB985AFD241 /* Octicons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Octicons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Octicons.ttf"; sourceTree = ""; };
+ E335F09B945C4E2391D1FCD3 /* ReactNativePermissions.xcodeproj */ = {isa = PBXFileReference; name = "ReactNativePermissions.xcodeproj"; path = "../node_modules/react-native-permissions/ios/ReactNativePermissions.xcodeproj"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; };
+ 75B79A57F6EF4FE2A21CEE97 /* libReactNativePermissions.a */ = {isa = PBXFileReference; name = "libReactNativePermissions.a"; path = "libReactNativePermissions.a"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
+ 92557FC291AB42ADB5028635 /* RNOpenAppSettings.xcodeproj */ = {isa = PBXFileReference; name = "RNOpenAppSettings.xcodeproj"; path = "../node_modules/react-native-app-settings/ios/RNOpenAppSettings.xcodeproj"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; };
+ E5E2957596074A7C85333B68 /* libRNOpenAppSettings.a */ = {isa = PBXFileReference; name = "libRNOpenAppSettings.a"; path = "libRNOpenAppSettings.a"; sourceTree = ""; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -453,6 +458,8 @@
054B5176D9D541119DF55198 /* libRNVectorIcons.a in Frameworks */,
AD3198E72354473C9CFBB5F9 /* libRNCWebView.a in Frameworks */,
1BF10613A6304DD5B4189358 /* libRCTContacts.a in Frameworks */,
+ 5732A1A6497B4CAD966524D3 /* libReactNativePermissions.a in Frameworks */,
+ 864F29A547984CC590F11FA6 /* libRNOpenAppSettings.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -698,6 +705,8 @@
2DACAA5CB9F345B5888D681E /* RNVectorIcons.xcodeproj */,
A6904FF8C83444048D6F2AF5 /* RNCWebView.xcodeproj */,
90515674F3834203B1DE6531 /* RCTContacts.xcodeproj */,
+ E335F09B945C4E2391D1FCD3 /* ReactNativePermissions.xcodeproj */,
+ 92557FC291AB42ADB5028635 /* RNOpenAppSettings.xcodeproj */,
);
name = Libraries;
sourceTree = "";
@@ -1406,6 +1415,8 @@
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
"$(SRCROOT)/../node_modules/react-native-webview/ios",
"$(SRCROOT)/../node_modules/react-native-contacts/ios/RCTContacts",
+ "$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
+ "$(SRCROOT)/../node_modules/react-native-app-settings/ios",
);
INFOPLIST_FILE = TagferTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
@@ -1417,6 +1428,8 @@
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
+ "\"$(SRCROOT)/$(TARGET_NAME)\"",
+ "\"$(SRCROOT)/$(TARGET_NAME)\"",
);
OTHER_LDFLAGS = (
"-ObjC",
@@ -1440,6 +1453,8 @@
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
"$(SRCROOT)/../node_modules/react-native-webview/ios",
"$(SRCROOT)/../node_modules/react-native-contacts/ios/RCTContacts",
+ "$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
+ "$(SRCROOT)/../node_modules/react-native-app-settings/ios",
);
INFOPLIST_FILE = TagferTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
@@ -1451,6 +1466,8 @@
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
+ "\"$(SRCROOT)/$(TARGET_NAME)\"",
+ "\"$(SRCROOT)/$(TARGET_NAME)\"",
);
OTHER_LDFLAGS = (
"-ObjC",
@@ -1475,6 +1492,8 @@
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
"$(SRCROOT)/../node_modules/react-native-webview/ios",
"$(SRCROOT)/../node_modules/react-native-contacts/ios/RCTContacts",
+ "$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
+ "$(SRCROOT)/../node_modules/react-native-app-settings/ios",
);
INFOPLIST_FILE = Tagfer/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
@@ -1501,6 +1520,8 @@
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
"$(SRCROOT)/../node_modules/react-native-webview/ios",
"$(SRCROOT)/../node_modules/react-native-contacts/ios/RCTContacts",
+ "$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
+ "$(SRCROOT)/../node_modules/react-native-app-settings/ios",
);
INFOPLIST_FILE = Tagfer/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
@@ -1534,6 +1555,8 @@
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
"$(SRCROOT)/../node_modules/react-native-webview/ios",
"$(SRCROOT)/../node_modules/react-native-contacts/ios/RCTContacts",
+ "$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
+ "$(SRCROOT)/../node_modules/react-native-app-settings/ios",
);
INFOPLIST_FILE = "Tagfer-tvOS/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
@@ -1544,6 +1567,8 @@
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
+ "\"$(SRCROOT)/$(TARGET_NAME)\"",
+ "\"$(SRCROOT)/$(TARGET_NAME)\"",
);
OTHER_LDFLAGS = (
"-ObjC",
@@ -1576,6 +1601,8 @@
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
"$(SRCROOT)/../node_modules/react-native-webview/ios",
"$(SRCROOT)/../node_modules/react-native-contacts/ios/RCTContacts",
+ "$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
+ "$(SRCROOT)/../node_modules/react-native-app-settings/ios",
);
INFOPLIST_FILE = "Tagfer-tvOS/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
@@ -1586,6 +1613,8 @@
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
+ "\"$(SRCROOT)/$(TARGET_NAME)\"",
+ "\"$(SRCROOT)/$(TARGET_NAME)\"",
);
OTHER_LDFLAGS = (
"-ObjC",
@@ -1617,6 +1646,8 @@
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
"$(SRCROOT)/../node_modules/react-native-webview/ios",
"$(SRCROOT)/../node_modules/react-native-contacts/ios/RCTContacts",
+ "$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
+ "$(SRCROOT)/../node_modules/react-native-app-settings/ios",
);
INFOPLIST_FILE = "Tagfer-tvOSTests/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
@@ -1627,6 +1658,8 @@
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
+ "\"$(SRCROOT)/$(TARGET_NAME)\"",
+ "\"$(SRCROOT)/$(TARGET_NAME)\"",
);
OTHER_LDFLAGS = (
"-ObjC",
@@ -1658,6 +1691,8 @@
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
"$(SRCROOT)/../node_modules/react-native-webview/ios",
"$(SRCROOT)/../node_modules/react-native-contacts/ios/RCTContacts",
+ "$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
+ "$(SRCROOT)/../node_modules/react-native-app-settings/ios",
);
INFOPLIST_FILE = "Tagfer-tvOSTests/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
@@ -1668,6 +1703,8 @@
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
"\"$(SRCROOT)/$(TARGET_NAME)\"",
+ "\"$(SRCROOT)/$(TARGET_NAME)\"",
+ "\"$(SRCROOT)/$(TARGET_NAME)\"",
);
OTHER_LDFLAGS = (
"-ObjC",
diff --git a/ios/Tagfer/Info.plist b/ios/Tagfer/Info.plist
index ff58dca..dc3e423 100644
--- a/ios/Tagfer/Info.plist
+++ b/ios/Tagfer/Info.plist
@@ -27,7 +27,7 @@
LSRequiresIPhoneOS
NSLocationWhenInUseUsageDescription
-
+
UILaunchStoryboardName
LaunchScreen
UIRequiredDeviceCapabilities
diff --git a/package-lock.json b/package-lock.json
index 967f41e..df29d40 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8523,6 +8523,11 @@
"yargs": "^9.0.0"
}
},
+ "react-native-app-settings": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/react-native-app-settings/-/react-native-app-settings-2.0.1.tgz",
+ "integrity": "sha512-MmYtXQbPBJ0tlAmn4MeeOOjrSR9Cup4PI4HFSsETDGUMrOGmb7WETrQ/9bZ06BeisNnqf8/Qj+efgH+OmFYDjQ=="
+ },
"react-native-contacts": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/react-native-contacts/-/react-native-contacts-2.2.5.tgz",
@@ -8630,6 +8635,11 @@
"tinymask": "^1.0.2"
}
},
+ "react-native-permissions": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/react-native-permissions/-/react-native-permissions-1.1.1.tgz",
+ "integrity": "sha512-t0Ujm177bagjUOSzhpmkSz+LqFW04HnY9TeZFavDCmV521fQvFz82aD+POXqWsAdsJVOK3umJYBNNqCjC3g0hQ=="
+ },
"react-native-safe-area-view": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/react-native-safe-area-view/-/react-native-safe-area-view-0.11.0.tgz",
diff --git a/package.json b/package.json
index 463dd18..57b3cc9 100644
--- a/package.json
+++ b/package.json
@@ -11,12 +11,14 @@
"i18n-js": "^3.1.0",
"react": "16.6.3",
"react-native": "0.57.8",
+ "react-native-app-settings": "^2.0.1",
"react-native-contacts": "^2.2.5",
"react-native-country-picker-modal": "^0.6.2",
"react-native-elements": "^0.19.1",
"react-native-flash-message": "^0.1.10",
"react-native-gesture-handler": "^1.0.12",
"react-native-masked-text": "^1.9.2",
+ "react-native-permissions": "^1.1.1",
"react-native-vector-icons": "^4.6.0",
"react-native-webview": "^2.14.3",
"react-navigation": "^3.0.9",
diff --git a/src/components/lists/ContactListItem.js b/src/components/lists/ContactListItem.js
index 63681b2..f266bdf 100644
--- a/src/components/lists/ContactListItem.js
+++ b/src/components/lists/ContactListItem.js
@@ -6,7 +6,10 @@ import { isEmpty } from '../../utils/aux';
const ContactListItem = ({ contact, selected, onPress }) => {
const { givenName, familyName, phoneNumbers } = contact;
- const fullName = `${contact.givenName} ${contact.familyName}`;
+ let fullName = '';
+
+ if (!isEmpty(givenName)) fullName += givenName;
+ if (!isEmpty(familyName)) fullName += familyName;
return (
{
if (error) {
@@ -90,29 +92,39 @@ export default class SignupScreenFive extends React.Component {
});
}
+ requestPermissions() {
+ Permissions.request('contacts').then(permission => {
+ if (permission === 'authorized') return this.getContacts();
+ this.props.navigation.navigate('signup6');
+ });
+ }
+
createSettingsAlert() {
Alert.alert(
- 'Tagfer does not have access to your contacts',
+ 'Contacts Access Denied',
'To enable access, tap Settings and turn on Contacts',
[
{ text: 'Cancel', onPress: () => this.props.navigation.navigate('signup6') },
- { text: 'Settings', onPress: () => Linking.openURL('app-settings:') }
+ { text: 'Settings', onPress: () => OpenAppSettings.open() }
]
);
}
- fetchContactsIOS() {
- Contacts.checkPermission((error, permission) => {
- if (error) this.props.navigation.navigate('signup6');
+ fetchContacts() {
+ Permissions.check('contacts').then(permission => {
+ if (Platform.OS === 'ios') {
+ if (permission === 'restricted') return this.props.navigation.navigate('signup6');
+ if (permission === 'denied') return this.createSettingsAlert();
+
+ return this.getContacts();
+ }
- if (permission === 'denied') {
- this.createSettingsAlert();
- } else {
- this.getContacts();
+ if (Platform.OS === 'android') {
+ return permission === 'restricted' ? this.createSettingsAlert() : this.requestPermissions();
}
});
}
- // END: iOS Handlers
+ // END: Fetch Contacts
renderItem(contact, index) {
const selected = this.state.selectedContacts.has(index);