diff --git a/tracker/tracker-assist/src/CallWindow.ts b/tracker/tracker-assist/src/CallWindow.ts
index 69ae0f125..73833eda1 100644
--- a/tracker/tracker-assist/src/CallWindow.ts
+++ b/tracker/tracker-assist/src/CallWindow.ts
@@ -1,196 +1,150 @@
-const defaultView = `
-
-
-
-
-
-
-
-
-
-
-
-`
-
-const V_WIDTH = 160;
-const V_HEIGHT = 120;
export default class CallWindow {
private iframe: HTMLIFrameElement;
private vRemote: HTMLVideoElement | null = null;
private vLocal: HTMLVideoElement | null = null;
- private soundBtn: HTMLButtonElement | null = null;
- private videoBtn: HTMLButtonElement | null = null;
+ private audioBtn: HTMLAnchorElement | null = null;
+ private videoBtn: HTMLAnchorElement | null = null;
+
+ private tsInterval: ReturnType;
constructor(endCall: () => void) {
- this.iframe = document.createElement('iframe');
- Object.assign(this.iframe.style, {
+ const iframe = this.iframe = document.createElement('iframe');
+ Object.assign(iframe.style, {
position: "absolute",
zIndex: "999999",
- width: `${2*V_WIDTH}px`,
- height: `${V_HEIGHT}px`,
- borderRadius: ".25em .25em .4em .4em",
- border: "4px rgba(0, 0, 0, .7)",
- top: `calc(100% - ${V_HEIGHT + 20}px)`,
- left: `calc(100% - ${2*V_WIDTH + 20}px)`,
+ //borderRadius: ".25em .25em .4em .4em",
+ //border: "4px rgba(0, 0, 0, .7)",
+ border: "none",
+ bottom: "10px",
+ right: "10px",
});
- document.body.appendChild(this.iframe);
+ //iframe.src = "//static.openreplay.com/tracker-assist/index.html";
+ iframe.onload = () => {
+ const doc = iframe.contentDocument;
+ if (!doc) {
+ console.error("OpenReplay: CallWindow iframe document is not reachable.")
+ return;
+ }
+ fetch("https://static.openreplay.com/tracker-assist/index.html")
+ //fetch("file:///Users/shikhu/work/asayer-tester/dist/assist/index.html")
+ .then(r => r.text())
+ .then((text) => {
+ iframe.onload = () => {
+ iframe.style.height = doc.body.scrollHeight + 'px';
+ iframe.style.width = doc.body.scrollWidth + 'px';
+ }
- const doc = this.iframe.contentDocument
- if (!doc) {
- console.error("OpenReplay: CallWindow iframe document is not reachable.")
- return;
- }
+ text = text.replace(/href="css/g, "href=\"https://static.openreplay.com/tracker-assist/css")
+ doc.open();
+ doc.write(text);
+ doc.close();
- doc.body.innerHTML = defaultView;
-
- this.vLocal = doc.getElementById("vLocal") as HTMLVideoElement;
- this.vLocal.height = V_HEIGHT
- this.vLocal.width = V_WIDTH
- this.vRemote = doc.getElementById("vRemote") as HTMLVideoElement;
- this.vRemote.height = V_HEIGHT
- this.vRemote.width = V_WIDTH
-
- const endCallBtn = doc.getElementById("endCallBtn") as HTMLButtonElement;
- endCallBtn.onclick = endCall;
- this.soundBtn = doc.getElementById("soundBtn") as HTMLButtonElement;
- this.soundBtn.onclick = () => this.toggleAudio();
+ this.vLocal = doc.getElementById("video-local") as HTMLVideoElement;
+ this.vRemote = doc.getElementById("video-remote") as HTMLVideoElement;
+ this._trySetStreams();
+ this.vLocal.parentElement && this.vLocal.parentElement.classList.add("d-none");
- this.videoBtn = doc.getElementById("videoBtn") as HTMLButtonElement;
- this.videoBtn.onclick = () => this.toggleVideo();
+ this.audioBtn = doc.getElementById("audio-btn") as HTMLAnchorElement;
+ this.audioBtn.onclick = () => this.toggleAudio();
+ this.videoBtn = doc.getElementById("video-btn") as HTMLAnchorElement;
+ this.videoBtn.onclick = () => this.toggleVideo();
+ const endCallBtn = doc.getElementById("end-call-btn") as HTMLAnchorElement;
+ endCallBtn.onclick = endCall;
+ const tsText = doc.getElementById("time-stamp");
+ const startTs = Date.now();
+ if (tsText) {
+ this.tsInterval = setInterval(() => {
+ const ellapsed = Date.now() - startTs;
+ const secsFull = ~~(ellapsed / 1000);
+ const mins = ~~(secsFull / 60);
+ const secs = secsFull - mins * 60
+ tsText.innerText = `${mins}:${secs < 10 ? 0 : ''}${secs}`;
+ }, 500);
+ }
- // TODO: better D'n'D
- doc.body.setAttribute("draggable", "true");
- doc.body.ondragstart = (e) => {
- if (!e.dataTransfer || !e.target) { return; }
- e.dataTransfer.setDragImage(doc.body, e.clientX, e.clientY);
- };
- doc.body.ondragend = e => {
- Object.assign(this.iframe.style, {
- left: `${e.clientX}px`,
- top: `${e.clientY}px`,
- })
+ // TODO: better D'n'D
+ doc.body.setAttribute("draggable", "true");
+ doc.body.ondragstart = (e) => {
+ if (!e.dataTransfer || !e.target) { return; }
+ e.dataTransfer.setDragImage(doc.body, e.clientX, e.clientY);
+ };
+ doc.body.ondragend = e => {
+ Object.assign(iframe.style, {
+ left: `${e.clientX}px`,
+ top: `${e.clientY}px`,
+ bottom: 'auto',
+ right: 'auto',
+ })
+ }
+ });
}
+ document.body.appendChild(iframe);
+
}
- private outputStream: MediaStream | null = null;
- setInputStream(iStream: MediaStream) {
- if (!this.vRemote) { return; }
- this.vRemote.srcObject = iStream;
+ private localStream: MediaStream | null = null;
+ private remoteStream: MediaStream | null = null;
+ private _trySetStreams() {
+ if (this.vRemote && this.remoteStream) {
+ this.vRemote.srcObject = this.remoteStream;
+ }
+ if (this.vLocal && this.localStream) {
+ this.vLocal.srcObject = this.localStream;
+ }
}
- setOutputStream(oStream: MediaStream) {
- if (!this.vLocal) { return; }
- this.outputStream = oStream;
- this.vLocal.srcObject = oStream;
+ setRemoteStream(rStream: MediaStream) {
+ this.remoteStream = rStream;
+ this._trySetStreams();
+ }
+ setLocalStream(lStream: MediaStream) {
+ this.localStream = lStream;
+ lStream.getVideoTracks().forEach(track => {
+ track.enabled = false;
+ });
+ this._trySetStreams();
}
toggleAudio() {
let enabled = true;
- this.outputStream?.getAudioTracks().forEach(track => {
+ this.localStream?.getAudioTracks().forEach(track => {
enabled = enabled && !track.enabled;
track.enabled = enabled;
});
+ const cList = this.audioBtn?.classList;
+ if (!this.audioBtn) { return; }
if (enabled) {
- this.soundBtn?.classList.remove("muted");
+ this.audioBtn.classList.remove("muted");
+ this.audioBtn.childNodes[1].textContent = "Mute";
} else {
- this.soundBtn?.classList.add("muted");
+ this.audioBtn.classList.add("muted");
+ this.audioBtn.childNodes[1].textContent = "Unmute";
}
}
toggleVideo() {
let enabled = true;
- this.outputStream?.getVideoTracks().forEach(track => {
+ this.localStream?.getVideoTracks().forEach(track => {
enabled = enabled && !track.enabled;
track.enabled = enabled;
});
+ if (!this.videoBtn || !this.vLocal || !this.vLocal.parentElement) { return; }
if (enabled) {
- this.videoBtn?.classList.remove("off");
+ this.vLocal.parentElement.classList.remove("d-none");
+ this.videoBtn.classList.remove("off");
+ this.videoBtn.childNodes[1].textContent = "Stop Video";
} else {
- this.videoBtn?.classList.add("off");
+ this.vLocal.parentElement.classList.add("d-none");
+ this.videoBtn.classList.add("off");
+ this.videoBtn.childNodes[1].textContent = "Start Video";
}
}
remove() {
+ clearInterval(this.tsInterval);
if (this.iframe.parentElement) {
document.body.removeChild(this.iframe);
}
diff --git a/tracker/tracker-assist/src/index.ts b/tracker/tracker-assist/src/index.ts
index 8d17a9911..ffa3502bc 100644
--- a/tracker/tracker-assist/src/index.ts
+++ b/tracker/tracker-assist/src/index.ts
@@ -135,9 +135,9 @@ export default function(opts: Partial = {}) {
call.on('error', onClose); // notify about error?
callUI = new CallWindow(onClose);
- callUI.setOutputStream(oStream);
+ callUI.setLocalStream(oStream);
call.on('stream', function(iStream) {
- callUI.setInputStream(iStream);
+ callUI.setRemoteStream(iStream);
dataConn.on('data', (data: any) => {
if (data === "call_end") {
onClose();