From f4dba95a7a0f765131ea6f38a6a8b4da9fa6d694 Mon Sep 17 00:00:00 2001 From: Shekar Siri Date: Wed, 29 Mar 2023 18:24:33 +0200 Subject: [PATCH] Fix sessions clear (#1071) * fix(ui): properly clean player inst on unmount * fix(ui): fix current session clearing --------- Co-authored-by: nick-delirium --- frontend/app/components/Session/Session.js | 7 ++++++- frontend/app/components/Session/WebPlayer.tsx | 6 +++++- .../SessionListContainer/SessionListContainer.tsx | 10 +++++++--- frontend/app/duck/sessions.ts | 4 +++- frontend/app/player/web/MessageManager.ts | 6 +++++- frontend/app/player/web/Screen/Screen.ts | 6 ++++++ frontend/app/player/web/WebPlayer.ts | 5 ++++- frontend/app/player/web/managers/DOM/DOMManager.ts | 4 ++-- 8 files changed, 38 insertions(+), 10 deletions(-) diff --git a/frontend/app/components/Session/Session.js b/frontend/app/components/Session/Session.js index 2a7cf81d8..bece203c8 100644 --- a/frontend/app/components/Session/Session.js +++ b/frontend/app/components/Session/Session.js @@ -2,7 +2,7 @@ import React from 'react'; import { useEffect, useState } from 'react'; import { connect } from 'react-redux'; import usePageTitle from 'App/hooks/usePageTitle'; -import { fetch as fetchSession } from 'Duck/sessions'; +import { fetch as fetchSession, clearCurrentSession } from 'Duck/sessions'; import { fetchList as fetchSlackList } from 'Duck/integrations/slack'; import { Link, NoContent, Loader } from 'UI'; import { sessions as sessionsRoute } from 'App/routes'; @@ -18,6 +18,7 @@ function Session({ loading, hasErrors, fetchSession, + clearCurrentSession, }) { usePageTitle("OpenReplay Session Player"); const [ initializing, setInitializing ] = useState(true) @@ -29,6 +30,9 @@ function Session({ console.error("No sessionID in route.") } setInitializing(false) + return () => { + clearCurrentSession(); + } },[ sessionId ]); useEffect(() => { @@ -65,4 +69,5 @@ export default withPermissions(['SESSION_REPLAY'], '', true)(connect((state, pro }, { fetchSession, fetchSlackList, + clearCurrentSession, })(Session)); diff --git a/frontend/app/components/Session/WebPlayer.tsx b/frontend/app/components/Session/WebPlayer.tsx index 659dbe540..9ccef8807 100644 --- a/frontend/app/components/Session/WebPlayer.tsx +++ b/frontend/app/components/Session/WebPlayer.tsx @@ -61,7 +61,11 @@ function WebPlayer(props: any) { WebPlayerInst.freeze() } - return () => WebPlayerInst.clean(); + return () => { + WebPlayerInst.clean(); + // @ts-ignore + setContextValue(defaultContextValue); + } }, [session.sessionId]); const isPlayerReady = contextValue.store?.get().ready diff --git a/frontend/app/components/shared/SessionListContainer/SessionListContainer.tsx b/frontend/app/components/shared/SessionListContainer/SessionListContainer.tsx index 67b1e12e7..e3bc98b62 100644 --- a/frontend/app/components/shared/SessionListContainer/SessionListContainer.tsx +++ b/frontend/app/components/shared/SessionListContainer/SessionListContainer.tsx @@ -3,18 +3,22 @@ import SessionList from './components/SessionList'; import SessionHeader from './components/SessionHeader'; import NotesList from './components/Notes/NoteList'; import { connect } from 'react-redux'; -import { fetchList as fetchMembers } from 'Duck/member'; import LatestSessionsMessage from './components/LatestSessionsMessage'; +import { clearCurrentSession } from "Duck/sessions"; function SessionListContainer({ activeTab, - fetchMembers, members, + clearCurrentSession, }: { activeTab: string; fetchMembers: () => void; members: object[]; + clearCurrentSession: () => void; }) { + React.useEffect(() => { + clearCurrentSession() + }, []) return (
@@ -32,5 +36,5 @@ export default connect( // @ts-ignore members: state.getIn(['members', 'list']), }), - { fetchMembers } + { clearCurrentSession } )(SessionListContainer); diff --git a/frontend/app/duck/sessions.ts b/frontend/app/duck/sessions.ts index b87afaaa4..0194ad7e7 100644 --- a/frontend/app/duck/sessions.ts +++ b/frontend/app/duck/sessions.ts @@ -126,7 +126,9 @@ const reducer = (state = initialState, action: IAction) => { return state.set('filteredEvents', filteredEvents).set('eventsQuery', query); } case CLEAR_CURRENT_SESSION: { - return state.set('current', new Session()) + const session = new Session(); + + return state.set('current', session) .set('eventsIndex', []) .set('visitedEvents', List()) .set('host', ''); diff --git a/frontend/app/player/web/MessageManager.ts b/frontend/app/player/web/MessageManager.ts index c54b86fb8..011d6c270 100644 --- a/frontend/app/player/web/MessageManager.ts +++ b/frontend/app/player/web/MessageManager.ts @@ -208,7 +208,11 @@ export default class MessageManager { for (let msg = fileReader.readNext();msg !== null;msg = fileReader.readNext()) { msgs.push(msg) } - const sorted = msgs.sort((m1, m2) => m1.time - m2.time) + const sorted = msgs.sort((m1, m2) => { + // @ts-ignore + if (m1.time === m2.time) return m1._index - m2._index + return m1.time - m2.time + }) let indx = sorted[0]._index let outOfOrderCounter = 0 diff --git a/frontend/app/player/web/Screen/Screen.ts b/frontend/app/player/web/Screen/Screen.ts index f27a251f1..d85857b01 100644 --- a/frontend/app/player/web/Screen/Screen.ts +++ b/frontend/app/player/web/Screen/Screen.ts @@ -82,6 +82,12 @@ export default class Screen { this.cursor = new Cursor(this.overlay, isMobile) // TODO: move outside } + clean() { + this.screen.removeChild(this.iframe) + this.screen.removeChild(this.overlay) + this.screen.remove(); + } + attach(parentElement: HTMLElement) { if (this.parentElement) { this.parentElement = null diff --git a/frontend/app/player/web/WebPlayer.ts b/frontend/app/player/web/WebPlayer.ts index 9ca769598..d0fa1d26c 100644 --- a/frontend/app/player/web/WebPlayer.ts +++ b/frontend/app/player/web/WebPlayer.ts @@ -22,7 +22,7 @@ export default class WebPlayer extends Player { } private readonly inspectorController: InspectorController - protected readonly screen: Screen + protected screen: Screen protected readonly messageManager: MessageManager private targetMarker: TargetMarker @@ -133,6 +133,9 @@ export default class WebPlayer extends Player { clean = () => { super.clean() + this.screen.clean() + // @ts-ignore + this.screen = undefined; window.removeEventListener('resize', this.scale) } } diff --git a/frontend/app/player/web/managers/DOM/DOMManager.ts b/frontend/app/player/web/managers/DOM/DOMManager.ts index bb4c999ae..cbeae3f7d 100644 --- a/frontend/app/player/web/managers/DOM/DOMManager.ts +++ b/frontend/app/player/web/managers/DOM/DOMManager.ts @@ -116,7 +116,7 @@ export default class DOMManager extends ListWalker { } const parent = this.vElements.get(parentID) || this.vRoots.get(parentID) if (!parent) { - logger.error("Insert error. Parent node not found", parentID); + logger.error("Insert error. Parent node not found", parentID, this.vElements, this.vRoots); return; } @@ -169,7 +169,7 @@ export default class DOMManager extends ListWalker { case MType.CreateDocument: doc = this.screen.document; if (!doc) { - logger.error("No root iframe document found", msg) + logger.error("No root iframe document found", msg, this.screen) return; } doc.open();