mostly functional

merge-requests/2/merge^2
Nato Boram 2019-11-29 02:26:41 -05:00
parent 26cf1d120f
commit 311a3b0698
No known key found for this signature in database
GPG Key ID: C035B4A0E33CF552
14 changed files with 234 additions and 11 deletions

View File

@ -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"

View File

@ -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"
}
}
}

View File

@ -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: [],

View File

@ -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>

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 { }

View File

@ -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();
});
});

View File

@ -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'
});
}
}

View File

@ -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"
]

View File

@ -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>

View File

@ -12,6 +12,6 @@
"src/**/*.d.ts"
],
"angularCompilerOptions": {
"enableIvy": true
"enableIvy": false
}
}

View File

@ -16,6 +16,6 @@
"src/**/*.d.ts"
],
"angularCompilerOptions": {
"enableIvy": true
"enableIvy": false
}
}

View File

@ -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"