style: share, combine

This commit is contained in:
goldsteinsveta 2020-09-07 16:05:17 +02:00 committed by goldsteinsveta
parent 85c5539166
commit 880d2885fa
No known key found for this signature in database
GPG Key ID: 2DE4B3A7D2DBC98E
6 changed files with 281 additions and 236 deletions

View File

@ -1,17 +1,20 @@
<template>
<div id="app">
<div id="app" class="measure">
<ForkMe url="https://github.com/paritytech/banana_split" />
<GeneralInfo />
<div v-if="secure">
<router-view />
<nav>
<router-link to="/share">
Create
</router-link>
<router-link to="/combine">
Restore
</router-link>
<h1 id="logo">Banana<br />Split</h1>
<div class="measure">
<router-link class="button-nav" to="/share">
Create
</router-link>
<router-link class="button-nav" to="/combine">
Restore
</router-link>
</div>
<GeneralInfo />
</nav>
<router-view />
</div>
<SavePageInfo v-else-if="!localFile" />
<GoOfflineInfo v-else-if="isOnline" />
@ -54,86 +57,196 @@ export default {
</script>
<style>
body {
margin: 0;
color: #49494b;
background: #ebe8e3;
:root {
--c_bg-app: #f2f1f0;
--c_bg-card: #fff;
--c_bg-emphasis-main: #353535;
--c_bg-emphasis-dark: #000;
--c_border-main: #d6d6d6;
--c_border-light: #ebebeb;
--c_text-main: #222;
--c_text-secondary: #606060;
--c_text-onEmphasis: #fff;
--w_app: 620px;
--f_main: "Avenir", Helvetica, Arial, sans-serif;
}
#app {
font-family: "Avenir Next Condensed", "Avenir", Helvetica, Arial, sans-serif;
* {
box-sizing: border-box;
}
html {
font-family: var(--f_main);
font-size: 8px;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
padding: 0 0 200px 0;
}
p {
font-family: "Avenir", Helvetica, Arial, sans-serif;
body {
margin: 0;
color: var(--c_text-main);
background: var(--c_bg-app);
font-size: 1.8rem;
}
nav {
padding: 20px;
background: linear-gradient(rgba(235, 232, 226, 0), #ebe8e3);
.measure {
width: var(--w_app);
max-width: 100vw;
}
.flex {
display: flex;
position: fixed;
bottom: 0;
left: 0;
right: 0;
}
.justify-between {
justify-content: space-between;
}
.align-center {
align-items: center;
}
#app {
margin: auto;
}
nav {
display: flex;
align-items: baseline;
}
.card,
.card-alt,
.card-qr {
border-radius: 1rem;
margin: 1rem 0;
}
.card,
.card-alt {
padding: 1rem 3rem;
}
.card,
.card-qr {
box-shadow: 0 0 3rem var(--c_border-main);
background-color: var(--c_bg-card);
}
.card-qr {
display: inline-flex;
margin: 0.5rem;
}
.card-qr:not(.remaining) {
animation: unblur 1s ease;
}
@keyframes unblur {
0% {
filter: blur(5px) brightness(200%);
}
100% {
filter: none;
}
}
.card-qr canvas {
width: 100%;
max-width: 200px;
}
.card-alt {
background-color: var(--c_bg-emphasis-main);
color: var(--c_text-onEmphasis);
}
.card[framed="true"] {
border: 1px solid var(--c_border-main);
}
.card[alt="true"] {
background: transparent;
box-shadow: none;
}
.card[alt="true"] .card-title {
border-bottom-color: transparent;
}
.card[alt="true"] .button-card {
background-color: var(--c_bg-emphasis-main);
color: var(--c_text-onEmphasis);
text-decoration: none;
}
.card[alt="true"] .button-card:hover {
background-color: var(--c_bg-emphasis-dark);
}
.card-title {
width: calc(100% + 6rem);
margin: -1rem 0 0 -3rem;
padding: 1rem 3rem;
text-align: center;
border-bottom: 1px solid var(--c_border-light);
}
.button-card {
width: 100%;
background: inherit;
text-decoration: underline;
}
.button-card,
.button-icon {
color: var(--c_text-secondary);
}
.button-card:hover,
.button-icon:hover {
color: var(--c_text-main);
}
h1 {
text-transform: uppercase;
font-weight: 600;
font-size: 1.5em;
font-size: 3.5rem;
line-height: 0.9em;
letter-spacing: -0.02em;
}
h2 {
font-size: 2.3rem;
font-weight: 500;
}
label {
font-size: 1.6rem;
color: var(--c_text-secondary);
}
input,
textarea {
background: var(--c_bg-card);
border: 1px solid var(--c_border-main);
padding: 1rem;
border-radius: 0.5rem;
font-size: 2rem;
font-family: var(--f_main);
}
textarea:disabled {
background: transparent;
}
nav a {
#logo {
position: absolute;
left: 0;
}
.button-nav {
font-weight: 600;
font-size: 1.5em;
color: #49494b;
border: 2px solid #49494b;
padding: 10px 20px;
flex: 1;
text-transform: uppercase;
font-size: 1.4em;
color: var(--c_text-main);
border: 1px solid transparent;
padding: 1rem 3rem;
margin: 0 1rem 0 0;
border-radius: 1rem;
text-decoration: none;
background: #ebe8e3;
}
nav a:first-child {
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
border-right-width: 1px;
.button-nav:hover,
.button-nav.router-link-exact-active {
border-color: var(--c_border-main);
}
nav a:last-child {
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
border-left-width: 1px;
}
nav a.router-link-exact-active {
background: #49494b;
color: #ebe8e3;
.button-nav.router-link-exact-active {
background: white;
}
button {
padding: 10px 20px;
margin: 10px 0;
border-radius: 5px;
font-family: "Avenir Next Condensed", "Avenir", Helvetica, Arial, sans-serif;
padding: 1.5rem 3rem;
border-radius: 1rem;
border: none;
font-size: 2.3rem;
font-weight: 600;
font-size: 1.5em;
text-transform: uppercase;
background: #49494b;
color: #ebe8e3;
cursor: pointer;
}
canvas {
/* border: 2px solid #49494b; */
/* padding: 20px; */
margin: 10px 0;
border-radius: 5px;
.button-icon {
padding: 1rem;
font-size: 4rem;
line-height: 0.8em;
background: transparent;
}
@media print {

View File

@ -12,7 +12,7 @@ export default {
context.fillStyle = "black";
context.font = "20px Arial";
var textSize = context.measureText(binding.value);
canvasElement.setAttribute("width", textSize.width + 30 + "px");
canvasElement.setAttribute("width", textSize.width + 20 + "px");
context.font = "20px Arial";
context.fillText(binding.value, 15, 20);
}
@ -25,9 +25,3 @@ export default {
}
};
</script>
<style>
.canvasText {
margin-bottom: -8px;
}
</style>

View File

@ -1,14 +1,11 @@
<template>
<div class="fold">
<h1 class="main-title">
Banana split
</h1>
<input id="fold-header" v-model="unfolded" type="checkbox" name="fold" />
<label for="fold-header">
<h2 v-if="unfolded">Shamir Secret Sharing for people with friends</h2>
<p v-else>What is this?</p>
<h2>What is this?</h2>
</label>
<div class="fold-content">
<div class="fold-content measure card-alt">
<h2>Shamir Secret Sharing for people with friends</h2>
<p>
Banana Split uses
<a href="https://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing">
@ -58,48 +55,39 @@ export default {
</script>
<style>
.main-title::before,
.main-title::after {
display: inline-block;
padding: 0 20px;
content: "\1F34C\1F368";
}
.main-title::after {
transform: scaleX(-1);
}
.fold {
position: relative;
overflow: hidden;
display: flex;
flex-direction: column;
align-items: flex-end;
width: 150px;
}
.fold input {
position: absolute;
opacity: 0;
z-index: -1;
visibility: hidden;
}
.fold label {
position: relative;
display: flex;
align-items: center;
width: 150px;
cursor: pointer;
}
.fold label * {
display: inline-block;
}
.fold-content {
max-height: 0;
padding: 10px 30px;
overflow: hidden;
-webkit-transition: max-height 0.35s;
-o-transition: max-height 0.35s;
transition: max-height 0.35s;
text-align: left;
}
.fold input[type="checkbox"]:not(:checked) ~ .fold-content {
padding: 0;
margin: 0;
}
.fold input:checked ~ .fold-content {
max-height: 100vh;
max-height: none;
}
.fold label::before {
display: inline;
-webkit-transition: all 0.35s;
-o-transition: all 0.35s;
transition: all 0.35s;
margin: 0 4px 0 0;
width: 1em;
overflow: hidden;
}
.fold input[type="checkbox"]:not(:checked) + label::before {
content: "▶";

View File

@ -8,7 +8,7 @@
</h3>
</div>
<qriously class="qr-code print-only" :value="shard" :size="600" />
<qriously class="screen-only" :value="shard" :size="200" />
<qriously class="screen-only card-qr" :value="shard" :size="200" />
<div class="print-only">
<div class="recovery-field">
<div class="recovery-title">
@ -128,16 +128,6 @@ export default {
height: 100vh;
}
h1 {
font-weight: 600;
font-size: 1.5em;
}
canvas {
margin: 0 auto;
display: block;
}
h3,
h4 {
font-weight: 400;

View File

@ -1,45 +1,54 @@
<template>
<div>
<h1>
Combine shards for <em v-if="title"> {{ title }}</em>
</h1>
<div v-if="needMoreShards">
<qrcode-stream @decode="onDecode" />
<div class="codes-row">
<div class="card measure" :alt="!recoveredSecret">
<h2 class="card-title">
Combine shards <span v-if="title"> for <em v-if="title"> {{ title }}</em></span>
</h2>
<div v-if="needMoreShards">
<qrcode-stream @decode="onDecode" />
</div>
<div v-else>
<p>
<label>1. Secret Phrase</label>
<input
v-model="passphrase"
type="text"
placeholder="type your passphrase"
autofocus
@keyup.enter="reconstruct"
/>
</p>
<p>
<label>2. Secret</label>
<textarea v-if="recoveredSecret" readonly>{{ recoveredSecret }}</textarea>
<textarea v-else readonly disabled/>
</p>
<div v-if="!recoveredSecret">
<button class="button-card" @click="reconstruct">
Reconstruct Secret
</button>
</div>
</div>
</div>
<div class="card flex" alt="true" :framed="recoveredSecret && true">
<qriously
v-for="code in qrCodes"
:key="code"
class="qrcode"
class="card-qr"
:value="code"
:size="200"
:padding="0"
/>
<qriously
v-for="n in remainingCodes"
:key="n"
class="qrcode remaining"
class="remaining card-qr"
:value="PLACEHOLDER_QR_DATA"
:size="200"
foreground="#aaa"
:padding="0"
/>
</div>
</div>
<div v-else>
<input
v-model="passphrase"
type="text"
placeholder="type your passphrase"
autofocus
@keyup.enter="reconstruct"
/>
<button @click="reconstruct">
Reconstruct Secret
</button>
</div>
<h2 v-if="recoveredSecret" class="secret">
{{ recoveredSecret }}
</h2>
</div>
</template>
@ -48,11 +57,6 @@
import crypto from "../util/crypto";
// It's actually used in the template
// eslint-disable-next-line no-unused-vars
const PLACEHOLDER_QR_DATA =
'{"t":"Very secret info","r":2,"d":"803c12929ba469d720a63fc8ca6f6ef1cc441f8f0b830ea04f8a484169ec800e4a7","n":"29abbb2c509adedb470f6d3fd3d083362b8c1a9283adf987"}';
export default {
name: "Combine",
data: function() {
@ -128,57 +132,14 @@ export default {
</script>
<style>
@keyframes unblur {
0% {
filter: blur(5px) brightness(200%);
}
100% {
filter: none;
}
}
.codes-row {
display: flex;
padding: 20px;
}
.qrcode {
display: inline-block;
padding: 10px;
flex: 1;
animation: unblur 1s ease;
}
.qrcode.remaining {
-webkit-filter: blur(5px);
-moz-filter: blur(5px);
-o-filter: blur(5px);
-ms-filter: blur(5px);
.remaining {
filter: blur(5px);
opacity: 0.5;
animation: none;
}
input {
margin: 0 auto;
}
canvas {
margin: 0;
padding: 0;
width: 100%;
}
.secret {
padding: 20px 20px 40px;
margin: 20px;
word-wrap: break-word;
background: #fff;
border-radius: 3px;
box-shadow: #dadada 0 2px 43px;
}
/* Flip video to make it easier to use */
.qrcode-stream {
transform: scaleX(-1);
border-radius: 8px;
overflow: hidden;
}
</style>

View File

@ -1,9 +1,11 @@
<template>
<div>
<div id="share-controls">
<h1>Create a secret split</h1>
<div id="share-controls" class="card measure" :alt="!encryptionMode">
<h2 class="card-title">
Create a secret split
</h2>
<p>
Name of your split
<label>1. Name of your split</label>
<input
v-model="title"
type="text"
@ -12,46 +14,55 @@
autofocus
/>
</p>
<textarea
v-model="secret"
:class="{ tooLong: secretTooLong }"
:disabled="encryptionMode"
placeholder="Your secret goes here"
/>
<p>
<label>2. Secret</label>
<textarea
v-model="secret"
:class="{ tooLong: secretTooLong }"
:disabled="encryptionMode"
placeholder="Your secret goes here"
/>
</p>
<div v-if="secretTooLong">
Inputs longer than 1024 characters make QR codes illegible
</div>
<p>
<label>3. Shards</label>
<br>
Will require any {{ requiredShards }} shards out of
<input v-model.number="totalShards" type="number" min="3" /> to
reconstruct
reconstructppa
</p>
<button :disabled="secretTooLong" v-on:click="toggleMode">
<button class="button-card" :disabled="secretTooLong" v-on:click="toggleMode">
<span v-if="encryptionMode">Back to editing data</span>
<span v-else>Generate QR codes!</span>
</button>
<div v-if="encryptionMode">
<p>Your passphrase for the recovery is:</p>
<p>
</div>
<div v-if="encryptionMode">
<div class="card" framed="true" alt="true">
<label>4. Your passphrase for the recovery is:</label>
<div class="flex justify-between align-center">
<canvas-text :text="recoveryPassphrase" />
<button @click="regenPassphrase">
<button class="button-icon" @click="regenPassphrase">
&#x21ba;
</button>
</p>
<button @click="print">
</div>
</div>
<div class="card" alt="true">
<button class="button-card" @click="print">
Print us!
</button>
</div>
</div>
<div id="qr-tiles">
<shard-info
v-for="shard in shards"
:key="shard"
:shard="shard"
:required-shards="requiredShards"
:title="title"
/>
<div id="qr-tiles">
<shard-info
v-for="shard in shards"
:key="shard"
:shard="shard"
:required-shards="requiredShards"
:title="title"
/>
</div>
</div>
</div>
</template>
@ -118,7 +129,6 @@ textarea.tooLong {
}
#share-controls {
width: 320px;
margin: 0 auto;
text-align: left;
}
@ -130,21 +140,10 @@ textarea.tooLong {
}
input[type="text"],
textarea {
width: 320px;
width: 100%;
display: block;
}
input,
textarea {
background: #eee;
border: 0;
padding: 10px 5px;
border-radius: 3px;
font-size: 1em;
font-weight: 600;
font-family: Avenir, Avenir next, Helvetica, Arial;
}
input:disabled,
textarea:disabled {
opacity: 0.5;