Public like counts on every card (#95 part B) - #105
Merged
Conversation
Counting likes per concept needs an index keyed by concept_id (the existing one is keyed by user_id). Partial on liked_at is not null so it only covers likes.
Return the count of likes by OTHER users on the day's concept; the client adds the viewer's own like on top, so a like/unlike is an instant +/-1.
The like number is shown wherever a card appears (Today, History, Saved), so the learned and saved rows now include the same others'-likes count.
Parse the server's others'-likes count into Concept.likeCount and into the learned/saved records, so every surface can render it.
Add a small flame+number badge, and show it in the concept action bar next to the like button: others' likes plus the viewer's own (optimistic), hidden at zero. Tapping like ticks it +/-1 instantly.
The count appears wherever a card is shown, per the issue: each row adds the viewer's own like to the server's others'-count and hides it at zero.
Match the codebase's memoisation pattern (cf. learnedIds in ProgressContext) so the liked-set isn't rebuilt on every render.
This was referenced Sep 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part B of #95 — turn Like into a public like count ("how many people liked this card"), shown wherever a card appears, hidden at zero, and instant. Builds on the responsiveness fix in #104 (part A).
Data model — no new table
Likes are already stored per-user in
concept_interactions.liked_at. The public count is just an aggregate; migration 0009 adds a by-concept partial index so it's fast (the existing index is keyed by user).Design that keeps it responsive
The backend returns the count of other users' likes (excludes the viewer); the client adds the viewer's own like on top:
So a like/unlike is an instant +1 / −1 with no round trip, and it reconciles on the next load — no baseline bookkeeping.
Backend
0009index onconcept_interactions (concept_id) where liked_at is not null.like_count(others') added to/v1/daily, and to thelearnedandsavedlists on/v1/me/state.Mobile
likeCountflows throughConcept,LearnedRecord,SavedConcept.LikeCountbadge (🔥 N), rendered on the Today card (next to the flame), History rows, and Saved rows.Decisions applied
Ships as
Backend is additive (safe to deploy before the app; old apps ignore
like_count). Mobile is JS-only (no native module) — ships over the air.Verification
pytest→ 89 passed.npx tsc --noEmit→ clean.