@atlaskit/emoji 64.5.2 → 64.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.
Files changed (77) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/admin/package.json +1 -0
  3. package/dist/cjs/api/EmojiRepository.js +4 -0
  4. package/dist/cjs/api/EmojiResource.js +62 -0
  5. package/dist/cjs/api/EmojiUtils.js +4 -0
  6. package/dist/cjs/api/internal/UsageFrequencyTracker.js +4 -1
  7. package/dist/cjs/api/media/SiteEmojiResource.js +59 -2
  8. package/dist/cjs/api/media/TokenManager.js +16 -7
  9. package/dist/cjs/components/common/CachingEmoji.js +44 -77
  10. package/dist/cjs/components/common/DeleteButton.js +2 -1
  11. package/dist/cjs/components/common/Emoji.js +76 -20
  12. package/dist/cjs/components/common/EmojiPlaceholder.js +1 -0
  13. package/dist/cjs/components/common/Popup.js +21 -1
  14. package/dist/cjs/components/common/ResourcedEmojiComponent.js +12 -1
  15. package/dist/cjs/components/picker/EmojiPickerComponent.js +4 -2
  16. package/dist/cjs/components/picker/EmojiPickerListSearch.js +5 -0
  17. package/dist/cjs/components/picker/styles.js +2 -0
  18. package/dist/cjs/types.js +25 -2
  19. package/dist/cjs/util/analytics/ufoExperiences.js +26 -1
  20. package/dist/cjs/util/browser-support.js +8 -0
  21. package/dist/cjs/util/storage-available.js +4 -0
  22. package/dist/cjs/version.json +1 -1
  23. package/dist/es2019/api/EmojiRepository.js +4 -0
  24. package/dist/es2019/api/EmojiResource.js +26 -1
  25. package/dist/es2019/api/EmojiUtils.js +4 -0
  26. package/dist/es2019/api/internal/UsageFrequencyTracker.js +4 -1
  27. package/dist/es2019/api/media/SiteEmojiResource.js +24 -0
  28. package/dist/es2019/api/media/TokenManager.js +13 -5
  29. package/dist/es2019/components/common/CachingEmoji.js +36 -77
  30. package/dist/es2019/components/common/DeleteButton.js +2 -1
  31. package/dist/es2019/components/common/Emoji.js +54 -21
  32. package/dist/es2019/components/common/EmojiPlaceholder.js +1 -0
  33. package/dist/es2019/components/common/Popup.js +21 -1
  34. package/dist/es2019/components/common/ResourcedEmojiComponent.js +9 -1
  35. package/dist/es2019/components/picker/EmojiPickerComponent.js +4 -1
  36. package/dist/es2019/components/picker/EmojiPickerListSearch.js +5 -0
  37. package/dist/es2019/components/picker/styles.js +3 -0
  38. package/dist/es2019/types.js +22 -1
  39. package/dist/es2019/util/analytics/ufoExperiences.js +27 -2
  40. package/dist/es2019/util/browser-support.js +1 -0
  41. package/dist/es2019/util/storage-available.js +4 -0
  42. package/dist/es2019/version.json +1 -1
  43. package/dist/esm/api/EmojiRepository.js +4 -0
  44. package/dist/esm/api/EmojiResource.js +61 -1
  45. package/dist/esm/api/EmojiUtils.js +4 -0
  46. package/dist/esm/api/internal/UsageFrequencyTracker.js +4 -1
  47. package/dist/esm/api/media/SiteEmojiResource.js +57 -2
  48. package/dist/esm/api/media/TokenManager.js +14 -5
  49. package/dist/esm/components/common/CachingEmoji.js +45 -79
  50. package/dist/esm/components/common/DeleteButton.js +2 -1
  51. package/dist/esm/components/common/Emoji.js +60 -21
  52. package/dist/esm/components/common/EmojiPlaceholder.js +1 -0
  53. package/dist/esm/components/common/Popup.js +21 -1
  54. package/dist/esm/components/common/ResourcedEmojiComponent.js +11 -1
  55. package/dist/esm/components/picker/EmojiPickerComponent.js +4 -1
  56. package/dist/esm/components/picker/EmojiPickerListSearch.js +5 -0
  57. package/dist/esm/components/picker/styles.js +2 -0
  58. package/dist/esm/types.js +22 -1
  59. package/dist/esm/util/analytics/ufoExperiences.js +27 -2
  60. package/dist/esm/util/browser-support.js +1 -0
  61. package/dist/esm/util/storage-available.js +4 -0
  62. package/dist/esm/version.json +1 -1
  63. package/dist/types/api/EmojiResource.d.ts +4 -0
  64. package/dist/types/api/media/SiteEmojiResource.d.ts +4 -0
  65. package/dist/types/api/media/TokenManager.d.ts +2 -1
  66. package/dist/types/components/common/CachingEmoji.d.ts +1 -4
  67. package/dist/types/components/common/Emoji.d.ts +2 -0
  68. package/dist/types/components/common/ResourcedEmojiComponent.d.ts +1 -0
  69. package/dist/types/types.d.ts +21 -0
  70. package/dist/types/util/browser-support.d.ts +1 -0
  71. package/element/package.json +1 -0
  72. package/package.json +7 -6
  73. package/picker/package.json +1 -0
  74. package/resource/package.json +1 -0
  75. package/typeahead/package.json +1 -0
  76. package/types/package.json +1 -0
  77. package/utils/package.json +1 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # @atlaskit/emoji
2
2
 
3
+ ## 64.7.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`2b241314079`](https://bitbucket.org/atlassian/atlassian-frontend/commits/2b241314079) - improve lazy load emoji with placeholder and improved analtyics tracking
8
+
9
+ ## 64.6.1
10
+
11
+ ### Patch Changes
12
+
13
+ - Updated dependencies
14
+
15
+ ## 64.6.0
16
+
17
+ ### Minor Changes
18
+
19
+ - [`b926172a999`](https://bitbucket.org/atlassian/atlassian-frontend/commits/b926172a999) - Custom Emoji Assets now load using inline media tokens preventing 401s
20
+
21
+ ### Patch Changes
22
+
23
+ - Updated dependencies
24
+
3
25
  ## 64.5.2
4
26
 
5
27
  ### Patch Changes
@@ -3,5 +3,6 @@
3
3
  "main": "../dist/cjs/admin.js",
4
4
  "module": "../dist/esm/admin.js",
5
5
  "module:es2019": "../dist/es2019/admin.js",
6
+ "sideEffects": false,
6
7
  "types": "../dist/types/admin.d.ts"
7
8
  }
@@ -307,6 +307,10 @@ var EmojiRepository = /*#__PURE__*/function () {
307
307
  // frequent category being shown in the picker).
308
308
 
309
309
  if (this.dynamicCategoryList.indexOf(_constants.frequentCategory) === -1) {
310
+ if (typeof window === 'undefined') {
311
+ return;
312
+ }
313
+
310
314
  window.setTimeout(function () {
311
315
  _this2.dynamicCategoryList.push(_constants.frequentCategory);
312
316
  });
@@ -7,6 +7,10 @@ Object.defineProperty(exports, "__esModule", {
7
7
  });
8
8
  exports.supportsUploadFeature = exports.default = exports.EmojiResource = void 0;
9
9
 
10
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
11
+
12
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
13
+
10
14
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
11
15
 
12
16
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
@@ -43,6 +47,10 @@ var _SiteEmojiResource = _interopRequireDefault(require("./media/SiteEmojiResour
43
47
 
44
48
  var _analytics = require("../util/analytics");
45
49
 
50
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
51
+
52
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
53
+
46
54
  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
47
55
 
48
56
  function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
@@ -204,6 +212,10 @@ var EmojiResource = /*#__PURE__*/function (_AbstractResource) {
204
212
  }, {
205
213
  key: "loadStoredTone",
206
214
  value: function loadStoredTone() {
215
+ if (typeof window === 'undefined') {
216
+ return undefined;
217
+ }
218
+
207
219
  var storedToneString = window.localStorage.getItem(_constants.selectedToneStorageKey);
208
220
 
209
221
  if (storedToneString) {
@@ -246,6 +258,52 @@ var EmojiResource = /*#__PURE__*/function (_AbstractResource) {
246
258
  (0, _get2.default)((0, _getPrototypeOf2.default)(EmojiResource.prototype), "notifyResult", this).call(this, result);
247
259
  }
248
260
  }
261
+ /**
262
+ * Returns the EmojiDescription with a valid media path that includes query token and client attributes to access the emoji media inline.
263
+ */
264
+
265
+ }, {
266
+ key: "getMediaEmojiDescriptionURLWithInlineToken",
267
+ value: function () {
268
+ var _getMediaEmojiDescriptionURLWithInlineToken = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(emoji) {
269
+ var tokenisedMediaPath;
270
+ return _regenerator.default.wrap(function _callee$(_context) {
271
+ while (1) {
272
+ switch (_context.prev = _context.next) {
273
+ case 0:
274
+ if (!(this.siteEmojiResource && (0, _typeHelpers.isMediaRepresentation)(emoji.representation))) {
275
+ _context.next = 5;
276
+ break;
277
+ }
278
+
279
+ _context.next = 3;
280
+ return this.siteEmojiResource.generateTokenisedMediaURL(emoji);
281
+
282
+ case 3:
283
+ tokenisedMediaPath = _context.sent;
284
+ return _context.abrupt("return", _objectSpread(_objectSpread({}, emoji), {}, {
285
+ representation: _objectSpread(_objectSpread({}, emoji.representation), {}, {
286
+ mediaPath: tokenisedMediaPath
287
+ })
288
+ }));
289
+
290
+ case 5:
291
+ return _context.abrupt("return", emoji);
292
+
293
+ case 6:
294
+ case "end":
295
+ return _context.stop();
296
+ }
297
+ }
298
+ }, _callee, this);
299
+ }));
300
+
301
+ function getMediaEmojiDescriptionURLWithInlineToken(_x) {
302
+ return _getMediaEmojiDescriptionURLWithInlineToken.apply(this, arguments);
303
+ }
304
+
305
+ return getMediaEmojiDescriptionURLWithInlineToken;
306
+ }()
249
307
  }, {
250
308
  key: "loadMediaEmoji",
251
309
  value: function loadMediaEmoji(emoji, useAlt) {
@@ -471,6 +529,10 @@ var EmojiResource = /*#__PURE__*/function (_AbstractResource) {
471
529
  value: function setSelectedTone(tone) {
472
530
  this.selectedTone = tone;
473
531
 
532
+ if (typeof window === 'undefined') {
533
+ return;
534
+ }
535
+
474
536
  if ((0, _storageAvailable.default)('localStorage')) {
475
537
  try {
476
538
  window.localStorage.setItem(_constants.selectedToneStorageKey, tone ? tone.toString() : '');
@@ -64,6 +64,10 @@ var calculateScale = function calculateScale(getRatio) {
64
64
  };
65
65
 
66
66
  var getPixelRatio = function getPixelRatio() {
67
+ if (typeof window === 'undefined') {
68
+ return 0;
69
+ }
70
+
67
71
  return window.devicePixelRatio;
68
72
  };
69
73
 
@@ -150,7 +150,10 @@ var Gateway = /*#__PURE__*/function () {
150
150
  }
151
151
  };
152
152
 
153
- window.setTimeout(wrappedFunc);
153
+ if (typeof window !== 'undefined') {
154
+ window.setTimeout(wrappedFunc);
155
+ }
156
+
154
157
  return true;
155
158
  }
156
159
  }, {
@@ -7,6 +7,10 @@ Object.defineProperty(exports, "__esModule", {
7
7
  });
8
8
  exports.mediaProportionOfProgress = exports.default = void 0;
9
9
 
10
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
11
+
12
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
13
+
10
14
  var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
11
15
 
12
16
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
@@ -92,12 +96,65 @@ var SiteEmojiResource = /*#__PURE__*/function () {
92
96
  this.mediaEmojiCache = new _MediaEmojiCache.default(this.tokenManager);
93
97
  }
94
98
  /**
95
- * Will load media emoji, returning a new EmojiDescription if, for example,
96
- * the URL has changed.
99
+ * Will generate an emoji media path that is inclusive of client and token within the query parameter
97
100
  */
98
101
 
99
102
 
100
103
  (0, _createClass2.default)(SiteEmojiResource, [{
104
+ key: "generateTokenisedMediaURL",
105
+ value: function () {
106
+ var _generateTokenisedMediaURL = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(emoji) {
107
+ var currentMediaPathURL, currentMediaPathPARAMS, readToken;
108
+ return _regenerator.default.wrap(function _callee$(_context) {
109
+ while (1) {
110
+ switch (_context.prev = _context.next) {
111
+ case 0:
112
+ if (!(emoji && (0, _typeHelpers.isMediaRepresentation)(emoji.representation))) {
113
+ _context.next = 9;
114
+ break;
115
+ }
116
+
117
+ currentMediaPathURL = new URL(emoji.representation.mediaPath);
118
+ currentMediaPathPARAMS = currentMediaPathURL.searchParams;
119
+ _context.next = 5;
120
+ return this.tokenManager.getToken('read');
121
+
122
+ case 5:
123
+ readToken = _context.sent;
124
+
125
+ if (currentMediaPathPARAMS.get('token') !== readToken.jwt) {
126
+ currentMediaPathPARAMS.set('token', readToken.jwt);
127
+ }
128
+
129
+ if (currentMediaPathPARAMS.get('client') !== readToken.clientId) {
130
+ currentMediaPathPARAMS.set('client', readToken.clientId);
131
+ }
132
+
133
+ return _context.abrupt("return", currentMediaPathURL.toString());
134
+
135
+ case 9:
136
+ throw Error('Emoji resource is not of type Media Representation');
137
+
138
+ case 10:
139
+ case "end":
140
+ return _context.stop();
141
+ }
142
+ }
143
+ }, _callee, this);
144
+ }));
145
+
146
+ function generateTokenisedMediaURL(_x) {
147
+ return _generateTokenisedMediaURL.apply(this, arguments);
148
+ }
149
+
150
+ return generateTokenisedMediaURL;
151
+ }()
152
+ /**
153
+ * Will load media emoji, returning a new EmojiDescription if, for example,
154
+ * the URL has changed.
155
+ */
156
+
157
+ }, {
101
158
  key: "loadMediaEmoji",
102
159
  value: function loadMediaEmoji(emoji, useAlt) {
103
160
  if (!(0, _typeHelpers.isMediaEmoji)(emoji)) {
@@ -5,7 +5,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.expireAdjustment = exports.default = void 0;
8
+ exports.default = exports.EXPIRES_AT_LATENCY_IN_SECONDS = void 0;
9
9
 
10
10
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
11
11
 
@@ -14,8 +14,8 @@ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/creat
14
14
  var _utilServiceSupport = require("@atlaskit/util-service-support");
15
15
 
16
16
  // expire 30 seconds early to factor in latency, slow services, etc
17
- var expireAdjustment = 30;
18
- exports.expireAdjustment = expireAdjustment;
17
+ var EXPIRES_AT_LATENCY_IN_SECONDS = 30;
18
+ exports.EXPIRES_AT_LATENCY_IN_SECONDS = EXPIRES_AT_LATENCY_IN_SECONDS;
19
19
 
20
20
  var TokenManager = /*#__PURE__*/function () {
21
21
  function TokenManager(siteServiceConfig) {
@@ -25,6 +25,18 @@ var TokenManager = /*#__PURE__*/function () {
25
25
  }
26
26
 
27
27
  (0, _createClass2.default)(TokenManager, [{
28
+ key: "isValidToken",
29
+ value: function isValidToken(mediaApiToken) {
30
+ var nowInSeconds = Date.now() / 1000;
31
+ var expiresAt = mediaApiToken.expiresAt - EXPIRES_AT_LATENCY_IN_SECONDS;
32
+
33
+ if (nowInSeconds < expiresAt) {
34
+ return true;
35
+ }
36
+
37
+ return false;
38
+ }
39
+ }, {
28
40
  key: "addToken",
29
41
  value: function addToken(type, mediaApiToken) {
30
42
  this.tokens.set(type, {
@@ -46,10 +58,7 @@ var TokenManager = /*#__PURE__*/function () {
46
58
  activeTokenRefresh = _tokenDetail.activeTokenRefresh;
47
59
 
48
60
  if (mediaApiToken) {
49
- var nowInSeconds = Date.now() / 1000;
50
- var expiresAt = mediaApiToken.expiresAt - expireAdjustment;
51
-
52
- if (nowInSeconds < expiresAt && !forceRefresh) {
61
+ if (this.isValidToken(mediaApiToken) && !forceRefresh) {
53
62
  // still valid
54
63
  return Promise.resolve(mediaApiToken);
55
64
  }
@@ -29,10 +29,10 @@ var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/h
29
29
 
30
30
  var _react = _interopRequireWildcard(require("react"));
31
31
 
32
- var _EmojiUtils = require("../../api/EmojiUtils");
33
-
34
32
  var _typeHelpers = require("../../util/type-helpers");
35
33
 
34
+ var _types = require("../../types");
35
+
36
36
  var _logger = _interopRequireDefault(require("../../util/logger"));
37
37
 
38
38
  var _Emoji = _interopRequireDefault(require("./Emoji"));
@@ -48,7 +48,7 @@ var _constants = require("../../util/constants");
48
48
  var _EmojiContext = require("../../context/EmojiContext");
49
49
 
50
50
  var _excluded = ["placeholderSize"],
51
- _excluded2 = ["children", "placeholderSize"];
51
+ _excluded2 = ["children"];
52
52
 
53
53
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
54
54
 
@@ -68,8 +68,12 @@ var CachingEmoji = function CachingEmoji(props) {
68
68
  emojiProps = (0, _objectWithoutProperties2.default)(props, _excluded); // start emoji rendered experience, it may have already started earlier in ResourcedEmoji
69
69
 
70
70
  (0, _analytics.useSampledUFOComponentExperience)(_analytics.ufoExperiences['emoji-rendered'].getInstance(emojiProps.emoji.id || emojiProps.emoji.shortName), _constants.SAMPLING_RATE_EMOJI_RENDERED_EXP, {
71
- source: 'caching-emoji'
71
+ source: 'caching-emoji',
72
+ emoji: emojiProps.emoji.shortName
72
73
  });
74
+ (0, _react.useEffect)(function () {
75
+ (0, _analytics.sampledUfoRenderedEmoji)(emojiProps.emoji).mark(_types.UfoEmojiTimings.MOUNTED_END); // eslint-disable-next-line react-hooks/exhaustive-deps
76
+ }, []);
73
77
 
74
78
  var emojiNode = function emojiNode() {
75
79
  if ((0, _typeHelpers.isMediaEmoji)(props.emoji)) {
@@ -101,55 +105,38 @@ var CachingMediaEmoji = /*#__PURE__*/function (_PureComponent) {
101
105
 
102
106
  (0, _classCallCheck2.default)(this, CachingMediaEmoji);
103
107
  _this = _super.call(this, props);
104
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "mounted", false);
105
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleLoadError", function (_emojiId, emoji) {
106
- var invalidImage = _this.state.invalidImage;
108
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleLoadError", function (_emojiId) {
107
109
  (0, _analytics.sampledUfoRenderedEmoji)(_emojiId).failure({
108
110
  metadata: {
109
111
  reason: 'load error'
110
112
  }
111
113
  });
112
114
 
113
- if (invalidImage || !emoji) {
114
- // do nothing, bad image
115
- return;
116
- }
117
-
118
115
  _this.setState({
119
- cachedEmoji: _this.loadEmoji(emoji, _this.context, true)
116
+ invalidImage: true
120
117
  });
121
118
  });
122
119
  _this.state = {
123
- cachedEmoji: _this.loadEmoji(props.emoji, context, false)
120
+ cachedEmoji: undefined
124
121
  };
122
+
123
+ _this.loadEmoji(props.emoji, context);
124
+
125
125
  return _this;
126
126
  }
127
127
 
128
128
  (0, _createClass2.default)(CachingMediaEmoji, [{
129
- key: "componentDidMount",
130
- value: function componentDidMount() {
131
- this.mounted = true;
132
- (0, _analytics.sampledUfoRenderedEmoji)(this.props.emoji).markFMP();
133
- }
134
- }, {
135
- key: "componentWillUnmount",
136
- value: function componentWillUnmount() {
137
- this.mounted = false;
138
- }
139
- }, {
140
- key: "UNSAFE_componentWillReceiveProps",
141
- value: function UNSAFE_componentWillReceiveProps(nextProps, nextContext) {
142
- if (nextProps.emoji !== this.props.emoji) {
143
- if (this.mounted) {
144
- this.setState({
145
- cachedEmoji: this.loadEmoji(nextProps.emoji, nextContext, false)
146
- });
147
- }
129
+ key: "componentDidUpdate",
130
+ value: function componentDidUpdate() {
131
+ var _this$state$cachedEmo;
132
+
133
+ if (this.props.emoji.shortName !== ((_this$state$cachedEmo = this.state.cachedEmoji) === null || _this$state$cachedEmo === void 0 ? void 0 : _this$state$cachedEmo.shortName)) {
134
+ this.loadEmoji(this.props.emoji, this.context);
148
135
  }
149
136
  }
150
137
  }, {
151
138
  key: "loadEmoji",
152
- value: function loadEmoji(emoji, context, forceLoad) {
139
+ value: function loadEmoji(emoji, context) {
153
140
  var _this2 = this;
154
141
 
155
142
  if (!context) {
@@ -166,60 +153,40 @@ var CachingMediaEmoji = /*#__PURE__*/function (_PureComponent) {
166
153
  return undefined;
167
154
  }
168
155
 
169
- var fitToHeight = this.props.fitToHeight;
170
- var useAlt = (0, _EmojiUtils.shouldUseAltRepresentation)(emoji, fitToHeight);
171
- var optimisticRendering = emojiProvider.optimisticMediaRendering(emoji, useAlt);
172
-
173
- if (optimisticRendering && !forceLoad) {
174
- (0, _logger.default)('Optimistic rendering', emoji.shortName);
175
- return emoji;
176
- }
177
-
178
156
  (0, _logger.default)('Loading image via media cache', emoji.shortName);
179
- var loadedEmoji = emojiProvider.loadMediaEmoji(emoji, useAlt);
180
-
181
- if ((0, _typeHelpers.isPromise)(loadedEmoji)) {
182
- loadedEmoji.then(function (cachedEmoji) {
183
- if (_this2.mounted) {
184
- _this2.setState({
185
- cachedEmoji: cachedEmoji,
186
- invalidImage: !cachedEmoji
187
- });
188
- }
189
- }).catch(function () {
190
- if (_this2.mounted) {
191
- _this2.setState({
192
- cachedEmoji: undefined,
193
- invalidImage: true
194
- });
195
-
196
- (0, _analytics.sampledUfoRenderedEmoji)(emoji).failure({
197
- metadata: {
198
- reason: 'failed to load media emoji'
199
- }
200
- });
201
- }
157
+ (0, _analytics.sampledUfoRenderedEmoji)(emoji).mark(_types.UfoEmojiTimings.MEDIA_START);
158
+ emojiProvider.getMediaEmojiDescriptionURLWithInlineToken(emoji).then(function (cachedEmoji) {
159
+ _this2.setState({
160
+ cachedEmoji: cachedEmoji,
161
+ invalidImage: false
202
162
  });
203
- return undefined;
204
- }
205
163
 
206
- if ((0, _typeHelpers.isEmojiDescription)(loadedEmoji)) {
207
- return loadedEmoji;
208
- }
164
+ (0, _analytics.sampledUfoRenderedEmoji)(emoji).mark(_types.UfoEmojiTimings.MEDIA_END);
165
+ }).catch(function () {
166
+ _this2.setState({
167
+ cachedEmoji: undefined,
168
+ invalidImage: true
169
+ });
209
170
 
210
- return undefined;
171
+ (0, _analytics.sampledUfoRenderedEmoji)(emoji).failure({
172
+ metadata: {
173
+ reason: 'failed to load media emoji'
174
+ }
175
+ });
176
+ });
211
177
  }
212
178
  }, {
213
179
  key: "render",
214
180
  value: function render() {
215
- var cachedEmoji = this.state.cachedEmoji;
181
+ var _this$state = this.state,
182
+ cachedEmoji = _this$state.cachedEmoji,
183
+ invalidImage = _this$state.invalidImage;
216
184
  var _this$props = this.props,
217
185
  children = _this$props.children,
218
- placeholderSize = _this$props.placeholderSize,
219
186
  otherProps = (0, _objectWithoutProperties2.default)(_this$props, _excluded2);
220
187
  var emojiComponent;
221
188
 
222
- if (cachedEmoji) {
189
+ if (cachedEmoji && !invalidImage) {
223
190
  emojiComponent = /*#__PURE__*/_react.default.createElement(_Emoji.default, (0, _extends2.default)({}, otherProps, {
224
191
  emoji: cachedEmoji,
225
192
  onLoadError: this.handleLoadError
@@ -227,13 +194,13 @@ var CachingMediaEmoji = /*#__PURE__*/function (_PureComponent) {
227
194
  } else {
228
195
  var _this$props2 = this.props,
229
196
  emoji = _this$props2.emoji,
230
- _placeholderSize = _this$props2.placeholderSize,
197
+ placeholderSize = _this$props2.placeholderSize,
231
198
  showTooltip = _this$props2.showTooltip,
232
199
  fitToHeight = _this$props2.fitToHeight;
233
200
  var shortName = emoji.shortName,
234
201
  representation = emoji.representation;
235
202
  emojiComponent = /*#__PURE__*/_react.default.createElement(_EmojiPlaceholder.default, {
236
- size: fitToHeight || _placeholderSize,
203
+ size: fitToHeight || placeholderSize,
237
204
  shortName: shortName,
238
205
  showTooltip: showTooltip,
239
206
  representation: representation
@@ -25,7 +25,8 @@ var _styles = require("./styles");
25
25
  var DeleteButton = function DeleteButton(props) {
26
26
  return (0, _core.jsx)("span", {
27
27
  css: _styles.deleteButton,
28
- className: _styles.emojiDeleteButton
28
+ className: _styles.emojiDeleteButton,
29
+ "data-testid": "emoji-delete-button"
29
30
  }, (0, _core.jsx)(_customThemeButton.default, {
30
31
  iconBefore: (0, _core.jsx)(_crossCircle.default, {
31
32
  label: _constants.deleteEmojiLabel,