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