* feat spot: init commit for extension * nvmrc * fix login flow * Spots Gridview Updates (#2422) * feat ui: login flow for spot extension * spot list, store and service created * some fixing for header * start work on single spot * spot player start * header for player, comments, icons, etc * split stuff into compoennts, create player state manager * player controls, activity panel etc etc * comments, empty page, rename and stuff * interval buttons etc * access modal * pubkey support * fix tooltip * limit 10 -> 9 * hls lib instead of videojs * some warnings * fix date display for exp * change public links * display more client data * fix cleaning, init comment * map network to replay player network ev * stream support, console panel, close panels on X * fixing streaming, destroy on leave * fix autoplay * show notification on spot login * fix spot login * backup player added, fix audio issue * show thumbnail when no video, add spot roles * add poster thumbnail * some fixes to video check * fix events jump * fix play btn * try catch over pubkey * feat ui: login flow for spot extension * spot list, store and service created * some fixing for header * start work on single spot * spot player start * header for player, comments, icons, etc * split stuff into compoennts, create player state manager * player controls, activity panel etc etc * comments, empty page, rename and stuff * interval buttons etc * access modal * pubkey support * fix tooltip * limit 10 -> 9 * hls lib instead of videojs * some warnings * fix date display for exp * change public links * display more client data * fix cleaning, init comment * map network to replay player network ev * stream support, console panel, close panels on X * fixing streaming, destroy on leave * fix autoplay * show notification on spot login * fix spot login * backup player added, fix audio issue * show thumbnail when no video, add spot roles * add poster thumbnail * some fixes to video check * fix events jump * fix play btn * try catch over pubkey * icons * Various updates * Update SVG.tsx * Update SideMenu.tsx * SpotList & Menu updates * feat ui: login flow for spot extension * spot list, store and service created * some fixing for header * start work on single spot * spot player start * header for player, comments, icons, etc * split stuff into compoennts, create player state manager * player controls, activity panel etc etc * comments, empty page, rename and stuff * interval buttons etc * access modal * pubkey support * fix tooltip * limit 10 -> 9 * hls lib instead of videojs * some warnings * fix date display for exp * change public links * display more client data * fix cleaning, init comment * map network to replay player network ev * stream support, console panel, close panels on X * fixing streaming, destroy on leave * fix autoplay * show notification on spot login * fix spot login * backup player added, fix audio issue * show thumbnail when no video, add spot roles * add poster thumbnail * some fixes to video check * fix events jump * fix play btn * try catch over pubkey * icons * spot login pinging * Spot List & Player Updates * move spot login flow to login comp, use separate spot login path for unique jwt * invalidate spot jwt on logout * add visual data on page load event * typo fix * Spot Listing improvements post review. * Update SpotListItem.tsx * Improved Spot List and Item Details * Minor improvements * More improvements * Public player header improvements * Moved formatExpirationTime to utils * fixes after merge --------- Co-authored-by: nick-delirium <nikita@openreplay.com> * set sso link to <a>? * some small perf fixes * login duck reformat... * Update frontend.yaml * add observer to spot list header * split list header * update spotjwt param in router * fix toast in router * fix async fetch, move ctx * capture space btn ev * fix header link * public sharing error msg * fix err msg for unsuccessful rec start * fix list alignment * Caching assets. Finally!!! * fix typing in comment field * add pubkey to comments, fix console jump btn * no content comp * change refresh token logic * move thumbnail ts * move thumbnail ts * fix tab change * switch up toggler * early exit if no jwt present * regenerate icons * fix location str * fix ctx * change thumnail res, return autoplay for video player * parse links in console rows, fix injected method parse? * remove ts from js * fix console parsing order? * fixes for autoplay * xray for spot player * move to spot list after login; esc to cancel; fix signup link; move ux commit * kb sc for skipping; xray for spot ext * track aborted requests * tooltip for readability * fixing empty state * New blank state + various minor improvements (#2471) * New blank state + various minor improvements * apres merge --------- Co-authored-by: nick-delirium <nikita@openreplay.com> * rm temp v * init or card * empty state debug * empty state debug * empty state debug * fix initor img * spotonly scope support * Improved Spot dead-end pages (#2475) * Improved Spot dead-end pages * Initiate OpenReplay Setup and some more * get scope changes * fix crash * scope upgrade/downgrade * scope setup flow * ping for backend * upgrade wxt deps * cancel ping int on expiration * check rec status * fix ping * check video processing state * check video processing state * fix xray close, network highlight, fcp rounding * update wxt, move open spot stuff to settings * fix some history issues * fix spot login flow * fix spot login again * fix spot login again * don't send two requests * limit messages for logged users * limit messages for logged users * fix public ignore * microphone stuff * microphone stuff * Various improvements (#2509) * Various improvements - Updated icons in mic settings - Included prefix in Spot title - Save recording notification has been updated - Other minor UI improvements * Inline declaration of spot name field, and settings UI * str f --------- Co-authored-by: nick-delirium <nikita@openreplay.com> * UI changes in player header, spot list (#2510) * Added UI elements in player page - Badge with counts for comments - Download and Delete dropdown in player - Spot selection -- UI improvement * Minor copy updates * completing changes --------- Co-authored-by: nick-delirium <nikita@openreplay.com> * rm cmt * fix cellmeasurer * thumbnail dur * fix download * Minor fixes (#2512) - Spot delete confirmation - Spot comments UI update - Minor copy updates * limit number of notif messages * add spot title to doc title, add cache groups for webpack * drop mic controls from recording popup view * fix for webpack compress * fix for auto mic pickup * change status banners * move svgs around, remove undefined check * refactor svgs * fix timetable scaling * fix error popup * self contain css * pre-select spot on spot onboarding --------- Co-authored-by: Sudheer Salavadi <connect.uxmaster@gmail.com> Co-authored-by: Rajesh Rajendran <rjshrjndrn@users.noreply.github.com>
274 lines
6.4 KiB
TypeScript
274 lines
6.4 KiB
TypeScript
import { makeAutoObservable } from 'mobx';
|
|
|
|
import { getResourceFromNetworkRequest } from 'App/player';
|
|
import { Log as PLog, ILog } from "App/player";
|
|
import { PlayingState } from 'App/player-ui'
|
|
|
|
interface Event {
|
|
time: number;
|
|
[key: string]: any;
|
|
}
|
|
|
|
interface Log extends Event {
|
|
level: 'log' | 'error' | 'warn' | 'info';
|
|
msg: string;
|
|
}
|
|
|
|
interface Location extends Event {
|
|
location: string;
|
|
}
|
|
|
|
interface Click extends Event {
|
|
label: string;
|
|
}
|
|
|
|
interface SpotNetworkRequest extends Event {
|
|
type: string;
|
|
statusCode: number;
|
|
url: string;
|
|
fromCache: boolean;
|
|
body: string;
|
|
encodedBodySize: number;
|
|
responseBodySize: number;
|
|
duration: number;
|
|
method: string;
|
|
}
|
|
|
|
|
|
const mapSpotNetworkToEv = (ev: SpotNetworkRequest): any => {
|
|
const { type, statusCode} = ev;
|
|
const mapType = (type: string) => {
|
|
switch (type) {
|
|
case 'xmlhttprequest':
|
|
return 'xhr';
|
|
case 'fetch':
|
|
return 'fetch';
|
|
case 'resource':
|
|
return 'resource';
|
|
default:
|
|
return 'other';
|
|
}
|
|
};
|
|
|
|
const request = JSON.stringify({
|
|
headers: ev.requestHeaders,
|
|
body: ev.body,
|
|
})
|
|
const response = JSON.stringify({
|
|
headers: ev.responseHeaders,
|
|
body: { warn: "Chrome Manifest V3 -- No response body available in Chrome 93+" }
|
|
})
|
|
return ({
|
|
...ev,
|
|
request,
|
|
response,
|
|
type: mapType(type),
|
|
status: statusCode,
|
|
})
|
|
};
|
|
|
|
export const PANELS = {
|
|
CONSOLE: 'CONSOLE',
|
|
NETWORK: 'NETWORK',
|
|
OVERVIEW: 'OVERVIEW',
|
|
} as const;
|
|
|
|
export type PanelType = keyof typeof PANELS;
|
|
|
|
class SpotPlayerStore {
|
|
time = 0;
|
|
duration = 0;
|
|
durationString = '';
|
|
isPlaying = true;
|
|
state = PlayingState.Playing;
|
|
isMuted = false;
|
|
volume = 1;
|
|
playbackRate = 1;
|
|
isFullScreen = false;
|
|
logs: ReturnType<typeof PLog>[] = [];
|
|
locations: Location[] = [];
|
|
clicks: Click[] = [];
|
|
network: ReturnType<typeof getResourceFromNetworkRequest>[] = [];
|
|
startTs = 0;
|
|
activePanel: PanelType | null = null;
|
|
skipInterval = 10;
|
|
browserVersion: string | null = null;
|
|
resolution: string | null = null;
|
|
platform: string | null = null;
|
|
|
|
constructor() {
|
|
makeAutoObservable(this);
|
|
}
|
|
|
|
clearData = () => {
|
|
this.time = 0;
|
|
this.duration = 0;
|
|
this.durationString = '';
|
|
this.isPlaying = true;
|
|
this.state = PlayingState.Playing;
|
|
this.isMuted = false;
|
|
this.volume = 1;
|
|
this.playbackRate = 1;
|
|
this.isFullScreen = false;
|
|
this.logs = [];
|
|
this.locations = [];
|
|
this.clicks = [];
|
|
this.network = [];
|
|
this.startTs = 0;
|
|
this.activePanel = null;
|
|
this.skipInterval = 10;
|
|
this.browserVersion = null;
|
|
this.resolution = null;
|
|
this.platform = null;
|
|
}
|
|
|
|
setDeviceData(browserVersion: string, resolution: string, platform: string) {
|
|
this.browserVersion = browserVersion;
|
|
this.resolution = resolution;
|
|
this.platform = platform;
|
|
}
|
|
|
|
setSkipInterval = (interval: number) => {
|
|
this.skipInterval = interval;
|
|
}
|
|
|
|
setActivePanel(panel: PanelType | null): void {
|
|
this.activePanel = panel;
|
|
}
|
|
|
|
setDuration(durString: string) {
|
|
const [minutes, seconds] = durString.split(':').map(Number);
|
|
this.durationString = durString;
|
|
this.duration = minutes * 60 + seconds;
|
|
}
|
|
|
|
setPlaybackRate(rate: number): void {
|
|
this.playbackRate = rate;
|
|
}
|
|
|
|
setStartTs(ts: number): void {
|
|
this.startTs = ts;
|
|
}
|
|
|
|
setTime(time: number): void {
|
|
this.time = Math.max(0, Math.min(time, this.duration));
|
|
}
|
|
|
|
setIsPlaying(isPlaying: boolean): void {
|
|
this.isPlaying = isPlaying;
|
|
this.state = isPlaying ? PlayingState.Playing : PlayingState.Paused;
|
|
}
|
|
|
|
onComplete = () => {
|
|
this.state = PlayingState.Completed;
|
|
}
|
|
|
|
setIsMuted(isMuted: boolean): void {
|
|
this.isMuted = isMuted;
|
|
}
|
|
|
|
setVolume(volume: number): void {
|
|
this.volume = volume;
|
|
}
|
|
|
|
setIsFullScreen(isFullScreen: boolean): void {
|
|
this.isFullScreen = isFullScreen;
|
|
}
|
|
|
|
setEvents(
|
|
logs: Log[],
|
|
locations: Location[],
|
|
clicks: Click[],
|
|
network: SpotNetworkRequest[]
|
|
): void {
|
|
this.logs = logs.map((log) => PLog({
|
|
...log,
|
|
time: log.time - this.startTs,
|
|
value: log.msg,
|
|
}));
|
|
|
|
this.locations = locations.map((location) => ({
|
|
...location,
|
|
time: location.time - this.startTs,
|
|
fcpTime: location.navTiming.fcpTime ? Math.round(location.navTiming.fcpTime) : null,
|
|
timeToInteractive: location.navTiming.timeToInteractive ? Math.round(location.navTiming.timeToInteractive) : null,
|
|
visuallyComplete: location.navTiming.visuallyComplete ? Math.round(location.navTiming.visuallyComplete) : null,
|
|
}));
|
|
|
|
this.clicks = clicks.map((click) => ({
|
|
...click,
|
|
time: click.time - this.startTs,
|
|
}));
|
|
|
|
this.network = network.map((request) => {
|
|
const ev = { ...request, timestamp: request.time };
|
|
return getResourceFromNetworkRequest(
|
|
mapSpotNetworkToEv(ev),
|
|
this.startTs
|
|
);
|
|
});
|
|
}
|
|
|
|
get currentLogIndex() {
|
|
return this.logs.findIndex((log) => log.time >= this.time);
|
|
}
|
|
|
|
getHighlightedEvent<T extends Log | Location | Click | SpotNetworkRequest>(
|
|
time: number,
|
|
events: T[]
|
|
): { event: T | null; index: number } {
|
|
if (!events.length) {
|
|
return { event: null, index: 0 };
|
|
}
|
|
let highlightedEvent = events[0];
|
|
const currentTs = time * 1000;
|
|
let index = 0;
|
|
for (let i = 0; i < events.length; i++) {
|
|
const event = events[i];
|
|
const nextEvent = events[i + 1];
|
|
|
|
if (
|
|
currentTs >= event.time &&
|
|
(!nextEvent || currentTs < nextEvent.time)
|
|
) {
|
|
highlightedEvent = event;
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return { event: highlightedEvent, index };
|
|
}
|
|
|
|
getClosestLocation(time: number): Location {
|
|
const { event } = this.getHighlightedEvent(time, this.locations);
|
|
return event ?? { location: 'loading', time: 0 };
|
|
}
|
|
|
|
getClosestClick(time: number): Click {
|
|
const { event } = this.getHighlightedEvent(time, this.clicks);
|
|
return event ?? { label: 'loading', time: 0 };
|
|
}
|
|
|
|
getClosestNetworkIndex(time: number): SpotNetworkRequest {
|
|
// @ts-ignore
|
|
const event = this.getHighlightedEvent(time, this.network);
|
|
// @ts-ignore
|
|
return event ?? { type: 'loading', time: 0 };
|
|
}
|
|
|
|
getClosestLog(time: number): Log {
|
|
const { event } = this.getHighlightedEvent(time, this.logs);
|
|
return (
|
|
event ?? {
|
|
msg: 'loading',
|
|
time: 0,
|
|
level: 'info',
|
|
}
|
|
);
|
|
}
|
|
}
|
|
|
|
const spotPlayerStore = new SpotPlayerStore();
|
|
|
|
export default spotPlayerStore;
|