Skip to content

Commit

Permalink
feat: add oneSignal module
Browse files Browse the repository at this point in the history
  • Loading branch information
Pooya Parsa committed Nov 17, 2017
1 parent f1e1fe1 commit bbc7b72
Show file tree
Hide file tree
Showing 9 changed files with 231 additions and 0 deletions.
71 changes: 71 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Package | Downloads | Latest | Changelog
@nuxtjs/meta | [![npm](https://img.shields.io/npm/dt/@nuxtjs/meta.svg?style=flat-square)](https://npmjs.com/package/@nuxtjs/meta) | [![npm (scoped with tag)](https://img.shields.io/npm/v/@nuxtjs/meta/latest.svg?style=flat-square)](https://npmjs.com/package/@nuxtjs/meta) | [Changelog](https://github.com/nuxt-community/pwa-module/blob/master/packages/meta/CHANGELOG.md)
@nuxtjs/workbox | [![npm](https://img.shields.io/npm/dt/@nuxtjs/workbox.svg?style=flat-square)](https://npmjs.com/package/@nuxtjs/workbox) | [![npm (scoped with tag)](https://img.shields.io/npm/v/@nuxtjs/workbox/latest.svg?style=flat-square)](https://npmjs.com/package/@nuxtjs/workbox) | [Changelog](https://github.com/nuxt-community/pwa-module/blob/master/packages/workbox/CHANGELOG.md)
@nuxtjs/icon | [![npm](https://img.shields.io/npm/dt/@nuxtjs/icon.svg?style=flat-square)](https://www.npmjs.com/package/@nuxtjs/icon) | [![npm (scoped with tag)](https://img.shields.io/npm/v/@nuxtjs/icon/latest.svg?style=flat-square)](https://www.npmjs.com/package/@nuxtjs/icon) | [Changelog](https://github.com/nuxt-community/pwa-module/blob/master/packages/icon/CHANGELOG.md)
@nuxtjs/onesignal | [![npm](https://img.shields.io/npm/dt/@nuxtjs/onesignal.svg?style=flat-square)](https://www.npmjs.com/package/@nuxtjs/onesignal) | [![npm (scoped with tag)](https://img.shields.io/npm/v/@nuxtjs/onesignal/latest.svg?style=flat-square)](https://www.npmjs.com/package/@nuxtjs/onesignal) | [Changelog](https://github.com/nuxt-community/pwa-module/blob/master/packages/onesignal/CHANGELOG.md)

## Contents

Expand All @@ -32,6 +33,7 @@ Package | Downloads | Latest | Changelog
- [Workbox](#workbox)
- [Icon](#icon)
- [Meta](#meta)
- [OneSignal](#onesignal)

## Quick Setup

Expand Down Expand Up @@ -157,6 +159,75 @@ Please read this resources if you want to enable `mobileAppIOS` option:
- https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariHTMLRef/Articles/MetaTags.html
- https://medium.com/@firt/dont-use-ios-web-app-meta-tag-irresponsibly-in-your-progressive-web-apps-85d70f4438cb

## OneSignal
OneSignal is a Free, high volume and reliable push notification service for websites and mobile applications.[Learn More](https://documentation.onesignal.com/docs/product-overview)

Setting and and using this module is little tricky as OneSignal requires to register it's own Service worker. (see [Web Push SDK Setup (HTTPS)](https://documentation.onesignal.com/docs/web-push-sdk-setup-https))

First add dependency as it is not being installed by default when using PWA module:

```bash
yarn add @nuxtjs/onesignal
# OR
npm i @nuxtjs/onesignal
```

Then add module to `nuxt.config.js` **BEFORE** `@nuxtjs/pwa` and provide options under `oneSignal`:

```js
modules: [
'@nuxtjs/onesignal',
'@nuxtjs/pwa',
],

// Options
oneSignal: {
appId: 'YOUR_APP_ID',
// ...your other init settings
}
```

### Async Functions
This module exposes oneSignal as `$OneSignal` everywhere. So you can call it.
Please note that because of async loading of OneSignal SDK script, every action should be pushed into `$OneSignal` stack.

```js
// Inside page components
this.$OneSignal.push(() => {
this.$OneSignal.isPushNotificationsEnabled((isEnabled) => {
if (isEnabled) {
console.log('Push notifications are enabled!')
} else {
console.log('Push notifications are not enabled yet.')
}
})
})

// Using window and array form
window.$OneSignal.push(['addListenerForNotificationOpened', (data) => {
console.log('Received NotificationOpened:', data }
]);
```
### Change OneSignal SDK Script URL
By default this modules ships with latest SDK dist.
You can use recommended CDN by using `cdn: true` or changing it to a custom value using `OneSignalSDK`.
```js
oneSignal: {
// Use CDN
cdn: true,

// Use any custom URL
OneSignalSDK: 'https://cdn.onesignal.com/sdks/OneSignalSDK.js'
}
```
### References
Please see [Web Push SDK Reference](https://documentation.onesignal.com/docs/web-push-sdk) for all available options and API functions.
## License
Expand Down
1 change: 1 addition & 0 deletions packages/onesignal/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
👉 Please refer to [nuxt-community/pwa-module](https://github.com/nuxt-community/pwa-module) for documentation.
2 changes: 2 additions & 0 deletions packages/onesignal/dist/OneSignalSDK.js

Large diffs are not rendered by default.

130 changes: 130 additions & 0 deletions packages/onesignal/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
const path = require('path')
const { writeFileSync, readFileSync } = require('fs')
const hashSum = require('hash-sum')
const debug = require('debug')('nuxt:pwa')

const fixUrl = url => url.replace(/\/\//g, '/').replace(':/', '://')
const isUrl = url => url.indexOf('http') === 0 || url.indexOf('//') === 0

// =============================================
// oneSignal Module
// =============================================

module.exports = function nuxtOneSignal (moduleOptions) {
const hook = () => {
debug('Adding OneSignal')
addOneSignal.call(this, moduleOptions)
}

if (this.options.mode === 'spa') {
return hook()
}

this.nuxt.hook ? this.nuxt.hook('build:before', hook) : this.nuxt.plugin('build', hook)
}

// =============================================
// addOneSignal
// =============================================

function addOneSignal (moduleOptions) {
// Router Base
const routerBase = this.options.router.base
let publicPath = fixUrl(`${routerBase}/${this.options.build.publicPath}`)
if (isUrl(this.options.build.publicPath)) { // CDN
publicPath = this.options.build.publicPath
if (publicPath.indexOf('//') === 0) {
publicPath = '/' + publicPath // Escape fixUrl
}
}

// Merge options
const defaults = {
OneSignalSDK: undefined,
cdn: false,
GcmSenderId: '482941778795',
allowLocalhostAsSecureOrigin: true,
importScripts: [
'/sw.js'
]
}

const options = Object.assign(defaults, moduleOptions, this.options.oneSignal)

if (options.OneSignalSDK === undefined) {
if (options.cdn) {
// Use OneSignalSDK.js from CDN
options.OneSignalSDK = 'https://cdn.onesignal.com/sdks/OneSignalSDK.js'
} else {
// Use OneSignalSDK.js from Dist
const OneSignalSDKJS = readFileSync(path.resolve(__dirname, 'dist/OneSignalSDK.js'))
const OneSignalSDKHash = hashSum(OneSignalSDKJS)
const OneSignalSDKFile = `ons.${OneSignalSDKHash}.js`

options.OneSignalSDK = fixUrl(publicPath + '/' + OneSignalSDKFile)

this.options.build.plugins.push({
apply (compiler) {
compiler.plugin('emit', function (compilation, cb) {
compilation.assets[OneSignalSDKFile] = {
source: () => OneSignalSDKJS,
size: () => OneSignalSDKJS.length
}
cb()
})
}
})
}
}

// Add the oneSignal SDK script to head
this.options.head.script.push({
async: true,
src: options.OneSignalSDK
})

// Adjust manifest for oneSignal
if (!this.options.manifest) {
this.options.manifest = {}
}
if (this.options.manifest.gcm_sender_id) {
debug('WARNING: Overriding gcm_sender_id for OnSignal')
}
this.options.manifest.gcm_sender_id = options.GcmSenderId

// Adjust swURL option of Workbox for oneSignal
if (!this.options.workbox) {
this.options.workbox = {}
}
if (this.options.workbox.swURL) {
debug('WARNING: Overriding swURL for OneSignal')
}
this.options.workbox.swURL = 'OneSignalSDKWorker.js'

// Provide OneSignalSDKWorker.js and OneSignalSDKUpdaterWorker.js
const makeSW = (name, scripts) => {
const workerScript = `importScripts(${scripts.map(i => `'${i}'`).join(', ')})\r\n`
writeFileSync(path.resolve(this.options.srcDir, 'static', name), workerScript, 'utf-8')
}

makeSW('OneSignalSDKWorker.js', [].concat(options.importScripts || []).concat(options.OneSignalSDK))
makeSW('OneSignalSDKUpdaterWorker.js', [options.OneSignalSDK])

// Add OneSignal init plugin
const onsOpts = Object.assign({}, options)
delete onsOpts.OneSignalSDK
delete onsOpts.cdn
delete onsOpts.GcmSenderId
delete onsOpts.importScripts

this.addPlugin({
src: path.resolve(__dirname, 'templates/plugin.js'),
ssr: false,
fileName: 'onesignal.js',
options: {
onsOpts
}
})
}

module.exports.meta = require('./package.json')
10 changes: 10 additions & 0 deletions packages/onesignal/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "@nuxtjs/onesignal",
"version": "2.0.0",
"license": "MIT",
"main": "index.js",
"repository": "https://github.com/nuxt-community/pwa-module",
"publishConfig": {
"access": "public"
}
}
9 changes: 9 additions & 0 deletions packages/onesignal/templates/plugin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
var OneSignal = window.OneSignal || [];

OneSignal.push(['init', <%= JSON.stringify(options.onsOpts, null, 2) %>]);

window.$OneSignal = OneSignal

export default function (ctx, inject) {
inject('OneSignal', OneSignal)
}
6 changes: 6 additions & 0 deletions test/fixture/nuxt.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module.exports = {
}
},
modules: [
'@nuxtjs/onesignal',
'@nuxtjs/pwa'
],
manifest: {
Expand All @@ -23,5 +24,10 @@ module.exports = {
importScripts: [
'custom-sw.js'
]
},
oneSignal: {
appId: 'd867ac26-f7be-4c62-9fdd-b756a33c4a8f',
OneSignalSDK: 'https://cdn.onesignal.com/sdks/OneSignalSDK.js'

}
}
1 change: 1 addition & 0 deletions test/fixture/static/OneSignalSDKUpdaterWorker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
importScripts('https://cdn.onesignal.com/sdks/OneSignalSDK.js')
1 change: 1 addition & 0 deletions test/fixture/static/OneSignalSDKWorker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
importScripts('/sw.js', 'https://cdn.onesignal.com/sdks/OneSignalSDK.js')

0 comments on commit bbc7b72

Please sign in to comment.