123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. import React from 'react';
  2. import {Appbar, List, TouchableRipple} from 'react-native-paper';
  3. import theme from './theme';
  4. import {
  5. FlatList,
  6. Platform,
  7. StatusBar,
  8. Text,
  9. View,
  10. GestureResponderEvent,
  11. } from 'react-native';
  12. import RNPermissions, {
  13. PermissionStatus,
  14. Permission,
  15. NotificationsResponse,
  16. } from 'react-native-permissions';
  17. const {PERMISSIONS, RESULTS} = RNPermissions;
  18. // eslint-disable-next-line @typescript-eslint/no-unused-vars
  19. const {SIRI, ...PERMISSIONS_IOS} = PERMISSIONS.IOS; // remove siri (certificate required)
  20. const PLATFORM_PERMISSIONS = Platform.select<
  21. typeof PERMISSIONS_IOS | typeof PERMISSIONS.ANDROID | {}
  22. >({
  23. ios: PERMISSIONS_IOS,
  24. android: PERMISSIONS.ANDROID,
  25. default: {},
  26. });
  27. const PERMISSIONS_VALUES: Permission[] = Object.values(PLATFORM_PERMISSIONS);
  28. const colors: {[key: string]: string} = {
  29. unavailable: '#cfd8dc',
  30. denied: '#ff9800',
  31. granted: '#43a047',
  32. blocked: '#e53935',
  33. };
  34. const icons: {[key: string]: string} = {
  35. unavailable: 'lens',
  36. denied: 'error',
  37. granted: 'check-circle',
  38. blocked: 'cancel',
  39. };
  40. const PermissionRow = ({
  41. name,
  42. status,
  43. onPress,
  44. }: {
  45. name: string;
  46. status: string;
  47. onPress: (event: GestureResponderEvent) => void;
  48. }) => (
  49. <TouchableRipple onPress={onPress}>
  50. <List.Item
  51. right={() => <List.Icon color={colors[status]} icon={icons[status]} />}
  52. title={name}
  53. description={status}
  54. />
  55. </TouchableRipple>
  56. );
  57. interface State {
  58. statuses: PermissionStatus[];
  59. notifications: NotificationsResponse;
  60. }
  61. function getSettingString(setting: boolean | undefined) {
  62. return setting
  63. ? RESULTS.GRANTED
  64. : setting === false
  65. ? RESULTS.DENIED
  66. : RESULTS.UNAVAILABLE;
  67. }
  68. export default class App extends React.Component<{}, State> {
  69. state: State = {
  70. statuses: [],
  71. notifications: {status: 'unavailable', settings: {}},
  72. };
  73. check = () =>
  74. Promise.all(PERMISSIONS_VALUES.map(_ => RNPermissions.check(_)))
  75. .then(statuses => this.setState({statuses}))
  76. .then(() => RNPermissions.checkNotifications())
  77. .then(notifications => this.setState({notifications}))
  78. .catch(error => console.warn(error));
  79. refresh = () => {
  80. this.setState({statuses: []}, this.check);
  81. };
  82. componentDidMount() {
  83. this.check();
  84. }
  85. render() {
  86. const {notifications} = this.state;
  87. const {settings} = notifications;
  88. return (
  89. <View style={{flex: 1, backgroundColor: theme.colors.background}}>
  90. <StatusBar
  91. backgroundColor={theme.colors.primary}
  92. barStyle="light-content"
  93. />
  94. <Appbar.Header>
  95. <Appbar.Content
  96. title="react-native-permissions"
  97. subtitle="Example application"
  98. />
  99. <Appbar.Action onPress={this.refresh} icon="refresh" />
  100. <Appbar.Action
  101. onPress={RNPermissions.openSettings}
  102. icon="settings-applications"
  103. />
  104. </Appbar.Header>
  105. <FlatList
  106. keyExtractor={item => item}
  107. data={Object.keys(PLATFORM_PERMISSIONS)}
  108. renderItem={({item, index}) => {
  109. const value = PERMISSIONS_VALUES[index];
  110. const status = this.state.statuses[index];
  111. return (
  112. <PermissionRow
  113. status={status}
  114. name={item}
  115. onPress={() => {
  116. RNPermissions.request(value)
  117. .then(() => this.check())
  118. .catch(err => console.error(err));
  119. }}
  120. />
  121. );
  122. }}
  123. />
  124. <View
  125. style={{backgroundColor: '#e0e0e0', height: 1}}
  126. accessibilityRole="none"
  127. />
  128. <TouchableRipple
  129. onPress={() => {
  130. RNPermissions.requestNotifications(['alert', 'badge', 'sound'])
  131. .then(() => this.check())
  132. .catch(err => console.error(err));
  133. }}>
  134. <List.Item
  135. right={() => (
  136. <List.Icon
  137. color={colors[notifications.status]}
  138. icon={icons[notifications.status]}
  139. />
  140. )}
  141. title="NOTIFICATIONS"
  142. description={notifications.status}
  143. />
  144. </TouchableRipple>
  145. <Text style={{margin: 15, marginTop: 0, color: '#777'}}>
  146. {`alert: ${getSettingString(settings.alert)}\n`}
  147. {`badge: ${getSettingString(settings.badge)}\n`}
  148. {`sound: ${getSettingString(settings.sound)}\n`}
  149. {`lockScreen: ${getSettingString(settings.lockScreen)}\n`}
  150. {`notificationCenter: ${getSettingString(
  151. settings.notificationCenter,
  152. )}\n`}
  153. {`carPlay: ${getSettingString(settings.carPlay)}\n`}
  154. {`criticalAlert: ${getSettingString(settings.criticalAlert)}\n`}
  155. </Text>
  156. </View>
  157. );
  158. }
  159. }