@streamlayer/feature-gamification 1.6.3 → 1.7.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/index.d.ts +5 -0
- package/lib/advertisement/index.js +67 -49
- package/lib/background.js +14 -6
- package/lib/gamification.d.ts +3 -1
- package/lib/gamification.js +33 -10
- package/lib/onboarding.js +7 -0
- package/lib/queries/index.d.ts +1 -0
- package/lib/queries/index.js +10 -0
- package/package.json +9 -9
|
@@ -7,6 +7,8 @@ export type Advertisement = {
|
|
|
7
7
|
loading?: boolean;
|
|
8
8
|
hiding?: boolean;
|
|
9
9
|
isViewed?: boolean;
|
|
10
|
+
isOpened?: boolean;
|
|
11
|
+
hasNotification?: boolean;
|
|
10
12
|
close?: () => void;
|
|
11
13
|
error?: string;
|
|
12
14
|
ctx?: Record<string, unknown>;
|
|
@@ -24,8 +26,11 @@ export type Advertisement = {
|
|
|
24
26
|
* - we subscribe to $feedSubscription, and show advertisement on activate
|
|
25
27
|
*/
|
|
26
28
|
export declare const advertisement: ($slStreamId: GamificationBackground["slStreamId"], $feedSubscription: GamificationBackground["feedSubscription"], instance: StreamLayerContext) => {
|
|
29
|
+
connect: () => void;
|
|
27
30
|
hide: (notificationId?: string) => void;
|
|
28
31
|
show: (advertisementId: string, data?: Awaited<ReturnType<typeof getPromotionDetail>>) => void;
|
|
32
|
+
open: () => void;
|
|
33
|
+
markAsViewed: () => void;
|
|
29
34
|
$store: import("nanostores").MapStore<Advertisement>;
|
|
30
35
|
};
|
|
31
36
|
export {};
|
|
@@ -18,11 +18,33 @@ import { parsePromotion } from './utils';
|
|
|
18
18
|
* - we subscribe to $feedSubscription, and show advertisement on activate
|
|
19
19
|
*/
|
|
20
20
|
export const advertisement = ($slStreamId, $feedSubscription, instance) => {
|
|
21
|
+
let connected = false;
|
|
21
22
|
const transport = instance.transport;
|
|
22
23
|
const logger = createLogger('advertisement');
|
|
23
24
|
const storage = new AdvertisementStorage();
|
|
24
25
|
const $store = createMapStore({});
|
|
25
26
|
const $activeAdvertisement = $activePromotionId($slStreamId, transport);
|
|
27
|
+
const open = () => {
|
|
28
|
+
$store.setKey('hasNotification', false);
|
|
29
|
+
};
|
|
30
|
+
const markAsViewed = () => {
|
|
31
|
+
const payload = $store.get();
|
|
32
|
+
const id = payload.data?.question.id;
|
|
33
|
+
const type = payload.data?.promotion?.type;
|
|
34
|
+
const isOpened = $store.get()?.isOpened;
|
|
35
|
+
if (id && !isOpened) {
|
|
36
|
+
logger.debug({ id }, 'markAsViewed: %o');
|
|
37
|
+
storage.setShowed(id);
|
|
38
|
+
$store.setKey('isOpened', true);
|
|
39
|
+
eventBus.emit('advertisement', {
|
|
40
|
+
action: 'opened',
|
|
41
|
+
payload: {
|
|
42
|
+
id,
|
|
43
|
+
type,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
};
|
|
26
48
|
/**
|
|
27
49
|
* Show advertisement by id
|
|
28
50
|
*/
|
|
@@ -34,6 +56,7 @@ export const advertisement = ($slStreamId, $feedSubscription, instance) => {
|
|
|
34
56
|
loading: false,
|
|
35
57
|
error: undefined,
|
|
36
58
|
data: response,
|
|
59
|
+
hasNotification: response?.notification?.enabled === NotificationEnabled.NOTIFICATION_ENABLED,
|
|
37
60
|
close: () => hide(response?.question.id),
|
|
38
61
|
isViewed: response && !!storage.isViewed(response.question.id),
|
|
39
62
|
}))
|
|
@@ -48,78 +71,73 @@ export const advertisement = ($slStreamId, $feedSubscription, instance) => {
|
|
|
48
71
|
loading: false,
|
|
49
72
|
error: undefined,
|
|
50
73
|
data,
|
|
74
|
+
hasNotification: data?.notification?.enabled === NotificationEnabled.NOTIFICATION_ENABLED,
|
|
51
75
|
close: () => hide(data.question.id),
|
|
52
76
|
isViewed: !!storage.isViewed(data.question.id),
|
|
53
77
|
});
|
|
54
78
|
}
|
|
55
79
|
};
|
|
56
|
-
$
|
|
57
|
-
|
|
80
|
+
$store.subscribe((active, prevActive) => {
|
|
81
|
+
// skip update on open
|
|
82
|
+
if (active.data && !active.isOpened) {
|
|
58
83
|
eventBus.emit('advertisement', {
|
|
59
84
|
action: 'received',
|
|
60
85
|
payload: {
|
|
61
|
-
|
|
62
|
-
|
|
86
|
+
id: active.data.question.id,
|
|
87
|
+
type: active.data?.promotion?.type,
|
|
88
|
+
hasNotification: !!active.hasNotification,
|
|
89
|
+
isViewed: !!storage.isViewed(active.data.question.id),
|
|
63
90
|
},
|
|
91
|
+
skipAnalytics: active.data.question.id === prevActive?.data?.question.id,
|
|
64
92
|
});
|
|
65
|
-
if (!prevActive?.data || active.data.id !== prevActive.data.id) {
|
|
66
|
-
show(active.data.question.id, active.data);
|
|
67
|
-
}
|
|
68
93
|
}
|
|
69
|
-
|
|
70
|
-
$store.subscribe((active, prevActive) => {
|
|
71
|
-
if (active.data) {
|
|
72
|
-
instance.sdk.onAdvertisementActivate({
|
|
73
|
-
stage: 'activate',
|
|
74
|
-
id: active.data.question.id,
|
|
75
|
-
hasNotification: active.data.notification?.enabled === NotificationEnabled.NOTIFICATION_ENABLED,
|
|
76
|
-
isViewed: !!storage.isViewed(active.data.question.id),
|
|
77
|
-
});
|
|
94
|
+
if (!active?.data && prevActive?.data) {
|
|
78
95
|
eventBus.emit('advertisement', {
|
|
79
|
-
action: '
|
|
96
|
+
action: 'closed',
|
|
80
97
|
payload: {
|
|
81
|
-
|
|
82
|
-
|
|
98
|
+
id: prevActive.data.question.id,
|
|
99
|
+
type: prevActive.data.promotion?.type,
|
|
100
|
+
hasNotification: !!prevActive.hasNotification,
|
|
101
|
+
isViewed: !!storage.isViewed(prevActive.data.question.id),
|
|
83
102
|
},
|
|
84
103
|
});
|
|
85
104
|
}
|
|
86
|
-
if (!active?.data && prevActive?.data) {
|
|
87
|
-
instance.sdk.onAdvertisementActivate({
|
|
88
|
-
stage: 'deactivate',
|
|
89
|
-
id: prevActive.data.question.id,
|
|
90
|
-
isViewed: !!storage.isViewed(prevActive.data.question.id),
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
105
|
});
|
|
94
|
-
const markAsViewed = (notificationId) => {
|
|
95
|
-
logger.debug({ notificationId }, 'markAsViewed: %o');
|
|
96
|
-
storage.setShowed(notificationId);
|
|
97
|
-
};
|
|
98
106
|
const hide = (notificationId) => {
|
|
99
107
|
if (!notificationId || $store.get()?.data?.question.id === notificationId) {
|
|
100
108
|
$store.set({});
|
|
101
109
|
}
|
|
102
|
-
if (notificationId) {
|
|
103
|
-
markAsViewed(notificationId);
|
|
104
|
-
}
|
|
105
110
|
};
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
if (!promotion) {
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
if (promotion.question.status === QuestionStatus.RESOLVED) {
|
|
112
|
-
hide(promotion.question.id);
|
|
113
|
-
logger.debug({ promotion }, 'resolved: %o');
|
|
111
|
+
const connect = () => {
|
|
112
|
+
if (connected) {
|
|
114
113
|
return;
|
|
115
114
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
115
|
+
connected = true;
|
|
116
|
+
$activeAdvertisement.subscribe((active, prevActive) => {
|
|
117
|
+
if (active.data) {
|
|
118
|
+
if (!prevActive?.data || active.data.id !== prevActive.data.id) {
|
|
119
|
+
show(active.data.question.id, active.data);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
$feedSubscription.addListener('promotion', (response) => {
|
|
124
|
+
const promotion = parsePromotion(response);
|
|
125
|
+
if (!promotion) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
if (promotion.question.status === QuestionStatus.RESOLVED) {
|
|
129
|
+
hide(promotion.question.id);
|
|
130
|
+
logger.debug({ promotion }, 'resolved: %o');
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (promotion.question.status === QuestionStatus.ACTIVE) {
|
|
134
|
+
logger.debug({ promotion }, 'active: %o');
|
|
135
|
+
show(promotion.question.id, promotion);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
logger.debug({ promotion }, 'skip: %o');
|
|
119
139
|
return;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
});
|
|
124
|
-
return { hide, show, $store };
|
|
140
|
+
});
|
|
141
|
+
};
|
|
142
|
+
return { connect, hide, show, open, markAsViewed, $store };
|
|
125
143
|
};
|
package/lib/background.js
CHANGED
|
@@ -90,7 +90,9 @@ export class GamificationBackground {
|
|
|
90
90
|
}
|
|
91
91
|
return;
|
|
92
92
|
}
|
|
93
|
-
|
|
93
|
+
window.requestAnimationFrame(() => {
|
|
94
|
+
this.activeQuestionId.mutate(response.data?.attributes);
|
|
95
|
+
});
|
|
94
96
|
}));
|
|
95
97
|
// refresh moderation if question empty, it`s mean that moderation was changed
|
|
96
98
|
this.cancels.add(this.feedSubscription.addListener('moderation update', (response) => {
|
|
@@ -103,20 +105,26 @@ export class GamificationBackground {
|
|
|
103
105
|
});
|
|
104
106
|
}));
|
|
105
107
|
this.cancels.add(this.activeQuestionId.subscribe((item, prevItem) => {
|
|
106
|
-
if (item.data?.feedItem) {
|
|
107
|
-
instance.
|
|
108
|
+
if (item.data?.feedItem && item.data?.feedItem?.id !== prevItem?.data?.feedItem?.id) {
|
|
109
|
+
instance.onQuestionActivate({
|
|
108
110
|
stage: 'activate',
|
|
109
111
|
id: item.data.feedItem.id,
|
|
110
|
-
isViewed: !!this.notifications.isViewed(
|
|
112
|
+
isViewed: !!this.notifications.isViewed(this.getCurrentSessionId({
|
|
113
|
+
prefix: 'notification',
|
|
114
|
+
entity: item.data.feedItem.id,
|
|
115
|
+
})),
|
|
111
116
|
hasNotification: true,
|
|
112
117
|
type: item.data.feedItem.type,
|
|
113
118
|
});
|
|
114
119
|
}
|
|
115
120
|
if (!item.data?.feedItem && prevItem?.data?.feedItem) {
|
|
116
|
-
instance.
|
|
121
|
+
instance.onQuestionActivate({
|
|
117
122
|
stage: 'deactivate',
|
|
118
123
|
id: prevItem.data.feedItem.id,
|
|
119
|
-
isViewed: !!this.notifications.isViewed(
|
|
124
|
+
isViewed: !!this.notifications.isViewed(this.getCurrentSessionId({
|
|
125
|
+
prefix: 'notification',
|
|
126
|
+
entity: prevItem.data.feedItem.id,
|
|
127
|
+
})),
|
|
120
128
|
hasNotification: true,
|
|
121
129
|
type: prevItem.data.feedItem.type,
|
|
122
130
|
});
|
package/lib/gamification.d.ts
CHANGED
|
@@ -43,12 +43,13 @@ export declare class Gamification extends AbstractFeature<'games', PlainMessage<
|
|
|
43
43
|
currentUserId: GamificationBackground['userId'];
|
|
44
44
|
/** pinned leaderboard id */
|
|
45
45
|
openedUser: WritableAtom<LeaderboardItem | undefined>;
|
|
46
|
-
closeFeature: () => void;
|
|
46
|
+
closeFeature: (destroy?: boolean) => void;
|
|
47
47
|
openFeature: () => void;
|
|
48
48
|
feedSubscription: GamificationBackground['feedSubscription'];
|
|
49
49
|
activeQuestionId: GamificationBackground['activeQuestionId'];
|
|
50
50
|
openedQuestionId: GamificationBackground['openedQuestionId'];
|
|
51
51
|
advertisement: GamificationBackground['advertisement'];
|
|
52
|
+
onboardingProcessed: WritableAtom<boolean>;
|
|
52
53
|
private notifications;
|
|
53
54
|
private transport;
|
|
54
55
|
/** gamification background class, handle subscriptions and notifications for closed overlay */
|
|
@@ -57,6 +58,7 @@ export declare class Gamification extends AbstractFeature<'games', PlainMessage<
|
|
|
57
58
|
private storage;
|
|
58
59
|
private submitAnswerTimeout;
|
|
59
60
|
private cancels;
|
|
61
|
+
private onQuestionActivate;
|
|
60
62
|
constructor(config: FeatureProps, source: FeatureSource, instance: StreamLayerContext);
|
|
61
63
|
get isInteractiveAllowed(): boolean;
|
|
62
64
|
checkInteractiveFlag: () => void;
|
package/lib/gamification.js
CHANGED
|
@@ -3,7 +3,6 @@ import { AbstractFeature, ApiStore, SingleStore, createSingleStore, eventBus, }
|
|
|
3
3
|
import { QuestionStatus, QuestionType, FeatureType, SilenceSetting, PickHistoryStatus, } from '@streamlayer/sdk-web-types';
|
|
4
4
|
import { NotificationType } from '@streamlayer/sdk-web-notifications';
|
|
5
5
|
import '@streamlayer/sdk-web-core/store';
|
|
6
|
-
import { onMount } from 'nanostores';
|
|
7
6
|
import * as queries from './queries';
|
|
8
7
|
import * as actions from './queries/actions';
|
|
9
8
|
import { GamificationStorage } from './storage';
|
|
@@ -12,7 +11,7 @@ import { deepLink } from './deepLink';
|
|
|
12
11
|
import { OnboardingStatus, onboarding } from './onboarding';
|
|
13
12
|
import { GamificationBackground, InteractiveAllowed } from './background';
|
|
14
13
|
import { ERROR } from './constants';
|
|
15
|
-
import { $questionByUser } from './queries';
|
|
14
|
+
import { $questionByUser, questionByUser } from './queries';
|
|
16
15
|
import { summary } from './userSummary';
|
|
17
16
|
import { friendSummary } from './friendSummary';
|
|
18
17
|
const InteractiveQuestionTypes = new Set([QuestionType.POLL, QuestionType.PREDICTION, QuestionType.TRIVIA]);
|
|
@@ -51,6 +50,7 @@ export class Gamification extends AbstractFeature {
|
|
|
51
50
|
activeQuestionId;
|
|
52
51
|
openedQuestionId;
|
|
53
52
|
advertisement;
|
|
53
|
+
onboardingProcessed;
|
|
54
54
|
notifications;
|
|
55
55
|
transport;
|
|
56
56
|
/** gamification background class, handle subscriptions and notifications for closed overlay */
|
|
@@ -59,10 +59,12 @@ export class Gamification extends AbstractFeature {
|
|
|
59
59
|
storage;
|
|
60
60
|
submitAnswerTimeout;
|
|
61
61
|
cancels = new Set();
|
|
62
|
+
onQuestionActivate;
|
|
62
63
|
constructor(config, source, instance) {
|
|
63
64
|
super(config, source);
|
|
64
65
|
this.background = new GamificationBackground(instance);
|
|
65
66
|
this.advertisement = this.background.advertisement;
|
|
67
|
+
this.onQuestionActivate = instance.onQuestionActivate;
|
|
66
68
|
this.feedSubscription = this.background.feedSubscription;
|
|
67
69
|
this.activeQuestionId = this.background.activeQuestionId;
|
|
68
70
|
this.openedQuestionId = this.background.openedQuestionId;
|
|
@@ -71,11 +73,12 @@ export class Gamification extends AbstractFeature {
|
|
|
71
73
|
this.friends = new ApiStore(queries.$friends(this.background.userId, instance.transport), 'gamification:friends');
|
|
72
74
|
this.currentUserId = this.background.userId;
|
|
73
75
|
this.openedUser = createSingleStore(undefined);
|
|
76
|
+
this.onboardingProcessed = createSingleStore(false);
|
|
74
77
|
this.leaderboardId = new SingleStore(createSingleStore(this.settings.getValue('pinnedLeaderboardId')), 'pinnedLeaderboardId').getStore();
|
|
75
78
|
this.onboardingStatus = onboarding(this, this.background, instance.transport, instance.notifications);
|
|
76
79
|
this.notifications = instance.notifications;
|
|
77
80
|
this.transport = instance.transport;
|
|
78
|
-
this.closeFeature = () => instance.sdk.closeFeature(
|
|
81
|
+
this.closeFeature = (destroy = true) => instance.sdk.closeFeature(destroy);
|
|
79
82
|
this.openFeature = () => instance.sdk.openFeature(FeatureType.GAMES);
|
|
80
83
|
this.openedQuestion = this.background.openedQuestion;
|
|
81
84
|
this.deepLink = deepLink(this.transport, this.background.slStreamId, instance.stores.providerStreamId.getStore(), this.background.userId);
|
|
@@ -94,12 +97,12 @@ export class Gamification extends AbstractFeature {
|
|
|
94
97
|
this.cancels.add(this.onboardingStatus.$store.listen(this.checkInteractiveFlag));
|
|
95
98
|
this.cancels.add(this.background.moderation.getStore().listen(this.checkInteractiveFlag));
|
|
96
99
|
this.cancels.add(this.settings.subscribe(this.checkInteractiveFlag));
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
this.cancels.add(this.onboardingStatus.$store.listen((status, prevStatus) => {
|
|
101
|
+
if (prevStatus === undefined || status !== OnboardingStatus.Unset) {
|
|
102
|
+
this.background.activeQuestionId.invalidate();
|
|
103
|
+
}
|
|
104
|
+
}));
|
|
105
|
+
this.background.activeQuestionId.listen(this.showInApp);
|
|
103
106
|
instance.sdk.onMount({ name: 'gamification', clear: true }, () => {
|
|
104
107
|
return () => {
|
|
105
108
|
for (const cancel of this.cancels) {
|
|
@@ -121,6 +124,12 @@ export class Gamification extends AbstractFeature {
|
|
|
121
124
|
this.background.interactiveAllowed.set(allowed ? InteractiveAllowed.ALLOWED : InteractiveAllowed.DISALLOWED);
|
|
122
125
|
};
|
|
123
126
|
connect = () => {
|
|
127
|
+
this.onboardingProcessed.subscribe((status) => {
|
|
128
|
+
console.log('onboardingProcessed status', status);
|
|
129
|
+
if (status) {
|
|
130
|
+
this.advertisement.connect();
|
|
131
|
+
}
|
|
132
|
+
});
|
|
124
133
|
this.cancels.add(this.background.feedSubscription.addListener('feed-subscription-prediction-close', async (response) => {
|
|
125
134
|
if (!this.isInteractiveAllowed) {
|
|
126
135
|
return;
|
|
@@ -145,7 +154,11 @@ export class Gamification extends AbstractFeature {
|
|
|
145
154
|
// order of operations is important here
|
|
146
155
|
const cancel = data.subscribe(() => { });
|
|
147
156
|
await data.get().promise;
|
|
148
|
-
|
|
157
|
+
// if question is not in the feed list, get extended question data from the server
|
|
158
|
+
let extendedQuestion = data.get().data;
|
|
159
|
+
if (!extendedQuestion) {
|
|
160
|
+
extendedQuestion = await questionByUser(id, this.transport);
|
|
161
|
+
}
|
|
149
162
|
cancel();
|
|
150
163
|
window.requestAnimationFrame(() => {
|
|
151
164
|
data.invalidate();
|
|
@@ -404,6 +417,16 @@ export class Gamification extends AbstractFeature {
|
|
|
404
417
|
return !!this.notifications.isViewed(questionId);
|
|
405
418
|
};
|
|
406
419
|
closeQuestion = (questionId) => {
|
|
420
|
+
if (questionId) {
|
|
421
|
+
this.onQuestionActivate({
|
|
422
|
+
stage: 'deactivate',
|
|
423
|
+
id: questionId,
|
|
424
|
+
isViewed: !!this.notifications.isViewed(this.background.getCurrentSessionId({
|
|
425
|
+
prefix: 'notification',
|
|
426
|
+
entity: questionId,
|
|
427
|
+
})),
|
|
428
|
+
});
|
|
429
|
+
}
|
|
407
430
|
return this.background.closeQuestion(questionId);
|
|
408
431
|
};
|
|
409
432
|
openUser = async (friendId) => {
|
package/lib/onboarding.js
CHANGED
|
@@ -28,6 +28,9 @@ const showOnboardingInApp = (service, background, notifications, storage) => {
|
|
|
28
28
|
type: NotificationType.ONBOARDING,
|
|
29
29
|
id: notificationId,
|
|
30
30
|
action: service.openFeature,
|
|
31
|
+
close: () => {
|
|
32
|
+
service.onboardingProcessed.set(true);
|
|
33
|
+
},
|
|
31
34
|
persistent: true,
|
|
32
35
|
autoHideDuration: 1000000,
|
|
33
36
|
data: {
|
|
@@ -103,6 +106,7 @@ export const onboarding = (service, background, transport, notifications) => {
|
|
|
103
106
|
const storage = new GamificationStorage();
|
|
104
107
|
const $store = createSingleStore(OnboardingStatus.Unset);
|
|
105
108
|
$store.subscribe((onboardingStatus) => {
|
|
109
|
+
console.log('onboardingStatus', onboardingStatus);
|
|
106
110
|
if (onboardingStatus === OnboardingStatus.Unset) {
|
|
107
111
|
return;
|
|
108
112
|
}
|
|
@@ -112,6 +116,9 @@ export const onboarding = (service, background, transport, notifications) => {
|
|
|
112
116
|
onboardingShowed = true;
|
|
113
117
|
}
|
|
114
118
|
}
|
|
119
|
+
else {
|
|
120
|
+
service.onboardingProcessed.set(true);
|
|
121
|
+
}
|
|
115
122
|
if (onboardingStatus === OnboardingStatus.Completed) {
|
|
116
123
|
background.activeQuestionId.invalidate(); // verified, it's necessary
|
|
117
124
|
}
|
package/lib/queries/index.d.ts
CHANGED
|
@@ -349,6 +349,7 @@ export declare const questionSubscription: (questionId: string, transport: Trans
|
|
|
349
349
|
}, 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>)>;
|
|
350
350
|
export declare const getQuestionByUser: (questionId: string, transport: Transport) => Promise<import("@streamlayer/sl-eslib/interactive/interactive.common_pb").ExtendedQuestion | undefined>;
|
|
351
351
|
export declare const getQuestionDetail: (questionId: string, transport: Transport) => Promise<import("@streamlayer/sl-eslib/interactive/interactive.common_pb").Question | undefined>;
|
|
352
|
+
export declare const questionByUser: ($questionId: string, transport: Transport) => Promise<import("@bufbuild/protobuf").PlainMessage<import("@streamlayer/sl-eslib/interactive/interactive.common_pb").ExtendedQuestion>>;
|
|
352
353
|
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>;
|
|
353
354
|
export declare const getPromotionDetail: (promoId: string, transport: Transport) => Promise<{
|
|
354
355
|
id: string;
|
package/lib/queries/index.js
CHANGED
|
@@ -14,6 +14,9 @@ export const $activeQuestion = (slStreamId, transport) => {
|
|
|
14
14
|
eventId: id,
|
|
15
15
|
},
|
|
16
16
|
});
|
|
17
|
+
if (res.data?.attributes?.question?.type === QuestionType.PROMOTION) {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
17
20
|
return res.data?.attributes;
|
|
18
21
|
},
|
|
19
22
|
dedupeTime: 1000 * 60 * 10, // 10 minutes
|
|
@@ -60,6 +63,13 @@ export const getQuestionDetail = async (questionId, transport) => {
|
|
|
60
63
|
});
|
|
61
64
|
return res.data?.attributes;
|
|
62
65
|
};
|
|
66
|
+
export const questionByUser = async ($questionId, transport) => {
|
|
67
|
+
const { client } = transport.createPromiseClient(Feed, { method: 'questionByUser', params: [$questionId] });
|
|
68
|
+
const res = await client.questionByUser({
|
|
69
|
+
questionId: $questionId,
|
|
70
|
+
});
|
|
71
|
+
return res.data?.attributes?.question;
|
|
72
|
+
};
|
|
63
73
|
export const $questionByUser = ($questionId, transport) => {
|
|
64
74
|
const { client, queryKey } = transport.createPromiseClient(Feed, { method: 'questionByUser', params: [$questionId] });
|
|
65
75
|
return transport.nanoquery.createFetcherStore(queryKey, {
|
package/package.json
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@streamlayer/feature-gamification",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"peerDependencies": {
|
|
5
5
|
"@bufbuild/protobuf": "^1.10.0",
|
|
6
6
|
"@fastify/deepmerge": "^2.0.0",
|
|
7
|
-
"@streamlayer/sl-eslib": "^5.
|
|
7
|
+
"@streamlayer/sl-eslib": "^5.130.0",
|
|
8
8
|
"nanostores": "^0.10.3",
|
|
9
|
-
"@streamlayer/sdk-web-
|
|
10
|
-
"@streamlayer/sdk-web-
|
|
11
|
-
"@streamlayer/sdk-web-
|
|
12
|
-
"@streamlayer/sdk-web-
|
|
13
|
-
"@streamlayer/sdk-web-notifications": "^1.
|
|
14
|
-
"@streamlayer/sdk-web-storage": "^1.0.
|
|
15
|
-
"@streamlayer/sdk-web-types": "^1.
|
|
9
|
+
"@streamlayer/sdk-web-core": "^1.5.0",
|
|
10
|
+
"@streamlayer/sdk-web-interfaces": "^1.2.0",
|
|
11
|
+
"@streamlayer/sdk-web-logger": "^1.0.21",
|
|
12
|
+
"@streamlayer/sdk-web-api": "^1.6.0",
|
|
13
|
+
"@streamlayer/sdk-web-notifications": "^1.2.0",
|
|
14
|
+
"@streamlayer/sdk-web-storage": "^1.0.21",
|
|
15
|
+
"@streamlayer/sdk-web-types": "^1.7.0"
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
18
18
|
"tslib": "^2.7.0"
|