| 1 | /**
|
|---|
| 2 | * ap-cirkel.js — de Cirkel (stap 10 van shaer-drc).
|
|---|
| 3 | *
|
|---|
| 4 | * De feed van uitgelichte accounts (auto_boost) plus zelf gebooste posts,
|
|---|
| 5 | * en de twee lijstjes eromheen. Leest ap_timeline, ap_following en
|
|---|
| 6 | * ap_my_reactions; schrijft niets. De enige snede tot nu toe zonder ook maar
|
|---|
| 7 | * een werktuig uit de dienstlaag: alleen db.
|
|---|
| 8 | */
|
|---|
| 9 | import db, { isoSql } from '../config/database.js';
|
|---|
| 10 |
|
|---|
| 11 | // ── Cirkel = posts from the accounts you auto-boost ("feature an artist") ──
|
|---|
| 12 | let _abCount, _cirkelPosts, _cirkelMembers;
|
|---|
| 13 | export function autoBoostCount(slug) {
|
|---|
| 14 | try { if (!_abCount) _abCount = db.prepare('SELECT COUNT(*) AS n FROM ap_following WHERE slug = ? AND auto_boost = 1'); return _abCount.get(slug).n; } catch { return 0; }
|
|---|
| 15 | }
|
|---|
| 16 | export function getCirkelPosts(slug, limit, offset) {
|
|---|
| 17 | try {
|
|---|
| 18 | // Cirkel = posts from featured (auto_boost) accounts + posts you boosted
|
|---|
| 19 | // (t.boosted), mixed by date. One row per note in ap_timeline → no duplicates.
|
|---|
| 20 | if (!_cirkelPosts) _cirkelPosts = db.prepare(`
|
|---|
| 21 | SELECT t.id, t.author_uri, t.author_name, t.author_handle, t.author_icon, t.author_url,
|
|---|
| 22 | t.content, t.url, t.published, t.media_json, t.nsfw, t.cw,
|
|---|
| 23 | (rb.target_uri IS NOT NULL) AS boosted
|
|---|
| 24 | FROM ap_timeline t
|
|---|
| 25 | LEFT JOIN ap_following f ON f.slug = t.slug AND f.actor_uri = t.author_uri
|
|---|
| 26 | -- Uit de tussentabel, niet uit t.boosted: die kolom is een afgeleide. De
|
|---|
| 27 | -- UNIQUE(site_slug, target_uri, kind) garandeert hoogstens één match, dus
|
|---|
| 28 | -- deze join kan geen rijen verdubbelen.
|
|---|
| 29 | LEFT JOIN ap_my_reactions rb ON rb.site_slug = t.slug AND rb.target_uri = t.id AND rb.kind = 'boost'
|
|---|
| 30 | WHERE t.slug = ? AND (f.auto_boost = 1 OR rb.target_uri IS NOT NULL)
|
|---|
| 31 | ORDER BY ${isoSql('COALESCE(t.published, t.created_at)')} DESC, t.rowid DESC
|
|---|
| 32 | LIMIT ? OFFSET ?`);
|
|---|
| 33 | return _cirkelPosts.all(slug, limit || 60, offset || 0);
|
|---|
| 34 | } catch { return []; }
|
|---|
| 35 | }
|
|---|
| 36 | export function getCirkelMembers(slug) {
|
|---|
| 37 | try { if (!_cirkelMembers) _cirkelMembers = db.prepare('SELECT name, url, icon FROM ap_following WHERE slug = ? AND auto_boost = 1 ORDER BY name'); return _cirkelMembers.all(slug); } catch { return []; }
|
|---|
| 38 | }
|
|---|