@devrongx/games 0.4.24 → 0.4.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
CSK_VS_RCB_CHALLENGE,
|
|
9
9
|
CSK_VS_RCB_POOL,
|
|
10
10
|
IUserBets,
|
|
11
|
+
IBetEntry,
|
|
11
12
|
calcBetSummary,
|
|
12
13
|
buildPoolLeaderboard,
|
|
13
14
|
ILeaderboardEntry,
|
|
@@ -121,6 +122,12 @@ export const PreMatchBetsPopup = ({ poolId, matchId: _matchId, match: matchProp
|
|
|
121
122
|
const [submitError, setSubmitError] = useState<string | null>(null);
|
|
122
123
|
const [submittedBets, setSubmittedBets] = useState<IUserBets | null>(null);
|
|
123
124
|
|
|
125
|
+
// ── Per-market editing state ────────────────────────────────────────────────
|
|
126
|
+
const [ignoredMarkets, setIgnoredMarkets] = useState<Set<number>>(new Set());
|
|
127
|
+
const [editingMarkets, setEditingMarkets] = useState<Set<number>>(new Set());
|
|
128
|
+
const [editingSnapshots, setEditingSnapshots] = useState<Record<number, IBetEntry | undefined>>({});
|
|
129
|
+
const [editSubmitting, setEditSubmitting] = useState<number | null>(null);
|
|
130
|
+
|
|
124
131
|
// ── Real bets restore: when user has submitted bets, load them into game state ─
|
|
125
132
|
const realBetsRestoredRef = useRef(false);
|
|
126
133
|
useEffect(() => {
|
|
@@ -300,6 +307,95 @@ export const PreMatchBetsPopup = ({ poolId, matchId: _matchId, match: matchProp
|
|
|
300
307
|
}
|
|
301
308
|
}, [poolId, config, bets, hasEntry, refetchEntry, refetchLB, refetchPool]);
|
|
302
309
|
|
|
310
|
+
// ── Per-market editing handlers ─────────────────────────────────────────────
|
|
311
|
+
const handleToggleIgnore = useCallback((mIdx: number) => {
|
|
312
|
+
setIgnoredMarkets(prev => {
|
|
313
|
+
const next = new Set(prev);
|
|
314
|
+
if (next.has(mIdx)) next.delete(mIdx); else next.add(mIdx);
|
|
315
|
+
return next;
|
|
316
|
+
});
|
|
317
|
+
}, []);
|
|
318
|
+
|
|
319
|
+
const handleEditMarket = useCallback((mIdx: number) => {
|
|
320
|
+
setEditingMarkets(prev => new Set(prev).add(mIdx));
|
|
321
|
+
setEditingSnapshots(prev => ({ ...prev, [mIdx]: bets[mIdx] ? { ...bets[mIdx] } : undefined }));
|
|
322
|
+
}, [bets]);
|
|
323
|
+
|
|
324
|
+
const handleConfirmMarketEdit = useCallback(async (mIdx: number) => {
|
|
325
|
+
if (!poolId || !config) return;
|
|
326
|
+
const bet = bets[mIdx];
|
|
327
|
+
if (!bet || bet.amount <= 0) return;
|
|
328
|
+
|
|
329
|
+
setEditSubmitting(mIdx);
|
|
330
|
+
setSubmitError(null);
|
|
331
|
+
try {
|
|
332
|
+
const market = config.markets[mIdx];
|
|
333
|
+
const betInput = {
|
|
334
|
+
challenge_id: market.backendChallengeId!,
|
|
335
|
+
selected_option: market.options[bet.optionIdx].key ?? market.options[bet.optionIdx].label.toLowerCase().replace(/\s+/g, "_"),
|
|
336
|
+
coin_amount: bet.amount,
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
if (!hasEntry) await joinTDPool(poolId);
|
|
340
|
+
await placeTDBets(poolId, [betInput]);
|
|
341
|
+
|
|
342
|
+
// Update only this market in submittedBets
|
|
343
|
+
setSubmittedBets(prev => prev ? { ...prev, [mIdx]: { ...bet } } : { [mIdx]: { ...bet } });
|
|
344
|
+
realBetsRestoredRef.current = true;
|
|
345
|
+
|
|
346
|
+
// Clear editing state for this market
|
|
347
|
+
setEditingMarkets(prev => { const next = new Set(prev); next.delete(mIdx); return next; });
|
|
348
|
+
setEditingSnapshots(prev => { const next = { ...prev }; delete next[mIdx]; return next; });
|
|
349
|
+
|
|
350
|
+
await Promise.all([refetchEntry(), refetchLB(), refetchPool()]);
|
|
351
|
+
} catch (err: unknown) {
|
|
352
|
+
setSubmitError(err instanceof Error ? err.message : "Failed to save changes");
|
|
353
|
+
} finally {
|
|
354
|
+
setEditSubmitting(null);
|
|
355
|
+
}
|
|
356
|
+
}, [poolId, config, bets, hasEntry, refetchEntry, refetchLB, refetchPool]);
|
|
357
|
+
|
|
358
|
+
const handleCancelMarketEdit = useCallback((mIdx: number) => {
|
|
359
|
+
setBets(prev => {
|
|
360
|
+
const next = { ...prev };
|
|
361
|
+
const snapshot = editingSnapshots[mIdx];
|
|
362
|
+
if (snapshot) { next[mIdx] = snapshot; } else { delete next[mIdx]; }
|
|
363
|
+
return next;
|
|
364
|
+
});
|
|
365
|
+
setEditingMarkets(prev => { const next = new Set(prev); next.delete(mIdx); return next; });
|
|
366
|
+
setEditingSnapshots(prev => { const next = { ...prev }; delete next[mIdx]; return next; });
|
|
367
|
+
}, [editingSnapshots]);
|
|
368
|
+
|
|
369
|
+
// ── Computed: saved summary, dirty tracking ─────────────────────────────────
|
|
370
|
+
const savedBetSummary = useMemo(
|
|
371
|
+
() => submittedBets && config ? calcBetSummary(submittedBets, config) : null,
|
|
372
|
+
[submittedBets, config],
|
|
373
|
+
);
|
|
374
|
+
|
|
375
|
+
const hasUnsavedEdits = useMemo(() => {
|
|
376
|
+
if (!submittedBets) return false;
|
|
377
|
+
const allKeys = new Set([...Object.keys(bets), ...Object.keys(submittedBets)].map(Number));
|
|
378
|
+
for (const k of allKeys) {
|
|
379
|
+
const cur = bets[k];
|
|
380
|
+
const sub = submittedBets[k];
|
|
381
|
+
if (!cur && !sub) continue;
|
|
382
|
+
if (!cur || !sub) return true;
|
|
383
|
+
if (cur.optionIdx !== sub.optionIdx || cur.amount !== sub.amount) return true;
|
|
384
|
+
}
|
|
385
|
+
return false;
|
|
386
|
+
}, [bets, submittedBets]);
|
|
387
|
+
|
|
388
|
+
const dirtyMarkets = useMemo(() => {
|
|
389
|
+
const dirty = new Set<number>();
|
|
390
|
+
for (const mIdx of editingMarkets) {
|
|
391
|
+
const cur = bets[mIdx];
|
|
392
|
+
const snap = editingSnapshots[mIdx];
|
|
393
|
+
if (!cur && !snap) continue;
|
|
394
|
+
if (!cur || !snap) { dirty.add(mIdx); continue; }
|
|
395
|
+
if (cur.optionIdx !== snap.optionIdx || cur.amount !== snap.amount) dirty.add(mIdx);
|
|
396
|
+
}
|
|
397
|
+
return dirty;
|
|
398
|
+
}, [editingMarkets, editingSnapshots, bets]);
|
|
303
399
|
|
|
304
400
|
// ── Loading ────────────────────────────────────────────────────────────────
|
|
305
401
|
if (poolId && (poolLoading || (!config && !poolLoading))) {
|
|
@@ -356,6 +452,16 @@ export const PreMatchBetsPopup = ({ poolId, matchId: _matchId, match: matchProp
|
|
|
356
452
|
submittedBets={poolId ? submittedBets : null}
|
|
357
453
|
onViewLeaderboard={poolId ? () => setShowFullLeaderboard(true) : undefined}
|
|
358
454
|
submitting={submitting}
|
|
455
|
+
ignoredMarkets={ignoredMarkets}
|
|
456
|
+
onToggleIgnore={handleToggleIgnore}
|
|
457
|
+
editingMarkets={editingMarkets}
|
|
458
|
+
dirtyMarkets={dirtyMarkets}
|
|
459
|
+
onEditMarket={handleEditMarket}
|
|
460
|
+
onConfirmMarketEdit={handleConfirmMarketEdit}
|
|
461
|
+
onCancelMarketEdit={handleCancelMarketEdit}
|
|
462
|
+
editSubmitting={editSubmitting}
|
|
463
|
+
savedBetSummary={savedBetSummary}
|
|
464
|
+
hasUnsavedEdits={hasUnsavedEdits}
|
|
359
465
|
/>
|
|
360
466
|
)}
|
|
361
467
|
|