From 1fd221b1995f706c8fbf3e770429da0f74193e18 Mon Sep 17 00:00:00 2001
From: Ticruz
Date: Mon, 4 Nov 2024 14:47:41 +0100
Subject: [PATCH 01/13] delete all group related functions
---
src/app/shared/EventInfo.svelte | 12 -
src/app/shared/GroupAbout.svelte | 17 -
src/app/shared/GroupActions.svelte | 15 -
src/app/shared/GroupActionsClosed.svelte | 133 ------
src/app/shared/GroupActionsOpen.svelte | 77 ----
src/app/shared/GroupAdmin.svelte | 17 -
src/app/shared/GroupAlert.svelte | 50 ---
src/app/shared/GroupCalendar.svelte | 8 -
src/app/shared/GroupDetailsForm.svelte | 178 --------
src/app/shared/GroupLink.svelte | 19 -
src/app/shared/GroupListItem.svelte | 65 ---
src/app/shared/GroupMarket.svelte | 24 --
src/app/shared/GroupMember.svelte | 34 --
src/app/shared/GroupMembers.svelte | 24 --
src/app/shared/GroupName.svelte | 12 -
src/app/shared/GroupNotes.svelte | 89 ----
src/app/shared/GroupRequest.svelte | 86 ----
src/app/shared/GroupRestrictAccess.svelte | 21 -
src/app/shared/GroupSummary.svelte | 37 --
src/app/shared/NoteActions.svelte | 25 +-
src/app/shared/NoteCreateInline.svelte | 49 +--
src/app/shared/NoteOptions.svelte | 43 +-
src/app/shared/NoteReply.svelte | 9 +-
src/app/views/Bech32Entity.svelte | 5 +-
src/app/views/EventEdit.svelte | 4 +-
src/app/views/GroupCreate.svelte | 110 -----
src/app/views/GroupDelete.svelte | 36 --
src/app/views/GroupDetail.svelte | 130 ------
src/app/views/GroupEdit.svelte | 44 --
src/app/views/GroupInfo.svelte | 59 ---
src/app/views/GroupInviteAdmin.svelte | 57 ---
src/app/views/GroupList.svelte | 7 +-
src/app/views/GroupRotate.svelte | 122 ------
src/app/views/Home.svelte | 8 +-
src/app/views/InviteAccept.svelte | 51 +--
src/app/views/InviteCreate.svelte | 86 +---
src/app/views/NoteCreate.svelte | 73 ++--
src/app/views/UserKeys.svelte | 76 +---
src/domain/group.ts | 41 --
src/domain/index.ts | 1 -
src/engine/commands.ts | 473 +++-------------------
src/engine/model.ts | 50 +--
src/engine/projections.ts | 161 +-------
src/engine/requests.ts | 18 -
src/engine/state.ts | 414 +++++--------------
src/util/store.ts | 28 --
46 files changed, 249 insertions(+), 2849 deletions(-)
delete mode 100644 src/app/shared/GroupAbout.svelte
delete mode 100644 src/app/shared/GroupActions.svelte
delete mode 100644 src/app/shared/GroupActionsClosed.svelte
delete mode 100644 src/app/shared/GroupActionsOpen.svelte
delete mode 100644 src/app/shared/GroupAdmin.svelte
delete mode 100644 src/app/shared/GroupAlert.svelte
delete mode 100644 src/app/shared/GroupCalendar.svelte
delete mode 100644 src/app/shared/GroupDetailsForm.svelte
delete mode 100644 src/app/shared/GroupLink.svelte
delete mode 100644 src/app/shared/GroupListItem.svelte
delete mode 100644 src/app/shared/GroupMarket.svelte
delete mode 100644 src/app/shared/GroupMember.svelte
delete mode 100644 src/app/shared/GroupMembers.svelte
delete mode 100644 src/app/shared/GroupName.svelte
delete mode 100644 src/app/shared/GroupNotes.svelte
delete mode 100644 src/app/shared/GroupRequest.svelte
delete mode 100644 src/app/shared/GroupRestrictAccess.svelte
delete mode 100644 src/app/shared/GroupSummary.svelte
delete mode 100644 src/app/views/GroupCreate.svelte
delete mode 100644 src/app/views/GroupDelete.svelte
delete mode 100644 src/app/views/GroupDetail.svelte
delete mode 100644 src/app/views/GroupEdit.svelte
delete mode 100644 src/app/views/GroupInfo.svelte
delete mode 100644 src/app/views/GroupInviteAdmin.svelte
delete mode 100644 src/app/views/GroupRotate.svelte
delete mode 100644 src/domain/group.ts
diff --git a/src/app/shared/EventInfo.svelte b/src/app/shared/EventInfo.svelte
index a9b752a70..912488c3d 100644
--- a/src/app/shared/EventInfo.svelte
+++ b/src/app/shared/EventInfo.svelte
@@ -7,7 +7,6 @@
import {secondsToDate, formatTimestamp, formatTimestampAsDate, getLocale} from "src/util/misc"
import Anchor from "src/partials/Anchor.svelte"
import Chip from "src/partials/Chip.svelte"
- import GroupLink from "src/app/shared/GroupLink.svelte"
import PersonLink from "src/app/shared/PersonLink.svelte"
import EventActions from "src/app/shared/EventActions.svelte"
import NoteContentKind1 from "src/app/shared/NoteContentKind1.svelte"
@@ -69,17 +68,6 @@
Created by
- {#if groupAddrs.length > 0}
- •
-
- Posted in
- {#if groupAddrs.length === 1}
-
- {:else}
- {groupAddrs.length} groups
- {/if}
-
- {/if}
diff --git a/src/app/shared/GroupAbout.svelte b/src/app/shared/GroupAbout.svelte
deleted file mode 100644
index 63b9fdecf..000000000
--- a/src/app/shared/GroupAbout.svelte
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-{#key $meta?.about}
-
-{/key}
diff --git a/src/app/shared/GroupActions.svelte b/src/app/shared/GroupActions.svelte
deleted file mode 100644
index 56e935c34..000000000
--- a/src/app/shared/GroupActions.svelte
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-{#if address.startsWith("34550:")}
-
-{/if}
-
-{#if address.startsWith("35834:")}
-
-{/if}
diff --git a/src/app/shared/GroupActionsClosed.svelte b/src/app/shared/GroupActionsClosed.svelte
deleted file mode 100644
index 0a7fad328..000000000
--- a/src/app/shared/GroupActionsClosed.svelte
+++ /dev/null
@@ -1,133 +0,0 @@
-
-
-
- {#if $signer}
- {#if !$status.access}
-
-
-
-
- Join
-
- {:else if $status.access === GroupAccess.Requested}
-
-
-
-
- Access Pending
-
- {:else if $status.access === GroupAccess.Granted}
-
-
-
-
- Leave
-
- {:else if $status.access === GroupAccess.Revoked}
-
-
-
-
- Access Revoked
-
- {/if}
- {/if}
-
-
-
-{#if showClaim}
-
-
- If you have an invite code, you can enter it below.
-
-
-
-
-
Cancel
-
Request access
-
-
-
-{/if}
diff --git a/src/app/shared/GroupActionsOpen.svelte b/src/app/shared/GroupActionsOpen.svelte
deleted file mode 100644
index d193e83bc..000000000
--- a/src/app/shared/GroupActionsOpen.svelte
+++ /dev/null
@@ -1,77 +0,0 @@
-
-
-
- {#if $session}
- {#if $status.joined}
-
-
-
-
- Leave
-
- {:else}
-
-
-
-
- Join
-
- {/if}
- {/if}
-
-
diff --git a/src/app/shared/GroupAdmin.svelte b/src/app/shared/GroupAdmin.svelte
deleted file mode 100644
index 51018d817..000000000
--- a/src/app/shared/GroupAdmin.svelte
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-{#each $requests as request (request.id)}
-
-{:else}
-
No action items found.
-{/each}
diff --git a/src/app/shared/GroupAlert.svelte b/src/app/shared/GroupAlert.svelte
deleted file mode 100644
index 6b4494c0c..000000000
--- a/src/app/shared/GroupAlert.svelte
+++ /dev/null
@@ -1,50 +0,0 @@
-
-
-
-
-
-
- {#if alert.type === "exit"}
- Access revoked
- {:else if alert.type === "invite"}
- Group invitation
- {/if}
-
-
- {formatTimestamp(alert.created_at)}
-
-
-
- The admin of
-
-
-
-
-
-
- has
- {#if alert.type === "exit"}
- removed you from the group.
- {:else if alert.type === "invite"}
- given you access to the group.
- {/if}
-
- {#if alert.content}
-
- "{alert.content}"
-
- {/if}
-
-
diff --git a/src/app/shared/GroupCalendar.svelte b/src/app/shared/GroupCalendar.svelte
deleted file mode 100644
index a87b5ada2..000000000
--- a/src/app/shared/GroupCalendar.svelte
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
diff --git a/src/app/shared/GroupDetailsForm.svelte b/src/app/shared/GroupDetailsForm.svelte
deleted file mode 100644
index 13de3c758..000000000
--- a/src/app/shared/GroupDetailsForm.svelte
+++ /dev/null
@@ -1,178 +0,0 @@
-
-
-
diff --git a/src/app/shared/GroupLink.svelte b/src/app/shared/GroupLink.svelte
deleted file mode 100644
index 1e0f757d6..000000000
--- a/src/app/shared/GroupLink.svelte
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
- {displayGroupMeta($meta)}
-
-
diff --git a/src/app/shared/GroupListItem.svelte b/src/app/shared/GroupListItem.svelte
deleted file mode 100644
index aa18f249c..000000000
--- a/src/app/shared/GroupListItem.svelte
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-
-
-
-
-
- {displayGroupMeta($meta)}
-
-
- {#if isCommunityAddress(address)}
- Open
- {/if}
- {#if isGroupAddress(address)}
- Closed
- {/if}
-
-
- {#if $meta?.about}
-
- {ellipsize($meta.about, 300)}
-
- {/if}
- {#if $members.length > 0}
-
- {/if}
-
-
diff --git a/src/app/shared/GroupMarket.svelte b/src/app/shared/GroupMarket.svelte
deleted file mode 100644
index 5e453bcc5..000000000
--- a/src/app/shared/GroupMarket.svelte
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
- Have something you'd like to sell on nostr?
- Create a listing
-
-
-
diff --git a/src/app/shared/GroupMember.svelte b/src/app/shared/GroupMember.svelte
deleted file mode 100644
index f29591fbc..000000000
--- a/src/app/shared/GroupMember.svelte
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
openPerson(pubkey)}>
-
-
- {#if $adminKey && pubkey !== $session.pubkey && isGroupAddress(address)}
- Remove
- {/if}
-
-
-
diff --git a/src/app/shared/GroupMembers.svelte b/src/app/shared/GroupMembers.svelte
deleted file mode 100644
index 6bf67ea35..000000000
--- a/src/app/shared/GroupMembers.svelte
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
- {#each members as pubkey (pubkey)}
-
- {:else}
- No members found.
- {/each}
-
diff --git a/src/app/shared/GroupName.svelte b/src/app/shared/GroupName.svelte
deleted file mode 100644
index 9664ec6ef..000000000
--- a/src/app/shared/GroupName.svelte
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
{display}
diff --git a/src/app/shared/GroupNotes.svelte b/src/app/shared/GroupNotes.svelte
deleted file mode 100644
index dafe3a951..000000000
--- a/src/app/shared/GroupNotes.svelte
+++ /dev/null
@@ -1,89 +0,0 @@
-
-
-
- {#if $signer}
-
- {/if}
- {#if tabs.length > 1}
-
-
-
- {/if}
- {#key feed}
-
- {/key}
-
diff --git a/src/app/shared/GroupRequest.svelte b/src/app/shared/GroupRequest.svelte
deleted file mode 100644
index 0749681c1..000000000
--- a/src/app/shared/GroupRequest.svelte
+++ /dev/null
@@ -1,86 +0,0 @@
-
-
-
-
-
-
- {#if request.kind === 25}
- Request to join
- {:else if request.kind === 26}
- Key rotation request
- {/if}
-
-
-
-
- "{request.content}"
-
-
- Resolving this request will
- {#if request.kind === 25}
- add to
- {:else if request.kind === 26}
- remove from
- {/if}
- {#if showGroup}
-
-
-
-
-
-
- {:else}
- the group.
- {/if}
-
- {#if claim}
- Claim: "{claim}"
- {/if}
-
-
-
diff --git a/src/app/shared/GroupRestrictAccess.svelte b/src/app/shared/GroupRestrictAccess.svelte
deleted file mode 100644
index b65cbe432..000000000
--- a/src/app/shared/GroupRestrictAccess.svelte
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
- {#if $status.access === GroupAccess.Requested}
- Your access request is awaiting approval.
- {:else}
- You don't have access to this group.
- {/if}
- {#if $session && !$status.access}
- Click publishGroupEntryRequest(address)}>here to request
- entry.
- {/if}
-
diff --git a/src/app/shared/GroupSummary.svelte b/src/app/shared/GroupSummary.svelte
deleted file mode 100644
index 37544eda2..000000000
--- a/src/app/shared/GroupSummary.svelte
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
- {#if isCommunityAddress(address)}
-
- Open
- {:else}
-
- Closed
- {/if}
-
-
-
-
- {#if !hideAbout && $meta?.about}
-
- {/if}
-
-
diff --git a/src/app/shared/NoteActions.svelte b/src/app/shared/NoteActions.svelte
index c1ecd4e9a..71c5a6fed 100644
--- a/src/app/shared/NoteActions.svelte
+++ b/src/app/shared/NoteActions.svelte
@@ -55,9 +55,8 @@
env,
publish,
deriveHandlersForKind,
- userIsGroupMember,
groupMeta,
- publishToZeroOrMoreGroups,
+ signAndPublish,
deleteEvent,
getSetting,
loadPubkeys,
@@ -128,11 +127,9 @@
const tags = [...tagReactionTo(note), ...getClientTags()]
const template = createEvent(7, {content, tags})
- const {events} = await publishToZeroOrMoreGroups(addresses, template)
+ const {event} = await signAndPublish(template)
- for (const event of events) {
- addToContext(event)
- }
+ addToContext(event)
}
const deleteReaction = e => {
@@ -140,7 +137,7 @@
removeFromContext(e)
}
- const crossPost = async (addresses = []) => {
+ const crossPost = async () => {
const content = JSON.stringify(note as SignedEvent)
const tags = [...tagEvent(note), tagPubkey(note.pubkey), ...getClientTags()]
@@ -151,7 +148,7 @@
template = createEvent(16, {content, tags: [...tags, ["k", String(note.kind)]]})
}
- publishToZeroOrMoreGroups(addresses, template)
+ signAndPublish(template)
showInfo("Note has been cross-posted!")
@@ -200,16 +197,11 @@
window.open(templateTag[1].replace("
", entity))
}
- const groupOptions = derived([groupMeta, userIsGroupMember], ([$gm, $isMember]) =>
- $gm.filter(g => $isMember(getAddress(g.event), true)),
- )
-
let view
let actions = []
let handlersShown = false
- $: disableActions =
- !$signer || (muted && !showHidden) || (note.wrap && address && !$userIsGroupMember(address))
+ $: disableActions = !$signer || (muted && !showHidden) || (note.wrap && address)
$: like = likes.find(e => e.pubkey === $sessionWithMeta?.pubkey)
$: $likesCount = likes.length
$: zap = zaps.find(e => e.request.pubkey === $sessionWithMeta?.pubkey)
@@ -458,11 +450,6 @@
{/if}
- {#each $groupOptions as g (getAddress(g.event))}
- crossPost([getAddress(g.event)])}>
-
-
- {/each}
{/if}
diff --git a/src/app/shared/NoteCreateInline.svelte b/src/app/shared/NoteCreateInline.svelte
index de27beac8..839dde2a9 100644
--- a/src/app/shared/NoteCreateInline.svelte
+++ b/src/app/shared/NoteCreateInline.svelte
@@ -1,34 +1,21 @@
-
-{#if !initialValues.kind}
-
-
Create Group
-
What type of group would you like to create?
-
- setKind(COMMUNITY)}>
-
-
-
- Anyone can participate in an open group. All content is public, although some clients will
- allow you to assign moderators and selectively show only certain content.
-
-
-
- setKind(GROUP)}>
-
-
-
- Messages posted to a closed group are encrypted so that only other members can see them.
- Only people you approve can join a closed group.
-
-
-
-{:else}
-
- setKind(null)} />
-
-
-{/if}
diff --git a/src/app/views/GroupDelete.svelte b/src/app/views/GroupDelete.svelte
deleted file mode 100644
index d3fe0f43e..000000000
--- a/src/app/views/GroupDelete.svelte
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-Delete Group
-Are you sure you want to delete {displayGroupMeta($meta)}?
-
- This will only hide this group from supporting clients. Messages sent to the group may not be
- deleted from relays.
-
-
diff --git a/src/app/views/GroupDetail.svelte b/src/app/views/GroupDetail.svelte
deleted file mode 100644
index 0d392f8c6..000000000
--- a/src/app/views/GroupDetail.svelte
+++ /dev/null
@@ -1,130 +0,0 @@
-
-
-
-
-
-
-
-
-
setActiveTab("notes")} class="text-2xl"
- >{displayGroupMeta($meta)}
-
-
-
-
-
-
-{#if tabs.length > 1}
-
-
-
{ucFirst(tab)}
- {#if tab === "admin" && $requests.length > 0}
-
- {$requests.length}
-
- {/if}
-
-
-{/if}
-
-{#key key}
- {#if address.startsWith("35834") && $status.access !== GroupAccess.Granted}
-
- {:else if activeTab === "notes"}
-
- {:else if activeTab === "calendar"}
-
- {:else if activeTab === "market"}
-
- {:else if activeTab === "members"}
-
- {:else if activeTab === "admin"}
-
- {/if}
-{/key}
diff --git a/src/app/views/GroupEdit.svelte b/src/app/views/GroupEdit.svelte
deleted file mode 100644
index d2a589579..000000000
--- a/src/app/views/GroupEdit.svelte
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
-
diff --git a/src/app/views/GroupInfo.svelte b/src/app/views/GroupInfo.svelte
deleted file mode 100644
index 09e821824..000000000
--- a/src/app/views/GroupInfo.svelte
+++ /dev/null
@@ -1,59 +0,0 @@
-
-
-Details
-
-
-{#if $adminKey}
-
-
-
Admin Key
-
-
-
-
- This is your group administration password. Keep it secret!
-
- Click
- here
- to share this key with another user. This will give them
- complete control over this group.
-
-
-
-
-
-
-{/if}
-{#if $meta?.relays.length > 0}
- Relays
- This group uses the following relays:
-
- {#each $meta.relays as tag}
-
- {/each}
-
-{/if}
diff --git a/src/app/views/GroupInviteAdmin.svelte b/src/app/views/GroupInviteAdmin.svelte
deleted file mode 100644
index b6254273b..000000000
--- a/src/app/views/GroupInviteAdmin.svelte
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-Invite Group Admin
-
- Keys are shared over nostr using encrypted messages. Be aware that this can reduce your group's
- privacy, for example if any receipient's key is compromised.
-
-
-Share Admin Key
-
-{#if modal === "confirm"}
-
- Confirm key share
-
- Are you sure you want to share the admin key for with the following
- people?
-
-
- {#each pubkeys as pubkey}
-
- {/each}
-
-
-
-{/if}
diff --git a/src/app/views/GroupList.svelte b/src/app/views/GroupList.svelte
index 09987745d..40bbcd3b3 100644
--- a/src/app/views/GroupList.svelte
+++ b/src/app/views/GroupList.svelte
@@ -1,16 +1,13 @@
- You can still access your groups at groups.coracle.social ,
- or you can try our new relay-based groups client at flotilla.social .
+ You can still access your groups at groups.coracle.social , or you can try our new
+ relay-based groups client at flotilla.social .
Continue to Groups
diff --git a/src/app/views/GroupRotate.svelte b/src/app/views/GroupRotate.svelte
deleted file mode 100644
index 06dceac1b..000000000
--- a/src/app/views/GroupRotate.svelte
+++ /dev/null
@@ -1,122 +0,0 @@
-
-
-
-
- Update Members
-
- Rotate keys periodically to change group membership and increase security.
-
-
-
- All members will receive a fresh invitation with a new key.
-
-
-
-
- Share the current key with all new members instead of creating a new one. This allows new
- members to see recent messages, and does not revoke access for removed members.
-
-
- Save
-
-
diff --git a/src/app/views/Home.svelte b/src/app/views/Home.svelte
index 5dc0fdcaa..af7b3e44d 100644
--- a/src/app/views/Home.svelte
+++ b/src/app/views/Home.svelte
@@ -1,11 +1,5 @@
-{#if env.FORCE_GROUP}
-
-{:else}
-
-{/if}
+
diff --git a/src/app/views/InviteAccept.svelte b/src/app/views/InviteAccept.svelte
index ec0d9c856..7bd181409 100644
--- a/src/app/views/InviteAccept.svelte
+++ b/src/app/views/InviteAccept.svelte
@@ -1,41 +1,23 @@
{#if $session}
@@ -68,22 +50,7 @@
{/if}
- {#if parsedGroups.length > 0}
-
-
- Groups
- Here is a selection of groups you might be interested in.
- {#each parsedGroups as group (group.address)}
-
-
-
-
-
- {/each}
-
-
- {/if}
Done
{:else}
-
+
{/if}
diff --git a/src/app/views/InviteCreate.svelte b/src/app/views/InviteCreate.svelte
index 2ac7c8e1f..d73f2d07b 100644
--- a/src/app/views/InviteCreate.svelte
+++ b/src/app/views/InviteCreate.svelte
@@ -1,22 +1,19 @@
@@ -157,30 +129,6 @@
Import Key
-
- These keys are used for accessing or managing closed groups. Save these to make sure you don't
- lose access to your groups.
-
- {#each addresses as address (address)}
- {@const sharedKey = sharedKeys[address]}
- {@const adminKey = adminKeys[address]}
-
-
-
-
-
-
- {#if sharedKey}
-
- {/if}
- {#if adminKey}
-
- {/if}
-
-
- {:else}
- No keys found.
- {/each}
diff --git a/src/domain/group.ts b/src/domain/group.ts
deleted file mode 100644
index be1aff5b3..000000000
--- a/src/domain/group.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import {fromPairs, nthEq} from "@welshman/lib"
-import type {TrustedEvent} from "@welshman/util"
-import {isSignedEvent} from "@welshman/util"
-
-export type GroupMeta = {
- kind: number
- feeds: string[][]
- relays: string[][]
- moderators: string[][]
- identifier: string
- name: string
- about: string
- banner: string
- image: string
- listing_is_public: boolean
- event?: TrustedEvent
-}
-
-export type PublishedGroupMeta = Omit & {
- event: TrustedEvent
-}
-
-export const readGroupMeta = (event: TrustedEvent) => {
- const meta = fromPairs(event.tags)
-
- return {
- event,
- kind: event.kind,
- feeds: event.tags.filter(nthEq(0, "feed")),
- relays: event.tags.filter(nthEq(0, "relay")),
- moderators: event.tags.filter(nthEq(0, "p")),
- identifier: meta.d,
- name: meta.name || "",
- banner: meta.banner || "",
- about: meta.about || meta.description || "",
- image: meta.image || meta.picture || "",
- listing_is_public: isSignedEvent(event),
- } as PublishedGroupMeta
-}
-
-export const displayGroupMeta = (meta: GroupMeta) => meta?.name || meta?.identifier || "[no name]"
diff --git a/src/domain/index.ts b/src/domain/index.ts
index 77b293184..3cd8739d2 100644
--- a/src/domain/index.ts
+++ b/src/domain/index.ts
@@ -1,6 +1,5 @@
export * from "./collection"
export * from "./feed"
-export * from "./group"
export * from "./handler"
export * from "./kind"
export * from "./list"
diff --git a/src/engine/commands.ts b/src/engine/commands.ts
index 2b51e45d8..a7fa0bc77 100644
--- a/src/engine/commands.ts
+++ b/src/engine/commands.ts
@@ -1,97 +1,83 @@
-import crypto from "crypto"
-import {get} from "svelte/store"
+import type {Session} from "@welshman/app"
import {
- ctx,
+ follow as baseFollow,
+ unfollow as baseUnfollow,
+ ensurePlaintext,
+ getRelayUrls,
+ inboxRelaySelectionsByPubkey,
+ nip46Perms,
+ pubkey,
+ repository,
+ session,
+ sessions,
+ signer,
+ tagPubkey,
+ userInboxRelaySelections,
+ userRelaySelections,
+} from "@welshman/app"
+import {
+ append,
cached,
- indexBy,
- nthNe,
+ ctx,
equals,
- splitAt,
first,
+ groupBy,
+ indexBy,
last,
- append,
+ now,
nthEq,
- groupBy,
+ nthNe,
remove,
- now,
+ splitAt,
} from "@welshman/lib"
-import type {TrustedEvent, Profile} from "@welshman/util"
+import type {Nip46Handler} from "@welshman/signer"
+import {Nip01Signer, Nip46Broker, Nip59, makeSecret} from "@welshman/signer"
+import type {Profile, TrustedEvent} from "@welshman/util"
import {
- getAddress,
- Tags,
- createEvent,
Address,
- isSignedEvent,
- normalizeRelayUrl,
- GROUP,
- COMMUNITY,
+ DIRECT_MESSAGE,
FEEDS,
FOLLOWS,
- RELAYS,
- PROFILE,
INBOX_RELAYS,
- DIRECT_MESSAGE,
- SEEN_CONVERSATION,
LOCAL_RELAY_URL,
- makeList,
- editProfile,
+ PROFILE,
+ RELAYS,
+ SEEN_CONVERSATION,
+ Tags,
+ addToListPublicly,
+ createEvent,
createProfile,
+ editProfile,
+ getAddress,
isPublishedProfile,
+ isSignedEvent,
+ makeList,
+ normalizeRelayUrl,
removeFromList,
- addToListPublicly,
} from "@welshman/util"
-import type {Nip46Handler} from "@welshman/signer"
-import {Nip59, Nip01Signer, getPubkey, makeSecret, Nip46Broker} from "@welshman/signer"
-import {
- updateSession,
- repository,
- pubkey,
- nip46Perms,
- signer,
- sessions,
- session,
- getRelayUrls,
- displayProfileByPubkey,
- inboxRelaySelectionsByPubkey,
- addNoFallbacks,
- ensurePlaintext,
- tagPubkey,
- userRelaySelections,
- userInboxRelaySelections,
- follow as baseFollow,
- unfollow as baseUnfollow,
-} from "@welshman/app"
-import type {Session} from "@welshman/app"
-import {Fetch, randomId, seconds, sleep, tryFunc} from "hurdak"
-import {assoc, flatten, identity, omit, partition, prop, reject, uniq, without} from "ramda"
-import {stripExifData, blobToFile} from "src/util/html"
-import {joinPath, parseJson} from "src/util/misc"
-import {appDataKeys} from "src/util/nostr"
-import {GroupAccess} from "src/engine/model"
-import {sortEventsDesc} from "src/engine/utils"
+import crypto from "crypto"
+import {Fetch, seconds, sleep, tryFunc} from "hurdak"
+import {assoc, flatten, identity, omit, prop, reject, uniq, without} from "ramda"
import {
+ addClientTags,
+ anonymous,
channels,
- getChannelSeenKey,
createAndPublish,
- deriveAdminKeyForGroup,
- userIsGroupMember,
- deriveSharedKeyForGroup,
- env,
- addClientTags,
+ getChannelIdFromEvent,
+ getChannelSeenKey,
getClientTags,
- groupAdminKeys,
- groupSharedKeys,
- groups,
+ hasNip44,
publish,
sign,
- hasNip44,
- withIndexers,
- anonymous,
- mentionGroup,
- userSeenStatusEvents,
- getChannelIdFromEvent,
userFeedFavorites,
+ userSeenStatusEvents,
+ withIndexers,
} from "src/engine/state"
+import {sortEventsDesc} from "src/engine/utils"
+import {blobToFile, stripExifData} from "src/util/html"
+import {joinPath, parseJson} from "src/util/misc"
+import {appDataKeys} from "src/util/nostr"
+import {get} from "svelte/store"
// Helpers
@@ -215,360 +201,17 @@ export const uploadFiles = async (urls, files, compressorOpts = {}) => {
return eventsToMeta(nip94Events)
}
-// Groups
-
// Key state management
-export const initSharedKey = (address: string, relays: string[]) => {
- const privkey = makeSecret()
- const pubkey = getPubkey(privkey)
- const key = {
- group: address,
- pubkey: pubkey,
- privkey: privkey,
- created_at: now(),
- hints: relays,
- }
-
- groupSharedKeys.key(pubkey).set(key)
-
- return key
-}
-
-export const initGroup = (kind, relays) => {
- const identifier = randomId()
- const privkey = makeSecret()
- const pubkey = getPubkey(privkey)
- const address = `${kind}:${pubkey}:${identifier}`
- const sharedKey = kind === 35834 ? initSharedKey(address, relays) : null
- const adminKey = {
- group: address,
- pubkey: pubkey,
- privkey: privkey,
- created_at: now(),
- hints: relays,
- }
-
- groupAdminKeys.key(pubkey).set(adminKey)
-
- groups.key(address).set({id: identifier, pubkey, address})
-
- return {identifier, address, adminKey, sharedKey}
-}
-
-const addGroupATags = (template, addresses) => ({
- ...template,
- tags: [...template.tags, ...addresses.map(mentionGroup)],
-})
-
-// Utils for publishing group-related messages
-// Relay selections for groups should ignore platform relays, since groups provide their own
-// relays, and can straddle public/private contexts.
-
-export const publishToGroupAdmin = async (address, template) => {
- const relays = ctx.app.router.WithinContext(address).getUrls()
- const pubkeys = [Address.from(address).pubkey, session.get().pubkey]
- const expireTag = [["expiration", String(now() + seconds(30, "day"))]]
- const helper = Nip59.fromSigner(signer.get())
-
- for (const pubkey of pubkeys) {
- const rumor = await helper.wrap(pubkey, template, expireTag)
-
- await publish({event: rumor.wrap, relays, forcePlatform: false})
- }
-}
-
-export const publishAsGroupAdminPublicly = async (address, template, relays = []) => {
- const _relays = ctx.app.router
- .merge([ctx.app.router.fromRelays(relays), ctx.app.router.WithinContext(address)])
- .getUrls()
- const adminKey = deriveAdminKeyForGroup(address).get()
- const event = await sign(template, {sk: adminKey.privkey})
-
- return publish({event, relays: _relays, forcePlatform: false})
-}
-
-export const publishAsGroupAdminPrivately = async (address, template, relays = []) => {
- const _relays = ctx.app.router
- .merge([ctx.app.router.fromRelays(relays), ctx.app.router.WithinContext(address)])
- .getUrls()
- const adminKey = deriveAdminKeyForGroup(address).get()
- const sharedKey = deriveSharedKeyForGroup(address).get()
- const adminSigner = new Nip01Signer(adminKey.privkey)
- const sharedSigner = new Nip01Signer(sharedKey.privkey)
- const helper = Nip59.fromSigner(adminSigner).withWrapper(sharedSigner)
- const rumor = await helper.wrap(sharedKey.pubkey, template)
-
- return publish({event: rumor.wrap, relays: _relays, forcePlatform: false})
-}
-
-export const publishToGroupsPublicly = async (addresses, template, {anonymous = false} = {}) => {
- for (const address of addresses) {
- if (!address.startsWith("34550:")) {
- throw new Error(`Attempted to publish publicly to an invalid address: ${address}`)
- }
- }
-
- const event = await sign(addGroupATags(template, addresses), {anonymous})
+export const signAndPublish = async (template, {anonymous = false} = {}) => {
+ const event = await sign(template, {anonymous})
const relays = ctx.app.router.PublishEvent(event).getUrls()
- return publish({event, relays, forcePlatform: false})
-}
-
-export const publishToGroupsPrivately = async (addresses, template, {anonymous = false} = {}) => {
- const $userIsGroupMember = userIsGroupMember.get()
-
- const events = []
- const pubs = []
- for (const address of addresses) {
- const relays = ctx.app.router.WithinContext(address).getUrls()
- const thisTemplate = addGroupATags(template, [address])
- const sharedKey = deriveSharedKeyForGroup(address).get()
-
- if (!address.startsWith("35834:")) {
- throw new Error(`Attempted to publish privately to an invalid address: ${address}`)
- }
-
- if (!$userIsGroupMember(address)) {
- throw new Error("Attempted to publish privately to a group the user is not a member of")
- }
-
- const userSigner = anonymous ? signer.get() : Nip01Signer.ephemeral()
- const wrapSigner = new Nip01Signer(sharedKey.privkey)
- const helper = Nip59.fromSigner(userSigner).withWrapper(wrapSigner)
- const rumor = await helper.wrap(sharedKey.pubkey, thisTemplate)
-
- events.push(rumor)
- pubs.push(await publish({event: rumor.wrap, relays, forcePlatform: false}))
- }
-
- return {events, pubs}
-}
-
-export const publishToZeroOrMoreGroups = async (addresses, template, {anonymous = false} = {}) => {
- const pubs = []
- const events = []
-
- if (addresses.length === 0) {
- const event = await sign(template, {anonymous})
- const relays = ctx.app.router.PublishEvent(event).getUrls()
-
- events.push(event)
- pubs.push(await publish({event, relays}))
- } else {
- const [wrap, nowrap] = partition((address: string) => address.startsWith("35834:"), addresses)
-
- if (wrap.length > 0) {
- const result = await publishToGroupsPrivately(wrap, template, {anonymous})
-
- for (const event of result.events) {
- events.push(event)
- }
-
- for (const pub of result.pubs) {
- pubs.push(pub)
- }
- }
-
- if (nowrap.length > 0) {
- const pub = await publishToGroupsPublicly(nowrap, template, {anonymous})
-
- events.push(pub.request.event)
- pubs.push(pub)
- }
- }
-
- return {events, pubs}
-}
-
-// Admin functions
-
-export const publishKeyShares = async (address, pubkeys, template) => {
- const adminKey = deriveAdminKeyForGroup(address).get()
-
- const pubs = []
+ const pub = await publish({event, relays})
- for (const pubkey of pubkeys) {
- const relays = ctx.app.router
- .merge([
- ctx.app.router.ForPubkeys([pubkey]),
- ctx.app.router.WithinContext(address),
- ctx.app.router.fromRelays(env.PLATFORM_RELAYS),
- ])
- .policy(addNoFallbacks)
- .getUrls()
-
- const adminSigner = new Nip01Signer(adminKey.privkey)
- const helper = Nip59.fromSigner(adminSigner)
- const rumor = await helper.wrap(pubkey, template)
-
- pubs.push(await publish({event: rumor.wrap, relays, forcePlatform: false}))
- }
-
- return pubs
-}
-
-export const publishAdminKeyShares = async (address, pubkeys) => {
- const relays = ctx.app.router.WithinContext(address).getUrls()
- const {privkey} = deriveAdminKeyForGroup(address).get()
- const template = createEvent(24, {
- tags: [
- mentionGroup(address),
- ["role", "admin"],
- ["privkey", privkey],
- ...getClientTags(),
- ...relays.map(url => ["relay", url]),
- ],
- })
-
- return publishKeyShares(address, pubkeys, template)
-}
-
-export const publishGroupInvites = async (address, pubkeys, gracePeriod = 0) => {
- const relays = ctx.app.router.WithinContext(address).getUrls()
- const adminKey = deriveAdminKeyForGroup(address).get()
- const {privkey} = deriveSharedKeyForGroup(address).get()
- const template = createEvent(24, {
- tags: [
- mentionGroup(address),
- ["role", "member"],
- ["privkey", privkey],
- ["grace_period", String(gracePeriod)],
- ...getClientTags(),
- ...relays.map(url => ["relay", url]),
- ],
- })
-
- return publishKeyShares(address, [...pubkeys, adminKey.pubkey], template)
-}
-
-export const publishGroupEvictions = async (address, pubkeys) =>
- publishKeyShares(
- address,
- pubkeys,
- createEvent(24, {
- tags: [mentionGroup(address), ...getClientTags()],
- }),
- )
-
-export const publishGroupMembers = async (address, op, pubkeys) => {
- const template = createEvent(27, {
- tags: [["op", op], mentionGroup(address), ...getClientTags(), ...pubkeys.map(tagPubkey)],
- })
-
- return publishAsGroupAdminPrivately(address, template)
-}
-
-export const publishCommunityMeta = (address, identifier, meta) => {
- const template = createEvent(COMMUNITY, {
- tags: [
- ["d", identifier],
- ["name", meta.name],
- ["about", meta.about],
- ["description", meta.about],
- ["banner", meta.banner],
- ["picture", meta.image],
- ["image", meta.image],
- ...meta.feeds,
- ...meta.relays,
- ...meta.moderators,
- ...getClientTags(),
- ],
- })
-
- return publishAsGroupAdminPublicly(address, template, meta.relays)
-}
-
-export const publishGroupMeta = (address, identifier, meta, listPublicly) => {
- const template = createEvent(GROUP, {
- tags: [
- ["d", identifier],
- ["name", meta.name],
- ["about", meta.about],
- ["description", meta.about],
- ["banner", meta.banner],
- ["picture", meta.image],
- ["image", meta.image],
- ...meta.feeds,
- ...meta.relays,
- ...meta.moderators,
- ...getClientTags(),
- ],
- })
-
- return listPublicly
- ? publishAsGroupAdminPublicly(address, template, meta.relays)
- : publishAsGroupAdminPrivately(address, template, meta.relays)
+ return {event, pub}
}
-export const deleteGroupMeta = address =>
- publishAsGroupAdminPublicly(address, createEvent(5, {tags: [mentionGroup(address)]}))
-
-// Member functions
-
-export const modifyGroupStatus = (session, address, timestamp, updates) => {
- if (!session.groups) {
- session.groups = {}
- }
-
- const newGroupStatus = updateRecord(session.groups[address], timestamp, updates)
-
- if (!equals(session.groups[address], newGroupStatus)) {
- session.groups[address] = newGroupStatus
- }
-
- return session
-}
-
-export const setGroupStatus = (pubkey, address, timestamp, updates) =>
- updateSession(pubkey, s => modifyGroupStatus(s, address, timestamp, updates))
-
-export const resetGroupAccess = address =>
- setGroupStatus(pubkey.get(), address, now(), {access: GroupAccess.None})
-
-export const publishGroupEntryRequest = (address, claim = null) => {
- if (deriveAdminKeyForGroup(address).get()) {
- publishGroupInvites(address, [session.get().pubkey])
- } else {
- setGroupStatus(pubkey.get(), address, now(), {access: GroupAccess.Requested})
-
- const tags = [...getClientTags(), mentionGroup(address)]
-
- if (claim) {
- tags.push(["claim", claim])
- }
-
- publishToGroupAdmin(
- address,
- createEvent(25, {
- content: `${displayProfileByPubkey(pubkey.get())} would like to join the group`,
- tags,
- }),
- )
- }
-}
-
-export const publishGroupExitRequest = address => {
- setGroupStatus(pubkey.get(), address, now(), {access: GroupAccess.None})
-
- if (!deriveAdminKeyForGroup(address).get()) {
- publishToGroupAdmin(
- address,
- createEvent(26, {
- content: `${displayProfileByPubkey(pubkey.get())} is leaving the group`,
- tags: [...getClientTags(), mentionGroup(address)],
- }),
- )
- }
-}
-
-export const publishCommunitiesList = addresses =>
- createAndPublish({
- kind: 10004,
- tags: [...addresses.map(mentionGroup), ...getClientTags()],
- relays: ctx.app.router.WriteRelays().getUrls(),
- })
-
// Deletes
export const publishDeletion = ({kind, address = null, id = null}) => {
diff --git a/src/engine/model.ts b/src/engine/model.ts
index 6dcb7ebbf..06da2da1b 100644
--- a/src/engine/model.ts
+++ b/src/engine/model.ts
@@ -1,46 +1,6 @@
+import type {Session} from "@welshman/app"
import type {Publish} from "@welshman/net"
import type {TrustedEvent, Zapper as WelshmanZapper} from "@welshman/util"
-import type {Session} from "@welshman/app"
-import {isTrustedEvent} from "@welshman/util"
-
-export enum GroupAccess {
- None = null,
- Requested = "requested",
- Granted = "granted",
- Revoked = "revoked",
-}
-
-export type Group = {
- id: string
- pubkey: string
- address: string
- members?: string[]
- recent_member_updates?: TrustedEvent[]
-}
-
-export type GroupKey = {
- group: string
- pubkey: string
- privkey: string
- created_at: number
- hints?: string[]
-}
-
-export type GroupRequest = TrustedEvent & {
- group: string
- resolved: boolean
-}
-
-export const isGroupRequest = (e: any): e is GroupRequest =>
- typeof e.group === "string" && typeof e.resolved === "boolean" && isTrustedEvent(e)
-
-export type GroupAlert = TrustedEvent & {
- group: string
- type: "exit" | "invite"
-}
-
-export const isGroupAlert = (e: any): e is GroupAlert =>
- typeof e.group === "string" && typeof e.type === "string" && isTrustedEvent(e)
export type DisplayEvent = TrustedEvent & {
replies?: DisplayEvent[]
@@ -80,15 +40,7 @@ export type Channel = {
messages: TrustedEvent[]
}
-export type GroupStatus = {
- joined: boolean
- joined_updated_at: number
- access: GroupAccess
- access_updated_at: number
-}
-
export type SessionWithMeta = Session & {
- groups?: Record
onboarding_tasks_completed?: string[]
}
diff --git a/src/engine/projections.ts b/src/engine/projections.ts
index 4ce18bef1..8ee94dc04 100644
--- a/src/engine/projections.ts
+++ b/src/engine/projections.ts
@@ -1,175 +1,24 @@
-import {mergeRight, prop, sortBy, uniq, whereEq, without} from "ramda"
-import {switcherFn} from "hurdak"
-import {ctx} from "@welshman/lib"
+import {ensurePlaintext, repository} from "@welshman/app"
import type {TrustedEvent} from "@welshman/util"
import {
- Tags,
- getIdFilters,
- MUTES,
APP_DATA,
+ FOLLOWS,
+ MUTES,
+ SEEN_CONTEXT,
SEEN_CONVERSATION,
SEEN_GENERAL,
- SEEN_CONTEXT,
- FOLLOWS,
- COMMUNITIES,
- WRAP,
} from "@welshman/util"
-import {getPubkey} from "@welshman/signer"
-import {repository, putSession, getSession, ensurePlaintext} from "@welshman/app"
-import {GroupAccess, type SessionWithMeta} from "src/engine/model"
-import {
- deriveAdminKeyForGroup,
- getGroupStatus,
- groupAdminKeys,
- groupAlerts,
- groupRequests,
- groupSharedKeys,
- groups,
- load,
- projections,
-} from "src/engine/state"
-import {modifyGroupStatus, setGroupStatus} from "src/engine/commands"
+import {projections} from "src/engine/state"
// Synchronize repository with projections. All events should be published to the
// repository, and when accepted, be propagated to projections. This avoids processing
// the same event multiple times, since repository deduplicates
-
repository.on("update", ({added}: {added: TrustedEvent[]}) => {
for (const event of added) {
projections.push(event)
}
})
-// Key sharing
-
-projections.addHandler(24, (e: TrustedEvent) => {
- const tags = Tags.fromEvent(e)
- const privkey = tags.get("privkey")?.value()
- const address = tags.get("a")?.value()
- const recipient = Tags.fromEvent(e.wrap).get("p")?.value()
- const relays = tags.values("relay").valueOf()
-
- if (!address) {
- return
- }
-
- const status = getGroupStatus(getSession(recipient), address)
-
- if (privkey) {
- const pubkey = getPubkey(privkey)
- const role = tags.get("role")?.value()
- const keys = role === "admin" ? groupAdminKeys : groupSharedKeys
-
- keys.key(pubkey).update($key => ({
- pubkey,
- privkey,
- group: address,
- created_at: e.created_at,
- hints: relays,
- ...$key,
- }))
-
- // Notify the user if this isn't just a key rotation
- if (status?.access !== GroupAccess.Granted) {
- groupAlerts.key(e.id).set({...e, group: address, type: "invite"})
- }
-
- // Load the group's metadata and posts
- load({
- delay: 5000,
- skipCache: true,
- relays: ctx.app.router.fromRelays(relays).getUrls(),
- filters: [
- ...getIdFilters([address]),
- {kinds: [WRAP], "#p": [pubkey]},
- {kinds: [WRAP], authors: [pubkey]},
- ],
- })
- } else if ([GroupAccess.Granted, GroupAccess.Requested].includes(status?.access)) {
- groupAlerts.key(e.id).set({...e, group: address, type: "exit"})
- }
-
- if (getSession(recipient)) {
- setGroupStatus(recipient, address, e.created_at, {
- access: privkey ? GroupAccess.Granted : GroupAccess.Revoked,
- })
- }
-})
-
-projections.addHandler(27, (e: TrustedEvent) => {
- const address = Tags.fromEvent(e).groups().values().first()
-
- if (!address) {
- return
- }
-
- let {members = [], recent_member_updates = []} = groups.key(address).get() || {}
-
- // Only replay updates if we have something new
- if (!recent_member_updates.find(whereEq({id: e.id}))) {
- recent_member_updates = sortBy(prop("created_at"), recent_member_updates.concat(e)).slice(-100)
-
- for (const event of recent_member_updates) {
- const tags = Tags.fromEvent(event)
- const op = tags.get("op")?.value()
- const pubkeys = tags.values("p").valueOf()
-
- members = switcherFn(op, {
- add: () => uniq(pubkeys.concat(members)),
- remove: () => without(pubkeys, members),
- set: () => pubkeys,
- default: () => members,
- })
- }
-
- groups.key(address).merge({members, recent_member_updates})
- }
-})
-
-// Membership
-
-projections.addHandler(COMMUNITIES, (e: TrustedEvent) => {
- let session = getSession(e.pubkey) as SessionWithMeta
-
- if (!session) {
- return
- }
-
- const addresses = Tags.fromEvent(e).communities().values().valueOf()
-
- for (const address of uniq(Object.keys(session.groups || {}).concat(addresses))) {
- session = modifyGroupStatus(session, address, e.created_at, {
- joined: addresses.includes(address),
- })
- }
-
- putSession(session)
-})
-
-const handleGroupRequest = access => (e: TrustedEvent) => {
- const address = Tags.fromEvent(e).get("a")?.value()
- const adminKey = deriveAdminKeyForGroup(address)
-
- // Don't bother the admin with old requests
- if (adminKey.get() && e.created_at) {
- groupRequests.key(e.id).update(
- mergeRight({
- ...e,
- group: address,
- resolved: false,
- }),
- )
- }
-
- if (getSession(e.pubkey)) {
- setGroupStatus(e.pubkey, address, e.created_at, {access})
- }
-}
-
-projections.addHandler(25, handleGroupRequest(GroupAccess.Requested))
-
-projections.addHandler(26, handleGroupRequest(GroupAccess.None))
-
// Decrypt encrypted events eagerly
projections.addHandler(SEEN_GENERAL, ensurePlaintext)
diff --git a/src/engine/requests.ts b/src/engine/requests.ts
index 45a472589..3955d8412 100644
--- a/src/engine/requests.ts
+++ b/src/engine/requests.ts
@@ -151,24 +151,6 @@ export const getStaleAddrs = (addrs: string[]) => {
return Array.from(stale)
}
-export const loadGroups = async (rawAddrs: string[], explicitRelays: string[] = []) => {
- const addrs = getStaleAddrs(rawAddrs)
- const authors = addrs.map(a => Address.from(a).pubkey)
- const identifiers = addrs.map(a => Address.from(a).identifier)
-
- if (addrs.length > 0) {
- const filters = [{kinds: [34550, 35834], authors, "#d": identifiers}]
- const relays = ctx.app.router
- .merge([
- ctx.app.router.product(addrs, explicitRelays),
- ctx.app.router.WithinMultipleContexts(addrs),
- ])
- .getUrls()
-
- return load({relays, filters, skipCache: true, forcePlatform: false})
- }
-}
-
export const loadGroupMessages = async (addrs: string[]) => {
for (const address of addrs) {
const keys = [...groupAdminKeys.get(), ...groupSharedKeys.get()]
diff --git a/src/engine/state.ts b/src/engine/state.ts
index eb47272ff..e7eea901e 100644
--- a/src/engine/state.ts
+++ b/src/engine/state.ts
@@ -1,157 +1,126 @@
-import Fuse from "fuse.js"
-import crypto from "crypto"
-import {get, derived, writable} from "svelte/store"
-import {doPipe, batch, seconds, sleep} from "hurdak"
-import {defaultTo, equals, assoc, sortBy, omit, partition, prop, whereEq, without} from "ramda"
+import type {PartialSubscribeRequest} from "@welshman/app"
+import {
+ subscribe as baseSubscribe,
+ db,
+ displayProfileByPubkey,
+ ensurePlaintext,
+ followsByPubkey,
+ freshness,
+ getDefaultAppContext,
+ getDefaultNetContext,
+ getNetwork,
+ getPlaintext,
+ getSession,
+ getSigner,
+ getUserWotScore,
+ handles,
+ initStorage,
+ loadRelay,
+ makeRouter,
+ maxWot,
+ mutesByPubkey,
+ plaintext,
+ pubkey,
+ relay,
+ relays,
+ repository,
+ session,
+ sessions,
+ setPlaintext,
+ signer,
+ storageAdapters,
+ tagPubkey,
+ tracker,
+ zappers,
+} from "@welshman/app"
+import * as Content from "@welshman/content"
import {
- ctx,
- setContext,
Worker,
- simpleCache,
- identity,
- last,
- nth,
- uniq,
- uniqBy,
- now,
- intersection,
- sort,
+ ctx,
groupBy,
+ identity,
indexBy,
+ now,
pushToMapKey,
- tryCatch,
+ setContext,
+ simpleCache,
+ sort,
take,
+ tryCatch,
+ uniq,
+ uniqBy,
} from "@welshman/lib"
+import type {PublishRequest} from "@welshman/net"
+import {Executor, Local, Multi, Plex, Relays, publish as basePublish} from "@welshman/net"
+import {Nip01Signer, Nip59} from "@welshman/signer"
+import {deriveEvents, deriveEventsMapped, throttled, withGetter} from "@welshman/store"
+import type {
+ EventTemplate,
+ Filter,
+ PublishedList,
+ SignedEvent,
+ StampedEvent,
+ TrustedEvent,
+} from "@welshman/util"
import {
- CLIENT_AUTH,
APP_DATA,
+ CLIENT_AUTH,
COMMUNITIES,
- COMMUNITY,
+ DIRECT_MESSAGE,
FEED,
FEEDS,
FOLLOWS,
- GROUP,
HANDLER_INFORMATION,
HANDLER_RECOMMENDATION,
LABEL,
+ LOCAL_RELAY_URL,
+ NAMED_BOOKMARKS,
SEEN_CONTEXT,
SEEN_CONVERSATION,
SEEN_GENERAL,
- DIRECT_MESSAGE,
- NAMED_BOOKMARKS,
- WRAP,
- Address,
Tags,
+ WRAP,
+ asDecryptedEvent,
createEvent,
getAddress,
- getIdentifier,
+ getAddressTagValues,
+ getAncestorTagValues,
getIdAndAddress,
- getIdOrAddress,
getIdFilters,
- LOCAL_RELAY_URL,
- isGroupAddress,
- isCommunityAddress,
- isHashedEvent,
- getPubkeyTagValues,
+ getIdOrAddress,
+ getIdentifier,
getListTags,
+ getPubkeyTagValues,
getTagValues,
- normalizeRelayUrl,
- isContextAddress,
- getContextTagValues,
- getAddressTagValues,
- getAncestorTagValues,
- getAddressTags,
+ isHashedEvent,
makeList,
+ normalizeRelayUrl,
readList,
- asDecryptedEvent,
} from "@welshman/util"
-import type {
- Filter,
- TrustedEvent,
- SignedEvent,
- EventTemplate,
- PublishedList,
- StampedEvent,
-} from "@welshman/util"
-import {Nip59, Nip01Signer} from "@welshman/signer"
-import {Executor, Multi, Plex, Local, Relays, publish as basePublish} from "@welshman/net"
-import type {PartialSubscribeRequest} from "@welshman/app"
-import type {PublishRequest} from "@welshman/net"
-import * as Content from "@welshman/content"
-import {withGetter, deriveEvents, deriveEventsMapped, throttled} from "@welshman/store"
-import {
- session,
- getSession,
- getSigner,
- signer,
- repository,
- relay,
- tracker,
- pubkey,
- handles,
- displayProfileByPubkey,
- mutesByPubkey,
- followsByPubkey,
- makeRouter,
- subscribe as baseSubscribe,
- storageAdapters,
- freshness,
- zappers,
- relays,
- initStorage,
- db,
- plaintext,
- getPlaintext,
- setPlaintext,
- ensurePlaintext,
- getDefaultNetContext,
- getDefaultAppContext,
- loadRelay,
- tagPubkey,
- getNetwork,
- getUserWotScore,
- sessions,
- maxWot,
- repositoryStore,
-} from "@welshman/app"
-import {parseJson, fromCsv, SearchHelper} from "src/util/misc"
-import {Collection as CollectionStore} from "src/util/store"
-import {isLike, repostKinds, noteKinds, reactionKinds, metaKinds, appDataKeys} from "src/util/nostr"
-import logger from "src/util/logger"
-import type {
- GroupMeta,
- PublishedFeed,
- PublishedListFeed,
- PublishedUserList,
- PublishedGroupMeta,
-} from "src/domain"
+import crypto from "crypto"
+import Fuse from "fuse.js"
+import {batch, doPipe, seconds, sleep} from "hurdak"
+import {assoc, equals, omit, partition, prop, sortBy, without} from "ramda"
+import type {PublishedFeed, PublishedListFeed, PublishedUserList} from "src/domain"
import {
- displayFeed,
+ CollectionSearch,
EDITABLE_LIST_KINDS,
UserListSearch,
- readFeed,
- readUserList,
+ displayFeed,
+ getHandlerAddress,
+ mapListToFeed,
readCollections,
- CollectionSearch,
+ readFeed,
readHandlers,
- mapListToFeed,
- getHandlerAddress,
- readGroupMeta,
- displayGroupMeta,
+ readUserList,
} from "src/domain"
-import type {
- Channel,
- Group,
- GroupAlert,
- GroupKey,
- GroupRequest,
- GroupStatus,
- PublishInfo,
- SessionWithMeta,
- AnonymousUserState,
-} from "src/engine/model"
-import {sortEventsAsc, unwrapRepost} from "src/engine/utils"
-import {GroupAccess, OnboardingTask} from "src/engine/model"
+import type {AnonymousUserState, Channel, PublishInfo, SessionWithMeta} from "src/engine/model"
+import {OnboardingTask} from "src/engine/model"
+import {sortEventsAsc} from "src/engine/utils"
+import logger from "src/util/logger"
+import {SearchHelper, fromCsv, parseJson} from "src/util/misc"
+import {appDataKeys, isLike, metaKinds, noteKinds, reactionKinds, repostKinds} from "src/util/nostr"
+import {derived, get, writable} from "svelte/store"
export const env = {
CLIENT_ID: import.meta.env.VITE_CLIENT_ID as string,
@@ -185,12 +154,6 @@ export const anonymous = withGetter(writable({follows: [], r
export const groupHints = withGetter(writable>({}))
export const publishes = withGetter(writable>({}))
-export const groups = new CollectionStore("address")
-export const groupAdminKeys = new CollectionStore("pubkey")
-export const groupSharedKeys = new CollectionStore("pubkey")
-export const groupRequests = new CollectionStore("id")
-export const groupAlerts = new CollectionStore("id")
-
export const projections = new Worker({
getKey: prop("kind"),
})
@@ -218,8 +181,7 @@ export const ensureMessagePlaintext = async (e: TrustedEvent) => {
}
export const canUnwrap = (event: TrustedEvent) =>
- event.kind === WRAP &&
- (getSession(Tags.fromEvent(event).get("p")?.value()) || getRecipientKey(event))
+ event.kind === WRAP && getSession(Tags.fromEvent(event).get("p")?.value())
export const ensureUnwrapped = async (event: TrustedEvent) => {
if (event.kind !== WRAP) {
@@ -244,17 +206,6 @@ export const ensureUnwrapped = async (event: TrustedEvent) => {
}
}
- // Decrypt by group key
- const secret = getRecipientKey(event)
-
- if (secret) {
- try {
- rumor = await Nip59.fromSecret(secret).unwrap(event as SignedEvent)
- } catch (e) {
- // pass
- }
- }
-
if (rumor && isHashedEvent(rumor)) {
tracker.copy(event.id, rumor.id)
relay.send("EVENT", rumor)
@@ -370,18 +321,6 @@ export const communityListsByPubkey = withGetter(
derived(communityLists, $ls => indexBy($l => $l.event.pubkey, $ls)),
)
-export const communityListsByAddress = derived(communityLists, $communityLists => {
- const m = new Map()
-
- for (const list of $communityLists) {
- for (const a of getAddressTagValues(getListTags(list))) {
- pushToMapKey(m, a, list)
- }
- }
-
- return m
-})
-
export const getCommunityList = (pk: string) =>
communityListsByPubkey.get().get(pk) as PublishedList | undefined
@@ -394,157 +333,10 @@ export const getCommunities = (pk: string) =>
export const deriveCommunities = (pk: string) =>
derived(communityListsByPubkey, m => new Set(getAddressTagValues(getListTags(m.get(pk)))))
-// Groups
-
-export const groupMeta = deriveEventsMapped(repository, {
- filters: [{kinds: [GROUP, COMMUNITY]}],
- itemToEvent: prop("event"),
- eventToItem: readGroupMeta,
-})
-
-export const groupMetaByAddress = withGetter(
- derived(groupMeta, $metas => indexBy($meta => getAddress($meta.event), $metas)),
-)
-
-export const deriveGroupMeta = (address: string) =>
- derived(groupMetaByAddress, $m => $m.get(address))
-
-export const displayGroupByAddress = a => displayGroupMeta(groupMetaByAddress.get().get(a))
-
-export class GroupSearch extends SearchHelper {
- config = {
- keys: [{name: "identifier", weight: 0.2}, "name", {name: "about", weight: 0.5}],
- threshold: 0.3,
- shouldSort: false,
- includeScore: true,
- }
-
- getSearch = () => {
- const fuse = new Fuse(this.options, this.config)
- const sortFn = (r: any) => r.score - Math.pow(Math.max(0, r.item.score), 1 / 100)
-
- return (term: string) =>
- term
- ? sortBy(sortFn, fuse.search(term)).map((r: any) => r.item)
- : sortBy(meta => -meta.score, this.options)
- }
-
- getValue = (option: GroupMeta) => getAddress(option.event)
-
- displayValue = displayGroupByAddress
-}
-
-export const groupMetaSearch = derived(
- [groupMeta, communityListsByAddress, userFollows],
- ([$groupMeta, $communityListsByAddress, $userFollows]) => {
- const options = $groupMeta.map(meta => {
- const lists = $communityListsByAddress.get(getAddress(meta.event)) || []
- const members = lists.map(l => l.event.pubkey)
- const followedMembers = intersection(members, Array.from($userFollows))
-
- return {...meta, score: followedMembers.length}
- })
-
- return new GroupSearch(options)
- },
-)
-
-// Legacy
-export const deriveGroup = address => {
- const {pubkey, identifier: id} = Address.from(address)
-
- return groups.key(address).derived(defaultTo({id, pubkey, address}))
-}
-
-export const getRecipientKey = wrap => {
- const pubkey = Tags.fromEvent(wrap).values("p").first()
- const sharedKey = groupSharedKeys.key(pubkey).get()
-
- if (sharedKey) {
- return sharedKey.privkey
- }
-
- const adminKey = groupAdminKeys.key(pubkey).get()
-
- if (adminKey) {
- return adminKey.privkey
- }
-
- return null
-}
-
-export const deriveSharedKeyForGroup = (address: string) =>
- groupSharedKeys.derived($keys =>
- last(sortBy(prop("created_at"), $keys.filter(whereEq({group: address})))),
- )
-
-export const deriveAdminKeyForGroup = (address: string) => groupAdminKeys.key(address.split(":")[1])
-
-export const getGroupStatus = (sessionWithMeta: SessionWithMeta, address: string) =>
- (sessionWithMeta?.groups?.[address] || {}) as GroupStatus
-
-export const deriveGroupStatus = address =>
- derived(sessionWithMeta, $sessionWithMeta => getGroupStatus($sessionWithMeta, address))
-
-export const userIsGroupMember = withGetter(
- derived(sessionWithMeta, $sessionWithMeta => (address, includeRequests = false) => {
- const status = getGroupStatus($sessionWithMeta, address)
-
- if (isCommunityAddress(address)) {
- return status.joined
- }
-
- if (isGroupAddress(address)) {
- if (includeRequests && status.access === GroupAccess.Requested) {
- return true
- }
-
- return status.access === GroupAccess.Granted
- }
-
- return false
- }),
-)
-
-export const deriveGroupOptions = (defaultGroups = []) =>
- derived([sessionWithMeta, userIsGroupMember], ([$sessionWithMeta, $userIsGroupMember]) => {
- const options = []
-
- for (const address of Object.keys($sessionWithMeta?.groups || {})) {
- const group = groups.key(address).get()
-
- if (group && $userIsGroupMember(address)) {
- options.push(group)
- }
- }
-
- for (const address of defaultGroups) {
- options.push({address})
- }
-
- return uniqBy(prop("address"), options)
- })
-
-export const getUserCircles = (sessionWithMeta: SessionWithMeta) => {
- const $userIsGroupMember = userIsGroupMember.get()
-
- return Object.entries(sessionWithMeta?.groups || {})
- .filter(([a, s]) => !repository.deletes.has(a) && $userIsGroupMember(a))
- .map(([a, s]) => a)
-}
-
-export const getUserGroups = (sessionWithMeta: SessionWithMeta) =>
- getUserCircles(sessionWithMeta).filter(isGroupAddress)
-
-export const getUserCommunities = (sessionWithMeta: SessionWithMeta) =>
- getUserCircles(sessionWithMeta).filter(isCommunityAddress)
-
-// Events
-
export const isEventMuted = withGetter(
derived(
- [userMutes, userFollows, userSettings, pubkey, userIsGroupMember],
- ([$userMutes, $userFollows, $userSettings, $pubkey, $userIsGroupMember]) => {
+ [userMutes, userFollows, userSettings, pubkey],
+ ([$userMutes, $userFollows, $userSettings, $pubkey]) => {
const words = $userSettings.muted_words
const minWot = $userSettings.min_wot_score
const regex =
@@ -566,11 +358,9 @@ export const isEventMuted = withGetter(
if (strict || $userFollows.has(e.pubkey)) return false
- const addresses = getAddressTagValues(e.tags || []).filter(isContextAddress)
- const wotAdjustment = addresses.some(a => $userIsGroupMember(a)) ? 1 : 0
const wotScore = getUserWotScore(e.pubkey)
- return wotScore < minWot - wotAdjustment
+ return wotScore < minWot
}
},
),
@@ -747,26 +537,6 @@ export const channelHasNewMessages = (channel: Channel) =>
export const hasNewMessages = derived(channels, $channels => $channels.some(channelHasNewMessages))
-// Relay selection
-
-export const getGroupRelayUrls = address => {
- const meta = groupMetaByAddress.get().get(address)
-
- if (meta?.relays) {
- return meta.relays.map(nth(1))
- }
-
- const latestKey = last(
- sortBy(prop("created_at"), get(groupSharedKeys).filter(whereEq({group: address}))),
- )
-
- if (latestKey?.hints) {
- return latestKey.hints
- }
-
- return get(groupHints)[address] || []
-}
-
export const forceRelays = (relays: string[], forceRelays: string[]) =>
forceRelays.length > 0 ? forceRelays : relays
diff --git a/src/util/store.ts b/src/util/store.ts
index 5f13e616f..36bb9a324 100644
--- a/src/util/store.ts
+++ b/src/util/store.ts
@@ -223,34 +223,6 @@ export class Key implements IReadable {
}
}
-export class DerivedKey implements IReadable {
- readonly pk: string
- readonly key: string
- base: IReadable>
- store: IReadable
-
- constructor(base: IReadable>, pk: string, key: string) {
- if (!(base.get() instanceof Map)) {
- throw new Error("`key` can only be used on map collections")
- }
-
- this.pk = pk
- this.key = key
- this.base = base
- this.store = base.derived(m => m.get(key) as T)
- }
-
- get = () => this.base.get().get(this.key) as T
-
- subscribe = (f: Subscriber) => this.store.subscribe(f)
-
- derived = (f: (v: T) => U) => this.store.derived(f)
-
- throttle = (t: number) => this.store.throttle(t)
-
- exists = () => this.base.get().has(this.key)
-}
-
export class Collection implements IReadable {
readonly pk: string
readonly mapStore: Writable>
From 344b07d5efbb14240422f8cd6c0fabfb3799eb2e Mon Sep 17 00:00:00 2001
From: Ticruz
Date: Mon, 4 Nov 2024 15:34:55 +0100
Subject: [PATCH 02/13] remove groupsummary too
---
src/app/shared/NoteActions.svelte | 1 -
src/app/shared/NoteContent.svelte | 6 ---
src/app/shared/NoteContentKind34550.svelte | 8 ----
src/app/shared/NoteContentKind35834.svelte | 8 ----
src/app/shared/NoteMeta.svelte | 50 ++++------------------
5 files changed, 9 insertions(+), 64 deletions(-)
delete mode 100644 src/app/shared/NoteContentKind34550.svelte
delete mode 100644 src/app/shared/NoteContentKind35834.svelte
diff --git a/src/app/shared/NoteActions.svelte b/src/app/shared/NoteActions.svelte
index 71c5a6fed..3b7161f8b 100644
--- a/src/app/shared/NoteActions.svelte
+++ b/src/app/shared/NoteActions.svelte
@@ -49,7 +49,6 @@
import PersonBadge from "src/app/shared/PersonBadge.svelte"
import HandlerCard from "src/app/shared/HandlerCard.svelte"
import RelayCard from "src/app/shared/RelayCard.svelte"
- import GroupSummary from "src/app/shared/GroupSummary.svelte"
import {router} from "src/app/util/router"
import {
env,
diff --git a/src/app/shared/NoteContent.svelte b/src/app/shared/NoteContent.svelte
index 3ddabdd63..eea2a77e6 100644
--- a/src/app/shared/NoteContent.svelte
+++ b/src/app/shared/NoteContent.svelte
@@ -20,8 +20,6 @@
import NoteContentKind31890 from "src/app/shared/NoteContentKind31890.svelte"
import NoteContentKind31923 from "src/app/shared/NoteContentKind31923.svelte"
import NoteContentKind32123 from "src/app/shared/NoteContentKind32123.svelte"
- import NoteContentKind34550 from "src/app/shared/NoteContentKind34550.svelte"
- import NoteContentKind35834 from "src/app/shared/NoteContentKind35834.svelte"
import NoteContentKindList from "src/app/shared/NoteContentKindList.svelte"
import {getSetting, env} from "src/engine"
import {CUSTOM_LIST_KINDS} from "src/domain"
@@ -84,10 +82,6 @@
{:else if note.kind === 32123}
- {:else if note.kind === 34550}
-
- {:else if note.kind === 35834}
-
{:else if CUSTOM_LIST_KINDS.includes(note.kind)}
{:else}
diff --git a/src/app/shared/NoteContentKind34550.svelte b/src/app/shared/NoteContentKind34550.svelte
deleted file mode 100644
index bb92a2d14..000000000
--- a/src/app/shared/NoteContentKind34550.svelte
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
diff --git a/src/app/shared/NoteContentKind35834.svelte b/src/app/shared/NoteContentKind35834.svelte
deleted file mode 100644
index bb92a2d14..000000000
--- a/src/app/shared/NoteContentKind35834.svelte
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
diff --git a/src/app/shared/NoteMeta.svelte b/src/app/shared/NoteMeta.svelte
index 69b7d44df..9a1179e4a 100644
--- a/src/app/shared/NoteMeta.svelte
+++ b/src/app/shared/NoteMeta.svelte
@@ -1,52 +1,20 @@
-{#if repostPubkeys.length > 0}
-
-
- {#if showGroup}
- Cross-posted
- {:else}
- Reposted
- {/if}
- {#if showGroup}
- {#if fromAddresses.length === 1}
- from
- {:else if fromAddresses.length > 1}
- from {fromAddresses.length} groups
- {/if}
- {#if toAddresses.length === 1}
- to
- {:else if toAddresses.length > 1}
- to {toAddresses.length} groups
- {/if}
- {/if}
- by
- {#if repostPubkeys.length === 1}
-
- {:else}
- {repostPubkeys.length} people
- {/if}
-
-{:else if fromAddresses.length > 0 && showGroup}
-
- {#if fromAddresses.length === 1}
- Posted in
- {:else if fromAddresses.length > 1}
- Posted in {fromAddresses.length} groups
- {/if}
-
-{/if}
+
+
+ Reposted by
+ {#if repostPubkeys.length === 1}
+
+ {:else}
+ {repostPubkeys.length} people
+ {/if}
+
From 807505924ec4bd533fa4326f6a5424823f520b32 Mon Sep 17 00:00:00 2001
From: Ticruz
Date: Mon, 4 Nov 2024 16:09:19 +0100
Subject: [PATCH 03/13] removing all groups leftovers
---
src/app/shared/FeedFormFilters.svelte | 14 ++-------
src/app/shared/FeedFormSectionContext.svelte | 28 -----------------
src/app/shared/NoteActions.svelte | 3 +-
src/app/state.ts | 4 ---
src/app/views/Calendar.svelte | 6 +---
src/app/views/Feeds.svelte | 6 +---
src/app/views/Notifications.svelte | 3 --
src/engine/requests.ts | 33 --------------------
src/engine/state.ts | 5 ---
9 files changed, 6 insertions(+), 96 deletions(-)
delete mode 100644 src/app/shared/FeedFormSectionContext.svelte
diff --git a/src/app/shared/FeedFormFilters.svelte b/src/app/shared/FeedFormFilters.svelte
index 310873cca..a7cb36db5 100644
--- a/src/app/shared/FeedFormFilters.svelte
+++ b/src/app/shared/FeedFormFilters.svelte
@@ -27,14 +27,13 @@
import FeedFormSectionPeople from "src/app/shared/FeedFormSectionPeople.svelte"
import FeedFormSectionRelays from "src/app/shared/FeedFormSectionRelays.svelte"
import FeedFormSectionTopics from "src/app/shared/FeedFormSectionTopics.svelte"
- import FeedFormSectionContext from "src/app/shared/FeedFormSectionContext.svelte"
import FeedFormSectionMentions from "src/app/shared/FeedFormSectionMentions.svelte"
import FeedFormSectionKinds from "src/app/shared/FeedFormSectionKinds.svelte"
import FeedFormSectionCreatedAt from "src/app/shared/FeedFormSectionCreatedAt.svelte"
import FeedFormSectionList from "src/app/shared/FeedFormSectionList.svelte"
import FeedFormSectionDVM from "src/app/shared/FeedFormSectionDVM.svelte"
import FeedFormSaveAsList from "src/app/shared/FeedFormSaveAsList.svelte"
- import {isTopicFeed, isPeopleFeed, isMentionFeed, isContextFeed} from "src/domain"
+ import {isTopicFeed, isPeopleFeed, isMentionFeed} from "src/domain"
export let feed
export let onChange
@@ -58,7 +57,6 @@
$: subFeeds = getFeedArgs(feed)
$: hasTopics = subFeeds.some(isTopicFeed)
$: hasMentions = subFeeds.some(isMentionFeed)
- $: hasContext = subFeeds.some(isContextFeed)
$: hasPeople = subFeeds.some(isPeopleFeed)
$: hasRelays = subFeeds.some(isRelayFeed)
$: hasKinds = subFeeds.some(isKindFeed)
@@ -75,8 +73,7 @@
isAuthorFeed(subFeed) ||
isRelayFeed(subFeed) ||
isTopicFeed(subFeed) ||
- isMentionFeed(subFeed) ||
- isContextFeed(subFeed)}
+ isMentionFeed(subFeed)}
{#if canSave || !isGlobalFeed(subFeed)}
@@ -89,8 +86,6 @@
{:else if isMentionFeed(subFeed)}
- {:else if isContextFeed(subFeed)}
-
{:else if isKindFeed(subFeed)}
{:else if isCreatedAtFeed(subFeed)}
@@ -120,7 +115,7 @@
{/each}
{/key}
-{#if !hasTopics || !hasMentions || !hasContext || !hasPeople || !hasRelays || !hasKinds || !hasCreatedAt || !hasDVM || !hasList}
+{#if !hasTopics || !hasMentions || !hasPeople || !hasRelays || !hasKinds || !hasCreatedAt || !hasDVM || !hasList}
{#if menuIsOpen}
@@ -131,9 +126,6 @@
{#if !hasMentions}
addFeed(makeTagFeed("#p"))}>Mentions
{/if}
- {#if !hasContext}
- addFeed(makeTagFeed("#a"))}>Groups
- {/if}
{#if !hasPeople}
addFeed(makeAuthorFeed())}>Authors
{/if}
diff --git a/src/app/shared/FeedFormSectionContext.svelte b/src/app/shared/FeedFormSectionContext.svelte
deleted file mode 100644
index 5a0424c10..000000000
--- a/src/app/shared/FeedFormSectionContext.svelte
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-Which groups would you like to see?
- onChange([FeedType.Tag, "#a", ...addresses])}>
-
- {#if context === "value"}
-
- {$groupMetaSearch.displayValue(item)}
-
- {:else}
-
- {/if}
-
-
diff --git a/src/app/shared/NoteActions.svelte b/src/app/shared/NoteActions.svelte
index 3b7161f8b..66c912d4b 100644
--- a/src/app/shared/NoteActions.svelte
+++ b/src/app/shared/NoteActions.svelte
@@ -54,7 +54,6 @@
env,
publish,
deriveHandlersForKind,
- groupMeta,
signAndPublish,
deleteEvent,
getSetting,
@@ -222,7 +221,7 @@
if ($signer) {
actions.push({label: "Quote", icon: "quote-left", onClick: quote})
- if (isSignedEvent(note) && !env.FORCE_GROUP && ($groupOptions.length > 0 || address)) {
+ if (isSignedEvent(note)) {
actions.push({label: "Cross-post", icon: "shuffle", onClick: () => setView("cross-post")})
}
diff --git a/src/app/state.ts b/src/app/state.ts
index 52f4bc962..44a0de590 100644
--- a/src/app/state.ts
+++ b/src/app/state.ts
@@ -20,7 +20,6 @@ import {
load,
loadPubkeys,
loadSeen,
- loadGroups,
loadDeletes,
loadHandlers,
loadMessages,
@@ -51,9 +50,6 @@ export const slowConnections = writable([])
export const loadAppData = () => {
// If we have a group, load that
- if (env.FORCE_GROUP) {
- loadGroups([env.FORCE_GROUP])
- }
}
export const loadUserData = async (hints: string[] = []) => {
diff --git a/src/app/views/Calendar.svelte b/src/app/views/Calendar.svelte
index 2d1caeae5..5cdc12a90 100644
--- a/src/app/views/Calendar.svelte
+++ b/src/app/views/Calendar.svelte
@@ -2,15 +2,11 @@
import {identity} from "ramda"
import {pubkey} from "@welshman/app"
import Calendar from "src/app/shared/Calendar.svelte"
- import {env, loadCircleMessages, userFollows} from "src/engine"
+ import {env, userFollows} from "src/engine"
const filter = env.FORCE_GROUP
? {kinds: [31923], "#a": [env.FORCE_GROUP]}
: {kinds: [31923], authors: [$pubkey, ...$userFollows].filter(identity)}
-
- if (env.FORCE_GROUP) {
- loadCircleMessages([env.FORCE_GROUP])
- }
diff --git a/src/app/views/Feeds.svelte b/src/app/views/Feeds.svelte
index d73d48c57..081431c67 100644
--- a/src/app/views/Feeds.svelte
+++ b/src/app/views/Feeds.svelte
@@ -5,7 +5,7 @@
import Feed from "src/app/shared/Feed.svelte"
import {router} from "src/app/util/router"
import {makeFeed} from "src/domain"
- import {env, loadCircleMessages} from "src/engine"
+ import {env} from "src/engine"
export let feed = null
@@ -19,10 +19,6 @@
feed = makeFeed({definition: makeScopeFeed(Scope.Follows)})
}
- if (env.FORCE_GROUP) {
- loadCircleMessages([env.FORCE_GROUP])
- }
-
document.title = "Feeds"
diff --git a/src/app/views/Notifications.svelte b/src/app/views/Notifications.svelte
index a6fecc20a..63c6e6799 100644
--- a/src/app/views/Notifications.svelte
+++ b/src/app/views/Notifications.svelte
@@ -8,9 +8,7 @@
import {router} from "src/app/util/router"
import {
sessionWithMeta,
- userSettings,
loadNotifications,
- loadCircleMessages,
unreadMainNotifications,
unreadReactionNotifications,
} from "src/engine"
@@ -33,7 +31,6 @@
onMount(() => {
loadNotifications()
- loadCircleMessages()
const scroller = createScroller(loadMore, {element})
diff --git a/src/engine/requests.ts b/src/engine/requests.ts
index 3955d8412..0854dbfc6 100644
--- a/src/engine/requests.ts
+++ b/src/engine/requests.ts
@@ -62,12 +62,9 @@ import {partition, uniq, without} from "ramda"
import {CUSTOM_LIST_KINDS} from "src/domain"
import {
env,
- getUserCircles,
load,
subscribePersistent,
sessionWithMeta,
- groupAdminKeys,
- groupSharedKeys,
type MySubscribeRequest,
} from "src/engine/state"
@@ -151,36 +148,6 @@ export const getStaleAddrs = (addrs: string[]) => {
return Array.from(stale)
}
-export const loadGroupMessages = async (addrs: string[]) => {
- for (const address of addrs) {
- const keys = [...groupAdminKeys.get(), ...groupSharedKeys.get()]
- const pubkeys = keys.filter(k => k.group === address).map(k => k.pubkey)
-
- await pullConservatively({
- relays: ctx.app.router.WithinContext(address).getUrls(),
- filters: [{kinds: [WRAP], "#p": pubkeys}],
- })
- }
-}
-
-export const loadCommunityMessages = async (addrs: string[]) => {
- await pullConservatively({
- relays: ctx.app.router.WithinMultipleContexts(addrs).getUrls(),
- filters: [{kinds: [...noteKinds, ...repostKinds], "#a": addrs}],
- })
-}
-
-export const loadCircleMessages = async (addrs?: string[]) => {
- if (!addrs) {
- addrs = getUserCircles(sessionWithMeta.get())
- }
-
- const [groups, communities] = partition(isGroupAddress, addrs)
-
- loadGroupMessages(groups)
- loadCommunityMessages(communities)
-}
-
export const loadEvent = async (idOrAddress: string, request: Partial = {}) =>
first(
await load({
diff --git a/src/engine/state.ts b/src/engine/state.ts
index e7eea901e..823b09bfa 100644
--- a/src/engine/state.ts
+++ b/src/engine/state.ts
@@ -1149,11 +1149,6 @@ if (!db) {
}),
plaintext: storageAdapters.fromObjectStore(plaintext, {throttle: 1000}),
repository: storageAdapters.fromRepository(repository, {throttle: 300, migrate: migrateEvents}),
- groups: {keyPath: "address", store: groups},
- groupAlerts: {keyPath: "id", store: groupAlerts},
- groupRequests: {keyPath: "id", store: groupRequests},
- groupSharedKeys: {keyPath: "pubkey", store: groupSharedKeys},
- groupAdminKeys: {keyPath: "pubkey", store: groupAdminKeys},
}).then(() => Promise.all(initialRelays.map(loadRelay)))
}
From 1275a57139b3428602b4bd970a65d79240c2ff90 Mon Sep 17 00:00:00 2001
From: Ticruz
Date: Tue, 5 Nov 2024 13:42:29 +0100
Subject: [PATCH 04/13] 0 repost noshow
---
src/app/shared/NoteMeta.svelte | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/src/app/shared/NoteMeta.svelte b/src/app/shared/NoteMeta.svelte
index 9a1179e4a..0fc145f4c 100644
--- a/src/app/shared/NoteMeta.svelte
+++ b/src/app/shared/NoteMeta.svelte
@@ -9,12 +9,14 @@
const repostPubkeys = uniq(pluck("pubkey", reposts))
-
-
- Reposted by
- {#if repostPubkeys.length === 1}
-
- {:else}
- {repostPubkeys.length} people
- {/if}
-
+{#if repostPubkeys.length > 0}
+
+
+ Reposted by
+ {#if repostPubkeys.length === 1}
+
+ {:else}
+ {repostPubkeys.length} people
+ {/if}
+
+{/if}
From c04b3c94ffcfdc1d1460c765490e73955a13184a Mon Sep 17 00:00:00 2001
From: Ticruz
Date: Tue, 5 Nov 2024 13:43:17 +0100
Subject: [PATCH 05/13] remove cross-post
---
src/app/shared/NoteActions.svelte | 47 ++-----------------------------
1 file changed, 2 insertions(+), 45 deletions(-)
diff --git a/src/app/shared/NoteActions.svelte b/src/app/shared/NoteActions.svelte
index 66c912d4b..ca0e7264d 100644
--- a/src/app/shared/NoteActions.svelte
+++ b/src/app/shared/NoteActions.svelte
@@ -68,14 +68,11 @@
export let replyCtrl
export let showHidden
export let addToContext
- export let contextAddress
export let removeFromContext
export let replies, likes, zaps
export let zapper
const signedEvent = asSignedEvent(note as any)
- const address = contextAddress || first(getContextTagValues(note.tags))
- const addresses = [address].filter(identity)
const nevent = nip19.neventEncode({
id: note.id,
kind: note.kind,
@@ -112,7 +109,7 @@
const createLabel = () => router.at("notes").of(note.id).at("label").open()
- const quote = () => router.at("notes/create").cx({quote: note, group: address}).open()
+ const quote = () => router.at("notes/create").cx({quote: note}).open()
const report = () => router.at("notes").of(note.id).at("report").open()
@@ -135,24 +132,6 @@
removeFromContext(e)
}
- const crossPost = async () => {
- const content = JSON.stringify(note as SignedEvent)
- const tags = [...tagEvent(note), tagPubkey(note.pubkey), ...getClientTags()]
-
- let template
- if (note.kind === 1) {
- template = createEvent(6, {content, tags})
- } else {
- template = createEvent(16, {content, tags: [...tags, ["k", String(note.kind)]]})
- }
-
- signAndPublish(template)
-
- showInfo("Note has been cross-posted!")
-
- setView(null)
- }
-
const startZap = () => {
const zapTags = note.tags.filter(nthEq(0, "zap"))
const defaultSplit = tagZapSplit(note.pubkey)
@@ -199,7 +178,7 @@
let actions = []
let handlersShown = false
- $: disableActions = !$signer || (muted && !showHidden) || (note.wrap && address)
+ $: disableActions = !$signer || (muted && !showHidden)
$: like = likes.find(e => e.pubkey === $sessionWithMeta?.pubkey)
$: $likesCount = likes.length
$: zap = zaps.find(e => e.request.pubkey === $sessionWithMeta?.pubkey)
@@ -221,10 +200,6 @@
if ($signer) {
actions.push({label: "Quote", icon: "quote-left", onClick: quote})
- if (isSignedEvent(note)) {
- actions.push({label: "Cross-post", icon: "shuffle", onClick: () => setView("cross-post")})
- }
-
actions.push({label: "Tag", icon: "tag", onClick: createLabel})
if (muted) {
@@ -431,24 +406,6 @@
- {:else if view === "cross-post"}
-
- Cross-post
-
- Select where you'd like to post to:
-
- {#if address}
-
crossPost()}>
-
-
-
-
Global
-
Post to your main feed.
-
-
-
- {/if}
-
{/if}
{/if}
From 718db8387c621cca0f8ed2327d08a93dfe740deb Mon Sep 17 00:00:00 2001
From: Ticruz
Date: Tue, 5 Nov 2024 13:46:15 +0100
Subject: [PATCH 06/13] remove groups in note options
---
src/app/shared/NoteOptions.svelte | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/app/shared/NoteOptions.svelte b/src/app/shared/NoteOptions.svelte
index 0da7c33b8..fbf19e31b 100644
--- a/src/app/shared/NoteOptions.svelte
+++ b/src/app/shared/NoteOptions.svelte
@@ -14,14 +14,14 @@
anonymous: boolean
}
- let values = {groups: [], ...initialValues}
+ let values = initialValues
let view = null
const dispatch = createEventDispatcher()
export const setView = name => {
view = name
- values = {groups: [], ...initialValues}
+ values = initialValues
}
const onSubmit = () => {
From 9c0c802bb7c99f1fe7df5550966d1c749e083397 Mon Sep 17 00:00:00 2001
From: Ticruz
Date: Tue, 5 Nov 2024 14:17:43 +0100
Subject: [PATCH 07/13] pub return only in signAndPublish
---
src/app/shared/NoteActions.svelte | 6 +++---
src/app/shared/NoteCreateInline.svelte | 2 +-
src/app/shared/NoteReply.svelte | 11 +++--------
src/app/views/NoteCreate.svelte | 2 +-
src/engine/commands.ts | 4 +---
5 files changed, 9 insertions(+), 16 deletions(-)
diff --git a/src/app/shared/NoteActions.svelte b/src/app/shared/NoteActions.svelte
index ca0e7264d..d2fa2ea01 100644
--- a/src/app/shared/NoteActions.svelte
+++ b/src/app/shared/NoteActions.svelte
@@ -122,9 +122,9 @@
const tags = [...tagReactionTo(note), ...getClientTags()]
const template = createEvent(7, {content, tags})
- const {event} = await signAndPublish(template)
+ const pub = await signAndPublish(template)
- addToContext(event)
+ addToContext(pub.request.event)
}
const deleteReaction = e => {
@@ -211,7 +211,7 @@
actions.push({label: "Report", icon: "triangle-exclamation", onClick: report})
}
- if (!env.FORCE_GROUP && env.PLATFORM_RELAYS.length === 0 && isSignedEvent(note)) {
+ if (env.PLATFORM_RELAYS.length === 0 && isSignedEvent(note)) {
actions.push({label: "Broadcast", icon: "rss", onClick: broadcast})
}
diff --git a/src/app/shared/NoteCreateInline.svelte b/src/app/shared/NoteCreateInline.svelte
index 839dde2a9..92186162e 100644
--- a/src/app/shared/NoteCreateInline.svelte
+++ b/src/app/shared/NoteCreateInline.svelte
@@ -65,7 +65,7 @@
}
const template = createEvent(1, {content, tags})
- const {pub} = await signAndPublish(template, opts)
+ const pub = await signAndPublish(template, opts)
showPublishInfo(pub)
opts = {...defaultOpts}
diff --git a/src/app/shared/NoteReply.svelte b/src/app/shared/NoteReply.svelte
index 8fe8db3e4..cb9e67b03 100644
--- a/src/app/shared/NoteReply.svelte
+++ b/src/app/shared/NoteReply.svelte
@@ -19,7 +19,6 @@
export let parent
export let addToContext
- export let contextAddress = false
export let showBorder = false
export let forceOpen = false
@@ -109,12 +108,12 @@
loading = true
const template = createEvent(1, {content, tags})
- const {pub, event} = await signAndPublish(template, opts)
+ const pub = await signAndPublish(template, opts)
loading = false
// Only track one event/pub to avoid apprent duplicates
- addToContext(event)
+ addToContext(pub.request.event)
showPublishInfo(pub)
clearDraft()
reset()
@@ -194,11 +193,7 @@
{/if}
{#if !env.FORCE_GROUP}
-
+
{/if}
{#if $nsecWarning}
diff --git a/src/app/views/NoteCreate.svelte b/src/app/views/NoteCreate.svelte
index 75a221176..6b0d175cd 100644
--- a/src/app/views/NoteCreate.svelte
+++ b/src/app/views/NoteCreate.svelte
@@ -143,7 +143,7 @@
}),
})
- const {pub} = await signAndPublish(template, opts)
+ const pub = await signAndPublish(template, opts)
showPublishInfo(pub)
router.clearModals()
diff --git a/src/engine/commands.ts b/src/engine/commands.ts
index a7fa0bc77..a667ac7fe 100644
--- a/src/engine/commands.ts
+++ b/src/engine/commands.ts
@@ -207,9 +207,7 @@ export const signAndPublish = async (template, {anonymous = false} = {}) => {
const event = await sign(template, {anonymous})
const relays = ctx.app.router.PublishEvent(event).getUrls()
- const pub = await publish({event, relays})
-
- return {event, pub}
+ return await publish({event, relays})
}
// Deletes
From 76e1b97906b7f2c2a4fe46a61aca263ecf82fd6f Mon Sep 17 00:00:00 2001
From: Ticruz
Date: Tue, 5 Nov 2024 14:20:10 +0100
Subject: [PATCH 08/13] remove FORCE_GROUP env variable
---
src/app/MenuDesktop.svelte | 6 ++----
src/app/MenuMobile.svelte | 2 +-
src/app/Nav.svelte | 4 ----
src/app/shared/Feed.svelte | 3 ---
src/app/shared/Note.svelte | 6 +-----
src/app/shared/NoteReply.svelte | 8 ++------
src/app/views/Calendar.svelte | 6 ++----
src/app/views/UserSettings.svelte | 2 +-
src/engine/state.ts | 5 +++--
9 files changed, 12 insertions(+), 30 deletions(-)
diff --git a/src/app/MenuDesktop.svelte b/src/app/MenuDesktop.svelte
index 7f38fd05e..c2d1503ae 100644
--- a/src/app/MenuDesktop.svelte
+++ b/src/app/MenuDesktop.svelte
@@ -77,7 +77,7 @@
: import.meta.env.VITE_APP_WORDMARK_LIGHT} />
Feeds
- {#if !env.FORCE_GROUP && env.PLATFORM_RELAYS.length === 0}
+ {#if env.PLATFORM_RELAYS.length === 0}
Relays
@@ -109,9 +109,7 @@
{/if}
-
- Groups
-
+ Groups
Settings
- {#if !env.FORCE_GROUP && env.PLATFORM_RELAYS.length === 0}
+ {#if env.PLATFORM_RELAYS.length === 0}
diff --git a/src/app/Nav.svelte b/src/app/Nav.svelte
index 02b5691ce..bb3f201eb 100644
--- a/src/app/Nav.svelte
+++ b/src/app/Nav.svelte
@@ -40,10 +40,6 @@
params.pubkey = props.pubkey
}
- if (env.FORCE_GROUP) {
- params.group = env.FORCE_GROUP
- }
-
router.at("notes/create").qp(params).open()
}
diff --git a/src/app/shared/Feed.svelte b/src/app/shared/Feed.svelte
index 63030804d..7a6ebb58c 100644
--- a/src/app/shared/Feed.svelte
+++ b/src/app/shared/Feed.svelte
@@ -18,7 +18,6 @@
export let feed: Feed
export let anchor = null
export let eager = false
- export let contextAddress = null
export let skipNetwork = false
export let forcePlatform = true
export let shouldListen = false
@@ -102,8 +101,6 @@
diff --git a/src/app/shared/Note.svelte b/src/app/shared/Note.svelte
index beea5ac06..c18603fa1 100644
--- a/src/app/shared/Note.svelte
+++ b/src/app/shared/Note.svelte
@@ -52,9 +52,7 @@
export let showParent = true
export let showLoading = false
export let showHidden = false
- export let showGroup = false
export let showMedia = getSetting("show_media")
- export let contextAddress = null
let ready = false
let event = note
@@ -213,7 +211,7 @@
{@const showReply = reply && !ancestors.replies.includes(anchor) && showParent}
{@const showRoot = root && !ancestors.roots.includes(anchor) && root !== reply && showParent}
-
+
{#if !showParent && !topLevel}
@@ -290,7 +288,6 @@
zapper={$zapper}
bind:this={actions}
{removeFromContext}
- {contextAddress}
{addToContext}
{replyCtrl}
{showHidden}
@@ -330,7 +327,6 @@
0}
bind:this={replyCtrl}
diff --git a/src/app/shared/NoteReply.svelte b/src/app/shared/NoteReply.svelte
index cb9e67b03..3a517aa87 100644
--- a/src/app/shared/NoteReply.svelte
+++ b/src/app/shared/NoteReply.svelte
@@ -170,9 +170,7 @@
images.addImage(e.detail)}>
- {#if !env.FORCE_GROUP}
- options.setView("settings")} />
- {/if}
+ options.setView("settings")} />
@@ -192,9 +190,7 @@
{/if}
-{#if !env.FORCE_GROUP}
-
-{/if}
+
{#if $nsecWarning}
nsecWarning.set(null)} onBypass={bypassNsecWarning} />
diff --git a/src/app/views/Calendar.svelte b/src/app/views/Calendar.svelte
index 5cdc12a90..d231d4102 100644
--- a/src/app/views/Calendar.svelte
+++ b/src/app/views/Calendar.svelte
@@ -2,11 +2,9 @@
import {identity} from "ramda"
import {pubkey} from "@welshman/app"
import Calendar from "src/app/shared/Calendar.svelte"
- import {env, userFollows} from "src/engine"
+ import {userFollows} from "src/engine"
- const filter = env.FORCE_GROUP
- ? {kinds: [31923], "#a": [env.FORCE_GROUP]}
- : {kinds: [31923], authors: [$pubkey, ...$userFollows].filter(identity)}
+ const filter = {kinds: [31923], authors: [$pubkey, ...$userFollows].filter(identity)}
diff --git a/src/app/views/UserSettings.svelte b/src/app/views/UserSettings.svelte
index ad2f08b40..178fa6385 100644
--- a/src/app/views/UserSettings.svelte
+++ b/src/app/views/UserSettings.svelte
@@ -66,7 +66,7 @@
faster, but will require more bandwidth and processing power.
- {#if !env.FORCE_GROUP && env.PLATFORM_RELAYS.length === 0}
+ {#if env.PLATFORM_RELAYS.length === 0}
diff --git a/src/engine/state.ts b/src/engine/state.ts
index 823b09bfa..2f7d8a657 100644
--- a/src/engine/state.ts
+++ b/src/engine/state.ts
@@ -92,6 +92,7 @@ import {
getListTags,
getPubkeyTagValues,
getTagValues,
+ isGroupAddress,
isHashedEvent,
makeList,
normalizeRelayUrl,
@@ -133,7 +134,6 @@ export const env = {
ENABLE_MARKET: JSON.parse(import.meta.env.VITE_ENABLE_MARKET) as boolean,
ENABLE_ZAPS: JSON.parse(import.meta.env.VITE_ENABLE_ZAPS) as boolean,
BLUR_CONTENT: JSON.parse(import.meta.env.VITE_BLUR_CONTENT) as boolean,
- FORCE_GROUP: import.meta.env.VITE_FORCE_GROUP as string,
IMGPROXY_URL: import.meta.env.VITE_IMGPROXY_URL as string,
MULTIPLEXTR_URL: import.meta.env.VITE_MULTIPLEXTR_URL as string,
NIP96_URLS: fromCsv(import.meta.env.VITE_NIP96_URLS) as string[],
@@ -1089,6 +1089,8 @@ const migrateEvents = (events: TrustedEvent[]) => {
if (events.length < 50_000) {
return events
}
+ // filter out all event posted to encrypted group
+ events = events.filter(e => !e.wrap?.tags.some(t => isGroupAddress(t[1])))
const scoreEvent = getScoreEvent()
@@ -1114,7 +1116,6 @@ if (!db) {
signEvent: (event: StampedEvent) => {
if (
event.kind === CLIENT_AUTH &&
- !env.FORCE_GROUP &&
env.PLATFORM_RELAYS.length === 0 &&
!getSetting("auto_authenticate")
) {
From db6946ca47faf1f51885a5492ebf343cf6392870 Mon Sep 17 00:00:00 2001
From: Ticruz
Date: Tue, 5 Nov 2024 14:55:05 +0100
Subject: [PATCH 09/13] remove all group command and utilities
---
src/app/App.svelte | 5 +-
src/app/shared/Feed.svelte | 1 -
src/app/shared/FeedFormSaveAsList.svelte | 4 +-
src/app/shared/NoteContentQuote.svelte | 29 +++----
src/app/state.ts | 4 -
src/app/util/feeds.ts | 16 +---
src/app/util/router.ts | 1 -
src/app/views/EventEdit.svelte | 1 -
src/app/views/Feeds.svelte | 2 +-
src/app/views/InviteCreate.svelte | 2 +-
src/app/views/NoteDetail.svelte | 2 +-
src/app/views/Onboarding.svelte | 6 +-
src/app/views/UserKeys.svelte | 106 +----------------------
src/engine/requests.ts | 34 +-------
src/engine/state.ts | 8 --
src/engine/utils/events.ts | 8 --
16 files changed, 23 insertions(+), 206 deletions(-)
diff --git a/src/app/App.svelte b/src/app/App.svelte
index dfe54038d..6a60b8be7 100644
--- a/src/app/App.svelte
+++ b/src/app/App.svelte
@@ -13,7 +13,7 @@
import {ready} from "src/engine"
import * as engine from "src/engine"
import * as domain from "src/domain"
- import {loadAppData, slowConnections, loadUserData} from "src/app/state"
+ import {slowConnections, loadUserData} from "src/app/state"
import {themeVariables, appName} from "src/partials/state"
import Toast from "src/partials/Toast.svelte"
import Menu from "src/app/Menu.svelte"
@@ -195,7 +195,6 @@
requireSigner: true,
serializers: {
pubkey: asPerson,
- group: asNaddr("group"),
type: asString("type"),
},
})
@@ -432,8 +431,6 @@
// before loading app data
await lib.sleep(350)
- loadAppData()
-
if ($session) {
loadUserData()
}
diff --git a/src/app/shared/Feed.svelte b/src/app/shared/Feed.svelte
index 7a6ebb58c..aa42175bf 100644
--- a/src/app/shared/Feed.svelte
+++ b/src/app/shared/Feed.svelte
@@ -24,7 +24,6 @@
export let showControls = false
export let hideSpinner = false
export let includeReposts = false
- export let showGroup = false
export let onEvent = null
const splits = [["zap", env.PLATFORM_PUBKEY, "", "1"]]
diff --git a/src/app/shared/FeedFormSaveAsList.svelte b/src/app/shared/FeedFormSaveAsList.svelte
index 4495fa9a4..23f030b25 100644
--- a/src/app/shared/FeedFormSaveAsList.svelte
+++ b/src/app/shared/FeedFormSaveAsList.svelte
@@ -12,7 +12,7 @@
import Anchor from "src/partials/Anchor.svelte"
import Popover2 from "src/partials/Popover2.svelte"
import ListForm from "src/app/shared/ListForm.svelte"
- import {makeUserList, isTopicFeed, isMentionFeed, isContextFeed} from "src/domain"
+ import {makeUserList, isTopicFeed, isMentionFeed} from "src/domain"
export let feed
export let onChange
@@ -36,8 +36,6 @@
return makeUserList({kind: NAMED_PEOPLE, tags: feed.slice(1).map(tagPubkey)})
} else if (isMentionFeed(feed)) {
return makeUserList({kind: NAMED_PEOPLE, tags: feed.slice(2).map(tagPubkey)})
- } else if (isContextFeed(feed)) {
- return makeUserList({kind: NAMED_COMMUNITIES, tags: feed.slice(2).map(a => ["a", a])})
} else if (isRelayFeed(feed)) {
return makeUserList({kind: NAMED_RELAYS, tags: feed.slice(1).map(url => ["r", url])})
} else if (isTopicFeed(feed)) {
diff --git a/src/app/shared/NoteContentQuote.svelte b/src/app/shared/NoteContentQuote.svelte
index 69cf610c4..d862f8e7b 100644
--- a/src/app/shared/NoteContentQuote.svelte
+++ b/src/app/shared/NoteContentQuote.svelte
@@ -35,9 +35,7 @@
return
}
- if (isGroup) {
- router.at("groups").of(address, {relays}).at("notes").open()
- } else if (noteId) {
+ if (noteId) {
router.at("notes").of(noteId, {relays}).open()
}
}
@@ -47,7 +45,6 @@
}
$: address = $quote ? getAddress($quote) : ""
- $: isGroup = address.match(/^(34550|35834):/)
$: profileDisplay = deriveProfileDisplay($quote?.pubkey)
$: muted = $quote && $isEventMuted($quote, true)
@@ -60,19 +57,17 @@
Show
{:else if $quote}
- {#if !isGroup}
-
-
-
- {$profileDisplay}
-
-
- {/if}
+
+
+
+ {$profileDisplay}
+
+
{:else}
diff --git a/src/app/state.ts b/src/app/state.ts
index 44a0de590..49a7fa577 100644
--- a/src/app/state.ts
+++ b/src/app/state.ts
@@ -48,10 +48,6 @@ export const slowConnections = writable([])
// Synchronization from events to state
-export const loadAppData = () => {
- // If we have a group, load that
-}
-
export const loadUserData = async (hints: string[] = []) => {
// Load relays, then load everything else so we have a better chance of finding it
const $pubkey = pubkey.get()
diff --git a/src/app/util/feeds.ts b/src/app/util/feeds.ts
index d5c3eaa5c..e00706b72 100644
--- a/src/app/util/feeds.ts
+++ b/src/app/util/feeds.ts
@@ -9,22 +9,15 @@ import {
getIdOrAddress,
getIdAndAddress,
getIdFilters,
- isContextAddress,
DIRECT_MESSAGE,
REACTION,
LIVE_CHAT_MESSAGE,
} from "@welshman/util"
import {Tracker} from "@welshman/net"
import type {Feed, RequestItem} from "@welshman/feeds"
-import {
- walkFeed,
- FeedLoader as CoreFeedLoader,
- isIntersectionFeed,
- isRelayFeed,
-} from "@welshman/feeds"
+import {FeedLoader as CoreFeedLoader, isIntersectionFeed, isRelayFeed} from "@welshman/feeds"
import {repository, tracker, getFilterSelections} from "@welshman/app"
import {noteKinds, isLike, reactionKinds, repostKinds} from "src/util/nostr"
-import {isAddressFeed} from "src/domain"
import type {DisplayEvent} from "src/engine"
import {
feedLoader as baseFeedLoader,
@@ -340,13 +333,6 @@ export const createFeed = (opts: FeedOpts) => {
function discardEvents(events) {
let strict = true
- // Be more tolerant when looking at communities
- walkFeed(opts.feed, feed => {
- if (isAddressFeed(feed)) {
- strict = strict && !(feed.slice(2) as string[]).some(isContextAddress)
- }
- })
-
return events.filter(e => {
if (repository.isDeleted(e)) return false
if (e.kind === REACTION && !isLike(e)) return false
diff --git a/src/app/util/router.ts b/src/app/util/router.ts
index 1ff1ee7ff..d109c1180 100644
--- a/src/app/util/router.ts
+++ b/src/app/util/router.ts
@@ -102,7 +102,6 @@ router.extend("qrcode", encodeURIComponent)
router.extend("media", encodeURIComponent)
router.extend("relays", encodeURIComponent)
router.extend("channels", getChannelId)
-router.extend("groups", encodeNaddr)
router.extend("events", encodeNaddr)
router.extend("lists", encodeNaddr)
router.extend("listings", encodeNaddr)
diff --git a/src/app/views/EventEdit.svelte b/src/app/views/EventEdit.svelte
index b808761cc..44ff526ef 100644
--- a/src/app/views/EventEdit.svelte
+++ b/src/app/views/EventEdit.svelte
@@ -51,7 +51,6 @@
loading = false
values = {
- groups: tags.context().values().valueOf(),
title: tags.get("name")?.value() || tags.get("title")?.value() || "",
location: tags.get("location")?.value() || "",
start: secondsToDate(tags.get("start")?.value() || now()),
diff --git a/src/app/views/Feeds.svelte b/src/app/views/Feeds.svelte
index 081431c67..c58d6fc90 100644
--- a/src/app/views/Feeds.svelte
+++ b/src/app/views/Feeds.svelte
@@ -31,4 +31,4 @@
{/if}
-
+
diff --git a/src/app/views/InviteCreate.svelte b/src/app/views/InviteCreate.svelte
index d73f2d07b..455b22195 100644
--- a/src/app/views/InviteCreate.svelte
+++ b/src/app/views/InviteCreate.svelte
@@ -49,7 +49,7 @@
relays = toSpliced(relays, i, 1)
}
- let relayInput, groupInput
+ let relayInput
let sections = []
let pubkeys = []
let relays = []
diff --git a/src/app/views/NoteDetail.svelte b/src/app/views/NoteDetail.svelte
index ed4f81cb9..044935d57 100644
--- a/src/app/views/NoteDetail.svelte
+++ b/src/app/views/NoteDetail.svelte
@@ -16,7 +16,7 @@
{#if $event}
-
+
{:else}
diff --git a/src/app/views/Onboarding.svelte b/src/app/views/Onboarding.svelte
index a0bd5ff52..b00af183b 100644
--- a/src/app/views/Onboarding.svelte
+++ b/src/app/views/Onboarding.svelte
@@ -52,11 +52,7 @@
}
const signup = async () => {
- if (invite?.groups) {
- router.at("invite").qp({groups: invite.groups}).push()
- } else {
- router.at("notes").push()
- }
+ router.at("notes").push()
// Immediately request access to any relays with a claim
for (const {url, claim} of invite?.parsedRelays || []) {
diff --git a/src/app/views/UserKeys.svelte b/src/app/views/UserKeys.svelte
index f73716202..5336cfbff 100644
--- a/src/app/views/UserKeys.svelte
+++ b/src/app/views/UserKeys.svelte
@@ -1,84 +1,14 @@
@@ -119,36 +49,4 @@
{/if}
-
-
-
-
-
Group keys
-
-
- Import Key
-
-
-
-
-{#if nsec !== null}
-
- Import group key
-
- Share group administration using a dedicated private key. These keys are still valuable, so
- keep them safe!
-
-
-
-
-
-
-
- Import key
-
-{/if}
diff --git a/src/engine/requests.ts b/src/engine/requests.ts
index 0854dbfc6..fce7fc05e 100644
--- a/src/engine/requests.ts
+++ b/src/engine/requests.ts
@@ -20,9 +20,7 @@ import {
} from "@welshman/lib"
import type {TrustedEvent} from "@welshman/util"
import {
- Address,
getIdFilters,
- isGroupAddress,
createEvent,
WRAP,
EPOCH,
@@ -57,16 +55,10 @@ import {
getNetwork,
} from "@welshman/app"
import type {AppSyncOpts} from "@welshman/app"
-import {noteKinds, reactionKinds, repostKinds} from "src/util/nostr"
+import {noteKinds, reactionKinds} from "src/util/nostr"
import {partition, uniq, without} from "ramda"
import {CUSTOM_LIST_KINDS} from "src/domain"
-import {
- env,
- load,
- subscribePersistent,
- sessionWithMeta,
- type MySubscribeRequest,
-} from "src/engine/state"
+import {env, load, subscribePersistent, type MySubscribeRequest} from "src/engine/state"
// Utils
@@ -126,28 +118,6 @@ export const loadAll = (feed, opts: LoadOpts = {}) => {
return {promise, loading, stop}
}
-// Groups
-
-export const attemptedAddrs = new Map()
-
-export const getStaleAddrs = (addrs: string[]) => {
- const stale = new Set()
-
- for (const addr of addrs) {
- const attempts = attemptedAddrs.get(addr) | 0
-
- if (attempts > 0) {
- continue
- }
-
- stale.add(addr)
-
- attemptedAddrs.set(addr, attempts + 1)
- }
-
- return Array.from(stale)
-}
-
export const loadEvent = async (idOrAddress: string, request: Partial = {}) =>
first(
await load({
diff --git a/src/engine/state.ts b/src/engine/state.ts
index 2f7d8a657..60d29ef93 100644
--- a/src/engine/state.ts
+++ b/src/engine/state.ts
@@ -906,14 +906,6 @@ export const createAndPublish = async ({
return publish({event, relays, verb, timeout, forcePlatform})
}
-// Publish
-
-export const mentionGroup = (address: string, ...args: unknown[]) => [
- "a",
- address,
- ctx.app.router.WithinContext(address).getUrl(),
-]
-
export const tagsFromContent = (content: string) => {
const tags = []
diff --git a/src/engine/utils/events.ts b/src/engine/utils/events.ts
index b5e7e57df..ff753cf4d 100644
--- a/src/engine/utils/events.ts
+++ b/src/engine/utils/events.ts
@@ -45,13 +45,5 @@ export const unwrapRepost = repost => {
return null
}
- const originalGroup = Tags.fromEvent(event).context().values().first()
- const repostGroup = Tags.fromEvent(repost).context().values().first()
-
- // Only show cross-posts, not reposts from global to global
- if (originalGroup === repostGroup) {
- return null
- }
-
return event
}
From 4fee030282374eeaaf887242b00a0c2a83d4db94 Mon Sep 17 00:00:00 2001
From: Ticruz
Date: Tue, 5 Nov 2024 15:27:00 +0100
Subject: [PATCH 10/13] remove unused variables and imports
---
src/app/Nav.svelte | 2 +-
src/app/shared/EventInfo.svelte | 1 -
src/app/shared/FeedFormSaveAsList.svelte | 8 +-------
src/app/shared/GroupCircle.svelte | 15 ---------------
src/app/shared/NoteActions.svelte | 10 ++--------
src/app/shared/NoteContentQuote.svelte | 3 +--
src/app/shared/NoteReply.svelte | 2 +-
src/app/util/feeds.ts | 2 +-
src/app/views/PersonDetail.svelte | 24 ++++++++++++------------
src/engine/utils/events.ts | 2 +-
10 files changed, 20 insertions(+), 49 deletions(-)
delete mode 100644 src/app/shared/GroupCircle.svelte
diff --git a/src/app/Nav.svelte b/src/app/Nav.svelte
index bb3f201eb..568daeaff 100644
--- a/src/app/Nav.svelte
+++ b/src/app/Nav.svelte
@@ -8,7 +8,7 @@
import PersonBadge from "src/app/shared/PersonBadge.svelte"
import {menuIsOpen, searchTerm} from "src/app/state"
import {router} from "src/app/util/router"
- import {env, hasNewNotifications, hasNewMessages} from "src/engine"
+ import {hasNewNotifications, hasNewMessages} from "src/engine"
let innerWidth = 0
let searching = false
diff --git a/src/app/shared/EventInfo.svelte b/src/app/shared/EventInfo.svelte
index 912488c3d..4c6f16d8e 100644
--- a/src/app/shared/EventInfo.svelte
+++ b/src/app/shared/EventInfo.svelte
@@ -26,7 +26,6 @@
const deleted = deriveIsDeletedByAddress(repository, event)
$: tags = Tags.fromEvent(event)
- $: groupAddrs = tags.context().values().valueOf()
$: ({name, title, location} = fromPairs(event.tags))
$: end = parseInt(tags.get("end")?.value())
$: start = parseInt(tags.get("start")?.value())
diff --git a/src/app/shared/FeedFormSaveAsList.svelte b/src/app/shared/FeedFormSaveAsList.svelte
index 23f030b25..cdfd32e7e 100644
--- a/src/app/shared/FeedFormSaveAsList.svelte
+++ b/src/app/shared/FeedFormSaveAsList.svelte
@@ -1,11 +1,5 @@
-
-{#if $meta?.image}
-
-{:else}
-
-{/if}
diff --git a/src/app/shared/NoteActions.svelte b/src/app/shared/NoteActions.svelte
index d2fa2ea01..94eb1b3fd 100644
--- a/src/app/shared/NoteActions.svelte
+++ b/src/app/shared/NoteActions.svelte
@@ -3,14 +3,12 @@
import {nip19} from "nostr-tools"
import {onMount} from "svelte"
import {derived} from "svelte/store"
- import {ctx, nth, nthEq, remove, last, sortBy, first} from "@welshman/lib"
+ import {ctx, nth, nthEq, remove, last, sortBy} from "@welshman/lib"
import {
repository,
signer,
trackerStore,
tagReactionTo,
- tagEvent,
- tagPubkey,
tagZapSplit,
mute,
unmute,
@@ -22,12 +20,10 @@
asSignedEvent,
isSignedEvent,
createEvent,
- getAddress,
- getContextTagValues,
getPubkeyTagValues,
} from "@welshman/util"
import {tweened} from "svelte/motion"
- import {identity, sum, pluck} from "ramda"
+ import {sum, pluck} from "ramda"
import {fly} from "src/util/transition"
import {formatSats} from "src/util/misc"
import {quantify, pluralize} from "hurdak"
@@ -41,8 +37,6 @@
import Menu from "src/partials/Menu.svelte"
import MenuItem from "src/partials/MenuItem.svelte"
import FlexColumn from "src/partials/FlexColumn.svelte"
- import Card from "src/partials/Card.svelte"
- import Heading from "src/partials/Heading.svelte"
import Modal from "src/partials/Modal.svelte"
import OverflowMenu from "src/partials/OverflowMenu.svelte"
import CopyValue from "src/partials/CopyValue.svelte"
diff --git a/src/app/shared/NoteContentQuote.svelte b/src/app/shared/NoteContentQuote.svelte
index d862f8e7b..5e44e6ae4 100644
--- a/src/app/shared/NoteContentQuote.svelte
+++ b/src/app/shared/NoteContentQuote.svelte
@@ -1,6 +1,6 @@
diff --git a/src/app/shared/NoteReply.svelte b/src/app/shared/NoteReply.svelte
index 3a517aa87..716169c55 100644
--- a/src/app/shared/NoteReply.svelte
+++ b/src/app/shared/NoteReply.svelte
@@ -14,7 +14,7 @@
import NsecWarning from "src/app/shared/NsecWarning.svelte"
import NoteOptions from "src/app/shared/NoteOptions.svelte"
import NoteImages from "src/app/shared/NoteImages.svelte"
- import {env, publish, signAndPublish, tagsFromContent, getClientTags} from "src/engine"
+ import {publish, signAndPublish, tagsFromContent, getClientTags} from "src/engine"
import {drafts} from "src/app/state"
export let parent
diff --git a/src/app/util/feeds.ts b/src/app/util/feeds.ts
index e00706b72..860905fc2 100644
--- a/src/app/util/feeds.ts
+++ b/src/app/util/feeds.ts
@@ -331,7 +331,7 @@ export const createFeed = (opts: FeedOpts) => {
}
function discardEvents(events) {
- let strict = true
+ const strict = true
return events.filter(e => {
if (repository.isDeleted(e)) return false
diff --git a/src/app/views/PersonDetail.svelte b/src/app/views/PersonDetail.svelte
index 542e055c7..89414c4b1 100644
--- a/src/app/views/PersonDetail.svelte
+++ b/src/app/views/PersonDetail.svelte
@@ -112,8 +112,10 @@
background-image: linear-gradient(to bottom, ${rgba}, ${rgba}, ${rgb}), url('${banner}')`} />
-
-
+
+
{#if pubkey === $session?.pubkey}
($following ? unfollow(pubkey) : follow(tagPubkey(pubkey)))}
>{$following ? "Unfollow" : "Follow"}
-
Message
+
Message
{/if}
@@ -169,10 +169,10 @@
-
+
{#if $handle}
{/if}
@@ -185,9 +185,9 @@
{#if $profile?.website}
-
+
{stripProtocol($profile.website)}
{/if}
@@ -217,9 +217,9 @@
{#if $userMutes.has(pubkey)}
You have muted this person.
{:else if activeTab === "notes"}
-
+
{:else if activeTab === "likes"}
-
+
{:else if activeTab === "collections"}
{:else if activeTab === "relays"}
diff --git a/src/engine/utils/events.ts b/src/engine/utils/events.ts
index ff753cf4d..ae8b72fc3 100644
--- a/src/engine/utils/events.ts
+++ b/src/engine/utils/events.ts
@@ -2,7 +2,7 @@ import {nip19} from "nostr-tools"
import {tryFunc, switcherFn} from "hurdak"
import {sortBy} from "@welshman/lib"
import type {TrustedEvent} from "@welshman/util"
-import {fromNostrURI, Address, hasValidSignature, Tags} from "@welshman/util"
+import {fromNostrURI, Address, hasValidSignature} from "@welshman/util"
import {parseJson} from "src/util/misc"
export const sortEventsAsc = events => sortBy((e: TrustedEvent) => e.created_at, events)
From 6980ff16a21098d49604256f60690a2cc4ea394b Mon Sep 17 00:00:00 2001
From: Ticruz
Date: Tue, 5 Nov 2024 16:02:13 +0100
Subject: [PATCH 11/13] pre-commit format
---
.husky/pre-commit | 5 +----
package.json | 4 ++--
2 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/.husky/pre-commit b/.husky/pre-commit
index 3c39d1f8f..2c9b45fc9 100755
--- a/.husky/pre-commit
+++ b/.husky/pre-commit
@@ -1,5 +1,2 @@
-#!/usr/bin/env sh
-. "$(dirname -- "$0")/_/husky.sh"
-
-npm run check
+npm run format && npm run check
diff --git a/package.json b/package.json
index 9e6af3f3f..d13f31e05 100644
--- a/package.json
+++ b/package.json
@@ -16,7 +16,7 @@
"check:fmt": "prettier --check $(git diff head --name-only --diff-filter d | grep -E '(js|ts|svelte)$' | xargs)",
"check:errors": "run-s check:ts check:es",
"check": "run-p check:errors check:fmt",
- "format": "prettier --write $(git diff head --name-only --diff-filter d | grep -E '(js|ts|svelte)$' | xargs)",
+ "format": "git diff head --name-only --diff-filter d | grep -E '(js|ts|svelte)$' | xargs -r prettier --write",
"watch": "find src -type f | entr -r"
},
"dependencies": {
@@ -99,4 +99,4 @@
"vite-plugin-pwa": "^0.20.5",
"vitest": "^2.1.3"
}
-}
+}
\ No newline at end of file
From 43bcac230bb885d4a2d8b291bd59b9dbe2a0f78f Mon Sep 17 00:00:00 2001
From: Ticruz
Date: Tue, 5 Nov 2024 16:12:44 +0100
Subject: [PATCH 12/13] remove VITE_FORCE_GROUP
---
.env | 1 -
1 file changed, 1 deletion(-)
diff --git a/.env b/.env
index 4e6071292..26bd9adb5 100644
--- a/.env
+++ b/.env
@@ -11,7 +11,6 @@ VITE_IMGPROXY_URL=https://imgproxy.coracle.social
VITE_DUFFLEPUD_URL=https://dufflepud.onrender.com
VITE_PLATFORM_ZAP_SPLIT=0
VITE_PLATFORM_PUBKEY=8ec86ac9e10979998652068ee6b00223b8e3265aabb3fe28fb6b3b6e294adc96
-VITE_FORCE_GROUP=
VITE_PLATFORM_RELAYS=
VITE_ENABLE_ZAPS=true
VITE_APP_NAME=Coracle
From e14184d695222fe58d70d9b9ffab9c2f284b1390 Mon Sep 17 00:00:00 2001
From: Ticruz
Date: Tue, 5 Nov 2024 16:13:34 +0100
Subject: [PATCH 13/13] remove VITE_FORCE_GROUP
---
README.md | 1 -
1 file changed, 1 deletion(-)
diff --git a/README.md b/README.md
index 4c100e789..04dfaacf8 100644
--- a/README.md
+++ b/README.md
@@ -98,7 +98,6 @@ Coracle is intended to be fully white-labeled by groups of various kinds. The fo
- `VITE_DUFFLEPUD_URL` is a [Dufflepud](https://github.com/coracle-social/dufflepud) instance url, which helps Coracle with things like link previews and image uploads.
- `VITE_PLATFORM_ZAP_SPLIT` is a decimal between 0 and 1 defining the default zap split percent.
- `VITE_PLATFORM_PUBKEY` is the pubkey of the platform owner. This gets zapped when using the platform zap split.
-- `VITE_FORCE_GROUP` is an optional `kind:34550` or `kind:35834` address. If provided, the home page of Coracle will be the home page for the group, and most views will be filtered down to the group's scope. For user privacy, `VITE_PLATFORM_RELAYS` should also be set when using `VITE_FORCE_GROUP`.
- `VITE_PLATFORM_RELAYS` is an optional comma-separated list of relay urls to use for feeds. If provided, most UI components related to relay selection will be hidden from the user.
- `VITE_ENABLE_ZAPS` can be set to `false` to disable zaps.
- `VITE_APP_NAME` is the app's name.