Skip to content

Commit 2bbd0c8

Browse files
authored
Merge pull request #16 from panz3r/major-rewrite
Major rewrite
2 parents 17bbe85 + f95b1f1 commit 2bbd0c8

File tree

10 files changed

+435
-86
lines changed

10 files changed

+435
-86
lines changed

README.md

Lines changed: 77 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
> :bell: Customisable in-app notification component for React Native
44
55
## Contents
6+
67
1. [UI](#ui)
78
2. [Install](#install)
8-
3. [Props](#props)
9-
4. [Usage](#usage)
10-
5. [Example](#example)
9+
3. [Versions](#versions)
10+
4. [Props](#props)
11+
5. [Usage](#usage)
1112

1213
## UI
14+
1315
The basic look of `react-native-in-app-notification`:
1416

1517
![A GIF showing what react-native-in-app-notification can do](http://i.imgur.com/3PILcKg.gif)
@@ -19,17 +21,45 @@ What you can make `react-native-in-app-notification` do with a customised compon
1921
![A GIF showing what react-native-in-app-notification can do](http://i.imgur.com/k0SBlrW.gif)
2022

2123
## Install
24+
2225
```bash
2326
yarn add react-native-in-app-notification
2427
```
28+
2529
OR
30+
2631
```bash
2732
npm install react-native-in-app-notification --save
2833
```
2934

35+
### Android
36+
37+
For Android you need to add the `VIBRATE` permission to your app `AndroidManifest.xml`
38+
```xml
39+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
40+
package="your.app.package.name">
41+
42+
<uses-permission android:name="android.permission.INTERNET" />
43+
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
44+
45+
<!-- Required by react-native-in-app-notification -->
46+
<uses-permission android:name="android.permission.VIBRATE" />
47+
48+
...
49+
</manifest>
50+
```
51+
52+
## Versions
53+
54+
| version | RN |
55+
| ------- | :-------- |
56+
| >=3.0.0 | >= 0.54.0 |
57+
| <3.0.0 | >= 0.43.4 |
58+
3059
## Props
60+
3161
| Prop Name | Prop Description | Data Type | Required | Default |
32-
|---------------------------|-----------------------------------------------------|------------------------|-------------|-----------------------------|
62+
| ------------------------- | --------------------------------------------------- | ---------------------- | ----------- | --------------------------- |
3363
| closeInterval | How long the notification stays visible | Number | No | `4000` |
3464
| openCloseDuration | The length of the open / close animation | Number | No | `200` |
3565
| height | The height of the Notification component | Number | No | `80` |
@@ -38,46 +68,77 @@ npm install react-native-in-app-notification --save
3868
| notificationBodyComponent | **See below about NotificationBody** | React Node or Function | Recommended | `./DefaultNotificationBody` |
3969

4070
### NotificationBody
71+
4172
The notification body is what is rendered inside the main Notification component and gives you the ability to customise how the notification looks. You can use the default notification body component in `./DefaultNotificationBody.js` as inspiration and guidance.
4273

4374
Your `notificationBodyComponent` component is given four props:
4475

4576
| Prop Name | Prop Description | Data Type | Default |
46-
|-----------|---------------------------------------------------------------|---------------------|---------|
77+
| --------- | ------------------------------------------------------------- | ------------------- | ------- |
4778
| title | The title passed to `NotificationRef.show` | String | `''` |
4879
| message | The message passed to `NotificationRef.show` | String | `''` |
4980
| onPress | The callback passed to `NotificationRef.show` | Function | `null` |
5081
| icon | Icon for notification passed to `NotificationRef.show` | ImageSourcePropType | `null` |
5182
| vibrate | Vibrate on show notification passed to `NotificationRef.show` | Boolean | `true` |
5283

5384
## Usage
54-
Adding `react-native-in-app-notification` is simple; just import the component and add it to the bottom of your component tree. Then create a ref to the component using `ref={(ref) => { this.notification = ref; }}` as a prop.
5585

56-
When you want to show the notification, just call `.show` on the ref you made earlier. `.show` can take three arguments: `title`, `message` and `onPress` all of which are optional - but you should probably include at least one of `title` or `message`! `onPress` doesn't need to be used for passive notifications and you can use `onClose` in your `NotificationBody` component to allow your users to close the notification.
86+
Adding `react-native-in-app-notification` is simple;
87+
Just wrap you main `App` component with the `InAppNotificationProvider` component exported from this module.
88+
89+
```javascript
90+
import { InAppNotificationProvider } from 'react-native-in-app-notification';
91+
92+
import App from './App.js';
93+
94+
class AppWithNotifications extends Component {
95+
render() {
96+
return (
97+
<InAppNotificationProvider>
98+
<App />
99+
</InAppNotificationProvider>
100+
);
101+
}
102+
}
103+
```
104+
105+
When you want to show the notification, just wrap the component which needs to display a notification with the `withInAppNotification` HOC and call the `.showNotification` methods from its props.
106+
107+
`.showNotification` can take three arguments (all of which are optional):
108+
109+
- `title`
110+
- `message`
111+
- `onPress`
112+
113+
**N.B:** you should probably include at least one of `title` or `message`!
114+
115+
`onPress` doesn't need to be used for passive notifications and you can use `onClose` in your `NotificationBody` component to allow your users to close the notification.
57116

58-
## Example
59117
```javascript
60118
import React, { Component } from 'react';
61119
import { View, Text, TouchableHighlight } from 'react-native';
62-
import Notification from 'react-native-in-app-notification';
120+
import { withInAppNotification } from 'react-native-in-app-notification';
63121

64122
class MyApp extends Component {
65123
render() {
66124
return (
67125
<View>
68126
<Text>This is my app</Text>
69127
<TouchableHighlight
70-
onPress={this.notification && this.notification.show({
71-
title: 'You pressed it!',
72-
message: 'The notification has been triggered',
73-
onPress: () => Alert.alert('Alert', 'You clicked the notification!'),
74-
})}
128+
onPress={() => {
129+
this.props.showNotification({
130+
title: 'You pressed it!',
131+
message: 'The notification has been triggered',
132+
onPress: () => Alert.alert('Alert', 'You clicked the notification!')
133+
});
134+
}}
75135
>
76136
<Text>Click me to trigger a notification</Text>
77137
</TouchableHighlight>
78-
<Notification ref={(ref) => { this.notification = ref; }} />
79138
</View>
80-
)
139+
);
81140
}
82141
}
142+
143+
export default withInAppNotification(MyApp);
83144
```

package.json

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
22
"name": "react-native-in-app-notification",
3-
"version": "2.2.0",
3+
"version": "3.0.0",
44
"description": "Customisable in-app notification component for React Native",
5-
"main": "Notification.js",
5+
"main": "src/index.js",
66
"repository": "https://github.com/robcalcroft/react-native-in-app-notification.git",
77
"author": "Rob Calcroft <rob@calcroft.com>",
88
"license": "MIT",
@@ -11,10 +11,12 @@
1111
},
1212
"peerDependencies": {
1313
"prop-types": "^15.5.10",
14-
"react": "^15.5.4",
15-
"react-native": "^0.43.4"
14+
"react": ">=16.3.0",
15+
"react-native": ">=0.54.0"
1616
},
1717
"dependencies": {
18+
"hoist-non-react-statics": "^3.0.1",
19+
"react-native-iphone-x-helper": "^1.2.0",
1820
"react-native-swipe-gestures": "^1.0.2"
1921
},
2022
"devDependencies": {

src/Context.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import React from 'react';
2+
3+
const context = React.createContext(() => {});
4+
5+
export default context;

DefaultNotificationBody.android.js renamed to src/DefaultNotificationBody/index.android.js

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,26 @@ class DefaultNotificationBody extends React.Component {
4040
constructor() {
4141
super();
4242

43+
this.onNotificationPress = this.onNotificationPress.bind(this);
4344
this.onSwipe = this.onSwipe.bind(this);
4445
}
4546

46-
componentWillReceiveProps(nextProps) {
47-
if ((this.props.vibrate || nextProps.vibrate) && nextProps.isOpen && !this.props.isOpen) {
47+
componentDidUpdate(prevProps) {
48+
if ((prevProps.vibrate || this.props.vibrate) && this.props.isOpen && !prevProps.isOpen) {
4849
Vibration.vibrate();
4950
}
5051
}
5152

53+
onNotificationPress() {
54+
const {
55+
onPress,
56+
onClose,
57+
} = this.props;
58+
59+
onClose();
60+
onPress();
61+
}
62+
5263
onSwipe(direction) {
5364
const { onClose } = this.props;
5465
const { SWIPE_LEFT, SWIPE_RIGHT } = swipeDirections;
@@ -64,8 +75,6 @@ class DefaultNotificationBody extends React.Component {
6475
message,
6576
iconApp,
6677
icon,
67-
onPress,
68-
onClose,
6978
} = this.props;
7079

7180
return (
@@ -74,10 +83,7 @@ class DefaultNotificationBody extends React.Component {
7483
style={styles.content}
7584
activeOpacity={0.3}
7685
underlayColor="transparent"
77-
onPress={() => {
78-
onClose();
79-
onPress();
80-
}}
86+
onPress={this.onNotificationPress}
8187
>
8288
<View style={styles.iconContainer}>
8389
{(icon || iconApp) && <Image source={icon || iconApp} style={styles.icon} />}
Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
33
import { TouchableOpacity, StatusBar, View, Text, Image, Vibration } from 'react-native';
4+
import { getStatusBarHeight, isIphoneX } from 'react-native-iphone-x-helper';
45
import GestureRecognizer, { swipeDirections } from 'react-native-swipe-gestures';
56

67
const styles = {
@@ -10,7 +11,7 @@ const styles = {
1011
},
1112
container: {
1213
position: 'absolute',
13-
top: 0,
14+
top: isIphoneX() && getStatusBarHeight(),
1415
bottom: 0,
1516
left: 0,
1617
right: 0,
@@ -60,19 +61,30 @@ class DefaultNotificationBody extends React.Component {
6061
constructor() {
6162
super();
6263

64+
this.onNotificationPress = this.onNotificationPress.bind(this);
6365
this.onSwipe = this.onSwipe.bind(this);
6466
}
6567

66-
componentWillReceiveProps(nextProps) {
67-
if (nextProps.isOpen !== this.props.isOpen) {
68-
StatusBar.setHidden(nextProps.isOpen);
68+
componentDidUpdate(prevProps) {
69+
if (this.props.isOpen !== prevProps.isOpen) {
70+
StatusBar.setHidden(this.props.isOpen);
6971
}
7072

71-
if ((this.props.vibrate || nextProps.vibrate) && nextProps.isOpen && !this.props.isOpen) {
73+
if ((prevProps.vibrate || this.props.vibrate) && this.props.isOpen && !prevProps.isOpen) {
7274
Vibration.vibrate();
7375
}
7476
}
7577

78+
onNotificationPress() {
79+
const {
80+
onPress,
81+
onClose,
82+
} = this.props;
83+
84+
onClose();
85+
onPress();
86+
}
87+
7688
onSwipe(direction) {
7789
const { SWIPE_UP } = swipeDirections;
7890

@@ -100,8 +112,6 @@ class DefaultNotificationBody extends React.Component {
100112
const {
101113
title,
102114
message,
103-
onPress,
104-
onClose,
105115
} = this.props;
106116

107117
return (
@@ -111,10 +121,7 @@ class DefaultNotificationBody extends React.Component {
111121
style={styles.content}
112122
activeOpacity={0.3}
113123
underlayColor="transparent"
114-
onPress={() => {
115-
onClose();
116-
onPress();
117-
}}
124+
onPress={this.onNotificationPress}
118125
>
119126
{this.renderIcon()}
120127
<View style={styles.textContainer}>

0 commit comments

Comments
 (0)