Add separate settings for group access and public listing

This commit is contained in:
Jon Staab 2023-12-19 17:42:03 -08:00
parent 66c65a68ef
commit 7f3f0b989f
7 changed files with 36 additions and 17 deletions

View File

@ -4,6 +4,7 @@
image: string
description: string
isPublic: boolean
access: string
relays: string[]
members?: Person[]
}
@ -18,6 +19,7 @@
import FieldInline from "src/partials/FieldInline.svelte"
import Toggle from "src/partials/Toggle.svelte"
import SearchSelect from "src/partials/SearchSelect.svelte"
import SelectButton from "src/partials/SelectButton.svelte"
import ImageInput from "src/partials/ImageInput.svelte"
import Textarea from "src/partials/Textarea.svelte"
import Input from "src/partials/Input.svelte"
@ -26,7 +28,7 @@
import Heading from "src/partials/Heading.svelte"
import PersonMultiSelect from "src/app/shared/PersonMultiSelect.svelte"
import type {Person} from "src/engine"
import {searchRelays, normalizeRelayUrl} from "src/engine"
import {GroupAccess, searchRelays, normalizeRelayUrl} from "src/engine"
export let onSubmit
export let values: Values
@ -94,7 +96,17 @@
<div slot="info">All members will receive a fresh invitation with a new key.</div>
</Field>
{/if}
<FieldInline label="Make Public">
<Field label="Access">
<SelectButton
bind:value={values.access}
options={Object.values(GroupAccess)}
displayOption={ucFirst} />
<div slot="info">
Anyone can join and post to open groups. Hybrid and closed groups support an
admin-controlled member list which can post privately to the group.
</div>
</Field>
<FieldInline label="List Publicly">
<Toggle bind:value={values.isPublic} />
<div slot="info">
If enabled, this will generate a public listing for the group. The member list and group

View File

@ -8,6 +8,7 @@
initGroup,
publishAdminKeyShares,
user,
GroupAccess,
} from "src/engine"
import {router} from "src/app/router"
@ -16,18 +17,18 @@
image: "",
description: "",
isPublic: false,
access: GroupAccess.Closed,
members: [$user],
relays: [],
}
const onSubmit = async (values: Values) => {
const members = pluck("pubkey", values.members)
const access = values.isPublic ? "hybrid" : "closed"
const {id, address} = initGroup(members, values.relays)
await publishAdminKeyShares(address, [$user.pubkey], values.relays)
await publishGroupInvites(address, members, values.relays)
await publishGroupMeta(address, {...values, access, id})
await publishGroupMeta(address, values.isPublic, {...values, id})
router.at("groups").of(address).at("members").replace()
}

View File

@ -2,7 +2,7 @@
import {toast} from "src/partials/state"
import type {Values} from "src/app/shared/GroupDetailsForm.svelte"
import GroupDetailsForm from "src/app/shared/GroupDetailsForm.svelte"
import {groups, publishGroupMeta, getGroupId, getGroupName} from "src/engine"
import {groups, publishGroupMeta, getGroupId, getGroupName, GroupAccess} from "src/engine"
import {router} from "src/app/router"
export let address
@ -14,13 +14,13 @@
name: getGroupName($group),
image: $group.image || "",
description: $group.description || "",
isPublic: $group.access && $group.access !== "closed",
relays: $group.relays || [],
access: $group.access || GroupAccess.Closed,
isPublic: $group.access === GroupAccess.Open,
}
const onSubmit = async (values: Values) => {
const access = values.isPublic ? "hybrid" : "closed"
const pub = await publishGroupMeta(address, {...values, access})
const pub = await publishGroupMeta(address, values.isPublic, values)
await pub.result

View File

@ -20,6 +20,7 @@
publishGroupInvites,
publishGroupEvictions,
publishGroupMeta,
GroupAccess,
} from "src/engine"
import {router} from "src/app/router"
@ -68,7 +69,9 @@
publishGroupEvictions(address, removedMembers)
// Re-publish group info
publishGroupMeta(address, $group)
if ($group.access !== GroupAccess.Open) {
publishGroupMeta(address, false, $group)
}
toast.show("info", "Invites have been sent!")
router.pop()

View File

@ -290,7 +290,7 @@ export const publishGroupInvites = async (address, pubkeys, relays, gracePeriod
export const publishGroupEvictions = async (address, pubkeys) =>
publishKeyShares(address, pubkeys, createEvent(24, {tags: [["a", address]]}))
export const publishGroupMeta = async (address, meta) => {
export const publishGroupMeta = async (address, isPublic, meta) => {
const template = createEvent(34550, {
tags: [
["d", meta.id],
@ -302,9 +302,9 @@ export const publishGroupMeta = async (address, meta) => {
],
})
return meta.access === GroupAccess.Closed
? publishAsGroupAdminPrivately(address, template, meta.relays)
: publishAsGroupAdminPublicly(address, template, meta.relays)
return isPublic
? publishAsGroupAdminPublicly(address, template, meta.relays)
: publishAsGroupAdminPrivately(address, template, meta.relays)
}
// Member functions

View File

@ -1,14 +1,17 @@
<script lang="ts">
import cx from "classnames"
import {identity} from "ramda"
export let options
export let value
export let onChange = null
export let displayOption = identity
</script>
<div>
<div class="inline-block">
<div class="flex cursor-pointer overflow-hidden rounded-full border border-solid border-lightest">
<div
class="flex cursor-pointer overflow-hidden rounded-full border border-solid border-lightest">
{#each options as option, i}
<div
class={cx("px-4 py-2 transition-all", {
@ -19,7 +22,7 @@
value = option
onChange?.(value)
}}>
{option}
{displayOption(option)}
</div>
{/each}
</div>

View File

@ -7,11 +7,11 @@
</script>
<div class="relative flex items-center justify-between overflow-auto pb-px pt-1">
<div class="absolute bottom-px left-0 right-0 h-px w-full bg-light" />
<div class="absolute bottom-px left-0 right-0 h-px w-full bg-mid" />
<div class="flex">
{#each tabs as tab}
<button
class="relative flex cursor-pointer gap-2 border-b border-solid px-8 pb-4 hover:border-lighter items-end transition-colors"
class="relative flex cursor-pointer items-end gap-2 border-b border-solid px-8 pb-4 transition-colors hover:border-lighter"
class:border-transparent={activeTab !== tab}
class:border-lighter={activeTab === tab}
on:click|preventDefault={() => setActiveTab(tab)}>