import React, { ReactNode } from "react";
import { MatrixEvent, EventTimelineSet, SyncState, TimelineWindow } from "matrix-js-sdk/src/matrix";
import { Layout } from "../../settings/enums/Layout";
import RoomContext from "../../contexts/RoomContext";
import { IScrollState } from "./ScrollPanel";
import ResizeNotifier from "../../utils/ResizeNotifier";
import { RoomPermalinkCreator } from "../../utils/permalinks/Permalinks";
import EditorStateTransfer from "../../utils/EditorStateTransfer";
interface IProps {
    timelineSet: EventTimelineSet;
    overlayTimelineSet?: EventTimelineSet;
    overlayTimelineSetFilter?: (event: MatrixEvent) => boolean;
    showReadReceipts?: boolean;
    manageReadReceipts?: boolean;
    sendReadReceiptOnLoad?: boolean;
    manageReadMarkers?: boolean;
    hidden?: boolean;
    highlightedEventId?: string;
    eventId?: string;
    eventScrollIntoView?: boolean;
    eventPixelOffset?: number;
    showUrlPreview?: boolean;
    timelineCap?: number;
    className?: string;
    empty?: ReactNode;
    showReactions?: boolean;
    layout?: Layout;
    alwaysShowTimestamps?: boolean;
    resizeNotifier?: ResizeNotifier;
    editState?: EditorStateTransfer;
    permalinkCreator?: RoomPermalinkCreator;
    membersLoaded?: boolean;
    onScroll?(event: Event): void;
    onEventScrolledIntoView?(eventId?: string): void;
    onReadMarkerUpdated?(): void;
    onPaginationRequest?(timelineWindow: TimelineWindow, direction: string, size: number): Promise<boolean>;
    hideThreadedMessages?: boolean;
    disableGrouping?: boolean;
}
interface IState {
    events: MatrixEvent[];
    liveEvents: MatrixEvent[];
    timelineLoading: boolean;
    canBackPaginate: boolean;
    canForwardPaginate: boolean;
    readMarkerVisible: boolean;
    readMarkerEventId: string | null;
    backPaginating: boolean;
    forwardPaginating: boolean;
    clientSyncState: SyncState | null;
    isTwelveHour: boolean;
    alwaysShowTimestamps: boolean;
    readMarkerInViewThresholdMs: number;
    readMarkerOutOfViewThresholdMs: number;
    editState?: EditorStateTransfer;
}
declare class TimelinePanel extends React.Component<IProps, IState> {
    static contextType: React.Context<import("./RoomView").IRoomState & {
        threadId?: string;
    }>;
    context: React.ContextType<typeof RoomContext>;
    static roomReadMarkerTsMap: Record<string, number>;
    static defaultProps: {
        timelineCap: number;
        className: string;
        sendReadReceiptOnLoad: boolean;
        hideThreadedMessages: boolean;
        disableGrouping: boolean;
    };
    private lastRRSentEventId;
    private lastRMSentEventId;
    private readonly messagePanel;
    private readonly dispatcherRef;
    private timelineWindow?;
    private overlayTimelineWindow?;
    private unmounted;
    private readReceiptActivityTimer;
    private readMarkerActivityTimer;
    private callEventGroupers;
    private initialReadMarkerId;
    constructor(props: IProps, context: React.ContextType<typeof RoomContext>);
    componentDidMount(): void;
    componentDidUpdate(prevProps: Readonly<IProps>): void;
    componentWillUnmount(): void;
    /**
     * Logs out debug info to describe the state of the TimelinePanel and the
     * events in the room according to the matrix-js-sdk. This is useful when
     * debugging problems like messages out of order, or messages that should
     * not be showing up in a thread, etc.
     *
     * It's too expensive and cumbersome to do all of these calculations for
     * every message change so instead we only log it out when asked.
     */
    private onDumpDebugLogs;
    private onMessageListUnfillRequest;
    private onPaginationRequest;
    private onMessageListFillRequest;
    private onMessageListScroll;
    private doManageReadMarkers;
    private onAction;
    private onRoomTimeline;
    private hasTimelineSetFor;
    private onRoomTimelineReset;
    canResetTimeline: () => boolean;
    private onRoomRedaction;
    private onThreadUpdate;
    private onEventVisibilityChange;
    private onVisibilityPowerLevelChange;
    private onEventReplaced;
    private onRoomReceipt;
    private onLocalEchoUpdated;
    private onAccountData;
    private onEventDecrypted;
    private onSync;
    private readMarkerTimeout;
    private updateReadMarkerOnUserActivity;
    private updateReadReceiptOnUserActivity;
    /**
     * Whether to send public or private receipts.
     */
    private determineReceiptType;
    /**
     * Whether a fully_read marker should be send.
     */
    private shouldSendFullyReadMarker;
    /**
     * Whether a read receipt should be send.
     */
    private shouldSendReadReceipt;
    private sendReadReceipts;
    /**
     * Sends a read receipt for event.
     * Resets the last sent event Id in case of an error, so that it will be retried next time.
     */
    private sendReadReceipt;
    /**
     * Sends a fully_read marker for readMarkerEvent.
     * Resets the last sent event Id in case of an error, so that it will be retried next time.
     */
    private sendFullyReadMarker;
    private updateReadMarker;
    private advanceReadMarkerPastMyEvents;
    jumpToLiveTimeline: () => void;
    scrollToEventIfNeeded: (eventId: string) => void;
    jumpToReadMarker: () => void;
    /**
     * update the read-up-to marker to match the read receipt
     */
    forgetReadMarker: () => Promise<void>;
    isAtEndOfLiveTimeline: () => boolean | undefined;
    getScrollState: () => IScrollState | null;
    getReadMarkerPosition: () => number | null;
    canJumpToReadMarker: () => boolean;
    handleScrollKey: (ev: React.KeyboardEvent | KeyboardEvent) => void;
    private initTimeline;
    private scrollIntoView;
    private extendOverlayWindowToCoverMainWindow;
    /**
     * (re)-load the event timeline, and initialise the scroll state, centered
     * around the given event.
     *
     * @param {string?}  eventId the event to focus on. If undefined, will
     *    scroll to the bottom of the room.
     *
     * @param {number?} pixelOffset   offset to position the given event at
     *    (pixels from the offsetBase). If omitted, defaults to 0.
     *
     * @param {number?} offsetBase the reference point for the pixelOffset. 0
     *     means the top of the container, 1 means the bottom, and fractional
     *     values mean somewhere in the middle. If omitted, it defaults to 0.
     *
     * @param {boolean?} scrollIntoView whether to scroll the event into view.
     */
    private loadTimeline;
    private reloadEvents;
    refreshTimeline(eventId?: string): void;
    private getEvents;
    private indexForEventId;
    /**
     * Get a list of undecryptable events currently visible on-screen.
     *
     * @param {boolean} addMargin Whether to add an extra margin beyond the viewport
     * where events are still considered "visible"
     *
     * @returns {MatrixEvent[] | null} A list of undecryptable events, or null if
     *     the list of events could not be determined.
     */
    getVisibleDecryptionFailures(addMargin?: boolean): MatrixEvent[] | null;
    private getLastDisplayedEventIndex;
    /**
     * Get the id of the event corresponding to our user's latest read-receipt.
     *
     * @param {Boolean} ignoreSynthesized If true, return only receipts that
     *                                    have been sent by the server, not
     *                                    implicit ones generated by the JS
     *                                    SDK.
     * @return {String} the event ID
     */
    private getCurrentReadReceipt;
    private setReadMarker;
    private shouldPaginate;
    private getRelationsForEvent;
    private buildLegacyCallEventGroupers;
    render(): React.ReactNode;
}
export default TimelinePanel;
