Repository navigation
feat(ui): POC C — Discover inside the agenda (nearby scope) - #676
Closed
MichaelDimmitt wants to merge 5 commits into
Closed
MichaelDimmitt wants to merge 5 commits into
MichaelDimmitt wants to merge 5 commits into
Conversation
Issue huddlz-hq#670 asks for several competing proofs of concept, each as its own draft PR, so one can be chosen and the rest declined. This is the shared brief those PRs are built from: the problem, what the code already does, one section per variant with its own task list, and the rubric they are all judged against. Records three findings that shape the variants: the return_to plumbing is already complete and safe but only the huddl page's RSVP button produces such a link; the agenda already loads both scopes every render to feed its chip counts; and the agenda has no query for huddlz outside a person's groups. Part of huddlz-hq#670
The POC variants are compared partly on whether people want to use them, so a variant that looks unfinished loses Desirable and Delightful for reasons unrelated to its idea. Ask each one to polish the surface it changes, and keep the scope discipline pointed at everything else. Part of huddlz-hq#670
3 of 8 tasks
The agenda only ever showed huddlz the person already has a relationship to, so somebody who signs in looking for something to go to has to leave for /discover. This adds a third scope beside RSVPs and Groups, showing upcoming huddlz near their home search location that they have not responded to, with no filters to configure. Nearby reuses Discover's query whole rather than adding a second search path: the same :search action, the same upcoming date filter and the same PostGIS distance filter, with no relationship argument so it reaches huddlz the person has nothing to do with. Results are put into the agenda's own entry shape, so the existing day grouping, status logic and list rendering draw them unchanged — a stranger's huddl reads as "No RSVP". - parse_scope/2 now takes the view mode: nearby is agenda-only, since a stranger's huddl is not a calendar fact and does not belong in a month cell. scope_param/2 drops the param from links leaving the agenda. - handle_params/3 is split: it loads the two synchronous scopes and sets URL state, and put_view_state/1 derives everything the views draw from whichever scope is selected. handle_async/3 calls put_view_state/1 again, so the async scope redraws through exactly the same path as the synchronous ones. A stale-ref guard drops a late reply. - The Nearby chip carries no count. RSVPs and Groups are counted by comparing two in-memory lists; a paginated search cannot be counted the same way, and a number arriving a beat late reads as a bug. - Three states the other scopes do not have, each answered in place: no saved location points at /profile, a search in flight draws placeholder rows in the agenda's shape, and nothing in range offers Discover. - The window is the agenda's existing @agenda_days, so the scopes stay comparable; the search overfills it, so Nearby never paginates. Part of huddlz-hq#670
Fill in the Discover-inside-the-agenda section: the measured click count (2, the same as the baseline — the win is controls to ignore, not clicks), how the chip-count and sync-vs-async walls were resolved, where the design strained, and an honest answer on whether the agenda stayed calm. Part of huddlz-hq#670
MichaelDimmitt
force-pushed
the
poc/670-discover-in-agenda
branch
from
October 9, 2026 03:46
8ecd458 to
e7b7cf0
Compare
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.
POC variant C for #67 8000 0: bring Discover's results into
/agendaas a third scope besideRSVPs and Groups, so a person who signs in looking for something to go to does not have to
leave for
/discover.Summary
One new chip, and one structural change behind it. The agenda used to derive everything it
draws inside
handle_params/3, which only works when every scope is synchronous:put_view_state/1is the whole answer to sync-vs-async: the async scope redraws throughexactly the code path the synchronous ones use, so there is no second rendering path and
no duplicated day-grouping logic.
The query is Discover's, borrowed whole rather than written again:
Nothing about day grouping, status logic or list rendering is new — nearby entries enter the
agenda's existing shape and the existing code draws them.
<div class="chip-group cal-scope"> <.chip id="calendar-scope-mine" count={@counts.mine}>RSVPs</.chip> <.chip id="calendar-scope-groups" count={@counts.groups}>Groups</.chip> + <.chip id="calendar-scope-nearby" count={@counts.nearby}>Nearby</.chip> # nil -> no count </div> +<p id="calendar-nearby-note">Upcoming huddlz within 25 miles of <b>St. Augustine, FL</b> + that you haven't responded to. [Search all huddlz →]</p>The two walls the spec flagged, and how they were resolved:
scope_counts/4compares two in-memory lists; a paginated async searchcannot be counted that way. Resolved by making counts optional per scope:
counts.nearbyisnil, and<.chip>already omits the count span fornil, so nocomponent change was needed. Counting after the search landed was rejected — a number
that appears a beat after the chip row paints reads as a bug. The cost is a permanently
asymmetric chip row ("RSVPs 2 · Groups 3 · Nearby"), not a polish item.
put_view_state/1split above, with a stale-refguard so a late reply from a scope the person has already left is dropped. The agenda's own
two scopes are untouched and still paint in the first render.
Did the agenda stay calm? Yes — but the calm is a restraint, not a property of the
design. Nearby is a fixed query with no knobs: click 1 lands on one list with one added
control, where Discover's console has ~14 (search field, huddlz/groups tabs, Location,
Within, Type, When, Sort). The moment someone adds a "Within" or "Type" control to this
surface, the agenda becomes Discover with a date rail and the variant's claim evaporates.
Nothing in the code prevents that. Full honest write-up, including the measured click count
(2 — the same as the baseline, because Discover already defaults a signed-in person's
location) is in the Findings section of
docs/research/post-login-landing-pocs.md.Nearby is agenda-only:
parse_scope/2takes the view mode and falls back to:minefor theweek and month grid, because a stranger's huddl is not a calendar fact.
Evidence
Screenshot
The Nearby filter on the agenda: a huddl from a group the person has not joined, with the scope note naming the distance and home location. The chip carries no count, by design.
The new scenario, before implementation — the nearby filter does not exist:
After:
Five scenarios cover: a nearby huddl from a group I don't belong to; nearby excluding huddlz
I already responded to; nearby excluding huddlz out of range (PostGIS
ST_DWithin); theRSVPs and Groups filters still behaving as before; and choosing nearby with no home search
location on file.
mix compile --warnings-as-errorsis clean.Merge Danger
Door: two-way.
Additive. No migration, no new resource, no change to an existing action. Reverting is
deleting a scope — the two existing scopes' code paths are unchanged and still synchronous.
The one non-additive edit is the
handle_params/3→put_view_state/1split insideCalendarLive, which is a pure refactor of that module's own private functions.Blast Radius:
CalendarLive./agenda,/calendar/weekand/calendar/monthall render through the refactoredderivation step, so a mistake there would affect all three views rather than only the new
scope — which is why the existing calendar and agenda scenarios were run alongside the new
ones.
scope_param/2now drops?scope=nearbyfrom links leaving the agenda, so ahand-typed
/calendar/week?scope=nearbyfalls back to the person's own RSVPs rather thanerroring. New CSS is confined to
.cal-scope-noteand.cal-agenda-skeleton; no existingselector was changed.
Part of #670
This is a POC for comparison, not intended to merge as-is. Verified by
scenario (failing -> passing) and a clean
--warnings-as-errorscompileonly;
mix precommitis a deliberate follow-up after review.Model: Claude Opus 5.5 (
claude-opus-5-5)🤖 Generated with Claude Code