Match intro "players joining" loading screen + i18n fix; checkpoint
CI/CD / CI - API (dotnet build + engine sim) (push) Successful in 7m38s
CI/CD / CI - Web (tsc + next build) (push) Successful in 1m9s
CI/CD / Deploy - local stack (db + server + web) (push) Failing after 1s

- MatchIntroOverlay: UNO-style pre-game reveal — the 4 seats animate into the
  table (with "?" placeholders until each player's data streams in for live
  matches), a 3-2-1-GO countdown, then the table shows. Wired via game-store
  matchIntroPending/consumeIntro, rendered online-only in GameScreen.
- Fix: intro.found / intro.getReady / intro.go existed only in the Persian dict;
  added the English strings (would have shown raw keys to EN users).
- Checkpoint of the in-progress UI/social batch (CoinsPill, shop titles section,
  friend-request rate limit, etc.) — all green.

Verified: tsc + next build + scripts/sim.ts + dotnet build server/Hokm.slnx all pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
soroush.asadi
2026-06-06 21:58:54 +03:30
parent cb27a16dc1
commit 03dfbe1e67
16 changed files with 319 additions and 79 deletions
@@ -11,10 +11,10 @@ public class ProfileService
public static readonly CoinPackDto[] Packs =
{
new() { Id = "p1", Coins = 50000, Bonus = 0, PriceToman = 95000, Tag = "starter" },
new() { Id = "p2", Coins = 120000, Bonus = 15000, PriceToman = 189000, Tag = "popular" },
new() { Id = "p3", Coins = 300000, Bonus = 50000, PriceToman = 389000, Tag = "best" },
new() { Id = "p4", Coins = 700000, Bonus = 150000, PriceToman = 790000 },
new() { Id = "p1", Coins = 5000, Bonus = 0, PriceToman = 99000, Tag = "starter" },
new() { Id = "p2", Coins = 11000, Bonus = 1000, PriceToman = 199000, Tag = "popular" },
new() { Id = "p3", Coins = 24000, Bonus = 4000, PriceToman = 399000, Tag = "best" },
new() { Id = "p4", Coins = 50000, Bonus = 15000, PriceToman = 799000 },
};
private static ProfileDto Default(string userId, string? name) => new()
@@ -120,9 +120,9 @@ public class ProfileService
// Coin-priced XP packs (XP is intentionally expensive). Server-authoritative.
public static readonly Dictionary<string, (int Price, int Xp)> XpPacks = new()
{
["xp1"] = (5000, 200),
["xp2"] = (12000, 600),
["xp3"] = (25000, 1500),
["xp1"] = (1500, 200),
["xp2"] = (4000, 600),
["xp3"] = (8000, 1500),
};
public async Task<(bool ok, ProfileDto? profile, string error)> ShopBuy(string uid, string kind, string id, int price)
@@ -165,7 +165,7 @@ public class ProfileService
/* ----------------------------- daily ------------------------------ */
// Mirror the client DAILY_REWARDS (src/lib/online/gamification.ts) exactly.
private static readonly int[] DailyRewards = { 300, 500, 750, 1000, 1500, 2500, 7500 };
private static readonly int[] DailyRewards = { 100, 150, 200, 300, 400, 600, 1500 };
private static string Today => DateTime.UtcNow.ToString("yyyy-MM-dd");
public async Task<(int day, string? lastClaimed, bool available)> GetDaily(string uid)