Skip to content

Commit

Permalink
Added the functionality to disable video sharing and webcam for certa…
Browse files Browse the repository at this point in the history
…in agents
  • Loading branch information
arnav-ti committed Jan 13, 2025
1 parent 59a8254 commit ed976cf
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 12 deletions.
46 changes: 43 additions & 3 deletions electron/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,11 @@ async function videoWindow() {
width: 32px;
height: 32px;
}
.action-button:not(.disabled):hover {
.action-button:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.action-button:not(:disabled):not(.disabled):hover {
background-color: rgba(255, 255, 255, 0.1);
}
.material-symbols-outlined {
Expand Down Expand Up @@ -540,8 +544,35 @@ async function videoWindow() {
ipcRenderer.send('control-action', { type: 'mic', value: !isMuted });
});
// Add requiresScreen state
let requiresScreen = true;
// Add handler for mode requirements updates
ipcRenderer.on('update-mode-requirements', (event, { requiresScreen: newRequiresScreen }) => {
requiresScreen = newRequiresScreen;
// Update button disabled states
screenButton.disabled = !requiresScreen;
webcamButton.disabled = !requiresScreen;
// If switching to a mode that doesn't require screen, stop any active streams
if (!requiresScreen) {
if (isScreenSharing) {
isScreenSharing = false;
screenButton.querySelector('span').textContent = 'present_to_all';
screenButton.querySelector('span').classList.remove('filled');
ipcRenderer.send('control-action', { type: 'screen', value: false });
}
if (isWebcamOn) {
isWebcamOn = false;
webcamButton.querySelector('span').textContent = 'videocam';
ipcRenderer.send('control-action', { type: 'webcam', value: false });
}
}
});
screenButton.addEventListener('click', () => {
if (!isConnected) return;
if (!isConnected || !requiresScreen) return;
if (isScreenSharing) {
isScreenSharing = false;
screenButton.querySelector('span').textContent = 'present_to_all';
Expand All @@ -555,7 +586,7 @@ async function videoWindow() {
});
webcamButton.addEventListener('click', () => {
if (!isConnected) return;
if (!isConnected || !requiresScreen) return;
isWebcamOn = !isWebcamOn;
webcamButton.querySelector('span').textContent = isWebcamOn ? 'videocam_off' : 'videocam';
ipcRenderer.send('control-action', { type: 'webcam', value: isWebcamOn });
Expand Down Expand Up @@ -899,4 +930,13 @@ async function getSelectedText() {
// Add this with other IPC handlers
ipcMain.handle('get-selected-text', async () => {
return await getSelectedText();
});

// Add this to handle mode requirements
ipcMain.on('update-mode-requirements', (event, { requiresScreen }) => {
const windows = BrowserWindow.getAllWindows();
const videoWindow = windows.find(win => win !== mainWindow && win !== overlayWindow);
if (videoWindow) {
videoWindow.webContents.send('update-mode-requirements', { requiresScreen });
}
});
2 changes: 0 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,6 @@ function App() {
</>
)}

<SidePanel />

<main>
<div className="main-app-area">
<Subtitles
Expand Down
46 changes: 40 additions & 6 deletions src/components/control-tray/ControlTray.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { useWebcam } from "../../hooks/use-webcam";
import { AudioRecorder } from "../../lib/audio-recorder";
import AudioPulse from "../audio-pulse/AudioPulse";
import "./control-tray.scss";
import { assistantConfigs } from "../../configs/assistant-configs";
import { assistantConfigs, type AssistantConfigMode } from "../../configs/assistant-configs";
import { trackEvent } from "../../configs/analytics";
const { ipcRenderer } = window.require('electron');

Expand All @@ -44,20 +44,21 @@ type MediaStreamButtonProps = {
offIcon: string;
start: () => Promise<any>;
stop: () => any;
disabled?: boolean;
};

/**
* button used for triggering webcam or screen-capture
*/
const MediaStreamButton = memo(
({ isStreaming, onIcon, offIcon, start, stop }: MediaStreamButtonProps) =>
({ isStreaming, onIcon, offIcon, start, stop, disabled }: MediaStreamButtonProps) =>
isStreaming ? (
<button className="action-button" onClick={stop}>
<span className="material-symbols-outlined">{onIcon}</span>
<button className="action-button" onClick={stop} disabled={disabled}>
<span className={cn("material-symbols-outlined", { "disabled-icon": disabled })}>{onIcon}</span>
</button>
) : (
<button className="action-button" onClick={start}>
<span className="material-symbols-outlined">{offIcon}</span>
<button className="action-button" onClick={start} disabled={disabled}>
<span className={cn("material-symbols-outlined", { "disabled-icon": disabled })}>{offIcon}</span>
</button>
),
);
Expand All @@ -84,6 +85,10 @@ function ControlTray({

const { client, connected, connect, disconnect, volume } = useLiveAPIContext();

// Add check for screen sharing requirement
const currentMode = selectedOption.value as AssistantConfigMode;
const requiresScreen = assistantConfigs[currentMode].requires_screen;

useEffect(() => {
if (!connected && connectButtonRef.current) {
connectButtonRef.current.focus();
Expand Down Expand Up @@ -192,6 +197,10 @@ function ControlTray({
const mode = modes[carouselIndex].value as keyof typeof assistantConfigs;
const modeName = assistantConfigs[mode].display_name;
ipcRenderer.send('update-carousel', modeName);
// Send mode requirements
ipcRenderer.send('update-mode-requirements', {
requiresScreen: assistantConfigs[mode].requires_screen
});
}, [carouselIndex, modes, setSelectedOption]);

const handleCarouselChange = useCallback((direction: 'next' | 'prev') => {
Expand Down Expand Up @@ -282,6 +291,29 @@ function ControlTray({
});
}, [muted, screenCapture.isStreaming, webcam.isStreaming, connected]);

useEffect(() => {
if (!requiresScreen) {
// Stop both screen sharing and webcam if mode doesn't require it
if (screenCapture.isStreaming || webcam.isStreaming) {
changeStreams()();
}
}
}, [requiresScreen, screenCapture.isStreaming, webcam.isStreaming, changeStreams]);

// Add CSS for disabled state
const styleSheet = document.styleSheets[0];
styleSheet.insertRule(`
.action-button:disabled {
cursor: not-allowed;
opacity: 0.5;
}
`, styleSheet.cssRules.length);
styleSheet.insertRule(`
.disabled-icon {
opacity: 0.5;
}
`, styleSheet.cssRules.length);

return (<>
<section className="control-tray">
<div className="control-tray-container">
Expand Down Expand Up @@ -309,13 +341,15 @@ function ControlTray({
stop={changeStreams()}
onIcon="cancel_presentation"
offIcon="present_to_all"
disabled={!requiresScreen}
/>
<MediaStreamButton
isStreaming={webcam.isStreaming}
start={changeStreams(webcam)}
stop={changeStreams()}
onIcon="videocam_off"
offIcon="videocam"
disabled={!requiresScreen}
/>
</>
)}
Expand Down
5 changes: 4 additions & 1 deletion src/configs/assistant-configs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export const readWriteTools: Tool[] = [
export const assistantConfigs = {
daily_helper: {
display_name: "Daily Helper",
requires_screen: true,
tools: [({googleSearch: {}} as Tool)],
systemInstruction: `You are ScreenSense AI, operating in Daily Assistant Mode.
Expand All @@ -103,7 +104,8 @@ Your role:
Your mission: Provide the best possible assistance for the user’s daily tasks using all the resources and abilities at your disposal while respecting the guidelines above.`
},
translator: {
display_name: "Transcriber",
display_name: "Transcriber",
requires_screen: false,
tools: translationTools,
systemInstruction: `You are ScreenSense AI, operating in Translator Mode.
Expand Down Expand Up @@ -139,6 +141,7 @@ Your mission: Provide accurate, real-time English subtitles from spoken content
},
author: {
display_name: "Author",
requires_screen: false,
tools: [...readWriteTools],
systemInstruction: `
You are ScreenSense AI, operating in Author Mode.
Expand Down

0 comments on commit ed976cf

Please sign in to comment.