diff --git a/frontend/app/components/Session/LivePlayer.tsx b/frontend/app/components/Session/LivePlayer.tsx index aeae34021..05305a4d4 100644 --- a/frontend/app/components/Session/LivePlayer.tsx +++ b/frontend/app/components/Session/LivePlayer.tsx @@ -7,13 +7,26 @@ import withPermissions from 'HOCs/withPermissions'; import { PlayerContext, defaultContextValue } from './playerContext'; import { makeAutoObservable } from 'mobx'; import { createLiveWebPlayer } from 'Player' -import type { IWebPlayer } from 'Player' import PlayerBlockHeader from '../Session_/PlayerBlockHeader'; import PlayerBlock from '../Session_/PlayerBlock'; import styles from '../Session_/session.module.css'; +import Session from 'App/mstore/types/session'; -function LivePlayer ({ +interface Props { + session: Session; + toggleFullscreen: (isOn: boolean) => void; + closeBottomBlock: () => void; + fullscreen: boolean; + loadingCredentials: boolean; + assistCredendials: RTCIceServer[]; + request: () => void; + isEnterprise: boolean; + userEmail: string; + userName: string; +} + +function LivePlayer({ session, toggleFullscreen, closeBottomBlock, @@ -24,12 +37,14 @@ function LivePlayer ({ isEnterprise, userEmail, userName, -}) { +}: Props) { const [contextValue, setContextValue] = useState(defaultContextValue); const [fullView, setFullView] = useState(false); + useEffect(() => { - if (loadingCredentials) { return } + if (loadingCredentials || !session.sessionId) { return } const sessionWithAgentData = { + // @ts-ignore burn immutable ...session.toJS(), agentInfo: { email: userEmail, @@ -42,6 +57,7 @@ function LivePlayer ({ (state) => makeAutoObservable(state) ) setContextValue({ player, store }) + player.play() return () => player.clean() }, [ session.sessionId, assistCredendials ]) @@ -71,10 +87,17 @@ function LivePlayer ({ return ( - {!fullView && ()} -
- -
+ {!fullView && ( + + )} +
+ +
); } @@ -91,7 +114,7 @@ export default withRequest({ true )( connect( - (state) => { + (state: any) => { return { session: state.getIn(['sessions', 'current']), showAssist: state.getIn(['sessions', 'showChatWindow']), diff --git a/frontend/app/components/Session_/Player/Controls/AssistSessionsTabs/index.tsx b/frontend/app/components/Session_/Player/Controls/AssistSessionsTabs/index.tsx new file mode 100644 index 000000000..245daf434 --- /dev/null +++ b/frontend/app/components/Session_/Player/Controls/AssistSessionsTabs/index.tsx @@ -0,0 +1 @@ +export { default } from './AssistSessionsTabs' diff --git a/frontend/app/components/Session_/Player/Controls/Timeline.tsx b/frontend/app/components/Session_/Player/Controls/Timeline.tsx index 07cf15535..686cf85b4 100644 --- a/frontend/app/components/Session_/Player/Controls/Timeline.tsx +++ b/frontend/app/components/Session_/Player/Controls/Timeline.tsx @@ -4,8 +4,8 @@ import { Icon } from 'UI' import TimeTracker from './TimeTracker'; import stl from './timeline.module.css'; import { setTimelinePointer, setTimelineHoverTime } from 'Duck/sessions'; -import DraggableCircle from './DraggableCircle'; -import CustomDragLayer from './CustomDragLayer'; +import DraggableCircle from './components/DraggableCircle'; +import CustomDragLayer from './components/CustomDragLayer'; import { debounce } from 'App/utils'; import TooltipContainer from './components/TooltipContainer'; import { PlayerContext } from 'App/components/Session/playerContext'; diff --git a/frontend/app/components/Session_/Player/Controls/Circle.tsx b/frontend/app/components/Session_/Player/Controls/components/Circle.tsx similarity index 90% rename from frontend/app/components/Session_/Player/Controls/Circle.tsx rename to frontend/app/components/Session_/Player/Controls/components/Circle.tsx index 73e1e1bb1..a658d5dd7 100644 --- a/frontend/app/components/Session_/Player/Controls/Circle.tsx +++ b/frontend/app/components/Session_/Player/Controls/components/Circle.tsx @@ -1,5 +1,5 @@ import React, { memo, FC } from 'react'; -import styles from './timeline.module.css'; +import styles from '../timeline.module.css'; import cn from 'classnames'; interface Props { diff --git a/frontend/app/components/Session_/Player/Controls/CustomDragLayer.tsx b/frontend/app/components/Session_/Player/Controls/components/CustomDragLayer.tsx similarity index 99% rename from frontend/app/components/Session_/Player/Controls/CustomDragLayer.tsx rename to frontend/app/components/Session_/Player/Controls/components/CustomDragLayer.tsx index 200c1c79f..eb93203b5 100644 --- a/frontend/app/components/Session_/Player/Controls/CustomDragLayer.tsx +++ b/frontend/app/components/Session_/Player/Controls/components/CustomDragLayer.tsx @@ -75,7 +75,7 @@ const CustomDragLayer: FC = memo(function CustomDragLayer(props) { return null; } } - + if (!isDragging) { return null; } diff --git a/frontend/app/components/Session_/Player/Controls/DraggableCircle.tsx b/frontend/app/components/Session_/Player/Controls/components/DraggableCircle.tsx similarity index 99% rename from frontend/app/components/Session_/Player/Controls/DraggableCircle.tsx rename to frontend/app/components/Session_/Player/Controls/components/DraggableCircle.tsx index 0bbffdc74..cb1e0f9d4 100644 --- a/frontend/app/components/Session_/Player/Controls/DraggableCircle.tsx +++ b/frontend/app/components/Session_/Player/Controls/components/DraggableCircle.tsx @@ -57,7 +57,7 @@ const DraggableCircle: FC = memo(function DraggableCircle({ useEffect(() => { preview(getEmptyImage(), { captureDraggingState: true }) }, []) - + return (
{ - const { live } = this.store.get() - if (live) return - if (this.store.get().playing) { cancelAnimationFrame(this.animationFrameRequestId) this.setTime(time) @@ -189,7 +186,7 @@ export default class Animator { } // TODO: clearify logic of live time-travel - jumpToLive() { + jumpToLive = () => { cancelAnimationFrame(this.animationFrameRequestId) this.setTime(this.store.get().endTime) this.startAnimation() diff --git a/frontend/app/player/web/MessageManager.ts b/frontend/app/player/web/MessageManager.ts index 72662a17b..c8f2f3205 100644 --- a/frontend/app/player/web/MessageManager.ts +++ b/frontend/app/player/web/MessageManager.ts @@ -8,7 +8,7 @@ import { Log } from './types'; import { toast } from 'react-toastify'; -import type { Store } from '../common/types'; +import type { Store, Timed } from '../common/types'; import ListWalker from '../common/ListWalker'; import PagesManager from './managers/PagesManager'; @@ -209,7 +209,7 @@ export default class MessageManager { this.setMessagesLoading(false) } - private loadMessages() { + private async loadMessages() { // TODO: reuseable decryptor instance const createNewParser = (shouldDecrypt=true) => { const decrypt = shouldDecrypt && this.session.fileKey @@ -226,18 +226,26 @@ export default class MessageManager { this.setMessagesLoading(true) this.waitingForFiles = true - loadFiles(this.session.domURL, createNewParser()) - .catch(() => // do if only the first file missing (404) (?) - requestEFSDom(this.session.sessionId) - .then(createNewParser(false)) - // Fallback to back Compatability with mobsUrl - .catch(e => - loadFiles(this.session.mobsUrl, createNewParser(false)) - ) - ) - .then(this.onFileReadSuccess) - .catch(this.onFileReadFailed) - .finally(this.onFileReadFinally) + try { + if (this.session.domURL && this.session.domURL.length > 0) { + await loadFiles(this.session.domURL, createNewParser()) + this.onFileReadSuccess() + } else { + const file = await requestEFSDom(this.session.sessionId) + const parser = createNewParser(false) + await parser(file) + } + } catch (e) { + console.error('Cant get session replay file:', e) + try { + // back compat with old mobsUrl + await loadFiles(this.session.mobsUrl, createNewParser(false)) + } catch (e) { + this.onFileReadFailed(e) + } + } finally { + this.onFileReadFinally() + } // load devtools if (this.session.devtoolsURL.length) { @@ -252,7 +260,7 @@ export default class MessageManager { } } - reloadWithUnprocessedFile(onSuccess: ()=>void) { + reloadWithUnprocessedFile(onSuccess: () => void) { const onData = (byteArray: Uint8Array) => { const onMessage = (msg: Message) => { this.lastMessageInFileTime = msg.time } this.parseAndDistributeMessages(new MFileReader(byteArray, this.sessionStart), onMessage) @@ -430,6 +438,7 @@ export default class MessageManager { ) break; case "fetch": + // @ts-ignore burn immutable this.lists.lists.fetch.append(Resource({ method: msg.method, url: msg.url,