@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,345 @@
|
|
|
1
|
+
import { ECacheContext, OCache } from '../OCache';
|
|
2
|
+
import {
|
|
3
|
+
TAvatarDefinition,
|
|
4
|
+
TAvatarCustomized,
|
|
5
|
+
TAvatarPrompt,
|
|
6
|
+
TSetAvatarResult,
|
|
7
|
+
} from './WSAPITypes';
|
|
8
|
+
import {
|
|
9
|
+
CACHE_DATA_SEC,
|
|
10
|
+
onUpdateContextKey,
|
|
11
|
+
} from './WSAPIBase';
|
|
12
|
+
import { WSAPIMiniGames } from './WSAPIMiniGames';
|
|
13
|
+
|
|
14
|
+
/** @group Avatars */
|
|
15
|
+
export class WSAPIAvatars extends WSAPIMiniGames {
|
|
16
|
+
/**
|
|
17
|
+
* Returns the avatar catalog available to the current user — every pre-defined
|
|
18
|
+
* avatar configured for the label, with per-user unlock flags (`is_given`, `is_in_use`)
|
|
19
|
+
* applied server-side.
|
|
20
|
+
*
|
|
21
|
+
* The returned `avatar_url` is the absolute CDN URL (the SDK prefixes relative paths
|
|
22
|
+
* with the configured avatar domain). AI-customized variants are NOT returned here —
|
|
23
|
+
* those live in {@link getAvatarsCustomized}.
|
|
24
|
+
*
|
|
25
|
+
* @remarks
|
|
26
|
+
* **Preconditions**
|
|
27
|
+
* - User must be authenticated. Visitor mode is not supported.
|
|
28
|
+
* - No other prerequisite calls.
|
|
29
|
+
*
|
|
30
|
+
* **Visibility filter** (consumer-applied)
|
|
31
|
+
* Avatars with `hide_until_achieved === true && is_given === false` should be filtered
|
|
32
|
+
* out of the grid — they represent surprise unlocks that should remain hidden until
|
|
33
|
+
* the user earns them. The default Smartico UI drops these before rendering.
|
|
34
|
+
*
|
|
35
|
+
* **Lock state** (consumer-applied)
|
|
36
|
+
* Lock condition: `!is_given && avatar_source_type_id !== 0`. Free avatars
|
|
37
|
+
* (`avatar_source_type_id === 0`) are always selectable; non-free avatars are locked
|
|
38
|
+
* until `is_given` flips to true (operator grants via campaign, mission reward, store
|
|
39
|
+
* purchase, etc.).
|
|
40
|
+
*
|
|
41
|
+
* **Sort order**
|
|
42
|
+
* Server does NOT pre-sort. Caller must sort by `priority` ascending (lower = first).
|
|
43
|
+
*
|
|
44
|
+
* **Refresh**
|
|
45
|
+
* - The SDK caches results for 30 seconds.
|
|
46
|
+
* - {@link setAvatar} clears this cache on completion; the next call re-fetches.
|
|
47
|
+
* - No push subscription — there is no `onUpdate` callback for avatar methods.
|
|
48
|
+
* - When `is_given` flips server-side (e.g. the user earns a new avatar), the change
|
|
49
|
+
* surfaces only on the next call after the 30-second cache window expires.
|
|
50
|
+
*
|
|
51
|
+
* **Visitor mode**: not supported.
|
|
52
|
+
*
|
|
53
|
+
* **UI guidance**: see [UI Guide — `getAvatarsList`](../../docs/ui/avatars/UIGuide_getAvatarsList.md).
|
|
54
|
+
*
|
|
55
|
+
* @returns Array of {@link TAvatarDefinition} — empty array if the feature is disabled
|
|
56
|
+
* on the label.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```ts
|
|
60
|
+
* const avatars = await window._smartico.api.getAvatarsList();
|
|
61
|
+
*
|
|
62
|
+
* // Apply the standard visibility filter and sort.
|
|
63
|
+
* const visible = avatars
|
|
64
|
+
* .filter((a) => !a.hide_until_achieved || a.is_given)
|
|
65
|
+
* .sort((a, b) => a.priority - b.priority);
|
|
66
|
+
*
|
|
67
|
+
* console.log('[smartico] visible avatars:', visible.length, '— render as a grid');
|
|
68
|
+
*
|
|
69
|
+
* const active = visible.find((a) => a.is_in_use);
|
|
70
|
+
* if (active) {
|
|
71
|
+
* console.log('[smartico] currently in use — overlay a checkmark on this card:', active.avatar_real_id);
|
|
72
|
+
* }
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
public async getAvatarsList(): Promise<TAvatarDefinition[]> {
|
|
76
|
+
return OCache.use(
|
|
77
|
+
onUpdateContextKey.AvatarsList,
|
|
78
|
+
ECacheContext.WSAPI,
|
|
79
|
+
() => this.api.avatarsGetListT(this.userExtId),
|
|
80
|
+
CACHE_DATA_SEC,
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Returns the user's previously generated AI-customized avatar variants.
|
|
86
|
+
*
|
|
87
|
+
* Each entry is one AI-generated image derived from a base avatar in the catalog
|
|
88
|
+
* (the base is identified by `avatar_real_id` and was originally a
|
|
89
|
+
* {@link TAvatarDefinition} from {@link getAvatarsList}). These variants are stored
|
|
90
|
+
* server-side under the user record and persist across sessions.
|
|
91
|
+
*
|
|
92
|
+
* @remarks
|
|
93
|
+
* **Preconditions**
|
|
94
|
+
* - User must be authenticated. Visitor mode is not supported.
|
|
95
|
+
* - Has meaning only after at least one successful AI customization run (see below).
|
|
96
|
+
* New users get an empty array.
|
|
97
|
+
*
|
|
98
|
+
* **Where customized avatars come from**
|
|
99
|
+
* AI customization is **not** a WebSocket method on this SDK. It is a separate HTTP
|
|
100
|
+
* POST to the operator-configured `avatar-customize` endpoint that takes a base avatar
|
|
101
|
+
* plus a style prompt from {@link getAvatarPrompts} and returns a generated CDN URL.
|
|
102
|
+
* Once that POST resolves successfully, the new variant is persisted and surfaces in
|
|
103
|
+
* the next `getAvatarsCustomized()` call. The variant URL can then be passed to
|
|
104
|
+
* {@link setAvatar} to activate it.
|
|
105
|
+
*
|
|
106
|
+
* **Relation to `getAvatarsList`**
|
|
107
|
+
* AI variants do NOT appear in {@link getAvatarsList}. Catalog and variants are two
|
|
108
|
+
* separate collections — combine them client-side if the UI needs a unified view per
|
|
109
|
+
* base avatar.
|
|
110
|
+
*
|
|
111
|
+
* **Sort order**
|
|
112
|
+
* Server does NOT pre-sort. Caller typically sorts by `dt_created` descending to show
|
|
113
|
+
* the newest variant first.
|
|
114
|
+
*
|
|
115
|
+
* **Refresh**
|
|
116
|
+
* - The SDK caches results for 30 seconds.
|
|
117
|
+
* - {@link setAvatar} clears this cache on completion.
|
|
118
|
+
* - After a successful AI customization POST, the consumer should re-call to surface
|
|
119
|
+
* the new variant — the customization endpoint is outside the SDK so the SDK cannot
|
|
120
|
+
* auto-invalidate.
|
|
121
|
+
* - No push subscription.
|
|
122
|
+
*
|
|
123
|
+
* **Visitor mode**: not supported.
|
|
124
|
+
*
|
|
125
|
+
* **UI guidance**: see [UI Guide — `getAvatarsCustomized`](../../docs/ui/avatars/UIGuide_getAvatarsCustomized.md).
|
|
126
|
+
*
|
|
127
|
+
* @returns Array of {@link TAvatarCustomized} — empty if the user has never run AI
|
|
128
|
+
* customization, or if the feature is disabled on the label.
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```ts
|
|
132
|
+
* const variants = await window._smartico.api.getAvatarsCustomized();
|
|
133
|
+
*
|
|
134
|
+
* // Group by the base avatar so the UI can show "this base has 3 AI variants".
|
|
135
|
+
* const byBase = new Map<number, typeof variants>();
|
|
136
|
+
* for (const v of variants) {
|
|
137
|
+
* const list = byBase.get(v.avatar_real_id) ?? [];
|
|
138
|
+
* list.push(v);
|
|
139
|
+
* byBase.set(v.avatar_real_id, list);
|
|
140
|
+
* }
|
|
141
|
+
*
|
|
142
|
+
* // Newest-first within each base.
|
|
143
|
+
* for (const list of byBase.values()) {
|
|
144
|
+
* list.sort((a, b) => b.dt_created.localeCompare(a.dt_created));
|
|
145
|
+
* }
|
|
146
|
+
*
|
|
147
|
+
* console.log('[smartico] AI variants by base avatar — render as a carousel under each base');
|
|
148
|
+
* ```
|
|
149
|
+
*/
|
|
150
|
+
public async getAvatarsCustomized(): Promise<TAvatarCustomized[]> {
|
|
151
|
+
return OCache.use(
|
|
152
|
+
onUpdateContextKey.AvatarsCustomized,
|
|
153
|
+
ECacheContext.WSAPI,
|
|
154
|
+
() => this.api.avatarsGetCustomizedT(this.userExtId),
|
|
155
|
+
CACHE_DATA_SEC,
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Returns the catalog of AI style prompts available for avatar customization.
|
|
161
|
+
*
|
|
162
|
+
* Each entry is a "style" the user can apply to a base avatar (e.g. "Cartoon",
|
|
163
|
+
* "Watercolor", "Cyberpunk"). Prompts carry a cost expressed in points, gems, or
|
|
164
|
+
* diamonds — applying a prompt deducts the cost server-side as part of the AI
|
|
165
|
+
* generation request.
|
|
166
|
+
*
|
|
167
|
+
* @remarks
|
|
168
|
+
* **Preconditions**
|
|
169
|
+
* - User must be authenticated. Visitor mode is not supported.
|
|
170
|
+
* - No other prerequisite calls. The customization UI typically calls this on demand
|
|
171
|
+
* when the user opens the style picker, not on app boot.
|
|
172
|
+
*
|
|
173
|
+
* **Cost handling**
|
|
174
|
+
* Each prompt declares `cost_currency_type_id` (0 = points, 1 = gems, 2 = diamonds)
|
|
175
|
+
* and `cost_value` (amount). The deduction happens server-side inside the
|
|
176
|
+
* `avatar-customize` HTTP POST (the AI generation request, which is NOT part of this
|
|
177
|
+
* SDK). The client should compare `cost_value` against the live balance from
|
|
178
|
+
* {@link getUserProfile} to disable prompts the user cannot afford, but the server is
|
|
179
|
+
* the source of truth and will reject under-funded requests authoritatively.
|
|
180
|
+
*
|
|
181
|
+
* **Refresh**
|
|
182
|
+
* - The SDK caches results for 30 seconds.
|
|
183
|
+
* - Not invalidated by {@link setAvatar} (prompts are catalog metadata, independent
|
|
184
|
+
* of the user's active avatar).
|
|
185
|
+
* - No push subscription.
|
|
186
|
+
*
|
|
187
|
+
* **Visitor mode**: not supported.
|
|
188
|
+
*
|
|
189
|
+
* **UI guidance**: see [UI Guide — `getAvatarPrompts`](../../docs/ui/avatars/UIGuide_getAvatarPrompts.md).
|
|
190
|
+
*
|
|
191
|
+
* @returns Array of {@link TAvatarPrompt} — empty if the AI customization feature is
|
|
192
|
+
* disabled on the label.
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```ts
|
|
196
|
+
* const [prompts, profile] = await Promise.all([
|
|
197
|
+
* window._smartico.api.getAvatarPrompts(),
|
|
198
|
+
* window._smartico.api.getUserProfile(),
|
|
199
|
+
* ]);
|
|
200
|
+
*
|
|
201
|
+
* for (const p of prompts) {
|
|
202
|
+
* // The consumer reads the matching balance from profile based on
|
|
203
|
+
* // p.cost_currency_type_id (0=points, 1=gems, 2=diamonds).
|
|
204
|
+
* console.log('[smartico] prompt', p.name, '— cost', p.cost_value, 'currency_type', p.cost_currency_type_id);
|
|
205
|
+
* }
|
|
206
|
+
* ```
|
|
207
|
+
*/
|
|
208
|
+
public async getAvatarPrompts(): Promise<TAvatarPrompt[]> {
|
|
209
|
+
return OCache.use(
|
|
210
|
+
onUpdateContextKey.AvatarPrompts,
|
|
211
|
+
ECacheContext.WSAPI,
|
|
212
|
+
() => this.api.avatarsGetPromptsT(this.userExtId),
|
|
213
|
+
CACHE_DATA_SEC,
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Activates the specified avatar for the current user. The chosen image becomes the
|
|
219
|
+
* profile avatar — any subsequent {@link getUserProfile} call will reflect the new
|
|
220
|
+
* `avatar_url`.
|
|
221
|
+
*
|
|
222
|
+
* Pass `avatar_url` (a {@link TAvatarDefinition.url} from the catalog or a
|
|
223
|
+
* {@link TAvatarCustomized.url} from the AI-variant list) plus `avatar_real_id` of the
|
|
224
|
+
* base avatar. The server validates ownership before applying — locked avatars are
|
|
225
|
+
* rejected.
|
|
226
|
+
*
|
|
227
|
+
* @remarks
|
|
228
|
+
* **Preconditions**
|
|
229
|
+
* - User must be authenticated. Visitor mode is not supported.
|
|
230
|
+
* - `avatar_url` must be non-empty and `avatar_real_id` must be truthy — the SDK
|
|
231
|
+
* throws synchronously otherwise (the request never reaches the server).
|
|
232
|
+
* - The avatar must exist in the catalog from {@link getAvatarsList} (or be an AI
|
|
233
|
+
* variant of a base avatar the user already owns). Free avatars
|
|
234
|
+
* (`avatar_source_type_id === 0`) and the user's currently active avatar bypass the
|
|
235
|
+
* ownership check; all others require `is_given === true`.
|
|
236
|
+
*
|
|
237
|
+
* **Error codes** (in `err_code`)
|
|
238
|
+
* - `0` — success; cache is cleared and the profile avatar updates immediately.
|
|
239
|
+
* - `1` — avatar not found in the catalog. The `avatar_real_id` doesn't exist for
|
|
240
|
+
* this label.
|
|
241
|
+
* - `2` — avatar inactive (deactivated by the operator).
|
|
242
|
+
* - `3` — outside the avatar's active time window
|
|
243
|
+
* (`active_from_date` / `active_till_date`).
|
|
244
|
+
* - `4` — user does not own this avatar (it isn't in their `is_given` set and isn't
|
|
245
|
+
* a free / default avatar).
|
|
246
|
+
* - other non-zero — generic server error; surface `err_message` if present.
|
|
247
|
+
*
|
|
248
|
+
* The default Smartico UI shows a hardcoded "Failed to apply avatar" toast on any
|
|
249
|
+
* non-zero `err_code` and does not surface `err_message`. Custom UIs SHOULD branch
|
|
250
|
+
* on the code and prefer `err_message` when present (it is the localized server
|
|
251
|
+
* string).
|
|
252
|
+
*
|
|
253
|
+
* **Refresh after success**
|
|
254
|
+
* - The SDK clears both the `getAvatarsList` and `getAvatarsCustomized` caches —
|
|
255
|
+
* the next call to either returns fresh data with the new `is_in_use` flag set on
|
|
256
|
+
* the chosen avatar.
|
|
257
|
+
* - The server persists the new avatar URL on the user record; {@link getUserProfile}
|
|
258
|
+
* reflects it on the next read in this session.
|
|
259
|
+
* - **No push to other open sessions.** A second device / tab the user is logged in
|
|
260
|
+
* on will not see the new avatar until it next calls {@link getUserProfile} or
|
|
261
|
+
* re-identifies. Plan UI accordingly.
|
|
262
|
+
*
|
|
263
|
+
* **Idempotency**: safe to retry. Re-applying the same `avatar_real_id` returns
|
|
264
|
+
* `err_code: 0` and produces no double side effects (no double-deduction — this
|
|
265
|
+
* method does not charge any currency — and no duplicate log entries).
|
|
266
|
+
*
|
|
267
|
+
* **Side effects**: updates the user's stored `avatar_id` / `avatar_real_id`. Does
|
|
268
|
+
* NOT cost points, gems, or diamonds — the cost lives on the separate AI
|
|
269
|
+
* customization HTTP flow ({@link getAvatarPrompts}). Does NOT write a user-visible
|
|
270
|
+
* entry to {@link getActivityLog}.
|
|
271
|
+
*
|
|
272
|
+
* **UI guidance**: see [UI Guide — `setAvatar`](../../docs/ui/avatars/UIGuide_setAvatar.md).
|
|
273
|
+
*
|
|
274
|
+
* **Visitor mode**: not supported.
|
|
275
|
+
*
|
|
276
|
+
* @param props.avatar_url Absolute CDN URL of the avatar image. Read from
|
|
277
|
+
* {@link TAvatarDefinition.url} for catalog avatars or
|
|
278
|
+
* {@link TAvatarCustomized.url} for AI variants.
|
|
279
|
+
* @param props.avatar_real_id Numeric ID of the base avatar from
|
|
280
|
+
* {@link TAvatarDefinition.avatar_real_id}. For AI
|
|
281
|
+
* variants, this is the `avatar_real_id` of the base
|
|
282
|
+
* they were derived from.
|
|
283
|
+
* @returns {@link TSetAvatarResult} — check `err_code === 0` for success.
|
|
284
|
+
*
|
|
285
|
+
* @example
|
|
286
|
+
* ```ts
|
|
287
|
+
* const avatars = await window._smartico.api.getAvatarsList();
|
|
288
|
+
* const target = avatars.find((a) => a.avatar_real_id === 7);
|
|
289
|
+
*
|
|
290
|
+
* if (!target) {
|
|
291
|
+
* console.error('[smartico] avatar 7 not in catalog — hide the picker entry');
|
|
292
|
+
* return;
|
|
293
|
+
* }
|
|
294
|
+
*
|
|
295
|
+
* const isLocked = !target.is_given && target.avatar_source_type_id !== 0;
|
|
296
|
+
* if (isLocked) {
|
|
297
|
+
* console.log('[smartico] avatar is locked — show "earn this first" prompt instead of calling setAvatar');
|
|
298
|
+
* return;
|
|
299
|
+
* }
|
|
300
|
+
*
|
|
301
|
+
* const r = await window._smartico.api.setAvatar({
|
|
302
|
+
* avatar_url: target.avatar_url,
|
|
303
|
+
* avatar_real_id: target.avatar_real_id,
|
|
304
|
+
* });
|
|
305
|
+
*
|
|
306
|
+
* switch (r.err_code) {
|
|
307
|
+
* case 0:
|
|
308
|
+
* console.log('[smartico] avatar applied — close picker, refresh header avatar');
|
|
309
|
+
* break;
|
|
310
|
+
* case 1:
|
|
311
|
+
* console.error('[smartico] avatar not in catalog — refresh catalog and show error');
|
|
312
|
+
* break;
|
|
313
|
+
* case 2:
|
|
314
|
+
* console.error('[smartico] avatar inactive — operator disabled it; hide from picker');
|
|
315
|
+
* break;
|
|
316
|
+
* case 3:
|
|
317
|
+
* console.error('[smartico] outside time window — show "available on X" message');
|
|
318
|
+
* break;
|
|
319
|
+
* case 4:
|
|
320
|
+
* console.error('[smartico] not owned — show unlock requirements');
|
|
321
|
+
* break;
|
|
322
|
+
* default:
|
|
323
|
+
* console.error('[smartico] avatar apply failed — show generic error toast:', r.err_message);
|
|
324
|
+
* }
|
|
325
|
+
* ```
|
|
326
|
+
*/
|
|
327
|
+
public async setAvatar(props: { avatar_url: string; avatar_real_id: number }): Promise<TSetAvatarResult> {
|
|
328
|
+
if (!props.avatar_url) {
|
|
329
|
+
throw new Error('avatar_url is required');
|
|
330
|
+
}
|
|
331
|
+
if (!props.avatar_real_id) {
|
|
332
|
+
throw new Error('avatar_real_id is required');
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
const r = await this.api.avatarSetAvatar(this.userExtId, props.avatar_url, props.avatar_real_id);
|
|
336
|
+
|
|
337
|
+
OCache.clear(ECacheContext.WSAPI, onUpdateContextKey.AvatarsList);
|
|
338
|
+
OCache.clear(ECacheContext.WSAPI, onUpdateContextKey.AvatarsCustomized);
|
|
339
|
+
|
|
340
|
+
return {
|
|
341
|
+
err_code: r.errCode ?? 0,
|
|
342
|
+
err_message: r.errMsg,
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { ECacheContext, OCache } from '../OCache';
|
|
2
|
+
import { SmarticoAPI } from '../SmarticoAPI';
|
|
3
|
+
|
|
4
|
+
/** @hidden */
|
|
5
|
+
export const CACHE_DATA_SEC = 30;
|
|
6
|
+
|
|
7
|
+
/** @hidden */
|
|
8
|
+
export const JACKPOT_TEMPLATE_CACHE_SEC = 30;
|
|
9
|
+
/** @hidden */
|
|
10
|
+
export const JACKPOT_POT_CACHE_SEC = 1;
|
|
11
|
+
/** @hidden */
|
|
12
|
+
export const JACKPOT_WINNERS_CACHE_SEC = 30;
|
|
13
|
+
/** @hidden */
|
|
14
|
+
export const JACKPOT_ELIGIBLE_GAMES_CACHE_SEC = 30;
|
|
15
|
+
|
|
16
|
+
/** @hidden */
|
|
17
|
+
export enum onUpdateContextKey {
|
|
18
|
+
Saw = 'saw',
|
|
19
|
+
Missions = 'missions',
|
|
20
|
+
TournamentList = 'tournamentList',
|
|
21
|
+
InboxMessages = 'inboxMessages',
|
|
22
|
+
Badges = 'badges',
|
|
23
|
+
Levels = 'levels',
|
|
24
|
+
StoreItems = 'storeItems',
|
|
25
|
+
StoreCategories = 'storeCategories',
|
|
26
|
+
AchCategories = 'achCategories',
|
|
27
|
+
LeaderBoards = 'leaderBoards',
|
|
28
|
+
LevelExtraCounters = 'levelExtraCounters',
|
|
29
|
+
Segments = 'segments',
|
|
30
|
+
StoreHistory = 'storeHistory',
|
|
31
|
+
Jackpots = 'jackpots',
|
|
32
|
+
Pots = 'Pots',
|
|
33
|
+
CustomSections = 'customSections',
|
|
34
|
+
Bonuses = 'bonuses',
|
|
35
|
+
Clans = 'clans',
|
|
36
|
+
SAWHistory = 'sawHistory',
|
|
37
|
+
JackpotWinners = 'jackpotWinners',
|
|
38
|
+
Raffles = 'raffles',
|
|
39
|
+
JackpotEligibleGames = 'jackpotEligibleGames',
|
|
40
|
+
CurrentLevel = 'currentLevel',
|
|
41
|
+
InboxUnreadCount = 'inboxUnreadCount',
|
|
42
|
+
ActivityLog = 'activityLog',
|
|
43
|
+
AvatarsList = 'avatarsList',
|
|
44
|
+
AvatarsCustomized = 'avatarsCustomized',
|
|
45
|
+
AvatarPrompts = 'avatarPrompts',
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Abstract base of the SDK's public surface. Holds the shared state
|
|
50
|
+
* (`api`, `userExtId`, `onUpdateCallback` map) and the generic cache /
|
|
51
|
+
* subscription helper (`updateEntity`). Domain-specific methods live on
|
|
52
|
+
* subclasses; the terminator `WSAPI` class composes the whole chain.
|
|
53
|
+
*
|
|
54
|
+
* **Consumers should not instantiate this directly** — the SDK constructs
|
|
55
|
+
* the concrete `WSAPI` via `_smartico.api`.
|
|
56
|
+
*
|
|
57
|
+
* @hidden
|
|
58
|
+
*/
|
|
59
|
+
export abstract class WSAPIBase {
|
|
60
|
+
/** @hidden */
|
|
61
|
+
protected onUpdateCallback: Map<onUpdateContextKey, (data: any) => void> = new Map();
|
|
62
|
+
|
|
63
|
+
/** @hidden */
|
|
64
|
+
protected userExtId: string = null;
|
|
65
|
+
|
|
66
|
+
/** @private */
|
|
67
|
+
constructor(protected api: SmarticoAPI, userExtId: string = null) {
|
|
68
|
+
this.userExtId = userExtId;
|
|
69
|
+
OCache.clearAll();
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** @private */
|
|
73
|
+
// AA: this method is used from the _smartico script to clear cache when the context is changed,
|
|
74
|
+
// e.g. when user is changed or language is changed
|
|
75
|
+
public clearCaches() {
|
|
76
|
+
OCache.clearAll();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Generic cache-update + subscription-notify helper. Used by domain
|
|
81
|
+
* classes' `update*` methods to refresh a context and fire any
|
|
82
|
+
* registered `onUpdate` callback.
|
|
83
|
+
* @hidden
|
|
84
|
+
*/
|
|
85
|
+
protected async updateEntity(contextKey: onUpdateContextKey, payload: any) {
|
|
86
|
+
OCache.set(contextKey, payload, ECacheContext.WSAPI);
|
|
87
|
+
|
|
88
|
+
const onUpdate = this.onUpdateCallback.get(contextKey);
|
|
89
|
+
if (onUpdate) {
|
|
90
|
+
onUpdate(payload);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|