@atlaskit/emoji 64.3.0 → 64.4.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/CHANGELOG.md +6 -0
- package/dist/cjs/components/common/RecordSelectionDefault.js +8 -2
- package/dist/cjs/components/common/UploadEmoji.js +8 -0
- package/dist/cjs/components/picker/EmojiPicker.js +13 -2
- package/dist/cjs/components/picker/EmojiPickerComponent.js +27 -2
- package/dist/cjs/components/typeahead/EmojiTypeAheadComponent.js +17 -0
- package/dist/cjs/components/uploader/EmojiUploadComponent.js +13 -0
- package/dist/cjs/index.js +6 -0
- package/dist/cjs/util/analytics/analytics.js +11 -41
- package/dist/cjs/util/analytics/index.js +16 -14
- package/dist/cjs/util/analytics/ufoExperiences.js +46 -0
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/components/common/RecordSelectionDefault.js +9 -2
- package/dist/es2019/components/common/UploadEmoji.js +4 -0
- package/dist/es2019/components/picker/EmojiPicker.js +9 -2
- package/dist/es2019/components/picker/EmojiPickerComponent.js +22 -3
- package/dist/es2019/components/typeahead/EmojiTypeAheadComponent.js +13 -1
- package/dist/es2019/components/uploader/EmojiUploadComponent.js +9 -0
- package/dist/es2019/index.js +2 -2
- package/dist/es2019/util/analytics/analytics.js +16 -37
- package/dist/es2019/util/analytics/index.js +2 -1
- package/dist/es2019/util/analytics/ufoExperiences.js +34 -0
- package/dist/es2019/version.json +1 -1
- package/dist/esm/components/common/RecordSelectionDefault.js +6 -3
- package/dist/esm/components/common/UploadEmoji.js +4 -0
- package/dist/esm/components/picker/EmojiPicker.js +8 -2
- package/dist/esm/components/picker/EmojiPickerComponent.js +23 -3
- package/dist/esm/components/typeahead/EmojiTypeAheadComponent.js +13 -1
- package/dist/esm/components/uploader/EmojiUploadComponent.js +10 -0
- package/dist/esm/index.js +2 -2
- package/dist/esm/util/analytics/analytics.js +8 -33
- package/dist/esm/util/analytics/index.js +2 -1
- package/dist/esm/util/analytics/ufoExperiences.js +34 -0
- package/dist/esm/version.json +1 -1
- package/dist/types/components/uploader/EmojiUploadComponent.d.ts +1 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/util/analytics/analytics.d.ts +3 -7
- package/dist/types/util/analytics/index.d.ts +3 -2
- package/dist/types/util/analytics/ufoExperiences.d.ts +12 -0
- package/package.json +1 -1
|
@@ -9,7 +9,7 @@ import { defaultListLimit } from '../../util/constants';
|
|
|
9
9
|
import { toEmojiId } from '../../util/type-helpers';
|
|
10
10
|
import { SearchSort } from '../../types';
|
|
11
11
|
import debug from '../../util/logger';
|
|
12
|
-
import { typeaheadCancelledEvent, typeaheadSelectedEvent, typeaheadRenderedEvent } from '../../util/analytics';
|
|
12
|
+
import { typeaheadCancelledEvent, typeaheadSelectedEvent, typeaheadRenderedEvent, ufoExperiences } from '../../util/analytics';
|
|
13
13
|
import { createRecordSelectionDefault } from '../common/RecordSelectionDefault';
|
|
14
14
|
import EmojiList from './EmojiTypeAheadList';
|
|
15
15
|
import { emojiTypeAhead } from './styles';
|
|
@@ -89,6 +89,11 @@ export default class EmojiTypeAheadComponent extends PureComponent {
|
|
|
89
89
|
const wasVisible = this.state.visible;
|
|
90
90
|
const visible = emojis.length > 0;
|
|
91
91
|
this.fireAnalyticsEvent(typeaheadRenderedEvent(Date.now() - this.renderStartTime, query, emojis));
|
|
92
|
+
ufoExperiences['emoji-searched'].success({
|
|
93
|
+
metadata: {
|
|
94
|
+
emojisLength: emojis.length
|
|
95
|
+
}
|
|
96
|
+
});
|
|
92
97
|
debug('emoji-typeahead.applyPropChanges', emojis.length, wasVisible, visible);
|
|
93
98
|
this.setState({
|
|
94
99
|
emojis: emojis,
|
|
@@ -175,6 +180,8 @@ export default class EmojiTypeAheadComponent extends PureComponent {
|
|
|
175
180
|
this.fireAnalyticsEvent(typeaheadCancelledEvent(Date.now() - this.openTime, query, emojis));
|
|
176
181
|
}
|
|
177
182
|
|
|
183
|
+
ufoExperiences['emoji-searched'].abort();
|
|
184
|
+
ufoExperiences['emoji-selection-recorded'].abort();
|
|
178
185
|
this.sessionId = uuid();
|
|
179
186
|
this.selected = false;
|
|
180
187
|
}
|
|
@@ -218,6 +225,11 @@ export default class EmojiTypeAheadComponent extends PureComponent {
|
|
|
218
225
|
options.sort = SearchSort.UsageFrequency;
|
|
219
226
|
}
|
|
220
227
|
|
|
228
|
+
ufoExperiences['emoji-searched'].start();
|
|
229
|
+
ufoExperiences['emoji-searched'].addMetadata({
|
|
230
|
+
queryLength: (query === null || query === void 0 ? void 0 : query.length) || 0,
|
|
231
|
+
source: 'typeahead'
|
|
232
|
+
});
|
|
221
233
|
this.renderStartTime = Date.now();
|
|
222
234
|
emojiProvider.filter(query, options);
|
|
223
235
|
}
|
|
@@ -9,6 +9,7 @@ import EmojiUploadPickerWithIntl from '../common/EmojiUploadPicker';
|
|
|
9
9
|
import { uploadEmoji } from '../common/UploadEmoji';
|
|
10
10
|
import { createAndFireEventInElementsChannel, selectedFileEvent, uploadCancelButton, uploadConfirmButton } from '../../util/analytics';
|
|
11
11
|
import { emojiUploadFooter, emojiUploadWidget } from './styles';
|
|
12
|
+
import { ufoExperiences } from '../../util/analytics/ufoExperiences';
|
|
12
13
|
export default class EmojiUploadComponent extends PureComponent {
|
|
13
14
|
constructor(props) {
|
|
14
15
|
super(props);
|
|
@@ -17,6 +18,10 @@ export default class EmojiUploadComponent extends PureComponent {
|
|
|
17
18
|
const {
|
|
18
19
|
emojiProvider
|
|
19
20
|
} = this.props;
|
|
21
|
+
ufoExperiences['emoji-uploaded'].start();
|
|
22
|
+
ufoExperiences['emoji-uploaded'].addMetadata({
|
|
23
|
+
retry
|
|
24
|
+
});
|
|
20
25
|
this.fireAnalytics(uploadConfirmButton({
|
|
21
26
|
retry
|
|
22
27
|
}));
|
|
@@ -78,6 +83,10 @@ export default class EmojiUploadComponent extends PureComponent {
|
|
|
78
83
|
this.state = {};
|
|
79
84
|
}
|
|
80
85
|
|
|
86
|
+
componentWillUnmount() {
|
|
87
|
+
ufoExperiences['emoji-uploaded'].abort();
|
|
88
|
+
}
|
|
89
|
+
|
|
81
90
|
render() {
|
|
82
91
|
const {
|
|
83
92
|
uploadErrorMessage
|
package/dist/es2019/index.js
CHANGED
|
@@ -13,12 +13,12 @@ import EmojiRepository from './api/EmojiRepository';
|
|
|
13
13
|
import EmojiLoader from './api/EmojiLoader';
|
|
14
14
|
import { denormaliseEmojiServiceResponse } from './api/EmojiUtils';
|
|
15
15
|
import { toEmojiId, toOptionalEmojiId } from './util/type-helpers';
|
|
16
|
-
import { recordSelectionFailedSli, recordSelectionSucceededSli } from './util/analytics';
|
|
16
|
+
import { recordSelectionFailedSli, recordSelectionSucceededSli, ufoExperiences } from './util/analytics';
|
|
17
17
|
import { customCategory, defaultEmojiHeight, emojiPickerWidth, emojiPickerHeight } from './util/constants';
|
|
18
18
|
import { UsageFrequencyTracker } from './api/internal/UsageFrequencyTracker';
|
|
19
19
|
export { // Classes
|
|
20
20
|
AbstractResource, Emoji, EmojiPlaceholder, EmojiLoader, EmojiPicker, EmojiUploader, EmojiResource, EmojiRepository, EmojiTypeAhead, ResourcedEmoji, // functions
|
|
21
|
-
denormaliseEmojiServiceResponse, toEmojiId, toOptionalEmojiId, recordSelectionFailedSli, recordSelectionSucceededSli, // Constants
|
|
21
|
+
denormaliseEmojiServiceResponse, toEmojiId, toOptionalEmojiId, recordSelectionFailedSli, recordSelectionSucceededSli, ufoExperiences, // Constants
|
|
22
22
|
emojiPickerWidth, emojiPickerHeight, defaultEmojiHeight, customCategory, UsageFrequencyTracker, EmojiTypeAheadItem };
|
|
23
23
|
export { // Enums
|
|
24
24
|
SearchSort } from './types';
|
|
@@ -1,32 +1,5 @@
|
|
|
1
1
|
import { createAndFireEvent } from '@atlaskit/analytics-next';
|
|
2
2
|
import { name as packageName, version as packageVersion } from '../../version.json';
|
|
3
|
-
import { ExperiencePerformanceTypes, ExperienceTypes, ConcurrentExperience } from '@atlaskit/ufo';
|
|
4
|
-
import { withSampling } from './samplingUfo';
|
|
5
|
-
|
|
6
|
-
const createRenderExperience = componentName => {
|
|
7
|
-
return {
|
|
8
|
-
platform: {
|
|
9
|
-
component: componentName
|
|
10
|
-
},
|
|
11
|
-
type: ExperienceTypes.Load,
|
|
12
|
-
performanceType: ExperiencePerformanceTypes.PageSegmentLoad
|
|
13
|
-
};
|
|
14
|
-
}; // const createInlineExperience = (componentName: string) => {
|
|
15
|
-
// return {
|
|
16
|
-
// platform: { component: componentName },
|
|
17
|
-
// type: ExperienceTypes.Experience,
|
|
18
|
-
// performanceType: ExperiencePerformanceTypes.InlineResult,
|
|
19
|
-
// };
|
|
20
|
-
// };
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
export const ufoExperiences = {
|
|
24
|
-
'emoji-rendered': new ConcurrentExperience('emoji-rendered', createRenderExperience('emoji')),
|
|
25
|
-
'emoji-resource-fetched': new ConcurrentExperience('emoji-resource-fetched', createRenderExperience('emoji-provider'))
|
|
26
|
-
};
|
|
27
|
-
export const sampledUfoRenderedEmoji = emojiId => {
|
|
28
|
-
return withSampling(ufoExperiences['emoji-rendered'].getInstance(emojiId.id || emojiId.shortName));
|
|
29
|
-
};
|
|
30
3
|
export const createAndFireEventInElementsChannel = createAndFireEvent('fabric-elements');
|
|
31
4
|
|
|
32
5
|
const createEvent = (eventType, action, actionSubject, actionSubjectId, attributes = {}) => ({
|
|
@@ -41,12 +14,16 @@ const createEvent = (eventType, action, actionSubject, actionSubjectId, attribut
|
|
|
41
14
|
}
|
|
42
15
|
});
|
|
43
16
|
|
|
44
|
-
export const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
17
|
+
export const recordSucceeded = source => {
|
|
18
|
+
return createEvent('operational', 'succeeded', 'recordEmojiSelection', undefined, {
|
|
19
|
+
source
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
export const recordFailed = source => {
|
|
23
|
+
return createEvent('operational', 'failed', 'recordEmojiSelection', undefined, {
|
|
24
|
+
source
|
|
25
|
+
});
|
|
26
|
+
};
|
|
50
27
|
|
|
51
28
|
const emojiPickerEvent = (action, attributes = {}, actionSubjectId) => createEvent('ui', action, 'emojiPicker', actionSubjectId, attributes);
|
|
52
29
|
|
|
@@ -146,15 +123,17 @@ export const typeaheadSelectedEvent = (pressed, duration, emoji, emojiList, quer
|
|
|
146
123
|
export const typeaheadRenderedEvent = (duration, query, emojiList) => createEvent('operational', 'rendered', 'emojiTypeahead', undefined, {
|
|
147
124
|
duration,
|
|
148
125
|
...extractCommonAttributes(query, emojiList)
|
|
149
|
-
});
|
|
126
|
+
}); // it's used in editor typeahead to fire success record analytics
|
|
127
|
+
|
|
150
128
|
export const recordSelectionSucceededSli = options => () => {
|
|
151
129
|
if (options && options.createAnalyticsEvent) {
|
|
152
|
-
createAndFireEvent('editor')(
|
|
130
|
+
createAndFireEvent('editor')(recordSucceeded('typeahead'))(options.createAnalyticsEvent);
|
|
153
131
|
}
|
|
154
|
-
};
|
|
132
|
+
}; // it's used in editor typeahead to fire failure record analytics
|
|
133
|
+
|
|
155
134
|
export const recordSelectionFailedSli = options => err => {
|
|
156
135
|
if (options && options.createAnalyticsEvent) {
|
|
157
|
-
createAndFireEvent('editor')(
|
|
136
|
+
createAndFireEvent('editor')(recordFailed('typeahead'))(options.createAnalyticsEvent);
|
|
158
137
|
}
|
|
159
138
|
|
|
160
139
|
return Promise.reject(err);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { ufoExperiencesSampled, clearSampled, isExperienceSampled, withSampling } from './samplingUfo';
|
|
2
|
-
export { categoryClickedEvent, createAndFireEventInElementsChannel, closedPickerEvent, deleteBeginEvent, deleteCancelEvent, deleteConfirmEvent,
|
|
2
|
+
export { categoryClickedEvent, createAndFireEventInElementsChannel, closedPickerEvent, deleteBeginEvent, deleteCancelEvent, deleteConfirmEvent, recordFailed, recordSucceeded, openedPickerEvent, pickerClickedEvent, pickerSearchedEvent, recordSelectionFailedSli, recordSelectionSucceededSli, selectedFileEvent, toneSelectedEvent, toneSelectorClosedEvent, toneSelectorOpenedEvent, typeaheadCancelledEvent, typeaheadRenderedEvent, typeaheadSelectedEvent, uploadBeginButton, uploadCancelButton, uploadConfirmButton, uploadFailedEvent, uploadSucceededEvent } from './analytics';
|
|
3
|
+
export { sampledUfoRenderedEmoji, ufoExperiences } from './ufoExperiences';
|
|
3
4
|
export { useSampledUFOComponentExperience } from './useSampledUFOComponentExperience';
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ExperiencePerformanceTypes, ExperienceTypes, ConcurrentExperience, UFOExperience } from '@atlaskit/ufo';
|
|
2
|
+
import { withSampling } from './samplingUfo'; // TODO: clean up as not needed
|
|
3
|
+
|
|
4
|
+
const createRenderExperience = componentName => {
|
|
5
|
+
return {
|
|
6
|
+
platform: {
|
|
7
|
+
component: componentName
|
|
8
|
+
},
|
|
9
|
+
type: ExperienceTypes.Load,
|
|
10
|
+
performanceType: ExperiencePerformanceTypes.PageSegmentLoad
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const createInlineExperience = componentName => {
|
|
15
|
+
return {
|
|
16
|
+
platform: {
|
|
17
|
+
component: componentName
|
|
18
|
+
},
|
|
19
|
+
type: ExperienceTypes.Experience,
|
|
20
|
+
performanceType: ExperiencePerformanceTypes.InlineResult
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const ufoExperiences = {
|
|
25
|
+
'emoji-rendered': new ConcurrentExperience('emoji-rendered', createRenderExperience('emoji')),
|
|
26
|
+
'emoji-resource-fetched': new ConcurrentExperience('emoji-resource-fetched', createRenderExperience('emoji-provider')),
|
|
27
|
+
'emoji-picker-opened': new UFOExperience('emoji-picker-opened', createRenderExperience('emoji-picker')),
|
|
28
|
+
'emoji-selection-recorded': new UFOExperience('emoji-selection-recorded', createInlineExperience('emoji-picker')),
|
|
29
|
+
'emoji-uploaded': new UFOExperience('emoji-uploaded', createInlineExperience('emoji-picker')),
|
|
30
|
+
'emoji-searched': new UFOExperience('emoji-searched', createInlineExperience('emoji-picker'))
|
|
31
|
+
};
|
|
32
|
+
export const sampledUfoRenderedEmoji = emojiId => {
|
|
33
|
+
return withSampling(ufoExperiences['emoji-rendered'].getInstance(emojiId.id || emojiId.shortName));
|
|
34
|
+
};
|
package/dist/es2019/version.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { recordFailed, recordSucceeded, ufoExperiences } from '../../util/analytics';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* A function that will wrap any configured Emoji 'onSelection' function to ensure recordSelection is always
|
|
@@ -12,10 +12,13 @@ export var createRecordSelectionDefault = function createRecordSelectionDefault(
|
|
|
12
12
|
return function (emojiId, emoji, event) {
|
|
13
13
|
try {
|
|
14
14
|
if (provider.recordSelection && emoji) {
|
|
15
|
+
ufoExperiences['emoji-selection-recorded'].start();
|
|
15
16
|
provider.recordSelection(emoji).then(function () {
|
|
16
|
-
|
|
17
|
+
fireAnalytics && fireAnalytics(recordSucceeded);
|
|
18
|
+
ufoExperiences['emoji-selection-recorded'].success();
|
|
17
19
|
}).catch(function () {
|
|
18
|
-
|
|
20
|
+
fireAnalytics && fireAnalytics(recordFailed);
|
|
21
|
+
ufoExperiences['emoji-selection-recorded'].failure();
|
|
19
22
|
});
|
|
20
23
|
}
|
|
21
24
|
} finally {
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import { supportsUploadFeature } from '../../api/EmojiResource';
|
|
2
2
|
import { uploadFailedEvent, uploadSucceededEvent } from '../../util/analytics';
|
|
3
3
|
import { messages } from '../i18n';
|
|
4
|
+
import { ufoExperiences } from '../../util/analytics/ufoExperiences';
|
|
4
5
|
export var uploadEmoji = function uploadEmoji(upload, emojiProvider, errorSetter, onSuccess, fireAnalytics) {
|
|
5
6
|
var startTime = Date.now();
|
|
6
7
|
errorSetter(undefined);
|
|
7
8
|
|
|
8
9
|
if (supportsUploadFeature(emojiProvider)) {
|
|
10
|
+
ufoExperiences['emoji-uploaded'].start();
|
|
9
11
|
emojiProvider.uploadCustomEmoji(upload).then(function (emojiDescription) {
|
|
10
12
|
fireAnalytics(uploadSucceededEvent({
|
|
11
13
|
duration: Date.now() - startTime
|
|
12
14
|
}));
|
|
13
15
|
onSuccess(emojiDescription);
|
|
16
|
+
ufoExperiences['emoji-uploaded'].success();
|
|
14
17
|
}).catch(function (err) {
|
|
15
18
|
errorSetter(messages.emojiUploadFailed); // eslint-disable-next-line no-console
|
|
16
19
|
|
|
@@ -19,6 +22,7 @@ export var uploadEmoji = function uploadEmoji(upload, emojiProvider, errorSetter
|
|
|
19
22
|
duration: Date.now() - startTime,
|
|
20
23
|
reason: messages.emojiUploadFailed.defaultMessage
|
|
21
24
|
}));
|
|
25
|
+
ufoExperiences['emoji-uploaded'].failure();
|
|
22
26
|
});
|
|
23
27
|
}
|
|
24
28
|
};
|
|
@@ -16,9 +16,11 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
|
|
|
16
16
|
/** @jsx jsx */
|
|
17
17
|
import { jsx } from '@emotion/core';
|
|
18
18
|
import { withAnalyticsEvents } from '@atlaskit/analytics-next';
|
|
19
|
+
import { ufoExperiences } from '../../util/analytics';
|
|
19
20
|
import LoadingEmojiComponent from '../common/LoadingEmojiComponent';
|
|
20
21
|
import { LoadingItem } from './EmojiPickerVirtualItems';
|
|
21
22
|
import { emojiPicker } from './styles';
|
|
23
|
+
import { UfoErrorBoundary } from '../common/UfoErrorBoundary';
|
|
22
24
|
|
|
23
25
|
var emojiPickerModuleLoader = function emojiPickerModuleLoader() {
|
|
24
26
|
return import(
|
|
@@ -50,6 +52,7 @@ export var EmojiPickerInternal = /*#__PURE__*/function (_LoadingEmojiComponen) {
|
|
|
50
52
|
asyncLoadedComponent: EmojiPickerInternal.AsyncLoadedComponent
|
|
51
53
|
});
|
|
52
54
|
|
|
55
|
+
ufoExperiences['emoji-picker-opened'].start();
|
|
53
56
|
return _this;
|
|
54
57
|
}
|
|
55
58
|
|
|
@@ -77,6 +80,7 @@ export var EmojiPickerInternal = /*#__PURE__*/function (_LoadingEmojiComponen) {
|
|
|
77
80
|
}
|
|
78
81
|
};
|
|
79
82
|
|
|
83
|
+
ufoExperiences['emoji-picker-opened'].markFMP();
|
|
80
84
|
return jsx("div", {
|
|
81
85
|
css: emojiPicker,
|
|
82
86
|
ref: handlePickerRef
|
|
@@ -89,9 +93,11 @@ export var EmojiPickerInternal = /*#__PURE__*/function (_LoadingEmojiComponen) {
|
|
|
89
93
|
emojiProvider = _this$props.emojiProvider,
|
|
90
94
|
otherProps = _objectWithoutProperties(_this$props, _excluded);
|
|
91
95
|
|
|
92
|
-
return jsx(
|
|
96
|
+
return jsx(UfoErrorBoundary, {
|
|
97
|
+
experiences: [ufoExperiences['emoji-picker-opened']]
|
|
98
|
+
}, jsx(EmojiPickerComponent, _extends({
|
|
93
99
|
emojiProvider: loadedEmojiProvider
|
|
94
|
-
}, otherProps));
|
|
100
|
+
}, otherProps)));
|
|
95
101
|
}
|
|
96
102
|
}]);
|
|
97
103
|
|
|
@@ -33,7 +33,7 @@ import { createRecordSelectionDefault } from '../common/RecordSelectionDefault';
|
|
|
33
33
|
import CategorySelector from './CategorySelector';
|
|
34
34
|
import EmojiPickerFooter from './EmojiPickerFooter';
|
|
35
35
|
import EmojiPickerList from './EmojiPickerList';
|
|
36
|
-
import { createAndFireEventInElementsChannel, categoryClickedEvent, closedPickerEvent, deleteBeginEvent, deleteCancelEvent, deleteConfirmEvent, openedPickerEvent, pickerClickedEvent, pickerSearchedEvent, selectedFileEvent, uploadBeginButton, uploadCancelButton, uploadConfirmButton, toneSelectorClosedEvent } from '../../util/analytics';
|
|
36
|
+
import { createAndFireEventInElementsChannel, categoryClickedEvent, closedPickerEvent, deleteBeginEvent, deleteCancelEvent, deleteConfirmEvent, openedPickerEvent, pickerClickedEvent, pickerSearchedEvent, selectedFileEvent, uploadBeginButton, uploadCancelButton, uploadConfirmButton, toneSelectorClosedEvent, ufoExperiences } from '../../util/analytics';
|
|
37
37
|
import { emojiPicker } from './styles';
|
|
38
38
|
var FREQUENTLY_USED_MAX = 16;
|
|
39
39
|
|
|
@@ -125,9 +125,19 @@ var EmojiPickerComponent = /*#__PURE__*/function (_PureComponent) {
|
|
|
125
125
|
});
|
|
126
126
|
|
|
127
127
|
_defineProperty(_assertThisInitialized(_this), "onSearch", function (query) {
|
|
128
|
-
|
|
128
|
+
var options = {
|
|
129
129
|
skinTone: _this.state.selectedTone
|
|
130
|
-
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
if (query !== _this.state.query) {
|
|
133
|
+
ufoExperiences['emoji-searched'].start();
|
|
134
|
+
ufoExperiences['emoji-searched'].addMetadata({
|
|
135
|
+
queryLength: query.length,
|
|
136
|
+
source: 'picker'
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
_this.updateEmojis(query, options);
|
|
131
141
|
});
|
|
132
142
|
|
|
133
143
|
_defineProperty(_assertThisInitialized(_this), "onSearchResult", function (searchResults) {
|
|
@@ -141,6 +151,12 @@ var EmojiPickerComponent = /*#__PURE__*/function (_PureComponent) {
|
|
|
141
151
|
queryLength: searchQuery.length,
|
|
142
152
|
numMatches: emojiToRender.length
|
|
143
153
|
}));
|
|
154
|
+
|
|
155
|
+
ufoExperiences['emoji-searched'].success({
|
|
156
|
+
metadata: {
|
|
157
|
+
emojisLength: emojiToRender.length
|
|
158
|
+
}
|
|
159
|
+
});
|
|
144
160
|
}
|
|
145
161
|
|
|
146
162
|
_this.setStateAfterEmojiChange(searchQuery, emojiToRender, searchResults.emojis, frequentlyUsedEmoji);
|
|
@@ -381,6 +397,7 @@ var EmojiPickerComponent = /*#__PURE__*/function (_PureComponent) {
|
|
|
381
397
|
value: function componentDidMount() {
|
|
382
398
|
var _this2 = this;
|
|
383
399
|
|
|
400
|
+
ufoExperiences['emoji-picker-opened'].success();
|
|
384
401
|
var _this$props = this.props,
|
|
385
402
|
emojiProvider = _this$props.emojiProvider,
|
|
386
403
|
hideToneSelector = _this$props.hideToneSelector;
|
|
@@ -415,6 +432,9 @@ var EmojiPickerComponent = /*#__PURE__*/function (_PureComponent) {
|
|
|
415
432
|
this.fireAnalytics(closedPickerEvent({
|
|
416
433
|
duration: this.calculateElapsedTime()
|
|
417
434
|
}));
|
|
435
|
+
ufoExperiences['emoji-picker-opened'].abort();
|
|
436
|
+
ufoExperiences['emoji-searched'].abort();
|
|
437
|
+
ufoExperiences['emoji-selection-recorded'].abort();
|
|
418
438
|
}
|
|
419
439
|
}, {
|
|
420
440
|
key: "UNSAFE_componentWillReceiveProps",
|
|
@@ -25,7 +25,7 @@ import { defaultListLimit } from '../../util/constants';
|
|
|
25
25
|
import { toEmojiId } from '../../util/type-helpers';
|
|
26
26
|
import { SearchSort } from '../../types';
|
|
27
27
|
import debug from '../../util/logger';
|
|
28
|
-
import { typeaheadCancelledEvent, typeaheadSelectedEvent, typeaheadRenderedEvent } from '../../util/analytics';
|
|
28
|
+
import { typeaheadCancelledEvent, typeaheadSelectedEvent, typeaheadRenderedEvent, ufoExperiences } from '../../util/analytics';
|
|
29
29
|
import { createRecordSelectionDefault } from '../common/RecordSelectionDefault';
|
|
30
30
|
import EmojiList from './EmojiTypeAheadList';
|
|
31
31
|
import { emojiTypeAhead } from './styles';
|
|
@@ -124,6 +124,11 @@ var EmojiTypeAheadComponent = /*#__PURE__*/function (_PureComponent) {
|
|
|
124
124
|
|
|
125
125
|
_this.fireAnalyticsEvent(typeaheadRenderedEvent(Date.now() - _this.renderStartTime, query, emojis));
|
|
126
126
|
|
|
127
|
+
ufoExperiences['emoji-searched'].success({
|
|
128
|
+
metadata: {
|
|
129
|
+
emojisLength: emojis.length
|
|
130
|
+
}
|
|
131
|
+
});
|
|
127
132
|
debug('emoji-typeahead.applyPropChanges', emojis.length, wasVisible, visible);
|
|
128
133
|
|
|
129
134
|
_this.setState({
|
|
@@ -215,6 +220,8 @@ var EmojiTypeAheadComponent = /*#__PURE__*/function (_PureComponent) {
|
|
|
215
220
|
this.fireAnalyticsEvent(typeaheadCancelledEvent(Date.now() - this.openTime, query, emojis));
|
|
216
221
|
}
|
|
217
222
|
|
|
223
|
+
ufoExperiences['emoji-searched'].abort();
|
|
224
|
+
ufoExperiences['emoji-selection-recorded'].abort();
|
|
218
225
|
this.sessionId = uuid();
|
|
219
226
|
this.selected = false;
|
|
220
227
|
}
|
|
@@ -260,6 +267,11 @@ var EmojiTypeAheadComponent = /*#__PURE__*/function (_PureComponent) {
|
|
|
260
267
|
options.sort = SearchSort.UsageFrequency;
|
|
261
268
|
}
|
|
262
269
|
|
|
270
|
+
ufoExperiences['emoji-searched'].start();
|
|
271
|
+
ufoExperiences['emoji-searched'].addMetadata({
|
|
272
|
+
queryLength: (query === null || query === void 0 ? void 0 : query.length) || 0,
|
|
273
|
+
source: 'typeahead'
|
|
274
|
+
});
|
|
263
275
|
this.renderStartTime = Date.now();
|
|
264
276
|
emojiProvider.filter(query, options);
|
|
265
277
|
}
|
|
@@ -19,6 +19,7 @@ import EmojiUploadPickerWithIntl from '../common/EmojiUploadPicker';
|
|
|
19
19
|
import { uploadEmoji } from '../common/UploadEmoji';
|
|
20
20
|
import { createAndFireEventInElementsChannel, selectedFileEvent, uploadCancelButton, uploadConfirmButton } from '../../util/analytics';
|
|
21
21
|
import { emojiUploadFooter, emojiUploadWidget } from './styles';
|
|
22
|
+
import { ufoExperiences } from '../../util/analytics/ufoExperiences';
|
|
22
23
|
|
|
23
24
|
var EmojiUploadComponent = /*#__PURE__*/function (_PureComponent) {
|
|
24
25
|
_inherits(EmojiUploadComponent, _PureComponent);
|
|
@@ -34,6 +35,10 @@ var EmojiUploadComponent = /*#__PURE__*/function (_PureComponent) {
|
|
|
34
35
|
|
|
35
36
|
_defineProperty(_assertThisInitialized(_this), "onUploadEmoji", function (upload, retry) {
|
|
36
37
|
var emojiProvider = _this.props.emojiProvider;
|
|
38
|
+
ufoExperiences['emoji-uploaded'].start();
|
|
39
|
+
ufoExperiences['emoji-uploaded'].addMetadata({
|
|
40
|
+
retry: retry
|
|
41
|
+
});
|
|
37
42
|
|
|
38
43
|
_this.fireAnalytics(uploadConfirmButton({
|
|
39
44
|
retry: retry
|
|
@@ -95,6 +100,11 @@ var EmojiUploadComponent = /*#__PURE__*/function (_PureComponent) {
|
|
|
95
100
|
}
|
|
96
101
|
|
|
97
102
|
_createClass(EmojiUploadComponent, [{
|
|
103
|
+
key: "componentWillUnmount",
|
|
104
|
+
value: function componentWillUnmount() {
|
|
105
|
+
ufoExperiences['emoji-uploaded'].abort();
|
|
106
|
+
}
|
|
107
|
+
}, {
|
|
98
108
|
key: "render",
|
|
99
109
|
value: function render() {
|
|
100
110
|
var uploadErrorMessage = this.state.uploadErrorMessage;
|
package/dist/esm/index.js
CHANGED
|
@@ -13,12 +13,12 @@ import EmojiRepository from './api/EmojiRepository';
|
|
|
13
13
|
import EmojiLoader from './api/EmojiLoader';
|
|
14
14
|
import { denormaliseEmojiServiceResponse } from './api/EmojiUtils';
|
|
15
15
|
import { toEmojiId, toOptionalEmojiId } from './util/type-helpers';
|
|
16
|
-
import { recordSelectionFailedSli, recordSelectionSucceededSli } from './util/analytics';
|
|
16
|
+
import { recordSelectionFailedSli, recordSelectionSucceededSli, ufoExperiences } from './util/analytics';
|
|
17
17
|
import { customCategory, defaultEmojiHeight, emojiPickerWidth, emojiPickerHeight } from './util/constants';
|
|
18
18
|
import { UsageFrequencyTracker } from './api/internal/UsageFrequencyTracker';
|
|
19
19
|
export { // Classes
|
|
20
20
|
AbstractResource, Emoji, EmojiPlaceholder, EmojiLoader, EmojiPicker, EmojiUploader, EmojiResource, EmojiRepository, EmojiTypeAhead, ResourcedEmoji, // functions
|
|
21
|
-
denormaliseEmojiServiceResponse, toEmojiId, toOptionalEmojiId, recordSelectionFailedSli, recordSelectionSucceededSli, // Constants
|
|
21
|
+
denormaliseEmojiServiceResponse, toEmojiId, toOptionalEmojiId, recordSelectionFailedSli, recordSelectionSucceededSli, ufoExperiences, // Constants
|
|
22
22
|
emojiPickerWidth, emojiPickerHeight, defaultEmojiHeight, customCategory, UsageFrequencyTracker, EmojiTypeAheadItem };
|
|
23
23
|
export { // Enums
|
|
24
24
|
SearchSort } from './types';
|
|
@@ -12,33 +12,6 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
|
|
|
12
12
|
|
|
13
13
|
import { createAndFireEvent } from '@atlaskit/analytics-next';
|
|
14
14
|
import { name as packageName, version as packageVersion } from '../../version.json';
|
|
15
|
-
import { ExperiencePerformanceTypes, ExperienceTypes, ConcurrentExperience } from '@atlaskit/ufo';
|
|
16
|
-
import { withSampling } from './samplingUfo';
|
|
17
|
-
|
|
18
|
-
var createRenderExperience = function createRenderExperience(componentName) {
|
|
19
|
-
return {
|
|
20
|
-
platform: {
|
|
21
|
-
component: componentName
|
|
22
|
-
},
|
|
23
|
-
type: ExperienceTypes.Load,
|
|
24
|
-
performanceType: ExperiencePerformanceTypes.PageSegmentLoad
|
|
25
|
-
};
|
|
26
|
-
}; // const createInlineExperience = (componentName: string) => {
|
|
27
|
-
// return {
|
|
28
|
-
// platform: { component: componentName },
|
|
29
|
-
// type: ExperienceTypes.Experience,
|
|
30
|
-
// performanceType: ExperiencePerformanceTypes.InlineResult,
|
|
31
|
-
// };
|
|
32
|
-
// };
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
export var ufoExperiences = {
|
|
36
|
-
'emoji-rendered': new ConcurrentExperience('emoji-rendered', createRenderExperience('emoji')),
|
|
37
|
-
'emoji-resource-fetched': new ConcurrentExperience('emoji-resource-fetched', createRenderExperience('emoji-provider'))
|
|
38
|
-
};
|
|
39
|
-
export var sampledUfoRenderedEmoji = function sampledUfoRenderedEmoji(emojiId) {
|
|
40
|
-
return withSampling(ufoExperiences['emoji-rendered'].getInstance(emojiId.id || emojiId.shortName));
|
|
41
|
-
};
|
|
42
15
|
export var createAndFireEventInElementsChannel = createAndFireEvent('fabric-elements');
|
|
43
16
|
|
|
44
17
|
var createEvent = function createEvent(eventType, action, actionSubject, actionSubjectId) {
|
|
@@ -55,12 +28,12 @@ var createEvent = function createEvent(eventType, action, actionSubject, actionS
|
|
|
55
28
|
};
|
|
56
29
|
};
|
|
57
30
|
|
|
58
|
-
export var
|
|
31
|
+
export var recordSucceeded = function recordSucceeded(source) {
|
|
59
32
|
return createEvent('operational', 'succeeded', 'recordEmojiSelection', undefined, {
|
|
60
33
|
source: source
|
|
61
34
|
});
|
|
62
35
|
};
|
|
63
|
-
export var
|
|
36
|
+
export var recordFailed = function recordFailed(source) {
|
|
64
37
|
return createEvent('operational', 'failed', 'recordEmojiSelection', undefined, {
|
|
65
38
|
source: source
|
|
66
39
|
});
|
|
@@ -222,18 +195,20 @@ export var typeaheadRenderedEvent = function typeaheadRenderedEvent(duration, qu
|
|
|
222
195
|
return createEvent('operational', 'rendered', 'emojiTypeahead', undefined, _objectSpread({
|
|
223
196
|
duration: duration
|
|
224
197
|
}, extractCommonAttributes(query, emojiList)));
|
|
225
|
-
};
|
|
198
|
+
}; // it's used in editor typeahead to fire success record analytics
|
|
199
|
+
|
|
226
200
|
export var recordSelectionSucceededSli = function recordSelectionSucceededSli(options) {
|
|
227
201
|
return function () {
|
|
228
202
|
if (options && options.createAnalyticsEvent) {
|
|
229
|
-
createAndFireEvent('editor')(
|
|
203
|
+
createAndFireEvent('editor')(recordSucceeded('typeahead'))(options.createAnalyticsEvent);
|
|
230
204
|
}
|
|
231
205
|
};
|
|
232
|
-
};
|
|
206
|
+
}; // it's used in editor typeahead to fire failure record analytics
|
|
207
|
+
|
|
233
208
|
export var recordSelectionFailedSli = function recordSelectionFailedSli(options) {
|
|
234
209
|
return function (err) {
|
|
235
210
|
if (options && options.createAnalyticsEvent) {
|
|
236
|
-
createAndFireEvent('editor')(
|
|
211
|
+
createAndFireEvent('editor')(recordFailed('typeahead'))(options.createAnalyticsEvent);
|
|
237
212
|
}
|
|
238
213
|
|
|
239
214
|
return Promise.reject(err);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { ufoExperiencesSampled, clearSampled, isExperienceSampled, withSampling } from './samplingUfo';
|
|
2
|
-
export { categoryClickedEvent, createAndFireEventInElementsChannel, closedPickerEvent, deleteBeginEvent, deleteCancelEvent, deleteConfirmEvent,
|
|
2
|
+
export { categoryClickedEvent, createAndFireEventInElementsChannel, closedPickerEvent, deleteBeginEvent, deleteCancelEvent, deleteConfirmEvent, recordFailed, recordSucceeded, openedPickerEvent, pickerClickedEvent, pickerSearchedEvent, recordSelectionFailedSli, recordSelectionSucceededSli, selectedFileEvent, toneSelectedEvent, toneSelectorClosedEvent, toneSelectorOpenedEvent, typeaheadCancelledEvent, typeaheadRenderedEvent, typeaheadSelectedEvent, uploadBeginButton, uploadCancelButton, uploadConfirmButton, uploadFailedEvent, uploadSucceededEvent } from './analytics';
|
|
3
|
+
export { sampledUfoRenderedEmoji, ufoExperiences } from './ufoExperiences';
|
|
3
4
|
export { useSampledUFOComponentExperience } from './useSampledUFOComponentExperience';
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ExperiencePerformanceTypes, ExperienceTypes, ConcurrentExperience, UFOExperience } from '@atlaskit/ufo';
|
|
2
|
+
import { withSampling } from './samplingUfo'; // TODO: clean up as not needed
|
|
3
|
+
|
|
4
|
+
var createRenderExperience = function createRenderExperience(componentName) {
|
|
5
|
+
return {
|
|
6
|
+
platform: {
|
|
7
|
+
component: componentName
|
|
8
|
+
},
|
|
9
|
+
type: ExperienceTypes.Load,
|
|
10
|
+
performanceType: ExperiencePerformanceTypes.PageSegmentLoad
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
var createInlineExperience = function createInlineExperience(componentName) {
|
|
15
|
+
return {
|
|
16
|
+
platform: {
|
|
17
|
+
component: componentName
|
|
18
|
+
},
|
|
19
|
+
type: ExperienceTypes.Experience,
|
|
20
|
+
performanceType: ExperiencePerformanceTypes.InlineResult
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export var ufoExperiences = {
|
|
25
|
+
'emoji-rendered': new ConcurrentExperience('emoji-rendered', createRenderExperience('emoji')),
|
|
26
|
+
'emoji-resource-fetched': new ConcurrentExperience('emoji-resource-fetched', createRenderExperience('emoji-provider')),
|
|
27
|
+
'emoji-picker-opened': new UFOExperience('emoji-picker-opened', createRenderExperience('emoji-picker')),
|
|
28
|
+
'emoji-selection-recorded': new UFOExperience('emoji-selection-recorded', createInlineExperience('emoji-picker')),
|
|
29
|
+
'emoji-uploaded': new UFOExperience('emoji-uploaded', createInlineExperience('emoji-picker')),
|
|
30
|
+
'emoji-searched': new UFOExperience('emoji-searched', createInlineExperience('emoji-picker'))
|
|
31
|
+
};
|
|
32
|
+
export var sampledUfoRenderedEmoji = function sampledUfoRenderedEmoji(emojiId) {
|
|
33
|
+
return withSampling(ufoExperiences['emoji-rendered'].getInstance(emojiId.id || emojiId.shortName));
|
|
34
|
+
};
|
package/dist/esm/version.json
CHANGED
|
@@ -16,6 +16,7 @@ export interface State {
|
|
|
16
16
|
export default class EmojiUploadComponent extends PureComponent<Props, State> {
|
|
17
17
|
private ref?;
|
|
18
18
|
constructor(props: Props);
|
|
19
|
+
componentWillUnmount(): void;
|
|
19
20
|
private onUploadEmoji;
|
|
20
21
|
private prepareForUpload;
|
|
21
22
|
onFileChooserClicked: () => void;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -12,10 +12,10 @@ import EmojiRepository from './api/EmojiRepository';
|
|
|
12
12
|
import EmojiLoader from './api/EmojiLoader';
|
|
13
13
|
import { denormaliseEmojiServiceResponse } from './api/EmojiUtils';
|
|
14
14
|
import { toEmojiId, toOptionalEmojiId } from './util/type-helpers';
|
|
15
|
-
import { recordSelectionFailedSli, recordSelectionSucceededSli } from './util/analytics';
|
|
15
|
+
import { recordSelectionFailedSli, recordSelectionSucceededSli, ufoExperiences } from './util/analytics';
|
|
16
16
|
import { customCategory, defaultEmojiHeight, emojiPickerWidth, emojiPickerHeight } from './util/constants';
|
|
17
17
|
import { UsageFrequencyTracker } from './api/internal/UsageFrequencyTracker';
|
|
18
|
-
export { AbstractResource, Emoji, EmojiPlaceholder, EmojiLoader, EmojiPicker, EmojiUploader, EmojiResource, EmojiRepository, EmojiTypeAhead, ResourcedEmoji, denormaliseEmojiServiceResponse, toEmojiId, toOptionalEmojiId, recordSelectionFailedSli, recordSelectionSucceededSli, emojiPickerWidth, emojiPickerHeight, defaultEmojiHeight, customCategory, UsageFrequencyTracker, EmojiTypeAheadItem, };
|
|
18
|
+
export { AbstractResource, Emoji, EmojiPlaceholder, EmojiLoader, EmojiPicker, EmojiUploader, EmojiResource, EmojiRepository, EmojiTypeAhead, ResourcedEmoji, denormaliseEmojiServiceResponse, toEmojiId, toOptionalEmojiId, recordSelectionFailedSli, recordSelectionSucceededSli, ufoExperiences, emojiPickerWidth, emojiPickerHeight, defaultEmojiHeight, customCategory, UsageFrequencyTracker, EmojiTypeAheadItem, };
|
|
19
19
|
export type { EmojiProvider, UploadingEmojiProvider, EmojiResourceConfig, };
|
|
20
20
|
export { SearchSort, } from './types';
|
|
21
21
|
export type { CategoryId, EmojiRepresentation, EmojiServiceRepresentation, Message, OptionalEmojiDescription, OptionalEmojiDescriptionWithVariations, OptionalUser, RelativePosition, ToneSelection, AltRepresentations, CategoryDescription, EmojiDescription, EmojiDescriptionWithVariations, EmojiId, EmojiImageRepresentation, EmojiMeta, EmojiResponse, EmojiSearchResult, EmojiServiceDescription, EmojiServiceDescriptionWithVariations, EmojiServiceResponse, EmojiUpload, EmojiVariationDescription, ImageRepresentation, MediaApiRepresentation, MediaApiToken, OnCategory, OnEmojiEvent, OnToneSelected, OnToneSelectorCancelled, SearchOptions, SpriteImageRepresentation, SpriteRepresentation, SpriteServiceRepresentation, SpriteSheet, SpriteSheets, Styles, User, } from './types';
|
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
import { AnalyticsEventPayload, CreateUIAnalyticsEvent } from '@atlaskit/analytics-next';
|
|
2
|
-
import { EmojiDescription
|
|
3
|
-
import { ConcurrentExperience } from '@atlaskit/ufo';
|
|
4
|
-
export declare type UfoExperienceName = 'emoji-rendered' | 'emoji-resource-fetched';
|
|
5
|
-
export declare const ufoExperiences: Record<UfoExperienceName, ConcurrentExperience>;
|
|
6
|
-
export declare const sampledUfoRenderedEmoji: (emojiId: EmojiId) => import("./samplingUfo").WithSampling;
|
|
2
|
+
import { EmojiDescription } from '../../types';
|
|
7
3
|
export declare const createAndFireEventInElementsChannel: (payload: Record<string, any>) => (createAnalyticsEvent: CreateUIAnalyticsEvent) => import("@atlaskit/analytics-next").UIAnalyticsEvent;
|
|
8
4
|
export declare type EmojiInsertionAnalytic = (source: 'picker' | 'typeahead') => AnalyticsEventPayload;
|
|
9
|
-
export declare const
|
|
10
|
-
export declare const
|
|
5
|
+
export declare const recordSucceeded: EmojiInsertionAnalytic;
|
|
6
|
+
export declare const recordFailed: EmojiInsertionAnalytic;
|
|
11
7
|
interface Duration {
|
|
12
8
|
duration: number;
|
|
13
9
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { ufoExperiencesSampled, clearSampled, isExperienceSampled, withSampling, } from './samplingUfo';
|
|
2
2
|
export type { UFOExperienceSampledRecords, WithSampling } from './samplingUfo';
|
|
3
|
-
export { categoryClickedEvent, createAndFireEventInElementsChannel, closedPickerEvent, deleteBeginEvent, deleteCancelEvent, deleteConfirmEvent,
|
|
4
|
-
export
|
|
3
|
+
export { categoryClickedEvent, createAndFireEventInElementsChannel, closedPickerEvent, deleteBeginEvent, deleteCancelEvent, deleteConfirmEvent, recordFailed, recordSucceeded, openedPickerEvent, pickerClickedEvent, pickerSearchedEvent, recordSelectionFailedSli, recordSelectionSucceededSli, selectedFileEvent, toneSelectedEvent, toneSelectorClosedEvent, toneSelectorOpenedEvent, typeaheadCancelledEvent, typeaheadRenderedEvent, typeaheadSelectedEvent, uploadBeginButton, uploadCancelButton, uploadConfirmButton, uploadFailedEvent, uploadSucceededEvent, } from './analytics';
|
|
4
|
+
export { sampledUfoRenderedEmoji, ufoExperiences } from './ufoExperiences';
|
|
5
|
+
export type { EmojiInsertionAnalytic } from './analytics';
|
|
5
6
|
export { useSampledUFOComponentExperience } from './useSampledUFOComponentExperience';
|