ui: move player slice reducer to mobx family
This commit is contained in:
parent
60ac0ed312
commit
1a2e143888
31 changed files with 349 additions and 526 deletions
|
|
@ -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<Note | undefined>(undefined);
|
||||
// @ts-ignore
|
||||
const [contextValue, setContextValue] = useState<IOSPlayerContext>(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)));
|
||||
|
|
|
|||
|
|
@ -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<ILivePlayerContext>(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);
|
||||
|
|
@ -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<ILivePlayerContext>(PlayerContext);
|
||||
const screenWrapper = React.useRef<HTMLDivElement>(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),
|
||||
|
|
|
|||
|
|
@ -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) {
|
|||
>
|
||||
<FullScreenButton
|
||||
size={16}
|
||||
onClick={props.fullscreenOn}
|
||||
onClick={fullscreenOn}
|
||||
customClasses={
|
||||
'rounded hover:bg-gray-light-shade color-gray-medium'
|
||||
}
|
||||
|
|
@ -174,6 +171,7 @@ const DevtoolsButtons = observer(({
|
|||
bottomBlock,
|
||||
}: DevtoolsButtonsProps) => {
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
<div
|
||||
|
|
@ -43,7 +44,6 @@ function PlayerBlock(props: IProps) {
|
|||
}
|
||||
|
||||
export default connect((state: any) => ({
|
||||
fullscreen: state.getIn(['player', 'fullscreen']),
|
||||
sessionId: state.getIn(['sessions', 'current']).sessionId,
|
||||
jiraConfig: state.getIn(['issues', 'list'])[0],
|
||||
}))(PlayerBlock)
|
||||
}))(observer(PlayerBlock))
|
||||
|
|
@ -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<HTMLDivElement>(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));
|
||||
|
|
|
|||
|
|
@ -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<string, any>;
|
||||
|
|
@ -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 (
|
||||
<div className={cn(styles.playerBlock, 'flex flex-col', 'overflow-x-hidden')}>
|
||||
{shouldShowSubHeader
|
||||
? <SubHeader sessionId={sessionId} jiraConfig={jiraConfig} />
|
||||
: null}
|
||||
<Player setActiveTab={setActiveTab} activeTab={activeTab} fullView={fullView} />
|
||||
<div
|
||||
className={cn(styles.playerBlock, 'flex flex-col', 'overflow-x-hidden')}
|
||||
>
|
||||
{shouldShowSubHeader ? (
|
||||
<SubHeader sessionId={sessionId} jiraConfig={jiraConfig} />
|
||||
) : null}
|
||||
<Player
|
||||
setActiveTab={setActiveTab}
|
||||
activeTab={activeTab}
|
||||
fullView={fullView}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default connect((state: Record<string, any>) => ({
|
||||
fullscreen: state.getIn(['player', 'fullscreen']),
|
||||
sessionId: state.getIn(['sessions', 'current']).sessionId,
|
||||
jiraConfig: state.getIn(['issues', 'list'])[0],
|
||||
}))(PlayerBlock);
|
||||
}))(observer(PlayerBlock));
|
||||
|
|
|
|||
|
|
@ -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<HTMLDivElement>(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));
|
||||
|
|
|
|||
|
|
@ -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<string, any>) => ({
|
||||
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));
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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<Note | undefined>(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)));
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}) => (
|
||||
<div className={ cn("relative border-r border-l py-1", stl.header) } style={customStyle} >
|
||||
<div className={ cn("w-full h-full flex justify-between items-center", className) } >
|
||||
<div className="w-full flex items-center justify-between">{ children }</div>
|
||||
{ showClose && <CloseButton onClick={ customClose ? customClose : closeBottomBlock } size="18" className="ml-2" /> }
|
||||
}) => {
|
||||
const { uiPlayerStore } = useStore();
|
||||
const closeBottomBlock = uiPlayerStore.closeBottomBlock;
|
||||
|
||||
return (
|
||||
<div className={cn("relative border-r border-l py-1", stl.header)} style={customStyle}>
|
||||
<div className={cn("w-full h-full flex justify-between items-center", className)}>
|
||||
<div className="w-full flex items-center justify-between">{children}</div>
|
||||
{showClose && <CloseButton onClick={customClose ? customClose : closeBottomBlock} size="18" className="ml-2" />}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
)
|
||||
};
|
||||
|
||||
Header.displayName = 'Header';
|
||||
|
||||
export default connect(null, { closeBottomBlock })(Header);
|
||||
export default Header;
|
||||
|
|
|
|||
|
|
@ -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<VListHandle>(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,
|
||||
|
|
|
|||
|
|
@ -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<string, any>[];
|
||||
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<string, any>) => ({
|
||||
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<string, any>) => ({
|
||||
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));
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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) {
|
|||
|
||||
<FullScreenButton
|
||||
size={16}
|
||||
onClick={props.fullscreenOn}
|
||||
onClick={fullscreenOn}
|
||||
customClasses={
|
||||
'rounded hover:bg-gray-light-shade color-gray-medium'
|
||||
}
|
||||
|
|
@ -438,32 +436,15 @@ export default connect(
|
|||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -23,18 +23,16 @@ interface IProps {
|
|||
tooltipVisible: boolean;
|
||||
timezone?: string;
|
||||
isMobile?: boolean;
|
||||
timelineZoomEnabled: boolean;
|
||||
timelineZoomStartTs: number;
|
||||
timelineZoomEndTs: number;
|
||||
}
|
||||
|
||||
function Timeline(props: IProps) {
|
||||
const { player, store } = useContext(PlayerContext);
|
||||
const [wasPlaying, setWasPlaying] = useState(false);
|
||||
const [maxWidth, setMaxWidth] = useState(0);
|
||||
const { settingsStore } = useStore();
|
||||
const { settingsStore, uiPlayerStore } = useStore();
|
||||
const timelineZoomEnabled = uiPlayerStore.timelineZoom.enabled;
|
||||
const { playing, skipToIssue, ready, endTime, devtoolsLoading, domLoading } = store.get();
|
||||
const { issues, timezone, timelineZoomEnabled } = props;
|
||||
const { issues, timezone } = props;
|
||||
|
||||
const progressRef = useRef<HTMLDivElement>(null);
|
||||
const timelineRef = useRef<HTMLDivElement>(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));
|
||||
|
|
|
|||
|
|
@ -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<string, any>) => ({
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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<string, any>) => ({
|
||||
timelineZoomStartTs: state.getIn(['player']).timelineZoom
|
||||
.startTs,
|
||||
timelineZoomEndTs: state.getIn(['player']).timelineZoom.endTs,
|
||||
}),
|
||||
{ toggleZoom }
|
||||
)(DraggableMarkers);
|
||||
export default observer(DraggableMarkers);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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<HTMLButtonElement>();
|
||||
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 <ReduxViewer />
|
||||
}
|
||||
|
|
@ -311,7 +307,7 @@ function Storage(props: Props) {
|
|||
.
|
||||
<br />
|
||||
<br />
|
||||
<button className="color-teal" onClick={() => props.hideHint('storage')}>
|
||||
<button className="color-teal" onClick={() => hideHint('storage')}>
|
||||
Got It!
|
||||
</button>
|
||||
</>
|
||||
|
|
@ -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);
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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<HTMLInputElement>) => void;
|
||||
showClose?: boolean;
|
||||
onClose?: () => void;
|
||||
}) => (
|
||||
<div className={cn('relative border-r border-l py-1', stl.header)}>
|
||||
<div
|
||||
className={cn(
|
||||
'w-full h-full flex justify-between items-center',
|
||||
className
|
||||
)}
|
||||
>
|
||||
<div className="w-full flex items-center justify-between">{children}</div>
|
||||
{showClose && (
|
||||
<Tooltip title="Close Panel">
|
||||
<CloseButton
|
||||
onClick={onClose ? onClose : closeBottomBlock}
|
||||
size="18"
|
||||
className="ml-2 hover:bg-black/10 rounded-lg p-1"
|
||||
/>
|
||||
</Tooltip>
|
||||
)}
|
||||
}) => {
|
||||
const { uiPlayerStore } = useStore();
|
||||
const closeBottomBlock = uiPlayerStore.closeBottomBlock;
|
||||
return (
|
||||
<div className={cn('relative border-r border-l py-1', stl.header)}>
|
||||
<div
|
||||
className={cn(
|
||||
'w-full h-full flex justify-between items-center',
|
||||
className
|
||||
)}
|
||||
>
|
||||
<div className="w-full flex items-center justify-between">
|
||||
{children}
|
||||
</div>
|
||||
{showClose && (
|
||||
<Tooltip title="Close Panel">
|
||||
<CloseButton
|
||||
onClick={onClose ? onClose : closeBottomBlock}
|
||||
size="18"
|
||||
className="ml-2 hover:bg-black/10 rounded-lg p-1"
|
||||
/>
|
||||
</Tooltip>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
};
|
||||
|
||||
Header.displayName = 'Header';
|
||||
|
||||
export default connect(null, { closeBottomBlock })(Header);
|
||||
export default Header;
|
||||
|
|
|
|||
|
|
@ -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<VListHandle>(null);
|
||||
const filter = devTools[INDEX_KEY].filter;
|
||||
|
|
@ -224,8 +221,4 @@ function ConsolePanel({
|
|||
);
|
||||
}
|
||||
|
||||
export default connect((state: Record<string, any>) => ({
|
||||
zoomEnabled: state.getIn(['player']).timelineZoom.enabled,
|
||||
zoomStartTs: state.getIn(['player']).timelineZoom.startTs,
|
||||
zoomEndTs: state.getIn(['player']).timelineZoom.endTs,
|
||||
}))(observer(ConsolePanel));
|
||||
export default observer(ConsolePanel);
|
||||
|
|
|
|||
|
|
@ -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 };
|
||||
|
|
|
|||
|
|
@ -28,15 +28,11 @@ const TABS = TAB_KEYS.map((tab) => ({ text: tab, key: tab }));
|
|||
type EventsList = Array<Timed & { name: string; source: string; key: string }>;
|
||||
|
||||
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<string, any>) => ({
|
||||
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<string, any>) => ({
|
||||
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,
|
||||
|
|
|
|||
|
|
@ -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<boolean | undefined>) => {
|
||||
state.fullscreen = action.payload !== undefined ? action.payload : !state.fullscreen;
|
||||
},
|
||||
fullscreenOff: (state) => {
|
||||
state.fullscreen = false;
|
||||
},
|
||||
fullscreenOn: (state) => {
|
||||
state.fullscreen = true;
|
||||
},
|
||||
toggleBottomBlock: (state, action: PayloadAction<number>) => {
|
||||
state.bottomBlock =
|
||||
state.bottomBlock !== action.payload && action.payload !== 0 ? action.payload : 0;
|
||||
},
|
||||
closeBottomBlock: (state) => {
|
||||
state.bottomBlock = 0;
|
||||
},
|
||||
changeSkipInterval: (state, action: PayloadAction<number>) => {
|
||||
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<ToggleZoomPayload>) => {
|
||||
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;
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
110
frontend/app/mstore/uiPlayerStore.ts
Normal file
110
frontend/app/mstore/uiPlayerStore.ts
Normal file
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue