UNPKG

maisonsport-common-ui

Version:

Suite of styled-components to be consumed by the React-Native App and by the Web (via React-Native for Web)

347 lines (305 loc) 13.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = _interopRequireWildcard(require("react")); var _reactNative = require("react-native"); var _propTypes = _interopRequireDefault(require("prop-types")); var _native = _interopRequireWildcard(require("styled-components/native")); var _styledSystem = require("styled-system"); var _composeReactRefs = _interopRequireDefault(require("@seznam/compose-react-refs")); var _theme = _interopRequireDefault(require("../../theme")); var _Box = _interopRequireDefault(require("../../atoms/Box")); var _Text = _interopRequireDefault(require("../../atoms/Text")); var _Touchable = _interopRequireDefault(require("../../atoms/Touchable")); var _TextInput = _interopRequireDefault(require("../../molecules/TextInput")); var _MessageBubble = _interopRequireDefault(require("../../molecules/MessageBubble")); var _MessageSendButton = _interopRequireDefault(require("../../molecules/MessageSendButton")); var _dateTime = require("../../util/dateTime"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function _templateObject() { const data = _taggedTemplateLiteral(["\n ", "\n ", "\n ", "\n"]); _templateObject = function () { return data; }; return data; } function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } const isIOS = _reactNative.Platform.OS === 'ios'; const StyledFlatList = _native.default.FlatList(_templateObject(), _styledSystem.layout, _styledSystem.space, _styledSystem.flexbox); StyledFlatList.defaultProps = { position: 'absolute' }; const MessageThread = /*#__PURE__*/(0, _react.forwardRef)(({ messages = [], userID, recipientID, inputPlaceholder, inputValue, inputBusy, inputHeight, inputBottomOffset, unreadMessageIndicatorText, onInputSubmit, onInputChangeText, onMessagePress, onMessageLongPress, renderItem, t, ListHeaderComponent = null, ...props }, ref) => { const [inputHeightState, setInputHeightState] = (0, _react.useState)(inputHeight); const [keyboardHeight, setKeyboardHeight] = (0, _react.useState)(0); const [keyboardOpen, setKeyboardOpen] = (0, _react.useState)(false); const [showUnreadMarker, setShowUnreadMarker] = (0, _react.useState)(true); const threadRef = (0, _react.useRef)(); const threadTrueHeight = (0, _react.useRef)(0); const scrollPosition = (0, _react.useRef)(); const previousMessagesLength = (0, _react.useRef)(messages.length); const androidExtraInputPaddingBottom = isIOS ? 0 : _theme.default.space[3]; const finalTextInputContainerHeight = inputHeightState + _theme.default.space[3] + androidExtraInputPaddingBottom + (showUnreadMarker ? _theme.default.space[2] * 4 : 0) + inputBottomOffset; const conversationThreadBottom = finalTextInputContainerHeight + keyboardHeight; function keyboardDidShow(event) { var _event$endCoordinates; const keyboardHeightAfterShow = isIOS ? (event === null || event === void 0 ? void 0 : (_event$endCoordinates = event.endCoordinates) === null || _event$endCoordinates === void 0 ? void 0 : _event$endCoordinates.height) || 0 : 0; if (isIOS) setKeyboardOpen(true); setKeyboardHeight(keyboardHeightAfterShow); } function keyboardDidHide() { setKeyboardOpen(false); setKeyboardHeight(0); } function handleSubmit() { if (!!inputValue !== false) { onInputSubmit(); } } function scrollToBottom() { // eslint-disable-next-line no-undef setTimeout(() => { var _threadRef$current; if (threadRef === null || threadRef === void 0 ? void 0 : (_threadRef$current = threadRef.current) === null || _threadRef$current === void 0 ? void 0 : _threadRef$current.scrollToEnd) { threadRef.current.scrollToEnd(); setShowUnreadMarker(false); } }, 500); } function renderMessage(item) { const { content, createdAt, from } = item; const position = {}; if ((from === null || from === void 0 ? void 0 : from.id) === userID) position.right = true; if ((from === null || from === void 0 ? void 0 : from.id) === recipientID) position.left = true; const formattedCreatedAt = (0, _dateTime.getFormattedTimeSent)(createdAt, t, true); return /*#__PURE__*/_react.default.createElement(_MessageBubble.default, _extends({}, position, { timeSent: formattedCreatedAt, onPress: () => onMessagePress({ ...item, userID, recipientID }), onLongPress: () => onMessageLongPress({ ...item, userID, recipientID }) }), (from === null || from === void 0 ? void 0 : from.id) ? content : "".concat(content, " \n ").concat(formattedCreatedAt)); } (0, _react.useEffect)(() => { _reactNative.Keyboard.addListener('keyboardDidShow', keyboardDidShow); _reactNative.Keyboard.addListener('keyboardDidHide', keyboardDidHide); return () => { _reactNative.Keyboard.removeListener('keyboardDidShow', keyboardDidShow); _reactNative.Keyboard.removeListener('keyboardDidHide', keyboardDidHide); }; }, []); (0, _react.useEffect)(() => { const { current: prevLength } = previousMessagesLength; const { current: lastKnownScrollPosition } = scrollPosition; const { current: threadContentHeight } = threadTrueHeight; if (prevLength < messages.length) { previousMessagesLength.current = messages.length; if (lastKnownScrollPosition < threadContentHeight - 800) { setShowUnreadMarker(true); } else { scrollToBottom(); } } }, [messages]); (0, _react.useEffect)(() => { scrollToBottom(); }, []); return /*#__PURE__*/_react.default.createElement(_native.ThemeProvider, { theme: _theme.default }, /*#__PURE__*/_react.default.createElement(_Box.default, { height: 1, position: "relative" }, /*#__PURE__*/_react.default.createElement(StyledFlatList, _extends({ ref: (0, _composeReactRefs.default)(ref, threadRef), top: 0, bottom: conversationThreadBottom, left: 0, right: 0, backgroundColor: _theme.default.colors.background, data: messages, stickyHeaderIndices: !keyboardOpen && ListHeaderComponent ? [0] : props.stickyHeaderIndices || [], scrollEventThrottle: 200, keyExtractor: item => item.id, ListHeaderComponent: keyboardOpen ? null : ListHeaderComponent || null, renderItem: ({ item }) => { if (item.renderCustom) { return item.renderCustom({ item, userID, recipientID }); } if (renderItem) { return renderItem({ item }); } return renderMessage(item); }, onScroll: event => { threadTrueHeight.current = event.nativeEvent.contentSize.height; scrollPosition.current = event.nativeEvent.contentOffset.y; } }, props)), /*#__PURE__*/_react.default.createElement(_Box.default, { height: finalTextInputContainerHeight, position: "absolute", alignItems: "flex-end", justifyContent: "flex-end", bottom: keyboardHeight + androidExtraInputPaddingBottom, left: 0, right: 0 }, showUnreadMarker && /*#__PURE__*/_react.default.createElement(_Touchable.default, { padding: 2, borderRadius: 20, borderWidth: 0.5, borderColor: "primary", marginBottom: 2, flexDirection: "row", alignSelf: "center", alignItems: "center", justifyContent: "space-around", backgroundColor: "background", onPress: scrollToBottom }, /*#__PURE__*/_react.default.createElement(_Text.default, { color: "primary", fontSize: 0, fontWeight: "bold", padding: 0, marginRight: 2 }, unreadMessageIndicatorText), /*#__PURE__*/_react.default.createElement(_reactNative.Image, { source: require('../../assets/images/chevron.png'), style: { tintColor: _theme.default.colors.primary, width: 10, height: 10, transform: [{ rotate: '90deg' }] } })), /*#__PURE__*/_react.default.createElement(_Box.default, { flexDirection: "row", justifyContent: "space-between", alignItems: "flex-end", paddingLeft: 3, marginBottom: inputBottomOffset }, /*#__PURE__*/_react.default.createElement(_Box.default, { flexGrow: 1 }, /*#__PURE__*/_react.default.createElement(_TextInput.default, { placeholder: inputPlaceholder, returnKeyType: "send", value: inputValue, onChangeText: onInputChangeText, onContentSizeChange: event => { var _event$nativeEvent, _event$nativeEvent$co; const heightAfterChange = inputHeight + ((event === null || event === void 0 ? void 0 : (_event$nativeEvent = event.nativeEvent) === null || _event$nativeEvent === void 0 ? void 0 : (_event$nativeEvent$co = _event$nativeEvent.contentSize) === null || _event$nativeEvent$co === void 0 ? void 0 : _event$nativeEvent$co.height) || 0); if (heightAfterChange >= _theme.default.sizes.textInputHeight_raw * 5) return; setInputHeightState(heightAfterChange); }, fontSize: 1, multiline: true, numberOfLines: 25, height: inputHeightState, maxHeight: _theme.default.sizes.textInputHeight_raw * 5, marginRight: 3, width: 1, iconRight: null, backgroundColor: _theme.default.colors.convoPink, style: { backgroundColor: _theme.default.colors.convoPink, textAlignVertical: 'bottom' } })), /*#__PURE__*/_react.default.createElement(_Box.default, { height: inputHeight, alignItems: "center", justifyContent: "center" }, /*#__PURE__*/_react.default.createElement(_MessageSendButton.default, { alignSelf: "center", onPress: handleSubmit, disabled: !!inputValue === false, busy: inputBusy })))))); }); MessageThread.defaultProps = { inputValue: '', inputBusy: false, inputHeight: _theme.default.sizes.textInputHeight_raw, inputBottomOffset: 0, refreshing: false, messages: [], unreadMessageIndicatorText: 'New messages', onMessagePress: () => {}, onMessageLongPress: () => {}, onRefresh: () => {}, t: key => key }; MessageThread.propTypes = { inputPlaceholder: _propTypes.default.string.isRequired, inputValue: _propTypes.default.string, inputBusy: _propTypes.default.bool, inputHeight: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]), inputBottomOffset: _propTypes.default.number, refreshing: _propTypes.default.bool, onInputChangeText: _propTypes.default.func.isRequired, onInputSubmit: _propTypes.default.func.isRequired, onMessagePress: _propTypes.default.func, onMessageLongPress: _propTypes.default.func, onRefresh: _propTypes.default.func, messages: _propTypes.default.arrayOf(_propTypes.default.shape({ id: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]).isRequired, from: _propTypes.default.shape({ __typename: _propTypes.default.string, id: _propTypes.default.string.isRequired, displayName: _propTypes.default.string.isRequired }), content: _propTypes.default.string.isRequired, createdAt: _propTypes.default.string.isRequired, readAt: _propTypes.default.string, renderCustom: _propTypes.default.func })), unreadMessageIndicatorText: _propTypes.default.string, userID: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]).isRequired, recipientID: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]).isRequired, t: _propTypes.default.func }; var _default = MessageThread; exports.default = _default; //# sourceMappingURL=index.js.map