Enhance FeedService filtering logic

- Added a watch function in useFeed to log updates to filtered posts,
aiding in debugging.
- Updated content filters to include text notes in announcements and
marketplace presets, ensuring broader content visibility.
- Enhanced FeedService to log detailed information during custom
filtering, improving traceability of filtering logic.
- Modified Home.vue to always use custom filters for better consistency
in feed display.

These changes improve the reactivity, flexibility, and clarity of the
feed system, enhancing the overall user experience.
This commit is contained in:
padreug 2025-09-16 22:03:37 +02:00
parent 7025ea81c6
commit f05398fa9e
4 changed files with 55 additions and 19 deletions

View file

@ -1,4 +1,4 @@
import { computed, ref, onMounted, onUnmounted } from 'vue'
import { computed, ref, onMounted, onUnmounted, watch } from 'vue'
import { injectService, SERVICE_TOKENS } from '@/core/di-container'
import type { FeedService, FeedConfig, ContentFilter } from '../services/FeedService'
@ -78,6 +78,11 @@ export function useFeed(config: UseFeedConfig) {
stopAutoRefresh()
})
// Debug posts reactivity
watch(filteredPosts, (newPosts) => {
console.log('useFeed: Posts updated, count:', newPosts.length)
}, { immediate: true })
return {
posts: filteredPosts,
isLoading: feedService?.isLoading ?? ref(false),

View file

@ -117,7 +117,8 @@ export const FILTER_PRESETS: Record<string, ContentFilter[]> = {
],
announcements: [
CONTENT_FILTERS.adminAnnouncements
CONTENT_FILTERS.adminAnnouncements,
CONTENT_FILTERS.textNotes // Include all text posts as fallback
],
community: [
@ -129,7 +130,8 @@ export const FILTER_PRESETS: Record<string, ContentFilter[]> = {
marketplace: [
CONTENT_FILTERS.marketStalls,
CONTENT_FILTERS.marketProducts,
CONTENT_FILTERS.marketGeneral
CONTENT_FILTERS.marketGeneral,
CONTENT_FILTERS.textNotes // Include text posts that may contain marketplace content
],
social: [

View file

@ -9,6 +9,7 @@ export interface FeedPost {
pubkey: string
content: string
created_at: number
kind: number
tags: string[][]
mentions: string[]
isReply: boolean
@ -124,6 +125,7 @@ export class FeedService extends BaseService {
if (config.feedType === 'custom' && config.contentFilters) {
// Use custom content filters
// Using custom content filters
for (const contentFilter of config.contentFilters) {
const filter: Filter = {
kinds: contentFilter.kinds,
@ -131,11 +133,18 @@ export class FeedService extends BaseService {
}
// Apply author filtering if specified
if (contentFilter.filterByAuthor === 'admin' && config.adminPubkeys?.length) {
if (contentFilter.filterByAuthor === 'admin') {
if (config.adminPubkeys?.length) {
filter.authors = config.adminPubkeys
// Using admin authors for filtering
} else {
// No admin pubkeys configured - include all authors for admin filters
// No admin pubkeys configured - include all authors
}
} else if (contentFilter.filterByAuthor === 'exclude-admin' && config.adminPubkeys?.length) {
// Note: Nostr doesn't support negative filters natively,
// we'll filter these out in post-processing
// Will exclude admin in post-processing
}
filters.push(filter)
@ -152,10 +161,9 @@ export class FeedService extends BaseService {
if (config.adminPubkeys && config.adminPubkeys.length > 0) {
filter.authors = config.adminPubkeys
} else {
// No admin pubkeys configured for announcements - don't subscribe
console.log('No admin pubkeys configured for announcements feed')
this._isLoading.value = false
return
// No admin pubkeys configured - fall back to all text posts
console.log('No admin pubkeys configured for announcements feed, showing all posts')
// filter.authors remains undefined, so all authors are included
}
}
@ -225,6 +233,7 @@ export class FeedService extends BaseService {
pubkey: event.pubkey,
content: event.content,
created_at: event.created_at,
kind: event.kind,
tags: event.tags || [],
mentions: event.tags?.filter((tag: string[]) => tag[0] === 'p').map((tag: string[]) => tag[1]) || [],
isReply: event.tags?.some((tag: string[]) => tag[0] === 'e' && tag[3] === 'reply') || false,
@ -261,21 +270,30 @@ export class FeedService extends BaseService {
// For custom content filters, check if event matches any active filter
if (config.feedType === 'custom' && config.contentFilters) {
return config.contentFilters.some(filter => {
console.log('FeedService: Using custom filters, count:', config.contentFilters.length)
const result = config.contentFilters.some(filter => {
console.log('FeedService: Checking filter:', filter.id, 'kinds:', filter.kinds, 'filterByAuthor:', filter.filterByAuthor)
// Check if event kind matches
if (!filter.kinds.includes(event.kind)) {
console.log('FeedService: Kind mismatch, event kind:', event.kind, 'filter kinds:', filter.kinds)
return false
}
// Apply author filtering
if (filter.filterByAuthor === 'admin') {
console.log('FeedService: Admin filter, isAdminPost:', isAdminPost)
return isAdminPost
} else if (filter.filterByAuthor === 'exclude-admin') {
console.log('FeedService: Exclude admin filter, isAdminPost:', isAdminPost)
return !isAdminPost
}
console.log('FeedService: Filter passed all checks')
return true
})
console.log('FeedService: Custom filter result:', result)
return result
}
// Legacy feed type handling
@ -326,16 +344,27 @@ export class FeedService extends BaseService {
* Get filtered posts for specific feed type
*/
getFilteredPosts(config: FeedConfig): FeedPost[] {
return this._posts.value
.filter(post => this.shouldIncludeEvent({
console.log('FeedService: getFilteredPosts called, total posts:', this._posts.value.length, 'config:', config.feedType)
const filtered = this._posts.value
.filter(post => {
const shouldInclude = this.shouldIncludeEvent({
id: post.id,
pubkey: post.pubkey,
content: post.content,
created_at: post.created_at,
kind: post.kind,
tags: post.tags
} as NostrEvent, config))
} as NostrEvent, config)
if (!shouldInclude) {
console.log('FeedService: Post filtered out in getFilteredPosts:', post.id)
}
return shouldInclude
})
.sort((a, b) => b.created_at - a.created_at)
.slice(0, config.maxPosts || 100)
console.log('FeedService: getFilteredPosts returning', filtered.length, 'posts')
return filtered
}
/**

View file

@ -59,7 +59,7 @@ const feedType = computed(() => {
for (const [presetName, presetFilters] of Object.entries(FILTER_PRESETS)) {
if (presetFilters.length === selectedFilters.value.length &&
presetFilters.every(pf => selectedFilters.value.some(sf => sf.id === pf.id))) {
return presetName === 'all' ? 'all' : 'custom'
return 'custom' // Always use custom for proper filtering
}
}