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
JavaScript
"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