@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.
Files changed (40) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/cjs/components/common/RecordSelectionDefault.js +8 -2
  3. package/dist/cjs/components/common/UploadEmoji.js +8 -0
  4. package/dist/cjs/components/picker/EmojiPicker.js +13 -2
  5. package/dist/cjs/components/picker/EmojiPickerComponent.js +27 -2
  6. package/dist/cjs/components/typeahead/EmojiTypeAheadComponent.js +17 -0
  7. package/dist/cjs/components/uploader/EmojiUploadComponent.js +13 -0
  8. package/dist/cjs/index.js +6 -0
  9. package/dist/cjs/util/analytics/analytics.js +11 -41
  10. package/dist/cjs/util/analytics/index.js +16 -14
  11. package/dist/cjs/util/analytics/ufoExperiences.js +46 -0
  12. package/dist/cjs/version.json +1 -1
  13. package/dist/es2019/components/common/RecordSelectionDefault.js +9 -2
  14. package/dist/es2019/components/common/UploadEmoji.js +4 -0
  15. package/dist/es2019/components/picker/EmojiPicker.js +9 -2
  16. package/dist/es2019/components/picker/EmojiPickerComponent.js +22 -3
  17. package/dist/es2019/components/typeahead/EmojiTypeAheadComponent.js +13 -1
  18. package/dist/es2019/components/uploader/EmojiUploadComponent.js +9 -0
  19. package/dist/es2019/index.js +2 -2
  20. package/dist/es2019/util/analytics/analytics.js +16 -37
  21. package/dist/es2019/util/analytics/index.js +2 -1
  22. package/dist/es2019/util/analytics/ufoExperiences.js +34 -0
  23. package/dist/es2019/version.json +1 -1
  24. package/dist/esm/components/common/RecordSelectionDefault.js +6 -3
  25. package/dist/esm/components/common/UploadEmoji.js +4 -0
  26. package/dist/esm/components/picker/EmojiPicker.js +8 -2
  27. package/dist/esm/components/picker/EmojiPickerComponent.js +23 -3
  28. package/dist/esm/components/typeahead/EmojiTypeAheadComponent.js +13 -1
  29. package/dist/esm/components/uploader/EmojiUploadComponent.js +10 -0
  30. package/dist/esm/index.js +2 -2
  31. package/dist/esm/util/analytics/analytics.js +8 -33
  32. package/dist/esm/util/analytics/index.js +2 -1
  33. package/dist/esm/util/analytics/ufoExperiences.js +34 -0
  34. package/dist/esm/version.json +1 -1
  35. package/dist/types/components/uploader/EmojiUploadComponent.d.ts +1 -0
  36. package/dist/types/index.d.ts +2 -2
  37. package/dist/types/util/analytics/analytics.d.ts +3 -7
  38. package/dist/types/util/analytics/index.d.ts +3 -2
  39. package/dist/types/util/analytics/ufoExperiences.d.ts +12 -0
  40. 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
@@ -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 insertionSucceeded = source => createEvent('operational', 'succeeded', 'recordEmojiSelection', undefined, {
45
- source
46
- });
47
- export const insertionFailed = source => createEvent('operational', 'failed', 'recordEmojiSelection', undefined, {
48
- source
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')(insertionSucceeded('typeahead'))(options.createAnalyticsEvent);
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')(insertionFailed('typeahead'))(options.createAnalyticsEvent);
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, insertionFailed, insertionSucceeded, openedPickerEvent, pickerClickedEvent, pickerSearchedEvent, recordSelectionFailedSli, recordSelectionSucceededSli, sampledUfoRenderedEmoji, selectedFileEvent, toneSelectedEvent, toneSelectorClosedEvent, toneSelectorOpenedEvent, typeaheadCancelledEvent, typeaheadRenderedEvent, typeaheadSelectedEvent, ufoExperiences, uploadBeginButton, uploadCancelButton, uploadConfirmButton, uploadFailedEvent, uploadSucceededEvent } from './analytics';
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
+ };
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/emoji",
3
- "version": "64.3.0",
3
+ "version": "64.4.0",
4
4
  "sideEffects": false
5
5
  }
@@ -1,4 +1,4 @@
1
- import { insertionFailed, insertionSucceeded } from '../../util/analytics';
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
- return fireAnalytics && fireAnalytics(insertionSucceeded);
17
+ fireAnalytics && fireAnalytics(recordSucceeded);
18
+ ufoExperiences['emoji-selection-recorded'].success();
17
19
  }).catch(function () {
18
- return fireAnalytics && fireAnalytics(insertionFailed);
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(EmojiPickerComponent, _extends({
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
- _this.updateEmojis(query, {
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 insertionSucceeded = function insertionSucceeded(source) {
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 insertionFailed = function insertionFailed(source) {
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')(insertionSucceeded('typeahead'))(options.createAnalyticsEvent);
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')(insertionFailed('typeahead'))(options.createAnalyticsEvent);
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, insertionFailed, insertionSucceeded, openedPickerEvent, pickerClickedEvent, pickerSearchedEvent, recordSelectionFailedSli, recordSelectionSucceededSli, sampledUfoRenderedEmoji, selectedFileEvent, toneSelectedEvent, toneSelectorClosedEvent, toneSelectorOpenedEvent, typeaheadCancelledEvent, typeaheadRenderedEvent, typeaheadSelectedEvent, ufoExperiences, uploadBeginButton, uploadCancelButton, uploadConfirmButton, uploadFailedEvent, uploadSucceededEvent } from './analytics';
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
+ };
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/emoji",
3
- "version": "64.3.0",
3
+ "version": "64.4.0",
4
4
  "sideEffects": false
5
5
  }
@@ -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;
@@ -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, EmojiId } from '../../types';
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 insertionSucceeded: EmojiInsertionAnalytic;
10
- export declare const insertionFailed: EmojiInsertionAnalytic;
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, insertionFailed, insertionSucceeded, openedPickerEvent, pickerClickedEvent, pickerSearchedEvent, recordSelectionFailedSli, recordSelectionSucceededSli, sampledUfoRenderedEmoji, selectedFileEvent, toneSelectedEvent, toneSelectorClosedEvent, toneSelectorOpenedEvent, typeaheadCancelledEvent, typeaheadRenderedEvent, typeaheadSelectedEvent, ufoExperiences, uploadBeginButton, uploadCancelButton, uploadConfirmButton, uploadFailedEvent, uploadSucceededEvent, } from './analytics';
4
- export type { EmojiInsertionAnalytic, UfoExperienceName } from './analytics';
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';