feat(activity): per-viewer archive and hide
Two new per-viewer flags on activities, mirroring the heart/done shape: - ARCHIVE: any viewer (incl. the owner) can archive a row. Out of sight by default but the permalink still resolves. For owners, archive also filters the row out of their /<bruker>/liste public page — "I'm done sharing this." - HIDE: only non-owners. "This doesn't appeal to me." Endpoint returns 400 cannot_hide_own when the owner tries it (they should delete or archive instead). Both default-filtered from GET /api/activities. Opt-in via query params with three modes each: exclude (default), include (1), only. ?archived=1&hidden=1 includes both; ?archived=only shows just the archive. The list endpoint composes the SQL filters per-viewer (anonymous viewers have no rows in either table → no-ops). Schema: two new tables user_archived_activities and user_hidden_activities, both composite-PK on (user_id, activity_id), cascade on both refs. Same shape as the existing engagement tables. Types: viewer_archived + viewer_hidden on every Activity variant. viewer_hidden on private is always false (the endpoint refuses); docstring on the type explains why. Bulk lookups extended so the list endpoint stays at constant queries. Single-row paths get per-row viewerArchived/viewerHidden helpers. fetchRowForViewer keeps preserving the viewer's custom sort_position on toggles. UI: two new buttons in ActivityRow's action row — "📦 Arkiver" / "📦 Arkivert" (everyone) and "🙈 Gjem" / "🙈 Skjult" (non-owners only). Two new checkboxes near the search field on /hjem: "📦 Vis arkivert" and "🙈 Vis skjult". Toggling either re-fetches from the server because the filtering is server-side. When an archive/hide flips the row out of the current view, Home.svelte triggers a refetch so the row disappears in real time. Public-list endpoint (/api/users/:bruker/list) also filters out the owner's own archived rows — consistent with "archive means filed away from active view." Tests: 3 new in engagement.test.ts — viewer archives + per-viewer isolation, owner's archive filters their public list, hide refuses on own row + ?hidden=only path. Suite goes 102 → 105.
This commit is contained in:
parent
ef02b3f585
commit
6e005fc2d7
8 changed files with 418 additions and 7 deletions
|
|
@ -223,6 +223,13 @@ export interface ActivityPublic {
|
|||
done_count: number;
|
||||
/** True when the authenticated viewer has marked this activity done. */
|
||||
viewer_done: boolean;
|
||||
/** True when the authenticated viewer has archived this activity for
|
||||
* themselves. Default-filtered from the main and public lists; the
|
||||
* client opts in via ?archived=1 to see them. Owner-archiving works too. */
|
||||
viewer_archived: boolean;
|
||||
/** True when the authenticated viewer has hidden this activity. Only
|
||||
* non-owners can hide. Default-filtered from lists; opt-in via ?hidden=1. */
|
||||
viewer_hidden: boolean;
|
||||
/** Effective sort position for THIS viewer: a custom value if they've
|
||||
* dragged this row, otherwise -created_at so unsorted/new rows float
|
||||
* to the top. Used by the client to compute drop-target midpoints. */
|
||||
|
|
@ -250,6 +257,8 @@ export interface ActivitySemi {
|
|||
viewer_bookmarked: boolean;
|
||||
done_count: number;
|
||||
viewer_done: boolean;
|
||||
viewer_archived: boolean;
|
||||
viewer_hidden: boolean;
|
||||
/** Effective sort position for THIS viewer: a custom value if they've
|
||||
* dragged this row, otherwise -created_at so unsorted/new rows float
|
||||
* to the top. Used by the client to compute drop-target midpoints. */
|
||||
|
|
@ -275,6 +284,11 @@ export interface ActivityPrivate {
|
|||
// for private rows. viewer_done reflects the owner's own state.
|
||||
done_count: number;
|
||||
viewer_done: boolean;
|
||||
// Private rows are owner-only, so viewer_hidden is always false (the
|
||||
// hide endpoint refuses on your own activities). viewer_archived is the
|
||||
// owner archiving their own private todo.
|
||||
viewer_archived: boolean;
|
||||
viewer_hidden: boolean;
|
||||
/** Effective sort position for THIS viewer: a custom value if they've
|
||||
* dragged this row, otherwise -created_at so unsorted/new rows float
|
||||
* to the top. Used by the client to compute drop-target midpoints. */
|
||||
|
|
@ -307,6 +321,8 @@ export interface ActivityFriends {
|
|||
viewer_bookmarked: boolean;
|
||||
done_count: number;
|
||||
viewer_done: boolean;
|
||||
viewer_archived: boolean;
|
||||
viewer_hidden: boolean;
|
||||
/** Effective sort position for THIS viewer: a custom value if they've
|
||||
* dragged this row, otherwise -created_at so unsorted/new rows float
|
||||
* to the top. Used by the client to compute drop-target midpoints. */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue