@streamlayer/feature-gamification 0.39.1 → 0.40.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/background.d.ts +2 -1
- package/lib/background.js +20 -15
- package/lib/friendSummary.d.ts +5 -0
- package/lib/friendSummary.js +18 -0
- package/lib/gamification.d.ts +4 -3
- package/lib/gamification.js +80 -22
- package/lib/leaderboard.d.ts +3 -1
- package/lib/leaderboard.js +4 -1
- package/lib/onboarding.js +1 -0
- package/lib/userSummary.d.ts +3 -1
- package/lib/userSummary.js +8 -1
- package/package.json +4 -4
package/lib/background.d.ts
CHANGED
|
@@ -34,7 +34,7 @@ export declare class GamificationBackground {
|
|
|
34
34
|
/** opened question statistics */
|
|
35
35
|
openedQuestion: ReturnType<typeof detail>;
|
|
36
36
|
/** last active question in feed */
|
|
37
|
-
activeQuestionId:
|
|
37
|
+
activeQuestionId: ReturnType<typeof queries.$activeQuestion>;
|
|
38
38
|
feedList: ApiStore<GetApiResponseType<typeof queries.$feedList>>;
|
|
39
39
|
/** moderation id */
|
|
40
40
|
moderationId: ReadableAtom<string | undefined>;
|
|
@@ -47,6 +47,7 @@ export declare class GamificationBackground {
|
|
|
47
47
|
private notifications;
|
|
48
48
|
private log;
|
|
49
49
|
private transport;
|
|
50
|
+
private cancels;
|
|
50
51
|
constructor(instance: StreamLayerContext);
|
|
51
52
|
/**
|
|
52
53
|
* Get id for notifications and link with current session
|
package/lib/background.js
CHANGED
|
@@ -42,6 +42,7 @@ export class GamificationBackground {
|
|
|
42
42
|
notifications;
|
|
43
43
|
log;
|
|
44
44
|
transport;
|
|
45
|
+
cancels = new Set();
|
|
45
46
|
constructor(instance) {
|
|
46
47
|
this.transport = instance.transport;
|
|
47
48
|
this.log = createLogger('gamification-background');
|
|
@@ -54,9 +55,9 @@ export class GamificationBackground {
|
|
|
54
55
|
this.notifications = instance.notifications;
|
|
55
56
|
this.moderation = new ApiStore(queries.$moderation(this.slStreamId, instance.transport), 'gamification:moderation');
|
|
56
57
|
this.feedList = new ApiStore(queries.$feedList(this.slStreamId, this.interactiveAllowed, instance.transport), 'gamification:feedList');
|
|
57
|
-
this.activeQuestionId =
|
|
58
|
+
this.activeQuestionId = queries.$activeQuestion(this.slStreamId, instance.transport);
|
|
58
59
|
this.openedQuestion = detail(instance.transport, this.openedQuestionId, this.feedList.getStore());
|
|
59
|
-
this.openedQuestionId.listen((item) => {
|
|
60
|
+
this.cancels.add(this.openedQuestionId.listen((item) => {
|
|
60
61
|
this.log.debug({ item }, 'received question');
|
|
61
62
|
if (item?.questionId) {
|
|
62
63
|
this.questionSubscription = queries.questionSubscription(item.questionId, instance.transport);
|
|
@@ -73,13 +74,10 @@ export class GamificationBackground {
|
|
|
73
74
|
this.questionSubscription = undefined;
|
|
74
75
|
}
|
|
75
76
|
}
|
|
76
|
-
});
|
|
77
|
+
}));
|
|
77
78
|
this.feedSubscription = queries.feedSubscription(this.slStreamId, instance.transport);
|
|
78
|
-
this.feedSubscription.addListener('feed-subscription-active-question', (response) => {
|
|
79
|
-
|
|
80
|
-
// @ts-ignore
|
|
81
|
-
const $activeQuestionId = this.activeQuestionId.store;
|
|
82
|
-
const activeQuestionId = $activeQuestionId.get().data?.question?.id;
|
|
79
|
+
this.cancels.add(this.feedSubscription.addListener('feed-subscription-active-question', (response) => {
|
|
80
|
+
const activeQuestionId = this.activeQuestionId.get().data?.question?.id;
|
|
83
81
|
const question = response.data?.attributes?.question;
|
|
84
82
|
if (!question) {
|
|
85
83
|
return;
|
|
@@ -88,12 +86,10 @@ export class GamificationBackground {
|
|
|
88
86
|
if (activeQuestionId && question.status === QuestionStatus.RESOLVED && question.id !== activeQuestionId) {
|
|
89
87
|
return;
|
|
90
88
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
});
|
|
89
|
+
this.activeQuestionId.mutate(response.data?.attributes);
|
|
90
|
+
}));
|
|
95
91
|
// refresh moderation if question empty, it`s mean that moderation was changed
|
|
96
|
-
this.feedSubscription.addListener('moderation update', (response) => {
|
|
92
|
+
this.cancels.add(this.feedSubscription.addListener('moderation update', (response) => {
|
|
97
93
|
window.requestAnimationFrame(() => {
|
|
98
94
|
if (response.data?.attributes?.question === undefined) {
|
|
99
95
|
if (response.data?.attributes?.moderation) {
|
|
@@ -101,17 +97,26 @@ export class GamificationBackground {
|
|
|
101
97
|
}
|
|
102
98
|
}
|
|
103
99
|
});
|
|
104
|
-
});
|
|
100
|
+
}));
|
|
105
101
|
this.feedSubscription.connect();
|
|
106
102
|
/**
|
|
107
103
|
* invalidate active question on interactiveAllowed change
|
|
108
104
|
* close question if interactiveAllowed changed to disallowed
|
|
109
105
|
* open question if interactiveAllowed changed to allowed
|
|
110
106
|
*/
|
|
111
|
-
this.interactiveAllowed.listen(() => {
|
|
107
|
+
this.cancels.add(this.interactiveAllowed.listen(() => {
|
|
112
108
|
window.requestAnimationFrame(() => {
|
|
113
109
|
this.activeQuestionId.invalidate();
|
|
114
110
|
});
|
|
111
|
+
}));
|
|
112
|
+
instance.sdk.onMount(() => {
|
|
113
|
+
return () => {
|
|
114
|
+
this.activeQuestionId.off();
|
|
115
|
+
for (const cancel of this.cancels) {
|
|
116
|
+
cancel();
|
|
117
|
+
this.cancels.delete(cancel);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
115
120
|
});
|
|
116
121
|
}
|
|
117
122
|
/**
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Transport } from '@streamlayer/sdk-web-api';
|
|
2
|
+
import { ReadableAtom } from 'nanostores';
|
|
3
|
+
import { LeaderboardItem } from '@streamlayer/sl-eslib/interactive/leaderboard/interactive.leaderboard_pb';
|
|
4
|
+
import { Gamification } from '.';
|
|
5
|
+
export declare const friendSummary: ($eventId: ReadableAtom<string | undefined>, $userId: ReadableAtom<string | undefined>, $friends: Gamification['friends'], friendId: string, transport: Transport) => Promise<LeaderboardItem | undefined>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { createUserSummaryFetch } from './queries/leaderboard';
|
|
2
|
+
export const friendSummary = async ($eventId, $userId, $friends, friendId, transport) => {
|
|
3
|
+
const fetch = createUserSummaryFetch(transport);
|
|
4
|
+
const eventId = $eventId.get();
|
|
5
|
+
const userId = $userId.get();
|
|
6
|
+
const usersIds = $friends
|
|
7
|
+
.getStore()
|
|
8
|
+
.get()
|
|
9
|
+
.data?.map((friend) => friend.slId) || [];
|
|
10
|
+
const request = {
|
|
11
|
+
eventId: eventId,
|
|
12
|
+
userId: friendId,
|
|
13
|
+
usersIds: [...usersIds, userId],
|
|
14
|
+
};
|
|
15
|
+
const res = await fetch(request);
|
|
16
|
+
const summary = res.data?.attributes?.summary;
|
|
17
|
+
return summary;
|
|
18
|
+
};
|
package/lib/gamification.d.ts
CHANGED
|
@@ -55,17 +55,18 @@ export declare class Gamification extends AbstractFeature<'games', PlainMessage<
|
|
|
55
55
|
/** Browser cache */
|
|
56
56
|
private storage;
|
|
57
57
|
private submitAnswerTimeout;
|
|
58
|
+
private cancels;
|
|
58
59
|
constructor(config: FeatureProps, source: FeatureSource, instance: StreamLayerContext);
|
|
59
60
|
get isInteractiveAllowed(): boolean;
|
|
60
61
|
checkInteractiveFlag: () => void;
|
|
61
62
|
connect: () => void;
|
|
62
63
|
disconnect: () => void;
|
|
63
64
|
submitAnswer: (questionId: string, answerId: string) => Promise<void>;
|
|
64
|
-
openQuestion: (questionId
|
|
65
|
+
openQuestion: (questionId?: string, question?: FeedItem & {
|
|
65
66
|
openedFrom?: 'list' | 'notification';
|
|
66
|
-
}) => void;
|
|
67
|
+
}) => void | (() => void);
|
|
67
68
|
closeQuestion: (questionId?: string) => void;
|
|
68
|
-
openUser: (
|
|
69
|
+
openUser: (friendId: string) => Promise<void>;
|
|
69
70
|
closeUser: () => void;
|
|
70
71
|
/**
|
|
71
72
|
* Show in-app notification for active question
|
package/lib/gamification.js
CHANGED
|
@@ -13,6 +13,7 @@ import { GamificationBackground, InteractiveAllowed } from './background';
|
|
|
13
13
|
import { ERROR } from './constants';
|
|
14
14
|
import { $questionByUser } from './queries';
|
|
15
15
|
import { summary } from './userSummary';
|
|
16
|
+
import { friendSummary } from './friendSummary';
|
|
16
17
|
const InteractiveQuestionTypes = new Set([QuestionType.POLL, QuestionType.PREDICTION, QuestionType.TRIVIA]);
|
|
17
18
|
/**
|
|
18
19
|
* Gamification (Games) Overlay
|
|
@@ -55,6 +56,7 @@ export class Gamification extends AbstractFeature {
|
|
|
55
56
|
/** Browser cache */
|
|
56
57
|
storage;
|
|
57
58
|
submitAnswerTimeout;
|
|
59
|
+
cancels = new Set();
|
|
58
60
|
constructor(config, source, instance) {
|
|
59
61
|
super(config, source);
|
|
60
62
|
this.background = new GamificationBackground(instance);
|
|
@@ -78,21 +80,44 @@ export class Gamification extends AbstractFeature {
|
|
|
78
80
|
this.leaderboardList = leaderboard(this.transport, this.background.slStreamId, this.background.userId, this.friends);
|
|
79
81
|
this.connect();
|
|
80
82
|
// refresh leaderboard on user summary update after earning points
|
|
81
|
-
this.userSummary.$store.listen((userSummary) => {
|
|
82
|
-
if (
|
|
83
|
+
this.cancels.add(this.userSummary.$store.listen((userSummary, prevValue) => {
|
|
84
|
+
if (prevValue?.summary && userSummary?.summary && !userSummary.fromLeaderboard) {
|
|
83
85
|
this.leaderboardList.invalidate(); // verified, it's necessary
|
|
84
86
|
}
|
|
85
|
-
});
|
|
87
|
+
}));
|
|
88
|
+
this.cancels.add(this.leaderboardList.$store.subscribe((leaderboard) => {
|
|
89
|
+
const userSummary = { ...(this.userSummary.$store.get() || {}) };
|
|
90
|
+
const userId = userSummary?.summary?.userId;
|
|
91
|
+
if (leaderboard.data.length && userId) {
|
|
92
|
+
const userRank = leaderboard.data.find((item) => item.userId === userId)?.rank;
|
|
93
|
+
if (userRank !== undefined) {
|
|
94
|
+
if (userSummary?.summary) {
|
|
95
|
+
userSummary.fromLeaderboard = true;
|
|
96
|
+
userSummary.summary.friendsRank = userRank;
|
|
97
|
+
// @ts-ignore
|
|
98
|
+
this.userSummary.$store.set(userSummary);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}));
|
|
86
103
|
/**
|
|
87
104
|
* listen for active question and show in-app notification
|
|
88
105
|
*/
|
|
89
|
-
this.background.activeQuestionId.listen(this.showInApp);
|
|
106
|
+
this.cancels.add(this.background.activeQuestionId.listen(this.showInApp));
|
|
90
107
|
/**
|
|
91
108
|
* listen for onboarding status, moderation onboarding changes and opt-in settings
|
|
92
109
|
*/
|
|
93
|
-
this.onboardingStatus.$store.listen(this.checkInteractiveFlag);
|
|
94
|
-
this.background.moderation.getStore().listen(this.checkInteractiveFlag);
|
|
95
|
-
this.settings.subscribe(this.checkInteractiveFlag);
|
|
110
|
+
this.cancels.add(this.onboardingStatus.$store.listen(this.checkInteractiveFlag));
|
|
111
|
+
this.cancels.add(this.background.moderation.getStore().listen(this.checkInteractiveFlag));
|
|
112
|
+
this.cancels.add(this.settings.subscribe(this.checkInteractiveFlag));
|
|
113
|
+
instance.sdk.onMount(() => {
|
|
114
|
+
return () => {
|
|
115
|
+
for (const cancel of this.cancels) {
|
|
116
|
+
cancel();
|
|
117
|
+
this.cancels.delete(cancel);
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
});
|
|
96
121
|
}
|
|
97
122
|
get isInteractiveAllowed() {
|
|
98
123
|
return this.background.interactiveAllowed.get() === InteractiveAllowed.ALLOWED;
|
|
@@ -106,7 +131,7 @@ export class Gamification extends AbstractFeature {
|
|
|
106
131
|
this.background.interactiveAllowed.set(allowed ? InteractiveAllowed.ALLOWED : InteractiveAllowed.DISALLOWED);
|
|
107
132
|
};
|
|
108
133
|
connect = () => {
|
|
109
|
-
this.background.feedSubscription.addListener('feed-subscription-prediction-close', async (response) => {
|
|
134
|
+
this.cancels.add(this.background.feedSubscription.addListener('feed-subscription-prediction-close', async (response) => {
|
|
110
135
|
if (!this.isInteractiveAllowed) {
|
|
111
136
|
return;
|
|
112
137
|
}
|
|
@@ -194,18 +219,23 @@ export class Gamification extends AbstractFeature {
|
|
|
194
219
|
}
|
|
195
220
|
this.userSummary.invalidate(); // verified, it's necessary
|
|
196
221
|
}
|
|
197
|
-
});
|
|
222
|
+
}));
|
|
198
223
|
// update feed list on question update received from subscription
|
|
199
224
|
// add new question to the top of the list
|
|
200
|
-
this.background.feedSubscription.addListener('feed-subscription-questions-list', (response) => {
|
|
225
|
+
this.cancels.add(this.background.feedSubscription.addListener('feed-subscription-questions-list', (response) => {
|
|
201
226
|
const feedList = [...(this.feedList.getStore().value?.data || [])];
|
|
202
227
|
const feedItem = response.data?.attributes?.feedItem;
|
|
203
228
|
const questionIndex = feedList.findIndex((item) => item.id === feedItem?.id);
|
|
204
|
-
if (!feedItem) {
|
|
229
|
+
if (!feedItem?.attributes) {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
// skip questions with status other than active or resolved
|
|
233
|
+
if (feedItem.attributes.status !== QuestionStatus.ACTIVE &&
|
|
234
|
+
feedItem.attributes.status !== QuestionStatus.RESOLVED) {
|
|
205
235
|
return;
|
|
206
236
|
}
|
|
207
237
|
if (questionIndex !== -1) {
|
|
208
|
-
if (feedItem.attributes
|
|
238
|
+
if (feedItem.attributes.attributes.case === 'question' &&
|
|
209
239
|
feedList[questionIndex].attributes?.attributes.case === 'question') {
|
|
210
240
|
const prev = feedList[questionIndex];
|
|
211
241
|
if (prev.attributes) {
|
|
@@ -267,7 +297,7 @@ export class Gamification extends AbstractFeature {
|
|
|
267
297
|
});
|
|
268
298
|
}
|
|
269
299
|
this.feedList.getStore().mutate(feedList);
|
|
270
|
-
});
|
|
300
|
+
}));
|
|
271
301
|
};
|
|
272
302
|
// not used
|
|
273
303
|
disconnect = () => {
|
|
@@ -345,6 +375,9 @@ export class Gamification extends AbstractFeature {
|
|
|
345
375
|
}
|
|
346
376
|
};
|
|
347
377
|
openQuestion = (questionId, question) => {
|
|
378
|
+
if (!questionId) {
|
|
379
|
+
return () => { };
|
|
380
|
+
}
|
|
348
381
|
this.notifications.close(this.background.getCurrentSessionId({
|
|
349
382
|
prefix: 'notification',
|
|
350
383
|
entity: questionId,
|
|
@@ -367,9 +400,34 @@ export class Gamification extends AbstractFeature {
|
|
|
367
400
|
closeQuestion = (questionId) => {
|
|
368
401
|
return this.background.closeQuestion(questionId);
|
|
369
402
|
};
|
|
370
|
-
openUser = (
|
|
371
|
-
const user = this.leaderboardList.$store.get().data?.find((item) => item.userId ===
|
|
372
|
-
|
|
403
|
+
openUser = async (friendId) => {
|
|
404
|
+
const user = this.leaderboardList.$store.get().data?.find((item) => item.userId === friendId);
|
|
405
|
+
if (!user) {
|
|
406
|
+
this.openedUser.set(user);
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
if (user.summaryLoaded) {
|
|
410
|
+
this.openedUser.set(user);
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
const userCopy = { ...user };
|
|
414
|
+
try {
|
|
415
|
+
const friendDetail = await friendSummary(this.background.slStreamId, this.background.userId, this.friends, friendId, this.transport);
|
|
416
|
+
if (friendDetail?.inTop !== undefined) {
|
|
417
|
+
this.leaderboardList.$store.setKey('data', this.leaderboardList.$store.get().data?.map((item) => {
|
|
418
|
+
if (item.userId === friendId) {
|
|
419
|
+
item.inTop = friendDetail.inTop;
|
|
420
|
+
}
|
|
421
|
+
return item;
|
|
422
|
+
}));
|
|
423
|
+
userCopy.inTop = friendDetail.inTop;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
catch (err) {
|
|
427
|
+
console.error(err);
|
|
428
|
+
}
|
|
429
|
+
// @ts-ignore
|
|
430
|
+
this.openedUser.set(userCopy);
|
|
373
431
|
};
|
|
374
432
|
closeUser = () => {
|
|
375
433
|
this.openedUser.set(undefined);
|
|
@@ -392,8 +450,8 @@ export class Gamification extends AbstractFeature {
|
|
|
392
450
|
if (this.isInteractiveAllowed) {
|
|
393
451
|
this.notifications.add({
|
|
394
452
|
type: NotificationType.QUESTION,
|
|
395
|
-
action: () =>
|
|
396
|
-
close: () =>
|
|
453
|
+
action: () => this.openQuestion(question.data?.question?.id, question.data?.feedItem),
|
|
454
|
+
close: () => this.closeQuestion(question.data?.question?.id),
|
|
397
455
|
autoHideDuration: 1000 * 60,
|
|
398
456
|
id: this.background.getCurrentSessionId({
|
|
399
457
|
prefix: 'notification',
|
|
@@ -429,8 +487,8 @@ export class Gamification extends AbstractFeature {
|
|
|
429
487
|
};
|
|
430
488
|
this.notifications.add({
|
|
431
489
|
type: NotificationType.QUESTION,
|
|
432
|
-
action: () =>
|
|
433
|
-
close: () =>
|
|
490
|
+
action: () => this.openQuestion(question?.data?.question?.id, question?.data?.feedItem),
|
|
491
|
+
close: () => this.closeQuestion(question?.data?.question?.id),
|
|
434
492
|
autoHideDuration: 1000 * 120,
|
|
435
493
|
emitEvent: true,
|
|
436
494
|
id: this.background.getCurrentSessionId({ prefix: 'notification', entity: question.data.question.id }),
|
|
@@ -454,8 +512,8 @@ export class Gamification extends AbstractFeature {
|
|
|
454
512
|
};
|
|
455
513
|
this.notifications.add({
|
|
456
514
|
type: NotificationType.QUESTION,
|
|
457
|
-
action: () =>
|
|
458
|
-
close: () =>
|
|
515
|
+
action: () => this.openQuestion(question.data?.question?.id, question.data?.feedItem),
|
|
516
|
+
close: () => this.closeQuestion(question.data?.question?.id),
|
|
459
517
|
autoHideDuration: 1000 * 120,
|
|
460
518
|
emitEvent: true,
|
|
461
519
|
id: this.background.getCurrentSessionId({ prefix: 'notification', entity: question.data.question.id }),
|
package/lib/leaderboard.d.ts
CHANGED
package/lib/leaderboard.js
CHANGED
|
@@ -37,7 +37,10 @@ export const leaderboard = (transport, $eventId, $userId, $friends, options) =>
|
|
|
37
37
|
};
|
|
38
38
|
const newData = await fetch(request);
|
|
39
39
|
$store.set({
|
|
40
|
-
data: newData.data.map((item) =>
|
|
40
|
+
data: newData.data.map((item, i) => ({
|
|
41
|
+
...item.attributes,
|
|
42
|
+
rank: i + 1,
|
|
43
|
+
})),
|
|
41
44
|
hasMore: false,
|
|
42
45
|
key: Date.now(),
|
|
43
46
|
loading: false,
|
package/lib/onboarding.js
CHANGED
|
@@ -154,6 +154,7 @@ export const onboarding = (service, background, transport, notifications) => {
|
|
|
154
154
|
action: 'onboardingPassed',
|
|
155
155
|
payload: {},
|
|
156
156
|
});
|
|
157
|
+
service.openFeature();
|
|
157
158
|
const notificationId = background.getCurrentSessionId({ prefix: 'onboarding' });
|
|
158
159
|
notifications.close(notificationId);
|
|
159
160
|
}
|
package/lib/userSummary.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ 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'], transport: Transport) => {
|
|
6
|
-
$store: import("nanostores").MapStore<LeaderboardSummaryItem
|
|
6
|
+
$store: import("nanostores").MapStore<(LeaderboardSummaryItem & {
|
|
7
|
+
fromLeaderboard?: boolean | undefined;
|
|
8
|
+
}) | undefined>;
|
|
7
9
|
invalidate: () => void;
|
|
8
10
|
};
|
package/lib/userSummary.js
CHANGED
|
@@ -12,13 +12,20 @@ export const summary = ($eventId, $userId, $friends, transport) => {
|
|
|
12
12
|
const usersIds = $friends
|
|
13
13
|
.getStore()
|
|
14
14
|
.get()
|
|
15
|
-
.data?.map((friend) => friend.slId)
|
|
15
|
+
.data?.map((friend) => friend.slId);
|
|
16
|
+
if (!usersIds) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
16
19
|
const request = {
|
|
17
20
|
eventId: eventId,
|
|
18
21
|
userId: userId,
|
|
19
22
|
usersIds: [...usersIds, userId],
|
|
20
23
|
};
|
|
21
24
|
const res = await fetch(request);
|
|
25
|
+
const prevData = $store.get()?.summary?.friendsRank;
|
|
26
|
+
if (res.data?.attributes?.summary?.friendsRank && prevData !== undefined) {
|
|
27
|
+
res.data.attributes.summary.friendsRank = prevData;
|
|
28
|
+
}
|
|
22
29
|
$store.set(res.data?.attributes);
|
|
23
30
|
};
|
|
24
31
|
const invalidate = () => {
|
package/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@streamlayer/feature-gamification",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.40.0",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"@bufbuild/protobuf": "^1.7.2",
|
|
6
6
|
"@fastify/deepmerge": "^1.3.0",
|
|
7
7
|
"@streamlayer/sl-eslib": "^5.83.1",
|
|
8
8
|
"nanostores": "^0.10.0",
|
|
9
|
-
"@streamlayer/sdk-web-api": "^0.24.
|
|
10
|
-
"@streamlayer/sdk-web-core": "^0.22.
|
|
9
|
+
"@streamlayer/sdk-web-api": "^0.24.2",
|
|
10
|
+
"@streamlayer/sdk-web-core": "^0.22.2",
|
|
11
11
|
"@streamlayer/sdk-web-interfaces": "^0.21.0",
|
|
12
12
|
"@streamlayer/sdk-web-logger": "^0.5.18",
|
|
13
|
-
"@streamlayer/sdk-web-notifications": "^0.15.
|
|
13
|
+
"@streamlayer/sdk-web-notifications": "^0.15.1",
|
|
14
14
|
"@streamlayer/sdk-web-storage": "^0.4.5",
|
|
15
15
|
"@streamlayer/sdk-web-types": "^0.23.0"
|
|
16
16
|
},
|