Get custom group feed working

This commit is contained in:
Jon Staab 2024-05-15 16:54:14 -07:00
parent ab1ebc9e96
commit 10c3d9070a
5 changed files with 85 additions and 61 deletions

View File

@ -18,8 +18,8 @@
<script lang="ts">
import {pluck, join, uniqBy} from "ramda"
import {ucFirst} from "hurdak"
import {Address} from "@welshman/util"
import {fly} from "src/util/transition"
import {parseAnything} from "src/util/nostr"
import {showInfo, showWarning} from "src/partials/Toast.svelte"
import Field from "src/partials/Field.svelte"
import FieldInline from "src/partials/FieldInline.svelte"
@ -32,10 +32,9 @@
import Anchor from "src/partials/Anchor.svelte"
import FlexColumn from "src/partials/FlexColumn.svelte"
import Heading from "src/partials/Heading.svelte"
import PersonBadge from "src/app/shared/PersonBadge.svelte"
import PersonMultiSelect from "src/app/shared/PersonMultiSelect.svelte"
import type {Person} from "src/engine"
import {env, searchRelays, normalizeRelayUrl, searchPeople, displayPubkey} from "src/engine"
import {env, hints, searchRelays, feedSearch, normalizeRelayUrl} from "src/engine"
export let onSubmit
export let values: Values
@ -49,19 +48,14 @@
showAdvanced = !showAdvanced
}
const addFeed = pubkey => {
values.feeds = uniqBy(join(":"), values.feeds.concat([["feed", "Custom Feed", pubkey]]))
feedsInput.clear()
}
const addFeed = address => {
if (address) {
const relayHint = hints.FromPubkeys([Address.from(address).pubkey]).getUrl()
const feedTag = ["feed", address, relayHint, "Custom Feed"]
const searchFeeds = term => {
parseAnything(term).then(result => {
if (result?.type === "npub") {
addFeed(result.data)
}
})
return $searchPeople(term).map(p => p.pubkey)
values.feeds = uniqBy(join(":"), values.feeds.concat([feedTag]))
feedsInput.clear()
}
}
const removeFeed = i => {
@ -155,22 +149,22 @@
<span>Hide Advanced Settings</span>
</Anchor>
<Field label="Custom Feeds">
{#each values.feeds as [_, label, pubkey], i (pubkey)}
{#each values.feeds as [_, address, hint, label], i (address)}
<ListItem on:remove={() => removeFeed(i)}>
<span slot="label">{displayPubkey(pubkey)}</span>
<span slot="label">{$feedSearch.display(address)}</span>
<span slot="data">
<Input bind:value={label} />
</span>
</ListItem>
{/each}
<SearchSelect
bind:this={feedsInput}
search={searchFeeds}
onChange={addFeed}
displayItem={displayPubkey}>
search={$feedSearch.search}
bind:this={feedsInput}
displayItem={$feedSearch.display}>
<i slot="before" class="fa fa-rss" />
<span slot="item" let:item>
<PersonBadge inert pubkey={item} />
{$feedSearch.display(item)}
</span>
</SearchSelect>
<div slot="info">

View File

@ -1,55 +1,77 @@
<script lang="ts">
import {without} from "ramda"
import {isGroupAddress} from "@welshman/util"
import {ucFirst} from "hurdak"
import {remove} from "@welshman/lib"
import {isGroupAddress, getAddress, getIdFilters, Address} from "@welshman/util"
import {feedFromFilter} from "@welshman/feeds"
import {noteKinds} from "src/util/nostr"
import FlexColumn from "src/partials/FlexColumn.svelte"
import Menu from "src/partials/Menu.svelte"
import MenuItem from "src/partials/MenuItem.svelte"
import Chip from "src/partials/Chip.svelte"
import Popover from "src/partials/Popover.svelte"
import Tabs from "src/partials/Tabs.svelte"
import Feed from "src/app/shared/Feed.svelte"
import NoteCreateInline from "src/app/shared/NoteCreateInline.svelte"
import {makeFeed} from "src/domain"
import {canSign, deriveGroup} from "src/engine"
import {makeFeed, readFeed} from "src/domain"
import {hints, repository, canSign, deriveGroup, load} from "src/engine"
export let address
const group = deriveGroup(address)
const feed = makeFeed({
definition: feedFromFilter({
kinds: without([30402], noteKinds),
"#a": [address],
}),
})
const mainFeed = feedFromFilter({kinds: remove(30402, noteKinds), "#a": [address]})
const setActiveTab = tab => {
activeTab = tab
feed = feeds.find(f => f.name === activeTab).feed
}
let activeTab = "feed"
let tabs = ["feed"]
let feeds = [{name: "feed", feed: makeFeed({definition: mainFeed})}]
let feed = makeFeed({definition: mainFeed})
for (const feed of $group.feeds || []) {
const [address, relay = "", name = ""] = feed.slice(1)
if (!Address.isAddress(address)) {
continue
}
const event = repository.getEvent(address)
if (event) {
feeds = feeds.concat({name, feed: readFeed(event)})
tabs = tabs.concat(name)
} else {
const relays = hints
.merge([hints.fromRelays([relay]), hints.FromPubkeys([Address.from(address).pubkey])])
.getUrls()
load({
relays,
filters: getIdFilters([address]),
onEvent: e => {
if (feeds.find(f => getAddress(e) === address)) {
return
}
feeds = feeds.concat({name, feed: readFeed(e)})
tabs = tabs.concat(name)
},
})
}
}
</script>
<FlexColumn large>
{#if $group.feeds?.length > 0}
<Popover
class="inline-block"
placement="bottom-end"
theme="transparent"
opts={{hideOnClick: true}}>
<div slot="trigger" class="flex cursor-pointer justify-end">
<Chip class="mb-2 mr-2 inline-block">
Viewing: {feed ? feed[1] : "Notes"}
<i class="fa fa-caret-down p-1" />
</Chip>
</div>
<div slot="tooltip">
<Menu>
<MenuItem>Notes</MenuItem>
{#each $group.feeds as feed (feed.join(":"))}
<MenuItem>{feed[1]}</MenuItem>
{/each}
</Menu>
</div>
</Popover>
{/if}
{#if $canSign}
<NoteCreateInline group={address} />
{/if}
<Feed eager {feed} shouldListen skipNetwork={isGroupAddress(address)} />
{#if tabs.length > 1}
<Tabs {tabs} {activeTab} {setActiveTab}>
<div slot="tab" let:tab class="flex gap-2">
<div>{ucFirst(tab)}</div>
</div>
</Tabs>
{/if}
{#key feed}
<Feed eager {feed} shouldListen skipNetwork={isGroupAddress(address)} />
{/key}
</FlexColumn>

View File

@ -104,7 +104,6 @@ export class FeedLoader {
})
if (opts.shouldListen && this.feedLoader.compiler.canCompile(opts.feed)) {
console.log("listen")
this.feedLoader.compiler.compile(opts.feed).then(requests => {
const tracker = new Tracker()
const signal = this.controller.signal

View File

@ -27,7 +27,7 @@
const userIsMember = g => deriveIsGroupMember(g.address, true).get()
const userGroups = groups.derived(
filter(g => !repository.isDeleted(g.address) && userIsMember(g)),
filter(g => !repository.deletes.has(g.address) && userIsMember(g)),
)
let q = ""

View File

@ -114,7 +114,14 @@ import {
} from "src/util/nostr"
import logger from "src/util/logger"
import type {Feed, List} from "src/domain"
import {EDITABLE_LIST_KINDS, ListSearch, readFeed, readList, mapListToFeed} from "src/domain"
import {
EDITABLE_LIST_KINDS,
ListSearch,
FeedSearch,
readFeed,
readList,
mapListToFeed,
} from "src/domain"
import type {
Channel,
DisplayEvent,
@ -1099,6 +1106,8 @@ export const userFeeds = new Derived([feeds, pubkey], ([$feeds, $pubkey]: [Feed[
),
)
export const feedSearch = feeds.derived($feeds => new FeedSearch($feeds))
export const lists = repository
.filter([{kinds: EDITABLE_LIST_KINDS}])
.derived($events => $events.filter(e => e.tags.length > 1).map(readList))