Browse Source

refine engagement and toggle on publications

imwald
Silberengel 1 week ago
parent
commit
18589c30e8
  1. 18
      src/components/Library/LibraryPublicationGrid.tsx
  2. 8
      src/hooks/useLibraryPublications.ts
  3. 2
      src/i18n/locales/de.ts
  4. 2
      src/i18n/locales/en.ts
  5. 71
      src/lib/library-publication-index.test.ts
  6. 202
      src/lib/library-publication-index.ts

18
src/components/Library/LibraryPublicationGrid.tsx

@ -5,7 +5,7 @@ import type { LibraryPublicationEntry } from '@/lib/library-publication-index' @@ -5,7 +5,7 @@ import type { LibraryPublicationEntry } from '@/lib/library-publication-index'
import { isBooklistNip32Label } from '@/lib/nip32-label'
import { cn } from '@/lib/utils'
import { useScreenSize } from '@/providers/ScreenSizeProvider'
import { BookOpen, Highlighter, MessageSquare, Tag } from 'lucide-react'
import { BookOpen, Bookmark, Highlighter, MessageSquare, Pin, Tag } from 'lucide-react'
import { useTranslation } from 'react-i18next'
function LabelBadgeIcon({ name }: { name: string }) {
@ -23,7 +23,9 @@ function EngagementBadges({ entry }: { entry: LibraryPublicationEntry }) { @@ -23,7 +23,9 @@ function EngagementBadges({ entry }: { entry: LibraryPublicationEntry }) {
otherLabels.length === 0 &&
!entry.hasLabel &&
!entry.hasComment &&
!entry.hasHighlight
!entry.hasHighlight &&
!entry.hasBookmark &&
!entry.hasPin
) {
return null
}
@ -83,6 +85,18 @@ function EngagementBadges({ entry }: { entry: LibraryPublicationEntry }) { @@ -83,6 +85,18 @@ function EngagementBadges({ entry }: { entry: LibraryPublicationEntry }) {
{t('Library badge highlight')}
</span>
)}
{entry.hasBookmark && (
<span className="inline-flex items-center gap-1 rounded-full bg-muted px-2 py-0.5 text-xs text-muted-foreground">
<Bookmark className="size-3" aria-hidden />
{t('Library badge bookmark')}
</span>
)}
{entry.hasPin && (
<span className="inline-flex items-center gap-1 rounded-full bg-muted px-2 py-0.5 text-xs text-muted-foreground">
<Pin className="size-3" aria-hidden />
{t('Library badge pin')}
</span>
)}
</div>
)
}

8
src/hooks/useLibraryPublications.ts

@ -40,7 +40,13 @@ const EMPTY_ENGAGEMENT: PublicationEngagementMaps = { @@ -40,7 +40,13 @@ const EMPTY_ENGAGEMENT: PublicationEngagementMaps = {
myHighlightAddresses: new Set(),
myHighlightEventIds: new Set(),
commentAddresses: new Set(),
highlightAddresses: new Set()
commentEventIds: new Set(),
highlightAddresses: new Set(),
highlightEventIds: new Set(),
bookmarkAddresses: new Set(),
bookmarkEventIds: new Set(),
pinAddresses: new Set(),
pinEventIds: new Set()
}
const EMPTY_BOOKLIST_TARGETS = { addresses: new Set<string>(), eventIds: new Set<string>() }

2
src/i18n/locales/de.ts

@ -1664,6 +1664,8 @@ export default { @@ -1664,6 +1664,8 @@ export default {
'Library badge label': 'Label',
'Library badge comment': 'Kommentar',
'Library badge highlight': 'Markierung',
'Library badge bookmark': 'Lesezeichen',
'Library badge pin': 'Angepinnt',
'Publication version': 'v{{version}}',
'Publication sections_one': '{{count}} Abschnitt',
'Publication sections_other': '{{count}} Abschnitte',

2
src/i18n/locales/en.ts

@ -1689,6 +1689,8 @@ export default { @@ -1689,6 +1689,8 @@ export default {
'Library badge my booklist': 'On my booklist',
'Library badge comment': 'Comment',
'Library badge highlight': 'Highlight',
'Library badge bookmark': 'Bookmark',
'Library badge pin': 'Pin',
'Add to my booklist': 'Add to my booklist',
'Remove from my booklist': 'Remove from my booklist',
'Add to my booklist failed': 'Failed to add to booklist',

71
src/lib/library-publication-index.test.ts

@ -39,6 +39,65 @@ function indexEvent(d: string, aTags: string[], id = d.padEnd(64, '0').slice(0, @@ -39,6 +39,65 @@ function indexEvent(d: string, aTags: string[], id = d.padEnd(64, '0').slice(0,
}
describe('library-publication-index', () => {
it('matches comments and highlights by root event id', () => {
const root = indexEvent('book', [`30041:${PK}:intro`])
const indexByAddress = buildIndexByAddress([root])
const comment: Event = {
id: '8'.repeat(64),
kind: ExtendedKind.COMMENT,
pubkey: 'f'.repeat(64),
created_at: 50,
content: 'nice book',
tags: [['e', root.id]],
sig: 'e'.repeat(128)
}
const highlight: Event = {
id: '9'.repeat(64),
kind: kinds.Highlights,
pubkey: 'f'.repeat(64),
created_at: 50,
content: 'quote',
tags: [['e', root.id]],
sig: 'e'.repeat(128)
}
const engagement = buildEngagementMapsFromEvents([], [comment], [highlight])
const engaged = filterEngagedPublications([root], indexByAddress, engagement)
expect(engaged).toHaveLength(1)
expect(engaged[0].hasComment).toBe(true)
expect(engaged[0].hasHighlight).toBe(true)
})
it('matches bookmark and pin lists from any author', () => {
const rootAddr = `30040:${PK}:book`
const root = indexEvent('book', [`30041:${PK}:intro`])
const indexByAddress = buildIndexByAddress([root])
const bookmarkList: Event = {
id: 'b'.repeat(64),
kind: kinds.BookmarkList,
pubkey: 'f'.repeat(64),
created_at: 100,
content: '',
tags: [['a', rootAddr]],
sig: 'd'.repeat(128)
}
const pinList: Event = {
id: 'p'.repeat(64),
kind: 10001,
pubkey: 'e'.repeat(64),
created_at: 100,
content: '',
tags: [['e', root.id]],
sig: 'd'.repeat(128)
}
const engagement = buildEngagementMapsFromEvents([], [], [], undefined, undefined, null, [
bookmarkList
], [pinList])
const engaged = filterEngagedPublications([root], indexByAddress, engagement)
expect(engaged).toHaveLength(1)
expect(engaged[0].hasBookmark).toBe(true)
expect(engaged[0].hasPin).toBe(true)
})
it('matches engagement on nested 30041 addresses', () => {
const leafAddr = `30041:${PK}:chapter-1`
const childAddr = `30040:${PK}:part-1`
@ -147,6 +206,8 @@ describe('library-publication-index', () => { @@ -147,6 +206,8 @@ describe('library-publication-index', () => {
hasMyHighlight: false,
hasComment: false,
hasHighlight: false,
hasBookmark: false,
hasPin: false,
engagementCount: 1
}
]
@ -358,6 +419,8 @@ describe('library-publication-index', () => { @@ -358,6 +419,8 @@ describe('library-publication-index', () => {
hasMyHighlight: false,
hasComment: false,
hasHighlight: false,
hasBookmark: false,
hasPin: false,
engagementCount: 0
},
{
@ -370,6 +433,8 @@ describe('library-publication-index', () => { @@ -370,6 +433,8 @@ describe('library-publication-index', () => {
hasMyHighlight: false,
hasComment: false,
hasHighlight: false,
hasBookmark: false,
hasPin: false,
engagementCount: 0
},
{
@ -382,6 +447,8 @@ describe('library-publication-index', () => { @@ -382,6 +447,8 @@ describe('library-publication-index', () => {
hasMyHighlight: false,
hasComment: true,
hasHighlight: false,
hasBookmark: false,
hasPin: false,
engagementCount: 1
},
{
@ -394,6 +461,8 @@ describe('library-publication-index', () => { @@ -394,6 +461,8 @@ describe('library-publication-index', () => {
hasMyHighlight: false,
hasComment: false,
hasHighlight: false,
hasBookmark: false,
hasPin: false,
engagementCount: 0
}
]
@ -479,6 +548,8 @@ describe('library-publication-index', () => { @@ -479,6 +548,8 @@ describe('library-publication-index', () => {
hasMyHighlight: false,
hasComment: false,
hasHighlight: false,
hasBookmark: false,
hasPin: false,
engagementCount: 0
}
const filtered = filterLibraryPublicationsByUser([entry], viewerPk, {

202
src/lib/library-publication-index.ts

@ -54,6 +54,8 @@ const ENGAGEMENT_FETCH_TIMEOUT_MS = 25_000 @@ -54,6 +54,8 @@ const ENGAGEMENT_FETCH_TIMEOUT_MS = 25_000
const LIBRARY_SEARCH_READING_CACHE_LIMIT = 200
export const LIBRARY_RELAY_SEARCH_LIMIT = 100
const LIBRARY_RELAY_SEARCH_TIMEOUT_MS = 28_000
/** NIP-51 pin list (kind 10001). */
const PIN_LIST_KIND = 10001
const QUERY_OPTS = {
globalTimeout: 18_000,
eoseTimeout: 3_000,
@ -74,7 +76,13 @@ export type PublicationEngagementMaps = { @@ -74,7 +76,13 @@ export type PublicationEngagementMaps = {
myHighlightAddresses: Set<string>
myHighlightEventIds: Set<string>
commentAddresses: Set<string>
commentEventIds: Set<string>
highlightAddresses: Set<string>
highlightEventIds: Set<string>
bookmarkAddresses: Set<string>
bookmarkEventIds: Set<string>
pinAddresses: Set<string>
pinEventIds: Set<string>
}
export type LibraryPublicationEntry = {
@ -88,6 +96,8 @@ export type LibraryPublicationEntry = { @@ -88,6 +96,8 @@ export type LibraryPublicationEntry = {
hasMyHighlight: boolean
hasComment: boolean
hasHighlight: boolean
hasBookmark: boolean
hasPin: boolean
engagementCount: number
}
@ -120,9 +130,15 @@ function librarySearchFingerprint(context: LibrarySearchContext): string { @@ -120,9 +130,15 @@ function librarySearchFingerprint(context: LibrarySearchContext): string {
? engagement.labelAddresses.size +
engagement.labelEventIds.size +
engagement.commentAddresses.size +
engagement.commentEventIds.size +
engagement.highlightAddresses.size +
engagement.highlightEventIds.size +
engagement.booklistAddresses.size +
engagement.booklistEventIds.size +
engagement.bookmarkAddresses.size +
engagement.bookmarkEventIds.size +
engagement.pinAddresses.size +
engagement.pinEventIds.size +
engagement.myBooklistAddresses.size +
engagement.myBooklistEventIds.size +
engagement.myCommentAddresses.size +
@ -344,7 +360,9 @@ export function buildEngagementMapsFromEvents( @@ -344,7 +360,9 @@ export function buildEngagementMapsFromEvents(
highlights: Event[],
targetAddresses?: Set<string>,
targetEventIds?: Set<string>,
viewerPubkey?: string | null
viewerPubkey?: string | null,
bookmarkLists: Event[] = [],
pinLists: Event[] = []
): PublicationEngagementMaps {
const labelAddresses = new Set<string>()
const labelEventIds = new Set<string>()
@ -359,7 +377,13 @@ export function buildEngagementMapsFromEvents( @@ -359,7 +377,13 @@ export function buildEngagementMapsFromEvents(
const myHighlightAddresses = new Set<string>()
const myHighlightEventIds = new Set<string>()
const commentAddresses = new Set<string>()
const commentEventIds = new Set<string>()
const highlightAddresses = new Set<string>()
const highlightEventIds = new Set<string>()
const bookmarkAddresses = new Set<string>()
const bookmarkEventIds = new Set<string>()
const pinAddresses = new Set<string>()
const pinEventIds = new Set<string>()
const addressMatches = (addr: string) => !targetAddresses || targetAddresses.has(addr)
const eventIdMatches = (id: string) => !targetEventIds || targetEventIds.has(id.toLowerCase())
@ -407,8 +431,9 @@ export function buildEngagementMapsFromEvents( @@ -407,8 +431,9 @@ export function buildEngagementMapsFromEvents(
commentAddresses.add(tag[1])
if (isViewerEvent) myCommentAddresses.add(tag[1])
}
if (tag[0] === 'e' && tag[1] && eventIdMatches(tag[1]) && isViewerEvent) {
myCommentEventIds.add(tag[1].toLowerCase())
if (tag[0] === 'e' && tag[1] && eventIdMatches(tag[1])) {
commentEventIds.add(tag[1].toLowerCase())
if (isViewerEvent) myCommentEventIds.add(tag[1].toLowerCase())
}
}
}
@ -420,8 +445,31 @@ export function buildEngagementMapsFromEvents( @@ -420,8 +445,31 @@ export function buildEngagementMapsFromEvents(
highlightAddresses.add(tag[1])
if (isViewerEvent) myHighlightAddresses.add(tag[1])
}
if (tag[0] === 'e' && tag[1] && eventIdMatches(tag[1]) && isViewerEvent) {
myHighlightEventIds.add(tag[1].toLowerCase())
if (tag[0] === 'e' && tag[1] && eventIdMatches(tag[1])) {
highlightEventIds.add(tag[1].toLowerCase())
if (isViewerEvent) myHighlightEventIds.add(tag[1].toLowerCase())
}
}
}
for (const ev of bookmarkLists) {
for (const tag of ev.tags) {
if (tag[0] === 'a' && tag[1] && addressMatches(tag[1])) {
bookmarkAddresses.add(tag[1])
}
if (tag[0] === 'e' && tag[1] && eventIdMatches(tag[1])) {
bookmarkEventIds.add(tag[1].toLowerCase())
}
}
}
for (const ev of pinLists) {
for (const tag of ev.tags) {
if (tag[0] === 'a' && tag[1] && addressMatches(tag[1])) {
pinAddresses.add(tag[1])
}
if (tag[0] === 'e' && tag[1] && eventIdMatches(tag[1])) {
pinEventIds.add(tag[1].toLowerCase())
}
}
}
@ -440,7 +488,13 @@ export function buildEngagementMapsFromEvents( @@ -440,7 +488,13 @@ export function buildEngagementMapsFromEvents(
myHighlightAddresses,
myHighlightEventIds,
commentAddresses,
highlightAddresses
commentEventIds,
highlightAddresses,
highlightEventIds,
bookmarkAddresses,
bookmarkEventIds,
pinAddresses,
pinEventIds
}
}
@ -500,13 +554,34 @@ export async function fetchPublicationEngagementMaps( @@ -500,13 +554,34 @@ export async function fetchPublicationEngagementMaps(
const commentWsFilters = addressChunks.map(
(chunk): Filter => ({ kinds: [ExtendedKind.COMMENT], '#A': chunk, limit: chunk.length * 12 })
)
const commentEventFilters = eventIdChunks.map(
(chunk): Filter => ({ kinds: [ExtendedKind.COMMENT], '#e': chunk, limit: chunk.length * 12 })
)
const highlightEventFilters = eventIdChunks.map(
(chunk): Filter => ({ kinds: [kinds.Highlights], '#e': chunk, limit: chunk.length * 12 })
)
const bookmarkAddressFilters = addressChunks.map(
(chunk): Filter => ({ kinds: [kinds.BookmarkList], '#a': chunk, limit: chunk.length * 8 })
)
const bookmarkEventFilters = eventIdChunks.map(
(chunk): Filter => ({ kinds: [kinds.BookmarkList], '#e': chunk, limit: chunk.length * 8 })
)
const pinAddressFilters = addressChunks.map(
(chunk): Filter => ({ kinds: [PIN_LIST_KIND], '#a': chunk, limit: chunk.length * 8 })
)
const pinEventFilters = eventIdChunks.map(
(chunk): Filter => ({ kinds: [PIN_LIST_KIND], '#e': chunk, limit: chunk.length * 8 })
)
const highlightPromise = Promise.all([
useWsEngagement && highlightFilters.length > 0
? queryService.fetchEvents(wsRelays, highlightFilters, QUERY_OPTS)
: Promise.resolve([] as Event[]),
useWsEngagement && highlightEventFilters.length > 0
? queryService.fetchEvents(wsRelays, highlightEventFilters, QUERY_OPTS)
: Promise.resolve([] as Event[]),
fetchHttpEngagementByAddresses(httpRelays, kinds.Highlights, '#a', addressChunks)
]).then(([scoped, bulk]) => dedupeEventsById([...scoped, ...bulk]))
]).then(([scoped, byEvent, bulk]) => dedupeEventsById([...scoped, ...byEvent, ...bulk]))
const labelPromise = Promise.all([
useWsEngagement && labelAddressFilters.length > 0
@ -522,13 +597,38 @@ export async function fetchPublicationEngagementMaps( @@ -522,13 +597,38 @@ export async function fetchPublicationEngagementMaps(
useWsEngagement && commentWsFilters.length > 0
? queryService.fetchEvents(wsRelays, commentWsFilters, QUERY_OPTS)
: Promise.resolve([] as Event[]),
useWsEngagement && commentEventFilters.length > 0
? queryService.fetchEvents(wsRelays, commentEventFilters, QUERY_OPTS)
: Promise.resolve([] as Event[]),
fetchHttpEngagementByAddresses(httpRelays, ExtendedKind.COMMENT, '#A', addressChunks)
]).then(([scoped, bulk]) => dedupeEventsById([...scoped, ...bulk]))
]).then(([scoped, byEvent, bulk]) => dedupeEventsById([...scoped, ...byEvent, ...bulk]))
const bookmarkPromise = Promise.all([
useWsEngagement && bookmarkAddressFilters.length > 0
? queryService.fetchEvents(wsRelays, bookmarkAddressFilters, QUERY_OPTS)
: Promise.resolve([] as Event[]),
useWsEngagement && bookmarkEventFilters.length > 0
? queryService.fetchEvents(wsRelays, bookmarkEventFilters, QUERY_OPTS)
: Promise.resolve([] as Event[]),
fetchHttpEngagementByAddresses(httpRelays, kinds.BookmarkList, '#a', addressChunks)
]).then(([byAddress, byEvent, bulk]) => dedupeEventsById([...byAddress, ...byEvent, ...bulk]))
const [highlights, labels, comments] = await Promise.all([
const pinPromise = Promise.all([
useWsEngagement && pinAddressFilters.length > 0
? queryService.fetchEvents(wsRelays, pinAddressFilters, QUERY_OPTS)
: Promise.resolve([] as Event[]),
useWsEngagement && pinEventFilters.length > 0
? queryService.fetchEvents(wsRelays, pinEventFilters, QUERY_OPTS)
: Promise.resolve([] as Event[]),
fetchHttpEngagementByAddresses(httpRelays, PIN_LIST_KIND, '#a', addressChunks)
]).then(([byAddress, byEvent, bulk]) => dedupeEventsById([...byAddress, ...byEvent, ...bulk]))
const [highlights, labels, comments, bookmarkLists, pinLists] = await Promise.all([
highlightPromise,
labelPromise,
commentPromise
commentPromise,
bookmarkPromise,
pinPromise
])
return buildEngagementMapsFromEvents(
@ -537,7 +637,9 @@ export async function fetchPublicationEngagementMaps( @@ -537,7 +637,9 @@ export async function fetchPublicationEngagementMaps(
dedupeEventsById(highlights),
targetAddresses,
targetEventIds,
options?.viewerPubkey
options?.viewerPubkey,
dedupeEventsById(bookmarkLists),
dedupeEventsById(pinLists)
)
}
@ -546,14 +648,56 @@ function addressHasEngagement( @@ -546,14 +648,56 @@ function addressHasEngagement(
eventId: string | undefined,
maps: PublicationEngagementMaps
): { hasLabel: boolean; hasComment: boolean; hasHighlight: boolean } {
const idLower = eventId?.toLowerCase()
const hasLabel =
maps.labelAddresses.has(address) ||
(eventId ? maps.labelEventIds.has(eventId.toLowerCase()) : false)
const hasComment = maps.commentAddresses.has(address)
const hasHighlight = maps.highlightAddresses.has(address)
maps.labelAddresses.has(address) || (idLower ? maps.labelEventIds.has(idLower) : false)
const hasComment =
maps.commentAddresses.has(address) || (idLower ? maps.commentEventIds.has(idLower) : false)
const hasHighlight =
maps.highlightAddresses.has(address) || (idLower ? maps.highlightEventIds.has(idLower) : false)
return { hasLabel, hasComment, hasHighlight }
}
function collectBookmarkPinFlagsForTarget(
address: string,
eventId: string | undefined,
maps: PublicationEngagementMaps
): { hasBookmark: boolean; hasPin: boolean } {
const idLower = eventId?.toLowerCase()
return {
hasBookmark:
maps.bookmarkAddresses.has(address) || (idLower ? maps.bookmarkEventIds.has(idLower) : false),
hasPin: maps.pinAddresses.has(address) || (idLower ? maps.pinEventIds.has(idLower) : false)
}
}
function targetHasPublicationEngagement(
flags: { hasLabel: boolean; hasComment: boolean; hasHighlight: boolean },
booklistFlags: { hasBooklistLabel: boolean },
bookmarkPinFlags: { hasBookmark: boolean; hasPin: boolean }
): boolean {
return (
flags.hasLabel ||
flags.hasComment ||
flags.hasHighlight ||
booklistFlags.hasBooklistLabel ||
bookmarkPinFlags.hasBookmark ||
bookmarkPinFlags.hasPin
)
}
/** True when a library row has any engagement signal from any author. */
export function publicationEntryHasEngagement(entry: LibraryPublicationEntry): boolean {
return (
entry.hasLabel ||
entry.hasBooklistLabel ||
entry.hasComment ||
entry.hasHighlight ||
entry.hasBookmark ||
entry.hasPin
)
}
function collectLabelNamesForTarget(
address: string,
eventId: string | undefined,
@ -617,6 +761,8 @@ export function buildLibraryPublicationEntry( @@ -617,6 +761,8 @@ export function buildLibraryPublicationEntry(
let hasLabel = false
let hasComment = false
let hasHighlight = false
let hasBookmark = false
let hasPin = false
let hasBooklistLabel = false
let hasMyBooklistLabel = false
let hasMyComment = false
@ -628,6 +774,7 @@ export function buildLibraryPublicationEntry( @@ -628,6 +774,7 @@ export function buildLibraryPublicationEntry(
const indexed = indexByAddress.get(addr)
const flags = addressHasEngagement(addr, indexed?.id, engagement)
const booklistFlags = collectBooklistFlagsForTarget(addr, indexed?.id, engagement)
const bookmarkPinFlags = collectBookmarkPinFlagsForTarget(addr, indexed?.id, engagement)
const myFlags = collectMyEngagementFlagsForTarget(addr, indexed?.id, engagement)
if (flags.hasLabel) {
hasLabel = true
@ -639,15 +786,20 @@ export function buildLibraryPublicationEntry( @@ -639,15 +786,20 @@ export function buildLibraryPublicationEntry(
if (myFlags.hasMyHighlight) hasMyHighlight = true
if (flags.hasComment) hasComment = true
if (flags.hasHighlight) hasHighlight = true
if (flags.hasLabel || flags.hasComment || flags.hasHighlight) engagementCount++
if (bookmarkPinFlags.hasBookmark) hasBookmark = true
if (bookmarkPinFlags.hasPin) hasPin = true
if (targetHasPublicationEngagement(flags, booklistFlags, bookmarkPinFlags)) engagementCount++
}
const rootFlags = addressHasEngagement(rootAddr ?? '', root.id, engagement)
const rootBooklistFlags = collectBooklistFlagsForTarget(rootAddr ?? '', root.id, engagement)
const rootBookmarkPinFlags = collectBookmarkPinFlagsForTarget(rootAddr ?? '', root.id, engagement)
const rootMyFlags = collectMyEngagementFlagsForTarget(rootAddr ?? '', root.id, engagement)
hasLabel = hasLabel || rootFlags.hasLabel
hasComment = hasComment || rootFlags.hasComment
hasHighlight = hasHighlight || rootFlags.hasHighlight
hasBookmark = hasBookmark || rootBookmarkPinFlags.hasBookmark
hasPin = hasPin || rootBookmarkPinFlags.hasPin
hasBooklistLabel = hasBooklistLabel || rootBooklistFlags.hasBooklistLabel
hasMyBooklistLabel = hasMyBooklistLabel || rootBooklistFlags.hasMyBooklistLabel
hasMyComment = hasMyComment || rootMyFlags.hasMyComment
@ -666,6 +818,8 @@ export function buildLibraryPublicationEntry( @@ -666,6 +818,8 @@ export function buildLibraryPublicationEntry(
hasMyHighlight,
hasComment,
hasHighlight,
hasBookmark,
hasPin,
engagementCount
}
}
@ -687,7 +841,7 @@ export function filterEngagedPublications( @@ -687,7 +841,7 @@ export function filterEngagedPublications(
): LibraryPublicationEntry[] {
return getTopLevelIndexEvents(roots)
.map((root) => buildLibraryPublicationEntry(root, indexByAddress, engagement))
.filter((entry) => entry.hasLabel || entry.hasComment || entry.hasHighlight)
.filter((entry) => publicationEntryHasEngagement(entry))
}
export function buildRecentPublicationEntries(
@ -713,7 +867,7 @@ export function computeLibraryFeedRootOrder( @@ -713,7 +867,7 @@ export function computeLibraryFeedRootOrder(
const restRoots: Event[] = []
for (const root of topLevel) {
const entry = buildLibraryPublicationEntry(root, indexByAddress, engagement)
if (entry.hasLabel || entry.hasComment || entry.hasHighlight) {
if (publicationEntryHasEngagement(entry)) {
engagedRoots.push(root)
} else {
restRoots.push(root)
@ -787,7 +941,9 @@ export function pickLibraryPublicationEntries( @@ -787,7 +941,9 @@ export function pickLibraryPublicationEntries(
export function sortLibraryPublications(entries: LibraryPublicationEntry[]): LibraryPublicationEntry[] {
return [...entries].sort((a, b) => {
if (a.hasLabel !== b.hasLabel) return a.hasLabel ? -1 : 1
const aEngaged = publicationEntryHasEngagement(a)
const bEngaged = publicationEntryHasEngagement(b)
if (aEngaged !== bEngaged) return aEngaged ? -1 : 1
if (a.engagementCount !== b.engagementCount) return b.engagementCount - a.engagementCount
return b.event.created_at - a.event.created_at
})
@ -810,7 +966,13 @@ function emptyPublicationEngagementMaps(): PublicationEngagementMaps { @@ -810,7 +966,13 @@ function emptyPublicationEngagementMaps(): PublicationEngagementMaps {
myHighlightAddresses: new Set(),
myHighlightEventIds: new Set(),
commentAddresses: new Set(),
highlightAddresses: new Set()
commentEventIds: new Set(),
highlightAddresses: new Set(),
highlightEventIds: new Set(),
bookmarkAddresses: new Set(),
bookmarkEventIds: new Set(),
pinAddresses: new Set(),
pinEventIds: new Set()
}
}

Loading…
Cancel
Save