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.

249 lines (248 loc) 9.71 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"); 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; } const ReactionUserListBottomSheet = ({ visible, onClose, onDismiss, reactionCtx, chatCtx, localizationCtx, onPressUserProfile }) => { const { width } = (0, _reactNative.useWindowDimensions)(); const safeArea = (0, _uikitUtils.useSafeAreaPadding)(['left', 'right', 'bottom']); const { colors } = (0, _uikitReactNativeFoundation.useUIKitTheme)(); const [tabIndex, setTabIndex] = (0, _react.useState)(0); const scrollRef = (0, _react.useRef)(); const tabIndicatorValue = (0, _react.useRef)([]); const tabIndicatorAnimated = (0, _react.useRef)({ x: new _reactNative.Animated.Value(0), width: new _reactNative.Animated.Value(0) }).current; const focusedWithLayoutCalculated = (0, _react.useRef)(false); const { emojiManager } = chatCtx; const { channel, message, focusIndex } = reactionCtx; const { STRINGS } = localizationCtx; const color = colors.ui.reaction.default; const reactions = (message === null || message === void 0 ? void 0 : message.reactions) ?? []; const focusedReaction = reactions[tabIndex]; const containerSafeArea = { paddingStart: safeArea.paddingStart + styles.layout.paddingHorizontal, paddingEnd: safeArea.paddingEnd + styles.layout.paddingHorizontal }; const focusTab = (index, animated = true) => { const indicatorValue = tabIndicatorValue.current[index]; if (indicatorValue) { var _scrollRef$current; setTabIndex(index); animateTabIndicator(indicatorValue.x, indicatorValue.width, animated); (_scrollRef$current = scrollRef.current) === null || _scrollRef$current === void 0 || _scrollRef$current.scrollTo({ x: indicatorValue.x, animated }); } }; const animateTabIndicator = (x, width, animated = true) => { const baseConfig = { duration: animated ? 300 : 0, easing: _reactNative.Easing.inOut(_reactNative.Easing.ease), useNativeDriver: false }; _reactNative.Animated.parallel([_reactNative.Animated.timing(tabIndicatorAnimated.x, { toValue: x, ...baseConfig }), _reactNative.Animated.timing(tabIndicatorAnimated.width, { toValue: width, ...baseConfig })]).start(); }; const layoutCalculated = () => { return tabIndicatorValue.current.filter(Boolean).length === reactions.length; }; (0, _react.useEffect)(() => { if (!visible) { tabIndicatorValue.current = []; tabIndicatorAnimated.x = new _reactNative.Animated.Value(0); tabIndicatorAnimated.width = new _reactNative.Animated.Value(0); focusedWithLayoutCalculated.current = false; } }, [visible]); const renderTabs = () => { return /*#__PURE__*/_react.default.createElement(_reactNative.Pressable, { style: styles.tabsWrapper }, reactions.map((reaction, index) => { const isFocused = (focusedReaction === null || focusedReaction === void 0 ? void 0 : focusedReaction.key) === reaction.key; const isLastItem = reactions.length - 1 === index; const emoji = emojiManager.allEmojiMap[reaction.key]; return /*#__PURE__*/_react.default.createElement(_reactNative.Pressable, { key: reaction.key, style: [styles.tabItem, isLastItem && { marginEnd: styles.layout.marginEnd }], onPress: () => focusTab(index), onLayout: e => { const indexForLayout = _reactNative.I18nManager.isRTL ? reactions.length - 1 - index : index; tabIndicatorValue.current[indexForLayout] = e.nativeEvent.layout; if (layoutCalculated()) { if (focusedWithLayoutCalculated.current) { // re-calculating layout when screen rotation focusTab(tabIndex, false); } else { focusedWithLayoutCalculated.current = true; focusTab(focusIndex); } } } }, /*#__PURE__*/_react.default.createElement(_uikitReactNativeFoundation.Image, { source: emojiManager.getEmojiIconSource(emoji), style: styles.tabEmoji }), /*#__PURE__*/_react.default.createElement(_uikitReactNativeFoundation.Text, { button: true, color: isFocused ? color.selected.highlight : color.enabled.highlight }, (0, _uikitUtils.truncatedCount)((0, _uikitUtils.getReactionCount)(reaction)))); }), /*#__PURE__*/_react.default.createElement(_reactNative.Animated.View, { style: [styles.tabIndicator, { start: tabIndicatorAnimated.x, width: tabIndicatorAnimated.width, backgroundColor: color.selected.highlight }] })); }; const renderPage = () => { const userCountDifference = ((focusedReaction === null || focusedReaction === void 0 ? void 0 : focusedReaction.count) || 0) - ((focusedReaction === null || focusedReaction === void 0 ? void 0 : focusedReaction.sampledUserInfoList.length) || 0); return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, focusedReaction === null || focusedReaction === void 0 ? void 0 : focusedReaction.sampledUserInfoList.map(reactedUserInfo => { if (channel !== null && channel !== void 0 && channel.isGroupChannel()) { return /*#__PURE__*/_react.default.createElement(_reactNative.Pressable, { key: reactedUserInfo.userId, onPress: async () => { await onClose(); onPressUserProfile(reactedUserInfo); }, style: styles.pageItem }, /*#__PURE__*/_react.default.createElement(_uikitReactNativeFoundation.Avatar, { size: 36, uri: reactedUserInfo === null || reactedUserInfo === void 0 ? void 0 : reactedUserInfo.profileUrl, containerStyle: styles.avatar }), /*#__PURE__*/_react.default.createElement(_uikitReactNativeFoundation.Text, { subtitle2: true, style: { flex: 1 } }, (reactedUserInfo === null || reactedUserInfo === void 0 ? void 0 : reactedUserInfo.nickname) || STRINGS.LABELS.USER_NO_NAME)); } return null; }), userCountDifference > 0 && /*#__PURE__*/_react.default.createElement(_reactNative.View, { style: styles.pageItem }, /*#__PURE__*/_react.default.createElement(_uikitReactNativeFoundation.Text, { body3: true, color: colors.onBackground02 }, STRINGS.REACTION.MORE_USERS(userCountDifference)))); }; return /*#__PURE__*/_react.default.createElement(_uikitReactNativeFoundation.Modal, { type: 'slide-no-gesture', visible: Boolean(visible && channel && message), onClose: onClose, onDismiss: onDismiss, backgroundStyle: styles.modal }, /*#__PURE__*/_react.default.createElement(_reactNative.View, { style: [styles.container, { width, paddingBottom: safeArea.paddingBottom, backgroundColor: colors.ui.dialog.default.none.background }] }, /*#__PURE__*/_react.default.createElement(_reactNative.ScrollView, { ref: scrollRef, horizontal: true, bounces: false, showsHorizontalScrollIndicator: false, contentContainerStyle: [containerSafeArea, styles.tabsContainer] }, renderTabs()), /*#__PURE__*/_react.default.createElement(_uikitReactNativeFoundation.Divider, { style: { top: -1 } }), /*#__PURE__*/_react.default.createElement(_reactNative.ScrollView, { bounces: false, showsVerticalScrollIndicator: false, style: styles.pageContainer, contentContainerStyle: containerSafeArea }, renderPage()))); }; const styles = (0, _uikitReactNativeFoundation.createStyleSheet)({ layout: { paddingHorizontal: 16, marginEnd: 0 }, container: { overflow: 'hidden', borderTopStartRadius: 8, borderTopEndRadius: 8, paddingTop: 16, alignItems: 'center' }, modal: { alignItems: 'center', justifyContent: 'flex-end' }, tabsContainer: { flexGrow: 1 }, tabsWrapper: { flexGrow: 1, flexDirection: 'row', alignItems: 'flex-start', justifyContent: 'center', height: 44 }, tabItem: { marginEnd: 16, flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }, tabEmoji: { width: 28, height: 28, marginEnd: 4 }, tabIndicator: { position: 'absolute', bottom: 0, height: 3 }, pageContainer: { height: 216, width: '100%' }, pageItem: { flexDirection: 'row', width: '100%', height: 48, alignItems: 'center' }, avatar: { marginEnd: 16 } }); var _default = exports.default = ReactionUserListBottomSheet; //# sourceMappingURL=ReactionUserListBottomSheet.js.map