diff --git a/html/js/core/game.js b/html/js/core/game.js index 68e3824..0e8a129 100644 --- a/html/js/core/game.js +++ b/html/js/core/game.js @@ -277,6 +277,8 @@ var Game = { }, stopWaitingScreen: function() { + this._awaitingPayment = false; + this._unconfirmedPayment = false; ScreenManager.stopWaitingScreen(); }, diff --git a/html/js/input/inputHandler.js b/html/js/input/inputHandler.js index dc015bb..38de57b 100644 --- a/html/js/input/inputHandler.js +++ b/html/js/input/inputHandler.js @@ -142,7 +142,25 @@ const InputHandler = { socket.emit('chat message', 'enter'); if (isDebugMode || ScreenManager.canEnterGame()) { - if (typeof ScreenManager !== 'undefined' && ScreenManager.drawWaitingScreen) { + // Check if we should show waiting screen + const addressRequired = typeof SocketHandlers !== 'undefined' && SocketHandlers.payoutAddressRequired(); + const hasAddress = typeof SocketHandlers !== 'undefined' && SocketHandlers._hasPayoutAddress; + const canAfford = typeof SocketHandlers !== 'undefined' && SocketHandlers.canAffordGame(); + const isFree = typeof SocketHandlers !== 'undefined' && SocketHandlers._gameMode === 'FREE'; + + // Only show waiting screen if address is set (if required) and they can afford it (if credits) + const shouldShowWaiting = isFree || (canAfford && (!addressRequired || hasAddress)); + + if (shouldShowWaiting && typeof ScreenManager !== 'undefined' && ScreenManager.drawWaitingScreen) { + // Optimistically set awaiting payment if needed + const isPaidCredits = typeof SocketHandlers !== 'undefined' && SocketHandlers._gameMode === 'PAID_CREDITS'; + const hasEnoughCredits = typeof SocketHandlers !== 'undefined' && SocketHandlers._creditsBalance >= (SocketHandlers._creditsPerGame || 1); + + if (!isFree && typeof Game !== 'undefined' && !Game._unconfirmedPayment) { + if (!(isPaidCredits && hasEnoughCredits)) { + Game._awaitingPayment = true; + } + } ScreenManager.drawWaitingScreen(); } } else { @@ -167,10 +185,41 @@ const InputHandler = { $('#startButton').click(function(e) { // Attempt immediate start socket.emit('auto_start'); - // We optimistically show waiting screen; if server later responds with payment requirement, audio handler will fire on payment_created - if (typeof ScreenManager !== 'undefined' && ScreenManager.drawWaitingScreen) { - ScreenManager.drawWaitingScreen(); + + // Check if we should show waiting screen + const addressRequired = typeof SocketHandlers !== 'undefined' && SocketHandlers.payoutAddressRequired(); + const hasAddress = typeof SocketHandlers !== 'undefined' && SocketHandlers._hasPayoutAddress; + const canAfford = typeof SocketHandlers !== 'undefined' && SocketHandlers.canAffordGame(); + const isFree = typeof SocketHandlers !== 'undefined' && SocketHandlers._gameMode === 'FREE'; + + // We only show waiting screen if: + // 1. It's free mode + // 2. We have address (if required) AND (it's direct pay OR we have credits) + const shouldShowWaiting = isFree || (canAfford && (!addressRequired || hasAddress)); + + if (shouldShowWaiting) { + // If in a paid mode but no payment detected yet, optimistically set awaiting payment + // UNLESS it is credits mode and we already have enough credits + const isPaidCredits = typeof SocketHandlers !== 'undefined' && SocketHandlers._gameMode === 'PAID_CREDITS'; + const hasEnoughCredits = typeof SocketHandlers !== 'undefined' && SocketHandlers._creditsBalance >= (SocketHandlers._creditsPerGame || 1); + + if (!isFree && typeof Game !== 'undefined' && !Game._unconfirmedPayment) { + if (!(isPaidCredits && hasEnoughCredits)) { + Game._awaitingPayment = true; + } + } + + if (typeof ScreenManager !== 'undefined' && ScreenManager.drawWaitingScreen) { + ScreenManager.drawWaitingScreen(); + } + } else { + // If not showing waiting screen, add helpful message to chat if missing address + if (addressRequired && !hasAddress) { + $('#messages').append($('
  • ').text("⚠️ Please set a payout address before starting.")); + UI.scrollChat(); + } } + $('#messages').append($('
  • ').text("🖱️ Game start requested...")); UI.scrollChat(); }); diff --git a/html/js/network/socketHandlers.js b/html/js/network/socketHandlers.js index 3c205dd..490354e 100644 --- a/html/js/network/socketHandlers.js +++ b/html/js/network/socketHandlers.js @@ -11,8 +11,31 @@ const SocketHandlers = { if (color) el.css('color', color); }, + _hasPayoutAddress: false, + _creditsBalance: 0, + _gameMode: 'free', + + _directPayoutsEnabled: false, + _paymentsEnabled: false, + + payoutAddressRequired: function() { + if (this._gameMode === 'PAID_SINGLE' && this._directPayoutsEnabled) return true; + if (this._gameMode === 'PAID_CREDITS' && this._creditsPayoutsEnabled) return true; + return false; + }, + + canAffordGame: function() { + if (this._gameMode === 'FREE') return true; + if (this._gameMode === 'PAID_SINGLE') return true; // Payment will be requested + if (this._gameMode === 'PAID_CREDITS') { + return this._creditsBalance >= (this._creditsPerGame || 1); + } + return false; + }, + _updateAddressButtonStatus: function(hasAddress) { const $btn = $('#manageAddressButton'); + this._hasPayoutAddress = !!hasAddress; if (!$btn.length) return; if (hasAddress) { @@ -195,6 +218,9 @@ const SocketHandlers = { _creditsPerGame: 1, _updateCreditsDisplay: function(balance, creditsPerGame) { + // Store current balance + this._creditsBalance = balance; + // Update stored creditsPerGame if provided if (creditsPerGame && creditsPerGame > 0) { SocketHandlers._creditsPerGame = creditsPerGame; @@ -296,7 +322,15 @@ const SocketHandlers = { if (data.status === 'waiting') { $('#messages').append($('
  • ').text(data.message)); - if (typeof Game !== 'undefined' && Game.drawWaitingScreen) { + // Check if we should show waiting screen + const addressRequired = SocketHandlers.payoutAddressRequired(); + const hasAddress = SocketHandlers._hasPayoutAddress; + const canAfford = SocketHandlers.canAffordGame(); + const isFree = SocketHandlers._gameMode === 'FREE'; + + const shouldShowWaiting = isFree || (canAfford && (!addressRequired || hasAddress)); + + if (shouldShowWaiting && typeof Game !== 'undefined' && Game.drawWaitingScreen) { Game.drawWaitingScreen(); } } @@ -515,6 +549,9 @@ const SocketHandlers = { // Store game mode and early entry config SocketHandlers._gameMode = data.mode; SocketHandlers._earlyEntryConfig = data.earlyEntry || { enabled: false }; + SocketHandlers._creditsPayoutsEnabled = !!data.creditsPayoutsEnabled; + SocketHandlers._directPayoutsEnabled = !!data.directPayoutsEnabled; + SocketHandlers._paymentsEnabled = !!data.paymentsEnabled; if (typeof UI !== 'undefined' && UI.updateGameTitle) { UI.updateGameTitle(data.cryptoType); @@ -632,6 +669,11 @@ const SocketHandlers = { }, 100); SocketHandlers._setBannerStatus('Pay', '#0af'); if (typeof Game !== 'undefined' && Game._paymentRequested) Game._paymentRequested(); + + // Show waiting screen (which will now say "Awaiting payment") + if (typeof Game !== 'undefined' && Game.drawWaitingScreen) { + Game.drawWaitingScreen(); + } // Sidebar QR (persistent) - create/update separate from chat scroll if (data.qr) {