diff --git a/frontend/app/components/Session/MobilePlayer.tsx b/frontend/app/components/Session/MobilePlayer.tsx index d8a88b7f4..16f4a9178 100644 --- a/frontend/app/components/Session/MobilePlayer.tsx +++ b/frontend/app/components/Session/MobilePlayer.tsx @@ -1,7 +1,6 @@ import React, { useEffect, useState } from 'react'; import { connect } from 'react-redux'; import { Modal, Loader } from 'UI'; -import { toggleFullscreen, closeBottomBlock } from 'Duck/components/player'; import { fetchList } from 'Duck/integrations'; import { createIOSPlayer } from 'Player'; import { makeAutoObservable } from 'mobx'; @@ -24,14 +23,16 @@ const TABS = { let playerInst: IOSPlayerContext['player'] | undefined; function MobilePlayer(props: any) { - const { session, toggleFullscreen, closeBottomBlock, fullscreen, fetchList } = props; - - const { notesStore, sessionStore } = useStore(); + const { session, fetchList } = props; + const { notesStore, sessionStore, uiPlayerStore } = useStore(); const [activeTab, setActiveTab] = useState(''); const [noteItem, setNoteItem] = useState(undefined); // @ts-ignore const [contextValue, setContextValue] = useState(defaultContextValue); const params: { sessionId: string } = useParams(); + const fullscreen = uiPlayerStore.fullscreen + const toggleFullscreen = uiPlayerStore.toggleFullscreen + const closeBottomBlock = uiPlayerStore.closeBottomBlock useEffect(() => { playerInst = undefined; @@ -147,12 +148,9 @@ export default connect( session: state.getIn(['sessions', 'current']), visitedEvents: state.getIn(['sessions', 'visitedEvents']), jwt: state.getIn(['user', 'jwt']), - fullscreen: state.getIn(['player']).fullcreen, showEvents: state.get('showEvents'), }), { - toggleFullscreen, - closeBottomBlock, fetchList, } )(withLocationHandlers()(observer(MobilePlayer))); diff --git a/frontend/app/components/Session/Player/LivePlayer/LiveControls.tsx b/frontend/app/components/Session/Player/LivePlayer/LiveControls.tsx index d9f2f2bf3..e9819cf46 100644 --- a/frontend/app/components/Session/Player/LivePlayer/LiveControls.tsx +++ b/frontend/app/components/Session/Player/LivePlayer/LiveControls.tsx @@ -1,12 +1,13 @@ import React from 'react'; import cn from 'classnames'; import { connect } from 'react-redux'; +import { useStore } from "App/mstore"; import LiveTag from './LiveTag'; import AssistSessionsTabs from './AssistSessionsTabs'; import { - CONSOLE, toggleBottomBlock, -} from 'Duck/components/player'; + CONSOLE, +} from 'App/mstore/uiPlayerStore'; import { PlayerContext, ILivePlayerContext } from 'App/components/Session/playerContext'; import { observer } from 'mobx-react-lite'; import { fetchSessions } from 'Duck/liveSearch'; @@ -18,6 +19,10 @@ import { SKIP_INTERVALS } from 'Components/Session_/Player/Controls/Controls' import styles from 'Components/Session_/Player/Controls/controls.module.css'; function Controls(props: any) { + const { uiPlayerStore } = useStore(); + const toggleBottomBlock = uiPlayerStore.toggleBottomBlock; + const bottomBlock = uiPlayerStore.bottomBlock; + const skipInterval = uiPlayerStore.skipInterval; // @ts-ignore ?? TODO const { player, store } = React.useContext(PlayerContext); const [noControls, setNoControls] = React.useState(false); @@ -35,10 +40,7 @@ function Controls(props: any) { const logRedCount = tabStates[currentTab]?.logMarkedCountNow || 0; const showExceptions = exceptionsList.length > 0; const { - bottomBlock, - toggleBottomBlock, closedLive, - skipInterval, session, fetchSessions: fetchAssistSessions, totalAssistSessions, @@ -141,6 +143,5 @@ export default connect( }, { fetchSessions, - toggleBottomBlock } )(ControlPlayer); \ No newline at end of file diff --git a/frontend/app/components/Session/Player/LivePlayer/LivePlayerInst.tsx b/frontend/app/components/Session/Player/LivePlayer/LivePlayerInst.tsx index 49e9599f7..a92518ea5 100644 --- a/frontend/app/components/Session/Player/LivePlayer/LivePlayerInst.tsx +++ b/frontend/app/components/Session/Player/LivePlayer/LivePlayerInst.tsx @@ -6,29 +6,31 @@ import React from 'react'; import { connect } from 'react-redux'; import { findDOMNode } from 'react-dom'; import cn from 'classnames'; +import { useStore } from "App/mstore"; import LiveControls from './LiveControls'; import ConsolePanel from 'Shared/DevTools/ConsolePanel'; import { observer } from 'mobx-react-lite'; import Overlay from './Overlay'; import stl from 'Components/Session_/Player/player.module.css'; import { PlayerContext, ILivePlayerContext } from 'App/components/Session/playerContext'; -import { CONSOLE } from 'Duck/components/player'; +import { CONSOLE } from 'App/mstore/uiPlayerStore'; interface IProps { closedLive: boolean; fullView: boolean; isMultiview?: boolean; - bottomBlock: number; } function Player(props: IProps) { + const { uiPlayerStore } = useStore() const defaultHeight = getDefaultPanelHeight(); const [panelHeight, setPanelHeight] = React.useState(defaultHeight); - const { closedLive, fullView, isMultiview, bottomBlock } = props; + const { closedLive, fullView, isMultiview } = props; // @ts-ignore TODO const playerContext = React.useContext(PlayerContext); const screenWrapper = React.useRef(null); const ready = playerContext.store.get().ready; + const bottomBlock = uiPlayerStore.bottomBlock React.useEffect(() => { if (!props.closedLive || isMultiview) { @@ -97,7 +99,6 @@ export default connect((state: any) => { const isAssist = window.location.pathname.includes('/assist/'); return { sessionId: state.getIn(['sessions', 'current']).sessionId, - bottomBlock: state.getIn(['player', 'bottomBlock']), closedLive: !!state.getIn(['sessions', 'errors']) || (isAssist && !state.getIn(['sessions', 'current']).live), diff --git a/frontend/app/components/Session/Player/MobilePlayer/MobileControls.tsx b/frontend/app/components/Session/Player/MobilePlayer/MobileControls.tsx index 75d67b53e..5bc1ab3b5 100644 --- a/frontend/app/components/Session/Player/MobilePlayer/MobileControls.tsx +++ b/frontend/app/components/Session/Player/MobilePlayer/MobileControls.tsx @@ -17,6 +17,8 @@ import { } from 'Components/Session_/Player/Controls/components/KeyboardHelp'; import PlayerControls from 'Components/Session_/Player/Controls/components/PlayerControls'; import styles from 'Components/Session_/Player/Controls/controls.module.css'; +import { fetchSessions } from 'Duck/liveSearch'; +import { Tooltip } from 'UI'; import { CONSOLE, EXCEPTIONS, @@ -24,17 +26,10 @@ import { OVERVIEW, PERFORMANCE, STACKEVENTS, - changeSkipInterval, - fullscreenOff, - fullscreenOn, - toggleBottomBlock, -} from 'Duck/components/player'; -import { fetchSessions } from 'Duck/liveSearch'; -import { Tooltip } from 'UI'; - -import { useStore } from '../../../../mstore'; -import { session as sessionRoute, withSiteId } from '../../../../routes'; -import { SummaryButton } from '../../../Session_/Player/Controls/Controls'; +} from 'App/mstore/uiPlayerStore'; +import { useStore } from 'App/mstore'; +import { session as sessionRoute, withSiteId } from 'App/routes'; +import { SummaryButton } from 'Components/Session_/Player/Controls/Controls'; import useShortcuts from '../ReplayPlayer/useShortcuts'; export const SKIP_INTERVALS = { @@ -51,13 +46,15 @@ function Controls(props: any) { const { player, store } = React.useContext(MobilePlayerContext); const history = useHistory(); const { playing, completed, skip, speed, messagesLoading } = store.get(); - + const { uiPlayerStore } = useStore(); + const fullscreen = uiPlayerStore.fullscreen; + const bottomBlock = uiPlayerStore.bottomBlock; + const toggleBottomBlock = uiPlayerStore.toggleBottomBlock + const fullscreenOn = uiPlayerStore.fullscreenOn; + const fullscreenOff = uiPlayerStore.fullscreenOff; + const changeSkipInterval = uiPlayerStore.changeSkipInterval; + const skipInterval = uiPlayerStore.skipInterval; const { - bottomBlock, - toggleBottomBlock, - fullscreen, - changeSkipInterval, - skipInterval, session, setActiveTab, previousSessionId, @@ -79,8 +76,8 @@ function Controls(props: any) { useShortcuts({ skipInterval, - fullScreenOn: props.fullscreenOn, - fullScreenOff: props.fullscreenOff, + fullScreenOn: fullscreenOn, + fullScreenOff: fullscreenOff, toggleBottomBlock, openNextSession: nextHandler, openPrevSession: prevHandler, @@ -151,7 +148,7 @@ function Controls(props: any) { > { const { aiSummaryStore } = useStore(); + const { store, player } = React.useContext(MobilePlayerContext); const { @@ -287,31 +285,14 @@ export default connect( const isEnterprise = state.getIn(['user', 'account', 'edition']) === 'ee'; return { disableDevtools: isEnterprise && !(permissions.includes('DEV_TOOLS') || permissions.includes('SERVICE_DEV_TOOLS')), - fullscreen: state.getIn(['player', 'fullscreen']), - bottomBlock: state.getIn(['player', 'bottomBlock']), - showStorageRedux: !state.getIn([ - 'player', - 'hiddenHints', - 'storage', - ]), - showStackRedux: !state.getIn([ - 'player', - 'hiddenHints', - 'stack', - ]), session: state.getIn(['sessions', 'current']), totalAssistSessions: state.getIn(['liveSearch', 'total']), - skipInterval: state.getIn(['player', 'skipInterval']), previousSessionId: state.getIn(['sessions', 'previousId']), nextSessionId: state.getIn(['sessions', 'nextId']), siteId: state.getIn(['site', 'siteId']), }; }, { - fullscreenOn, - fullscreenOff, - toggleBottomBlock, fetchSessions, - changeSkipInterval, } )(ControlPlayer); diff --git a/frontend/app/components/Session/Player/MobilePlayer/MobileOverlay.tsx b/frontend/app/components/Session/Player/MobilePlayer/MobileOverlay.tsx index 00de8365a..9ed68b5df 100644 --- a/frontend/app/components/Session/Player/MobilePlayer/MobileOverlay.tsx +++ b/frontend/app/components/Session/Player/MobilePlayer/MobileOverlay.tsx @@ -4,8 +4,7 @@ import { PERFORMANCE, STACKEVENTS, STORAGE, - toggleBottomBlock, -} from 'Duck/components/player'; +} from 'App/mstore/uiPlayerStore'; import React from 'react'; import AutoplayTimer from 'Components/Session_/Player/Overlay/AutoplayTimer'; import PlayIconLayer from 'Components/Session_/Player/Overlay/PlayIconLayer'; @@ -14,14 +13,13 @@ import { PlayerContext } from 'App/components/Session/playerContext'; import { observer } from 'mobx-react-lite'; import { Dropdown } from 'antd'; import type { MenuProps } from 'antd'; -import { connect } from 'react-redux'; import { Icon } from 'UI'; +import { useStore } from 'App/mstore' interface Props { nextId?: string; closedLive?: boolean; isClickmap?: boolean; - toggleBottomBlock: (block: number) => void; } enum ItemKey { @@ -62,9 +60,10 @@ const menuItems: MenuProps['items'] = [ }, ]; -function Overlay({ nextId, isClickmap, toggleBottomBlock }: Props) { +function Overlay({ nextId, isClickmap }: Props) { const { player, store } = React.useContext(PlayerContext); - + const { uiPlayerStore } = useStore(); + const toggleBottomBlock = uiPlayerStore.toggleBottomBlock; const togglePlay = () => player.togglePlay(); const { playing, messagesLoading, completed, autoplay } = store.get(); const loading = messagesLoading @@ -110,6 +109,4 @@ function Overlay({ nextId, isClickmap, toggleBottomBlock }: Props) { ); } -export default connect(null, { - toggleBottomBlock, -})(observer(Overlay)); +export default observer(Overlay); diff --git a/frontend/app/components/Session/Player/MobilePlayer/PerfWarnings.tsx b/frontend/app/components/Session/Player/MobilePlayer/PerfWarnings.tsx index 235fffa6b..91d3d5e5f 100644 --- a/frontend/app/components/Session/Player/MobilePlayer/PerfWarnings.tsx +++ b/frontend/app/components/Session/Player/MobilePlayer/PerfWarnings.tsx @@ -1,12 +1,12 @@ -import {IosPerformanceEvent} from "Player/web/messages"; +import { MobilePerformanceEvent } from "Player/web/messages"; import React from 'react'; import { MobilePlayerContext } from 'App/components/Session/playerContext'; import { observer } from 'mobx-react-lite'; import { Icon } from 'UI'; import { mapIphoneModel } from 'Player/mobile/utils'; import cn from 'classnames'; -import { connect } from 'react-redux'; -import { NONE } from 'Duck/components/player'; +import { NONE } from 'App/mstore/uiPlayerStore'; +import { useStore } from "App/mstore"; type warningsType = | 'thermalState' @@ -38,13 +38,14 @@ const elements = { }, } as const; -function PerfWarnings({ userDevice, bottomBlock }: { userDevice: string; bottomBlock: number }) { +function PerfWarnings({ userDevice }: { userDevice: string }) { const { store } = React.useContext(MobilePlayerContext); + const { uiPlayerStore } = useStore(); const { scale, performanceListNow, performanceList } = store.get() - + const bottomBlock = uiPlayerStore.bottomBlock; const allElements = Object.keys(elements) as warningsType[]; const list = React.useMemo(() => allElements - .filter(el => performanceList.findIndex((pw: IosPerformanceEvent & { techName: warningsType }) => pw.techName === el) !== -1) + .filter(el => performanceList.findIndex((pw: MobilePerformanceEvent & { techName: warningsType }) => pw.techName === el) !== -1) , [performanceList.length]) const contStyles = { @@ -105,6 +106,4 @@ function PerfWarnings({ userDevice, bottomBlock }: { userDevice: string; bottomB ); } -export default connect((state: any) => ({ - bottomBlock: state.getIn(['player', 'bottomBlock']), -}))(observer(PerfWarnings)); +export default observer(PerfWarnings); diff --git a/frontend/app/components/Session/Player/MobilePlayer/PlayerBlock.tsx b/frontend/app/components/Session/Player/MobilePlayer/PlayerBlock.tsx index fe3bf6f8d..d2e7e3f45 100644 --- a/frontend/app/components/Session/Player/MobilePlayer/PlayerBlock.tsx +++ b/frontend/app/components/Session/Player/MobilePlayer/PlayerBlock.tsx @@ -3,7 +3,8 @@ import cn from 'classnames'; import { connect } from 'react-redux'; import Player from './PlayerInst'; import MobilePlayerSubheader from './MobilePlayerSubheader'; - +import { useStore } from 'App/mstore' +import { observer } from 'mobx-react-lite'; import styles from 'Components/Session_/playerBlock.module.css'; interface IProps { @@ -17,14 +18,14 @@ interface IProps { function PlayerBlock(props: IProps) { const { - fullscreen, sessionId, activeTab, jiraConfig, fullView = false, setActiveTab, } = props; - + const { uiPlayerStore } = useStore(); + const fullscreen = uiPlayerStore.fullscreen; const shouldShowSubHeader = !fullscreen && !fullView return (
({ - fullscreen: state.getIn(['player', 'fullscreen']), sessionId: state.getIn(['sessions', 'current']).sessionId, jiraConfig: state.getIn(['issues', 'list'])[0], -}))(PlayerBlock) \ No newline at end of file +}))(observer(PlayerBlock)) \ No newline at end of file diff --git a/frontend/app/components/Session/Player/MobilePlayer/PlayerInst.tsx b/frontend/app/components/Session/Player/MobilePlayer/PlayerInst.tsx index 19080b4e8..79a3fee1a 100644 --- a/frontend/app/components/Session/Player/MobilePlayer/PlayerInst.tsx +++ b/frontend/app/components/Session/Player/MobilePlayer/PlayerInst.tsx @@ -11,8 +11,7 @@ import { PERFORMANCE, EXCEPTIONS, OVERVIEW, - fullscreenOff, -} from 'Duck/components/player'; +} from 'App/mstore/uiPlayerStore'; import { MobileNetworkPanel } from 'Shared/DevTools/NetworkPanel'; import { MobilePerformance } from 'Components/Session_/Performance'; import { MobileExceptions } from 'Components/Session_/Exceptions/Exceptions'; @@ -27,13 +26,12 @@ import { MobileStackEventPanel } from 'Shared/DevTools/StackEventPanel'; import ReplayWindow from "Components/Session/Player/MobilePlayer/ReplayWindow"; import PerfWarnings from "Components/Session/Player/MobilePlayer/PerfWarnings"; import { debounceUpdate, getDefaultPanelHeight } from "Components/Session/Player/ReplayPlayer/PlayerInst"; +import { observer } from 'mobx-react-lite'; +import { useStore } from 'App/mstore'; interface IProps { fullView: boolean; isMultiview?: boolean; - bottomBlock: number; - fullscreen: boolean; - fullscreenOff: () => any; nextId: string; sessionId: string; activeTab: string; @@ -50,10 +48,7 @@ function Player(props: IProps) { const defaultHeight = getDefaultPanelHeight() const [panelHeight, setPanelHeight] = React.useState(defaultHeight); const { - fullscreen, - fullscreenOff, nextId, - bottomBlock, activeTab, fullView, videoURL, @@ -62,6 +57,10 @@ function Player(props: IProps) { screenHeight, platform, } = props; + const { uiPlayerStore } = useStore(); + const fullscreenOff = uiPlayerStore.fullscreenOff; + const fullscreen = uiPlayerStore.fullscreen; + const bottomBlock = uiPlayerStore.bottomBlock; const playerContext = React.useContext(MobilePlayerContext); const isReady = playerContext.store.get().ready const screenWrapper = React.useRef(null); @@ -169,18 +168,15 @@ function Player(props: IProps) { export default connect( (state: any) => ({ - fullscreen: state.getIn(['player', 'fullscreen']), nextId: state.getIn(['sessions', 'nextId']), sessionId: state.getIn(['sessions', 'current']).sessionId, userDevice: state.getIn(['sessions', 'current']).userDevice, videoURL: state.getIn(['sessions', 'current']).videoURL, - bottomBlock: state.getIn(['player', 'bottomBlock']), platform: state.getIn(['sessions', 'current']).platform, screenWidth: state.getIn(['sessions', 'current']).screenWidth, screenHeight: state.getIn(['sessions', 'current']).screenHeight, }), { - fullscreenOff, updateLastPlayedSession, } -)(Player); +)(observer(Player)); diff --git a/frontend/app/components/Session/Player/ReplayPlayer/PlayerBlock.tsx b/frontend/app/components/Session/Player/ReplayPlayer/PlayerBlock.tsx index 176ba549a..c424d7a47 100644 --- a/frontend/app/components/Session/Player/ReplayPlayer/PlayerBlock.tsx +++ b/frontend/app/components/Session/Player/ReplayPlayer/PlayerBlock.tsx @@ -1,12 +1,15 @@ -import React from 'react'; import cn from 'classnames'; +import { observer } from 'mobx-react-lite'; +import React from 'react'; import { connect } from 'react-redux'; -import Player from './PlayerInst'; + +import { useStore } from 'App/mstore'; import SubHeader from 'Components/Session_/Subheader'; import styles from 'Components/Session_/playerBlock.module.css'; +import Player from './PlayerInst'; + interface IProps { - fullscreen: boolean; sessionId: string; activeTab: string; jiraConfig: Record; @@ -15,21 +18,33 @@ interface IProps { } function PlayerBlock(props: IProps) { - const { fullscreen, sessionId, activeTab, jiraConfig, fullView = false, setActiveTab } = props; - + const { + sessionId, + activeTab, + jiraConfig, + fullView = false, + setActiveTab, + } = props; + const { uiPlayerStore } = useStore(); + const fullscreen = uiPlayerStore.fullscreen; const shouldShowSubHeader = !fullscreen && !fullView; return ( -
- {shouldShowSubHeader - ? - : null} - +
+ {shouldShowSubHeader ? ( + + ) : null} +
); } export default connect((state: Record) => ({ - fullscreen: state.getIn(['player', 'fullscreen']), sessionId: state.getIn(['sessions', 'current']).sessionId, jiraConfig: state.getIn(['issues', 'list'])[0], -}))(PlayerBlock); +}))(observer(PlayerBlock)); diff --git a/frontend/app/components/Session/Player/ReplayPlayer/PlayerInst.tsx b/frontend/app/components/Session/Player/ReplayPlayer/PlayerInst.tsx index 3a26b37b0..492830801 100644 --- a/frontend/app/components/Session/Player/ReplayPlayer/PlayerInst.tsx +++ b/frontend/app/components/Session/Player/ReplayPlayer/PlayerInst.tsx @@ -16,8 +16,7 @@ import { EXCEPTIONS, INSPECTOR, OVERVIEW, - fullscreenOff, -} from 'Duck/components/player'; +} from 'App/mstore/uiPlayerStore'; import { WebNetworkPanel } from 'Shared/DevTools/NetworkPanel'; import Storage from 'Components/Session_/Storage'; import { ConnectedPerformance } from 'Components/Session_/Performance'; @@ -34,13 +33,11 @@ import ProfilerPanel from 'Shared/DevTools/ProfilerPanel'; import { PlayerContext } from 'App/components/Session/playerContext'; import { debounce } from 'App/utils'; import { observer } from 'mobx-react-lite'; +import { useStore } from 'App/mstore'; interface IProps { fullView: boolean; isMultiview?: boolean; - bottomBlock: number; - fullscreen: boolean; - fullscreenOff: () => any; nextId: string; sessionId: string; activeTab: string; @@ -63,9 +60,13 @@ export const getDefaultPanelHeight = () => { } function Player(props: IProps) { + const { uiPlayerStore } = useStore(); + const fullscreenOff = uiPlayerStore.fullscreenOff; + const bottomBlock = uiPlayerStore.bottomBlock; + const fullscreen = uiPlayerStore.fullscreen; const defaultHeight = getDefaultPanelHeight() const [panelHeight, setPanelHeight] = React.useState(defaultHeight); - const { fullscreen, fullscreenOff, nextId, bottomBlock, activeTab, fullView } = props; + const { nextId, activeTab, fullView } = props; const playerContext = React.useContext(PlayerContext); const isReady = playerContext.store.get().ready; const screenWrapper = React.useRef(null); @@ -83,7 +84,7 @@ function Player(props: IProps) { React.useEffect(() => { playerContext.player.scale(); - }, [props.bottomBlock, props.fullscreen, playerContext.player, activeTab, fullView]); + }, [bottomBlock, fullscreen, playerContext.player, activeTab, fullView]); if (!playerContext.player) return null; @@ -163,13 +164,10 @@ function Player(props: IProps) { export default connect( (state: any) => ({ - fullscreen: state.getIn(['player', 'fullscreen']), nextId: state.getIn(['sessions', 'nextId']), sessionId: state.getIn(['sessions', 'current']).sessionId, - bottomBlock: state.getIn(['player', 'bottomBlock']), }), { - fullscreenOff, updateLastPlayedSession, } )(observer(Player)); diff --git a/frontend/app/components/Session/Player/ReplayPlayer/SummaryBlock/index.tsx b/frontend/app/components/Session/Player/ReplayPlayer/SummaryBlock/index.tsx index ee8c49476..fcd58bd5d 100644 --- a/frontend/app/components/Session/Player/ReplayPlayer/SummaryBlock/index.tsx +++ b/frontend/app/components/Session/Player/ReplayPlayer/SummaryBlock/index.tsx @@ -19,22 +19,18 @@ function isTitleLine(line: string): boolean { function SummaryBlock({ sessionId, - zoomEnabled, - zoomStartTs, - zoomEndTs, - zoomTab, duration, }: { sessionId: string; - zoomEnabled: boolean; - zoomStartTs: number; - zoomEndTs: number; - zoomTab: 'overview' | 'journey' | 'issues' | 'errors'; duration: any; }) { const { store } = React.useContext(PlayerContext) const { tabStates } = store.get(); - const { aiSummaryStore } = useStore(); + const { aiSummaryStore, uiPlayerStore } = useStore(); + const zoomEnabled = uiPlayerStore.timelineZoom.enabled; + const zoomStartTs = uiPlayerStore.timelineZoom.startTs; + const zoomEndTs = uiPlayerStore.timelineZoom.endTs; + const zoomTab = uiPlayerStore.zoomTab; React.useEffect(() => { debounceUpdate = debounce( @@ -155,9 +151,5 @@ const summaryBlockStyle: React.CSSProperties = { }; export default connect((state: Record) => ({ - zoomEnabled: state.getIn(['player']).timelineZoom.enabled, - zoomStartTs: state.getIn(['player']).timelineZoom.startTs, - zoomEndTs: state.getIn(['player']).timelineZoom.endTs, - zoomTab: state.getIn(['player']).zoomTab, duration: state.getIn(['sessions', 'current']).durationSeconds, }))(observer(SummaryBlock)); diff --git a/frontend/app/components/Session/Player/ReplayPlayer/useShortcuts.ts b/frontend/app/components/Session/Player/ReplayPlayer/useShortcuts.ts index 0c7e8fdb2..44f264711 100644 --- a/frontend/app/components/Session/Player/ReplayPlayer/useShortcuts.ts +++ b/frontend/app/components/Session/Player/ReplayPlayer/useShortcuts.ts @@ -4,7 +4,7 @@ import { toast } from 'react-toastify'; import { PlayerContext } from 'Components/Session/playerContext'; import { SKIP_INTERVALS } from 'Components/Session_/Player/Controls/Controls'; -import { blockValues, blocks } from 'Duck/components/player'; +import { blockValues, blocks } from 'App/mstore/uiPlayerStore'; function useShortcuts({ skipInterval, diff --git a/frontend/app/components/Session/WebPlayer.tsx b/frontend/app/components/Session/WebPlayer.tsx index d98674f39..93970d515 100644 --- a/frontend/app/components/Session/WebPlayer.tsx +++ b/frontend/app/components/Session/WebPlayer.tsx @@ -9,7 +9,6 @@ import { toast } from 'react-toastify'; import { useStore } from 'App/mstore'; import { Note } from 'App/services/NotesService'; -import { closeBottomBlock, toggleFullscreen } from 'Duck/components/player'; import { fetchList } from 'Duck/integrations'; import { Loader, Modal } from 'UI'; @@ -37,13 +36,13 @@ let playerInst: IPlayerContext['player'] | undefined; function WebPlayer(props: any) { const { session, - toggleFullscreen, - closeBottomBlock, - fullscreen, fetchList, startedAt, } = props; - const { notesStore, sessionStore, uxtestingStore } = useStore(); + const { notesStore, sessionStore, uxtestingStore, uiPlayerStore } = useStore(); + const fullscreen = uiPlayerStore.fullscreen; + const toggleFullscreen = uiPlayerStore.toggleFullscreen; + const closeBottomBlock = uiPlayerStore.closeBottomBlock; const [activeTab, setActiveTab] = useState(''); const [noteItem, setNoteItem] = useState(undefined); const [visuallyAdjusted, setAdjusted] = useState(false); @@ -255,13 +254,9 @@ export default connect( prefetched: state.getIn(['sessions', 'prefetched']), visitedEvents: state.getIn(['sessions', 'visitedEvents']), jwt: state.getIn(['user', 'jwt']), - fullscreen: state.getIn(['player', 'fullscreen']), - showEvents: state.get('showEvents'), startedAt: state.getIn(['sessions', 'current']).startedAt || 0, }), { - toggleFullscreen, - closeBottomBlock, fetchList, } )(withLocationHandlers()(observer(WebPlayer))); diff --git a/frontend/app/components/Session_/BottomBlock/Header.js b/frontend/app/components/Session_/BottomBlock/Header.js index 05b361bee..18ef3fe5f 100644 --- a/frontend/app/components/Session_/BottomBlock/Header.js +++ b/frontend/app/components/Session_/BottomBlock/Header.js @@ -1,28 +1,31 @@ import React from 'react'; -import { connect } from 'react-redux'; import cn from 'classnames'; -import { closeBottomBlock } from 'Duck/components/player'; import { CloseButton } from 'UI'; import stl from './header.module.css'; +import { useStore } from 'App/mstore'; const Header = ({ children, className, - closeBottomBlock, onFilterChange, showClose = true, customStyle, customClose, ...props -}) => ( -
-
-
{ children }
- { showClose && } +}) => { + const { uiPlayerStore } = useStore(); + const closeBottomBlock = uiPlayerStore.closeBottomBlock; + + return ( +
+
+
{children}
+ {showClose && } +
-
-); + ) +}; Header.displayName = 'Header'; -export default connect(null, { closeBottomBlock })(Header); +export default Header; diff --git a/frontend/app/components/Session_/EventsBlock/EventsBlock.tsx b/frontend/app/components/Session_/EventsBlock/EventsBlock.tsx index 16d269588..b93410379 100644 --- a/frontend/app/components/Session_/EventsBlock/EventsBlock.tsx +++ b/frontend/app/components/Session_/EventsBlock/EventsBlock.tsx @@ -27,16 +27,15 @@ interface IProps { filterOutNote: (id: string) => void; eventsIndex: number[]; uxtVideo: string; - zoomEnabled: boolean; - zoomStartTs: number; - zoomEndTs: number; } function EventsBlock(props: IProps) { - const { notesStore, uxtestingStore } = useStore(); + const { notesStore, uxtestingStore, uiPlayerStore } = useStore(); const [mouseOver, setMouseOver] = React.useState(false); const scroller = React.useRef(null); - + const zoomEnabled = uiPlayerStore.timelineZoom.enabled; + const zoomStartTs = uiPlayerStore.timelineZoom.startTs; + const zoomEndTs = uiPlayerStore.timelineZoom.endTs; const { store, player } = React.useContext(PlayerContext); const { @@ -88,9 +87,9 @@ function EventsBlock(props: IProps) { filteredLength > 0 ? filteredEvents : eventsWithMobxNotes, tabChangeEvents ).filter((e) => - props.zoomEnabled + zoomEnabled ? 'time' in e - ? e.time >= props.zoomStartTs && e.time <= props.zoomEndTs + ? e.time >= zoomStartTs && e.time <= zoomEndTs : false : true ); @@ -98,9 +97,9 @@ function EventsBlock(props: IProps) { filteredLength, notesWithEvtsLength, notesLength, - props.zoomEnabled, - props.zoomStartTs, - props.zoomEndTs, + zoomEnabled, + zoomStartTs, + zoomEndTs, ]); const findLastFitting = React.useCallback( (time: number) => { @@ -275,9 +274,6 @@ export default connect( filteredEvents: state.getIn(['sessions', 'filteredEvents']), query: state.getIn(['sessions', 'eventsQuery']), eventsIndex: state.getIn(['sessions', 'eventsIndex']), - zoomEnabled: state.getIn(['player']).timelineZoom.enabled, - zoomStartTs: state.getIn(['player']).timelineZoom.startTs, - zoomEndTs: state.getIn(['player']).timelineZoom.endTs, }), { setEventFilter, diff --git a/frontend/app/components/Session_/OverviewPanel/OverviewPanel.tsx b/frontend/app/components/Session_/OverviewPanel/OverviewPanel.tsx index dd4a04113..f5064100d 100644 --- a/frontend/app/components/Session_/OverviewPanel/OverviewPanel.tsx +++ b/frontend/app/components/Session_/OverviewPanel/OverviewPanel.tsx @@ -12,7 +12,6 @@ import { useStore } from 'App/mstore'; import SummaryBlock from 'Components/Session/Player/ReplayPlayer/SummaryBlock'; import { SummaryButton } from 'Components/Session_/Player/Controls/Controls'; import TimelineZoomButton from 'Components/Session_/Player/Controls/components/TimelineZoomButton'; -import { setZoomTab, toggleBottomBlock } from 'Duck/components/player'; import { Icon, NoContent } from 'UI'; import BottomBlock from '../BottomBlock'; @@ -28,21 +27,16 @@ import VerticalPointerLine, { VerticalPointerLineComp } from './components/Verti function MobileOverviewPanelCont({ issuesList, sessionId, - zoomEnabled, - zoomStartTs, - zoomEndTs, - setZoomTab, - zoomTab, }: { issuesList: Record[]; sessionId: string; - zoomEnabled: boolean; - zoomStartTs: number; - zoomEndTs: number; - setZoomTab: (tab: string) => void; - zoomTab: 'overview' | 'journey' | 'issues' | 'errors'; }) { - const { aiSummaryStore } = useStore(); + const { aiSummaryStore, uiPlayerStore } = useStore(); + const zoomEnabled = uiPlayerStore.timelineZoom.enabled; + const zoomStartTs = uiPlayerStore.timelineZoom.startTs; + const zoomEndTs = uiPlayerStore.timelineZoom.endTs; + const setZoomTab = uiPlayerStore.setZoomTab; + const zoomTab = uiPlayerStore.zoomTab; const { store, player } = React.useContext(MobilePlayerContext); const [dataLoaded, setDataLoaded] = React.useState(false); const [selectedFeatures, setSelectedFeatures] = React.useState([ @@ -131,20 +125,15 @@ function MobileOverviewPanelCont({ function WebOverviewPanelCont({ sessionId, - zoomEnabled, - zoomStartTs, - zoomEndTs, - setZoomTab, - zoomTab, }: { sessionId: string; - zoomEnabled: boolean; - zoomStartTs: number; - zoomEndTs: number; - setZoomTab: (tab: string) => void; - zoomTab: 'overview' | 'journey' | 'issues' | 'errors'; }) { - const { aiSummaryStore } = useStore(); + const { aiSummaryStore, uiPlayerStore } = useStore(); + const zoomEnabled = uiPlayerStore.timelineZoom.enabled; + const zoomStartTs = uiPlayerStore.timelineZoom.startTs; + const zoomEndTs = uiPlayerStore.timelineZoom.endTs; + const setZoomTab = uiPlayerStore.setZoomTab; + const zoomTab = uiPlayerStore.zoomTab; const { store } = React.useContext(PlayerContext); const [selectedFeatures, setSelectedFeatures] = React.useState([ 'PERFORMANCE', @@ -386,27 +375,12 @@ export const OverviewPanel = connect( (state: Record) => ({ issuesList: state.getIn(['sessions', 'current']).issues, sessionId: state.getIn(['sessions', 'current']).sessionId, - zoomEnabled: state.getIn(['player']).timelineZoom.enabled, - zoomStartTs: state.getIn(['player']).timelineZoom.startTs, - zoomEndTs: state.getIn(['player']).timelineZoom.endTs, }), - { - toggleBottomBlock, - setZoomTab, - } )(observer(WebOverviewPanelCont)); export const MobileOverviewPanel = connect( (state: Record) => ({ issuesList: state.getIn(['sessions', 'current']).issues, sessionId: state.getIn(['sessions', 'current']).sessionId, - zoomEnabled: state.getIn(['player']).timelineZoom.enabled, - zoomStartTs: state.getIn(['player']).timelineZoom.startTs, - zoomEndTs: state.getIn(['player']).timelineZoom.endTs, - zoomTab: state.getIn(['player']).zoomTab, - }), - { - toggleBottomBlock, - setZoomTab, - } + }) )(observer(MobileOverviewPanelCont)); diff --git a/frontend/app/components/Session_/OverviewPanel/components/TimelinePointer/TimelinePointer.tsx b/frontend/app/components/Session_/OverviewPanel/components/TimelinePointer/TimelinePointer.tsx index d67e03781..028f54922 100644 --- a/frontend/app/components/Session_/OverviewPanel/components/TimelinePointer/TimelinePointer.tsx +++ b/frontend/app/components/Session_/OverviewPanel/components/TimelinePointer/TimelinePointer.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { NETWORK, EXCEPTIONS } from 'Duck/components/player'; +import { NETWORK, EXCEPTIONS } from 'App/mstore/uiPlayerStore'; import { useModal } from 'App/components/Modal'; import { Icon } from 'UI'; import StackEventModal from '../StackEventModal'; diff --git a/frontend/app/components/Session_/Player/Controls/Controls.tsx b/frontend/app/components/Session_/Player/Controls/Controls.tsx index c4577a230..b8bf33365 100644 --- a/frontend/app/components/Session_/Player/Controls/Controls.tsx +++ b/frontend/app/components/Session_/Player/Controls/Controls.tsx @@ -30,11 +30,7 @@ import { PROFILER, STACKEVENTS, STORAGE, - changeSkipInterval, - fullscreenOff, - fullscreenOn, - toggleBottomBlock, -} from 'Duck/components/player'; +} from 'App/mstore/uiPlayerStore'; import { fetchSessions } from 'Duck/liveSearch'; import { Icon } from 'UI'; @@ -74,7 +70,15 @@ function getStorageName(type: any) { function Controls(props: any) { const { player, store } = React.useContext(PlayerContext); - const { uxtestingStore } = useStore(); + const { uxtestingStore, uiPlayerStore } = useStore(); + const fullscreen = uiPlayerStore.fullscreen; + const bottomBlock = uiPlayerStore.bottomBlock; + const toggleBottomBlock = uiPlayerStore.toggleBottomBlock; + const fullscreenOn = uiPlayerStore.fullscreenOn; + const fullscreenOff = uiPlayerStore.fullscreenOff; + const changeSkipInterval = uiPlayerStore.changeSkipInterval; + const skipInterval = uiPlayerStore.skipInterval; + const showStorageRedux = !uiPlayerStore.hiddenHints.storage; const history = useHistory(); const { playing, @@ -87,13 +91,7 @@ function Controls(props: any) { } = store.get(); const { - bottomBlock, - toggleBottomBlock, - fullscreen, - changeSkipInterval, - skipInterval, disableDevtools, - showStorageRedux, session, previousSessionId, nextSessionId, @@ -115,8 +113,8 @@ function Controls(props: any) { useShortcuts({ skipInterval, - fullScreenOn: props.fullscreenOn, - fullScreenOff: props.fullscreenOff, + fullScreenOn: fullscreenOn, + fullScreenOff: fullscreenOff, toggleBottomBlock, openNextSession: nextHandler, openPrevSession: prevHandler, @@ -189,7 +187,7 @@ function Controls(props: any) { (null); const timelineRef = useRef(null); @@ -185,9 +183,6 @@ export default connect( startedAt: state.getIn(['sessions', 'current']).startedAt || 0, timezone: state.getIn(['sessions', 'current']).timezone, tooltipVisible: state.getIn(['sessions', 'timeLineTooltip', 'isVisible']), - timelineZoomEnabled: state.getIn(['player']).timelineZoom.enabled, - timelineZoomStartTs: state.getIn(['player']).timelineZoom.startTs, - timelineZoomEndTs: state.getIn(['player']).timelineZoom.endTs, }), { setTimelinePointer, setTimelineHoverTime } )(observer(Timeline)); diff --git a/frontend/app/components/Session_/Player/Controls/components/TimelineZoomButton.tsx b/frontend/app/components/Session_/Player/Controls/components/TimelineZoomButton.tsx index c2fbd5fe9..5db0182c8 100644 --- a/frontend/app/components/Session_/Player/Controls/components/TimelineZoomButton.tsx +++ b/frontend/app/components/Session_/Player/Controls/components/TimelineZoomButton.tsx @@ -1,18 +1,13 @@ import React from 'react'; -import { connect } from 'react-redux'; import { Button, Tooltip } from 'antd'; -import { toggleZoom } from 'Duck/components/player'; import { PlayerContext } from 'Components/Session/playerContext'; import { observer } from 'mobx-react-lite'; +import { useStore } from 'App/mstore'; -interface Props { - enabled: boolean; - startTs: number; - endTs: number; - toggleZoom: typeof toggleZoom; -} - -function TimelineZoomButton({ enabled, toggleZoom }: Props) { +function TimelineZoomButton() { + const { uiPlayerStore } = useStore(); + const toggleZoom = uiPlayerStore.toggleZoom; + const enabled = uiPlayerStore.timelineZoom.enabled; const { store } = React.useContext(PlayerContext); const onClickHandler = () => { @@ -41,11 +36,4 @@ function TimelineZoomButton({ enabled, toggleZoom }: Props) { ); } -export default connect( - (state: Record) => ({ - enabled: state.getIn(['player']).timelineZoom.enabled, - startTs: state.getIn(['player']).timelineZoom.startTs, - endTs: state.getIn(['player']).timelineZoom.endTs, - }), - { toggleZoom } -)(observer(TimelineZoomButton)); +export default observer(TimelineZoomButton); diff --git a/frontend/app/components/Session_/Player/Controls/components/ZoomDragLayer.tsx b/frontend/app/components/Session_/Player/Controls/components/ZoomDragLayer.tsx index b531d93b6..edbd53a8f 100644 --- a/frontend/app/components/Session_/Player/Controls/components/ZoomDragLayer.tsx +++ b/frontend/app/components/Session_/Player/Controls/components/ZoomDragLayer.tsx @@ -1,22 +1,19 @@ import React, { useCallback, useState } from 'react'; -import { connect } from 'react-redux'; - +import { observer } from 'mobx-react-lite'; +import { useStore } from "App/mstore"; import { getTimelinePosition } from 'Components/Session_/Player/Controls/getTimelinePosition'; -import { toggleZoom } from 'Duck/components/player'; interface Props { - timelineZoomStartTs: number; - timelineZoomEndTs: number; scale: number; - toggleZoom: typeof toggleZoom; } const DraggableMarkers = ({ - timelineZoomStartTs, - timelineZoomEndTs, scale, - toggleZoom, }: Props) => { + const { uiPlayerStore } = useStore(); + const toggleZoom = uiPlayerStore.toggleZoom; + const timelineZoomStartTs = uiPlayerStore.timelineZoom.startTs; + const timelineZoomEndTs = uiPlayerStore.timelineZoom.endTs; const [startPos, setStartPos] = useState( getTimelinePosition(timelineZoomStartTs, scale) ); @@ -195,11 +192,4 @@ const DraggableMarkers = ({ ); }; -export default connect( - (state: Record) => ({ - timelineZoomStartTs: state.getIn(['player']).timelineZoom - .startTs, - timelineZoomEndTs: state.getIn(['player']).timelineZoom.endTs, - }), - { toggleZoom } -)(DraggableMarkers); +export default observer(DraggableMarkers); diff --git a/frontend/app/components/Session_/Player/Overlay.tsx b/frontend/app/components/Session_/Player/Overlay.tsx index fda1a2403..2aaec6f59 100644 --- a/frontend/app/components/Session_/Player/Overlay.tsx +++ b/frontend/app/components/Session_/Player/Overlay.tsx @@ -14,8 +14,7 @@ import { PERFORMANCE, STACKEVENTS, STORAGE, - toggleBottomBlock, -} from 'Duck/components/player'; +} from 'App/mstore/uiPlayerStore'; import { Icon } from 'UI'; import { useModal } from '../../Modal'; @@ -24,12 +23,12 @@ import AutoplayTimer from './Overlay/AutoplayTimer'; import ElementsMarker from './Overlay/ElementsMarker'; import Loader from './Overlay/Loader'; import PlayIconLayer from './Overlay/PlayIconLayer'; +import { useStore } from 'App/mstore' interface Props { nextId?: string; closedLive?: boolean; isClickmap?: boolean; - toggleBottomBlock: (block: number) => void; } enum ItemKey { @@ -87,9 +86,10 @@ const menuItems: MenuProps['items'] = [ }, ]; -function Overlay({ nextId, isClickmap, toggleBottomBlock }: Props) { +function Overlay({ nextId, isClickmap }: Props) { const { player, store } = React.useContext(PlayerContext); - + const { uiPlayerStore } = useStore(); + const toggleBottomBlock = uiPlayerStore.toggleBottomBlock; const togglePlay = () => player.togglePlay(); const { playing, @@ -178,6 +178,4 @@ function Overlay({ nextId, isClickmap, toggleBottomBlock }: Props) { ); } -export default connect(null, { - toggleBottomBlock, -})(observer(Overlay)); +export default observer(Overlay); diff --git a/frontend/app/components/Session_/Storage/Storage.tsx b/frontend/app/components/Session_/Storage/Storage.tsx index ec87e436d..2b138728e 100644 --- a/frontend/app/components/Session_/Storage/Storage.tsx +++ b/frontend/app/components/Session_/Storage/Storage.tsx @@ -1,6 +1,5 @@ import React from 'react'; -import { connect } from 'react-redux'; -import { hideHint } from 'Duck/components/player'; +import { useStore } from 'App/mstore' import { PlayerContext } from 'App/components/Session/playerContext'; import { observer } from 'mobx-react-lite'; import { JSONTree, NoContent, Tooltip } from 'UI'; @@ -33,12 +32,11 @@ const storageDecodeKeys = { [STORAGE_TYPES.MOBX]: ['payload'], [STORAGE_TYPES.NONE]: ['state, action', 'payload', 'mutation'], } -interface Props { - hideHint: (args: string) => void; - hintIsHidden: boolean; -} -function Storage(props: Props) { +function Storage() { + const { uiPlayerStore } = useStore(); + const hintIsHidden = uiPlayerStore.hiddenHints.storage; + const hideHint = uiPlayerStore.hideHint; const lastBtnRef = React.useRef(); const [showDiffs, setShowDiffs] = React.useState(false); const [stateObject, setState] = React.useState({}); @@ -223,8 +221,6 @@ function Storage(props: Props) { ); }; - const { hintIsHidden } = props; - if (type === STORAGE_TYPES.REDUX) { return } @@ -311,7 +307,7 @@ function Storage(props: Props) { .

- @@ -344,14 +340,7 @@ function Storage(props: Props) { ); } -export default connect( - (state: any) => ({ - hintIsHidden: state.getIn(['player', 'hiddenHints', 'storage']), - }), - { - hideHint, - } -)(observer(Storage)); +export default observer(Storage); /** diff --git a/frontend/app/components/shared/DevTools/BottomBlock/Header.tsx b/frontend/app/components/shared/DevTools/BottomBlock/Header.tsx index 5d9ae4b87..ccb233416 100644 --- a/frontend/app/components/shared/DevTools/BottomBlock/Header.tsx +++ b/frontend/app/components/shared/DevTools/BottomBlock/Header.tsx @@ -1,9 +1,8 @@ import { Tooltip } from 'antd'; import cn from 'classnames'; import React from 'react'; -import { connect } from 'react-redux'; -import { closeBottomBlock } from 'Duck/components/player'; +import { useStore } from 'App/mstore'; import { CloseButton } from 'UI'; import stl from './header.module.css'; @@ -11,7 +10,6 @@ import stl from './header.module.css'; const Header = ({ children, className, - closeBottomBlock, onClose, onFilterChange, showClose = true, @@ -19,32 +17,37 @@ const Header = ({ }: { children?: React.ReactNode; className?: string; - closeBottomBlock?: () => void; onFilterChange?: (e: React.ChangeEvent) => void; showClose?: boolean; onClose?: () => void; -}) => ( -
-
-
{children}
- {showClose && ( - - - - )} +}) => { + const { uiPlayerStore } = useStore(); + const closeBottomBlock = uiPlayerStore.closeBottomBlock; + return ( +
+
+
+ {children} +
+ {showClose && ( + + + + )} +
-
-); + ); +}; Header.displayName = 'Header'; -export default connect(null, { closeBottomBlock })(Header); +export default Header; diff --git a/frontend/app/components/shared/DevTools/ConsolePanel/ConsolePanel.tsx b/frontend/app/components/shared/DevTools/ConsolePanel/ConsolePanel.tsx index 2329b0138..8d97c4609 100644 --- a/frontend/app/components/shared/DevTools/ConsolePanel/ConsolePanel.tsx +++ b/frontend/app/components/shared/DevTools/ConsolePanel/ConsolePanel.tsx @@ -11,7 +11,6 @@ import ErrorDetailsModal from 'App/components/Dashboard/components/Errors/ErrorD import { useModal } from 'App/components/Modal'; import useAutoscroll, { getLastItemTime } from '../useAutoscroll'; import { useRegExListFilterMemo, useTabListFilterMemo } from '../useListFilter'; -import { connect } from 'react-redux'; import { VList, VListHandle } from "virtua"; const ALL = 'ALL'; @@ -87,18 +86,16 @@ const INDEX_KEY = 'console'; function ConsolePanel({ isLive, - zoomEnabled, - zoomStartTs, - zoomEndTs, }: { isLive?: boolean; - zoomEnabled: boolean; - zoomStartTs: number; - zoomEndTs: number; }) { const { sessionStore: { devTools }, + uiPlayerStore, } = useStore(); + const zoomEnabled = uiPlayerStore.timelineZoom.enabled; + const zoomStartTs = uiPlayerStore.timelineZoom.startTs; + const zoomEndTs = uiPlayerStore.timelineZoom.endTs; const _list = useRef(null); const filter = devTools[INDEX_KEY].filter; @@ -224,8 +221,4 @@ function ConsolePanel({ ); } -export default connect((state: Record) => ({ - zoomEnabled: state.getIn(['player']).timelineZoom.enabled, - zoomStartTs: state.getIn(['player']).timelineZoom.startTs, - zoomEndTs: state.getIn(['player']).timelineZoom.endTs, -}))(observer(ConsolePanel)); +export default observer(ConsolePanel); diff --git a/frontend/app/components/shared/DevTools/NetworkPanel/NetworkPanel.tsx b/frontend/app/components/shared/DevTools/NetworkPanel/NetworkPanel.tsx index 3001d3449..f53c1364f 100644 --- a/frontend/app/components/shared/DevTools/NetworkPanel/NetworkPanel.tsx +++ b/frontend/app/components/shared/DevTools/NetworkPanel/NetworkPanel.tsx @@ -180,15 +180,9 @@ function renderStatus({ function NetworkPanelCont({ startedAt, panelHeight, - zoomEnabled, - zoomStartTs, - zoomEndTs, }: { startedAt: number; panelHeight: number; - zoomEnabled: boolean; - zoomStartTs: number; - zoomEndTs: number; }) { const { player, store } = React.useContext(PlayerContext); @@ -229,18 +223,15 @@ function NetworkPanelCont({ function MobileNetworkPanelCont({ startedAt, panelHeight, - zoomEnabled, - zoomStartTs, - zoomEndTs, }: { startedAt: number; panelHeight: number; - zoomEnabled: boolean; - zoomStartTs: number; - zoomEndTs: number; }) { const { player, store } = React.useContext(MobilePlayerContext); - + const { uiPlayerStore } = useStore(); + const zoomEnabled = uiPlayerStore.timelineZoom.enabled; + const zoomStartTs = uiPlayerStore.timelineZoom.startTs; + const zoomEndTs = uiPlayerStore.timelineZoom.endTs; const domContentLoadedTime = undefined; const loadTime = undefined; const domBuildingTime = undefined; @@ -304,7 +295,7 @@ interface Props { player: WebPlayer | MobilePlayer; startedAt: number; isMobile?: boolean; - zoomEnabled: boolean; + zoomEnabled?: boolean; zoomStartTs?: number; zoomEndTs?: number; panelHeight: number; @@ -680,16 +671,10 @@ export const NetworkPanelComp = observer( const WebNetworkPanel = connect((state: any) => ({ startedAt: state.getIn(['sessions', 'current']).startedAt, - zoomEnabled: state.getIn(['player']).timelineZoom.enabled, - zoomStartTs: state.getIn(['player']).timelineZoom.startTs, - zoomEndTs: state.getIn(['player']).timelineZoom.endTs, }))(observer(NetworkPanelCont)); const MobileNetworkPanel = connect((state: any) => ({ startedAt: state.getIn(['sessions', 'current']).startedAt, - zoomEnabled: state.getIn(['player']).timelineZoom.enabled, - zoomStartTs: state.getIn(['player']).timelineZoom.startTs, - zoomEndTs: state.getIn(['player']).timelineZoom.endTs, }))(observer(MobileNetworkPanelCont)); export { WebNetworkPanel, MobileNetworkPanel }; diff --git a/frontend/app/components/shared/DevTools/StackEventPanel/StackEventPanel.tsx b/frontend/app/components/shared/DevTools/StackEventPanel/StackEventPanel.tsx index b2f36f04c..d50d6aab9 100644 --- a/frontend/app/components/shared/DevTools/StackEventPanel/StackEventPanel.tsx +++ b/frontend/app/components/shared/DevTools/StackEventPanel/StackEventPanel.tsx @@ -28,15 +28,11 @@ const TABS = TAB_KEYS.map((tab) => ({ text: tab, key: tab })); type EventsList = Array; const WebStackEventPanelComp = observer( - ({ - zoomEnabled, - zoomStartTs, - zoomEndTs, - }: { - zoomEnabled: boolean; - zoomStartTs: number; - zoomEndTs: number; - }) => { + () => { + 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(); @@ -56,22 +52,14 @@ const WebStackEventPanelComp = observer( } ); -export const WebStackEventPanel = connect((state: Record) => ({ - zoomEnabled: state.getIn(['player']).timelineZoom.enabled, - zoomStartTs: state.getIn(['player']).timelineZoom.startTs, - zoomEndTs: state.getIn(['player']).timelineZoom.endTs, -}))(WebStackEventPanelComp); +export const WebStackEventPanel = WebStackEventPanelComp; const MobileStackEventPanelComp = observer( - ({ - zoomEnabled, - zoomStartTs, - zoomEndTs, - }: { - zoomEnabled: boolean; - zoomStartTs: number; - zoomEndTs: number; - }) => { + () => { + 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(); @@ -89,11 +77,7 @@ const MobileStackEventPanelComp = observer( } ); -export const MobileStackEventPanel = connect((state: Record) => ({ - zoomEnabled: state.getIn(['player']).timelineZoom.enabled, - zoomStartTs: state.getIn(['player']).timelineZoom.startTs, - zoomEndTs: state.getIn(['player']).timelineZoom.endTs, -}))(MobileStackEventPanelComp); +export const MobileStackEventPanel = MobileStackEventPanelComp; function EventsPanel({ list, diff --git a/frontend/app/duck/components/player.ts b/frontend/app/duck/components/player.ts deleted file mode 100644 index 6be257b85..000000000 --- a/frontend/app/duck/components/player.ts +++ /dev/null @@ -1,140 +0,0 @@ -import { PayloadAction, createSlice } from '@reduxjs/toolkit'; - -interface PlayerState { - fullscreen: boolean; - bottomBlock: number; - hiddenHints: { - storage?: string; - stack?: string; - }; - skipInterval: number; - timelineZoom: { - enabled: boolean; - startTs: number; - endTs: number; - }; - zoomTab: 'overview' | 'journey' | 'issues' | 'errors'; -} - -const initialState: PlayerState = { - fullscreen: false, - bottomBlock: 0, - hiddenHints: { - storage: localStorage.getItem('storageHideHint') || undefined, - stack: localStorage.getItem('stackHideHint') || undefined, - }, - skipInterval: parseInt(localStorage.getItem('CHANGE_SKIP_INTERVAL') || '10', 10), - timelineZoom: { - enabled: false, - startTs: 0, - endTs: 0, - }, - zoomTab: 'overview', -}; - -export const playerSlice = createSlice({ - name: 'player', - initialState, - reducers: { - toggleFullscreen: (state, action: PayloadAction) => { - state.fullscreen = action.payload !== undefined ? action.payload : !state.fullscreen; - }, - fullscreenOff: (state) => { - state.fullscreen = false; - }, - fullscreenOn: (state) => { - state.fullscreen = true; - }, - toggleBottomBlock: (state, action: PayloadAction) => { - state.bottomBlock = - state.bottomBlock !== action.payload && action.payload !== 0 ? action.payload : 0; - }, - closeBottomBlock: (state) => { - state.bottomBlock = 0; - }, - changeSkipInterval: (state, action: PayloadAction) => { - const skipInterval = action.payload; - localStorage.setItem('CHANGE_SKIP_INTERVAL', skipInterval.toString()); - state.skipInterval = skipInterval; - }, - hideHint: (state, action: PayloadAction<'storage' | 'stack'>) => { - const name = action.payload; - localStorage.setItem(`${name}HideHint`, 'true'); - state.hiddenHints[name] = 'true'; - state.bottomBlock = 0; - }, - toggleZoom: (state, action: PayloadAction) => { - const { enabled, range } = action.payload; - state.timelineZoom = { - enabled, - startTs: Math.round(range?.[0] ?? 0), - endTs: Math.round(range?.[1] ?? 0), - }; - }, - setZoomTab: (state, action: PayloadAction<'overview' | 'journey' | 'issues' | 'errors'>) => { - state.zoomTab = action.payload; - }, - }, -}); - -interface ToggleZoomPayload { - enabled: boolean; - range?: [number, number]; -} - -export const { - toggleFullscreen, - toggleBottomBlock, - changeSkipInterval, - hideHint, - toggleZoom, - setZoomTab, - closeBottomBlock, - fullscreenOff, - fullscreenOn, -} = playerSlice.actions; - -export default playerSlice.reducer; - -export const NONE = 0; -export const CONSOLE = 1; -export const NETWORK = 2; -export const STACKEVENTS = 3; -export const STORAGE = 4; -export const PROFILER = 5; -export const PERFORMANCE = 6; -export const GRAPHQL = 7; -export const FETCH = 8; -export const EXCEPTIONS = 9; -export const INSPECTOR = 11; -export const OVERVIEW = 12; - -export const blocks = { - none: NONE, - console: CONSOLE, - network: NETWORK, - stackEvents: STACKEVENTS, - storage: STORAGE, - profiler: PROFILER, - performance: PERFORMANCE, - graphql: GRAPHQL, - fetch: FETCH, - exceptions: EXCEPTIONS, - inspector: INSPECTOR, - overview: OVERVIEW, -} as const; - -export const blockValues = [ - NONE, - CONSOLE, - NETWORK, - STACKEVENTS, - STORAGE, - PROFILER, - PERFORMANCE, - GRAPHQL, - FETCH, - EXCEPTIONS, - INSPECTOR, - OVERVIEW, -] as const; diff --git a/frontend/app/duck/index.ts b/frontend/app/duck/index.ts index 193e843ba..1e19955d3 100644 --- a/frontend/app/duck/index.ts +++ b/frontend/app/duck/index.ts @@ -6,7 +6,6 @@ import sessions from './sessions'; import assignments from './assignments'; import filters from './filters'; import funnelFilters from './funnelFilters'; -import player from './components/player' import sources from './sources'; import site from './site'; import customFields from './customField'; @@ -23,7 +22,6 @@ const rootReducer = combineReducers({ assignments, filters, funnelFilters, - player, site, customFields, errors, diff --git a/frontend/app/mstore/index.tsx b/frontend/app/mstore/index.tsx index 0faf86249..bed726abd 100644 --- a/frontend/app/mstore/index.tsx +++ b/frontend/app/mstore/index.tsx @@ -24,6 +24,7 @@ import AiFiltersStore from "./aiFiltersStore"; import SpotStore from "./spotStore"; import LoginStore from "./loginStore"; import FilterStore from "./filterStore"; +import UiPlayerStore from './uiPlayerStore'; export class RootStore { dashboardStore: DashboardStore; @@ -49,6 +50,7 @@ export class RootStore { spotStore: SpotStore; loginStore: LoginStore; filterStore: FilterStore; + uiPlayerStore: UiPlayerStore; constructor() { this.dashboardStore = new DashboardStore(); @@ -74,6 +76,7 @@ export class RootStore { this.spotStore = new SpotStore(); this.loginStore = new LoginStore(); this.filterStore = new FilterStore(); + this.uiPlayerStore = new UiPlayerStore(); } initClient() { diff --git a/frontend/app/mstore/uiPlayerStore.ts b/frontend/app/mstore/uiPlayerStore.ts new file mode 100644 index 000000000..34c7a5cd2 --- /dev/null +++ b/frontend/app/mstore/uiPlayerStore.ts @@ -0,0 +1,110 @@ +import { makeAutoObservable } from 'mobx'; + +interface ToggleZoomPayload { + enabled: boolean; + range?: [number, number]; +} + +export const NONE = 0; +export const CONSOLE = 1; +export const NETWORK = 2; +export const STACKEVENTS = 3; +export const STORAGE = 4; +export const PROFILER = 5; +export const PERFORMANCE = 6; +export const GRAPHQL = 7; +export const FETCH = 8; +export const EXCEPTIONS = 9; +export const INSPECTOR = 11; +export const OVERVIEW = 12; + +export const blocks = { + none: NONE, + console: CONSOLE, + network: NETWORK, + stackEvents: STACKEVENTS, + storage: STORAGE, + profiler: PROFILER, + performance: PERFORMANCE, + graphql: GRAPHQL, + fetch: FETCH, + exceptions: EXCEPTIONS, + inspector: INSPECTOR, + overview: OVERVIEW, +} as const; + +export const blockValues = [ + NONE, + CONSOLE, + NETWORK, + STACKEVENTS, + STORAGE, + PROFILER, + PERFORMANCE, + GRAPHQL, + FETCH, + EXCEPTIONS, + INSPECTOR, + OVERVIEW, +] as const; + +export default class UiPlayerStore { + fullscreen = false; + bottomBlock = 0; + hiddenHints = { + storage: localStorage.getItem('storageHideHint') || undefined, + stack: localStorage.getItem('stackHideHint') || undefined, + }; + skipInterval: 2 | 5 | 10 | 15 | 20 | 30 | 60 = parseInt(localStorage.getItem('CHANGE_SKIP_INTERVAL') || '10', 10) as (2 | 5 | 10 | 15 | 20 | 30 | 60) + timelineZoom = { + enabled: false, + startTs: 0, + endTs: 0, + } + zoomTab: 'overview' | 'journey' | 'issues' | 'errors' = 'overview' + + constructor() { + makeAutoObservable(this); + } + + toggleFullscreen = (val?: boolean) => { + this.fullscreen = val ?? !this.fullscreen; + } + + fullscreenOff = () => { + this.fullscreen = false; + } + + fullscreenOn = () => { + this.fullscreen = true; + } + + toggleBottomBlock = (block: number) => { + this.bottomBlock = this.bottomBlock === block ? 0 : block; + } + + closeBottomBlock = () => { + this.bottomBlock = 0; + } + + changeSkipInterval = (interval: 2 | 5 | 10 | 15 | 20 | 30 | 60) => { + localStorage.setItem('CHANGE_SKIP_INTERVAL', interval.toString()); + this.skipInterval = interval; + } + + hideHint = (hint: 'storage' | 'stack') => { + this.hiddenHints[hint] = 'true'; + localStorage.setItem(`${hint}HideHint`, 'true'); + this.bottomBlock = 0; + } + + toggleZoom = (payload: ToggleZoomPayload) => { + this.timelineZoom.enabled = payload.enabled; + this.timelineZoom.startTs = payload.range?.[0] ?? 0; + this.timelineZoom.endTs = payload.range?.[1] ?? 0; + } + + setZoomTab = (tab: 'overview' | 'journey' | 'issues' | 'errors') => { + this.zoomTab = tab; + } +} \ No newline at end of file