mirror of
https://github.com/dergigi/boris.git
synced 2026-01-28 03:04:21 +01:00
fix: use parent event timestamp for bookmarks instead of placeholder
- Add parentCreatedAt parameter to processApplesauceBookmarks function - Replace all Math.floor(Date.now() / 1000) placeholders with parentCreatedAt || 0 - Update all call sites in bookmarkProcessing.ts to pass evt.created_at - Individual bookmarks now inherit timestamp from their bookmark list event - Bookmarks without valid parent timestamp will show as 0 (epoch) and be filtered by hideBookmarksWithoutCreationDate setting - Eliminates 'now' placeholder timestamps in bookmark sidebar
This commit is contained in:
@@ -62,7 +62,8 @@ export { dedupeNip51Events } from './bookmarkEvents'
|
||||
export const processApplesauceBookmarks = (
|
||||
bookmarks: unknown,
|
||||
activeAccount: ActiveAccount,
|
||||
isPrivate: boolean
|
||||
isPrivate: boolean,
|
||||
parentCreatedAt?: number
|
||||
): IndividualBookmark[] => {
|
||||
if (!bookmarks) return []
|
||||
|
||||
@@ -76,14 +77,14 @@ export const processApplesauceBookmarks = (
|
||||
allItems.push({
|
||||
id: note.id,
|
||||
content: '',
|
||||
created_at: Math.floor(Date.now() / 1000),
|
||||
created_at: parentCreatedAt || 0,
|
||||
pubkey: note.author || activeAccount.pubkey,
|
||||
kind: 1, // Short note kind
|
||||
tags: [],
|
||||
parsedContent: undefined,
|
||||
type: 'event' as const,
|
||||
isPrivate,
|
||||
added_at: Math.floor(Date.now() / 1000)
|
||||
added_at: parentCreatedAt || 0
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -96,14 +97,14 @@ export const processApplesauceBookmarks = (
|
||||
allItems.push({
|
||||
id: coordinate,
|
||||
content: '',
|
||||
created_at: Math.floor(Date.now() / 1000),
|
||||
created_at: parentCreatedAt || 0,
|
||||
pubkey: article.pubkey,
|
||||
kind: article.kind, // Usually 30023 for long-form articles
|
||||
tags: [],
|
||||
parsedContent: undefined,
|
||||
type: 'event' as const,
|
||||
isPrivate,
|
||||
added_at: Math.floor(Date.now() / 1000)
|
||||
added_at: parentCreatedAt || 0
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -114,14 +115,14 @@ export const processApplesauceBookmarks = (
|
||||
allItems.push({
|
||||
id: `hashtag-${hashtag}`,
|
||||
content: `#${hashtag}`,
|
||||
created_at: Math.floor(Date.now() / 1000),
|
||||
created_at: parentCreatedAt || 0,
|
||||
pubkey: activeAccount.pubkey,
|
||||
kind: 1,
|
||||
tags: [['t', hashtag]],
|
||||
parsedContent: undefined,
|
||||
type: 'event' as const,
|
||||
isPrivate,
|
||||
added_at: Math.floor(Date.now() / 1000)
|
||||
added_at: parentCreatedAt || 0
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -132,14 +133,14 @@ export const processApplesauceBookmarks = (
|
||||
allItems.push({
|
||||
id: `url-${url}`,
|
||||
content: url,
|
||||
created_at: Math.floor(Date.now() / 1000),
|
||||
created_at: parentCreatedAt || 0,
|
||||
pubkey: activeAccount.pubkey,
|
||||
kind: 1,
|
||||
tags: [['r', url]],
|
||||
parsedContent: undefined,
|
||||
type: 'event' as const,
|
||||
isPrivate,
|
||||
added_at: Math.floor(Date.now() / 1000)
|
||||
added_at: parentCreatedAt || 0
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -153,14 +154,14 @@ export const processApplesauceBookmarks = (
|
||||
.map((bookmark: BookmarkData) => ({
|
||||
id: bookmark.id!,
|
||||
content: bookmark.content || '',
|
||||
created_at: bookmark.created_at || Math.floor(Date.now() / 1000),
|
||||
created_at: bookmark.created_at || parentCreatedAt || 0,
|
||||
pubkey: activeAccount.pubkey,
|
||||
kind: bookmark.kind || 30001,
|
||||
tags: bookmark.tags || [],
|
||||
parsedContent: bookmark.content ? (getParsedContent(bookmark.content) as ParsedContent) : undefined,
|
||||
type: 'event' as const,
|
||||
isPrivate,
|
||||
added_at: bookmark.created_at || Math.floor(Date.now() / 1000)
|
||||
added_at: bookmark.created_at || parentCreatedAt || 0
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ async function decryptEvent(
|
||||
const hiddenTags = JSON.parse(decryptedContent) as string[][]
|
||||
const manualPrivate = Helpers.parseBookmarkTags(hiddenTags)
|
||||
privateItems.push(
|
||||
...processApplesauceBookmarks(manualPrivate, activeAccount, true).map(i => ({
|
||||
...processApplesauceBookmarks(manualPrivate, activeAccount, true, evt.created_at).map(i => ({
|
||||
...i,
|
||||
sourceKind: evt.kind,
|
||||
setName: dTag,
|
||||
@@ -84,7 +84,7 @@ async function decryptEvent(
|
||||
const priv = Helpers.getHiddenBookmarks(evt)
|
||||
if (priv) {
|
||||
privateItems.push(
|
||||
...processApplesauceBookmarks(priv, activeAccount, true).map(i => ({
|
||||
...processApplesauceBookmarks(priv, activeAccount, true, evt.created_at).map(i => ({
|
||||
...i,
|
||||
sourceKind: evt.kind,
|
||||
setName: dTag,
|
||||
@@ -155,7 +155,7 @@ export async function collectBookmarksFromEvents(
|
||||
|
||||
const pub = Helpers.getPublicBookmarks(evt)
|
||||
publicItemsAll.push(
|
||||
...processApplesauceBookmarks(pub, activeAccount, false).map(i => ({
|
||||
...processApplesauceBookmarks(pub, activeAccount, false, evt.created_at).map(i => ({
|
||||
...i,
|
||||
sourceKind: evt.kind,
|
||||
setName: dTag,
|
||||
@@ -181,7 +181,7 @@ export async function collectBookmarksFromEvents(
|
||||
const priv = Helpers.getHiddenBookmarks(evt)
|
||||
if (priv) {
|
||||
publicItemsAll.push(
|
||||
...processApplesauceBookmarks(priv, activeAccount, true).map(i => ({
|
||||
...processApplesauceBookmarks(priv, activeAccount, true, evt.created_at).map(i => ({
|
||||
...i,
|
||||
sourceKind: evt.kind,
|
||||
setName: dTag,
|
||||
|
||||
@@ -121,36 +121,11 @@ export function hasContent(bookmark: IndividualBookmark): boolean {
|
||||
// Check if bookmark has a real creation date (not "Now" / current time)
|
||||
export function hasCreationDate(bookmark: IndividualBookmark): boolean {
|
||||
if (!bookmark.created_at) return false
|
||||
|
||||
// For web bookmarks (kind 39701), they always have real timestamps from events
|
||||
if (bookmark.kind === 39701 || bookmark.sourceKind === 39701) {
|
||||
return true
|
||||
}
|
||||
|
||||
// If bookmark has no content, it likely failed to hydrate and its timestamp is a placeholder
|
||||
const hasContent = bookmark.content && bookmark.content.trim().length > 0
|
||||
if (!hasContent) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check for URL-only bookmarks (synthetic bookmarks from NIP-51 processing)
|
||||
// These get placeholder timestamps and should be filtered if they haven't been properly hydrated
|
||||
const contentIsUrl = /^https?:\/\//i.test(bookmark.content.trim())
|
||||
const hasMinimalTags = !bookmark.tags || bookmark.tags.length <= 1
|
||||
|
||||
// If content is just a URL and there are minimal tags, this is likely an unhydrated reference
|
||||
// These bookmarks are created with placeholder timestamps during NIP-51 processing
|
||||
if (contentIsUrl && hasMinimalTags) {
|
||||
// Additionally check if the ID suggests it's a synthetic bookmark
|
||||
const isSyntheticId = bookmark.id.startsWith('url-') ||
|
||||
bookmark.id.startsWith('hashtag-') ||
|
||||
/^[0-9a-f]{64}$/i.test(bookmark.id) === false && !bookmark.id.includes(':')
|
||||
if (isSyntheticId) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
// If timestamp is missing or equals current time (within 1 second), consider it invalid
|
||||
const now = Math.floor(Date.now() / 1000)
|
||||
const createdAt = Math.floor(bookmark.created_at)
|
||||
// If created_at is within 1 second of now, it's likely missing/placeholder
|
||||
return Math.abs(createdAt - now) > 1
|
||||
}
|
||||
|
||||
// Bookmark sets helpers (kind 30003)
|
||||
|
||||
Reference in New Issue
Block a user