fix(ui) - fixes from dev (#1175)

* fix(player): consider stringDict before any CreateDocument (fastfix)

* style(player/DOMManager/safeCSSRules): depend on interfaces

* fixup! fix(player): consider stringDict before any CreateDocument (fastfix)

* fix(ui) - user sessions modal - navigation

* fix(player): proper unmount

---------

Co-authored-by: Alex Kaminskii <alex@openreplay.com>
Co-authored-by: nick-delirium <nikita@openreplay.com>
This commit is contained in:
Shekar Siri 2023-04-17 14:40:26 +02:00 committed by GitHub
parent 8d8f320ddb
commit c3ce2dfeb8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 62 additions and 46 deletions

View file

@ -1,37 +1,29 @@
import { useModal } from 'App/components/Modal';
import React, { useState } from 'react';
import React from 'react';
import SessionList from '../SessionList';
import stl from './assistTabs.module.css'
import stl from './assistTabs.module.css';
interface Props {
userId: any,
userNumericHash: any,
userId: any;
}
const AssistTabs = (props: Props) => {
const [showMenu, setShowMenu] = useState(false)
const { showModal } = useModal();
return (
<div className="relative mr-4">
<div className="flex items-center">
{props.userId && (
<>
<div
className={stl.btnLink}
onClick={() => showModal(<SessionList userId={props.userId} />, { right: true, width: 700 })}
>
Active Sessions
</div>
</>
<div
className={stl.btnLink}
onClick={() =>
showModal(<SessionList userId={props.userId} />, { right: true, width: 700 })
}
>
Active Sessions
</div>
)}
</div>
{/* <SlideModal
title={ <div>{props.userId}'s <span className="color-gray-medium">Live Sessions</span> </div> }
isDisplayed={ showMenu }
content={ showMenu && <SessionList /> }
onClose={ () => setShowMenu(false) }
/> */}
</div>
);
};

View file

@ -46,7 +46,7 @@ function SessionList(props: Props) {
>
<div className="p-4">
{props.list.map((session: any) => (
<div className="mb-6">
<div className="mb-6" key={session.sessionId}>
{session.pageTitle && session.pageTitle !== '' && (
<div className="flex items-center mb-2">
<Label size="small" className="p-1">
@ -55,7 +55,7 @@ function SessionList(props: Props) {
<span className="ml-2 font-medium">{session.pageTitle}</span>
</div>
)}
<SessionItem compact={true} onClick={() => hideModal()} key={session.sessionId} session={session} />
<SessionItem compact={true} onClick={hideModal} session={session} />
</div>
))}
</div>

View file

@ -71,12 +71,13 @@ function LivePlayer({
return () => {
if (!location.pathname.includes('multiview') || !location.pathname.includes(usedSession.sessionId)) {
console.debug('unmount', usedSession.sessionId)
playerInst?.clean?.();
// @ts-ignore default empty
setContextValue(defaultContextValue)
}
}
}, [location.pathname]);
}, [location.pathname, usedSession.sessionId]);
// LAYOUT (TODO: local layout state - useContext or something..)
useEffect(() => {

View file

@ -46,7 +46,7 @@ function LivePlayerBlockHeader(props: any) {
history.push(withSiteId(ASSIST_ROUTE, siteId));
};
const { userId, userNumericHash, metadata, isCallActive, agentIds } = session;
const { userId, metadata, isCallActive, agentIds } = session;
let _metaList = Object.keys(metadata)
.filter((i) => metaList.includes(i))
.map((key) => {
@ -87,7 +87,7 @@ function LivePlayerBlockHeader(props: any) {
</div>
)}
<UserCard className="" width={width} height={height} />
<AssistTabs userId={userId} userNumericHash={userNumericHash} />
<AssistTabs userId={userId} />
<div className={cn('ml-auto flex items-center h-full', { hidden: closedLive })}>
{_metaList.length > 0 && (

View file

@ -55,6 +55,7 @@ interface Props {
compact?: boolean;
isDisabled?: boolean;
isAdd?: boolean;
ignoreAssist?: boolean;
}
function SessionItem(props: RouteComponentProps & Props) {
@ -70,6 +71,7 @@ function SessionItem(props: RouteComponentProps & Props) {
lastPlayedSessionId,
onClick = null,
compact = false,
ignoreAssist = false,
} = props;
const {
@ -99,9 +101,10 @@ function SessionItem(props: RouteComponentProps & Props) {
const hasUserId = userId || userAnonymousId;
const isSessions = isRoute(SESSIONS_ROUTE, location.pathname);
const isAssist =
isRoute(ASSIST_ROUTE, location.pathname) ||
isRoute(ASSIST_LIVE_SESSION, location.pathname) ||
location.pathname.includes('multiview');
!ignoreAssist &&
(isRoute(ASSIST_ROUTE, location.pathname) ||
isRoute(ASSIST_LIVE_SESSION, location.pathname) ||
location.pathname.includes('multiview'));
const isLastPlayed = lastPlayedSessionId === sessionId;
const _metaList = Object.keys(metadata)

View file

@ -70,7 +70,7 @@ function UserSessionsModal(props: Props) {
<Loader loading={loading}>
{data.sessions.map((session: any) => (
<div className="border-b last:border-none" key={session.sessionId}>
<SessionItem key={session.sessionId} session={session} compact={true} onClick={hideModal} />
<SessionItem key={session.sessionId} session={session} compact={true} onClick={hideModal} ignoreAssist={true} />
</div>
))}
</Loader>

View file

@ -90,7 +90,7 @@ export default class WebLivePlayer extends WebPlayer {
clean = () => {
this.incomingMessages.length = 0
this.assistManager.clean()
this.screen.clean()
this.screen?.clean?.()
// @ts-ignore
this.screen = undefined;
super.clean()

View file

@ -38,7 +38,6 @@ export default class DOMManager extends ListWalker<Message> {
private olStyleSheets: Map<number, OnloadStyleSheet> = new Map()
/** @depreacted since tracker 4.0.2 Mapping by nodeID */
private olStyleSheetsDeprecated: Map<number, OnloadStyleSheet> = new Map()
private stringDict: Record<number,string> = {}
private upperBodyId: number = -1;
private nodeScrollManagers: Map<number, ListWalker<SetNodeScroll>> = new Map()
@ -49,6 +48,7 @@ export default class DOMManager extends ListWalker<Message> {
constructor(
private readonly screen: Screen,
private readonly isMobile: boolean,
private stringDict: Record<number,string>,
public readonly time: number,
setCssLoading: ConstructorParameters<typeof StylesManager>[1],
) {
@ -57,6 +57,10 @@ export default class DOMManager extends ListWalker<Message> {
this.stylesManager = new StylesManager(screen, setCssLoading)
}
setStringDict(stringDict: Record<number,string>) {
this.stringDict = stringDict
}
append(m: Message): void {
if (m.tp === MType.SetNodeScroll) {
let scrollManager = this.nodeScrollManagers.get(m.id)
@ -192,7 +196,6 @@ export default class DOMManager extends ListWalker<Message> {
// Maybetodo: start Document as 0-node in tracker
this.vTexts.clear()
this.stylesManager.reset()
this.stringDict = {}
return
}
case MType.CreateTextNode: {
@ -227,12 +230,9 @@ export default class DOMManager extends ListWalker<Message> {
case MType.SetNodeAttribute:
this.setNodeAttribute(msg)
return
case MType.StringDict:
this.stringDict[msg.key] = msg.value
return
case MType.SetNodeAttributeDict:
this.stringDict[msg.nameKey] === undefined && logger.error("No dictionary key for msg 'name': ", msg)
this.stringDict[msg.valueKey] === undefined && logger.error("No dictionary key for msg 'value': ", msg)
this.stringDict[msg.nameKey] === undefined && logger.error("No dictionary key for msg 'name': ", msg, this.stringDict)
this.stringDict[msg.valueKey] === undefined && logger.error("No dictionary key for msg 'value': ", msg, this.stringDict)
if (this.stringDict[msg.nameKey] === undefined || this.stringDict[msg.valueKey] === undefined ) { return }
this.setNodeAttribute({
id: msg.id,

View file

@ -1,14 +1,15 @@
import logger from 'App/logger';
export type { PostponedStyleSheet } from './VirtualDOM'
export function insertRule(sheet: CSSStyleSheet | PostponedStyleSheet, msg: { rule: string, index: number }) {
export function insertRule(
sheet: { insertRule: (rule: string, index: number) => void },
msg: { rule: string, index: number }
) {
try {
sheet.insertRule(msg.rule, msg.index)
} catch (e) {
logger.warn(e, msg)
try {
sheet.insertRule(msg.rule, 0)
sheet.insertRule(msg.rule, 0) // TODO: index renumeration in case of subsequent rule deletion
logger.warn("Inserting rule into 0-index", e, msg)
} catch (e) {
logger.warn("Cannot insert rule.", e, msg)
@ -16,7 +17,10 @@ export function insertRule(sheet: CSSStyleSheet | PostponedStyleSheet, msg: { ru
}
}
export function deleteRule(sheet: CSSStyleSheet | PostponedStyleSheet, msg: { index: number }) {
export function deleteRule(
sheet: { deleteRule: (index: number) => void },
msg: { index: number }
) {
try {
sheet.deleteRule(msg.index)
} catch (e) {

View file

@ -1,13 +1,21 @@
import type Screen from '../Screen/Screen';
import type { Message } from '../messages';
import logger from 'App/logger';
import { MType } from '../messages';
import type Screen from '../Screen/Screen';
import type { Message, StringDict } from '../messages';
import { MType} from '../messages';
import ListWalker from '../../common/ListWalker';
import DOMManager from './DOM/DOMManager';
export default class PagesManager extends ListWalker<DOMManager> {
private currentPage: DOMManager | null = null
/**
* String Dictionary in tracker may be desync with CreateDocument (why???)
* e.g. some StringDictionary and other messages before any 'CreateDocument' one
* TODO: understand why and fix
*/
private currentStringDict: Record<number, string> = {}
constructor(
private screen: Screen,
@ -19,11 +27,19 @@ export default class PagesManager extends ListWalker<DOMManager> {
Assumed that messages added in a correct time sequence.
*/
appendMessage(m: Message): void {
if (m.tp === MType.StringDict) {
if (this.currentStringDict[m.key] !== undefined) {
this.currentStringDict = {} /* refresh stringDict */
this.last?.setStringDict(this.currentStringDict)
}
this.currentStringDict[m.key] = m.value
return
}
if (m.tp === MType.CreateDocument) {
super.append(new DOMManager(this.screen, this.isMobile, m.time, this.setCssLoading))
super.append(new DOMManager(this.screen, this.isMobile, this.currentStringDict, m.time, this.setCssLoading))
}
if (this.last === null) {
// Log wrong
logger.warn("DOMMessage before any document created, skipping:", m)
return;
}
this.last.append(m)