"use strict"; (self["webpackChunktinode_webapp"] = self["webpackChunktinode_webapp"] || []).push([["src_views_messages-view_jsx"],{ /***/ "./src/views/logo-view.jsx": /*!*********************************!*\ !*** ./src/views/logo-view.jsx ***! \*********************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": function() { return /* binding */ LogoView; } /* harmony export */ }); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react"); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _config_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../config.js */ "./src/config.js"); /* harmony import */ var react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react/jsx-dev-runtime */ "./node_modules/react/jsx-dev-runtime.js"); function Icon({ children }) { return (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxDEV)("i", { className: "material-icons", "aria-hidden": "true", children: children }, void 0, false); } class LogoView extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComponent) { render() { return (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxDEV)("div", { id: "dummy-view", children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxDEV)("div", { children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxDEV)("span", { id: "dummy-view-icon", children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxDEV)(Icon, { children: "forum" }, void 0, false) }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxDEV)("h2", { children: _config_js__WEBPACK_IMPORTED_MODULE_1__.BASE_APP_NAME }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxDEV)("p", { children: "选择一个会话开始聊天" }, void 0, false)] }, void 0, true) }, void 0, false); } } ; /***/ }), /***/ "./src/views/messages-view.jsx": /*!*************************************!*\ !*** ./src/views/messages-view.jsx ***! \*************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react"); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-intl */ "react-intl"); /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var tinode_sdk__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! tinode-sdk */ "tinode-sdk"); /* harmony import */ var tinode_sdk__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(tinode_sdk__WEBPACK_IMPORTED_MODULE_2__); /* harmony import */ var _widgets_chat_message_jsx__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../widgets/chat-message.jsx */ "./src/widgets/chat-message.jsx"); /* harmony import */ var _widgets_contact_badges_jsx__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../widgets/contact-badges.jsx */ "./src/widgets/contact-badges.jsx"); /* harmony import */ var _widgets_error_panel_jsx__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../widgets/error-panel.jsx */ "./src/widgets/error-panel.jsx"); /* harmony import */ var _widgets_group_subs_jsx__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../widgets/group-subs.jsx */ "./src/widgets/group-subs.jsx"); /* harmony import */ var _widgets_invitation_jsx__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../widgets/invitation.jsx */ "./src/widgets/invitation.jsx"); /* harmony import */ var _widgets_letter_tile_jsx__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../widgets/letter-tile.jsx */ "./src/widgets/letter-tile.jsx"); /* harmony import */ var _widgets_load_spinner_jsx__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../widgets/load-spinner.jsx */ "./src/widgets/load-spinner.jsx"); /* harmony import */ var _logo_view_jsx__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./logo-view.jsx */ "./src/views/logo-view.jsx"); /* harmony import */ var _widgets_meta_message_jsx__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../widgets/meta-message.jsx */ "./src/widgets/meta-message.jsx"); /* harmony import */ var _widgets_pinned_messages_jsx__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../widgets/pinned-messages.jsx */ "./src/widgets/pinned-messages.jsx"); /* harmony import */ var _security_support_view_jsx__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./security-support-view.jsx */ "./src/views/security-support-view.jsx"); /* harmony import */ var _widgets_send_message_jsx__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../widgets/send-message.jsx */ "./src/widgets/send-message.jsx"); /* harmony import */ var _config_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../config.js */ "./src/config.js"); /* harmony import */ var _constants_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../constants.js */ "./src/constants.js"); /* harmony import */ var _lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ../lib/blob-helpers.js */ "./src/lib/blob-helpers.js"); /* harmony import */ var _lib_utils_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ../lib/utils.js */ "./src/lib/utils.js"); /* harmony import */ var _lib_im_api_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ../lib/im-api.js */ "./src/lib/im-api.js"); /* harmony import */ var _lib_navigation_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ../lib/navigation.js */ "./src/lib/navigation.js"); /* harmony import */ var _lib_strformat_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ../lib/strformat.js */ "./src/lib/strformat.js"); /* harmony import */ var react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! react/jsx-dev-runtime */ "./node_modules/react/jsx-dev-runtime.js"); const CallPanel = react__WEBPACK_IMPORTED_MODULE_0___default().lazy(_ => __webpack_require__.e(/*! import() */ "src_widgets_call-panel_jsx").then(__webpack_require__.bind(__webpack_require__, /*! ../widgets/call-panel.jsx */ "./src/widgets/call-panel.jsx"))); const DocPreview = react__WEBPACK_IMPORTED_MODULE_0___default().lazy(_ => __webpack_require__.e(/*! import() */ "src_widgets_doc-preview_jsx").then(__webpack_require__.bind(__webpack_require__, /*! ../widgets/doc-preview.jsx */ "./src/widgets/doc-preview.jsx"))); const ImagePreview = react__WEBPACK_IMPORTED_MODULE_0___default().lazy(_ => __webpack_require__.e(/*! import() */ "src_widgets_image-preview_jsx").then(__webpack_require__.bind(__webpack_require__, /*! ../widgets/image-preview.jsx */ "./src/widgets/image-preview.jsx"))); const TheCardPreview = react__WEBPACK_IMPORTED_MODULE_0___default().lazy(_ => Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_libphonenumber-js_mobile_exports_parsePhoneNumberWithError_js"), __webpack_require__.e("src_widgets_the-card-preview_jsx")]).then(__webpack_require__.bind(__webpack_require__, /*! ../widgets/the-card-preview.jsx */ "./src/widgets/the-card-preview.jsx"))); const VideoPreview = react__WEBPACK_IMPORTED_MODULE_0___default().lazy(_ => __webpack_require__.e(/*! import() */ "src_widgets_video-preview_jsx").then(__webpack_require__.bind(__webpack_require__, /*! ../widgets/video-preview.jsx */ "./src/widgets/video-preview.jsx"))); const NOTIFICATION_EXEC_INTERVAL = 300; const SHOW_GO_TO_LAST_DIST = 100; const FETCH_PAGE_TRIGGER = 40; const messages = (0,react_intl__WEBPACK_IMPORTED_MODULE_1__.defineMessages)({ message_deleted: { id: 'message_deleted', defaultMessage: 'message deleted', description: 'Placeholder shown in the timeline where a message was recalled or deleted' }, online_now: { id: 'online_now', defaultMessage: 'online now', description: 'Indicator that the user or topic is currently online' }, last_seen: { id: 'last_seen_timestamp', defaultMessage: 'Last seen: {timestamp}', description: 'Label for the timestamp of when the user or topic was last online' }, not_found: { id: 'title_not_found', defaultMessage: 'Not found', description: 'Title shown when topic is not found' }, channel: { id: 'channel', defaultMessage: 'channel', description: 'Subtitle shown for channels in MessagesView instead of last seen' }, file_attachment_too_large: { id: 'file_attachment_too_large', defaultMessage: 'The file size {size} exceeds the {limit} limit.', description: 'Error message when attachment is too large' }, invalid_content: { id: 'invalid_content', defaultMessage: 'invalid content', description: 'Shown when the message is unreadable' }, editing_message: { id: 'editing_message', defaultMessage: 'Editing', description: 'Title over message editing preview' }, drag_file: { id: 'drag_file', defaultMessage: 'Drag file here', description: 'Prompt on the file drag-n-drop overlay banner' }, self_topic_name: { id: 'self_topic_name', defaultMessage: 'Saved messages', description: 'Name of self topic for UI' }, subscriber_count: { id: 'subscriber_count', defaultMessage: '{count, plural, ' + 'one {{count, number} subscriber} ' + 'two {{count, number} subscribers} ' + 'three {{count, number} subscribers} ' + 'few {{count, number} subscribers} ' + 'many {{count, number} subscribers} ' + 'other {{count, number} subscribers}}', description: 'Count of channel subscribers' }, member_count: { id: 'member_count', defaultMessage: '{count, plural, ' + 'one {{count, number} member} ' + 'two {{count, number} members} ' + 'three {{count, number} members} ' + 'few {{count, number} members} ' + 'many {{count, number} members} ' + 'other {{count, number} members}}', description: 'Count of group topic members' }, cannot_parse_vcard: { id: 'cannot_parse_vcard', defaultMessage: 'Cannot parse vCard file.', description: 'Error message when vCard file cannot be parsed' } }); function isUnconfirmed(acs) { if (acs) { const ex = acs.getExcessive() || ''; return acs.isJoiner('given') && (ex.includes('R') || ex.includes('W')); } return false; } function isPeerRestricted(acs) { if (acs) { const ms = acs.getMissing() || ''; return acs.isJoiner('want') && (ms.includes('R') || ms.includes('W')); } return false; } const MENTION_ALL_UID = '__mention_all__'; function shouldPresentCallPanel(callState) { return callState == _constants_js__WEBPACK_IMPORTED_MODULE_16__.CALL_STATE_OUTGOING_INITATED || callState == _constants_js__WEBPACK_IMPORTED_MODULE_16__.CALL_STATE_IN_PROGRESS; } class MessagesView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component) { constructor(props) { super(props); this.state = MessagesView.getDerivedStateFromProps(props, {}); this.state.messagePolicy = null; this.state.toast = null; this.state.riskDialog = null; this.mentionedUsers = []; this.mentionAllPending = false; this.componentSetup = this.componentSetup.bind(this); this.leave = this.leave.bind(this); this.sendMessage = this.sendMessage.bind(this); this.handleRiskConfirm = this.handleRiskConfirm.bind(this); this.handleRiskCancel = this.handleRiskCancel.bind(this); this.retrySend = this.retrySend.bind(this); this.sendImageAttachment = this.sendImageAttachment.bind(this); this.sendVideoAttachment = this.sendVideoAttachment.bind(this); this.sendFileAttachment = this.sendFileAttachment.bind(this); this.sendAudioAttachment = this.sendAudioAttachment.bind(this); this.sendTheCardAttachment = this.sendTheCardAttachment.bind(this); this.sendKeyPress = this.sendKeyPress.bind(this); this.subscribe = this.subscribe.bind(this); this.handleScrollReference = this.handleScrollReference.bind(this); this.mountDnDEvents = this.mountDnDEvents.bind(this); this.handleScrollEvent = this.handleScrollEvent.bind(this); this.handleDescChange = this.handleDescChange.bind(this); this.handleSubsUpdated = this.handleSubsUpdated.bind(this); this.handleMessageUpdate = this.handleMessageUpdate.bind(this); this.handleAuxUpdate = this.handleAuxUpdate.bind(this); this.handleAllMessagesReceived = this.handleAllMessagesReceived.bind(this); this.handleInfoReceipt = this.handleInfoReceipt.bind(this); this.handleExpandMedia = this.handleExpandMedia.bind(this); this.handleClosePreview = this.handleClosePreview.bind(this); this.handleCallPanelToggle = this.handleCallPanelToggle.bind(this); this.handleFormResponse = this.handleFormResponse.bind(this); this.handleContextClick = this.handleContextClick.bind(this); this.handleShowMessageContextMenu = this.handleShowMessageContextMenu.bind(this); this.handleNewChatAcceptance = this.handleNewChatAcceptance.bind(this); this.handleEnablePeer = this.handleEnablePeer.bind(this); this.loadRelationshipContext = this.loadRelationshipContext.bind(this); this.loadGroupContext = this.loadGroupContext.bind(this); this.loadDraft = this.loadDraft.bind(this); this.handleComposerChange = this.handleComposerChange.bind(this); this.clearDraft = this.clearDraft.bind(this); this.mentionSearch = this.mentionSearch.bind(this); this.mentionSelected = this.mentionSelected.bind(this); this.handleShowAnnouncement = this.handleShowAnnouncement.bind(this); this.handleShowJoinRequests = this.handleShowJoinRequests.bind(this); this.handleSendFriendVerification = this.handleSendFriendVerification.bind(this); this.handleBatchDelete = this.handleBatchDelete.bind(this); this.handleBatchFavorite = this.handleBatchFavorite.bind(this); this.handleAttachFile = this.handleAttachFile.bind(this); this.handleAttachImageOrVideo = this.handleAttachImageOrVideo.bind(this); this.handleCancelUpload = this.handleCancelUpload.bind(this); this.postReadNotification = this.postReadNotification.bind(this); this.clearNotificationQueue = this.clearNotificationQueue.bind(this); this.goToLatestMessage = this.goToLatestMessage.bind(this); this.handleFileDrop = this.handleFileDrop.bind(this); this.handlePickReply = this.handlePickReply.bind(this); this.handleEditMessage = this.handleEditMessage.bind(this); this.handleCancelReply = this.handleCancelReply.bind(this); this.handleQuoteClick = this.handleQuoteClick.bind(this); this.jumpToMessage = this.jumpToMessage.bind(this); this.handleUnpinMessage = this.handleUnpinMessage.bind(this); this.handleCallHangup = this.handleCallHangup.bind(this); this.isDragEnabled = this.isDragEnabled.bind(this); this.handleDragStart = this.handleDragStart.bind(this); this.handleDragIn = this.handleDragIn.bind(this); this.handleDragOut = this.handleDragOut.bind(this); this.handleDrag = this.handleDrag.bind(this); this.handleDrop = this.handleDrop.bind(this); this.chatMessageRefs = []; this.getOrCreateMessageRef = this.getOrCreateMessageRef.bind(this); this.getVisibleMessageRange = this.getVisibleMessageRange.bind(this); this.dragCounter = 0; this.dndRef = null; this.readNotificationQueue = []; this.readNotificationTimer = null; this.keyPressTimer = null; } getOrCreateMessageRef(seqId) { if (this.chatMessageRefs[seqId]) { return this.chatMessageRefs[seqId]; } const ref = react__WEBPACK_IMPORTED_MODULE_0___default().createRef(); this.chatMessageRefs[seqId] = ref; return ref; } getVisibleMessageRange(holderRect) { let min = Number.MAX_SAFE_INTEGER, max = -1; let visibilityStatus = false; this.chatMessageRefs.every((ref, seq) => { if (ref.current) { const { top, bottom, height } = ref.current.getBoundingClientRect(); const visible = top <= holderRect.top ? holderRect.top - top <= height : bottom - holderRect.bottom <= height; if (visible) { visibilityStatus = true; min = Math.min(min, seq); max = Math.max(max, seq); } else if (visibilityStatus) { return false; } } return true; }); return max >= min ? { min: min, max: max } : { min: 0, max: 0 }; } componentDidMount() { if (this.messagesScroller) { this.messagesScroller.addEventListener('scroll', this.handleScrollEvent); } this.mountDnDEvents(this.dndRef); this.componentSetup({}, {}); (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_19__.getBootstrap)().then(data => { this.setState({ messagePolicy: data.message_policy || null }); }).catch(_ => {}); } componentWillUnmount() { if (this.state.rtcPanel) { this.handleCallHangup(this.state.topic, this.props.callSeq); } if (this.messagesScroller) { this.messagesScroller.removeEventListener('scroll', this.handleScrollEvent); } window.clearTimeout(this.toastTimer); this.clearNotificationQueue(); if (this.dndRef) { this.dndRef.removeEventListener('dragstart', this.handleDragStart); this.dndRef.removeEventListener('dragenter', this.handleDragIn); this.dndRef.removeEventListener('dragleave', this.handleDragOut); this.dndRef.removeEventListener('dragover', this.handleDrag); this.dndRef.removeEventListener('drop', this.handleDrop); } } componentDidUpdate(prevProps, prevState) { if (this.messagesScroller && (prevState.topic != this.state.topic || prevState.maxSeqId != this.state.maxSeqId || prevState.minSeqId != this.state.minSeqId)) { if (this.state.scrollPosition < SHOW_GO_TO_LAST_DIST) { this.messagesScroller.scrollTop = this.messagesScroller.scrollHeight - this.state.scrollPosition - this.messagesScroller.offsetHeight; } } if (!this.props.applicationVisible) { this.clearNotificationQueue(); } else { this.postReadNotification(0); } if (this.props.jumpToSeq && this.props.jumpToSeq != prevProps.jumpToSeq) { this.jumpToMessage(parseInt(this.props.jumpToSeq, 10)); } this.componentSetup(prevProps, prevState); } componentSetup(prevProps, prevState) { const topic = this.props.tinode ? this.props.tinode.getTopic(this.state.topic) : undefined; if (this.state.topic != prevState.topic) { if (prevState.topic && !tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Tinode.isNewGroupTopicName(prevState.topic)) { this.leave(prevState.topic); if (prevState.rtcPanel) { this.handleCallHangup(prevState.topic, prevProps.callSeq); } } if (topic) { topic.onData = this.handleMessageUpdate; topic.onAllMessagesReceived = this.handleAllMessagesReceived; topic.onInfo = this.handleInfoReceipt; topic.onMetaDesc = this.handleDescChange; topic.onSubsUpdated = this.handleSubsUpdated; topic.onPres = this.handleSubsUpdated; topic.onAuxUpdated = this.handleAuxUpdate; } this.mentionedUsers = []; this.mentionAllPending = false; this.loadRelationshipContext(topic); this.loadGroupContext(topic); this.loadDraft(topic); } if (topic) { if (this.state.topic != prevState.topic || this.props.myUserId && !prevProps.myUserId) { const newTopic = this.props.newTopicParams && this.props.newTopicParams._topicName == this.props.topic; if (topic.isP2PType() && newTopic && !_config_js__WEBPACK_IMPORTED_MODULE_15__.IMMEDIATE_P2P_SUBSCRIPTION) { topic.getMeta(topic.startMetaQuery().withDesc().build()); } else if (this.props.myUserId) { this.subscribe(topic); } } else if (topic.isSubscribed() && this.state.isReader && !prevState.isReader) { topic.getMeta(topic.startMetaQuery().withLaterData().build()); } else if (!topic.isSubscribed() && this.props.ready && !prevProps.ready) { this.subscribe(topic); } } } static getDerivedStateFromProps(nextProps, prevState) { let nextState = {}; if (!nextProps.topic) { nextState = { minSeqId: -1, maxSeqId: -1, latestClearId: -1, onlineSubs: [], topic: null, title: '', avatar: null, isVerified: false, isStaff: false, isDangerous: false, deleted: false, docPreview: null, imagePreview: null, imagePostview: null, videoPreview: null, videoPostview: null, rtcPanel: null, minimizedCallPanel: false, typingIndicator: false, scrollPosition: 0, fetchingMessages: false, peerMessagingDisabled: false, channel: false, reply: null, contentToEdit: null, showGoToLastButton: false, dragging: false, pins: [], pinsLoaded: false, selectedPin: 0, subsVersion: 0, relationshipContext: null, groupRoles: null, myGroupRole: null, groupAnnouncement: null, pendingJoinRequests: 0, draftText: null, draftVersion: 0 }; } else if (nextProps.topic != prevState.topic) { const topic = nextProps.tinode.getTopic(nextProps.topic); nextState = { topic: nextProps.topic, deleted: topic._deleted, docPreview: null, imagePreview: null, imagePostview: null, videoPreview: null, videoPostview: null, rtcPanel: null, minimizedCallPanel: false, typingIndicator: false, scrollPosition: 0, fetchingMessages: false, showGoToLastButton: false, contentToEdit: null, dragging: false, selectedPin: 0, relationshipContext: null, groupRoles: null, myGroupRole: null, groupAnnouncement: null, pendingJoinRequests: 0, draftText: null, draftVersion: 0, riskDialog: null }; if (nextProps.forwardMessage) { if (nextProps.forwardMessage.content) { const content = nextProps.forwardMessage.content; const size = content?.length || content?.size || 0; nextState.docPreview = { object: content, type: nextProps.forwardMessage.type, size: size }; } else { nextState.reply = { content: nextProps.forwardMessage.preview, seq: null }; } } else { nextState.reply = null; } if (topic) { const subs = []; if (nextProps.connected) { topic.subscribers(sub => { if (sub.online && sub.user != nextProps.myUserId) { subs.push(sub); } }); } Object.assign(nextState, { onlineSubs: subs }); if (topic.isSelfType()) { Object.assign(nextState, { title: nextProps.intl.formatMessage(messages.self_topic_name), avatar: true }); } else if (topic.public) { Object.assign(nextState, { title: (0,_lib_utils_js__WEBPACK_IMPORTED_MODULE_18__.topicDisplayName)(topic.name, topic.public, ''), avatar: (0,_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_17__.makeImageUrl)(topic.public.photo) }); } else { Object.assign(nextState, { title: '', avatar: null }); } const peer = topic.p2pPeerDesc(); if (peer) { Object.assign(nextState, { peerMessagingDisabled: isPeerRestricted(peer.acs) }); } else if (prevState.peerMessagingDisabled) { Object.assign(nextState, { peerMessagingDisabled: false }); } Object.assign(nextState, { minSeqId: topic.minMsgSeq(), maxSeqId: topic.maxMsgSeq(), latestClearId: topic.maxClearId(), channel: topic.isChannelType(), pins: (topic.aux('pins') || []).slice(), pinsLoaded: false }); if (nextProps.callTopic == topic.name && shouldPresentCallPanel(nextProps.callState)) { nextState.rtcPanel = nextProps.callTopic; } } else { Object.assign(nextState, { minSeqId: -1, maxSeqId: -1, latestClearId: -1, onlineSubs: [], title: '', avatar: null, peerMessagingDisabled: false, channel: false, pins: [], pinsLoaded: false }); } } else { if (nextProps.callTopic == prevState.topic && !prevState.rtcPanel && shouldPresentCallPanel(nextProps.callState)) { nextState.rtcPanel = nextProps.callTopic; } } if (nextProps.acs) { if (nextProps.acs.isWriter() != prevState.isWriter) { nextState.isWriter = !prevState.isWriter; } if (nextProps.acs.isReader() != prevState.isReader) { nextState.isReader = !prevState.isReader; } if (nextProps.acs.isAdmin() != prevState.isAdmin) { nextState.isAdmin = !prevState.isAdmin; } if (!nextProps.acs.isReader('given') != prevState.readingBlocked) { nextState.readingBlocked = !prevState.readingBlocked; } if (nextProps.acs.isSharer() != prevState.isSharer) { nextState.isSharer = !prevState.isSharer; } } else { if (prevState.isWriter) { nextState.isWriter = false; } if (prevState.isReader) { nextState.isReader = false; } if (prevState.isAdmin) { nextState.isAdmin = false; } if (!prevState.readingBlocked) { nextState.readingBlocked = true; } if (prevState.isSharer) { nextState.isSharer = false; } } if (isUnconfirmed(nextProps.acs) == !prevState.unconformed) { nextState.unconfirmed = !prevState.unconformed; } if (!nextProps.connected && prevState.onlineSubs && prevState.onlineSubs.length > 0) { nextState.onlineSubs = []; } return nextState; } subscribe(topic) { if (topic.isSubscribed() || !this.props.ready) { return; } const newTopic = this.props.newTopicParams && this.props.newTopicParams._topicName == this.props.topic; let getQuery = topic.startMetaQuery().withLaterDesc().withLaterSub().withAux(); if (this.state.isReader || newTopic) { getQuery = getQuery.withLaterData(_config_js__WEBPACK_IMPORTED_MODULE_15__.MESSAGES_PAGE); if (this.state.isReader) { getQuery = getQuery.withLaterDel(); } this.setState({ fetchingMessages: true }); } const setQuery = newTopic ? this.props.newTopicParams : undefined; topic.subscribe(getQuery.build(), setQuery).then(ctrl => { if (ctrl.code == 303) { _lib_navigation_js__WEBPACK_IMPORTED_MODULE_20__["default"].navigateTo(_lib_navigation_js__WEBPACK_IMPORTED_MODULE_20__["default"].setUrlTopic('', ctrl.params.topic)); return; } if (this.state.topic != ctrl.topic) { this.setState({ topic: ctrl.topic }); } if (this.state.deleted) { this.setState({ deleted: false }); } this.props.onNewTopicCreated(this.props.topic, ctrl.topic); let discard = []; topic.queuedMessages(pub => { if (pub._sending) { return; } if (pub._fatal || pub.head && pub.head.webrtc) { discard.push(pub.seq); return; } if (topic.isSubscribed()) { this.retrySend(pub); } }); if (discard.length > 0) { topic.delMessagesList(discard, true); } }).catch(err => { console.error("Failed subscription to", this.state.topic, err); this.props.onError(err.message, 'err'); const blankState = MessagesView.getDerivedStateFromProps({}, {}); blankState.title = this.props.intl.formatMessage(messages.not_found); this.setState(blankState); }); } leave(oldTopicName) { if (!oldTopicName || !this.props.tinode.isTopicCached(oldTopicName)) { return; } const oldTopic = this.props.tinode.getTopic(oldTopicName); if (oldTopic && oldTopic.isSubscribed()) { oldTopic.leave(false).catch(_ => {}).finally(_ => { this.setState({ fetchingMessages: false }); oldTopic.onData = undefined; oldTopic.onAllMessagesReceived = undefined; oldTopic.onInfo = undefined; oldTopic.onMetaDesc = undefined; oldTopic.onSubsUpdated = undefined; oldTopic.onPres = undefined; oldTopic.onAuxUpdated = undefined; }); } } handleScrollReference(node) { if (node) { node.addEventListener('scroll', this.handleScrollEvent); this.messagesScroller = node; this.messagesScroller.scrollTop = this.messagesScroller.scrollHeight - this.state.scrollPosition - this.messagesScroller.offsetHeight; } } handleScrollEvent(event) { const pos = event.target.scrollHeight - event.target.scrollTop - event.target.offsetHeight; this.setState({ scrollPosition: pos, showGoToLastButton: pos > SHOW_GO_TO_LAST_DIST && pos < this.state.scrollPosition }); if (this.state.fetchingMessages || this.processingScrollEvent) { return; } if (event.target.scrollTop <= FETCH_PAGE_TRIGGER) { const topic = this.props.tinode.getTopic(this.state.topic); if (topic && topic.isSubscribed()) { this.processingScrollEvent = true; const { min, max } = this.getVisibleMessageRange(event.target.getBoundingClientRect()); const gaps = topic.msgHasMoreMessages(min, max, false); if (gaps.length > 0) { this.setState({ fetchingMessages: true }, _ => { topic.getMessagesPage(_config_js__WEBPACK_IMPORTED_MODULE_15__.MESSAGES_PAGE, gaps, min, max).catch(err => this.props.onError(err.message, 'err')).finally(_ => this.setState({ fetchingMessages: false })); }); } } } this.processingScrollEvent = false; } mountDnDEvents(dnd) { if (dnd) { dnd.addEventListener('dragstart', this.handleDragStart); dnd.addEventListener('dragenter', this.handleDragIn); dnd.addEventListener('dragleave', this.handleDragOut); dnd.addEventListener('dragover', this.handleDrag); dnd.addEventListener('drop', this.handleDrop); this.dndRef = dnd; } } goToLatestMessage() { this.setState({ scrollPosition: 0 }); if (this.messagesScroller) { this.messagesScroller.scrollTop = this.messagesScroller.scrollHeight - this.messagesScroller.offsetHeight; } } handleDescChange(desc) { if (tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Tinode.isSelfTopicName(this.props.topic)) { this.setState({ title: this.props.intl.formatMessage(messages.self_topic_name), avatar: true }); } else if (desc.public) { this.setState({ title: (0,_lib_utils_js__WEBPACK_IMPORTED_MODULE_18__.topicDisplayName)(this.props.topic, desc.public, ''), avatar: (0,_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_17__.makeImageUrl)(desc.public.photo) }); } else { this.setState({ title: '', avatar: null }); } if (desc.acs) { this.setState({ isWriter: desc.acs.isWriter(), isReader: desc.acs.isReader(), isAdmin: desc.acs.isAdmin(), readingBlocked: !desc.acs.isReader('given'), unconfirmed: isUnconfirmed(desc.acs) }); } } postReadNotification(seq) { if (!this.props.applicationVisible || !this.state.topic) { return; } if (!this.readNotificationTimer) { this.readNotificationTimer = setInterval(_ => { if (this.readNotificationQueue.length == 0) { clearInterval(this.readNotificationTimer); this.readNotificationTimer = null; return; } let seq = -1; while (this.readNotificationQueue.length > 0) { const n = this.readNotificationQueue[0]; if (n.topicName != this.state.topic) { this.readNotificationQueue.shift(); continue; } const now = new Date(); if (n.sendAt <= now) { this.readNotificationQueue.shift(); if (n.seq == 0 || tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Tinode.isServerAssignedSeq(n.seq)) { seq = Math.max(seq, n.seq); } } else { break; } } if (seq >= 0) { const topic = this.props.tinode.getTopic(this.state.topic); if (topic) { try { topic.noteRead(seq); } catch (err) { console.error("Failed to send read notification", err); } } } }, NOTIFICATION_EXEC_INTERVAL); } const now = new Date(); this.readNotificationQueue.push({ topicName: this.state.topic, seq: seq, sendAt: now.setMilliseconds(now.getMilliseconds() + _config_js__WEBPACK_IMPORTED_MODULE_15__.READ_DELAY) }); } clearNotificationQueue() { this.readNotificationQueue = []; if (this.readNotificationTimer) { clearInterval(this.readNotificationTimer); this.readNotificationTimer = null; } } handleSubsUpdated() { if (this.state.topic) { const subs = []; const topic = this.props.tinode.getTopic(this.state.topic); topic.subscribers(sub => { if (sub.online && sub.user != this.props.myUserId) { subs.push(sub); } }); const newState = { onlineSubs: subs, subsVersion: this.state.subsVersion + 1 }; const peer = topic.p2pPeerDesc(); if (peer) { Object.assign(newState, { peerMessagingDisabled: isPeerRestricted(peer.acs) }); } else if (this.state.peerMessagingDisabled) { Object.assign(newState, { peerMessagingDisabled: false }); } this.setState(newState); } } handleMessageUpdate(msg) { if (!this.state.topic) { return; } const topic = this.props.tinode.getTopic(this.state.topic); if (!msg) { this.setState({ latestClearId: topic.maxClearId() }); return; } clearTimeout(this.keyPressTimer); this.setState({ maxSeqId: topic.maxMsgSeq(), minSeqId: topic.minMsgSeq(), typingIndicator: false }, _ => { if (topic.isNewMessage(msg.seq)) { if (this.state.scrollPosition > SHOW_GO_TO_LAST_DIST) { this.setState({ showGoToLastButton: true }); } else { this.goToLatestMessage(); } } else { if (this.messagesScroller) { this.messagesScroller.scrollTop = this.messagesScroller.scrollHeight - this.state.scrollPosition - this.messagesScroller.offsetHeight; } } }); const status = topic.msgStatus(msg, true); if (status >= tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Tinode.MESSAGE_STATUS_SENT && msg.from != this.props.myUserId) { this.postReadNotification(msg.seq); } } handleAllMessagesReceived(count) { this.setState({ fetchingMessages: false }); if (!count) { const topic = this.props.tinode.getTopic(this.state.topic); if (topic) { this.postReadNotification(topic.seq); } return; } if (!this.state.pinsLoaded) { const topic = this.props.tinode.getTopic(this.state.topic); this.setState({ pinsLoaded: true }, _ => { topic.getPinnedMessages(); }); } else { this.setState({ pinsLoaded: false }); } } handleAuxUpdate(aux) { const pins = (aux['pins'] || []).slice(); let selectedPin = this.state.selectedPin; if (pins.length > this.state.pins.length) { selectedPin = 0; } else if (selectedPin >= pins.length) { selectedPin = Math.max(0, pins.length - 1); } this.setState({ pins: pins, selectedPin: selectedPin }); } handleInfoReceipt(info) { switch (info.what) { case 'kp': { clearTimeout(this.keyPressTimer); this.keyPressTimer = setTimeout(_ => this.setState({ typingIndicator: false }), _config_js__WEBPACK_IMPORTED_MODULE_15__.KEYPRESS_DELAY + 1000); if (!this.state.typingIndicator) { this.setState({ typingIndicator: true }); } break; } case 'read': case 'recv': this.forceUpdate(); break; default: console.info("Other change in topic: ", info.what); } } handleExpandMedia(content) { if (!content) { return; } if (content.video) { this.setState({ videoPostview: content }); } else { this.setState({ imagePostview: content }); } } handleClosePreview() { if (this.state.imagePreview && this.state.imagePreview.url) { URL.revokeObjectURL(this.state.imagePreview.url); } if (this.state.videoPreview && this.state.videoPreview.url) { URL.revokeObjectURL(this.state.videoPreview.url); } this.setState({ imagePostview: null, imagePreview: null, docPreview: null, videoPreview: null, videoPostview: null }); this.props.onCancelForwardMessage(); } handleFormResponse(action, text, data) { if (action == 'pub') { this.sendMessage(tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.attachJSON(tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.parse(text), data)); } else if (action == 'url') { const url = new URL(data.ref); const params = url.searchParams; for (let key in data.resp) { if (data.resp.hasOwnProperty(key)) { params.set(key, data.resp[key]); } } ['name', 'seq'].forEach(key => { if (data[key]) { params.set(key, data[key]); } }); params.set('uid', this.props.myUserId); params.set('topic', this.state.topic); url.search = params; window.open(url, '_blank'); } else { console.info("Unknown action in form", action); } } handleContextClick(e) { e.preventDefault(); e.stopPropagation(); this.props.showContextMenu({ topicName: this.state.topic, y: e.pageY, x: e.pageX }); } handleShowMessageContextMenu(params, messageSpecificMenuItems) { if (params.userFrom == 'chan') { params.userFrom = this.state.topic; params.userName = this.state.title; } params.topicName = this.state.topic; let menuItems = messageSpecificMenuItems || []; if (this.state.reply && this.state.reply.editing) { menuItems = menuItems.filter(item => item !== 'menu_item_reply'); } const topic = this.props.tinode.getTopic(params.topicName); if (topic) { const editWindow = this.state.messagePolicy ? this.state.messagePolicy.edit_window_seconds : 0; if (menuItems.includes('menu_item_edit') && !(editWindow > 0 && params.timestamp && params.timestamp.getTime() > new Date().getTime() - editWindow * 1000)) { menuItems = menuItems.filter(item => item !== 'menu_item_edit'); } menuItems.push('menu_item_copy', 'menu_item_favorite'); const recallWindow = this.state.messagePolicy ? this.state.messagePolicy.recall_window_seconds : 0; const canRecallAsAdmin = topic.isGroupType() && topic.getAccessMode() && topic.getAccessMode().isAdmin(); if ((params.userFrom == this.props.myUserId || canRecallAsAdmin) && params.seq > 0 && recallWindow > 0 && params.timestamp && params.timestamp.getTime() > new Date().getTime() - recallWindow * 1000) { menuItems.push('menu_item_recall'); } if (topic.isSelfType()) { menuItems.push('message_delete_generic'); } else { if (!topic.isChannelType()) { menuItems.push('message_delete'); } const acs = topic.getAccessMode(); if (acs && acs.isDeleter()) { let canDelete = acs.isOwner(); if (!canDelete) { const maxDelAge = this.props.tinode.getServerParam(tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Tinode.MSG_DELETE_AGE, 0) | 0; canDelete = maxDelAge == 0 || (maxDelAge > 0 && params.timestamp ? params.timestamp.getTime() > new Date().getTime() - maxDelAge * 1000 : false); } if (canDelete) { menuItems.push('message_delete_hard'); } } } } menuItems.push('menu_item_select'); this.props.showContextMenu(params, menuItems); } handleNewChatAcceptance(action) { this.props.onNewChat(this.state.topic, action); } handleEnablePeer(e) { e.preventDefault(); this.props.onChangePermissions(this.state.topic, _config_js__WEBPACK_IMPORTED_MODULE_15__.DEFAULT_P2P_ACCESS_MODE, this.state.topic); } loadRelationshipContext(topic) { if (!topic || !topic.isP2PType()) { return; } const topicName = topic.name; (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_19__.getConversationContext)(topicName).then(data => { if (this.state.topic == topicName) { this.setState({ relationshipContext: data }); } }).catch(_ => {}); } loadGroupContext(topic) { if (!topic || !topic.isGroupType() || topic.isChannelType()) { return; } const topicName = topic.name; (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_19__.getGroupMembers)(topicName).then(data => { if (this.state.topic != topicName) { return; } const roles = {}; (data.items || []).forEach(m => { roles[m.user_id] = m.role; }); this.setState({ groupRoles: roles, myGroupRole: roles[this.props.myUserId] || null }); if (roles[this.props.myUserId] == 'owner' || roles[this.props.myUserId] == 'admin') { (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_19__.getGroupJoinRequests)(topicName, 'pending').then(reqData => { if (this.state.topic == topicName) { this.setState({ pendingJoinRequests: (reqData.items || []).length }); } }).catch(_ => {}); } }).catch(_ => {}); (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_19__.getLatestGroupAnnouncement)(topicName).then(data => { if (this.state.topic == topicName) { this.setState({ groupAnnouncement: data && data.content ? data : null }); } }).catch(_ => {}); } mentionSearch(query) { const topic = this.props.tinode ? this.props.tinode.getTopic(this.state.topic) : null; if (!topic || !topic.isGroupType()) { return Promise.resolve([]); } return (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_19__.getGroupMembers)(this.state.topic, { mentionable: true, query }).then(data => { const items = data.items || []; const canMentionAll = !!(data.permissions && data.permissions.can_mention_all); if (canMentionAll && '所有人'.includes((query || '').trim())) { return [{ user_id: MENTION_ALL_UID, display_name: '所有人' }, ...items]; } return items; }); } mentionSelected(uid, name) { if (uid === MENTION_ALL_UID) { this.mentionAllPending = true; return; } this.mentionedUsers = (this.mentionedUsers || []).filter(m => m.name !== name); this.mentionedUsers.push({ uid, name }); } loadDraft(topic) { if (!topic) { return; } const topicName = topic.name; (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_19__.getTopicDraft)(topicName).then(data => { if (this.state.topic != topicName) { return; } this.setState({ draftText: data.content || '', draftVersion: data.version || 0 }); }).catch(_ => {}); } handleComposerChange(text) { if (this.state.reply && this.state.reply.editing) { return; } if (this.props.forwardMessage) { return; } const topicName = this.state.topic; if (!topicName) { return; } const version = this.state.draftVersion || 0; this.draftSaveTimers = this.draftSaveTimers || {}; if (this.draftSaveTimers[topicName]) { window.clearTimeout(this.draftSaveTimers[topicName]); } this.draftSaveTimers[topicName] = window.setTimeout(() => { delete this.draftSaveTimers[topicName]; (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_19__.updateTopicDraft)(topicName, text, [], version).then(d => { if (this.state.topic == topicName) { this.setState({ draftVersion: d.version }); } }).catch(_ => {}); }, 600); } clearDraft(topicName, knownVersion) { if (this.draftSaveTimers && this.draftSaveTimers[topicName]) { window.clearTimeout(this.draftSaveTimers[topicName]); delete this.draftSaveTimers[topicName]; } const version = knownVersion != null ? knownVersion : this.state.topic == topicName ? this.state.draftVersion || 0 : 0; (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_19__.updateTopicDraft)(topicName, '', [], version).then(d => { if (this.state.topic == topicName) { this.setState({ draftText: '', draftVersion: d.version }); } }).catch(_ => {}); } handleShowAnnouncement(e) { e.preventDefault(); let hash = _lib_navigation_js__WEBPACK_IMPORTED_MODULE_20__["default"].addUrlParam(_lib_navigation_js__WEBPACK_IMPORTED_MODULE_20__["default"].setUrlSidePanel('', 'group-announcement-detail'), 'topic', this.state.topic); hash = _lib_navigation_js__WEBPACK_IMPORTED_MODULE_20__["default"].addUrlParam(hash, 'from', 'chat'); _lib_navigation_js__WEBPACK_IMPORTED_MODULE_20__["default"].navigateTo(hash); } handleShowJoinRequests(e) { e.preventDefault(); let hash = _lib_navigation_js__WEBPACK_IMPORTED_MODULE_20__["default"].addUrlParam(_lib_navigation_js__WEBPACK_IMPORTED_MODULE_20__["default"].setUrlSidePanel('', 'group-join-requests'), 'topic', this.state.topic); hash = _lib_navigation_js__WEBPACK_IMPORTED_MODULE_20__["default"].addUrlParam(hash, 'from', 'chat'); _lib_navigation_js__WEBPACK_IMPORTED_MODULE_20__["default"].navigateTo(hash); } handleSendFriendVerification(e) { e.preventDefault(); _lib_navigation_js__WEBPACK_IMPORTED_MODULE_20__["default"].navigateTo(_lib_navigation_js__WEBPACK_IMPORTED_MODULE_20__["default"].addUrlParam(_lib_navigation_js__WEBPACK_IMPORTED_MODULE_20__["default"].setUrlSidePanel('', 'friend-verification'), 'uid', this.state.topic)); } showToast(text) { this.setState({ toast: text }); window.clearTimeout(this.toastTimer); this.toastTimer = window.setTimeout(() => this.setState({ toast: null }), 3500); } handleBatchDelete() { const topic = this.props.tinode.getTopic(this.state.topic); if (!topic || !this.props.selectedSeqs.length) { return; } const remaining = this.props.selectedSeqs.filter(seq => !topic.cancelSend(seq)); if (!remaining.length) { this.props.onExitSelectMode(); return; } topic.delMessagesList(remaining, true).then(_ => { this.props.onExitSelectMode(); }).catch(err => { this.props.onError(err.message, 'err'); }); } handleBatchFavorite() { if (!this.props.selectedSeqs.length) { return; } const topicName = this.state.topic; const seqs = this.props.selectedSeqs.slice(); (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_19__.favoriteMessages)(seqs.map(seq => ({ topic: topicName, seq }))).then(() => { return (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_19__.getFavorites)({ type: 'all', limit: 100 }).then(data => { const items = data && data.items || []; const landed = new Set(items.filter(it => it.source && it.source.topic == topicName).map(it => String(it.source.seq))); const missing = seqs.filter(seq => !landed.has(String(seq))); if (missing.length === seqs.length) { this.props.onError('收藏失败', 'err'); } else if (missing.length) { this.showToast(`已收藏 ${seqs.length - missing.length}/${seqs.length} 条`); } else { this.showToast('收藏成功'); } }); }).catch(err => { this.props.onError(err.message, 'err'); }); } sendKeyPress(audio) { const topic = this.props.tinode.getTopic(this.state.topic); if (!topic.isSubscribed()) { return; } if (audio) { return; } topic.noteKeyPress(); } applyMentionResolution(parsed) { if (!parsed || !Array.isArray(parsed.ent) || !this.mentionedUsers || !this.mentionedUsers.length) { return; } parsed.ent.forEach(e => { if (e.tp === 'MN' && e.data && typeof e.data.val === 'string') { const match = this.mentionedUsers.find(m => m.name === e.data.val); if (match) { e.data.val = match.uid; } } }); } sendMessage(msg, uploadCompletionPromise, uploader, typeHint) { const originalText = typeof msg === 'string' ? msg : null; let head; if (!msg && this.props.forwardMessage) { msg = this.props.forwardMessage.msg; head = this.props.forwardMessage.head; this.handleCancelReply(); } else if (this.state.reply) { if (this.state.reply.editing) { if (msg == this.state.contentToEdit) { this.handleCancelReply(); return; } head = { replace: ':' + this.state.reply.seq }; } else if (this.state.reply.content) { head = { reply: '' + this.state.reply.seq }; if (typeof msg == 'string') { msg = tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.parse(msg); this.applyMentionResolution(msg); } msg = tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.append(tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.sanitizeEntities(this.state.reply.content), msg); } this.handleCancelReply(); } else if (typeof msg == 'string' && this.mentionedUsers && this.mentionedUsers.length) { const parsed = tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.parse(msg); this.applyMentionResolution(parsed); msg = parsed; } this.mentionedUsers = []; if (this.mentionAllPending) { head = { ...(head || {}), mention_all: true }; this.mentionAllPending = false; } if (typeHint) { head = { ...(head || {}), 'x-im-type': typeHint }; } const topicForDraft = this.state.topic; const draftVersionAtSend = this.state.draftVersion || 0; const doSend = () => { const result = this.props.sendMessage(msg, uploadCompletionPromise, uploader, head); if (originalText != null && result && typeof result.then == 'function' && topicForDraft) { result.then(() => this.clearDraft(topicForDraft, draftVersionAtSend)); } return result; }; const urlMatches = originalText && originalText.match(/https?:\/\/\S+/g); if (urlMatches) { const RISK_RANK = { block: 2, warn: 1, allow: 0 }; const urls = Array.from(new Set(urlMatches)); return Promise.all(urls.map(url => (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_19__.checkURL)(url, 'message_compose'))).then(results => { const result = results.reduce((worst, r) => (RISK_RANK[r.decision] || 0) > (RISK_RANK[worst.decision] || 0) ? r : worst); if (result.decision === 'allow') { return doSend(); } return new Promise(resolve => { if (this.state.riskDialog) this.state.riskDialog.resolve(false); this.setState({ riskDialog: { blocked: result.decision === 'block', challengeId: result.risk_challenge_id, send: doSend, resolve } }); }); }).catch(_ => doSend()); } return doSend(); } handleRiskConfirm() { const dialog = this.state.riskDialog; if (!dialog) return; this.setState({ riskDialog: null }); const finish = () => dialog.resolve(dialog.send()); if (dialog.challengeId) { (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_19__.confirmRiskChallenge)(dialog.challengeId, 'continue').then(finish).catch(finish); } else { finish(); } } handleRiskCancel() { const dialog = this.state.riskDialog; if (!dialog) return; this.setState({ riskDialog: null }); if (dialog.challengeId && !dialog.blocked) { (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_19__.confirmRiskChallenge)(dialog.challengeId, 'cancel').catch(_ => {}); } dialog.resolve(false); } retrySend(pub) { this.props.sendMessage(pub.content, undefined, undefined, pub.head).then(_ => { const topic = this.props.tinode.getTopic(this.state.topic); topic.delMessagesList([pub.seq], true); }); } sendFileAttachment(file) { const maxInbandAttachmentSize = this.props.tinode.getServerParam('maxMessageSize', _config_js__WEBPACK_IMPORTED_MODULE_15__.MAX_INBAND_ATTACHMENT_SIZE) * 0.75 - 1024 | 0; if (tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.TheCard.isFileSupported(file.type, file.name) || file.type == tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.TheCard.contentType) { if (this.sendTheCardAttachment(file, maxInbandAttachmentSize)) { return; } } const jsonMimeConverter = fileType => fileType === _config_js__WEBPACK_IMPORTED_MODULE_15__.DRAFTY_FR_MIME_TYPE_LEGACY ? 'application/octet-stream' : fileType; if (file.size > maxInbandAttachmentSize) { const uploader = (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_19__.createChatUploader)(this.props.tinode); if (!uploader) { this.props.onError(this.props.intl.formatMessage(messages.cannot_initiate_upload)); return; } const uploadCompletionPromise = uploader.upload(file); const msg = tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.attachFile(null, { mime: jsonMimeConverter(file.type), filename: file.name, size: file.size, urlPromise: uploadCompletionPromise }); this.sendMessage(msg, uploadCompletionPromise, uploader, 'file'); } else { (0,_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_17__.fileToBase64)(file).then(b64 => this.sendMessage(tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.attachFile(null, { mime: jsonMimeConverter(b64.mime), data: b64.bits, filename: b64.name, size: file.size }), undefined, undefined, 'file')).catch(err => this.props.onError(err.message, 'err')); } } sendTheCardAttachment(file, maxInbandAttachmentSize) { if (file.size > maxInbandAttachmentSize) { return false; } if (file.type == tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.TheCard.contentType) { this.sendMessage(tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.appendTheCard(null, file.object)); return true; } (0,_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_17__.importVCard)(file).then(card => { this.sendMessage(tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.appendTheCard(null, card)); }).catch(err => { this.props.onError(this.props.intl.formatMessage(messages.cannot_parse_vcard, { error: err.message }), 'err'); }); return true; } handleAttachFile(file) { const maxExternAttachmentSize = this.props.tinode.getServerParam('maxFileUploadSize', _config_js__WEBPACK_IMPORTED_MODULE_15__.MAX_EXTERN_ATTACHMENT_SIZE); if (file.size > maxExternAttachmentSize) { this.props.onError(this.props.intl.formatMessage(messages.file_attachment_too_large, { size: (0,_lib_strformat_js__WEBPACK_IMPORTED_MODULE_21__.bytesToHumanSize)(file.size), limit: (0,_lib_strformat_js__WEBPACK_IMPORTED_MODULE_21__.bytesToHumanSize)(maxExternAttachmentSize) }), 'err'); } else { this.setState({ docPreview: { file: file, name: file.name, size: file.size, type: file.type } }); } } handleCallHangup(topic, seq) { this.props.onVideoCallClosed(); this.setState({ rtcPanel: null }); this.props.onCallHangup(topic, seq); } handleCallPanelToggle() { this.setState({ minimizedCallPanel: !this.state.minimizedCallPanel }); } sendImageAttachment(caption, blob) { const mime = this.state.imagePreview.mime; const width = this.state.imagePreview.width; const height = this.state.imagePreview.height; const fname = this.state.imagePreview.filename; const maxInbandAttachmentSize = this.props.tinode.getServerParam('maxMessageSize', _config_js__WEBPACK_IMPORTED_MODULE_15__.MAX_INBAND_ATTACHMENT_SIZE) * 0.75 - 1024 | 0; if (blob.size > maxInbandAttachmentSize) { const uploader = (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_19__.createChatUploader)(this.props.tinode); if (!uploader) { this.props.onError(this.props.intl.formatMessage(messages.cannot_initiate_upload)); return; } const uploadCompletionPromise = uploader.upload(blob); (0,_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_17__.imageScaled)(blob, _config_js__WEBPACK_IMPORTED_MODULE_15__.IMAGE_PREVIEW_DIM, _config_js__WEBPACK_IMPORTED_MODULE_15__.IMAGE_PREVIEW_DIM, -1, false).then(scaled => (0,_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_17__.blobToBase64)(scaled.blob)).then(b64 => { let msg = tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.insertImage(null, 0, { mime: mime, _tempPreview: b64.bits, bits: b64.bits, width: width, height: height, filename: fname, size: blob.size, urlPromise: uploadCompletionPromise }); if (caption) { msg = tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.appendLineBreak(msg); msg = tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.append(msg, tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.parse(caption)); } this.sendMessage(msg, uploadCompletionPromise, uploader, 'image'); }).catch(err => this.props.onError(err, 'err')); return; } (0,_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_17__.blobToBase64)(blob).then(b64 => { let msg = tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.insertImage(null, 0, { mime: b64.mime, bits: b64.bits, width: width, height: height, filename: fname, size: blob.size }); if (caption) { msg = tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.appendLineBreak(msg); msg = tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.append(msg, tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.parse(caption)); } this.sendMessage(msg, undefined, undefined, 'image'); }); } sendVideoAttachment(caption, videoBlob, previewBlob, params) { const width = params.width; const height = params.height; const maxInbandAttachmentSize = this.props.tinode.getServerParam('maxMessageSize', _config_js__WEBPACK_IMPORTED_MODULE_15__.MAX_INBAND_ATTACHMENT_SIZE) * 0.75 - 1024 | 0; const uploads = []; let uploader; if (videoBlob.size + previewBlob.size > maxInbandAttachmentSize) { uploader = (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_19__.createChatUploader)(this.props.tinode); if (!uploader) { this.props.onError(this.props.intl.formatMessage(messages.cannot_initiate_upload)); return; } uploads[0] = videoBlob.size > maxInbandAttachmentSize * 0.675 ? uploader.upload(videoBlob) : null; uploads[1] = previewBlob.size > maxInbandAttachmentSize * 0.275 ? uploader.upload(previewBlob) : null; } if (uploads.length == 0) { Promise.all([(0,_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_17__.blobToBase64)(videoBlob), (0,_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_17__.blobToBase64)(previewBlob)]).then(b64s => { const [v64, i64] = b64s; let msg = tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.insertVideo(null, 0, { mime: v64.mime, bits: v64.bits, preview: i64.bits, premime: i64.mime, width: width, height: height, duration: params.duration, filename: params.name, size: videoBlob.size }); if (caption) { msg = tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.appendLineBreak(msg); msg = tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.append(msg, tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.parse(caption)); } this.sendMessage(msg, undefined, undefined, 'video'); }); return; } const uploadCompletionPromise = Promise.all(uploads); const b64conv = []; b64conv[0] = uploads[0] ? null : (0,_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_17__.blobToBase64)(videoBlob); b64conv[1] = uploads[1] ? null : (0,_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_17__.imageScaled)(previewBlob, _config_js__WEBPACK_IMPORTED_MODULE_15__.MAX_IMAGE_DIM, _config_js__WEBPACK_IMPORTED_MODULE_15__.MAX_IMAGE_DIM, -1, false).then(scaled => (0,_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_17__.blobToBase64)(scaled.blob)); b64conv[2] = (0,_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_17__.imageScaled)(previewBlob, _config_js__WEBPACK_IMPORTED_MODULE_15__.VIDEO_PREVIEW_DIM, _config_js__WEBPACK_IMPORTED_MODULE_15__.VIDEO_PREVIEW_DIM, -1, false).then(scaled => (0,_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_17__.blobToBase64)(scaled.blob)); Promise.all(b64conv).then(b64s => { const [video, img, preview] = b64s; let msg = tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.insertVideo(null, 0, { mime: params.mime, bits: video ? video.bits : null, _tempPreview: preview.bits, preview: img ? img.bits : preview.bits, premime: img ? img.mime : preview.mime, width: width, height: height, duration: params.duration, filename: params.name, size: videoBlob.size, urlPromise: uploadCompletionPromise }); if (caption) { msg = tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.appendLineBreak(msg); msg = tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.append(msg, tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.parse(caption)); } this.sendMessage(msg, uploadCompletionPromise, uploader, 'video'); }).catch(err => this.props.onError(err.message, 'err')); } handleAttachImageOrVideo(file) { const maxExternAttachmentSize = this.props.tinode.getServerParam('maxFileUploadSize', _config_js__WEBPACK_IMPORTED_MODULE_15__.MAX_EXTERN_ATTACHMENT_SIZE); if (file.type.startsWith('video/')) { this.setState({ videoPreview: { url: URL.createObjectURL(file), blob: file, filename: file.name, size: file.size, mime: file.type } }); return; } (0,_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_17__.imageScaled)(file, _config_js__WEBPACK_IMPORTED_MODULE_15__.MAX_IMAGE_DIM, _config_js__WEBPACK_IMPORTED_MODULE_15__.MAX_IMAGE_DIM, maxExternAttachmentSize, false).then(scaled => { this.setState({ imagePreview: { url: URL.createObjectURL(scaled.blob), blob: scaled.blob, filename: scaled.name, width: scaled.width, height: scaled.height, size: scaled.blob.size, mime: scaled.mime } }); }).catch(err => { this.props.onError(err.message, 'err'); }); } handleFileDrop(files) { if (!files || files.length == 0) { return; } const file = files[0]; if (file.type && file.type.startsWith('image/')) { this.handleAttachImageOrVideo(file); } else { this.handleAttachFile(file); } } sendAudioAttachment(url, preview, duration) { fetch(url).then(result => result.blob()).then(blob => { const maxInbandAttachmentSize = this.props.tinode.getServerParam('maxMessageSize', _config_js__WEBPACK_IMPORTED_MODULE_15__.MAX_INBAND_ATTACHMENT_SIZE) * 0.75 - 1024; if (blob.size > maxInbandAttachmentSize) { const uploader = (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_19__.createChatUploader)(this.props.tinode); if (!uploader) { this.props.onError(this.props.intl.formatMessage(messages.cannot_initiate_upload)); return; } const uploadCompletionPromise = uploader.upload(blob); const msg = tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.appendAudio(null, { mime: blob.type, size: blob.size, duration: duration, preview: preview, urlPromise: uploadCompletionPromise }); this.sendMessage(msg, uploadCompletionPromise, uploader, 'voice'); } else { (0,_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_17__.blobToBase64)(blob).then(b64 => { this.sendMessage(tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.appendAudio(null, { mime: b64.mime, bits: b64.bits, size: blob.size, duration: duration, preview: preview }), undefined, undefined, 'voice'); }); } }).catch(err => { this.props.onError(err.message, 'err'); }); ; } handleCancelUpload(seq, uploader) { const topic = this.props.tinode.getTopic(this.state.topic); const found = topic.findMessage(seq); if (found) { found._cancelled = true; } uploader.cancel(); } handlePickReply(seq, content, senderId, senderName) { if (!seq || !content) { this.setState({ reply: null }); return; } content = typeof content == 'string' ? tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.init(content) : content; if (tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.isValid(content)) { content = tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.replyContent(content, _config_js__WEBPACK_IMPORTED_MODULE_15__.QUOTED_REPLY_LENGTH); } else { content = tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.append(tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.init('\u26A0 '), tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.wrapInto(this.props.intl.formatMessage(messages.invalid_content), 'EM')); } this.setState({ reply: { content: tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.quote(senderName, senderId, content), seq: seq } }); this.props.onCancelForwardMessage(); } handleEditMessage(seq, content) { if (!seq || !content) { this.setState({ reply: null }); return; } content = typeof content == 'string' ? tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.init(content) : content; const editable = tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.toMarkdown(content); if (tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.isValid(content)) { content = tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.replyContent(content, _config_js__WEBPACK_IMPORTED_MODULE_15__.EDIT_PREVIEW_LENGTH); } else { content = tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.append(tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.init('\u26A0 '), tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.wrapInto(this.props.intl.formatMessage(messages.invalid_content), 'EM')); } this.setState({ reply: { content: tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.quote(this.props.intl.formatMessage(messages.editing_message), null, content), seq: seq, editing: true }, contentToEdit: editable }); this.props.onCancelForwardMessage(); } handleCancelReply() { this.setState({ reply: null, contentToEdit: null }); this.props.onCancelForwardMessage(); } handleQuoteClick(replyToSeq) { const ref = this.getOrCreateMessageRef(replyToSeq); if (ref && ref.current) { ref.current.scrollIntoView({ block: "center", behavior: "smooth" }); ref.current.classList.add('flash'); setTimeout(_ => { ref.current.classList.remove('flash'); }, 1000); } else { console.error("Unresolved message ref", replyToSeq); if (this.props.onError) { this.props.onError('该消息已被删除或撤回', 'err'); } } } jumpToMessage(seq) { const topic = this.props.tinode && this.props.topic ? this.props.tinode.getTopic(this.props.topic) : null; if (!topic || !seq || isNaN(seq)) { return; } _lib_navigation_js__WEBPACK_IMPORTED_MODULE_20__["default"].navigateTo(_lib_navigation_js__WEBPACK_IMPORTED_MODULE_20__["default"].removeUrlParam(window.location.hash, 'jumpseq')); const jump = () => window.setTimeout(() => this.handleQuoteClick(seq), 150); if (topic.findMessage(seq)) { jump(); } else { topic.getMeta(topic.startMetaQuery().withData(Math.max(1, seq - 20), seq + 21, 41).build()).then(jump).catch(err => this.props.onError(err.message, 'err')); } } handleUnpinMessage(seq) { const topic = this.props.tinode.getTopic(this.state.topic); topic.pinMessage(seq, false); } isDragEnabled() { const editingMessage = !!(this.state.reply && this.state.reply.editing); return this.state.isWriter && !this.state.unconfirmed && !this.props.forwardMessage && !this.state.peerMessagingDisabled && !editingMessage; } handleDragStart(e) { e.preventDefault(); e.stopPropagation(); e.dataTransfer.clearData(); } handleDragIn(e) { e.preventDefault(); e.stopPropagation(); this.dragCounter++; if (e.dataTransfer.items && e.dataTransfer.items.length > 0) { this.setState({ dragging: true }); } } handleDragOut(e) { e.preventDefault(); e.stopPropagation(); this.dragCounter--; if (this.dragCounter <= 0) { this.setState({ dragging: false }); } } handleDrag(e) { e.preventDefault(); e.stopPropagation(); } handleDrop(e) { e.preventDefault(); e.stopPropagation(); this.setState({ dragging: false }); if (this.isDragEnabled() && e.dataTransfer.files && e.dataTransfer.files.length > 0) { this.handleFileDrop(e.dataTransfer.files); this.dragCounter = 0; } } render() { const { formatMessage } = this.props.intl; const overlay = this.state.rtcPanel && (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(react__WEBPACK_IMPORTED_MODULE_0__.Suspense, { fallback: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, { id: "loading_note", defaultMessage: "Loading...", description: "Message shown when component is loading" }, void 0, false) }, void 0, false), children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(CallPanel, { topic: this.state.topic, seq: this.props.callSeq, callState: this.props.callState, callAudioOnly: this.props.callAudioOnly, tinode: this.props.tinode, title: this.state.title, avatar: this.state.avatar || true, minimized: this.state.minimizedCallPanel, onError: this.props.onError, onHangup: this.handleCallHangup, onToggleMinimize: this.handleCallPanelToggle, onInvite: this.props.onCallInvite, onSendOffer: this.props.onCallSendOffer, onIceCandidate: this.props.onCallIceCandidate, onSendAnswer: this.props.onCallSendAnswer }, void 0, false) }, void 0, false); const riskDialog = this.state.riskDialog && (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(_security_support_view_jsx__WEBPACK_IMPORTED_MODULE_13__.RiskConfirmDialog, { blocked: this.state.riskDialog.blocked, onConfirm: this.handleRiskConfirm, onCancel: this.handleRiskCancel }, void 0, false); let component; if (!this.state.topic) { component = (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(_logo_view_jsx__WEBPACK_IMPORTED_MODULE_10__["default"], {}, void 0, false); } else { let component2; if (this.state.imagePreview) { component2 = (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(react__WEBPACK_IMPORTED_MODULE_0__.Suspense, { fallback: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, { id: "loading_note", defaultMessage: "Loading...", description: "Message shown when component is loading" }, void 0, false) }, void 0, false), children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(ImagePreview, { content: this.state.imagePreview, tinode: this.props.tinode, reply: this.state.reply, onCancelReply: this.handleCancelReply, onClose: this.handleClosePreview, onSendMessage: this.sendImageAttachment }, void 0, false) }, void 0, false); } else if (this.state.videoPreview) { component2 = (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(react__WEBPACK_IMPORTED_MODULE_0__.Suspense, { fallback: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, { id: "loading_note", defaultMessage: "Loading...", description: "Message shown when component is loading" }, void 0, false) }, void 0, false), children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(VideoPreview, { content: this.state.videoPreview, tinode: this.props.tinode, reply: this.state.reply, onError: this.props.onError, onCancelReply: this.handleCancelReply, onClose: this.handleClosePreview, onSendMessage: this.sendVideoAttachment }, void 0, false) }, void 0, false); } else if (this.state.imagePostview) { component2 = (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(react__WEBPACK_IMPORTED_MODULE_0__.Suspense, { fallback: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, { id: "loading_note", defaultMessage: "Loading...", description: "Message shown when component is loading" }, void 0, false) }, void 0, false), children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(ImagePreview, { content: this.state.imagePostview, onClose: this.handleClosePreview }, void 0, false) }, void 0, false); } else if (this.state.videoPostview) { component2 = (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(react__WEBPACK_IMPORTED_MODULE_0__.Suspense, { fallback: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, { id: "loading_note", defaultMessage: "Loading...", description: "Message shown when component is loading" }, void 0, false) }, void 0, false), children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(VideoPreview, { content: this.state.videoPostview, tinode: this.props.tinode, onError: this.props.onError, onClose: this.handleClosePreview }, void 0, false) }, void 0, false); } else if (this.state.docPreview) { if (tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.TheCard.isFileSupported(this.state.docPreview.type, this.state.docPreview.name) || this.state.docPreview.type == tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.TheCard.contentType) { component2 = (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(react__WEBPACK_IMPORTED_MODULE_0__.Suspense, { fallback: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, { id: "loading_note", defaultMessage: "Loading...", description: "Message shown when component is loading" }, void 0, false) }, void 0, false), children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(TheCardPreview, { content: this.state.docPreview, tinode: this.props.tinode, reply: this.state.reply, onCancelReply: this.handleCancelReply, onClose: this.handleClosePreview, onSendMessage: this.sendFileAttachment }, void 0, false) }, void 0, false); } else { component2 = (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(react__WEBPACK_IMPORTED_MODULE_0__.Suspense, { fallback: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, { id: "loading_note", defaultMessage: "Loading...", description: "Message shown when component is loading" }, void 0, false) }, void 0, false), children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(DocPreview, { content: this.state.docPreview, tinode: this.props.tinode, reply: this.state.reply, onCancelReply: this.handleCancelReply, onClose: this.handleClosePreview, onSendMessage: this.sendFileAttachment }, void 0, false) }, void 0, false); } } else { const topic = this.props.tinode.getTopic(this.state.topic); const isChannel = topic.isChannelType() || topic.chan; const groupTopic = topic.isGroupType() && !isChannel; const icon_badges = []; if (topic.trusted) { if (topic.trusted.verified) { icon_badges.push({ icon: 'verified', color: 'badge-inv' }); } if (topic.trusted.staff) { icon_badges.push({ icon: 'staff', color: 'badge-inv' }); } if (topic.trusted.danger) { icon_badges.push({ icon: 'dangerous', color: 'badge-inv' }); } } const pinnedMessages = []; this.state.pins.forEach(seq => pinnedMessages.push(topic.latestMsgVersion(seq) || topic.findMessage(seq))); const messageNodes = []; let previousFrom = null; let prevDate = null; let chatBoxClass = groupTopic ? 'chat-box group' : 'chat-box'; topic.messages((msg, prev, next, i) => { let nextFrom = next ? next.from || 'chan' : null; let sequence = 'single'; let thisFrom = msg.from || 'chan'; if (thisFrom == previousFrom) { if (thisFrom == nextFrom) { sequence = 'middle'; } else { sequence = 'last'; } } else if (thisFrom == nextFrom) { sequence = 'first'; } previousFrom = thisFrom; const isReply = !(thisFrom == this.props.myUserId); const deliveryStatus = topic.msgStatus(msg, true); let userFrom = thisFrom, userName, userAvatar; const user = topic.userDesc(thisFrom); if (user && user.public) { userName = user.public.fn; userAvatar = (0,_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_17__.makeImageUrl)(user.public.photo); } const ref = this.getOrCreateMessageRef(msg.seq); let replyToSeq = msg.head ? parseInt(msg.head.reply) : null; if (!replyToSeq || isNaN(replyToSeq)) { replyToSeq = null; } if (msg.hi) { messageNodes.push((0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(_widgets_meta_message_jsx__WEBPACK_IMPORTED_MODULE_11__["default"], { deleted: true, deletedText: this.props.intl.formatMessage(messages.message_deleted) }, msg.seq, false)); } else { const thisDate = new Date(msg.ts); if (!prevDate || prevDate.toDateString() != thisDate.toDateString()) { messageNodes.push((0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(_widgets_meta_message_jsx__WEBPACK_IMPORTED_MODULE_11__["default"], { date: (0,_lib_strformat_js__WEBPACK_IMPORTED_MODULE_21__.relativeDateFormat)(msg.ts), locale: this.props.intl.locale }, 'date-' + msg.seq, false)); prevDate = thisDate; } messageNodes.push((0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(_widgets_chat_message_jsx__WEBPACK_IMPORTED_MODULE_3__["default"], { tinode: this.props.tinode, topic: this.state.topic, content: msg.content, mimeType: msg.head && msg.head.mime, head: msg.head, replyToSeq: replyToSeq, edited: msg.head && !msg.head.webrtc && msg.head.replace, timestamp: msg.ts, response: isReply, seq: msg.seq, isGroup: groupTopic, isChan: this.state.channel, userFrom: userFrom, userName: userName, userAvatar: userAvatar, senderRole: groupTopic && this.state.groupRoles ? this.state.groupRoles[thisFrom] : null, sequence: sequence, received: deliveryStatus, uploader: msg._uploader, userIsWriter: this.state.isWriter, userIsAdmin: this.state.isAdmin, relationship: this.state.relationshipContext ? this.state.relationshipContext.relationship : null, onSendFriendVerification: this.handleSendFriendVerification, selectMode: this.props.selectMode, selected: this.props.selectedSeqs && this.props.selectedSeqs.includes(msg.seq), onToggleSelect: this.props.onToggleMessageSelect, pinned: this.state.pins.includes(msg.seq), viewportWidth: this.props.viewportWidth, showContextMenu: this.handleShowMessageContextMenu, onExpandMedia: this.handleExpandMedia, onFormResponse: this.handleFormResponse, onCancelUpload: this.handleCancelUpload, pickReply: this.handlePickReply, editMessage: this.handleEditMessage, onQuoteClick: this.handleQuoteClick, onAcceptCall: this.props.onAcceptCall, onError: this.props.onError, ref: ref }, msg.seq, false)); } }); let lastSeen = null; if (isChannel) { if (topic.subcnt) { lastSeen = formatMessage(messages.subscriber_count, { count: topic.subcnt }); } } else { const cont = this.props.tinode.getMeTopic().getContact(this.state.topic); if (cont) { if (tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Tinode.isP2PTopicName(cont.topic)) { if (cont.online) { lastSeen = formatMessage(messages.online_now); } else if (cont.seen) { lastSeen = formatMessage(messages.last_seen, { timestamp: (0,_lib_strformat_js__WEBPACK_IMPORTED_MODULE_21__.shortDateFormat)(cont.seen.when, this.props.intl.locale) }); } } else if (tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Tinode.isGroupTopicName(cont.topic)) { if (topic.subcnt) { lastSeen = formatMessage(messages.member_count, { count: topic.subcnt }); } } } } const avatar = this.state.avatar || true; const online = this.state.deleted || topic.isSelfType() ? null : this.props.online ? 'online' + (this.state.typingIndicator ? ' typing' : '') : 'offline'; const titleClass = 'panel-title' + (this.state.deleted ? ' deleted' : ''); const darkModeClass = this.props.colorSchema == 'dark' ? 'dark' : ''; const editingMessage = !!(this.state.reply && this.state.reply.editing); let messagesComponent = (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.Fragment, { children: [this.state.groupAnnouncement ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("a", { href: "#", id: "group-announcement-banner", onClick: this.handleShowAnnouncement, children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("i", { className: "material-icons", children: "campaign" }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("span", { children: this.state.groupAnnouncement.content }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("i", { className: "material-icons", children: "chevron_right" }, void 0, false)] }, void 0, true) : null, this.state.pendingJoinRequests > 0 ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("a", { href: "#", id: "group-join-request-banner", onClick: this.handleShowJoinRequests, children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("i", { className: "material-icons", children: "person_add_alt" }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("span", { children: ["新邀请进群申请(", this.state.pendingJoinRequests, ")"] }, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("i", { className: "material-icons", children: "chevron_right" }, void 0, false)] }, void 0, true) : null, (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { id: "messages-container", className: darkModeClass, children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("button", { id: "go-to-latest", className: 'action-button' + (this.state.showGoToLastButton ? '' : ' hidden'), onClick: this.goToLatestMessage, children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("i", { className: "material-icons", children: "arrow_downward" }, void 0, false) }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { id: "messages-panel", ref: this.handleScrollReference, children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("ul", { id: "scroller", className: chatBoxClass, children: messageNodes }, void 0, false) }, void 0, false), !this.state.isReader ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { id: "write-only-background", children: this.state.readingBlocked ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { id: "write-only-note", children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, { id: "messages_not_readable", defaultMessage: "no access to messages", description: "Message shown in topic without the read access" }, void 0, false) }, void 0, false) : null }, void 0, false) : null, (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { className: 'toast' + (this.state.toast ? ' show' : ''), children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("i", { className: "material-icons", children: "check" }, void 0, false), "\xA0", this.state.toast] }, void 0, true)] }, void 0, true), this.state.peerMessagingDisabled && !this.state.unconfirmed ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { id: "peer-messaging-disabled-note", children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("i", { className: "material-icons secondary", children: "block" }, void 0, false), " ", (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, { id: "peers_messaging_disabled", defaultMessage: "Peer's messaging is disabled.", description: "Shown when the p2p peer's messaging is disabled" }, void 0, false), " ", (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("a", { href: "#", onClick: this.handleEnablePeer, children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, { id: "enable_peers_messaging", defaultMessage: "Enable", description: "Call to action to enable peer's messaging" }, void 0, false) }, void 0, false), "."] }, void 0, true) : null, !this.state.unconfirmed && this.state.relationshipContext && this.state.relationshipContext.relationship == 'pending_inbound' ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { id: "relationship-status-note", children: "以上是打招呼的消息" }, void 0, false) : null, !this.state.unconfirmed && this.state.relationshipContext && this.state.relationshipContext.relationship == 'pending_outbound' ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { id: "relationship-status-note", children: "好友申请正在等待处理" }, void 0, false) : null, !this.state.unconfirmed && this.state.relationshipContext && this.state.relationshipContext.relationship == 'none' ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { id: "relationship-status-note", children: ["你们还不是好友,发送消息前需先验证 ", (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("a", { href: "#", onClick: this.handleSendFriendVerification, children: "发送朋友验证" }, void 0, false)] }, void 0, true) : null, this.props.selectMode ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { id: "batch-action-bar", children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { id: "batch-action-count", children: ["已选 ", this.props.selectedSeqs.length, " 个"] }, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { id: "batch-action-buttons", children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("a", { href: "#", onClick: e => { e.preventDefault(); this.props.selectedSeqs.length && this.props.onShowBatchForward(); }, className: this.props.selectedSeqs.length ? '' : 'disabled', children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("i", { className: "material-icons", children: "forward" }, void 0, false), "转发"] }, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("a", { href: "#", onClick: e => { e.preventDefault(); this.handleBatchFavorite(); }, className: this.props.selectedSeqs.length ? '' : 'disabled', children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("i", { className: "material-icons", children: "star_border" }, void 0, false), "收藏"] }, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("a", { href: "#", onClick: e => { e.preventDefault(); this.handleBatchDelete(); }, className: this.props.selectedSeqs.length ? '' : 'disabled', children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("i", { className: "material-icons", children: "delete_outline" }, void 0, false), "删除"] }, void 0, true)] }, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("a", { href: "#", id: "batch-action-cancel", onClick: e => { e.preventDefault(); this.props.onExitSelectMode(); }, children: "取消" }, void 0, false)] }, void 0, true) : this.state.unconfirmed ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(_widgets_invitation_jsx__WEBPACK_IMPORTED_MODULE_7__["default"], { onAction: this.handleNewChatAcceptance }, void 0, false) : (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(_widgets_send_message_jsx__WEBPACK_IMPORTED_MODULE_14__["default"], { tinode: this.props.tinode, topicName: this.state.topic, noInput: !!this.props.forwardMessage, disabled: !this.state.isWriter || this.state.deleted, reply: this.state.reply, initMessage: this.state.contentToEdit != null ? this.state.contentToEdit : this.state.draftText, sendOnEnter: this.props.sendOnEnter, onKeyPress: this.sendKeyPress, onRecordingProgress: this.sendKeyPress, onMessageChange: this.props.forwardMessage ? null : this.handleComposerChange, onMentionSearch: this.props.forwardMessage || !groupTopic ? null : this.mentionSearch, onMentionSelected: this.mentionSelected, onSendMessage: this.sendMessage, onAttachFile: this.props.forwardMessage || editingMessage ? null : this.handleAttachFile, onAttachImage: this.props.forwardMessage || editingMessage ? null : this.handleAttachImageOrVideo, onAttachAudio: this.props.forwardMessage || editingMessage ? null : this.sendAudioAttachment, canStartCall: !this.props.forwardMessage && this.props.canStartCall, onStartAudioCall: this.props.onStartAudioCall, onStartVideoCall: this.props.onStartVideoCall, onError: this.props.onError, onQuoteClick: this.handleQuoteClick, onCancelReply: this.handleCancelReply }, void 0, false)] }, void 0, true); component2 = (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.Fragment, { children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { id: "topic-caption-panel", className: "caption-panel", children: [this.props.displayMobile ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("a", { href: "#", id: "hide-message-view", onClick: e => { e.preventDefault(); this.leave(this.state.topic); this.props.onHideMessagesView(); }, children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("i", { className: "material-icons", children: "arrow_back" }, void 0, false) }, void 0, false) : null, (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { className: "avatar-box", children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(_widgets_letter_tile_jsx__WEBPACK_IMPORTED_MODULE_8__["default"], { authorizeURL: this.props.tinode.authorizeURL, avatar: avatar, topic: this.state.topic, title: this.state.title, deleted: this.state.deleted }, void 0, false), !isChannel ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("span", { className: online }, void 0, false) : null] }, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { id: "topic-title-group", children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { id: "topic-title", className: titleClass, children: [this.state.title || (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("i", { children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, { id: "unnamed_topic", defaultMessage: "Unnamed", description: "Title shown when the topic has no name" }, void 0, false) }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(_widgets_contact_badges_jsx__WEBPACK_IMPORTED_MODULE_4__["default"], { badges: icon_badges }, void 0, false)] }, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { id: "topic-last-seen", children: lastSeen }, void 0, false)] }, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { style: { marginLeft: 'auto' } }, void 0, false), !this.props.displayMobile && this.state.pins.length > 0 ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(_widgets_pinned_messages_jsx__WEBPACK_IMPORTED_MODULE_12__["default"], { tinode: this.props.tinode, pins: this.state.pins, messages: pinnedMessages, selected: this.state.selectedPin, isAdmin: this.state.isAdmin, setSelected: index => this.setState({ selectedPin: index }), onSelected: this.handleQuoteClick, onCancel: this.handleUnpinMessage }, void 0, false) : null, groupTopic ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(_widgets_group_subs_jsx__WEBPACK_IMPORTED_MODULE_6__["default"], { tinode: this.props.tinode, subscribers: this.state.onlineSubs }, void 0, false) : null, (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("a", { href: "#", onClick: this.handleContextClick, children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("i", { className: "material-icons", children: "more_vert" }, void 0, false) }, void 0, false) }, void 0, false)] }, void 0, true), this.props.displayMobile ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.Fragment, { children: [this.state.pins.length > 0 ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(_widgets_pinned_messages_jsx__WEBPACK_IMPORTED_MODULE_12__["default"], { tinode: this.props.tinode, pins: this.state.pins, messages: pinnedMessages, selected: this.state.selectedPin, isAdmin: this.state.isAdmin, setSelected: index => this.setState({ selectedPin: index }), onSelected: this.handleQuoteClick, onCancel: this.handleUnpinMessage }, void 0, false) : null, (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(_widgets_error_panel_jsx__WEBPACK_IMPORTED_MODULE_5__["default"], { level: this.props.errorLevel, text: this.props.errorText, onClearError: this.props.onError }, void 0, false)] }, void 0, true) : null, (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(_widgets_load_spinner_jsx__WEBPACK_IMPORTED_MODULE_9__["default"], { show: this.state.fetchingMessages }, void 0, false), messagesComponent, this.state.dragging && this.isDragEnabled() ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { className: "drag-n-drop", children: formatMessage(messages.drag_file) }, void 0, false) : null] }, void 0, true); } component = (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)("div", { id: "topic-view", ref: this.mountDnDEvents, children: [component2, overlay, riskDialog] }, void 0, true); } return component; } } ; /* harmony default export */ __webpack_exports__["default"] = ((0,react_intl__WEBPACK_IMPORTED_MODULE_1__.injectIntl)(MessagesView)); /***/ }), /***/ "./src/widgets/attachment.jsx": /*!************************************!*\ !*** ./src/widgets/attachment.jsx ***! \************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": function() { return /* binding */ Attachment; } /* harmony export */ }); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react"); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-intl */ "react-intl"); /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var _file_progress_jsx__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./file-progress.jsx */ "./src/widgets/file-progress.jsx"); /* harmony import */ var _lib_im_api_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../lib/im-api.js */ "./src/lib/im-api.js"); /* harmony import */ var _lib_strformat_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../lib/strformat.js */ "./src/lib/strformat.js"); /* harmony import */ var _lib_utils_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../lib/utils.js */ "./src/lib/utils.js"); /* harmony import */ var react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! react/jsx-dev-runtime */ "./node_modules/react/jsx-dev-runtime.js"); const ATTACHMENT_TYPE_META = { image: ['image', '#3ba55c'], video: ['videocam', '#3b82c4'], audio: ['audiotrack', '#8b5cf6'], document: ['description', '#e05d44'], file: ['insert_drive_file', '#8a8f98'] }; function attachmentTypeFromMime(mime) { const m = (mime || '').toLowerCase(); if (m.startsWith('image/')) return 'image'; if (m.startsWith('video/')) return 'video'; if (m.startsWith('audio/')) return 'audio'; if (m === 'application/pdf' || m === 'text/plain' || m.includes('msword') || m.includes('wordprocessingml') || m.includes('spreadsheetml') || m.includes('presentationml') || m === 'application/vnd.ms-excel' || m === 'application/vnd.ms-powerpoint') { return 'document'; } return 'file'; } class Attachment extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component) { constructor(props) { super(props); this.state = { downloader: null, progress: 0 }; this.downloadFile = this.downloadFile.bind(this); this.handleCancel = this.handleCancel.bind(this); } downloadFile(url, filename, mimetype) { if (!url) { this.props.onError("Invalid download URL '" + url + "'"); return; } const downloader = (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_3__.createFileDownloader)(this.props.tinode); this.setState({ downloader: downloader }); downloader.download(url, filename, mimetype, loaded => this.setState({ progress: loaded / this.props.size }), err => this.props.onError(err, 'err')).then(_ => this.setState({ downloader: null, progress: 0 })).catch(err => { if (err) { this.props.onError("Error downloading file: " + err.message, 'err'); } this.setState({ downloader: null, progress: 0 }); }); } handleCancel() { if (this.props.uploading) { this.props.onCancelUpload(); } else if (this.state.downloader) { this.state.downloader.cancel(); } } render() { let filename = this.props.filename || 'file_attachment'; if (filename.length > 36) { filename = filename.substr(0, 16) + '...' + filename.substr(-16); } let size = this.props.size > 0 ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("span", { className: "small gray", children: ["(", (0,_lib_strformat_js__WEBPACK_IMPORTED_MODULE_4__.bytesToHumanSize)(this.props.size), ")"] }, void 0, true) : null; let url, helperFunc; if (!this.props.uploading && !this.state.downloader && (0,_lib_utils_js__WEBPACK_IMPORTED_MODULE_5__.isUrlRelative)(this.props.downloadUrl)) { url = '#'; helperFunc = e => { e.preventDefault(); this.downloadFile(this.props.downloadUrl, this.props.filename, this.props.mimetype); }; } else { url = (0,_lib_utils_js__WEBPACK_IMPORTED_MODULE_5__.sanitizeUrl)(this.props.downloadUrl); helperFunc = null; } const downloadWidget = (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)(react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.Fragment, { children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("i", { className: "material-icons", children: "file_download" }, void 0, false), " ", (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, { id: "save_attachment", defaultMessage: "save", description: "Call to save an attachment" }, void 0, false)] }, void 0, true); const [icon, color] = ATTACHMENT_TYPE_META[attachmentTypeFromMime(this.props.mimetype)]; return (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("div", { className: "attachment", children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("div", { children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("i", { className: "material-icons big", style: { color }, children: icon }, void 0, false) }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("div", { className: "flex-column", children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("div", { children: [filename, " ", size] }, void 0, true), this.props.uploading || this.state.downloader ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)(_file_progress_jsx__WEBPACK_IMPORTED_MODULE_2__["default"], { progress: this.props.uploading ? this.props.progress : this.state.progress, onCancel: this.handleCancel }, void 0, false) : (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("div", { children: url ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("a", { href: url, download: this.props.filename, onClick: helperFunc, children: downloadWidget }, void 0, false) : (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("span", { className: "light-gray", children: downloadWidget }, void 0, false) }, void 0, false)] }, void 0, true)] }, void 0, true); } } ; /***/ }), /***/ "./src/widgets/chat-message.jsx": /*!**************************************!*\ !*** ./src/widgets/chat-message.jsx ***! \**************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react"); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-intl */ "react-intl"); /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var tinode_sdk__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! tinode-sdk */ "tinode-sdk"); /* harmony import */ var tinode_sdk__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(tinode_sdk__WEBPACK_IMPORTED_MODULE_2__); /* harmony import */ var _attachment_jsx__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./attachment.jsx */ "./src/widgets/attachment.jsx"); /* harmony import */ var _forward_bundle_jsx__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./forward-bundle.jsx */ "./src/widgets/forward-bundle.jsx"); /* harmony import */ var _letter_tile_jsx__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./letter-tile.jsx */ "./src/widgets/letter-tile.jsx"); /* harmony import */ var _received_marker_jsx__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./received-marker.jsx */ "./src/widgets/received-marker.jsx"); /* harmony import */ var _lib_formatters_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../lib/formatters.js */ "./src/lib/formatters.js"); /* harmony import */ var _lib_utils_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../lib/utils.js */ "./src/lib/utils.js"); /* harmony import */ var _lib_navigation_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../lib/navigation.js */ "./src/lib/navigation.js"); /* harmony import */ var react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! react/jsx-dev-runtime */ "./node_modules/react/jsx-dev-runtime.js"); const VOICE_PLAYED_KEY_PREFIX = 'im-voice-played:'; function isVoicePlayed(myUid, topic, seq) { try { const list = JSON.parse(localStorage.getItem(VOICE_PLAYED_KEY_PREFIX + myUid + ':' + topic) || '[]'); return Array.isArray(list) && list.includes(seq); } catch (_) { return false; } } function markVoicePlayed(myUid, topic, seq) { try { const key = VOICE_PLAYED_KEY_PREFIX + myUid + ':' + topic; const list = JSON.parse(localStorage.getItem(key) || '[]'); const set = Array.isArray(list) ? list : []; if (!set.includes(seq)) { localStorage.setItem(key, JSON.stringify(set.concat(seq).slice(-500))); } } catch (_) {} } class BaseChatMessage extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComponent) { constructor(props) { super(props); this.state = { progress: 0, voicePlayed: isVoicePlayed(props.tinode.getCurrentUserID(), props.topic, props.seq) }; if (props.uploader) { props.uploader.onProgress = this.handleProgress.bind(this); } this.handleExpandImage = this.handleExpandImage.bind(this); this.handlePlayVideo = this.handlePlayVideo.bind(this); this.handleFormButtonClick = this.handleFormButtonClick.bind(this); this.handleQuoteClick = this.handleQuoteClick.bind(this); this.handleContextClick = this.handleContextClick.bind(this); this.handleCancelUpload = this.handleCancelUpload.bind(this); this.handleDraftyClick = this.handleDraftyClick.bind(this); this.handleVoicePlayed = this.handleVoicePlayed.bind(this); this.formatterContext = { formatMessage: props.intl.formatMessage.bind(props.intl), viewportWidth: props.viewportWidth, authorizeURL: props.tinode.authorizeURL.bind(props.tinode), onHandleClick: this.handleDraftyClick, onVoicePlayed: this.handleVoicePlayed }; } handleDraftyClick = (e, action) => { switch (action) { case 'image': this.handleExpandImage(e); break; case 'video': this.handlePlayVideo(e); break; case 'form_button': this.handleFormButtonClick(e); break; case 'quote': this.handleQuoteClick(e); break; case 'contact_chat': e.preventDefault(); try { const pathname = new URL(e.target.dataset.val)?.pathname; const parts = pathname.split('/').filter(Boolean); _lib_navigation_js__WEBPACK_IMPORTED_MODULE_9__["default"].navigateTo(_lib_navigation_js__WEBPACK_IMPORTED_MODULE_9__["default"].setUrlTopic('', parts.pop() || '')); } catch (error) { console.error("Invalid URL:", error); } break; case 'contact_find': e.preventDefault(); let hashUrl = _lib_navigation_js__WEBPACK_IMPORTED_MODULE_9__["default"].setUrlSidePanel(window.location.hash, 'newtpk'); hashUrl = _lib_navigation_js__WEBPACK_IMPORTED_MODULE_9__["default"].addUrlParam(hashUrl, 'q', e.target.dataset.val); hashUrl = _lib_navigation_js__WEBPACK_IMPORTED_MODULE_9__["default"].addUrlParam(hashUrl, 'tab', 'find'); _lib_navigation_js__WEBPACK_IMPORTED_MODULE_9__["default"].navigateTo(hashUrl); break; default: console.info('Unhandled drafty action.', action, e.target.dataset); break; } }; handleExpandImage(e) { e.preventDefault(); this.props.onExpandMedia({ url: e.target.src, filename: e.target.dataset.name, width: e.target.dataset.width, height: e.target.dataset.height, size: e.target.dataset.size, type: e.target.dataset.mime }); } handlePlayVideo(e) { e.preventDefault(); this.props.onExpandMedia({ video: true, url: e.target.dataset.src, preview: e.target.src, filename: e.target.dataset.name, width: e.target.dataset.width, height: e.target.dataset.height, duration: e.target.dataset.duration, size: e.target.dataset.size, type: e.target.dataset.mime }); } handleFormButtonClick(e) { e.preventDefault(); const data = { seq: this.props.seq }; data.resp = {}; if (e.target.dataset.name) { data.resp[e.target.dataset.name] = e.target.dataset.val ? e.target.dataset.val : e.target.dataset.val === undefined ? 1 : '' + e.target.dataset.val; } if (e.target.dataset.act == 'url') { data.ref = (0,_lib_utils_js__WEBPACK_IMPORTED_MODULE_8__.sanitizeUrl)(e.target.dataset.ref) || 'about:blank'; } const text = e.target.dataset.title || 'unknown'; this.props.onFormResponse(e.target.dataset.act, text, data); } handleContextClick(e) { e.preventDefault(); e.stopPropagation(); const menuItems = []; if (this.props.received == tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Tinode.MESSAGE_STATUS_FAILED) { menuItems.push('menu_item_send_retry'); } if (this.props.received > tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Tinode.MESSAGE_STATUS_FATAL) { if (this.props.userIsWriter) { menuItems.push('menu_item_reply'); if (!this.props.response) { let immutable = false; tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.entities(this.props.content, (_0, _1, tp) => { immutable = ['AU', 'EX', 'FM', 'IM', 'TC', 'VC', 'VD'].includes(tp); return immutable; }); if (!immutable) { tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.styles(this.props.content, tp => { immutable = ['QQ'].includes(tp); return immutable; }); } if (!immutable) { menuItems.push('menu_item_edit'); } } } if (this.props.userIsAdmin) { menuItems.push(this.props.pinned ? 'menu_item_unpin' : 'menu_item_pin'); } } menuItems.push('menu_item_forward'); this.props.showContextMenu({ seq: this.props.seq, replace: this.props.edited ? parseInt(this.props.edited.split(':')[1]) : 0, content: this.props.content, head: this.props.head, userFrom: this.props.userFrom, userName: this.props.userName, y: e.pageY, x: e.pageX, pickReply: this.props.pickReply, editMessage: this.props.editMessage, timestamp: this.props.timestamp }, menuItems); } handleProgress(ratio) { this.setState({ progress: ratio }); } handleCancelUpload() { this.props.onCancelUpload(this.props.seq, this.props.uploader); } handleVoicePlayed() { if (this.state.voicePlayed) { return; } markVoicePlayed(this.props.tinode.getCurrentUserID(), this.props.topic, this.props.seq); this.setState({ voicePlayed: true }); } handleQuoteClick(e) { e.preventDefault(); e.stopPropagation(); const replyToSeq = this.props.replyToSeq; if (replyToSeq) { this.props.onQuoteClick(replyToSeq); } } renderFailReason() { if (this.props.response || this.props.received != tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Tinode.MESSAGE_STATUS_FAILED && this.props.received != tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Tinode.MESSAGE_STATUS_FATAL) { return null; } if (this.props.relationship == 'blocked_by_peer' || this.props.relationship == 'blocked_by_me') { return (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)("div", { className: "message-fail-reason", children: "消息已发送,但被对方拒收了" }, void 0, false); } if (this.props.relationship == 'none') { return (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)("div", { className: "message-fail-reason", children: ["你还不是他(她)朋友。", (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)("a", { href: "#", onClick: this.props.onSendFriendVerification, children: "发送朋友验证" }, void 0, false)] }, void 0, true); } return null; } render() { const sideClass = this.props.sequence + ' ' + (this.props.response ? 'left' : 'right'); const bubbleClass = this.props.sequence == 'single' || this.props.sequence == 'last' ? 'bubble tip' : 'bubble'; const avatar = this.props.userAvatar || true; const isFailed = !this.props.response && (this.props.received == tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Tinode.MESSAGE_STATUS_FAILED || this.props.received == tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Tinode.MESSAGE_STATUS_FATAL); const failReason = this.renderFailReason(); let isVoiceMessage = false; if (this.props.response && this.props.mimeType == tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.getContentType() && tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.isValid(this.props.content)) { tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.entities(this.props.content, (_0, _1, tp) => { if (tp === 'AU') { isVoiceMessage = true; } return isVoiceMessage; }); } const showVoiceUnreadDot = isVoiceMessage && !this.state.voicePlayed; let textSizeClass = 'message-content'; const fullDisplay = this.props.isGroup && this.props.response && (this.props.sequence == 'single' || this.props.sequence == 'last'); let content = this.props.content; if (this.props.head && (this.props.head['x-im-type'] === 'system_notice' || this.props.head['x-im-type'] === 'system_action') && content && typeof content == 'object' && typeof content.text == 'string') { content = content.text; } let bundleCard = null; if (this.props.head && this.props.head['x-im-type'] === 'forward_bundle' && content && typeof content == 'object' && (content.items || content.preview)) { bundleCard = (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)(_forward_bundle_jsx__WEBPACK_IMPORTED_MODULE_4__["default"], { content: content, tinode: this.props.tinode }, void 0, false); } const attachments = []; if (this.props.mimeType == tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.getContentType() && tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.isValid(content)) { tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.attachments(content, (att, i) => { if (tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.isFormResponseType(att.mime)) { return; } attachments.push((0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)(_attachment_jsx__WEBPACK_IMPORTED_MODULE_3__["default"], { tinode: this.props.tinode, downloadUrl: tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.getDownloadUrl(att), filename: att.name, uploading: tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.isProcessing(att), mimetype: att.mime, size: tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.getEntitySize(att), progress: this.state.progress, onCancelUpload: this.handleCancelUpload, onError: this.props.onError }, i, false)); }, this); const tree = tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.format(content, _lib_formatters_js__WEBPACK_IMPORTED_MODULE_7__.fullFormatter, this.formatterContext); content = react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, tree); } else if (typeof content == 'string') { if (new RegExp('^\\p{RGI_Emoji}{1,5}$', 'v').test(content || '')) { textSizeClass += ' emoji-' + (content || '').match(/(?:👨🏻‍❤️‍💋‍👨🏻|👨🏻‍❤️‍💋‍👨🏼|👨🏻‍❤️‍💋‍👨🏽|👨🏻‍❤️‍💋‍👨🏾|👨🏻‍❤️‍💋‍👨🏿|👨🏼‍❤️‍💋‍👨🏻|👨🏼‍❤️‍💋‍👨🏼|👨🏼‍❤️‍💋‍👨🏽|👨🏼‍❤️‍💋‍👨🏾|👨🏼‍❤️‍💋‍👨🏿|👨🏽‍❤️‍💋‍👨🏻|👨🏽‍❤️‍💋‍👨🏼|👨🏽‍❤️‍💋‍👨🏽|👨🏽‍❤️‍💋‍👨🏾|👨🏽‍❤️‍💋‍👨🏿|👨🏾‍❤️‍💋‍👨🏻|👨🏾‍❤️‍💋‍👨🏼|👨🏾‍❤️‍💋‍👨🏽|👨🏾‍❤️‍💋‍👨🏾|👨🏾‍❤️‍💋‍👨🏿|👨🏿‍❤️‍💋‍👨🏻|👨🏿‍❤️‍💋‍👨🏼|👨🏿‍❤️‍💋‍👨🏽|👨🏿‍❤️‍💋‍👨🏾|👨🏿‍❤️‍💋‍👨🏿|👩🏻‍❤️‍💋‍👨🏻|👩🏻‍❤️‍💋‍👨🏼|👩🏻‍❤️‍💋‍👨🏽|👩🏻‍❤️‍💋‍👨🏾|👩🏻‍❤️‍💋‍👨🏿|👩🏻‍❤️‍💋‍👩🏻|👩🏻‍❤️‍💋‍👩🏼|👩🏻‍❤️‍💋‍👩🏽|👩🏻‍❤️‍💋‍👩🏾|👩🏻‍❤️‍💋‍👩🏿|👩🏼‍❤️‍💋‍👨🏻|👩🏼‍❤️‍💋‍👨🏼|👩🏼‍❤️‍💋‍👨🏽|👩🏼‍❤️‍💋‍👨🏾|👩🏼‍❤️‍💋‍👨🏿|👩🏼‍❤️‍💋‍👩🏻|👩🏼‍❤️‍💋‍👩🏼|👩🏼‍❤️‍💋‍👩🏽|👩🏼‍❤️‍💋‍👩🏾|👩🏼‍❤️‍💋‍👩🏿|👩🏽‍❤️‍💋‍👨🏻|👩🏽‍❤️‍💋‍👨🏼|👩🏽‍❤️‍💋‍👨🏽|👩🏽‍❤️‍💋‍👨🏾|👩🏽‍❤️‍💋‍👨🏿|👩🏽‍❤️‍💋‍👩🏻|👩🏽‍❤️‍💋‍👩🏼|👩🏽‍❤️‍💋‍👩🏽|👩🏽‍❤️‍💋‍👩🏾|👩🏽‍❤️‍💋‍👩🏿|👩🏾‍❤️‍💋‍👨🏻|👩🏾‍❤️‍💋‍👨🏼|👩🏾‍❤️‍💋‍👨🏽|👩🏾‍❤️‍💋‍👨🏾|👩🏾‍❤️‍💋‍👨🏿|👩🏾‍❤️‍💋‍👩🏻|👩🏾‍❤️‍💋‍👩🏼|👩🏾‍❤️‍💋‍👩🏽|👩🏾‍❤️‍💋‍👩🏾|👩🏾‍❤️‍💋‍👩🏿|👩🏿‍❤️‍💋‍👨🏻|👩🏿‍❤️‍💋‍👨🏼|👩🏿‍❤️‍💋‍👨🏽|👩🏿‍❤️‍💋‍👨🏾|👩🏿‍❤️‍💋‍👨🏿|👩🏿‍❤️‍💋‍👩🏻|👩🏿‍❤️‍💋‍👩🏼|👩🏿‍❤️‍💋‍👩🏽|👩🏿‍❤️‍💋‍👩🏾|👩🏿‍❤️‍💋‍👩🏿|🧑🏻‍❤️‍💋‍🧑🏼|🧑🏻‍❤️‍💋‍🧑🏽|🧑🏻‍❤️‍💋‍🧑🏾|🧑🏻‍❤️‍💋‍🧑🏿|🧑🏼‍❤️‍💋‍🧑🏻|🧑🏼‍❤️‍💋‍🧑🏽|🧑🏼‍❤️‍💋‍🧑🏾|🧑🏼‍❤️‍💋‍🧑🏿|🧑🏽‍❤️‍💋‍🧑🏻|🧑🏽‍❤️‍💋‍🧑🏼|🧑🏽‍❤️‍💋‍🧑🏾|🧑🏽‍❤️‍💋‍🧑🏿|🧑🏾‍❤️‍💋‍🧑🏻|🧑🏾‍❤️‍💋‍🧑🏼|🧑🏾‍❤️‍💋‍🧑🏽|🧑🏾‍❤️‍💋‍🧑🏿|🧑🏿‍❤️‍💋‍🧑🏻|🧑🏿‍❤️‍💋‍🧑🏼|🧑🏿‍❤️‍💋‍🧑🏽|🧑🏿‍❤️‍💋‍🧑🏾|🏴󠁧󠁢󠁥󠁮󠁧󠁿|🏴󠁧󠁢󠁳󠁣󠁴󠁿|🏴󠁧󠁢󠁷󠁬󠁳󠁿|👨🏻‍❤️‍👨🏻|👨🏻‍❤️‍👨🏼|👨🏻‍❤️‍👨🏽|👨🏻‍❤️‍👨🏾|👨🏻‍❤️‍👨🏿|👨🏻‍🐰‍👨🏼|👨🏻‍🐰‍👨🏽|👨🏻‍🐰‍👨🏾|👨🏻‍🐰‍👨🏿|👨🏻‍🤝‍👨🏼|👨🏻‍🤝‍👨🏽|👨🏻‍🤝‍👨🏾|👨🏻‍🤝‍👨🏿|👨🏻‍🫯‍👨🏼|👨🏻‍🫯‍👨🏽|👨🏻‍🫯‍👨🏾|👨🏻‍🫯‍👨🏿|👨🏼‍❤️‍👨🏻|👨🏼‍❤️‍👨🏼|👨🏼‍❤️‍👨🏽|👨🏼‍❤️‍👨🏾|👨🏼‍❤️‍👨🏿|👨🏼‍🐰‍👨🏻|👨🏼‍🐰‍👨🏽|👨🏼‍🐰‍👨🏾|👨🏼‍🐰‍👨🏿|👨🏼‍🤝‍👨🏻|👨🏼‍🤝‍👨🏽|👨🏼‍🤝‍👨🏾|👨🏼‍🤝‍👨🏿|👨🏼‍🫯‍👨🏻|👨🏼‍🫯‍👨🏽|👨🏼‍🫯‍👨🏾|👨🏼‍🫯‍👨🏿|👨🏽‍❤️‍👨🏻|👨🏽‍❤️‍👨🏼|👨🏽‍❤️‍👨🏽|👨🏽‍❤️‍👨🏾|👨🏽‍❤️‍👨🏿|👨🏽‍🐰‍👨🏻|👨🏽‍🐰‍👨🏼|👨🏽‍🐰‍👨🏾|👨🏽‍🐰‍👨🏿|👨🏽‍🤝‍👨🏻|👨🏽‍🤝‍👨🏼|👨🏽‍🤝‍👨🏾|👨🏽‍🤝‍👨🏿|👨🏽‍🫯‍👨🏻|👨🏽‍🫯‍👨🏼|👨🏽‍🫯‍👨🏾|👨🏽‍🫯‍👨🏿|👨🏾‍❤️‍👨🏻|👨🏾‍❤️‍👨🏼|👨🏾‍❤️‍👨🏽|👨🏾‍❤️‍👨🏾|👨🏾‍❤️‍👨🏿|👨🏾‍🐰‍👨🏻|👨🏾‍🐰‍👨🏼|👨🏾‍🐰‍👨🏽|👨🏾‍🐰‍👨🏿|👨🏾‍🤝‍👨🏻|👨🏾‍🤝‍👨🏼|👨🏾‍🤝‍👨🏽|👨🏾‍🤝‍👨🏿|👨🏾‍🫯‍👨🏻|👨🏾‍🫯‍👨🏼|👨🏾‍🫯‍👨🏽|👨🏾‍🫯‍👨🏿|👨🏿‍❤️‍👨🏻|👨🏿‍❤️‍👨🏼|👨🏿‍❤️‍👨🏽|👨🏿‍❤️‍👨🏾|👨🏿‍❤️‍👨🏿|👨🏿‍🐰‍👨🏻|👨🏿‍🐰‍👨🏼|👨🏿‍🐰‍👨🏽|👨🏿‍🐰‍👨🏾|👨🏿‍🤝‍👨🏻|👨🏿‍🤝‍👨🏼|👨🏿‍🤝‍👨🏽|👨🏿‍🤝‍👨🏾|👨🏿‍🫯‍👨🏻|👨🏿‍🫯‍👨🏼|👨🏿‍🫯‍👨🏽|👨🏿‍🫯‍👨🏾|👩🏻‍❤️‍👨🏻|👩🏻‍❤️‍👨🏼|👩🏻‍❤️‍👨🏽|👩🏻‍❤️‍👨🏾|👩🏻‍❤️‍👨🏿|👩🏻‍❤️‍👩🏻|👩🏻‍❤️‍👩🏼|👩🏻‍❤️‍👩🏽|👩🏻‍❤️‍👩🏾|👩🏻‍❤️‍👩🏿|👩🏻‍🐰‍👩🏼|👩🏻‍🐰‍👩🏽|👩🏻‍🐰‍👩🏾|👩🏻‍🐰‍👩🏿|👩🏻‍🤝‍👨🏼|👩🏻‍🤝‍👨🏽|👩🏻‍🤝‍👨🏾|👩🏻‍🤝‍👨🏿|👩🏻‍🤝‍👩🏼|👩🏻‍🤝‍👩🏽|👩🏻‍🤝‍👩🏾|👩🏻‍🤝‍👩🏿|👩🏻‍🫯‍👩🏼|👩🏻‍🫯‍👩🏽|👩🏻‍🫯‍👩🏾|👩🏻‍🫯‍👩🏿|👩🏼‍❤️‍👨🏻|👩🏼‍❤️‍👨🏼|👩🏼‍❤️‍👨🏽|👩🏼‍❤️‍👨🏾|👩🏼‍❤️‍👨🏿|👩🏼‍❤️‍👩🏻|👩🏼‍❤️‍👩🏼|👩🏼‍❤️‍👩🏽|👩🏼‍❤️‍👩🏾|👩🏼‍❤️‍👩🏿|👩🏼‍🐰‍👩🏻|👩🏼‍🐰‍👩🏽|👩🏼‍🐰‍👩🏾|👩🏼‍🐰‍👩🏿|👩🏼‍🤝‍👨🏻|👩🏼‍🤝‍👨🏽|👩🏼‍🤝‍👨🏾|👩🏼‍🤝‍👨🏿|👩🏼‍🤝‍👩🏻|👩🏼‍🤝‍👩🏽|👩🏼‍🤝‍👩🏾|👩🏼‍🤝‍👩🏿|👩🏼‍🫯‍👩🏻|👩🏼‍🫯‍👩🏽|👩🏼‍🫯‍👩🏾|👩🏼‍🫯‍👩🏿|👩🏽‍❤️‍👨🏻|👩🏽‍❤️‍👨🏼|👩🏽‍❤️‍👨🏽|👩🏽‍❤️‍👨🏾|👩🏽‍❤️‍👨🏿|👩🏽‍❤️‍👩🏻|👩🏽‍❤️‍👩🏼|👩🏽‍❤️‍👩🏽|👩🏽‍❤️‍👩🏾|👩🏽‍❤️‍👩🏿|👩🏽‍🐰‍👩🏻|👩🏽‍🐰‍👩🏼|👩🏽‍🐰‍👩🏾|👩🏽‍🐰‍👩🏿|👩🏽‍🤝‍👨🏻|👩🏽‍🤝‍👨🏼|👩🏽‍🤝‍👨🏾|👩🏽‍🤝‍👨🏿|👩🏽‍🤝‍👩🏻|👩🏽‍🤝‍👩🏼|👩🏽‍🤝‍👩🏾|👩🏽‍🤝‍👩🏿|👩🏽‍🫯‍👩🏻|👩🏽‍🫯‍👩🏼|👩🏽‍🫯‍👩🏾|👩🏽‍🫯‍👩🏿|👩🏾‍❤️‍👨🏻|👩🏾‍❤️‍👨🏼|👩🏾‍❤️‍👨🏽|👩🏾‍❤️‍👨🏾|👩🏾‍❤️‍👨🏿|👩🏾‍❤️‍👩🏻|👩🏾‍❤️‍👩🏼|👩🏾‍❤️‍👩🏽|👩🏾‍❤️‍👩🏾|👩🏾‍❤️‍👩🏿|👩🏾‍🐰‍👩🏻|👩🏾‍🐰‍👩🏼|👩🏾‍🐰‍👩🏽|👩🏾‍🐰‍👩🏿|👩🏾‍🤝‍👨🏻|👩🏾‍🤝‍👨🏼|👩🏾‍🤝‍👨🏽|👩🏾‍🤝‍👨🏿|👩🏾‍🤝‍👩🏻|👩🏾‍🤝‍👩🏼|👩🏾‍🤝‍👩🏽|👩🏾‍🤝‍👩🏿|👩🏾‍🫯‍👩🏻|👩🏾‍🫯‍👩🏼|👩🏾‍🫯‍👩🏽|👩🏾‍🫯‍👩🏿|👩🏿‍❤️‍👨🏻|👩🏿‍❤️‍👨🏼|👩🏿‍❤️‍👨🏽|👩🏿‍❤️‍👨🏾|👩🏿‍❤️‍👨🏿|👩🏿‍❤️‍👩🏻|👩🏿‍❤️‍👩🏼|👩🏿‍❤️‍👩🏽|👩🏿‍❤️‍👩🏾|👩🏿‍❤️‍👩🏿|👩🏿‍🐰‍👩🏻|👩🏿‍🐰‍👩🏼|👩🏿‍🐰‍👩🏽|👩🏿‍🐰‍👩🏾|👩🏿‍🤝‍👨🏻|👩🏿‍🤝‍👨🏼|👩🏿‍🤝‍👨🏽|👩🏿‍🤝‍👨🏾|👩🏿‍🤝‍👩🏻|👩🏿‍🤝‍👩🏼|👩🏿‍🤝‍👩🏽|👩🏿‍🤝‍👩🏾|👩🏿‍🫯‍👩🏻|👩🏿‍🫯‍👩🏼|👩🏿‍🫯‍👩🏽|👩🏿‍🫯‍👩🏾|🧑🏻‍❤️‍🧑🏼|🧑🏻‍❤️‍🧑🏽|🧑🏻‍❤️‍🧑🏾|🧑🏻‍❤️‍🧑🏿|🧑🏻‍🐰‍🧑🏼|🧑🏻‍🐰‍🧑🏽|🧑🏻‍🐰‍🧑🏾|🧑🏻‍🐰‍🧑🏿|🧑🏻‍🤝‍🧑🏻|🧑🏻‍🤝‍🧑🏼|🧑🏻‍🤝‍🧑🏽|🧑🏻‍🤝‍🧑🏾|🧑🏻‍🤝‍🧑🏿|🧑🏻‍🫯‍🧑🏼|🧑🏻‍🫯‍🧑🏽|🧑🏻‍🫯‍🧑🏾|🧑🏻‍🫯‍🧑🏿|🧑🏼‍❤️‍🧑🏻|🧑🏼‍❤️‍🧑🏽|🧑🏼‍❤️‍🧑🏾|🧑🏼‍❤️‍🧑🏿|🧑🏼‍🐰‍🧑🏻|🧑🏼‍🐰‍🧑🏽|🧑🏼‍🐰‍🧑🏾|🧑🏼‍🐰‍🧑🏿|🧑🏼‍🤝‍🧑🏻|🧑🏼‍🤝‍🧑🏼|🧑🏼‍🤝‍🧑🏽|🧑🏼‍🤝‍🧑🏾|🧑🏼‍🤝‍🧑🏿|🧑🏼‍🫯‍🧑🏻|🧑🏼‍🫯‍🧑🏽|🧑🏼‍🫯‍🧑🏾|🧑🏼‍🫯‍🧑🏿|🧑🏽‍❤️‍🧑🏻|🧑🏽‍❤️‍🧑🏼|🧑🏽‍❤️‍🧑🏾|🧑🏽‍❤️‍🧑🏿|🧑🏽‍🐰‍🧑🏻|🧑🏽‍🐰‍🧑🏼|🧑🏽‍🐰‍🧑🏾|🧑🏽‍🐰‍🧑🏿|🧑🏽‍🤝‍🧑🏻|🧑🏽‍🤝‍🧑🏼|🧑🏽‍🤝‍🧑🏽|🧑🏽‍🤝‍🧑🏾|🧑🏽‍🤝‍🧑🏿|🧑🏽‍🫯‍🧑🏻|🧑🏽‍🫯‍🧑🏼|🧑🏽‍🫯‍🧑🏾|🧑🏽‍🫯‍🧑🏿|🧑🏾‍❤️‍🧑🏻|🧑🏾‍❤️‍🧑🏼|🧑🏾‍❤️‍🧑🏽|🧑🏾‍❤️‍🧑🏿|🧑🏾‍🐰‍🧑🏻|🧑🏾‍🐰‍🧑🏼|🧑🏾‍🐰‍🧑🏽|🧑🏾‍🐰‍🧑🏿|🧑🏾‍🤝‍🧑🏻|🧑🏾‍🤝‍🧑🏼|🧑🏾‍🤝‍🧑🏽|🧑🏾‍🤝‍🧑🏾|🧑🏾‍🤝‍🧑🏿|🧑🏾‍🫯‍🧑🏻|🧑🏾‍🫯‍🧑🏼|🧑🏾‍🫯‍🧑🏽|🧑🏾‍🫯‍🧑🏿|🧑🏿‍❤️‍🧑🏻|🧑🏿‍❤️‍🧑🏼|🧑🏿‍❤️‍🧑🏽|🧑🏿‍❤️‍🧑🏾|🧑🏿‍🐰‍🧑🏻|🧑🏿‍🐰‍🧑🏼|🧑🏿‍🐰‍🧑🏽|🧑🏿‍🐰‍🧑🏾|🧑🏿‍🤝‍🧑🏻|🧑🏿‍🤝‍🧑🏼|🧑🏿‍🤝‍🧑🏽|🧑🏿‍🤝‍🧑🏾|🧑🏿‍🤝‍🧑🏿|🧑🏿‍🫯‍🧑🏻|🧑🏿‍🫯‍🧑🏼|🧑🏿‍🫯‍🧑🏽|🧑🏿‍🫯‍🧑🏾|👨‍❤️‍💋‍👨|👨‍👨‍👦‍👦|👨‍👨‍👧‍👦|👨‍👨‍👧‍👧|👨‍👩‍👦‍👦|👨‍👩‍👧‍👦|👨‍👩‍👧‍👧|👩‍❤️‍💋‍👨|👩‍❤️‍💋‍👩|👩‍👩‍👦‍👦|👩‍👩‍👧‍👦|👩‍👩‍👧‍👧|🧑‍🧑‍🧒‍🧒|🏃🏻‍♀️‍➡️|🏃🏻‍♂️‍➡️|🏃🏼‍♀️‍➡️|🏃🏼‍♂️‍➡️|🏃🏽‍♀️‍➡️|🏃🏽‍♂️‍➡️|🏃🏾‍♀️‍➡️|🏃🏾‍♂️‍➡️|🏃🏿‍♀️‍➡️|🏃🏿‍♂️‍➡️|👨🏻‍🦯‍➡️|👨🏻‍🦼‍➡️|👨🏻‍🦽‍➡️|👨🏼‍🦯‍➡️|👨🏼‍🦼‍➡️|👨🏼‍🦽‍➡️|👨🏽‍🦯‍➡️|👨🏽‍🦼‍➡️|👨🏽‍🦽‍➡️|👨🏾‍🦯‍➡️|👨🏾‍🦼‍➡️|👨🏾‍🦽‍➡️|👨🏿‍🦯‍➡️|👨🏿‍🦼‍➡️|👨🏿‍🦽‍➡️|👩🏻‍🦯‍➡️|👩🏻‍🦼‍➡️|👩🏻‍🦽‍➡️|👩🏼‍🦯‍➡️|👩🏼‍🦼‍➡️|👩🏼‍🦽‍➡️|👩🏽‍🦯‍➡️|👩🏽‍🦼‍➡️|👩🏽‍🦽‍➡️|👩🏾‍🦯‍➡️|👩🏾‍🦼‍➡️|👩🏾‍🦽‍➡️|👩🏿‍🦯‍➡️|👩🏿‍🦼‍➡️|👩🏿‍🦽‍➡️|🚶🏻‍♀️‍➡️|🚶🏻‍♂️‍➡️|🚶🏼‍♀️‍➡️|🚶🏼‍♂️‍➡️|🚶🏽‍♀️‍➡️|🚶🏽‍♂️‍➡️|🚶🏾‍♀️‍➡️|🚶🏾‍♂️‍➡️|🚶🏿‍♀️‍➡️|🚶🏿‍♂️‍➡️|🧎🏻‍♀️‍➡️|🧎🏻‍♂️‍➡️|🧎🏼‍♀️‍➡️|🧎🏼‍♂️‍➡️|🧎🏽‍♀️‍➡️|🧎🏽‍♂️‍➡️|🧎🏾‍♀️‍➡️|🧎🏾‍♂️‍➡️|🧎🏿‍♀️‍➡️|🧎🏿‍♂️‍➡️|🧑🏻‍🦯‍➡️|🧑🏻‍🦼‍➡️|🧑🏻‍🦽‍➡️|🧑🏼‍🦯‍➡️|🧑🏼‍🦼‍➡️|🧑🏼‍🦽‍➡️|🧑🏽‍🦯‍➡️|🧑🏽‍🦼‍➡️|🧑🏽‍🦽‍➡️|🧑🏾‍🦯‍➡️|🧑🏾‍🦼‍➡️|🧑🏾‍🦽‍➡️|🧑🏿‍🦯‍➡️|🧑🏿‍🦼‍➡️|🧑🏿‍🦽‍➡️|🫱🏻‍🫲🏼|🫱🏻‍🫲🏽|🫱🏻‍🫲🏾|🫱🏻‍🫲🏿|🫱🏼‍🫲🏻|🫱🏼‍🫲🏽|🫱🏼‍🫲🏾|🫱🏼‍🫲🏿|🫱🏽‍🫲🏻|🫱🏽‍🫲🏼|🫱🏽‍🫲🏾|🫱🏽‍🫲🏿|🫱🏾‍🫲🏻|🫱🏾‍🫲🏼|🫱🏾‍🫲🏽|🫱🏾‍🫲🏿|🫱🏿‍🫲🏻|🫱🏿‍🫲🏼|🫱🏿‍🫲🏽|🫱🏿‍🫲🏾|🏃‍♀️‍➡️|🏃‍♂️‍➡️|👨‍❤️‍👨|👨‍👦‍👦|👨‍👧‍👦|👨‍👧‍👧|👨‍👨‍👦|👨‍👨‍👧|👨‍👩‍👦|👨‍👩‍👧|👨‍🦯‍➡️|👨‍🦼‍➡️|👨‍🦽‍➡️|👩‍❤️‍👨|👩‍❤️‍👩|👩‍👦‍👦|👩‍👧‍👦|👩‍👧‍👧|👩‍👩‍👦|👩‍👩‍👧|👩‍🦯‍➡️|👩‍🦼‍➡️|👩‍🦽‍➡️|🚶‍♀️‍➡️|🚶‍♂️‍➡️|🧎‍♀️‍➡️|🧎‍♂️‍➡️|🧑‍🤝‍🧑|🧑‍🦯‍➡️|🧑‍🦼‍➡️|🧑‍🦽‍➡️|🧑‍🧑‍🧒|🧑‍🧒‍🧒|🏃🏻‍♀️|🏃🏻‍♂️|🏃🏻‍➡️|🏃🏼‍♀️|🏃🏼‍♂️|🏃🏼‍➡️|🏃🏽‍♀️|🏃🏽‍♂️|🏃🏽‍➡️|🏃🏾‍♀️|🏃🏾‍♂️|🏃🏾‍➡️|🏃🏿‍♀️|🏃🏿‍♂️|🏃🏿‍➡️|🏄🏻‍♀️|🏄🏻‍♂️|🏄🏼‍♀️|🏄🏼‍♂️|🏄🏽‍♀️|🏄🏽‍♂️|🏄🏾‍♀️|🏄🏾‍♂️|🏄🏿‍♀️|🏄🏿‍♂️|🏊🏻‍♀️|🏊🏻‍♂️|🏊🏼‍♀️|🏊🏼‍♂️|🏊🏽‍♀️|🏊🏽‍♂️|🏊🏾‍♀️|🏊🏾‍♂️|🏊🏿‍♀️|🏊🏿‍♂️|🏋🏻‍♀️|🏋🏻‍♂️|🏋🏼‍♀️|🏋🏼‍♂️|🏋🏽‍♀️|🏋🏽‍♂️|🏋🏾‍♀️|🏋🏾‍♂️|🏋🏿‍♀️|🏋🏿‍♂️|🏌🏻‍♀️|🏌🏻‍♂️|🏌🏼‍♀️|🏌🏼‍♂️|🏌🏽‍♀️|🏌🏽‍♂️|🏌🏾‍♀️|🏌🏾‍♂️|🏌🏿‍♀️|🏌🏿‍♂️|👁️‍🗨️|👨🏻‍⚕️|👨🏻‍⚖️|👨🏻‍✈️|👨🏻‍🌾|👨🏻‍🍳|👨🏻‍🍼|👨🏻‍🎓|👨🏻‍🎤|👨🏻‍🎨|👨🏻‍🏫|👨🏻‍🏭|👨🏻‍💻|👨🏻‍💼|👨🏻‍🔧|👨🏻‍🔬|👨🏻‍🚀|👨🏻‍🚒|👨🏻‍🦯|👨🏻‍🦰|👨🏻‍🦱|👨🏻‍🦲|👨🏻‍🦳|👨🏻‍🦼|👨🏻‍🦽|👨🏼‍⚕️|👨🏼‍⚖️|👨🏼‍✈️|👨🏼‍🌾|👨🏼‍🍳|👨🏼‍🍼|👨🏼‍🎓|👨🏼‍🎤|👨🏼‍🎨|👨🏼‍🏫|👨🏼‍🏭|👨🏼‍💻|👨🏼‍💼|👨🏼‍🔧|👨🏼‍🔬|👨🏼‍🚀|👨🏼‍🚒|👨🏼‍🦯|👨🏼‍🦰|👨🏼‍🦱|👨🏼‍🦲|👨🏼‍🦳|👨🏼‍🦼|👨🏼‍🦽|👨🏽‍⚕️|👨🏽‍⚖️|👨🏽‍✈️|👨🏽‍🌾|👨🏽‍🍳|👨🏽‍🍼|👨🏽‍🎓|👨🏽‍🎤|👨🏽‍🎨|👨🏽‍🏫|👨🏽‍🏭|👨🏽‍💻|👨🏽‍💼|👨🏽‍🔧|👨🏽‍🔬|👨🏽‍🚀|👨🏽‍🚒|👨🏽‍🦯|👨🏽‍🦰|👨🏽‍🦱|👨🏽‍🦲|👨🏽‍🦳|👨🏽‍🦼|👨🏽‍🦽|👨🏾‍⚕️|👨🏾‍⚖️|👨🏾‍✈️|👨🏾‍🌾|👨🏾‍🍳|👨🏾‍🍼|👨🏾‍🎓|👨🏾‍🎤|👨🏾‍🎨|👨🏾‍🏫|👨🏾‍🏭|👨🏾‍💻|👨🏾‍💼|👨🏾‍🔧|👨🏾‍🔬|👨🏾‍🚀|👨🏾‍🚒|👨🏾‍🦯|👨🏾‍🦰|👨🏾‍🦱|👨🏾‍🦲|👨🏾‍🦳|👨🏾‍🦼|👨🏾‍🦽|👨🏿‍⚕️|👨🏿‍⚖️|👨🏿‍✈️|👨🏿‍🌾|👨🏿‍🍳|👨🏿‍🍼|👨🏿‍🎓|👨🏿‍🎤|👨🏿‍🎨|👨🏿‍🏫|👨🏿‍🏭|👨🏿‍💻|👨🏿‍💼|👨🏿‍🔧|👨🏿‍🔬|👨🏿‍🚀|👨🏿‍🚒|👨🏿‍🦯|👨🏿‍🦰|👨🏿‍🦱|👨🏿‍🦲|👨🏿‍🦳|👨🏿‍🦼|👨🏿‍🦽|👩🏻‍⚕️|👩🏻‍⚖️|👩🏻‍✈️|👩🏻‍🌾|👩🏻‍🍳|👩🏻‍🍼|👩🏻‍🎓|👩🏻‍🎤|👩🏻‍🎨|👩🏻‍🏫|👩🏻‍🏭|👩🏻‍💻|👩🏻‍💼|👩🏻‍🔧|👩🏻‍🔬|👩🏻‍🚀|👩🏻‍🚒|👩🏻‍🦯|👩🏻‍🦰|👩🏻‍🦱|👩🏻‍🦲|👩🏻‍🦳|👩🏻‍🦼|👩🏻‍🦽|👩🏼‍⚕️|👩🏼‍⚖️|👩🏼‍✈️|👩🏼‍🌾|👩🏼‍🍳|👩🏼‍🍼|👩🏼‍🎓|👩🏼‍🎤|👩🏼‍🎨|👩🏼‍🏫|👩🏼‍🏭|👩🏼‍💻|👩🏼‍💼|👩🏼‍🔧|👩🏼‍🔬|👩🏼‍🚀|👩🏼‍🚒|👩🏼‍🦯|👩🏼‍🦰|👩🏼‍🦱|👩🏼‍🦲|👩🏼‍🦳|👩🏼‍🦼|👩🏼‍🦽|👩🏽‍⚕️|👩🏽‍⚖️|👩🏽‍✈️|👩🏽‍🌾|👩🏽‍🍳|👩🏽‍🍼|👩🏽‍🎓|👩🏽‍🎤|👩🏽‍🎨|👩🏽‍🏫|👩🏽‍🏭|👩🏽‍💻|👩🏽‍💼|👩🏽‍🔧|👩🏽‍🔬|👩🏽‍🚀|👩🏽‍🚒|👩🏽‍🦯|👩🏽‍🦰|👩🏽‍🦱|👩🏽‍🦲|👩🏽‍🦳|👩🏽‍🦼|👩🏽‍🦽|👩🏾‍⚕️|👩🏾‍⚖️|👩🏾‍✈️|👩🏾‍🌾|👩🏾‍🍳|👩🏾‍🍼|👩🏾‍🎓|👩🏾‍🎤|👩🏾‍🎨|👩🏾‍🏫|👩🏾‍🏭|👩🏾‍💻|👩🏾‍💼|👩🏾‍🔧|👩🏾‍🔬|👩🏾‍🚀|👩🏾‍🚒|👩🏾‍🦯|👩🏾‍🦰|👩🏾‍🦱|👩🏾‍🦲|👩🏾‍🦳|👩🏾‍🦼|👩🏾‍🦽|👩🏿‍⚕️|👩🏿‍⚖️|👩🏿‍✈️|👩🏿‍🌾|👩🏿‍🍳|👩🏿‍🍼|👩🏿‍🎓|👩🏿‍🎤|👩🏿‍🎨|👩🏿‍🏫|👩🏿‍🏭|👩🏿‍💻|👩🏿‍💼|👩🏿‍🔧|👩🏿‍🔬|👩🏿‍🚀|👩🏿‍🚒|👩🏿‍🦯|👩🏿‍🦰|👩🏿‍🦱|👩🏿‍🦲|👩🏿‍🦳|👩🏿‍🦼|👩🏿‍🦽|👮🏻‍♀️|👮🏻‍♂️|👮🏼‍♀️|👮🏼‍♂️|👮🏽‍♀️|👮🏽‍♂️|👮🏾‍♀️|👮🏾‍♂️|👮🏿‍♀️|👮🏿‍♂️|👯🏻‍♀️|👯🏻‍♂️|👯🏼‍♀️|👯🏼‍♂️|👯🏽‍♀️|👯🏽‍♂️|👯🏾‍♀️|👯🏾‍♂️|👯🏿‍♀️|👯🏿‍♂️|👰🏻‍♀️|👰🏻‍♂️|👰🏼‍♀️|👰🏼‍♂️|👰🏽‍♀️|👰🏽‍♂️|👰🏾‍♀️|👰🏾‍♂️|👰🏿‍♀️|👰🏿‍♂️|👱🏻‍♀️|👱🏻‍♂️|👱🏼‍♀️|👱🏼‍♂️|👱🏽‍♀️|👱🏽‍♂️|👱🏾‍♀️|👱🏾‍♂️|👱🏿‍♀️|👱🏿‍♂️|👳🏻‍♀️|👳🏻‍♂️|👳🏼‍♀️|👳🏼‍♂️|👳🏽‍♀️|👳🏽‍♂️|👳🏾‍♀️|👳🏾‍♂️|👳🏿‍♀️|👳🏿‍♂️|👷🏻‍♀️|👷🏻‍♂️|👷🏼‍♀️|👷🏼‍♂️|👷🏽‍♀️|👷🏽‍♂️|👷🏾‍♀️|👷🏾‍♂️|👷🏿‍♀️|👷🏿‍♂️|💁🏻‍♀️|💁🏻‍♂️|💁🏼‍♀️|💁🏼‍♂️|💁🏽‍♀️|💁🏽‍♂️|💁🏾‍♀️|💁🏾‍♂️|💁🏿‍♀️|💁🏿‍♂️|💂🏻‍♀️|💂🏻‍♂️|💂🏼‍♀️|💂🏼‍♂️|💂🏽‍♀️|💂🏽‍♂️|💂🏾‍♀️|💂🏾‍♂️|💂🏿‍♀️|💂🏿‍♂️|💆🏻‍♀️|💆🏻‍♂️|💆🏼‍♀️|💆🏼‍♂️|💆🏽‍♀️|💆🏽‍♂️|💆🏾‍♀️|💆🏾‍♂️|💆🏿‍♀️|💆🏿‍♂️|💇🏻‍♀️|💇🏻‍♂️|💇🏼‍♀️|💇🏼‍♂️|💇🏽‍♀️|💇🏽‍♂️|💇🏾‍♀️|💇🏾‍♂️|💇🏿‍♀️|💇🏿‍♂️|🕵🏻‍♀️|🕵🏻‍♂️|🕵🏼‍♀️|🕵🏼‍♂️|🕵🏽‍♀️|🕵🏽‍♂️|🕵🏾‍♀️|🕵🏾‍♂️|🕵🏿‍♀️|🕵🏿‍♂️|🙅🏻‍♀️|🙅🏻‍♂️|🙅🏼‍♀️|🙅🏼‍♂️|🙅🏽‍♀️|🙅🏽‍♂️|🙅🏾‍♀️|🙅🏾‍♂️|🙅🏿‍♀️|🙅🏿‍♂️|🙆🏻‍♀️|🙆🏻‍♂️|🙆🏼‍♀️|🙆🏼‍♂️|🙆🏽‍♀️|🙆🏽‍♂️|🙆🏾‍♀️|🙆🏾‍♂️|🙆🏿‍♀️|🙆🏿‍♂️|🙇🏻‍♀️|🙇🏻‍♂️|🙇🏼‍♀️|🙇🏼‍♂️|🙇🏽‍♀️|🙇🏽‍♂️|🙇🏾‍♀️|🙇🏾‍♂️|🙇🏿‍♀️|🙇🏿‍♂️|🙋🏻‍♀️|🙋🏻‍♂️|🙋🏼‍♀️|🙋🏼‍♂️|🙋🏽‍♀️|🙋🏽‍♂️|🙋🏾‍♀️|🙋🏾‍♂️|🙋🏿‍♀️|🙋🏿‍♂️|🙍🏻‍♀️|🙍🏻‍♂️|🙍🏼‍♀️|🙍🏼‍♂️|🙍🏽‍♀️|🙍🏽‍♂️|🙍🏾‍♀️|🙍🏾‍♂️|🙍🏿‍♀️|🙍🏿‍♂️|🙎🏻‍♀️|🙎🏻‍♂️|🙎🏼‍♀️|🙎🏼‍♂️|🙎🏽‍♀️|🙎🏽‍♂️|🙎🏾‍♀️|🙎🏾‍♂️|🙎🏿‍♀️|🙎🏿‍♂️|🚣🏻‍♀️|🚣🏻‍♂️|🚣🏼‍♀️|🚣🏼‍♂️|🚣🏽‍♀️|🚣🏽‍♂️|🚣🏾‍♀️|🚣🏾‍♂️|🚣🏿‍♀️|🚣🏿‍♂️|🚴🏻‍♀️|🚴🏻‍♂️|🚴🏼‍♀️|🚴🏼‍♂️|🚴🏽‍♀️|🚴🏽‍♂️|🚴🏾‍♀️|🚴🏾‍♂️|🚴🏿‍♀️|🚴🏿‍♂️|🚵🏻‍♀️|🚵🏻‍♂️|🚵🏼‍♀️|🚵🏼‍♂️|🚵🏽‍♀️|🚵🏽‍♂️|🚵🏾‍♀️|🚵🏾‍♂️|🚵🏿‍♀️|🚵🏿‍♂️|🚶🏻‍♀️|🚶🏻‍♂️|🚶🏻‍➡️|🚶🏼‍♀️|🚶🏼‍♂️|🚶🏼‍➡️|🚶🏽‍♀️|🚶🏽‍♂️|🚶🏽‍➡️|🚶🏾‍♀️|🚶🏾‍♂️|🚶🏾‍➡️|🚶🏿‍♀️|🚶🏿‍♂️|🚶🏿‍➡️|🤦🏻‍♀️|🤦🏻‍♂️|🤦🏼‍♀️|🤦🏼‍♂️|🤦🏽‍♀️|🤦🏽‍♂️|🤦🏾‍♀️|🤦🏾‍♂️|🤦🏿‍♀️|🤦🏿‍♂️|🤵🏻‍♀️|🤵🏻‍♂️|🤵🏼‍♀️|🤵🏼‍♂️|🤵🏽‍♀️|🤵🏽‍♂️|🤵🏾‍♀️|🤵🏾‍♂️|🤵🏿‍♀️|🤵🏿‍♂️|🤷🏻‍♀️|🤷🏻‍♂️|🤷🏼‍♀️|🤷🏼‍♂️|🤷🏽‍♀️|🤷🏽‍♂️|🤷🏾‍♀️|🤷🏾‍♂️|🤷🏿‍♀️|🤷🏿‍♂️|🤸🏻‍♀️|🤸🏻‍♂️|🤸🏼‍♀️|🤸🏼‍♂️|🤸🏽‍♀️|🤸🏽‍♂️|🤸🏾‍♀️|🤸🏾‍♂️|🤸🏿‍♀️|🤸🏿‍♂️|🤹🏻‍♀️|🤹🏻‍♂️|🤹🏼‍♀️|🤹🏼‍♂️|🤹🏽‍♀️|🤹🏽‍♂️|🤹🏾‍♀️|🤹🏾‍♂️|🤹🏿‍♀️|🤹🏿‍♂️|🤼🏻‍♀️|🤼🏻‍♂️|🤼🏼‍♀️|🤼🏼‍♂️|🤼🏽‍♀️|🤼🏽‍♂️|🤼🏾‍♀️|🤼🏾‍♂️|🤼🏿‍♀️|🤼🏿‍♂️|🤽🏻‍♀️|🤽🏻‍♂️|🤽🏼‍♀️|🤽🏼‍♂️|🤽🏽‍♀️|🤽🏽‍♂️|🤽🏾‍♀️|🤽🏾‍♂️|🤽🏿‍♀️|🤽🏿‍♂️|🤾🏻‍♀️|🤾🏻‍♂️|🤾🏼‍♀️|🤾🏼‍♂️|🤾🏽‍♀️|🤾🏽‍♂️|🤾🏾‍♀️|🤾🏾‍♂️|🤾🏿‍♀️|🤾🏿‍♂️|🦸🏻‍♀️|🦸🏻‍♂️|🦸🏼‍♀️|🦸🏼‍♂️|🦸🏽‍♀️|🦸🏽‍♂️|🦸🏾‍♀️|🦸🏾‍♂️|🦸🏿‍♀️|🦸🏿‍♂️|🦹🏻‍♀️|🦹🏻‍♂️|🦹🏼‍♀️|🦹🏼‍♂️|🦹🏽‍♀️|🦹🏽‍♂️|🦹🏾‍♀️|🦹🏾‍♂️|🦹🏿‍♀️|🦹🏿‍♂️|🧍🏻‍♀️|🧍🏻‍♂️|🧍🏼‍♀️|🧍🏼‍♂️|🧍🏽‍♀️|🧍🏽‍♂️|🧍🏾‍♀️|🧍🏾‍♂️|🧍🏿‍♀️|🧍🏿‍♂️|🧎🏻‍♀️|🧎🏻‍♂️|🧎🏻‍➡️|🧎🏼‍♀️|🧎🏼‍♂️|🧎🏼‍➡️|🧎🏽‍♀️|🧎🏽‍♂️|🧎🏽‍➡️|🧎🏾‍♀️|🧎🏾‍♂️|🧎🏾‍➡️|🧎🏿‍♀️|🧎🏿‍♂️|🧎🏿‍➡️|🧏🏻‍♀️|🧏🏻‍♂️|🧏🏼‍♀️|🧏🏼‍♂️|🧏🏽‍♀️|🧏🏽‍♂️|🧏🏾‍♀️|🧏🏾‍♂️|🧏🏿‍♀️|🧏🏿‍♂️|🧑🏻‍⚕️|🧑🏻‍⚖️|🧑🏻‍✈️|🧑🏻‍🌾|🧑🏻‍🍳|🧑🏻‍🍼|🧑🏻‍🎄|🧑🏻‍🎓|🧑🏻‍🎤|🧑🏻‍🎨|🧑🏻‍🏫|🧑🏻‍🏭|🧑🏻‍💻|🧑🏻‍💼|🧑🏻‍🔧|🧑🏻‍🔬|🧑🏻‍🚀|🧑🏻‍🚒|🧑🏻‍🦯|🧑🏻‍🦰|🧑🏻‍🦱|🧑🏻‍🦲|🧑🏻‍🦳|🧑🏻‍🦼|🧑🏻‍🦽|🧑🏻‍🩰|🧑🏼‍⚕️|🧑🏼‍⚖️|🧑🏼‍✈️|🧑🏼‍🌾|🧑🏼‍🍳|🧑🏼‍🍼|🧑🏼‍🎄|🧑🏼‍🎓|🧑🏼‍🎤|🧑🏼‍🎨|🧑🏼‍🏫|🧑🏼‍🏭|🧑🏼‍💻|🧑🏼‍💼|🧑🏼‍🔧|🧑🏼‍🔬|🧑🏼‍🚀|🧑🏼‍🚒|🧑🏼‍🦯|🧑🏼‍🦰|🧑🏼‍🦱|🧑🏼‍🦲|🧑🏼‍🦳|🧑🏼‍🦼|🧑🏼‍🦽|🧑🏼‍🩰|🧑🏽‍⚕️|🧑🏽‍⚖️|🧑🏽‍✈️|🧑🏽‍🌾|🧑🏽‍🍳|🧑🏽‍🍼|🧑🏽‍🎄|🧑🏽‍🎓|🧑🏽‍🎤|🧑🏽‍🎨|🧑🏽‍🏫|🧑🏽‍🏭|🧑🏽‍💻|🧑🏽‍💼|🧑🏽‍🔧|🧑🏽‍🔬|🧑🏽‍🚀|🧑🏽‍🚒|🧑🏽‍🦯|🧑🏽‍🦰|🧑🏽‍🦱|🧑🏽‍🦲|🧑🏽‍🦳|🧑🏽‍🦼|🧑🏽‍🦽|🧑🏽‍🩰|🧑🏾‍⚕️|🧑🏾‍⚖️|🧑🏾‍✈️|🧑🏾‍🌾|🧑🏾‍🍳|🧑🏾‍🍼|🧑🏾‍🎄|🧑🏾‍🎓|🧑🏾‍🎤|🧑🏾‍🎨|🧑🏾‍🏫|🧑🏾‍🏭|🧑🏾‍💻|🧑🏾‍💼|🧑🏾‍🔧|🧑🏾‍🔬|🧑🏾‍🚀|🧑🏾‍🚒|🧑🏾‍🦯|🧑🏾‍🦰|🧑🏾‍🦱|🧑🏾‍🦲|🧑🏾‍🦳|🧑🏾‍🦼|🧑🏾‍🦽|🧑🏾‍🩰|🧑🏿‍⚕️|🧑🏿‍⚖️|🧑🏿‍✈️|🧑🏿‍🌾|🧑🏿‍🍳|🧑🏿‍🍼|🧑🏿‍🎄|🧑🏿‍🎓|🧑🏿‍🎤|🧑🏿‍🎨|🧑🏿‍🏫|🧑🏿‍🏭|🧑🏿‍💻|🧑🏿‍💼|🧑🏿‍🔧|🧑🏿‍🔬|🧑🏿‍🚀|🧑🏿‍🚒|🧑🏿‍🦯|🧑🏿‍🦰|🧑🏿‍🦱|🧑🏿‍🦲|🧑🏿‍🦳|🧑🏿‍🦼|🧑🏿‍🦽|🧑🏿‍🩰|🧔🏻‍♀️|🧔🏻‍♂️|🧔🏼‍♀️|🧔🏼‍♂️|🧔🏽‍♀️|🧔🏽‍♂️|🧔🏾‍♀️|🧔🏾‍♂️|🧔🏿‍♀️|🧔🏿‍♂️|🧖🏻‍♀️|🧖🏻‍♂️|🧖🏼‍♀️|🧖🏼‍♂️|🧖🏽‍♀️|🧖🏽‍♂️|🧖🏾‍♀️|🧖🏾‍♂️|🧖🏿‍♀️|🧖🏿‍♂️|🧗🏻‍♀️|🧗🏻‍♂️|🧗🏼‍♀️|🧗🏼‍♂️|🧗🏽‍♀️|🧗🏽‍♂️|🧗🏾‍♀️|🧗🏾‍♂️|🧗🏿‍♀️|🧗🏿‍♂️|🧘🏻‍♀️|🧘🏻‍♂️|🧘🏼‍♀️|🧘🏼‍♂️|🧘🏽‍♀️|🧘🏽‍♂️|🧘🏾‍♀️|🧘🏾‍♂️|🧘🏿‍♀️|🧘🏿‍♂️|🧙🏻‍♀️|🧙🏻‍♂️|🧙🏼‍♀️|🧙🏼‍♂️|🧙🏽‍♀️|🧙🏽‍♂️|🧙🏾‍♀️|🧙🏾‍♂️|🧙🏿‍♀️|🧙🏿‍♂️|🧚🏻‍♀️|🧚🏻‍♂️|🧚🏼‍♀️|🧚🏼‍♂️|🧚🏽‍♀️|🧚🏽‍♂️|🧚🏾‍♀️|🧚🏾‍♂️|🧚🏿‍♀️|🧚🏿‍♂️|🧛🏻‍♀️|🧛🏻‍♂️|🧛🏼‍♀️|🧛🏼‍♂️|🧛🏽‍♀️|🧛🏽‍♂️|🧛🏾‍♀️|🧛🏾‍♂️|🧛🏿‍♀️|🧛🏿‍♂️|🧜🏻‍♀️|🧜🏻‍♂️|🧜🏼‍♀️|🧜🏼‍♂️|🧜🏽‍♀️|🧜🏽‍♂️|🧜🏾‍♀️|🧜🏾‍♂️|🧜🏿‍♀️|🧜🏿‍♂️|🧝🏻‍♀️|🧝🏻‍♂️|🧝🏼‍♀️|🧝🏼‍♂️|🧝🏽‍♀️|🧝🏽‍♂️|🧝🏾‍♀️|🧝🏾‍♂️|🧝🏿‍♀️|🧝🏿‍♂️|⛹🏻‍♀️|⛹🏻‍♂️|⛹🏼‍♀️|⛹🏼‍♂️|⛹🏽‍♀️|⛹🏽‍♂️|⛹🏾‍♀️|⛹🏾‍♂️|⛹🏿‍♀️|⛹🏿‍♂️|🏋️‍♀️|🏋️‍♂️|🏌️‍♀️|🏌️‍♂️|🏳️‍⚧️|🏳️‍🌈|🕵️‍♀️|🕵️‍♂️|😶‍🌫️|⛓️‍💥|⛹️‍♀️|⛹️‍♂️|❤️‍🔥|❤️‍🩹|🍄‍🟫|🍋‍🟩|🏃‍♀️|🏃‍♂️|🏃‍➡️|🏄‍♀️|🏄‍♂️|🏊‍♀️|🏊‍♂️|🏴‍☠️|🐕‍🦺|🐦‍🔥|🐻‍❄️|👨‍⚕️|👨‍⚖️|👨‍✈️|👨‍🌾|👨‍🍳|👨‍🍼|👨‍🎓|👨‍🎤|👨‍🎨|👨‍🏫|👨‍🏭|👨‍👦|👨‍👧|👨‍💻|👨‍💼|👨‍🔧|👨‍🔬|👨‍🚀|👨‍🚒|👨‍🦯|👨‍🦰|👨‍🦱|👨‍🦲|👨‍🦳|👨‍🦼|👨‍🦽|👩‍⚕️|👩‍⚖️|👩‍✈️|👩‍🌾|👩‍🍳|👩‍🍼|👩‍🎓|👩‍🎤|👩‍🎨|👩‍🏫|👩‍🏭|👩‍👦|👩‍👧|👩‍💻|👩‍💼|👩‍🔧|👩‍🔬|👩‍🚀|👩‍🚒|👩‍🦯|👩‍🦰|👩‍🦱|👩‍🦲|👩‍🦳|👩‍🦼|👩‍🦽|👮‍♀️|👮‍♂️|👯‍♀️|👯‍♂️|👰‍♀️|👰‍♂️|👱‍♀️|👱‍♂️|👳‍♀️|👳‍♂️|👷‍♀️|👷‍♂️|💁‍♀️|💁‍♂️|💂‍♀️|💂‍♂️|💆‍♀️|💆‍♂️|💇‍♀️|💇‍♂️|😮‍💨|😵‍💫|🙂‍↔️|🙂‍↕️|🙅‍♀️|🙅‍♂️|🙆‍♀️|🙆‍♂️|🙇‍♀️|🙇‍♂️|🙋‍♀️|🙋‍♂️|🙍‍♀️|🙍‍♂️|🙎‍♀️|🙎‍♂️|🚣‍♀️|🚣‍♂️|🚴‍♀️|🚴‍♂️|🚵‍♀️|🚵‍♂️|🚶‍♀️|🚶‍♂️|🚶‍➡️|🤦‍♀️|🤦‍♂️|🤵‍♀️|🤵‍♂️|🤷‍♀️|🤷‍♂️|🤸‍♀️|🤸‍♂️|🤹‍♀️|🤹‍♂️|🤼‍♀️|🤼‍♂️|🤽‍♀️|🤽‍♂️|🤾‍♀️|🤾‍♂️|🦸‍♀️|🦸‍♂️|🦹‍♀️|🦹‍♂️|🧍‍♀️|🧍‍♂️|🧎‍♀️|🧎‍♂️|🧎‍➡️|🧏‍♀️|🧏‍♂️|🧑‍⚕️|🧑‍⚖️|🧑‍✈️|🧑‍🌾|🧑‍🍳|🧑‍🍼|🧑‍🎄|🧑‍🎓|🧑‍🎤|🧑‍🎨|🧑‍🏫|🧑‍🏭|🧑‍💻|🧑‍💼|🧑‍🔧|🧑‍🔬|🧑‍🚀|🧑‍🚒|🧑‍🦯|🧑‍🦰|🧑‍🦱|🧑‍🦲|🧑‍🦳|🧑‍🦼|🧑‍🦽|🧑‍🧒|🧑‍🩰|🧔‍♀️|🧔‍♂️|🧖‍♀️|🧖‍♂️|🧗‍♀️|🧗‍♂️|🧘‍♀️|🧘‍♂️|🧙‍♀️|🧙‍♂️|🧚‍♀️|🧚‍♂️|🧛‍♀️|🧛‍♂️|🧜‍♀️|🧜‍♂️|🧝‍♀️|🧝‍♂️|🧞‍♀️|🧞‍♂️|🧟‍♀️|🧟‍♂️|\*️⃣|🇦🇨|🇦🇩|🇦🇪|🇦🇫|🇦🇬|🇦🇮|🇦🇱|🇦🇲|🇦🇴|🇦🇶|🇦🇷|🇦🇸|🇦🇹|🇦🇺|🇦🇼|🇦🇽|🇦🇿|🇧🇦|🇧🇧|🇧🇩|🇧🇪|🇧🇫|🇧🇬|🇧🇭|🇧🇮|🇧🇯|🇧🇱|🇧🇲|🇧🇳|🇧🇴|🇧🇶|🇧🇷|🇧🇸|🇧🇹|🇧🇻|🇧🇼|🇧🇾|🇧🇿|🇨🇦|🇨🇨|🇨🇩|🇨🇫|🇨🇬|🇨🇭|🇨🇮|🇨🇰|🇨🇱|🇨🇲|🇨🇳|🇨🇴|🇨🇵|🇨🇶|🇨🇷|🇨🇺|🇨🇻|🇨🇼|🇨🇽|🇨🇾|🇨🇿|🇩🇪|🇩🇬|🇩🇯|🇩🇰|🇩🇲|🇩🇴|🇩🇿|🇪🇦|🇪🇨|🇪🇪|🇪🇬|🇪🇭|🇪🇷|🇪🇸|🇪🇹|🇪🇺|🇫🇮|🇫🇯|🇫🇰|🇫🇲|🇫🇴|🇫🇷|🇬🇦|🇬🇧|🇬🇩|🇬🇪|🇬🇫|🇬🇬|🇬🇭|🇬🇮|🇬🇱|🇬🇲|🇬🇳|🇬🇵|🇬🇶|🇬🇷|🇬🇸|🇬🇹|🇬🇺|🇬🇼|🇬🇾|🇭🇰|🇭🇲|🇭🇳|🇭🇷|🇭🇹|🇭🇺|🇮🇨|🇮🇩|🇮🇪|🇮🇱|🇮🇲|🇮🇳|🇮🇴|🇮🇶|🇮🇷|🇮🇸|🇮🇹|🇯🇪|🇯🇲|🇯🇴|🇯🇵|🇰🇪|🇰🇬|🇰🇭|🇰🇮|🇰🇲|🇰🇳|🇰🇵|🇰🇷|🇰🇼|🇰🇾|🇰🇿|🇱🇦|🇱🇧|🇱🇨|🇱🇮|🇱🇰|🇱🇷|🇱🇸|🇱🇹|🇱🇺|🇱🇻|🇱🇾|🇲🇦|🇲🇨|🇲🇩|🇲🇪|🇲🇫|🇲🇬|🇲🇭|🇲🇰|🇲🇱|🇲🇲|🇲🇳|🇲🇴|🇲🇵|🇲🇶|🇲🇷|🇲🇸|🇲🇹|🇲🇺|🇲🇻|🇲🇼|🇲🇽|🇲🇾|🇲🇿|🇳🇦|🇳🇨|🇳🇪|🇳🇫|🇳🇬|🇳🇮|🇳🇱|🇳🇴|🇳🇵|🇳🇷|🇳🇺|🇳🇿|🇴🇲|🇵🇦|🇵🇪|🇵🇫|🇵🇬|🇵🇭|🇵🇰|🇵🇱|🇵🇲|🇵🇳|🇵🇷|🇵🇸|🇵🇹|🇵🇼|🇵🇾|🇶🇦|🇷🇪|🇷🇴|🇷🇸|🇷🇺|🇷🇼|🇸🇦|🇸🇧|🇸🇨|🇸🇩|🇸🇪|🇸🇬|🇸🇭|🇸🇮|🇸🇯|🇸🇰|🇸🇱|🇸🇲|🇸🇳|🇸🇴|🇸🇷|🇸🇸|🇸🇹|🇸🇻|🇸🇽|🇸🇾|🇸🇿|🇹🇦|🇹🇨|🇹🇩|🇹🇫|🇹🇬|🇹🇭|🇹🇯|🇹🇰|🇹🇱|🇹🇲|🇹🇳|🇹🇴|🇹🇷|🇹🇹|🇹🇻|🇹🇼|🇹🇿|🇺🇦|🇺🇬|🇺🇲|🇺🇳|🇺🇸|🇺🇾|🇺🇿|🇻🇦|🇻🇨|🇻🇪|🇻🇬|🇻🇮|🇻🇳|🇻🇺|🇼🇫|🇼🇸|🇽🇰|🇾🇪|🇾🇹|🇿🇦|🇿🇲|🇿🇼|🎅🏻|🎅🏼|🎅🏽|🎅🏾|🎅🏿|🏂🏻|🏂🏼|🏂🏽|🏂🏾|🏂🏿|🏃🏻|🏃🏼|🏃🏽|🏃🏾|🏃🏿|🏄🏻|🏄🏼|🏄🏽|🏄🏾|🏄🏿|🏇🏻|🏇🏼|🏇🏽|🏇🏾|🏇🏿|🏊🏻|🏊🏼|🏊🏽|🏊🏾|🏊🏿|🏋🏻|🏋🏼|🏋🏽|🏋🏾|🏋🏿|🏌🏻|🏌🏼|🏌🏽|🏌🏾|🏌🏿|🐈‍⬛|🐦‍⬛|👂🏻|👂🏼|👂🏽|👂🏾|👂🏿|👃🏻|👃🏼|👃🏽|👃🏾|👃🏿|👆🏻|👆🏼|👆🏽|👆🏾|👆🏿|👇🏻|👇🏼|👇🏽|👇🏾|👇🏿|👈🏻|👈🏼|👈🏽|👈🏾|👈🏿|👉🏻|👉🏼|👉🏽|👉🏾|👉🏿|👊🏻|👊🏼|👊🏽|👊🏾|👊🏿|👋🏻|👋🏼|👋🏽|👋🏾|👋🏿|👌🏻|👌🏼|👌🏽|👌🏾|👌🏿|👍🏻|👍🏼|👍🏽|👍🏾|👍🏿|👎🏻|👎🏼|👎🏽|👎🏾|👎🏿|👏🏻|👏🏼|👏🏽|👏🏾|👏🏿|👐🏻|👐🏼|👐🏽|👐🏾|👐🏿|👦🏻|👦🏼|👦🏽|👦🏾|👦🏿|👧🏻|👧🏼|👧🏽|👧🏾|👧🏿|👨🏻|👨🏼|👨🏽|👨🏾|👨🏿|👩🏻|👩🏼|👩🏽|👩🏾|👩🏿|👫🏻|👫🏼|👫🏽|👫🏾|👫🏿|👬🏻|👬🏼|👬🏽|👬🏾|👬🏿|👭🏻|👭🏼|👭🏽|👭🏾|👭🏿|👮🏻|👮🏼|👮🏽|👮🏾|👮🏿|👯🏻|👯🏼|👯🏽|👯🏾|👯🏿|👰🏻|👰🏼|👰🏽|👰🏾|👰🏿|👱🏻|👱🏼|👱🏽|👱🏾|👱🏿|👲🏻|👲🏼|👲🏽|👲🏾|👲🏿|👳🏻|👳🏼|👳🏽|👳🏾|👳🏿|👴🏻|👴🏼|👴🏽|👴🏾|👴🏿|👵🏻|👵🏼|👵🏽|👵🏾|👵🏿|👶🏻|👶🏼|👶🏽|👶🏾|👶🏿|👷🏻|👷🏼|👷🏽|👷🏾|👷🏿|👸🏻|👸🏼|👸🏽|👸🏾|👸🏿|👼🏻|👼🏼|👼🏽|👼🏾|👼🏿|💁🏻|💁🏼|💁🏽|💁🏾|💁🏿|💂🏻|💂🏼|💂🏽|💂🏾|💂🏿|💃🏻|💃🏼|💃🏽|💃🏾|💃🏿|💅🏻|💅🏼|💅🏽|💅🏾|💅🏿|💆🏻|💆🏼|💆🏽|💆🏾|💆🏿|💇🏻|💇🏼|💇🏽|💇🏾|💇🏿|💏🏻|💏🏼|💏🏽|💏🏾|💏🏿|💑🏻|💑🏼|💑🏽|💑🏾|💑🏿|💪🏻|💪🏼|💪🏽|💪🏾|💪🏿|🕴🏻|🕴🏼|🕴🏽|🕴🏾|🕴🏿|🕵🏻|🕵🏼|🕵🏽|🕵🏾|🕵🏿|🕺🏻|🕺🏼|🕺🏽|🕺🏾|🕺🏿|🖐🏻|🖐🏼|🖐🏽|🖐🏾|🖐🏿|🖕🏻|🖕🏼|🖕🏽|🖕🏾|🖕🏿|🖖🏻|🖖🏼|🖖🏽|🖖🏾|🖖🏿|🙅🏻|🙅🏼|🙅🏽|🙅🏾|🙅🏿|🙆🏻|🙆🏼|🙆🏽|🙆🏾|🙆🏿|🙇🏻|🙇🏼|🙇🏽|🙇🏾|🙇🏿|🙋🏻|🙋🏼|🙋🏽|🙋🏾|🙋🏿|🙌🏻|🙌🏼|🙌🏽|🙌🏾|🙌🏿|🙍🏻|🙍🏼|🙍🏽|🙍🏾|🙍🏿|🙎🏻|🙎🏼|🙎🏽|🙎🏾|🙎🏿|🙏🏻|🙏🏼|🙏🏽|🙏🏾|🙏🏿|🚣🏻|🚣🏼|🚣🏽|🚣🏾|🚣🏿|🚴🏻|🚴🏼|🚴🏽|🚴🏾|🚴🏿|🚵🏻|🚵🏼|🚵🏽|🚵🏾|🚵🏿|🚶🏻|🚶🏼|🚶🏽|🚶🏾|🚶🏿|🛀🏻|🛀🏼|🛀🏽|🛀🏾|🛀🏿|🛌🏻|🛌🏼|🛌🏽|🛌🏾|🛌🏿|🤌🏻|🤌🏼|🤌🏽|🤌🏾|🤌🏿|🤏🏻|🤏🏼|🤏🏽|🤏🏾|🤏🏿|🤘🏻|🤘🏼|🤘🏽|🤘🏾|🤘🏿|🤙🏻|🤙🏼|🤙🏽|🤙🏾|🤙🏿|🤚🏻|🤚🏼|🤚🏽|🤚🏾|🤚🏿|🤛🏻|🤛🏼|🤛🏽|🤛🏾|🤛🏿|🤜🏻|🤜🏼|🤜🏽|🤜🏾|🤜🏿|🤝🏻|🤝🏼|🤝🏽|🤝🏾|🤝🏿|🤞🏻|🤞🏼|🤞🏽|🤞🏾|🤞🏿|🤟🏻|🤟🏼|🤟🏽|🤟🏾|🤟🏿|🤦🏻|🤦🏼|🤦🏽|🤦🏾|🤦🏿|🤰🏻|🤰🏼|🤰🏽|🤰🏾|🤰🏿|🤱🏻|🤱🏼|🤱🏽|🤱🏾|🤱🏿|🤲🏻|🤲🏼|🤲🏽|🤲🏾|🤲🏿|🤳🏻|🤳🏼|🤳🏽|🤳🏾|🤳🏿|🤴🏻|🤴🏼|🤴🏽|🤴🏾|🤴🏿|🤵🏻|🤵🏼|🤵🏽|🤵🏾|🤵🏿|🤶🏻|🤶🏼|🤶🏽|🤶🏾|🤶🏿|🤷🏻|🤷🏼|🤷🏽|🤷🏾|🤷🏿|🤸🏻|🤸🏼|🤸🏽|🤸🏾|🤸🏿|🤹🏻|🤹🏼|🤹🏽|🤹🏾|🤹🏿|🤼🏻|🤼🏼|🤼🏽|🤼🏾|🤼🏿|🤽🏻|🤽🏼|🤽🏽|🤽🏾|🤽🏿|🤾🏻|🤾🏼|🤾🏽|🤾🏾|🤾🏿|🥷🏻|🥷🏼|🥷🏽|🥷🏾|🥷🏿|🦵🏻|🦵🏼|🦵🏽|🦵🏾|🦵🏿|🦶🏻|🦶🏼|🦶🏽|🦶🏾|🦶🏿|🦸🏻|🦸🏼|🦸🏽|🦸🏾|🦸🏿|🦹🏻|🦹🏼|🦹🏽|🦹🏾|🦹🏿|🦻🏻|🦻🏼|🦻🏽|🦻🏾|🦻🏿|🧍🏻|🧍🏼|🧍🏽|🧍🏾|🧍🏿|🧎🏻|🧎🏼|🧎🏽|🧎🏾|🧎🏿|🧏🏻|🧏🏼|🧏🏽|🧏🏾|🧏🏿|🧑🏻|🧑🏼|🧑🏽|🧑🏾|🧑🏿|🧒🏻|🧒🏼|🧒🏽|🧒🏾|🧒🏿|🧓🏻|🧓🏼|🧓🏽|🧓🏾|🧓🏿|🧔🏻|🧔🏼|🧔🏽|🧔🏾|🧔🏿|🧕🏻|🧕🏼|🧕🏽|🧕🏾|🧕🏿|🧖🏻|🧖🏼|🧖🏽|🧖🏾|🧖🏿|🧗🏻|🧗🏼|🧗🏽|🧗🏾|🧗🏿|🧘🏻|🧘🏼|🧘🏽|🧘🏾|🧘🏿|🧙🏻|🧙🏼|🧙🏽|🧙🏾|🧙🏿|🧚🏻|🧚🏼|🧚🏽|🧚🏾|🧚🏿|🧛🏻|🧛🏼|🧛🏽|🧛🏾|🧛🏿|🧜🏻|🧜🏼|🧜🏽|🧜🏾|🧜🏿|🧝🏻|🧝🏼|🧝🏽|🧝🏾|🧝🏿|🫃🏻|🫃🏼|🫃🏽|🫃🏾|🫃🏿|🫄🏻|🫄🏼|🫄🏽|🫄🏾|🫄🏿|🫅🏻|🫅🏼|🫅🏽|🫅🏾|🫅🏿|🫰🏻|🫰🏼|🫰🏽|🫰🏾|🫰🏿|🫱🏻|🫱🏼|🫱🏽|🫱🏾|🫱🏿|🫲🏻|🫲🏼|🫲🏽|🫲🏾|🫲🏿|🫳🏻|🫳🏼|🫳🏽|🫳🏾|🫳🏿|🫴🏻|🫴🏼|🫴🏽|🫴🏾|🫴🏿|🫵🏻|🫵🏼|🫵🏽|🫵🏾|🫵🏿|🫶🏻|🫶🏼|🫶🏽|🫶🏾|🫶🏿|🫷🏻|🫷🏼|🫷🏽|🫷🏾|🫷🏿|🫸🏻|🫸🏼|🫸🏽|🫸🏾|🫸🏿|#️⃣|0️⃣|1️⃣|2️⃣|3️⃣|4️⃣|5️⃣|6️⃣|7️⃣|8️⃣|9️⃣|☝🏻|☝🏼|☝🏽|☝🏾|☝🏿|⛹🏻|⛹🏼|⛹🏽|⛹🏾|⛹🏿|✊🏻|✊🏼|✊🏽|✊🏾|✊🏿|✋🏻|✋🏼|✋🏽|✋🏾|✋🏿|✌🏻|✌🏼|✌🏽|✌🏾|✌🏿|✍🏻|✍🏼|✍🏽|✍🏾|✍🏿|🅰️|🅱️|🅾️|🅿️|🈂️|🈷️|🌡️|🌤️|🌥️|🌦️|🌧️|🌨️|🌩️|🌪️|🌫️|🌬️|🌶️|🍽️|🎖️|🎗️|🎙️|🎚️|🎛️|🎞️|🎟️|🏋️|🏌️|🏍️|🏎️|🏔️|🏕️|🏖️|🏗️|🏘️|🏙️|🏚️|🏛️|🏜️|🏝️|🏞️|🏟️|🏳️|🏵️|🏷️|🐿️|👁️|📽️|🕉️|🕊️|🕯️|🕰️|🕳️|🕴️|🕵️|🕶️|🕷️|🕸️|🕹️|🖇️|🖊️|🖋️|🖌️|🖍️|🖐️|🖥️|🖨️|🖱️|🖲️|🖼️|🗂️|🗃️|🗄️|🗑️|🗒️|🗓️|🗜️|🗝️|🗞️|🗡️|🗣️|🗨️|🗯️|🗳️|🗺️|🛋️|🛍️|🛎️|🛏️|🛠️|🛡️|🛢️|🛣️|🛤️|🛥️|🛩️|🛰️|🛳️|©️|®️|‼️|⁉️|™️|ℹ️|↔️|↕️|↖️|↗️|↘️|↙️|↩️|↪️|⌨️|⏏️|⏭️|⏮️|⏯️|⏱️|⏲️|⏸️|⏹️|⏺️|Ⓜ️|▪️|▫️|▶️|◀️|◻️|◼️|☀️|☁️|☂️|☃️|☄️|☎️|☑️|☘️|☝️|☠️|☢️|☣️|☦️|☪️|☮️|☯️|☸️|☹️|☺️|♀️|♂️|♟️|♠️|♣️|♥️|♦️|♨️|♻️|♾️|⚒️|⚔️|⚕️|⚖️|⚗️|⚙️|⚛️|⚜️|⚠️|⚧️|⚰️|⚱️|⛈️|⛏️|⛑️|⛓️|⛩️|⛰️|⛱️|⛴️|⛷️|⛸️|⛹️|✂️|✈️|✉️|✌️|✍️|✏️|✒️|✔️|✖️|✝️|✡️|✳️|✴️|❄️|❇️|❣️|❤️|➡️|⤴️|⤵️|⬅️|⬆️|⬇️|〰️|〽️|㊗️|㊙️|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55\u{1F004}\u{1F0CF}\u{1F18E}\u{1F191}-\u{1F19A}\u{1F201}\u{1F21A}\u{1F22F}\u{1F232}-\u{1F236}\u{1F238}-\u{1F23A}\u{1F250}\u{1F251}\u{1F300}-\u{1F320}\u{1F32D}-\u{1F335}\u{1F337}-\u{1F37C}\u{1F37E}-\u{1F393}\u{1F3A0}-\u{1F3CA}\u{1F3CF}-\u{1F3D3}\u{1F3E0}-\u{1F3F0}\u{1F3F4}\u{1F3F8}-\u{1F43E}\u{1F440}\u{1F442}-\u{1F4FC}\u{1F4FF}-\u{1F53D}\u{1F54B}-\u{1F54E}\u{1F550}-\u{1F567}\u{1F57A}\u{1F595}\u{1F596}\u{1F5A4}\u{1F5FB}-\u{1F64F}\u{1F680}-\u{1F6C5}\u{1F6CC}\u{1F6D0}-\u{1F6D2}\u{1F6D5}-\u{1F6D8}\u{1F6DC}-\u{1F6DF}\u{1F6EB}\u{1F6EC}\u{1F6F4}-\u{1F6FC}\u{1F7E0}-\u{1F7EB}\u{1F7F0}\u{1F90C}-\u{1F93A}\u{1F93C}-\u{1F945}\u{1F947}-\u{1F9FF}\u{1FA70}-\u{1FA7C}\u{1FA80}-\u{1FA8A}\u{1FA8E}-\u{1FAC6}\u{1FAC8}\u{1FACD}-\u{1FADC}\u{1FADF}-\u{1FAEA}\u{1FAEF}-\u{1FAF8}])/ug).length; } } else { content = (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)(react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.Fragment, { children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)("i", { className: "material-icons gray", children: "warning_amber" }, void 0, false), " ", (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)("i", { className: "gray", children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, { id: "invalid_content", defaultMessage: "invalid content", description: "Shown when the message is unreadable" }, void 0, false) }, void 0, false)] }, void 0, true); } return (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)("li", { ref: this.props.innerRef, className: sideClass, children: [this.props.selectMode ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)("i", { className: 'material-icons select-checkbox' + (this.props.selected ? ' blue' : ''), onClick: () => this.props.onToggleSelect(this.props.seq), children: this.props.selected ? 'check_circle' : 'radio_button_unchecked' }, void 0, false) : null, this.props.isGroup && this.props.response ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)("div", { className: "avatar-box", children: fullDisplay ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)(_letter_tile_jsx__WEBPACK_IMPORTED_MODULE_5__["default"], { authorizeURL: this.props.tinode.authorizeURL, topic: this.props.userFrom, title: this.props.userName, avatar: avatar }, void 0, false) : null }, void 0, false) : null, isFailed && failReason ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)("i", { className: "material-icons red message-fail-icon", children: "error" }, void 0, false) : null, (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)("div", { children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)("div", { className: bubbleClass, children: [showVoiceUnreadDot ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)("i", { className: "voice-unread-dot" }, void 0, false) : null, (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)("div", { className: "content-meta", children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)("div", { className: textSizeClass, children: [bundleCard || content, attachments] }, void 0, true), this.props.timestamp ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)(_received_marker_jsx__WEBPACK_IMPORTED_MODULE_6__["default"], { edited: this.props.edited, timestamp: this.props.timestamp, received: this.props.received }, void 0, false) : null] }, void 0, true), this.props.showContextMenu && !this.props.selectMode ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)("span", { className: "menuTrigger", children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)("a", { href: "#", onClick: this.handleContextClick, children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)("i", { className: "material-icons", children: "expand_more" }, void 0, false) }, void 0, false) }, void 0, false) : null] }, void 0, true), failReason, fullDisplay ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)("div", { className: "author", children: [this.props.userName || (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)("i", { children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, { id: "user_not_found", defaultMessage: "Not found", description: "In place of a user's full name when the user is not found." }, void 0, false) }, void 0, false), this.props.senderRole == 'owner' ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)("em", { className: "role-badge owner", children: "群主" }, void 0, false) : this.props.senderRole == 'admin' ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)("em", { className: "role-badge admin", children: "管理员" }, void 0, false) : null] }, void 0, true) : null] }, void 0, true)] }, void 0, true); } } ; const IntlChatMessage = (0,react_intl__WEBPACK_IMPORTED_MODULE_1__.injectIntl)(BaseChatMessage); const ChatMessage = react__WEBPACK_IMPORTED_MODULE_0___default().forwardRef((props, ref) => (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_10__.jsxDEV)(IntlChatMessage, { innerRef: ref, ...props }, void 0, false)); /* harmony default export */ __webpack_exports__["default"] = (ChatMessage); /***/ }), /***/ "./src/widgets/forward-bundle.jsx": /*!****************************************!*\ !*** ./src/widgets/forward-bundle.jsx ***! \****************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": function() { return /* binding */ ForwardBundle; } /* harmony export */ }); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react"); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react/jsx-dev-runtime */ "./node_modules/react/jsx-dev-runtime.js"); function senderName(tinode, from) { const raw = (from || '').trim(); if (!raw) return ''; const uid = raw.startsWith('usr') ? raw : 'usr' + raw; const topic = tinode && tinode.getTopic ? tinode.getTopic(uid) : null; const pub = topic && topic.public; return pub && (pub.fn || pub.name) || ''; } const TYPE_LABEL = { image: '[图片]', video: '[视频]', voice: '[语音]', file: '[文件]', link: '[链接]' }; function lineText(entry) { if (!entry) return ''; const summary = (entry.summary || entry.text || '').trim(); if (summary) return summary; return TYPE_LABEL[entry.type] || ''; } class ForwardBundle extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComponent) { constructor(props) { super(props); this.state = { expanded: false }; this.handleToggle = this.handleToggle.bind(this); } handleToggle(e) { e.preventDefault(); e.stopPropagation(); this.setState(s => ({ expanded: !s.expanded })); } render() { const c = this.props.content || {}; const count = Number(c.item_count) || (Array.isArray(c.items) ? c.items.length : 0); const rows = this.state.expanded ? c.items || [] : c.preview || []; const comment = (c.comment || '').trim(); return (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxDEV)("div", { className: "forward-bundle", children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxDEV)("div", { className: "forward-bundle-title", children: c.title || '聊天记录' }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxDEV)("ul", { className: "forward-bundle-lines", children: rows.map((entry, i) => { const who = senderName(this.props.tinode, entry.from); return (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxDEV)("li", { children: [who ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxDEV)("b", { children: [who, ":"] }, void 0, true) : null, lineText(entry)] }, (entry.seq != null ? entry.seq : i) + ':' + i, true); }) }, void 0, false), count > rows.length || this.state.expanded ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxDEV)("button", { type: "button", className: "forward-bundle-more", onClick: this.handleToggle, children: this.state.expanded ? '收起' : `查看完整记录(共 ${count} 条)` }, void 0, false) : (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxDEV)("div", { className: "forward-bundle-count", children: ["共 ", count, " 条消息"] }, void 0, true), comment ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxDEV)("div", { className: "forward-bundle-comment", children: comment }, void 0, false) : null] }, void 0, true); } } /***/ }), /***/ "./src/widgets/group-subs.jsx": /*!************************************!*\ !*** ./src/widgets/group-subs.jsx ***! \************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": function() { return /* binding */ GroupSubs; } /* harmony export */ }); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react"); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-intl */ "react-intl"); /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var _config_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../config.js */ "./src/config.js"); /* harmony import */ var _letter_tile_jsx__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./letter-tile.jsx */ "./src/widgets/letter-tile.jsx"); /* harmony import */ var _lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../lib/blob-helpers.js */ "./src/lib/blob-helpers.js"); /* harmony import */ var react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! react/jsx-dev-runtime */ "./node_modules/react/jsx-dev-runtime.js"); class GroupSubs extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component) { constructor(props) { super(props); } render() { const usersOnline = []; const totalCount = (this.props.subscribers || []).length; const countToShow = Math.min(_config_js__WEBPACK_IMPORTED_MODULE_2__.MAX_ONLINE_IN_TOPIC, totalCount); (this.props.subscribers || []).some(sub => { usersOnline.push((0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("div", { className: "avatar-box", children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)(_letter_tile_jsx__WEBPACK_IMPORTED_MODULE_3__["default"], { authorizeURL: this.props.tinode.authorizeURL, topic: sub.user, avatar: (0,_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_4__.makeImageUrl)(sub.public ? sub.public.photo : null) || true, title: sub.public ? sub.public.fn : null }, void 0, false) }, sub.user, false)); return usersOnline.length == countToShow; }); if (usersOnline.length == 0) { return null; } return (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("div", { id: "topic-users", children: [usersOnline, " ", totalCount > countToShow ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("span", { children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, { id: "more_online_members", defaultMessage: "+{overflow} more", description: "Shown in MessagesView title bar when the number of online subscribers exceeds MAX_ONLINE_IN_TOPIC", values: { overflow: totalCount - countToShow } }, void 0, false) }, void 0, false) : null] }, void 0, true); } } ; /***/ }), /***/ "./src/widgets/invitation.jsx": /*!************************************!*\ !*** ./src/widgets/invitation.jsx ***! \************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": function() { return /* binding */ Invitation; } /* harmony export */ }); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react"); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-intl */ "react-intl"); /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react/jsx-dev-runtime */ "./node_modules/react/jsx-dev-runtime.js"); class Invitation extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComponent) { constructor(props) { super(props); this.handleButtonAction = this.handleButtonAction.bind(this); } handleButtonAction(evt, data) { evt.preventDefault(); this.props.onAction(data); } render() { return (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxDEV)("div", { className: "accept-invite-panel", children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxDEV)("div", { className: "title", children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxDEV)(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, { id: "chat_invitation", defaultMessage: "You are invited to start a new chat. What would you like to do?", description: "New chat invitation message: [Accept] [Ignore] [Block]." }, void 0, false) }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxDEV)("div", { className: "footer", children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxDEV)("button", { className: "primary", onClick: event => { this.handleButtonAction(event, "accept"); }, children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxDEV)(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, { id: "chat_invitation_accept", defaultMessage: "Accept", description: "Action [Accept] for chat invitation." }, void 0, false) }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxDEV)("button", { className: "secondary", onClick: event => { this.handleButtonAction(event, "delete"); }, children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxDEV)(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, { id: "chat_invitation_ignore", defaultMessage: "Ignore", description: "Action [Ignore] for chat invitation." }, void 0, false) }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxDEV)("button", { className: "secondary", onClick: event => { this.handleButtonAction(event, "block"); }, children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxDEV)(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, { id: "chat_invitation_block", defaultMessage: "Block", description: "Action [Block] for chat invitation." }, void 0, false) }, void 0, false)] }, void 0, true)] }, void 0, true); } } ; /***/ }), /***/ "./src/widgets/meta-message.jsx": /*!**************************************!*\ !*** ./src/widgets/meta-message.jsx ***! \**************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": function() { return /* binding */ MetaMessage; } /* harmony export */ }); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react"); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react/jsx-dev-runtime */ "./node_modules/react/jsx-dev-runtime.js"); class MetaMessage extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComponent) { constructor(props) { super(props); } render() { let content = null; let bubbleClass = 'bubble'; if (this.props.date) { content = (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxDEV)(react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, { children: this.props.date }, void 0, false); bubbleClass += ' date'; } else if (this.props.deleted) { content = (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxDEV)("i", { className: "gray", children: this.props.deletedText || '消息已删除' }, void 0, false); bubbleClass += ' deleted'; } if (!content) { return (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxDEV)(react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, { children: null }, void 0, false); } return (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxDEV)("li", { className: "meta", children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxDEV)("div", { className: bubbleClass, children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxDEV)("div", { className: "message-content", children: content }, void 0, false) }, void 0, false) }, void 0, false); } } ; /***/ }), /***/ "./src/widgets/pinned-messages.jsx": /*!*****************************************!*\ !*** ./src/widgets/pinned-messages.jsx ***! \*****************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react"); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-intl */ "react-intl"); /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var tinode_sdk__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! tinode-sdk */ "tinode-sdk"); /* harmony import */ var tinode_sdk__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(tinode_sdk__WEBPACK_IMPORTED_MODULE_2__); /* harmony import */ var _lib_formatters_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../lib/formatters.js */ "./src/lib/formatters.js"); /* harmony import */ var _config_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../config.js */ "./src/config.js"); /* harmony import */ var react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! react/jsx-dev-runtime */ "./node_modules/react/jsx-dev-runtime.js"); const messages = (0,react_intl__WEBPACK_IMPORTED_MODULE_1__.defineMessages)({ message_not_found: { id: 'message_not_found', defaultMessage: 'message not found', description: 'Pinned message is not found' }, message_deleted: { id: 'message_deleted', defaultMessage: 'message deleted', description: 'Pinned message is deleted' } }); class PinnedMessages extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComponent) { constructor(props) { super(props); this.touchX = null; this.touchY = null; this.touchSurface = react__WEBPACK_IMPORTED_MODULE_0___default().createRef(); this.getSelectedIndex = this.getSelectedIndex.bind(this); this.handleCancel = this.handleCancel.bind(this); this.handleSelected = this.handleSelected.bind(this); this.handleMoveNext = this.handleMoveNext.bind(this); this.handleMovePrev = this.handleMovePrev.bind(this); this.handleTouchEventStart = this.handleTouchEventStart.bind(this); this.handleTouchEventEnd = this.handleTouchEventEnd.bind(this); this.handleTouchCancel = this.handleTouchCancel.bind(this); } componentDidMount() { this.touchSurface.current.addEventListener('touchstart', this.handleTouchEventStart, { passive: true }); this.touchSurface.current.addEventListener('touchend', this.handleTouchEventEnd, { passive: true }); this.touchSurface.current.addEventListener('touchcancel', this.handleTouchCancel, { passive: true }); } componentWillUnmount() { this.touchSurface.current.removeEventListener('touchstart', this.handleTouchEventStart); this.touchSurface.current.removeEventListener('touchend', this.handleTouchEventEnd); this.touchSurface.current.removeEventListener('touchcancel', this.handleTouchCancel); } getSelectedIndex() { const list = this.props.pins || []; return list.length - this.props.selected - 1; } handleCancel(e) { e.preventDefault(); this.props.onCancel(this.props.pins[this.getSelectedIndex()]); } handleSelected(e) { e.preventDefault(); this.props.onSelected(this.props.pins[this.getSelectedIndex()]); } handleMoveNext(e, isTouch) { isTouch || e.preventDefault(); e.stopPropagation(); const idx = Math.max(this.props.selected - 1, 0); if (idx != this.props.selected) { this.props.setSelected(idx); } } handleMovePrev(e, isTouch) { isTouch || e.preventDefault(); e.stopPropagation(); const idx = Math.min(this.props.selected + 1, (this.props.pins || []).length - 1); if (idx != this.props.selected) { this.props.setSelected(idx); } } handleTouchEventStart(e) { if (e.touches.length == 1) { this.touchX = e.touches[0].clientX; this.touchY = e.touches[0].clientY; } } handleTouchEventEnd(e) { if (this.touchX === null || e.changedTouches.length != 1) { this.touchX = null; return; } const dX = this.touchX - e.changedTouches[0].clientX; const dY = this.touchY - e.changedTouches[0].clientY; this.touchX = null; if (Math.abs(dX) > Math.abs(dY) || Math.abs(dY) < _config_js__WEBPACK_IMPORTED_MODULE_4__.MIN_SWIPE_DISTANCE) { return; } if (dY > 0) { this.handleMovePrev(e, true); } else { this.handleMoveNext(e, true); } } handleTouchCancel() { this.touchX = null; } render() { const selected = this.getSelectedIndex(); let messageShown = (this.props.messages || [])[selected]; messageShown = messageShown ? messageShown._deleted ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("i", { className: "gray", children: this.props.intl.formatMessage(messages.message_deleted) }, void 0, false) : tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.format(messageShown.content, _lib_formatters_js__WEBPACK_IMPORTED_MODULE_3__.previewFormatter, { formatMessage: this.props.intl.formatMessage.bind(this.props.intl), authorizeURL: this.props.tinode.authorizeURL.bind(this.props.tinode) }) : (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("i", { className: "gray", children: this.props.intl.formatMessage(messages.message_not_found) }, void 0, false); const dots = []; this.props.pins.forEach(seq => { const cn = dots.length == selected ? 'adot' : 'dot'; dots.push((0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("div", { className: cn }, seq, false)); }); return (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("div", { id: "pinned-wrapper", ref: this.touchSurface, children: [this.props.isAdmin ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("div", { className: "cancel", children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("a", { href: "#", onClick: this.handleCancel, children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("i", { className: "material-icons gray", children: "close" }, void 0, false) }, void 0, false) }, void 0, false) : (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("div", { children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("i", { className: "material-icons gray", children: "push_pin" }, void 0, false) }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("div", { className: "pinned-scroll", children: dots }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("div", { className: "pinned", onClick: this.handleSelected, children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("p", { children: messageShown }, void 0, false) }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("div", { className: "pinned-menu", children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("span", { className: "menuTrigger upper", children: selected > 0 ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("a", { href: "#", onClick: this.handleMovePrev, children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("i", { className: "material-icons", children: "expand_less" }, void 0, false) }, void 0, false) : null }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("span", { className: "menuTrigger lower", children: this.props.selected > 0 ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("a", { href: "#", onClick: this.handleMoveNext, children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("i", { className: "material-icons", children: "expand_more" }, void 0, false) }, void 0, false) : null }, void 0, false)] }, void 0, true)] }, void 0, true); } } /* harmony default export */ __webpack_exports__["default"] = ((0,react_intl__WEBPACK_IMPORTED_MODULE_1__.injectIntl)(PinnedMessages)); /***/ }), /***/ "./src/widgets/received-marker.jsx": /*!*****************************************!*\ !*** ./src/widgets/received-marker.jsx ***! \*****************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react"); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-intl */ "react-intl"); /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var tinode_sdk__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! tinode-sdk */ "tinode-sdk"); /* harmony import */ var tinode_sdk__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(tinode_sdk__WEBPACK_IMPORTED_MODULE_2__); /* harmony import */ var _lib_utils_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../lib/utils.js */ "./src/lib/utils.js"); /* harmony import */ var react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! react/jsx-dev-runtime */ "./node_modules/react/jsx-dev-runtime.js"); const messages = (0,react_intl__WEBPACK_IMPORTED_MODULE_1__.defineMessages)({ message_sending: { id: 'message_sending', defaultMessage: 'sending...', description: 'Message being sent, in place of time stamp' }, message_sending_failed: { id: 'message_sending_failed', defaultMessage: 'failed', description: 'Failed to send message, in place of time stamp' }, message_edited_marker: { id: 'message_edited_marker', defaultMessage: ', edited', description: 'Marker indicating that the message was edited' } }); class ReceivedMarker extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComponent) { render() { const { formatMessage } = this.props.intl; let timestamp; if (this.props.received <= tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Tinode.MESSAGE_STATUS_SENDING) { timestamp = formatMessage(messages.message_sending); } else if (this.props.received == tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Tinode.MESSAGE_STATUS_FAILED || this.props.received == tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Tinode.MESSAGE_STATUS_FATAL) { timestamp = formatMessage(messages.message_sending_failed); } else { timestamp = this.props.timestamp.toLocaleTimeString(this.props.intl.locale, { timeStyle: 'short' }); } const icon = (0,_lib_utils_js__WEBPACK_IMPORTED_MODULE_3__.deliveryMarker)(this.props.received); const marker = icon ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxDEV)("i", { className: 'material-icons small ' + (icon.color || ''), children: icon.name }, void 0, false) : null; const edited = this.props.edited ? formatMessage(messages.message_edited_marker) : null; return (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxDEV)("span", { className: "timestamp", children: [timestamp, edited, '\u00a0', marker] }, void 0, true); } } ; /* harmony default export */ __webpack_exports__["default"] = ((0,react_intl__WEBPACK_IMPORTED_MODULE_1__.injectIntl)(ReceivedMarker)); /***/ }), /***/ "./src/widgets/send-message.jsx": /*!**************************************!*\ !*** ./src/widgets/send-message.jsx ***! \**************************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { __webpack_require__.r(__webpack_exports__); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react"); /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-intl */ "react-intl"); /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var tinode_sdk__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! tinode-sdk */ "tinode-sdk"); /* harmony import */ var tinode_sdk__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(tinode_sdk__WEBPACK_IMPORTED_MODULE_2__); /* harmony import */ var _config_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../config.js */ "./src/config.js"); /* harmony import */ var _lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../lib/blob-helpers.js */ "./src/lib/blob-helpers.js"); /* harmony import */ var _lib_formatters_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../lib/formatters.js */ "./src/lib/formatters.js"); /* harmony import */ var _lib_im_api_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../lib/im-api.js */ "./src/lib/im-api.js"); /* harmony import */ var react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! react/jsx-dev-runtime */ "./node_modules/react/jsx-dev-runtime.js"); const AudioRecorder = react__WEBPACK_IMPORTED_MODULE_0___default().lazy(_ => Promise.all(/*! import() */[__webpack_require__.e("vendors-node_modules_webm-duration-fix_lib_index_js"), __webpack_require__.e("src_widgets_audio-recorder_jsx")]).then(__webpack_require__.bind(__webpack_require__, /*! ./audio-recorder.jsx */ "./src/widgets/audio-recorder.jsx"))); const EMOJI_LIST = ['😀', '😁', '😂', '🤣', '😃', '😄', '😅', '😆', '😉', '😊', '😋', '😎', '😍', '😘', '🥰', '😗', '😙', '😚', '🙂', '🤗', '🤩', '🤔', '🤨', '😐', '😑', '😶', '🙄', '😏', '😣', '😥', '😮', '🤐', '😯', '😪', '😫', '🥱', '😴', '😌', '😛', '😜', '😝', '🤤', '😒', '😓', '😔', '😕', '🙃', '🤑', '😲', '☹️', '🙁', '😖', '😞', '😟', '😤', '😢', '😭', '😦', '😧', '😨', '😩', '🤯', '😬', '😰', '😱', '🥵', '🥶', '😳', '🤪', '😵', '😡', '😠', '🤬', '😷', '🤒', '🤕', '🤢', '🤮', '🥳', '🥴', '🥺', '🤫', '🤭', '🧐', '🤓', '😈', '👿', '👍', '👎', '👏', '🙌', '🤝', '🙏', '💪', '❤️', '🧡', '💛', '💚', '💙', '💜', '🖤', '💔', '💕', '💯', '🔥', '🎉', '🎂', '🌹', '☀️', '🌙', '⭐']; const FAVORITE_TYPE_LABEL = { image: '[图片]', video: '[视频]', voice: '[语音]', file: '[文件]', link: '[链接]', text: '[文本]' }; function favoriteSummary(item) { if (item.type === 'image' || item.type === 'video' || item.type === 'voice') { return FAVORITE_TYPE_LABEL[item.type]; } const content = item.snapshot && item.snapshot.content; if (typeof content === 'string' && content.trim()) return content; if (content && typeof content.txt === 'string' && content.txt.trim()) return content.txt; return FAVORITE_TYPE_LABEL[item.type] || item.type || item.favorite_id; } const RECENT_EMOJI_KEY = 'im-recent-emoji'; const MAX_RECENT_EMOJI = 30; function loadRecentEmoji() { try { const raw = JSON.parse(localStorage.getItem(RECENT_EMOJI_KEY) || '[]'); return Array.isArray(raw) ? raw : []; } catch (_) { return []; } } function pushRecentEmoji(emoji) { try { const list = [emoji].concat(loadRecentEmoji().filter(e => e !== emoji)).slice(0, MAX_RECENT_EMOJI); localStorage.setItem(RECENT_EMOJI_KEY, JSON.stringify(list)); } catch (_) {} } const messages = (0,react_intl__WEBPACK_IMPORTED_MODULE_1__.defineMessages)({ messaging_disabled: { id: 'messaging_disabled_prompt', defaultMessage: 'Messaging disabled', description: 'Prompt in SendMessage in read-only topic' }, type_new_message: { id: 'new_message_prompt', defaultMessage: 'New message', description: 'Prompt in send message field' }, add_image_caption: { id: 'image_caption_prompt', defaultMessage: 'Image caption', description: 'Prompt in SendMessage for attached image' }, file_attachment_too_large: { id: 'file_attachment_too_large', defaultMessage: 'The file size {size} exceeds the {limit} limit.', description: 'Error message when attachment is too large' }, cannot_initiate_upload: { id: 'cannot_initiate_file_upload', defaultMessage: 'Cannot initiate file upload.', description: 'Generic error messagewhen attachment fails' }, icon_title_record_voice: { id: 'icon_title_record_voice', defaultMessage: 'Record voice message', description: 'Icon tool tip for recording a voice message' }, icon_title_attach_file: { id: 'icon_title_attach_file', defaultMessage: 'Attach file', description: 'Icon tool tip for attaching a file' }, icon_title_add_image: { id: 'icon_title_add_image', defaultMessage: 'Add image', description: 'Icon tool tip for attaching an image' }, icon_title_send: { id: 'icon_title_send', defaultMessage: 'Send message', description: 'Icon tool tip for sending a message' } }); class SendMessage extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComponent) { constructor(props) { super(props); this.state = { quote: null, message: '', audioRec: false, audioAvailable: !!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia), mentionQuery: null, mentionResults: [], mentionHighlight: 0, emojiOpen: false, emojiTab: 'emoji', recentEmoji: loadRecentEmoji(), attachOpen: false, cardPicker: null, favPicker: null, audioCancelling: false }; this.keypressTimestamp = 0; this.handlePasteEvent = this.handlePasteEvent.bind(this); this.handleAttachImage = this.handleAttachImage.bind(this); this.handleAttachFile = this.handleAttachFile.bind(this); this.handleAttachAudio = this.handleAttachAudio.bind(this); this.handleSend = this.handleSend.bind(this); this.handleKeyPress = this.handleKeyPress.bind(this); this.handleMessageTyping = this.handleMessageTyping.bind(this); this.handleDropAttach = this.handleDropAttach.bind(this); this.handleQuoteClick = this.handleQuoteClick.bind(this); this.selectMention = this.selectMention.bind(this); this.startHoldRecording = this.startHoldRecording.bind(this); this.handleHoldMove = this.handleHoldMove.bind(this); this.endHoldRecording = this.endHoldRecording.bind(this); this.handleHoldVisibilityChange = this.handleHoldVisibilityChange.bind(this); this.toggleEmojiPanel = this.toggleEmojiPanel.bind(this); this.insertEmoji = this.insertEmoji.bind(this); this.deleteLastChar = this.deleteLastChar.bind(this); this.toggleAttachPanel = this.toggleAttachPanel.bind(this); this.openCardPicker = this.openCardPicker.bind(this); this.openFavPicker = this.openFavPicker.bind(this); this.sendCard = this.sendCard.bind(this); this.sendFavorite = this.sendFavorite.bind(this); this.formatReply = this.formatReply.bind(this); } componentDidMount() { if (this.messageEditArea) { this.messageEditArea.addEventListener('paste', this.handlePasteEvent, false); if (window.getComputedStyle(this.messageEditArea).getPropertyValue('transition-property') == 'all') { this.messageEditArea.focus(); } } this.setState({ quote: this.formatReply() }); } componentWillUnmount() { if (this.messageEditArea) { this.messageEditArea.removeEventListener('paste', this.handlePasteEvent, false); } if (this.mentionSearchTimer) { window.clearTimeout(this.mentionSearchTimer); } window.removeEventListener('mousemove', this.handleHoldMove); window.removeEventListener('mouseup', this.endHoldRecording); window.removeEventListener('touchmove', this.handleHoldMove); window.removeEventListener('touchend', this.endHoldRecording); window.removeEventListener('blur', this.endHoldRecording); document.removeEventListener('visibilitychange', this.handleHoldVisibilityChange); } componentDidUpdate(prevProps) { if (this.messageEditArea) { if (window.getComputedStyle(this.messageEditArea).getPropertyValue('transition-property') == 'all') { this.messageEditArea.focus(); } this.messageEditArea.style.height = '0px'; this.messageEditArea.style.height = this.messageEditArea.scrollHeight + 'px'; } if (prevProps.topicName != this.props.topicName) { this.setState({ message: this.props.initMessage || '', audioRec: false, quote: null, mentionQuery: null, mentionResults: [], emojiOpen: false, attachOpen: false, cardPicker: null, favPicker: null }); } else if (!prevProps.disabled && this.props.disabled && this.state.audioRec) { this.endHoldRecording(); this.setState({ audioRec: false }); } else if (prevProps.initMessage != this.props.initMessage) { const msg = this.props.initMessage || ''; this.setState({ message: msg }, _ => { this.messageEditArea.scrollTop = this.messageEditArea.scrollHeight; this.messageEditArea.setSelectionRange(msg.length, msg.length); }); } if (prevProps.reply != this.props.reply) { this.setState({ quote: this.formatReply() }); } } formatReply() { return this.props.reply ? tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.format(this.props.reply.content, _lib_formatters_js__WEBPACK_IMPORTED_MODULE_5__.replyFormatter, { formatMessage: this.props.intl.formatMessage.bind(this.props.intl), authorizeURL: this.props.tinode.authorizeURL.bind(this.props.tinode) }) : null; } handlePasteEvent(e) { if (this.props.disabled) { return; } if ((0,_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_4__.filePasted)(e, file => { if (this.props.onAttachImage) { this.props.onAttachImage(file); } }, file => { if (this.props.onAttachFile) { this.props.onAttachFile(file); } }, this.props.onError)) { e.preventDefault(); } } handleAttachImage(e) { if (e.target.files && e.target.files.length > 0 && this.props.onAttachImage) { this.props.onAttachImage(e.target.files[0]); } e.target.value = ''; } handleAttachFile(e) { if (e.target.files && e.target.files.length > 0 && this.props.onAttachFile) { this.props.onAttachFile(e.target.files[0]); } e.target.value = ''; } handleDropAttach(files) { if (files && files.length > 0 && this.props.onAttachFile) { this.props.onAttachFile(files[0]); } } handleAttachAudio(url, preview, duration) { this.setState({ audioRec: false }); if (this.props.onAttachAudio) { this.props.onAttachAudio(url, preview, duration); } } handleSend(e) { e.preventDefault(); const message = this.state.message.trim(); if (message || this.props.acceptBlank || this.props.noInput) { const result = this.props.onSendMessage(message); if (result && typeof result.then == 'function') { result.then(sent => { if (sent !== false) this.setState({ message: '' }); }); } else { this.setState({ message: '' }); } } } handleKeyPress(e) { if (this.state.audioRec) { e.preventDefault(); e.stopPropagation(); return; } if (this.state.mentionQuery != null) { if (e.key === 'Escape') { e.preventDefault(); this.setState({ mentionQuery: null, mentionResults: [] }); return; } if (this.state.mentionResults.length > 0 && (e.key === 'ArrowDown' || e.key === 'ArrowUp')) { e.preventDefault(); const delta = e.key === 'ArrowDown' ? 1 : -1; const count = this.state.mentionResults.length; this.setState({ mentionHighlight: (this.state.mentionHighlight + delta + count) % count }); return; } if (e.key === 'Enter' && this.state.mentionResults.length > 0) { e.preventDefault(); e.stopPropagation(); this.selectMention(this.state.mentionResults[this.state.mentionHighlight]); return; } } if (e.key === 'Enter') { if (this.props.sendOnEnter == 'plain') { if (!e.shiftKey) { e.preventDefault(); e.stopPropagation(); this.handleSend(e); } } else { if (e.ctrlKey || e.metaKey) { e.preventDefault(); e.stopPropagation(); this.handleSend(e); } } } } handleMessageTyping(e) { this.setState({ message: e.target.value }); this.updateMentionState(e.target.value, e.target.selectionStart); if (this.props.onMessageChange) { this.props.onMessageChange(e.target.value); } if (this.props.onKeyPress) { const now = new Date().getTime(); if (now - this.keypressTimestamp > _config_js__WEBPACK_IMPORTED_MODULE_3__.KEYPRESS_DELAY) { this.props.onKeyPress(); this.keypressTimestamp = now; } } } updateMentionState(text, caret) { if (!this.props.onMentionSearch || caret == null) { return; } const before = text.slice(0, caret); const match = /(?:^|\s)@([^\s@]*)$/.exec(before); if (!match) { if (this.state.mentionQuery != null) { this.setState({ mentionQuery: null, mentionResults: [] }); } return; } const query = match[1]; const start = caret - query.length - 1; this.setState({ mentionQuery: query, mentionStart: start, mentionHighlight: 0 }); if (this.mentionSearchTimer) { window.clearTimeout(this.mentionSearchTimer); } this.mentionSearchTimer = window.setTimeout(() => { this.props.onMentionSearch(query).then(results => { if (this.state.mentionQuery != null) { this.setState({ mentionResults: results || [] }); } }).catch(() => {}); }, 200); } selectMention(item) { const { message, mentionStart, mentionQuery } = this.state; if (mentionStart == null || mentionQuery == null) { return; } const name = item.group_nickname || item.display_name || item.user_id; const insertion = '@' + name + ' '; const end = mentionStart + 1 + mentionQuery.length; const newMessage = message.slice(0, mentionStart) + insertion + message.slice(end); const caretPos = mentionStart + insertion.length; this.setState({ message: newMessage, mentionQuery: null, mentionResults: [] }); if (this.props.onMentionSelected) { this.props.onMentionSelected(item.user_id, name); } if (this.props.onMessageChange) { this.props.onMessageChange(newMessage); } requestAnimationFrame(() => { if (this.messageEditArea) { this.messageEditArea.focus(); this.messageEditArea.setSelectionRange(caretPos, caretPos); } }); } handleQuoteClick(e) { e.preventDefault(); e.stopPropagation(); if (this.props.reply && this.props.onQuoteClick) { const replyToSeq = this.props.reply.seq; this.props.onQuoteClick(replyToSeq); } } toggleEmojiPanel(e) { e.preventDefault(); this.setState(s => ({ emojiOpen: !s.emojiOpen, attachOpen: false, audioRec: false })); } insertEmoji(emoji) { const ta = this.messageEditArea; const start = ta ? ta.selectionStart : this.state.message.length; const end = ta ? ta.selectionEnd : this.state.message.length; const newMessage = this.state.message.slice(0, start) + emoji + this.state.message.slice(end); pushRecentEmoji(emoji); this.setState({ message: newMessage, recentEmoji: loadRecentEmoji() }); if (this.props.onMessageChange) { this.props.onMessageChange(newMessage); } const caretPosEmoji = start + emoji.length; requestAnimationFrame(() => { if (this.messageEditArea) { this.messageEditArea.focus(); this.messageEditArea.setSelectionRange(caretPosEmoji, caretPosEmoji); } }); } deleteLastChar() { const ta = this.messageEditArea; const start = ta ? ta.selectionStart : this.state.message.length; const end = ta ? ta.selectionEnd : this.state.message.length; let newMessage, caretPos; if (start !== end) { newMessage = this.state.message.slice(0, start) + this.state.message.slice(end); caretPos = start; } else if (start > 0) { const before = Array.from(this.state.message.slice(0, start)); before.pop(); newMessage = before.join('') + this.state.message.slice(start); caretPos = before.join('').length; } else { return; } this.setState({ message: newMessage }); if (this.props.onMessageChange) { this.props.onMessageChange(newMessage); } requestAnimationFrame(() => { if (this.messageEditArea) { this.messageEditArea.focus(); this.messageEditArea.setSelectionRange(caretPos, caretPos); } }); } toggleAttachPanel(e) { e.preventDefault(); this.setState(s => ({ attachOpen: !s.attachOpen, emojiOpen: false })); } openCardPicker(e) { e.preventDefault(); this.setState({ attachOpen: false, cardPicker: { loading: true } }); (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_6__.getFriends)().then(data => { this.setState({ cardPicker: { loading: false, items: data.items || [] } }); }).catch(() => this.setState({ cardPicker: { loading: false, items: [], error: true } })); } sendCard(item) { this.setState({ cardPicker: null }); const build = avatarUrl => { const card = new tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.TheCard(item.display_name || item.user_id, avatarUrl); tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.TheCard.setTinodeID(card, item.user_id); this.props.onSendMessage(tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.appendTheCard(null, card), undefined, undefined, 'card'); }; if (item.avatar_file_id) { (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_6__.getFileUrl)(item.avatar_file_id).then(build).catch(() => build(undefined)); } else { build(undefined); } } openFavPicker(e) { e.preventDefault(); this.setState({ attachOpen: false, favPicker: { loading: true } }); (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_6__.getFavorites)({ type: 'all' }).then(data => { this.setState({ favPicker: { loading: false, items: data.items || [] } }); }).catch(() => this.setState({ favPicker: { loading: false, items: [], error: true } })); } sendFavorite(item) { this.setState({ favPicker: null }); if (!this.props.topicName) { return; } (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_6__.forwardFavorites)([item.favorite_id], [this.props.topicName]).then(result => { const failed = (result && result.items || []).filter(r => r.status === 'failed'); if (failed.length && this.props.onError) { this.props.onError('发送失败:' + ((0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_6__.translateReason)(failed[0].reason) || failed[0].reason || '未知原因'), 'err'); } }).catch(err => { if (this.props.onError) { this.props.onError(err && err.message || '发送失败', 'err'); } }); } startHoldRecording(e) { e.preventDefault(); if (this.state.audioRec) { return; } this.holdStartY = 'touches' in e ? e.touches[0] && e.touches[0].clientY : e.clientY; this.setState({ audioRec: true, audioCancelling: false, emojiOpen: false, attachOpen: false }); window.addEventListener('mousemove', this.handleHoldMove); window.addEventListener('mouseup', this.endHoldRecording); window.addEventListener('touchmove', this.handleHoldMove, { passive: false }); window.addEventListener('touchend', this.endHoldRecording); window.addEventListener('blur', this.endHoldRecording); document.addEventListener('visibilitychange', this.handleHoldVisibilityChange); } handleHoldVisibilityChange() { if (document.hidden) { this.endHoldRecording(); } } handleHoldMove(e) { const y = 'touches' in e ? e.touches[0] && e.touches[0].clientY : e.clientY; if (y == null || this.holdStartY == null) { return; } const cancelling = this.holdStartY - y > 80; if (cancelling !== this.state.audioCancelling) { this.setState({ audioCancelling: cancelling }); } } endHoldRecording() { window.removeEventListener('mousemove', this.handleHoldMove); window.removeEventListener('mouseup', this.endHoldRecording); window.removeEventListener('touchmove', this.handleHoldMove); window.removeEventListener('touchend', this.endHoldRecording); window.removeEventListener('blur', this.endHoldRecording); document.removeEventListener('visibilitychange', this.handleHoldVisibilityChange); this.holdStartY = null; const fakeEvent = { preventDefault: () => {} }; if (this.audioRecorderInstance) { if (this.state.audioCancelling) { this.audioRecorderInstance.handleDelete(fakeEvent); } else { this.audioRecorderInstance.handleDone(fakeEvent); } } } render() { const { formatMessage } = this.props.intl; const prompt = this.props.disabled ? formatMessage(messages.messaging_disabled) : this.props.messagePrompt ? formatMessage(messages[this.props.messagePrompt]) : formatMessage(messages.type_new_message); const sendIcon = this.props.reply && this.props.reply.editing ? 'check_circle' : 'send'; const quote = this.state.quote ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("div", { id: "reply-quote-preview", children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("div", { className: "cancel", children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("a", { href: "#", onClick: e => { e.preventDefault(); this.props.onCancelReply(); }, children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("i", { className: "material-icons gray", children: "close" }, void 0, false) }, void 0, false) }, void 0, false), this.state.quote] }, void 0, true) : null; const audioEnabled = this.state.audioAvailable && this.props.onAttachAudio; const mentionPanel = this.state.mentionQuery != null ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("div", { id: "mention-picker", children: this.state.mentionResults.length === 0 ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("div", { className: "mention-picker-empty", children: "无匹配成员" }, void 0, false) : this.state.mentionResults.map((item, i) => (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("div", { className: 'mention-picker-row' + (i === this.state.mentionHighlight ? ' active' : ''), onMouseDown: e => { e.preventDefault(); this.selectMention(item); }, onMouseEnter: () => this.setState({ mentionHighlight: i }), children: item.group_nickname || item.display_name || item.user_id }, item.user_id, false)) }, void 0, false) : null; return (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("div", { id: "send-message-wrapper", children: [!this.props.noInput ? quote : null, mentionPanel, (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("div", { id: "send-message-panel", children: !this.props.disabled ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)(react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.Fragment, { children: [this.props.noInput ? quote || (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("div", { className: "hr thin" }, void 0, false) : this.state.audioRec ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)(react__WEBPACK_IMPORTED_MODULE_0__.Suspense, { fallback: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("div", { children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, { id: "loading_note", defaultMessage: "Loading...", description: "Message shown when component is loading" }, void 0, false) }, void 0, false), children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)(AudioRecorder, { ref: ref => { this.audioRecorderInstance = ref; }, holdMode: true, cancelling: this.state.audioCancelling, onRecordingProgress: _ => this.props.onKeyPress(true), onDeleted: _ => this.setState({ audioRec: false }), onFinished: this.handleAttachAudio }, void 0, false) }, void 0, false) : (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("textarea", { id: "send-message-input", placeholder: prompt, value: this.state.message, onChange: this.handleMessageTyping, onKeyDown: this.handleKeyPress, ref: ref => { this.messageEditArea = ref; } }, void 0, false), !this.props.noInput && !this.state.audioRec ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("a", { href: "#", onClick: this.toggleEmojiPanel, title: "表情", children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("i", { className: "material-icons secondary", children: this.state.emojiOpen ? 'keyboard' : 'insert_emoticon' }, void 0, false) }, void 0, false) : null, this.props.onAttachFile && !this.state.audioRec ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("a", { href: "#", onClick: this.toggleAttachPanel, title: formatMessage(messages.icon_title_attach_file), children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("i", { className: "material-icons secondary", children: this.state.attachOpen ? 'keyboard' : 'add_circle_outline' }, void 0, false) }, void 0, false) : null, this.state.message || !audioEnabled ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("a", { href: "#", onClick: this.handleSend, title: formatMessage(messages.icon_title_send), children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("i", { className: "material-icons", children: sendIcon }, void 0, false) }, void 0, false) : !this.state.audioRec ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("a", { href: "#", onMouseDown: this.startHoldRecording, onTouchStart: this.startHoldRecording, onClick: e => e.preventDefault(), title: formatMessage(messages.icon_title_record_voice), children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("i", { className: "material-icons", children: "mic" }, void 0, false) }, void 0, false) : null, (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("input", { type: "file", ref: ref => { this.attachFile = ref; }, onChange: this.handleAttachFile, style: { display: 'none' } }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("input", { type: "file", ref: ref => { this.attachImage = ref; }, accept: "image/*, video/*", onChange: this.handleAttachImage, style: { display: 'none' } }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("input", { type: "file", ref: ref => { this.attachCamera = ref; }, accept: "image/*", capture: "environment", onChange: this.handleAttachImage, style: { display: 'none' } }, void 0, false)] }, void 0, true) : (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("div", { id: "writing-disabled", children: prompt }, void 0, false) }, void 0, false), this.state.emojiOpen ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("div", { id: "emoji-panel", children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("div", { id: "emoji-panel-tabs", children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("a", { href: "#", className: this.state.emojiTab === 'emoji' ? 'active' : '', onClick: e => { e.preventDefault(); this.setState({ emojiTab: 'emoji' }); }, children: "😊" }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("a", { href: "#", className: this.state.emojiTab === 'recent' ? 'active' : '', onClick: e => { e.preventDefault(); this.setState({ emojiTab: 'recent' }); }, children: "♡" }, void 0, false)] }, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("div", { id: "emoji-panel-grid", children: (this.state.emojiTab === 'emoji' ? EMOJI_LIST : this.state.recentEmoji).length === 0 ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("div", { className: "emoji-panel-empty", children: "还没有常用表情" }, void 0, false) : (this.state.emojiTab === 'emoji' ? EMOJI_LIST : this.state.recentEmoji).map((emoji, i) => (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("a", { href: "#", onClick: e => { e.preventDefault(); this.insertEmoji(emoji); }, children: emoji }, emoji + i, false)) }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("div", { id: "emoji-panel-footer", children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("a", { href: "#", onClick: e => { e.preventDefault(); this.deleteLastChar(); }, title: "删除", children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("i", { className: "material-icons", children: "backspace" }, void 0, false) }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("a", { href: "#", className: 'emoji-panel-send' + (this.state.message ? ' active' : ''), onClick: e => { e.preventDefault(); this.handleSend(e); }, title: formatMessage(messages.icon_title_send), children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("i", { className: "material-icons", children: sendIcon }, void 0, false) }, void 0, false)] }, void 0, true)] }, void 0, true) : null, this.state.attachOpen ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("div", { id: "attach-panel", children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("a", { href: "#", onClick: e => { e.preventDefault(); this.setState({ attachOpen: false }); this.attachImage.click(); }, children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("i", { className: "material-icons", children: "photo" }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("span", { children: "照片" }, void 0, false)] }, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("a", { href: "#", onClick: e => { e.preventDefault(); this.setState({ attachOpen: false }); this.attachCamera.click(); }, children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("i", { className: "material-icons", children: "photo_camera" }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("span", { children: "拍摄" }, void 0, false)] }, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("a", { href: "#", className: this.props.canStartCall ? '' : 'disabled', onClick: e => { e.preventDefault(); this.setState({ attachOpen: false }); if (this.props.canStartCall && this.props.onStartAudioCall) this.props.onStartAudioCall(); }, children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("i", { className: "material-icons", children: "call" }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("span", { children: "语音通话" }, void 0, false)] }, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("a", { href: "#", onClick: this.openCardPicker, children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("i", { className: "material-icons", children: "badge" }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("span", { children: "名片" }, void 0, false)] }, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("a", { href: "#", onClick: e => { e.preventDefault(); this.setState({ attachOpen: false }); this.attachFile.click(); }, children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("i", { className: "material-icons", children: "attach_file" }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("span", { children: "文件" }, void 0, false)] }, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("a", { href: "#", onClick: this.openFavPicker, children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("i", { className: "material-icons", children: "star_border" }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("span", { children: "收藏" }, void 0, false)] }, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("a", { href: "#", className: this.props.canStartCall ? '' : 'disabled', onClick: e => { e.preventDefault(); this.setState({ attachOpen: false }); if (this.props.canStartCall && this.props.onStartVideoCall) this.props.onStartVideoCall(); }, children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("i", { className: "material-icons", children: "videocam" }, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("span", { children: "视频通话" }, void 0, false)] }, void 0, true)] }, void 0, true) : null, this.state.cardPicker ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("div", { className: "send-message-picker-backdrop", onClick: () => this.setState({ cardPicker: null }), children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("section", { onClick: e => e.stopPropagation(), children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("header", { children: ["选择联系人", (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("a", { href: "#", onClick: e => { e.preventDefault(); this.setState({ cardPicker: null }); }, children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("i", { className: "material-icons", children: "close" }, void 0, false) }, void 0, false)] }, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("div", { className: "send-message-picker-list", children: this.state.cardPicker.loading ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("p", { className: "send-message-picker-empty", children: "加载中…" }, void 0, false) : this.state.cardPicker.items.length === 0 ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("p", { className: "send-message-picker-empty", children: this.state.cardPicker.error ? '加载失败' : '暂无好友' }, void 0, false) : this.state.cardPicker.items.map(item => (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("a", { href: "#", onClick: e => { e.preventDefault(); this.sendCard(item); }, children: item.display_name || item.user_id }, item.user_id, false)) }, void 0, false)] }, void 0, true) }, void 0, false) : null, this.state.favPicker ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("div", { className: "send-message-picker-backdrop", onClick: () => this.setState({ favPicker: null }), children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("section", { onClick: e => e.stopPropagation(), children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("header", { children: ["我的收藏", (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("a", { href: "#", onClick: e => { e.preventDefault(); this.setState({ favPicker: null }); }, children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("i", { className: "material-icons", children: "close" }, void 0, false) }, void 0, false)] }, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("div", { className: "send-message-picker-list", children: this.state.favPicker.loading ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("p", { className: "send-message-picker-empty", children: "加载中…" }, void 0, false) : this.state.favPicker.items.length === 0 ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("p", { className: "send-message-picker-empty", children: this.state.favPicker.error ? '加载失败' : '暂无收藏' }, void 0, false) : this.state.favPicker.items.map(item => (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("a", { href: "#", onClick: e => { e.preventDefault(); this.sendFavorite(item); }, children: favoriteSummary(item) }, item.favorite_id, false)) }, void 0, false)] }, void 0, true) }, void 0, false) : null] }, void 0, true); } } ; /* harmony default export */ __webpack_exports__["default"] = ((0,react_intl__WEBPACK_IMPORTED_MODULE_1__.injectIntl)(SendMessage)); /***/ }) }]); //# sourceMappingURL=src_views_messages-view_jsx.dev.js.map