mostly functional
parent
26cf1d120f
commit
311a3b0698
14
angular.json
14
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"
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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: [],
|
||||
|
|
|
@ -1 +1,47 @@
|
|||
<p>pages works!</p>
|
||||
<div fxLayout="column" fxLayoutAlign="start center" fxLayoutGap="1em">
|
||||
|
||||
<!-- Form -->
|
||||
<form fxLayout="row" fxLayoutAlign="space-evenly center" fxLayoutGap="1em" (submit)="cache()">
|
||||
|
||||
<!-- Hash -->
|
||||
<mat-form-field>
|
||||
<input matInput [(ngModel)]="hash" name="hash">
|
||||
</mat-form-field>
|
||||
|
||||
<!-- Cache -->
|
||||
<button mat-flat-button color="primary" type="submit">Cache</button>
|
||||
|
||||
</form>
|
||||
|
||||
<mat-progress-bar *ngIf="dataSource && gateways" mode="determinate" [value]="dataSource.data.length / gateways.length * 100">
|
||||
</mat-progress-bar>
|
||||
|
||||
<table mat-table [dataSource]="dataSource" matSort class="mat-elevation-z8">
|
||||
|
||||
<!-- Result Column -->
|
||||
<ng-container matColumnDef="error">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header> Status </th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<div [ngSwitch]="element.error">
|
||||
<div *ngSwitchCase="null">✅</div>
|
||||
<div *ngSwitchDefault [matTooltip]="element.error.statusText">❌</div>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<!-- Gateway Column -->
|
||||
<ng-container matColumnDef="gateway">
|
||||
<th mat-header-cell *matHeaderCellDef> Gateway </th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<a [href]="element.gateway" [ngClass]="{
|
||||
'aqua-muted': element.error,
|
||||
aqua: !element.error
|
||||
}"> {{ element.gateway }} </a>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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<Result>;
|
||||
displayedColumns = [
|
||||
'error',
|
||||
'gateway',
|
||||
];
|
||||
|
||||
@ViewChild(MatTable, { static: false }) matTable: MatTable<Result>;
|
||||
@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;
|
||||
}
|
||||
|
|
|
@ -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 { }
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
});
|
|
@ -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<string[]> {
|
||||
return this.http.get<string[]>('/assets/json/gateways.json');
|
||||
}
|
||||
|
||||
get(gateway: string, hash: string): Observable<Blob> {
|
||||
return this.http.get<Blob>(`${gateway.replace(':hash', hash)}#x-ipfs-companion-no-redirect`, {
|
||||
responseType: 'blob' as '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"
|
||||
]
|
|
@ -12,6 +12,9 @@
|
|||
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500&display=swap" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
|
||||
<!-- IPFS-CSS -->
|
||||
<link href="assets/ipfs-css/ipfs.css" rel="stylesheet">
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
|
|
@ -12,6 +12,6 @@
|
|||
"src/**/*.d.ts"
|
||||
],
|
||||
"angularCompilerOptions": {
|
||||
"enableIvy": true
|
||||
"enableIvy": false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,6 @@
|
|||
"src/**/*.d.ts"
|
||||
],
|
||||
"angularCompilerOptions": {
|
||||
"enableIvy": true
|
||||
"enableIvy": false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue