stream-chat-react
Version:
React components to create chat conversations or livestream style chat
608 lines (571 loc) • 993 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var React = require('react');
var sanitizeUrl = require('@braintree/sanitize-url');
var ReactPlayer = require('react-player');
var prettybytes = require('pretty-bytes');
var DefaultEmojiIndex = require('emoji-mart/dist/utils/emoji-index/nimble-emoji-index.js');
var Dayjs = require('dayjs');
var calendar = require('dayjs/plugin/calendar');
var LocalizedFormat = require('dayjs/plugin/localizedFormat');
var i18n = require('i18next');
var updateLocale = require('dayjs/plugin/updateLocale');
var localeData = require('dayjs/plugin/localeData');
var relativeTime = require('dayjs/plugin/relativeTime');
require('dayjs/locale/de');
require('dayjs/locale/es');
require('dayjs/locale/fr');
require('dayjs/locale/hi');
require('dayjs/locale/it');
require('dayjs/locale/ja');
require('dayjs/locale/ko');
require('dayjs/locale/nl');
require('dayjs/locale/pt');
require('dayjs/locale/ru');
require('dayjs/locale/tr');
require('dayjs/locale/en');
var ImageGallery = require('react-image-gallery');
var reactFileUtils = require('react-file-utils');
var _defineProperty$2 = require('@babel/runtime/helpers/defineProperty');
var _slicedToArray$2 = require('@babel/runtime/helpers/slicedToArray');
var emojiRegex = require('emoji-regex');
var linkify = require('linkifyjs');
var nanoid = require('nanoid');
var RootReactMarkdown = require('react-markdown');
var ReactMarkdown = require('react-markdown/with-html');
var uniqBy = require('lodash.uniqby');
var _extends = require('@babel/runtime/helpers/extends');
var _typeof = require('@babel/runtime/helpers/typeof');
var _classCallCheck = require('@babel/runtime/helpers/classCallCheck');
var _createClass = require('@babel/runtime/helpers/createClass');
var _assertThisInitialized = require('@babel/runtime/helpers/assertThisInitialized');
var _inherits = require('@babel/runtime/helpers/inherits');
var _possibleConstructorReturn = require('@babel/runtime/helpers/possibleConstructorReturn');
var _getPrototypeOf = require('@babel/runtime/helpers/getPrototypeOf');
var PropTypes = require('prop-types');
var Textarea = require('react-textarea-autosize');
var getCaretCoordinates = require('textarea-caret');
var reactIs = require('react-is');
var debounce$1 = require('lodash.debounce');
var throttle = require('lodash.throttle');
var streamChat = require('stream-chat');
var deepequal = require('react-fast-compare');
var ReactDOM = require('react-dom');
var reactVirtuoso = require('react-virtuoso');
var nimbleEmoji = require('emoji-mart/dist/components/emoji/nimble-emoji');
var nimblePicker = require('emoji-mart/dist/components/picker/nimble-picker');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
function _interopNamespace(e) {
if (e && e.__esModule) return e;
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n["default"] = e;
return Object.freeze(n);
}
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
var React__namespace = /*#__PURE__*/_interopNamespace(React);
var ReactPlayer__default = /*#__PURE__*/_interopDefaultLegacy(ReactPlayer);
var prettybytes__default = /*#__PURE__*/_interopDefaultLegacy(prettybytes);
var DefaultEmojiIndex__default = /*#__PURE__*/_interopDefaultLegacy(DefaultEmojiIndex);
var Dayjs__default = /*#__PURE__*/_interopDefaultLegacy(Dayjs);
var calendar__default = /*#__PURE__*/_interopDefaultLegacy(calendar);
var LocalizedFormat__default = /*#__PURE__*/_interopDefaultLegacy(LocalizedFormat);
var i18n__default = /*#__PURE__*/_interopDefaultLegacy(i18n);
var updateLocale__default = /*#__PURE__*/_interopDefaultLegacy(updateLocale);
var localeData__default = /*#__PURE__*/_interopDefaultLegacy(localeData);
var relativeTime__default = /*#__PURE__*/_interopDefaultLegacy(relativeTime);
var ImageGallery__default = /*#__PURE__*/_interopDefaultLegacy(ImageGallery);
var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty$2);
var _slicedToArray__default = /*#__PURE__*/_interopDefaultLegacy(_slicedToArray$2);
var emojiRegex__default = /*#__PURE__*/_interopDefaultLegacy(emojiRegex);
var linkify__namespace = /*#__PURE__*/_interopNamespace(linkify);
var RootReactMarkdown__default = /*#__PURE__*/_interopDefaultLegacy(RootReactMarkdown);
var ReactMarkdown__default = /*#__PURE__*/_interopDefaultLegacy(ReactMarkdown);
var uniqBy__default = /*#__PURE__*/_interopDefaultLegacy(uniqBy);
var _extends__default = /*#__PURE__*/_interopDefaultLegacy(_extends);
var _typeof__default = /*#__PURE__*/_interopDefaultLegacy(_typeof);
var _classCallCheck__default = /*#__PURE__*/_interopDefaultLegacy(_classCallCheck);
var _createClass__default = /*#__PURE__*/_interopDefaultLegacy(_createClass);
var _assertThisInitialized__default = /*#__PURE__*/_interopDefaultLegacy(_assertThisInitialized);
var _inherits__default = /*#__PURE__*/_interopDefaultLegacy(_inherits);
var _possibleConstructorReturn__default = /*#__PURE__*/_interopDefaultLegacy(_possibleConstructorReturn);
var _getPrototypeOf__default = /*#__PURE__*/_interopDefaultLegacy(_getPrototypeOf);
var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes);
var Textarea__default = /*#__PURE__*/_interopDefaultLegacy(Textarea);
var getCaretCoordinates__default = /*#__PURE__*/_interopDefaultLegacy(getCaretCoordinates);
var debounce__default = /*#__PURE__*/_interopDefaultLegacy(debounce$1);
var throttle__default = /*#__PURE__*/_interopDefaultLegacy(throttle);
var deepequal__default = /*#__PURE__*/_interopDefaultLegacy(deepequal);
var ReactDOM__namespace = /*#__PURE__*/_interopNamespace(ReactDOM);
var nimbleEmoji__default = /*#__PURE__*/_interopDefaultLegacy(nimbleEmoji);
var nimblePicker__default = /*#__PURE__*/_interopDefaultLegacy(nimblePicker);
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __rest(s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
}
function __awaiter$1(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
function __generator$1(thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
}
function __spreadArray$1(to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || from);
}
function toVal(mix) {
var k, y, str='';
if (typeof mix === 'string' || typeof mix === 'number') {
str += mix;
} else if (typeof mix === 'object') {
if (Array.isArray(mix)) {
for (k=0; k < mix.length; k++) {
if (mix[k]) {
if (y = toVal(mix[k])) {
str && (str += ' ');
str += y;
}
}
}
} else {
for (k in mix) {
if (mix[k]) {
str && (str += ' ');
str += k;
}
}
}
}
return str;
}
function clsx () {
var i=0, tmp, x, str='';
while (i < arguments.length) {
if (tmp = arguments[i++]) {
if (x = toVal(tmp)) {
str && (str += ' ');
str += x;
}
}
}
return str;
}
var UnMemoizedAttachmentActions = function (props) {
var actionHandler = props.actionHandler, actions = props.actions, id = props.id, text = props.text;
var handleActionClick = function (event, name, value) { return actionHandler === null || actionHandler === void 0 ? void 0 : actionHandler(name, value, event); };
return (React__default["default"].createElement("div", { className: 'str-chat__message-attachment-actions' },
React__default["default"].createElement("div", { className: 'str-chat__message-attachment-actions-form' },
React__default["default"].createElement("span", null, text),
actions.map(function (action) { return (React__default["default"].createElement("button", { className: "str-chat__message-attachment-actions-button str-chat__message-attachment-actions-button--".concat(action.style), "data-testid": "".concat(action.name), "data-value": action.value, key: "".concat(id, "-").concat(action.value), onClick: function (event) { return handleActionClick(event, action.name, action.value); } }, action.text)); }))));
};
/**
* A component for rendering the actions you can take on an attachment.
*/
var AttachmentActions = React__default["default"].memo(UnMemoizedAttachmentActions);
var DownloadIcon$1 = function (_a) {
var className = _a.className;
return (React__default["default"].createElement("svg", { className: className, "data-testid": 'download', fill: 'none', height: '24', viewBox: '0 0 24 24', width: '24', xmlns: 'http://www.w3.org/2000/svg' },
React__default["default"].createElement("path", { d: 'M19.35 10.04C18.67 6.59 15.64 4 12 4C9.11 4 6.6 5.64 5.35 8.04C2.34 8.36 0 10.91 0 14C0 17.31 2.69 20 6 20H19C21.76 20 24 17.76 24 15C24 12.36 21.95 10.22 19.35 10.04ZM19 18H6C3.79 18 2 16.21 2 14C2 11.95 3.53 10.24 5.56 10.03L6.63 9.92L7.13 8.97C8.08 7.14 9.94 6 12 6C14.62 6 16.88 7.86 17.39 10.43L17.69 11.93L19.22 12.04C20.78 12.14 22 13.45 22 15C22 16.65 20.65 18 19 18ZM13.45 10H10.55V13H8L12 17L16 13H13.45V10Z', fill: 'black' })));
};
var PlayTriangleIcon = function () { return (React__default["default"].createElement("svg", { fill: 'none', viewBox: '0 0 12 14', xmlns: 'http://www.w3.org/2000/svg' },
React__default["default"].createElement("path", { d: 'M0.5 0V14L11.5 7L0.5 0Z', fill: '#080707' }))); };
var PauseIcon = function () { return (React__default["default"].createElement("svg", { fill: 'none', viewBox: '0 0 12 14', xmlns: 'http://www.w3.org/2000/svg' },
React__default["default"].createElement("path", { d: 'M0 14H4V0H0V14ZM8 0V14H12V0H8Z', fill: '#080707' }))); };
var FileSizeIndicator = function (_a) {
var fileSize = _a.fileSize;
if (!(fileSize && Number.isFinite(Number(fileSize))))
return null;
return (React__default["default"].createElement("span", { className: 'str-chat__message-attachment-file--item-size' }, prettybytes__default["default"](fileSize)));
};
var UnMemoizedSafeAnchor = function (props) {
var children = props.children, className = props.className, download = props.download, href = props.href, rel = props.rel, target = props.target;
if (!href)
return null;
var sanitized = sanitizeUrl.sanitizeUrl(href);
return (React__default["default"].createElement("a", { "aria-label": 'Attachment', className: className, download: download, href: sanitized, rel: rel, target: target }, children));
};
var SafeAnchor = React__default["default"].memo(UnMemoizedSafeAnchor);
var DownloadButton = function (_a) {
var assetUrl = _a.assetUrl;
return (React__default["default"].createElement(SafeAnchor, { className: 'str-chat__message-attachment-file--item-download', download: true, href: assetUrl, target: '_blank' },
React__default["default"].createElement(DownloadIcon$1, { className: 'str-chat__message-attachment-download-icon' })));
};
var PROGRESS_UPDATE_INTERVAL = 100;
var useAudioController = function () {
var _a = React.useState(false), isPlaying = _a[0], setIsPlaying = _a[1];
var _b = React.useState(0), progress = _b[0], setProgress = _b[1];
var audioRef = React.useRef(null);
var togglePlay = React.useCallback(function () {
setIsPlaying(function (playing) { return !playing; });
}, []);
var seek = React.useCallback(function (_a) {
var clientX = _a.clientX, currentTarget = _a.currentTarget;
if (!audioRef.current)
return;
var _b = currentTarget.getBoundingClientRect(), width = _b.width, x = _b.x;
var ratio = (clientX - x) / width;
if (!isPlaying)
setProgress(ratio * 100);
audioRef.current.currentTime = ratio * audioRef.current.duration;
}, [isPlaying]);
React.useEffect(function () {
if (!audioRef.current || !isPlaying)
return;
var interval = window.setInterval(function () {
if (!audioRef.current)
return;
var _a = audioRef.current, currentTime = _a.currentTime, duration = _a.duration;
setProgress((currentTime / duration) * 100);
if (currentTime === duration)
setIsPlaying(false);
}, PROGRESS_UPDATE_INTERVAL);
audioRef.current.play();
return function () {
var _a;
(_a = audioRef.current) === null || _a === void 0 ? void 0 : _a.pause();
window.clearInterval(interval);
};
}, [isPlaying]);
return {
audioRef: audioRef,
isPlaying: isPlaying,
progress: progress,
seek: seek,
togglePlay: togglePlay,
};
};
var getDisplayName = function (Component) {
return Component.displayName || Component.name || 'Component';
};
var ChatContext = React__default["default"].createContext(undefined);
var ChatProvider = function (_a) {
var children = _a.children, value = _a.value;
return (React__default["default"].createElement(ChatContext.Provider, { value: value }, children));
};
var useChatContext = function (componentName) {
var contextValue = React.useContext(ChatContext);
if (!contextValue) {
console.warn("The useChatContext hook was called outside of the ChatContext provider. Make sure this hook is called within a child of the Chat component. The errored call is located in the ".concat(componentName, " component."));
return {};
}
return contextValue;
};
/**
* Typescript currently does not support partial inference so if ChatContext
* typing is desired while using the HOC withChatContext the Props for the
* wrapped component must be provided as the first generic.
*/
var withChatContext = function (Component) {
var WithChatContextComponent = function (props) {
var chatContext = useChatContext();
return React__default["default"].createElement(Component, __assign({}, props, chatContext));
};
WithChatContextComponent.displayName = "WithChatContext".concat(getDisplayName(Component));
return WithChatContextComponent;
};
var AudioV1 = function (_a) {
var og = _a.og;
var asset_url = og.asset_url, description = og.description, image_url = og.image_url, text = og.text, title = og.title;
var _b = useAudioController(), audioRef = _b.audioRef, isPlaying = _b.isPlaying, progress = _b.progress, togglePlay = _b.togglePlay;
return (React__default["default"].createElement("div", { className: 'str-chat__audio' },
React__default["default"].createElement("div", { className: 'str-chat__audio__wrapper' },
React__default["default"].createElement("audio", { ref: audioRef },
React__default["default"].createElement("source", { "data-testid": 'audio-source', src: asset_url, type: 'audio/mp3' })),
React__default["default"].createElement("div", { className: 'str-chat__audio__image' },
React__default["default"].createElement("div", { className: 'str-chat__audio__image--overlay' }, !isPlaying ? (React__default["default"].createElement("button", { className: 'str-chat__audio__image--button', "data-testid": 'play-audio', onClick: togglePlay },
React__default["default"].createElement("svg", { height: '40', viewBox: '0 0 64 64', width: '40', xmlns: 'http://www.w3.org/2000/svg' },
React__default["default"].createElement("path", { d: 'M32 58c14.36 0 26-11.64 26-26S46.36 6 32 6 6 17.64 6 32s11.64 26 26 26zm0 6C14.327 64 0 49.673 0 32 0 14.327 14.327 0 32 0c17.673 0 32 14.327 32 32 0 17.673-14.327 32-32 32zm13.237-28.412L26.135 45.625a3.27 3.27 0 0 1-4.426-1.4 3.319 3.319 0 0 1-.372-1.47L21 23.36c-.032-1.823 1.41-3.327 3.222-3.358a3.263 3.263 0 0 1 1.473.322l19.438 9.36a3.311 3.311 0 0 1 .103 5.905z', fillRule: 'nonzero' })))) : (React__default["default"].createElement("button", { className: 'str-chat__audio__image--button', "data-testid": 'pause-audio', onClick: togglePlay },
React__default["default"].createElement("svg", { height: '40', viewBox: '0 0 64 64', width: '40', xmlns: 'http://www.w3.org/2000/svg' },
React__default["default"].createElement("path", { d: 'M32 58.215c14.478 0 26.215-11.737 26.215-26.215S46.478 5.785 32 5.785 5.785 17.522 5.785 32 17.522 58.215 32 58.215zM32 64C14.327 64 0 49.673 0 32 0 14.327 14.327 0 32 0c17.673 0 32 14.327 32 32 0 17.673-14.327 32-32 32zm-7.412-45.56h2.892a2.17 2.17 0 0 1 2.17 2.17v23.865a2.17 2.17 0 0 1-2.17 2.17h-2.892a2.17 2.17 0 0 1-2.17-2.17V20.61a2.17 2.17 0 0 1 2.17-2.17zm12.293 0h2.893a2.17 2.17 0 0 1 2.17 2.17v23.865a2.17 2.17 0 0 1-2.17 2.17h-2.893a2.17 2.17 0 0 1-2.17-2.17V20.61a2.17 2.17 0 0 1 2.17-2.17z', fillRule: 'nonzero' }))))),
image_url && React__default["default"].createElement("img", { alt: "".concat(description), src: image_url })),
React__default["default"].createElement("div", { className: 'str-chat__audio__content' },
React__default["default"].createElement("span", { className: 'str-chat__audio__content--title' },
React__default["default"].createElement("strong", null, title)),
React__default["default"].createElement("span", { className: 'str-chat__audio__content--subtitle' }, text),
React__default["default"].createElement("div", { className: 'str-chat__audio__content--progress' },
React__default["default"].createElement("div", { "data-progress": progress, "data-testid": 'audio-progress', role: 'progressbar', style: { width: "".concat(progress, "%") } }))))));
};
var PlayButton = function (_a) {
var isPlaying = _a.isPlaying, onClick = _a.onClick;
return (React__default["default"].createElement("button", { className: 'str-chat__message-attachment-audio-widget--play-button', "data-testid": isPlaying ? 'pause-audio' : 'play-audio', onClick: onClick }, isPlaying ? React__default["default"].createElement(PauseIcon, null) : React__default["default"].createElement(PlayTriangleIcon, null)));
};
var ProgressBar = function (_a) {
var onClick = _a.onClick, progress = _a.progress;
return (React__default["default"].createElement("div", { className: 'str-chat__message-attachment-audio-widget--progress-track', "data-progress": progress, "data-testid": 'audio-progress', onClick: onClick, role: 'progressbar', style: {
background: "linear-gradient(\n\t\t to right, \n\t\t var(--str-chat__primary-color),\n\t\t var(--str-chat__primary-color) ".concat(progress, "%,\n\t\t var(--str-chat__disabled-color) ").concat(progress, "%,\n\t\t var(--str-chat__disabled-color)\n\t )"),
} },
React__default["default"].createElement("div", { className: 'str-chat__message-attachment-audio-widget--progress-slider', style: { left: "".concat(progress, "px") } })));
};
var AudioV2 = function (_a) {
var og = _a.og;
var asset_url = og.asset_url, file_size = og.file_size, title = og.title;
var _b = useAudioController(), audioRef = _b.audioRef, isPlaying = _b.isPlaying, progress = _b.progress, seek = _b.seek, togglePlay = _b.togglePlay;
if (!asset_url)
return null;
var dataTestId = 'audio-widget';
var rootClassName = 'str-chat__message-attachment-audio-widget';
return (React__default["default"].createElement("div", { className: rootClassName, "data-testid": dataTestId },
React__default["default"].createElement("audio", { ref: audioRef },
React__default["default"].createElement("source", { "data-testid": 'audio-source', src: asset_url, type: 'audio/mp3' })),
React__default["default"].createElement("div", { className: 'str-chat__message-attachment-audio-widget--play-controls' },
React__default["default"].createElement(PlayButton, { isPlaying: isPlaying, onClick: togglePlay })),
React__default["default"].createElement("div", { className: 'str-chat__message-attachment-audio-widget--text' },
React__default["default"].createElement("div", { className: 'str-chat__message-attachment-audio-widget--text-first-row' },
React__default["default"].createElement("div", { className: 'str-chat__message-attachment-audio-widget--title' }, title),
React__default["default"].createElement(DownloadButton, { assetUrl: asset_url })),
React__default["default"].createElement("div", { className: 'str-chat__message-attachment-audio-widget--text-second-row' },
React__default["default"].createElement(FileSizeIndicator, { fileSize: file_size }),
React__default["default"].createElement(ProgressBar, { onClick: seek, progress: progress })))));
};
var UnMemoizedAudio = function (props) {
var themeVersion = useChatContext('Audio').themeVersion;
return themeVersion === '1' ? React__default["default"].createElement(AudioV1, __assign({}, props)) : React__default["default"].createElement(AudioV2, __assign({}, props));
};
/**
* Audio attachment with play/pause button and progress bar
*/
var Audio = React__default["default"].memo(UnMemoizedAudio);
var CloseIconRound = function () { return (React__default["default"].createElement("svg", { "data-testid": 'close-icon-round', fill: 'none', height: '28', viewBox: '0 0 28 28', width: '28', xmlns: 'http://www.w3.org/2000/svg' },
React__default["default"].createElement("rect", { fill: '#72767E', height: '28', rx: '14', width: '28' }),
React__default["default"].createElement("circle", { cx: '14', cy: '14', fill: '#72767E', r: '12' }),
React__default["default"].createElement("path", { clipRule: 'evenodd', d: 'M28 14C28 21.732 21.732 28 14 28C6.26801 28 0 21.732 0 14C0 6.26801 6.26801 0 14 0C21.732 0 28 6.26801 28 14ZM26 14C26 20.6274 20.6274 26 14 26C7.37258 26 2 20.6274 2 14C2 7.37258 7.37258 2 14 2C20.6274 2 26 7.37258 26 14ZM19.59 7L21 8.41L15.41 14L21 19.59L19.59 21L14 15.41L8.41 21L7 19.59L12.59 14L7 8.41L8.41 7L14 12.59L19.59 7Z', fill: 'white', fillRule: 'evenodd' }))); };
var ChannelActionContext = React__default["default"].createContext(undefined);
var ChannelActionProvider = function (_a) {
var children = _a.children, value = _a.value;
return (React__default["default"].createElement(ChannelActionContext.Provider, { value: value }, children));
};
var useChannelActionContext = function (componentName) {
var contextValue = React.useContext(ChannelActionContext);
if (!contextValue) {
console.warn("The useChannelActionContext hook was called outside of the ChannelActionContext provider. Make sure this hook is called within a child of the Channel component. The errored call is located in the ".concat(componentName, " component."));
return {};
}
return contextValue;
};
/**
* Typescript currently does not support partial inference, so if ChannelActionContext
* typing is desired while using the HOC withChannelActionContext, the Props for the
* wrapped component must be provided as the first generic.
*/
var withChannelActionContext = function (Component) {
var WithChannelActionContextComponent = function (props) {
var channelActionContext = useChannelActionContext();
return React__default["default"].createElement(Component, __assign({}, props, channelActionContext));
};
WithChannelActionContextComponent.displayName = (Component.displayName ||
Component.name ||
'Component').replace('Base', '');
return WithChannelActionContextComponent;
};
var ChannelStateContext = React__default["default"].createContext(undefined);
var ChannelStateProvider = function (_a) {
var children = _a.children, value = _a.value;
return (React__default["default"].createElement(ChannelStateContext.Provider, { value: value }, children));
};
var useChannelStateContext = function (componentName) {
var contextValue = React.useContext(ChannelStateContext);
if (!contextValue) {
console.warn("The useChannelStateContext hook was called outside of the ChannelStateContext provider. Make sure this hook is called within a child of the Channel component. The errored call is located in the ".concat(componentName, " component."));
return {};
}
return contextValue;
};
/**
* Typescript currently does not support partial inference, so if ChannelStateContext
* typing is desired while using the HOC withChannelStateContext, the Props for the
* wrapped component must be provided as the first generic.
*/
var withChannelStateContext = function (Component) {
var WithChannelStateContextComponent = function (props) {
var channelStateContext = useChannelStateContext();
return React__default["default"].createElement(Component, __assign({}, props, channelStateContext));
};
WithChannelStateContextComponent.displayName = (Component.displayName ||
Component.name ||
'Component').replace('Base', '');
return WithChannelStateContextComponent;
};
var ComponentContext = React__default["default"].createContext(undefined);
var ComponentProvider = function (_a) {
var children = _a.children, value = _a.value;
return (React__default["default"].createElement(ComponentContext.Provider, { value: value }, children));
};
var useComponentContext = function (componentName) {
var contextValue = React.useContext(ComponentContext);
if (!contextValue) {
console.warn("The useComponentContext hook was called outside of the ComponentContext provider. Make sure this hook is called within a child of the Channel component. The errored call is located in the ".concat(componentName, " component."));
return {};
}
return contextValue;
};
/**
* Typescript currently does not support partial inference, so if ComponentContext
* typing is desired while using the HOC withComponentContext, the Props for the
* wrapped component must be provided as the first generic.
*/
var withComponentContext = function (Component) {
var WithComponentContextComponent = function (props) {
var componentContext = useComponentContext();
return React__default["default"].createElement(Component, __assign({}, props, componentContext));
};
WithComponentContextComponent.displayName = (Component.displayName ||
Component.name ||
'Component').replace('Base', '');
return WithComponentContextComponent;
};
var DefaultEmoji$1 = React__default["default"].lazy(function () { return Promise.resolve().then(function () { return DefaultEmoji; }); });
var DefaultEmojiPicker$1 = React__default["default"].lazy(function () { return Promise.resolve().then(function () { return DefaultEmojiPicker; }); });
var EmojiContext = React__default["default"].createContext(undefined);
var EmojiProvider = function (_a) {
var children = _a.children, value = _a.value;
var _b = value.Emoji, Emoji = _b === void 0 ? DefaultEmoji$1 : _b, emojiConfig = value.emojiConfig, _c = value.EmojiIndex, EmojiIndex = _c === void 0 ? DefaultEmojiIndex__default["default"] : _c, _d = value.EmojiPicker, EmojiPicker = _d === void 0 ? DefaultEmojiPicker$1 : _d;
var emojiContextValue = {
Emoji: Emoji,
emojiConfig: emojiConfig,
EmojiIndex: EmojiIndex,
EmojiPicker: EmojiPicker,
};
return React__default["default"].createElement(EmojiContext.Provider, { value: emojiContextValue }, children);
};
var useEmojiContext = function (componentName) {
var contextValue = React.useContext(EmojiContext);
if (!contextValue) {
console.warn("The useEmojiContext hook was called outside of the EmojiContext provider. Make sure this hook is called within a child of the Channel component. The errored call is located in the ".concat(componentName, " component."));
return {};
}
return contextValue;
};
/**
* Typescript currently does not support partial inference, so if EmojiContext
* typing is desired while using the HOC withEmojiContext, the Props for the
* wrapped component must be provided as the first generic.
*/
var withEmojiContext = function (Component) {
var WithEmojiContextComponent = function (props) {
var componentContext = useEmojiContext();
return React__default["default"].createElement(Component, __assign({}, props, componentContext));
};
WithEmojiContextComponent.displayName = (Component.displayName ||
Component.name ||
'Component').replace('Base', '');
return WithEmojiContextComponent;
};
var MessageContext = React__default["default"].createContext(undefined);
var MessageProvider = function (_a) {
var children = _a.children, value = _a.value;
return (React__default["default"].createElement(MessageContext.Provider, { value: value }, children));
};
var useMessageContext = function (componentName) {
var contextValue = React.useContext(MessageContext);
if (!contextValue) {
console.warn("The useMessageContext hook was called outside of the MessageContext provider. Make sure this hook is called within the Message's UI component. The errored call is located in the ".concat(componentName, " component."));
return {};
}
return contextValue;
};
/**
* Typescript currently does not support partial inference, so if MessageContext
* typing is desired while using the HOC withMessageContext, the Props for the
* wrapped component must be provided as the first generic.
*/
var withMessageContext = function (Component) {
var WithMessageContextComponent = function (props) {
var messageContext = useMessageContext();
return React__default["default"].createElement(Component, __assign({}, props, messageContext));
};
WithMessageContextComponent.displayName = (Component.displayName ||
Component.name ||
'Component').replace('Base', '');
return WithMessageContextComponent;
};
var MessageInputContext = React.createContext(undefined);
var MessageInputContextProvider = function (_a) {
var children = _a.children, value = _a.value;
return (React__default["default"].createElement(MessageInputContext.Provider, { value: value }, children));
};
var useMessageInputContext = function (componentName) {
var contextValue = React.useContext(MessageInputContext);
if (!contextValue) {
console.warn("The useMessageInputContext hook was called outside of the MessageInputContext provider. Make sure this hook is called within the MessageInput's UI component. The errored call is located in the ".concat(componentName, " component."));
return {};
}
return contextValue;
};
var Cancel$b="Stornieren";var Close$b="Schließen";var Delete$b="Löschen";var Delivered$b="Zugestellt";var Flag$b="Meldung";var Menu$b="Menü";var Mute$b="Stumm schalten";var New$b="Neu";var Pin$b="Pin";var Reply$b="Antworten";var Search$b="Suche";var Send$b="Senden";var Thread$c="Thread";var Unmute$b="Stummschaltung aufheben";var Unpin$b="Pin entfernen";var live$b="live";var replyCount_one$b="1 Antwort";var replyCount_other$b="{{ count }} Antworten";var searchResultsCount_one$b="1 Ergebnis";var searchResultsCount_other$b="{{ count }} Ergebnisse";var deTranslations = {"Attach files":"Dateien anhängen",Cancel:Cancel$b,"Channel Missing":"Kanal fehlt",Close:Close$b,"Close emoji picker":"Emoji-Picker schließen","Commands matching":"Übereinstimmende Befehle","Connection failure, reconnecting now...":"Verbindungsfehler, Wiederherstellung der Verbindung...",Delete:Delete$b,Delivered:Delivered$b,"Drag your files here":"Drag your files here","Edit Message":"Nachricht bearbeiten","Edit message request failed":"Anfrage zum Bearbeiten der Nachricht fehlgeschlagen","Emoji matching":"Emoji passend","Empty message...":"Leere Nachricht...","Error adding flag":"Fehler beim Hinzufügen des Flags","Error connecting to chat, refresh the page to try again.":"Verbindungsfehler zum Chat, Aktualisiere die Seite um es erneut zu versuchen.","Error deleting message":"Fehler beim Löschen der Nachricht","Error muting a user ...":"Fehler beim Stummschalten eines Nutzers.","Error pinning message":"Fehler beim Pinnen der Nachricht","Error removing message pin":"Fehler beim Entfernen der gepinnten Nachricht","Error unmuting a user ...":"Stummschaltung des Nutzers fehlgeschlagen ...","Error uploading file":"Fehler beim Hochladen der Datei","Error uploading image":"Hochladen des Bildes fehlgeschlagen","Error · Unsent":"Fehler nicht gesendet","Error: {{ errorMessage }}":"Fehler: {{ errorMessage }}",Flag:Flag$b,"Latest Messages":"Neueste Nachrichten",Menu:Menu$b,"Message Failed · Click to try again":"Nachricht fehlgeschlagen · Klicken, um es erneut zu versuchen","Message Failed · Unauthorized":"Nachricht fehlgeschlagen · Nicht autorisiert","Message deleted":"Nachricht gelöscht","Message has been successfully flagged":"Nachricht wurde erfolgreich gemeldet","Message pinned":"Nachricht gepinnt",Mute:Mute$b,New:New$b,"New Messages!":"Neue Nachrichten!","No chats here yet…":"Noch keine Chats hier...","No results found":"keine Ergebnisse gefunden","Nothing yet...":"Noch nichts...","Open emoji picker":"Emoji-Picker öffnen","People matching":"Passende Personen","Pick your emoji":"Emoji wählen",Pin:Pin$b,"Pinned by":"Gepinnt von",Reply:Reply$b,"Reply to Message":"Auf Nachricht antworten",Search:Search$b,"Searching...":"Suchen...",Send:Send$b,"Send message request failed":"Senden der Nachrichtenanfrage fehlgeschlagen","Sending...":"Senden...","Slow Mode ON":"Slow-Mode EIN","Some of the files will not be accepted":"Some of the files will not be accepted","This message was deleted...":"Diese Nachricht wurde gelöscht...",Thread:Thread$c,"Type your message":"Nachricht eingeben",Unmute:Unmute$b,Unpin:Unpin$b,"Upload type: \"{{ type }}\" is not allowed":"Upload-Typ: \"{{ type }}\" ist nicht erlaubt","Wait until all attachments have uploaded":"Bitte warten, bis alle Anhänge hochgeladen wurden","You have no channels currently":"Du hast momentan noch keinen Channels","You've reached the maximum number of files":"Die maximale Dateianzahl ist erreicht",live:live$b,replyCount_one:replyCount_one$b,replyCount_other:replyCount_other$b,searchResultsCount_one:searchResultsCount_one$b,searchResultsCount_other:searchResultsCount_other$b,"this content could not be displayed":"Dieser Inhalt konnte nicht angezeigt werden","{{ commaSeparatedUsers }} and {{ moreCount }} more":"{{ commaSeparatedUsers }} und {{moreCount}} Mehr","{{ commaSeparatedUsers }}, and {{ lastUser }}":"{{ commaSeparatedUsers }} und {{ lastUser }}","{{ firstUser }} and {{ secondUser }}":"{{ firstUser }} und {{ secondUser }}","{{ imageCount }} more":"{{ imageCount }} mehr","{{ memberCount }} members":"{{ memberCount }} Mitglieder","{{ user }} has been muted":"{{ user }} wurde stummgeschaltet","{{ user }} has been unmuted":"{{ user }} wurde nicht stummgeschaltet","{{ user }} is typing...":"{{ user }} tippt...","{{ users }} and more are typing...":"{{ users }} und mehr tippen...","{{ users }} and {{ user }} are typing...":"{{ users }} und {{ user }} tippen...","{{ watcherCount }} online":"{{ watcherCount }} online","🏙 Attachment...":"🏙 Anhang..."};
var Cancel$a="Cancel";var Close$a="Close";var Delete$a="Delete";var Delivered$a="Delivered";var Flag$a="Flag";var Menu$a="Menu";var Mute$a="Mute";var New$a="New";var Pin$a="Pin";var Reply$a="Reply";var Search$a="Search";var Send$a="Send";var Thread$b="Thread";var Unmute$a="Unmute";var Unpin$a="Unpin";var live$a="live";var replyCount_one$a="1 reply";var replyCount_other$a="{{ count }} replies";var searchResultsCount_one$a="1 result";var searchResultsCount_other$a="{{ count }} results";var enTranslations = {"Attach files":"Attach files",Cancel:Cancel$a,"Channel Missing":"Channel Missing",Close:Close$a,"Close emoji picker":"Close emoji picker","Commands matching":"Commands matching","Connection failure, reconnecting now...":"Connection failure, reconnecting now...",Delete:Delete$a,Delivered:Delivered$a,"Drag your files here":"Drag your files here","Edit Message":"Edit Message","Edit message request failed":"Edit message request failed","Emoji matching":"Emoji matching","Empty message...":"Empty message...","Error adding flag":"Error adding flag","Error connecting to chat, refresh the page to try again.":"Error connecting to chat, refresh the page to try again.","Error deleting message":"Error deleting message","Error muting a user ...":"Error muting a user ...","Error pinning message":"Error pinning message","Error removing message pin":"Error removing message pin","Error unmuting a user ...":"Error unmuting a user ...","Error uploading file":"Error uploading file","Error uploading image":"Error uploading image","Error · Unsent":"Error · Unsent","Error: {{ errorMessage }}":"Error: {{ errorMessage }}",Flag:Flag$a,"Latest Messages":"Latest Messages",Menu:Menu$a,"Message Failed · Click to try again":"Message Failed · Click to try again","Message Failed · Unauthorized":"Message Failed · Unauthorized","Message deleted":"Message deleted","Message has been successfully flagged":"Message has been successfully flagged","Message pinned":"Message pinned",Mute:Mute$a,New:New$a,"New Messages!":"New Messages!","No chats here yet…":"No chats here yet…","No results found":"No results found","Nothing yet...":"Nothing yet...","Open emoji picker":"Open emoji picker","People matching":"People matching","Pick your emoji":"Pick your emoji",Pin:Pin$a,"Pinned by":"Pinned by",Reply:Reply$a,"Reply to Message":"Reply to Message",Search:Search$a,"Searching...":"Searching...",Send:Send$a,"Send message request failed":"Send message request failed","Sending...":"Sending...","Slow Mode ON":"Slow Mode ON","Some of the files will not be accepted":"Some of the files will not be accepted","This message was deleted...":"This message was deleted...",Thread:Thread$b,"Type your message":"Type your message",Unmute:Unmute$a,Unpin:Unpin$a,"Upload type: \"{{ type }}\" is not allowed":"Upload type: \"{{ type }}\" is not allowed","Wait until all attachments have uploaded":"Wait until all attachments have uploaded","You have no channels currently":"You have no channels currently","You've reached the maximum number of files":"You've reached the maximum number of files",live:live$a,replyCount_one:replyCount_one$a,replyCount_other:replyCount_other$a,searchResultsCount_one:searchResultsCount_one$a,searchResultsCount_other:searchResultsCount_other$a,"this content could not be displayed":"this content could not be displayed","{{ commaSeparatedUsers }} and {{ moreCount }} more":"{{ commaSeparatedUsers }} and {{ moreCount }} more","{{ commaSeparatedUsers }}, and {{ lastUser }}":"{{ commaSeparatedUsers }}, and {{ lastUser }}","{{ firstUser }} and {{ secondUser }}":"{{ firstUser }} and {{ secondUser }}","{{ imageCount }} more":"{{ imageCount }} more","{{ memberCount }} members":"{{ memberCount }} members","{{ user }} has been muted":"{{ user }} has been muted","{{ user }} has been unmuted":"{{ user }} has been unmuted","{{ user }} is typing...":"{{ user }} is typing...","{{ users }} and more are typing...":"{{ users }} and more are typing...","{{ users }} and {{ user }} are typing...":"{{ users }} and {{ user }} are typing...","{{ watcherCount }} online":"{{ watcherCount }} online","🏙 Attachment...":"🏙 Attachment..."};
var Cancel$9="Cancelar";var Close$9="Cerca";var Delete$9="Borrar";var Delivered$9="Entregado";var Flag$9="Bandera";var Menu$9="Menú";var Mute$9="Mudo";var New$9="Nuevo";var Pin$9="Alfiler";var Reply$9="Respuesta";var Search$9="Buscar";var Send$9="Enviar";var Thread$a="Hilo";var Unmute$9="Activar sonido";var Unpin$9="Desprender";var live$9="En Vivo";var replyCount_many$4="{{ count }} respuestas";var replyCount_one$9="1 respuesta";var replyCount_other$9="{{ count }} respuestas";var searchResultsCount_many$4="{{ count }} resultados";var searchResultsCount_one$9="1 resultado";var searchResultsCount_other$9="{{ count }} resultados";var esTranslations = {"Attach files":"Adjuntar archivos",Cancel:Cancel$9,"Channel Missing":"Falta canal",Close:Close$9,"Close emoji picker":"Cerrar el selector de emojis","Commands matching":"Coincidencia de comandos","Connection failure, reconnecting now...":"Fallo de conexión, reconectando ahora ...",Delete:Delete$9,Delivered:Delivered$9,"Drag your files here":"Drag your files here","Edit Message":"Editar mensaje","Edit message request failed":"Error al editar la solicitud de mensaje","Emoji matching":"Coincidencia de emoji","Empty message...":"Mensaje vacío ...","Error adding flag":"Error al agregar la bandera","Error connecting to chat, refresh the page to try again.":"Error al conectarse al chat, actualice la página para volver a intentarlo.","Error deleting message":"Error al eliminar el mensaje","Error muting a user ...":"Error al silenciar a un usuario ...","Error pinning message":"Mensaje de error al fijar","Error removing message pin":"Error al quitar el pin del mensaje","Error unmuting a user ...":"Error al activar el silencio de un usuario ...","Error uploading file":"Error al cargar el archivo","Error uploading image":"Error subiendo imagen","Error · Unsent":"Error · No enviado","Error: {{ errorMessage }}":"Error: {{ errorMessage }}",Flag:Flag$9,"Latest Messages":"Últimos mensajes",Menu:Menu$9,"Message Failed · Click to try again":"Mensaje fallido · Haga clic para volver a intentarlo","Message Failed · Unauthorized":"Mensaje fallido · No autorizado","Message deleted":"Mensaje borrado","Message has been successfully flagged":"El mensaje se marcó correctamente","Message pinned":"Mensaje fijado",Mute:Mute$9,New:New$9,"New Messages!":"¡Nuevos mensajes!","No chats here yet…":"Aún no hay mensajes aquí...","No results found":"No se han encontrado resultados","Nothing yet...":"Nada aún...","Open emoji picker":"Selector de emoji abierto","People matching":"Personas que coinciden","Pick your emoji":"Elige tu emoji",Pin:Pin$9,"Pinned by":"Fijado por",Reply:Reply$9,"Reply to Message":"Responder al mensaje",Search:Search$9,"Searching...":"Buscando...",Send:Send$9,"Send message request failed":"Error al enviar la solicitud de mensaje","Sending...":"Enviando...","Slow Mode ON":"Modo lento activado","Some of the files will not be accepted":"Some of the files will not be accepted","This message was deleted...":"Este mensaje fue eliminado ...",Thread:Thread$a,"Type your message":"Escribe tu mensaje",Unmute:Unmute$9,Unpin:Unpin$9,"Upload type: \"{{ type }}\" is not allowed":"Tipo de carga: \"{{ type }}\" no está permitido","Wait until all attachments have uploaded":"Espere hasta que se hayan cargado todos los archivos adjuntos","You have no channels currently":"Actualmente no tienes canales","You've reached the maximum number of files":"Has alcanzado el número máximo de archivos",live:live$9,replyCount_many:replyCount_many$4,replyCount_one:replyCount_one$9,replyCount_other:replyCount_other$9,searchResultsCount_many:searchResultsCount_many$4,searchResultsCount_one:searchResultsCount_one$9,searchResultsCount_other:searchResultsCount_other$9,"this content could not be displayed":"este contenido no se pudo mostrar","{{ commaSeparatedUsers }} and {{ moreCount }} more":"{{ commaSeparatedUsers }} y {{ moreCount }} más","{{ commaSeparatedUsers }}, and {{ lastUser }}":"{{ commaSeparatedUsers }} y {{ lastUser }}","{{ firstUser }} and {{ secondUser }}":"{{ firstUser }} y {{ secondUser }}","{{ imageCount }} more":"{{ imageCount }} más","{{ memberCount }} members":"{{ memberCount }} miembros","{{ user }} has been muted":"{{ user }} ha sido silenciado","{{ user }} has been unmuted":"{{ user }} se ha desactivado","{{ user }} is typing...":"{{ user }} está escribiendo...","{{ users }} and more are typing...":"{{ users }} y más están escribiendo...","{{ users }} and {{ user }} are typing...":"{{ users }} y {{ user }} están escribiendo...","{{ watcherCount }} online":"{{ watcherCount }} en línea","🏙 Attachment...":"🏙 Adjunto..."};
var Cancel$8="Annuler";var Close$8="Fermer";var Delete$8="Supprimer";var Delivered$8="Publié";var Flag$8="Signaler";var Menu$8="Menu";var Mute$8="Muet";var New$8="Nouveaux";var Pin$8="Épingle";var Reply$8="Réponse";var Search$8="Rechercher";var Send$8="Envoyer";var Thread$9="Fil de discussion";var Unmute$8="Désactiver muet";var Unpin$8="Détacher";var live$8="en direct";var replyCount_many$3="{{ count }} réponses";var replyCount_one$8="1 réponse";var replyCount_other$8="{{ count }} réponses";var searchResultsCount_many$3="{{ count }} résultats";var searchResultsCount_one$8="1 résultat";var searchResultsCount_other$8="{{ count }} résultats";var frTranslations = {"Attach files":"Pièces jointes",Cancel:Cancel$8,"Channel Missing":"Canal Manquant",Close:Close$8,"Close emoji picker":"Fermer le sélecteur d'emojis","Commands matching":"Correspondance des commandes","Connection failure, reconnecting now...":"Échec de la connexion, reconnexion en cours...",Delete:Delete$8,Delivered:Delivered$8,"Drag your files here":"Drag your files here","Edit Message":"Éditer un message","Edit message request failed":"Échec de la demande de modification du message","Emoji matching":"Correspondance emoji","Empty message...":"Message vide...","Error adding flag":"Erreur lors de l'ajout du drapeau","Error connecting to chat, refresh the page to try again.":"Erreur de connexion au chat, rafraîchissez la page pour réessayer.","Error deleting message":"Erreur lors de la suppression du message","Error muting a user ...":"Erreur de mise en sourdine d'un utilisateur ...","Error pinning message":"Erreur d'épinglage du message","Error removing message pin":"Erreur lors de la suppression du code PIN du message","Error unmuting a user ...":"Erreur de désactivation de la fonction sourdine pour un utilisateur ...","Error uploading file":"Erreur lors du téléchargement du fichier","Error uploading image":"Erreur lors de l'envoi de l'image","Error · Unsent":"Erreur - Non envoyé","Error: {{ errorMessage }}":"Erreur : {{ errorMessage }}",Flag:Flag$8,"Latest Message