ui: move player slice reducer to mobx family

This commit is contained in:
nick-delirium 2024-09-10 15:38:35 +02:00
parent 60ac0ed312
commit 1a2e143888
No known key found for this signature in database
GPG key ID: 93ABD695DF5FDBA0
31 changed files with 349 additions and 526 deletions

View file

@ -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)));

View file

@ -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);

View file

@ -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),

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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))

View file

@ -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));

View file

@ -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));

View file

@ -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));

View file

@ -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));

View file

@ -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,

View file

@ -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)));

View file

@ -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;

View file

@ -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,

View file

@ -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));

View file

@ -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';

View file

@ -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);

View file

@ -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));

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);
/**

View file

@ -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;

View file

@ -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);

View file

@ -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 };

View file

@ -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,

View file

@ -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;

View file

@ -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,

View file

@ -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() {

View 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;
}
}