import { Timed } from 'Player'; import React, { useEffect, useMemo, useState } from 'react'; import { observer } from 'mobx-react-lite'; import { Tabs, NoContent, Icon } from 'UI'; import { Input } from 'antd'; import { SearchOutlined, InfoCircleOutlined } from '@ant-design/icons'; import { PlayerContext, MobilePlayerContext, } from 'App/components/Session/playerContext'; import BottomBlock from '../BottomBlock'; import { useModal } from 'App/components/Modal'; import { useStore } from 'App/mstore'; import { typeList } from 'Types/session/stackEvent'; import StackEventRow from 'Shared/DevTools/StackEventRow'; import StackEventModal from '../StackEventModal'; import { Segmented, Tooltip } from 'antd'; import useAutoscroll, { getLastItemTime } from '../useAutoscroll'; import { useRegExListFilterMemo, useTabListFilterMemo } from '../useListFilter'; import { VList, VListHandle } from 'virtua'; const mapNames = (type: string) => { if (type === 'openreplay') return 'OpenReplay'; return type; }; const INDEX_KEY = 'stackEvent'; const ALL = 'ALL'; const TAB_KEYS = [ALL, ...typeList] as const; const TABS = TAB_KEYS.map((tab) => ({ text: tab, key: tab })); type EventsList = Array< Timed & { name: string; source: string; key: string; payload?: string[] } >; const WebStackEventPanelComp = observer(() => { const { uiPlayerStore } = useStore(); const zoomEnabled = uiPlayerStore.timelineZoom.enabled; const zoomStartTs = uiPlayerStore.timelineZoom.startTs; const zoomEndTs = uiPlayerStore.timelineZoom.endTs; const { player, store } = React.useContext(PlayerContext); const jump = (t: number) => player.jump(t); const { currentTab, tabStates } = store.get(); const { stackList: list = [], stackListNow: listNow = [] } = tabStates[currentTab]; return ( ); }); export const WebStackEventPanel = WebStackEventPanelComp; const MobileStackEventPanelComp = observer(() => { const { uiPlayerStore } = useStore(); const zoomEnabled = uiPlayerStore.timelineZoom.enabled; const zoomStartTs = uiPlayerStore.timelineZoom.startTs; const zoomEndTs = uiPlayerStore.timelineZoom.endTs; const { player, store } = React.useContext(MobilePlayerContext); const jump = (t: number) => player.jump(t); const { eventList: list = [], eventListNow: listNow = [] } = store.get(); return ( ); }); export const MobileStackEventPanel = MobileStackEventPanelComp; const EventsPanel = observer( ({ list, listNow, jump, zoomEnabled, zoomStartTs, zoomEndTs, isMobile, }: { list: EventsList; listNow: EventsList; jump: (t: number) => void; zoomEnabled: boolean; zoomStartTs: number; zoomEndTs: number; isMobile?: boolean; }) => { const { sessionStore: { devTools }, } = useStore(); const { showModal } = useModal(); const [isDetailsModalActive, setIsDetailsModalActive] = useState(false); // TODO:embed that into useModal const filter = devTools[INDEX_KEY].filter; const activeTab = devTools[INDEX_KEY].activeTab; const activeIndex = devTools[INDEX_KEY].index; const inZoomRangeList = list.filter(({ time }) => zoomEnabled ? zoomStartTs <= time && time <= zoomEndTs : true ); const inZoomRangeListNow = listNow.filter(({ time }) => zoomEnabled ? zoomStartTs <= time && time <= zoomEndTs : true ); let filteredList = useRegExListFilterMemo( inZoomRangeList, (it) => { const searchBy = [it.name]; if (it.payload) { const payload = Array.isArray(it.payload) ? it.payload.join(',') : JSON.stringify(it.payload); searchBy.push(payload); } return searchBy; }, filter ); filteredList = useTabListFilterMemo( filteredList, (it) => it.source, ALL, activeTab ); const onTabClick = (activeTab: (typeof TAB_KEYS)[number]) => devTools.update(INDEX_KEY, { activeTab }); const onFilterChange = ({ target: { value }, }: React.ChangeEvent) => devTools.update(INDEX_KEY, { filter: value }); const tabs = useMemo( () => TABS.filter( ({ key }) => key === ALL || inZoomRangeList.some(({ source }) => key === source) ), [inZoomRangeList.length] ); const [timeoutStartAutoscroll, stopAutoscroll] = useAutoscroll( filteredList, getLastItemTime(inZoomRangeListNow), activeIndex, (index) => devTools.update(INDEX_KEY, { index }) ); const onMouseEnter = stopAutoscroll; const onMouseLeave = () => { if (isDetailsModalActive) { return; } timeoutStartAutoscroll(); }; const showDetails = (item: any) => { setIsDetailsModalActive(true); showModal(, { right: true, width: 500, onClose: () => { setIsDetailsModalActive(false); timeoutStartAutoscroll(); }, }); devTools.update(INDEX_KEY, { index: filteredList.indexOf(item) }); stopAutoscroll(); }; const _list = React.useRef(null); useEffect(() => { if (_list.current) { _list.current.scrollToIndex(activeIndex); } }, [activeIndex]); return ( Stack Events {isMobile ? null : ( Current Tab ), value: 'current', disabled: true, }, ]} defaultValue="all" size="small" className="rounded-full font-medium" /> )} } /> No Data } size="small" show={filteredList.length === 0} > {filteredList.map((item, index) => ( { stopAutoscroll(); devTools.update(INDEX_KEY, { index: filteredList.indexOf(item), }); jump(item.time); }} onClick={() => showDetails(item)} /> ))} ); } );