UNPKG

@sendbird/uikit-react-native

Version:

Sendbird UIKit for React Native: A feature-rich and customizable chat UI kit with messaging, channel management, and user authentication.

209 lines (205 loc) 8.95 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = _interopRequireWildcard(require("react")); var _reactNative = require("react-native"); var _uikitReactNativeFoundation = require("@sendbird/uikit-react-native-foundation"); var _uikitUtils = require("@sendbird/uikit-utils"); var _useContext = require("../../hooks/useContext"); var _useMentionTextInput = _interopRequireDefault(require("../../hooks/useMentionTextInput")); var _AttachmentsButton = _interopRequireDefault(require("./AttachmentsButton")); var _EditInput = _interopRequireDefault(require("./EditInput")); var _MessageToReplyPreview = require("./MessageToReplyPreview"); var _SendInput = _interopRequireDefault(require("./SendInput")); var _VoiceMessageInput = _interopRequireDefault(require("./VoiceMessageInput")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } const AUTO_FOCUS = _reactNative.Platform.select({ ios: false, android: true, default: false }); const KEYBOARD_AVOID_VIEW_BEHAVIOR = _reactNative.Platform.select({ ios: 'padding', default: undefined }); // FIXME(iOS): Dynamic style does not work properly when typing the CJK. (https://github.com/facebook/react-native/issues/26107) // To workaround temporarily, change the key for re-mount the component. // -> This will affect to keyboard blur when add/remove first mentioned user. // const GET_INPUT_KEY = (shouldReset: boolean) => { // return Platform.OS === 'ios' && shouldReset ? 'uikit-input-clear' : 'uikit-input'; // }; // TODO: Refactor 'Edit' mode to clearly const ChannelInput = props => { const { channel, keyboardAvoidOffset, messageToEdit, setMessageToEdit } = props; const safeArea = (0, _uikitUtils.useSafeAreaPadding)(['top', 'left', 'right', 'bottom']); const { colors, typography } = (0, _uikitReactNativeFoundation.useUIKitTheme)(); const { sbOptions, mentionManager } = (0, _useContext.useSendbirdChat)(); const { selection, onSelectionChange, textInputRef, text, onChangeText, mentionedUsers } = (0, _useMentionTextInput.default)({ messageToEdit }); const inputMode = (0, _uikitUtils.useIIFE)(() => { if (messageToEdit && !messageToEdit.isFileMessage()) return 'edit';else return 'send'; }); const mentionAvailable = sbOptions.uikit.groupChannel.channel.enableMention && channel.isGroupChannel() && !channel.isBroadcast; const inputKeyToRemount = 'input'; //GET_INPUT_KEY(mentionAvailable ? mentionedUsers.length === 0 : false); const [inputHeight, setInputHeight] = (0, _react.useState)(styles.inputDefault.height); const fontStyle = (0, _react.useMemo)(() => { if (!typography.body3.fontSize) return typography.body3; // NOTE: iOS does not support textAlignVertical, so we should adjust lineHeight to center the text in multiline TextInput. return { ...typography.body3, lineHeight: typography.body3.fontSize * 1.275, textAlignVertical: 'center' }; }, [typography.body3.fontSize]); const textInputStyle = _reactNative.StyleSheet.flatten([styles.input, fontStyle, props.style]); useTypingTrigger(text, channel); useTextClearOnDisabled(onChangeText, props.inputDisabled); useAutoFocusOnEditMode(textInputRef, messageToEdit); const onPressToMention = (user, searchStringRange) => { const mentionedMessageText = mentionManager.asMentionedMessageText(user, true); const range = { start: searchStringRange.start, end: searchStringRange.start + mentionedMessageText.length - 1 }; onChangeText((0, _uikitUtils.replace)(text, searchStringRange.start, searchStringRange.end, mentionedMessageText), { user, range }); }; if (!props.shouldRenderInput) { return /*#__PURE__*/_react.default.createElement(SafeAreaBottom, { height: safeArea.paddingBottom }); } return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_reactNative.KeyboardAvoidingView, { keyboardVerticalOffset: -safeArea.paddingBottom + keyboardAvoidOffset, behavior: KEYBOARD_AVOID_VIEW_BEHAVIOR }, /*#__PURE__*/_react.default.createElement(_reactNative.View, { style: { paddingStart: safeArea.paddingStart, paddingEnd: safeArea.paddingEnd, backgroundColor: colors.background } }, /*#__PURE__*/_react.default.createElement(_reactNative.View, { onLayout: e => setInputHeight(e.nativeEvent.layout.height), style: styles.inputContainer }, inputMode === 'send' && /*#__PURE__*/_react.default.createElement(_SendInput.default, _extends({}, props, { key: inputKeyToRemount, ref: textInputRef, text: text, onChangeText: onChangeText, onSelectionChange: onSelectionChange, mentionedUsers: mentionedUsers, VoiceMessageInput: props.VoiceMessageInput ?? _VoiceMessageInput.default, AttachmentsButton: props.AttachmentsButton ?? _AttachmentsButton.default, MessageToReplyPreview: props.MessageToReplyPreview ?? _MessageToReplyPreview.MessageToReplyPreview, style: textInputStyle })), inputMode === 'edit' && messageToEdit && /*#__PURE__*/_react.default.createElement(_EditInput.default, _extends({}, props, { key: inputKeyToRemount, ref: textInputRef, text: text, onChangeText: onChangeText, autoFocus: AUTO_FOCUS, onSelectionChange: onSelectionChange, mentionedUsers: mentionedUsers, messageToEdit: messageToEdit, setMessageToEdit: setMessageToEdit, style: textInputStyle }))), /*#__PURE__*/_react.default.createElement(SafeAreaBottom, { height: safeArea.paddingBottom }))), mentionAvailable && props.SuggestedMentionList && /*#__PURE__*/_react.default.createElement(props.SuggestedMentionList, { text: text, selection: selection, inputHeight: inputHeight, topInset: safeArea.paddingTop, bottomInset: safeArea.paddingBottom, onPressToMention: onPressToMention, mentionedUsers: mentionedUsers })); }; const useTypingTrigger = (text, channel) => { (0, _react.useEffect)(() => { function triggerTyping() { if (channel.isGroupChannel()) { const action = () => text.length === 0 ? channel.endTyping() : channel.startTyping(); action().catch(error => { _uikitUtils.Logger.debug('ChannelInput: Failed to trigger typing', error); }); } } triggerTyping(); }, channel.isGroupChannel() ? [text] : []); }; const useTextClearOnDisabled = (setText, chatDisabled) => { (0, _react.useEffect)(() => { if (chatDisabled) setText(''); }, [chatDisabled]); }; const useAutoFocusOnEditMode = (textInputRef, messageToEdit) => { (0, _react.useEffect)(() => { if (messageToEdit !== null && messageToEdit !== void 0 && messageToEdit.isUserMessage()) { if (!AUTO_FOCUS) setTimeout(() => { var _textInputRef$current; return (_textInputRef$current = textInputRef.current) === null || _textInputRef$current === void 0 ? void 0 : _textInputRef$current.focus(); }, 500); } }, [messageToEdit]); }; const SafeAreaBottom = ({ height }) => { return /*#__PURE__*/_react.default.createElement(_reactNative.View, { style: { height } }); }; const styles = (0, _uikitReactNativeFoundation.createStyleSheet)({ inputContainer: { justifyContent: 'center', width: '100%' }, inputDefault: { height: 56 }, input: { flex: 1, marginEnd: 4, borderRadius: 20, paddingTop: 8, paddingBottom: 8, minHeight: 36, // Android - padding area is hidden // iOS - padding area is visible maxHeight: _reactNative.Platform.select({ ios: 36 * 2 + 16, android: 36 * 2 }) } }); var _default = exports.default = /*#__PURE__*/_react.default.memo(ChannelInput); //# sourceMappingURL=index.js.map