mirror of
https://github.com/narrrl/narl-workspace.git
synced 2026-11-03 16:41:27 +01:00
vault prompt: appears at once and stays put between questions
The password box rose into place like the [y/N] prompt, a 380 ms slide and fade, and was taken down and put up again for every question: twice for :vault, three times for :passwd, and right after the command line closed for :unlock. Whatever was typed in that time went into a field still moving and half transparent. It now appears without an entrance, and an answer puts it away a turn later, so a question that follows straight on takes over the same box. Password managers are asked to leave the field alone; it is not the login.
This commit is contained in:
1 parent
e4e3e2b5aa
commit
b19fb21fc4
2 files changed
+23
-5
No files matched your search
@@ -3,6 +3,12 @@
|
|||||||
* The password `workspace.askSecret` asks for, in the same place as the
|
* The password `workspace.askSecret` asks for, in the same place as the
|
||||||
* `[y/N]` prompt. A masked field of its own rather than the command line, so
|
* `[y/N]` prompt. A masked field of its own rather than the command line, so
|
||||||
* a password never shows on screen or lands in the command history.
|
* a password never shows on screen or lands in the command history.
|
||||||
|
*
|
||||||
|
* It appears at once rather than rising into place like the `[y/N]` prompt:
|
||||||
|
* it is where the next keys go, and a field still sliding and fading in
|
||||||
|
* under them reads as a stutter. Password managers are asked to leave the
|
||||||
|
* field alone: it is not the login, and their menus redrawn on every key
|
||||||
|
* are a flicker of their own.
|
||||||
*/
|
*/
|
||||||
import { workspace } from './store.svelte'
|
import { workspace } from './store.svelte'
|
||||||
|
|
||||||
@@ -38,6 +44,10 @@
|
|||||||
type="password"
|
type="password"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
|
data-1p-ignore
|
||||||
|
data-lpignore="true"
|
||||||
|
data-bwignore
|
||||||
|
data-form-type="other"
|
||||||
bind:this={input}
|
bind:this={input}
|
||||||
bind:value
|
bind:value
|
||||||
{onkeydown}
|
{onkeydown}
|
||||||
@@ -67,7 +77,6 @@
|
|||||||
border-bottom: 0;
|
border-bottom: 0;
|
||||||
border-radius: var(--radius-l) var(--radius-l) 0 0;
|
border-radius: var(--radius-l) var(--radius-l) 0 0;
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
animation: rise var(--t-slow) var(--ease-snap) both;
|
|
||||||
}
|
}
|
||||||
.text { flex: none; color: var(--light); }
|
.text { flex: none; color: var(--light); }
|
||||||
input {
|
input {
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ class Workspace {
|
|||||||
*/
|
*/
|
||||||
prompt = $state<{ text: string; resolve: (yes: boolean) => void } | null>(null)
|
prompt = $state<{ text: string; resolve: (yes: boolean) => void } | null>(null)
|
||||||
/** A password asked for in the same place, typed into a masked field. */
|
/** A password asked for in the same place, typed into a masked field. */
|
||||||
secret = $state<{ text: string; resolve: (value: string | null) => void } | null>(null)
|
secret = $state.raw<{ text: string; resolve: (value: string | null) => void } | null>(null)
|
||||||
/** The vault, as last heard from the server; null until asked. */
|
/** The vault, as last heard from the server; null until asked. */
|
||||||
vault = $state<VaultStatus | null>(null)
|
vault = $state<VaultStatus | null>(null)
|
||||||
media = $state<MediaFile[]>([])
|
media = $state<MediaFile[]>([])
|
||||||
@@ -217,13 +217,22 @@ class Workspace {
|
|||||||
askSecret(text: string): Promise<string | null> {
|
askSecret(text: string): Promise<string | null> {
|
||||||
this.secret?.resolve(null)
|
this.secret?.resolve(null)
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
this.secret = {
|
let answered = false
|
||||||
|
const asked = {
|
||||||
text,
|
text,
|
||||||
resolve: (value) => {
|
resolve: (value: string | null) => {
|
||||||
this.secret = null
|
if (answered) return
|
||||||
|
answered = true
|
||||||
|
// Put away a turn later, so a question that follows straight on —
|
||||||
|
// the second of two passwords — takes over the same box instead
|
||||||
|
// of a new one appearing under the fingers already typing it.
|
||||||
|
setTimeout(() => {
|
||||||
|
if (this.secret === asked) this.secret = null
|
||||||
|
})
|
||||||
resolve(value)
|
resolve(value)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
this.secret = asked
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user