"use strict";
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const prop_types_1 = __importDefault(require("prop-types"));
const react_1 = __importDefault(require("react"));
const react_native_1 = require("react-native");
const LoadEarlier_1 = __importDefault(require("./LoadEarlier"));
const Message_1 = __importDefault(require("./Message"));
const Color_1 = __importDefault(require("./Color"));
const utils_1 = require("./utils");
const TypingIndicator_1 = __importDefault(require("./TypingIndicator"));
const styles = react_native_1.StyleSheet.create({
    container: {
        flex: 1,
    },
    containerAlignTop: {
        flexDirection: 'row',
        alignItems: 'flex-start',
    },
    contentContainerStyle: {
        flexGrow: 1,
        justifyContent: 'flex-start',
    },
    emptyChatContainer: {
        flex: 1,
        transform: [{ scaleY: -1 }],
    },
    headerWrapper: {
        flex: 1,
    },
    listStyle: {
        flex: 1,
    },
    scrollToBottomStyle: {
        opacity: 0.8,
        position: 'absolute',
        right: 10,
        bottom: 30,
        zIndex: 999,
        height: 40,
        width: 40,
        borderRadius: 20,
        backgroundColor: Color_1.default.white,
        alignItems: 'center',
        justifyContent: 'center',
        shadowColor: Color_1.default.black,
        shadowOpacity: 0.5,
        shadowOffset: { width: 0, height: 0 },
        shadowRadius: 1,
    },
});
class MessageContainer extends react_1.default.PureComponent {
    constructor() {
        super(...arguments);
        this.state = {
            showScrollBottom: false,
            hasScrolled: false,
        };
        this.renderTypingIndicator = () => {
            if (react_native_1.Platform.OS === 'web') {
                return null;
            }
            return react_1.default.createElement(TypingIndicator_1.default, { isTyping: this.props.isTyping || false });
        };
        this.renderFooter = () => {
            if (this.props.renderFooter) {
                return this.props.renderFooter(this.props);
            }
            return this.renderTypingIndicator();
        };
        this.renderLoadEarlier = () => {
            if (this.props.loadEarlier === true) {
                const loadEarlierProps = Object.assign({}, this.props);
                if (this.props.renderLoadEarlier) {
                    return this.props.renderLoadEarlier(loadEarlierProps);
                }
                return react_1.default.createElement(LoadEarlier_1.default, Object.assign({}, loadEarlierProps));
            }
            return null;
        };
        this.scrollToBottom = (animated = true) => {
            const { inverted } = this.props;
            if (inverted) {
                this.scrollTo({ offset: 0, animated });
            }
            else if (this.props.forwardRef && this.props.forwardRef.current) {
                this.props.forwardRef.current.scrollToEnd({ animated });
            }
        };
        this.handleOnScroll = (event) => {
            const { nativeEvent: { contentOffset: { y: contentOffsetY }, contentSize: { height: contentSizeHeight }, layoutMeasurement: { height: layoutMeasurementHeight }, }, } = event;
            const { scrollToBottomOffset } = this.props;
            if (this.props.inverted) {
                if (contentOffsetY > scrollToBottomOffset) {
                    this.setState({ showScrollBottom: true, hasScrolled: true });
                }
                else {
                    this.setState({ showScrollBottom: false, hasScrolled: true });
                }
            }
            else if (contentOffsetY < scrollToBottomOffset &&
                contentSizeHeight - layoutMeasurementHeight > scrollToBottomOffset) {
                this.setState({ showScrollBottom: true, hasScrolled: true });
            }
            else {
                this.setState({ showScrollBottom: false, hasScrolled: true });
            }
        };
        this.renderRow = ({ item, index }) => {
            if (!item._id && item._id !== 0) {
                utils_1.warning('GiftedChat: `_id` is missing for message', JSON.stringify(item));
            }
            if (!item.user) {
                if (!item.system) {
                    utils_1.warning('GiftedChat: `user` is missing for message', JSON.stringify(item));
                }
                item.user = { _id: 0 };
            }
            const _a = this.props, { messages, user, inverted } = _a, restProps = __rest(_a, ["messages", "user", "inverted"]);
            if (messages && user) {
                const previousMessage = (inverted ? messages[index + 1] : messages[index - 1]) || {};
                const nextMessage = (inverted ? messages[index - 1] : messages[index + 1]) || {};
                const messageProps = Object.assign(Object.assign({}, restProps), { user, key: item._id, currentMessage: item, 
                    // @ts-ignore
                    previousMessage,
                    inverted,
                    // @ts-ignore
                    nextMessage, position: item.user._id === user._id ? 'right' : 'left' });
                if (this.props.renderMessage) {
                    return this.props.renderMessage(messageProps);
                }
                return react_1.default.createElement(Message_1.default, Object.assign({}, messageProps));
            }
            return null;
        };
        this.renderChatEmpty = () => {
            if (this.props.renderChatEmpty) {
                return this.props.inverted ? (this.props.renderChatEmpty()) : (react_1.default.createElement(react_native_1.View, { style: styles.emptyChatContainer }, this.props.renderChatEmpty()));
            }
            return react_1.default.createElement(react_native_1.View, { style: styles.container });
        };
        this.renderHeaderWrapper = () => (react_1.default.createElement(react_native_1.View, { style: styles.headerWrapper }, this.renderLoadEarlier()));
        this.onLayoutList = () => {
            if (!this.props.inverted &&
                !!this.props.messages &&
                this.props.messages.length) {
                setTimeout(() => this.scrollToBottom && this.scrollToBottom(false), 15 * this.props.messages.length);
            }
        };
        this.onEndReached = ({ distanceFromEnd }) => {
            const { loadEarlier, onLoadEarlier, infiniteScroll, isLoadingEarlier } = this.props;
            if (infiniteScroll &&
                (this.state.hasScrolled || distanceFromEnd > 0) &&
                distanceFromEnd <= 100 &&
                loadEarlier &&
                onLoadEarlier &&
                !isLoadingEarlier &&
                react_native_1.Platform.OS !== 'web') {
                onLoadEarlier();
            }
        };
        this.keyExtractor = (item) => `${item._id}`;
    }
    scrollTo(options) {
        if (this.props.forwardRef && this.props.forwardRef.current && options) {
            this.props.forwardRef.current.scrollToOffset(options);
        }
    }
    renderScrollBottomComponent() {
        const { scrollToBottomComponent } = this.props;
        if (scrollToBottomComponent) {
            return scrollToBottomComponent();
        }
        return react_1.default.createElement(react_native_1.Text, null, "V");
    }
    renderScrollToBottomWrapper() {
        const propsStyle = this.props.scrollToBottomStyle || {};
        return (react_1.default.createElement(react_native_1.View, { style: [styles.scrollToBottomStyle, propsStyle] },
            react_1.default.createElement(react_native_1.TouchableOpacity, { onPress: () => this.scrollToBottom(), hitSlop: {
                    top: 5,
                    left: 5,
                    right: 5,
                    bottom: 5,
                } }, this.renderScrollBottomComponent())));
    }
    render() {
        const { inverted } = this.props;
        return (react_1.default.createElement(react_native_1.View, { style: this.props.alignTop
                ? styles.containerAlignTop
                : styles.container },
            this.state.showScrollBottom && this.props.scrollToBottom
                ? this.renderScrollToBottomWrapper()
                : null,
            react_1.default.createElement(react_native_1.FlatList, Object.assign({ ref: this.props.forwardRef, extraData: [this.props.extraData, this.props.isTyping], keyExtractor: this.keyExtractor, enableEmptySections: true, automaticallyAdjustContentInsets: false, inverted: inverted, data: this.props.messages, style: styles.listStyle, contentContainerStyle: styles.contentContainerStyle, renderItem: this.renderRow }, this.props.invertibleScrollViewProps, { ListEmptyComponent: this.renderChatEmpty, ListFooterComponent: inverted ? this.renderHeaderWrapper : this.renderFooter, ListHeaderComponent: inverted ? this.renderFooter : this.renderHeaderWrapper, onScroll: this.handleOnScroll, scrollEventThrottle: 100, onLayout: this.onLayoutList, onEndReached: this.onEndReached, onEndReachedThreshold: 0.1 }, this.props.listViewProps))));
    }
}
exports.default = MessageContainer;
MessageContainer.defaultProps = {
    messages: [],
    user: {},
    isTyping: false,
    renderChatEmpty: null,
    renderFooter: null,
    renderMessage: null,
    onLoadEarlier: () => { },
    onQuickReply: () => { },
    inverted: true,
    loadEarlier: false,
    listViewProps: {},
    invertibleScrollViewProps: {},
    extraData: null,
    scrollToBottom: false,
    scrollToBottomOffset: 200,
    alignTop: false,
    scrollToBottomStyle: {},
    infiniteScroll: false,
    isLoadingEarlier: false,
};
MessageContainer.propTypes = {
    messages: prop_types_1.default.arrayOf(prop_types_1.default.object),
    isTyping: prop_types_1.default.bool,
    user: prop_types_1.default.object,
    renderChatEmpty: prop_types_1.default.func,
    renderFooter: prop_types_1.default.func,
    renderMessage: prop_types_1.default.func,
    renderLoadEarlier: prop_types_1.default.func,
    onLoadEarlier: prop_types_1.default.func,
    listViewProps: prop_types_1.default.object,
    inverted: prop_types_1.default.bool,
    loadEarlier: prop_types_1.default.bool,
    invertibleScrollViewProps: prop_types_1.default.object,
    extraData: prop_types_1.default.object,
    scrollToBottom: prop_types_1.default.bool,
    scrollToBottomOffset: prop_types_1.default.number,
    scrollToBottomComponent: prop_types_1.default.func,
    alignTop: prop_types_1.default.bool,
    scrollToBottomStyle: utils_1.StylePropType,
    infiniteScroll: prop_types_1.default.bool,
};
//# sourceMappingURL=MessageContainer.js.map