forked from coracle/flotilla
Improve group membership detection
This commit is contained in:
+3
-20
@@ -53,6 +53,7 @@ import {
|
||||
tagEventForComment,
|
||||
tagEventForQuote,
|
||||
thunkIsComplete,
|
||||
getThunkError,
|
||||
} from "@welshman/app"
|
||||
import type {Thunk} from "@welshman/app"
|
||||
import {
|
||||
@@ -83,21 +84,6 @@ export const getPubkeyPetname = (pubkey: string) => {
|
||||
return display
|
||||
}
|
||||
|
||||
export const getThunkError = (thunk: Thunk) =>
|
||||
new Promise<string>(resolve => {
|
||||
thunk.subscribe($thunk => {
|
||||
for (const [relay, status] of Object.entries($thunk.status)) {
|
||||
if (status === PublishStatus.Failure) {
|
||||
resolve($thunk.details[relay])
|
||||
}
|
||||
}
|
||||
|
||||
if (thunkIsComplete($thunk)) {
|
||||
resolve("")
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
export const prependParent = (parent: TrustedEvent | undefined, {content, tags}: EventContent) => {
|
||||
if (parent) {
|
||||
const nevent = nip19.neventEncode({
|
||||
@@ -189,12 +175,9 @@ export const removeSpaceMembership = async (url: string) => {
|
||||
return publishThunk({event, relays})
|
||||
}
|
||||
|
||||
export const addRoomMembership = async (url: string, room: string, name: string) => {
|
||||
export const addRoomMembership = async (url: string, room: string) => {
|
||||
const list = get(userMembership) || makeList({kind: GROUPS})
|
||||
const newTags = [
|
||||
["r", url],
|
||||
["group", room, url, name],
|
||||
]
|
||||
const newTags = [["r", url], ["group", room, url]]
|
||||
const event = await addToListPublicly(list, ...newTags).reconcile(nip44EncryptToSelf)
|
||||
const relays = uniq([...Router.get().FromUser().getUrls(), ...getRelayTagValues(event.tags)])
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import SecondaryNavItem from "@lib/components/SecondaryNavItem.svelte"
|
||||
import ChannelName from "@app/components/ChannelName.svelte"
|
||||
import {makeRoomPath} from "@app/routes"
|
||||
import {deriveChannel, channelIsLocked} from "@app/state"
|
||||
import {deriveChannel} from "@app/state"
|
||||
import {notifications} from "@app/notifications"
|
||||
|
||||
interface Props {
|
||||
@@ -23,7 +23,7 @@
|
||||
href={path}
|
||||
{replaceState}
|
||||
notification={notify ? $notifications.has(path) : false}>
|
||||
{#if channelIsLocked($channel)}
|
||||
{#if $channel?.closed || $channel?.private}
|
||||
<Icon icon="lock" size={4} />
|
||||
{:else}
|
||||
<Icon icon="hashtag" />
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import {goto} from "$app/navigation"
|
||||
import {randomId} from "@welshman/lib"
|
||||
import {displayRelayUrl} from "@welshman/util"
|
||||
import {deriveRelay} from "@welshman/app"
|
||||
import {deriveRelay, getThunkError} from "@welshman/app"
|
||||
import {preventDefault} from "@lib/html"
|
||||
import Field from "@lib/components/Field.svelte"
|
||||
import Spinner from "@lib/components/Spinner.svelte"
|
||||
@@ -11,7 +11,7 @@
|
||||
import ModalHeader from "@lib/components/ModalHeader.svelte"
|
||||
import ModalFooter from "@lib/components/ModalFooter.svelte"
|
||||
import {hasNip29, loadChannel} from "@app/state"
|
||||
import {addRoomMembership, createRoom, editRoom, joinRoom, getThunkError} from "@app/commands"
|
||||
import {createRoom, editRoom, joinRoom} from "@app/commands"
|
||||
import {makeSpacePath} from "@app/routes"
|
||||
import {pushToast} from "@app/toast"
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
|
||||
await loadChannel(url, room)
|
||||
|
||||
addRoomMembership(url, room, name)
|
||||
goto(makeSpacePath(url, room))
|
||||
}
|
||||
|
||||
|
||||
+39
-7
@@ -34,6 +34,9 @@ import {
|
||||
GROUPS,
|
||||
THREAD,
|
||||
COMMENT,
|
||||
GROUP_JOIN,
|
||||
GROUP_ADD_USER,
|
||||
GROUP_REMOVE_USER,
|
||||
getGroupTags,
|
||||
getRelayTagValues,
|
||||
getPubkeyTagValues,
|
||||
@@ -43,6 +46,8 @@ import {
|
||||
getListTags,
|
||||
asDecryptedEvent,
|
||||
normalizeRelayUrl,
|
||||
getTag,
|
||||
getTagValues,
|
||||
} from "@welshman/util"
|
||||
import type {TrustedEvent, SignedEvent, PublishedList, List, Filter} from "@welshman/util"
|
||||
import {Nip59, decrypt} from "@welshman/signer"
|
||||
@@ -486,8 +491,8 @@ export type Channel = {
|
||||
room: string
|
||||
name: string
|
||||
event: TrustedEvent
|
||||
access: "public" | "private"
|
||||
membership: "open" | "closed"
|
||||
closed: boolean
|
||||
private: boolean
|
||||
picture?: string
|
||||
about?: string
|
||||
}
|
||||
@@ -520,8 +525,8 @@ export const channels = derived(
|
||||
room,
|
||||
event,
|
||||
name: meta.name || room,
|
||||
access: meta.private ? "private" : "public",
|
||||
membership: meta.closed ? "closed" : "open",
|
||||
closed: Boolean(getTag("closed", event.tags)),
|
||||
private: Boolean(getTag("private", event.tags)),
|
||||
picture: meta.picture,
|
||||
about: meta.about,
|
||||
})
|
||||
@@ -563,9 +568,6 @@ export const displayChannel = (url: string, room: string) =>
|
||||
export const roomComparator = (url: string) => (room: string) =>
|
||||
displayChannel(url, room).toLowerCase()
|
||||
|
||||
export const channelIsLocked = (channel?: Channel) =>
|
||||
channel?.access === "private" && channel?.membership === "closed"
|
||||
|
||||
// User stuff
|
||||
|
||||
export const userSettings = withGetter(
|
||||
@@ -626,6 +628,36 @@ export const deriveOtherRooms = (url: string) =>
|
||||
),
|
||||
)
|
||||
|
||||
export enum MembershipStatus {
|
||||
Initial,
|
||||
Pending,
|
||||
Granted,
|
||||
}
|
||||
|
||||
export const deriveUserMembershipStatus = (url: string, room: string) =>
|
||||
derived(
|
||||
[pubkey, deriveEventsForUrl(url, [{kinds: [GROUP_JOIN, GROUP_ADD_USER, GROUP_REMOVE_USER], '#h': [room]}])],
|
||||
([$pubkey, $events]) => {
|
||||
let status = MembershipStatus.Initial
|
||||
|
||||
for (const event of $events) {
|
||||
if (event.kind === GROUP_JOIN && event.pubkey === $pubkey) {
|
||||
status = MembershipStatus.Pending
|
||||
}
|
||||
|
||||
if (event.kind === GROUP_REMOVE_USER && getTagValues("p", event.tags).includes($pubkey!)) {
|
||||
break
|
||||
}
|
||||
|
||||
if (event.kind === GROUP_ADD_USER && getTagValues("p", event.tags).includes($pubkey!)) {
|
||||
return MembershipStatus.Granted
|
||||
}
|
||||
}
|
||||
|
||||
return status
|
||||
}
|
||||
)
|
||||
|
||||
// Other utils
|
||||
|
||||
export const encodeRelay = (url: string) =>
|
||||
|
||||
Reference in New Issue
Block a user