Files
pluto/try.html
Julien Eluard 9438050fe0 Deploy website
Deploy website version based on 5ac25d2d46
2019-03-15 17:16:04 +01:00

317 lines
11 KiB
HTML

<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><title>Pluto · A grammar for data manipulation</title><meta name="viewport" content="width=device-width"/><meta name="generator" content="Docusaurus"/><meta name="description" content="A grammar for data manipulation"/><meta name="docsearch:language" content="en"/><meta property="og:title" content="Pluto · A grammar for data manipulation"/><meta property="og:type" content="website"/><meta property="og:url" content="https://status-im.github.io/pluto/index.html"/><meta property="og:description" content="A grammar for data manipulation"/><meta name="twitter:card" content="summary"/><link rel="shortcut icon" href="/pluto/img/favicon.png"/><link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css"/><script type="text/javascript" src="https://buttons.github.io/buttons.js"></script><script type="text/javascript" src="/pluto/js/pluto.js"></script><link rel="stylesheet" href="/pluto/css/prism.css"/><link rel="stylesheet" href="/pluto/css/main.css"/></head><body><div class="fixedHeaderContainer"><div class="headerWrapper wrapper"><header><a href="/pluto/"><img class="logo" src="/pluto/img/logo_white.png" alt="Pluto"/><h2 class="headerTitleWithLogo">Pluto</h2></a><div class="navigationWrapper navigationSlider"><nav class="slidingNav"><ul class="nav-site nav-site-internal"><li class="siteNavItemActive"><a href="/pluto/try.html" target="_self">Try</a></li></ul></nav></div></header></div></div><div class="navPusher"><div><!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/codemirror@5.40.2/lib/codemirror.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.indigo-pink.min.css">
<script defer src="https://code.getmdl.io/1.3.0/material.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/codemirror@5.40.2/lib/codemirror.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/codemirror@5.40.2/mode/clojure/clojure.js"></script>
<script src="https://cdn.jsdelivr.net/npm/parinfer@3.12.0/parinfer.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/parinfer-codemirror@1.4.2/parinfer-codemirror.min.js"></script>
<script src="https://cdn.rawgit.com/neocotic/qrious/master/dist/qrious.js"></script>
</head>
<body>
<script>
const TIMEOUT = 5; // seconds
const timeout = new Promise((resolve, reject) => {
return setTimeout(() => reject(new Error('request timeout')), TIMEOUT * 1000);
});
async function cat(hash) {
try {
const response = await Promise.race([timeout, fetch("https://ipfs.infura.io:5001/api/v0/cat?arg=" + hash)]);
if (response.status === 200) {
return response.text();
}
return null;
} catch {
return null;
}
}
async function add(content) {
const formData = new FormData();
formData.append("extension.edn", content);
const response = await fetch("https://ipfs.infura.io:5001/api/v0/add", {
method: 'post',
body: formData
});
if (response.status === 200) {
return response.json();
}
return null;
}
const defaultHash = "QmSbBVf31sjoqTe5DRUSBd2ADVQejWRqduU3FgfbC32kjP";
function clearHash() {
history.replaceState({hash: null}, null, document.location.href.split('?')[0]);
}
async function main () {
const params = (new URL(document.location)).searchParams;
const hash = params.get("hash") || defaultHash;
const content = await cat(hash);
if (content != null) {
codeMirror.setValue(content);
history.replaceState({hash: hash}, null, document.location.href.split('?')[0] + "?hash=" + hash);
displayQR(hash);
} else {
codeMirror.setValue("Failed to load the extension");
clearHash();
}
}
function extensionLink(hash) {
return "https://get.status.im/extension/ipfs@" + hash;
}
async function publish() {
const content = codeMirror.getValue();
const bel = document.getElementById("publish");
bel.disabled = true;
const object = await add(content);
if (object !== null) {
const hash = object.Hash;
history.pushState({hash: hash}, null, document.location.href.split('?')[0] + "?hash=" + hash);
displayQR(hash);
} else {
const qel = document.getElementById("qr-wrapper");
qel.innerHTML = "Failed to publish the extension";
}
bel.disabled = false;
}
function clearErrors() {
const elErrors = document.getElementById("errors");
elErrors.innerHTML = '';
elErrors.className = "";
}
function appendErrors(el, errors, h) {
const names = errors.map( (error, i) => {
return [error.type, error.value]
})
var s = '<div>Errors</div><ul>';
names.forEach(function(element) {
s = s.concat("<li>" + element[0]);
if (element[1] != null) {
s = s.concat(":" + JSON.stringify(element[1]));
}
s = s.concat("</li>");
});
s = s.concat("</ul>")
el.innerHTML = h+s;
}
function displayErrors(errors) {
const elErrors = document.getElementById("errors");
if (errors == null) {
elErrors.innerHTML = '<div>No errors</div>';
elErrors.classList.add("ok");
} else {
elErrors.classList.add("errors");
if (Array.isArray(errors)) {
appendErrors(el, errors);
} else {
for (var property in errors) {
if (errors.hasOwnProperty(property)) {
for (var property2 in errors[property]) {
if (errors[property].hasOwnProperty(property2)) {
appendErrors(elErrors, errors[property][property2], "<h4>"+property+"</h4><h5>"+property2+"</h5>")
}
}
}
}
}
}
}
function clearQR() {
const qel = document.getElementById("qr-wrapper");
qel.innerHTML = '';
}
function displayQR(hash) {
const qel = document.getElementById("qr-wrapper");
const s = extensionLink(hash);
qel.innerHTML = '<canvas id="qr"></canvas><a href="' + s + '">Universal link</a><a href="https://ipfs.infura.io/ipfs/' + hash + '/">IPFS link</a>';
new QRious({
element: document.getElementById('qr'),
value: s,
size: 250
});
}
main();
</script>
<div id="wrapper">
<main>
<div id="content"></div>
<div id="errors"></div>
</main>
<aside id="side-column">
<div id="panel">
<p>A playground to experiment with extensions and easily publish them on IPFS. Go ahead, modify the default extension on the left side!</p>
<p>Find more details about building your own extension in this <a href="https://status.im/extensions/">tutorial</a></p>
<button id="publish" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect" onclick="publish()">Publish</button>
<div id="qr-wrapper"></div>
</div>
<div id="docs">
<h6>Components</h6>
<ul>
<li><code>view</code></li>
<li><code>text</code></li>
<li>
<code>touchable-opacity</code>
<pre class="inline-args">{:on-press Event}</pre>
</li>
<li>
<code>image</code>
<pre class="inline-args">{:uri String}</pre>
</li>
<li>
<code>input</code>
<pre>{:on-change Event
:placeholder String}</pre></li>
<li>
<code>button</code>
<pre class="inline-args">{:on-click Event}</pre></li>
<li>
<code>link</code>
<pre class="inline-args">{:uri String}</pre>
</li>
<li>
<code>checkbox</code>
<pre class="inline-args">{:on-change Event :checked Bool}</pre>
</li>
<li>
<code>list</code>
<pre class="inline-args">{:data Vector :item-view View :key Keyword}</pre>
</li>
<li>
<code>picker</code>
<pre class="inline-args">{:on-change Event :selected String :enabled Boolean :data Vector}</pre>
</li>
<li>
<code>activity-indicator</code>
<pre class="inline-args">{:animating Boolean :color String :size Keyword :hides-when-stopped Boolean}</pre>
</li>
<li>
<code>nft-token-viewer</code>
<pre class="inline-args">{:token String}</pre>
</li>
<li><code>transaction-status</code>
<pre class="inline-args">{:outgoing String :tx-hash String}</pre></li>
<li><code>asset-selector</code></li>
<li><code>token-selector</code></li>
</ul>
<h6>Queries</h6>
<ul>
<li>
<code>store/get</code>
<pre class="inline-args">{:key String}</pre>
</li>
<li>
<code>wallet/collectibles</code>
<pre class="inline-args">{:token String :symbol String}</pre>
</li>
</ul>
<h6>Events</h6>
<ul>
<li>
<code>alert</code>
<pre class="inline-args">{:value String}</pre>
</li>
<li>
<code>log</code>
<pre class="inline-args">{:value String}</pre>
</li>
<li>
<code>store/put</code>
<pre class="inline-args">{:key String :value String}</pre>
</li>
<li>
<code>store/append</code>
<pre class="inline-args">{:key String :value String}</pre>
</li>
<li>
<code>store/clear</code>
<pre class="inline-args">{:key String}</pre>
</li>
<li>
<code>http/get</code>
<pre>{:url String
:timeout? String
:on-success Event
:on-failure? Event}</pre>
</li>
<li>
<code>http/post</code>
<pre>{:url String
:body String
:timeout? String
:on-success Event
:on-failure? Event}</pre>
</li>
<li>
<code>ipfs/cat</code>
<pre>{:hash String
:on-success Event
:on-failure? Event}</pre>
</li>
<li>
<code>ethereum/send-transaction</code>
<pre>{:to String
:gas? String
:gas-price? String
:value? String
:method? String
:params? Vector
:nonce? String
:on-result? Event}</pre>
</li>
<li>
<code>ethereum/logs</code>
<pre>{:fromBlock? String
:toBlock? String
:address? Vector
:topics? Vector
:blockhash? String
:on-result Event}</pre>
</li>
<li>
<code>ethereum/call</code>
<pre>{:to String
:method String
:params? Vector
:on-result? Event}</pre>
</li>
</ul>
</div>
</aside>
</div>
<script>
const codeMirror = CodeMirror(document.getElementById("content"));
codeMirror.setValue("Loading content ...");
codeMirror.on("change", function(c, change) {
clearErrors();
clearQR();
clearHash();
const read = pluto.js.read(codeMirror.getValue());
const readJS = pluto.js.from_clj(read);
displayErrors(readJS.errors);
if (readJS.errors == null) {
const parsed = pluto.js.parse(read);
const parsedJS = pluto.js.from_clj(parsed);
displayErrors(parsedJS.errors);
}
});
parinferCodeMirror.init(codeMirror);
</script>
</body>
</html>
</div><footer class="nav-footer" id="footer"><section class="sitemap"><a href="/pluto/" class="nav-home"><img src="/pluto/img/logo_white.png" alt="Pluto" width="66" height="58"/></a><div><h5>Community</h5><a href="https://chat.status.im">Project Chat</a><a href="https://twitter.com/ethstatus" target="_blank" rel="noreferrer noopener">Twitter</a></div><div><h5>More</h5><a href="https://blog.status.im/">Blog</a><a href="https://github.com/status-im/pluto/">GitHub</a></div></section><section class="copyright">Copyright © 2019 Status.im</section></footer></div></body></html>