Add footer
parent
0de342a5f2
commit
a8be0af2a9
|
|
@ -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...)
|
||||
|
||||
|
|
|
|||
28
index.html
28
index.html
|
|
@ -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>
|
||||
|
|
|
|||
13
index.js
13
index.js
|
|
@ -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);
|
||||
});
|
||||
};
|
||||
|
|
|
|||
55
style.css
55
style.css
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue