From 3954c2ebe653f2066ea6292bd642943acca635e8 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 3 Aug 2026 14:32:26 +0000 Subject: [PATCH] docs(commons): add annotated mockup for the poll results page Self-contained HTML mockup accompanying the poll results proposal: the Android screen with seven numbered callouts, the Desktop deck column, the loading / closed / empty states, and a side-by-side of the two candidate readings for a multiple-choice percentage. Mockup interiors use the app's real theme values from ui/theme/Color.kt and Theme.kt so the screens read as Amethyst rather than as generic UI; the annotation layer around them uses a separate neutral set. Light and dark both supported, following the viewer's preference. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01AQorYBSv9oMvKa8hF1uGBv --- commons/plans/2026-08-03-poll-results-page.md | 6 + .../assets/2026-08-03-poll-results-page.html | 1861 +++++++++++++++++ 2 files changed, 1867 insertions(+) create mode 100644 commons/plans/assets/2026-08-03-poll-results-page.html diff --git a/commons/plans/2026-08-03-poll-results-page.md b/commons/plans/2026-08-03-poll-results-page.md index 0cb3c8d17c..2a1bd9e142 100644 --- a/commons/plans/2026-08-03-poll-results-page.md +++ b/commons/plans/2026-08-03-poll-results-page.md @@ -12,6 +12,12 @@ consumers: amethyst, desktopApp > **Status:** proposal. Nothing implemented. This document surveys what exists, > names four correctness bugs the current tally has, and specifies a shared > results surface for Android and Desktop. _Authored 2026-08-03._ +> +> **Visual mockup:** [`assets/2026-08-03-poll-results-page.html`](assets/2026-08-03-poll-results-page.html) +> — annotated screens for the Android page, the Desktop deck column, the loading / +> closed / empty states, and a side-by-side of the two multi-choice percentage +> readings from §10.1. Open it in a browser; it renders in Amethyst's own theme +> tokens and follows the viewer's light/dark preference. ## 1. Motivation diff --git a/commons/plans/assets/2026-08-03-poll-results-page.html b/commons/plans/assets/2026-08-03-poll-results-page.html new file mode 100644 index 0000000000..20524de2f1 --- /dev/null +++ b/commons/plans/assets/2026-08-03-poll-results-page.html @@ -0,0 +1,1861 @@ +Poll results — Amethyst design proposal + + + +
+
+ + +
+
+ Design proposal + · + Amethyst + · + NIP‑88 polls + · + 2026‑08‑03 +
+

Poll results, with the counts and the people in them

+

+ A poll in Amethyst currently ends its life as a percentage bar and four avatars in the feed. + This proposes a dedicated results screen that answers the two questions people actually ask — + how many votes each answer got, and who voted for what — shared between Android and Desktop. +

+
+
Event kinds
1068 · 1018
+
Core module
commons
+
Front ends
Android · Desktop
+
New event kinds
0
+
Bugs fixed en route
4
+
+
+ + +
+
+
01 — The gap
+

What a finished poll looks like today

+

+ The inline card is deliberately compact, and that compactness is the whole problem: no vote + counts anywhere, at most four voter avatars, and no route to the fifth. Desktop already grew a + voter popup to work around it, which is the demand showing up as a divergence. +

+
+ +
+
+
Today — inline feed card
+
+
Which relay should Amethyst suggest first to brand-new users?
+
+
+
+
+
nos.lol
+ +
46%
+
+
+
+
+
+
relay.damus.io
+ +
35%
+
+
+
+
+
+
purplepag.es
+ +
19%
+
+
+
+
+

+ The +171 chip is a dead end — it counts people you cannot reach. Percentages appear + without their counts, and on a multiple-choice poll the denominator is wrong + (PollResponsesCache.kt:52). +

+
+ +
+
Proposed — the same card, two additions
+
+
Which relay should Amethyst suggest first to brand-new users?
+
nos.lol
+
relay.damus.io
+
purplepag.es
+
Poll votes are public. Anyone can see who voted for what.
+
+
View results
+
380 votes
+
+
+

+ Two changes to the card itself: a vote count beside the percentage, and the privacy + line placed where the choice is made rather than after it. The avatar stack and the + count both become the entry point to the full results screen. +

+
+
+
+ + +
+
+
02 — The screen
+

Poll results, Android

+

+ Summary above detail: totals, then per-option breakdown, then every voter with the option they + chose on the same row. Try the option chips — they filter the list below. +

+
+ +
+
+ 1 + 2 + 3 + 4 + 5 + 6 + 7 + +
+
+
+
Poll results
+
+
+ +
+
+
+
NF
+
+
Nadia Ferreira
+
npub1v0ry…8qk2 · 2d ago
+
+
+
Which relay should Amethyst suggest first to brand-new users?
+
+ Open · closes in 4h + Single choice +
+
380 voters · 380 selections
+
+ +
+
+
+
+
+
+
nos.lol
+
175 of 380 voters
+
+ +
46%
+
+
+
+
+
+
+
+
relay.damus.io
+
133 of 380 voters
+
+ +
35%
+
+
+
+
+
+
+
purplepag.es
+
72 of 380 voters
+
+ +
19%
+
+
+
+
+ +
+ You voted nos.lol + +
+ +
+
+ + + + +
+
+ Everyone ▾ + Relevance ▾ + ⚲ Search voters +
+
+ +
+
+
VP
+
+
you you
+
npub1gcx…wq7d
+
+
nos.lol
2d ago
+
+
+
BS
+
+
Bruno Sá follows
+
bruno@nostrplebs.com
+
+
relay.damus.io
2d ago
+
+
+
MK
+
+
mira.k follows
+
npub18ht…2m4v
+
+
nos.lol
2d ago
+
+
+
AR
+
+
Ana Reis follows
+
npub1t4qz…p09h
+
+
nos.lol
1d ago
+
+
+
RW
+
+
relaywrangler
+
npub1kk9m…4zzt
+
+
purplepag.es
1d ago
+
+
+
LN
+
+
npub1q8f…j3xw
+
no profile found
+
+
relay.damus.io
22h ago
+
+
+
TS
+
+
tomás
+
npub1w2ns…6vhc
+
+
nos.lol
14h ago
+
+
+
HM
+
+
hodlmatrix
+
npub1xr7d…5ktp
+
+
purplepag.es
9h ago
+
+
+ +
+
380 of ~412 responses loaded from 6 relays
+
3 responses ignored (unknown option) · 2 voters hidden by your mute list
+
+
+
+
+ +
+
+
1
+
+
Refresh is for relays, not for the tally
+

+ The tally is already a live StateFlow — new votes animate in without asking. + The refresh action re-runs the backfill against the poll's own relays, which is the only + part that can be stale. +

+
+
+
+
2
+
+
Both totals, stated plainly
+

+ Voters is distinct pubkeys; selections is how many boxes were ticked. They + are identical on a single-choice poll and diverge on multiple choice — which is exactly + where today's percentages go wrong (§03). +

+
+
+
+
3
+
+
Counts beside percentages, winner marked
+

+ Each row gains N of M voters. The winner keeps the existing green treatment + from RenderClosedItem so the screen reads as the card it came + from, and the bar keeps the same 800 ms tween. +

+
+
+
+
4
+
+
Your own vote, and a way out of it
+

+ Desktop already allows re-voting; Android does not. This strip makes the behaviour the + same on both, and puts your vote where you don't have to hunt the list for yourself. +

+
+
+
+
5
+
+
Filter the list, never the summary
+

+ Option chips scope the voter list only — the bars above stay put, so the totals can't + appear to change while you browse. Audience is Everyone / Following / Following + WoT, + reusing the follow set the tally already sorts by. +

+
+
+
+
6
+
+
One row per person, with their choice on it
+

+ The default is a flat list of everyone, so "who voted for what" is answered without + drilling into an option. You are pinned first, follows next — that ordering already + exists in filterTo. Multiple-choice rows list every option + that person picked. +

+
+
+
+
7
+
+
Say how complete the tally is
+

+ A NIP-45 count against the poll's relays gives the "~412" — so a partial + tally can admit it instead of presenting itself as final. The second line accounts for + every response that was dropped and why. +

+
+
+
+
+
+ + +
+
+
03 — Open question, needs your call
+

What a multiple-choice percentage should mean

+

+ Same poll, same votes, two readings. 240 people voted and ticked 456 boxes between them. + This is the one decision that blocks the tally work, because it changes the numbers on the + existing feed card too. +

+
+ +
+
+
+

Share of voters

+ proposed +
+
+
+
+
+
Groups
168 of 240 voters
+
70%
+
+
+
+
+
+
Polls
132 of 240 voters
+
55%
+
+
+
+
+
+
Search
96 of 240 voters
+
40%
+
+
+
+
+
+
Wallet
60 of 240 voters
+
25%
+
+
+
bars sum to 190% — by design
+
+
+ "7 in 10 people want Groups." Matches how a poll bar is read. Costs you a total that + doesn't add to 100, which the per-row caption explains. +
+
+ +
+
+

Share of selections

+ what ships today +
+
+
+
+
+
Groups
168 of 456 selections
+
37%
+
+
+
+
+
+
Polls
132 of 456 selections
+
29%
+
+
+
+
+
+
Search
96 of 456 selections
+
21%
+
+
+
+
+
+
Wallet
60 of 456 selections
+
13%
+
+
+
bars sum to 100%
+
+
+ "Groups took 37% of the vote." Tidier, and a voter who ticks four boxes counts four + times. Desktop already contradicts this in its own footer, which uses distinct voters. +
+
+
+
+ + +
+
+
04 — States
+

The three the screen has to get right

+

+ Every one of these is a moment where a number could look like a bug unless the screen says + what happened. +

+
+ +
+
+
Loading · partial tally
+
+
+
+
Poll results
+
+
+
112 voters so far
+
+
+
+
+
nos.lol
58 of 112 voters
+
52%
+
+
+
+
+
+
relay.damus.io
34 of 112 voters
+
30%
+
+
+
+
+
+
+
+
+
+
+
Loading page 2 of 5 from 6 relays…
+
+
+
+ +
+
Closed poll
+
+
+
+
Poll results
+
+
+
+ Ended 2d ago + Single choice +
+
412 voters · final
+
+
+
+
+
nos.lol
189 of 412 voters
+
46%
+
+
+
+
+
+
+
relay.damus.io
142 of 412 voters
+
34%
+
+
+
+
+
+
No new votes accepted. 7 votes arrived after the deadline and are excluded.
+
+
+
+ +
+
No votes yet
+
+
+
+
Poll results
+
+
+
Open · closes in 3d
+
+
+
+
+
nos.lol
0 voters
+
0%
+
+
+
+
+
+
relay.damus.io
0 voters
+
0%
+
+
+
+
+ No votes yet + Be the first — your vote will show up here. +
+
+
+
+
+
+ + +
+
+
05 — Desktop
+

The same screen as a deck column

+

+ Desktop navigates by DeckColumnType, not routes, so results open as a + column beside the feed. The existing voter popup stays as the quick peek and grows a + See all voters footer that opens this column. +

+
+ +
+
+
+
+
+
+
+ +
+
Polls Open
+
+
+
Which relay should Amethyst suggest first?
+
Nadia Ferreira · 380 voters
+
+
+
Should the composer default to plain text?
+
Bruno Sá · 96 voters
+
+
+
Pick the next language for the UI
+
mira.k · 1,204 voters
+
+
+
+ +
+
Poll results 380 voters · 6 relays
+
+
Which relay should Amethyst suggest first to brand-new users?
+
+ Open · closes in 4h + Single choice +
+
+
+
+
+
nos.lol
175 of 380 voters
+
46%
+
+
+
+
+
+
+
relay.damus.io
133 of 380 voters
+
35%
+
+
+
+
+
+
purplepag.es
72 of 380 voters
+
19%
+
+
+
+
+ All options + nos.lol · 175 + relay.damus.io · 133 +
+
+
+
VP
+
+
you you
+
+
nos.lol
2d ago
+
+
+
BS
+
+
Bruno Sá follows
+
+
relay.damus.io
2d ago
+
+
+
MK
+
+
mira.k follows
+
+
nos.lol
2d ago
+
+
+
+
+ +
Add a column
+
+
+ + +
+
+
06 — Prerequisites
+

Four tally bugs, and one missing subscription

+

+ The results page would inherit all of these, so they land first. The four tally bugs share one + root cause — ResponseTally never sees the + PollEvent, so it cannot know the poll's type, its valid option codes, + or its window. The fifth is separate: Android asks the wrong relays for votes. Both fixes + improve the feed card on their own. +

+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
What breaksImpactConsequenceWhere
Multiple-choice denominatorwrong numberA voter who picks three options counts three times. Desktop's footer and its own bars already disagree about this.PollResponsesCache.kt:52
Every response tag countedspecNIP-88 keeps only the first tag on a single-choice poll. One malformed vote lands in every bucket.PollResponsesCache.kt:129
Votes after the deadlinespecOnly createdAt is compared, so a late vote beats a valid earlier one and closed polls keep moving.Note.kt:1685
Unknown option codeswrong numberA code that isn't in the poll creates a phantom bucket that still drags every real percentage down.PollResponsesCache.kt:129
Poll relays never queriedmissing dataAndroid reads votes from the author's inbox relays, not the relays the poll publishes votes to — so its tallies are short. Desktop patched this per-card.FilterRepliesAndReactionsToNotes.kt:89
+
+
+ + +
+
+
07 — Sequence
+

What lands, in what order

+

The first two phases are bug fixes wearing a feature's clothes — worth shipping even if the screen never gets built.

+
+ +
+
+
P0
+
Poll-aware tallyNew PollTallyPolicy in commons + tests. Fixes all four numbers above.
+
Ships alone — corrects the feed card on both platforms
+
+
+
P1
+
Shared response subscriptionDesktop's per-card fix lifted into a shared assembler, plus fetchAllPages backfill.
+
Ships alone — Android tallies stop being short
+
+
+
P2
+
The screenViewModel + shared composables + Android route + entry points from the card.
+
The feature
+
+
+
P3
+
Filters, sort, search, completeness footer, privacy lineEverything in §02 notes 5 and 7.
+
Polish
+
+
+
P4
+
Desktop column, then zap pollsKind 6969 shares the shell but not the tally — it is weighted by sats, not by people.
+
Parity, then breadth
+
+
+
+ +
+
+ On the palette. Every colour inside a mockup is lifted from + ui/theme/Color.kt and Theme.kt — the purple + accent, the green winner state, the amber warning, the surface ramp. The annotation layer around + them uses a separate neutral set, so you can always tell the app from the commentary. Greys stay + hue-free in both, per the decision recorded at Theme.kt:157. +
+
Mockup only — no code in this proposal has been written. Numbers and handles are fictional.
+
+ +
+
+ +