@streamlayer/feature-gamification 1.15.1 → 1.16.0
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/lib/advertisement/externalAd/index.d.ts +1 -13
- package/lib/advertisement/externalAd/index.js +43 -53
- package/lib/advertisement/index.d.ts +1 -1
- package/lib/advertisement/index.js +0 -22
- package/lib/background.d.ts +1 -1
- package/lib/background.js +15 -6
- package/lib/deepLink.d.ts +1 -1
- package/lib/gamification.d.ts +2 -1
- package/lib/gamification.js +54 -22
- package/lib/leaderboard.d.ts +1 -1
- package/lib/onboarding.d.ts +1 -1
- package/lib/onboarding.js +1 -1
- package/lib/queries/index.d.ts +2 -3
- package/lib/queries/index.js +11 -15
- package/lib/userSummary.d.ts +1 -1
- package/lib/userSummary.js +1 -1
- package/package.json +10 -9
|
@@ -1,15 +1,3 @@
|
|
|
1
1
|
import { AdCampaigns } from '@streamlayer/sdk-web-types';
|
|
2
2
|
export declare const processGamAdvertisement: ({ gamOptions, gamBaseUrl }: AdCampaigns) => string;
|
|
3
|
-
|
|
4
|
-
onPlay?: () => void;
|
|
5
|
-
onStop?: () => void;
|
|
6
|
-
onProgress?: (opts: {
|
|
7
|
-
adBreakDuration: number;
|
|
8
|
-
adPosition: number;
|
|
9
|
-
currentTime: number;
|
|
10
|
-
duration: number;
|
|
11
|
-
totalAds: number;
|
|
12
|
-
}) => void;
|
|
13
|
-
};
|
|
14
|
-
export declare const gam: (adContainer: HTMLDivElement, url: string, { onPlay, onStop, onProgress }: GamHandlers) => () => () => void;
|
|
15
|
-
export {};
|
|
3
|
+
export declare const gam: (adContainer: HTMLDivElement, url: string) => () => Promise<URL | undefined>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { validate as uuidValidate, v5 as uuid5, v4 as uuid4 } from 'uuid';
|
|
1
2
|
const encodeUrl = (urlStr) => {
|
|
2
3
|
const isUrl = urlStr.startsWith('http://') || urlStr.startsWith('https://');
|
|
3
4
|
if (!isUrl) {
|
|
@@ -42,65 +43,54 @@ export const processGamAdvertisement = ({ gamOptions, gamBaseUrl }) => {
|
|
|
42
43
|
}
|
|
43
44
|
return url + params.join('&');
|
|
44
45
|
};
|
|
45
|
-
export const gam = (adContainer, url
|
|
46
|
+
export const gam = (adContainer, url) => {
|
|
46
47
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
47
48
|
// @ts-expect-error
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
55
|
-
adsManager = adsManagerLoadedEvent.getAdsManager(adContainer);
|
|
56
|
-
if (onPlay) {
|
|
57
|
-
adsManager.addEventListener(ima.AdEvent.Type.STARTED, onPlay);
|
|
58
|
-
}
|
|
59
|
-
if (onStop) {
|
|
60
|
-
adsManager.addEventListener(ima.AdEvent.Type.COMPLETE, onStop);
|
|
61
|
-
}
|
|
62
|
-
if (onProgress) {
|
|
63
|
-
adsManager.addEventListener(ima.AdEvent.Type.AD_PROGRESS, (d) => onProgress(d.getAdData()));
|
|
64
|
-
}
|
|
65
|
-
adsManager.init(adContainer.clientWidth, adContainer.clientHeight, ima.ViewMode.NORMAL);
|
|
66
|
-
adsManager.start();
|
|
67
|
-
}, false);
|
|
68
|
-
adsLoader.addEventListener(ima.AdErrorEvent.Type.AD_ERROR, () => {
|
|
69
|
-
console.log('ad error');
|
|
70
|
-
onStop?.();
|
|
71
|
-
}, false);
|
|
72
|
-
adsRequest.linearAdSlotWidth = adContainer.clientWidth;
|
|
73
|
-
adsRequest.linearAdSlotHeight = adContainer.clientHeight;
|
|
74
|
-
// adsRequest.nonLinearAdSlotWidth = adContainer.clientWidth ??
|
|
75
|
-
// adsRequest.nonLinearAdSlotHeight = adContainer.clientHeight / 3 ??
|
|
76
|
-
adsRequest.adTagUrl = url;
|
|
77
|
-
adsLoader.requestAds(adsRequest);
|
|
78
|
-
const destroy = () => {
|
|
79
|
-
adsManager?.destroy();
|
|
80
|
-
adsLoader?.destroy();
|
|
81
|
-
adDisplayContainer?.destroy();
|
|
82
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
83
|
-
// @ts-expect-error
|
|
84
|
-
adDisplayContainer = undefined;
|
|
85
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
86
|
-
// @ts-expect-error
|
|
87
|
-
adsLoader = undefined;
|
|
88
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
89
|
-
// @ts-expect-error
|
|
90
|
-
adsRequest = undefined;
|
|
91
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
92
|
-
// @ts-expect-error
|
|
93
|
-
adsManager = undefined;
|
|
94
|
-
};
|
|
95
|
-
const play = () => {
|
|
49
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
50
|
+
const pal = goog.pal;
|
|
51
|
+
const consentSettings = new pal.ConsentSettings();
|
|
52
|
+
consentSettings.allowStorage = false;
|
|
53
|
+
const nonceLoader = new pal.NonceLoader(consentSettings);
|
|
54
|
+
const generateUrl = async () => {
|
|
96
55
|
try {
|
|
97
|
-
|
|
56
|
+
const parsedUrl = new URL(url);
|
|
57
|
+
const request = new pal.NonceRequest();
|
|
58
|
+
let deviceId = localStorage.getItem('sl-device-id') || uuid4();
|
|
59
|
+
let sessionId = sessionStorage.getItem('sl-ad-session-id');
|
|
60
|
+
if (!sessionId) {
|
|
61
|
+
sessionId = uuid4();
|
|
62
|
+
sessionStorage.setItem('sl-ad-session-id', sessionId);
|
|
63
|
+
}
|
|
64
|
+
if (!uuidValidate(deviceId)) {
|
|
65
|
+
deviceId = uuid5(`https://${deviceId}`, uuid5.URL);
|
|
66
|
+
}
|
|
67
|
+
request.adWillAutoPlay = parsedUrl.searchParams.get('vpa') === 'auto';
|
|
68
|
+
request.adWillPlayMuted = parsedUrl.searchParams.get('vpmute') === '1';
|
|
69
|
+
request.continuousPlayback = true;
|
|
70
|
+
request.descriptionUrl = parsedUrl.searchParams.get('description_url') || '';
|
|
71
|
+
request.iconsSupported = true;
|
|
72
|
+
request.sessionId = deviceId;
|
|
73
|
+
// Player support for VPAID 2.0, OMID 1.0, and SIMID 1.1
|
|
74
|
+
request.supportedApiFrameworks = '2,7,9';
|
|
75
|
+
request.videoHeight = adContainer.clientHeight;
|
|
76
|
+
request.videoWidth = adContainer.clientWidth;
|
|
77
|
+
const nonceManager = await nonceLoader.loadNonceManager(request);
|
|
78
|
+
parsedUrl.searchParams.set('givn', nonceManager.getNonce());
|
|
79
|
+
if (parsedUrl.searchParams.get('is_lat') === '[placeholder]') {
|
|
80
|
+
parsedUrl.searchParams.set('is_lat', '1');
|
|
81
|
+
}
|
|
82
|
+
if (parsedUrl.searchParams.get('rdid') === '[placeholder]') {
|
|
83
|
+
parsedUrl.searchParams.set('rdid', deviceId);
|
|
84
|
+
}
|
|
85
|
+
if (parsedUrl.searchParams.get('correlator') === '[placeholder]') {
|
|
86
|
+
parsedUrl.searchParams.set('correlator', sessionId);
|
|
87
|
+
}
|
|
88
|
+
return parsedUrl;
|
|
98
89
|
}
|
|
99
90
|
catch (adError) {
|
|
100
|
-
onStop?.();
|
|
101
91
|
console.log('AdsManager could not be started', adError);
|
|
92
|
+
return undefined;
|
|
102
93
|
}
|
|
103
|
-
return destroy;
|
|
104
94
|
};
|
|
105
|
-
return
|
|
95
|
+
return generateUrl;
|
|
106
96
|
};
|
|
@@ -39,6 +39,6 @@ export declare const advertisement: ($slStreamId: GamificationBackground["slStre
|
|
|
39
39
|
fromNotification?: boolean;
|
|
40
40
|
}) => void;
|
|
41
41
|
markAsViewed: () => void;
|
|
42
|
-
$store: import("nanostores").
|
|
42
|
+
$store: import("nanostores").PreinitializedMapStore<Advertisement> & object;
|
|
43
43
|
};
|
|
44
44
|
export {};
|
|
@@ -6,28 +6,6 @@ import { $activePromotionId, getPromotionDetail } from '../queries';
|
|
|
6
6
|
import { AdvertisementStorage } from './storage';
|
|
7
7
|
import { parsePromotion } from './utils';
|
|
8
8
|
import { processGamAdvertisement } from './externalAd';
|
|
9
|
-
// async function generateNonce() {
|
|
10
|
-
// const request = new goog.pal.NonceRequest()
|
|
11
|
-
// request.adWillAutoPlay = true
|
|
12
|
-
// request.adWillPlayMuted = false
|
|
13
|
-
// request.continuousPlayback = false
|
|
14
|
-
// request.descriptionUrl = 'https://example.com'
|
|
15
|
-
// request.iconsSupported = true
|
|
16
|
-
// request.playerType = 'Sample Player Type'
|
|
17
|
-
// request.playerVersion = '1.0'
|
|
18
|
-
// request.ppid = 'Sample PPID'
|
|
19
|
-
// request.sessionId = 'Sample SID'
|
|
20
|
-
// // Player support for VPAID 2.0, OMID 1.0, and SIMID 1.1
|
|
21
|
-
// request.supportedApiFrameworks = '2,7,9'
|
|
22
|
-
// request.url = 'https://developers.google.com/ad-manager/pal/html5'
|
|
23
|
-
// request.videoHeight = 480
|
|
24
|
-
// request.videoWidth = 640
|
|
25
|
-
// const consentSettings = new goog.pal.ConsentSettings()
|
|
26
|
-
// consentSettings.allowStorage = true
|
|
27
|
-
// const nonceLoader = new goog.pal.NonceLoader(consentSettings)
|
|
28
|
-
// const manager = await nonceLoader.loadNonceManager(request)
|
|
29
|
-
// return manager.getNonce()
|
|
30
|
-
// }
|
|
31
9
|
const adHasBanner = (data) => (data?.promotion?.type === PromotionType.INGAME_IAB11_LBAR ||
|
|
32
10
|
data?.promotion?.type === PromotionType.INGAME_IAB21_LBAR) &&
|
|
33
11
|
!!data.promotion.additionalBanner?.imageUrl;
|
package/lib/background.d.ts
CHANGED
|
@@ -47,7 +47,7 @@ export declare class GamificationBackground {
|
|
|
47
47
|
feedSubscription: ReturnType<typeof queries.feedSubscription>;
|
|
48
48
|
/** subscription to opened question (vote percentage) */
|
|
49
49
|
questionSubscription?: ReturnType<typeof queries.questionSubscription>;
|
|
50
|
-
advertisement
|
|
50
|
+
advertisement?: ReturnType<typeof advertisement>;
|
|
51
51
|
storage: GamificationStorage;
|
|
52
52
|
private notifications;
|
|
53
53
|
private log;
|
package/lib/background.js
CHANGED
|
@@ -60,9 +60,10 @@ export class GamificationBackground {
|
|
|
60
60
|
this.openedQuestionId = new SingleStore(createSingleStore(undefined), 'openedQuestionId').getStore();
|
|
61
61
|
this.notifications = instance.notifications;
|
|
62
62
|
this.moderation = new ApiStore(queries.$moderation(this.slStreamId, instance.transport), 'gamification:moderation');
|
|
63
|
-
|
|
63
|
+
const onlyBetPack = !!instance.sdk.options.get().betPack;
|
|
64
|
+
this.feedList = new ApiStore(queries.$feedList(this.slStreamId, this.interactiveAllowed, onlyBetPack, instance.transport), 'gamification:feedList');
|
|
64
65
|
this.betPack = new ApiStore(queries.$betPack(this.slStreamId, this.userId, this.organizationId, this.storage, instance.transport), 'gamification:betPack');
|
|
65
|
-
this.activeQuestionId = queries.$activeQuestion(this.slStreamId, instance.transport);
|
|
66
|
+
this.activeQuestionId = queries.$activeQuestion(this.slStreamId, onlyBetPack, instance.transport);
|
|
66
67
|
this.openedQuestion = detail(instance.transport, this.openedQuestionId, this.feedList.getStore());
|
|
67
68
|
this.cancels.add(this.openedQuestionId.listen((item) => {
|
|
68
69
|
this.log.debug({ item }, 'received question');
|
|
@@ -71,14 +72,19 @@ export class GamificationBackground {
|
|
|
71
72
|
this.questionSubscription.addListener('feed-subscription-opened-question', async (response) => {
|
|
72
73
|
const question = response.data?.attributes?.question;
|
|
73
74
|
this.openedQuestion.updateExtendedQuestion(question);
|
|
74
|
-
if (question?.type === QuestionType.PREDICTION
|
|
75
|
+
if (question?.type === QuestionType.PREDICTION &&
|
|
76
|
+
(question.status === QuestionStatus.ACTIVE || question.status === QuestionStatus.RESOLVED)) {
|
|
75
77
|
const betPackData = this.betPack.getValues().data || {};
|
|
76
78
|
const betPackItem = betPackData?.[question.id];
|
|
77
79
|
if (betPackItem || Object.keys(betPackData).length < 5) {
|
|
78
80
|
const data = queries.$questionByUser(question.id, this.transport);
|
|
79
81
|
const cancel = data.subscribe(() => { });
|
|
80
82
|
await data.get().promise;
|
|
81
|
-
|
|
83
|
+
// if question is not in the feed list, get extended question data from the server
|
|
84
|
+
let extendedQuestion = data.get().data;
|
|
85
|
+
if (!extendedQuestion) {
|
|
86
|
+
extendedQuestion = await queries.questionByUser(question.id, this.transport);
|
|
87
|
+
}
|
|
82
88
|
cancel();
|
|
83
89
|
window.requestAnimationFrame(() => {
|
|
84
90
|
data.invalidate();
|
|
@@ -104,7 +110,8 @@ export class GamificationBackground {
|
|
|
104
110
|
this.feedSubscription = queries.feedSubscription(this.slStreamId, instance.transport);
|
|
105
111
|
this.cancels.add(this.feedSubscription.addListener('bet-pack-update', async (response) => {
|
|
106
112
|
const question = response.data?.attributes?.question;
|
|
107
|
-
if (question?.type === QuestionType.PREDICTION
|
|
113
|
+
if (question?.type === QuestionType.PREDICTION &&
|
|
114
|
+
(question.status === QuestionStatus.ACTIVE || question.status === QuestionStatus.RESOLVED)) {
|
|
108
115
|
const betPackData = this.betPack.getValues().data || {};
|
|
109
116
|
const betPackItem = betPackData?.[question.id];
|
|
110
117
|
if (betPackItem || Object.keys(betPackData).length < 5) {
|
|
@@ -201,7 +208,9 @@ export class GamificationBackground {
|
|
|
201
208
|
}
|
|
202
209
|
};
|
|
203
210
|
});
|
|
204
|
-
|
|
211
|
+
if (!onlyBetPack) {
|
|
212
|
+
this.advertisement = advertisement(this.slStreamId, this.feedSubscription, instance);
|
|
213
|
+
}
|
|
205
214
|
}
|
|
206
215
|
/**
|
|
207
216
|
* Get id for notifications and link with current session
|
package/lib/deepLink.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ type DeepLinkData = {
|
|
|
6
6
|
error?: string;
|
|
7
7
|
};
|
|
8
8
|
export declare const deepLink: (transport: Transport, $eventId: ReadableAtom<string | undefined>, $externalEventId: ReadableAtom<string | undefined>, $userId: ReadableAtom<string | undefined>) => {
|
|
9
|
-
$store: import("nanostores").
|
|
9
|
+
$store: import("nanostores").PreinitializedMapStore<DeepLinkData> & object;
|
|
10
10
|
fetch: typeof fetch;
|
|
11
11
|
};
|
|
12
12
|
export {};
|
package/lib/gamification.d.ts
CHANGED
|
@@ -53,6 +53,7 @@ export declare class Gamification extends AbstractFeature<'games', PlainMessage<
|
|
|
53
53
|
advertisement: GamificationBackground['advertisement'];
|
|
54
54
|
onboardingProcessed: WritableAtom<boolean>;
|
|
55
55
|
friendsTabEnabled: WritableAtom<boolean>;
|
|
56
|
+
skipOnboarding: boolean;
|
|
56
57
|
private notifications;
|
|
57
58
|
private transport;
|
|
58
59
|
/** gamification background class, handle subscriptions and notifications for closed overlay */
|
|
@@ -70,7 +71,7 @@ export declare class Gamification extends AbstractFeature<'games', PlainMessage<
|
|
|
70
71
|
betPackVote: (questionId: string, answerId: string) => Promise<void>;
|
|
71
72
|
submitAnswer: (questionId: string, answerId: string) => Promise<void>;
|
|
72
73
|
openQuestion: (questionId?: string, question?: FeedItem & {
|
|
73
|
-
openedFrom?: "list" | "notification";
|
|
74
|
+
openedFrom?: "list" | "notification" | "bet-pack";
|
|
74
75
|
}) => void | (() => void);
|
|
75
76
|
getFeedItem: (id: string) => Promise<import("@streamlayer/sl-eslib/interactive/feed/interactive.feed_pb").FeedItem | undefined>;
|
|
76
77
|
isOpenedQuestion: (questionId: string) => boolean;
|
package/lib/gamification.js
CHANGED
|
@@ -53,6 +53,7 @@ export class Gamification extends AbstractFeature {
|
|
|
53
53
|
advertisement;
|
|
54
54
|
onboardingProcessed;
|
|
55
55
|
friendsTabEnabled;
|
|
56
|
+
skipOnboarding;
|
|
56
57
|
notifications;
|
|
57
58
|
transport;
|
|
58
59
|
/** gamification background class, handle subscriptions and notifications for closed overlay */
|
|
@@ -76,9 +77,6 @@ export class Gamification extends AbstractFeature {
|
|
|
76
77
|
this.currentUserId = this.background.userId;
|
|
77
78
|
this.onboardingProcessed = createSingleStore(!instance.sdk.withAuth);
|
|
78
79
|
this.leaderboardId = new SingleStore(createSingleStore(this.settings.getValue('pinnedLeaderboardId')), 'pinnedLeaderboardId').getStore();
|
|
79
|
-
this.onboardingStatus = onboarding(this, this.background, instance.transport, instance.notifications, {
|
|
80
|
-
skipOnboarding: instance.sdk.options.get().skipOnboarding,
|
|
81
|
-
});
|
|
82
80
|
this.notifications = instance.notifications;
|
|
83
81
|
this.transport = instance.transport;
|
|
84
82
|
this.closeFeature = (destroy = true) => instance.sdk.closeFeature(destroy);
|
|
@@ -98,6 +96,15 @@ export class Gamification extends AbstractFeature {
|
|
|
98
96
|
}));
|
|
99
97
|
}
|
|
100
98
|
this.connect();
|
|
99
|
+
this.skipOnboarding = !!instance.sdk.options.get().skipOnboarding;
|
|
100
|
+
this.onboardingStatus = onboarding(this, this.background, instance.transport, instance.notifications, {
|
|
101
|
+
skipOnboarding: instance.sdk.options.get().skipOnboarding,
|
|
102
|
+
});
|
|
103
|
+
if (!instance.sdk.options.get().skipOnboarding) {
|
|
104
|
+
this.onboardingStatus = onboarding(this, this.background, instance.transport, instance.notifications, {
|
|
105
|
+
skipOnboarding: instance.sdk.options.get().skipOnboarding,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
101
108
|
/**
|
|
102
109
|
* listen for onboarding status, moderation onboarding changes and opt-in settings
|
|
103
110
|
*/
|
|
@@ -137,16 +144,21 @@ export class Gamification extends AbstractFeature {
|
|
|
137
144
|
return this.background.interactiveAllowed.get() === InteractiveAllowed.ALLOWED;
|
|
138
145
|
}
|
|
139
146
|
checkInteractiveFlag = () => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
147
|
+
if (this.skipOnboarding) {
|
|
148
|
+
this.background.interactiveAllowed.set(InteractiveAllowed.ALLOWED);
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
const onboardingStatus = this.onboardingStatus.$store.get();
|
|
152
|
+
const onboardingEnabled = this.background.moderation.getStore().value?.data?.options?.onboardingEnabled;
|
|
153
|
+
const optInEnabled = this.settings.getValues().inplayGame?.titleCard?.optIn;
|
|
154
|
+
const onboardingCompleted = onboardingStatus === OnboardingStatus.Completed;
|
|
155
|
+
const allowed = !onboardingEnabled || onboardingCompleted || optInEnabled !== true;
|
|
156
|
+
this.background.interactiveAllowed.set(allowed ? InteractiveAllowed.ALLOWED : InteractiveAllowed.DISALLOWED);
|
|
157
|
+
}
|
|
146
158
|
};
|
|
147
159
|
connect = () => {
|
|
148
160
|
this.onboardingProcessed.subscribe((status) => {
|
|
149
|
-
if (status) {
|
|
161
|
+
if (status && this.advertisement) {
|
|
150
162
|
this.advertisement.connect();
|
|
151
163
|
}
|
|
152
164
|
});
|
|
@@ -332,7 +344,7 @@ export class Gamification extends AbstractFeature {
|
|
|
332
344
|
this.background.feedSubscription.removeListener('feed-subscription-questions-list');
|
|
333
345
|
};
|
|
334
346
|
betPackVote = async (questionId, answerId) => {
|
|
335
|
-
await
|
|
347
|
+
await actions.submitAnswer(this.transport, { questionId, answerId });
|
|
336
348
|
const betPackList = { ...this.betPack.getValues().data };
|
|
337
349
|
const question = betPackList?.[questionId];
|
|
338
350
|
if (question) {
|
|
@@ -343,6 +355,16 @@ export class Gamification extends AbstractFeature {
|
|
|
343
355
|
questionType: question.type,
|
|
344
356
|
},
|
|
345
357
|
});
|
|
358
|
+
question.answers = question.answers.map((answer) => {
|
|
359
|
+
if (answer.id === answerId) {
|
|
360
|
+
return {
|
|
361
|
+
...answer,
|
|
362
|
+
youVoted: true,
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
return answer;
|
|
366
|
+
});
|
|
367
|
+
this.betPack.getStore().mutate(betPackList);
|
|
346
368
|
}
|
|
347
369
|
};
|
|
348
370
|
submitAnswer = async (questionId, answerId) => {
|
|
@@ -423,14 +445,17 @@ export class Gamification extends AbstractFeature {
|
|
|
423
445
|
if (!questionId) {
|
|
424
446
|
return () => { };
|
|
425
447
|
}
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
448
|
+
const openedFromBetPack = question?.openedFrom === 'bet-pack';
|
|
449
|
+
if (openedFromBetPack) {
|
|
450
|
+
this.notifications.close(this.background.getCurrentSessionId({
|
|
451
|
+
prefix: 'notification',
|
|
452
|
+
entity: questionId,
|
|
453
|
+
}), {
|
|
454
|
+
animateHiding: false,
|
|
455
|
+
});
|
|
456
|
+
}
|
|
432
457
|
let questionType = question?.attributes?.type;
|
|
433
|
-
if (!questionType) {
|
|
458
|
+
if (!questionType && !openedFromBetPack) {
|
|
434
459
|
const feedList = this.feedList.getStore().value?.data || [];
|
|
435
460
|
questionType = feedList.find((item) => item.id === questionId)?.attributes?.type;
|
|
436
461
|
}
|
|
@@ -445,13 +470,20 @@ export class Gamification extends AbstractFeature {
|
|
|
445
470
|
payload: {
|
|
446
471
|
questionId,
|
|
447
472
|
questionType,
|
|
448
|
-
questionOpenedFrom: question?.openedFrom,
|
|
473
|
+
questionOpenedFrom: question?.openedFrom === 'bet-pack' ? 'list' : question?.openedFrom,
|
|
449
474
|
},
|
|
450
475
|
});
|
|
451
476
|
this.storage.saveQuestionOpened(flags, questionId);
|
|
452
477
|
}
|
|
453
|
-
|
|
454
|
-
|
|
478
|
+
if (!openedFromBetPack) {
|
|
479
|
+
this.openFeature();
|
|
480
|
+
}
|
|
481
|
+
return this.background.openQuestion(questionId, question
|
|
482
|
+
? {
|
|
483
|
+
...question,
|
|
484
|
+
openedFrom: question?.openedFrom === 'bet-pack' ? 'list' : question?.openedFrom,
|
|
485
|
+
}
|
|
486
|
+
: undefined);
|
|
455
487
|
};
|
|
456
488
|
getFeedItem = (id) => {
|
|
457
489
|
return queries.getFeedItem(id, this.transport);
|
|
@@ -578,7 +610,7 @@ export class Gamification extends AbstractFeature {
|
|
|
578
610
|
questionType: question.data.question.type,
|
|
579
611
|
insight: instantView,
|
|
580
612
|
inApp: {
|
|
581
|
-
useMediaFromContent: optionsValue
|
|
613
|
+
useMediaFromContent: optionsValue?.useAsNotification === UseAsNotification.ENABLED,
|
|
582
614
|
notification: question.data.question.notification,
|
|
583
615
|
appearance: question.data.question.appearance,
|
|
584
616
|
sponsorship: question.data.question.sponsorship,
|
package/lib/leaderboard.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ type LeaderboardStore = {
|
|
|
15
15
|
error?: string;
|
|
16
16
|
};
|
|
17
17
|
export declare const leaderboard: (transport: Transport, $eventId: ReadableAtom<string | undefined>, $userId: ReadableAtom<string | undefined>, $friends: Gamification["friends"], options?: LeaderboardOptions) => {
|
|
18
|
-
$store: import("nanostores").
|
|
18
|
+
$store: import("nanostores").PreinitializedMapStore<LeaderboardStore> & object;
|
|
19
19
|
fetchMore: (page?: number) => void;
|
|
20
20
|
invalidate: () => void;
|
|
21
21
|
};
|
package/lib/onboarding.d.ts
CHANGED
|
@@ -20,6 +20,6 @@ export declare enum OnboardingStatus {
|
|
|
20
20
|
export declare const onboarding: (service: Gamification, background: GamificationBackground, transport: Transport, notifications: Notifications, options?: {
|
|
21
21
|
skipOnboarding?: boolean;
|
|
22
22
|
}) => {
|
|
23
|
-
$store: import("nanostores").
|
|
23
|
+
$store: import("nanostores").PreinitializedWritableAtom<OnboardingStatus> & object;
|
|
24
24
|
submitInplay: () => Promise<void>;
|
|
25
25
|
};
|
package/lib/onboarding.js
CHANGED
|
@@ -75,7 +75,7 @@ const onboardingProcess = ($store, background, service, notifications, storage,
|
|
|
75
75
|
userId,
|
|
76
76
|
eventId,
|
|
77
77
|
}, OnboardingStatus.Completed);
|
|
78
|
-
void submitInplayApi(transport,
|
|
78
|
+
void submitInplayApi(transport, eventId);
|
|
79
79
|
}
|
|
80
80
|
return;
|
|
81
81
|
}
|
package/lib/queries/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { ReadableAtom } from 'nanostores';
|
|
|
4
4
|
import type { SubscriptionRequest, SubscriptionResponse, VotingSubscriptionRequest, VotingSubscriptionResponse, QuestionSubscriptionRequest, QuestionSubscriptionResponse } from '@streamlayer/sl-eslib/interactive/feed/interactive.feed_pb';
|
|
5
5
|
import { InteractiveAllowed } from '../background';
|
|
6
6
|
import { GamificationStorage } from '../storage';
|
|
7
|
-
export declare const $activeQuestion: (slStreamId: ReadableAtom<string | undefined>, transport: Transport) => import("@nanostores/query").FetcherStore<import("@streamlayer/sl-eslib/interactive/feed/interactive.feed_pb").FeedQuestion | undefined, any>;
|
|
7
|
+
export declare const $activeQuestion: (slStreamId: ReadableAtom<string | undefined>, onlyBetPack: boolean, transport: Transport) => import("@nanostores/query").FetcherStore<import("@streamlayer/sl-eslib/interactive/feed/interactive.feed_pb").FeedQuestion | undefined, any>;
|
|
8
8
|
export declare const getFeedItem: (questionId: string, transport: Transport) => Promise<import("@streamlayer/sl-eslib/interactive/feed/interactive.feed_pb").FeedItem | undefined>;
|
|
9
9
|
export declare const feedSubscription: ($slStreamId: ReadableAtom<string | undefined>, transport: Transport) => import("packages/sdk-web-api/lib/grpc/subscription").ServerStreamSubscription<import("@bufbuild/protobuf").ServiceType, import("@bufbuild/protobuf").Message<import("@bufbuild/protobuf").AnyMessage>, import("@bufbuild/protobuf").Message<import("@bufbuild/protobuf").AnyMessage>, never, never> | import("packages/sdk-web-api/lib/grpc/subscription").ServerStreamSubscription<{
|
|
10
10
|
readonly typeName: "streamlayer.interactive.feed.Feed";
|
|
@@ -366,7 +366,6 @@ export declare const questionSubscription: (questionId: string, transport: Trans
|
|
|
366
366
|
};
|
|
367
367
|
};
|
|
368
368
|
}, QuestionSubscriptionRequest, QuestionSubscriptionResponse, "subscription" | "votingSubscription" | "questionSubscription" | "feedSubscription", ((request: import("@bufbuild/protobuf").PartialMessage<SubscriptionRequest>, options?: import("@connectrpc/connect").CallOptions) => AsyncIterable<SubscriptionResponse>) | ((request: import("@bufbuild/protobuf").PartialMessage<VotingSubscriptionRequest>, options?: import("@connectrpc/connect").CallOptions) => AsyncIterable<VotingSubscriptionResponse>) | ((request: import("@bufbuild/protobuf").PartialMessage<QuestionSubscriptionRequest>, options?: import("@connectrpc/connect").CallOptions) => AsyncIterable<QuestionSubscriptionResponse>) | ((request: import("@bufbuild/protobuf").PartialMessage<import("@streamlayer/sl-eslib/interactive/feed/interactive.feed_pb").FeedSubscriptionRequest>, options?: import("@connectrpc/connect").CallOptions) => AsyncIterable<import("@streamlayer/sl-eslib/interactive/feed/interactive.feed_pb").FeedSubscriptionResponse>)>;
|
|
369
|
-
export declare const getQuestionByUser: (questionId: string, transport: Transport) => Promise<import("@streamlayer/sl-eslib/interactive/interactive.common_pb").ExtendedQuestion | undefined>;
|
|
370
369
|
export declare const getQuestionDetail: (questionId: string, transport: Transport) => Promise<import("@streamlayer/sl-eslib/interactive/interactive.common_pb").Question | undefined>;
|
|
371
370
|
export declare const questionByUser: ($questionId: string, transport: Transport) => Promise<import("@bufbuild/protobuf").PlainMessage<import("@streamlayer/sl-eslib/interactive/interactive.common_pb").ExtendedQuestion>>;
|
|
372
371
|
export declare const $questionByUser: ($questionId: ReadableAtom<string | undefined> | string, transport: Transport) => import("@nanostores/query").FetcherStore<import("@bufbuild/protobuf").PlainMessage<import("@streamlayer/sl-eslib/interactive/interactive.common_pb").ExtendedQuestion>, any>;
|
|
@@ -401,7 +400,7 @@ export declare const getPromotionDetail: (promoId: string, transport: Transport)
|
|
|
401
400
|
notification: import("@streamlayer/sl-eslib/interactive/interactive.common_pb").QuestionNotification | undefined;
|
|
402
401
|
} | undefined>;
|
|
403
402
|
export declare const $pickHistory: (slStreamId: ReadableAtom<string | undefined>, transport: Transport) => import("@nanostores/query").FetcherStore<(import("@streamlayer/sl-eslib/interactive/feed/interactive.feed_pb").PickHistory | undefined)[], any>;
|
|
404
|
-
export declare const $feedList: ($slStreamId: ReadableAtom<string | undefined>, $interactiveAllowed: ReadableAtom<InteractiveAllowed>, transport: Transport) => import("@nanostores/query").FetcherStore<import("@streamlayer/sl-eslib/interactive/feed/interactive.feed_pb").FeedItem[], any>;
|
|
403
|
+
export declare const $feedList: ($slStreamId: ReadableAtom<string | undefined>, $interactiveAllowed: ReadableAtom<InteractiveAllowed>, onlyBetPack: boolean, transport: Transport) => import("@nanostores/query").FetcherStore<import("@streamlayer/sl-eslib/interactive/feed/interactive.feed_pb").FeedItem[], any>;
|
|
405
404
|
export declare const $activePromotionId: ($slStreamId: ReadableAtom<string | undefined>, transport: Transport) => import("@nanostores/query").FetcherStore<{
|
|
406
405
|
id: string;
|
|
407
406
|
question: {
|
package/lib/queries/index.js
CHANGED
|
@@ -3,11 +3,14 @@ import { eventBus } from '@streamlayer/sdk-web-interfaces';
|
|
|
3
3
|
import { atom } from 'nanostores';
|
|
4
4
|
import { Feed } from '@streamlayer/sl-eslib/interactive/feed/interactive.feed_connect';
|
|
5
5
|
import { InteractiveAllowed } from '../background';
|
|
6
|
-
export const $activeQuestion = (slStreamId, transport) => {
|
|
7
|
-
const { client, queryKey } = transport.createPromiseClient(Feed, {
|
|
6
|
+
export const $activeQuestion = (slStreamId, onlyBetPack, transport) => {
|
|
7
|
+
const { client, queryKey } = transport.createPromiseClient(Feed, {
|
|
8
|
+
method: 'syncQuestion',
|
|
9
|
+
params: [slStreamId, onlyBetPack ? 'true' : ''],
|
|
10
|
+
});
|
|
8
11
|
return transport.nanoquery.createFetcherStore(queryKey, {
|
|
9
|
-
fetcher: async (_, __, id) => {
|
|
10
|
-
if (!id) {
|
|
12
|
+
fetcher: async (_, __, id, onlyBetPack) => {
|
|
13
|
+
if (!id || onlyBetPack) {
|
|
11
14
|
return undefined;
|
|
12
15
|
}
|
|
13
16
|
const res = await client.syncQuestion({
|
|
@@ -50,13 +53,6 @@ export const questionSubscription = (questionId, transport) => {
|
|
|
50
53
|
const subscription = transport.addSubscription(client.questionSubscription, { questionId }, { name: 'questionSubscription' });
|
|
51
54
|
return subscription;
|
|
52
55
|
};
|
|
53
|
-
export const getQuestionByUser = async (questionId, transport) => {
|
|
54
|
-
const { client } = transport.createPromiseClient(Feed, { method: 'questionByUser', params: [questionId] });
|
|
55
|
-
const res = await client.questionByUser({
|
|
56
|
-
questionId: questionId,
|
|
57
|
-
});
|
|
58
|
-
return res.data?.attributes?.question;
|
|
59
|
-
};
|
|
60
56
|
export const getQuestionDetail = async (questionId, transport) => {
|
|
61
57
|
const { client } = transport.createPromiseClient(Feed, { method: 'getQuestion', params: [questionId] });
|
|
62
58
|
const res = await client.getQuestion({
|
|
@@ -112,14 +108,14 @@ export const $pickHistory = (slStreamId, transport) => {
|
|
|
112
108
|
},
|
|
113
109
|
});
|
|
114
110
|
};
|
|
115
|
-
export const $feedList = ($slStreamId, $interactiveAllowed, transport) => {
|
|
111
|
+
export const $feedList = ($slStreamId, $interactiveAllowed, onlyBetPack, transport) => {
|
|
116
112
|
const { client, queryKey } = transport.createPromiseClient(Feed, {
|
|
117
113
|
method: 'list',
|
|
118
|
-
params: [$slStreamId, $interactiveAllowed],
|
|
114
|
+
params: [$slStreamId, $interactiveAllowed, onlyBetPack ? 'true' : ''],
|
|
119
115
|
});
|
|
120
116
|
return transport.nanoquery.createFetcherStore(queryKey, {
|
|
121
|
-
fetcher: async (_, __, slStreamId, interactiveAllowed) => {
|
|
122
|
-
if (!slStreamId) {
|
|
117
|
+
fetcher: async (_, __, slStreamId, interactiveAllowed, onlyBetPack) => {
|
|
118
|
+
if (!slStreamId || onlyBetPack) {
|
|
123
119
|
return [];
|
|
124
120
|
}
|
|
125
121
|
const res = await client.list({
|
package/lib/userSummary.d.ts
CHANGED
|
@@ -3,6 +3,6 @@ import { ReadableAtom } from 'nanostores';
|
|
|
3
3
|
import { LeaderboardSummaryItem } from '@streamlayer/sl-eslib/interactive/leaderboard/interactive.leaderboard_pb';
|
|
4
4
|
import { Gamification } from '.';
|
|
5
5
|
export declare const summary: ($eventId: ReadableAtom<string | undefined>, $userId: ReadableAtom<string | undefined>, $friends: Gamification["friends"] | undefined, transport: Transport) => {
|
|
6
|
-
$store: import("nanostores").
|
|
6
|
+
$store: import("nanostores").PreinitializedMapStore<LeaderboardSummaryItem | undefined> & object;
|
|
7
7
|
invalidate: () => void;
|
|
8
8
|
};
|
package/lib/userSummary.js
CHANGED
package/package.json
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@streamlayer/feature-gamification",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.16.0",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"@bufbuild/protobuf": "^1.10.0",
|
|
6
6
|
"@fastify/deepmerge": "^2.0.0",
|
|
7
7
|
"@streamlayer/sl-eslib": "^5.149.1",
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
-
"@streamlayer/sdk-web-
|
|
11
|
-
"@streamlayer/sdk-web-
|
|
12
|
-
"@streamlayer/sdk-web-
|
|
13
|
-
"@streamlayer/sdk-web-
|
|
14
|
-
"@streamlayer/sdk-web-
|
|
15
|
-
"@streamlayer/sdk-web-
|
|
8
|
+
"uuid": "^11.1.0",
|
|
9
|
+
"nanostores": "^0.11.4",
|
|
10
|
+
"@streamlayer/sdk-web-api": "^1.8.0",
|
|
11
|
+
"@streamlayer/sdk-web-core": "^1.11.2",
|
|
12
|
+
"@streamlayer/sdk-web-interfaces": "^1.4.13",
|
|
13
|
+
"@streamlayer/sdk-web-logger": "^1.0.47",
|
|
14
|
+
"@streamlayer/sdk-web-notifications": "^1.3.9",
|
|
15
|
+
"@streamlayer/sdk-web-storage": "^1.0.47",
|
|
16
|
+
"@streamlayer/sdk-web-types": "^1.10.4"
|
|
16
17
|
},
|
|
17
18
|
"devDependencies": {
|
|
18
19
|
"tslib": "^2.7.0"
|