fix: stabilize list loading and show correct list count

This commit is contained in:
Bhavishy
2026-04-14 19:26:43 +05:30
parent 2cea6c4ef4
commit 0db751bd45
13 changed files with 792 additions and 491 deletions
+55 -69
View File
@@ -14,6 +14,7 @@ import {
simpleCache,
normalizeUrl,
nthNe,
randomId,
} from "@welshman/lib"
import {Nip01Signer} from "@welshman/signer"
import type {UploadTask} from "@welshman/editor"
@@ -33,11 +34,11 @@ import {
ROOMS,
COMMENT,
APP_DATA,
asDecryptedEvent,
isSignedEvent,
makeEvent,
normalizeRelayUrl,
makeList,
Address,
addToListPublicly,
removeFromListByPredicate,
updateList,
@@ -49,7 +50,6 @@ import {
toNostrURI,
RelayMode,
getTagValues,
readList,
uploadBlob,
canUploadBlob,
encryptFile,
@@ -86,10 +86,14 @@ import {
import {compressFile} from "@lib/html"
import type {SettingsValues, SpaceNotificationSettings} from "@app/core/state"
import {
BOOKMARKS,
BOOKMARK_LISTS,
SETTINGS,
PROTECTED,
INDEXER_RELAYS,
DEFAULT_BLOSSOM_SERVERS,
getBookmarkList,
getBookmarkCollection,
userSpaceUrls,
userSettingsValues,
getSetting,
@@ -171,59 +175,51 @@ export const broadcastUserData = async (relays: string[]) => {
// List updates
const BOOKMARKS = 10003
const BOOKMARK_LISTS = 30003
const parseListKey = (key: string) => {
const [kind, ...rest] = key.split(":")
return {
kind: parseInt(kind),
d: rest.join(":"),
const getSavedItemsList = (owner = pubkey.get() || "") => {
if (!owner) {
return makeList({kind: BOOKMARKS})
}
return getBookmarkList().get(owner) || makeList({kind: BOOKMARKS})
}
const getUserBookmarkList = (key = `${BOOKMARKS}:`) => {
const author = pubkey.get()
const {kind, d} = parseListKey(key)
const getBookmarkListFromAddress = (address: string) => {
const parsed = Address.from(address)
if (!author) {
return makeList({kind})
if (parsed.kind === BOOKMARKS) {
return getSavedItemsList(parsed.pubkey)
}
const latest = first(
repository
.query([{kinds: [kind], authors: [author]}])
.filter(event => getTagValue("d", event.tags) === d),
)
if (parsed.kind === BOOKMARK_LISTS) {
return getBookmarkCollection().get(address)
}
return latest ? readList(asDecryptedEvent(latest)) : makeList({kind})
return undefined
}
export const createBookmarkList = async (title: string) => {
const d = title.trim()
const label = title.trim()
if (!d) {
return
}
const existing = getUserBookmarkList(`${BOOKMARK_LISTS}:${d}`)
if (existing.event?.id) {
if (!label) {
return
}
const list = makeList({kind: BOOKMARK_LISTS})
const event = await updateList(list, {publicTags: [["d", d]]}).reconcile(nip44EncryptToSelf)
const relays = uniq([...Router.get().FromUser().getUrls(), ...getRelayTagValues(event.tags)])
const event = await updateList(list, {
publicTags: [
["d", randomId()],
["title", label],
],
}).reconcile(nip44EncryptToSelf)
const relays = Router.get().FromUser().getUrls()
return publishThunk({event, relays})
}
export const addEventBookmark = async (target: TrustedEvent, key = `${BOOKMARKS}:`) => {
const list = getUserBookmarkList(key)
const {d} = parseListKey(key)
export const addEventBookmark = async (target: TrustedEvent, address?: string) => {
const list = address ? getBookmarkListFromAddress(address) : getSavedItemsList()
if (d && !list.event?.id) {
if (!list) {
return
}
@@ -234,20 +230,15 @@ export const addEventBookmark = async (target: TrustedEvent, key = `${BOOKMARKS}
}
const event = await addToListPublicly(list, ["e", target.id]).reconcile(nip44EncryptToSelf)
const relays = uniq([
...Router.get().FromUser().getUrls(),
...Router.get().Event(target).limit(3).getUrls(),
...getRelayTagValues(event.tags),
])
const relays = Router.get().FromUser().getUrls()
return publishThunk({event, relays})
}
export const removeEventBookmark = async (target: TrustedEvent, key = `${BOOKMARKS}:`) => {
const list = getUserBookmarkList(key)
const {d} = parseListKey(key)
export const removeEventBookmark = async (target: TrustedEvent, address?: string) => {
const list = address ? getBookmarkListFromAddress(address) : getSavedItemsList()
if (d && !list.event?.id) {
if (!list) {
return
}
@@ -269,51 +260,46 @@ export const removeEventBookmark = async (target: TrustedEvent, key = `${BOOKMAR
(tag[0] === "e" && tag[1] === target.id) ||
(targetAddress !== undefined && tag[0] === "a" && tag[1] === targetAddress),
).reconcile(nip44EncryptToSelf)
const relays = uniq([
...INDEXER_RELAYS,
...getRelayTagValues(event.tags),
...Router.get().Event(target).limit(3).getUrls(),
])
const relays = Router.get().FromUser().getUrls()
return publishThunk({event, relays})
}
export const deleteBookmarkList = async (key: string) => {
const list = getUserBookmarkList(key)
const {kind, d} = parseListKey(key)
export const deleteBookmarkList = async (address: string) => {
const list = getBookmarkCollection().get(address)
const {kind} = Address.from(address)
if (kind !== BOOKMARK_LISTS || !d || !list.event) {
if (kind !== BOOKMARK_LISTS || !list?.event) {
return
}
const relays = uniq([...INDEXER_RELAYS, ...getRelayTagValues(list.event.tags)])
const address = `${kind}:${list.event.pubkey}:${d}`
const relays = Router.get().FromUser().getUrls()
return publishDelete({protect: false, event: list.event, tags: [["a", address]], relays})
}
export const renameBookmarkList = async (key: string, title: string) => {
const list = getUserBookmarkList(key)
const {kind, d} = parseListKey(key)
const nextD = title.trim()
export const renameBookmarkList = async (address: string, title: string) => {
const list = getBookmarkCollection().get(address)
const {kind} = Address.from(address)
const nextTitle = title.trim()
if (kind !== BOOKMARK_LISTS || !d || !nextD || !list.event) {
if (kind !== BOOKMARK_LISTS || !nextTitle || !list?.event) {
return
}
if (nextD === d) {
const currentTitle =
getTagValue("title", list.event.tags) || getTagValue("d", list.event.tags) || ""
if (nextTitle === currentTitle) {
return
}
const existing = getUserBookmarkList(`${BOOKMARK_LISTS}:${nextD}`)
if (existing.event?.id && existing.event.id !== list.event.id) {
return
}
const publicTags = [["d", nextD], ...list.publicTags.filter(tag => tag[0] !== "d")]
const publicTags = [
["d", getTagValue("d", list.event.tags) || randomId()],
["title", nextTitle],
]
const event = await updateList(list, {publicTags}).reconcile(nip44EncryptToSelf)
const relays = uniq([...INDEXER_RELAYS, ...getRelayTagValues(list.event.tags)])
const relays = Router.get().FromUser().getUrls()
return publishThunk({event, relays})
}