@smartico/public-api 0.0.379 → 0.0.381
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/.nvmrc +1 -1
- package/CLAUDE.md +103 -0
- package/README.md +53 -2
- package/dist/Base/ClassId.d.ts +2 -0
- package/dist/Jackpots/JackpotDetails.d.ts +14 -15
- package/dist/Jackpots/JackpotPot.d.ts +10 -6
- package/dist/Raffle/GetRaffleWonPrizesRequest.d.ts +9 -0
- package/dist/Raffle/GetRaffleWonPrizesResponse.d.ts +52 -0
- package/dist/Raffle/index.d.ts +2 -0
- package/dist/SmarticoAPI.d.ts +6 -1
- package/dist/SmarticoLib/index.d.ts +5 -1
- package/dist/Store/BuyStoreItemErrorCode.d.ts +9 -1
- package/dist/Tournaments/TournamentRegistrationError.d.ts +3 -1
- package/dist/WSAPI/WSAPI.d.ts +13 -1235
- package/dist/WSAPI/WSAPIAvatars.d.ts +296 -0
- package/dist/WSAPI/WSAPIBase.d.ts +71 -0
- package/dist/WSAPI/WSAPIBonuses.d.ts +240 -0
- package/dist/WSAPI/WSAPIClans.d.ts +388 -0
- package/dist/WSAPI/WSAPIGamePick.d.ts +593 -0
- package/dist/WSAPI/WSAPIGeneral.d.ts +172 -0
- package/dist/WSAPI/WSAPIInbox.d.ts +615 -0
- package/dist/WSAPI/WSAPIJackpots.d.ts +344 -0
- package/dist/WSAPI/WSAPILeaderBoard.d.ts +139 -0
- package/dist/WSAPI/WSAPIMiniGames.d.ts +510 -0
- package/dist/WSAPI/WSAPIMissions.d.ts +517 -0
- package/dist/WSAPI/WSAPIRaffles.d.ts +643 -0
- package/dist/WSAPI/WSAPIStore.d.ts +656 -0
- package/dist/WSAPI/WSAPITournaments.d.ts +501 -0
- package/dist/WSAPI/WSAPITypes.d.ts +376 -205
- package/dist/WSAPI/WSAPIUser.d.ts +533 -0
- package/dist/index.js +6745 -1661
- package/dist/index.js.map +1 -1
- package/dist/index.modern.mjs +6324 -1342
- package/dist/index.modern.mjs.map +1 -1
- package/docs/Callbacks.md +162 -0
- package/docs/SmarticoObject.md +445 -0
- package/docs/Transforms.md +99 -0
- package/docs/api/README.md +82 -2
- package/docs/api/classes/WSAPIAvatars.md +344 -0
- package/docs/api/classes/WSAPIBonuses.md +271 -0
- package/docs/api/classes/WSAPIClans.md +436 -0
- package/docs/api/classes/WSAPIGamePick.md +710 -0
- package/docs/api/classes/WSAPIGeneral.md +212 -0
- package/docs/api/classes/WSAPIInbox.md +801 -0
- package/docs/api/classes/WSAPIJackpots.md +439 -0
- package/docs/api/classes/WSAPILeaderBoard.md +157 -0
- package/docs/api/classes/WSAPIMiniGames.md +612 -0
- package/docs/api/classes/WSAPIMissions.md +590 -0
- package/docs/api/classes/WSAPIRaffles.md +773 -0
- package/docs/api/classes/WSAPIStore.md +719 -0
- package/docs/api/classes/WSAPITournaments.md +571 -0
- package/docs/api/classes/WSAPIUser.md +637 -0
- package/docs/api/documents/Callbacks.md +162 -0
- package/docs/api/documents/SmarticoObject.md +445 -0
- package/docs/api/documents/Transforms.md +99 -0
- package/docs/api/enumerations/AchievementClaimPeriodTypeId.md +13 -0
- package/docs/api/enumerations/BonusStatus-1.md +11 -6
- package/docs/api/enumerations/BuyStoreItemErrorCode.md +32 -0
- package/docs/api/enumerations/JoinClanErrorCode.md +81 -0
- package/docs/api/enumerations/TournamentRegistrationError.md +12 -0
- package/docs/api/functions/clanTournamentPlayersTransform.md +13 -0
- package/docs/api/interfaces/AvatarCustomized.md +25 -0
- package/docs/api/interfaces/AvatarDefinition.md +94 -0
- package/docs/api/interfaces/AvatarPrompt.md +45 -0
- package/docs/api/interfaces/BonusMetaMap-1.md +4 -1
- package/docs/api/interfaces/BonusTemplateMetaMap-1.md +9 -4
- package/docs/api/interfaces/Clan.md +4 -0
- package/docs/api/interfaces/ClanInfo.md +109 -0
- package/docs/api/interfaces/ClanMember.md +53 -0
- package/docs/api/interfaces/ClanPrizePublicMeta.md +41 -0
- package/docs/api/interfaces/ClanPrizeStructureEntry.md +7 -1
- package/docs/api/interfaces/ClanPublicMeta.md +4 -0
- package/docs/api/interfaces/ClanTournamentPlayerRaw.md +67 -0
- package/docs/api/interfaces/GemsDiamondsLog.md +43 -0
- package/docs/api/interfaces/GetClanInfoResponse.md +61 -0
- package/docs/api/interfaces/GetClanTournamentPlayersResponse.md +81 -0
- package/docs/api/interfaces/GetRaffleWonPrizesRequest.md +59 -0
- package/docs/api/interfaces/GetRaffleWonPrizesResponse.md +95 -0
- package/docs/api/interfaces/InboxMarkMessageAction.md +10 -2
- package/docs/api/interfaces/JackpotDetails.md +14 -15
- package/docs/api/interfaces/JackpotPot.md +9 -6
- package/docs/api/interfaces/LeaderBoardDetailsT.md +14 -8
- package/docs/api/interfaces/LeaderBoardUserT.md +8 -5
- package/docs/api/interfaces/LeaderBoardsRewardsT.md +7 -0
- package/docs/api/interfaces/PointsLog.md +43 -0
- package/docs/api/interfaces/RaffleWonPrize.md +59 -0
- package/docs/api/interfaces/RaffleWonPrizePublicMeta.md +27 -0
- package/docs/api/interfaces/RaffleWonPrizeUser.md +43 -0
- package/docs/api/interfaces/SAWTemplateUI.md +10 -0
- package/docs/api/interfaces/TAchCategory.md +14 -4
- package/docs/api/interfaces/TAvatarCustomized.md +4 -4
- package/docs/api/interfaces/TAvatarDefinition.md +13 -14
- package/docs/api/interfaces/TAvatarPrompt.md +6 -6
- package/docs/api/interfaces/TBonus.md +16 -8
- package/docs/api/interfaces/TBuyStoreItemResult.md +4 -11
- package/docs/api/interfaces/TClaimBonusResult.md +5 -5
- package/docs/api/interfaces/TClan.md +8 -4
- package/docs/api/interfaces/TClanInfo.md +47 -0
- package/docs/api/interfaces/TClanJoinResult.md +11 -1
- package/docs/api/interfaces/TClanTournamentPlayer.md +55 -0
- package/docs/api/interfaces/TClanTournamentPlayersResult.md +27 -0
- package/docs/api/interfaces/TClans.md +3 -1
- package/docs/api/interfaces/TGetTranslations.md +4 -0
- package/docs/api/interfaces/TInboxMessage.md +14 -6
- package/docs/api/interfaces/TInboxMessageBody.md +18 -12
- package/docs/api/interfaces/TLevel.md +17 -20
- package/docs/api/interfaces/TLevelCurrent.md +19 -18
- package/docs/api/interfaces/TMiniGamePlayBatchResult.md +14 -6
- package/docs/api/interfaces/TMiniGamePlayResult.md +9 -4
- package/docs/api/interfaces/TMissionClaimRewardResult.md +6 -3
- package/docs/api/interfaces/TMissionOptInResult.md +6 -3
- package/docs/api/interfaces/TMissionOrBadge.md +5 -4
- package/docs/api/interfaces/TRaffleOptinResponse.md +4 -2
- package/docs/api/interfaces/TSegmentCheckResult.md +10 -0
- package/docs/api/interfaces/TSetAvatarResult.md +3 -3
- package/docs/api/interfaces/TStoreItem.md +11 -1
- package/docs/api/interfaces/TTournament.md +1 -1
- package/docs/api/interfaces/TTournamentDetailed.md +9 -1
- package/docs/api/interfaces/TTournamentRegistrationResult.md +4 -2
- package/docs/api/interfaces/TUICustomSection.md +23 -19
- package/docs/api/interfaces/TUserProfile.md +18 -16
- package/docs/api/interfaces/TransformedRaffleClaimPrizeResponse.md +6 -2
- package/docs/api/interfaces/UserAchievement.md +1 -1
- package/docs/api/interfaces/UserLevelExtraCountersT.md +9 -2
- package/docs/api/type-aliases/ActivityLogEntry.md +3 -0
- package/docs/native/ADDING_METHODS.md +7 -2
- package/docs/native/PROTOCOL.md +337 -0
- package/docs/ui/avatars/UIGuide_getAvatarPrompts.md +100 -0
- package/docs/ui/avatars/UIGuide_getAvatarsCustomized.md +90 -0
- package/docs/ui/avatars/UIGuide_getAvatarsList.md +105 -0
- package/docs/ui/avatars/UIGuide_setAvatar.md +118 -0
- package/docs/ui/bonuses/UIGuide_claimBonus.md +144 -0
- package/docs/ui/bonuses/UIGuide_getBonuses.md +176 -0
- package/docs/ui/clans/UIGuide_getClanInfo.md +153 -0
- package/docs/ui/clans/UIGuide_getClans.md +172 -0
- package/docs/ui/clans/UIGuide_joinClan.md +196 -0
- package/docs/ui/gamepick/UIGuide_gamePickGetActiveRound.md +99 -0
- package/docs/ui/gamepick/UIGuide_gamePickGetActiveRounds.md +76 -0
- package/docs/ui/gamepick/UIGuide_gamePickGetBoard.md +81 -0
- package/docs/ui/gamepick/UIGuide_gamePickGetGameInfo.md +78 -0
- package/docs/ui/gamepick/UIGuide_gamePickGetHistory.md +55 -0
- package/docs/ui/gamepick/UIGuide_gamePickGetRoundInfoForUser.md +71 -0
- package/docs/ui/gamepick/UIGuide_gamePickGetUserInfo.md +64 -0
- package/docs/ui/gamepick/UIGuide_gamePickSubmitSelection.md +103 -0
- package/docs/ui/gamepick/UIGuide_gamePickSubmitSelectionQuiz.md +67 -0
- package/docs/ui/general/UIGuide_getCustomSections.md +137 -0
- package/docs/ui/general/UIGuide_getRelatedItemsForGame.md +140 -0
- package/docs/ui/inbox/UIGuide_deleteInboxMessage.md +135 -0
- package/docs/ui/inbox/UIGuide_getInboxMessageBody.md +133 -0
- package/docs/ui/inbox/UIGuide_getInboxMessages.md +186 -0
- package/docs/ui/inbox/UIGuide_markInboxMessageAsRead.md +122 -0
- package/docs/ui/inbox/UIGuide_markUnmarkInboxMessageAsFavorite.md +84 -0
- package/docs/ui/jackpots/UIGuide_getJackpotEligibleGames.md +73 -0
- package/docs/ui/jackpots/UIGuide_getJackpotWinners.md +83 -0
- package/docs/ui/jackpots/UIGuide_jackpotGet.md +138 -0
- package/docs/ui/jackpots/UIGuide_jackpotOptIn.md +85 -0
- package/docs/ui/jackpots/UIGuide_jackpotOptOut.md +65 -0
- package/docs/ui/leaderboard/UIGuide_getLeaderBoard.md +166 -0
- package/docs/ui/minigames/UIGuide_getMiniGames.md +153 -0
- package/docs/ui/minigames/UIGuide_getMiniGamesHistory.md +90 -0
- package/docs/ui/minigames/UIGuide_playMiniGame.md +150 -0
- package/docs/ui/minigames/UIGuide_playMiniGameBatch.md +128 -0
- package/docs/ui/missions/UIGuide_getAchCategories.md +17 -0
- package/docs/ui/missions/UIGuide_getBadges.md +237 -0
- package/docs/ui/missions/UIGuide_getMissions.md +268 -0
- package/docs/ui/missions/UIGuide_requestMissionClaimReward.md +21 -0
- package/docs/ui/missions/UIGuide_requestMissionOptIn.md +16 -0
- package/docs/ui/raffles/UIGuide_claimRafflePrize.md +99 -0
- package/docs/ui/raffles/UIGuide_getRaffleDrawRun.md +117 -0
- package/docs/ui/raffles/UIGuide_getRaffleDrawRunsHistory.md +92 -0
- package/docs/ui/raffles/UIGuide_getRaffleWonPrizes.md +120 -0
- package/docs/ui/raffles/UIGuide_getRaffles.md +175 -0
- package/docs/ui/raffles/UIGuide_requestRaffleOptin.md +114 -0
- package/docs/ui/store/UIGuide_buyStoreItem.md +133 -0
- package/docs/ui/store/UIGuide_getStoreCategories.md +19 -0
- package/docs/ui/store/UIGuide_getStoreItems.md +264 -0
- package/docs/ui/store/UIGuide_getStorePurchasedItems.md +122 -0
- package/docs/ui/tournaments/UIGuide_getClanTournamentPlayers.md +140 -0
- package/docs/ui/tournaments/UIGuide_getTournamentInstanceInfo.md +265 -0
- package/docs/ui/tournaments/UIGuide_getTournamentsList.md +236 -0
- package/docs/ui/tournaments/UIGuide_registerInTournament.md +156 -0
- package/docs/ui/user/UIGuide_getActivityLog.md +130 -0
- package/docs/ui/user/UIGuide_getLevels.md +167 -0
- package/docs/ui/user/UIGuide_getUserProfile.md +213 -0
- package/package.json +3 -3
- package/scripts/postdoc-cleanup.js +195 -0
- package/src/Base/ClassId.ts +2 -0
- package/src/Jackpots/JackpotDetails.ts +14 -15
- package/src/Jackpots/JackpotPot.ts +10 -6
- package/src/Missions/MissionsUtils.ts +5 -2
- package/src/Raffle/GetRaffleWonPrizesRequest.ts +12 -0
- package/src/Raffle/GetRaffleWonPrizesResponse.ts +56 -0
- package/src/Raffle/index.ts +3 -1
- package/src/SmarticoAPI.ts +14 -1
- package/src/SmarticoLib/index.ts +4 -0
- package/src/Store/BuyStoreItemErrorCode.ts +8 -0
- package/src/Store/StoreItem.ts +1 -0
- package/src/Store/StoreItemPurchased.ts +1 -0
- package/src/Store/StoreItemType.ts +1 -1
- package/src/Tournaments/TournamentRegistrationError.ts +4 -0
- package/src/WSAPI/WSAPI.ts +27 -2007
- package/src/WSAPI/WSAPIAvatars.ts +345 -0
- package/src/WSAPI/WSAPIBase.ts +93 -0
- package/src/WSAPI/WSAPIBonuses.ts +268 -0
- package/src/WSAPI/WSAPIClans.ts +417 -0
- package/src/WSAPI/WSAPIGamePick.ts +667 -0
- package/src/WSAPI/WSAPIGeneral.ts +199 -0
- package/src/WSAPI/WSAPIInbox.ts +711 -0
- package/src/WSAPI/WSAPIJackpots.ts +448 -0
- package/src/WSAPI/WSAPILeaderBoard.ts +154 -0
- package/src/WSAPI/WSAPIMiniGames.ts +597 -0
- package/src/WSAPI/WSAPIMissions.ts +572 -0
- package/src/WSAPI/WSAPIRaffles.ts +703 -0
- package/src/WSAPI/WSAPIStore.ts +732 -0
- package/src/WSAPI/WSAPITournaments.ts +541 -0
- package/src/WSAPI/WSAPITypes.ts +376 -207
- package/src/WSAPI/WSAPIUser.ts +606 -0
- package/tsconfig.json +26 -2
- package/docs/api/classes/WSAPI.md +0 -1927
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# UI Guide — `getClans`
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
- Powers the **clan-browser screen** (and the clan-pick modal during
|
|
5
|
+
tournament registration via
|
|
6
|
+
[`registerInTournament`](../../api/classes/WSAPITournaments.md#registerintournament)).
|
|
7
|
+
- Returned `clans[]` is already server-sorted by `rating_position` ASC
|
|
8
|
+
(1 = best). The default Smartico UI re-sorts on the same key as a
|
|
9
|
+
defensive measure but no client-side ordering work is required.
|
|
10
|
+
- Loading indicator: the first call is a server round-trip
|
|
11
|
+
(typically 100–500 ms); subsequent calls within the 30 s cache
|
|
12
|
+
window resolve effectively synchronously.
|
|
13
|
+
- `onUpdate` is poll-driven (no server push). For near-live state, the
|
|
14
|
+
consumer must poll on an interval — the default Smartico UI polls
|
|
15
|
+
every 30 s while the clan screen is open.
|
|
16
|
+
|
|
17
|
+
## List view organization
|
|
18
|
+
|
|
19
|
+
A single flat ranked list — no tabs. Render `clans[]` in the order
|
|
20
|
+
returned (already sorted by `rating_position`).
|
|
21
|
+
|
|
22
|
+
**Client-side search filter**: filter `clan.public_meta.name` against
|
|
23
|
+
the user's typed query (case-insensitive). No server round-trip.
|
|
24
|
+
|
|
25
|
+
**Sticky "my clan" footer**: when the user is in a clan and the
|
|
26
|
+
visible list is long enough (the default Smartico UI uses ≥ 7 visible
|
|
27
|
+
items), pin a duplicate of the user's clan row at the bottom of the
|
|
28
|
+
scroll area so it remains visible while the user scrolls. Skip this
|
|
29
|
+
when the user is clanless or the list is short.
|
|
30
|
+
|
|
31
|
+
No dedicated "My Clan" panel at the top of the list — the user's clan
|
|
32
|
+
appears at its natural `rating_position`, just highlighted in place.
|
|
33
|
+
|
|
34
|
+
## Item card / row
|
|
35
|
+
|
|
36
|
+
Fields rendered (column structure for desktop; mobile may collapse):
|
|
37
|
+
|
|
38
|
+
| Column | Source | Notes |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| Rank | `rating_position` | Display as `#N`. Apply `.top-1` / `.top-2` / `.top-3` styling for positions 1–3. |
|
|
41
|
+
| Icon / image | `public_meta.image_url` | Square. Fallback: first character of `public_meta.name` rendered as a letter avatar. |
|
|
42
|
+
| Name | `public_meta.name` | Translated server-side. Add "Your clan" badge next to the name if `clan.clan_id === user_clan_id`. |
|
|
43
|
+
| Rating score | `rating_score` | Numeric; the higher, the better. |
|
|
44
|
+
| Members | `member_count` / `capacity_limit` | Desktop: render a progress bar at `member_count / capacity_limit * 100%` with a label `N / M`. Mobile: text-only `N / M`. |
|
|
45
|
+
| Entry fee | `entry_fee_amount` + `entry_fee_currency_type_id` | "Free" when `entry_fee_amount === 0` or `entry_fee_currency_type_id === 3`. Otherwise `"{amount} {Points|Gems|Diamonds}"`. |
|
|
46
|
+
|
|
47
|
+
**Whole-row click target**: opens the detail modal (via
|
|
48
|
+
[`getClanInfo`](../../api/classes/WSAPIClans.md#getclaninfo) to load
|
|
49
|
+
members on demand). The row itself has no inline Join CTA — joining
|
|
50
|
+
happens from inside the detail modal (see "Action button decision
|
|
51
|
+
matrix" below).
|
|
52
|
+
|
|
53
|
+
**Detail-only fields** (not on row): `description`, full `members[]`
|
|
54
|
+
list (from `getClanInfo`), full progress bar styling on desktop.
|
|
55
|
+
|
|
56
|
+
## Action button decision matrix
|
|
57
|
+
|
|
58
|
+
The Join CTA lives in the detail modal (or the clan-pick modal during
|
|
59
|
+
tournament registration). Evaluate in priority order — first match
|
|
60
|
+
wins.
|
|
61
|
+
|
|
62
|
+
| State | Condition | Button label | Enabled? | Notes |
|
|
63
|
+
|---|---|---|---|---|
|
|
64
|
+
| **Your clan** | `clan.clan_id === user_clan_id` | "Your clan" | No-op | Highlight; no join action. |
|
|
65
|
+
| **Cooldown active** | `cooldown_until !== null` | `"Cooldown until <local-date>"` | Disabled | Affects ALL clans — the cooldown is user-level, not per-clan. Format `cooldown_until` from UTC to local time (`DD-MM-YYYY HH:mm` style). |
|
|
66
|
+
| **Clan full** | `member_count >= capacity_limit` | "Clan is full" | Disabled | |
|
|
67
|
+
| **Insufficient balance** | `entry_fee_amount > 0` AND user's balance for `entry_fee_currency_type_id` < `entry_fee_amount` | `"Not enough {Points|Gems|Diamonds} (deficit)"` | Disabled | Cross-check against {@link getUserProfile} balance for the currency. |
|
|
68
|
+
| **Joinable — free** | `entry_fee_amount === 0` OR `entry_fee_currency_type_id === 3` | "Join free" | Enabled | |
|
|
69
|
+
| **Joinable — paid** | default | `"Join ({amount} {Points|Gems|Diamonds})"` | Enabled | |
|
|
70
|
+
|
|
71
|
+
The enabled Join click invokes
|
|
72
|
+
[`joinClan(clan_id)`](../../api/classes/WSAPIClans.md#joinclan). See
|
|
73
|
+
its own UI guide for the in-flight + error-code matrix.
|
|
74
|
+
|
|
75
|
+
**Picker mode (`registerInTournament` clan-pick modal)**: when the
|
|
76
|
+
user is in cooldown, the default Smartico UI disables every row in the
|
|
77
|
+
picker (not just the buttons) — `onClick` is suppressed entirely.
|
|
78
|
+
|
|
79
|
+
## Cooldown rendering
|
|
80
|
+
|
|
81
|
+
- The cooldown is **user-level**, not per-clan. While
|
|
82
|
+
`cooldown_until !== null`, the user cannot join any clan.
|
|
83
|
+
- Format: `cooldown_until` is an ISO 8601 UTC string
|
|
84
|
+
(`"YYYY-MM-DDTHH:MM:SS"`, no timezone suffix). Parse as UTC, display
|
|
85
|
+
in user-local time. The default Smartico UI shows
|
|
86
|
+
`DD-MM-YYYY HH:mm` (e.g. `"01-06-2026 16:30"`).
|
|
87
|
+
- No "X days remaining" countdown — show the absolute expiry datetime.
|
|
88
|
+
If your product surface justifies a countdown, render one yourself.
|
|
89
|
+
|
|
90
|
+
## Image / asset specs
|
|
91
|
+
|
|
92
|
+
| Field | Aspect ratio | Notes |
|
|
93
|
+
|---|---|---|
|
|
94
|
+
| `public_meta.image_url` | 1:1 (square) | Recommended source size not strictly enforced; the default Smartico UI sizes via CSS. Provide a square image for best results. |
|
|
95
|
+
|
|
96
|
+
**Fallback**: when `image_url` is missing or fails to load, render
|
|
97
|
+
the first character of `public_meta.name` as a letter avatar in the
|
|
98
|
+
icon container.
|
|
99
|
+
|
|
100
|
+
## Status-specific visual treatments
|
|
101
|
+
|
|
102
|
+
- **Your clan**: row gets a `.highlight` background tint + "Your clan"
|
|
103
|
+
badge next to the name.
|
|
104
|
+
- **Top-3 rank**: rows for `rating_position` 1–3 get podium accents
|
|
105
|
+
(gold/silver/bronze).
|
|
106
|
+
- **Full clan**: no row-level treatment — only the detail-modal button
|
|
107
|
+
shows the disabled state.
|
|
108
|
+
- **Cooldown active**: only the detail-modal button is disabled (or
|
|
109
|
+
in the picker, the whole row is dimmed).
|
|
110
|
+
- **Insufficient balance**: only the detail-modal button is disabled.
|
|
111
|
+
|
|
112
|
+
## Empty / loading / error states
|
|
113
|
+
|
|
114
|
+
- **Loading (first fetch)**: render a spinner / shimmer skeleton of
|
|
115
|
+
rows.
|
|
116
|
+
- **Empty list (no clans configured)**: render a neutral empty-state
|
|
117
|
+
illustration with copy like "No clans available".
|
|
118
|
+
- **Empty search results**: same empty-state illustration with
|
|
119
|
+
query-aware copy (e.g. "No clans matching '<query>'").
|
|
120
|
+
- **Error**: the default Smartico UI keeps the spinner visible
|
|
121
|
+
indefinitely on fetch failure (no error boundary). For a better UX,
|
|
122
|
+
catch the rejected promise and render a "Failed to load — Try again"
|
|
123
|
+
affordance.
|
|
124
|
+
|
|
125
|
+
## Refresh
|
|
126
|
+
|
|
127
|
+
`onUpdate` is poll-driven only. Two ways to keep the list fresh:
|
|
128
|
+
|
|
129
|
+
1. **Poll**: re-call `getClans()` on a 30-second interval while the
|
|
130
|
+
clan screen is visible. The cache deduplicates rapid refetches.
|
|
131
|
+
2. **Re-call after mutations**: after a successful
|
|
132
|
+
[`joinClan`](../../api/classes/WSAPIClans.md#joinclan), re-call
|
|
133
|
+
`getClans()` immediately to pick up the new `user_clan_id` and any
|
|
134
|
+
refreshed `member_count` / `cooldown_until` fields.
|
|
135
|
+
|
|
136
|
+
There is no server push that refreshes the clans list automatically
|
|
137
|
+
— another user joining your clan, an operator kicking you, or a clan
|
|
138
|
+
being archived will all only surface on the next consumer-driven
|
|
139
|
+
fetch.
|
|
140
|
+
|
|
141
|
+
## Animations / transitions
|
|
142
|
+
|
|
143
|
+
- **List entry**: rows fade-in with a ~30 ms stagger on first render.
|
|
144
|
+
- **Rank reorder between polls**: if you implement live updates,
|
|
145
|
+
detect `rating_position` changes by diffing the previous and
|
|
146
|
+
current arrays, and animate rows to their new position (FLIP
|
|
147
|
+
animation). Don't full-re-render the list.
|
|
148
|
+
- **Join success celebration**: when `user_clan_id` flips between
|
|
149
|
+
polls (detect by comparing pre- and post-refresh values), play a
|
|
150
|
+
brief "Welcome to {clan name}" toast and animate the now-highlighted
|
|
151
|
+
row.
|
|
152
|
+
|
|
153
|
+
## Mobile vs desktop
|
|
154
|
+
|
|
155
|
+
- **Member fill**: desktop renders a progress bar; mobile renders
|
|
156
|
+
text-only (`N / M`).
|
|
157
|
+
- **Columns**: desktop shows `#`, Clan, Rating, Members, Entry;
|
|
158
|
+
mobile drops Members (entry fee inlines below the name).
|
|
159
|
+
- **Sticky my-clan footer**: same threshold on both (≥ 7 visible
|
|
160
|
+
rows).
|
|
161
|
+
- **Search**: same client-side filter; desktop typically has a
|
|
162
|
+
search input at the top; mobile may use a dedicated search sheet.
|
|
163
|
+
|
|
164
|
+
## Performance
|
|
165
|
+
|
|
166
|
+
- 30 s polling on the clans surface is fine for typical clan
|
|
167
|
+
catalogs (< 200 clans). For very large catalogs, consider polling
|
|
168
|
+
only while the surface is in the viewport.
|
|
169
|
+
- Use keyed per-row rendering — celebration / rank-reorder animations
|
|
170
|
+
break if the DOM nodes are recreated on every poll tick.
|
|
171
|
+
- Image lazy-loading is safe; clans below the fold rarely need
|
|
172
|
+
immediate paint.
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# UI Guide — `joinClan`
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
- Action-focused mutation. The user is on the clans browser or the
|
|
5
|
+
detail modal, the CTA is "Join (...)", and they click it.
|
|
6
|
+
- A successful response (`errCode === 0`) means: membership persisted,
|
|
7
|
+
entry fee (if any) already debited, cooldown restarted, CRM events
|
|
8
|
+
fired. The SDK has done all of this server-side by the time the
|
|
9
|
+
promise resolves.
|
|
10
|
+
- The SDK does NOT auto-refresh `getClans` after success. The
|
|
11
|
+
consumer must re-call manually.
|
|
12
|
+
- Latency: typically 200–800 ms for a healthy WebSocket connection
|
|
13
|
+
(the server performs balance checks + atomic DB writes
|
|
14
|
+
synchronously).
|
|
15
|
+
|
|
16
|
+
## Loading state
|
|
17
|
+
|
|
18
|
+
- **Trigger**: set an in-flight flag (`joining = true`) immediately
|
|
19
|
+
on click, BEFORE the call. This is the consumer's responsibility
|
|
20
|
+
— the SDK has no in-flight guard.
|
|
21
|
+
- **Visual**: replace the button label with animated dots / spinner.
|
|
22
|
+
Disable the button. Keep the modal open.
|
|
23
|
+
- **Reset**: clear the in-flight flag on response — success or error.
|
|
24
|
+
|
|
25
|
+
## Idempotency UI guard
|
|
26
|
+
|
|
27
|
+
**Two distinct hazards** the consumer must guard against:
|
|
28
|
+
|
|
29
|
+
1. **Double-click during in-flight**: the SDK does NOT prevent two
|
|
30
|
+
simultaneous `joinClan` calls. If the user clicks twice before the
|
|
31
|
+
first response arrives, both requests reach the server. If the
|
|
32
|
+
first succeeds, the second behaves as a clan-switch to the same
|
|
33
|
+
clan — which, on labels with `CLAN_COOLDOWN_DAYS = 0`, will
|
|
34
|
+
**deduct the entry fee a second time**. Guard with an in-flight
|
|
35
|
+
flag (see "Loading state").
|
|
36
|
+
|
|
37
|
+
2. **Same-clan re-click**: the SDK does NOT short-circuit when the
|
|
38
|
+
user clicks Join on the clan they're already in. The server
|
|
39
|
+
treats it as a clan-switch to the same clan, and on labels with
|
|
40
|
+
cooldown=0 will re-deduct the fee. The Join button MUST be
|
|
41
|
+
disabled (or show "Your clan") whenever
|
|
42
|
+
`target.clan_id === user_clan_id`. Don't rely on the server to
|
|
43
|
+
silently no-op.
|
|
44
|
+
|
|
45
|
+
Recommended pattern:
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
const [joining, setJoining] = useState(false);
|
|
49
|
+
|
|
50
|
+
const onJoin = async () => {
|
|
51
|
+
if (joining) return; // in-flight guard
|
|
52
|
+
if (target.clan_id === userClanId) return; // same-clan guard
|
|
53
|
+
if (cooldownUntil) return; // cooldown guard
|
|
54
|
+
if (target.member_count >= target.capacity_limit) return;
|
|
55
|
+
// (also: balance guard — handled by the pre-render CTA state matrix)
|
|
56
|
+
|
|
57
|
+
setJoining(true);
|
|
58
|
+
const r = await window._smartico.api.joinClan(target.clan_id);
|
|
59
|
+
setJoining(false);
|
|
60
|
+
handleResponse(r);
|
|
61
|
+
if (r.errCode === 0) await window._smartico.api.getClans();
|
|
62
|
+
};
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Action button decision matrix
|
|
66
|
+
|
|
67
|
+
`errCode` branch behavior. Refer to the `joinClan` TSDoc for the full
|
|
68
|
+
table of codes; UI handling per code:
|
|
69
|
+
|
|
70
|
+
| `errCode` | Action |
|
|
71
|
+
|---|---|
|
|
72
|
+
| `0` (success) | Show success toast (e.g. `"Joined {clan.name}"`). Close modal (or transition it to the "Your clan" state). Call `getClans()` to refresh `user_clan_id`, `member_count`, and `cooldown_until`. The default Smartico UI also dispatches an optimistic local state update so the Join button instantly flips to "Your clan" before the refresh lands. |
|
|
73
|
+
| `1000` (invalid parameters) | Programming error from SDK consumer side — should not occur. Show a generic error toast. |
|
|
74
|
+
| `1001` (not found / archived) | Refresh `getClans()`; the clan should disappear from the list. Show a brief "clan no longer available" toast. |
|
|
75
|
+
| `1002` (full) | Show "Clan is full". Refresh `getClans()`; the now-full clan's button will pre-disable to "Clan is full". |
|
|
76
|
+
| `1003` (insufficient funds) | Show insufficient-balance UI naming the currency (`['points','gems','diamonds'][entry_fee_currency_type_id]`) and the deficit (`entry_fee_amount`). Optional: deep-link to a currency-earning surface. |
|
|
77
|
+
| `1004` (segment mismatch) | Show a gating message — operator-supplied copy if the clan exposes one; otherwise a generic "Not eligible for this clan". Don't retry. |
|
|
78
|
+
| `1005` | `joinClan` does NOT return `1005`. If you see it in this method's response, treat as a generic error. |
|
|
79
|
+
| `1006` (cooldown active) | Show "Cooldown until {cooldown_until local-formatted}". Disable the Join CTA across ALL clans until cooldown expires. |
|
|
80
|
+
| `1007` (archived) | Defined in the public enum but the server emits `1001` instead. Handle as a synonym for `1001` defensively. |
|
|
81
|
+
| `1011` | `joinClan` does NOT return `1011`. If you see it in this method's response, treat as a generic error. |
|
|
82
|
+
| Other | Generic error toast with `errMsg` if any. |
|
|
83
|
+
|
|
84
|
+
## Per-error-code message strategy
|
|
85
|
+
|
|
86
|
+
| `errCode` | `errMsg` usable? | Operator-supplied copy | Best source |
|
|
87
|
+
|---|---|---|---|
|
|
88
|
+
| `0` (success) | — | — | Localized `"Joined {clan.name}"` |
|
|
89
|
+
| `1003` (insufficient funds) | Fallback | — | Localized `"Insufficient {currency}"` + deficit derived from `entry_fee_amount` and the user's balance |
|
|
90
|
+
| `1004` (segment mismatch) | Fallback | If the clan has an operator-supplied entry-conditions message, prefer it | Otherwise localized "Not eligible for this clan" |
|
|
91
|
+
| `1006` (cooldown) | Fallback | — | Localized "Cooldown until {date}" — format `cooldown_until` from UTC to local |
|
|
92
|
+
| `1002` (full) | Fallback | — | Localized "Clan is full" |
|
|
93
|
+
| All others | Use `errMsg` as a fallback when no specific localized copy is available | — | Localized error per code |
|
|
94
|
+
|
|
95
|
+
## Optimistic update
|
|
96
|
+
|
|
97
|
+
The default Smartico UI optimistically flips the user's clan
|
|
98
|
+
membership state on `errCode === 0` (before `getClans()` refreshes).
|
|
99
|
+
This is **safe** for this method because:
|
|
100
|
+
|
|
101
|
+
- The server has already committed the membership row when the
|
|
102
|
+
response returns.
|
|
103
|
+
- The fee is already debited.
|
|
104
|
+
- If the optimistic update sets `user_clan_id` to the new clan, the
|
|
105
|
+
refresh from `getClans()` will confirm the same value.
|
|
106
|
+
|
|
107
|
+
You can mirror this pattern: on `errCode === 0`, immediately update
|
|
108
|
+
the UI to show the user in the new clan, then re-fetch in the
|
|
109
|
+
background. If the refresh disagrees (very unlikely), reconcile.
|
|
110
|
+
|
|
111
|
+
Do NOT optimistically update on any non-zero `errCode` — those are
|
|
112
|
+
real failures.
|
|
113
|
+
|
|
114
|
+
## Success celebration
|
|
115
|
+
|
|
116
|
+
The default Smartico UI does not play a dedicated celebration
|
|
117
|
+
animation (no confetti, no full-screen overlay). The button flips
|
|
118
|
+
to "Your clan" immediately via optimistic update, and the modal
|
|
119
|
+
re-renders with refreshed member data once `getClans()` returns.
|
|
120
|
+
|
|
121
|
+
If your product surface justifies a celebration, drive it from the
|
|
122
|
+
`onUpdate` detection: when `result.user_clan_id` flips between
|
|
123
|
+
pre-join and post-join fetches, play your celebration.
|
|
124
|
+
|
|
125
|
+
## Refresh after response
|
|
126
|
+
|
|
127
|
+
The SDK does NOT auto-refresh the `getClans` cache. After a
|
|
128
|
+
successful join, manually call `getClans()` to pick up:
|
|
129
|
+
|
|
130
|
+
- The new `user_clan_id`
|
|
131
|
+
- The new `cooldown_until` (cooldown restarts at join time)
|
|
132
|
+
- The updated `member_count` on the joined clan
|
|
133
|
+
- The decremented `member_count` on any previously-joined clan
|
|
134
|
+
(clan-switch case)
|
|
135
|
+
|
|
136
|
+
The user's balance update from the entry-fee debit arrives via the
|
|
137
|
+
SDK's user-properties update channel — subscribe separately to
|
|
138
|
+
{@link getUserProfile} if your UI shows the balance.
|
|
139
|
+
|
|
140
|
+
## Clan-switch semantics
|
|
141
|
+
|
|
142
|
+
When the user is in clan A and successfully joins clan B, the
|
|
143
|
+
server performs an **atomic transition**: deactivate A membership,
|
|
144
|
+
insert B membership, debit fee — all in one transaction. The user
|
|
145
|
+
is never observably clanless during the switch.
|
|
146
|
+
|
|
147
|
+
From the UI's perspective, this is identical to a fresh join. No
|
|
148
|
+
special handling required — the response is the same `errCode === 0`,
|
|
149
|
+
and `getClans()` refresh will show the user in clan B with a fresh
|
|
150
|
+
cooldown.
|
|
151
|
+
|
|
152
|
+
## Special case — tournament clan-pick flow
|
|
153
|
+
|
|
154
|
+
When `registerInTournament(tournamentId)` returns `1005` (user has
|
|
155
|
+
no clan and the tournament is clan-based), the default UI typically:
|
|
156
|
+
|
|
157
|
+
1. Opens a clan-picker driven by `getClans`.
|
|
158
|
+
2. User picks a clan → call `joinClan(clanId)`.
|
|
159
|
+
3. On `errCode === 0`, automatically retry
|
|
160
|
+
`registerInTournament(tournamentId)`.
|
|
161
|
+
4. Handle `1011` on the retry: user joined the clan but joined
|
|
162
|
+
after this tournament started (and has prior tournament scores)
|
|
163
|
+
— show an explanatory message; the user is in the clan but
|
|
164
|
+
blocked from this specific tournament run.
|
|
165
|
+
|
|
166
|
+
The SDK does NOT chain these calls automatically. Each step is the
|
|
167
|
+
consumer's responsibility. See the
|
|
168
|
+
[UI Guide for `registerInTournament`](../tournaments/UIGuide_registerInTournament.md)
|
|
169
|
+
for the recommended sequence.
|
|
170
|
+
|
|
171
|
+
## Animations / transitions
|
|
172
|
+
|
|
173
|
+
- **Loading dots**: 3-dot bouncing animation on the button while the
|
|
174
|
+
promise is in flight.
|
|
175
|
+
- **Button state flip**: when the response arrives, animate the
|
|
176
|
+
button label transition (~150 ms ease-out).
|
|
177
|
+
- **Member list refresh**: after `getClans()` re-fetch, the affected
|
|
178
|
+
clan rows (`member_count` change, your clan now highlighted) get a
|
|
179
|
+
brief highlight pulse on update.
|
|
180
|
+
|
|
181
|
+
## Mobile vs desktop
|
|
182
|
+
|
|
183
|
+
- **Loading state**: identical (dots on the button).
|
|
184
|
+
- **Error surfacing**: desktop typically uses a toast/snackbar;
|
|
185
|
+
mobile may use a centered modal with a clear "OK" affordance.
|
|
186
|
+
- **Cooldown / insufficient-balance disabled states**: rendered the
|
|
187
|
+
same way on both — the disabled button shows the constraint text.
|
|
188
|
+
|
|
189
|
+
## Performance
|
|
190
|
+
|
|
191
|
+
- Single round-trip per click. No batching needed.
|
|
192
|
+
- The `getClans()` refresh after success adds ~50–500 ms (cache miss
|
|
193
|
+
→ fresh fetch). Treat as fire-and-forget; the optimistic UI flip
|
|
194
|
+
has already happened.
|
|
195
|
+
- Don't poll `getClans()` to detect join completion — the response
|
|
196
|
+
promise is the authoritative signal.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# UI Guide — `gamePickGetActiveRound`
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
- Returns a single round with its events, user selections, scoring rules.
|
|
5
|
+
- Powers the round-detail / prediction-input screen.
|
|
6
|
+
- No cache; no push subscription.
|
|
7
|
+
|
|
8
|
+
## Detail view layout
|
|
9
|
+
|
|
10
|
+
Top-to-bottom sections in the default Smartico UI:
|
|
11
|
+
|
|
12
|
+
1. **Header**: round name + description + status pill (see
|
|
13
|
+
[`gamePickGetActiveRounds`](../../api/classes/WSAPIGamePick.md#gamepickgetactiverounds)
|
|
14
|
+
for status mapping).
|
|
15
|
+
2. **Timer / deadline**: countdown to `last_bet_date` ("Bets close in 2h 15m").
|
|
16
|
+
3. **Score recap (if scored)**: `user_score`, full/partial/lost counts.
|
|
17
|
+
4. **Event list**: one row per event in `events[]`.
|
|
18
|
+
|
|
19
|
+
## Event row layout
|
|
20
|
+
|
|
21
|
+
Each event row carries:
|
|
22
|
+
|
|
23
|
+
| Field | Source | Notes |
|
|
24
|
+
|---|---|---|
|
|
25
|
+
| Teams / question | `event_meta.team1_name`, `event_meta.team2_name` (MatchX) or `event_meta.text` (Quiz) | Heading |
|
|
26
|
+
| Team images | `event_meta.team1_img`, `event_meta.team2_img` | 32×32 px (1:1) |
|
|
27
|
+
| Match date | `match_date` | "Sat 25 May · 16:00" |
|
|
28
|
+
| Sport | `event_meta.sport` | Small chip |
|
|
29
|
+
| Odds | `odds_details` | Optional display |
|
|
30
|
+
| User selection input | based on `market_type_id` | Score pickers (MatchX) / radio (Quiz) |
|
|
31
|
+
| Resolution badge | `resolution_type_id` (`GamePickResolutionType`) | Only after resolution |
|
|
32
|
+
| `is_open_for_bets` | boolean | Disable input when false |
|
|
33
|
+
|
|
34
|
+
## Prediction input by `market_type_id`
|
|
35
|
+
|
|
36
|
+
| Market | Input type |
|
|
37
|
+
|---|---|
|
|
38
|
+
| MatchX Goals / Winner | Two numeric pickers (team1 score / team2 score) |
|
|
39
|
+
| Quiz 1×2 | Three buttons (1 / X / 2) |
|
|
40
|
+
| Quiz Yes / No | Two buttons (Yes / No) |
|
|
41
|
+
| Quiz custom | Operator-defined buttons |
|
|
42
|
+
|
|
43
|
+
## Action button decision matrix
|
|
44
|
+
|
|
45
|
+
Bottom CTA per round state:
|
|
46
|
+
|
|
47
|
+
| State | CTA |
|
|
48
|
+
|---|---|
|
|
49
|
+
| `is_active_now && has_open_for_bet_events && !user_placed_bet` | "Submit predictions" (primary) |
|
|
50
|
+
| `is_active_now && has_open_for_bet_events && user_placed_bet` (and edits made) | "Update predictions" (primary) |
|
|
51
|
+
| `is_active_now && user_placed_bet` (no pending changes) | Disabled "Predictions submitted" |
|
|
52
|
+
| `!has_open_for_bet_events` | Hidden / "View only" message |
|
|
53
|
+
| `is_resolved` | "View results" — links to history |
|
|
54
|
+
|
|
55
|
+
## Resolution badges (`GamePickResolutionType`)
|
|
56
|
+
|
|
57
|
+
| Value | Badge |
|
|
58
|
+
|---|---|
|
|
59
|
+
| `None` (0) | No badge (event not yet resolved) |
|
|
60
|
+
| `Lost` (2) | Red X icon |
|
|
61
|
+
| `PartialWin` (3) | Amber half-star |
|
|
62
|
+
| `FullWin` (4) | Green checkmark |
|
|
63
|
+
|
|
64
|
+
## Edits and `allow_edit_answers`
|
|
65
|
+
|
|
66
|
+
When the round is open and an event's `is_open_for_bets` is true, the user
|
|
67
|
+
can edit predictions for that event. The `allow_edit_answers` flag on the
|
|
68
|
+
round controls whether edits are accepted; the server enforces this and
|
|
69
|
+
returns `errCode: 3` (no-op) if submits happen after the deadline.
|
|
70
|
+
|
|
71
|
+
## Error states
|
|
72
|
+
|
|
73
|
+
| `errCode` | Treatment |
|
|
74
|
+
|---|---|
|
|
75
|
+
| `4` (round / event not found) | Refresh active rounds and bounce back to lobby |
|
|
76
|
+
| `100002` (template not found) | Bounce back to lobby |
|
|
77
|
+
| `100000` (auth) | Re-init session |
|
|
78
|
+
|
|
79
|
+
## Refresh
|
|
80
|
+
|
|
81
|
+
- No SDK cache.
|
|
82
|
+
- Re-call after a submit to surface the persisted predictions and updated
|
|
83
|
+
state.
|
|
84
|
+
- Poll every 30–60 s while the user is on the screen if event resolution
|
|
85
|
+
updates matter.
|
|
86
|
+
|
|
87
|
+
## Mobile vs desktop
|
|
88
|
+
|
|
89
|
+
- **Mobile**: event rows stack full-width with score pickers below the
|
|
90
|
+
teams.
|
|
91
|
+
- **Desktop**: 2-column event grid; score pickers inline with teams.
|
|
92
|
+
|
|
93
|
+
## Performance
|
|
94
|
+
|
|
95
|
+
- Single round-trip. The full event list ships in one payload.
|
|
96
|
+
- For lobby views with many rounds, prefer
|
|
97
|
+
[`gamePickGetGameInfo`](../../api/classes/WSAPIGamePick.md#gamepickgetgameinfo)
|
|
98
|
+
for a metadata-only round list and only call this method when the user
|
|
99
|
+
opens a specific round.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# UI Guide — `gamePickGetActiveRounds`
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
- Returns every open round for a MatchX or Quiz game template, with full
|
|
5
|
+
event lists and the user's selections per event.
|
|
6
|
+
- Powers the rounds-lobby screen.
|
|
7
|
+
- No SDK cache; every call is a live HTTP roundtrip to the Game Pick games
|
|
8
|
+
server.
|
|
9
|
+
- No push subscription — poll if you need live status updates.
|
|
10
|
+
|
|
11
|
+
## List view organization
|
|
12
|
+
|
|
13
|
+
Single flat list of round cards. The default Smartico UI sorts by `open_date`
|
|
14
|
+
ascending (closest-opening or already-open first). Rounds with status
|
|
15
|
+
`NoEventsDefined` (1) are filtered out server-side and never appear.
|
|
16
|
+
|
|
17
|
+
## Item card / tile
|
|
18
|
+
|
|
19
|
+
Fields rendered per round card:
|
|
20
|
+
|
|
21
|
+
| Field | Source | Notes |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| Round name | `round_name` | Title |
|
|
24
|
+
| Description | `round_description` | Subtitle (truncated) |
|
|
25
|
+
| Open / close window | `open_date`, `last_bet_date` | "Bets close in 2h 15m" |
|
|
26
|
+
| Event count | `events.length` | "5 matches" / "10 questions" |
|
|
27
|
+
| User progress | `user_placed_bet` | "Predictions submitted" badge or "Make your picks" CTA |
|
|
28
|
+
| Score so far | `user_score` | Visible after resolution |
|
|
29
|
+
| Status pill | `round_status_id` | See mapping below |
|
|
30
|
+
|
|
31
|
+
## Status pill mapping (`GPRoundStatus`)
|
|
32
|
+
|
|
33
|
+
| Value | Label / treatment |
|
|
34
|
+
|---|---|
|
|
35
|
+
| `Other` (-1) | Active — green pill "Open" |
|
|
36
|
+
| `NoMoreBetsAllowed` (2) | Amber pill "Bets closed" |
|
|
37
|
+
| `AllEventsResolved_ButNotRound` (3) | Blue pill "Awaiting resolution" |
|
|
38
|
+
| `RoundResolved` (4) | Gray pill "Resolved" |
|
|
39
|
+
|
|
40
|
+
(Status 1 `NoEventsDefined` never appears here.)
|
|
41
|
+
|
|
42
|
+
## Click target
|
|
43
|
+
|
|
44
|
+
Single tap opens the round-detail view (calls
|
|
45
|
+
[`gamePickGetActiveRound`](../../api/classes/WSAPIGamePick.md#gamepickgetactiveround)
|
|
46
|
+
for that round).
|
|
47
|
+
|
|
48
|
+
## Empty / loading / error states
|
|
49
|
+
|
|
50
|
+
- **Empty (`errCode: 100003`)**: "No open rounds right now — check back later."
|
|
51
|
+
- **Loading**: skeleton card list (2–3 placeholders).
|
|
52
|
+
- **Error (`errCode: 100002`)**: "Game not found" — likely template ID is
|
|
53
|
+
wrong; bounce back to the lobby.
|
|
54
|
+
- **Error (`errCode: 100000`)**: "Session expired — please log in again" —
|
|
55
|
+
hash auth failure.
|
|
56
|
+
|
|
57
|
+
## Refresh
|
|
58
|
+
|
|
59
|
+
- No SDK cache.
|
|
60
|
+
- Poll every 30–60 s while the user is on the lobby screen to catch
|
|
61
|
+
status changes (events going from open to closed).
|
|
62
|
+
- Re-call after any submit ([`gamePickSubmitSelection`](../../api/classes/WSAPIGamePick.md#gamepicksubmitselection)
|
|
63
|
+
or [`gamePickSubmitSelectionQuiz`](../../api/classes/WSAPIGamePick.md#gamepicksubmitselectionquiz))
|
|
64
|
+
to reflect the new `user_placed_bet` state on the relevant round card.
|
|
65
|
+
|
|
66
|
+
## Mobile vs desktop
|
|
67
|
+
|
|
68
|
+
- **Mobile**: full-width round cards stacked vertically.
|
|
69
|
+
- **Desktop**: 2- or 3-column grid of round cards.
|
|
70
|
+
|
|
71
|
+
## Performance
|
|
72
|
+
|
|
73
|
+
- Each call ships the full event list. For lobbies with many rounds, prefer
|
|
74
|
+
[`gamePickGetGameInfo`](../../api/classes/WSAPIGamePick.md#gamepickgetgameinfo)
|
|
75
|
+
which returns round metadata only (no events), then call this method only
|
|
76
|
+
when the user wants to see prediction-able rounds in detail.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# UI Guide — `gamePickGetBoard`
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
- Returns a leaderboard scoped to one round, OR (with `round_id: -1`) the
|
|
5
|
+
season / overall leaderboard for the template.
|
|
6
|
+
- Powers leaderboard screens within the Game Pick experience.
|
|
7
|
+
- No cache; no push subscription.
|
|
8
|
+
|
|
9
|
+
## List view organization
|
|
10
|
+
|
|
11
|
+
Server-ranked. `users[]` is the public top list; `my_user` carries the
|
|
12
|
+
current user's row separately (renders as a sticky "you are here" footer).
|
|
13
|
+
|
|
14
|
+
## Row layout
|
|
15
|
+
|
|
16
|
+
Each leaderboard row shows:
|
|
17
|
+
|
|
18
|
+
| Field | Source | Notes |
|
|
19
|
+
|---|---|---|
|
|
20
|
+
| Rank | `gp_position` | Big number or "—" when null (not yet ranked) |
|
|
21
|
+
| Avatar | `avatar_url` | 32×32 px (1:1) |
|
|
22
|
+
| Username | `public_username` | May be masked / anonymized by label settings — see below |
|
|
23
|
+
| Score | `resolution_score` | Total score in the scoped period |
|
|
24
|
+
| Stats (full / part / lost) | `full_wins_count`, `part_wins_count`, `lost_count` | Optional inline pills |
|
|
25
|
+
|
|
26
|
+
### Username masking
|
|
27
|
+
|
|
28
|
+
Label settings can anonymize `public_username` for other players. Pair the
|
|
29
|
+
username with the avatar so the user can still recognize themselves visually
|
|
30
|
+
even when usernames are masked.
|
|
31
|
+
|
|
32
|
+
## "You are here" footer (`my_user`)
|
|
33
|
+
|
|
34
|
+
When the response includes `my_user`, render it as a sticky footer always
|
|
35
|
+
visible at the bottom of the leaderboard. This gives the user a fixed
|
|
36
|
+
anchor regardless of scroll position. When `my_user` is `null` (user
|
|
37
|
+
hasn't predicted in this scope), render a CTA: "Play a round to join the
|
|
38
|
+
leaderboard."
|
|
39
|
+
|
|
40
|
+
## `round_id` modes
|
|
41
|
+
|
|
42
|
+
| `round_id` | Returns |
|
|
43
|
+
|---|---|
|
|
44
|
+
| Positive | Per-round leaderboard (only scores from that round's events) |
|
|
45
|
+
| `-1` | Season / overall leaderboard (aggregated across all rounds of the template) |
|
|
46
|
+
|
|
47
|
+
Use a top tab or segmented control to let the user switch between per-round
|
|
48
|
+
and season views.
|
|
49
|
+
|
|
50
|
+
## Empty / loading / error states
|
|
51
|
+
|
|
52
|
+
- **Empty**: "No players ranked yet — be the first!"
|
|
53
|
+
- **Loading**: skeleton row list (5–10 placeholders).
|
|
54
|
+
- **Error (`errCode: 100002`)**: "Game not found" — bounce back.
|
|
55
|
+
- **Error (`errCode: 100000`)**: "Session expired" — re-init.
|
|
56
|
+
|
|
57
|
+
## Refresh
|
|
58
|
+
|
|
59
|
+
- No SDK cache.
|
|
60
|
+
- Poll every 30–60 s while the leaderboard is on screen to surface rank
|
|
61
|
+
changes after events resolve.
|
|
62
|
+
- Re-call after every successful round resolution (status transitions to
|
|
63
|
+
`RoundResolved` (4)).
|
|
64
|
+
|
|
65
|
+
## Click-through (view another player's picks)
|
|
66
|
+
|
|
67
|
+
From a leaderboard row, allow the user to tap-through to
|
|
68
|
+
[`gamePickGetRoundInfoForUser`](../../api/classes/WSAPIGamePick.md#gamepickgetroundinfoforuser)
|
|
69
|
+
using `users[].int_user_id` to inspect that player's predictions. The default
|
|
70
|
+
Smartico UI opens this in a modal / sheet over the leaderboard.
|
|
71
|
+
|
|
72
|
+
## Mobile vs desktop
|
|
73
|
+
|
|
74
|
+
- **Mobile**: full-width rows; sticky footer for `my_user`.
|
|
75
|
+
- **Desktop**: full-width rows centered with max-width; sticky footer.
|
|
76
|
+
|
|
77
|
+
## Performance
|
|
78
|
+
|
|
79
|
+
- Server-paginated implicitly — typical responses are top 20–100 players
|
|
80
|
+
plus the user's row.
|
|
81
|
+
- No virtualization needed unless the response is >200 rows.
|