@atlaskit/emoji 71.6.5 → 71.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/afm-cc/tsconfig.json +3 -0
- package/afm-products/tsconfig.json +3 -0
- package/dist/cjs/api/ai/generateEmojiImage.js +101 -0
- package/dist/cjs/components/common/CreateEmojiWithRovo.compiled.css +12 -0
- package/dist/cjs/components/common/CreateEmojiWithRovo.js +150 -0
- package/dist/cjs/components/common/EmojiActions.js +6 -2
- package/dist/cjs/components/common/EmojiUploadPicker.js +30 -1
- package/dist/cjs/components/i18n.js +25 -0
- package/dist/cjs/components/picker/EmojiPickerComponent.compiled.css +3 -0
- package/dist/cjs/components/picker/EmojiPickerComponent.js +22 -3
- package/dist/cjs/components/picker/EmojiPickerList.js +6 -2
- package/dist/cjs/components/uploader/EmojiUploadComponent.js +5 -2
- package/dist/cjs/util/ai-emoji.js +72 -0
- package/dist/cjs/util/analytics/analytics.js +14 -2
- package/dist/cjs/util/analytics/index.js +18 -0
- package/dist/es2019/api/ai/generateEmojiImage.js +64 -0
- package/dist/es2019/components/common/CreateEmojiWithRovo.compiled.css +12 -0
- package/dist/es2019/components/common/CreateEmojiWithRovo.js +113 -0
- package/dist/es2019/components/common/EmojiActions.js +6 -2
- package/dist/es2019/components/common/EmojiUploadPicker.js +28 -1
- package/dist/es2019/components/i18n.js +25 -0
- package/dist/es2019/components/picker/EmojiPickerComponent.compiled.css +3 -0
- package/dist/es2019/components/picker/EmojiPickerComponent.js +22 -3
- package/dist/es2019/components/picker/EmojiPickerList.js +6 -2
- package/dist/es2019/components/uploader/EmojiUploadComponent.js +5 -2
- package/dist/es2019/util/ai-emoji.js +64 -0
- package/dist/es2019/util/analytics/analytics.js +5 -1
- package/dist/es2019/util/analytics/index.js +1 -1
- package/dist/esm/api/ai/generateEmojiImage.js +94 -0
- package/dist/esm/components/common/CreateEmojiWithRovo.compiled.css +12 -0
- package/dist/esm/components/common/CreateEmojiWithRovo.js +141 -0
- package/dist/esm/components/common/EmojiActions.js +6 -2
- package/dist/esm/components/common/EmojiUploadPicker.js +30 -1
- package/dist/esm/components/i18n.js +25 -0
- package/dist/esm/components/picker/EmojiPickerComponent.compiled.css +3 -0
- package/dist/esm/components/picker/EmojiPickerComponent.js +22 -3
- package/dist/esm/components/picker/EmojiPickerList.js +6 -2
- package/dist/esm/components/uploader/EmojiUploadComponent.js +5 -2
- package/dist/esm/util/ai-emoji.js +66 -0
- package/dist/esm/util/analytics/analytics.js +13 -1
- package/dist/esm/util/analytics/index.js +1 -1
- package/dist/types/api/ai/generateEmojiImage.d.ts +29 -0
- package/dist/types/components/common/CreateEmojiWithRovo.d.ts +24 -0
- package/dist/types/components/common/EmojiActions.d.ts +11 -0
- package/dist/types/components/common/EmojiUploadPicker.d.ts +9 -0
- package/dist/types/components/i18n.d.ts +25 -0
- package/dist/types/components/picker/EmojiPicker.d.ts +6 -0
- package/dist/types/components/picker/EmojiPickerComponent.d.ts +6 -0
- package/dist/types/components/picker/EmojiPickerList.d.ts +5 -0
- package/dist/types/components/uploader/EmojiUploadComponent.d.ts +2 -0
- package/dist/types/util/ai-emoji.d.ts +41 -0
- package/dist/types/util/analytics/analytics.d.ts +7 -0
- package/dist/types/util/analytics/index.d.ts +1 -1
- package/package.json +7 -2
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure utilities for the "Create an emoji with Rovo" (AI emoji generation) flow.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Maximum length of an auto-generated shortname. Matches the `maxNameLength`
|
|
7
|
+
* used by the manual emoji upload flow (see EmojiUploadPicker).
|
|
8
|
+
*/
|
|
9
|
+
export const MAX_SHORTNAME_LENGTH = 50;
|
|
10
|
+
const LEADING_ARTICLES = ['a', 'an', 'the'];
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Convert a free-text emoji description into a slugified shortname suitable for
|
|
14
|
+
* the `:shortname:` field expected by pf-emoji-service.
|
|
15
|
+
*
|
|
16
|
+
* Rules (v1):
|
|
17
|
+
* - Strip leading articles (a, an, the)
|
|
18
|
+
* - Lowercase
|
|
19
|
+
* - Replace runs of whitespace with a single underscore
|
|
20
|
+
* - Remove any character that is not a-z, 0-9 or underscore
|
|
21
|
+
* - Collapse repeated underscores and trim leading/trailing underscores
|
|
22
|
+
* - Truncate to {@link MAX_SHORTNAME_LENGTH} characters
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* slugifyPrompt('a cat wearing a hard hat') // => 'cat_wearing_a_hard_hat'
|
|
26
|
+
*/
|
|
27
|
+
export const slugifyPrompt = prompt => {
|
|
28
|
+
if (!prompt) {
|
|
29
|
+
return '';
|
|
30
|
+
}
|
|
31
|
+
let words = prompt.trim().toLowerCase().split(/\s+/);
|
|
32
|
+
|
|
33
|
+
// Strip a single leading article only (e.g. "a cat" -> "cat").
|
|
34
|
+
if (words.length > 1 && LEADING_ARTICLES.includes(words[0])) {
|
|
35
|
+
words = words.slice(1);
|
|
36
|
+
}
|
|
37
|
+
const slug = words.join('_')
|
|
38
|
+
// remove everything that is not a word char (letters, digits, underscore)
|
|
39
|
+
.replace(/[^a-z0-9_]/g, '')
|
|
40
|
+
// collapse repeated underscores introduced by removed characters
|
|
41
|
+
.replace(/_+/g, '_')
|
|
42
|
+
// trim leading/trailing underscores
|
|
43
|
+
.replace(/^_+|_+$/g, '');
|
|
44
|
+
return slug.slice(0, MAX_SHORTNAME_LENGTH);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Prefix prepended to the user's description so the header-image backend
|
|
49
|
+
* produces clean, emoji-style output instead of a scene/photo.
|
|
50
|
+
*
|
|
51
|
+
* Kept as a single line (no newlines) — newlines in the prompt can degrade the
|
|
52
|
+
* model's output. Learnings from ShipIt 56 ("Emoji Pop") showed that a simple
|
|
53
|
+
* prompt prefix significantly improved emoji quality.
|
|
54
|
+
*/
|
|
55
|
+
export const EMOJI_PROMPT_PREFIX = 'Generate a clean, simple, emoji-style icon of ';
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Wrap the raw user prompt with the emoji-style prefix.
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* wrapEmojiPrompt('a cat wearing a hard hat')
|
|
62
|
+
* // => 'Generate a clean, simple, emoji-style icon of a cat wearing a hard hat'
|
|
63
|
+
*/
|
|
64
|
+
export const wrapEmojiPrompt = userPrompt => `${EMOJI_PROMPT_PREFIX}${userPrompt.trim()}`;
|
|
@@ -9,7 +9,7 @@ const createEvent = (eventType, action, actionSubject, actionSubjectId, attribut
|
|
|
9
9
|
actionSubjectId,
|
|
10
10
|
attributes: {
|
|
11
11
|
packageName: "@atlaskit/emoji",
|
|
12
|
-
packageVersion: "71.6.
|
|
12
|
+
packageVersion: "71.6.6",
|
|
13
13
|
...attributes
|
|
14
14
|
}
|
|
15
15
|
});
|
|
@@ -91,6 +91,10 @@ export const uploadConfirmButton = attributes => emojiUploaderEvent('clicked', '
|
|
|
91
91
|
export const uploadCancelButton = () => emojiUploaderEvent('clicked', 'cancelButton');
|
|
92
92
|
export const uploadSucceededEvent = attributes => createEvent('operational', 'finished', 'emojiUploader', undefined, attributes);
|
|
93
93
|
export const uploadFailedEvent = attributes => createEvent('operational', 'failed', 'emojiUploader', undefined, attributes);
|
|
94
|
+
const aiEmojiGenerationEvent = (action, actionSubjectId, attributes) => createEvent('ui', action, 'emojiPickerAiGeneration', actionSubjectId, attributes);
|
|
95
|
+
export const aiGenerationStartedEvent = attributes => aiEmojiGenerationEvent('started', 'generateButton', attributes);
|
|
96
|
+
export const aiGenerationCompletedEvent = attributes => createEvent('operational', 'completed', 'emojiPickerAiGeneration', undefined, attributes);
|
|
97
|
+
export const aiGenerationFailedEvent = attributes => createEvent('operational', 'failed', 'emojiPickerAiGeneration', undefined, attributes);
|
|
94
98
|
export const deleteBeginEvent = attributes => createEvent('ui', 'clicked', 'emojiPicker', 'deleteEmojiTrigger', attributes);
|
|
95
99
|
export const deleteConfirmEvent = attributes => createEvent('ui', 'clicked', 'emojiPicker', 'deleteEmojiConfirm', attributes);
|
|
96
100
|
export const deleteCancelEvent = attributes => createEvent('ui', 'clicked', 'emojiPicker', 'deleteEmojiCancel', attributes);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { ufoExperiencesSampled, clearSampled, isExperienceSampled, withSampling } from './samplingUfo';
|
|
2
|
-
export { categoryClickedEvent, createAndFireEventInElementsChannel, closedPickerEvent, deleteBeginEvent, deleteCancelEvent, deleteConfirmEvent, recordFailed, recordFailedEmoji, recordSucceeded, recordSucceededEmoji, openedPickerEvent, pickerClickedEvent, pickerSearchedEvent, recordSelectionFailedSli, recordSelectionSucceededSli, selectedFileEvent, toneSelectedEvent, toneSelectorClosedEvent, toneSelectorOpenedEvent, typeaheadCancelledEvent, typeaheadRenderedEvent, typeaheadSelectedEvent, uploadBeginButton, uploadCancelButton, uploadConfirmButton, uploadFailedEvent, uploadSucceededEvent } from './analytics';
|
|
2
|
+
export { aiGenerationStartedEvent, aiGenerationCompletedEvent, aiGenerationFailedEvent, categoryClickedEvent, createAndFireEventInElementsChannel, closedPickerEvent, deleteBeginEvent, deleteCancelEvent, deleteConfirmEvent, recordFailed, recordFailedEmoji, recordSucceeded, recordSucceededEmoji, openedPickerEvent, pickerClickedEvent, pickerSearchedEvent, recordSelectionFailedSli, recordSelectionSucceededSli, selectedFileEvent, toneSelectedEvent, toneSelectorClosedEvent, toneSelectorOpenedEvent, typeaheadCancelledEvent, typeaheadRenderedEvent, typeaheadSelectedEvent, uploadBeginButton, uploadCancelButton, uploadConfirmButton, uploadFailedEvent, uploadSucceededEvent } from './analytics';
|
|
3
3
|
export { sampledUfoRenderedEmoji, ufoExperiences } from './ufoExperiences';
|
|
4
4
|
export { useSampledUFOComponentExperience } from './useSampledUFOComponentExperience';
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
2
|
+
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
3
|
+
/**
|
|
4
|
+
* Calls the Confluence "header image" AI backend to generate an emoji-style
|
|
5
|
+
* image (base64) from a text description.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { wrapEmojiPrompt } from '../../util/ai-emoji';
|
|
9
|
+
import debug from '../../util/logger';
|
|
10
|
+
var HEADER_IMAGE_GENERATION_ENDPOINT = '/gateway/api/assist/api/ai/v2/ai-feature/confluence-header-image-generation';
|
|
11
|
+
|
|
12
|
+
/** Emojis are square, so we always request a 1:1 image from the BE. */
|
|
13
|
+
var EMOJI_ASPECT_RATIO = '1:1';
|
|
14
|
+
|
|
15
|
+
/** Shape of the `ai_feature_output` envelope returned by the BE. */
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Generate an emoji-style image and return its base64 image data.
|
|
19
|
+
*
|
|
20
|
+
* @throws Error if the request fails, the BE returns a body-level error, or no
|
|
21
|
+
* image data is returned.
|
|
22
|
+
*/
|
|
23
|
+
export var generateEmojiImage = /*#__PURE__*/function () {
|
|
24
|
+
var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(_ref) {
|
|
25
|
+
var contentId, prompt, wrappedPrompt, response, json, output;
|
|
26
|
+
return _regeneratorRuntime.wrap(function (_context) {
|
|
27
|
+
while (1) switch (_context.prev = _context.next) {
|
|
28
|
+
case 0:
|
|
29
|
+
contentId = _ref.contentId, prompt = _ref.prompt;
|
|
30
|
+
wrappedPrompt = wrapEmojiPrompt(prompt);
|
|
31
|
+
_context.next = 1;
|
|
32
|
+
return fetch(HEADER_IMAGE_GENERATION_ENDPOINT, {
|
|
33
|
+
method: 'POST',
|
|
34
|
+
headers: {
|
|
35
|
+
'content-type': 'application/json;charset=UTF-8',
|
|
36
|
+
'X-Experience-Id': 'confluence-ai-first-creation',
|
|
37
|
+
'X-Product': 'confluence'
|
|
38
|
+
},
|
|
39
|
+
body: JSON.stringify({
|
|
40
|
+
ai_feature_input: {
|
|
41
|
+
adfContent: wrappedPrompt,
|
|
42
|
+
contentId: contentId,
|
|
43
|
+
useRawPrompt: true,
|
|
44
|
+
// Emojis are square — request a 1:1 image from the BE.
|
|
45
|
+
aspectRatio: EMOJI_ASPECT_RATIO
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
});
|
|
49
|
+
case 1:
|
|
50
|
+
response = _context.sent;
|
|
51
|
+
if (response.ok) {
|
|
52
|
+
_context.next = 2;
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
debug('generateEmojiImage failed', response.status);
|
|
56
|
+
throw new Error("Emoji image generation failed with status ".concat(response.status));
|
|
57
|
+
case 2:
|
|
58
|
+
_context.next = 3;
|
|
59
|
+
return response.json();
|
|
60
|
+
case 3:
|
|
61
|
+
json = _context.sent;
|
|
62
|
+
output = json === null || json === void 0 ? void 0 : json.ai_feature_output;
|
|
63
|
+
if (output) {
|
|
64
|
+
_context.next = 4;
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
throw new Error('Emoji image generation returned no content');
|
|
68
|
+
case 4:
|
|
69
|
+
if (!output.error) {
|
|
70
|
+
_context.next = 5;
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
throw new Error(output.error.error_message || output.error.error_reason || 'Emoji image generation failed');
|
|
74
|
+
case 5:
|
|
75
|
+
if (output.imageData) {
|
|
76
|
+
_context.next = 6;
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
throw new Error('Emoji image generation did not return image data');
|
|
80
|
+
case 6:
|
|
81
|
+
return _context.abrupt("return", {
|
|
82
|
+
imageData: output.imageData,
|
|
83
|
+
mediaFileId: output.mediaFileId
|
|
84
|
+
});
|
|
85
|
+
case 7:
|
|
86
|
+
case "end":
|
|
87
|
+
return _context.stop();
|
|
88
|
+
}
|
|
89
|
+
}, _callee);
|
|
90
|
+
}));
|
|
91
|
+
return function generateEmojiImage(_x) {
|
|
92
|
+
return _ref2.apply(this, arguments);
|
|
93
|
+
};
|
|
94
|
+
}();
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
|
|
2
|
+
._zulp12x7{gap:var(--ds-space-075,6px)}
|
|
3
|
+
._zulpu2gc{gap:var(--ds-space-100,8px)}
|
|
4
|
+
._x3doia51{border-top:var(--ds-border-width,1px) solid var(--ds-border,#0b120e24)}._16jlkb7n{flex-grow:1}
|
|
5
|
+
._19pku2gc{margin-top:var(--ds-space-100,8px)}
|
|
6
|
+
._1e0c1txw{display:flex}
|
|
7
|
+
._1o9zkb7n{flex-shrink:1}
|
|
8
|
+
._2lx21bp4{flex-direction:column}
|
|
9
|
+
._4cvr1h6o{align-items:center}
|
|
10
|
+
._4cvr1y6m{align-items:flex-start}
|
|
11
|
+
._ca0qutpp{padding-top:var(--ds-space-150,9pt)}
|
|
12
|
+
._i0dlf1ug{flex-basis:0%}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/* CreateEmojiWithRovo.tsx generated by @compiled/babel-plugin v0.39.1 */
|
|
2
|
+
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
|
|
3
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
4
|
+
import "./CreateEmojiWithRovo.compiled.css";
|
|
5
|
+
import * as React from 'react';
|
|
6
|
+
import { ax, ix } from "@compiled/react/runtime";
|
|
7
|
+
import _regeneratorRuntime from "@babel/runtime/regenerator";
|
|
8
|
+
import { useCallback, useState } from 'react';
|
|
9
|
+
import { FormattedMessage, useIntl } from 'react-intl';
|
|
10
|
+
import { IconButton } from '@atlaskit/button/new';
|
|
11
|
+
import TextField from '@atlaskit/textfield';
|
|
12
|
+
import ArrowUpIcon from '@atlaskit/icon/core/arrow-up';
|
|
13
|
+
import { RovoIcon } from '@atlaskit/logo';
|
|
14
|
+
import { Text } from '@atlaskit/primitives/compiled';
|
|
15
|
+
import { generateEmojiImage } from '../../api/ai/generateEmojiImage';
|
|
16
|
+
import { slugifyPrompt } from '../../util/ai-emoji';
|
|
17
|
+
import { aiGenerationStartedEvent, aiGenerationCompletedEvent, aiGenerationFailedEvent } from '../../util/analytics';
|
|
18
|
+
import { messages } from '../i18n';
|
|
19
|
+
import EmojiErrorMessage from './EmojiErrorMessage';
|
|
20
|
+
export var createEmojiWithRovoTestId = 'create-emoji-with-rovo';
|
|
21
|
+
export var createEmojiWithRovoPromptTestId = 'create-emoji-with-rovo-prompt';
|
|
22
|
+
export var createEmojiWithRovoGenerateTestId = 'create-emoji-with-rovo-generate';
|
|
23
|
+
var sectionStyles = null;
|
|
24
|
+
var headerStyles = null;
|
|
25
|
+
var promptRowStyles = null;
|
|
26
|
+
var promptInputStyles = null;
|
|
27
|
+
var CreateEmojiWithRovo = function CreateEmojiWithRovo(props) {
|
|
28
|
+
var contentId = props.contentId,
|
|
29
|
+
fireAnalytics = props.fireAnalytics,
|
|
30
|
+
onEmojiGenerated = props.onEmojiGenerated;
|
|
31
|
+
var _useIntl = useIntl(),
|
|
32
|
+
formatMessage = _useIntl.formatMessage;
|
|
33
|
+
var _useState = useState(''),
|
|
34
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
35
|
+
prompt = _useState2[0],
|
|
36
|
+
setPrompt = _useState2[1];
|
|
37
|
+
var _useState3 = useState(false),
|
|
38
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
39
|
+
isGenerating = _useState4[0],
|
|
40
|
+
setIsGenerating = _useState4[1];
|
|
41
|
+
var _useState5 = useState(false),
|
|
42
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
43
|
+
hasError = _useState6[0],
|
|
44
|
+
setHasError = _useState6[1];
|
|
45
|
+
var onPromptChange = useCallback(function (event) {
|
|
46
|
+
setPrompt(event.target.value);
|
|
47
|
+
// Clear any previous error as soon as the user edits the prompt to retry.
|
|
48
|
+
setHasError(false);
|
|
49
|
+
}, []);
|
|
50
|
+
var onGenerate = useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
|
|
51
|
+
var trimmedPrompt, startTime, _yield$generateEmojiI, imageData, dataURL, suggestedName, _t;
|
|
52
|
+
return _regeneratorRuntime.wrap(function (_context) {
|
|
53
|
+
while (1) switch (_context.prev = _context.next) {
|
|
54
|
+
case 0:
|
|
55
|
+
trimmedPrompt = prompt.trim();
|
|
56
|
+
if (!(!trimmedPrompt || isGenerating)) {
|
|
57
|
+
_context.next = 1;
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
return _context.abrupt("return");
|
|
61
|
+
case 1:
|
|
62
|
+
setHasError(false);
|
|
63
|
+
setIsGenerating(true);
|
|
64
|
+
fireAnalytics === null || fireAnalytics === void 0 || fireAnalytics(aiGenerationStartedEvent({
|
|
65
|
+
promptLength: trimmedPrompt.length
|
|
66
|
+
}));
|
|
67
|
+
startTime = Date.now();
|
|
68
|
+
_context.prev = 2;
|
|
69
|
+
_context.next = 3;
|
|
70
|
+
return generateEmojiImage({
|
|
71
|
+
contentId: contentId,
|
|
72
|
+
prompt: trimmedPrompt
|
|
73
|
+
});
|
|
74
|
+
case 3:
|
|
75
|
+
_yield$generateEmojiI = _context.sent;
|
|
76
|
+
imageData = _yield$generateEmojiI.imageData;
|
|
77
|
+
dataURL = "data:image/png;base64,".concat(imageData);
|
|
78
|
+
suggestedName = slugifyPrompt(trimmedPrompt);
|
|
79
|
+
fireAnalytics === null || fireAnalytics === void 0 || fireAnalytics(aiGenerationCompletedEvent({
|
|
80
|
+
duration: Date.now() - startTime
|
|
81
|
+
}));
|
|
82
|
+
// Hand the generated image to the parent upload form.
|
|
83
|
+
onEmojiGenerated(dataURL, suggestedName);
|
|
84
|
+
_context.next = 5;
|
|
85
|
+
break;
|
|
86
|
+
case 4:
|
|
87
|
+
_context.prev = 4;
|
|
88
|
+
_t = _context["catch"](2);
|
|
89
|
+
setHasError(true);
|
|
90
|
+
fireAnalytics === null || fireAnalytics === void 0 || fireAnalytics(aiGenerationFailedEvent({
|
|
91
|
+
errorType: _t instanceof Error ? _t.message : 'generation_failed'
|
|
92
|
+
}));
|
|
93
|
+
case 5:
|
|
94
|
+
_context.prev = 5;
|
|
95
|
+
setIsGenerating(false);
|
|
96
|
+
return _context.finish(5);
|
|
97
|
+
case 6:
|
|
98
|
+
case "end":
|
|
99
|
+
return _context.stop();
|
|
100
|
+
}
|
|
101
|
+
}, _callee, null, [[2, 4, 5, 6]]);
|
|
102
|
+
})), [contentId, fireAnalytics, isGenerating, onEmojiGenerated, prompt]);
|
|
103
|
+
var generateDisabled = !prompt.trim() || isGenerating;
|
|
104
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
105
|
+
"data-testid": createEmojiWithRovoTestId,
|
|
106
|
+
className: ax(["_zulpu2gc _x3doia51 _1e0c1txw _2lx21bp4 _ca0qutpp _19pku2gc"])
|
|
107
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
108
|
+
className: ax(["_zulp12x7 _1e0c1txw _4cvr1h6o"])
|
|
109
|
+
}, /*#__PURE__*/React.createElement(RovoIcon, {
|
|
110
|
+
appearance: "brand",
|
|
111
|
+
size: "xsmall",
|
|
112
|
+
label: formatMessage(messages.createEmojiWithRovoTitle)
|
|
113
|
+
}), /*#__PURE__*/React.createElement(Text, {
|
|
114
|
+
size: "medium",
|
|
115
|
+
weight: "bold"
|
|
116
|
+
}, /*#__PURE__*/React.createElement(FormattedMessage, messages.createEmojiWithRovoTitle))), /*#__PURE__*/React.createElement("div", {
|
|
117
|
+
className: ax(["_zulpu2gc _1e0c1txw _4cvr1y6m"])
|
|
118
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
119
|
+
className: ax(["_16jlkb7n _1o9zkb7n _i0dlf1ug"])
|
|
120
|
+
}, /*#__PURE__*/React.createElement(TextField, {
|
|
121
|
+
value: prompt,
|
|
122
|
+
onChange: onPromptChange,
|
|
123
|
+
placeholder: formatMessage(messages.createEmojiWithRovoPromptPlaceholder),
|
|
124
|
+
"aria-label": formatMessage(messages.createEmojiWithRovoPromptAriaLabel),
|
|
125
|
+
isCompact: true,
|
|
126
|
+
isDisabled: isGenerating,
|
|
127
|
+
testId: createEmojiWithRovoPromptTestId
|
|
128
|
+
})), /*#__PURE__*/React.createElement(IconButton, {
|
|
129
|
+
appearance: "primary",
|
|
130
|
+
icon: ArrowUpIcon,
|
|
131
|
+
label: formatMessage(messages.createEmojiWithRovoGenerateLabel),
|
|
132
|
+
isDisabled: generateDisabled,
|
|
133
|
+
isLoading: isGenerating,
|
|
134
|
+
onClick: onGenerate,
|
|
135
|
+
testId: createEmojiWithRovoGenerateTestId
|
|
136
|
+
})), hasError && /*#__PURE__*/React.createElement(EmojiErrorMessage, {
|
|
137
|
+
errorStyle: "chooseFile",
|
|
138
|
+
message: /*#__PURE__*/React.createElement(FormattedMessage, messages.createEmojiWithRovoError)
|
|
139
|
+
}));
|
|
140
|
+
};
|
|
141
|
+
export default CreateEmojiWithRovo;
|
|
@@ -317,7 +317,9 @@ export var EmojiActions = function EmojiActions(props) {
|
|
|
317
317
|
onUploadEmoji: onUploadEmoji,
|
|
318
318
|
onFileChooserClicked: onFileChooserClicked,
|
|
319
319
|
errorMessage: uploadErrorMessage,
|
|
320
|
-
initialUploadName: initialUploadName
|
|
320
|
+
initialUploadName: initialUploadName,
|
|
321
|
+
contentId: props.contentId,
|
|
322
|
+
fireAnalytics: props.fireAnalytics
|
|
321
323
|
})) : /*#__PURE__*/React.createElement("div", {
|
|
322
324
|
className: ax(["_16jlidpf _1o9zidpf _i0dl1wug _n7zl1uh4 _16qsjgpa"])
|
|
323
325
|
}, /*#__PURE__*/React.createElement(EmojiUploadPicker, {
|
|
@@ -325,7 +327,9 @@ export var EmojiActions = function EmojiActions(props) {
|
|
|
325
327
|
onUploadEmoji: onUploadEmoji,
|
|
326
328
|
onFileChooserClicked: onFileChooserClicked,
|
|
327
329
|
errorMessage: uploadErrorMessage,
|
|
328
|
-
initialUploadName: initialUploadName
|
|
330
|
+
initialUploadName: initialUploadName,
|
|
331
|
+
contentId: props.contentId,
|
|
332
|
+
fireAnalytics: props.fireAnalytics
|
|
329
333
|
}));
|
|
330
334
|
}
|
|
331
335
|
if (emojiToDelete) {
|
|
@@ -13,6 +13,7 @@ import AkButton from '@atlaskit/button/standard-button';
|
|
|
13
13
|
import { Text } from '@atlaskit/primitives/compiled';
|
|
14
14
|
import FocusLock from 'react-focus-lock';
|
|
15
15
|
import * as ImageUtil from '../../util/image';
|
|
16
|
+
import CreateEmojiWithRovo from './CreateEmojiWithRovo';
|
|
16
17
|
import debug from '../../util/logger';
|
|
17
18
|
import { messages } from '../i18n';
|
|
18
19
|
import EmojiErrorMessage from './EmojiErrorMessage';
|
|
@@ -21,6 +22,7 @@ import FileChooser from './FileChooser';
|
|
|
21
22
|
import { UploadStatus } from './internal-types';
|
|
22
23
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
23
24
|
import FeatureGates from '@atlaskit/feature-gate-js-client';
|
|
25
|
+
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
24
26
|
import Button from '@atlaskit/button/new';
|
|
25
27
|
import { Box } from '@atlaskit/primitives/compiled';
|
|
26
28
|
import { getDocument } from '@atlaskit/browser-apis';
|
|
@@ -91,6 +93,7 @@ var ChooseEmojiFile = /*#__PURE__*/memo(function (props) {
|
|
|
91
93
|
nameErrorMessage = props.nameErrorMessage,
|
|
92
94
|
previewImage = props.previewImage,
|
|
93
95
|
uploadStatus = props.uploadStatus,
|
|
96
|
+
aiSection = props.aiSection,
|
|
94
97
|
intl = props.intl;
|
|
95
98
|
var formatMessage = intl.formatMessage;
|
|
96
99
|
var disableChooser = !name;
|
|
@@ -139,7 +142,7 @@ var ChooseEmojiFile = /*#__PURE__*/memo(function (props) {
|
|
|
139
142
|
}, errorMessage && /*#__PURE__*/React.createElement(EmojiErrorMessage, {
|
|
140
143
|
errorStyle: "chooseFile",
|
|
141
144
|
message: errorMessage
|
|
142
|
-
}))), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", {
|
|
145
|
+
}))), aiSection, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("label", {
|
|
143
146
|
htmlFor: "new-emoji-name-input",
|
|
144
147
|
className: ax(["_1w90azsu", "_11c8wadc _k48p1pd9"])
|
|
145
148
|
}, /*#__PURE__*/React.createElement(FormattedMessage, messages.emojiNameLabel)), /*#__PURE__*/React.createElement(TextField, {
|
|
@@ -237,6 +240,8 @@ var EmojiUploadPicker = function EmojiUploadPicker(props) {
|
|
|
237
240
|
onUploadCancelled = props.onUploadCancelled,
|
|
238
241
|
_props$disableFocusLo = props.disableFocusLock,
|
|
239
242
|
disableFocusLock = _props$disableFocusLo === void 0 ? false : _props$disableFocusLo,
|
|
243
|
+
contentId = props.contentId,
|
|
244
|
+
fireAnalytics = props.fireAnalytics,
|
|
240
245
|
intl = props.intl;
|
|
241
246
|
var _useState = useState(errorMessage ? UploadStatus.Error : UploadStatus.Waiting),
|
|
242
247
|
_useState2 = _slicedToArray(_useState, 2),
|
|
@@ -320,6 +325,18 @@ var EmojiUploadPicker = function EmojiUploadPicker(props) {
|
|
|
320
325
|
var cancelChooseFile = useCallback(function () {
|
|
321
326
|
setPreviewImage(undefined);
|
|
322
327
|
}, []);
|
|
328
|
+
|
|
329
|
+
// When the Rovo section generates an image, feed it into the existing upload
|
|
330
|
+
// form (same preview, name field and "Add emoji" button as a manual upload).
|
|
331
|
+
var onEmojiGenerated = useCallback(function (dataURL, suggestedName) {
|
|
332
|
+
setFilename('rovo-emoji.png');
|
|
333
|
+
setPreviewImage(dataURL);
|
|
334
|
+
setChooseEmojiErrorMessage(undefined);
|
|
335
|
+
// Only auto-populate the name if the user hasn't already typed one.
|
|
336
|
+
setName(function (current) {
|
|
337
|
+
return current || sanitizeName(suggestedName);
|
|
338
|
+
});
|
|
339
|
+
}, []);
|
|
323
340
|
var errorOnUpload = useCallback(function (event) {
|
|
324
341
|
debug('File load error: ', event);
|
|
325
342
|
setChooseEmojiErrorMessage( /*#__PURE__*/React.createElement(FormattedMessage, messages.emojiUploadFailed));
|
|
@@ -403,6 +420,17 @@ var EmojiUploadPicker = function EmojiUploadPicker(props) {
|
|
|
403
420
|
onFileChooserClicked && onFileChooserClicked();
|
|
404
421
|
};
|
|
405
422
|
var isDuplicateNameError = errorMessage !== null && errorMessage !== undefined && isRefreshEmojiPickerEnabled();
|
|
423
|
+
|
|
424
|
+
// "Create an emoji with Rovo" AI generation section. Only rendered when the
|
|
425
|
+
// experiment is on AND a page content id is available (the image generation
|
|
426
|
+
// backend requires it). It is rendered inside ChooseEmojiFile (between the
|
|
427
|
+
// drop area and the Emoji name field) so the generated image reuses the
|
|
428
|
+
// single shared name field and "Add emoji" button.
|
|
429
|
+
var aiSection = contentId && expValEquals('confluence_ai_generated_emojis', 'isEnabled', true) ? /*#__PURE__*/React.createElement(CreateEmojiWithRovo, {
|
|
430
|
+
contentId: contentId,
|
|
431
|
+
fireAnalytics: fireAnalytics,
|
|
432
|
+
onEmojiGenerated: onEmojiGenerated
|
|
433
|
+
}) : null;
|
|
406
434
|
var content = name && previewImage && !isRefreshEmojiPickerEnabled() ? /*#__PURE__*/React.createElement(EmojiUploadPreview, {
|
|
407
435
|
errorMessage: errorMessage,
|
|
408
436
|
name: name,
|
|
@@ -421,6 +449,7 @@ var EmojiUploadPicker = function EmojiUploadPicker(props) {
|
|
|
421
449
|
uploadStatus: uploadStatus,
|
|
422
450
|
errorMessage: chooseEmojiErrorMessage,
|
|
423
451
|
nameErrorMessage: isDuplicateNameError ? errorMessage : undefined,
|
|
452
|
+
aiSection: aiSection,
|
|
424
453
|
intl: intl
|
|
425
454
|
});
|
|
426
455
|
return disableFocusLock || isRefreshEmojiPickerEnabled() ? content : /*#__PURE__*/React.createElement(FocusLock, {
|
|
@@ -100,6 +100,31 @@ export var messages = defineMessages({
|
|
|
100
100
|
defaultMessage: 'Add emoji',
|
|
101
101
|
description: 'Label for the submit button in the custom emoji upload panel that saves the new emoji to the workspace.'
|
|
102
102
|
},
|
|
103
|
+
createEmojiWithRovoTitle: {
|
|
104
|
+
id: 'fabric.emoji.ai.create.title',
|
|
105
|
+
defaultMessage: 'Create an emoji with Rovo',
|
|
106
|
+
description: 'Section heading for the AI emoji generation area where users describe an emoji and generate it with AI.'
|
|
107
|
+
},
|
|
108
|
+
createEmojiWithRovoPromptPlaceholder: {
|
|
109
|
+
id: 'fabric.emoji.ai.prompt.placeholder',
|
|
110
|
+
defaultMessage: 'Describe your emoji...',
|
|
111
|
+
description: 'Placeholder text for the input where the user describes the emoji they want the AI to generate.'
|
|
112
|
+
},
|
|
113
|
+
createEmojiWithRovoPromptAriaLabel: {
|
|
114
|
+
id: 'fabric.emoji.ai.prompt.ariaLabel',
|
|
115
|
+
defaultMessage: 'Describe the emoji you want to generate',
|
|
116
|
+
description: 'Accessible label for the AI emoji description input field.'
|
|
117
|
+
},
|
|
118
|
+
createEmojiWithRovoGenerateLabel: {
|
|
119
|
+
id: 'fabric.emoji.ai.generate.label',
|
|
120
|
+
defaultMessage: 'Generate',
|
|
121
|
+
description: 'Label for the button that triggers AI generation of the described emoji.'
|
|
122
|
+
},
|
|
123
|
+
createEmojiWithRovoError: {
|
|
124
|
+
id: 'fabric.emoji.ai.error',
|
|
125
|
+
defaultMessage: 'Something went wrong. Try a different description.',
|
|
126
|
+
description: 'Inline error message shown when AI emoji generation or upload fails, prompting the user to try again.'
|
|
127
|
+
},
|
|
103
128
|
retryLabel: {
|
|
104
129
|
id: 'fabric.emoji.retry.label',
|
|
105
130
|
defaultMessage: 'Retry',
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
._2rkofajl{border-radius:var(--ds-radius-small,3px)}._16jlkb7n{flex-grow:1}
|
|
5
5
|
._16qs130s{box-shadow:var(--ds-shadow-overlay,0 8px 9pt #1e1f2126,0 0 1px #1e1f214f)}
|
|
6
6
|
._18m915vq{overflow-y:hidden}
|
|
7
|
+
._18m91wug{overflow-y:auto}
|
|
7
8
|
._1bah1yb4{justify-content:space-between}
|
|
8
9
|
._1bsb10mj{width:var(--_gsvyy7)}
|
|
9
10
|
._1e0c1txw{display:flex}
|
|
@@ -27,11 +28,13 @@
|
|
|
27
28
|
._4t3ibqjm{height:310px}
|
|
28
29
|
._4t3iihnn{height:434px}
|
|
29
30
|
._4t3iixjv{height:375px}
|
|
31
|
+
._4t3ikbql{height:450px}
|
|
30
32
|
._4t3iqbeb{height:339px}
|
|
31
33
|
._4t3iuxo9{height:var(--_19dn98e)}
|
|
32
34
|
._4t3ivixp{height:349px}
|
|
33
35
|
._4t3ixt2k{height:509px}
|
|
34
36
|
._bfhk1bhr{background-color:var(--ds-surface-overlay,#fff)}
|
|
35
37
|
._c71l1y6z{max-height:calc(80vh - 86px)}
|
|
38
|
+
._c71l8k0t{max-height:calc(100vh - 86px)}
|
|
36
39
|
._i0dlf1ug{flex-basis:0%}
|
|
37
40
|
._kqswh2mm{position:relative}
|
|
@@ -35,6 +35,7 @@ import { useIsMounted } from '../../hooks/useIsMounted';
|
|
|
35
35
|
import { messages } from '../i18n';
|
|
36
36
|
import { defaultProductivityColor, getStoredProductivityColor, storeProductivityColor } from '../../util/productivity-colors';
|
|
37
37
|
import { filterHiddenEmojis } from '../../util/hidden-emojis';
|
|
38
|
+
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
38
39
|
var isRefreshEmojiPickerEnabled = function isRefreshEmojiPickerEnabled() {
|
|
39
40
|
if (!FeatureGates.initializeCompleted()) {
|
|
40
41
|
return false;
|
|
@@ -55,6 +56,17 @@ var heightOffset = 80;
|
|
|
55
56
|
var emojiPicker = null;
|
|
56
57
|
var emojiPickerNew = null;
|
|
57
58
|
var emojiPickerWrapper = null;
|
|
59
|
+
|
|
60
|
+
// When the "Create an emoji with Rovo" section is shown in the upload panel the
|
|
61
|
+
// picker needs more vertical room than the fixed upload height. Make it tall
|
|
62
|
+
// enough to fit the whole section without scrolling, but still let it scroll as
|
|
63
|
+
// a safety net on very short viewports.
|
|
64
|
+
var emojiPickerWrapperScrollable = null;
|
|
65
|
+
|
|
66
|
+
// When the AI emoji experiment is on, grow the upload panel from its default
|
|
67
|
+
// height to 450px so the manual upload form + the slim "Create an emoji with
|
|
68
|
+
// Rovo" section are both visible without scrolling.
|
|
69
|
+
var withAiUploadHeight = null;
|
|
58
70
|
var withPreviewHeight = {
|
|
59
71
|
small: "_4t3ivixp _1tkegx0z",
|
|
60
72
|
medium: "_4t3i2300 _1tke5x59",
|
|
@@ -87,6 +99,7 @@ var EmojiPickerComponent = function EmojiPickerComponent(_ref) {
|
|
|
87
99
|
onPickerRef = _ref.onPickerRef,
|
|
88
100
|
hideToneSelector = _ref.hideToneSelector,
|
|
89
101
|
createAnalyticsEvent = _ref.createAnalyticsEvent,
|
|
102
|
+
contentId = _ref.contentId,
|
|
90
103
|
_ref$size = _ref.size,
|
|
91
104
|
size = _ref$size === void 0 ? defaultEmojiPickerSize : _ref$size;
|
|
92
105
|
var _useIntl = useIntl(),
|
|
@@ -660,13 +673,17 @@ var EmojiPickerComponent = function EmojiPickerComponent(_ref) {
|
|
|
660
673
|
var showPreview = isRefreshEmojiPickerEnabled() ? !uploading : selectedEmoji && !uploading;
|
|
661
674
|
var shouldRenderFooter = showPreview && !(emojiToDelete && isRefreshEmojiPickerEnabled()) && !(query && filteredEmojis.length === 0 && isRefreshEmojiPickerEnabled()) && (Boolean(selectedEmoji) || uploadEnabled || !isRefreshEmojiPickerEnabled());
|
|
662
675
|
var useFooterSpaceForList = showPreview && !selectedEmoji && !uploadEnabled && !emojiToDelete && !(query && filteredEmojis.length === 0) && isRefreshEmojiPickerEnabled();
|
|
676
|
+
|
|
677
|
+
// When the AI emoji section is shown in the upload panel, grow the picker so
|
|
678
|
+
// the section isn't clipped by the fixed upload height.
|
|
679
|
+
var showAiUpload = uploading && !!contentId && expValEquals('confluence_ai_generated_emojis', 'isEnabled', true);
|
|
663
680
|
return /*#__PURE__*/React.createElement("div", {
|
|
664
681
|
ref: setPickerRef,
|
|
665
682
|
"data-emoji-picker-container": true,
|
|
666
683
|
role: "dialog",
|
|
667
684
|
"aria-label": formatMessage(messages.emojiPickerTitle),
|
|
668
685
|
"aria-modal": true,
|
|
669
|
-
className: ax([isRefreshEmojiPickerEnabled() ? "_19itahnd _2rko1mok _1e0c1txw _2lx21bp4 _1bah1yb4 _bfhk1bhr _16qs130s _4t3iuxo9 _1bsb10mj _1ul910mj _c71l1y6z _kqswh2mm" : "_19itahnd _2rkofajl _1e0c1txw _2lx21bp4 _1bah1yb4 _bfhk1bhr _16qs130s _4t3iuxo9 _1bsb10mj _1ul910mj _c71l1y6z _kqswh2mm", !!emojiToDelete && isRefreshEmojiPickerEnabled() ? withDeleteRefreshHeight[size] : uploading && isRefreshEmojiPickerEnabled() ? withUploadRefreshHeight[size] : query && filteredEmojis.length === 0 && isRefreshEmojiPickerEnabled() ? withNoResultsRefreshHeight[size] : showPreview ? withPreviewHeight[size] : withoutPreviewHeight[size]]),
|
|
686
|
+
className: ax([isRefreshEmojiPickerEnabled() ? "_19itahnd _2rko1mok _1e0c1txw _2lx21bp4 _1bah1yb4 _bfhk1bhr _16qs130s _4t3iuxo9 _1bsb10mj _1ul910mj _c71l1y6z _kqswh2mm" : "_19itahnd _2rkofajl _1e0c1txw _2lx21bp4 _1bah1yb4 _bfhk1bhr _16qs130s _4t3iuxo9 _1bsb10mj _1ul910mj _c71l1y6z _kqswh2mm", !!emojiToDelete && isRefreshEmojiPickerEnabled() ? withDeleteRefreshHeight[size] : uploading && isRefreshEmojiPickerEnabled() ? withUploadRefreshHeight[size] : query && filteredEmojis.length === 0 && isRefreshEmojiPickerEnabled() ? withNoResultsRefreshHeight[size] : showPreview ? withPreviewHeight[size] : withoutPreviewHeight[size], showAiUpload && "_4t3ikbql _c71l8k0t"]),
|
|
670
687
|
style: {
|
|
671
688
|
"--_19dn98e": ix("".concat(emojiPickerHeight, "px")),
|
|
672
689
|
"--_gsvyy7": ix("".concat(emojiPickerWidth, "px"))
|
|
@@ -676,7 +693,7 @@ var EmojiPickerComponent = function EmojiPickerComponent(_ref) {
|
|
|
676
693
|
onKeyPress: suppressKeyPress,
|
|
677
694
|
onKeyUp: suppressKeyPress,
|
|
678
695
|
onKeyDown: suppressKeyPress,
|
|
679
|
-
className: ax(["_16jlkb7n _1o9zkb7n _i0dlf1ug _1reo15vq _18m915vq _1e0c1txw _2lx21bp4 _1bah1yb4 _1tkeidpf"])
|
|
696
|
+
className: ax(["_16jlkb7n _1o9zkb7n _i0dlf1ug _1reo15vq _18m915vq _1e0c1txw _2lx21bp4 _1bah1yb4 _1tkeidpf", showAiUpload && "_1reo15vq _18m91wug"])
|
|
680
697
|
}, /*#__PURE__*/React.createElement(CategorySelector, {
|
|
681
698
|
activeCategoryId: (uploading || emojiToDelete) && isRefreshEmojiPickerEnabled() ? null : activeCategory,
|
|
682
699
|
dynamicCategories: dynamicCategories,
|
|
@@ -713,7 +730,9 @@ var EmojiPickerComponent = function EmojiPickerComponent(_ref) {
|
|
|
713
730
|
onOpenUpload: onOpenUpload,
|
|
714
731
|
size: size,
|
|
715
732
|
activeCategoryId: activeCategory,
|
|
716
|
-
useFooterSpaceForList: useFooterSpaceForList
|
|
733
|
+
useFooterSpaceForList: useFooterSpaceForList,
|
|
734
|
+
contentId: contentId,
|
|
735
|
+
fireAnalytics: fireAnalytics
|
|
717
736
|
}), shouldRenderFooter && /*#__PURE__*/React.createElement(EmojiPickerFooter, {
|
|
718
737
|
selectedEmoji: selectedEmoji,
|
|
719
738
|
uploadEnabled: uploadEnabled,
|
|
@@ -86,7 +86,9 @@ export var EmojiPickerVirtualListInternal = /*#__PURE__*/React.forwardRef(functi
|
|
|
86
86
|
onProductivityColorSelected = props.onProductivityColorSelected,
|
|
87
87
|
activeCategoryId = props.activeCategoryId,
|
|
88
88
|
selectedProductivityColor = props.selectedProductivityColor,
|
|
89
|
-
useFooterSpaceForList = props.useFooterSpaceForList
|
|
89
|
+
useFooterSpaceForList = props.useFooterSpaceForList,
|
|
90
|
+
contentId = props.contentId,
|
|
91
|
+
fireAnalytics = props.fireAnalytics;
|
|
90
92
|
var _useIntl = useIntl(),
|
|
91
93
|
formatMessage = _useIntl.formatMessage;
|
|
92
94
|
var listRef = useRef(null);
|
|
@@ -505,7 +507,9 @@ export var EmojiPickerVirtualListInternal = /*#__PURE__*/React.forwardRef(functi
|
|
|
505
507
|
onProductivityColorSelected: isTeamojiExperimentEnabled ? onProductivityColorSelected : undefined,
|
|
506
508
|
query: query,
|
|
507
509
|
onChange: onSearch,
|
|
508
|
-
resultsCount: visibleEmojis.length
|
|
510
|
+
resultsCount: visibleEmojis.length,
|
|
511
|
+
contentId: contentId,
|
|
512
|
+
fireAnalytics: fireAnalytics
|
|
509
513
|
}), /*#__PURE__*/React.createElement(EmojiPickerListContextProvider, {
|
|
510
514
|
initialEmojisFocus: {
|
|
511
515
|
rowIndex: 1,
|
|
@@ -20,7 +20,8 @@ var EmojiUploadComponent = function EmojiUploadComponent(props) {
|
|
|
20
20
|
var emojiProvider = props.emojiProvider,
|
|
21
21
|
createAnalyticsEvent = props.createAnalyticsEvent,
|
|
22
22
|
onUploaderRef = props.onUploaderRef,
|
|
23
|
-
disableFocusLock = props.disableFocusLock
|
|
23
|
+
disableFocusLock = props.disableFocusLock,
|
|
24
|
+
contentId = props.contentId;
|
|
24
25
|
var _useState = useState(),
|
|
25
26
|
_useState2 = _slicedToArray(_useState, 2),
|
|
26
27
|
uploadErrorMessage = _useState2[0],
|
|
@@ -122,7 +123,9 @@ var EmojiUploadComponent = function EmojiUploadComponent(props) {
|
|
|
122
123
|
onUploadCancelled: onUploadCancelled,
|
|
123
124
|
onUploadEmoji: onUploadEmoji,
|
|
124
125
|
errorMessage: uploadErrorMessage ? /*#__PURE__*/React.createElement(FormattedMessage, uploadErrorMessage) : null,
|
|
125
|
-
disableFocusLock: disableFocusLock
|
|
126
|
+
disableFocusLock: disableFocusLock,
|
|
127
|
+
contentId: contentId,
|
|
128
|
+
fireAnalytics: fireAnalytics
|
|
126
129
|
})));
|
|
127
130
|
};
|
|
128
131
|
var _default_1 = /*#__PURE__*/memo(EmojiUploadComponent);
|