diff --git a/.env.example b/.env.example
index 0c784bd..94541e9 100644
--- a/.env.example
+++ b/.env.example
@@ -1,3 +1,4 @@
PUBLIC_RELAY_URL=ws://localhost:3334
PUBLIC_GROUP_ID=mygrouprandomid
PUBLIC_MODE=simple # simple | full
+PUBLIC_JOINCODE=no # yes | no — show invite-code field on join failure
diff --git a/src/lib/auth.svelte.ts b/src/lib/auth.svelte.ts
index e792844..ebc8df6 100644
--- a/src/lib/auth.svelte.ts
+++ b/src/lib/auth.svelte.ts
@@ -3,6 +3,7 @@ import type { WindowNostr } from "@nostr/tools/nip07";
import type { EventTemplate, VerifiedEvent } from "@nostr/tools/core";
import * as nip19 from "@nostr/tools/nip19";
import { finalizeEvent, getPublicKey } from "@nostr/tools/pure";
+import { resetJoinState, initJoinForUser } from "$lib/join.svelte";
declare global {
interface Window {
@@ -58,6 +59,7 @@ function makeNsecSigner(secretKey: Uint8Array): Signer {
async function setUser(pubkey: string) {
const { loadNostrUser } = await import("@nostr/gadgets/metadata");
user = await loadNostrUser(pubkey);
+ initJoinForUser(pubkey);
}
export async function loginWithExtension() {
@@ -108,6 +110,7 @@ export function logout() {
localStorage.removeItem(PUBKEY_KEY);
localStorage.removeItem(METHOD_KEY);
localStorage.removeItem(NSEC_KEY);
+ resetJoinState();
}
export async function restoreSession() {
diff --git a/src/lib/components/JoinModal.svelte b/src/lib/components/JoinModal.svelte
new file mode 100644
index 0000000..d8c0fb3
--- /dev/null
+++ b/src/lib/components/JoinModal.svelte
@@ -0,0 +1,115 @@
+
+
+
+ {#if joinState.codeRequired} + This community requires an invite code. Enter your code below to + request access. If you don't have one, contact the admin. + {:else} + We could not add you to the group automatically. The relay may be + processing your request, or the admin needs to approve it manually. + {/if} +
+ + {#if joinState.modalError} +