Skip to content

Commit c30f488

Browse files
committed
Initial commit
0 parents  commit c30f488

15 files changed

+615
-0
lines changed

.editorconfig

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# EditorConfig is awesome: http://EditorConfig.org
2+
3+
# top-most EditorConfig file
4+
root = true
5+
6+
# Unix-style newlines with a newline ending every file
7+
[*]
8+
end_of_line = lf
9+
insert_final_newline = true
10+
11+
[*.js]
12+
charset = utf-8
13+
indent_style = space
14+
indent_size = 2
15+
16+
[{package.json}]
17+
indent_style = space
18+
indent_size = 2

.eslintignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
example/**
2+
node_modules/**

.eslintrc

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
{
2+
"env": {
3+
"browser": true,
4+
"node": true,
5+
"es6": true,
6+
"mocha": true
7+
},
8+
"ecmaFeatures": {
9+
"jsx": true
10+
},
11+
"parser": "babel-eslint",
12+
"plugins": [
13+
"react"
14+
],
15+
"rules": {
16+
"comma-spacing": 1,
17+
"key-spacing": 0,
18+
"no-underscore-dangle": 0,
19+
"no-unused-vars": [1, { "vars": "all", "args": "none" }],
20+
"no-var": 2,
21+
"quotes": [1, "single", "avoid-escape"],
22+
"react/display-name": 0,
23+
"react/jsx-no-undef": 1,
24+
"react/jsx-uses-react": 1,
25+
"react/no-did-mount-set-state": 1,
26+
"react/no-did-update-set-state": 1,
27+
"react/no-multi-comp": 1,
28+
"react/prop-types": [1, { "ignore": ["children", "className"] }],
29+
"react/react-in-jsx-scope": 1,
30+
"react/self-closing-comp": 1,
31+
"react/wrap-multilines": 1,
32+
"react/jsx-uses-vars": 1,
33+
"strict": 1
34+
}
35+
}

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.DS_Store
2+
node_modules
3+
npm-debug.log
4+
dist
5+
example/bundle.js

.travis.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
language: node_js
2+
node_js:
3+
- "0.10"
4+
before_install:
5+
- "export DISPLAY=:99.0"
6+
- "sh -e /etc/init.d/xvfb start"

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## Change Log
2+
3+
### Ver 0.1.0 Initial release

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
Copyright (c) 2015 Takeharu.Oshida
3+
4+
Permission is hereby granted, free of charge, to any person obtaining
5+
a copy of this software and associated documentation files (the
6+
"Software"), to deal in the Software without restriction, including
7+
without limitation the rights to use, copy, modify, merge, publish,
8+
distribute, sublicense, and/or sell copies of the Software, and to
9+
permit persons to whom the Software is furnished to do so, subject to
10+
the following conditions:
11+
12+
The above copyright notice and this permission notice shall be
13+
included in all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

README.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# React-web-notification [![Build Status](https://travis-ci.org/georgeOsdDev/react-web-notification.svg?branch=develop)](https://travis-ci.org/georgeOsdDev/react-web-notification) [![npm version](https://badge.fury.io/js/react-web-notification.svg)](http://badge.fury.io/js/react-web-notification)
2+
3+
React component with [HTML5 Web Notification API](https://developer.mozilla.org/en/docs/Web/API/notification).
4+
5+
## Demo
6+
7+
[View Demo](http://georgeosddev.github.io/react-web-notification/example/)
8+
9+
## Installation
10+
11+
```bash
12+
npm install --save react-web-notification
13+
```
14+
15+
## API
16+
17+
### `Notification`
18+
19+
React component which wrap web-notification.
20+
21+
#### Props
22+
23+
```javascript
24+
Notification.propTypes = {
25+
ignore: React.PropTypes.bool,
26+
notSupported: React.PropTypes.func,
27+
onPermissionGranted: React.PropTypes.func,
28+
onPermissionDenied: React.PropTypes.func,
29+
onShow: React.PropTypes.func,
30+
onClick: React.PropTypes.func,
31+
onClose: React.PropTypes.func,
32+
onError: React.PropTypes.func,
33+
timeout: React.PropTypes.number,
34+
title: React.PropTypes.string.isRequired,
35+
options: React.PropTypes.object
36+
};
37+
38+
```
39+
40+
* `ignore` : if true, nothing will be happen
41+
42+
* `notSupported()` : Called when [HTML5 Web Notification API](https://developer.mozilla.org/en/docs/Web/API/notification) is not supported.
43+
44+
* `onPermissionGranted()` : Called when permission granted.
45+
46+
* `onPermissionDenied()` : Called when permission denied. `Notification` will do nothing until permission granted again.
47+
48+
* `onShow(e, tag)` : Called when Desktop notification is shown.
49+
50+
* `onClick(e, tag)` : Called when Desktop notification is clicked.
51+
52+
* `onClose(e, tag)` : Called when Desktop notification is closed.
53+
54+
* `onError(e, tag)` : Called when Desktop notification happen error.
55+
56+
* `timeout` : milli sec to close notification automatically.(Default 5000)
57+
58+
* `title` : Notification title.
59+
60+
* `options` : Notification options. set `body`, `tag`, `icon` here.
61+
See also (https://developer.mozilla.org/en-US/docs/Web/API/Notification/Notification)
62+
63+
64+
## Usage example
65+
66+
See [example](https://github.com/georgeOsdDev/react-web-notification/tree/develop/example)
67+
68+
```bash
69+
npm install
70+
npm run start:example
71+
```
72+
73+
## Tests
74+
75+
```bash
76+
npm test
77+
```

components/Notification.js

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
'use strict';
2+
3+
import React from 'react';
4+
5+
const PERMISSION_GRANTED = 'granted';
6+
7+
const seqGen = () => {
8+
let i = 0;
9+
return () => {
10+
return i++;
11+
};
12+
};
13+
const seq = seqGen();
14+
15+
class Notification extends React.Component {
16+
constructor(props) {
17+
super(props);
18+
19+
let supported = false;
20+
let granted = false;
21+
if (!('Notification' in window)) {
22+
supported = false;
23+
} else {
24+
supported = true;
25+
if (window.Notification.permission === PERMISSION_GRANTED) {
26+
granted = true;
27+
}
28+
}
29+
30+
this.state = {
31+
supported: supported,
32+
granted: granted
33+
};
34+
// Do not save Notification instance in state
35+
this.notifications = {};
36+
}
37+
38+
componentDidMount(){
39+
if (!this.state.supported) {
40+
this.props.notSupported();
41+
} else {
42+
if(this.state.granted) {
43+
this.props.onPermissionGranted();
44+
} else {
45+
window.Notification.requestPermission( (permission) => {
46+
let result = permission === PERMISSION_GRANTED;
47+
this.setState({
48+
granted: result
49+
}, () => {
50+
if (result) {
51+
this.props.onPermissionGranted();
52+
} else {
53+
this.props.onPermissionDenied();
54+
}
55+
});
56+
});
57+
}
58+
}
59+
}
60+
61+
render() {
62+
if (!this.props.ignore && this.props.title && this.state.supported && this.state.granted) {
63+
64+
let opt = this.props.options;
65+
if (typeof opt.tag !== 'string') {
66+
opt.tag = 'web-notification-' + seq();
67+
}
68+
69+
let n = new window.Notification(this.props.title, opt);
70+
n.onshow = (e) => {
71+
this.props.onShow(e, opt.tag);
72+
setTimeout(() => {
73+
this.close(opt.tag);
74+
}, this.props.timeout);
75+
};
76+
n.onclick = (e) => {this.props.onClick(e, opt.tag); };
77+
n.onclose = (e) => {this.props.onClose(e, opt.tag); };
78+
n.onerror = (e) => {this.props.onError(e, opt.tag); };
79+
this.notifications[opt.tag] = n;
80+
}
81+
82+
// is this neccessary?
83+
return (
84+
<input type='hidden' name='dummy-for-react-web-notification' style={{display: 'none'}} />
85+
);
86+
}
87+
88+
close(tag) {
89+
if (this.notifications[tag] && typeof this.notifications[tag].close === 'function') {
90+
this.notifications[tag].close();
91+
}
92+
}
93+
}
94+
95+
Notification.propTypes = {
96+
ignore: React.PropTypes.bool,
97+
notSupported: React.PropTypes.func,
98+
onPermissionGranted: React.PropTypes.func,
99+
onPermissionDenied: React.PropTypes.func,
100+
onShow: React.PropTypes.func,
101+
onClick: React.PropTypes.func,
102+
onClose: React.PropTypes.func,
103+
onError: React.PropTypes.func,
104+
timeout: React.PropTypes.number,
105+
title: React.PropTypes.string.isRequired,
106+
options: React.PropTypes.object
107+
};
108+
109+
Notification.defaultProps = {
110+
ignore: false,
111+
notSupported: () => {},
112+
onPermissionGranted: () => {},
113+
onPermissionDenied: () => {},
114+
onShow: () => {},
115+
onClick: () => {},
116+
onClose: () => {},
117+
onError: () => {},
118+
timeout: 5000,
119+
options: {}
120+
};
121+
122+
export default Notification;

example/Notifications_button_24.png

325 Bytes
Loading

0 commit comments

Comments
 (0)