facetime-commands.ts
1 import { Plugin } from 'obsidian'; 2 import { UIService } from '../services/ui-service'; 3 import { FaceTimeService } from '../services/facetime-service'; 4 import { useInterBrainStore } from '../store/interbrain-store'; 5 import { VaultService } from '../services/vault-service'; 6 7 /** 8 * FaceTime integration commands for video calling 9 */ 10 export function registerFaceTimeCommands( 11 plugin: Plugin, 12 uiService: UIService, 13 vaultService: VaultService, 14 faceTimeService: FaceTimeService 15 ): void { 16 17 // Start Video Call - Initiates FaceTime call with selected person 18 plugin.addCommand({ 19 id: 'start-video-call', 20 name: 'Start Video Call', 21 callback: async () => { 22 try { 23 const store = useInterBrainStore.getState(); 24 const selectedNode = store.selectedNode; 25 26 // Validate node selection 27 if (!selectedNode) { 28 uiService.showError('Please select a person DreamNode first'); 29 return; 30 } 31 32 // Validate node type 33 if (selectedNode.type !== 'dreamer') { 34 uiService.showError('Video calls are only available for person (dreamer) nodes'); 35 return; 36 } 37 38 console.log(`Starting video call with: ${selectedNode.name}`); 39 40 // Read metadata to get contact info 41 const metadataPath = `${selectedNode.repoPath}/.udd`; 42 let metadata; 43 44 try { 45 const metadataContent = await vaultService.readFile(metadataPath); 46 metadata = JSON.parse(metadataContent); 47 } catch (error) { 48 console.error('Failed to read metadata:', error); 49 uiService.showError('Failed to read DreamNode metadata'); 50 return; 51 } 52 53 // Check for contact information 54 const email = metadata.email; 55 const phone = metadata.phone; 56 57 if (!email && !phone) { 58 uiService.showError( 59 'No contact information found for this person. Please add an email or phone number to the DreamNode metadata.' 60 ); 61 return; 62 } 63 64 // Use email if available, otherwise phone 65 const contact = email || phone; 66 67 // Show loading state 68 uiService.showInfo(`Initiating FaceTime call with ${selectedNode.name}...`); 69 70 // Start the FaceTime call 71 await faceTimeService.startCall(contact); 72 73 // Trigger the full Start Conversation Mode command (which handles copilot mode + transcription) 74 (plugin.app as any).commands.executeCommandById('interbrain:start-conversation-mode'); 75 76 uiService.showSuccess(`FaceTime call started with ${selectedNode.name}`); 77 } catch (error) { 78 console.error('Start Video Call command failed:', error); 79 uiService.showError( 80 `Failed to start video call: ${error instanceof Error ? error.message : 'Unknown error'}` 81 ); 82 } 83 } 84 }); 85 86 // End Video Call - Quits FaceTime and exits copilot mode 87 plugin.addCommand({ 88 id: 'end-video-call', 89 name: 'End Video Call', 90 callback: async () => { 91 try { 92 const store = useInterBrainStore.getState(); 93 94 // Show loading state 95 uiService.showInfo('Ending FaceTime call...'); 96 97 // End the FaceTime call 98 await faceTimeService.endCall(); 99 100 // Trigger the full End Conversation Mode command (which handles copilot exit + cleanup) 101 if (store.spatialLayout === 'copilot') { 102 (plugin.app as any).commands.executeCommandById('interbrain:end-conversation-mode'); 103 } 104 105 uiService.showSuccess('FaceTime call ended'); 106 } catch (error) { 107 console.error('End Video Call command failed:', error); 108 uiService.showError( 109 `Failed to end video call: ${error instanceof Error ? error.message : 'Unknown error'}` 110 ); 111 } 112 } 113 }); 114 }