Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 78 additions & 58 deletions src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,18 @@
position
export let startHidden: boolean
export let compactMode: boolean
export let texts: Record<string, string>
export let nstartMeLanguage: string

// Helper function to get text with fallback
function t(key: string): string {
const value = texts[key]
if (value) return value

console.warn(`Text not found: ${key}`)

return key
}

const win = window as any
const pool = new SimplePool()
Expand Down Expand Up @@ -83,10 +95,12 @@
let metadataSub: SubCloser | null
let pendingRejections: ((reason?: any) => void)[] = []

const connectBunkerError =
$: connectBunkerError = t(
'We could not connect to a NIP-46 bunker with that url, are you sure it is set up correctly?'
const connectNip05Error =
)
$: connectNip05Error = t(
'We were not able to connect using this address. For it to work it has to come from a NIP-46 provider.'
)

const BASE_YPOS = 20
export let right = 20
Expand Down Expand Up @@ -529,7 +543,7 @@
}

function handleCreateAccount() {
window.location.href = `https://nstart.me?an=${currentDomain}&at=web&ac=${currentProtocol}//${currentDomain}&sfb=yes`
window.location.href = `https://nstart.me/${nstartMeLanguage}/?an=${currentDomain}&at=web&ac=${currentProtocol}//${currentDomain}&sfb=yes`
}
</script>

Expand Down Expand Up @@ -563,14 +577,14 @@
<!-- Connecting view ################### -->
{#if connecting}
<div class="flex items-center px-2">
Connecting to bunker
{t('Connecting to bunker')}
<Spinner />
</div>
{:else if !identity}
{#if compactMode}
<div class="w-6 text-center">N</div>
{:else}
<div class="flex items-center px-2">Connect with Nostr</div>
<div class="flex items-center px-2">{t('Connect with Nostr')}</div>
{/if}
{:else if !compactMode}
<div class="flex items-center px-2">
Expand Down Expand Up @@ -616,123 +630,128 @@

{#if showAuth}
<div class="m-auto w-full">
<div class="text-center text-lg">Create a Nostr account</div>
<div class="text-center text-lg">{t('Create a Nostr account')}</div>
<div class="mt-4 text-center text-sm leading-4">
A new window will now open, taking you to
{t('A new window will now open, taking you to')}
<strong>{new URL(showAuth).host}</strong>
where the account creation will occur. If nothing happens, ensure your
browser is not blocking popups.
<br /> Afterward, you'll be redirected back to this page.
{t(
'where the account creation will occur. If nothing happens, ensure your browser is not blocking popups.'
)}
<br />
{t("Afterward, you'll be redirected back to this page.")}
</div>
<button
class="mt-4 block w-full cursor-pointer rounded border-0 px-2 py-1 text-lg text-white disabled:cursor-default disabled:bg-neutral-400 disabled:text-neutral-200 bg-{accent}-900 hover:bg-{accent}-950"
on:click={() => openAuthURLPopup(showAuth)}
>
Start account creation »
{t('Start account creation »')}
</button>
</div>
{:else if showLogin}
<div class="m-auto w-full">
<div class="text-center text-lg">Login into a Nostr account</div>
<div class="text-center text-lg">
{t('Login into a Nostr account')}
</div>
<div class="mt-4 text-center text-sm leading-4">
A new window will now open, taking you to <strong
>{new URL(showLogin).host}</strong
>
where you can login and approve the permissions. If nothing happens,
ensure your browser is not blocking popups. <br />
Afterward, you'll be redirected back to this page.
{t('A new window will now open, taking you to')}
<strong>{new URL(showLogin).host}</strong>
{t(
'where you can login and approve the permissions. If nothing happens, ensure your browser is not blocking popups.'
)} <br />
{t("Afterward, you'll be redirected back to this page.")}
</div>
<button
class="mt-4 block w-full cursor-pointer rounded border-0 px-2 py-1 text-lg text-white disabled:cursor-default disabled:bg-neutral-400 disabled:text-neutral-200 bg-{accent}-900 hover:bg-{accent}-950"
on:click={() => openAuthURLPopup(showLogin)}
>
Login now »
{t('Login now »')}
</button>
</div>
{:else if showConfirmAction}
<div class="m-auto w-full">
<div class="text-center text-lg">
An action requires your confirmation
{t('An action requires your confirmation')}
</div>
<div class="mt-4 text-center text-sm leading-4">
A new window will now open, taking you to <strong
>{new URL(showConfirmAction).host}</strong
>
where you can approve the current action. If nothing happens, ensure
your browser is not blocking popups.<br />
Afterward, you'll be redirected back to this page.
{t('A new window will now open, taking you to')}
<strong>{new URL(showConfirmAction).host}</strong>
{t(
'where you can approve the current action. If nothing happens, ensure your browser is not blocking popups.'
)}<br />
{t("Afterward, you'll be redirected back to this page.")}
</div>
<button
class="mt-4 block w-full cursor-pointer rounded border-0 px-2 py-1 text-lg text-white disabled:cursor-default disabled:bg-neutral-400 disabled:text-neutral-200 bg-{accent}-900 hover:bg-{accent}-950"
on:click={() => {
openAuthURLPopup(showConfirmAction)
}}
>
Confirm action »
{t('Confirm action »')}
</button>
</div>

<!-- Show info ################### -->
{:else if showInfo}
<div class="text-center text-lg">What is that?</div>
<div class="text-center text-lg">{t('What is that?')}</div>
<div class="text-base leading-5">
<p class="mb mt-4">
This widget is created with <i>window.nostr.js</i>, a small script
you can drop in any page that already uses NIP-07 and make it also
work with NIP-46 automatically when the user doesn't have an
extension installed.
{t('This widget is created with')} <i>window.nostr.js</i>{t(
", a small script you can drop in any page that already uses NIP-07 and make it also work with NIP-46 automatically when the user doesn't have an extension installed."
)}
<br />
It adds a small floating button on the side of the window that users
can use to create Nostr accuonts or connect to their NIP-46 bunkers.
{t(
'It adds a small floating button on the side of the window that users can use to create Nostr accuonts or connect to their NIP-46 bunkers.'
)}
</p>
<p class="mt-4">
This tool is opensource, get the code from the <a
{t('This tool is opensource, get the code from the')}
<a
target="_blank"
class="underline"
href="https://github.com/fiatjaf/window.nostr.js"
>project's page</a
>{t("project's page")}</a
>.
</p>
<p class="mt-4">
You don't know what Nostr is?
{t("You don't know what Nostr is?")}
<a target="_blank" class="underline" href="https://www.nostr.com"
>Learn more</a
>{t('Learn more')}</a
>.
</p>
</div>

<!-- Create account view ################### -->
{:else if creating}
<div class="text-center text-lg">Create a Nostr account</div>
<div class="text-center text-lg">{t('Create a Nostr account')}</div>
<div class="mt-4 text-base leading-5">
To use this Nostr app you need a profile. The following button opens a
wizard that help you to create your keypair and safely manage it in a
few steps. Are you ready?
{t(
'To use this Nostr app you need a profile. The following button opens a wizard that help you to create your keypair and safely manage it in a few steps. Are you ready?'
)}
</div>
<button
class="mt-4 block w-full cursor-pointer rounded border-0 px-2 py-1 text-lg text-white disabled:cursor-default disabled:bg-neutral-400 disabled:text-neutral-200 bg-{accent}-900 hover:bg-{accent}-950"
on:click={handleCreateAccount}
disabled={awaitingCreation}
>Create an account »
>{t('Create an account »')}
</button>
<div class="mt-6 text-center text-sm leading-3">
Do you already have a Nostr address?<br />
{t('Do you already have a Nostr address?')}<br />
<button
class="cursor-pointer border-0 bg-transparent text-sm text-white underline"
on:click={handleOpenLogin}>Login now</button
on:click={handleOpenLogin}>{t('Login now')}</button
>
</div>

<!-- Login view ################### -->
{:else if !identity}
<div class="text-center text-lg">
How do you want to connect to Nostr?
{t('How do you want to connect to Nostr?')}
</div>
<form class="mb-1 mt-4 flex flex-col" on:submit={handleConnect}>
<!-- svelte-ignore a11y-autofocus -->
<input
class="box-border w-full rounded px-2 py-1 text-lg text-neutral-800 outline-none"
placeholder="user@provider or bunker://..."
placeholder={t('user@provider or bunker://...')}
bind:this={bunkerInput}
bind:value={bunkerInputValue}
autofocus
Expand All @@ -751,35 +770,36 @@
disabled={!bunkerInputValueIsGood || connecting}
>
{#if connecting}
Connecting to bunker
{t('Connecting to bunker')}
<Spinner />
{:else}
Connect »
{t('Connect »')}
{/if}
</button>
{#if connecting && takingTooLong}
<div class="mt-6 text-center text-sm leading-3">
Waiting too much?
{t('Waiting too much?')}
<button
class="cursor-pointer border-0 bg-transparent text-sm text-white underline"
on:click={handleAbortConnection}>Cancel the connection</button
on:click={handleAbortConnection}
>{t('Cancel the connection')}</button
>
</div>
{/if}
</form>
{#if !connecting}
<div class="mt-6 text-center text-sm leading-3">
{#if hasTriedToConnectButFailed}
Is this bunker provider broken?<br />
{t('Is this bunker provider broken?')}<br />
<button
class="cursor-pointer border-0 bg-transparent text-sm text-white underline"
on:click={handleErasePointer}>Clear it</button
on:click={handleErasePointer}>{t('Clear it')}</button
>
{:else}
Do you need a Nostr account?<br />
{t('Do you need a Nostr account?')}<br />
<button
class="cursor-pointer border-0 bg-transparent text-sm text-white underline"
on:click={handleCreateAccount}>Sign up now</button
on:click={handleCreateAccount}>{t('Sign up now')}</button
>
{/if}
</div>
Expand All @@ -788,7 +808,7 @@
<!-- Connected view ################### -->
{:else}
<div class="text-center">
<div class="mb-4 text-sm">You are connected to Nostr as</div>
<div class="mb-4 text-sm">{t('You are connected to Nostr as')}</div>
<a
target="_blank"
href={'https://nosta.me/' + identity.npub}
Expand Down Expand Up @@ -817,10 +837,10 @@
</div>
<button
class="my-2 mt-6 block w-full cursor-pointer rounded border-0 px-2 py-1 text-lg text-white bg-{accent}-900 hover:bg-{accent}-950"
on:click={handleDisconnect}>Disconnect</button
on:click={handleDisconnect}>{t('Disconnect')}</button
>
<div class="mt-6 block break-all text-center text-sm">
This webpage is using the public key:<br />
{t('This webpage is using the public key:')}<br />
{getPublicKey(clientSecret)}
</div>
{/if}
Expand Down
5 changes: 4 additions & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import styles from './app.css?inline'
import App from './App.svelte'
import defaultTexts from './texts.json'

// To customize the widget add this code before the <script src='...' inclusion
// --- --- --- --- --- --- --- --- ---
Expand Down Expand Up @@ -38,7 +39,9 @@ const app = new App({
accent: win.wnjParams?.accent || 'cyan',
position: win.wnjParams?.position === 'bottom' ? 'bottom' : 'top',
startHidden: win.wnjParams?.startHidden,
compactMode: win.wnjParams?.compactMode
compactMode: win.wnjParams?.compactMode,
texts: win.wnjParams?.texts || defaultTexts,
nstartMeLanguage: win.wnjParams?.nstartMeLanguage || 'en'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ability to set a language to nstart.me link, what do you think @fiatjaf ?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good.

}
})

Expand Down
41 changes: 41 additions & 0 deletions src/texts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"Connect with Nostr": "Connect with Nostr",
"Connecting to bunker": "Connecting to bunker",
"Create a Nostr account": "Create a Nostr account",
"A new window will now open, taking you to": "A new window will now open, taking you to",
"where the account creation will occur. If nothing happens, ensure your browser is not blocking popups.": "where the account creation will occur. If nothing happens, ensure your browser is not blocking popups.",
"Afterward, you'll be redirected back to this page.": "Afterward, you'll be redirected back to this page.",
"Start account creation »": "Start account creation »",
"To use this Nostr app you need a profile. The following button opens a wizard that help you to create your keypair and safely manage it in a few steps. Are you ready?": "To use this Nostr app you need a profile. The following button opens a wizard that help you to create your keypair and safely manage it in a few steps. Are you ready?",
"Create an account »": "Create an account »",
"Do you already have a Nostr address?": "Do you already have a Nostr address?",
"Login now": "Login now",
"Login into a Nostr account": "Login into a Nostr account",
"where you can login and approve the permissions. If nothing happens, ensure your browser is not blocking popups.": "where you can login and approve the permissions. If nothing happens, ensure your browser is not blocking popups.",
"Login now »": "Login now »",
"How do you want to connect to Nostr?": "How do you want to connect to Nostr?",
"user@provider or bunker://...": "user@provider or bunker://...",
"Connect »": "Connect »",
"An action requires your confirmation": "An action requires your confirmation",
"where you can approve the current action. If nothing happens, ensure your browser is not blocking popups.": "where you can approve the current action. If nothing happens, ensure your browser is not blocking popups.",
"Confirm action »": "Confirm action »",
"What is that?": "What is that?",
"This widget is created with": "This widget is created with",
", a small script you can drop in any page that already uses NIP-07 and make it also work with NIP-46 automatically when the user doesn't have an extension installed.": ", a small script you can drop in any page that already uses NIP-07 and make it also work with NIP-46 automatically when the user doesn't have an extension installed.",
"It adds a small floating button on the side of the window that users can use to create Nostr accuonts or connect to their NIP-46 bunkers.": "It adds a small floating button on the side of the window that users can use to create Nostr accuonts or connect to their NIP-46 bunkers.",
"This tool is opensource, get the code from the": "This tool is opensource, get the code from the",
"project's page": "project's page",
"You don't know what Nostr is?": "You don't know what Nostr is?",
"Learn more": "Learn more",
"You are connected to Nostr as": "You are connected to Nostr as",
"Disconnect": "Disconnect",
"This webpage is using the public key:": "This webpage is using the public key:",
"Waiting too much?": "Waiting too much?",
"Cancel the connection": "Cancel the connection",
"Is this bunker provider broken?": "Is this bunker provider broken?",
"Clear it": "Clear it",
"Do you need a Nostr account?": "Do you need a Nostr account?",
"Sign up now": "Sign up now",
"We could not connect to a NIP-46 bunker with that url, are you sure it is set up correctly?": "We could not connect to a NIP-46 bunker with that url, are you sure it is set up correctly?",
"We were not able to connect using this address. For it to work it has to come from a NIP-46 provider.": "We were not able to connect using this address. For it to work it has to come from a NIP-46 provider."
}