{"id":31646393,"url":"https://github.com/tchongas/mcsrobsremote","last_synced_at":"2026-02-12T06:18:09.004Z","repository":{"id":314498732,"uuid":"1047979147","full_name":"Tchongas/MCSRobsremote","owner":"Tchongas","description":"Remote Obs Controller in Electron","archived":false,"fork":false,"pushed_at":"2025-10-02T03:45:59.000Z","size":615,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-02T05:23:27.365Z","etag":null,"topics":["electron","obs-studio"],"latest_commit_sha":null,"homepage":"http://tchongas.red/MCSRobsremote/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Tchongas.png","metadata":{"files":{"readme":"README-HANDLERS.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-31T16:49:39.000Z","updated_at":"2025-10-02T03:45:52.000Z","dependencies_parsed_at":"2025-09-12T21:44:11.731Z","dependency_job_id":"0e0e5a99-c4ea-4be3-a271-1a4f510dbf0f","html_url":"https://github.com/Tchongas/MCSRobsremote","commit_stats":null,"previous_names":["tchongas/mcsrobsremote"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/Tchongas/MCSRobsremote","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tchongas%2FMCSRobsremote","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tchongas%2FMCSRobsremote/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tchongas%2FMCSRobsremote/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tchongas%2FMCSRobsremote/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Tchongas","download_url":"https://codeload.github.com/Tchongas/MCSRobsremote/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tchongas%2FMCSRobsremote/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278727839,"owners_count":26035410,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-07T02:00:06.786Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["electron","obs-studio"],"created_at":"2025-10-07T05:49:26.810Z","updated_at":"2025-10-07T05:49:29.935Z","avatar_url":"https://github.com/Tchongas.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Source Handler System\n\n## Overview\n\nThe dashboard now uses a modular, plugin-like architecture for source controls. Each source type (browser, microphone, etc.) has its own dedicated handler that registers with the central `HandlerRegistry`.\n\n## Architecture\n\n```\nrenderer/logic/\n├── handlers/\n│   ├── HandlerRegistry.js      # Central registry system\n│   ├── BrowserSourceHandler.js # Browser source controls\n│   └── MicrophoneHandler.js    # Microphone controls\n├── dashboard.js                # Main dashboard (now lightweight)\n└── sourceTypes.js              # Type detection utilities\n```\n\n## Handler Interface\n\nEach handler must implement:\n\n```javascript\nconst MyHandler = {\n  name: 'MyHandler',           // Required: unique identifier\n  version: '1.0.0',           // Optional: version string\n  \n  // Required: determines if this handler applies to a source\n  canHandle(sourceKind, sourceName, context) {\n    return sourceKind === 'my_source_type';\n  },\n  \n  // Required: creates UI controls for the source\n  async createControls(options, sourceName, displayName, context) {\n    // Add controls to the options DOM element\n  },\n  \n  // Optional: handler execution priority (higher = first)\n  priority() {\n    return 5;\n  },\n  \n  // Optional: handle remote updates (e.g., mute state changes)\n  onRemoteUpdate(sourceName, eventType, data) {\n    // Update UI based on remote changes\n  },\n  \n  // Optional: cleanup when source is removed\n  cleanup(sourceName) {\n    // Cleanup resources\n  }\n};\n```\n\n## Creating New Handlers\n\n1. **Create handler file**: `renderer/logic/handlers/MySourceHandler.js`\n\n```javascript\n(function() {\n  const MySourceHandler = {\n    name: 'MySourceHandler',\n    version: '1.0.0',\n    \n    canHandle(sourceKind, sourceName, context) {\n      return sourceKind === 'my_source_type';\n    },\n    \n    async createControls(options, sourceName, displayName, context) {\n      const row = document.createElement('div');\n      row.className = 'dash-option-row';\n      \n      const button = document.createElement('button');\n      button.textContent = 'My Control';\n      button.addEventListener('click', async () =\u003e {\n        // Handle button click\n      });\n      \n      row.appendChild(button);\n      options.appendChild(row);\n    }\n  };\n\n  // Auto-register when loaded\n  if (window.HandlerRegistry) {\n    window.HandlerRegistry.register(MySourceHandler);\n  } else {\n    window.addEventListener('handlerRegistryReady', () =\u003e {\n      window.HandlerRegistry.register(MySourceHandler);\n    });\n  }\n})();\n```\n\n2. **Add to HTML**: Include script in `index.html` after `HandlerRegistry.js`\n\n```html\n\u003cscript src=\"renderer/logic/handlers/MySourceHandler.js\"\u003e\u003c/script\u003e\n```\n\n## Registry API\n\n```javascript\n// Register a handler\nwindow.HandlerRegistry.register(handler);\n\n// Unregister a handler\nwindow.HandlerRegistry.unregister('HandlerName');\n\n// Process source (called by dashboard)\nawait window.HandlerRegistry.processSource(options, sourceName, displayName, context);\n\n// Handle remote updates\nwindow.HandlerRegistry.handleRemoteUpdate(sourceName, eventType, data);\n\n// Get registered handlers (debugging)\nwindow.HandlerRegistry.getRegisteredHandlers();\n```\n\n## Context Object\n\nHandlers receive a context object with:\n\n```javascript\n{\n  inputKindMap: Map,    // sourceName -\u003e inputKind mapping\n  micNameSet: Set       // Set of detected microphone names\n}\n```\n\n## Benefits\n\n- **Modularity**: Each source type is self-contained\n- **Extensibility**: Easy to add new source types\n- **Maintainability**: Clear separation of concerns\n- **Testability**: Handlers can be tested independently\n- **Performance**: Only applicable handlers are executed\n- **Priority System**: Control execution order\n- **Hot-swappable**: Handlers can be registered/unregistered at runtime\n\n## Examples\n\nSee existing handlers:\n- `BrowserSourceHandler.js`: URL editing, parameter controls\n- `MicrophoneHandler.js`: Mute/unmute, volume control\n\n## Migration Notes\n\nThe old monolithic approach in `dashboard.js` has been replaced with this handler system. The dashboard now:\n\n1. Builds context from OBS inputs\n2. Calls `HandlerRegistry.processSource()` for each item\n3. Handlers determine applicability and create controls\n4. Remote updates are forwarded to applicable handlers\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftchongas%2Fmcsrobsremote","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftchongas%2Fmcsrobsremote","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftchongas%2Fmcsrobsremote/lists"}