diff --git a/desktop/app.js b/desktop/app.js
index 584c5f2..e4d43c8 100644
--- a/desktop/app.js
+++ b/desktop/app.js
@@ -702,6 +702,19 @@ function renderVideo(peerId, displayName, stream, source) {
${label}
`;
+ container.onclick = () => {
+ const isFullscreen = container.classList.contains('fullscreen');
+ // Reset all
+ document.querySelectorAll('.video-item').forEach(el => el.classList.remove('fullscreen'));
+
+ if (isFullscreen) {
+ el.videoGrid.classList.remove('has-fullscreen');
+ } else {
+ container.classList.add('fullscreen');
+ el.videoGrid.classList.add('has-fullscreen');
+ }
+ };
+
el.videoGrid.appendChild(container);
videoEl = container.querySelector("video");
}
diff --git a/desktop/styles.css b/desktop/styles.css
index 03887fe..fa213cb 100644
--- a/desktop/styles.css
+++ b/desktop/styles.css
@@ -638,7 +638,14 @@ select {
background: #000;
border-radius: var(--radius-lg);
overflow: hidden;
- transition: box-shadow var(--transition);
+ transition: all var(--transition);
+ cursor: pointer;
+ z-index: 1;
+}
+
+.video-item:hover {
+ box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.2);
+ z-index: 2;
}
.video-item video {
@@ -646,6 +653,37 @@ select {
height: 100%;
object-fit: contain;
background: #000;
+ pointer-events: none;
+}
+
+/* Fullscreen Feed Support */
+.video-grid.has-fullscreen {
+ display: flex;
+ padding: 0;
+ overflow: hidden;
+ position: absolute;
+ top: 48px;
+ /* Below chat-header */
+ left: 0;
+ right: 0;
+ bottom: 0;
+ z-index: 100;
+ background: var(--bg-main);
+}
+
+.video-grid.has-fullscreen .video-item {
+ display: none;
+}
+
+.video-grid.has-fullscreen .video-item.fullscreen {
+ display: block;
+ flex: 1;
+ width: 100%;
+ height: 100%;
+ border-radius: 0;
+ cursor: zoom-out;
+ z-index: 10;
+ aspect-ratio: auto;
}
.video-item .video-label {
@@ -659,6 +697,8 @@ select {
border-radius: 100px;
font-size: 12px;
font-weight: 500;
+ pointer-events: none;
+ z-index: 5;
}
/* Voice Activity */
@@ -786,6 +826,7 @@ select {
/* Chat Pane */
/* ═══════════════════════════════════════════════════════════ */
.chat-pane {
+ position: relative;
display: flex;
flex-direction: column;
background: var(--bg-main);
diff --git a/main.js b/main.js
index 67053af..9cf53ae 100644
--- a/main.js
+++ b/main.js
@@ -64,29 +64,36 @@ function createWindow() {
console.log(`Loading desktop app from: ${localUrl}`);
- const loadDesktopApp = () => {
- win.loadURL(localUrl).catch((err) => {
+ const loadDesktopApp = (queryParams = '') => {
+ const fullUrl = queryParams ? `${localUrl}&${queryParams}` : localUrl;
+ win.loadURL(fullUrl).catch((err) => {
console.error(`Failed to load desktop file: ${err}`);
});
};
// Use a navigation listener to detect when the remote login is complete
win.webContents.on('will-navigate', (event, navigatedUrl) => {
- const normalizedNav = navigatedUrl.replace(/\/$/, '');
- // If the user lands back on the remote root, they are logged in.
- // Redirect them back to our local bugfixed desktop UI.
- if (normalizedNav === backendUrl) {
- console.log("Detected remote landing (login success), returning to desktop UI...");
- event.preventDefault();
- loadDesktopApp();
+ try {
+ const urlObj = new URL(navigatedUrl);
+ const backendObj = new URL(backendUrl);
+ if (urlObj.origin === backendObj.origin && urlObj.pathname === '/') {
+ console.log("Detected remote landing (login success), returning to desktop UI...");
+ event.preventDefault();
+ loadDesktopApp(urlObj.search.slice(1));
+ }
+ } catch (e) {
+ console.error(e);
}
});
win.webContents.on('did-navigate', (event, navigatedUrl) => {
- const normalizedNav = navigatedUrl.replace(/\/$/, '');
- if (normalizedNav === backendUrl) {
- loadDesktopApp();
- }
+ try {
+ const urlObj = new URL(navigatedUrl);
+ const backendObj = new URL(backendUrl);
+ if (urlObj.origin === backendObj.origin && urlObj.pathname === '/') {
+ loadDesktopApp(urlObj.search.slice(1));
+ }
+ } catch (e) { }
});
loadDesktopApp();
@@ -95,6 +102,9 @@ function createWindow() {
// win.webContents.openDevTools();
}
+app.commandLine.appendSwitch('disable-webrtc-hw-encoding'); // Sometime helps resolve codec mismatch behavior
+app.commandLine.appendSwitch('log-level', '3'); // Silences standard Chromium warning logs (like SRTP transport unprotect logs which are benign timing issues)
+
app.whenReady().then(() => {
createWindow();
diff --git a/static/app.js b/static/app.js
index e8e0058..b25e224 100644
--- a/static/app.js
+++ b/static/app.js
@@ -684,6 +684,19 @@ function renderVideo(peerId, displayName, stream, source) {
${label}
`;
+ container.onclick = () => {
+ const isFullscreen = container.classList.contains('fullscreen');
+ // Reset all
+ document.querySelectorAll('.video-item').forEach(el => el.classList.remove('fullscreen'));
+
+ if (isFullscreen) {
+ el.videoGrid.classList.remove('has-fullscreen');
+ } else {
+ container.classList.add('fullscreen');
+ el.videoGrid.classList.add('has-fullscreen');
+ }
+ };
+
el.videoGrid.appendChild(container);
videoEl = container.querySelector("video");
}
diff --git a/static/styles.css b/static/styles.css
index 03887fe..fa213cb 100644
--- a/static/styles.css
+++ b/static/styles.css
@@ -638,7 +638,14 @@ select {
background: #000;
border-radius: var(--radius-lg);
overflow: hidden;
- transition: box-shadow var(--transition);
+ transition: all var(--transition);
+ cursor: pointer;
+ z-index: 1;
+}
+
+.video-item:hover {
+ box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.2);
+ z-index: 2;
}
.video-item video {
@@ -646,6 +653,37 @@ select {
height: 100%;
object-fit: contain;
background: #000;
+ pointer-events: none;
+}
+
+/* Fullscreen Feed Support */
+.video-grid.has-fullscreen {
+ display: flex;
+ padding: 0;
+ overflow: hidden;
+ position: absolute;
+ top: 48px;
+ /* Below chat-header */
+ left: 0;
+ right: 0;
+ bottom: 0;
+ z-index: 100;
+ background: var(--bg-main);
+}
+
+.video-grid.has-fullscreen .video-item {
+ display: none;
+}
+
+.video-grid.has-fullscreen .video-item.fullscreen {
+ display: block;
+ flex: 1;
+ width: 100%;
+ height: 100%;
+ border-radius: 0;
+ cursor: zoom-out;
+ z-index: 10;
+ aspect-ratio: auto;
}
.video-item .video-label {
@@ -659,6 +697,8 @@ select {
border-radius: 100px;
font-size: 12px;
font-weight: 500;
+ pointer-events: none;
+ z-index: 5;
}
/* Voice Activity */
@@ -786,6 +826,7 @@ select {
/* Chat Pane */
/* ═══════════════════════════════════════════════════════════ */
.chat-pane {
+ position: relative;
display: flex;
flex-direction: column;
background: var(--bg-main);
diff --git a/test.html b/test.html
new file mode 100644
index 0000000..b7652f7
--- /dev/null
+++ b/test.html
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+