From a3c80b319ada5d49e04fe2c42bd30eb9fc88c55c Mon Sep 17 00:00:00 2001
From: Florian Raith <37345813+FlorianRaith@users.noreply.github.com>
Date: Fri, 4 Aug 2023 14:37:35 +0200
Subject: [PATCH] Sync browser url (#42)

* Sync browser url

* Format code
---
 src/browser/browser.service.ts | 52 +++++++++-------------------------
 src/browser/browser.ts         | 22 ++++++++------
 src/channel/browser.gateway.ts |  1 +
 src/channel/channel.gateway.ts |  2 ++
 4 files changed, 30 insertions(+), 47 deletions(-)

diff --git a/src/browser/browser.service.ts b/src/browser/browser.service.ts
index 5140ee3..e4d8831 100644
--- a/src/browser/browser.service.ts
+++ b/src/browser/browser.service.ts
@@ -1,8 +1,10 @@
 import { Browser } from './browser';
 import { Injectable, Logger, OnModuleDestroy } from '@nestjs/common';
-import puppeteer, { Browser as PuppeteerBrowser } from 'puppeteer';
+import puppeteer from 'puppeteer';
 import * as path from 'path';
 import * as process from 'process';
+import { Server } from 'socket.io';
+import { Channel } from '../channel/channel';
 
 const LOGGER = new Logger('BrowserService');
 
@@ -11,8 +13,7 @@ const EXTENSION_ID = 'jjndjgheafjngoipoacpjgeicjeomjli';
 
 @Injectable()
 export class BrowserService implements OnModuleDestroy {
-  public browser: PuppeteerBrowser | null;
-  public browserContexts: Map<string, Browser> = new Map();
+  private browserContexts: Map<string, Browser> = new Map();
 
   private async openBrowser() {
     const args = [];
@@ -34,48 +35,21 @@ export class BrowserService implements OnModuleDestroy {
         height: 1080,
       },
     });
-
-    /**
-     * Tried to enable extension in incognito mode, so that for every new room a
-     * new IncognitoBrowserContext is created instead of a completely new browser.
-     * But I did not get this to work.
-     *
-     * In theory if a new browser instance is created for every room, this code can
-     * be moved into the browser class.
-     */
-    /*
-    const settings = await this.browser.newPage();
-    await settings.goto(`chrome://extensions/?id=${EXTENSION_ID}`);
-    await settings.evaluate(() => {
-      (document as any)
-        .querySelector('extensions-manager')
-        .shadowRoot.querySelector(
-          '#viewManager > extensions-detail-view.active',
-        )
-        .shadowRoot.querySelector(
-          'div#container.page-container > div.page-content > div#options-section extensions-toggle-row#allow-incognito',
-        )
-        .shadowRoot.querySelector('label#label input')
-        .click();
-    });
-    await settings.close();
-     */
   }
 
-  public async openWebsite(channelId: string, url: string): Promise<string> {
+  public async openWebsite(
+    channelId: string,
+    url: string,
+    server: Server,
+  ): Promise<string> {
     LOGGER.debug(`Opening website with url: ${url}`);
 
-    /*if (!this.browser) {
-      await this.openBrowser();
-    }*/
-
     if (!this.browserContexts.has(channelId)) {
       LOGGER.debug(`Creating new browser context for channel: ${channelId}`);
 
-      //const browserContext = await this.browser.createIncognitoBrowserContext();
       const browserContext = await this.openBrowser();
 
-      const browser = new Browser(browserContext, url);
+      const browser = new Browser(browserContext, url, server, channelId);
 
       this.browserContexts.set(channelId, browser);
 
@@ -92,6 +66,10 @@ export class BrowserService implements OnModuleDestroy {
     return this.browserContexts.get(channelId)?.peerId;
   }
 
+  public getFromChannel(channel: Channel): Browser | null {
+    return this.browserContexts.get(channel.id) ?? null;
+  }
+
   public async moveMouse(
     channelId: string,
     x: number,
@@ -138,8 +116,6 @@ export class BrowserService implements OnModuleDestroy {
   }
 
   public async close(): Promise<void> {
-    await this.browser?.close();
-
     for (const browser of this.browserContexts.values()) {
       await browser.close();
     }
diff --git a/src/browser/browser.ts b/src/browser/browser.ts
index 81c754b..10c7fa0 100644
--- a/src/browser/browser.ts
+++ b/src/browser/browser.ts
@@ -1,12 +1,8 @@
-import {
-  Browser as PuppeteerBrowser,
-  BrowserContext,
-  KeyInput,
-  Page,
-} from 'puppeteer';
+import { Browser as PuppeteerBrowser, KeyInput, Page } from 'puppeteer';
 import { Logger } from '@nestjs/common';
 import * as path from 'path';
 import * as process from 'process';
+import { Server } from 'socket.io';
 
 const LOGGER = new Logger('Browser');
 
@@ -19,8 +15,9 @@ export class Browser {
 
   constructor(
     private browser: PuppeteerBrowser,
-    // private browser: BrowserContext,
-    public readonly url: string,
+    public url: string,
+    private readonly server: Server,
+    private readonly channelId: string,
   ) {}
 
   public async open(): Promise<string> {
@@ -32,6 +29,13 @@ export class Browser {
     await this.page.goto(this.url);
     await this.page.setViewport({ width: 1920, height: 1080 });
 
+    this.page.on('domcontentloaded', async () => {
+      const url = await this.page.url();
+      this.url = url;
+      this.server.to(this.channelId).emit('browser-url', url);
+      await this.page.setViewport({ width: 1920, height: 1080 });
+    });
+
     this.page.on('load', async () => {
       /**
        * For some reason every a time a page is loaded (e.g. after clicking a link)
@@ -48,7 +52,6 @@ export class Browser {
     await this.page.bringToFront();
 
     const id = await extensionPage.evaluate(async () => {
-      console.log('hello world');
       // eslint-disable-next-line @typescript-eslint/ban-ts-comment
       // @ts-ignore
       return await START_RECORDING();
@@ -183,6 +186,7 @@ async function installMouseHelper(page) {
           },
           true,
         );
+
         function updateButtons(buttons) {
           for (let i = 0; i < 5; i++) {
             // eslint-disable-next-line @typescript-eslint/ban-ts-comment
diff --git a/src/channel/browser.gateway.ts b/src/channel/browser.gateway.ts
index 09f685b..33d34b8 100644
--- a/src/channel/browser.gateway.ts
+++ b/src/channel/browser.gateway.ts
@@ -41,6 +41,7 @@ export class BrowserGateway {
     const peerId = await this.browserService.openWebsite(
       channel.id,
       payload.url,
+      this.server,
     );
     this.server.to(channel.id).emit('open-website', peerId);
 
diff --git a/src/channel/channel.gateway.ts b/src/channel/channel.gateway.ts
index 1ef1775..e7c09e0 100644
--- a/src/channel/channel.gateway.ts
+++ b/src/channel/channel.gateway.ts
@@ -123,9 +123,11 @@ export class ChannelGateway implements OnGatewayConnection {
     }));
 
     const browserPeerId = this.browsers.getPeerId(channel.id);
+    const browser = this.browsers.getFromChannel(channel);
 
     return {
       browserPeerId: browserPeerId || '',
+      browserUrl: browser?.url || 'https://www.google.com',
       room: {
         ...channel.room,
         category: channel.room.category.id,
-- 
GitLab