@memberjunction/ng-conversations 6.2.0-edge.2 → 6.2.0-edge.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (279) hide show
  1. package/README.md +4 -7
  2. package/dist/lib/components/collection/collection-view.component.d.ts.map +1 -1
  3. package/dist/lib/components/collection/collection-view.component.js +1 -0
  4. package/dist/lib/components/collection/collection-view.component.js.map +1 -1
  5. package/dist/lib/components/composer/ai-composer.component.d.ts +14 -2
  6. package/dist/lib/components/composer/ai-composer.component.d.ts.map +1 -1
  7. package/dist/lib/components/composer/ai-composer.component.js +35 -4
  8. package/dist/lib/components/composer/ai-composer.component.js.map +1 -1
  9. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +632 -55
  10. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
  11. package/dist/lib/components/conversation/conversation-chat-area.component.js +2748 -624
  12. package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
  13. package/dist/lib/components/conversation/forks-popover.component.d.ts +37 -0
  14. package/dist/lib/components/conversation/forks-popover.component.d.ts.map +1 -0
  15. package/dist/lib/components/conversation/forks-popover.component.js +164 -0
  16. package/dist/lib/components/conversation/forks-popover.component.js.map +1 -0
  17. package/dist/lib/components/export/export-modal.component.d.ts +7 -2
  18. package/dist/lib/components/export/export-modal.component.d.ts.map +1 -1
  19. package/dist/lib/components/export/export-modal.component.js +16 -3
  20. package/dist/lib/components/export/export-modal.component.js.map +1 -1
  21. package/dist/lib/components/message/conversation-message-rating.component.d.ts.map +1 -1
  22. package/dist/lib/components/message/conversation-message-rating.component.js +11 -9
  23. package/dist/lib/components/message/conversation-message-rating.component.js.map +1 -1
  24. package/dist/lib/components/message/message-input.component.d.ts +121 -11
  25. package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
  26. package/dist/lib/components/message/message-input.component.js +307 -106
  27. package/dist/lib/components/message/message-input.component.js.map +1 -1
  28. package/dist/lib/components/message/message-item.component.d.ts +178 -5
  29. package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
  30. package/dist/lib/components/message/message-item.component.js +919 -306
  31. package/dist/lib/components/message/message-item.component.js.map +1 -1
  32. package/dist/lib/components/message/message-list.component.d.ts +92 -21
  33. package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
  34. package/dist/lib/components/message/message-list.component.js +337 -52
  35. package/dist/lib/components/message/message-list.component.js.map +1 -1
  36. package/dist/lib/components/realtime/avatar/realtime-avatar-channel.d.ts +34 -0
  37. package/dist/lib/components/realtime/avatar/realtime-avatar-channel.d.ts.map +1 -0
  38. package/dist/lib/components/realtime/avatar/realtime-avatar-channel.js +75 -0
  39. package/dist/lib/components/realtime/avatar/realtime-avatar-channel.js.map +1 -0
  40. package/dist/lib/components/realtime/avatar/realtime-avatar-surface.component.d.ts +80 -0
  41. package/dist/lib/components/realtime/avatar/realtime-avatar-surface.component.d.ts.map +1 -0
  42. package/dist/lib/components/realtime/avatar/realtime-avatar-surface.component.js +202 -0
  43. package/dist/lib/components/realtime/avatar/realtime-avatar-surface.component.js.map +1 -0
  44. package/dist/lib/components/realtime/capture/realtime-camera-check-card.component.d.ts +45 -0
  45. package/dist/lib/components/realtime/capture/realtime-camera-check-card.component.d.ts.map +1 -0
  46. package/dist/lib/components/realtime/capture/realtime-camera-check-card.component.js +123 -0
  47. package/dist/lib/components/realtime/capture/realtime-camera-check-card.component.js.map +1 -0
  48. package/dist/lib/components/realtime/capture/realtime-capture-channel.d.ts +90 -0
  49. package/dist/lib/components/realtime/capture/realtime-capture-channel.d.ts.map +1 -0
  50. package/dist/lib/components/realtime/capture/realtime-capture-channel.js +223 -0
  51. package/dist/lib/components/realtime/capture/realtime-capture-channel.js.map +1 -0
  52. package/dist/lib/components/realtime/capture/realtime-capture-model.d.ts +98 -0
  53. package/dist/lib/components/realtime/capture/realtime-capture-model.d.ts.map +1 -0
  54. package/dist/lib/components/realtime/capture/realtime-capture-model.js +161 -0
  55. package/dist/lib/components/realtime/capture/realtime-capture-model.js.map +1 -0
  56. package/dist/lib/components/realtime/capture/realtime-capture-surface.component.d.ts +48 -0
  57. package/dist/lib/components/realtime/capture/realtime-capture-surface.component.d.ts.map +1 -0
  58. package/dist/lib/components/realtime/capture/realtime-capture-surface.component.js +205 -0
  59. package/dist/lib/components/realtime/capture/realtime-capture-surface.component.js.map +1 -0
  60. package/dist/lib/components/realtime/channels/client-context-channel.d.ts +19 -2
  61. package/dist/lib/components/realtime/channels/client-context-channel.d.ts.map +1 -1
  62. package/dist/lib/components/realtime/channels/client-context-channel.js +83 -9
  63. package/dist/lib/components/realtime/channels/client-context-channel.js.map +1 -1
  64. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts +30 -9
  65. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts.map +1 -1
  66. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js +78 -14
  67. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js.map +1 -1
  68. package/dist/lib/components/realtime/identity-verification/identity-verification-channel.d.ts +71 -0
  69. package/dist/lib/components/realtime/identity-verification/identity-verification-channel.d.ts.map +1 -0
  70. package/dist/lib/components/realtime/identity-verification/identity-verification-channel.js +259 -0
  71. package/dist/lib/components/realtime/identity-verification/identity-verification-channel.js.map +1 -0
  72. package/dist/lib/components/realtime/identity-verification/identity-verification-model.d.ts +129 -0
  73. package/dist/lib/components/realtime/identity-verification/identity-verification-model.d.ts.map +1 -0
  74. package/dist/lib/components/realtime/identity-verification/identity-verification-model.js +373 -0
  75. package/dist/lib/components/realtime/identity-verification/identity-verification-model.js.map +1 -0
  76. package/dist/lib/components/realtime/identity-verification/identity-verification-surface.component.d.ts +77 -0
  77. package/dist/lib/components/realtime/identity-verification/identity-verification-surface.component.d.ts.map +1 -0
  78. package/dist/lib/components/realtime/identity-verification/identity-verification-surface.component.js +420 -0
  79. package/dist/lib/components/realtime/identity-verification/identity-verification-surface.component.js.map +1 -0
  80. package/dist/lib/components/realtime/interactive-component/component-contract.d.ts +83 -0
  81. package/dist/lib/components/realtime/interactive-component/component-contract.d.ts.map +1 -0
  82. package/dist/lib/components/realtime/interactive-component/component-contract.js +292 -0
  83. package/dist/lib/components/realtime/interactive-component/component-contract.js.map +1 -0
  84. package/dist/lib/components/realtime/interactive-component/component-data-state.d.ts +39 -0
  85. package/dist/lib/components/realtime/interactive-component/component-data-state.d.ts.map +1 -0
  86. package/dist/lib/components/realtime/interactive-component/component-data-state.js +152 -0
  87. package/dist/lib/components/realtime/interactive-component/component-data-state.js.map +1 -0
  88. package/dist/lib/components/realtime/interactive-component/component-instance-engine.d.ts +109 -0
  89. package/dist/lib/components/realtime/interactive-component/component-instance-engine.d.ts.map +1 -0
  90. package/dist/lib/components/realtime/interactive-component/component-instance-engine.js +146 -0
  91. package/dist/lib/components/realtime/interactive-component/component-instance-engine.js.map +1 -0
  92. package/dist/lib/components/realtime/interactive-component/component-spec-content.d.ts +19 -0
  93. package/dist/lib/components/realtime/interactive-component/component-spec-content.d.ts.map +1 -0
  94. package/dist/lib/components/realtime/interactive-component/component-spec-content.js +39 -0
  95. package/dist/lib/components/realtime/interactive-component/component-spec-content.js.map +1 -0
  96. package/dist/lib/components/realtime/interactive-component/interactive-component-channel.d.ts +183 -0
  97. package/dist/lib/components/realtime/interactive-component/interactive-component-channel.d.ts.map +1 -0
  98. package/dist/lib/components/realtime/interactive-component/interactive-component-channel.js +761 -0
  99. package/dist/lib/components/realtime/interactive-component/interactive-component-channel.js.map +1 -0
  100. package/dist/lib/components/realtime/interactive-component/interactive-component-config.d.ts +25 -0
  101. package/dist/lib/components/realtime/interactive-component/interactive-component-config.d.ts.map +1 -0
  102. package/dist/lib/components/realtime/interactive-component/interactive-component-config.js +57 -0
  103. package/dist/lib/components/realtime/interactive-component/interactive-component-config.js.map +1 -0
  104. package/dist/lib/components/realtime/interactive-component/interactive-component-host.component.d.ts +40 -0
  105. package/dist/lib/components/realtime/interactive-component/interactive-component-host.component.d.ts.map +1 -0
  106. package/dist/lib/components/realtime/interactive-component/interactive-component-host.component.js +97 -0
  107. package/dist/lib/components/realtime/interactive-component/interactive-component-host.component.js.map +1 -0
  108. package/dist/lib/components/realtime/interactive-component/interactive-component-types.d.ts +144 -0
  109. package/dist/lib/components/realtime/interactive-component/interactive-component-types.d.ts.map +1 -0
  110. package/dist/lib/components/realtime/interactive-component/interactive-component-types.js +57 -0
  111. package/dist/lib/components/realtime/interactive-component/interactive-component-types.js.map +1 -0
  112. package/dist/lib/components/realtime/interactive-component/react-component-handle.d.ts +36 -0
  113. package/dist/lib/components/realtime/interactive-component/react-component-handle.d.ts.map +1 -0
  114. package/dist/lib/components/realtime/interactive-component/react-component-handle.js +55 -0
  115. package/dist/lib/components/realtime/interactive-component/react-component-handle.js.map +1 -0
  116. package/dist/lib/components/realtime/interactive-component/realtime-interactive-component-surface.component.d.ts +55 -0
  117. package/dist/lib/components/realtime/interactive-component/realtime-interactive-component-surface.component.d.ts.map +1 -0
  118. package/dist/lib/components/realtime/interactive-component/realtime-interactive-component-surface.component.js +210 -0
  119. package/dist/lib/components/realtime/interactive-component/realtime-interactive-component-surface.component.js.map +1 -0
  120. package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.d.ts +32 -0
  121. package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.d.ts.map +1 -0
  122. package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.js +90 -0
  123. package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.js.map +1 -0
  124. package/dist/lib/components/realtime/media/media-channel.d.ts +7 -0
  125. package/dist/lib/components/realtime/media/media-channel.d.ts.map +1 -1
  126. package/dist/lib/components/realtime/media/media-channel.js +28 -1
  127. package/dist/lib/components/realtime/media/media-channel.js.map +1 -1
  128. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts +8 -1
  129. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts.map +1 -1
  130. package/dist/lib/components/realtime/realtime-agent-banner.component.js +89 -71
  131. package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -1
  132. package/dist/lib/components/realtime/realtime-agent-orb.component.d.ts +21 -0
  133. package/dist/lib/components/realtime/realtime-agent-orb.component.d.ts.map +1 -0
  134. package/dist/lib/components/realtime/realtime-agent-orb.component.js +49 -0
  135. package/dist/lib/components/realtime/realtime-agent-orb.component.js.map +1 -0
  136. package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts +44 -11
  137. package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts.map +1 -1
  138. package/dist/lib/components/realtime/realtime-agent-picker.component.js +162 -50
  139. package/dist/lib/components/realtime/realtime-agent-picker.component.js.map +1 -1
  140. package/dist/lib/components/realtime/realtime-audio-visuals.d.ts +8 -2
  141. package/dist/lib/components/realtime/realtime-audio-visuals.d.ts.map +1 -1
  142. package/dist/lib/components/realtime/realtime-audio-visuals.js +14 -18
  143. package/dist/lib/components/realtime/realtime-audio-visuals.js.map +1 -1
  144. package/dist/lib/components/realtime/realtime-composer.component.d.ts +42 -2
  145. package/dist/lib/components/realtime/realtime-composer.component.d.ts.map +1 -1
  146. package/dist/lib/components/realtime/realtime-composer.component.js +137 -102
  147. package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -1
  148. package/dist/lib/components/realtime/realtime-perception-chip.component.d.ts +71 -0
  149. package/dist/lib/components/realtime/realtime-perception-chip.component.d.ts.map +1 -0
  150. package/dist/lib/components/realtime/realtime-perception-chip.component.js +221 -0
  151. package/dist/lib/components/realtime/realtime-perception-chip.component.js.map +1 -0
  152. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +264 -22
  153. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts.map +1 -1
  154. package/dist/lib/components/realtime/realtime-session-overlay.component.js +851 -135
  155. package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -1
  156. package/dist/lib/components/realtime/realtime-surface-placement-prefs.d.ts +14 -0
  157. package/dist/lib/components/realtime/realtime-surface-placement-prefs.d.ts.map +1 -0
  158. package/dist/lib/components/realtime/realtime-surface-placement-prefs.js +14 -0
  159. package/dist/lib/components/realtime/realtime-surface-placement-prefs.js.map +1 -0
  160. package/dist/lib/components/realtime/realtime-surface-stage.model.d.ts +74 -0
  161. package/dist/lib/components/realtime/realtime-surface-stage.model.d.ts.map +1 -0
  162. package/dist/lib/components/realtime/realtime-surface-stage.model.js +171 -0
  163. package/dist/lib/components/realtime/realtime-surface-stage.model.js.map +1 -0
  164. package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts +71 -13
  165. package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts.map +1 -1
  166. package/dist/lib/components/realtime/realtime-surface-tabs.component.js +232 -73
  167. package/dist/lib/components/realtime/realtime-surface-tabs.component.js.map +1 -1
  168. package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts +5 -0
  169. package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts.map +1 -1
  170. package/dist/lib/components/realtime/realtime-surface-tabs.model.js +8 -0
  171. package/dist/lib/components/realtime/realtime-surface-tabs.model.js.map +1 -1
  172. package/dist/lib/components/realtime/realtime-ui-config.d.ts +12 -2
  173. package/dist/lib/components/realtime/realtime-ui-config.d.ts.map +1 -1
  174. package/dist/lib/components/realtime/realtime-ui-config.js +5 -1
  175. package/dist/lib/components/realtime/realtime-ui-config.js.map +1 -1
  176. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts +10 -1
  177. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts.map +1 -1
  178. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js +42 -2
  179. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js.map +1 -1
  180. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.d.ts +20 -3
  181. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.d.ts.map +1 -1
  182. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.js +44 -10
  183. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.js.map +1 -1
  184. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts +28 -44
  185. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts.map +1 -1
  186. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js +76 -162
  187. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js.map +1 -1
  188. package/dist/lib/components/search/search-panel.component.d.ts +2 -0
  189. package/dist/lib/components/search/search-panel.component.d.ts.map +1 -1
  190. package/dist/lib/components/search/search-panel.component.js +25 -12
  191. package/dist/lib/components/search/search-panel.component.js.map +1 -1
  192. package/dist/lib/components/workspace/conversation-workspace.component.d.ts +22 -31
  193. package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
  194. package/dist/lib/components/workspace/conversation-workspace.component.js +50 -63
  195. package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
  196. package/dist/lib/conversations.module.d.ts +30 -29
  197. package/dist/lib/conversations.module.d.ts.map +1 -1
  198. package/dist/lib/conversations.module.js +27 -5
  199. package/dist/lib/conversations.module.js.map +1 -1
  200. package/dist/lib/events/chat-events.d.ts +25 -0
  201. package/dist/lib/events/chat-events.d.ts.map +1 -1
  202. package/dist/lib/events/chat-events.js +36 -0
  203. package/dist/lib/events/chat-events.js.map +1 -1
  204. package/dist/lib/models/agent-turn.model.d.ts +5 -0
  205. package/dist/lib/models/agent-turn.model.d.ts.map +1 -1
  206. package/dist/lib/models/agent-turn.model.js.map +1 -1
  207. package/dist/lib/services/agent-state.service.d.ts +34 -8
  208. package/dist/lib/services/agent-state.service.d.ts.map +1 -1
  209. package/dist/lib/services/agent-state.service.js +82 -29
  210. package/dist/lib/services/agent-state.service.js.map +1 -1
  211. package/dist/lib/services/artifact-state.service.d.ts +0 -9
  212. package/dist/lib/services/artifact-state.service.d.ts.map +1 -1
  213. package/dist/lib/services/artifact-state.service.js +1 -32
  214. package/dist/lib/services/artifact-state.service.js.map +1 -1
  215. package/dist/lib/services/browser-realtime-media-host.d.ts +12 -0
  216. package/dist/lib/services/browser-realtime-media-host.d.ts.map +1 -1
  217. package/dist/lib/services/browser-realtime-media-host.js +19 -0
  218. package/dist/lib/services/browser-realtime-media-host.js.map +1 -1
  219. package/dist/lib/services/browser-recording-unload-guard.d.ts +30 -0
  220. package/dist/lib/services/browser-recording-unload-guard.d.ts.map +1 -0
  221. package/dist/lib/services/browser-recording-unload-guard.js +43 -0
  222. package/dist/lib/services/browser-recording-unload-guard.js.map +1 -0
  223. package/dist/lib/services/conversation-agent.service.d.ts +35 -11
  224. package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
  225. package/dist/lib/services/conversation-agent.service.js +65 -20
  226. package/dist/lib/services/conversation-agent.service.js.map +1 -1
  227. package/dist/lib/services/conversation-detail-window.store.d.ts +22 -4
  228. package/dist/lib/services/conversation-detail-window.store.d.ts.map +1 -1
  229. package/dist/lib/services/conversation-detail-window.store.js +50 -9
  230. package/dist/lib/services/conversation-detail-window.store.js.map +1 -1
  231. package/dist/lib/services/conversation-naming.d.ts +72 -22
  232. package/dist/lib/services/conversation-naming.d.ts.map +1 -1
  233. package/dist/lib/services/conversation-naming.js +84 -10
  234. package/dist/lib/services/conversation-naming.js.map +1 -1
  235. package/dist/lib/services/data-cache.service.d.ts +13 -5
  236. package/dist/lib/services/data-cache.service.d.ts.map +1 -1
  237. package/dist/lib/services/data-cache.service.js +39 -19
  238. package/dist/lib/services/data-cache.service.js.map +1 -1
  239. package/dist/lib/services/export.service.d.ts +26 -9
  240. package/dist/lib/services/export.service.d.ts.map +1 -1
  241. package/dist/lib/services/export.service.js +61 -18
  242. package/dist/lib/services/export.service.js.map +1 -1
  243. package/dist/lib/services/realtime-audio-recorder.d.ts +33 -5
  244. package/dist/lib/services/realtime-audio-recorder.d.ts.map +1 -1
  245. package/dist/lib/services/realtime-audio-recorder.js +71 -11
  246. package/dist/lib/services/realtime-audio-recorder.js.map +1 -1
  247. package/dist/lib/services/realtime-pairing.d.ts +10 -5
  248. package/dist/lib/services/realtime-pairing.d.ts.map +1 -1
  249. package/dist/lib/services/realtime-pairing.js +15 -6
  250. package/dist/lib/services/realtime-pairing.js.map +1 -1
  251. package/dist/lib/services/realtime-session.service.d.ts +3 -2
  252. package/dist/lib/services/realtime-session.service.d.ts.map +1 -1
  253. package/dist/lib/services/realtime-session.service.js +7 -2
  254. package/dist/lib/services/realtime-session.service.js.map +1 -1
  255. package/dist/lib/services/search.service.d.ts +7 -2
  256. package/dist/lib/services/search.service.d.ts.map +1 -1
  257. package/dist/lib/services/search.service.js +13 -4
  258. package/dist/lib/services/search.service.js.map +1 -1
  259. package/dist/lib/util/frame-zone.d.ts +10 -0
  260. package/dist/lib/util/frame-zone.d.ts.map +1 -0
  261. package/dist/lib/util/frame-zone.js +10 -0
  262. package/dist/lib/util/frame-zone.js.map +1 -0
  263. package/dist/lib/utils/conversation-branching.d.ts +4 -0
  264. package/dist/lib/utils/conversation-branching.d.ts.map +1 -0
  265. package/dist/lib/utils/conversation-branching.js +5 -0
  266. package/dist/lib/utils/conversation-branching.js.map +1 -0
  267. package/dist/lib/utils/conversation-forks.d.ts +315 -0
  268. package/dist/lib/utils/conversation-forks.d.ts.map +1 -0
  269. package/dist/lib/utils/conversation-forks.js +456 -0
  270. package/dist/lib/utils/conversation-forks.js.map +1 -0
  271. package/dist/public-api.d.ts +23 -1
  272. package/dist/public-api.d.ts.map +1 -1
  273. package/dist/public-api.js +30 -1
  274. package/dist/public-api.js.map +1 -1
  275. package/package.json +37 -32
  276. package/dist/lib/components/thread/thread-panel.component.d.ts +0 -126
  277. package/dist/lib/components/thread/thread-panel.component.d.ts.map +0 -1
  278. package/dist/lib/components/thread/thread-panel.component.js +0 -440
  279. package/dist/lib/components/thread/thread-panel.component.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"realtime-composer.component.js","sourceRoot":"","sources":["../../../../src/lib/components/realtime/realtime-composer.component.ts","../../../../src/lib/components/realtime/realtime-composer.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, ElementRef, EventEmitter, HostListener, Input, Output, ViewChild, inject } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { RealtimeSessionService } from '../../services/realtime-session.service';\n\n/**\n * The call overlay's BOTTOM DOCK — the progressive-disclosure composer\n * (`plans/realtime/mockups/redesign-a-progressive.html`). One component, two shapes,\n * keyed off the overlay's disclosure {@link Level}:\n *\n * - **Levels 0–1 (phone-call strip)** — big round call controls, centered: Mute, the\n * Captions toggle (level 1+, arriving WITH the text it controls), the Details peek\n * (level 0 paths where the surface panel isn't earned yet — lets the user look at the\n * Activity/Whiteboard panels on demand), the Type control, and End call. There's no visible\n * composer yet — the Type control opens it, and so does simply starting to type (the overlay\n * captures the first printable keystroke and seeds it via {@link AppendAndFocus}).\n * - **Level 2+ (the dock)** — mute/captions shrink to compact minis and the in-call text\n * input docks beside them (one bottom bar, per Redesign A's fused composer+controls).\n * Submit calls {@link RealtimeSessionService.SendText}, which injects the text as a user\n * turn into the SAME live voice call.\n *\n * Mute talks to the session service directly (pure local toggle); captions / Details /\n * End are emitted up so the overlay shell owns that state and lifecycle.\n */\n@Component({\n standalone: true,\n selector: 'mj-realtime-composer',\n imports: [CommonModule, FormsModule],\n templateUrl: './realtime-composer.component.html',\n styleUrl: './realtime-composer.component.css'\n})\nexport class RealtimeComposerComponent {\n /**\n * Whether the typed-input dock is OPEN. A two-way door owned by the user: the strip's\n * Type control (or the T hotkey) opens it; the dock's hide control closes it — typing\n * never becomes permanent chrome. Default closed (voice-first), reset per session.\n */\n @Input() Open = false;\n\n /**\n * COMPACT (Calm Orb · overlay) presentation: collapse the phone-call strip to the\n * mockup's lean dock — **Mute + End + a \"•••\"** overflow button. The \"•••\" blooms a small\n * sheet hosting the secondary actions (Captions / Details / Type). The fused level-2 dock\n * (minis + text input) is unchanged. Fed from the overlay's resolved `Ui.compact`.\n * Default `false` (the full 5-button strip is unchanged).\n */\n @Input() Compact = false;\n\n /** Emitted when the user opens (Type control / typing) or closes (hide control) the dock. */\n @Output() OpenChanged = new EventEmitter<boolean>();\n\n /** Whether captions are currently shown (drives the captions control's active state). */\n @Input() CaptionsOn = true;\n\n /** Whether the Details peek control renders (true until the surface panel is earned). */\n @Input() ShowDetails = false;\n\n /** Whether the Details peek is currently open (active state on the control). */\n @Input() DetailsOn = false;\n\n /** Emitted when the user toggles captions; the overlay flips its caption state. */\n @Output() CaptionsToggled = new EventEmitter<boolean>();\n\n /** Emitted when the user toggles the Details peek (the on-demand surface panel). */\n @Output() DetailsToggled = new EventEmitter<void>();\n\n /** Emitted when the user ends the call from the strip's End control. */\n @Output() EndRequested = new EventEmitter<void>();\n\n /** Emitted with the new muted state whenever the user toggles the mic from the dock. */\n @Output() MuteChanged = new EventEmitter<boolean>();\n\n /** Current draft text in the dock's composer input. */\n public Draft = '';\n\n /**\n * The mic mute state. A two-way reflection: the overlay may push it down (e.g. its\n * `SetMuted()` / focus-pill toggle) so all mute affordances stay in sync, and this\n * component updates it locally + emits {@link MuteChanged} when its own button is used.\n */\n @Input() IsMuted = false;\n\n @ViewChild('dockInput') private dockInput?: ElementRef<HTMLInputElement | HTMLTextAreaElement>;\n\n private realtime = inject(RealtimeSessionService);\n\n /** True when there's non-whitespace text to send. */\n public get CanSend(): boolean {\n return this.Draft.trim().length > 0;\n }\n\n /** True while the big-controls phone-call strip renders (instead of the dock). */\n public get StripMode(): boolean {\n return !this.Open;\n }\n\n /**\n * Whether the compact \"•••\" overflow sheet (Captions / Details / Type) is open. Only used\n * in {@link Compact} strip mode; any outside click or action selection closes it.\n */\n public MoreOpen = false;\n\n /** Open/close the compact overflow sheet (stops propagation so the outside-click close skips it). */\n public ToggleMore(event: MouseEvent): void {\n event.stopPropagation();\n this.MoreOpen = !this.MoreOpen;\n }\n\n /** Any outside click closes the compact overflow sheet. */\n @HostListener('document:click')\n public OnDocumentClick(): void {\n if (this.MoreOpen) {\n this.MoreOpen = false;\n }\n }\n\n /** Toggle the local microphone mute and surface the new state to the overlay. */\n public ToggleMute(): void {\n this.IsMuted = this.realtime.ToggleMute();\n this.MuteChanged.emit(this.IsMuted);\n }\n\n /** Toggle captions visibility and notify the overlay. */\n public ToggleCaptions(): void {\n this.CaptionsOn = !this.CaptionsOn;\n this.CaptionsToggled.emit(this.CaptionsOn);\n }\n\n /** Focuses the dock's text input (the overlay's Type control lands here). */\n public FocusInput(): void {\n this.dockInput?.nativeElement.focus();\n }\n\n /**\n * TYPE-TO-COMPOSE: the overlay captured a printable keystroke while nothing was focused, so seed\n * the draft with that character, focus the input, and put the caret at the end — the user just\n * keeps typing and their first key isn't lost. Appends (rather than replaces) so a leftover draft\n * is preserved. The native value is synced inline so the caret math is correct before Angular's\n * next change-detection pass reconciles ngModel.\n *\n * @param text the character(s) to seed (typically the single key that opened the composer).\n */\n public AppendAndFocus(text: string): void {\n this.Draft = (this.Draft ?? '') + text;\n const el = this.dockInput?.nativeElement;\n if (el) {\n el.value = this.Draft;\n el.focus();\n el.setSelectionRange(this.Draft.length, this.Draft.length);\n this.AutoResize();\n }\n }\n\n /** Auto-resizes the textarea up to 140px height as text grows or contracts. */\n public AutoResize(): void {\n const el = this.dockInput?.nativeElement;\n if (el && el instanceof HTMLTextAreaElement) {\n el.style.height = 'auto';\n const newHeight = Math.max(24, Math.min(el.scrollHeight, 140));\n el.style.height = `${newHeight}px`;\n }\n }\n\n /** Send the typed text into the live session, then clear the input. */\n public Send(): void {\n if (!this.CanSend) {\n return;\n }\n this.realtime.SendText(this.Draft);\n this.Draft = '';\n const el = this.dockInput?.nativeElement;\n if (el && el instanceof HTMLTextAreaElement) {\n el.style.height = 'auto';\n }\n }\n\n /** Enter sends (Shift+Enter inserts a newline in textarea). */\n public OnKeydown(event: KeyboardEvent): void {\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n this.Send();\n }\n }\n}\n","@if (StripMode && Compact) {\n <!-- COMPACT (Calm Orb · overlay): the lean dock — Mute + End + a first-class Captions toggle\n (kept out of the \"•••\" so text stays ONE TAP in the overlay, where the banner no longer\n carries a duplicate CC) + a \"•••\" that blooms a small sheet with the remaining secondary\n actions (Details / Type). Round controls, red End — matches the mockup. -->\n <div class=\"dock-lean\" role=\"group\" aria-label=\"Call controls\">\n <div class=\"lean-more\" [class.lean-more--open]=\"MoreOpen\">\n <div class=\"lean-sheet\" (click)=\"$event.stopPropagation()\" role=\"menu\" aria-label=\"More call controls\">\n @if (ShowDetails) {\n <button type=\"button\" class=\"lean-sheet__btn\" [class.lean-sheet__btn--on]=\"DetailsOn\"\n (click)=\"DetailsToggled.emit(); MoreOpen = false\"\n [title]=\"DetailsOn ? 'Hide the session panels' : 'Peek at the session panels'\"\n [attr.aria-pressed]=\"DetailsOn\">\n <i class=\"fa-solid fa-table-columns\" aria-hidden=\"true\"></i>\n <small>Details</small>\n </button>\n }\n <button type=\"button\" class=\"lean-sheet__btn\"\n (click)=\"OpenChanged.emit(true); MoreOpen = false\"\n title=\"Type into the live session\" aria-label=\"Open the typed-input composer\">\n <i class=\"fa-regular fa-keyboard\" aria-hidden=\"true\"></i>\n <small>Type</small>\n </button>\n </div>\n <button type=\"button\" class=\"lean-ctrl lean-ctrl--more\" [class.lean-ctrl--on]=\"MoreOpen\"\n (click)=\"ToggleMore($event)\"\n title=\"More controls\" aria-label=\"More call controls\"\n [attr.aria-expanded]=\"MoreOpen\">\n <i class=\"fa-solid fa-ellipsis\" aria-hidden=\"true\"></i>\n </button>\n </div>\n\n <!-- Captions: first-class in the lean dock (the overlay's only text toggle now). -->\n <button type=\"button\" class=\"lean-ctrl lean-ctrl--more\" [class.lean-ctrl--on]=\"CaptionsOn\"\n (click)=\"ToggleCaptions()\"\n [title]=\"CaptionsOn ? 'Voice-first — back to the orb' : 'Show the conversation as text'\"\n [attr.aria-pressed]=\"CaptionsOn\">\n <i class=\"fa-solid fa-closed-captioning\" aria-hidden=\"true\"></i>\n </button>\n\n <button type=\"button\" class=\"lean-ctrl lean-ctrl--lg\" [class.lean-ctrl--muted]=\"IsMuted\"\n (click)=\"ToggleMute()\"\n [title]=\"IsMuted ? 'Unmute microphone' : 'Mute microphone'\"\n [attr.aria-pressed]=\"IsMuted\">\n <i class=\"fa-solid\" [ngClass]=\"IsMuted ? 'fa-microphone-slash' : 'fa-microphone'\" aria-hidden=\"true\"></i>\n </button>\n\n <button type=\"button\" class=\"lean-ctrl lean-ctrl--lg lean-ctrl--end\" (click)=\"EndRequested.emit()\"\n title=\"End call\" aria-label=\"End call\">\n <i class=\"fa-solid fa-phone-slash\" aria-hidden=\"true\"></i>\n </button>\n </div>\n} @else if (StripMode) {\n <!-- Levels 0–1: phone-call strip — big round controls, nothing to configure.\n Captions arrives at level 1 WITH the text it controls; Details peeks at the\n surface panels on demand; End stays the deliberate rightmost action. -->\n <div class=\"strip\" role=\"group\" aria-label=\"Call controls\">\n <div class=\"ctrl-group\">\n <button type=\"button\" class=\"ctrl\" [class.ctrl--muted]=\"IsMuted\"\n (click)=\"ToggleMute()\"\n [title]=\"IsMuted ? 'Unmute microphone' : 'Mute microphone'\"\n [attr.aria-pressed]=\"IsMuted\">\n <i class=\"fa-solid\" [ngClass]=\"IsMuted ? 'fa-microphone-slash' : 'fa-microphone'\" aria-hidden=\"true\"></i>\n </button>\n <span class=\"ctrl-label\">{{ IsMuted ? 'Unmute' : 'Mute' }}</span>\n </div>\n\n <div class=\"ctrl-group\">\n <button type=\"button\" class=\"ctrl\" [class.ctrl--on]=\"CaptionsOn\"\n (click)=\"ToggleCaptions()\"\n [title]=\"CaptionsOn ? 'Voice-first — back to the orb' : 'Show the conversation as text'\"\n [attr.aria-pressed]=\"CaptionsOn\">\n <i class=\"fa-solid fa-closed-captioning\" aria-hidden=\"true\"></i>\n </button>\n <span class=\"ctrl-label\">Captions</span>\n </div>\n\n @if (ShowDetails) {\n <div class=\"ctrl-group\">\n <button type=\"button\" class=\"ctrl\" [class.ctrl--on]=\"DetailsOn\"\n (click)=\"DetailsToggled.emit()\"\n [title]=\"DetailsOn ? 'Hide the session panels' : 'Peek at the session panels'\"\n [attr.aria-pressed]=\"DetailsOn\">\n <i class=\"fa-solid fa-table-columns\" aria-hidden=\"true\"></i>\n </button>\n <span class=\"ctrl-label\">Details</span>\n </div>\n }\n\n <div class=\"ctrl-group\">\n <button type=\"button\" class=\"ctrl\" (click)=\"OpenChanged.emit(true)\"\n title=\"Type into the live session\" aria-label=\"Open the typed-input composer\">\n <i class=\"fa-regular fa-keyboard\" aria-hidden=\"true\"></i>\n </button>\n <span class=\"ctrl-label\">Type</span>\n </div>\n\n <div class=\"ctrl-group\">\n <button type=\"button\" class=\"ctrl ctrl--end\" (click)=\"EndRequested.emit()\"\n title=\"End call\" aria-label=\"End call\">\n <i class=\"fa-solid fa-phone-slash\" aria-hidden=\"true\"></i>\n </button>\n <span class=\"ctrl-label ctrl-label--end\">End call</span>\n </div>\n </div>\n} @else {\n <!-- Level 2+: the fused dock — compact minis + the in-call composer in ONE bottom bar. -->\n <div class=\"dock\">\n <div class=\"dock__minis\">\n <button type=\"button\" class=\"mini\" [class.mini--muted]=\"IsMuted\"\n (click)=\"ToggleMute()\"\n [title]=\"IsMuted ? 'Unmute microphone' : 'Mute microphone'\"\n [attr.aria-pressed]=\"IsMuted\">\n <i class=\"fa-solid\" [ngClass]=\"IsMuted ? 'fa-microphone-slash' : 'fa-microphone'\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" class=\"mini\" [class.mini--on]=\"CaptionsOn\"\n (click)=\"ToggleCaptions()\"\n [title]=\"CaptionsOn ? 'Voice-first — back to the orb' : 'Show the conversation as text'\"\n [attr.aria-pressed]=\"CaptionsOn\">\n <i class=\"fa-solid fa-closed-captioning\" aria-hidden=\"true\"></i>\n </button>\n @if (ShowDetails) {\n <button type=\"button\" class=\"mini\" [class.mini--on]=\"DetailsOn\"\n (click)=\"DetailsToggled.emit()\"\n [title]=\"DetailsOn ? 'Hide the session panels' : 'Show the session panels'\"\n [attr.aria-pressed]=\"DetailsOn\">\n <i class=\"fa-solid fa-table-columns\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n <div class=\"dock__box\">\n <textarea\n #dockInput\n class=\"dock__input\"\n rows=\"1\"\n placeholder=\"Type into the live session — joins this same voice call…\"\n [(ngModel)]=\"Draft\"\n (keydown)=\"OnKeydown($event)\"\n (input)=\"AutoResize()\"\n aria-label=\"Type a message into the live voice session\"></textarea>\n <span class=\"dock__hint\" aria-hidden=\"true\">↵ send</span>\n <button\n class=\"dock__send\"\n type=\"button\"\n [disabled]=\"!CanSend\"\n (click)=\"Send()\"\n title=\"Send into live session\"\n aria-label=\"Send\">\n <i class=\"fa-solid fa-paper-plane\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <button type=\"button\" class=\"mini dock__hide\" (click)=\"OpenChanged.emit(false)\"\n title=\"Hide typing — back to the voice controls\"\n aria-label=\"Close the typed-input composer\">\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" class=\"mini mini--end\" (click)=\"EndRequested.emit()\"\n title=\"End call\" aria-label=\"End call\">\n <i class=\"fa-solid fa-phone-slash\" aria-hidden=\"true\"></i>\n </button>\n </div>\n}\n"]}
1
+ {"version":3,"file":"realtime-composer.component.js","sourceRoot":"","sources":["../../../../src/lib/components/realtime/realtime-composer.component.ts","../../../../src/lib/components/realtime/realtime-composer.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, ElementRef, EventEmitter, HostListener, Input, Output, ViewChild, inject } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { MJButtonDirective } from '@memberjunction/ng-ui-components';\nimport { MediaControlsComponent, type MediaSharePanel, type MediaShareRequest } from '@memberjunction/ng-realtime-media';\nimport type { MediaDevice, MediaDeviceSelection } from '@memberjunction/ai-realtime-client/media';\nimport { RealtimeSessionService } from '../../services/realtime-session.service';\n\n/**\n * The call overlay's BOTTOM DOCK — the progressive-disclosure composer\n * (`plans/realtime/mockups/redesign-a-progressive.html`). One component, two shapes,\n * keyed off the overlay's disclosure {@link Level}:\n *\n * - **Levels 0–1 (phone-call strip)** — big round call controls, centered: Mute, the\n * Captions toggle (level 1+, arriving WITH the text it controls), the Details peek\n * (level 0 paths where the surface panel isn't earned yet — lets the user look at the\n * Activity/Whiteboard panels on demand), the Type control, and End call. There's no visible\n * composer yet — the Type control opens it, and so does simply starting to type (the overlay\n * captures the first printable keystroke and seeds it via {@link AppendAndFocus}).\n * - **Level 2+ (the dock)** — mute/captions shrink to small circles and the in-call text\n * input docks beside them (one bottom bar, per Redesign A's fused composer+controls).\n * Submit calls {@link RealtimeSessionService.SendText}, which injects the text as a user\n * turn into the SAME live voice call.\n *\n * The controls are the design system's: the microphone, the camera and Share are `mj-media-controls` (the call controls\n * the LiveKit room uses too) and every other control an `mjButton` circle, sized per shape (52, 44 or 32 px). The camera\n * and Share show only when the overlay says the call offers them; the camera is optional here, so it is neutral while off.\n * In the strip and the lean dock the microphone carries the device chevron, whose menu picks the microphone and, while the\n * camera is open, the camera ({@link Devices}); the fused dock, short of room, leaves it out, as it does the Share arrow.\n *\n * Mute talks to the session service directly (pure local toggle); captions / Details /\n * End are emitted up so the overlay shell owns that state and lifecycle.\n */\n@Component({\n standalone: true,\n selector: 'mj-realtime-composer',\n imports: [CommonModule, FormsModule, MJButtonDirective, MediaControlsComponent],\n templateUrl: './realtime-composer.component.html',\n styleUrl: './realtime-composer.component.css'\n})\nexport class RealtimeComposerComponent {\n /**\n * Whether the typed-input dock is OPEN. A two-way door owned by the user: the strip's\n * Type control (or the T hotkey) opens it; the dock's hide control closes it — typing\n * never becomes permanent chrome. Default closed (voice-first), reset per session.\n */\n @Input() Open = false;\n\n /**\n * COMPACT (Calm Orb · overlay) presentation: collapse the phone-call strip to the\n * mockup's lean dock — **Mute + End + a \"•••\"** overflow button. The \"•••\" blooms a small\n * sheet hosting the secondary actions (Captions / Details / Type). The fused level-2 dock\n * (minis + text input) is unchanged. Fed from the overlay's resolved `Ui.compact`.\n * Default `false` (the full 5-button strip is unchanged).\n */\n @Input() Compact = false;\n\n /** Emitted when the user opens (Type control / typing) or closes (hide control) the dock. */\n @Output() OpenChanged = new EventEmitter<boolean>();\n\n /** Whether captions are currently shown (drives the captions control's active state). */\n @Input() CaptionsOn = true;\n\n /** Whether the Details peek control renders (true until the surface panel is earned). */\n @Input() ShowDetails = false;\n\n /** Whether the Details peek is currently open (active state on the control). */\n @Input() DetailsOn = false;\n\n /** Emitted when the user toggles captions; the overlay flips its caption state. */\n @Output() CaptionsToggled = new EventEmitter<boolean>();\n\n /** Emitted when the user toggles the Details peek (the on-demand surface panel). */\n @Output() DetailsToggled = new EventEmitter<void>();\n\n /** Emitted when the user ends the call from the strip's End control. */\n @Output() EndRequested = new EventEmitter<void>();\n\n /** Emitted with the new muted state whenever the user toggles the mic from the dock. */\n @Output() MuteChanged = new EventEmitter<boolean>();\n\n /** Current draft text in the dock's composer input. */\n public Draft = '';\n\n /** Show the camera button: the call offers the camera (the runtime's `CaptureOffers$`). */\n @Input() ShowCamera = false;\n\n /** Show the Share button: the call offers a screen share. */\n @Input() ShowShare = false;\n\n /** Whether the camera is on (or starting). */\n @Input() CameraOn = false;\n\n /** Whether the user is sharing (or choosing what to share). */\n @Input() Sharing = false;\n\n /**\n * The panels of the page the Share menu offers under \"This panel\" (the overlay's on-screen panels). The typed-input\n * dock, whose Share button has no menu, leaves them out.\n */\n @Input() SharePanels: readonly MediaSharePanel[] = [];\n\n /**\n * The microphones and cameras the device menu offers: the call's microphones, and its cameras while the camera is\n * open. With none there is no device chevron. The typed-input dock leaves the chevron out.\n */\n @Input() Devices: readonly MediaDevice[] = [];\n\n /** The microphone the device menu shows as picked. */\n @Input() SelectedMicrophoneID: string | null = null;\n\n /** The camera the device menu shows as picked. */\n @Input() SelectedCameraID: string | null = null;\n\n /** The user asked to turn the camera on (`true`) or off (`false`). The overlay starts or stops it. */\n @Output() CameraToggled = new EventEmitter<boolean>();\n\n /** The user asked to share a screen, window or tab, or one of {@link SharePanels}. */\n @Output() ShareRequested = new EventEmitter<MediaShareRequest>();\n\n /** The user asked to stop sharing. */\n @Output() StopShareRequested = new EventEmitter<void>();\n\n /** The user picked a microphone or a camera in the device menu. The overlay switches to it. */\n @Output() DeviceSelected = new EventEmitter<MediaDeviceSelection>();\n\n /**\n * The mic mute state. A two-way reflection: the overlay may push it down (e.g. its\n * `SetMuted()` / focus-pill toggle) so all mute affordances stay in sync, and this\n * component updates it locally + emits {@link MuteChanged} when its own button is used.\n */\n @Input() IsMuted = false;\n\n @ViewChild('dockInput') private dockInput?: ElementRef<HTMLInputElement | HTMLTextAreaElement>;\n\n private realtime = inject(RealtimeSessionService);\n\n /** The captions control's tooltip: what a click does. */\n public get CaptionsTitle(): string {\n return this.CaptionsOn ? 'Voice-first — back to the orb' : 'Show the conversation as text';\n }\n\n /** True when there's non-whitespace text to send. */\n public get CanSend(): boolean {\n return this.Draft.trim().length > 0;\n }\n\n /** True while the big-controls phone-call strip renders (instead of the dock). */\n public get StripMode(): boolean {\n return !this.Open;\n }\n\n /**\n * Whether the compact \"•••\" overflow sheet (Captions / Details / Type) is open. Only used\n * in {@link Compact} strip mode; any outside click or action selection closes it.\n */\n public MoreOpen = false;\n\n /** Open/close the compact overflow sheet (stops propagation so the outside-click close skips it). */\n public ToggleMore(event: MouseEvent): void {\n event.stopPropagation();\n this.MoreOpen = !this.MoreOpen;\n }\n\n /** Any outside click closes the compact overflow sheet. */\n @HostListener('document:click')\n public OnDocumentClick(): void {\n if (this.MoreOpen) {\n this.MoreOpen = false;\n }\n }\n\n /** Toggle the local microphone mute and surface the new state to the overlay. */\n public ToggleMute(): void {\n this.IsMuted = this.realtime.ToggleMute();\n this.MuteChanged.emit(this.IsMuted);\n }\n\n /** Toggle captions visibility and notify the overlay. */\n public ToggleCaptions(): void {\n this.CaptionsOn = !this.CaptionsOn;\n this.CaptionsToggled.emit(this.CaptionsOn);\n }\n\n /** Focuses the dock's text input (the overlay's Type control lands here). */\n public FocusInput(): void {\n this.dockInput?.nativeElement.focus();\n }\n\n /**\n * TYPE-TO-COMPOSE: the overlay captured a printable keystroke while nothing was focused, so seed\n * the draft with that character, focus the input, and put the caret at the end — the user just\n * keeps typing and their first key isn't lost. Appends (rather than replaces) so a leftover draft\n * is preserved. The native value is synced inline so the caret math is correct before Angular's\n * next change-detection pass reconciles ngModel.\n *\n * @param text the character(s) to seed (typically the single key that opened the composer).\n */\n public AppendAndFocus(text: string): void {\n this.Draft = (this.Draft ?? '') + text;\n const el = this.dockInput?.nativeElement;\n if (el) {\n el.value = this.Draft;\n el.focus();\n el.setSelectionRange(this.Draft.length, this.Draft.length);\n this.AutoResize();\n }\n }\n\n /** Auto-resizes the textarea up to 140px height as text grows or contracts. */\n public AutoResize(): void {\n const el = this.dockInput?.nativeElement;\n if (el && el instanceof HTMLTextAreaElement) {\n el.style.height = 'auto';\n const newHeight = Math.max(24, Math.min(el.scrollHeight, 140));\n el.style.height = `${newHeight}px`;\n }\n }\n\n /** Send the typed text into the live session, then clear the input. */\n public Send(): void {\n if (!this.CanSend) {\n return;\n }\n this.realtime.SendText(this.Draft);\n this.Draft = '';\n const el = this.dockInput?.nativeElement;\n if (el && el instanceof HTMLTextAreaElement) {\n el.style.height = 'auto';\n }\n }\n\n /** Enter sends (Shift+Enter inserts a newline in textarea). */\n public OnKeydown(event: KeyboardEvent): void {\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n this.Send();\n }\n }\n}\n","@if (StripMode && Compact) {\n <!-- COMPACT (Calm Orb · overlay): the lean dock — a \"•••\" that blooms a small sheet with the secondary actions\n (Details / Type), a first-class Captions toggle (text stays ONE TAP in the overlay), the call's media controls\n (the microphone with its device chevron, and the camera and Share when offered) and a red End. Circles from the\n design system. -->\n <div class=\"dock-lean\" role=\"group\" aria-label=\"Call controls\">\n <div class=\"lean-more\" [class.lean-more--open]=\"MoreOpen\">\n <div class=\"lean-sheet\" (click)=\"$event.stopPropagation()\" role=\"menu\" aria-label=\"More call controls\">\n @if (ShowDetails) {\n <button type=\"button\" class=\"lean-sheet__btn\" [class.lean-sheet__btn--on]=\"DetailsOn\"\n (click)=\"DetailsToggled.emit(); MoreOpen = false\"\n [title]=\"DetailsOn ? 'Hide the session panels' : 'Peek at the session panels'\"\n [attr.aria-pressed]=\"DetailsOn\">\n <i class=\"fa-solid fa-table-columns\" aria-hidden=\"true\"></i>\n <small>Details</small>\n </button>\n }\n <button type=\"button\" class=\"lean-sheet__btn\"\n (click)=\"OpenChanged.emit(true); MoreOpen = false\"\n title=\"Type into the live session\" aria-label=\"Open the typed-input composer\">\n <i class=\"fa-regular fa-keyboard\" aria-hidden=\"true\"></i>\n <small>Type</small>\n </button>\n </div>\n <button type=\"button\" mjButton Shape=\"circle\" [Variant]=\"MoreOpen ? 'primary' : 'secondary'\"\n AriaLabel=\"More call controls\" title=\"More controls\"\n [attr.aria-expanded]=\"MoreOpen\"\n (click)=\"ToggleMore($event)\">\n <i class=\"fa-solid fa-ellipsis\" aria-hidden=\"true\"></i>\n </button>\n </div>\n\n <!-- Captions: first-class in the lean dock (the overlay's only text toggle now). -->\n <button type=\"button\" mjButton Shape=\"circle\" [Toggleable]=\"true\" [Selected]=\"CaptionsOn\"\n AriaLabel=\"Captions\" [title]=\"CaptionsTitle\"\n (click)=\"ToggleCaptions()\">\n <i class=\"fa-solid fa-closed-captioning\" aria-hidden=\"true\"></i>\n </button>\n\n <mj-media-controls class=\"lean__media\"\n Size=\"lg\"\n [MicrophoneOn]=\"!IsMuted\"\n [ShowCamera]=\"ShowCamera\"\n [ShowShare]=\"ShowShare\"\n [CameraOn]=\"CameraOn\"\n [Sharing]=\"Sharing\"\n [SharePanels]=\"SharePanels\"\n [CameraOptional]=\"true\"\n [ShowDeviceMenu]=\"true\"\n [Devices]=\"Devices\"\n [SelectedMicrophoneID]=\"SelectedMicrophoneID\"\n [SelectedCameraID]=\"SelectedCameraID\"\n (MicrophoneToggled)=\"ToggleMute()\"\n (CameraToggled)=\"CameraToggled.emit($event)\"\n (ShareRequested)=\"ShareRequested.emit($event)\"\n (StopShareRequested)=\"StopShareRequested.emit()\"\n (DeviceSelected)=\"DeviceSelected.emit($event)\"></mj-media-controls>\n\n <button type=\"button\" mjButton Shape=\"circle\" Size=\"lg\" Variant=\"danger\"\n AriaLabel=\"End call\" title=\"End call\" (click)=\"EndRequested.emit()\">\n <i class=\"fa-solid fa-phone-slash\" aria-hidden=\"true\"></i>\n </button>\n </div>\n} @else if (StripMode) {\n <!-- Levels 0–1: phone-call strip — big labelled circles: the call's media controls (the microphone with its device\n chevron, and the camera and Share when the call offers them), Captions (level 1+, arriving WITH the text it\n controls), the Details peek at the surface panels, Type, and End call, the deliberate rightmost action. -->\n <div class=\"strip\" role=\"group\" aria-label=\"Call controls\">\n <mj-media-controls class=\"strip__media\"\n Size=\"lg\"\n [ShowLabels]=\"true\"\n [MicrophoneOn]=\"!IsMuted\"\n [ShowCamera]=\"ShowCamera\"\n [ShowShare]=\"ShowShare\"\n [CameraOn]=\"CameraOn\"\n [Sharing]=\"Sharing\"\n [SharePanels]=\"SharePanels\"\n [CameraOptional]=\"true\"\n [ShowDeviceMenu]=\"true\"\n [Devices]=\"Devices\"\n [SelectedMicrophoneID]=\"SelectedMicrophoneID\"\n [SelectedCameraID]=\"SelectedCameraID\"\n (MicrophoneToggled)=\"ToggleMute()\"\n (CameraToggled)=\"CameraToggled.emit($event)\"\n (ShareRequested)=\"ShareRequested.emit($event)\"\n (StopShareRequested)=\"StopShareRequested.emit()\"\n (DeviceSelected)=\"DeviceSelected.emit($event)\"></mj-media-controls>\n\n <div class=\"ctrl-group\">\n <button type=\"button\" mjButton Shape=\"circle\" Size=\"lg\" [Toggleable]=\"true\" [Selected]=\"CaptionsOn\"\n AriaLabel=\"Captions\" [title]=\"CaptionsTitle\"\n (click)=\"ToggleCaptions()\">\n <i class=\"fa-solid fa-closed-captioning\" aria-hidden=\"true\"></i>\n </button>\n <span class=\"ctrl-label\" aria-hidden=\"true\">Captions</span>\n </div>\n\n @if (ShowDetails) {\n <div class=\"ctrl-group\">\n <button type=\"button\" mjButton Shape=\"circle\" Size=\"lg\" [Toggleable]=\"true\" [Selected]=\"DetailsOn\"\n AriaLabel=\"Details\" [title]=\"DetailsOn ? 'Hide the session panels' : 'Peek at the session panels'\"\n (click)=\"DetailsToggled.emit()\">\n <i class=\"fa-solid fa-table-columns\" aria-hidden=\"true\"></i>\n </button>\n <span class=\"ctrl-label\" aria-hidden=\"true\">Details</span>\n </div>\n }\n\n <div class=\"ctrl-group\">\n <button type=\"button\" mjButton Shape=\"circle\" Size=\"lg\"\n AriaLabel=\"Open the typed-input composer\" title=\"Type into the live session\"\n (click)=\"OpenChanged.emit(true)\">\n <i class=\"fa-regular fa-keyboard\" aria-hidden=\"true\"></i>\n </button>\n <span class=\"ctrl-label\" aria-hidden=\"true\">Type</span>\n </div>\n\n <div class=\"ctrl-group\">\n <button type=\"button\" mjButton Shape=\"circle\" Size=\"lg\" Variant=\"danger\"\n AriaLabel=\"End call\" title=\"End call\" (click)=\"EndRequested.emit()\">\n <i class=\"fa-solid fa-phone-slash\" aria-hidden=\"true\"></i>\n </button>\n <span class=\"ctrl-label ctrl-label--end\" aria-hidden=\"true\">End call</span>\n </div>\n </div>\n} @else {\n <!-- Level 2+: the fused dock — small circles and the in-call composer in ONE bottom bar. -->\n <div class=\"dock\">\n <div class=\"dock__minis\">\n <!-- No Share arrow and no device chevron in the dock, which is short of room: the browser's picker still offers\n every kind of surface, and Hide brings back the strip, which has the device menu. -->\n <mj-media-controls Size=\"sm\"\n [MicrophoneOn]=\"!IsMuted\"\n [ShowCamera]=\"ShowCamera\"\n [ShowShare]=\"ShowShare\"\n [ShowShareMenu]=\"false\"\n [CameraOn]=\"CameraOn\"\n [Sharing]=\"Sharing\"\n [CameraOptional]=\"true\"\n (MicrophoneToggled)=\"ToggleMute()\"\n (CameraToggled)=\"CameraToggled.emit($event)\"\n (ShareRequested)=\"ShareRequested.emit($event)\"\n (StopShareRequested)=\"StopShareRequested.emit()\"></mj-media-controls>\n <button type=\"button\" mjButton Shape=\"circle\" Size=\"sm\" [Toggleable]=\"true\" [Selected]=\"CaptionsOn\"\n AriaLabel=\"Captions\" [title]=\"CaptionsTitle\"\n (click)=\"ToggleCaptions()\">\n <i class=\"fa-solid fa-closed-captioning\" aria-hidden=\"true\"></i>\n </button>\n @if (ShowDetails) {\n <button type=\"button\" mjButton Shape=\"circle\" Size=\"sm\" [Toggleable]=\"true\" [Selected]=\"DetailsOn\"\n AriaLabel=\"Details\" [title]=\"DetailsOn ? 'Hide the session panels' : 'Show the session panels'\"\n (click)=\"DetailsToggled.emit()\">\n <i class=\"fa-solid fa-table-columns\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n <div class=\"dock__box\">\n <textarea\n #dockInput\n class=\"dock__input\"\n rows=\"1\"\n placeholder=\"Type into the live session — joins this same voice call…\"\n [(ngModel)]=\"Draft\"\n (keydown)=\"OnKeydown($event)\"\n (input)=\"AutoResize()\"\n aria-label=\"Type a message into the live voice session\"></textarea>\n <span class=\"dock__hint\" aria-hidden=\"true\">↵ send</span>\n <button\n class=\"dock__send\"\n type=\"button\"\n [disabled]=\"!CanSend\"\n (click)=\"Send()\"\n title=\"Send into live session\"\n aria-label=\"Send\">\n <i class=\"fa-solid fa-paper-plane\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <button type=\"button\" mjButton Shape=\"circle\" Size=\"sm\" class=\"dock__hide\"\n AriaLabel=\"Close the typed-input composer\" title=\"Hide typing — back to the voice controls\"\n (click)=\"OpenChanged.emit(false)\">\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n <button type=\"button\" mjButton Shape=\"circle\" Size=\"sm\" Variant=\"danger\"\n AriaLabel=\"End call\" title=\"End call\" (click)=\"EndRequested.emit()\">\n <i class=\"fa-solid fa-phone-slash\" aria-hidden=\"true\"></i>\n </button>\n </div>\n}\n"]}
@@ -0,0 +1,71 @@
1
+ import { EventEmitter } from '@angular/core';
2
+ import type { VideoSourceState } from '@memberjunction/ai-realtime-client';
3
+ import * as i0 from "@angular/core";
4
+ /** Raised when the user switches one of the agent's video sources on or off. */
5
+ export interface RealtimePerceptionToggle {
6
+ /** The source's id (from the arbiter). */
7
+ SourceID: string;
8
+ /** Whether the agent may see it from now on. */
9
+ Enabled: boolean;
10
+ }
11
+ /**
12
+ * The "agent can see" chip: a persistent, honest indicator in the realtime overlay of what the agent is
13
+ * looking at, with a switch per source to stop it.
14
+ *
15
+ * Shown whenever the session has a video source (a whiteboard, a remote browser, a shared screen), so a
16
+ * person is never unsure whether the agent can see their screen. The trigger summarizes ("Agent can see:
17
+ * Whiteboard"); opening it lists each source with a switch. Turning a source off removes it from what the
18
+ * agent receives and tells the agent (the runtime owns both, and remembers the choice per channel).
19
+ *
20
+ * The agent may see fewer sources than are on (Gemini sees one). Then the trigger names the one it sees ("Agent
21
+ * sees: Camera"), and the panel lets the user pick another ({@link SourcePicked}) and, once they have, let the
22
+ * call choose again.
23
+ *
24
+ * Purely presentational: it renders the sources it is given and raises {@link SourceToggled}; it never
25
+ * touches the session. Every control has an accessible name; the open panel closes on Escape.
26
+ *
27
+ * @example
28
+ * ```html
29
+ * <mj-realtime-perception-chip [Sources]="VideoSources" (SourceToggled)="OnToggle($event)">
30
+ * </mj-realtime-perception-chip>
31
+ * ```
32
+ */
33
+ export declare class RealtimePerceptionChipComponent {
34
+ /** The video sources the agent can or could see. The chip is hidden while this is empty. */
35
+ Sources: readonly VideoSourceState[];
36
+ /** Raised when the user switches a source on or off. */
37
+ SourceToggled: EventEmitter<RealtimePerceptionToggle>;
38
+ /** Raised when the user picks the source the agent sees (its id), or lets the call choose again (`null`). */
39
+ SourcePicked: EventEmitter<string | null>;
40
+ /** Whether the per-source panel is open. */
41
+ Expanded: boolean;
42
+ /** The sources the agent may currently see (switched on). */
43
+ get EnabledSources(): readonly VideoSourceState[];
44
+ /** The one-line summary on the trigger: with more sources on than the agent sees, the ones it sees. */
45
+ get Summary(): string;
46
+ /** Whether the user may pick a source: some source that is on is not one the agent sees. */
47
+ get CanPick(): boolean;
48
+ /** Whether the user has picked the source the agent sees, so the call can be let choose again. */
49
+ get HasPick(): boolean;
50
+ /** The trigger's accessible name: the summary plus what activating it does. */
51
+ get TriggerLabel(): string;
52
+ /** Opens or closes the panel. */
53
+ TogglePanel(): void;
54
+ /** Closes the panel on Escape, wherever focus is inside the chip. */
55
+ OnEscape(): void;
56
+ /** A switch changed: raise the event for the host to apply. */
57
+ OnSwitch(source: VideoSourceState, enabled: boolean): void;
58
+ /** The user picks the source the agent sees, or lets the call choose again (`null`). */
59
+ OnPick(source: VideoSourceState | null): void;
60
+ /** The row's status text: whether the agent is looking at it right now, and whether by the user's pick. */
61
+ StatusText(source: VideoSourceState): string;
62
+ /** The pick button's accessible name. */
63
+ PickLabel(source: VideoSourceState): string;
64
+ /** The switch's accessible name. */
65
+ SwitchLabel(source: VideoSourceState): string;
66
+ /** track fn for the source list. */
67
+ TrackSource(_index: number, source: VideoSourceState): string;
68
+ static ɵfac: i0.ɵɵFactoryDeclaration<RealtimePerceptionChipComponent, never>;
69
+ static ɵcmp: i0.ɵɵComponentDeclaration<RealtimePerceptionChipComponent, "mj-realtime-perception-chip", never, { "Sources": { "alias": "Sources"; "required": false; }; }, { "SourceToggled": "SourceToggled"; "SourcePicked": "SourcePicked"; }, never, never, true, never>;
70
+ }
71
+ //# sourceMappingURL=realtime-perception-chip.component.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realtime-perception-chip.component.d.ts","sourceRoot":"","sources":["../../../../src/lib/components/realtime/realtime-perception-chip.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,YAAY,EAA+B,MAAM,eAAe,CAAC;AAErF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;;AAG3E,gFAAgF;AAChF,MAAM,WAAW,wBAAwB;IACvC,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,gDAAgD;IAChD,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAOa,+BAA+B;IAC1C,4FAA4F;IACnF,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAM;IAEnD,wDAAwD;IAC9C,aAAa,yCAAgD;IAEvE,6GAA6G;IACnG,YAAY,8BAAqC;IAE3D,4CAA4C;IACrC,QAAQ,UAAS;IAExB,6DAA6D;IAC7D,IAAW,cAAc,IAAI,SAAS,gBAAgB,EAAE,CAEvD;IAED,uGAAuG;IACvG,IAAW,OAAO,IAAI,MAAM,CAa3B;IAED,4FAA4F;IAC5F,IAAW,OAAO,IAAI,OAAO,CAE5B;IAED,kGAAkG;IAClG,IAAW,OAAO,IAAI,OAAO,CAE5B;IAED,+EAA+E;IAC/E,IAAW,YAAY,IAAI,MAAM,CAEhC;IAED,iCAAiC;IAC1B,WAAW,IAAI,IAAI;IAI1B,qEAAqE;IAE9D,QAAQ,IAAI,IAAI;IAIvB,+DAA+D;IACxD,QAAQ,CAAC,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAMjE,wFAAwF;IACjF,MAAM,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,GAAG,IAAI;IAIpD,2GAA2G;IACpG,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM;IAUnD,yCAAyC;IAClC,SAAS,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM;IAIlD,oCAAoC;IAC7B,WAAW,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM;IAIpD,oCAAoC;IAC7B,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,MAAM;yCA9FzD,+BAA+B;2CAA/B,+BAA+B;CAiG3C"}
@@ -0,0 +1,221 @@
1
+ import { Component, EventEmitter, HostListener, Input, Output } from '@angular/core';
2
+ import { FormsModule } from '@angular/forms';
3
+ import { MJButtonDirective, MJSwitchComponent } from '@memberjunction/ng-ui-components';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "@angular/forms";
6
+ function RealtimePerceptionChipComponent_Conditional_0_Conditional_5_Conditional_2_Template(rf, ctx) { if (rf & 1) {
7
+ i0.ɵɵtext(0, " The agent sees fewer sources than are on. Pick the one it sees, or turn a source off. ");
8
+ } }
9
+ function RealtimePerceptionChipComponent_Conditional_0_Conditional_5_Conditional_3_Template(rf, ctx) { if (rf & 1) {
10
+ i0.ɵɵtext(0, " Turn a source off and the agent stops seeing it. ");
11
+ } }
12
+ function RealtimePerceptionChipComponent_Conditional_0_Conditional_5_For_6_Conditional_5_Template(rf, ctx) { if (rf & 1) {
13
+ const _r4 = i0.ɵɵgetCurrentView();
14
+ i0.ɵɵelementStart(0, "button", 14);
15
+ i0.ɵɵlistener("click", function RealtimePerceptionChipComponent_Conditional_0_Conditional_5_For_6_Conditional_5_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r4); const source_r5 = i0.ɵɵnextContext().$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnPick(source_r5)); });
16
+ i0.ɵɵtext(1, "Show");
17
+ i0.ɵɵelementEnd();
18
+ } if (rf & 2) {
19
+ const source_r5 = i0.ɵɵnextContext().$implicit;
20
+ const ctx_r1 = i0.ɵɵnextContext(3);
21
+ i0.ɵɵattribute("aria-label", ctx_r1.PickLabel(source_r5));
22
+ } }
23
+ function RealtimePerceptionChipComponent_Conditional_0_Conditional_5_For_6_Template(rf, ctx) { if (rf & 1) {
24
+ const _r3 = i0.ɵɵgetCurrentView();
25
+ i0.ɵɵelementStart(0, "li", 8)(1, "span", 10);
26
+ i0.ɵɵtext(2);
27
+ i0.ɵɵelementEnd();
28
+ i0.ɵɵelementStart(3, "span", 11);
29
+ i0.ɵɵtext(4);
30
+ i0.ɵɵelementEnd();
31
+ i0.ɵɵconditionalCreate(5, RealtimePerceptionChipComponent_Conditional_0_Conditional_5_For_6_Conditional_5_Template, 2, 1, "button", 12);
32
+ i0.ɵɵelementStart(6, "mj-switch", 13);
33
+ i0.ɵɵlistener("ngModelChange", function RealtimePerceptionChipComponent_Conditional_0_Conditional_5_For_6_Template_mj_switch_ngModelChange_6_listener($event) { const source_r5 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnSwitch(source_r5, $event)); });
34
+ i0.ɵɵelementEnd()();
35
+ } if (rf & 2) {
36
+ const source_r5 = ctx.$implicit;
37
+ const ctx_r1 = i0.ɵɵnextContext(3);
38
+ i0.ɵɵadvance(2);
39
+ i0.ɵɵtextInterpolate(source_r5.Label);
40
+ i0.ɵɵadvance();
41
+ i0.ɵɵclassProp("perception-chip__status--live", source_r5.Enabled && source_r5.Active);
42
+ i0.ɵɵadvance();
43
+ i0.ɵɵtextInterpolate(ctx_r1.StatusText(source_r5));
44
+ i0.ɵɵadvance();
45
+ i0.ɵɵconditional(ctx_r1.CanPick && source_r5.Enabled && !source_r5.Active ? 5 : -1);
46
+ i0.ɵɵadvance();
47
+ i0.ɵɵproperty("AriaLabel", ctx_r1.SwitchLabel(source_r5))("ngModel", source_r5.Enabled);
48
+ } }
49
+ function RealtimePerceptionChipComponent_Conditional_0_Conditional_5_Conditional_7_Template(rf, ctx) { if (rf & 1) {
50
+ const _r6 = i0.ɵɵgetCurrentView();
51
+ i0.ɵɵelementStart(0, "button", 15);
52
+ i0.ɵɵlistener("click", function RealtimePerceptionChipComponent_Conditional_0_Conditional_5_Conditional_7_Template_button_click_0_listener() { i0.ɵɵrestoreView(_r6); const ctx_r1 = i0.ɵɵnextContext(3); return i0.ɵɵresetView(ctx_r1.OnPick(null)); });
53
+ i0.ɵɵtext(1, " Let the call choose ");
54
+ i0.ɵɵelementEnd();
55
+ } }
56
+ function RealtimePerceptionChipComponent_Conditional_0_Conditional_5_Template(rf, ctx) { if (rf & 1) {
57
+ i0.ɵɵelementStart(0, "div", 5)(1, "p", 6);
58
+ i0.ɵɵconditionalCreate(2, RealtimePerceptionChipComponent_Conditional_0_Conditional_5_Conditional_2_Template, 1, 0)(3, RealtimePerceptionChipComponent_Conditional_0_Conditional_5_Conditional_3_Template, 1, 0);
59
+ i0.ɵɵelementEnd();
60
+ i0.ɵɵelementStart(4, "ul", 7);
61
+ i0.ɵɵrepeaterCreate(5, RealtimePerceptionChipComponent_Conditional_0_Conditional_5_For_6_Template, 7, 7, "li", 8, i0.ɵɵcomponentInstance().TrackSource, true);
62
+ i0.ɵɵelementEnd();
63
+ i0.ɵɵconditionalCreate(7, RealtimePerceptionChipComponent_Conditional_0_Conditional_5_Conditional_7_Template, 2, 0, "button", 9);
64
+ i0.ɵɵelementEnd();
65
+ } if (rf & 2) {
66
+ const ctx_r1 = i0.ɵɵnextContext(2);
67
+ i0.ɵɵadvance(2);
68
+ i0.ɵɵconditional(ctx_r1.CanPick ? 2 : 3);
69
+ i0.ɵɵadvance(3);
70
+ i0.ɵɵrepeater(ctx_r1.Sources);
71
+ i0.ɵɵadvance(2);
72
+ i0.ɵɵconditional(ctx_r1.HasPick ? 7 : -1);
73
+ } }
74
+ function RealtimePerceptionChipComponent_Conditional_0_Template(rf, ctx) { if (rf & 1) {
75
+ const _r1 = i0.ɵɵgetCurrentView();
76
+ i0.ɵɵelementStart(0, "div", 1)(1, "button", 2);
77
+ i0.ɵɵlistener("click", function RealtimePerceptionChipComponent_Conditional_0_Template_button_click_1_listener() { i0.ɵɵrestoreView(_r1); const ctx_r1 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r1.TogglePanel()); });
78
+ i0.ɵɵelement(2, "i", 3);
79
+ i0.ɵɵelementStart(3, "span", 4);
80
+ i0.ɵɵtext(4);
81
+ i0.ɵɵelementEnd()();
82
+ i0.ɵɵconditionalCreate(5, RealtimePerceptionChipComponent_Conditional_0_Conditional_5_Template, 8, 2, "div", 5);
83
+ i0.ɵɵelementEnd();
84
+ } if (rf & 2) {
85
+ const ctx_r1 = i0.ɵɵnextContext();
86
+ i0.ɵɵclassProp("perception-chip--off", ctx_r1.EnabledSources.length === 0);
87
+ i0.ɵɵadvance();
88
+ i0.ɵɵattribute("aria-expanded", ctx_r1.Expanded)("aria-label", ctx_r1.TriggerLabel);
89
+ i0.ɵɵadvance();
90
+ i0.ɵɵclassProp("fa-eye", ctx_r1.EnabledSources.length > 0)("fa-eye-slash", ctx_r1.EnabledSources.length === 0);
91
+ i0.ɵɵadvance(2);
92
+ i0.ɵɵtextInterpolate(ctx_r1.Summary);
93
+ i0.ɵɵadvance();
94
+ i0.ɵɵconditional(ctx_r1.Expanded ? 5 : -1);
95
+ } }
96
+ /**
97
+ * The "agent can see" chip: a persistent, honest indicator in the realtime overlay of what the agent is
98
+ * looking at, with a switch per source to stop it.
99
+ *
100
+ * Shown whenever the session has a video source (a whiteboard, a remote browser, a shared screen), so a
101
+ * person is never unsure whether the agent can see their screen. The trigger summarizes ("Agent can see:
102
+ * Whiteboard"); opening it lists each source with a switch. Turning a source off removes it from what the
103
+ * agent receives and tells the agent (the runtime owns both, and remembers the choice per channel).
104
+ *
105
+ * The agent may see fewer sources than are on (Gemini sees one). Then the trigger names the one it sees ("Agent
106
+ * sees: Camera"), and the panel lets the user pick another ({@link SourcePicked}) and, once they have, let the
107
+ * call choose again.
108
+ *
109
+ * Purely presentational: it renders the sources it is given and raises {@link SourceToggled}; it never
110
+ * touches the session. Every control has an accessible name; the open panel closes on Escape.
111
+ *
112
+ * @example
113
+ * ```html
114
+ * <mj-realtime-perception-chip [Sources]="VideoSources" (SourceToggled)="OnToggle($event)">
115
+ * </mj-realtime-perception-chip>
116
+ * ```
117
+ */
118
+ export class RealtimePerceptionChipComponent {
119
+ /** The video sources the agent can or could see. The chip is hidden while this is empty. */
120
+ Sources = [];
121
+ /** Raised when the user switches a source on or off. */
122
+ SourceToggled = new EventEmitter();
123
+ /** Raised when the user picks the source the agent sees (its id), or lets the call choose again (`null`). */
124
+ SourcePicked = new EventEmitter();
125
+ /** Whether the per-source panel is open. */
126
+ Expanded = false;
127
+ /** The sources the agent may currently see (switched on). */
128
+ get EnabledSources() {
129
+ return this.Sources.filter((s) => s.Enabled);
130
+ }
131
+ /** The one-line summary on the trigger: with more sources on than the agent sees, the ones it sees. */
132
+ get Summary() {
133
+ const enabled = this.EnabledSources;
134
+ if (enabled.length === 0) {
135
+ return 'Agent view off';
136
+ }
137
+ if (enabled.length === 1) {
138
+ return `Agent can see: ${enabled[0].Label}`;
139
+ }
140
+ const seen = enabled.filter((s) => s.Active);
141
+ if (seen.length === 0 || seen.length === enabled.length) {
142
+ return `Agent can see ${enabled.length} sources`;
143
+ }
144
+ return seen.length === 1 ? `Agent sees: ${seen[0].Label}` : `Agent sees ${seen.length} of ${enabled.length} sources`;
145
+ }
146
+ /** Whether the user may pick a source: some source that is on is not one the agent sees. */
147
+ get CanPick() {
148
+ return this.EnabledSources.some((s) => !s.Active);
149
+ }
150
+ /** Whether the user has picked the source the agent sees, so the call can be let choose again. */
151
+ get HasPick() {
152
+ return this.Sources.some((s) => s.Picked);
153
+ }
154
+ /** The trigger's accessible name: the summary plus what activating it does. */
155
+ get TriggerLabel() {
156
+ return `${this.Summary}. ${this.Expanded ? 'Hide' : 'Show'} what the agent can see.`;
157
+ }
158
+ /** Opens or closes the panel. */
159
+ TogglePanel() {
160
+ this.Expanded = !this.Expanded;
161
+ }
162
+ /** Closes the panel on Escape, wherever focus is inside the chip. */
163
+ OnEscape() {
164
+ this.Expanded = false;
165
+ }
166
+ /** A switch changed: raise the event for the host to apply. */
167
+ OnSwitch(source, enabled) {
168
+ if (enabled !== source.Enabled) {
169
+ this.SourceToggled.emit({ SourceID: source.SourceID, Enabled: enabled });
170
+ }
171
+ }
172
+ /** The user picks the source the agent sees, or lets the call choose again (`null`). */
173
+ OnPick(source) {
174
+ this.SourcePicked.emit(source?.SourceID ?? null);
175
+ }
176
+ /** The row's status text: whether the agent is looking at it right now, and whether by the user's pick. */
177
+ StatusText(source) {
178
+ if (!source.Enabled) {
179
+ return 'Off';
180
+ }
181
+ if (!source.Active) {
182
+ return 'Available';
183
+ }
184
+ return source.Picked ? 'Viewing now, your pick' : 'Viewing now';
185
+ }
186
+ /** The pick button's accessible name. */
187
+ PickLabel(source) {
188
+ return `Show the agent ${source.Label}`;
189
+ }
190
+ /** The switch's accessible name. */
191
+ SwitchLabel(source) {
192
+ return `Let the agent see ${source.Label}`;
193
+ }
194
+ /** track fn for the source list. */
195
+ TrackSource(_index, source) {
196
+ return source.SourceID;
197
+ }
198
+ static ɵfac = function RealtimePerceptionChipComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || RealtimePerceptionChipComponent)(); };
199
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: RealtimePerceptionChipComponent, selectors: [["mj-realtime-perception-chip"]], hostBindings: function RealtimePerceptionChipComponent_HostBindings(rf, ctx) { if (rf & 1) {
200
+ i0.ɵɵlistener("keydown.escape", function RealtimePerceptionChipComponent_keydown_escape_HostBindingHandler() { return ctx.OnEscape(); });
201
+ } }, inputs: { Sources: "Sources" }, outputs: { SourceToggled: "SourceToggled", SourcePicked: "SourcePicked" }, decls: 1, vars: 1, consts: [[1, "perception-chip", 3, "perception-chip--off"], [1, "perception-chip"], ["type", "button", "mjButton", "", "variant", "outline", "size", "sm", "aria-haspopup", "true", 1, "perception-chip__trigger", 3, "click"], ["aria-hidden", "true", 1, "fa-solid"], [1, "perception-chip__summary"], ["role", "group", "aria-label", "What the agent can see", 1, "perception-chip__panel"], [1, "perception-chip__hint"], [1, "perception-chip__list"], [1, "perception-chip__row"], ["type", "button", "mjButton", "", "variant", "flat", "size", "sm", 1, "perception-chip__auto"], [1, "perception-chip__label"], [1, "perception-chip__status"], ["type", "button", "mjButton", "", "variant", "flat", "size", "sm", 1, "perception-chip__pick"], [3, "ngModelChange", "AriaLabel", "ngModel"], ["type", "button", "mjButton", "", "variant", "flat", "size", "sm", 1, "perception-chip__pick", 3, "click"], ["type", "button", "mjButton", "", "variant", "flat", "size", "sm", 1, "perception-chip__auto", 3, "click"]], template: function RealtimePerceptionChipComponent_Template(rf, ctx) { if (rf & 1) {
202
+ i0.ɵɵconditionalCreate(0, RealtimePerceptionChipComponent_Conditional_0_Template, 6, 10, "div", 0);
203
+ } if (rf & 2) {
204
+ i0.ɵɵconditional(ctx.Sources.length > 0 ? 0 : -1);
205
+ } }, dependencies: [FormsModule, i1.NgControlStatus, i1.NgModel, MJButtonDirective, MJSwitchComponent], styles: ["[_nghost-%COMP%] {\n display: block;\n}\n\n.perception-chip[_ngcontent-%COMP%] {\n position: relative;\n display: flex;\n justify-content: flex-start;\n padding: 8px 22px 0;\n}\n\n.perception-chip__trigger[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n margin-right: 6px;\n color: var(--mj-status-success);\n}\n.perception-chip--off[_ngcontent-%COMP%] .perception-chip__trigger[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-muted);\n}\n\n.perception-chip__panel[_ngcontent-%COMP%] {\n position: absolute;\n bottom: 100%;\n left: 22px;\n z-index: 5;\n min-width: 260px;\n max-width: min(360px, calc(100vw - 44px));\n padding: 12px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md, 8px);\n background: var(--mj-bg-surface-elevated);\n color: var(--mj-text-primary);\n box-shadow: var(--mj-shadow-md, 0 4px 16px color-mix(in srgb, var(--mj-text-primary) 18%, transparent));\n}\n\n.perception-chip__hint[_ngcontent-%COMP%] {\n margin: 0 0 8px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.perception-chip__list[_ngcontent-%COMP%] {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.perception-chip__row[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 6px 0;\n border-top: 1px solid var(--mj-border-subtle);\n}\n.perception-chip__row[_ngcontent-%COMP%]:first-child {\n border-top: 0;\n}\n\n.perception-chip__label[_ngcontent-%COMP%] {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 13px;\n font-weight: 600;\n}\n\n.perception-chip__status[_ngcontent-%COMP%] {\n flex: 0 0 auto;\n font-size: 11.5px;\n color: var(--mj-text-muted);\n}\n.perception-chip__status--live[_ngcontent-%COMP%] {\n color: var(--mj-status-success-text, var(--mj-status-success));\n font-weight: 600;\n}\n\n\n.perception-chip__auto[_ngcontent-%COMP%] {\n margin-top: 8px;\n}"] });
206
+ }
207
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(RealtimePerceptionChipComponent, [{
208
+ type: Component,
209
+ args: [{ standalone: true, selector: 'mj-realtime-perception-chip', imports: [FormsModule, MJButtonDirective, MJSwitchComponent], template: "@if (Sources.length > 0) {\n <div class=\"perception-chip\" [class.perception-chip--off]=\"EnabledSources.length === 0\">\n <button type=\"button\" mjButton variant=\"outline\" size=\"sm\" class=\"perception-chip__trigger\"\n aria-haspopup=\"true\"\n [attr.aria-expanded]=\"Expanded\"\n [attr.aria-label]=\"TriggerLabel\"\n (click)=\"TogglePanel()\">\n <i class=\"fa-solid\" [class.fa-eye]=\"EnabledSources.length > 0\" [class.fa-eye-slash]=\"EnabledSources.length === 0\"\n aria-hidden=\"true\"></i>\n <span class=\"perception-chip__summary\">{{ Summary }}</span>\n </button>\n\n @if (Expanded) {\n <div class=\"perception-chip__panel\" role=\"group\" aria-label=\"What the agent can see\">\n <p class=\"perception-chip__hint\">\n @if (CanPick) {\n The agent sees fewer sources than are on. Pick the one it sees, or turn a source off.\n } @else {\n Turn a source off and the agent stops seeing it.\n }\n </p>\n <ul class=\"perception-chip__list\">\n @for (source of Sources; track TrackSource($index, source)) {\n <li class=\"perception-chip__row\">\n <span class=\"perception-chip__label\">{{ source.Label }}</span>\n <span class=\"perception-chip__status\"\n [class.perception-chip__status--live]=\"source.Enabled && source.Active\">{{ StatusText(source) }}</span>\n @if (CanPick && source.Enabled && !source.Active) {\n <button type=\"button\" mjButton variant=\"flat\" size=\"sm\" class=\"perception-chip__pick\"\n [attr.aria-label]=\"PickLabel(source)\"\n (click)=\"OnPick(source)\">Show</button>\n }\n <mj-switch [AriaLabel]=\"SwitchLabel(source)\"\n [ngModel]=\"source.Enabled\"\n (ngModelChange)=\"OnSwitch(source, $event)\"></mj-switch>\n </li>\n }\n </ul>\n @if (HasPick) {\n <button type=\"button\" mjButton variant=\"flat\" size=\"sm\" class=\"perception-chip__auto\" (click)=\"OnPick(null)\">\n Let the call choose\n </button>\n }\n </div>\n }\n </div>\n}\n", styles: [":host {\n display: block;\n}\n\n.perception-chip {\n position: relative;\n display: flex;\n justify-content: flex-start;\n padding: 8px 22px 0;\n}\n\n.perception-chip__trigger i {\n margin-right: 6px;\n color: var(--mj-status-success);\n}\n.perception-chip--off .perception-chip__trigger i {\n color: var(--mj-text-muted);\n}\n\n.perception-chip__panel {\n position: absolute;\n bottom: 100%;\n left: 22px;\n z-index: 5;\n min-width: 260px;\n max-width: min(360px, calc(100vw - 44px));\n padding: 12px 14px;\n border: 1px solid var(--mj-border-default);\n border-radius: var(--mj-radius-md, 8px);\n background: var(--mj-bg-surface-elevated);\n color: var(--mj-text-primary);\n box-shadow: var(--mj-shadow-md, 0 4px 16px color-mix(in srgb, var(--mj-text-primary) 18%, transparent));\n}\n\n.perception-chip__hint {\n margin: 0 0 8px;\n font-size: 12px;\n color: var(--mj-text-muted);\n}\n\n.perception-chip__list {\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.perception-chip__row {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 6px 0;\n border-top: 1px solid var(--mj-border-subtle);\n}\n.perception-chip__row:first-child {\n border-top: 0;\n}\n\n.perception-chip__label {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-size: 13px;\n font-weight: 600;\n}\n\n.perception-chip__status {\n flex: 0 0 auto;\n font-size: 11.5px;\n color: var(--mj-text-muted);\n}\n.perception-chip__status--live {\n color: var(--mj-status-success-text, var(--mj-status-success));\n font-weight: 600;\n}\n\n/* \"Let the call choose\", under the list. */\n.perception-chip__auto {\n margin-top: 8px;\n}\n"] }]
210
+ }], null, { Sources: [{
211
+ type: Input
212
+ }], SourceToggled: [{
213
+ type: Output
214
+ }], SourcePicked: [{
215
+ type: Output
216
+ }], OnEscape: [{
217
+ type: HostListener,
218
+ args: ['keydown.escape']
219
+ }] }); })();
220
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(RealtimePerceptionChipComponent, { className: "RealtimePerceptionChipComponent", filePath: "src/lib/components/realtime/realtime-perception-chip.component.ts", lineNumber: 43 }); })();
221
+ //# sourceMappingURL=realtime-perception-chip.component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realtime-perception-chip.component.js","sourceRoot":"","sources":["../../../../src/lib/components/realtime/realtime-perception-chip.component.ts","../../../../src/lib/components/realtime/realtime-perception-chip.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, EventEmitter, HostListener, Input, Output } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport type { VideoSourceState } from '@memberjunction/ai-realtime-client';\nimport { MJButtonDirective, MJSwitchComponent } from '@memberjunction/ng-ui-components';\n\n/** Raised when the user switches one of the agent's video sources on or off. */\nexport interface RealtimePerceptionToggle {\n /** The source's id (from the arbiter). */\n SourceID: string;\n /** Whether the agent may see it from now on. */\n Enabled: boolean;\n}\n\n/**\n * The \"agent can see\" chip: a persistent, honest indicator in the realtime overlay of what the agent is\n * looking at, with a switch per source to stop it.\n *\n * Shown whenever the session has a video source (a whiteboard, a remote browser, a shared screen), so a\n * person is never unsure whether the agent can see their screen. The trigger summarizes (\"Agent can see:\n * Whiteboard\"); opening it lists each source with a switch. Turning a source off removes it from what the\n * agent receives and tells the agent (the runtime owns both, and remembers the choice per channel).\n *\n * The agent may see fewer sources than are on (Gemini sees one). Then the trigger names the one it sees (\"Agent\n * sees: Camera\"), and the panel lets the user pick another ({@link SourcePicked}) and, once they have, let the\n * call choose again.\n *\n * Purely presentational: it renders the sources it is given and raises {@link SourceToggled}; it never\n * touches the session. Every control has an accessible name; the open panel closes on Escape.\n *\n * @example\n * ```html\n * <mj-realtime-perception-chip [Sources]=\"VideoSources\" (SourceToggled)=\"OnToggle($event)\">\n * </mj-realtime-perception-chip>\n * ```\n */\n@Component({\n standalone: true,\n selector: 'mj-realtime-perception-chip',\n imports: [FormsModule, MJButtonDirective, MJSwitchComponent],\n templateUrl: './realtime-perception-chip.component.html',\n styleUrl: './realtime-perception-chip.component.css'\n})\nexport class RealtimePerceptionChipComponent {\n /** The video sources the agent can or could see. The chip is hidden while this is empty. */\n @Input() Sources: readonly VideoSourceState[] = [];\n\n /** Raised when the user switches a source on or off. */\n @Output() SourceToggled = new EventEmitter<RealtimePerceptionToggle>();\n\n /** Raised when the user picks the source the agent sees (its id), or lets the call choose again (`null`). */\n @Output() SourcePicked = new EventEmitter<string | null>();\n\n /** Whether the per-source panel is open. */\n public Expanded = false;\n\n /** The sources the agent may currently see (switched on). */\n public get EnabledSources(): readonly VideoSourceState[] {\n return this.Sources.filter((s) => s.Enabled);\n }\n\n /** The one-line summary on the trigger: with more sources on than the agent sees, the ones it sees. */\n public get Summary(): string {\n const enabled = this.EnabledSources;\n if (enabled.length === 0) {\n return 'Agent view off';\n }\n if (enabled.length === 1) {\n return `Agent can see: ${enabled[0].Label}`;\n }\n const seen = enabled.filter((s) => s.Active);\n if (seen.length === 0 || seen.length === enabled.length) {\n return `Agent can see ${enabled.length} sources`;\n }\n return seen.length === 1 ? `Agent sees: ${seen[0].Label}` : `Agent sees ${seen.length} of ${enabled.length} sources`;\n }\n\n /** Whether the user may pick a source: some source that is on is not one the agent sees. */\n public get CanPick(): boolean {\n return this.EnabledSources.some((s) => !s.Active);\n }\n\n /** Whether the user has picked the source the agent sees, so the call can be let choose again. */\n public get HasPick(): boolean {\n return this.Sources.some((s) => s.Picked);\n }\n\n /** The trigger's accessible name: the summary plus what activating it does. */\n public get TriggerLabel(): string {\n return `${this.Summary}. ${this.Expanded ? 'Hide' : 'Show'} what the agent can see.`;\n }\n\n /** Opens or closes the panel. */\n public TogglePanel(): void {\n this.Expanded = !this.Expanded;\n }\n\n /** Closes the panel on Escape, wherever focus is inside the chip. */\n @HostListener('keydown.escape')\n public OnEscape(): void {\n this.Expanded = false;\n }\n\n /** A switch changed: raise the event for the host to apply. */\n public OnSwitch(source: VideoSourceState, enabled: boolean): void {\n if (enabled !== source.Enabled) {\n this.SourceToggled.emit({ SourceID: source.SourceID, Enabled: enabled });\n }\n }\n\n /** The user picks the source the agent sees, or lets the call choose again (`null`). */\n public OnPick(source: VideoSourceState | null): void {\n this.SourcePicked.emit(source?.SourceID ?? null);\n }\n\n /** The row's status text: whether the agent is looking at it right now, and whether by the user's pick. */\n public StatusText(source: VideoSourceState): string {\n if (!source.Enabled) {\n return 'Off';\n }\n if (!source.Active) {\n return 'Available';\n }\n return source.Picked ? 'Viewing now, your pick' : 'Viewing now';\n }\n\n /** The pick button's accessible name. */\n public PickLabel(source: VideoSourceState): string {\n return `Show the agent ${source.Label}`;\n }\n\n /** The switch's accessible name. */\n public SwitchLabel(source: VideoSourceState): string {\n return `Let the agent see ${source.Label}`;\n }\n\n /** track fn for the source list. */\n public TrackSource(_index: number, source: VideoSourceState): string {\n return source.SourceID;\n }\n}\n","@if (Sources.length > 0) {\n <div class=\"perception-chip\" [class.perception-chip--off]=\"EnabledSources.length === 0\">\n <button type=\"button\" mjButton variant=\"outline\" size=\"sm\" class=\"perception-chip__trigger\"\n aria-haspopup=\"true\"\n [attr.aria-expanded]=\"Expanded\"\n [attr.aria-label]=\"TriggerLabel\"\n (click)=\"TogglePanel()\">\n <i class=\"fa-solid\" [class.fa-eye]=\"EnabledSources.length > 0\" [class.fa-eye-slash]=\"EnabledSources.length === 0\"\n aria-hidden=\"true\"></i>\n <span class=\"perception-chip__summary\">{{ Summary }}</span>\n </button>\n\n @if (Expanded) {\n <div class=\"perception-chip__panel\" role=\"group\" aria-label=\"What the agent can see\">\n <p class=\"perception-chip__hint\">\n @if (CanPick) {\n The agent sees fewer sources than are on. Pick the one it sees, or turn a source off.\n } @else {\n Turn a source off and the agent stops seeing it.\n }\n </p>\n <ul class=\"perception-chip__list\">\n @for (source of Sources; track TrackSource($index, source)) {\n <li class=\"perception-chip__row\">\n <span class=\"perception-chip__label\">{{ source.Label }}</span>\n <span class=\"perception-chip__status\"\n [class.perception-chip__status--live]=\"source.Enabled && source.Active\">{{ StatusText(source) }}</span>\n @if (CanPick && source.Enabled && !source.Active) {\n <button type=\"button\" mjButton variant=\"flat\" size=\"sm\" class=\"perception-chip__pick\"\n [attr.aria-label]=\"PickLabel(source)\"\n (click)=\"OnPick(source)\">Show</button>\n }\n <mj-switch [AriaLabel]=\"SwitchLabel(source)\"\n [ngModel]=\"source.Enabled\"\n (ngModelChange)=\"OnSwitch(source, $event)\"></mj-switch>\n </li>\n }\n </ul>\n @if (HasPick) {\n <button type=\"button\" mjButton variant=\"flat\" size=\"sm\" class=\"perception-chip__auto\" (click)=\"OnPick(null)\">\n Let the call choose\n </button>\n }\n </div>\n }\n </div>\n}\n"]}