84 lines
2.4 KiB
TypeScript
84 lines
2.4 KiB
TypeScript
import type { Article } from '@/types/nostr'
|
|
|
|
/**
|
|
* Find similar articles based on category and title keywords
|
|
*/
|
|
export function findSimilarArticles(currentArticle: Article, allArticles: Article[], limit: number = 3): Article[] {
|
|
if (!currentArticle.category) {
|
|
return []
|
|
}
|
|
|
|
const currentTitleWords = extractKeywords(currentArticle.title)
|
|
const similar = allArticles
|
|
.filter((article) => {
|
|
if (article.id === currentArticle.id || article.isPresentation) {
|
|
return false
|
|
}
|
|
if (article.category !== currentArticle.category) {
|
|
return false
|
|
}
|
|
const articleTitleWords = extractKeywords(article.title)
|
|
return hasCommonKeywords(currentTitleWords, articleTitleWords)
|
|
})
|
|
.sort((a, b) => {
|
|
const aWords = extractKeywords(a.title)
|
|
const bWords = extractKeywords(b.title)
|
|
const aScore = countCommonKeywords(currentTitleWords, aWords)
|
|
const bScore = countCommonKeywords(currentTitleWords, bWords)
|
|
return bScore - aScore
|
|
})
|
|
.slice(0, limit)
|
|
|
|
return similar
|
|
}
|
|
|
|
/**
|
|
* Find articles by the same author
|
|
*/
|
|
export function findAuthorArticles(currentArticle: Article, allArticles: Article[], limit: number = 3): Article[] {
|
|
return allArticles
|
|
.filter((article) => {
|
|
if (article.id === currentArticle.id || article.isPresentation) {
|
|
return false
|
|
}
|
|
return article.pubkey === currentArticle.pubkey
|
|
})
|
|
.sort((a, b) => b.createdAt - a.createdAt)
|
|
.slice(0, limit)
|
|
}
|
|
|
|
/**
|
|
* Find articles in the same category
|
|
*/
|
|
export function findCategoryArticles(currentArticle: Article, allArticles: Article[], limit: number = 3): Article[] {
|
|
if (!currentArticle.category) {
|
|
return []
|
|
}
|
|
|
|
return allArticles
|
|
.filter((article) => {
|
|
if (article.id === currentArticle.id || article.isPresentation) {
|
|
return false
|
|
}
|
|
return article.category === currentArticle.category
|
|
})
|
|
.sort((a, b) => b.createdAt - a.createdAt)
|
|
.slice(0, limit)
|
|
}
|
|
|
|
function extractKeywords(text: string): string[] {
|
|
return text
|
|
.toLowerCase()
|
|
.split(/\s+/)
|
|
.filter((word) => word.length > 3)
|
|
.filter((word, index, array) => array.indexOf(word) === index)
|
|
}
|
|
|
|
function hasCommonKeywords(words1: string[], words2: string[]): boolean {
|
|
return words1.some((word) => words2.includes(word))
|
|
}
|
|
|
|
function countCommonKeywords(words1: string[], words2: string[]): number {
|
|
return words1.filter((word) => words2.includes(word)).length
|
|
}
|