Refactor screencast IDs (#800)

Fixes #713, mapping watch windows to exact column/row by id
This commit is contained in:
sua yoo 2023-05-03 10:33:04 -07:00 committed by GitHub
parent 9a1c2ba871
commit 60581411eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -3,7 +3,7 @@ import { msg, localized, str } from "@lit/localize";
import { property, state } from "lit/decorators.js"; import { property, state } from "lit/decorators.js";
type Message = { type Message = {
id: string; // page ID id: number; // page ID
}; };
type InitMessage = Message & { type InitMessage = Message & {
@ -133,17 +133,13 @@ export class Screencast extends LitElement {
// List of browser screens // List of browser screens
@state() @state()
private dataList: Array<ScreencastMessage | null> = []; private dataMap: { [index: string]: ScreencastMessage | null } = {};
@state() @state()
private focusedScreenData?: ScreencastMessage; private focusedScreenData?: ScreencastMessage;
// Websocket connections // Websocket connections
private wsMap: Map<number, WebSocket> = new Map(); private wsMap: Map<number, WebSocket> = new Map();
// Map data order to screen data
private dataMap: { [index: number]: ScreencastMessage | null } = {};
// Map page ID to data order
private pageOrderMap: Map<string, number> = new Map();
// Number of available browsers. // Number of available browsers.
// Multiply by scale to get available browser window count // Multiply by scale to get available browser window count
private browsersCount = 1; private browsersCount = 1;
@ -166,14 +162,12 @@ export class Screencast extends LitElement {
this.disconnectAll(); this.disconnectAll();
this.connectAll(); this.connectAll();
} }
if (changedProperties.has("scale")) { const prevScale = changedProperties.get("scale");
const prevScale = changedProperties.get("scale"); if (prevScale !== undefined) {
if (prevScale) { if (this.scale > prevScale) {
if (this.scale > prevScale) { this.scaleUp();
this.scaleUp(); } else {
} else { this.scaleDown();
this.scaleDown();
}
} }
} }
} }
@ -185,36 +179,17 @@ export class Screencast extends LitElement {
} }
render() { render() {
const screenCount = this.scale * this.browsersCount;
return html` return html`
<div class="wrapper"> <div class="wrapper">
<div <div
class="container" class="container"
style="grid-template-columns: repeat(${this style="grid-template-columns: repeat(${screenCount > 2
.browsersCount}, minmax(0, 1fr)); grid-template-rows: repeat(${this ? Math.ceil(screenCount / 2)
.scale}, minmax(2rem, auto))" : screenCount}, 1fr);"
> >
${this.dataList.map( ${Array.from({ length: screenCount }).map((_, i) =>
(pageData) => this.renderScreen(`${i}`)
html` <figure
class="screen"
title=${pageData?.url || ""}
role=${pageData ? "button" : "presentation"}
@click=${pageData
? () => (this.focusedScreenData = pageData)
: () => {}}
>
<figcaption class="caption">
${pageData?.url || html`&nbsp;`}
</figcaption>
<div
class="frame"
style="aspect-ratio: ${this.screenWidth / this.screenHeight}"
>
${pageData
? html`<img src="data:image/png;base64,${pageData.data}" />`
: html`<sl-spinner></sl-spinner>`}
</div>
</figure>`
)} )}
</div> </div>
</div> </div>
@ -247,6 +222,26 @@ export class Screencast extends LitElement {
`; `;
} }
private renderScreen = (id: string) => {
const pageData = this.dataMap[id];
return html` <figure
class="screen"
title=${pageData?.url || ""}
role=${pageData ? "button" : "presentation"}
@click=${pageData ? () => (this.focusedScreenData = pageData) : () => {}}
>
<figcaption class="caption">${pageData?.url || html`&nbsp;`}</figcaption>
<div
class="frame"
style="aspect-ratio: ${this.screenWidth / this.screenHeight}"
>
${pageData
? html`<img src="data:image/png;base64,${pageData.data}" />`
: html`<sl-spinner></sl-spinner>`}
</div>
</figure>`;
};
private scaleUp() { private scaleUp() {
// Reconnect after 20 second delay // Reconnect after 20 second delay
this.timerIds.push( this.timerIds.push(
@ -306,22 +301,17 @@ export class Screencast extends LitElement {
message: InitMessage | ScreencastMessage | CloseMessage message: InitMessage | ScreencastMessage | CloseMessage
) { ) {
if (message.msg === "init") { if (message.msg === "init") {
this.dataList = Array.from( const dataMap: any = {};
{ length: message.browsers * this.scale }, for (let i = 0; i < message.browsers * this.scale; i++) {
() => null dataMap[i] = null;
); }
this.dataMap = this.dataList.reduce( this.dataMap = dataMap;
(acc, val, i) => ({
...acc,
[i]: val,
}),
{}
);
this.browsersCount = message.browsers; this.browsersCount = message.browsers;
this.screenWidth = message.width; this.screenWidth = message.width;
this.screenHeight = message.height; this.screenHeight = message.height;
} else { } else {
const { id } = message; const { id } = message;
const dataMap = { ...this.dataMap };
if (message.msg === "screencast") { if (message.msg === "screencast") {
if (message.url === "about:blank") { if (message.url === "about:blank") {
@ -329,34 +319,16 @@ export class Screencast extends LitElement {
return; return;
} }
let idx = this.pageOrderMap.get(id);
if (idx === undefined) {
// Find and fill first empty slot
idx = this.dataList.indexOf(null);
if (idx === -1) {
console.debug("no empty slots");
}
this.pageOrderMap.set(id, idx);
}
if (this.focusedScreenData?.id === id) { if (this.focusedScreenData?.id === id) {
this.focusedScreenData = message; this.focusedScreenData = message;
} }
this.dataMap[idx] = message; dataMap[id] = message;
this.updateDataList();
} else if (message.msg === "close") { } else if (message.msg === "close") {
const idx = this.pageOrderMap.get(id); dataMap[id] = null;
if (idx !== undefined && idx !== null) {
this.dataMap[idx] = null;
this.updateDataList();
this.pageOrderMap.set(id, -1);
}
} }
this.dataMap = dataMap;
} }
} }
@ -415,12 +387,7 @@ export class Screencast extends LitElement {
}); });
} }
updateDataList() {
this.dataList = Object.values(this.dataMap);
}
unfocusScreen() { unfocusScreen() {
this.updateDataList();
this.focusedScreenData = undefined; this.focusedScreenData = undefined;
} }
} }