- Création lib/platformCommissions.ts : configuration centralisée des commissions - Articles : 800 sats (700 auteur, 100 plateforme) - Avis : 70 sats (49 lecteur, 21 plateforme) - Sponsoring : 0.046 BTC (0.042 auteur, 0.004 plateforme) - Validation des montants à chaque étape : - Publication : vérification du montant avant publication - Paiement : vérification du montant avant acceptation - Erreurs explicites si montant incorrect - Tracking des commissions sur Nostr : - Tags author_amount et platform_commission dans événements - Interface ContentDeliveryTracking étendue - Traçabilité complète pour audit - Logs structurés avec informations de commission - Documentation complète du système Les commissions sont maintenant systématiques, validées et traçables.
119 lines
3.5 KiB
TypeScript
119 lines
3.5 KiB
TypeScript
import type { Article } from '@/types/nostr'
|
|
import type { ArticleFilters, SortOption } from '@/components/ArticleFilters'
|
|
|
|
/**
|
|
* Filter articles based on search query
|
|
*/
|
|
export function filterArticlesBySearch(articles: Article[], searchQuery: string): Article[] {
|
|
if (!searchQuery.trim()) {
|
|
return articles
|
|
}
|
|
|
|
const query = searchQuery.toLowerCase().trim()
|
|
|
|
return articles.filter((article) => {
|
|
const titleMatch = article.title.toLowerCase().includes(query)
|
|
const previewMatch = article.preview.toLowerCase().includes(query)
|
|
const contentMatch = article.content.toLowerCase().includes(query)
|
|
|
|
return titleMatch || previewMatch || contentMatch
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Filter articles based on filters (author, category)
|
|
*/
|
|
export function filterArticles(articles: Article[], filters: ArticleFilters): Article[] {
|
|
let filtered = articles
|
|
|
|
// Exclude presentation articles from standard article lists
|
|
filtered = filtered.filter((article) => !article.isPresentation)
|
|
|
|
// Only show articles with valid categories (science-fiction or scientific-research)
|
|
filtered = filtered.filter((article) => {
|
|
return article.category === 'science-fiction' || article.category === 'scientific-research'
|
|
})
|
|
|
|
// Filter by category
|
|
if (filters.category && filters.category !== 'all') {
|
|
filtered = filtered.filter((article) => article.category === filters.category)
|
|
}
|
|
|
|
// Filter by author
|
|
if (filters.authorPubkey) {
|
|
filtered = filtered.filter((article) => article.pubkey === filters.authorPubkey)
|
|
}
|
|
|
|
return filtered
|
|
}
|
|
|
|
/**
|
|
* Get author sponsoring from their presentation article
|
|
* We need to look up the sponsoring from presentation articles
|
|
* For now, we'll use a cache or extract from already loaded articles
|
|
*/
|
|
function getAuthorSponsoringFromCache(
|
|
pubkey: string,
|
|
presentationArticles: Map<string, Article>
|
|
): number {
|
|
const presentation = presentationArticles.get(pubkey)
|
|
return presentation?.isPresentation ? presentation.totalSponsoring ?? 0 : 0
|
|
}
|
|
|
|
/**
|
|
* Sort articles based on sort option
|
|
* Default sort: by sponsoring (descending) then by date (newest first)
|
|
*/
|
|
export function sortArticles(
|
|
articles: Article[],
|
|
sortBy: SortOption,
|
|
presentationArticles?: Map<string, Article>
|
|
): Article[] {
|
|
const sorted = [...articles]
|
|
const presentationMap = presentationArticles ?? new Map<string, Article>()
|
|
|
|
switch (sortBy) {
|
|
case 'oldest':
|
|
return sorted.sort((a, b) => a.createdAt - b.createdAt)
|
|
|
|
case 'newest':
|
|
default:
|
|
// Default: sort by sponsoring (descending) then by date (newest first)
|
|
return sorted.sort((a, b) => {
|
|
const sponsoringA = getAuthorSponsoringFromCache(a.pubkey, presentationMap)
|
|
const sponsoringB = getAuthorSponsoringFromCache(b.pubkey, presentationMap)
|
|
|
|
// First sort by sponsoring (descending)
|
|
if (sponsoringA !== sponsoringB) {
|
|
return sponsoringB - sponsoringA
|
|
}
|
|
|
|
// Then sort by date (newest first)
|
|
return b.createdAt - a.createdAt
|
|
})
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Apply all filters and sorting to articles
|
|
*/
|
|
export function applyFiltersAndSort(
|
|
articles: Article[],
|
|
searchQuery: string,
|
|
filters: ArticleFilters,
|
|
presentationArticles?: Map<string, Article>
|
|
): Article[] {
|
|
let result = articles
|
|
|
|
// First apply search filter
|
|
result = filterArticlesBySearch(result, searchQuery)
|
|
|
|
// Then apply other filters
|
|
result = filterArticles(result, filters)
|
|
|
|
// Finally apply sorting (with presentation articles for sponsoring lookup)
|
|
result = sortArticles(result, filters.sortBy, presentationArticles)
|
|
|
|
return result
|
|
}
|