Skip to content

Commit b0b7d39

Browse files
markets/: key the position rebuild on your own holdings
The in-place updater refreshed the derived numbers but never the text that only your OWN trade changes: the per-row 'risked X to returns Y if right' meta and the 'you hold N to win' line on the outcome buttons. Betting again on something you already held left the card contradicting itself -- a stated stake of 226.00 beside a P&L computed from the real 276, and a footer whose total didn't match the rows it sat under. It never self-healed; only a reload rebuilt it. The shape key now includes the user's own share balances. A third party's trade leaves those untouched, so the cheap focus-preserving path still runs for price ticks -- which is what it was for -- while your own bet forces the rebuild that rewrites the stake and payout text. Verified both halves against a real second agent (a bearer with credentials:'omit', since the session cookie otherwise takes precedence): carol's trade keeps the shape, keeps focus on the same Cash out node, and tracks the server P&L to the cent; alice's own bet rebuilds and the meta matches /api/me exactly. 75 plugin tests green.
1 parent 6756b95 commit b0b7d39

1 file changed

Lines changed: 9 additions & 3 deletions

File tree

markets/ui.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -948,7 +948,9 @@ export function renderUi(prefix) {
948948
// to BODY every few seconds on a live market.
949949
const existing = $('d-outcomes').querySelectorAll('.out-btn');
950950
const reuse = !settledView(m) && existing.length === m.outcomes.length
951-
&& m.outcomes.every((o, i) => existing[i].dataset.o === o);
951+
&& m.outcomes.every((o, i) => existing[i].dataset.o === o)
952+
// …and your holdings are unchanged, or "you hold N to win" goes stale.
953+
&& held.every((h, i) => existing[i].dataset.h === String(h));
952954
if (reuse) {
953955
existing.forEach((b, i) => {
954956
b.querySelector('.pc').textContent = pct(m.prices[i]);
@@ -957,7 +959,7 @@ export function renderUi(prefix) {
957959
});
958960
} else $('d-outcomes').innerHTML = m.outcomes.map((o, i) =>
959961
'<button type="button" class="out-btn" data-i="' + i + '" data-o="' + esc(o) + '"'
960-
+ ' aria-pressed="' + (i === pick) + '" style="--oc:' + col(i) + '">'
962+
+ ' data-h="' + held[i] + '" aria-pressed="' + (i === pick) + '" style="--oc:' + col(i) + '">'
961963
+ '<span class="nm">' + esc(o)
962964
+ (held[i] > 0 ? '<div class="meta" style="margin:0">you hold ' + cr(held[i]) + ' to win</div>' : '')
963965
+ '</span>'
@@ -1043,7 +1045,11 @@ export function renderUi(prefix) {
10431045
// unchanged; rebuilding threw focus off the Cash out buttons every
10441046
// time anyone else traded.
10451047
const legs = pos.shares.map((s, i) => (s > 0 ? i : -1)).filter((i) => i >= 0);
1046-
const shape = m.id + ':' + legs.join(',');
1048+
// Include YOUR OWN holdings: the stake and payout text is only
1049+
// stale when you trade, and a third party's tick leaves shares
1050+
// untouched, so this keeps the focus-preserving path for ticks and
1051+
// forces a rebuild for your own bets.
1052+
const shape = m.id + ':' + legs.join(',') + ':' + pos.shares.join(',');
10471053
// Toggle the up/down class, never ASSIGN className — assigning it
10481054
// dropped the v-pnl/v-total hooks this very function needs, so the
10491055
// next tick threw, froze every P&L figure, and (via an early

0 commit comments

Comments
 (0)