Redesign 1 bcrypt #226

Merged
bones7242 merged 156 commits from redesign-1-bcrypt into master 2017-10-30 15:55:14 +01:00
9 changed files with 292 additions and 285 deletions
Showing only changes of commit f3fbc2068b - Show all commits

View file

@ -13,17 +13,9 @@
} }
/* publish */ /* publish */
#drop-zone {
border: 1px dashed lightgrey;
padding: 1em;
height: 13em;
background: #F5F0EF;
}
#asset-preview-holder {
width: 100%;
margin-bottom: 1em;
}
/* show routes */ /* show routes */
.show-asset { .show-asset {

View file

@ -36,10 +36,6 @@ h1 {
h2 { h2 {
font-size: x-large; font-size: x-large;
margin-top: 1em;
border-top: 1px #999 solid;
background-color: lightgray;
padding: 6px;
} }
h3 { h3 {
@ -173,6 +169,14 @@ input:-webkit-autofill {
border: 1px solid grey; border: 1px solid grey;
} }
.input-disabled {
border: 1px solid black;
padding: 0.5em;
margin: 0.5em 0.3em 0.5em 0.3em;
color: black;
background-color: white;
}
/* BUTTONS */ /* BUTTONS */
button { button {

View file

@ -1,14 +1,25 @@
/* Publish Form */ /* Publish Form */
/* blocks */
.publish {
}
/* elements */
.publish-dropzone { .publish-dropzone {
border: 1px dashed lightgrey; border: 1px dashed lightgrey;
padding: 1em; padding: 1em;
height: 13em; height: 13em;
background: #F5F0EF; background: #F5F0EF;
}
.asset-preview {
display: block;
width: 100%;
}
/* Show page */
.asset-display {
display: block;
width: 100%;
}
.copy-input {
} }

View file

@ -1,94 +0,0 @@
/* drop zone functions */
function drop_handler(ev) {
ev.preventDefault();
// if dropped items aren't files, reject them
var dt = ev.dataTransfer;
if (dt.items) {
if (dt.items[0].kind == 'file') {
var droppedFile = dt.items[0].getAsFile();
previewAndStageFile(droppedFile);
}
}
}
function dragover_handler(ev) {
ev.preventDefault();
}
function dragend_handler(ev) {
var dt = ev.dataTransfer;
if (dt.items) {
for (var i = 0; i < dt.items.length; i++) {
dt.items.remove(i);
}
} else {
ev.dataTransfer.clearData();
}
}
/* publish functions */
// update the publish status
function updatePublishStatus(msg){
document.getElementById('publish-status').innerHTML = msg;
}
// When a file is selected for publish, validate that file and
// stage it so it will be ready when the publish button is clicked.
function previewAndStageFile(selectedFile){
var previewHolder = document.getElementById('asset-preview-holder');
var dropzone = document.getElementById('drop-zone');
var previewReader = new FileReader();
var nameInput = document.getElementById('claim-name-input');
// validate the file's name, type, and size
try {
validateFile(selectedFile);
} catch (error) {
showError('input-error-file-selection', error.message);
return;
}
// set the image preview, if an image was provided
if (selectedFile.type !== 'video/mp4') {
previewReader.readAsDataURL(selectedFile);
previewReader.onloadend = function () {
dropzone.style.display = 'none';
previewHolder.style.display = 'block';
previewHolder.innerHTML = '<img width="100%" src="' + previewReader.result + '" alt="image preview"/>';
};
}
// set the name input value to the image name if none is set yet
if (nameInput.value === "") {
var filename = selectedFile.name.substring(0, selectedFile.name.indexOf('.'))
nameInput.value = cleanseClaimName(filename);
checkClaimName(nameInput.value);
}
// store the selected file for upload
stagedFiles = [selectedFile];
}
// Validate the publish submission and then trigger publishing.
function publishSelectedImage(event) {
var claimName = document.getElementById('claim-name-input').value;
var channelName = document.getElementById('channel-name-select').value;
// prevent default so this script can handle submission
event.preventDefault();
// validate, submit, and handle response
validateFilePublishSubmission(stagedFiles, claimName, channelName)
.then(() => {
uploader.submitFiles(stagedFiles);
})
.catch(error => {
if (error.name === 'FileError') {
showError(document.getElementById('input-error-file-selection'), error.message);
} else if (error.name === 'NameError') {
showError(document.getElementById('input-error-claim-name'), error.message);
} else if (error.name === 'ChannelNameError'){
console.log(error);
showError(document.getElementById('input-error-channel-select'), error.message);
} else {
showError(document.getElementById('input-error-publish-submit'), error.message);
}
return;
})
};

View file

@ -1,24 +1,25 @@
<script src="/assets/js/generalFunctions.js"></script> <script src="/assets/js/generalFunctions.js"></script>
{{> topBar}} {{> topBar}}
<div class="row" id="file-selection-area"> <div class="row" id="drop-zone-wrapper">
<div id="drop-zone" ondrop="drop_handler(event);" ondragover="dragover_handler(event);" ondragend="dragend_handler(event)"> <div class="publish-dropzone align-content-center" ondrop="drop_handler(event);" ondragover="dragover_handler(event);" ondragend="dragend_handler(event)">
<div class="row"> <p>Drag and drop your file here, or choose your file below.</p>
<p>Drag and drop your file here, or choose your file below.</p> <div class="info-message info-message--failure" id="input-error-file-selection" hidden="true"></div>
<div class="info-message info-message--failure" id="input-error-file-selection" hidden="true"></div> <input type="file" id="siofu_input" name="file" accept="video/*,image/*" onchange="previewAndStageFile(event.target.files[0])" enctype="multipart/form-data"/>
</div>
<div class="row">
<input type="file" id="siofu_input" name="file" accept="video/*,image/*" onchange="previewAndStageFile(event.target.files[0])" enctype="multipart/form-data"/>
</div>
</div> </div>
</div> </div>
<div class="row"> <div class="row" id="publish-form-wrapper" hidden="true">
<div class="column column--5" id="asset-preview-holder"></div> <div class="column column--4 align-content-top" >
<div class="column column--5" id="publish-active-area"> <div id="asset-preview-holder" class="asset-show"></div>
{{> publishForm-Channel}} </div><div class="column column--1" ></div><div class="column column--5 align-content-top">
{{> publishForm-Url}} <div id="publish-status" hidden="true"></div>
{{> publishForm-Details}} <div id="publish-progress-bar" hidden="true"></div>
{{> publishForm-Submit}} <div id="publish-active-area">
{{> publishForm-Channel}}
{{> publishForm-Url}}
{{> publishForm-Details}}
{{> publishForm-Submit}}
</div>
</div> </div>
</div> </div>
@ -26,35 +27,39 @@
<script src="/siofu/client.js"></script> <script src="/siofu/client.js"></script>
<script src="/assets/js/validationFunctions.js"></script> <script src="/assets/js/validationFunctions.js"></script>
<script src="/assets/js/publishFileFunctions.js"></script> <script src="/assets/js/publishFileFunctions.js"></script>
<script type="text/javascript" >
function resetPublishArea (){
// reset file selection area
document.getElementById('file-selection-area').innerHTML = `<div id="drop-zone" ondrop="drop_handler(event);" ondragover="dragover_handler(event);" ondragend="dragend_handler(event)">
<p>Drag and drop your file here, or choose your file below.</p>
<div class="info-message info-message--failure" id="input-error-file-selection" hidden="true"></div>
<input type="file" id="siofu_input" name="file" accept="video/*,image/*" onchange="previewAndStageFile(event.target.files[0])" enctype="multipart/form-data"/>
</div>
<div id="asset-preview-holder"></div>`;
// reset inputs
document.getElementById('claim-name-input').value = '';
document.getElementById('publish-title').value = '';
document.getElementById('publish-description').value = '';
document.getElementById('publish-nsfw').checked = false;
// remove staged files
stagedFiles = null;
// clear any errors
document.getElementById('input-error-file-selection').innerHTML = '';
document.getElementById('input-error-claim-name').innerHTML = '';
document.getElementById('input-error-publish-submit').innerHTML = '';
document.getElementById('input-success-claim-name').hidden = true;
}
</script>
<script typ="text/javascript"> <script typ="text/javascript">
// define variables var socket = io();
var socket = io(); var uploader = new SocketIOFileUpload(socket);
var uploader = new SocketIOFileUpload(socket); var stagedFiles = null;
var stagedFiles = null; /* drop zone functions */
function drop_handler(ev) {
ev.preventDefault();
// if dropped items aren't files, reject them
var dt = ev.dataTransfer;
if (dt.items) {
if (dt.items[0].kind == 'file') {
var droppedFile = dt.items[0].getAsFile();
previewAndStageFile(droppedFile);
}
}
}
function dragover_handler(ev) {
ev.preventDefault();
}
function dragend_handler(ev) {
var dt = ev.dataTransfer;
if (dt.items) {
for (var i = 0; i < dt.items.length; i++) {
dt.items.remove(i);
}
} else {
ev.dataTransfer.clearData();
}
}
/* socketio-file-upload listeners */ /* socketio-file-upload listeners */
function updatePublishStatus(msg){
document.getElementById('publish-status').innerHTML = msg;
}
uploader.addEventListener('start', function(event){ uploader.addEventListener('start', function(event){
var name = document.getElementById('claim-name-input').value; var name = document.getElementById('claim-name-input').value;
var title = document.getElementById('publish-title').value; var title = document.getElementById('publish-title').value;
@ -69,10 +74,12 @@
event.file.meta.nsfw = nsfw; event.file.meta.nsfw = nsfw;
event.file.meta.type = stagedFiles[0].type; event.file.meta.type = stagedFiles[0].type;
event.file.meta.channel = channel; event.file.meta.channel = channel;
// re-set the html in the publish area // hide the submit area
document.getElementById('publish-active-area').innerHTML = '<div id="publish-status"></div><div id="progress-bar"></div>'; document.getElementById('publish-active-area').hidden = true;
// start a progress animation // show the progress status and animation
createProgressBar(document.getElementById('progress-bar'), 12); document.getElementById('publish-status').hidden = false;
document.getElementById('publish-progress-bar').hidden = false;
createProgressBar(document.getElementById('publish-progress-bar'), 12);
// google analytics // google analytics
ga('send', { ga('send', {
hitType: 'event', hitType: 'event',
@ -89,16 +96,15 @@
updatePublishStatus(msg); updatePublishStatus(msg);
}); });
socket.on('publish-failure', function(msg){ socket.on('publish-failure', function(msg){
document.getElementById('publish-active-area').innerHTML = '<p> --(✖╭╮✖)→ </p><p>' + JSON.stringify(msg) + '</p><strong>For help, post the above error text in the #speech channel on the <a href="https://lbry.slack.com/" target="_blank">lbry slack</a></strong>'; updatePublishStatus('<p> --(✖╭╮✖)→ </p><p>' + JSON.stringify(msg) + '</p><strong>For help, post the above error text in the #speech channel on the <a href="https://lbry.slack.com/" target="_blank">lbry slack</a></strong>');
document.getElementById('publish-progress-bar').hidden = true;
}); });
socket.on('publish-complete', function(msg){ socket.on('publish-complete', function(msg){
var publishResults;
var showUrl = msg.result.claim_id + "/" + msg.name; var showUrl = msg.result.claim_id + "/" + msg.name;
// build new publish area // update status
publishResults = '<p>Your publish is complete! You are being redirected to it now.</p>'; updatePublishStatus('<p>Your publish is complete! You are being redirected to it now.</p><p><a target="_blank" href="' + showUrl + '">If you do not get redirected, click here.</a></p>');
publishResults += '<p><a target="_blank" href="' + showUrl + '">If you do not get redirected, click here.</a></p>'; document.getElementById('publish-progress-bar').hidden = true;
// update publish area // redirect the user
document.getElementById('publish-active-area').innerHTML = publishResults;
window.location.href = showUrl; window.location.href = showUrl;
}); });
</script> </script>

View file

@ -1,23 +1,19 @@
<div class="row"> <a href="/{{fileInfo.claimId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}">
<div id="asset-placeholder"> {{#ifConditional fileInfo.fileType '===' 'video/mp4'}}
<a href="/{{fileInfo.claimId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}"> {{#ifConditional fileInfo.fileExt '===' 'gifv'}}
{{#ifConditional fileInfo.fileType '===' 'video/mp4'}} <video class="asset-display" autoplay loop muted>
{{#ifConditional fileInfo.fileExt '===' 'gifv'}} <source src="/media/{{fileInfo.fileName}}">
<video class="show-asset" autoplay loop muted> {{!--fallback--}}
<source src="/media/{{fileInfo.fileName}}"> Your browser does not support the <code>video</code> element.
{{!--fallback--}} </video>
Your browser does not support the <code>video</code> element. {{else}}
</video> <video class="asset-display" autoplay controls>
{{else}} <source src="/media/{{fileInfo.fileName}}">
<video class="show-asset" autoplay controls> {{!--fallback--}}
<source src="/media/{{fileInfo.fileName}}"> Your browser does not support the <code>video</code> element.
{{!--fallback--}} </video>
Your browser does not support the <code>video</code> element. {{/ifConditional}}
</video> {{else}}
{{/ifConditional}} <img class="asset-display" src="/media/{{fileInfo.fileName}}" />
{{else}} {{/ifConditional}}
<img class="show-asset" src="/media/{{fileInfo.fileName}}" /> </a>
{{/ifConditional}}
</a>
</div>
</div>

View file

@ -1,76 +1,99 @@
<div class="panel">
<h2>Title</h2> <h2>Title</h2>
<p>{{fileInfo.title}}</> <div class="row row--thin">
</div> {{fileInfo.title}}
<div class="panel links"> </div>
<h2>Links</h2> <h2>Links</h2>
{{!--short direct link to asset--}} {{!-- short direct link to asset --}}
<div class="share-option"> <div class="row row--thin">
<a href="/{{fileInfo.shortId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}">Permanent Short Link</a> (most convenient) <div class="column column--5">
<div class="input-error" id="input-error-copy-short-link" hidden="true"></div> <a href="/{{fileInfo.shortId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}">Short Link</a>
<br/> <div class="input-error" id="input-error-copy-short-link" hidden="true"></div>
<input type="text" id="short-link" class="link" readonly spellcheck="false" value="https://spee.ch/{{fileInfo.shortId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}" onclick="select()"/> <br/>
<button class="copy-button" data-elementtocopy="short-link" onclick="copyToClipboard(event)">copy</button> <input type="text" id="short-link" class="input-disabled" readonly spellcheck="false" value="https://spee.ch/{{fileInfo.shortId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}" onclick="select()"/>
</div><div class="column column--4">
<button class="copy-button" data-elementtocopy="short-link" onclick="copyToClipboard(event)">copy</button>
</div>
</div> </div>
{{!-- link to show route for asset--}} {{!-- html text for embedding asset--}}
<div class="share-option"> <div class="row row--thin">
<a href="/{{fileInfo.claimId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}">Permanent Long Link</a> (fastest service) <div class="column column--5">
<div class="input-error" id="input-error-copy-long-link" hidden="true"></div> Embed HTML
</br> <div class="input-error" id="input-error-copy-embed-text" hidden="true"></div>
<input type="text" id="long-link" class="link" readonly onclick="select()" spellcheck="false" value="https://spee.ch/{{fileInfo.claimId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}"/> <br/>
<button class="copy-button" data-elementtocopy="long-link" onclick="copyToClipboard(event)">copy</button> {{#ifConditional fileInfo.fileType '===' 'video/mp4'}}
</div> <input type="text" id="embed-text" class="input-disabled" readonly onclick="select()" spellcheck="false" value='&lt;video width="100%" controls src="https://spee.ch/{{fileInfo.claimId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}"/>&lt;/video>'/>
{{!-- html text for embedding asset--}} {{else}}
<div class="share-option"> <input type="text" id="embed-text" class="input-disabled" readonly onclick="select()" spellcheck="false" value='&lt;img src="https://spee.ch/{{fileInfo.claimId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}" />'/>
Embed HTML {{/ifConditional}}
<div class="input-error" id="input-error-copy-embed-text" hidden="true"></div> </div><div class="column column--5">
<br/> <button class="copy-button" data-elementtocopy="embed-text" onclick="copyToClipboard(event)">copy</button>
{{#ifConditional fileInfo.fileType '===' 'video/mp4'}} </div>
<input type="text" id="embed-text" class="link" readonly onclick="select()" spellcheck="false" value='&lt;video width="100%" controls src="https://spee.ch/{{fileInfo.claimId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}"/>&lt;/video>'/> </div>
{{else}} {{!-- more options --}}
<input type="text" id="embed-text" class="link" readonly onclick="select()" spellcheck="false" value='&lt;img src="https://spee.ch/{{fileInfo.claimId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}" />'/> <!--<div hidden="true">-->
{{/ifConditional}} <!--{{!-- long link to asset --}}-->
<button class="copy-button" data-elementtocopy="embed-text" onclick="copyToClipboard(event)">copy</button> <!--<div class="share-option">-->
</div> <!--<a href="/{{fileInfo.claimId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}">Permanent Long Link</a> (fastest service)-->
{{!--markdown text using asset--}} <!--<div class="input-error" id="input-error-copy-long-link" hidden="true"></div>-->
{{#ifConditional fileInfo.fileType '===' 'video/mp4'}} <!--</br>-->
{{else}} <!--<input type="text" id="long-link" class="link" readonly onclick="select()" spellcheck="false" value="https://spee.ch/{{fileInfo.claimId}}/{{fileInfo.name}}.{{fileInfo.fileExt}}"/>-->
<div class="share-option"> <!--<button class="copy-button" data-elementtocopy="long-link" onclick="copyToClipboard(event)">copy</button>-->
Markdown <!--</div>-->
<div class="input-error" id="input-error-copy-markdown-text" hidden="true"></div> <!--{{!-- optional: markdown text for non-videos--}}-->
<br/> <!--{{#ifConditional fileInfo.fileType '===' 'video/mp4'}}-->
<input type="text" id="markdown-text" class="link" readonly onclick="select()" spellcheck="false" value='![{{fileInfo.name}}](https://spee.ch/{{fileInfo.claimId}}/{{fileInfo.name}}.{{fileInfo.fileExt}})'/> <!--{{else}}-->
<button class="copy-button" data-elementtocopy="markdown-text" onclick="copyToClipboard(event)">copy</button> <!--<div class="share-option">-->
</div> <!--Markdown-->
{{/ifConditional}} <!--<div class="input-error" id="input-error-copy-markdown-text" hidden="true"></div>-->
</div> <!--<br/>-->
<div class="panel"> <!--<input type="text" id="markdown-text" class="link" readonly onclick="select()" spellcheck="false" value='![{{fileInfo.name}}](https://spee.ch/{{fileInfo.claimId}}/{{fileInfo.name}}.{{fileInfo.fileExt}})'/>-->
<!--<button class="copy-button" data-elementtocopy="markdown-text" onclick="copyToClipboard(event)">copy</button>-->
<!--</div>-->
<!--{{/ifConditional}}-->
<!--</div>-->
<h2>Description</h2> <h2>Description</h2>
<p>{{fileInfo.description}}</p> <div class="row row--thin">
</div> {{fileInfo.description}}
<div class="panel"> </div>
<h2>Metadata</h2> <h2>Metadata</h2>
<table class="metadata-table" style="table-layout: fixed"> <div class="row row--thin">
<tr class="metadata-row"> <table class="metadata-table" style="table-layout: fixed">
<td class="left-column">Name</td> <tr class="metadata-row">
<td>{{fileInfo.name}}</td> <td class="left-column">Name</td>
</tr> <td>{{fileInfo.name}}</td>
<tr class="metadata-row"> </tr>
<td class="left-column">Claim Id</td> <tr class="metadata-row">
<td>{{fileInfo.claimId}}</td> <td class="left-column">Claim Id</td>
</tr> <td class="wrap-words">{{fileInfo.claimId}}</td>
<tr class="metadata-row"> </tr>
<td class="left-column">File Name</td> <tr class="metadata-row">
<td>{{fileInfo.fileName}}</td> <td class="left-column">File Name</td>
</tr> <td>{{fileInfo.fileName}}</td>
<tr> </tr>
<td class="left-column">File Type</td> <tr>
<td>{{#if fileInfo.fileType}} <td class="left-column">File Type</td>
{{fileInfo.fileType}} <td>{{#if fileInfo.fileType}}
{{else}} {{fileInfo.fileType}}
unknown {{else}}
{{/if}} unknown
</td> {{/if}}
</tr> </td>
</table> </tr>
</div> </table>
</div>
<script type ="text/javascript">
function copyToClipboard(event){
var elementToCopy = event.target.dataset.elementtocopy;
var element = document.getElementById(elementToCopy);
var errorElement = 'input-error-copy-text' + elementToCopy;
element.select();
try {
document.execCommand('copy');
} catch (err) {
showError(errorElement, 'Oops, unable to copy');
}
}
</script>

View file

@ -1,3 +1,86 @@
<div class="input-error" id="input-error-publish-submit" hidden="true"></div> <div class="input-error" id="input-error-publish-submit" hidden="true"></div>
<button id="publish-submit" onclick="publishSelectedImage(event)">Publish</button> <button id="publish-submit" onclick="publishSelectedImage(event)">Publish</button>
<button onclick="resetPublishArea()">Reset</button> <button onclick="resetPublishArea()">Reset</button>
<script type="text/javascript" >
}
</script>
<script type="text/javascript" >
function resetPublishArea () {
// reset the drop zone
// remove staged files
stagedFiles = null;
// reset publish form inputs
document.getElementById('claim-name-input').value = '';
document.getElementById('publish-title').value = '';
document.getElementById('publish-description').value = '';
document.getElementById('publish-nsfw').checked = false;
// clear any errors
document.getElementById('input-error-file-selection').innerHTML = '';
document.getElementById('input-error-claim-name').innerHTML = '';
document.getElementById('input-error-publish-submit').innerHTML = '';
document.getElementById('input-success-claim-name').hidden = true;
}
/* publish functions */
// When a file is selected for publish, validate that file and
// stage it so it will be ready when the publish button is clicked.
function previewAndStageFile(selectedFile){
const publishForm = document.getElementById('publish-form-wrapper');
var previewHolder = document.getElementById('asset-preview-holder');
var dropzone = document.getElementById('drop-zone-wrapper');
var previewReader = new FileReader();
var nameInput = document.getElementById('claim-name-input');
// validate the file's name, type, and size
try {
validateFile(selectedFile);
} catch (error) {
showError('input-error-file-selection', error.message);
return;
}
// set the image preview, if an image was provided
if (selectedFile.type !== 'video/mp4') {
previewReader.readAsDataURL(selectedFile);
previewReader.onloadend = function () {
previewHolder.innerHTML = '<img width="100%" src="' + previewReader.result + '" alt="image preview"/>';
};
}
// hide the drop zone
dropzone.hidden = true;
publishForm.hidden = false;
// set the name input value to the image name if none is set yet
if (nameInput.value === "") {
var filename = selectedFile.name.substring(0, selectedFile.name.indexOf('.'))
nameInput.value = cleanseClaimName(filename);
checkClaimName(nameInput.value);
}
// store the selected file for upload
stagedFiles = [selectedFile];
}
// Validate the publish submission and then trigger publishing.
function publishSelectedImage(event) {
var claimName = document.getElementById('claim-name-input').value;
var channelName = document.getElementById('channel-name-select').value;
// prevent default so this script can handle submission
event.preventDefault();
// validate, submit, and handle response
validateFilePublishSubmission(stagedFiles, claimName, channelName)
.then(() => {
uploader.submitFiles(stagedFiles);
})
.catch(error => {
if (error.name === 'FileError') {
showError(document.getElementById('input-error-file-selection'), error.message);
} else if (error.name === 'NameError') {
showError(document.getElementById('input-error-claim-name'), error.message);
} else if (error.name === 'ChannelNameError'){
console.log(error);
showError(document.getElementById('input-error-channel-select'), error.message);
} else {
showError(document.getElementById('input-error-publish-submit'), error.message);
}
return;
})
};
</script>

View file

@ -1,24 +1,10 @@
{{> topBar}} {{> topBar}}
<div class="main"> <div class="row">
{{> asset}} <div class="column column--5 align-content-top">
</div> {{> asset}}
<div class="sidebar"> </div><div class="column column--1">
{{> assetInfo}} </div><div class="column column--4 align-content-top">
</div> {{> assetInfo}}
</div>
</div>
<script type ="text/javascript">
function copyToClipboard(event){
var elementToCopy = event.target.dataset.elementtocopy;
var element = document.getElementById(elementToCopy);
var errorElement = 'input-error-copy-text' + elementToCopy;
element.select();
try {
document.execCommand('copy');
} catch (err) {
showError(errorElement, 'Oops, unable to copy');
}
}
</script>