diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c81038..9960917 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 2.3.4 +## 2.3.5 - Fix(no provider for rendered2) closes [#28](https://github.com/MurhafSousli/ngx-disqus/issues/28) diff --git a/lib/README.md b/lib/README.md new file mode 100644 index 0000000..75b5448 --- /dev/null +++ b/lib/README.md @@ -0,0 +1,107 @@ +

+ +

Angular Disqus Module

+

+ +Add Disqus to your app instantly! + +[![npm](https://img.shields.io/badge/demo-online-ed1c46.svg)](https://murhafsousli.github.io/ngx-disqus/) +[![npm](https://img.shields.io/npm/v/ngx-disqus.svg)](https://www.npmjs.com/package/ngx-disqus) +[![Build Status](https://travis-ci.org/MurhafSousli/ngx-disqus.svg)](https://travis-ci.org/MurhafSousli/ngx-disqus) +[![npm](https://img.shields.io/npm/l/express.svg?maxAge=2592000)](/LICENSE) + +## Installation + +Install it with npm + +```bash +$ npm install --save ngx-disqus +``` + +### SystemJS + +If you are using SystemJS, you should also adjust your configuration to point to the UMD bundle. + +In your systemjs config file, map needs to tell the System loader where to look for ngx-disqus: + +```ts +map: { + 'ngx-disqus': 'node_modules/ngx-disqus/bundles/ngx-disqus.umd.js', +} +``` + +Here is a [stackblitz](https://stackblitz.com/edit/ngx-disqus) + +## Usage + +Import `DisqusModule` in the root module + +```ts +import { DisqusModule } from "ngx-disqus"; +@NgModule({ + imports: [ + // ... + DisqusModule.forRoot('disqus_shortname') + ] +}) +``` + +The paramter `shortname` is the unique identifier for your website as registered on Disqus, make sure it is defined in your module. + +Now you can add Disqus component + +```ts +@Component({ + selector: 'any-component', + template: `` +}) +export class AnyComponent { + + pageId = '/about'; +} +``` + +Disqus component requires the `identifier` input to work properly on your app +For example If the page URL is `localhost:4200/about` then the identifier should be `/about`. + +## More Options + +See Disqus official documentation ([JavaScript configuration variables](https://help.disqus.com/customer/portal/articles/472098-javascript-configuration-variables)) before using these inputs. + +```ts + +``` + +___ + +### NOTE + +The HashLocationStrategy is not compatible with Disqus + +For more info check [DISQUS on ajax sites](https://help.disqus.com/customer/portal/articles/472107-using-disqus-on-ajax-sites) + +___ + +## Issues + +If you identify any errors in this component, or have an idea for an improvement, please open an [issue](https://github.com/MurhafSousli/ngx-disqus/issues). I am excited to see what the community thinks of this project, and I would love your input! + +## Author + +**Murhaf Sousli** + +- [github/murhafsousli](https://github.com/MurhafSousli) +- [twitter/murhafsousli](https://twitter.com/MurhafSousli) + +## More plugins + +- [ngx-sharebuttons](https://github.com/MurhafSousli/ngx-sharebuttons) +- [ng-gallery](https://github.com/MurhafSousli/ng-gallery) +- [ngx-progressbar](https://github.com/MurhafSousli/ngx-progressbar) +- [ngx-scrollbar](https://github.com/MurhafSousli/ngx-scrollbar) +- [ngx-bar-rating](https://github.com/MurhafSousli/ngx-bar-rating) +- [ngx-disqus](https://github.com/MurhafSousli/ngx-disqus) +- [ngx-wordpress](https://github.com/MurhafSousli/ngx-wordpress) +- [ngx-highlightjs](https://github.com/MurhafSousli/ngx-highlightjs) +- [ng-teximate](https://github.com/MurhafSousli/ng-teximate) \ No newline at end of file diff --git a/lib/index.ts b/lib/index.ts new file mode 100644 index 0000000..4aaf8f9 --- /dev/null +++ b/lib/index.ts @@ -0,0 +1 @@ +export * from './public_api'; diff --git a/lib/ng-package.json b/lib/ng-package.json new file mode 100644 index 0000000..0484100 --- /dev/null +++ b/lib/ng-package.json @@ -0,0 +1,8 @@ +{ + "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", + "lib": { + "entryFile": "src/index.ts" + }, + "dest": "../dist", + "workingDirectory": "../../.ng_build" +} diff --git a/lib/package.json b/lib/package.json new file mode 100644 index 0000000..2cb21c2 --- /dev/null +++ b/lib/package.json @@ -0,0 +1,27 @@ +{ + "name": "ngx-disqus", + "version": "2.3.6", + "description": "Angular Disqus Module", + "homepage": "http://github.com/murhafsousli/ngx-disqus", + "author": { + "name": "Murhaf Sousli", + "url": "http://github.com/murhafsousli" + }, + "repository": { + "type": "git", + "url": "git://github.com/murhafsousli/ngx-disqus.git" + }, + "bugs": { + "url": "http://github.com/murhafsousli/ngx-disqus/issues" + }, + "license": "MIT", + "keywords": [ + "angular", + "comments", + "disqus" + ], + "private": false, + "peerDependencies": { + "@angular/common": ">=5.0.0" + } +} diff --git a/lib/public_api.ts b/lib/public_api.ts new file mode 100644 index 0000000..8420b10 --- /dev/null +++ b/lib/public_api.ts @@ -0,0 +1 @@ +export * from './src'; diff --git a/lib/src/disqus.component.ts b/lib/src/disqus.component.ts new file mode 100644 index 0000000..cb3abcc --- /dev/null +++ b/lib/src/disqus.component.ts @@ -0,0 +1,113 @@ +import { + Component, + Input, + Output, + OnChanges, + OnDestroy, + ChangeDetectionStrategy, + Renderer2, + ElementRef, + EventEmitter +} from '@angular/core'; +import { DisqusService } from './disqus.service'; +import { DisqusComment, DisqusReady } from './disqus.model'; + +@Component({ + selector: 'disqus', + template: '
', + changeDetection: ChangeDetectionStrategy.OnPush +}) + +export class DisqusComponent implements OnChanges, OnDestroy { + + /** DISQUS options */ + @Input() url: string; + @Input() identifier: string; + @Input() title: string; + @Input() category: string; + @Input() language: string; + + /** DISQUS events */ + @Output() newComment = new EventEmitter(true); + @Output() ready = new EventEmitter(true); + @Output() paginate = new EventEmitter(true); + + constructor(private renderer: Renderer2, private el: ElementRef, private dService: DisqusService) { } + + ngOnChanges() { + /** Reset Disqus if any input changed */ + + if (!this.dService.window.DISQUS) { + this.addDisqusScript(); + } else { + this.reset(); + } + } + + /** Add DISQUS script */ + addDisqusScript() { + + /** Set DISQUS config */ + this.dService.window.disqus_config = this.getConfig(); + + const disqusScript = this.renderer.createElement('script'); + disqusScript.src = `//${this.dService.shortname}.disqus.com/embed.js`; + disqusScript.async = true; + disqusScript.type = 'text/javascript'; + this.renderer.setAttribute(disqusScript, 'data-timestamp', new Date().getTime().toString()); + this.renderer.appendChild(this.el.nativeElement, disqusScript); + } + + /** Reset DISQUS with the new config */ + reset() { + this.dService.window.DISQUS.reset({ + reload: true, + config: this.getConfig() + }); + } + + /** Create DISQUS config from inputs */ + getConfig() { + const self = this; + return function () { + this.page.identifier = self.identifier; + this.page.url = self.validateUrl(self.url); + this.page.title = self.title; + this.category_id = self.category; + this.language = self.language; + + /* Available callbacks are afterRender, onInit, onNewComment, onPaginate, onReady, preData, preInit, preReset */ + this.callbacks.onNewComment = [(e) => { + self.newComment.emit(e); + }]; + + this.callbacks.onReady = [(e) => { + self.ready.emit(e); + }]; + + this.callbacks.onPaginate = [(e) => { + self.paginate.emit(e); + }]; + }; + } + + validateUrl(url: string) { + /** Validate URL input */ + if (url) { + const r = /(http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/; + + if (r.test(url)) { + return url; + } else { + console.warn('[Disqus]: Invalid URL, return undefined'); + } + } + /** DISQUS will fallback to "Window.location.href" when URL is undefined */ + return undefined; + } + + ngOnDestroy() { + this.dService.window.DISQUS = undefined; + this.dService.window.disqus_config = undefined; + } +} diff --git a/lib/src/disqus.model.ts b/lib/src/disqus.model.ts new file mode 100644 index 0000000..83549ce --- /dev/null +++ b/lib/src/disqus.model.ts @@ -0,0 +1,7 @@ +export interface DisqusComment { + id: number; + name: string; +} +export interface DisqusReady { + height: number; +} diff --git a/lib/src/disqus.module.ts b/lib/src/disqus.module.ts new file mode 100644 index 0000000..88f0378 --- /dev/null +++ b/lib/src/disqus.module.ts @@ -0,0 +1,29 @@ +import { NgModule, ModuleWithProviders, InjectionToken } from '@angular/core'; +import { DisqusComponent } from './disqus.component'; +import { DisqusService } from './disqus.service'; +import { SHORTNAME } from './disqus.token'; + +/** Initialize Disqus with shortname */ +export function DisqusFactory(shortname: string) { + return new DisqusService(shortname); +} + +@NgModule({ + declarations: [DisqusComponent], + exports: [DisqusComponent] +}) +export class DisqusModule { + static forRoot(shortname: string): ModuleWithProviders { + return { + ngModule: DisqusModule, + providers: [ + { provide: SHORTNAME, useValue: shortname }, + { + provide: DisqusService, + useFactory: DisqusFactory, + deps: [SHORTNAME] + } + ] + }; + } +} diff --git a/lib/src/disqus.service.ts b/lib/src/disqus.service.ts new file mode 100644 index 0000000..d8f652b --- /dev/null +++ b/lib/src/disqus.service.ts @@ -0,0 +1,20 @@ +import { Injectable, Inject } from '@angular/core'; +import { SHORTNAME } from './disqus.token'; + +declare const global: any; + +@Injectable() +export class DisqusService { + + constructor( @Inject(SHORTNAME) public shortname: string) { + } + + get window() { + return _window(); + } +} + +function _window() { + return typeof window !== 'undefined' ? window : global; +} + diff --git a/lib/src/disqus.token.ts b/lib/src/disqus.token.ts new file mode 100644 index 0000000..5990a8c --- /dev/null +++ b/lib/src/disqus.token.ts @@ -0,0 +1,3 @@ +import { InjectionToken } from '@angular/core'; + +export const SHORTNAME = new InjectionToken('SHORTNAME'); diff --git a/lib/src/index.ts b/lib/src/index.ts new file mode 100644 index 0000000..78522fb --- /dev/null +++ b/lib/src/index.ts @@ -0,0 +1,2 @@ +export { DisqusModule } from './disqus.module'; +export { DisqusComment, DisqusReady } from './disqus.model'; diff --git a/ng-package.json b/ng-package.json deleted file mode 100644 index 2d34148..0000000 --- a/ng-package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "$schema": "./node_modules/ng-packagr/ng-package.schema.json", - "lib": { - "entryFile": "src/app/disqus/index.ts" - } - } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 01b02d7..9419490 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "ngx-disqus", - "version": "2.3.4", + "version": "2.3.5", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1573,6 +1573,12 @@ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", "dev": true }, + "conventional-commit-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/conventional-commit-types/-/conventional-commit-types-2.2.0.tgz", + "integrity": "sha1-XblXOdbCEqy+e29lahG5QLqmiUY=", + "dev": true + }, "convert-source-map": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", @@ -1636,8 +1642,7 @@ "core-js": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz", - "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=", - "dev": true + "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs=" }, "core-object": { "version": "3.1.5", @@ -1923,6 +1928,19 @@ "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=", "dev": true }, + "cz-conventional-changelog": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cz-conventional-changelog/-/cz-conventional-changelog-2.1.0.tgz", + "integrity": "sha1-L0vHOQ4yROTfKT5ro1Hkx0Cnx2Q=", + "dev": true, + "requires": { + "conventional-commit-types": "2.2.0", + "lodash.map": "4.6.0", + "longest": "1.0.1", + "right-pad": "1.0.1", + "word-wrap": "1.2.3" + } + }, "d": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", @@ -5142,6 +5160,12 @@ "lodash.isarray": "3.0.4" } }, + "lodash.map": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz", + "integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=", + "dev": true + }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -7827,6 +7851,12 @@ "align-text": "0.1.4" } }, + "right-pad": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/right-pad/-/right-pad-1.0.1.tgz", + "integrity": "sha1-jKCMLLtbVedNr6lr9/0aJ9VoyNA=", + "dev": true + }, "rimraf": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", @@ -7908,7 +7938,6 @@ "version": "5.5.2", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.2.tgz", "integrity": "sha512-oRYoIKWBU3Ic37fLA5VJu31VqQO4bWubRntcHSJ+cwaDQBwdnZ9x4zmhJfm/nFQ2E82/I4loSioHnACamrKGgA==", - "dev": true, "requires": { "symbol-observable": "1.0.4" } @@ -8824,8 +8853,7 @@ "symbol-observable": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.4.tgz", - "integrity": "sha1-Kb9hXUqnEhvdiYsi1LP5vE4qoD0=", - "dev": true + "integrity": "sha1-Kb9hXUqnEhvdiYsi1LP5vE4qoD0=" }, "tapable": { "version": "0.2.8", @@ -10076,6 +10104,12 @@ "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", "dev": true }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, "wordwrap": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", @@ -10240,8 +10274,7 @@ "zone.js": { "version": "0.8.18", "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.8.18.tgz", - "integrity": "sha512-knKOBQM0oea3/x9pdyDuDi7RhxDlJhOIkeixXSiTKWLgs4LpK37iBc+1HaHwzlciHUKT172CymJFKo8Xgh+44Q==", - "dev": true + "integrity": "sha512-knKOBQM0oea3/x9pdyDuDi7RhxDlJhOIkeixXSiTKWLgs4LpK37iBc+1HaHwzlciHUKT172CymJFKo8Xgh+44Q==" } } } diff --git a/package.json b/package.json index 7c2c72d..b9fa332 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "ngx-disqus", "description": "Angular Disqus Module", - "version": "2.3.4", + "version": "2.3.5", "scripts": { "ng": "ng", "start": "ng serve", @@ -9,7 +9,7 @@ "test": "ng test", "lint": "ng lint", "e2e": "ng e2e", - "packagr": "ng-packagr -p ng-package.json" + "packagr": "ng-packagr -p lib/ng-package.json" }, "homepage": "http://github.com/murhafsousli/ngx-disqus", "author": { @@ -50,6 +50,7 @@ "@types/jasminewd2": "~2.0.2", "@types/node": "~6.0.60", "codelyzer": "^4.0.1", + "cz-conventional-changelog": "^2.1.0", "jasmine-core": "~2.6.2", "jasmine-spec-reporter": "~4.1.0", "karma": "~1.7.0", diff --git a/tsconfig.json b/tsconfig.json index a6c016b..17d6a14 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,6 +8,7 @@ "emitDecoratorMetadata": true, "experimentalDecorators": true, "target": "es5", + "baseUrl": "lib", "typeRoots": [ "node_modules/@types" ],