From 507d2cda1b40d5e1268a4296dd86aad75480eb89 Mon Sep 17 00:00:00 2001 From: cipchk Date: Sun, 24 Feb 2019 16:01:29 +0800 Subject: [PATCH] chore: used github api v4 --- README.md | 12 +++-- lib/src/component.ts | 94 +++++++++++++++++++++++++++++--------- lib/src/service.ts | 43 +++++++++++------ lib/src/style.less | 3 -- package.json | 41 +++++++++-------- src/app/app.component.html | 20 +++++--- src/app/app.component.ts | 18 +++++++- src/app/app.module.ts | 4 +- 8 files changed, 161 insertions(+), 74 deletions(-) diff --git a/README.md b/README.md index df5a929..9e2aba1 100644 --- a/README.md +++ b/README.md @@ -33,16 +33,20 @@ export class AppModule { } ### 2、Template ```html - + ``` | Name | Type | Default | Summary | | ------- | ------------- | ----- | ----- | -| `type` | `stargazers,subscribers,forks` | - | - | +| `token` | `string` | - | **REQUIRED** To communicate with the GraphQL server, you'll need an OAuth token with the right scopes, [Creating a personal access token for the command line](https://help.github.com/en/articles/creating-a-personal-access-token-for-the-command-line) | +| `namespace` | `string` | - | **REQUIRED** Your GitHub id or organization name. | +| `repo` | `string` | - | **REQUIRED** The name of your repository. | +| `type` | `stargazers,subscribers,watchers,forks` | `stargazers`| - | | `size` | `default,large` | - | - | -| `namespace` | `string` | - | Your GitHub id or organization name. | -| `repo` | `string` | - | The name of your repository. | | `showZero` | `boolean` | `false` | Can be show zero value | +| `query` | `string` | - | Custom query string in github api v4, pls refer to [GraphQL API v4](https://developer.github.com/v4/guides/) | +| `callback` | `(data: any) => string` | - | Callback in data render | +| `svg` | `string` | - | Icon | ## Troubleshooting diff --git a/lib/src/component.ts b/lib/src/component.ts index 9f62c9d..00a69af 100644 --- a/lib/src/component.ts +++ b/lib/src/component.ts @@ -10,21 +10,23 @@ import { } from '@angular/core'; import { GithubButtonService } from './service'; import { Subscription } from 'rxjs'; +import { filter } from 'rxjs/operators'; +import { DomSanitizer } from '@angular/platform-browser'; @Component({ selector: 'github-button', template: ` - + {{ typeToLabel[type] }} - {{ count }} + {{ value }} `, @@ -38,26 +40,30 @@ import { Subscription } from 'rxjs'; }) export class GithubButtonComponent implements OnChanges, OnInit, OnDestroy { private notify$: Subscription; - typeToLabel = { + _svg = this.dom.bypassSecurityTrustHtml(``); + value: string; + + // region: fields + + @Input() type: 'stargazers' | 'subscribers' | 'watchers' | 'forks' = + 'stargazers'; + @Input() typeToLabel = { stargazers: 'Star', subscribers: 'Watch', forks: 'Fork', }; - typeToPath = { + @Input() typeToPath = { forks: 'network', }; - count: number; - - // region: fields - - @Input() type: 'stargazers' | 'subscribers' | 'forks' = 'stargazers'; - @Input() size: 'default' | 'large'; - + @Input() set svg(value: string) { + this._svg = this.dom.bypassSecurityTrustHtml(value); + } @Input() namespace: string; - @Input() repo: string; - + @Input() token: string; + @Input() query: string = null; + @Input() callback: (data: any) => string = null; @Input() showZero = false; // endregion @@ -67,27 +73,71 @@ export class GithubButtonComponent implements OnChanges, OnInit, OnDestroy { } get count_url() { - return `//github.com/${this.namespace}/${this.repo}/${this.typeToPath[ - this.type - ] || this.type}/`; + const type = this.typeToPath[this.type]; + return `//github.com/${this.namespace}/${this.repo}/${ + type ? type + '/' : '' + }`; + } + + get defaultQuery(): string { + const { namespace, repo } = this; + return `query { repository(owner:"${namespace}", name:"${repo}") { stargazers { totalCount } forkCount watchers(first: 1) { totalCount } } }`; } constructor( private srv: GithubButtonService, + private dom: DomSanitizer, private cdr: ChangeDetectorRef, ) {} - private setCount(data: any) { - this.count = data ? data[`${this.type}_count`] : 0; - this.cdr.detectChanges(); + private setCount(res: any) { + const { callback, type, showZero, cdr } = this; + const { data } = res; + let c = ''; + if (data != null) { + if (callback) { + c = callback(data); + } else { + const { forkCount, stargazers, watchers } = data.repository; + switch (type) { + case 'forks': + c = forkCount; + break; + case 'stargazers': + c = stargazers!.totalCount; + break; + case 'watchers': + case 'subscribers': + c = watchers!.totalCount; + break; + } + c = showZero && +c <= 0 ? '0' : c; + } + } + this.value = c; + cdr.detectChanges(); } ngOnInit(): void { - this.notify$ = this.srv.notify.subscribe(res => this.setCount(res)); + this.notify$ = this.srv.notify + .pipe( + filter( + res => + res != null && + res.key === + this.srv.getKey( + this.namespace, + this.repo, + this.query || this.defaultQuery, + ), + ), + ) + .subscribe(res => this.setCount(res)); } ngOnChanges(): void { - this.srv.req(this.namespace, this.repo); + const { namespace, repo, token, query, defaultQuery } = this; + this.srv.req(namespace, repo, token, query || defaultQuery); } ngOnDestroy(): void { diff --git a/lib/src/service.ts b/lib/src/service.ts index b5e7b6b..dea476c 100644 --- a/lib/src/service.ts +++ b/lib/src/service.ts @@ -1,4 +1,5 @@ import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; import { BehaviorSubject } from 'rxjs'; @Injectable({ providedIn: 'root' }) @@ -10,22 +11,34 @@ export class GithubButtonService { return this._notify.asObservable(); } - req(namespace: string, repo: string): void { - const url = `https://api.github.com/repos/${namespace}/${repo}`; - if (this.cached[url] != null) { - this._notify.next(this.cached[url]); + constructor(private http: HttpClient) {} + + getKey(namespace: string, repo: string, query: string): string { + return `${namespace}_${repo}_${query}`; + } + + req(namespace: string, repo: string, token: string, query: string): void { + const key = this.getKey(namespace, repo, query); + if (this.cached[key] === null) { + this._notify.next(this.cached[key]); return; } - this.cached[url] = {}; - const xhr = new XMLHttpRequest(); - xhr.onreadystatechange = () => { - if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) { - this.cached[url] = JSON.parse(xhr.responseText); - this._notify.next(this.cached[url]); - return; - } - }; - xhr.open('GET', url, true); - xhr.send(); + this.cached[key] = null; + this.http + .post( + `https://api.github.com/graphql`, + { + query, + }, + { + headers: { + // Authorization: `bearer ${token}`, + }, + }, + ) + .subscribe((res: any) => { + this.cached[key] = { key, data: res.data }; + this._notify.next(this.cached[key]); + }); } } diff --git a/lib/src/style.less b/lib/src/style.less index 1c24d8b..b7ddca7 100644 --- a/lib/src/style.less +++ b/lib/src/style.less @@ -51,9 +51,6 @@ width: 14px; height: 14px; margin-right: 4px; - background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIGlkPSJMYXllcl8xIiB4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjQwcHgiIGhlaWdodD0iNDBweCIgdmlld0JveD0iMTIgMTIgNDAgNDAiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMTIgMTIgNDAgNDAiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxwYXRoIGZpbGw9IiMzMzMzMzMiIGQ9Ik0zMiAxMy40Yy0xMC41IDAtMTkgOC41LTE5IDE5YzAgOC40IDUuNSAxNS41IDEzIDE4YzEgMC4yIDEuMy0wLjQgMS4zLTAuOWMwLTAuNSAwLTEuNyAwLTMuMiBjLTUuMyAxLjEtNi40LTIuNi02LjQtMi42QzIwIDQxLjYgMTguOCA0MSAxOC44IDQxYy0xLjctMS4yIDAuMS0xLjEgMC4xLTEuMWMxLjkgMC4xIDIuOSAyIDIuOSAyYzEuNyAyLjkgNC41IDIuMSA1LjUgMS42IGMwLjItMS4yIDAuNy0yLjEgMS4yLTIuNmMtNC4yLTAuNS04LjctMi4xLTguNy05LjRjMC0yLjEgMC43LTMuNyAyLTUuMWMtMC4yLTAuNS0wLjgtMi40IDAuMi01YzAgMCAxLjYtMC41IDUuMiAyIGMxLjUtMC40IDMuMS0wLjcgNC44LTAuN2MxLjYgMCAzLjMgMC4yIDQuNyAwLjdjMy42LTIuNCA1LjItMiA1LjItMmMxIDIuNiAwLjQgNC42IDAuMiA1YzEuMiAxLjMgMiAzIDIgNS4xYzAgNy4zLTQuNSA4LjktOC43IDkuNCBjMC43IDAuNiAxLjMgMS43IDEuMyAzLjVjMCAyLjYgMCA0LjYgMCA1LjJjMCAwLjUgMC40IDEuMSAxLjMgMC45YzcuNS0yLjYgMTMtOS43IDEzLTE4LjFDNTEgMjEuOSA0Mi41IDEzLjQgMzIgMTMuNHoiLz48L3N2Zz4='); - background-size: 100% 100%; - background-repeat: no-repeat; } .gh-count { position: relative; diff --git a/package.json b/package.json index 8daea2d..5ad40c1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ng-github-button", - "version": "2.1.4", + "version": "3.0.0", "description": "Unofficial GitHub buttons in Angular.", "repository": { "type": "git", @@ -34,30 +34,29 @@ "release": "npm run build && cd publish && npm publish --access public" }, "devDependencies": { - "@angular/animations": "~7.0.0", - "@angular/common": "~7.0.0", - "@angular/compiler": "~7.0.0", - "@angular/core": "~7.0.0", - "@angular/forms": "~7.0.0", - "@angular/http": "~7.0.0", - "@angular/platform-browser": "~7.0.0", - "@angular/platform-browser-dynamic": "~7.0.0", - "@angular/router": "~7.0.0", + "@angular/animations": "~7.2.0", + "@angular/common": "~7.2.0", + "@angular/compiler": "~7.2.0", + "@angular/core": "~7.2.0", + "@angular/forms": "~7.2.0", + "@angular/platform-browser": "~7.2.0", + "@angular/platform-browser-dynamic": "~7.2.0", + "@angular/router": "~7.2.0", "core-js": "^2.5.4", "rxjs": "~6.3.3", + "tslib": "^1.9.0", "zone.js": "~0.8.26", - "ngx-highlight-js": "^2.0.0", - "@angular-devkit/build-angular": "~0.10.0", - "@angular/cli": "~7.0.4", - "@angular/compiler-cli": "~7.0.0", - "@angular/language-service": "~7.0.0", + "@angular-devkit/build-angular": "~0.13.0", + "@angular/cli": "~7.3.3", + "@angular/compiler-cli": "~7.2.0", + "@angular/language-service": "~7.2.0", "@types/node": "~8.9.4", "@types/jasmine": "~2.8.8", "@types/jasminewd2": "~2.0.3", "codelyzer": "~4.5.0", "jasmine-core": "~2.99.1", "jasmine-spec-reporter": "~4.2.1", - "karma": "~3.0.0", + "karma": "~4.0.0", "karma-chrome-launcher": "~2.2.0", "karma-coverage-istanbul-reporter": "~2.0.1", "karma-jasmine": "~1.1.2", @@ -65,10 +64,12 @@ "protractor": "~5.4.0", "ts-node": "~7.0.0", "tslint": "~5.11.0", - "typescript": "~3.1.1", - "codecov": "^3.0.0", - "ng-packagr": "^4.4.0", - "tsickle": "^0.33.1" + "typescript": "~3.2.2", + "ngx-highlight-js": "^2.1.1", + "codecov": "^3.2.0", + "ng-packagr": "^4.7.0", + "tsickle": "^0.34.0", + "gh-pages": "^2.0.1" }, "ngPackage": { "lib": { diff --git a/src/app/app.component.html b/src/app/app.component.html index 48496c0..add2af2 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,26 +1,34 @@

ng-github-button

Unofficial GitHub buttons in Angular.

- +
- +
- +
+
+
+
+ +
+
diff --git a/src/app/app.component.ts b/src/app/app.component.ts index fa687c6..24062a6 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,8 +1,22 @@ import { Component } from '@angular/core'; @Component({ - selector: 'app-root', - templateUrl: './app.component.html' + selector: 'app-root', + templateUrl: './app.component.html', }) export class AppComponent { + token = `75cdf4b6c16ad7fde95f170320c81f6375dce35e`; + + diskUsageQuery = ` + query { + { + repository(owner: "ng-alain", name: "ng-alain") { + diskUsage + } + } + } + `; + diskUsageCallback(data: any): string { + return `${(data.repository.diskUsage / 1024).toFixed(2)} KB`; + } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 427f2d6..11fbf44 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,5 +1,5 @@ import { NgModule } from '@angular/core'; -import { Routes, RouterModule } from '@angular/router'; +import { HttpClientModule } from '@angular/common/http'; import { BrowserModule } from '@angular/platform-browser'; import { CommonModule } from '@angular/common'; import { HighlightJsModule } from 'ngx-highlight-js'; @@ -9,7 +9,7 @@ import { GithubButtonModule } from 'ng-github-button'; import { AppComponent } from './app.component'; @NgModule({ - imports: [BrowserModule, CommonModule, HighlightJsModule, GithubButtonModule], + imports: [BrowserModule, CommonModule, HttpClientModule, HighlightJsModule, GithubButtonModule], declarations: [AppComponent], providers: [], bootstrap: [AppComponent],