mirror of
https://github.com/dergigi/boris.git
synced 2026-01-08 17:34:52 +01:00
feat: add named kind constants, streaming updates, and fix reads/links tabs
- Create src/config/kinds.ts with named Nostr kind constants - Add streaming support to fetchAllReads and fetchLinks with onItem callbacks - Update all services to use KINDS constants instead of magic numbers - Add mergeReadItem utility for DRY state management - Add fallbackTitleFromUrl for external links without titles - Relax validation to allow external items without titles - Update Me.tsx to use streaming with Map-based state for reads/links - Fix refresh to merge new data instead of clearing state - Fix empty states for Reads and Links tabs (no more infinite skeletons) - Services updated: readsService, linksService, libraryService, bookmarkService, exploreService, highlights/fetchByAuthor
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { NostrEvent } from 'nostr-tools'
|
||||
import { ReadItem } from './readsService'
|
||||
import { fallbackTitleFromUrl } from '../utils/readItemMerge'
|
||||
|
||||
const READING_POSITION_PREFIX = 'boris:reading-position:'
|
||||
|
||||
@@ -117,24 +118,30 @@ export function sortByReadingActivity(items: ReadItem[]): ReadItem[] {
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters out items without timestamps or proper titles
|
||||
* Filters out items without timestamps and enriches external items with fallback titles
|
||||
*/
|
||||
export function filterValidItems(items: ReadItem[]): ReadItem[] {
|
||||
return items.filter(item => {
|
||||
// Only include items that have a timestamp
|
||||
const hasTimestamp = (item.readingTimestamp && item.readingTimestamp > 0) ||
|
||||
(item.markedAt && item.markedAt > 0)
|
||||
if (!hasTimestamp) return false
|
||||
|
||||
// Filter out items without titles
|
||||
if (!item.title || item.title === 'Untitled') {
|
||||
// For Nostr articles, we need the title from the event
|
||||
return items
|
||||
.filter(item => {
|
||||
// Only include items that have a timestamp
|
||||
const hasTimestamp = (item.readingTimestamp && item.readingTimestamp > 0) ||
|
||||
(item.markedAt && item.markedAt > 0)
|
||||
if (!hasTimestamp) return false
|
||||
|
||||
// For Nostr articles, we need the event to be valid
|
||||
if (item.type === 'article' && !item.event) return false
|
||||
// For external URLs, we need a proper title
|
||||
if (item.type === 'external' && !item.title) return false
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
// For external URLs, we need at least a URL
|
||||
if (item.type === 'external' && !item.url) return false
|
||||
|
||||
return true
|
||||
})
|
||||
.map(item => {
|
||||
// Add fallback title for external URLs without titles
|
||||
if (item.type === 'external' && !item.title && item.url) {
|
||||
return { ...item, title: fallbackTitleFromUrl(item.url) }
|
||||
}
|
||||
return item
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user