A social RSS reader built on the AT Protocol. glean.at
glean atproto atmosphere rss feed social app
14
fork

Configure Feed

Select the types of activity you want to include in your feed.

Filter read articles in recommendations and mark read status

+7 -3
+6 -2
internal/cluster/scoring.go
··· 36 36 Author string 37 37 Summary string 38 38 Published sql.NullTime 39 + IsRead bool 39 40 Score float64 40 41 } 41 42 ··· 218 219 SELECT a.id, a.title, COALESCE(a.url, ''), la.feed_url, COALESCE(f.title, ''), 219 220 COALESCE(f.favicon_url, ''), 220 221 COALESCE(a.author, ''), COALESCE(a.summary, ''), a.published, 222 + COALESCE(rs.is_read, 0), 221 223 COALESCE(la.like_signal, 0) * ? 222 224 + COALESCE(sl.social, 0) * ? 223 225 + EXP(-0.023 * CAST(julianday('now') - julianday(a.published) AS REAL)) * 0.2 ··· 226 228 JOIN articles.articles a ON a.feed_url = la.feed_url AND a.url = la.article_url 227 229 LEFT JOIN articles.feeds f ON f.feed_url = la.feed_url 228 230 LEFT JOIN social_likes sl ON sl.feed_url = la.feed_url AND sl.article_url = la.article_url 231 + LEFT JOIN articles.read_state rs ON rs.article_id = a.id AND rs.user_did = ? 232 + WHERE COALESCE(rs.is_read, 0) = 0 229 233 ORDER BY score DESC, (CASE WHEN a.published > 'now' THEN 1 ELSE 0 END), a.published DESC 230 234 LIMIT ? 231 - `, userDID, userDID, userDID, userDID, userDID, userDID, w.WLike, w.WSocial, limit) 235 + `, userDID, userDID, userDID, userDID, userDID, userDID, w.WLike, w.WSocial, userDID, limit) 232 236 if err != nil { 233 237 return nil, err 234 238 } ··· 238 242 for rows.Next() { 239 243 rec := &ArticleRecommendation{} 240 244 if err := rows.Scan(&rec.ArticleID, &rec.Title, &rec.URL, &rec.FeedURL, &rec.FeedTitle, 241 - &rec.FaviconURL, &rec.Author, &rec.Summary, &rec.Published, &rec.Score); err != nil { 245 + &rec.FaviconURL, &rec.Author, &rec.Summary, &rec.Published, &rec.IsRead, &rec.Score); err != nil { 242 246 return nil, err 243 247 } 244 248 recs = append(recs, rec)
+1 -1
internal/tmpl/partials/recommendation-article-card.html
··· 3 3 <div class="flex items-start justify-between gap-4"> 4 4 <div class="min-w-0 flex-1"> 5 5 <div class="flex items-center gap-2"> 6 - <span class="w-2 h-2 rounded-full bg-spot-green shrink-0"></span> 6 + {{if not .IsRead}}<span class="w-2 h-2 rounded-full bg-spot-green shrink-0"></span>{{end}} 7 7 <a href="/articles/{{.ArticleID}}" class="font-bold text-spot-text hover:text-spot-green transition text-lg leading-tight">{{.Title}}</a> 8 8 </div> 9 9 <div class="text-sm text-spot-secondary mt-1 flex items-center gap-2">