diff --git a/angular.json b/angular.json index 29e0b56..4247459 100644 --- a/angular.json +++ b/angular.json @@ -25,7 +25,12 @@ "aot": true, "assets": [ "src/favicon.png", - "src/assets" + "src/assets", + { + "glob": "*", + "input": "node_modules/ipfs-css", + "output": "assets/ipfs-css" + } ], "styles": [ "src/styles.scss" @@ -90,7 +95,12 @@ "karmaConfig": "karma.conf.js", "assets": [ "src/favicon.png", - "src/assets" + "src/assets", + { + "glob": "*", + "input": "node_modules/ipfs-css", + "output": "assets/ipfs-css" + } ], "styles": [ "src/styles.scss" diff --git a/package.json b/package.json index 15e1b87..f07cefb 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.0.0", "scripts": { "ng": "ng", - "start": "ng serve --open --ssl", + "start": "ng serve --ssl", "build": "ng build", "build:prod": "ng build --prod", "build:gitlab": "ng build --prod --base-href /public-gateway-cacher/", @@ -19,6 +19,7 @@ "@angular/common": "~8.2.14", "@angular/compiler": "~8.2.14", "@angular/core": "~8.2.14", + "@angular/flex-layout": "^8.0.0-beta.27", "@angular/forms": "~8.2.14", "@angular/material": "^8.2.3", "@angular/platform-browser": "~8.2.14", @@ -55,4 +56,4 @@ "tslint-rxjs-subject-restrictions-rule": "^1.0.4", "typescript": "~3.5.3" } -} \ No newline at end of file +} diff --git a/src/app/app.module.ts b/src/app/app.module.ts index fa426be..6ff3c49 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,3 +1,5 @@ +import { CommonModule } from '@angular/common'; +import { HttpClientModule } from '@angular/common/http'; import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; @@ -9,8 +11,10 @@ import { AppComponent } from './app.component'; AppComponent ], imports: [ + CommonModule, BrowserModule, BrowserAnimationsModule, + HttpClientModule, AppRoutingModule, ], providers: [], diff --git a/src/app/pages/pages.component.html b/src/app/pages/pages.component.html index c56369e..8c1ad88 100644 --- a/src/app/pages/pages.component.html +++ b/src/app/pages/pages.component.html @@ -1 +1,47 @@ -

pages works!

+
+ + +
+ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
Status +
+
+
+
+
Gateway + {{ element.gateway }} +
+ +
diff --git a/src/app/pages/pages.component.scss b/src/app/pages/pages.component.scss index 8b13789..9fff96f 100644 --- a/src/app/pages/pages.component.scss +++ b/src/app/pages/pages.component.scss @@ -1 +1,20 @@ +.mat-form-field { + min-width: 30em; +} +.mat-progress-bar { + max-width: 60em; +} + +.mat-header-cell { + padding: 1em; +} + +.mat-column-error { + text-align: center; + min-width: 5em; +} + +.mat-column-gateway { + min-width: 50em; +} diff --git a/src/app/pages/pages.component.ts b/src/app/pages/pages.component.ts index d8ad6cb..3777580 100644 --- a/src/app/pages/pages.component.ts +++ b/src/app/pages/pages.component.ts @@ -1,4 +1,8 @@ -import { Component, OnInit } from '@angular/core'; +import { HttpErrorResponse } from '@angular/common/http'; +import { Component, OnInit, ViewChild } from '@angular/core'; +import { MatSort } from '@angular/material/sort'; +import { MatTable, MatTableDataSource } from '@angular/material/table'; +import { GatewayService } from '../services/gateway.service'; @Component({ selector: 'app-pages', @@ -7,9 +11,47 @@ import { Component, OnInit } from '@angular/core'; }) export class PagesComponent implements OnInit { - constructor() { } + gateways: string[]; + hash: string; + dataSource: MatTableDataSource; + displayedColumns = [ + 'error', + 'gateway', + ]; + + @ViewChild(MatTable, { static: false }) matTable: MatTable; + @ViewChild(MatSort, { static: false }) sort: MatSort; + + constructor( + private readonly gatewayService: GatewayService + ) { } + + ngOnInit(): void { + this.dataSource = new MatTableDataSource([]); + this.dataSource.sort = this.sort; + this.gatewayService.list().subscribe(gateways => this.gateways = gateways); + } + + cache(): void { + const hash = this.hash; + this.dataSource.data = []; + this.matTable.renderRows(); + + this.gateways.forEach(gateway => { + this.gatewayService.get(gateway, hash).subscribe(_ => { + this.dataSource.data.push({ gateway: `${gateway.replace(':hash', hash)}`, error: null }); + this.matTable.renderRows(); + }, (error: HttpErrorResponse) => { + this.dataSource.data.push({ gateway: `${gateway.replace(':hash', hash)}`, error }); + this.matTable.renderRows(); + }); + }); - ngOnInit() { } } + +interface Result { + gateway: string; + error: HttpErrorResponse; +} diff --git a/src/app/pages/pages.module.ts b/src/app/pages/pages.module.ts index 37481e9..2966605 100644 --- a/src/app/pages/pages.module.ts +++ b/src/app/pages/pages.module.ts @@ -1,5 +1,13 @@ import { CommonModule } from '@angular/common'; import { NgModule } from '@angular/core'; +import { FlexLayoutModule } from '@angular/flex-layout'; +import { FormsModule } from '@angular/forms'; +import { MatButtonModule } from '@angular/material/button'; +import { MatInputModule } from '@angular/material/input'; +import { MatProgressBarModule } from '@angular/material/progress-bar'; +import { MatSortModule } from '@angular/material/sort'; +import { MatTableModule } from '@angular/material/table'; +import { MatTooltipModule } from '@angular/material/tooltip'; import { PagesRoutingModule } from './pages-routing.module'; import { PagesComponent } from './pages.component'; @@ -7,7 +15,15 @@ import { PagesComponent } from './pages.component'; declarations: [PagesComponent], imports: [ CommonModule, - PagesRoutingModule + FlexLayoutModule, + FormsModule, + MatButtonModule, + MatInputModule, + MatProgressBarModule, + MatSortModule, + MatTableModule, + MatTooltipModule, + PagesRoutingModule, ] }) export class PagesModule { } diff --git a/src/app/services/gateway.service.spec.ts b/src/app/services/gateway.service.spec.ts new file mode 100644 index 0000000..ce041cd --- /dev/null +++ b/src/app/services/gateway.service.spec.ts @@ -0,0 +1,12 @@ +import { TestBed } from '@angular/core/testing'; + +import { GatewayService } from './gateway.service'; + +describe('GatewayService', () => { + beforeEach(() => TestBed.configureTestingModule({})); + + it('should be created', () => { + const service: GatewayService = TestBed.get(GatewayService); + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/services/gateway.service.ts b/src/app/services/gateway.service.ts new file mode 100644 index 0000000..f3e46e1 --- /dev/null +++ b/src/app/services/gateway.service.ts @@ -0,0 +1,24 @@ +import { HttpClient } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs'; + +@Injectable({ + providedIn: 'root' +}) +export class GatewayService { + + constructor( + private readonly http: HttpClient + ) { } + + list(): Observable { + return this.http.get('/assets/json/gateways.json'); + } + + get(gateway: string, hash: string): Observable { + return this.http.get(`${gateway.replace(':hash', hash)}#x-ipfs-companion-no-redirect`, { + responseType: 'blob' as 'json' + }); + } + +} diff --git a/src/assets/json/gateways.json b/src/assets/json/gateways.json new file mode 100644 index 0000000..ab9987f --- /dev/null +++ b/src/assets/json/gateways.json @@ -0,0 +1,39 @@ +[ + "https://ipfs.io/ipfs/:hash", + "https://gateway.ipfs.io/ipfs/:hash", + "https://ipfs.infura.io/ipfs/:hash", + "https://rx14.co.uk/ipfs/:hash", + "https://ninetailed.ninja/ipfs/:hash", + "https://ipfs.globalupload.io/:hash", + "https://ipfs.jes.xxx/ipfs/:hash", + "https://siderus.io/ipfs/:hash", + "https://eu.siderus.io/ipfs/:hash", + "https://na.siderus.io/ipfs/:hash", + "https://ap.siderus.io/ipfs/:hash", + "https://10.via0.com/ipfs/:hash", + "https://ipfs.eternum.io/ipfs/:hash", + "https://hardbin.com/ipfs/:hash", + "https://ipfs.wa.hle.rs/ipfs/:hash", + "https://gateway.blocksec.com/ipfs/:hash", + "https://ipfs.renehsz.com/ipfs/:hash", + "https://cloudflare-ipfs.com/ipfs/:hash", + "https://ipns.co/:hash", + "https://ipfs.mrh.io/ipfs/:hash", + "https://gateway.originprotocol.com/ipfs/:hash", + "https://gateway.pinata.cloud/ipfs/:hash", + "https://ipfs.doolta.com/ipfs/:hash", + "https://ipfs.sloppyta.co/ipfs/:hash", + "https://ipfs.busy.org/ipfs/:hash", + "https://ipfs.greyh.at/ipfs/:hash", + "https://gateway.serph.network/ipfs/:hash", + "https://jorropo.ovh/ipfs/:hash", + "https://gateway.temporal.cloud/ipfs/:hash", + "https://ipfs.fooock.com/ipfs/:hash", + "https://cdn.cwinfo.net/ipfs/:hash", + "https://ipfs.privacytools.io/ipfs/:hash", + "https://ipfs.jeroendeneef.com/ipfs/:hash", + "https://permaweb.io/ipfs/:hash", + "https://ipfs.stibarc.gq/ipfs/:hash", + "https://ipfs.best-practice.se/ipfs/:hash", + "https://lineageos-on-ipfs.com/ipfs/:hash" +] diff --git a/src/index.html b/src/index.html index a2328e6..5a6dc35 100644 --- a/src/index.html +++ b/src/index.html @@ -12,6 +12,9 @@ + + + diff --git a/tsconfig.app.json b/tsconfig.app.json index c9bfd72..7c6b81b 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -12,6 +12,6 @@ "src/**/*.d.ts" ], "angularCompilerOptions": { - "enableIvy": true + "enableIvy": false } } diff --git a/tsconfig.spec.json b/tsconfig.spec.json index efa6f18..f6442e1 100644 --- a/tsconfig.spec.json +++ b/tsconfig.spec.json @@ -16,6 +16,6 @@ "src/**/*.d.ts" ], "angularCompilerOptions": { - "enableIvy": true + "enableIvy": false } } diff --git a/yarn.lock b/yarn.lock index d9addcc..f35fe0c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -190,6 +190,13 @@ dependencies: tslib "^1.9.0" +"@angular/flex-layout@^8.0.0-beta.27": + version "8.0.0-beta.27" + resolved "https://registry.yarnpkg.com/@angular/flex-layout/-/flex-layout-8.0.0-beta.27.tgz#a697d5a90e6d04c06b02ee872f88f384d1723f7c" + integrity sha512-qmpvQPesU4ZQ56IscwgmVRpK2UnyV+gwvXUql7TMv0QV215hLcHczjGsrKkLfW2By5E7XEyDat9br72uVXcPMw== + dependencies: + tslib "^1.7.1" + "@angular/forms@~8.2.14": version "8.2.14" resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-8.2.14.tgz#7d357c346a3884881beb044c50ec4a09d3d7ee8e"