@streamlayer/feature-gamification 1.16.10 → 1.16.12
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.js +52 -32
- package/lib/detail.js +15 -7
- package/lib/gamification.js +14 -1
- package/lib/queries/deepLink.js +1 -1
- package/lib/queries/index.js +31 -16
- package/lib/queries/moderation.js +1 -1
- package/package.json +8 -8
package/lib/background.js
CHANGED
|
@@ -4,7 +4,6 @@ import { QuestionStatus, QuestionType } from '@streamlayer/sdk-web-types';
|
|
|
4
4
|
import '@streamlayer/sdk-web-core/store';
|
|
5
5
|
import * as queries from './queries';
|
|
6
6
|
import { detail } from './detail';
|
|
7
|
-
import { advertisement } from './advertisement';
|
|
8
7
|
import { GamificationStorage } from './storage';
|
|
9
8
|
export var InteractiveAllowed;
|
|
10
9
|
(function (InteractiveAllowed) {
|
|
@@ -68,32 +67,50 @@ export class GamificationBackground {
|
|
|
68
67
|
this.cancels.add(this.openedQuestionId.listen((item) => {
|
|
69
68
|
this.log.debug({ item }, 'received question');
|
|
70
69
|
if (item?.questionId) {
|
|
70
|
+
this.log.info('cleanup on close question');
|
|
71
|
+
if (this.questionSubscription !== undefined) {
|
|
72
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
73
|
+
instance.transport.removeSubscription(this.questionSubscription);
|
|
74
|
+
this.questionSubscription = undefined;
|
|
75
|
+
}
|
|
71
76
|
this.questionSubscription = queries.questionSubscription(item.questionId, instance.transport);
|
|
72
|
-
this.questionSubscription.addListener('feed-subscription-opened-question',
|
|
77
|
+
this.questionSubscription.addListener('feed-subscription-opened-question', (response) => {
|
|
73
78
|
const question = response.data?.attributes?.question;
|
|
74
79
|
this.openedQuestion.updateExtendedQuestion(question);
|
|
75
|
-
if (
|
|
80
|
+
if (this.betPack &&
|
|
81
|
+
question?.type === QuestionType.PREDICTION &&
|
|
76
82
|
(question.status === QuestionStatus.ACTIVE || question.status === QuestionStatus.RESOLVED)) {
|
|
77
83
|
const betPackData = this.betPack.getValues().data?.data || {};
|
|
78
84
|
const betPackItem = betPackData?.[question.id];
|
|
79
|
-
if (betPackItem
|
|
80
|
-
const
|
|
81
|
-
const
|
|
82
|
-
|
|
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
|
-
}
|
|
88
|
-
cancel();
|
|
89
|
-
window.requestAnimationFrame(() => {
|
|
90
|
-
data.invalidate();
|
|
85
|
+
if (betPackItem) {
|
|
86
|
+
const answers = [];
|
|
87
|
+
const sortedPrev = betPackItem.answers.sort((a, b) => {
|
|
88
|
+
return a.id > b.id ? 1 : -1;
|
|
91
89
|
});
|
|
90
|
+
const sortedNew = question.answers.sort((a, b) => {
|
|
91
|
+
return a.id > b.id ? 1 : -1;
|
|
92
|
+
});
|
|
93
|
+
for (let i = 0; i < sortedPrev.length; i++) {
|
|
94
|
+
answers.push({
|
|
95
|
+
...sortedPrev[i],
|
|
96
|
+
...sortedNew[i],
|
|
97
|
+
correct: sortedPrev[i].correct,
|
|
98
|
+
youVoted: sortedPrev[i].youVoted,
|
|
99
|
+
pointsEarned: sortedPrev[i].pointsEarned,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
92
102
|
this.betPack.getStore().mutate({
|
|
93
103
|
timestamp: Date.now(),
|
|
94
104
|
data: {
|
|
95
105
|
...betPackData,
|
|
96
|
-
[question.id]:
|
|
106
|
+
[question.id]: {
|
|
107
|
+
...betPackItem,
|
|
108
|
+
status: question.status,
|
|
109
|
+
marketClosed: question.marketClosed,
|
|
110
|
+
activatedAt: question.activatedAt,
|
|
111
|
+
answerSetAt: question.answerSetAt,
|
|
112
|
+
answers,
|
|
113
|
+
},
|
|
97
114
|
},
|
|
98
115
|
});
|
|
99
116
|
}
|
|
@@ -113,25 +130,28 @@ export class GamificationBackground {
|
|
|
113
130
|
this.feedSubscription = queries.feedSubscription(this.slStreamId, instance.transport);
|
|
114
131
|
this.cancels.add(this.feedSubscription.addListener('bet-pack-update', async (response) => {
|
|
115
132
|
const question = response.data?.attributes?.question;
|
|
116
|
-
if (
|
|
133
|
+
if (this.betPack &&
|
|
134
|
+
question?.type === QuestionType.PREDICTION &&
|
|
117
135
|
(question.status === QuestionStatus.ACTIVE || question.status === QuestionStatus.RESOLVED)) {
|
|
118
136
|
const betPackData = this.betPack.getValues().data?.data || {};
|
|
119
137
|
const betPackItem = betPackData?.[question.id];
|
|
120
|
-
if (betPackItem
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
138
|
+
if (betPackItem) {
|
|
139
|
+
this.betPack.getStore().mutate({
|
|
140
|
+
timestamp: Date.now(),
|
|
141
|
+
data: {
|
|
142
|
+
...betPackData,
|
|
143
|
+
[question.id]: {
|
|
144
|
+
...betPackItem,
|
|
145
|
+
status: question.status,
|
|
146
|
+
marketClosed: question.marketClosed,
|
|
147
|
+
activatedAt: question.activatedAt,
|
|
148
|
+
answerSetAt: question.answerSetAt,
|
|
149
|
+
},
|
|
150
|
+
},
|
|
133
151
|
});
|
|
134
|
-
|
|
152
|
+
}
|
|
153
|
+
else if (!betPackItem && Object.keys(betPackData).length < 5) {
|
|
154
|
+
const extendedQuestion = await queries.questionByUser(question.id, this.transport);
|
|
135
155
|
this.betPack.getStore().mutate({
|
|
136
156
|
timestamp: Date.now(),
|
|
137
157
|
data: {
|
|
@@ -215,7 +235,7 @@ export class GamificationBackground {
|
|
|
215
235
|
};
|
|
216
236
|
});
|
|
217
237
|
if (!onlyBetPack) {
|
|
218
|
-
this.advertisement = advertisement(this.slStreamId, this.feedSubscription, instance)
|
|
238
|
+
// this.advertisement = advertisement(this.slStreamId, this.feedSubscription, instance)
|
|
219
239
|
}
|
|
220
240
|
}
|
|
221
241
|
/**
|
package/lib/detail.js
CHANGED
|
@@ -22,16 +22,24 @@ export const detail = (transport, $openedQuestionId, $feedList) => {
|
|
|
22
22
|
const currentQuestion = $extendedStore.get().data;
|
|
23
23
|
const mergeQuestionAnswers = (currentAnswers, newAnswers) => {
|
|
24
24
|
if (!currentAnswers || !newAnswers) {
|
|
25
|
-
return currentAnswers || newAnswers || []
|
|
25
|
+
return (currentAnswers || newAnswers || []).sort((a, b) => {
|
|
26
|
+
return a.id > b.id ? 1 : -1;
|
|
27
|
+
});
|
|
26
28
|
}
|
|
29
|
+
const sortedPrev = currentAnswers.sort((a, b) => {
|
|
30
|
+
return a.id > b.id ? 1 : -1;
|
|
31
|
+
});
|
|
32
|
+
const sortedNew = newAnswers.sort((a, b) => {
|
|
33
|
+
return a.id > b.id ? 1 : -1;
|
|
34
|
+
});
|
|
27
35
|
const answers = [];
|
|
28
|
-
for (let i = 0; i <
|
|
36
|
+
for (let i = 0; i < sortedPrev.length; i++) {
|
|
29
37
|
answers.push({
|
|
30
|
-
...
|
|
31
|
-
...
|
|
32
|
-
correct:
|
|
33
|
-
youVoted:
|
|
34
|
-
pointsEarned:
|
|
38
|
+
...sortedPrev[i],
|
|
39
|
+
...sortedNew[i],
|
|
40
|
+
correct: sortedPrev[i].correct,
|
|
41
|
+
youVoted: sortedPrev[i].youVoted,
|
|
42
|
+
pointsEarned: sortedPrev[i].pointsEarned,
|
|
35
43
|
});
|
|
36
44
|
}
|
|
37
45
|
return answers;
|
package/lib/gamification.js
CHANGED
|
@@ -190,6 +190,7 @@ export class Gamification extends AbstractFeature {
|
|
|
190
190
|
let extendedQuestion = data.get().data;
|
|
191
191
|
if (!extendedQuestion) {
|
|
192
192
|
extendedQuestion = await questionByUser(id, this.transport);
|
|
193
|
+
data.mutate(extendedQuestion);
|
|
193
194
|
}
|
|
194
195
|
cancel();
|
|
195
196
|
window.requestAnimationFrame(() => {
|
|
@@ -301,7 +302,12 @@ export class Gamification extends AbstractFeature {
|
|
|
301
302
|
status: prev.attributes.attributes.value.status,
|
|
302
303
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
303
304
|
// @ts-ignore
|
|
304
|
-
openForVoting:
|
|
305
|
+
openForVoting:
|
|
306
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
307
|
+
// @ts-ignore
|
|
308
|
+
prev.attributes.attributes.value.openForVoting === false
|
|
309
|
+
? false
|
|
310
|
+
: feedItem.attributes.attributes.value.openForVoting,
|
|
305
311
|
},
|
|
306
312
|
},
|
|
307
313
|
},
|
|
@@ -348,6 +354,9 @@ export class Gamification extends AbstractFeature {
|
|
|
348
354
|
this.background.feedSubscription.removeListener('feed-subscription-questions-list');
|
|
349
355
|
};
|
|
350
356
|
betPackVote = async (questionId, answerId) => {
|
|
357
|
+
if (!this.betPack) {
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
351
360
|
try {
|
|
352
361
|
await actions.submitAnswer(this.transport, { questionId, answerId });
|
|
353
362
|
}
|
|
@@ -461,6 +470,10 @@ export class Gamification extends AbstractFeature {
|
|
|
461
470
|
return () => { };
|
|
462
471
|
}
|
|
463
472
|
const openedFromBetPack = question?.openedFrom === 'bet-pack';
|
|
473
|
+
if (!openedFromBetPack) {
|
|
474
|
+
const query = queries.$questionByUser(questionId, this.transport);
|
|
475
|
+
query.invalidate();
|
|
476
|
+
}
|
|
464
477
|
this.notifications.close(this.background.getCurrentSessionId({
|
|
465
478
|
prefix: 'notification',
|
|
466
479
|
entity: questionId,
|
package/lib/queries/deepLink.js
CHANGED
package/lib/queries/index.js
CHANGED
|
@@ -24,7 +24,7 @@ export const $activeQuestion = (slStreamId, onlyBetPack, transport) => {
|
|
|
24
24
|
return res.data?.attributes;
|
|
25
25
|
},
|
|
26
26
|
dedupeTime: 1000 * 60 * 10, // 10 minutes
|
|
27
|
-
refetchInterval:
|
|
27
|
+
refetchInterval: Infinity,
|
|
28
28
|
});
|
|
29
29
|
};
|
|
30
30
|
export const getFeedItem = async (questionId, transport) => {
|
|
@@ -67,17 +67,29 @@ export const questionByUser = async ($questionId, transport) => {
|
|
|
67
67
|
});
|
|
68
68
|
return res.data?.attributes?.question;
|
|
69
69
|
};
|
|
70
|
+
const storeCache = new Map();
|
|
70
71
|
export const $questionByUser = ($questionId, transport) => {
|
|
71
|
-
const { client, queryKey } = transport.createPromiseClient(Feed, {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const res = await client.questionByUser({
|
|
75
|
-
questionId: questionId,
|
|
76
|
-
});
|
|
77
|
-
return res.data?.attributes?.question;
|
|
78
|
-
},
|
|
79
|
-
dedupeTime: 1000 * 60 * 5,
|
|
72
|
+
const { client, queryKey, queryKeyStr } = transport.createPromiseClient(Feed, {
|
|
73
|
+
method: 'questionByUser',
|
|
74
|
+
params: [$questionId],
|
|
80
75
|
});
|
|
76
|
+
if (storeCache.has(queryKeyStr)) {
|
|
77
|
+
return storeCache.get(queryKeyStr);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
const store = transport.nanoquery.createFetcherStore(queryKey, {
|
|
81
|
+
fetcher: async (_, __, questionId) => {
|
|
82
|
+
const res = await client.questionByUser({
|
|
83
|
+
questionId: questionId,
|
|
84
|
+
});
|
|
85
|
+
return res.data?.attributes?.question;
|
|
86
|
+
},
|
|
87
|
+
dedupeTime: Infinity,
|
|
88
|
+
refetchInterval: Infinity,
|
|
89
|
+
});
|
|
90
|
+
storeCache.set(queryKeyStr, store);
|
|
91
|
+
return store;
|
|
92
|
+
}
|
|
81
93
|
};
|
|
82
94
|
export const getPromotionDetail = async (promoId, transport) => {
|
|
83
95
|
if (!promoId) {
|
|
@@ -146,8 +158,8 @@ export const $feedList = ($slStreamId, $interactiveAllowed, $slUserId, $slOrgani
|
|
|
146
158
|
}
|
|
147
159
|
return res.data;
|
|
148
160
|
},
|
|
149
|
-
dedupeTime:
|
|
150
|
-
refetchInterval:
|
|
161
|
+
dedupeTime: Infinity,
|
|
162
|
+
refetchInterval: Infinity,
|
|
151
163
|
});
|
|
152
164
|
};
|
|
153
165
|
export const $activePromotionId = ($slStreamId, transport) => {
|
|
@@ -177,8 +189,8 @@ export const $activePromotionId = ($slStreamId, transport) => {
|
|
|
177
189
|
}
|
|
178
190
|
return undefined;
|
|
179
191
|
},
|
|
180
|
-
dedupeTime:
|
|
181
|
-
refetchInterval:
|
|
192
|
+
dedupeTime: Infinity,
|
|
193
|
+
refetchInterval: Infinity,
|
|
182
194
|
});
|
|
183
195
|
};
|
|
184
196
|
export { $userSummary, $leaderboardList } from './leaderboard';
|
|
@@ -235,11 +247,14 @@ export const $betPack = ($slStreamId, $slUserId, $slOrganizationId, storage, tra
|
|
|
235
247
|
});
|
|
236
248
|
storage.saveQuestionReceived(flags, question.id);
|
|
237
249
|
}
|
|
250
|
+
question.answers = question.answers.sort((a, b) => {
|
|
251
|
+
return a.id > b.id ? 1 : -1;
|
|
252
|
+
});
|
|
238
253
|
return { ...acc, [question.id]: question };
|
|
239
254
|
}, {}),
|
|
240
255
|
};
|
|
241
256
|
},
|
|
242
|
-
dedupeTime:
|
|
243
|
-
refetchInterval:
|
|
257
|
+
dedupeTime: Infinity,
|
|
258
|
+
refetchInterval: Infinity,
|
|
244
259
|
});
|
|
245
260
|
};
|
package/package.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@streamlayer/feature-gamification",
|
|
3
|
-
"version": "1.16.
|
|
3
|
+
"version": "1.16.12",
|
|
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
8
|
"uuid": "^11.1.0",
|
|
9
9
|
"nanostores": "^0.11.4",
|
|
10
|
-
"@streamlayer/sdk-web-api": "^1.8.
|
|
11
|
-
"@streamlayer/sdk-web-core": "^1.11.
|
|
12
|
-
"@streamlayer/sdk-web-interfaces": "^1.5.
|
|
13
|
-
"@streamlayer/sdk-web-logger": "^1.0.
|
|
14
|
-
"@streamlayer/sdk-web-notifications": "^1.3.
|
|
15
|
-
"@streamlayer/sdk-web-storage": "^1.0.
|
|
16
|
-
"@streamlayer/sdk-web-types": "^1.10.
|
|
10
|
+
"@streamlayer/sdk-web-api": "^1.8.12",
|
|
11
|
+
"@streamlayer/sdk-web-core": "^1.11.14",
|
|
12
|
+
"@streamlayer/sdk-web-interfaces": "^1.5.3",
|
|
13
|
+
"@streamlayer/sdk-web-logger": "^1.0.59",
|
|
14
|
+
"@streamlayer/sdk-web-notifications": "^1.3.21",
|
|
15
|
+
"@streamlayer/sdk-web-storage": "^1.0.59",
|
|
16
|
+
"@streamlayer/sdk-web-types": "^1.10.16"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"tslib": "^2.7.0"
|