@atlaskit/emoji 64.5.2 → 64.6.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 +10 -0
- package/admin/package.json +1 -0
- package/dist/cjs/api/EmojiResource.js +54 -0
- package/dist/cjs/api/media/SiteEmojiResource.js +59 -2
- package/dist/cjs/api/media/TokenManager.js +16 -7
- package/dist/cjs/components/common/CachingEmoji.js +32 -68
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/api/EmojiResource.js +18 -1
- package/dist/es2019/api/media/SiteEmojiResource.js +24 -0
- package/dist/es2019/api/media/TokenManager.js +13 -5
- package/dist/es2019/components/common/CachingEmoji.js +27 -70
- package/dist/es2019/version.json +1 -1
- package/dist/esm/api/EmojiResource.js +53 -1
- package/dist/esm/api/media/SiteEmojiResource.js +57 -2
- package/dist/esm/api/media/TokenManager.js +14 -5
- package/dist/esm/components/common/CachingEmoji.js +33 -69
- package/dist/esm/version.json +1 -1
- package/dist/types/api/EmojiResource.d.ts +4 -0
- package/dist/types/api/media/SiteEmojiResource.d.ts +4 -0
- package/dist/types/api/media/TokenManager.d.ts +2 -1
- package/dist/types/components/common/CachingEmoji.d.ts +1 -3
- package/dist/types/types.d.ts +6 -0
- package/element/package.json +1 -0
- package/package.json +3 -3
- package/picker/package.json +1 -0
- package/resource/package.json +1 -0
- package/typeahead/package.json +1 -0
- package/types/package.json +1 -0
- package/utils/package.json +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @atlaskit/emoji
|
|
2
2
|
|
|
3
|
+
## 64.6.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`b926172a999`](https://bitbucket.org/atlassian/atlassian-frontend/commits/b926172a999) - Custom Emoji Assets now load using inline media tokens preventing 401s
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies
|
|
12
|
+
|
|
3
13
|
## 64.5.2
|
|
4
14
|
|
|
5
15
|
### Patch Changes
|
package/admin/package.json
CHANGED
|
@@ -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; } }
|
|
@@ -246,6 +254,52 @@ var EmojiResource = /*#__PURE__*/function (_AbstractResource) {
|
|
|
246
254
|
(0, _get2.default)((0, _getPrototypeOf2.default)(EmojiResource.prototype), "notifyResult", this).call(this, result);
|
|
247
255
|
}
|
|
248
256
|
}
|
|
257
|
+
/**
|
|
258
|
+
* Returns the EmojiDescription with a valid media path that includes query token and client attributes to access the emoji media inline.
|
|
259
|
+
*/
|
|
260
|
+
|
|
261
|
+
}, {
|
|
262
|
+
key: "getMediaEmojiDescriptionURLWithInlineToken",
|
|
263
|
+
value: function () {
|
|
264
|
+
var _getMediaEmojiDescriptionURLWithInlineToken = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(emoji) {
|
|
265
|
+
var tokenisedMediaPath;
|
|
266
|
+
return _regenerator.default.wrap(function _callee$(_context) {
|
|
267
|
+
while (1) {
|
|
268
|
+
switch (_context.prev = _context.next) {
|
|
269
|
+
case 0:
|
|
270
|
+
if (!(this.siteEmojiResource && (0, _typeHelpers.isMediaRepresentation)(emoji.representation))) {
|
|
271
|
+
_context.next = 5;
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
_context.next = 3;
|
|
276
|
+
return this.siteEmojiResource.generateTokenisedMediaURL(emoji);
|
|
277
|
+
|
|
278
|
+
case 3:
|
|
279
|
+
tokenisedMediaPath = _context.sent;
|
|
280
|
+
return _context.abrupt("return", _objectSpread(_objectSpread({}, emoji), {}, {
|
|
281
|
+
representation: _objectSpread(_objectSpread({}, emoji.representation), {}, {
|
|
282
|
+
mediaPath: tokenisedMediaPath
|
|
283
|
+
})
|
|
284
|
+
}));
|
|
285
|
+
|
|
286
|
+
case 5:
|
|
287
|
+
return _context.abrupt("return", emoji);
|
|
288
|
+
|
|
289
|
+
case 6:
|
|
290
|
+
case "end":
|
|
291
|
+
return _context.stop();
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}, _callee, this);
|
|
295
|
+
}));
|
|
296
|
+
|
|
297
|
+
function getMediaEmojiDescriptionURLWithInlineToken(_x) {
|
|
298
|
+
return _getMediaEmojiDescriptionURLWithInlineToken.apply(this, arguments);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return getMediaEmojiDescriptionURLWithInlineToken;
|
|
302
|
+
}()
|
|
249
303
|
}, {
|
|
250
304
|
key: "loadMediaEmoji",
|
|
251
305
|
value: function loadMediaEmoji(emoji, useAlt) {
|
|
@@ -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
|
|
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.
|
|
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
|
|
18
|
-
exports.
|
|
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
|
-
|
|
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,8 +29,6 @@ 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
|
|
|
36
34
|
var _logger = _interopRequireDefault(require("../../util/logger"));
|
|
@@ -101,55 +99,43 @@ var CachingMediaEmoji = /*#__PURE__*/function (_PureComponent) {
|
|
|
101
99
|
|
|
102
100
|
(0, _classCallCheck2.default)(this, CachingMediaEmoji);
|
|
103
101
|
_this = _super.call(this, props);
|
|
104
|
-
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "
|
|
105
|
-
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleLoadError", function (_emojiId, emoji) {
|
|
106
|
-
var invalidImage = _this.state.invalidImage;
|
|
102
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "handleLoadError", function (_emojiId) {
|
|
107
103
|
(0, _analytics.sampledUfoRenderedEmoji)(_emojiId).failure({
|
|
108
104
|
metadata: {
|
|
109
105
|
reason: 'load error'
|
|
110
106
|
}
|
|
111
107
|
});
|
|
112
108
|
|
|
113
|
-
if (invalidImage || !emoji) {
|
|
114
|
-
// do nothing, bad image
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
109
|
_this.setState({
|
|
119
|
-
|
|
110
|
+
invalidImage: true
|
|
120
111
|
});
|
|
121
112
|
});
|
|
122
113
|
_this.state = {
|
|
123
|
-
cachedEmoji:
|
|
114
|
+
cachedEmoji: undefined
|
|
124
115
|
};
|
|
116
|
+
|
|
117
|
+
_this.loadEmoji(props.emoji, context);
|
|
118
|
+
|
|
125
119
|
return _this;
|
|
126
120
|
}
|
|
127
121
|
|
|
128
122
|
(0, _createClass2.default)(CachingMediaEmoji, [{
|
|
129
123
|
key: "componentDidMount",
|
|
130
124
|
value: function componentDidMount() {
|
|
131
|
-
this.mounted = true;
|
|
132
125
|
(0, _analytics.sampledUfoRenderedEmoji)(this.props.emoji).markFMP();
|
|
133
126
|
}
|
|
134
127
|
}, {
|
|
135
|
-
key: "
|
|
136
|
-
value: function
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
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
|
-
}
|
|
128
|
+
key: "componentDidUpdate",
|
|
129
|
+
value: function componentDidUpdate() {
|
|
130
|
+
var _this$state$cachedEmo;
|
|
131
|
+
|
|
132
|
+
if (this.props.emoji.shortName !== ((_this$state$cachedEmo = this.state.cachedEmoji) === null || _this$state$cachedEmo === void 0 ? void 0 : _this$state$cachedEmo.shortName)) {
|
|
133
|
+
this.loadEmoji(this.props.emoji, this.context);
|
|
148
134
|
}
|
|
149
135
|
}
|
|
150
136
|
}, {
|
|
151
137
|
key: "loadEmoji",
|
|
152
|
-
value: function loadEmoji(emoji, context
|
|
138
|
+
value: function loadEmoji(emoji, context) {
|
|
153
139
|
var _this2 = this;
|
|
154
140
|
|
|
155
141
|
if (!context) {
|
|
@@ -166,60 +152,38 @@ var CachingMediaEmoji = /*#__PURE__*/function (_PureComponent) {
|
|
|
166
152
|
return undefined;
|
|
167
153
|
}
|
|
168
154
|
|
|
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
155
|
(0, _logger.default)('Loading image via media cache', emoji.shortName);
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
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
|
-
}
|
|
156
|
+
emojiProvider.getMediaEmojiDescriptionURLWithInlineToken(emoji).then(function (cachedEmoji) {
|
|
157
|
+
_this2.setState({
|
|
158
|
+
cachedEmoji: cachedEmoji,
|
|
159
|
+
invalidImage: false
|
|
160
|
+
});
|
|
161
|
+
}).catch(function () {
|
|
162
|
+
_this2.setState({
|
|
163
|
+
cachedEmoji: undefined,
|
|
164
|
+
invalidImage: true
|
|
202
165
|
});
|
|
203
|
-
return undefined;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
if ((0, _typeHelpers.isEmojiDescription)(loadedEmoji)) {
|
|
207
|
-
return loadedEmoji;
|
|
208
|
-
}
|
|
209
166
|
|
|
210
|
-
|
|
167
|
+
(0, _analytics.sampledUfoRenderedEmoji)(emoji).failure({
|
|
168
|
+
metadata: {
|
|
169
|
+
reason: 'failed to load media emoji'
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
});
|
|
211
173
|
}
|
|
212
174
|
}, {
|
|
213
175
|
key: "render",
|
|
214
176
|
value: function render() {
|
|
215
|
-
var
|
|
177
|
+
var _this$state = this.state,
|
|
178
|
+
cachedEmoji = _this$state.cachedEmoji,
|
|
179
|
+
invalidImage = _this$state.invalidImage;
|
|
216
180
|
var _this$props = this.props,
|
|
217
181
|
children = _this$props.children,
|
|
218
182
|
placeholderSize = _this$props.placeholderSize,
|
|
219
183
|
otherProps = (0, _objectWithoutProperties2.default)(_this$props, _excluded2);
|
|
220
184
|
var emojiComponent;
|
|
221
185
|
|
|
222
|
-
if (cachedEmoji) {
|
|
186
|
+
if (cachedEmoji && !invalidImage) {
|
|
223
187
|
emojiComponent = /*#__PURE__*/_react.default.createElement(_Emoji.default, (0, _extends2.default)({}, otherProps, {
|
|
224
188
|
emoji: cachedEmoji,
|
|
225
189
|
onLoadError: this.handleLoadError
|
package/dist/cjs/version.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
2
|
import { AbstractResource, utils as serviceUtils } from '@atlaskit/util-service-support';
|
|
3
3
|
import { selectedToneStorageKey } from '../util/constants';
|
|
4
|
-
import { isMediaEmoji, isPromise, toEmojiId } from '../util/type-helpers';
|
|
4
|
+
import { isMediaEmoji, isMediaRepresentation, isPromise, toEmojiId } from '../util/type-helpers';
|
|
5
5
|
import storageAvailable from '../util/storage-available';
|
|
6
6
|
import { ProviderTypes } from '../types';
|
|
7
7
|
import debug from '../util/logger';
|
|
@@ -181,6 +181,23 @@ export class EmojiResource extends AbstractResource {
|
|
|
181
181
|
super.notifyResult(result);
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
|
+
/**
|
|
185
|
+
* Returns the EmojiDescription with a valid media path that includes query token and client attributes to access the emoji media inline.
|
|
186
|
+
*/
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
async getMediaEmojiDescriptionURLWithInlineToken(emoji) {
|
|
190
|
+
if (this.siteEmojiResource && isMediaRepresentation(emoji.representation)) {
|
|
191
|
+
const tokenisedMediaPath = await this.siteEmojiResource.generateTokenisedMediaURL(emoji);
|
|
192
|
+
return { ...emoji,
|
|
193
|
+
representation: { ...emoji.representation,
|
|
194
|
+
mediaPath: tokenisedMediaPath
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return emoji;
|
|
200
|
+
}
|
|
184
201
|
|
|
185
202
|
loadMediaEmoji(emoji, useAlt) {
|
|
186
203
|
if (!this.siteEmojiResource || !isMediaEmoji(emoji)) {
|
|
@@ -63,6 +63,30 @@ export default class SiteEmojiResource {
|
|
|
63
63
|
this.tokenManager.addToken('read', mediaApiToken);
|
|
64
64
|
this.mediaEmojiCache = new MediaEmojiCache(this.tokenManager);
|
|
65
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Will generate an emoji media path that is inclusive of client and token within the query parameter
|
|
68
|
+
*/
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
async generateTokenisedMediaURL(emoji) {
|
|
72
|
+
if (emoji && isMediaRepresentation(emoji.representation)) {
|
|
73
|
+
const currentMediaPathURL = new URL(emoji.representation.mediaPath);
|
|
74
|
+
const currentMediaPathPARAMS = currentMediaPathURL.searchParams;
|
|
75
|
+
const readToken = await this.tokenManager.getToken('read');
|
|
76
|
+
|
|
77
|
+
if (currentMediaPathPARAMS.get('token') !== readToken.jwt) {
|
|
78
|
+
currentMediaPathPARAMS.set('token', readToken.jwt);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (currentMediaPathPARAMS.get('client') !== readToken.clientId) {
|
|
82
|
+
currentMediaPathPARAMS.set('client', readToken.clientId);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return currentMediaPathURL.toString();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
throw Error('Emoji resource is not of type Media Representation');
|
|
89
|
+
}
|
|
66
90
|
/**
|
|
67
91
|
* Will load media emoji, returning a new EmojiDescription if, for example,
|
|
68
92
|
* the URL has changed.
|
|
@@ -1,12 +1,23 @@
|
|
|
1
1
|
import { utils as serviceUtils } from '@atlaskit/util-service-support'; // expire 30 seconds early to factor in latency, slow services, etc
|
|
2
2
|
|
|
3
|
-
export const
|
|
3
|
+
export const EXPIRES_AT_LATENCY_IN_SECONDS = 30;
|
|
4
4
|
export default class TokenManager {
|
|
5
5
|
constructor(siteServiceConfig) {
|
|
6
6
|
this.siteServiceConfig = siteServiceConfig;
|
|
7
7
|
this.tokens = new Map();
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
isValidToken(mediaApiToken) {
|
|
11
|
+
const nowInSeconds = Date.now() / 1000;
|
|
12
|
+
const expiresAt = mediaApiToken.expiresAt - EXPIRES_AT_LATENCY_IN_SECONDS;
|
|
13
|
+
|
|
14
|
+
if (nowInSeconds < expiresAt) {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
|
|
10
21
|
addToken(type, mediaApiToken) {
|
|
11
22
|
this.tokens.set(type, {
|
|
12
23
|
mediaApiToken
|
|
@@ -27,10 +38,7 @@ export default class TokenManager {
|
|
|
27
38
|
} = tokenDetail;
|
|
28
39
|
|
|
29
40
|
if (mediaApiToken) {
|
|
30
|
-
|
|
31
|
-
const expiresAt = mediaApiToken.expiresAt - expireAdjustment;
|
|
32
|
-
|
|
33
|
-
if (nowInSeconds < expiresAt && !forceRefresh) {
|
|
41
|
+
if (this.isValidToken(mediaApiToken) && !forceRefresh) {
|
|
34
42
|
// still valid
|
|
35
43
|
return Promise.resolve(mediaApiToken);
|
|
36
44
|
}
|
|
@@ -2,8 +2,7 @@ import _extends from "@babel/runtime/helpers/extends";
|
|
|
2
2
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { PureComponent } from 'react';
|
|
5
|
-
import {
|
|
6
|
-
import { isEmojiDescription, isMediaEmoji, isPromise } from '../../util/type-helpers';
|
|
5
|
+
import { isMediaEmoji } from '../../util/type-helpers';
|
|
7
6
|
import debug from '../../util/logger';
|
|
8
7
|
import Emoji from './Emoji';
|
|
9
8
|
import EmojiPlaceholder from './EmojiPlaceholder';
|
|
@@ -48,53 +47,36 @@ export class CachingMediaEmoji extends PureComponent {
|
|
|
48
47
|
constructor(props, context) {
|
|
49
48
|
super(props);
|
|
50
49
|
|
|
51
|
-
_defineProperty(this, "
|
|
52
|
-
|
|
53
|
-
_defineProperty(this, "handleLoadError", (_emojiId, emoji) => {
|
|
54
|
-
const {
|
|
55
|
-
invalidImage
|
|
56
|
-
} = this.state;
|
|
50
|
+
_defineProperty(this, "handleLoadError", _emojiId => {
|
|
57
51
|
sampledUfoRenderedEmoji(_emojiId).failure({
|
|
58
52
|
metadata: {
|
|
59
53
|
reason: 'load error'
|
|
60
54
|
}
|
|
61
55
|
});
|
|
62
|
-
|
|
63
|
-
if (invalidImage || !emoji) {
|
|
64
|
-
// do nothing, bad image
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
56
|
this.setState({
|
|
69
|
-
|
|
57
|
+
invalidImage: true
|
|
70
58
|
});
|
|
71
59
|
});
|
|
72
60
|
|
|
73
61
|
this.state = {
|
|
74
|
-
cachedEmoji:
|
|
62
|
+
cachedEmoji: undefined
|
|
75
63
|
};
|
|
64
|
+
this.loadEmoji(props.emoji, context);
|
|
76
65
|
}
|
|
77
66
|
|
|
78
67
|
componentDidMount() {
|
|
79
|
-
this.mounted = true;
|
|
80
68
|
sampledUfoRenderedEmoji(this.props.emoji).markFMP();
|
|
81
69
|
}
|
|
82
70
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
71
|
+
componentDidUpdate() {
|
|
72
|
+
var _this$state$cachedEmo;
|
|
86
73
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if (this.mounted) {
|
|
90
|
-
this.setState({
|
|
91
|
-
cachedEmoji: this.loadEmoji(nextProps.emoji, nextContext, false)
|
|
92
|
-
});
|
|
93
|
-
}
|
|
74
|
+
if (this.props.emoji.shortName !== ((_this$state$cachedEmo = this.state.cachedEmoji) === null || _this$state$cachedEmo === void 0 ? void 0 : _this$state$cachedEmo.shortName)) {
|
|
75
|
+
this.loadEmoji(this.props.emoji, this.context);
|
|
94
76
|
}
|
|
95
77
|
}
|
|
96
78
|
|
|
97
|
-
loadEmoji(emoji, context
|
|
79
|
+
loadEmoji(emoji, context) {
|
|
98
80
|
if (!context) {
|
|
99
81
|
return;
|
|
100
82
|
}
|
|
@@ -111,54 +93,29 @@ export class CachingMediaEmoji extends PureComponent {
|
|
|
111
93
|
return undefined;
|
|
112
94
|
}
|
|
113
95
|
|
|
114
|
-
const {
|
|
115
|
-
fitToHeight
|
|
116
|
-
} = this.props;
|
|
117
|
-
const useAlt = shouldUseAltRepresentation(emoji, fitToHeight);
|
|
118
|
-
const optimisticRendering = emojiProvider.optimisticMediaRendering(emoji, useAlt);
|
|
119
|
-
|
|
120
|
-
if (optimisticRendering && !forceLoad) {
|
|
121
|
-
debug('Optimistic rendering', emoji.shortName);
|
|
122
|
-
return emoji;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
96
|
debug('Loading image via media cache', emoji.shortName);
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
cachedEmoji: undefined,
|
|
140
|
-
invalidImage: true
|
|
141
|
-
});
|
|
142
|
-
sampledUfoRenderedEmoji(emoji).failure({
|
|
143
|
-
metadata: {
|
|
144
|
-
reason: 'failed to load media emoji'
|
|
145
|
-
}
|
|
146
|
-
});
|
|
97
|
+
emojiProvider.getMediaEmojiDescriptionURLWithInlineToken(emoji).then(cachedEmoji => {
|
|
98
|
+
this.setState({
|
|
99
|
+
cachedEmoji,
|
|
100
|
+
invalidImage: false
|
|
101
|
+
});
|
|
102
|
+
}).catch(() => {
|
|
103
|
+
this.setState({
|
|
104
|
+
cachedEmoji: undefined,
|
|
105
|
+
invalidImage: true
|
|
106
|
+
});
|
|
107
|
+
sampledUfoRenderedEmoji(emoji).failure({
|
|
108
|
+
metadata: {
|
|
109
|
+
reason: 'failed to load media emoji'
|
|
147
110
|
}
|
|
148
111
|
});
|
|
149
|
-
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
if (isEmojiDescription(loadedEmoji)) {
|
|
153
|
-
return loadedEmoji;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
return undefined;
|
|
112
|
+
});
|
|
157
113
|
}
|
|
158
114
|
|
|
159
115
|
render() {
|
|
160
116
|
const {
|
|
161
|
-
cachedEmoji
|
|
117
|
+
cachedEmoji,
|
|
118
|
+
invalidImage
|
|
162
119
|
} = this.state;
|
|
163
120
|
const {
|
|
164
121
|
children,
|
|
@@ -167,7 +124,7 @@ export class CachingMediaEmoji extends PureComponent {
|
|
|
167
124
|
} = this.props;
|
|
168
125
|
let emojiComponent;
|
|
169
126
|
|
|
170
|
-
if (cachedEmoji) {
|
|
127
|
+
if (cachedEmoji && !invalidImage) {
|
|
171
128
|
emojiComponent = /*#__PURE__*/React.createElement(Emoji, _extends({}, otherProps, {
|
|
172
129
|
emoji: cachedEmoji,
|
|
173
130
|
onLoadError: this.handleLoadError
|
package/dist/es2019/version.json
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
2
|
+
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
1
3
|
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
2
4
|
import _createClass from "@babel/runtime/helpers/createClass";
|
|
3
5
|
import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
|
|
@@ -7,13 +9,17 @@ import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstruct
|
|
|
7
9
|
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
|
|
8
10
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
9
11
|
|
|
12
|
+
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; }
|
|
13
|
+
|
|
14
|
+
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) { _defineProperty(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; }
|
|
15
|
+
|
|
10
16
|
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
|
|
11
17
|
|
|
12
18
|
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; } }
|
|
13
19
|
|
|
14
20
|
import { AbstractResource, utils as serviceUtils } from '@atlaskit/util-service-support';
|
|
15
21
|
import { selectedToneStorageKey } from '../util/constants';
|
|
16
|
-
import { isMediaEmoji, isPromise, toEmojiId } from '../util/type-helpers';
|
|
22
|
+
import { isMediaEmoji, isMediaRepresentation, isPromise, toEmojiId } from '../util/type-helpers';
|
|
17
23
|
import storageAvailable from '../util/storage-available';
|
|
18
24
|
import { ProviderTypes } from '../types';
|
|
19
25
|
import debug from '../util/logger';
|
|
@@ -221,6 +227,52 @@ export var EmojiResource = /*#__PURE__*/function (_AbstractResource) {
|
|
|
221
227
|
_get(_getPrototypeOf(EmojiResource.prototype), "notifyResult", this).call(this, result);
|
|
222
228
|
}
|
|
223
229
|
}
|
|
230
|
+
/**
|
|
231
|
+
* Returns the EmojiDescription with a valid media path that includes query token and client attributes to access the emoji media inline.
|
|
232
|
+
*/
|
|
233
|
+
|
|
234
|
+
}, {
|
|
235
|
+
key: "getMediaEmojiDescriptionURLWithInlineToken",
|
|
236
|
+
value: function () {
|
|
237
|
+
var _getMediaEmojiDescriptionURLWithInlineToken = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(emoji) {
|
|
238
|
+
var tokenisedMediaPath;
|
|
239
|
+
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
240
|
+
while (1) {
|
|
241
|
+
switch (_context.prev = _context.next) {
|
|
242
|
+
case 0:
|
|
243
|
+
if (!(this.siteEmojiResource && isMediaRepresentation(emoji.representation))) {
|
|
244
|
+
_context.next = 5;
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
_context.next = 3;
|
|
249
|
+
return this.siteEmojiResource.generateTokenisedMediaURL(emoji);
|
|
250
|
+
|
|
251
|
+
case 3:
|
|
252
|
+
tokenisedMediaPath = _context.sent;
|
|
253
|
+
return _context.abrupt("return", _objectSpread(_objectSpread({}, emoji), {}, {
|
|
254
|
+
representation: _objectSpread(_objectSpread({}, emoji.representation), {}, {
|
|
255
|
+
mediaPath: tokenisedMediaPath
|
|
256
|
+
})
|
|
257
|
+
}));
|
|
258
|
+
|
|
259
|
+
case 5:
|
|
260
|
+
return _context.abrupt("return", emoji);
|
|
261
|
+
|
|
262
|
+
case 6:
|
|
263
|
+
case "end":
|
|
264
|
+
return _context.stop();
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}, _callee, this);
|
|
268
|
+
}));
|
|
269
|
+
|
|
270
|
+
function getMediaEmojiDescriptionURLWithInlineToken(_x) {
|
|
271
|
+
return _getMediaEmojiDescriptionURLWithInlineToken.apply(this, arguments);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return getMediaEmojiDescriptionURLWithInlineToken;
|
|
275
|
+
}()
|
|
224
276
|
}, {
|
|
225
277
|
key: "loadMediaEmoji",
|
|
226
278
|
value: function loadMediaEmoji(emoji, useAlt) {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
2
|
+
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
1
3
|
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
|
|
2
4
|
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
3
5
|
import _createClass from "@babel/runtime/helpers/createClass";
|
|
@@ -73,12 +75,65 @@ var SiteEmojiResource = /*#__PURE__*/function () {
|
|
|
73
75
|
this.mediaEmojiCache = new MediaEmojiCache(this.tokenManager);
|
|
74
76
|
}
|
|
75
77
|
/**
|
|
76
|
-
* Will
|
|
77
|
-
* the URL has changed.
|
|
78
|
+
* Will generate an emoji media path that is inclusive of client and token within the query parameter
|
|
78
79
|
*/
|
|
79
80
|
|
|
80
81
|
|
|
81
82
|
_createClass(SiteEmojiResource, [{
|
|
83
|
+
key: "generateTokenisedMediaURL",
|
|
84
|
+
value: function () {
|
|
85
|
+
var _generateTokenisedMediaURL = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(emoji) {
|
|
86
|
+
var currentMediaPathURL, currentMediaPathPARAMS, readToken;
|
|
87
|
+
return _regeneratorRuntime.wrap(function _callee$(_context) {
|
|
88
|
+
while (1) {
|
|
89
|
+
switch (_context.prev = _context.next) {
|
|
90
|
+
case 0:
|
|
91
|
+
if (!(emoji && isMediaRepresentation(emoji.representation))) {
|
|
92
|
+
_context.next = 9;
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
currentMediaPathURL = new URL(emoji.representation.mediaPath);
|
|
97
|
+
currentMediaPathPARAMS = currentMediaPathURL.searchParams;
|
|
98
|
+
_context.next = 5;
|
|
99
|
+
return this.tokenManager.getToken('read');
|
|
100
|
+
|
|
101
|
+
case 5:
|
|
102
|
+
readToken = _context.sent;
|
|
103
|
+
|
|
104
|
+
if (currentMediaPathPARAMS.get('token') !== readToken.jwt) {
|
|
105
|
+
currentMediaPathPARAMS.set('token', readToken.jwt);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (currentMediaPathPARAMS.get('client') !== readToken.clientId) {
|
|
109
|
+
currentMediaPathPARAMS.set('client', readToken.clientId);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return _context.abrupt("return", currentMediaPathURL.toString());
|
|
113
|
+
|
|
114
|
+
case 9:
|
|
115
|
+
throw Error('Emoji resource is not of type Media Representation');
|
|
116
|
+
|
|
117
|
+
case 10:
|
|
118
|
+
case "end":
|
|
119
|
+
return _context.stop();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}, _callee, this);
|
|
123
|
+
}));
|
|
124
|
+
|
|
125
|
+
function generateTokenisedMediaURL(_x) {
|
|
126
|
+
return _generateTokenisedMediaURL.apply(this, arguments);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return generateTokenisedMediaURL;
|
|
130
|
+
}()
|
|
131
|
+
/**
|
|
132
|
+
* Will load media emoji, returning a new EmojiDescription if, for example,
|
|
133
|
+
* the URL has changed.
|
|
134
|
+
*/
|
|
135
|
+
|
|
136
|
+
}, {
|
|
82
137
|
key: "loadMediaEmoji",
|
|
83
138
|
value: function loadMediaEmoji(emoji, useAlt) {
|
|
84
139
|
if (!isMediaEmoji(emoji)) {
|
|
@@ -2,7 +2,7 @@ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
|
2
2
|
import _createClass from "@babel/runtime/helpers/createClass";
|
|
3
3
|
import { utils as serviceUtils } from '@atlaskit/util-service-support'; // expire 30 seconds early to factor in latency, slow services, etc
|
|
4
4
|
|
|
5
|
-
export var
|
|
5
|
+
export var EXPIRES_AT_LATENCY_IN_SECONDS = 30;
|
|
6
6
|
|
|
7
7
|
var TokenManager = /*#__PURE__*/function () {
|
|
8
8
|
function TokenManager(siteServiceConfig) {
|
|
@@ -13,6 +13,18 @@ var TokenManager = /*#__PURE__*/function () {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
_createClass(TokenManager, [{
|
|
16
|
+
key: "isValidToken",
|
|
17
|
+
value: function isValidToken(mediaApiToken) {
|
|
18
|
+
var nowInSeconds = Date.now() / 1000;
|
|
19
|
+
var expiresAt = mediaApiToken.expiresAt - EXPIRES_AT_LATENCY_IN_SECONDS;
|
|
20
|
+
|
|
21
|
+
if (nowInSeconds < expiresAt) {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}, {
|
|
16
28
|
key: "addToken",
|
|
17
29
|
value: function addToken(type, mediaApiToken) {
|
|
18
30
|
this.tokens.set(type, {
|
|
@@ -34,10 +46,7 @@ var TokenManager = /*#__PURE__*/function () {
|
|
|
34
46
|
activeTokenRefresh = _tokenDetail.activeTokenRefresh;
|
|
35
47
|
|
|
36
48
|
if (mediaApiToken) {
|
|
37
|
-
|
|
38
|
-
var expiresAt = mediaApiToken.expiresAt - expireAdjustment;
|
|
39
|
-
|
|
40
|
-
if (nowInSeconds < expiresAt && !forceRefresh) {
|
|
49
|
+
if (this.isValidToken(mediaApiToken) && !forceRefresh) {
|
|
41
50
|
// still valid
|
|
42
51
|
return Promise.resolve(mediaApiToken);
|
|
43
52
|
}
|
|
@@ -16,8 +16,7 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
|
|
|
16
16
|
|
|
17
17
|
import React from 'react';
|
|
18
18
|
import { PureComponent } from 'react';
|
|
19
|
-
import {
|
|
20
|
-
import { isEmojiDescription, isMediaEmoji, isPromise } from '../../util/type-helpers';
|
|
19
|
+
import { isMediaEmoji } from '../../util/type-helpers';
|
|
21
20
|
import debug from '../../util/logger';
|
|
22
21
|
import Emoji from './Emoji';
|
|
23
22
|
import EmojiPlaceholder from './EmojiPlaceholder';
|
|
@@ -69,57 +68,44 @@ export var CachingMediaEmoji = /*#__PURE__*/function (_PureComponent) {
|
|
|
69
68
|
|
|
70
69
|
_this = _super.call(this, props);
|
|
71
70
|
|
|
72
|
-
_defineProperty(_assertThisInitialized(_this), "
|
|
73
|
-
|
|
74
|
-
_defineProperty(_assertThisInitialized(_this), "handleLoadError", function (_emojiId, emoji) {
|
|
75
|
-
var invalidImage = _this.state.invalidImage;
|
|
71
|
+
_defineProperty(_assertThisInitialized(_this), "handleLoadError", function (_emojiId) {
|
|
76
72
|
sampledUfoRenderedEmoji(_emojiId).failure({
|
|
77
73
|
metadata: {
|
|
78
74
|
reason: 'load error'
|
|
79
75
|
}
|
|
80
76
|
});
|
|
81
77
|
|
|
82
|
-
if (invalidImage || !emoji) {
|
|
83
|
-
// do nothing, bad image
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
78
|
_this.setState({
|
|
88
|
-
|
|
79
|
+
invalidImage: true
|
|
89
80
|
});
|
|
90
81
|
});
|
|
91
82
|
|
|
92
83
|
_this.state = {
|
|
93
|
-
cachedEmoji:
|
|
84
|
+
cachedEmoji: undefined
|
|
94
85
|
};
|
|
86
|
+
|
|
87
|
+
_this.loadEmoji(props.emoji, context);
|
|
88
|
+
|
|
95
89
|
return _this;
|
|
96
90
|
}
|
|
97
91
|
|
|
98
92
|
_createClass(CachingMediaEmoji, [{
|
|
99
93
|
key: "componentDidMount",
|
|
100
94
|
value: function componentDidMount() {
|
|
101
|
-
this.mounted = true;
|
|
102
95
|
sampledUfoRenderedEmoji(this.props.emoji).markFMP();
|
|
103
96
|
}
|
|
104
97
|
}, {
|
|
105
|
-
key: "
|
|
106
|
-
value: function
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
value: function UNSAFE_componentWillReceiveProps(nextProps, nextContext) {
|
|
112
|
-
if (nextProps.emoji !== this.props.emoji) {
|
|
113
|
-
if (this.mounted) {
|
|
114
|
-
this.setState({
|
|
115
|
-
cachedEmoji: this.loadEmoji(nextProps.emoji, nextContext, false)
|
|
116
|
-
});
|
|
117
|
-
}
|
|
98
|
+
key: "componentDidUpdate",
|
|
99
|
+
value: function componentDidUpdate() {
|
|
100
|
+
var _this$state$cachedEmo;
|
|
101
|
+
|
|
102
|
+
if (this.props.emoji.shortName !== ((_this$state$cachedEmo = this.state.cachedEmoji) === null || _this$state$cachedEmo === void 0 ? void 0 : _this$state$cachedEmo.shortName)) {
|
|
103
|
+
this.loadEmoji(this.props.emoji, this.context);
|
|
118
104
|
}
|
|
119
105
|
}
|
|
120
106
|
}, {
|
|
121
107
|
key: "loadEmoji",
|
|
122
|
-
value: function loadEmoji(emoji, context
|
|
108
|
+
value: function loadEmoji(emoji, context) {
|
|
123
109
|
var _this2 = this;
|
|
124
110
|
|
|
125
111
|
if (!context) {
|
|
@@ -136,53 +122,31 @@ export var CachingMediaEmoji = /*#__PURE__*/function (_PureComponent) {
|
|
|
136
122
|
return undefined;
|
|
137
123
|
}
|
|
138
124
|
|
|
139
|
-
var fitToHeight = this.props.fitToHeight;
|
|
140
|
-
var useAlt = shouldUseAltRepresentation(emoji, fitToHeight);
|
|
141
|
-
var optimisticRendering = emojiProvider.optimisticMediaRendering(emoji, useAlt);
|
|
142
|
-
|
|
143
|
-
if (optimisticRendering && !forceLoad) {
|
|
144
|
-
debug('Optimistic rendering', emoji.shortName);
|
|
145
|
-
return emoji;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
125
|
debug('Loading image via media cache', emoji.shortName);
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}
|
|
159
|
-
}).catch(function () {
|
|
160
|
-
if (_this2.mounted) {
|
|
161
|
-
_this2.setState({
|
|
162
|
-
cachedEmoji: undefined,
|
|
163
|
-
invalidImage: true
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
sampledUfoRenderedEmoji(emoji).failure({
|
|
167
|
-
metadata: {
|
|
168
|
-
reason: 'failed to load media emoji'
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
}
|
|
126
|
+
emojiProvider.getMediaEmojiDescriptionURLWithInlineToken(emoji).then(function (cachedEmoji) {
|
|
127
|
+
_this2.setState({
|
|
128
|
+
cachedEmoji: cachedEmoji,
|
|
129
|
+
invalidImage: false
|
|
130
|
+
});
|
|
131
|
+
}).catch(function () {
|
|
132
|
+
_this2.setState({
|
|
133
|
+
cachedEmoji: undefined,
|
|
134
|
+
invalidImage: true
|
|
172
135
|
});
|
|
173
|
-
return undefined;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
if (isEmojiDescription(loadedEmoji)) {
|
|
177
|
-
return loadedEmoji;
|
|
178
|
-
}
|
|
179
136
|
|
|
180
|
-
|
|
137
|
+
sampledUfoRenderedEmoji(emoji).failure({
|
|
138
|
+
metadata: {
|
|
139
|
+
reason: 'failed to load media emoji'
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
});
|
|
181
143
|
}
|
|
182
144
|
}, {
|
|
183
145
|
key: "render",
|
|
184
146
|
value: function render() {
|
|
185
|
-
var
|
|
147
|
+
var _this$state = this.state,
|
|
148
|
+
cachedEmoji = _this$state.cachedEmoji,
|
|
149
|
+
invalidImage = _this$state.invalidImage;
|
|
186
150
|
|
|
187
151
|
var _this$props = this.props,
|
|
188
152
|
children = _this$props.children,
|
|
@@ -191,7 +155,7 @@ export var CachingMediaEmoji = /*#__PURE__*/function (_PureComponent) {
|
|
|
191
155
|
|
|
192
156
|
var emojiComponent;
|
|
193
157
|
|
|
194
|
-
if (cachedEmoji) {
|
|
158
|
+
if (cachedEmoji && !invalidImage) {
|
|
195
159
|
emojiComponent = /*#__PURE__*/React.createElement(Emoji, _extends({}, otherProps, {
|
|
196
160
|
emoji: cachedEmoji,
|
|
197
161
|
onLoadError: this.handleLoadError
|
package/dist/esm/version.json
CHANGED
|
@@ -69,6 +69,10 @@ export declare class EmojiResource extends AbstractResource<string, EmojiSearchR
|
|
|
69
69
|
protected isLoaded: () => false | EmojiRepository | undefined;
|
|
70
70
|
protected retryIfLoading<T>(retry: Retry<T>, defaultResponse: T): Promise<T>;
|
|
71
71
|
protected notifyResult(result: EmojiSearchResult): void;
|
|
72
|
+
/**
|
|
73
|
+
* Returns the EmojiDescription with a valid media path that includes query token and client attributes to access the emoji media inline.
|
|
74
|
+
*/
|
|
75
|
+
getMediaEmojiDescriptionURLWithInlineToken(emoji: EmojiDescription): Promise<EmojiDescription>;
|
|
72
76
|
loadMediaEmoji(emoji: EmojiDescription, useAlt?: boolean): OptionalEmojiDescription | Promise<OptionalEmojiDescription>;
|
|
73
77
|
optimisticMediaRendering(emoji: EmojiDescription, useAlt?: boolean): boolean;
|
|
74
78
|
filter(query?: string, options?: SearchOptions): void;
|
|
@@ -17,6 +17,10 @@ export default class SiteEmojiResource {
|
|
|
17
17
|
private mediaEmojiCache;
|
|
18
18
|
protected tokenManager: TokenManager;
|
|
19
19
|
constructor(siteServiceConfig: ServiceConfig, mediaApiToken: MediaApiToken);
|
|
20
|
+
/**
|
|
21
|
+
* Will generate an emoji media path that is inclusive of client and token within the query parameter
|
|
22
|
+
*/
|
|
23
|
+
generateTokenisedMediaURL(emoji: EmojiDescription): Promise<string>;
|
|
20
24
|
/**
|
|
21
25
|
* Will load media emoji, returning a new EmojiDescription if, for example,
|
|
22
26
|
* the URL has changed.
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { MediaApiToken } from '../../types';
|
|
2
2
|
import { ServiceConfig } from '@atlaskit/util-service-support';
|
|
3
|
-
export declare const
|
|
3
|
+
export declare const EXPIRES_AT_LATENCY_IN_SECONDS = 30;
|
|
4
4
|
export declare type TokenType = 'read' | 'upload';
|
|
5
5
|
export default class TokenManager {
|
|
6
6
|
private siteServiceConfig;
|
|
7
7
|
private tokens;
|
|
8
8
|
constructor(siteServiceConfig: ServiceConfig);
|
|
9
|
+
isValidToken(mediaApiToken: MediaApiToken): boolean;
|
|
9
10
|
addToken(type: TokenType, mediaApiToken: MediaApiToken): void;
|
|
10
11
|
getToken(type: TokenType, forceRefresh?: boolean): Promise<MediaApiToken>;
|
|
11
12
|
}
|
|
@@ -19,13 +19,11 @@ export declare const CachingEmoji: (props: CachingEmojiProps) => JSX.Element;
|
|
|
19
19
|
* rendering paths depending on caching strategy.
|
|
20
20
|
*/
|
|
21
21
|
export declare class CachingMediaEmoji extends PureComponent<CachingEmojiProps, State> {
|
|
22
|
-
private mounted;
|
|
23
22
|
static contextType: React.Context<EmojiContextType>;
|
|
24
23
|
context: ContextType<typeof EmojiContext>;
|
|
25
24
|
constructor(props: EmojiProps, context: ContextType<typeof EmojiContext>);
|
|
26
25
|
componentDidMount(): void;
|
|
27
|
-
|
|
28
|
-
UNSAFE_componentWillReceiveProps(nextProps: EmojiProps, nextContext: EmojiContextType): void;
|
|
26
|
+
componentDidUpdate(): void;
|
|
29
27
|
private loadEmoji;
|
|
30
28
|
private handleLoadError;
|
|
31
29
|
render(): JSX.Element;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -4,6 +4,12 @@ import { CategoryId } from './components/picker/categories';
|
|
|
4
4
|
import { Provider } from '@atlaskit/util-service-support/types';
|
|
5
5
|
export type { CategoryId } from './components/picker/categories';
|
|
6
6
|
export interface EmojiProvider extends Provider<string, EmojiSearchResult, any, undefined, SearchOptions> {
|
|
7
|
+
/**
|
|
8
|
+
* Returns an immutable copy of EmojiDescription where mediaPath has token and client appended to url
|
|
9
|
+
*
|
|
10
|
+
* Will allow emoji to render site emojis without needing to fail first
|
|
11
|
+
*/
|
|
12
|
+
getMediaEmojiDescriptionURLWithInlineToken(emoji: EmojiDescription): Promise<EmojiDescription>;
|
|
7
13
|
/**
|
|
8
14
|
* Returns the first matching emoji matching the shortName, or null if none found.
|
|
9
15
|
*
|
package/element/package.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/emoji",
|
|
3
|
-
"version": "64.
|
|
3
|
+
"version": "64.6.0",
|
|
4
4
|
"description": "Fabric emoji React components",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"@atlaskit/analytics-next": "^8.2.0",
|
|
30
30
|
"@atlaskit/button": "^16.3.0",
|
|
31
31
|
"@atlaskit/icon": "^21.10.0",
|
|
32
|
-
"@atlaskit/media-client": "^
|
|
32
|
+
"@atlaskit/media-client": "^16.0.0",
|
|
33
33
|
"@atlaskit/spinner": "^15.0.0",
|
|
34
34
|
"@atlaskit/textfield": "^5.1.0",
|
|
35
35
|
"@atlaskit/theme": "^12.1.0",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"@atlaskit/docs": "*",
|
|
55
55
|
"@atlaskit/editor-test-helpers": "^17.0.0",
|
|
56
56
|
"@atlaskit/elements-test-helpers": "^0.7.0",
|
|
57
|
-
"@atlaskit/media-core": "^
|
|
57
|
+
"@atlaskit/media-core": "^33.0.0",
|
|
58
58
|
"@atlaskit/section-message": "^6.0.0",
|
|
59
59
|
"@atlaskit/util-data-test": "^17.2.0",
|
|
60
60
|
"@atlaskit/visual-regression": "*",
|
package/picker/package.json
CHANGED
package/resource/package.json
CHANGED
package/typeahead/package.json
CHANGED
package/types/package.json
CHANGED