First version
This commit is contained in:
commit
cc019b423f
96
.gitignore
vendored
Executable file
96
.gitignore
vendored
Executable file
@ -0,0 +1,96 @@
|
||||
# See https://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# TypeScript v1 declaration files
|
||||
typings/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
|
||||
# next.js build output
|
||||
.next
|
||||
|
||||
# nuxt.js build output
|
||||
.nuxt
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# Serverless directories
|
||||
.serverless
|
11585
package-lock.json
generated
Executable file
11585
package-lock.json
generated
Executable file
File diff suppressed because it is too large
Load Diff
19
package.json
Executable file
19
package.json
Executable file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "rnn-chat",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"axios": "^0.18.0",
|
||||
"chat-template": "0.0.26",
|
||||
"react": "^16.4.1",
|
||||
"react-chat-bubble": "^0.8.7",
|
||||
"react-dom": "^16.4.1",
|
||||
"react-scripts": "1.1.4"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test --env=jsdom",
|
||||
"eject": "react-scripts eject"
|
||||
}
|
||||
}
|
BIN
public/favicon.ico
Executable file
BIN
public/favicon.ico
Executable file
Binary file not shown.
After Width: | Height: | Size: 3.8 KiB |
40
public/index.html
Executable file
40
public/index.html
Executable file
@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="theme-color" content="#000000">
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is added to the
|
||||
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
||||
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>React App</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
You need to enable JavaScript to run this app.
|
||||
</noscript>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
</html>
|
15
public/manifest.json
Executable file
15
public/manifest.json
Executable file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
}
|
||||
],
|
||||
"start_url": "./index.html",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
38
src/App.css
Executable file
38
src/App.css
Executable file
@ -0,0 +1,38 @@
|
||||
.App {
|
||||
text-align: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
|
||||
}
|
||||
|
||||
#root {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.App-logo {
|
||||
animation: App-logo-spin infinite 20s linear;
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
.App-header {
|
||||
background-color: #222;
|
||||
height: 150px;
|
||||
padding: 20px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.App-title {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.App-intro {
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
@keyframes App-logo-spin {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
99
src/App.js
Executable file
99
src/App.js
Executable file
@ -0,0 +1,99 @@
|
||||
import React, { Component } from 'react';
|
||||
import logo from './logo.svg';
|
||||
import './App.css';
|
||||
|
||||
import ChatBubble from './react-chat-bubble/src/components/ChatBubble';
|
||||
|
||||
import axios from 'axios';
|
||||
|
||||
|
||||
|
||||
class App extends Component {
|
||||
|
||||
|
||||
state = {
|
||||
messages: [
|
||||
{
|
||||
type: 1,
|
||||
image: "https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Default_profile_picture_%28male%29_on_Facebook.jpg/240px-Default_profile_picture_%28male%29_on_Facebook.jpg",
|
||||
text: "Hello! Type something!"
|
||||
}
|
||||
],
|
||||
disabled : false
|
||||
};
|
||||
|
||||
handleNewMessage = async (text) =>
|
||||
{
|
||||
|
||||
console.log("!!! handleNewMessage");
|
||||
|
||||
await this.setState({
|
||||
messages: this.state.messages.concat([{
|
||||
text: text,
|
||||
type: 0,
|
||||
image: "https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Default_profile_picture_%28male%29_on_Facebook.jpg/240px-Default_profile_picture_%28male%29_on_Facebook.jpg"
|
||||
}])
|
||||
|
||||
});
|
||||
|
||||
try {
|
||||
|
||||
await this.setState({
|
||||
messages: this.state.messages.concat([{
|
||||
text : "Wait, I am processing...",
|
||||
type: 1,
|
||||
image: "https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Default_profile_picture_%28male%29_on_Facebook.jpg/240px-Default_profile_picture_%28male%29_on_Facebook.jpg"
|
||||
}]),
|
||||
disabled: true
|
||||
});
|
||||
|
||||
|
||||
|
||||
let response = await axios.get('http://localhost:3001', {
|
||||
params: {
|
||||
phrase: text
|
||||
},
|
||||
responseType: 'text'
|
||||
});
|
||||
|
||||
|
||||
console.log("!!! RESPONSE");
|
||||
console.log(response);
|
||||
console.log(response.data);
|
||||
|
||||
await this.setState({
|
||||
messages: this.state.messages.concat([{
|
||||
text : response.data,
|
||||
type: 1,
|
||||
image: "https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Default_profile_picture_%28male%29_on_Facebook.jpg/240px-Default_profile_picture_%28male%29_on_Facebook.jpg"
|
||||
}]),
|
||||
disabled: false
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
componentWillMount(){
|
||||
document.body.style.height = "100%";
|
||||
}
|
||||
|
||||
componentWillUnmount(){
|
||||
//document.body.style.backgroundColor = null;
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
return <ChatBubble messages={this.state.messages}
|
||||
onNewMessage={this.handleNewMessage} disabled={this.state.disabled}/>
|
||||
}
|
||||
}
|
||||
export default App;
|
9
src/App.test.js
Executable file
9
src/App.test.js
Executable file
@ -0,0 +1,9 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import App from './App';
|
||||
|
||||
it('renders without crashing', () => {
|
||||
const div = document.createElement('div');
|
||||
ReactDOM.render(<App />, div);
|
||||
ReactDOM.unmountComponentAtNode(div);
|
||||
});
|
5
src/index.css
Executable file
5
src/index.css
Executable file
@ -0,0 +1,5 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: sans-serif;
|
||||
}
|
8
src/index.js
Executable file
8
src/index.js
Executable file
@ -0,0 +1,8 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import './index.css';
|
||||
import App from './App';
|
||||
import registerServiceWorker from './registerServiceWorker';
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById('root'));
|
||||
registerServiceWorker();
|
7
src/logo.svg
Executable file
7
src/logo.svg
Executable file
@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3">
|
||||
<g fill="#61DAFB">
|
||||
<path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/>
|
||||
<circle cx="420.9" cy="296.5" r="45.7"/>
|
||||
<path d="M520.5 78.1z"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.6 KiB |
17
src/react-chat-bubble/.babelrc
Executable file
17
src/react-chat-bubble/.babelrc
Executable file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"presets": [
|
||||
[
|
||||
"env",
|
||||
{
|
||||
"targets": {
|
||||
"browsers": [
|
||||
"last 2 versions",
|
||||
"safari >= 7"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"react"
|
||||
],
|
||||
"plugins": ["transform-class-properties"]
|
||||
}
|
1
src/react-chat-bubble/.npmignore
Executable file
1
src/react-chat-bubble/.npmignore
Executable file
@ -0,0 +1 @@
|
||||
/node_modules
|
67
src/react-chat-bubble/README.md
Executable file
67
src/react-chat-bubble/README.md
Executable file
@ -0,0 +1,67 @@
|
||||
|
||||
A Chat bubble component for building Chat App in ReactJS.
|
||||
|
||||
## Demo
|
||||
![Alt Chatbubble](https://raw.githubusercontent.com/sabinbajracharya/react-chat-bubble/master/screenshots/chatbubble.png?raw=true "Chatbubble")
|
||||
|
||||
## Installing the react-chat-bubble
|
||||
|
||||
```
|
||||
npm install --save react-chat-bubble
|
||||
```
|
||||
|
||||
## Using the Component
|
||||
|
||||
If you are using ES6 modules, if not, you are encouraged to use [`import` and `export`](http://exploringjs.com/es6/ch_modules.html) instead.
|
||||
|
||||
Example:
|
||||
|
||||
```js
|
||||
import ChatBubble from 'react-chat-bubble';
|
||||
|
||||
class App extends Component {
|
||||
render() {
|
||||
<ChatBubble messages = {this.state.messages} />
|
||||
}
|
||||
}
|
||||
export default App;
|
||||
```
|
||||
|
||||
The message object passed as prop should be of following format:
|
||||
```json
|
||||
this.state.messages =
|
||||
[{
|
||||
"type" : 0,
|
||||
"image": "cat.jpg",
|
||||
"text": "Hello! Good Morning!"
|
||||
}, {
|
||||
"type": 1,
|
||||
"image": "dog.jpg",
|
||||
"text": "Hello! Good Afternoon!"
|
||||
}];
|
||||
|
||||
```
|
||||
```
|
||||
type = 0 for sender AND 1 for receiver
|
||||
image = url of contact image
|
||||
text = message from the user
|
||||
```
|
||||
|
||||
## To-do
|
||||
```
|
||||
> More style customization
|
||||
> Delivered and seen status
|
||||
```
|
||||
|
||||
|
||||
##License
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 Sabin Bir Bajracharya.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
25
src/react-chat-bubble/build/ChatBubble.js
vendored
Executable file
25
src/react-chat-bubble/build/ChatBubble.js
vendored
Executable file
File diff suppressed because one or more lines are too long
1
src/react-chat-bubble/build/ChatBubble.js.map
Executable file
1
src/react-chat-bubble/build/ChatBubble.js.map
Executable file
@ -0,0 +1 @@
|
||||
{"version":3,"file":"ChatBubble.js","sources":["webpack:///ChatBubble.js"],"mappings":"AAAA;;;;;AA0SA;AAm6IA;;;;;;;;;;;;;;AAkhBA;AAipIA;AAgjJA;AAy/HA","sourceRoot":""}
|
20
src/react-chat-bubble/build/index.html
Executable file
20
src/react-chat-bubble/build/index.html
Executable file
@ -0,0 +1,20 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
html, body, #root {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
<script type="text/javascript" src="ChatBubble.js" charset="utf-8"></script>
|
||||
</body>
|
||||
</html>
|
100
src/react-chat-bubble/lib/ChatBubble.css
Executable file
100
src/react-chat-bubble/lib/ChatBubble.css
Executable file
@ -0,0 +1,100 @@
|
||||
.bubble-container{
|
||||
margin-top: 8px;
|
||||
margin-bottom: 8px;
|
||||
display:flex;
|
||||
font-family: sans-serif;
|
||||
font-size: 14px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.bubble-direction-reverse {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
.bubble{
|
||||
background-color: #F2F2F2;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 0 6px #B2B2B2;
|
||||
display: block;
|
||||
padding: 10px 18px;
|
||||
position: relative;
|
||||
vertical-align: top;
|
||||
color: white;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.bubble::before {
|
||||
background-color: #F2F2F2;
|
||||
content: "\00a0";
|
||||
display: block;
|
||||
height: 16px;
|
||||
position: absolute;
|
||||
top: 11px;
|
||||
transform: rotate( 29deg ) skew( -35deg );
|
||||
-moz-transform: rotate( 29deg ) skew( -35deg );
|
||||
-ms-transform: rotate( 29deg ) skew( -35deg );
|
||||
-o-transform: rotate( 29deg ) skew( -35deg );
|
||||
-webkit-transform: rotate( 29deg ) skew( -35deg );
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.me {
|
||||
background-color: #8f5db7;
|
||||
margin-left: 18px;
|
||||
margin-right:60px;
|
||||
}
|
||||
|
||||
.me::before {
|
||||
box-shadow: -2px 2px 2px 0 rgba( 178, 178, 178, .4 );
|
||||
left: -9px;
|
||||
background-color: #8f5db7;
|
||||
}
|
||||
|
||||
.you {
|
||||
background-color: #087FFE;
|
||||
margin-left: 60px;
|
||||
margin-right:18px;
|
||||
}
|
||||
|
||||
.you::before {
|
||||
box-shadow: 2px -2px 2px 0 rgba( 178, 178, 178, .4 );
|
||||
right: -9px;
|
||||
background-color: #087FFE;
|
||||
}
|
||||
|
||||
.img-circle {
|
||||
border-radius: 42%;
|
||||
height:42px;
|
||||
width:42px;
|
||||
}
|
||||
|
||||
.chats {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.chat-list {
|
||||
height: calc(100% - 3rem);
|
||||
overflow-y: scroll;
|
||||
padding: 1rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.new-message {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: #087FFE;
|
||||
height: 3rem;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.new-message-input {
|
||||
width: 99%;
|
||||
height: 80%;
|
||||
font-size: 1.5rem;
|
||||
}
|
134
src/react-chat-bubble/lib/ChatBubble.js
vendored
Executable file
134
src/react-chat-bubble/lib/ChatBubble.js
vendored
Executable file
@ -0,0 +1,134 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
||||
|
||||
var _react = require('react');
|
||||
|
||||
var _react2 = _interopRequireDefault(_react);
|
||||
|
||||
var _propTypes = require('prop-types');
|
||||
|
||||
var _propTypes2 = _interopRequireDefault(_propTypes);
|
||||
|
||||
require('./ChatBubble.css');
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
||||
|
||||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||||
|
||||
var ChatBubble = function (_Component) {
|
||||
_inherits(ChatBubble, _Component);
|
||||
|
||||
function ChatBubble() {
|
||||
var _ref;
|
||||
|
||||
var _temp, _this, _ret;
|
||||
|
||||
_classCallCheck(this, ChatBubble);
|
||||
|
||||
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
|
||||
args[_key] = arguments[_key];
|
||||
}
|
||||
|
||||
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = ChatBubble.__proto__ || Object.getPrototypeOf(ChatBubble)).call.apply(_ref, [this].concat(args))), _this), _this.state = {
|
||||
newMessage: ''
|
||||
}, _this.handleSubmit = function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var _this2 = _this,
|
||||
onNewMessage = _this2.props.onNewMessage,
|
||||
newMessage = _this2.state.newMessage;
|
||||
|
||||
|
||||
if (onNewMessage && newMessage) {
|
||||
onNewMessage(newMessage);
|
||||
}
|
||||
|
||||
_this.setState({
|
||||
newMessage: ''
|
||||
});
|
||||
}, _this.handleInputChange = function (e) {
|
||||
return _this.setState({
|
||||
newMessage: e.target.value
|
||||
});
|
||||
}, _temp), _possibleConstructorReturn(_this, _ret);
|
||||
}
|
||||
|
||||
_createClass(ChatBubble, [{
|
||||
key: 'getConversations',
|
||||
value: function getConversations(messages) {
|
||||
if (messages == undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
var listItems = messages.map(function (message, index) {
|
||||
var bubbleClass = 'me';
|
||||
var bubbleDirection = '';
|
||||
|
||||
if (message.type === 0) {
|
||||
bubbleClass = 'you';
|
||||
bubbleDirection = "bubble-direction-reverse";
|
||||
}
|
||||
return _react2.default.createElement(
|
||||
'div',
|
||||
{ className: 'bubble-container ' + bubbleDirection, key: index },
|
||||
_react2.default.createElement('img', { className: 'img-circle', src: message.image }),
|
||||
_react2.default.createElement(
|
||||
'div',
|
||||
{ className: 'bubble ' + bubbleClass },
|
||||
message.text
|
||||
)
|
||||
);
|
||||
});
|
||||
return listItems;
|
||||
}
|
||||
}, {
|
||||
key: 'render',
|
||||
value: function render() {
|
||||
var messages = this.props.messages,
|
||||
newMessage = this.state.newMessage;
|
||||
|
||||
var chatList = this.getConversations(messages);
|
||||
|
||||
return _react2.default.createElement(
|
||||
'div',
|
||||
{ className: 'chats' },
|
||||
_react2.default.createElement(
|
||||
'div',
|
||||
{ className: 'chat-list' },
|
||||
chatList
|
||||
),
|
||||
_react2.default.createElement(
|
||||
'form',
|
||||
{
|
||||
className: 'new-message',
|
||||
onSubmit: this.handleSubmit
|
||||
},
|
||||
_react2.default.createElement('input', {
|
||||
value: newMessage,
|
||||
placeholder: 'Write a new message',
|
||||
onChange: this.handleInputChange,
|
||||
className: 'new-message-input'
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
}]);
|
||||
|
||||
return ChatBubble;
|
||||
}(_react.Component);
|
||||
|
||||
ChatBubble.propTypes = {
|
||||
messages: _propTypes2.default.array.isRequired,
|
||||
onNewMessage: _propTypes2.default.func.isRequired
|
||||
};
|
||||
|
||||
exports.default = ChatBubble;
|
4187
src/react-chat-bubble/package-lock.json
generated
Executable file
4187
src/react-chat-bubble/package-lock.json
generated
Executable file
File diff suppressed because it is too large
Load Diff
80
src/react-chat-bubble/package.json
Executable file
80
src/react-chat-bubble/package.json
Executable file
@ -0,0 +1,80 @@
|
||||
{
|
||||
"_from": "react-chat-bubble",
|
||||
"_id": "react-chat-bubble@0.8.7",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-CbXbVNHJi0Zdl4fJQPDDwVp5IxE=",
|
||||
"_location": "/react-chat-bubble",
|
||||
"_phantomChildren": {
|
||||
"create-react-class": "15.6.3",
|
||||
"fbjs": "0.8.17",
|
||||
"loose-envify": "1.3.1",
|
||||
"object-assign": "4.1.1",
|
||||
"prop-types": "15.6.2"
|
||||
},
|
||||
"_requested": {
|
||||
"type": "tag",
|
||||
"registry": true,
|
||||
"raw": "react-chat-bubble",
|
||||
"name": "react-chat-bubble",
|
||||
"escapedName": "react-chat-bubble",
|
||||
"rawSpec": "",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "latest"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"#USER",
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/react-chat-bubble/-/react-chat-bubble-0.8.7.tgz",
|
||||
"_shasum": "09b5db54d1c98b465d9787c940f0c3c15a792311",
|
||||
"_spec": "react-chat-bubble",
|
||||
"_where": "D:\\Work\\nodejsprojects\\rnn-chat",
|
||||
"author": {
|
||||
"name": "Sabin Bajracharya"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/sabinbajracharya/react-chat-bubble/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"prop-types": "^15.5.10",
|
||||
"react": "^15.4.2",
|
||||
"react-dom": "^15.4.2"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "A chat bubble component for ReactJS",
|
||||
"devDependencies": {
|
||||
"babel-cli": "^6.24.1",
|
||||
"babel-core": "^6.22.1",
|
||||
"babel-loader": "^6.2.10",
|
||||
"babel-plugin-transform-class-properties": "^6.24.1",
|
||||
"babel-preset-env": "^1.6.0",
|
||||
"babel-preset-react": "^6.22.0",
|
||||
"css-loader": "^0.26.1",
|
||||
"style-loader": "^0.13.1",
|
||||
"webpack": "^1.14.0"
|
||||
},
|
||||
"homepage": "https://github.com/sabinbajracharya/react-chat-bubble#readme",
|
||||
"keywords": [
|
||||
"chat",
|
||||
"bubble",
|
||||
"reactjs",
|
||||
"component",
|
||||
"conversation",
|
||||
"ui"
|
||||
],
|
||||
"license": "ISC",
|
||||
"main": "lib/ChatBubble.js",
|
||||
"name": "react-chat-bubble",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/sabinbajracharya/react-chat-bubble.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "webpack --progress --colors --p",
|
||||
"start": "webpack --progress --colors --watch -d",
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"transpile": "babel ./src/components/ChatBubble.js --out-file lib/ChatBubble.js"
|
||||
},
|
||||
"version": "0.8.7"
|
||||
}
|
BIN
src/react-chat-bubble/screenshots/chatbubble.png
Executable file
BIN
src/react-chat-bubble/screenshots/chatbubble.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 46 KiB |
100
src/react-chat-bubble/src/components/ChatBubble.css
Executable file
100
src/react-chat-bubble/src/components/ChatBubble.css
Executable file
@ -0,0 +1,100 @@
|
||||
.bubble-container{
|
||||
margin-top: 8px;
|
||||
margin-bottom: 8px;
|
||||
display:flex;
|
||||
font-family: sans-serif;
|
||||
font-size: 14px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.bubble-direction-reverse {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
.bubble{
|
||||
background-color: #F2F2F2;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 0 6px #B2B2B2;
|
||||
display: block;
|
||||
padding: 10px 18px;
|
||||
position: relative;
|
||||
vertical-align: top;
|
||||
color: white;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.bubble::before {
|
||||
background-color: #F2F2F2;
|
||||
content: "\00a0";
|
||||
display: block;
|
||||
height: 16px;
|
||||
position: absolute;
|
||||
top: 11px;
|
||||
transform: rotate( 29deg ) skew( -35deg );
|
||||
-moz-transform: rotate( 29deg ) skew( -35deg );
|
||||
-ms-transform: rotate( 29deg ) skew( -35deg );
|
||||
-o-transform: rotate( 29deg ) skew( -35deg );
|
||||
-webkit-transform: rotate( 29deg ) skew( -35deg );
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.me {
|
||||
background-color: #8f5db7;
|
||||
margin-left: 18px;
|
||||
margin-right:60px;
|
||||
}
|
||||
|
||||
.me::before {
|
||||
box-shadow: -2px 2px 2px 0 rgba( 178, 178, 178, .4 );
|
||||
left: -9px;
|
||||
background-color: #8f5db7;
|
||||
}
|
||||
|
||||
.you {
|
||||
background-color: #087FFE;
|
||||
margin-left: 60px;
|
||||
margin-right:18px;
|
||||
}
|
||||
|
||||
.you::before {
|
||||
box-shadow: 2px -2px 2px 0 rgba( 178, 178, 178, .4 );
|
||||
right: -9px;
|
||||
background-color: #087FFE;
|
||||
}
|
||||
|
||||
.img-circle {
|
||||
border-radius: 42%;
|
||||
height:42px;
|
||||
width:42px;
|
||||
}
|
||||
|
||||
.chats {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.chat-list {
|
||||
height: calc(100% - 3rem);
|
||||
overflow-y: scroll;
|
||||
padding: 1rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.new-message {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: #087FFE;
|
||||
height: 3rem;
|
||||
margin: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.new-message-input {
|
||||
width: 99%;
|
||||
height: 80%;
|
||||
font-size: 1.5rem;
|
||||
}
|
83
src/react-chat-bubble/src/components/ChatBubble.js
vendored
Executable file
83
src/react-chat-bubble/src/components/ChatBubble.js
vendored
Executable file
@ -0,0 +1,83 @@
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types'
|
||||
import './ChatBubble.css';
|
||||
|
||||
class ChatBubble extends Component {
|
||||
state = {
|
||||
newMessage: ''
|
||||
}
|
||||
|
||||
getConversations(messages){
|
||||
if(messages == undefined){
|
||||
return;
|
||||
}
|
||||
|
||||
const listItems = messages.map((message, index) => {
|
||||
let bubbleClass = 'me';
|
||||
let bubbleDirection = '';
|
||||
|
||||
if(message.type === 0){
|
||||
bubbleClass = 'you';
|
||||
bubbleDirection = "bubble-direction-reverse";
|
||||
}
|
||||
return (
|
||||
<div className={`bubble-container ${bubbleDirection}`} key={index}>
|
||||
<img className={`img-circle`} src={message.image} />
|
||||
<div className={`bubble ${bubbleClass}`}>{message.text}</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
return listItems;
|
||||
}
|
||||
|
||||
handleSubmit = e => {
|
||||
e.preventDefault()
|
||||
|
||||
const {props: {onNewMessage}, state: {newMessage}} = this
|
||||
|
||||
if(onNewMessage && newMessage) {
|
||||
onNewMessage(newMessage)
|
||||
}
|
||||
|
||||
this.setState({
|
||||
newMessage: '',
|
||||
})
|
||||
}
|
||||
|
||||
handleInputChange = e => this.setState({
|
||||
newMessage: e.target.value,
|
||||
})
|
||||
|
||||
render() {
|
||||
const {props: {messages, disabled}, state: {newMessage}} = this;
|
||||
const chatList = this.getConversations(messages);
|
||||
|
||||
return (
|
||||
<div className="chats">
|
||||
<div className="chat-list">
|
||||
{chatList}
|
||||
</div>
|
||||
<form
|
||||
className="new-message"
|
||||
onSubmit={this.handleSubmit}
|
||||
>
|
||||
<input
|
||||
value={newMessage}
|
||||
placeholder="Write a new message"
|
||||
onChange={this.handleInputChange}
|
||||
className="new-message-input"
|
||||
|
||||
disabled={disabled}
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ChatBubble.propTypes = {
|
||||
messages: PropTypes.array.isRequired,
|
||||
onNewMessage: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default ChatBubble;
|
46
src/react-chat-bubble/src/index.js
vendored
Executable file
46
src/react-chat-bubble/src/index.js
vendored
Executable file
@ -0,0 +1,46 @@
|
||||
import React, { Component } from "react";
|
||||
import ReactDOM from "react-dom";
|
||||
import ChatBubble from "./components/ChatBubble";
|
||||
|
||||
|
||||
const image = 'http://www.bradfordwhite.com/sites/default/files/images/corporate_imgs/iStock_000012107870XSmall.jpg';
|
||||
|
||||
class App extends Component {
|
||||
state = {
|
||||
messages: [
|
||||
{
|
||||
type: 0,
|
||||
image,
|
||||
text: "Hello! Good Morning!"
|
||||
},
|
||||
{
|
||||
type: 1,
|
||||
image,
|
||||
text: "Hello! Good Afternoon!"
|
||||
}
|
||||
],
|
||||
};
|
||||
|
||||
handleNewMessage = text =>
|
||||
this.setState({
|
||||
messages: this.state.messages.concat([{
|
||||
text,
|
||||
type: 0,
|
||||
image,
|
||||
}])
|
||||
});
|
||||
|
||||
render() {
|
||||
return (
|
||||
<ChatBubble
|
||||
messages={this.state.messages}
|
||||
onNewMessage={this.handleNewMessage}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<App/>,
|
||||
document.getElementById('root')
|
||||
);
|
30
src/react-chat-bubble/webpack.config.js
Executable file
30
src/react-chat-bubble/webpack.config.js
Executable file
@ -0,0 +1,30 @@
|
||||
const webpack = require('webpack');
|
||||
module.exports = {
|
||||
//devtool:'source-map',
|
||||
devtool: 'cheap-module-source-map',
|
||||
entry: './src/index.js',
|
||||
output: {
|
||||
path: __dirname + "/build",
|
||||
filename: "ChatBubble.js"
|
||||
},
|
||||
module: {
|
||||
loaders: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
loader: "babel-loader"
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
loaders: [ 'style-loader', 'css-loader' ]
|
||||
}
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
'NODE_ENV': JSON.stringify('production')
|
||||
}
|
||||
})
|
||||
]
|
||||
};
|
2889
src/react-chat-bubble/yarn.lock
Executable file
2889
src/react-chat-bubble/yarn.lock
Executable file
File diff suppressed because it is too large
Load Diff
117
src/registerServiceWorker.js
Executable file
117
src/registerServiceWorker.js
Executable file
@ -0,0 +1,117 @@
|
||||
// In production, we register a service worker to serve assets from local cache.
|
||||
|
||||
// This lets the app load faster on subsequent visits in production, and gives
|
||||
// it offline capabilities. However, it also means that developers (and users)
|
||||
// will only see deployed updates on the "N+1" visit to a page, since previously
|
||||
// cached resources are updated in the background.
|
||||
|
||||
// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
|
||||
// This link also includes instructions on opting out of this behavior.
|
||||
|
||||
const isLocalhost = Boolean(
|
||||
window.location.hostname === 'localhost' ||
|
||||
// [::1] is the IPv6 localhost address.
|
||||
window.location.hostname === '[::1]' ||
|
||||
// 127.0.0.1/8 is considered localhost for IPv4.
|
||||
window.location.hostname.match(
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||
)
|
||||
);
|
||||
|
||||
export default function register() {
|
||||
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
|
||||
// The URL constructor is available in all browsers that support SW.
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
|
||||
if (publicUrl.origin !== window.location.origin) {
|
||||
// Our service worker won't work if PUBLIC_URL is on a different origin
|
||||
// from what our page is served on. This might happen if a CDN is used to
|
||||
// serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
|
||||
return;
|
||||
}
|
||||
|
||||
window.addEventListener('load', () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
|
||||
|
||||
if (isLocalhost) {
|
||||
// This is running on localhost. Lets check if a service worker still exists or not.
|
||||
checkValidServiceWorker(swUrl);
|
||||
|
||||
// Add some additional logging to localhost, pointing developers to the
|
||||
// service worker/PWA documentation.
|
||||
navigator.serviceWorker.ready.then(() => {
|
||||
console.log(
|
||||
'This web app is being served cache-first by a service ' +
|
||||
'worker. To learn more, visit https://goo.gl/SC7cgQ'
|
||||
);
|
||||
});
|
||||
} else {
|
||||
// Is not local host. Just register service worker
|
||||
registerValidSW(swUrl);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function registerValidSW(swUrl) {
|
||||
navigator.serviceWorker
|
||||
.register(swUrl)
|
||||
.then(registration => {
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
installingWorker.onstatechange = () => {
|
||||
if (installingWorker.state === 'installed') {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// At this point, the old content will have been purged and
|
||||
// the fresh content will have been added to the cache.
|
||||
// It's the perfect time to display a "New content is
|
||||
// available; please refresh." message in your web app.
|
||||
console.log('New content is available; please refresh.');
|
||||
} else {
|
||||
// At this point, everything has been precached.
|
||||
// It's the perfect time to display a
|
||||
// "Content is cached for offline use." message.
|
||||
console.log('Content is cached for offline use.');
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error during service worker registration:', error);
|
||||
});
|
||||
}
|
||||
|
||||
function checkValidServiceWorker(swUrl) {
|
||||
// Check if the service worker can be found. If it can't reload the page.
|
||||
fetch(swUrl)
|
||||
.then(response => {
|
||||
// Ensure service worker exists, and that we really are getting a JS file.
|
||||
if (
|
||||
response.status === 404 ||
|
||||
response.headers.get('content-type').indexOf('javascript') === -1
|
||||
) {
|
||||
// No service worker found. Probably a different app. Reload the page.
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister().then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// Service worker found. Proceed as normal.
|
||||
registerValidSW(swUrl);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
console.log(
|
||||
'No internet connection found. App is running in offline mode.'
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export function unregister() {
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister();
|
||||
});
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user