Add footer

master
Boris Kubiak 2020-04-24 15:30:20 +02:00
parent 0de342a5f2
commit a8be0af2a9
4 changed files with 84 additions and 16 deletions

View File

@ -2,9 +2,9 @@
[NoPaste](https://nopaste.ml/) is a client-side paste service which works with **no database**, and **no back-end code**
Instead, the pasted data is **compressed** then **stored** into a unique URL that can be decoded later. For example, [this is the CSS code used by NoPaste][example]
Instead, the data is **compressed** then **stored** into a unique URL that can be decoded later. For example, [this is the CSS code used by NoPaste][example]
As a result, there is no risk of data being lost, censored or deleted. The whole data is **in the link** and nowhere else 🤯
As a result, there is no risk of data being lost, censored or deleted. The whole data stored is **in the link** and nowhere else! 🤯
**Note:** This project is a fork of [Topaz's paste service][topaz-example], with a reworked design and a few additional features (syntax highlighting, line numbers, embedding...)

View File

@ -7,7 +7,7 @@
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
/>
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>NoPaste - Client-side paste service</title>
<title>NoPaste - No-database paste service</title>
<script src="https://cdn.jsdelivr.net/combine/
npm/lzma@2.3.2/src/lzma.min.js,
npm/slim-select@1.25.0/dist/slimselect.min.js,
@ -33,9 +33,13 @@ npm/codemirror@5.52.0/theme/dracula.min.css
/>
<link rel="stylesheet" href="style.css" />
<link href="favicon.ico" rel="icon" type="image/x-icon" />
<meta
name="description"
content="NoPaste is a client-side paste service which works with no database, and no back-end code. The whole data is stored in shareable links and nowhere else!"
/>
</head>
<body class="m-0">
<div id="copy" class="container-fluid hidden">
<div id="copy" class="container-fluid hidden shadow-bottom hide-readonly">
<div class="row my-1">
<div class="col my-1">
<input
@ -59,7 +63,7 @@ npm/codemirror@5.52.0/theme/dracula.min.css
</div>
</div>
</div>
<div id="controls" class="container-fluid">
<div id="controls" class="container-fluid shadow-bottom hide-readonly">
<div class="row align-items-center justify-content-end my-1">
<div class="col mb-1">
<h1 class="title my-0">{ NoPaste }</h1>
@ -78,6 +82,24 @@ npm/codemirror@5.52.0/theme/dracula.min.css
</div>
<div id="progress"></div>
<div id="editor"></div>
<footer class="shadow-top container-fluid">
<div class="row my-1">
<div class="col mono" id="stats"></div>
<div class="col-auto">
<a href="javascript:void(0)" class="description-trigger">What is NoPaste?</a>
<div id="description" class="hidden shadow-bottom p-3">
NoPaste is a client-side paste service which works with <b>no database</b>, and
<b>no back-end code</b>.<br /><br />
Instead, the data is <b>compressed</b> then <b>stored</b> into a unique URL that can be decoded
later.<br /><br />
As a result, there is no risk of data being lost, censored or deleted. The whole data is stored
<b>in the link</b> and nowhere else!
</div>
<div class="overlay hidden"></div>
</div>
<div class="col-auto"><a href="https://github.com/bokub/nopaste" target="_blank">Github</a></div>
</div>
</footer>
</body>
<script src="index.js"></script>

View File

@ -4,6 +4,7 @@ const lzma = new LZMA(window.URL.createObjectURL(blob));
let editor = null;
let select = null;
let clipboard = null;
let statsEl = null;
const init = () => {
initCodeEditor();
@ -24,6 +25,11 @@ const initCodeEditor = () => {
if (readOnly) {
document.body.classList.add('readonly');
}
statsEl = document.getElementById('stats');
editor.on('change', () => {
statsEl.innerHTML = `Length: ${editor.getValue().length} | Lines: ${editor['doc'].size}`;
});
};
const initLangSelector = () => {
@ -67,12 +73,17 @@ const initClipboard = () => {
};
const generateLink = (mode) => {
compress(editor.getValue(), (base64, err) => {
const data = editor.getValue();
compress(data, (base64, err) => {
if (err) {
alert('Failed to compress data: ' + err);
return;
}
const url = buildUrl(base64, mode);
statsEl.innerHTML = `Data length: ${data.length} | Link length: ${
url.length
} | Compression ratio: ${Math.round((100 * url.length) / data.length)}%`;
showCopyBar(url);
});
};

View File

@ -4,6 +4,8 @@ body {
display: flex;
flex-flow: column;
height: 100vh;
color: #fff;
font: normal 14px Roboto, sans-serif;
}
#editor {
@ -13,10 +15,11 @@ body {
}
#controls,
#copy {
#copy,
#description,
footer {
background-color: #3b3b47;
z-index: 10;
box-shadow: rgba(0, 0, 0, 0.15) 0 3px 10px;
}
#progress {
@ -28,8 +31,7 @@ body {
#copy:not(.hidden) + #controls,
.hidden,
.readonly #controls,
.readonly #copy {
.readonly .hide-readonly {
display: none;
}
@ -38,23 +40,57 @@ body {
width: 100%;
}
/* Styling */
.shadow-bottom {
box-shadow: rgba(0, 0, 0, 0.15) 0 3px 10px;
}
.shadow-top {
box-shadow: rgba(0, 0, 0, 0.15) 0 -3px 10px;
}
a,
a:hover,
a:active {
color: #fff;
}
.CodeMirror {
height: 100%;
font-size: 14px;
font-family: JetBrainsMono, sans-serif;
}
.title {
color: #fff;
font: normal 24px JetBrainsMono, sans-serif;
white-space: nowrap;
}
.mono {
font-family: JetBrainsMono, sans-serif;
}
.description-trigger:hover + #description {
display: block;
position: fixed;
bottom: 20px;
margin: 40px;
right: 0;
max-width: 350px;
}
.description-trigger:hover + #description + .overlay {
/* Used to un-hover on mobile */
display: block;
position: fixed;
background: transparent;
right: 0;
top: 0;
left: 0;
bottom: 25px;
}
#description b {
font-weight: normal;
color: #ff79c6;
}
/* Form elements */
#controls .ss-main {
width: 180px;
font-family: Roboto, sans-serif;
}
.ss-main .ss-single-selected,
@ -65,8 +101,7 @@ input[type='search'] {
color: #fff !important;
border-radius: 2px !important;
border: 1px solid #ccc !important;
font-size: 14px !important;
font-family: Roboto, sans-serif;
font: normal 14px Roboto, sans-serif;
height: 26px !important;
}