fix(player): extract time state observing components from controls
This commit is contained in:
parent
cea9ca87e4
commit
9ba3a7e7f6
8 changed files with 139 additions and 78 deletions
|
|
@ -188,8 +188,8 @@ function Performance({
|
|||
const [_data, setData] = React.useState<any[]>([])
|
||||
|
||||
const {
|
||||
connType,
|
||||
connBandwidth,
|
||||
// connType,
|
||||
// connBandwidth,
|
||||
tabStates,
|
||||
currentTab,
|
||||
} = store.get();
|
||||
|
|
@ -237,18 +237,6 @@ function Performance({
|
|||
value={formatBytes(userDeviceHeapSize)}
|
||||
display={true}
|
||||
/>
|
||||
<InfoLine.Point
|
||||
label="Connection Type"
|
||||
value={connType}
|
||||
display={connType != null && connType !== 'unknown'}
|
||||
/>
|
||||
<InfoLine.Point
|
||||
label="Connection Speed"
|
||||
value={
|
||||
connBandwidth >= 1000 ? `${connBandwidth / 1000} Mbps` : `${connBandwidth} Kbps`
|
||||
}
|
||||
display={connBandwidth != null}
|
||||
/>
|
||||
</InfoLine>
|
||||
</div>
|
||||
</BottomBlock.Header>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
import React, { useContext } from 'react';
|
||||
import stl from './timeline.module.css';
|
||||
import { PlayerContext } from 'Components/Session/playerContext';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { getTimelinePosition } from './getTimelinePosition'
|
||||
|
||||
function EventsList({ scale }: { scale: number }) {
|
||||
const { store } = useContext(PlayerContext);
|
||||
|
||||
const { tabStates, eventCount } = store.get();
|
||||
const events = React.useMemo(() => {
|
||||
return Object.values(tabStates)[0]?.eventList || [];
|
||||
}, [eventCount]);
|
||||
return (
|
||||
<>
|
||||
{events.map((e) => (
|
||||
<div
|
||||
/*@ts-ignore TODO */
|
||||
key={e.key}
|
||||
className={stl.event}
|
||||
style={{ left: `${getTimelinePosition(e.time, scale)}%` }}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default observer(EventsList);
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
import React from 'react';
|
||||
import { Icon } from 'UI';
|
||||
import { useStore } from "App/mstore";
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { getTimelinePosition } from './getTimelinePosition'
|
||||
|
||||
function NotesList({ scale }: { scale: number }) {
|
||||
const { notesStore } = useStore();
|
||||
const notes = notesStore.sessionNotes;
|
||||
|
||||
const visibleNotes = React.useMemo(() => {
|
||||
return notes.filter(note => note.timestamp > 0)
|
||||
}, [notes.length])
|
||||
|
||||
return (
|
||||
<>
|
||||
{visibleNotes.map((note) => (
|
||||
<div
|
||||
key={note.noteId}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
background: 'white',
|
||||
zIndex: 3,
|
||||
pointerEvents: 'none',
|
||||
height: 10,
|
||||
width: 16,
|
||||
left: `${getTimelinePosition(note.timestamp, scale)}%`,
|
||||
}}
|
||||
>
|
||||
<Icon name="quotes" style={{ width: 16, height: 10 }} color="main" />
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default observer(NotesList)
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
import React, { useContext } from 'react';
|
||||
import stl from 'Components/Session_/Player/Controls/timeline.module.css';
|
||||
import { PlayerContext } from 'Components/Session/playerContext';
|
||||
import { getTimelinePosition } from './getTimelinePosition';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
|
||||
function SkipIntervalsList({ scale }: { scale: number }) {
|
||||
const { store } = useContext(PlayerContext);
|
||||
const { skipIntervals, skip } = store.get();
|
||||
|
||||
if (!skip) return null;
|
||||
|
||||
return (
|
||||
<>
|
||||
{skipIntervals.map((interval) => (
|
||||
<div
|
||||
key={interval.start}
|
||||
className={stl.skipInterval}
|
||||
style={{
|
||||
left: `${getTimelinePosition(interval.start, scale)}%`,
|
||||
width: `${(interval.end - interval.start) * scale}%`,
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default observer(SkipIntervalsList);
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
import React, { useEffect, useMemo, useContext, useState, useRef } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Icon } from 'UI'
|
||||
import TimeTracker from './TimeTracker';
|
||||
import stl from './timeline.module.css';
|
||||
import { setTimelinePointer, setTimelineHoverTime } from 'Duck/sessions';
|
||||
|
|
@ -13,12 +12,10 @@ import { observer } from 'mobx-react-lite';
|
|||
import { useStore } from 'App/mstore';
|
||||
import { DateTime, Duration } from 'luxon';
|
||||
import Issue from "Types/session/issue";
|
||||
|
||||
function getTimelinePosition(value: number, scale: number) {
|
||||
const pos = value * scale;
|
||||
|
||||
return pos > 100 ? 99 : pos;
|
||||
}
|
||||
import EventsList from './EventsList';
|
||||
import NotesList from './NotesList';
|
||||
import SkipIntervalsList from './SkipIntervalsList'
|
||||
import TimelineTracker from "Components/Session_/Player/Controls/TimelineTracker";
|
||||
|
||||
interface IProps {
|
||||
issues: Issue[]
|
||||
|
|
@ -30,28 +27,19 @@ interface IProps {
|
|||
function Timeline(props: IProps) {
|
||||
const { player, store } = useContext(PlayerContext)
|
||||
const [wasPlaying, setWasPlaying] = useState(false)
|
||||
const { notesStore, settingsStore } = useStore();
|
||||
const { settingsStore } = useStore();
|
||||
const {
|
||||
playing,
|
||||
time,
|
||||
skipIntervals,
|
||||
skip,
|
||||
skipToIssue,
|
||||
ready,
|
||||
endTime,
|
||||
devtoolsLoading,
|
||||
domLoading,
|
||||
tabStates,
|
||||
eventCount,
|
||||
} = store.get()
|
||||
const { issues } = props;
|
||||
const notes = notesStore.sessionNotes;
|
||||
|
||||
const progressRef = useRef<HTMLDivElement>(null)
|
||||
const timelineRef = useRef<HTMLDivElement>(null)
|
||||
const events = React.useMemo(() => {
|
||||
return Object.values(tabStates)[0]?.eventList || []
|
||||
}, [eventCount])
|
||||
|
||||
const scale = 100 / endTime;
|
||||
|
||||
|
|
@ -151,42 +139,22 @@ function Timeline(props: IProps) {
|
|||
onMouseLeave={hideTimeTooltip}
|
||||
>
|
||||
<TooltipContainer />
|
||||
<DraggableCircle
|
||||
left={time * scale}
|
||||
onDrop={onDragEnd}
|
||||
/>
|
||||
<TimelineTracker scale={scale} onDragEnd={onDragEnd} />
|
||||
<CustomDragLayer
|
||||
onDrag={onDrag}
|
||||
minX={0}
|
||||
maxX={progressRef.current ? progressRef.current.offsetWidth : 0}
|
||||
/>
|
||||
<TimeTracker scale={scale} left={time * scale} />
|
||||
|
||||
{skip ?
|
||||
skipIntervals.map((interval) => (
|
||||
<div
|
||||
key={interval.start}
|
||||
className={stl.skipInterval}
|
||||
style={{
|
||||
left: `${getTimelinePosition(interval.start, scale)}%`,
|
||||
width: `${(interval.end - interval.start) * scale}%`,
|
||||
}}
|
||||
/>
|
||||
)) : null}
|
||||
|
||||
<div className={stl.timeline} ref={timelineRef}>
|
||||
{devtoolsLoading || domLoading || !ready ? <div className={stl.stripes} /> : null}
|
||||
</div>
|
||||
|
||||
{events.map((e) => {
|
||||
if (!e || e.key == undefined) console.log(e)
|
||||
return (
|
||||
<div
|
||||
/*@ts-ignore TODO */
|
||||
key={e.key}
|
||||
className={stl.event}
|
||||
style={{ left: `${getTimelinePosition(e.time, scale)}%` }}
|
||||
/>
|
||||
)})}
|
||||
<EventsList scale={scale} />
|
||||
<NotesList scale={scale} />
|
||||
<SkipIntervalsList scale={scale} />
|
||||
|
||||
{/* TODO: refactor and make any sense out of this */}
|
||||
|
||||
{/* {issues.map((i: Issue) => (*/}
|
||||
|
|
@ -196,22 +164,6 @@ function Timeline(props: IProps) {
|
|||
{/* style={{ left: `${getTimelinePosition(i.time, scale)}%` }}*/}
|
||||
{/* />*/}
|
||||
{/*))}*/}
|
||||
{notes.map((note) => note.timestamp > 0 ? (
|
||||
<div
|
||||
key={note.noteId}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
background: 'white',
|
||||
zIndex: 3,
|
||||
pointerEvents: 'none',
|
||||
height: 10,
|
||||
width: 16,
|
||||
left: `${getTimelinePosition(note.timestamp, scale)}%`,
|
||||
}}
|
||||
>
|
||||
<Icon name="quotes" style={{ width: 16, height: 10 }} color="main" />
|
||||
</div>
|
||||
) : null)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
import React, { useContext } from 'react';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import DraggableCircle from 'Components/Session_/Player/Controls/components/DraggableCircle';
|
||||
import TimeTracker from 'Components/Session_/Player/Controls/TimeTracker';
|
||||
import { PlayerContext } from 'Components/Session/playerContext';
|
||||
|
||||
function TimelineTracker({ scale, onDragEnd }: { scale: number, onDragEnd: () => void }) {
|
||||
const { store } = useContext(PlayerContext);
|
||||
|
||||
const { time } = store.get();
|
||||
|
||||
return (
|
||||
<>
|
||||
<DraggableCircle left={time * scale} onDrop={onDragEnd} />
|
||||
<TimeTracker scale={scale} left={time * scale} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default observer(TimelineTracker);
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
export function getTimelinePosition(value: number, scale: number) {
|
||||
const pos = value * scale;
|
||||
|
||||
return pos > 100 ? 99 : pos;
|
||||
}
|
||||
|
|
@ -264,11 +264,12 @@ export default class TabSessionManager {
|
|||
// @ts-ignore comes from parent state
|
||||
this.state.update({ location: lastLocationMsg.url })
|
||||
}
|
||||
const lastConnectionInfoMsg = this.connectionInfoManger.moveGetLast(t, index);
|
||||
if (!!lastConnectionInfoMsg) {
|
||||
stateToUpdate.connType = lastConnectionInfoMsg.type;
|
||||
stateToUpdate.connBandwidth = lastConnectionInfoMsg.downlink;
|
||||
}
|
||||
// ConnectionInformation message is not used at this moment
|
||||
// const lastConnectionInfoMsg = this.connectionInfoManger.moveGetLast(t, index);
|
||||
// if (!!lastConnectionInfoMsg) {
|
||||
// stateToUpdate.connType = lastConnectionInfoMsg.type;
|
||||
// stateToUpdate.connBandwidth = lastConnectionInfoMsg.downlink;
|
||||
// }
|
||||
const lastPerformanceTrackMessage = this.performanceTrackManager.moveGetLast(t, index);
|
||||
if (!!lastPerformanceTrackMessage) {
|
||||
stateToUpdate.performanceChartTime = lastPerformanceTrackMessage.time;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue