diff --git a/src/cards.css b/src/cards.css index c3a7a58..f389937 100644 --- a/src/cards.css +++ b/src/cards.css @@ -10,7 +10,7 @@ } @media (orientation: portrait) { .mbox { - padding: 0 calc(.5 * var(--gap)); + padding: 0 var(--gap-half); } } .mbox:last-child { diff --git a/src/form.css b/src/form.css index 5a0151b..ac76cda 100644 --- a/src/form.css +++ b/src/form.css @@ -43,6 +43,7 @@ label { transition: background-color var(--transition-duration); } +input[type="number"], input[type="password"], input[type="text"], input[type="url"], @@ -54,6 +55,7 @@ textarea { margin: 0 0 1.2rem 0; padding: var(--padding); } +input[type="number"]:focus, input[type="password"]:focus, input[type="text"]:focus, input[type="url"]:focus, @@ -169,11 +171,13 @@ button:disabled { margin-left: var(--gap); } .form-inline button, +.form-inline input[type="number"], .form-inline input[type="text"], .form-inline textarea { margin: .4rem 0; } +.form-inline input[type="number"], .form-inline input[type="text"], .form-inline textarea { flex-basis: 50%; @@ -187,6 +191,46 @@ button:disabled { flex-grow: 0; } +label.number { + display: flex; + flex-direction: row; + flex-wrap: nowrap; + gap: var(--gap); + padding: 0; +} +* + label.number { + margin: var(--gap) 0 0 0; +} +label.number span { + flex-grow: 1; + padding: 0 0 0 var(--padding); +} +label.number input[type="number"] { + align-self: baseline; + margin-bottom: 0; +} +@media (orientation: landscape) { + label.number span { + align-self: center; + } + label.number input[type="number"] + span { + padding: 0 var(--padding) 0 0; + } +} +@media (orientation: portrait) { + label.number { + flex-direction: column; + gap: var(--gap-half); + padding: 0; + } + label.number span { + padding: 0 var(--padding); + } + label.number input[type="number"] { + align-self: stretch; + } +} + button#publish { align-self: end; order: 2; diff --git a/src/index.html b/src/index.html index 68246ac..31493a0 100644 --- a/src/index.html +++ b/src/index.html @@ -83,6 +83,27 @@ +
+ + +
diff --git a/src/main.css b/src/main.css index 01e10b9..11d7024 100644 --- a/src/main.css +++ b/src/main.css @@ -15,6 +15,7 @@ --focus-outline: var(--focus-outline-width) var(--focus-outline-style) var(--focus-outline-color); --font-small: 1.2rem; --gap: 2.4rem; + --gap-half: 1.2rem; --max-width: 96ch; } diff --git a/src/main.js b/src/main.js index 31beb96..6cbd997 100644 --- a/src/main.js +++ b/src/main.js @@ -40,10 +40,6 @@ let pubkey = localStorage.getItem('pub_key') || (() => { return pubkey; })(); -// arbitrary difficulty, still experimenting. -// measured empirically, takes N sec on average to mine a text note event. -const difficulty = 16; - const subList = []; const unSubAll = () => { subList.forEach(sub => sub.unsub()); @@ -756,6 +752,23 @@ function hideNewMessage(hide) { newMessageDiv.hidden = hide; } +// arbitrary difficulty default, still experimenting. +let difficulty = JSON.parse(localStorage.getItem('mining_target')) ?? 16; +const miningTargetInput = document.querySelector('#miningTarget'); +miningTargetInput.addEventListener('input', (e) => { + localStorage.setItem('mining_target', miningTargetInput.valueAsNumber); + difficulty = miningTargetInput.valueAsNumber; +}); +miningTargetInput.value = difficulty; + +let timeout = JSON.parse(localStorage.getItem('mining_timeout')) ?? 5; +const miningTimeoutInput = document.querySelector('#miningTimeout'); +miningTimeoutInput.addEventListener('input', (e) => { + localStorage.setItem('mining_timeout', miningTimeoutInput.valueAsNumber); + timeout = miningTimeoutInput.valueAsNumber; +}); +miningTimeoutInput.value = timeout; + async function upvote(eventId, eventPubkey) { const privatekey = localStorage.getItem('private_key'); const note = replyList.find(r => r.id === eventId) || textNoteList.find(n => n.id === (eventId)); @@ -771,7 +784,7 @@ async function upvote(eventId, eventPubkey) { content: '+', tags, created_at: Math.floor(Date.now() * 0.001), - }, difficulty, 10).catch(console.warn); + }, difficulty, timeout).catch(console.warn); if (newReaction) { const sig = await signEvent(newReaction, privatekey).catch(console.error); if (sig) { @@ -810,7 +823,7 @@ writeForm.addEventListener('submit', async (e) => { pubkey, tags, created_at: Math.floor(Date.now() * 0.001), - }, difficulty, 10).catch(console.warn); + }, difficulty, timeout).catch(console.warn); if (newEvent) { const sig = await signEvent(newEvent, privatekey).catch(onSendError); if (sig) { @@ -954,7 +967,7 @@ profileForm.addEventListener('submit', async (e) => { content: JSON.stringify(Object.fromEntries(form)), tags: [], created_at: Math.floor(Date.now() * 0.001), - }, difficulty, 10).catch(console.warn); + }, difficulty, timeout).catch(console.warn); if (newProfile) { const sig = await signEvent(newProfile, privatekey).catch(console.error); if (sig) { @@ -1031,8 +1044,12 @@ function validatePow(evt) { * * powEvent returns a rejected promise if the funtion runs for longer than timeout. * a zero timeout makes mineEvent run without a time limit. + * a zero mining target just resolves the promise without trying to find a 'nonce'. */ -function powEvent(evt, difficulty, timeout = 0) { +function powEvent(evt, difficulty, timeout) { + if (difficulty === 0) { + return Promise.resolve(evt); + } return new Promise((resolve, reject) => { const worker = new Worker('./worker.js'); diff --git a/src/tabs.css b/src/tabs.css index 39cf5ec..9938ecc 100644 --- a/src/tabs.css +++ b/src/tabs.css @@ -45,7 +45,7 @@ input[type="radio"]:checked + label { .tab-content { max-width: var(--max-width); min-height: 200px; - padding: calc(.5 * var(--gap)) 0 100px 0; + padding: var(--gap-half) 0 100px 0; } .tabbed { align-items: start;