refactor(ui/player): fix console rerender

This commit is contained in:
sylenien 2022-11-25 15:01:46 +01:00
parent 4af4824059
commit f9e837c0c8
6 changed files with 86 additions and 48 deletions

View file

@ -12,7 +12,6 @@ function Autoplay(props) {
const { player, store } = React.useContext(PlayerContext)
const { autoplay } = store.get()
const { toggleAutoplay } = player
useEffect(() => {
props.setAutoplayValues();
@ -21,10 +20,10 @@ function Autoplay(props) {
return (
<div className="flex items-center">
<div
onClick={toggleAutoplay}
onClick={() => player.toggleAutoplay()}
className="cursor-pointer flex items-center mr-2 hover:bg-gray-light-shade rounded-md p-2"
>
<Toggler name="sessionsLive" onChange={toggleAutoplay} checked={autoplay} />
<Toggler name="sessionsLive" onChange={() => player.toggleAutoplay()} checked={autoplay} />
<span className="ml-2 whitespace-nowrap">Auto-Play</span>
</div>

View file

@ -75,11 +75,11 @@ function Controls(props: any) {
inspectorMode,
markedTargets,
// messagesLoading: fullscreenDisabled, UPDATE
stackList,
// stackList,
exceptionsList,
profilesList,
graphqlList,
fetchList,
// fetchList,
liveTimeTravel,
logMarkedCountNow: logRedCount,
resourceMarkedCountNow: resourceRedCount,
@ -204,10 +204,10 @@ function Controls(props: any) {
const toggleBottomTools = (blockName: number) => {
if (blockName === INSPECTOR) {
player.toggleInspectorMode(false);
// player.toggleInspectorMode(false);
bottomBlock && toggleBottomBlock();
} else {
player.toggleInspectorMode(false);
// player.toggleInspectorMode(false);
toggleBottomBlock(blockName);
}
};

View file

@ -20,7 +20,7 @@ import {
OVERVIEW,
} from 'Duck/components/player';
import NetworkPanel from 'Shared/DevTools/NetworkPanel';
import StackEvents from '../StackEvents/StackEvents';
// import StackEvents from '../StackEvents/StackEvents';
import Storage from '../Storage';
import { ConnectedPerformance } from '../Performance';
import GraphQL from '../GraphQL';
@ -40,7 +40,6 @@ import StackEventPanel from 'Shared/DevTools/StackEventPanel';
function Player(props) {
const {
className,
bottomBlockIsActive,
fullscreen,
fullscreenOff,
nextId,
@ -51,6 +50,7 @@ function Player(props) {
} = props;
const playerContext = React.useContext(PlayerContext)
const screenWrapper = React.useRef();
const bottomBlockIsActive = !fullscreen && bottomBlock !== NONE
React.useEffect(() => {
props.updateLastPlayedSession(props.sessionId);
@ -67,6 +67,8 @@ function Player(props) {
if (!playerContext.player) return null;
console.log(bottomBlock)
const maxWidth = activeTab ? 'calc(100vw - 270px)' : '100vw';
return (
<div
@ -112,6 +114,7 @@ export default connect((state) => {
fullscreen: state.getIn(['components', 'player', 'fullscreen']),
nextId: state.getIn(['sessions', 'nextId']),
sessionId: state.getIn(['sessions', 'current', 'sessionId']),
bottomBlock: state.getIn(['components', 'player', 'bottomBlock']),
closedLive:
!!state.getIn(['sessions', 'errors']) ||
(isAssist && !state.getIn(['sessions', 'current', 'live'])),

View file

@ -9,14 +9,13 @@ import styles from './playerBlock.module.css';
@connect((state) => ({
fullscreen: state.getIn(['components', 'player', 'fullscreen']),
bottomBlock: state.getIn(['components', 'player', 'bottomBlock']),
sessionId: state.getIn(['sessions', 'current', 'sessionId']),
disabled: state.getIn(['components', 'targetDefiner', 'inspectorMode']),
jiraConfig: state.getIn(['issues', 'list']).first(),
}))
export default class PlayerBlock extends React.PureComponent {
render() {
const { fullscreen, bottomBlock, sessionId, disabled, activeTab, jiraConfig, fullView = false } = this.props;
const { fullscreen, sessionId, disabled, activeTab, jiraConfig, fullView = false } = this.props;
return (
<div className={cn(styles.playerBlock, 'flex flex-col overflow-x-hidden')}>
@ -25,9 +24,7 @@ export default class PlayerBlock extends React.PureComponent {
)}
<Player
className="flex-1"
bottomBlockIsActive={!fullscreen && bottomBlock !== NONE}
// bottomBlockIsActive={ true }
bottomBlock={bottomBlock}
fullscreen={fullscreen}
activeTab={activeTab}
fullView={fullView}

View file

@ -13,6 +13,7 @@ import { useObserver } from 'mobx-react-lite';
import { useStore } from 'App/mstore';
import ErrorDetailsModal from 'App/components/Dashboard/components/Errors/ErrorDetailsModal';
import { useModal } from 'App/components/Modal';
import { throttle } from 'App/utils'
const ALL = 'ALL';
const INFO = 'INFO';
@ -28,6 +29,7 @@ const LEVEL_TAB = {
};
const TABS = [ALL, ERRORS, WARNINGS, INFO].map((tab) => ({ text: tab, key: tab }));
let throttledCall = () => 999
function renderWithNL(s = '') {
if (typeof s !== 'string') return '';
@ -64,11 +66,24 @@ const TIMEOUT_DURATION = 5000;
function ConsolePanel() {
const { player, store } = React.useContext(PlayerContext)
const additionalHeight = 0;
const {
sessionStore: { devTools },
} = useStore();
const filter = devTools[INDEX_KEY].filter;
const activeTab = devTools[INDEX_KEY].activeTab;
const activeIndex = devTools[INDEX_KEY].index;
const [isDetailsModalActive, setIsDetailsModalActive] = useState(false);
const [filteredList, setFilteredList] = useState([]);
const [pauseSync, setPauseSync] = useState(activeIndex > 0);
const synRef: any = useRef({});
const { showModal } = useModal();
const jump = (t: number) => player.jump(t)
const { logList, exceptionsList, time } = store.get()
const logExceptions = exceptionsList.map(({ time, errorId, name, projectId }: any) =>
const logExceptions = exceptionsList.map(({ time, errorId, name }: any) =>
Log({
level: LEVEL.ERROR,
value: name,
@ -78,19 +93,6 @@ function ConsolePanel() {
);
// @ts-ignore
const logs = logList.concat(logExceptions)
const additionalHeight = 0;
const {
sessionStore: { devTools },
} = useStore();
const [isDetailsModalActive, setIsDetailsModalActive] = useState(false);
const [filteredList, setFilteredList] = useState([]);
const filter = useObserver(() => devTools[INDEX_KEY].filter);
const activeTab = useObserver(() => devTools[INDEX_KEY].activeTab);
const activeIndex = useObserver(() => devTools[INDEX_KEY].index);
const [pauseSync, setPauseSync] = useState(activeIndex > 0);
const synRef: any = useRef({});
const { showModal } = useModal();
const onTabClick = (activeTab: any) => devTools.update(INDEX_KEY, { activeTab });
const onFilterChange = ({ target: { value } }: any) => {
@ -116,30 +118,10 @@ function ConsolePanel() {
removePause();
};
useEffect(() => {
if (pauseSync) {
removePause();
}
return () => {
clearTimeout(timeOut);
if (!synRef.current.pauseSync) {
devTools.update(INDEX_KEY, { index: 0 });
}
};
}, []);
const getCurrentIndex = () => {
return filteredList.filter((item: any) => item.time <= time).length - 1;
};
useEffect(() => {
const currentIndex = getCurrentIndex();
if (currentIndex !== activeIndex && !pauseSync) {
devTools.update(INDEX_KEY, { index: currentIndex });
}
}, [time]);
const cache = new CellMeasurerCache({
fixedWidth: true,
keyMapper: (index: number) => filteredList[index],
@ -177,6 +159,27 @@ function ConsolePanel() {
);
};
useEffect(() => {
if (pauseSync) {
removePause();
}
throttledCall = throttle(getCurrentIndex, 500, undefined)
return () => {
clearTimeout(timeOut);
if (!synRef.current.pauseSync) {
devTools.update(INDEX_KEY, { index: 0 });
}
};
}, []);
useEffect(() => {
const currentIndex = throttledCall()
if (currentIndex !== activeIndex && !pauseSync) {
devTools.update(INDEX_KEY, { index: currentIndex });
}
}, [time]);
React.useMemo(() => {
const filterRE = getRE(filter, 'i');
let list = logs;
@ -186,16 +189,19 @@ function ConsolePanel() {
(!!filter ? filterRE.test(value) : true) &&
(activeTab === ALL || activeTab === LEVEL_TAB[level])
);
console.log('log filter tab', logs.length, filter, activeTab)
setFilteredList(list);
}, [logs, filter, activeTab]);
}, [logs.length, filter, activeTab]);
useEffect(() => {
if (_list.current) {
console.log('active index')
// @ts-ignore
_list.current.scrollToRow(activeIndex);
}
}, [activeIndex]);
console.log('rerender')
return (
<BottomBlock
style={{ height: 300 + additionalHeight + 'px' }}

View file

@ -2,6 +2,7 @@ import JSBI from 'jsbi';
import chroma from 'chroma-js';
import * as htmlToImage from 'html-to-image';
import { SESSION_FILTER } from 'App/constants/storageKeys';
import { useEffect, useRef, useState } from 'react';
export function debounce(callback, wait, context = this) {
let timeout = null;
@ -380,3 +381,35 @@ export function millisToMinutesAndSeconds(millis: any) {
const seconds: any = ((millis % 60000) / 1000).toFixed(0);
return minutes + 'm' + (seconds < 10 ? '0' : '') + seconds + 's';
}
export function throttle(func, wait, options) {
var context, args, result;
var timeout = null;
var previous = 0;
if (!options) options = {};
var later = function() {
previous = options.leading === false ? 0 : Date.now();
timeout = null;
result = func.apply(context, args);
if (!timeout) context = args = null;
};
return function() {
var now = Date.now();
if (!previous && options.leading === false) previous = now;
var remaining = wait - (now - previous);
context = this;
args = arguments;
if (remaining <= 0 || remaining > wait) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
previous = now;
result = func.apply(context, args);
if (!timeout) context = args = null;
} else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining);
}
return result;
};
};