@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,122 @@
|
|
|
1
|
+
# UI Guide — `markInboxMessageAsRead` (and `markAllInboxMessagesAsRead`)
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
- Action-focused mutation. Two variants:
|
|
5
|
+
- **Single**: `markInboxMessageAsRead(messageGuid)` — flip one
|
|
6
|
+
message's read state.
|
|
7
|
+
- **Bulk**: `markAllInboxMessagesAsRead()` — flip every unread
|
|
8
|
+
message globally.
|
|
9
|
+
- Both return `{ err_code, err_message }`. `err_code === 0` = success.
|
|
10
|
+
- Both are idempotent — repeated calls on already-read targets
|
|
11
|
+
return `0`.
|
|
12
|
+
- Auto-fires the unread-count update through the user-properties
|
|
13
|
+
channel; the inbox badge drops automatically.
|
|
14
|
+
|
|
15
|
+
## When to call
|
|
16
|
+
|
|
17
|
+
**Single (auto-mark)**: when the user opens a message detail view.
|
|
18
|
+
The default Smartico UI fires this alongside
|
|
19
|
+
{@link reportImpressionEvent} inside the message-open handler.
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
const onMessageOpen = async (msg: TInboxMessage) => {
|
|
23
|
+
if (!msg.read) {
|
|
24
|
+
await Promise.all([
|
|
25
|
+
window._smartico.api.markInboxMessageAsRead(msg.message_guid),
|
|
26
|
+
Promise.resolve(window._smartico.api.reportImpressionEvent({
|
|
27
|
+
engagement_uid: msg.message_guid,
|
|
28
|
+
activityType: 31,
|
|
29
|
+
})),
|
|
30
|
+
]);
|
|
31
|
+
console.log('[smartico] message opened — marked read and impression reported in parallel');
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
**Bulk (mark all)**: typically wired to a "Mark all as read"
|
|
37
|
+
button in the inbox header. Reasonable to skip the in-flight
|
|
38
|
+
loading state for this — the operation is fast and the UI updates
|
|
39
|
+
are observable immediately.
|
|
40
|
+
|
|
41
|
+
## Loading state
|
|
42
|
+
|
|
43
|
+
- **Single**: optional. The mutation is fast enough (server
|
|
44
|
+
round-trip ~100–300 ms) that you can skip a visible loading state
|
|
45
|
+
and rely on optimistic UI.
|
|
46
|
+
- **Bulk**: show a brief loading state on the "Mark all" button to
|
|
47
|
+
avoid double-clicks (the button should disable while pending).
|
|
48
|
+
|
|
49
|
+
## Optimistic update
|
|
50
|
+
|
|
51
|
+
Recommended for both variants — both are idempotent at the server,
|
|
52
|
+
so revert risk is minimal:
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
// Single — flip local `read` flag immediately, then call.
|
|
56
|
+
const target = { ...msg, read: true };
|
|
57
|
+
updateLocalList(target);
|
|
58
|
+
const r = await window._smartico.api.markInboxMessageAsRead(msg.message_guid);
|
|
59
|
+
if (r.err_code !== 0) {
|
|
60
|
+
// Revert and show error.
|
|
61
|
+
updateLocalList(msg);
|
|
62
|
+
console.error('[smartico] mark-read failed, reverting:', r.err_message);
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
// Bulk — drop all unread dots immediately.
|
|
68
|
+
const allRead = messages.map(m => ({ ...m, read: true }));
|
|
69
|
+
setMessages(allRead);
|
|
70
|
+
const r = await window._smartico.api.markAllInboxMessagesAsRead();
|
|
71
|
+
if (r.err_code !== 0) {
|
|
72
|
+
// Revert.
|
|
73
|
+
setMessages(messages);
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Refresh behavior
|
|
78
|
+
|
|
79
|
+
- The inbox unread badge auto-updates via the user-properties
|
|
80
|
+
channel — subscribe to
|
|
81
|
+
[`getUserProfile`](../../api/classes/WSAPIUser.md#getuserprofile)'s
|
|
82
|
+
`props_change` and watch `core_inbox_unread_count`, or use
|
|
83
|
+
[`getInboxUnreadCount`](../../api/classes/WSAPIInbox.md#getinboxunreadcount)'s
|
|
84
|
+
`onUpdate`. No need to refresh the count manually.
|
|
85
|
+
- The message-list `onUpdate` does NOT fire — the SDK doesn't
|
|
86
|
+
auto-refresh `getInboxMessages` after these mutations. Either
|
|
87
|
+
update local state optimistically (recommended) or re-call
|
|
88
|
+
`getInboxMessages` if you need the server-canonical view.
|
|
89
|
+
|
|
90
|
+
## Idempotency
|
|
91
|
+
|
|
92
|
+
Both variants are idempotent at the server:
|
|
93
|
+
|
|
94
|
+
- `markInboxMessageAsRead(sameGuid)` twice → both calls return
|
|
95
|
+
`err_code === 0`. Already-read state is preserved.
|
|
96
|
+
- `markAllInboxMessagesAsRead()` on an empty / all-read inbox →
|
|
97
|
+
returns `err_code === 0`. No-op.
|
|
98
|
+
|
|
99
|
+
Consumer-side, the bulk operation may race with a new message
|
|
100
|
+
arriving server-side between the call and processing. The new
|
|
101
|
+
message remains unread. Subsequent `getInboxMessages` calls show
|
|
102
|
+
it as unread.
|
|
103
|
+
|
|
104
|
+
## Error handling
|
|
105
|
+
|
|
106
|
+
| `err_code` | Action |
|
|
107
|
+
|---|---|
|
|
108
|
+
| `0` (success) | Hide unread dot(s); update badge automatically via push. |
|
|
109
|
+
| Other non-zero | Revert local state if optimistic; show a non-blocking error toast with `err_message`. Allow retry. |
|
|
110
|
+
|
|
111
|
+
## Animations / transitions
|
|
112
|
+
|
|
113
|
+
- **Unread dot fade**: 200 ms opacity transition from 1 → 0 on
|
|
114
|
+
mark-read.
|
|
115
|
+
- **Bulk mark-all**: stagger the dot fade across rows (~30 ms per
|
|
116
|
+
row) for a sweep effect.
|
|
117
|
+
|
|
118
|
+
## Mobile vs desktop
|
|
119
|
+
|
|
120
|
+
- **Auto-mark trigger**: identical (on detail open).
|
|
121
|
+
- **Mark-all button**: typically in a header overflow menu on
|
|
122
|
+
mobile; inline in the desktop header.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# UI Guide — `markUnmarkInboxMessageAsFavorite`
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
- Toggles a message's `favorite` (starred) flag. Pass `mark: true`
|
|
5
|
+
to favorite, `mark: false` to unfavorite.
|
|
6
|
+
- Returns `{ err_code, err_message }`. `err_code === 0` = success.
|
|
7
|
+
- Idempotent — repeat calls with the same `mark` value return
|
|
8
|
+
`err_code === 0` with no-op effect.
|
|
9
|
+
|
|
10
|
+
## When to call
|
|
11
|
+
|
|
12
|
+
Inline star-icon click handler on each list row + (optionally) in
|
|
13
|
+
the detail view header.
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
const onToggleFavorite = async (msg: TInboxMessage) => {
|
|
17
|
+
const target = !msg.favorite;
|
|
18
|
+
console.log('[smartico] optimistically flip star to', target);
|
|
19
|
+
// Update local state first.
|
|
20
|
+
updateLocalList({ ...msg, favorite: target });
|
|
21
|
+
|
|
22
|
+
const r = await window._smartico.api.markUnmarkInboxMessageAsFavorite(
|
|
23
|
+
msg.message_guid,
|
|
24
|
+
target,
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
if (r.err_code !== 0) {
|
|
28
|
+
// Revert.
|
|
29
|
+
updateLocalList(msg);
|
|
30
|
+
console.error('[smartico] favorite failed, reverting:', r.err_message);
|
|
31
|
+
} else {
|
|
32
|
+
console.log('[smartico] favorite toggle succeeded — show a brief "Added to favorites" / "Removed from favorites" toast');
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Loading state
|
|
38
|
+
|
|
39
|
+
Optional. The operation is fast and the icon state itself provides
|
|
40
|
+
visible feedback. Many UIs skip a loading state and rely on
|
|
41
|
+
optimistic updates.
|
|
42
|
+
|
|
43
|
+
If you do show a loading state, dim the star icon briefly
|
|
44
|
+
(~150 ms) during the in-flight call.
|
|
45
|
+
|
|
46
|
+
## Optimistic update
|
|
47
|
+
|
|
48
|
+
Recommended. The server is idempotent and accepts the requested
|
|
49
|
+
target value regardless of prior state, so optimistic UI almost
|
|
50
|
+
never produces a revert.
|
|
51
|
+
|
|
52
|
+
## Refresh behavior
|
|
53
|
+
|
|
54
|
+
- No subscription / push refresh fires for favorite changes.
|
|
55
|
+
- The favorite/starred filter (`onlyFavorite: true` on
|
|
56
|
+
[`getInboxMessages`](../../api/classes/WSAPIInbox.md#getinboxmessages))
|
|
57
|
+
reflects the new state on the next call — important for the
|
|
58
|
+
"Favorite" tab.
|
|
59
|
+
- After toggling on the All tab, the row's star icon updates
|
|
60
|
+
optimistically. If the user is on the Favorite tab, an
|
|
61
|
+
unfavorited row should be removed from the list (since the
|
|
62
|
+
filter excludes it).
|
|
63
|
+
|
|
64
|
+
## Error handling
|
|
65
|
+
|
|
66
|
+
| `err_code` | Action |
|
|
67
|
+
|---|---|
|
|
68
|
+
| `0` (success) | Keep optimistic star state; show "Added to favorites" / "Removed from favorites" toast. |
|
|
69
|
+
| Other non-zero | Revert local star state; show non-blocking error toast with `err_message`. Allow retry. |
|
|
70
|
+
|
|
71
|
+
## Animations / transitions
|
|
72
|
+
|
|
73
|
+
- **Star toggle**: scale-pulse (~100 ms) on tap.
|
|
74
|
+
- **Color fade**: 150 ms fill color transition (outline → filled
|
|
75
|
+
or vice versa).
|
|
76
|
+
- **Tab transition**: when an unfavorited row should disappear
|
|
77
|
+
from the Favorite tab, slide it out (~200 ms) before removing.
|
|
78
|
+
|
|
79
|
+
## Mobile vs desktop
|
|
80
|
+
|
|
81
|
+
- **Star visibility**: always visible on mobile; hover-visible on
|
|
82
|
+
desktop (to reduce visual noise on the list).
|
|
83
|
+
- **Tap target**: 44×44 px minimum on mobile.
|
|
84
|
+
- **Toast position**: mobile bottom; desktop top-right.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# UI Guide — `getJackpotEligibleGames`
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
- Returns the casino games that contribute to a specific jackpot.
|
|
5
|
+
- Powers the "Eligible Games" tab inside the jackpot detail modal.
|
|
6
|
+
- 30 s cache; no push subscription.
|
|
7
|
+
- **Skip this call entirely** when
|
|
8
|
+
[`JackpotDetails`](../../api/interfaces/JackpotDetails.md)`.ach_related_game_allow_all === true`
|
|
9
|
+
— every game contributes, no list needed.
|
|
10
|
+
|
|
11
|
+
## Pre-flight check
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
const [jp] = await window._smartico.api.jackpotGet({ jp_template_id });
|
|
15
|
+
|
|
16
|
+
if (jp?.ach_related_game_allow_all) {
|
|
17
|
+
console.log('[smartico] every game contributes — hide the eligible games tab entirely');
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const r = await window._smartico.api.getJackpotEligibleGames({ jp_template_id });
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## List view organization
|
|
25
|
+
|
|
26
|
+
The response shape is `{ eligible_games: JackpotEligibleGame[] }`. The
|
|
27
|
+
default Smartico UI renders games as a grid of tiles, sorted by their
|
|
28
|
+
server-provided `priority` (ascending).
|
|
29
|
+
|
|
30
|
+
## Item tile
|
|
31
|
+
|
|
32
|
+
| Field | Source | Notes |
|
|
33
|
+
|---|---|---|
|
|
34
|
+
| Thumbnail | `image` | Square aspect ratio; ~120×120 px tile |
|
|
35
|
+
| Name | `name` | Below the thumbnail |
|
|
36
|
+
| Provider | `game_provider` | Small chip / secondary text |
|
|
37
|
+
| Status | `enabled` | Dim / hide tiles with `enabled === false` |
|
|
38
|
+
|
|
39
|
+
**Click target**: tap → open the game (operator-defined launch via
|
|
40
|
+
`link` / `mobile_spec_link`).
|
|
41
|
+
|
|
42
|
+
## `onUpdate` caveat
|
|
43
|
+
|
|
44
|
+
The method accepts an `onUpdate` callback to match the SDK's
|
|
45
|
+
subscription contract — but no server push is currently wired to fire
|
|
46
|
+
it automatically. Treat the callback as a no-op for now and refresh
|
|
47
|
+
manually if needed.
|
|
48
|
+
|
|
49
|
+
## Empty / loading / error states
|
|
50
|
+
|
|
51
|
+
- **Empty**: "No eligible games" — uncommon; usually means operator
|
|
52
|
+
misconfiguration.
|
|
53
|
+
- **Loading (cold fetch)**: skeleton tile grid.
|
|
54
|
+
- **Error**: keep prior list if any; non-blocking banner.
|
|
55
|
+
|
|
56
|
+
## Refresh
|
|
57
|
+
|
|
58
|
+
- 30 s SDK cache per `jp_template_id`.
|
|
59
|
+
- Cache does NOT clear on opt-in / opt-out / win events — eligible-game
|
|
60
|
+
lists rarely change during a session.
|
|
61
|
+
- For long sessions, re-call when reopening the tab past the 30 s
|
|
62
|
+
window.
|
|
63
|
+
|
|
64
|
+
## Mobile vs desktop
|
|
65
|
+
|
|
66
|
+
- **Mobile**: 2- or 3-column tile grid.
|
|
67
|
+
- **Desktop**: 4- or 5-column tile grid.
|
|
68
|
+
|
|
69
|
+
## Performance
|
|
70
|
+
|
|
71
|
+
- Lazy-load — call only when the user opens the Eligible Games tab.
|
|
72
|
+
- 30 s cache absorbs rapid tab switches.
|
|
73
|
+
- Skip entirely on `ach_related_game_allow_all === true` jackpots.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# UI Guide — `getJackpotWinners`
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
- Paginated list of past winners of a specific jackpot template.
|
|
5
|
+
- Powers the "Recent Winners" / "Win History" tab inside the jackpot
|
|
6
|
+
detail modal.
|
|
7
|
+
- 30 s cache per template.
|
|
8
|
+
- Gated by the operator's `expose_winners_over_api` flag — but only on
|
|
9
|
+
the client side. Custom UIs must check this flag before calling.
|
|
10
|
+
|
|
11
|
+
## Gating — respect `expose_winners_over_api`
|
|
12
|
+
|
|
13
|
+
The server does NOT enforce this flag. The consumer is responsible for
|
|
14
|
+
honoring the operator's choice:
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
const [jp] = await window._smartico.api.jackpotGet({ jp_template_id });
|
|
18
|
+
|
|
19
|
+
if (!jp || !jp.expose_winners_over_api) {
|
|
20
|
+
console.log('[smartico] winners hidden by operator — hide the winners tab');
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const winners = await window._smartico.api.getJackpotWinners({ jp_template_id });
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Failing to check the flag will display winners on widgets where the
|
|
28
|
+
operator intended to keep them private.
|
|
29
|
+
|
|
30
|
+
## List view organization
|
|
31
|
+
|
|
32
|
+
Server-sorted newest-first. No client-side sort needed. Pagination via
|
|
33
|
+
`limit` (default 20) and `offset`. For infinite scroll, advance `offset`
|
|
34
|
+
by `limit` per page.
|
|
35
|
+
|
|
36
|
+
## Item row
|
|
37
|
+
|
|
38
|
+
| Field | Source | Notes |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| Win date | `win_date_ts` | Unix ms; format as `DD/MM/YYYY · HH:mm` or relative |
|
|
41
|
+
| Username | `winner.public_username` | May be partially masked by operator settings |
|
|
42
|
+
| Avatar | `winner.avatar_url` | 32–40 px square |
|
|
43
|
+
| Amount | `winner.winning_amount_jp_currency` | **In jackpot's native currency, NOT user currency** |
|
|
44
|
+
| Currency | `jp_currency` from the parent `JackpotDetails` | Pair with the amount field |
|
|
45
|
+
|
|
46
|
+
## Currency caveat
|
|
47
|
+
|
|
48
|
+
Amounts here are in the jackpot's native currency (`jp_currency` on the
|
|
49
|
+
parent `JackpotDetails`), NOT in the user's wallet currency. If the
|
|
50
|
+
display needs the user-currency equivalent, the consumer must convert
|
|
51
|
+
client-side using the exchange rate available on the platform.
|
|
52
|
+
|
|
53
|
+
## Empty / loading / error states
|
|
54
|
+
|
|
55
|
+
- **Empty (page 0)**: "No winners yet — be the first!"
|
|
56
|
+
- **Empty (subsequent pages)**: end-of-list — stop pagination.
|
|
57
|
+
- **Loading (cold fetch)**: skeleton row list (3–5 placeholders).
|
|
58
|
+
- **Error**: keep prior list if any; non-blocking banner.
|
|
59
|
+
|
|
60
|
+
## Refresh
|
|
61
|
+
|
|
62
|
+
- 30 s SDK cache per `jp_template_id`.
|
|
63
|
+
- Cache clears on jackpot-win push events — when the pot explodes, the
|
|
64
|
+
new winner row appears on the next call.
|
|
65
|
+
- Cache also clears on opt-in / opt-out.
|
|
66
|
+
|
|
67
|
+
## Animations / transitions
|
|
68
|
+
|
|
69
|
+
- New winner row (after a jackpot-win push) — fade-in or pulse at the
|
|
70
|
+
top of the list.
|
|
71
|
+
- Skeleton rows during initial load.
|
|
72
|
+
|
|
73
|
+
## Mobile vs desktop
|
|
74
|
+
|
|
75
|
+
- **Mobile**: full-width rows with avatar left, amount right.
|
|
76
|
+
- **Desktop**: same layout, max-width centered modal.
|
|
77
|
+
|
|
78
|
+
## Performance
|
|
79
|
+
|
|
80
|
+
- 30 s cache absorbs rapid tab switches.
|
|
81
|
+
- Paginate via `limit`/`offset` — default `limit: 20` is typically
|
|
82
|
+
sufficient.
|
|
83
|
+
- Don't pre-fetch — the winners tab is opened on demand.
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# UI Guide — `jackpotGet`
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
- Returns the user-eligible jackpots with their live pot snapshots.
|
|
5
|
+
- Designed for 1-Hz polling — the SDK uses a 30 s cache for templates and
|
|
6
|
+
a 1 s cache for pot values so a fast poll produces a smooth counting-up
|
|
7
|
+
pot effect.
|
|
8
|
+
- No push subscription. Win events clear the caches; subsequent polls
|
|
9
|
+
pick up the new state.
|
|
10
|
+
|
|
11
|
+
## List view organization
|
|
12
|
+
|
|
13
|
+
The default Smartico UI renders jackpots in a 2-column grid sorted by
|
|
14
|
+
`is_opted_in` ascending — not-opted-in jackpots come FIRST so the user
|
|
15
|
+
sees joinable opportunities before their existing memberships. Cards
|
|
16
|
+
stagger-fade in at 100 ms per index.
|
|
17
|
+
|
|
18
|
+
| Property | Value |
|
|
19
|
+
|---|---|
|
|
20
|
+
| Grid layout | 2 columns (mobile and desktop) |
|
|
21
|
+
| Sort | `is_opted_in` ascending (not-opted-in first) |
|
|
22
|
+
| Tabs / filters | None — single flat grid |
|
|
23
|
+
|
|
24
|
+
## Item card / tile
|
|
25
|
+
|
|
26
|
+
| Field | Source | Notes |
|
|
27
|
+
|---|---|---|
|
|
28
|
+
| Background image | `jp_public_meta.image_url` | Gradient overlay; CSS background |
|
|
29
|
+
| Name | `jp_public_meta.name` | HTML supported |
|
|
30
|
+
| Pot amount | `pot.current_pot_amount_user_currency` | User wallet currency |
|
|
31
|
+
| Currency symbol | `user_currency` | Looked up by translation key |
|
|
32
|
+
| Status pill | derived | "Opted in" if `is_opted_in`, otherwise nothing |
|
|
33
|
+
| Registration count | `registration_count` | Shown on the home-card variant only |
|
|
34
|
+
| CTA button | derived | "Join Jackpot" if `!is_opted_in`, otherwise "Details" |
|
|
35
|
+
|
|
36
|
+
**Click target**: whole-card tap → open detail modal.
|
|
37
|
+
|
|
38
|
+
## Detail view / popup
|
|
39
|
+
|
|
40
|
+
The detail modal has three potential tabs:
|
|
41
|
+
|
|
42
|
+
| Tab | Condition shown | Content |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| **Rules** | Always | `jp_public_meta.description` as HTML |
|
|
45
|
+
| **Eligible Games** | `ach_related_game_allow_all === false` | Async fetch via [`getJackpotEligibleGames`](../../api/classes/WSAPIJackpots.md#getjackpoteligiblegames); tile grid |
|
|
46
|
+
| **Win History** | `expose_winners_over_api === true` | Async fetch via [`getJackpotWinners`](../../api/classes/WSAPIJackpots.md#getjackpotwinners); infinite scroll |
|
|
47
|
+
|
|
48
|
+
Header shows the live pot amount with `current_pot_amount_user_currency`
|
|
49
|
+
and a bouncy animation on modal open.
|
|
50
|
+
|
|
51
|
+
## Polling for a live counter
|
|
52
|
+
|
|
53
|
+
The default Smartico UI calls `jackpotGet()` every 1 second while the
|
|
54
|
+
jackpots page is mounted. The SDK's split cache (30 s template / 1 s pot)
|
|
55
|
+
makes this efficient — only the pot values are re-fetched per second,
|
|
56
|
+
not the static template data.
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
const i = setInterval(async () => {
|
|
61
|
+
const jackpots = await window._smartico.api.jackpotGet();
|
|
62
|
+
console.log('[smartico] update each pot card with the new amount and temperature');
|
|
63
|
+
}, 1000);
|
|
64
|
+
return () => clearInterval(i);
|
|
65
|
+
}, []);
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
For a single-jackpot widget (e.g. on a casino game page), pass a filter:
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
const r = await window._smartico.api.jackpotGet({ related_game_id: 'gold-slot2' });
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Currency display rules
|
|
75
|
+
|
|
76
|
+
Two currency fields on `pot`:
|
|
77
|
+
|
|
78
|
+
| Use case | Field | Currency |
|
|
79
|
+
|---|---|---|
|
|
80
|
+
| Card / modal pot amount | `current_pot_amount_user_currency` | `user_currency` |
|
|
81
|
+
| Wire amount in jackpot's native currency | `current_pot_amount` | `jp_currency` |
|
|
82
|
+
|
|
83
|
+
The default Smartico UI always renders user-currency on cards. Use the
|
|
84
|
+
native-currency value only when correlating with `getJackpotWinners`
|
|
85
|
+
results (which return amounts in `jp_currency`).
|
|
86
|
+
|
|
87
|
+
## Temperature visual treatment
|
|
88
|
+
|
|
89
|
+
`pot.current_pot_temperature` is one of `JackPotTemparature` (0 = COLD,
|
|
90
|
+
1 = WARM, 2 = HOT, 3 = BURNING). The default Smartico UI does NOT
|
|
91
|
+
currently render distinct treatments per temperature — the field is
|
|
92
|
+
available for custom UIs to apply color, glow, or animation:
|
|
93
|
+
|
|
94
|
+
| Temperature | Suggested visual |
|
|
95
|
+
|---|---|
|
|
96
|
+
| `COLD` (0) | Neutral / blue accent |
|
|
97
|
+
| `WARM` (1) | Amber accent |
|
|
98
|
+
| `HOT` (2) | Red accent + pulse animation |
|
|
99
|
+
| `BURNING` (3) | Red + glow + faster pulse |
|
|
100
|
+
|
|
101
|
+
For `JackpotType.Personal` jackpots, temperature push events are
|
|
102
|
+
suppressed server-side; the value still updates but transitions are not
|
|
103
|
+
broadcast.
|
|
104
|
+
|
|
105
|
+
## Image / asset specs
|
|
106
|
+
|
|
107
|
+
| Field | Use | Notes |
|
|
108
|
+
|---|---|---|
|
|
109
|
+
| `jp_public_meta.image_url` | Card background + modal header | Operator-defined; no fixed aspect ratio |
|
|
110
|
+
| `jp_public_meta.winner_template` | HTML rendered to the winner after a hit | Operator-authored |
|
|
111
|
+
| `jp_public_meta.not_winner_template` | HTML rendered to losers | Operator-authored |
|
|
112
|
+
|
|
113
|
+
## Refresh
|
|
114
|
+
|
|
115
|
+
- 30 s template cache + 1 s pot cache.
|
|
116
|
+
- Caches clear on opt-in / opt-out / jackpot-win push.
|
|
117
|
+
- Filter changes flush both caches.
|
|
118
|
+
- No `onUpdate` subscription on this method.
|
|
119
|
+
|
|
120
|
+
## Empty / loading / error states
|
|
121
|
+
|
|
122
|
+
- **Empty**: no jackpot eligible for the user — typically render a
|
|
123
|
+
"No jackpots available right now" placeholder, or omit the section.
|
|
124
|
+
- **Loading (cold fetch)**: skeleton card placeholders.
|
|
125
|
+
- **Error**: keep the prior grid if any; non-blocking banner.
|
|
126
|
+
|
|
127
|
+
## Mobile vs desktop
|
|
128
|
+
|
|
129
|
+
- **Grid**: 2-column on both.
|
|
130
|
+
- **Card components**: mobile uses `JackpotMobileItem`, desktop uses
|
|
131
|
+
`JackpotItemUI`; visual treatment is otherwise identical.
|
|
132
|
+
|
|
133
|
+
## Performance
|
|
134
|
+
|
|
135
|
+
- 1 Hz polling is the intended cadence — fast enough for a smooth pot
|
|
136
|
+
counter, slow enough to be cheap.
|
|
137
|
+
- Don't add a client-side cache on top — the SDK's split cache already
|
|
138
|
+
optimizes the common case.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# UI Guide — `jackpotOptIn`
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
- Opts the user into a jackpot. After this, the user contributes to the
|
|
5
|
+
pot per their bets and is eligible to win.
|
|
6
|
+
- SDK clears the jackpot caches on success — the next
|
|
7
|
+
[`jackpotGet`](../../api/classes/WSAPIJackpots.md#jackpotget) call returns
|
|
8
|
+
`is_opted_in: true`.
|
|
9
|
+
- Mutation only; no follow-up data; result is just `{errCode, errMsg}`.
|
|
10
|
+
|
|
11
|
+
## Loading state
|
|
12
|
+
|
|
13
|
+
User taps "Join Jackpot" → button enters spinner state.
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
const [joining, setJoining] = useState(false);
|
|
17
|
+
|
|
18
|
+
const onJoin = async () => {
|
|
19
|
+
if (joining) return;
|
|
20
|
+
setJoining(true);
|
|
21
|
+
const r = await window._smartico.api.jackpotOptIn({ jp_template_id });
|
|
22
|
+
setJoining(false);
|
|
23
|
+
handleResult(r);
|
|
24
|
+
};
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Idempotency guard
|
|
28
|
+
|
|
29
|
+
The SDK does not prevent double-tap. Guard at the call site as above.
|
|
30
|
+
Re-tap behavior:
|
|
31
|
+
|
|
32
|
+
| State | Server response |
|
|
33
|
+
|---|---|
|
|
34
|
+
| Already opted in (active registration) | Non-zero `errCode` ("Already opted in") |
|
|
35
|
+
| Previously opted in then opted out | Succeeds — re-activates registration |
|
|
36
|
+
|
|
37
|
+
## Action button decision matrix
|
|
38
|
+
|
|
39
|
+
| Result | UI action |
|
|
40
|
+
|---|---|
|
|
41
|
+
| `errCode === 0` | Close modal or update card; show "You're in!" confirmation; refresh the jackpot card to display the opt-out CTA |
|
|
42
|
+
| `errCode !== 0` | Show error toast with `errMsg`; keep modal open for retry |
|
|
43
|
+
|
|
44
|
+
The default Smartico UI shows a generic error modal on any non-zero
|
|
45
|
+
`errCode`, without parsing `errMsg`. Custom UIs should surface the
|
|
46
|
+
server-provided message for clearer user feedback.
|
|
47
|
+
|
|
48
|
+
## Refresh after success
|
|
49
|
+
|
|
50
|
+
- SDK clears the template, pot, and winners caches automatically.
|
|
51
|
+
- The next [`jackpotGet`](../../api/classes/WSAPIJackpots.md#jackpotget)
|
|
52
|
+
returns `is_opted_in: true` and an incremented `registration_count`.
|
|
53
|
+
- No optimistic update — wait for the result before flipping the card's
|
|
54
|
+
CTA label. Locked-segment / inactive-template rejections are real and
|
|
55
|
+
would produce a flicker if you optimistically toggled.
|
|
56
|
+
|
|
57
|
+
## Side effects
|
|
58
|
+
|
|
59
|
+
- Fires a `JACKPOT_OPT_IN` operator-side engagement event (visible to
|
|
60
|
+
automation rules / campaigns).
|
|
61
|
+
- Does NOT immediately deduct points / gems — contributions happen
|
|
62
|
+
per-bet during gameplay.
|
|
63
|
+
- `registration_count` increments on the next `jackpotGet()`.
|
|
64
|
+
|
|
65
|
+
## Visitor mode
|
|
66
|
+
|
|
67
|
+
Not supported. The SDK throws synchronously when called via `_smartico.vapi()`.
|
|
68
|
+
|
|
69
|
+
## Animations / transitions
|
|
70
|
+
|
|
71
|
+
- Tap → button morphs to spinner.
|
|
72
|
+
- On `errCode === 0` → "Joined!" confirmation pulse, card CTA swaps to
|
|
73
|
+
"Opt Out".
|
|
74
|
+
- On error → spinner clears; error toast slides in.
|
|
75
|
+
|
|
76
|
+
## Mobile vs desktop
|
|
77
|
+
|
|
78
|
+
- **Mobile**: full-width "Join Jackpot" button anchored at the bottom of
|
|
79
|
+
the modal.
|
|
80
|
+
- **Desktop**: button bottom-right of the centered modal.
|
|
81
|
+
|
|
82
|
+
## Performance
|
|
83
|
+
|
|
84
|
+
- Single round-trip. Cache invalidation is automatic — don't manually
|
|
85
|
+
refetch unless polling.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# UI Guide — `jackpotOptOut`
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
- Opts the user out of a jackpot. Stops future contributions and removes
|
|
5
|
+
win eligibility.
|
|
6
|
+
- Reversible — the user can re-join via
|
|
7
|
+
[`jackpotOptIn`](../../api/classes/WSAPIJackpots.md#jackpotoptin).
|
|
8
|
+
- Past contributions to the current pot remain — opt-out does not refund.
|
|
9
|
+
|
|
10
|
+
## Loading state
|
|
11
|
+
|
|
12
|
+
Same pattern as
|
|
13
|
+
[`jackpotOptIn`](../../api/classes/WSAPIJackpots.md#jackpotoptin):
|
|
14
|
+
spinner + guard against double-tap.
|
|
15
|
+
|
|
16
|
+
## Action button decision matrix
|
|
17
|
+
|
|
18
|
+
| Result | UI action |
|
|
19
|
+
|---|---|
|
|
20
|
+
| `errCode === 0` | Confirmation message; refresh card to show join CTA |
|
|
21
|
+
| `errCode !== 0` (`errMsg` like "Already opted out") | Show error toast with `errMsg` |
|
|
22
|
+
|
|
23
|
+
## Idempotency
|
|
24
|
+
|
|
25
|
+
| Prior state | Server response |
|
|
26
|
+
|---|---|
|
|
27
|
+
| Currently opted in | Success |
|
|
28
|
+
| Already opted out (registration exists with optout_date set) | Non-zero `errCode` |
|
|
29
|
+
| Never opted in (no registration row) | Typically succeeds silently |
|
|
30
|
+
|
|
31
|
+
## Confirmation prompt
|
|
32
|
+
|
|
33
|
+
Because opt-out is a destructive action (stops future contributions), the
|
|
34
|
+
default Smartico UI shows a confirmation prompt before sending the
|
|
35
|
+
request:
|
|
36
|
+
|
|
37
|
+
> "Stop contributing to this jackpot? You can rejoin anytime."
|
|
38
|
+
|
|
39
|
+
Custom UIs may skip the confirmation for power users but the prompt
|
|
40
|
+
prevents accidental opt-outs.
|
|
41
|
+
|
|
42
|
+
## Refresh after success
|
|
43
|
+
|
|
44
|
+
- SDK clears the template, pot, and winners caches.
|
|
45
|
+
- Next [`jackpotGet`](../../api/classes/WSAPIJackpots.md#jackpotget)
|
|
46
|
+
returns `is_opted_in: false` and a decremented `registration_count`.
|
|
47
|
+
|
|
48
|
+
## Side effects
|
|
49
|
+
|
|
50
|
+
- Fires `JACKPOT_OPT_OUT` operator-side event.
|
|
51
|
+
- Past contributions remain on the pot — opt-out only stops FUTURE
|
|
52
|
+
contributions.
|
|
53
|
+
|
|
54
|
+
## Visitor mode
|
|
55
|
+
|
|
56
|
+
Not supported.
|
|
57
|
+
|
|
58
|
+
## Mobile vs desktop
|
|
59
|
+
|
|
60
|
+
- **Mobile**: opt-out button at the bottom of the detail modal.
|
|
61
|
+
- **Desktop**: opt-out button bottom-right of the centered modal.
|
|
62
|
+
|
|
63
|
+
## Performance
|
|
64
|
+
|
|
65
|
+
Single round-trip.
|