feat: add pinned post functionality

This commit is contained in:
codytseng 2025-10-12 21:39:16 +08:00
parent 9c554da2da
commit d131026af9
31 changed files with 563 additions and 56 deletions

View file

@ -838,14 +838,13 @@ class ClientService extends EventTarget {
}
let event: NEvent | undefined
if (filter.ids) {
if (filter.ids?.length) {
event = await this.fetchEventById(relays, filter.ids[0])
} else {
if (author) {
const relayList = await this.fetchRelayList(author)
relays.push(...relayList.write.slice(0, 4))
}
event = await this.tryHarderToFetchEvent(relays, filter)
}
if (!event && author) {
const relayList = await this.fetchRelayList(author)
event = await this.tryHarderToFetchEvent(relayList.write.slice(0, 5), filter)
}
if (event && event.id !== id) {
@ -1261,6 +1260,8 @@ class ClientService extends EventTarget {
return params.map(({ pubkey, kind, d }) => {
const key = `${kind}:${pubkey}:${d ?? ''}`
const event = eventMap.get(key)
if (kind === kinds.Pinlist) return event ?? null
if (event) {
indexedDb.putReplaceableEvent(event)
return event
@ -1321,6 +1322,10 @@ class ClientService extends EventTarget {
return evt ? getServersFromServerTags(evt.tags) : []
}
async fetchPinListEvent(pubkey: string) {
return this.fetchReplaceableEvent(pubkey, kinds.Pinlist)
}
async updateBlossomServerListEventCache(evt: NEvent) {
await this.updateReplaceableEventCache(evt)
}

View file

@ -19,6 +19,7 @@ const StoreNames = {
MUTE_DECRYPTED_TAGS: 'muteDecryptedTags',
USER_EMOJI_LIST_EVENTS: 'userEmojiListEvents',
EMOJI_SET_EVENTS: 'emojiSetEvents',
PIN_LIST_EVENTS: 'pinListEvents',
FAVORITE_RELAYS: 'favoriteRelays',
RELAY_SETS: 'relaySets',
FOLLOWING_FAVORITE_RELAYS: 'followingFavoriteRelays',
@ -42,7 +43,7 @@ class IndexedDbService {
init(): Promise<void> {
if (!this.initPromise) {
this.initPromise = new Promise((resolve, reject) => {
const request = window.indexedDB.open('jumble', 8)
const request = window.indexedDB.open('jumble', 9)
request.onerror = (event) => {
reject(event)
@ -94,6 +95,9 @@ class IndexedDbService {
if (!db.objectStoreNames.contains(StoreNames.RELAY_INFOS)) {
db.createObjectStore(StoreNames.RELAY_INFOS, { keyPath: 'key' })
}
if (!db.objectStoreNames.contains(StoreNames.PIN_LIST_EVENTS)) {
db.createObjectStore(StoreNames.PIN_LIST_EVENTS, { keyPath: 'key' })
}
if (db.objectStoreNames.contains(StoreNames.RELAY_INFO_EVENTS)) {
db.deleteObjectStore(StoreNames.RELAY_INFO_EVENTS)
}
@ -459,6 +463,8 @@ class IndexedDbService {
return StoreNames.USER_EMOJI_LIST_EVENTS
case kinds.Emojisets:
return StoreNames.EMOJI_SET_EVENTS
case kinds.Pinlist:
return StoreNames.PIN_LIST_EVENTS
default:
return undefined
}
@ -492,6 +498,10 @@ class IndexedDbService {
{
name: StoreNames.RELAY_INFOS,
expirationTimestamp: Date.now() - 1000 * 60 * 60 * 24 // 1 days
},
{
name: StoreNames.PIN_LIST_EVENTS,
expirationTimestamp: Date.now() - 1000 * 60 * 60 * 24 * 30 // 30 days
}
]
const transaction = this.db!.transaction(