Skip to content

Commit

Permalink
Redesign UI to be more IPFS-like (#83)
Browse files Browse the repository at this point in the history
* Preventing CORB + some explanatory comments

* Nicer look

Just changed its look

* Update screenshot

* screenshot updated

* bash script updated

* Sorting refactor + max-width

* Versioning app.js for caching pourposes + sorting default order value
  • Loading branch information
lazyweirdo authored and jamiew committed Dec 24, 2019
1 parent 46f01be commit c076bbb
Show file tree
Hide file tree
Showing 5 changed files with 196 additions and 58 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
You can view this website on GitHub Pages: https://ipfs.github.io/public-gateway-checker/

[![screenshot_2019-12-14.png](https://ipfs.io/ipfs/QmX53EdPJxH377WHfwH8wV3tu8Zzjq9ojgQS6U82JRM6bd?filename=screenshot_2019-12-14.png)](https://ipfs.github.io/public-gateway-checker/)
[![screenshot_2019-12-19.jpg](https://ipfs.io/ipfs/QmQuMMz9RUbdknhabTW4WpJ2LSiAstV6drCTS9ZFsmy5K7?filename=screenshot_2019-12-19.jpg)](https://ipfs.github.io/public-gateway-checker/)

**NOTE:** All of these (except `ipfs.io` and `dweb.link`) are hosted by third-parties and should be treated as such.

Expand Down
111 changes: 70 additions & 41 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,37 +11,64 @@ const HASH_STRING = 'Hello from IPFS Gateway Checker';
let checker = document.getElementById('checker');
checker.nodes = [];

checker.updateStats = function(node) {
checker.checkGateways = function(gateways) {
gateways.forEach((gateway) => {
let node = new Node(this.results, gateway, this.nodes.length);
this.nodes.push(node);
this.results.append(node.tag);
node.check();
});
};

checker.updateStats = function() {
this.stats.update();
};

let Stats = function(parent) {
this.parent = parent;
this.tag = document.getElementById('checker.stats');//document.createElement("div"); // TODO:: ugly i know, WIP
this.tag.className = "Stats";

this.gateways = document.createElement("div");
this.gateways.textContent = `0/0`;
this.gateways.className = "Gateways";
this.tag.append(this.gateways);

this.totals = document.createElement("div");
this.totals.textContent = `0 ✅`;
this.totals.className = "Totals";
this.tag.append(this.totals);
};

Stats.prototype.update = function() {
let up = 0, down = 0;
for (let savedNode of this.nodes) {
for (let savedNode of this.parent.nodes) {
if ("up" in savedNode.status) {
savedNode.status.up ? ++up : ++down;
}
}
let gtwschckd = `${up+down}/${this.nodes.length} gateways checked`;
let totals = ` ==> ${up} ✅ - ${down} ❌`;
this.stats.textContent = gtwschckd + totals;
this.gateways.textContent = `${up+down}/${this.parent.nodes.length} gateways`;
this.totals.textContent = `${up} ✅`;
};

checker.stats = document.getElementById('checker.stats');
checker.stats.parent = checker;

checker.stats = new Stats(checker);

checker.results = document.getElementById('checker.results');
checker.results.parent = checker;
checker.results.checked = function(node) {
this.prepend(node.tag);
this.parent.updateStats(node);
};

checker.results.failed = function(node) {
this.append(node.tag);
this.parent.updateStats(node);
};

let Status = function(parent, index) {
this.parent = parent;
this.tag = document.createElement("span");
this.tag.textContent = ' WAIT: 🕑 - ';
this.tag = document.createElement("div");
this.tag.className = "Status";
this.tag.textContent = '🕑';
};

Status.prototype.check = function() {
Expand All @@ -53,7 +80,7 @@ Status.prototype.check = function() {

// 3 important things here
// 1) we add #x-ipfs-companion-no-redirect to the final url (self explanatory)
// 2) we add ?filename=anyname.js as a parameter to let the gateway set correct Content-Type header
// 2) we add ?filename=anyname.js as a parameter to let the gateway guess Content-Type header
// to be sent in headers in order to prevent CORB
// 3) parameter 'i' is the one used to identify the gateway once the script executes
let src = `${gatewayAndScriptHash}?i=${this.parent.index}&now=${now}&filename=anyname.js#x-ipfs-companion-no-redirect`;
Expand All @@ -66,15 +93,15 @@ Status.prototype.check = function() {
// and, even though it is failing here, we know it is UP
if (!this.up) {
this.up = false;
this.tag.textContent = 'DOWN: ❌ - ';
this.tag.textContent = '';
this.parent.failed();
}
};
};

Status.prototype.checked = function() {
this.up = true;
this.tag.innerHTML = '  UP: ✅ - ';
this.tag.innerHTML = '';
};

// this function is executed from that previously loaded script
Expand All @@ -94,8 +121,9 @@ function OnScriptloaded(src) {

let Cors = function(parent) {
this.parent = parent;
this.tag = document.createElement("span");
this.tag.textContent = ' CORS: 🕑 - ';
this.tag = document.createElement("div");
this.tag.className = "Cors";
this.tag.textContent = '🕑';
};

Cors.prototype.check = function() {
Expand All @@ -108,7 +136,7 @@ Cors.prototype.check = function() {
const matched = (HASH_STRING === text.trim());
if (matched) {
this.parent.checked();
this.tag.textContent = ' CORS: ✅ - ';
this.tag.textContent = '';
} else {
this.onerror();
}
Expand All @@ -118,32 +146,35 @@ Cors.prototype.check = function() {
};

Cors.prototype.onerror = function() {
this.tag.textContent = ' CORS: ❌ - ';
this.tag.textContent = '';
};

let Origin = function(parent) {
this.parent = parent;

this.tag = document.createElement("span");
this.tag.textContent = ' ORIGIN: 🕑 - ';
this.tag = document.createElement("div");
this.tag.className = "Origin";
this.tag.textContent = '🕑';
};

Origin.prototype.check = function() {
const cidInSubdomain = this.parent.gateway.startsWith('https://:hash.ipfs.');
if (cidInSubdomain) {
this.tag.textContent = ' ORIGIN: ✅ - ';
this.tag.textContent = '';
} else {
this.onerror();
}
};

Origin.prototype.onerror = function() {
this.tag.textContent = ' ORIGIN: ❌ - ';
this.tag.textContent = '';
};


let Node = function(parent, gateway, index) {
this.parent = parent;
this.tag = document.createElement("div");
this.tag.className = "Node";
this.tag.style["order"] = Date.now();

this.status = new Status(this);
this.tag.append(this.status.tag);
Expand All @@ -154,11 +185,15 @@ let Node = function(parent, gateway, index) {
this.origin = new Origin(this);
this.tag.append(this.origin.tag);

this.link = document.createElement("span");
this.link.textContent = gateway.replace(':hash', HASH_TO_TEST);
this.link = document.createElement("div");
let gatewayAndHash = gateway.replace(':hash', HASH_TO_TEST);
this.link.url = new URL(gatewayAndHash);
this.link.textContent = this.link.url.host.replace(`${HASH_TO_TEST}.`, "");
this.link.className = "Link";
this.tag.append(this.link);

this.took = document.createElement("span");
this.took = document.createElement("div");
this.took.className = "Took";
this.tag.append(this.took);

this.gateway = gateway;
Expand All @@ -167,7 +202,7 @@ let Node = function(parent, gateway, index) {
};

Node.prototype.check = function() {
this.checkingTime = performance.now();
this.checkingTime = Date.now();
this.status.check();
this.cors.check();
this.origin.check();
Expand All @@ -178,28 +213,22 @@ Node.prototype.checked = function() {
if (!this.status.up) {
this.status.checked();
this.parent.checked(this);
let gatewayTitle = this.gateway.split(":hash")[0];
let gatewayAndHash = this.gateway.replace(':hash', HASH_TO_TEST);
this.link.innerHTML = `<a title="${gatewayTitle}" href="${gatewayAndHash}#x-ipfs-companion-no-redirect" target="_blank">${gatewayAndHash}</a>`;
let ms = (performance.now() - this.checkingTime).toFixed(2);
this.took.textContent = ` (${ms}ms)`;
let url = this.link.url;
let host = url.host.replace(`${HASH_TO_TEST}.`, "");
this.link.innerHTML = `<a title="${url.origin}" href="${url}#x-ipfs-companion-no-redirect" target="_blank">${host}</a>`;
let ms = Date.now() - this.checkingTime;
this.tag.style["order"] = ms;
let s = (ms / 1000).toFixed(2);
this.took.textContent = `${s}s`;
}
};

Node.prototype.failed = function() {
this.parent.failed(this);
};

function checkGateways (gateways) {
gateways.forEach((gateway) => {
let node = new Node(checker.results, gateway, checker.nodes.length);
checker.nodes.push(node);
checker.results.append(node.tag);
node.check();
});
}

fetch('./gateways.json')
.then(res => res.json())
.then(gateways => checkGateways(gateways));
.then(gateways => checker.checkGateways(gateways));

26 changes: 11 additions & 15 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,18 @@
<head>
<meta charset="UTF-8">
<title>Public IPFS Gateways</title>
<style>
body, html {
font-family: monospace;
color: #121212;
background-color: #FAFAFA;
}

h1, h3 {
font-weight: normal;
}
</style>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="mobile-web-app-capable" content="yes">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="styles.css" type="text/css" rel="stylesheet"/>
</head>
<body id="checker">
<h1>Public IPFS Gateways</h1>
<h3 id="checker.stats"></h3>
<div id="checker.results"></div>
<div class="Header"><a href="https://ipfs.io" target="_blank" title="ipfs.io"><img src="https://ipfs.io/ipfs/QmTqZhR6f7jzdhLgPArDPnsbZpvvgxzCZycXK7ywkLxSyU?filename=ipfs-logo.3ea91a2f.svg" height="50"></a><div class="Title">Public Gateways</div></div>
<div id="checker.stats" class="Stats"></div>
<div id="checker.results" class="Results">
<div class="Node"><div class="Status">UP</div><div class="Cors">cors</div><div class="Origin" title="Orign Isolation">
<a href="https://docs.ipfs.io/guides/guides/addressing/#subdomain-gateway" target="_blank">OI</a></div><div class="Link"></div><div class="Took">resp</div></div>
</div>
</body>
<script src="./app.js"></script>
<script src="./app.js?v=0.1"></script>
</html>
2 changes: 1 addition & 1 deletion publish-to-ipfs.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#! /usr/bin/env bash

ipfs add -wQ app.js index.html gateways.json > lastpubver
ipfs add -wQ styles.css app.js index.html gateways.json > lastpubver
113 changes: 113 additions & 0 deletions styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
body, html {
font-family: monospace;
color: #222;
background-color: #FAFAFA;
margin: 0;
padding: 0;
box-sizing: border-box;
text-align: center;
}

div.Header {
display: flex;
justify-content: space-between;
align-items: center;
width: calc(100% - 2rem);
background-color: #0b3a53;
padding: 1rem;
}

div.Header a {
box-sizing: border-box;
}

div.Header a img {
height: 50px;
}

div.Header div.Title {
position: relative;
display: inline-block;
color: #69c4cd;
font-family: Montserrat,Verdana,system-ui,sans-serif;
font-size: 1.5rem;
text-align: right;
font-weight: 200;
}

div.Stats {
display: flex;
justify-content: flex-start;
align-items: center;
margin: 1em auto;
width: 95%;
max-width: 1024px;
}

div.Stats div.Totals,
div.Stats div.Gateways {
border-radius: 9999px;
color: white;
font-weight: bold;
padding: 0.5em 1em;
margin: 0 1em 0 0;
}

div.Stats div.Gateways {
background-color: #0b3a53;
}

div.Stats div.Totals {
background-color: rgb(0, 181, 0);
}

div.Results {
display: flex;
flex-direction: column;
justify-content: center;
margin: 0 auto;
width: 100%;
max-width: 1024px;
}

div.Node {
display: flex;
justify-content: space-evenly;
align-items: center;
width: 95%;
padding: 0.5em 0;
margin: 0 2.5%;
border-bottom: 1px solid #EEE;
}

div.Node div.Link {
width: 100%;
text-align: left;
}

div.Node div.Link a {
text-decoration: none;
color: #357edd;
white-space: nowrap;
}

div.Node div.Status,
div.Node div.Cors,
div.Node div.Origin {
width: 4em;
text-align: center;
font-weight: bold;
}

div.Node div.Cors,
div.Node div.Origin {
font-size: 80%;
}

div.Node div.Took {
width: 5em;
text-align: right;
font-size: 80%;
font-style: italic;
}

0 comments on commit c076bbb

Please sign in to comment.