feat: send screen recordings (#128)
* first pass implementation * remove screenrecord shortcut hint * refactor * fix: prevent mirror review of screen recording * feat: allow recording with webcam overlay * fix: review screen recording without clipped content * tidy keyboard hints consistent position * refactor: re-use one component for screen picker huddles and screen clips use same picker component now. We had to make sure that tailwind works for both of them. * fix: improve visibility of keyboard hints During compose video or screen recording, the keyboard hints were invisible if the content was super bright.
This commit was merged in pull request #128.
This commit is contained in:
@@ -25,6 +25,7 @@ if (process.platform === 'darwin' && !app.isPackaged) {
|
||||
let mainWindow: BrowserWindow | null = null;
|
||||
let autoplayWindow: BrowserWindow | null = null;
|
||||
let huddleWindow: BrowserWindow | null = null;
|
||||
let screenRecordWindow: BrowserWindow | null = null;
|
||||
|
||||
const createWindow = () => {
|
||||
mainWindow = new BrowserWindow({
|
||||
@@ -121,6 +122,43 @@ function positionAutoplayWindow() {
|
||||
autoplayWindow.setPosition(width - winW - 16, 16);
|
||||
}
|
||||
|
||||
const createScreenRecordWindow = () => {
|
||||
if (screenRecordWindow) return;
|
||||
|
||||
const { width, height } = screen.getPrimaryDisplay().workAreaSize;
|
||||
const winW = 240;
|
||||
const winH = 48;
|
||||
|
||||
screenRecordWindow = new BrowserWindow({
|
||||
width: winW,
|
||||
height: winH,
|
||||
x: Math.round((width - winW) / 2),
|
||||
y: height - winH - 32,
|
||||
resizable: false,
|
||||
frame: false,
|
||||
alwaysOnTop: true,
|
||||
skipTaskbar: true,
|
||||
focusable: true,
|
||||
show: false,
|
||||
webPreferences: {
|
||||
preload: path.join(__dirname, 'preload.js'),
|
||||
},
|
||||
});
|
||||
screenRecordWindow.setVisibleOnAllWorkspaces(true);
|
||||
|
||||
if (SCREEN_RECORD_WINDOW_VITE_DEV_SERVER_URL) {
|
||||
screenRecordWindow.loadURL(SCREEN_RECORD_WINDOW_VITE_DEV_SERVER_URL);
|
||||
} else {
|
||||
screenRecordWindow.loadFile(
|
||||
path.join(__dirname, `../renderer/${SCREEN_RECORD_WINDOW_VITE_NAME}/index.html`),
|
||||
);
|
||||
}
|
||||
|
||||
screenRecordWindow.on('closed', () => {
|
||||
screenRecordWindow = null;
|
||||
});
|
||||
};
|
||||
|
||||
// Window control IPC handlers
|
||||
ipcMain.on('window:minimize', (event) => {
|
||||
BrowserWindow.fromWebContents(event.sender)?.minimize();
|
||||
@@ -170,6 +208,41 @@ ipcMain.handle('screen:get-sources', async () => {
|
||||
}));
|
||||
});
|
||||
|
||||
// Screen recording IPC handlers
|
||||
ipcMain.on('screen-record:start', (_event, data: { includeCamera: boolean }) => {
|
||||
createScreenRecordWindow();
|
||||
if (!screenRecordWindow) return;
|
||||
|
||||
// Resize based on whether camera preview is shown
|
||||
const winW = data.includeCamera ? 200 : 240;
|
||||
const winH = data.includeCamera ? 176 : 48;
|
||||
const { width, height } = screen.getPrimaryDisplay().workAreaSize;
|
||||
screenRecordWindow.setSize(winW, winH);
|
||||
screenRecordWindow.setPosition(
|
||||
Math.round((width - winW) / 2),
|
||||
height - winH - 32,
|
||||
);
|
||||
|
||||
const send = () => {
|
||||
screenRecordWindow?.webContents.send('screen-record:init', data);
|
||||
screenRecordWindow?.showInactive();
|
||||
};
|
||||
|
||||
if (screenRecordWindow.webContents.isLoading()) {
|
||||
screenRecordWindow.webContents.once('did-finish-load', send);
|
||||
} else {
|
||||
send();
|
||||
}
|
||||
});
|
||||
ipcMain.on('screen-record:stop', () => {
|
||||
mainWindow?.webContents.send('screen-record:stopped');
|
||||
screenRecordWindow?.close();
|
||||
mainWindow?.focus();
|
||||
});
|
||||
ipcMain.on('screen-record:cancel', () => {
|
||||
screenRecordWindow?.close();
|
||||
});
|
||||
|
||||
// Autoplay IPC handlers
|
||||
ipcMain.on('autoplay:play', (_event, payload) => {
|
||||
if (!autoplayWindow) createAutoplayWindow();
|
||||
|
||||
Reference in New Issue
Block a user