Join relay and group dynamically, dropping PUBLIC_JOINCODE
This commit is contained in:
parent
aaa9a0c1e5
commit
6ecd618bce
9 changed files with 453 additions and 178 deletions
|
|
@ -15,9 +15,9 @@
|
|||
} from "$lib/moderation.svelte";
|
||||
import {
|
||||
withJoin,
|
||||
joinState,
|
||||
membershipOf,
|
||||
ensureMembershipChecked,
|
||||
openJoinModal,
|
||||
} from "$lib/join.svelte";
|
||||
import { activeGroup } from "$lib/active.svelte";
|
||||
import type { NostrUser } from "@nostr/gadgets/metadata";
|
||||
|
|
@ -76,7 +76,7 @@
|
|||
});
|
||||
|
||||
function onJoinToChat() {
|
||||
openJoinModal(activeGroup.id, () => tick().then(() => inputEl?.focus()));
|
||||
withJoin(activeGroup.id, () => tick().then(() => inputEl?.focus()));
|
||||
}
|
||||
|
||||
function requestDeleteMessage(msg: ChatMessageData) {
|
||||
|
|
@ -486,9 +486,10 @@
|
|||
{:else if joinToChat}
|
||||
<button
|
||||
onclick={onJoinToChat}
|
||||
class="bg-accent hover:bg-accent-hover w-full rounded px-3 py-2 text-sm font-medium text-white"
|
||||
disabled={joinState.busy}
|
||||
class="bg-accent hover:bg-accent-hover w-full rounded px-3 py-2 text-sm font-medium text-white disabled:opacity-50"
|
||||
>
|
||||
Join to chat
|
||||
{joinState.busy ? "Joining…" : "Join to chat"}
|
||||
</button>
|
||||
{:else}
|
||||
<div class="relative">
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@
|
|||
import {
|
||||
membershipOf,
|
||||
ensureMembershipChecked,
|
||||
openJoinModal,
|
||||
withJoin,
|
||||
joinState,
|
||||
} from "$lib/join.svelte";
|
||||
import { sortPref } from "$lib/sort.svelte";
|
||||
import { page } from "$app/state";
|
||||
|
|
@ -71,12 +72,7 @@
|
|||
openLogin(onNewTopic);
|
||||
return;
|
||||
}
|
||||
await ensureMembershipChecked(groupId);
|
||||
if (membershipOf(groupId) !== "member") {
|
||||
openJoinModal(groupId, openDraft);
|
||||
return;
|
||||
}
|
||||
openDraft();
|
||||
await withJoin(groupId, openDraft);
|
||||
}
|
||||
|
||||
function onPrivateJoin() {
|
||||
|
|
@ -84,7 +80,7 @@
|
|||
openLogin();
|
||||
return;
|
||||
}
|
||||
openJoinModal(groupId, () => loadThreads(groupId, sort));
|
||||
withJoin(groupId, () => loadThreads(groupId, sort));
|
||||
}
|
||||
|
||||
function relativeTime(ts: number): string {
|
||||
|
|
@ -138,9 +134,14 @@
|
|||
<div class="flex items-center gap-2">
|
||||
<button
|
||||
onclick={onNewTopic}
|
||||
class="bg-accent hover:bg-accent-hover rounded px-4 py-1.5 font-medium text-white md:px-6 md:text-sm"
|
||||
disabled={joinState.busy}
|
||||
class="bg-accent hover:bg-accent-hover rounded px-4 py-1.5 font-medium text-white disabled:opacity-50 md:px-6 md:text-sm"
|
||||
>
|
||||
{joinToPost ? "Join to post" : "New discussion"}
|
||||
{joinState.busy
|
||||
? "Joining…"
|
||||
: joinToPost
|
||||
? "Join to post"
|
||||
: "New discussion"}
|
||||
</button>
|
||||
<SortToggle {sort} />
|
||||
</div>
|
||||
|
|
@ -165,9 +166,14 @@
|
|||
</p>
|
||||
<button
|
||||
onclick={onPrivateJoin}
|
||||
class="bg-accent hover:bg-accent-hover mt-5 rounded px-6 py-1.5 font-medium text-white"
|
||||
disabled={joinState.busy}
|
||||
class="bg-accent hover:bg-accent-hover mt-5 rounded px-6 py-1.5 font-medium text-white disabled:opacity-50"
|
||||
>
|
||||
{auth.user ? "Request to join" : "Log in to join"}
|
||||
{joinState.busy
|
||||
? "Joining…"
|
||||
: auth.user
|
||||
? "Request to join"
|
||||
: "Log in to join"}
|
||||
</button>
|
||||
</div>
|
||||
{:else}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,38 @@
|
|||
<script lang="ts">
|
||||
import { joinState, closeJoinModal, submitJoin } from "$lib/join.svelte";
|
||||
import { joinState, closeJoinModal, submitJoinCode } from "$lib/join.svelte";
|
||||
import { tick } from "svelte";
|
||||
|
||||
let code = $state("");
|
||||
let codeInput = $state<HTMLInputElement | null>(null);
|
||||
// Pending approval hides the code field behind a discreet link, so a group
|
||||
// that doesn't hand out codes doesn't send people hunting for one.
|
||||
let codeRevealed = $state(false);
|
||||
|
||||
const step = $derived(joinState.modalStep);
|
||||
const showCode = $derived(
|
||||
step === "relay-code" ||
|
||||
(step === "group-code" && joinState.modalCodeHinted) ||
|
||||
codeRevealed,
|
||||
);
|
||||
const canOfferCode = $derived(
|
||||
step === "pending" || (step === "group-code" && !joinState.modalCodeHinted),
|
||||
);
|
||||
|
||||
$effect(() => {
|
||||
if (joinState.modalOpen && joinState.needsCode) {
|
||||
if (!joinState.modalOpen) {
|
||||
code = "";
|
||||
codeRevealed = false;
|
||||
}
|
||||
});
|
||||
|
||||
$effect(() => {
|
||||
if (joinState.modalOpen && showCode) {
|
||||
tick().then(() => codeInput?.focus());
|
||||
}
|
||||
if (!joinState.modalOpen) code = "";
|
||||
});
|
||||
|
||||
async function onSubmit() {
|
||||
await submitJoin(code.trim() || undefined);
|
||||
await submitJoinCode(code.trim() || undefined);
|
||||
}
|
||||
|
||||
function onClose() {
|
||||
|
|
@ -56,15 +75,28 @@
|
|||
id="join-title"
|
||||
class="mb-2 text-lg font-semibold text-neutral-900 dark:text-neutral-100"
|
||||
>
|
||||
Join this group
|
||||
{#if step === "relay-code"}
|
||||
Invite code required
|
||||
{:else if step === "pending"}
|
||||
Request sent
|
||||
{:else if step === "error"}
|
||||
Could not join
|
||||
{:else}
|
||||
Join this group
|
||||
{/if}
|
||||
</h2>
|
||||
<p class="mb-4 text-sm text-neutral-600 dark:text-neutral-400">
|
||||
{#if joinState.needsCode}
|
||||
Join this group to participate. If you have an invite code, enter it
|
||||
below — otherwise just send the request.
|
||||
{#if step === "relay-code"}
|
||||
This relay only accepts members. Enter an invite code to join.
|
||||
{:else if step === "pending"}
|
||||
Your request to join has been sent. An admin needs to approve it
|
||||
before you can participate.
|
||||
{:else if step === "error"}
|
||||
The relay refused the request.
|
||||
{:else if joinState.modalCodeHinted}
|
||||
This group requires an invite code to join.
|
||||
{:else}
|
||||
Join this group to participate. Your request is sent to the relay and,
|
||||
where needed, approved by an admin.
|
||||
The group refused the join request.
|
||||
{/if}
|
||||
</p>
|
||||
|
||||
|
|
@ -77,13 +109,17 @@
|
|||
</div>
|
||||
{/if}
|
||||
|
||||
{#if joinState.needsCode}
|
||||
<label for="join-code-input" class="sr-only">Invite code</label>
|
||||
{#if showCode}
|
||||
<label for="join-code-input" class="sr-only">
|
||||
{step === "relay-code" ? "Relay invite code" : "Group invite code"}
|
||||
</label>
|
||||
<input
|
||||
id="join-code-input"
|
||||
bind:this={codeInput}
|
||||
type="text"
|
||||
placeholder="Invite code (optional)"
|
||||
placeholder={step === "relay-code"
|
||||
? "Relay invite code"
|
||||
: "Group invite code"}
|
||||
bind:value={code}
|
||||
disabled={joinState.busy}
|
||||
autocomplete="off"
|
||||
|
|
@ -92,6 +128,14 @@
|
|||
onkeydown={(e) => e.key === "Enter" && onSubmit()}
|
||||
class="focus:ring-accent mb-3 w-full rounded border border-neutral-200 px-3 py-2 text-sm focus:ring-1 focus:outline-none disabled:opacity-50 dark:border-neutral-700"
|
||||
/>
|
||||
{:else if canOfferCode}
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => (codeRevealed = true)}
|
||||
class="mb-3 text-sm text-neutral-500 underline hover:text-neutral-800 dark:text-neutral-400 dark:hover:text-neutral-200"
|
||||
>
|
||||
Have an invite code?
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
<div class="flex justify-end gap-2">
|
||||
|
|
@ -103,18 +147,16 @@
|
|||
>
|
||||
Close
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onclick={onSubmit}
|
||||
disabled={joinState.busy}
|
||||
class="bg-accent hover:bg-accent-hover rounded px-3 py-2 text-sm font-medium text-white disabled:cursor-not-allowed disabled:opacity-50"
|
||||
>
|
||||
{joinState.busy
|
||||
? "Joining…"
|
||||
: joinState.needsCode
|
||||
? "Request access"
|
||||
: "Join"}
|
||||
</button>
|
||||
{#if showCode}
|
||||
<button
|
||||
type="button"
|
||||
onclick={onSubmit}
|
||||
disabled={joinState.busy || !code.trim()}
|
||||
class="bg-accent hover:bg-accent-hover rounded px-3 py-2 text-sm font-medium text-white disabled:cursor-not-allowed disabled:opacity-50"
|
||||
>
|
||||
{joinState.busy ? "Joining…" : "Join"}
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue