- 06 Jun, 2026 3 commits
-
-
Mahmoud Aglan authored
Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- HUD badge on rank tab for pending tournament matches - Bracket API + horizontal scrollable bracket visualization (RTL) - Arena mode: join/seek/pair/play loop with live standings - Tournament lobby with countdown timer + player grid - Live tournament spectating with auto-refresh pairings - Format-specific tabs in tournament detail (bracket/arena) Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Players can now play tournament matches from the app. Adds create-or-join API, realtime pairing notifications, auto-result reporting to Swiss API, and tournament-aware chess result screen. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
- 05 Jun, 2026 37 commits
-
-
Mahmoud Aglan authored
Categorized into Bullet, Blitz, Rapid, and Classical with Arabic labels: - Bullet: 1+0, 1+1, 2+1 - Blitz: 3+0, 3+2, 5+0, 5+3, 5+5 - Rapid: 10+0, 10+5, 15+10, 20+0, 30+0 - Classical: 45+45, 60+0, 90+30 Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Ad area now flex:1 (absorbs all dead space above the board). Hidden by default — only shown when an active campaign is loaded. Game UI pushed further down for thumb reach. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- Add ad banner slot in the dead space above the board - Move emote toggle button inline with player profile data - Emote panel now opens below player bar (no more fixed overlay) - Reduce top spacer to flex:0.4 so game sits near-center (slightly bottom-biased) - Add api/ads.php endpoint to serve active campaigns from ad_campaigns table - Ad system tracks impressions and filters by slot/game targeting Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Uses a flex:1 spacer div at the top of the layout instead of manipulating board container flex. On tall screens, dead space goes above the opponent bar — everything else stays packed at the bottom within thumb reach. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The justify-content:flex-end approach left dead space at top. Instead: keep flex:1 on board container (fills screen), use align-items:flex-end so the canvas sits at the bottom of its container. Emote button stays at fixed position off the board. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Portrait mobile games should have everything within thumb reach at the bottom. Removed flex:1 stretching and added justify-content:flex-end so the board, bars, and controls all stack from the bottom up. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Board content now aligns to bottom (thumb zone) instead of center. Emote button repositioned to fixed bottom-right, off the chess squares. Control buttons enlarged to 48px+ with safe-area padding. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- Login: show brand logo via assetImg() instead of plain text, larger register link - Bot select: 44px back button, difficulty color bars, fallback initials when portrait fails - Chess board: raise max-width 400→500px, reduce padding — fills more screen - Chess controls: min-height 44px, better contrast (#e2e8f0), larger border-radius - Ludo board: raise cap 360→420px to fill available space - Ludo exit button: 44px circular touch target instead of rectangular - Tab bar items: min 44px touch targets with centered content - HUD bell button: 36→44px - Game menu: staggered entrance animation on buttons/chips - Fix 9px font in ludo panels → 10px minimum Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Ludo multiplayer: - Sync state to server on EVERY turn change (including no-valid-moves pass) - Use turn_count to detect stale vs fresh server state (prevents re-processing) - Non-host players poll at 1.5s and receive dice rolls + board state - Bot turns run only on host, results synced to server for other players - Fix double-encoding of game_state/positions in API - Play notification sound when turn returns to player Chess multiplayer: - Detect move type (check/capture/castle) from FEN diff on received moves - Show check highlight (red king square) for opponent's checking moves - Play correct SFX (check/capture/castle) instead of generic 'move' - Show last-move highlight squares for received moves - Skip polling during recovery to prevent SFX burst on reconnect - Track captured pieces from opponent's moves - Sync move list from server history Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Three critical multiplayer sync issues fixed: 1. Resign now notifies server (action:'resign') BEFORE ending locally. Opponent's polling detects status:'completed' + result and shows win. 2. Reconnect recovery completely rewritten: - Determines player color from match data (white_player_id vs userId) - Flips board correctly for black - Sets lastKnownMoveCount from server to prevent duplicate move processing - Detects if game already ended while disconnected (opponent resigned) - Restores canSelect with correct color check 3. sendLiveMove now includes clock times (white_time_remaining_ms, black_time_remaining_ms) so opponent sees accurate clocks. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Panel positions: - Forced direction:ltr on panel rows so Green=top-left, Yellow=top-right, Red=bottom-left, Blue=bottom-right — matching the board zones visually. (The page is RTL Arabic which was reversing element order.) Exit button: - Added exit button (✕) next to dice area - Single player: confirms then ends game as loss - Multiplayer: notifies server to replace player with bot, then exits - Confirmation dialog prevents accidental exits Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Problem 1: Reconnection reset board to starting position - engine.create() always starts fresh - FIX: if params.recovered, fetch match from server → engine.load(current_fen) - Also restores clock times + determines whose turn from FEN Problem 2: Opponent name stuck on 'جاري التحميل' - params.opponentId was undefined (not passed on reconnect or matchmaking) - FIX: if no opponentId in params, fetch match → get white/black_player_id → find opponent - Uses fetchAndRenderOpponent() helper to update avatar/name/level Problem 3: Other player can't see moves after reconnect - This was because board reset to start position - Now board loads current_fen from server → correct position displayed - Polling continues from correct move_count Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Emotes now pop up next to the player panel that sent them and gently float up in place before fading. Duration increased from 1.8s to 3s. Multiplayer sync unchanged — still uses sendEmote/onEmoteReceived. Bot emotes in ludo also use the new positioned animation. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Ludo: - Each panel shows: avatar (photo/bot
🤖 ), name, level - YOUR panel shows your profile photo + display_name + level - Bot panels show🤖 emoji with colored border matching their zone - Panel positions already match zone colors (Green TL, Yellow TR, Red BL, Blue BR) Chess: - Opponent bar: photo (bot portrait for bots, profile pic for humans) + name + level - YOUR bar: your profile photo + display_name + Lv.X - Gold border around your avatar, blue border around opponent's - Live mode: fetches opponent profile → updates avatar, name, level dynamically - Bot mode: shows Stockfish portrait + bot name + 'بوت' label Both games now feel player-centric — you always see WHO you're playing against with their real identity, not generic 'Opponent' or 'Bot 1' text. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Chess game scene: - Imports and calls matchLive.start(matchId, 'chess', callbacks) - Creates localStorage entry → browser refresh auto-resumes - matchLive.session.destroy() on endGame → clears recovery Ludo game scene: - Same pattern: matchLive.start(matchId, 'ludo', callbacks) - Clears session on endGame Now the flow works: 1. Player enters live game → matchLive.start() saves to localStorage 2. Player refreshes browser → engine boot finds recovery → verifies server → auto-rejoins 3. Game ends normally → matchLive.session.destroy() clears localStorage 4. Player goes to homepage after game → no recovery popup (correct) Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Self-hosted Supabase Kong requires apikey param even for public bucket URLs. Without it, browsers get 401 when loading the image. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Supabase Storage requires both Authorization and apikey headers. The missing apikey caused "No API key found in request" → 500 on upload. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Standard Ludo board: Green(TL), Yellow(TR), Red(BL), Blue(BR) Player order: 0=Red(BL), 1=Green(TL), 2=Yellow(TR), 3=Blue(BR) Path is now CLOCKWISE: - Red enters from bottom center going UP - Green enters from left center going RIGHT - Yellow enters from top center going DOWN - Blue enters from right center going LEFT All positions recalculated from scratch: - SHARED_PATH: 52 squares going clockwise matching reference image - HOME_COLUMNS: each player's 6-square run toward center - HOME_BASES: pieces start in correct corners - START_SQUARES: [0, 13, 26, 39] with correct global positions - Center triangles: point toward center from each player's side - Home zones: correct corner colors - Panel positions: match board layout spatially Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Replace finfo_open with simpler mime_content_type(). Add global exception/error handlers that return JSON instead of HTML error pages. Include curl errors and storage HTTP codes in error responses for debugging. Remove fileinfo from Dockerfile (already bundled in PHP 8.3). Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Add upload_max_filesize=10M to PHP config (default 2M was rejecting compressed images). Add fileinfo extension explicitly. Improve error messages in avatar.php to report the actual failure reason. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Resize any image to 512x512 center-cropped JPEG at 82% quality before uploading. Handles huge photos from phone cameras that would fail or timeout on upload. Removes the 5MB size gate since compression brings all images to ~50-150KB. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The player order was wrong — Blue was assigned to Green's position and vice versa. On a standard Ludo board going clockwise from Red (top-left): Red(TL) → Green(BL) → Yellow(BR) → Blue(TR) Fixed: - COLORS order: red, green, yellow, blue (was red, blue, yellow, green) - HOME_BASES: matched to correct corners - HOME_COLUMNS: Green enters from left, Blue from right - HOME_ENTRY: correct global squares for each player - Center triangles: Red(top), Green(left), Yellow(bottom), Blue(right) - Home zone drawing: correct corner positions - Player panels: top row = Red(TL) + Blue(TR), bottom = Green(BL) + Yellow(BR) Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Player reconnection: - On app boot, checks localStorage for active match - Verifies match is still 'in_progress' on server before rejoining - If match ended/aborted → clears recovery, goes to homepage - If server unreachable → tries to rejoin anyway (optimistic) Match auto-close: - handleGet() checks updated_at timestamp on every poll - If match hasn't been updated in 30+ seconds → both players inactive - Server marks match as 'completed' with result 'aborted' - Next player who polls sees status='completed' → game ends cleanly - Prevents zombie matches lingering forever Flow: 1. Both players disconnect → no pings → updated_at goes stale 2. After 30s, if either player comes back and polls → server closes match 3. Match shows as 'aborted' → player sees 'game ended' UI 4. If only one player comes back within 30s → they keep playing (match alive) Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Replace cluttered logo/level/coins/gems/bell HUD with clean layout: avatar+level badge (left), coins+gems (center), bell (right). Avatar taps navigate to profile. Add profile photo upload with camera badge overlay, client+server validation, Supabase Storage upload endpoint. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
New core module handles ALL connection edge cases: TAB REFRESH RECOVERY: - Active match stored in localStorage with timestamp - On app boot, checks for recoverable match (< 5 min old) - Automatically re-enters the game scene with recovered state - Fetches latest state from server immediately TAB VISIBILITY (switch/minimize): - Pauses polling when tab is hidden (saves bandwidth) - Resumes and immediately fetches latest state on return - Resets disconnect timers on tab return OPPONENT DISCONNECT DETECTION: - Tracks lastOpponentActivity timestamp - After 30s: fires onOpponentDisconnect (show warning UI) - After 60s: fires onOpponentAbandon (auto-claim win) - If opponent comes back: fires onOpponentReconnect NETWORK LOSS HANDLING: - If server unreachable for 10s: fires onConnectionLost - On recovery: fires onConnectionRestored - Polling continues with error tolerance SERVER PING (keep-alive): - Every 10s, pings server with player ID + timestamp - Stored in game_state.ping field - Opponent's polling reads this to know sender is alive API: - create(matchId, gameType, callbacks) — start session - destroy() — clean up timers + localStorage - getRecoverableMatch() — check for resume on boot - markOpponentActive() — call when opponent data received - isConnected() / isOpponentConnected() — status checks Engine updated: - Imports match-session on boot - Checks for recoverable match after auth - Auto-resumes game if found Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Uses contain-fit logic: scales image to fit within the square while preserving natural proportions, centered within the cell. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Game tiles (chess, domino, ludo, backgammon) now get their gradient colors from the theme — editing chess_primary/chess_secondary etc in admin branding immediately changes the homepage tile colors. Also uploaded proper game icons. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Tab bar icons (play, rank, social, shop, profile) now use assetImg() which loads from platform_assets. Uploaded matching PNGs from app icons. Falls back to original SVGs if no custom icons uploaded. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
Chess board: - Square colors now read from theme system (getColor) instead of hardcoded constants — editing board colors in admin branding instantly affects all modes (game, analysis, puzzles) Logos: - HUD brand text replaced with assetImg('logo') — shows uploaded PNG - Splash screen uses logo image instead of text - Favicon and apple-touch-icon added to index.php Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
- Pieces now have 10% padding (was 5%) making them visually smaller - Move animation 120ms (was 200ms) with cubic ease-out - Slight squish (85% scale) at midpoint of move - Bigger squish (72% scale) when capturing a piece - Dragging piece slightly smaller (1.1x instead of 1.2x) Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
The admin was only reading from local theme.json and platform_theme, but uploaded emoji/asset URLs are stored in platform_assets. Now loads them on page render so the preview thumbnails actually appear. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-
Mahmoud Aglan authored
When chess piece images are uploaded via admin (chess_piece_wK, chess_piece_bQ, etc.), the board renders them instead of vector paths. Falls back to the original canvas paths if no images are uploaded. Re-renders automatically once images finish loading. Co-Authored-By:Claude Opus 4.6 <noreply@anthropic.com>
-