mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
- Added `data-testid` attributes to key modals (Disclaimer, Login, Upload, Video, Profile, Lockdown) to facilitate reliable selection in Playwright tests. - Updated `js/disclaimer.js` and `js/index.js` to respect a new `playwright-bypass-disclaimer` localStorage flag, allowing automated tests to skip the disclaimer modal entirely.
423 lines
15 KiB
HTML
423 lines
15 KiB
HTML
<div
|
|
id="loginModal"
|
|
class="bv-modal hidden p-0 sm:p-0 lg:p-8 lg:items-start lg:justify-center overflow-hidden"
|
|
role="dialog"
|
|
aria-modal="true"
|
|
aria-labelledby="loginModalTitle"
|
|
aria-describedby="loginModalDescription"
|
|
data-ds="new"
|
|
data-testid="login-modal"
|
|
>
|
|
<div class="bv-modal-backdrop" data-dismiss></div>
|
|
|
|
<div
|
|
class="modal-sheet w-full h-full max-w-none rounded-none border-0 lg:max-h-modal-shell lg:max-w-5xl lg:rounded-modal-xl lg:border lg:h-auto flex min-h-0 flex-col overflow-hidden"
|
|
tabindex="-1"
|
|
>
|
|
<!-- Header with the special exit button (unchanged) -->
|
|
<div class="modal-header">
|
|
<h2 id="loginModalTitle" class="text-xl font-bold text-text">
|
|
Login Options
|
|
</h2>
|
|
<button
|
|
id="closeLoginModal"
|
|
class="modal-close"
|
|
>
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
class="h-6 w-6"
|
|
fill="none"
|
|
viewBox="0 0 24 24"
|
|
stroke="currentColor"
|
|
>
|
|
<path
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
stroke-width="2"
|
|
d="M6 18L18 6M6 6l12 12"
|
|
/>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Body -->
|
|
<div
|
|
id="loginModalDescription"
|
|
class="modal-body flex-1 space-y-6 overflow-y-auto"
|
|
>
|
|
<div class="space-y-2 text-left">
|
|
<p class="text-sm text-text-muted">
|
|
Choose how you'd like to sign in. Connect a browser extension, link a
|
|
remote signer, or work directly with your keys when you need to.
|
|
</p>
|
|
</div>
|
|
|
|
<section
|
|
class="space-y-5 rounded-3xl border border-border bg-overlay-panel-soft/90 p-4 shadow-lg backdrop-blur-sm sm:p-5"
|
|
>
|
|
<div class="space-y-1">
|
|
<h3 class="text-base font-semibold text-text">Available methods</h3>
|
|
<p class="text-sm text-text-muted">
|
|
Pick the option that matches how you manage your Nostr identity.
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Login provider buttons are rendered dynamically -->
|
|
<div
|
|
data-login-providers
|
|
class="grid auto-rows-fr gap-4 sm:grid-cols-2 xl:grid-cols-3"
|
|
></div>
|
|
</section>
|
|
|
|
<div class="space-y-3">
|
|
<div class="space-y-1 text-left">
|
|
<h3 class="text-sm font-semibold uppercase tracking-wide text-text-muted">
|
|
Need an invite?
|
|
</h3>
|
|
<p class="text-sm text-text-muted">
|
|
Submit an application and we'll send you updates when new slots open.
|
|
</p>
|
|
</div>
|
|
<button
|
|
id="openApplicationModal"
|
|
class="btn w-full"
|
|
type="button"
|
|
>
|
|
Application Form
|
|
</button>
|
|
</div>
|
|
|
|
<template data-login-provider-template>
|
|
<button
|
|
class="login-option"
|
|
type="button"
|
|
data-provider-button
|
|
>
|
|
<span class="login-option__header">
|
|
<span class="login-option__copy">
|
|
<span
|
|
data-provider-eyebrow
|
|
class="login-option__eyebrow hidden"
|
|
></span>
|
|
<span data-provider-label class="login-option__label"></span>
|
|
<span
|
|
data-provider-description
|
|
class="login-option__description"
|
|
></span>
|
|
</span>
|
|
<span aria-hidden="true" class="login-option__chevron">
|
|
<svg
|
|
xmlns="http://www.w3.org/2000/svg"
|
|
viewBox="0 0 24 24"
|
|
fill="none"
|
|
stroke="currentColor"
|
|
class="h-5 w-5"
|
|
>
|
|
<path
|
|
stroke-linecap="round"
|
|
stroke-linejoin="round"
|
|
stroke-width="2"
|
|
d="M9 5l7 7-7 7"
|
|
/>
|
|
</svg>
|
|
</span>
|
|
</span>
|
|
<div data-provider-status-row class="login-option__status hidden">
|
|
<span data-provider-status class="truncate"></span>
|
|
<button
|
|
type="button"
|
|
class="btn-link text-sm hidden"
|
|
data-provider-disconnect
|
|
>
|
|
Disconnect
|
|
</button>
|
|
</div>
|
|
<span
|
|
data-provider-capabilities
|
|
class="login-option__capabilities hidden"
|
|
></span>
|
|
</button>
|
|
</template>
|
|
<template data-login-nsec-dialog>
|
|
<form
|
|
data-nsec-form
|
|
class="space-y-4 rounded-xl border border-border bg-overlay-panel-soft px-5 py-4"
|
|
>
|
|
<div class="space-y-2">
|
|
<h3 class="text-lg font-semibold text-text">Direct key login</h3>
|
|
<p class="text-sm text-text-muted" data-nsec-warning>
|
|
"Unsafe by default" — imported keys stay decrypted only for this session
|
|
unless you protect them with a passphrase.
|
|
</p>
|
|
</div>
|
|
<div
|
|
data-nsec-error
|
|
class="hidden rounded-lg border border-danger/60 bg-danger/10 px-4 py-2 text-sm text-danger"
|
|
role="alert"
|
|
></div>
|
|
<fieldset data-nsec-unlock-section class="space-y-3 hidden">
|
|
<legend class="text-sm font-semibold text-text">Unlock saved key</legend>
|
|
<label class="inline-flex items-center gap-2 text-sm text-text">
|
|
<input
|
|
type="radio"
|
|
name="nsec-mode"
|
|
value="unlock"
|
|
class="radio"
|
|
data-nsec-mode="unlock"
|
|
/>
|
|
<span>Use the encrypted key stored on this device</span>
|
|
</label>
|
|
<div class="space-y-2 pl-6" data-nsec-unlock-fields>
|
|
<label class="block text-sm font-medium text-text" for="nsecUnlockPassphrase">
|
|
Passphrase
|
|
</label>
|
|
<input
|
|
id="nsecUnlockPassphrase"
|
|
type="password"
|
|
class="input"
|
|
autocomplete="current-password"
|
|
data-nsec-unlock-passphrase
|
|
required
|
|
/>
|
|
</div>
|
|
</fieldset>
|
|
<fieldset data-nsec-import-section class="space-y-3">
|
|
<legend class="text-sm font-semibold text-text">Import a new secret</legend>
|
|
<label class="inline-flex items-center gap-2 text-sm text-text">
|
|
<input
|
|
type="radio"
|
|
name="nsec-mode"
|
|
value="import"
|
|
class="radio"
|
|
data-nsec-mode="import"
|
|
checked
|
|
/>
|
|
<span>Paste an nsec, hex key, or mnemonic seed</span>
|
|
</label>
|
|
<div class="space-y-3 pl-6" data-nsec-import-fields>
|
|
<label class="block text-sm font-medium text-text" for="nsecSecretInput">
|
|
Secret
|
|
</label>
|
|
<textarea
|
|
id="nsecSecretInput"
|
|
class="input"
|
|
rows="3"
|
|
spellcheck="false"
|
|
autocomplete="off"
|
|
data-nsec-secret
|
|
required
|
|
></textarea>
|
|
<label class="inline-flex items-center gap-2 text-sm text-text">
|
|
<input type="checkbox" class="checkbox" data-nsec-remember />
|
|
<span>Remember this key on this device</span>
|
|
</label>
|
|
<div class="space-y-2" data-nsec-passphrase-fields hidden>
|
|
<label class="block text-sm font-medium text-text" for="nsecPassphraseInput">
|
|
Passphrase
|
|
</label>
|
|
<input
|
|
id="nsecPassphraseInput"
|
|
type="password"
|
|
class="input"
|
|
autocomplete="new-password"
|
|
data-nsec-passphrase
|
|
/>
|
|
<label class="block text-sm font-medium text-text" for="nsecPassphraseConfirm">
|
|
Confirm passphrase
|
|
</label>
|
|
<input
|
|
id="nsecPassphraseConfirm"
|
|
type="password"
|
|
class="input"
|
|
autocomplete="new-password"
|
|
data-nsec-passphrase-confirm
|
|
/>
|
|
</div>
|
|
</div>
|
|
</fieldset>
|
|
<div class="flex justify-end gap-2">
|
|
<button type="button" class="btn-ghost" data-nsec-cancel>Cancel</button>
|
|
<button type="submit" class="btn" data-nsec-submit>Continue</button>
|
|
</div>
|
|
</form>
|
|
</template>
|
|
<template data-login-generate-dialog>
|
|
<div
|
|
data-generate-view
|
|
class="space-y-4 rounded-xl border border-border bg-overlay-panel-soft px-5 py-4"
|
|
>
|
|
<div class="space-y-2">
|
|
<h3 class="text-lg font-semibold text-text">Create a new Nostr key</h3>
|
|
<p class="text-sm text-text-muted">
|
|
Save your keys somewhere safe. We'll only enable login after you
|
|
confirm you've backed them up.
|
|
</p>
|
|
</div>
|
|
<div class="space-y-3">
|
|
<div class="space-y-2">
|
|
<label class="block text-sm font-medium text-text">
|
|
Public key (npub)
|
|
</label>
|
|
<div class="space-y-2 sm:flex sm:items-start sm:gap-2 sm:space-y-0">
|
|
<div
|
|
data-generate-npub
|
|
class="min-w-0 flex-1 break-all rounded-lg border border-border bg-overlay-panel px-3 py-2 text-sm text-text"
|
|
></div>
|
|
<button
|
|
type="button"
|
|
class="btn-ghost text-sm"
|
|
data-generate-copy-npub
|
|
>
|
|
Copy npub
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="space-y-2">
|
|
<label class="block text-sm font-medium text-text" for="generatedNsec">
|
|
Secret key (nsec)
|
|
</label>
|
|
<div class="space-y-2 sm:flex sm:items-start sm:gap-2 sm:space-y-0">
|
|
<input
|
|
id="generatedNsec"
|
|
type="password"
|
|
class="input min-w-0 flex-1"
|
|
readonly
|
|
data-generate-nsec
|
|
/>
|
|
<div class="flex flex-wrap items-center gap-2">
|
|
<button
|
|
type="button"
|
|
class="btn-ghost text-sm"
|
|
data-generate-reveal-nsec
|
|
>
|
|
Reveal
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="btn-ghost text-sm"
|
|
data-generate-copy-nsec
|
|
>
|
|
Copy nsec
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<button
|
|
type="button"
|
|
class="btn-link text-sm"
|
|
data-generate-download
|
|
>
|
|
Download backup
|
|
</button>
|
|
</div>
|
|
<label class="inline-flex items-center gap-2 text-sm text-text">
|
|
<input type="checkbox" class="checkbox" data-generate-confirm />
|
|
<span>I saved these keys and understand they're private.</span>
|
|
</label>
|
|
</div>
|
|
<div class="flex justify-end gap-2">
|
|
<button type="button" class="btn-ghost" data-generate-cancel>
|
|
Cancel
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="btn"
|
|
data-generate-login
|
|
disabled
|
|
>
|
|
Continue
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<template data-login-nip46-dialog>
|
|
<form
|
|
data-nip46-form
|
|
class="space-y-4 rounded-xl border border-border bg-overlay-panel-soft px-5 py-4"
|
|
>
|
|
<div class="space-y-2">
|
|
<h3 class="text-lg font-semibold text-text">Pair a remote signer</h3>
|
|
<p class="text-sm text-text-muted">
|
|
Scan the QR code with your signer (like Amber or NsecBunker) to login.
|
|
</p>
|
|
</div>
|
|
<div
|
|
data-nip46-error
|
|
class="hidden rounded-lg border border-danger/60 bg-danger/10 px-4 py-2 text-sm text-danger"
|
|
role="alert"
|
|
></div>
|
|
<div data-nip46-handshake-panel class="space-y-6">
|
|
<div class="flex flex-col items-center gap-6">
|
|
<div
|
|
class="flex aspect-square w-full max-w-xs items-center justify-center rounded-2xl border border-border-strong bg-white p-4 shadow-sm"
|
|
data-nip46-qr
|
|
aria-hidden="true"
|
|
>
|
|
<div class="w-full text-center text-sm text-text-muted animate-pulse">
|
|
Generating code...
|
|
</div>
|
|
</div>
|
|
|
|
<div class="w-full space-y-4 text-center">
|
|
<!-- Hidden input for copy functionality -->
|
|
<input
|
|
type="text"
|
|
class="sr-only"
|
|
data-nip46-handshake-uri
|
|
readonly
|
|
aria-hidden="true"
|
|
>
|
|
|
|
<button
|
|
type="button"
|
|
class="btn w-full sm:max-w-xs"
|
|
data-nip46-copy-uri
|
|
disabled
|
|
>
|
|
Copy Connect Link
|
|
</button>
|
|
|
|
<details class="text-sm text-text-muted">
|
|
<summary class="cursor-pointer hover:text-text hover:underline">Trouble scanning?</summary>
|
|
<div class="mt-2 p-2 bg-overlay-panel border border-border rounded-lg break-all text-xs font-mono text-left select-all" data-nip46-debug-uri>
|
|
<!-- Raw URI injected here for debugging/manual copy -->
|
|
</div>
|
|
</details>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div
|
|
data-nip46-status
|
|
class="hidden rounded-lg border border-info/40 bg-info/10 px-4 py-3 text-sm text-info font-medium text-center"
|
|
role="status"
|
|
></div>
|
|
<div
|
|
data-nip46-auth
|
|
class="hidden rounded-lg border border-warning/50 bg-warning/10 px-4 py-2 text-sm text-warning"
|
|
role="alert"
|
|
>
|
|
<p data-nip46-auth-message class="mb-2"></p>
|
|
<button type="button" class="btn-link text-sm" data-nip46-auth-open>
|
|
Open signer challenge
|
|
</button>
|
|
</div>
|
|
|
|
<div class="flex justify-between items-center pt-2">
|
|
<button
|
|
type="button"
|
|
class="btn-link text-sm hidden"
|
|
data-nip46-reuse
|
|
>
|
|
Reconnect saved
|
|
</button>
|
|
<button type="button" class="btn-ghost" data-nip46-cancel>Cancel</button>
|
|
</div>
|
|
<!-- Hidden submit to satisfy form semantics if needed, though we trigger via logic -->
|
|
<button type="submit" class="hidden" data-nip46-submit></button>
|
|
</form>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
</div>
|