fix: max button uses MAX_BET

This commit is contained in:
Face 2025-05-29 16:54:48 +03:00
parent 1cae171748
commit 8a69bbca88
2 changed files with 77 additions and 27 deletions

View file

@ -172,6 +172,7 @@
} }
const cssEaseInOut = bezier(0.42, 0, 0.58, 1.0); const cssEaseInOut = bezier(0.42, 0, 0.58, 1.0);
const MAX_BET_AMOUNT = 1000000;
let { let {
balance = $bindable(), balance = $bindable(),
@ -182,13 +183,16 @@
} = $props(); } = $props();
let betAmount = $state(10); let betAmount = $state(10);
let betAmountDisplay = $state('10');
let selectedSide = $state('heads'); let selectedSide = $state('heads');
let isFlipping = $state(false); let isFlipping = $state(false);
let coinRotation = $state(0); let coinRotation = $state(0);
let lastResult = $state<CoinflipResult | null>(null); let lastResult = $state<CoinflipResult | null>(null);
let activeSoundTimeouts = $state<NodeJS.Timeout[]>([]); let activeSoundTimeouts = $state<NodeJS.Timeout[]>([]);
let canBet = $derived(betAmount > 0 && betAmount <= balance && !isFlipping); let canBet = $derived(
betAmount > 0 && betAmount <= balance && betAmount <= MAX_BET_AMOUNT && !isFlipping
);
function selectSide(side: string) { function selectSide(side: string) {
if (!isFlipping) { if (!isFlipping) {
@ -197,11 +201,27 @@
} }
function setBetAmount(amount: number) { function setBetAmount(amount: number) {
if (amount >= 0 && amount <= balance) { const clampedAmount = Math.min(amount, Math.min(balance, MAX_BET_AMOUNT));
betAmount = amount; if (clampedAmount >= 0) {
betAmount = clampedAmount;
betAmountDisplay = clampedAmount.toLocaleString();
} }
} }
function handleBetAmountInput(event: Event) {
const target = event.target as HTMLInputElement;
const value = target.value.replace(/,/g, '');
const numValue = parseFloat(value) || 0;
const clampedValue = Math.min(numValue, Math.min(balance, MAX_BET_AMOUNT));
betAmount = clampedValue;
betAmountDisplay = target.value;
}
function handleBetAmountBlur() {
betAmountDisplay = betAmount.toLocaleString();
}
async function flipCoin() { async function flipCoin() {
if (!canBet) return; if (!canBet) return;
@ -395,12 +415,16 @@
<label for="bet-amount" class="mb-2 block text-sm font-medium">Bet Amount</label> <label for="bet-amount" class="mb-2 block text-sm font-medium">Bet Amount</label>
<Input <Input
id="bet-amount" id="bet-amount"
type="number" type="text"
bind:value={betAmount} value={betAmountDisplay}
min="1" oninput={handleBetAmountInput}
max={balance} onblur={handleBetAmountBlur}
disabled={isFlipping} disabled={isFlipping}
placeholder="Enter bet amount"
/> />
<p class="text-muted-foreground mt-1 text-xs">
Max bet: {MAX_BET_AMOUNT.toLocaleString()}
</p>
</div> </div>
<!-- Percentage Quick Actions --> <!-- Percentage Quick Actions -->
@ -409,25 +433,27 @@
<Button <Button
size="sm" size="sm"
variant="outline" variant="outline"
onclick={() => setBetAmount(Math.floor((balance || 0) * 0.25))} onclick={() =>
setBetAmount(Math.floor(Math.min(balance || 0, MAX_BET_AMOUNT) * 0.25))}
disabled={isFlipping}>25%</Button disabled={isFlipping}>25%</Button
> >
<Button <Button
size="sm" size="sm"
variant="outline" variant="outline"
onclick={() => setBetAmount(Math.floor((balance || 0) * 0.5))} onclick={() => setBetAmount(Math.floor(Math.min(balance || 0, MAX_BET_AMOUNT) * 0.5))}
disabled={isFlipping}>50%</Button disabled={isFlipping}>50%</Button
> >
<Button <Button
size="sm" size="sm"
variant="outline" variant="outline"
onclick={() => setBetAmount(Math.floor((balance || 0) * 0.75))} onclick={() =>
setBetAmount(Math.floor(Math.min(balance || 0, MAX_BET_AMOUNT) * 0.75))}
disabled={isFlipping}>75%</Button disabled={isFlipping}>75%</Button
> >
<Button <Button
size="sm" size="sm"
variant="outline" variant="outline"
onclick={() => setBetAmount(Math.floor(balance || 0))} onclick={() => setBetAmount(Math.floor(Math.min(balance || 0, MAX_BET_AMOUNT)))}
disabled={isFlipping}>Max</Button disabled={isFlipping}>Max</Button
> >
</div> </div>

View file

@ -42,8 +42,10 @@
const BASE_SPINS_PER_REEL = [8, 10, 12]; const BASE_SPINS_PER_REEL = [8, 10, 12];
const NUM_RENDERED_CYCLES = Math.max(...BASE_SPINS_PER_REEL) + 3; const NUM_RENDERED_CYCLES = Math.max(...BASE_SPINS_PER_REEL) + 3;
const MAX_BET_AMOUNT = 1000000;
let betAmount = $state(10); let betAmount = $state(10);
let betAmountDisplay = $state('10');
let isSpinning = $state(false); let isSpinning = $state(false);
const createReelStrip = () => { const createReelStrip = () => {
@ -66,19 +68,30 @@
}) })
); );
let canBet = $derived(betAmount > 0 && betAmount <= balance && !isSpinning); let canBet = $derived(
betAmount > 0 && betAmount <= balance && betAmount <= MAX_BET_AMOUNT && !isSpinning
);
function setBetAmount(amount: number) { function setBetAmount(amount: number) {
if (amount >= 0 && amount <= balance) { const clampedAmount = Math.min(amount, Math.min(balance, MAX_BET_AMOUNT));
betAmount = amount; if (clampedAmount >= 0) {
betAmount = clampedAmount;
betAmountDisplay = clampedAmount.toLocaleString();
} }
} }
function getVisibleSymbolIndex(position: number, logicalReelCycleLength: number): number { function handleBetAmountInput(event: Event) {
const symbolHeight = 60; const target = event.target as HTMLInputElement;
let index = Math.round(1 - position / symbolHeight); const value = target.value.replace(/,/g, '');
index = ((index % logicalReelCycleLength) + logicalReelCycleLength) % logicalReelCycleLength; const numValue = parseFloat(value) || 0;
return index; const clampedValue = Math.min(numValue, Math.min(balance, MAX_BET_AMOUNT));
betAmount = clampedValue;
betAmountDisplay = target.value;
}
function handleBetAmountBlur() {
betAmountDisplay = betAmount.toLocaleString();
} }
async function spin() { async function spin() {
@ -176,6 +189,13 @@
} }
} }
function getVisibleSymbolIndex(position: number, logicalReelCycleLength: number): number {
const symbolHeight = 60;
let index = Math.round(1 - position / symbolHeight);
index = ((index % logicalReelCycleLength) + logicalReelCycleLength) % logicalReelCycleLength;
return index;
}
$effect(() => { $effect(() => {
if (!isSpinning) { if (!isSpinning) {
const newDisplayedSymbols = reelSymbols.map((logicalCycle, i) => { const newDisplayedSymbols = reelSymbols.map((logicalCycle, i) => {
@ -276,12 +296,16 @@
<label for="bet-amount" class="mb-2 block text-sm font-medium">Bet Amount</label> <label for="bet-amount" class="mb-2 block text-sm font-medium">Bet Amount</label>
<Input <Input
id="bet-amount" id="bet-amount"
type="number" type="text"
bind:value={betAmount} value={betAmountDisplay}
min="1" oninput={handleBetAmountInput}
max={balance} onblur={handleBetAmountBlur}
disabled={isSpinning} disabled={isSpinning}
placeholder="Enter bet amount"
/> />
<p class="text-muted-foreground mt-1 text-xs">
Max bet: {MAX_BET_AMOUNT.toLocaleString()}
</p>
</div> </div>
<!-- Percentage Quick Actions --> <!-- Percentage Quick Actions -->
@ -290,25 +314,25 @@
<Button <Button
size="sm" size="sm"
variant="outline" variant="outline"
onclick={() => setBetAmount(Math.floor(balance * 0.25))} onclick={() => setBetAmount(Math.floor(Math.min(balance, MAX_BET_AMOUNT) * 0.25))}
disabled={isSpinning}>25%</Button disabled={isSpinning}>25%</Button
> >
<Button <Button
size="sm" size="sm"
variant="outline" variant="outline"
onclick={() => setBetAmount(Math.floor(balance * 0.5))} onclick={() => setBetAmount(Math.floor(Math.min(balance, MAX_BET_AMOUNT) * 0.5))}
disabled={isSpinning}>50%</Button disabled={isSpinning}>50%</Button
> >
<Button <Button
size="sm" size="sm"
variant="outline" variant="outline"
onclick={() => setBetAmount(Math.floor(balance * 0.75))} onclick={() => setBetAmount(Math.floor(Math.min(balance, MAX_BET_AMOUNT) * 0.75))}
disabled={isSpinning}>75%</Button disabled={isSpinning}>75%</Button
> >
<Button <Button
size="sm" size="sm"
variant="outline" variant="outline"
onclick={() => setBetAmount(Math.floor(balance))} onclick={() => setBetAmount(Math.floor(Math.min(balance, MAX_BET_AMOUNT)))}
disabled={isSpinning}>Max</Button disabled={isSpinning}>Max</Button
> >
</div> </div>