@memberjunction/ng-conversations 6.2.0-edge.3 → 6.2.0-edge.5

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 (318) hide show
  1. package/README.md +33 -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-agent-picker.component.d.ts +1 -1
  10. package/dist/lib/components/conversation/conversation-agent-picker.component.js +3 -3
  11. package/dist/lib/components/conversation/conversation-agent-picker.component.js.map +1 -1
  12. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts +651 -53
  13. package/dist/lib/components/conversation/conversation-chat-area.component.d.ts.map +1 -1
  14. package/dist/lib/components/conversation/conversation-chat-area.component.js +3002 -661
  15. package/dist/lib/components/conversation/conversation-chat-area.component.js.map +1 -1
  16. package/dist/lib/components/conversation/forks-popover.component.d.ts +37 -0
  17. package/dist/lib/components/conversation/forks-popover.component.d.ts.map +1 -0
  18. package/dist/lib/components/conversation/forks-popover.component.js +164 -0
  19. package/dist/lib/components/conversation/forks-popover.component.js.map +1 -0
  20. package/dist/lib/components/export/export-modal.component.d.ts +7 -2
  21. package/dist/lib/components/export/export-modal.component.d.ts.map +1 -1
  22. package/dist/lib/components/export/export-modal.component.js +16 -3
  23. package/dist/lib/components/export/export-modal.component.js.map +1 -1
  24. package/dist/lib/components/message/conversation-message-rating.component.d.ts.map +1 -1
  25. package/dist/lib/components/message/conversation-message-rating.component.js +11 -9
  26. package/dist/lib/components/message/conversation-message-rating.component.js.map +1 -1
  27. package/dist/lib/components/message/message-input.component.d.ts +96 -11
  28. package/dist/lib/components/message/message-input.component.d.ts.map +1 -1
  29. package/dist/lib/components/message/message-input.component.js +253 -112
  30. package/dist/lib/components/message/message-input.component.js.map +1 -1
  31. package/dist/lib/components/message/message-item.component.d.ts +304 -16
  32. package/dist/lib/components/message/message-item.component.d.ts.map +1 -1
  33. package/dist/lib/components/message/message-item.component.js +2029 -363
  34. package/dist/lib/components/message/message-item.component.js.map +1 -1
  35. package/dist/lib/components/message/message-list.component.d.ts +101 -22
  36. package/dist/lib/components/message/message-list.component.d.ts.map +1 -1
  37. package/dist/lib/components/message/message-list.component.js +326 -55
  38. package/dist/lib/components/message/message-list.component.js.map +1 -1
  39. package/dist/lib/components/realtime/avatar/realtime-avatar-channel.d.ts +34 -0
  40. package/dist/lib/components/realtime/avatar/realtime-avatar-channel.d.ts.map +1 -0
  41. package/dist/lib/components/realtime/avatar/realtime-avatar-channel.js +75 -0
  42. package/dist/lib/components/realtime/avatar/realtime-avatar-channel.js.map +1 -0
  43. package/dist/lib/components/realtime/avatar/realtime-avatar-surface.component.d.ts +80 -0
  44. package/dist/lib/components/realtime/avatar/realtime-avatar-surface.component.d.ts.map +1 -0
  45. package/dist/lib/components/realtime/avatar/realtime-avatar-surface.component.js +202 -0
  46. package/dist/lib/components/realtime/avatar/realtime-avatar-surface.component.js.map +1 -0
  47. package/dist/lib/components/realtime/capture/realtime-camera-check-card.component.d.ts +45 -0
  48. package/dist/lib/components/realtime/capture/realtime-camera-check-card.component.d.ts.map +1 -0
  49. package/dist/lib/components/realtime/capture/realtime-camera-check-card.component.js +123 -0
  50. package/dist/lib/components/realtime/capture/realtime-camera-check-card.component.js.map +1 -0
  51. package/dist/lib/components/realtime/capture/realtime-capture-channel.d.ts +90 -0
  52. package/dist/lib/components/realtime/capture/realtime-capture-channel.d.ts.map +1 -0
  53. package/dist/lib/components/realtime/capture/realtime-capture-channel.js +223 -0
  54. package/dist/lib/components/realtime/capture/realtime-capture-channel.js.map +1 -0
  55. package/dist/lib/components/realtime/capture/realtime-capture-model.d.ts +98 -0
  56. package/dist/lib/components/realtime/capture/realtime-capture-model.d.ts.map +1 -0
  57. package/dist/lib/components/realtime/capture/realtime-capture-model.js +161 -0
  58. package/dist/lib/components/realtime/capture/realtime-capture-model.js.map +1 -0
  59. package/dist/lib/components/realtime/capture/realtime-capture-surface.component.d.ts +48 -0
  60. package/dist/lib/components/realtime/capture/realtime-capture-surface.component.d.ts.map +1 -0
  61. package/dist/lib/components/realtime/capture/realtime-capture-surface.component.js +205 -0
  62. package/dist/lib/components/realtime/capture/realtime-capture-surface.component.js.map +1 -0
  63. package/dist/lib/components/realtime/channels/client-context-channel.d.ts +19 -2
  64. package/dist/lib/components/realtime/channels/client-context-channel.d.ts.map +1 -1
  65. package/dist/lib/components/realtime/channels/client-context-channel.js +83 -9
  66. package/dist/lib/components/realtime/channels/client-context-channel.js.map +1 -1
  67. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts +30 -9
  68. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.d.ts.map +1 -1
  69. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js +78 -14
  70. package/dist/lib/components/realtime/channels/realtime-channel-pane.component.js.map +1 -1
  71. package/dist/lib/components/realtime/identity-verification/identity-verification-channel.d.ts +71 -0
  72. package/dist/lib/components/realtime/identity-verification/identity-verification-channel.d.ts.map +1 -0
  73. package/dist/lib/components/realtime/identity-verification/identity-verification-channel.js +259 -0
  74. package/dist/lib/components/realtime/identity-verification/identity-verification-channel.js.map +1 -0
  75. package/dist/lib/components/realtime/identity-verification/identity-verification-model.d.ts +129 -0
  76. package/dist/lib/components/realtime/identity-verification/identity-verification-model.d.ts.map +1 -0
  77. package/dist/lib/components/realtime/identity-verification/identity-verification-model.js +373 -0
  78. package/dist/lib/components/realtime/identity-verification/identity-verification-model.js.map +1 -0
  79. package/dist/lib/components/realtime/identity-verification/identity-verification-surface.component.d.ts +77 -0
  80. package/dist/lib/components/realtime/identity-verification/identity-verification-surface.component.d.ts.map +1 -0
  81. package/dist/lib/components/realtime/identity-verification/identity-verification-surface.component.js +420 -0
  82. package/dist/lib/components/realtime/identity-verification/identity-verification-surface.component.js.map +1 -0
  83. package/dist/lib/components/realtime/interactive-component/component-contract.d.ts +83 -0
  84. package/dist/lib/components/realtime/interactive-component/component-contract.d.ts.map +1 -0
  85. package/dist/lib/components/realtime/interactive-component/component-contract.js +292 -0
  86. package/dist/lib/components/realtime/interactive-component/component-contract.js.map +1 -0
  87. package/dist/lib/components/realtime/interactive-component/component-data-state.d.ts +39 -0
  88. package/dist/lib/components/realtime/interactive-component/component-data-state.d.ts.map +1 -0
  89. package/dist/lib/components/realtime/interactive-component/component-data-state.js +152 -0
  90. package/dist/lib/components/realtime/interactive-component/component-data-state.js.map +1 -0
  91. package/dist/lib/components/realtime/interactive-component/component-instance-engine.d.ts +109 -0
  92. package/dist/lib/components/realtime/interactive-component/component-instance-engine.d.ts.map +1 -0
  93. package/dist/lib/components/realtime/interactive-component/component-instance-engine.js +146 -0
  94. package/dist/lib/components/realtime/interactive-component/component-instance-engine.js.map +1 -0
  95. package/dist/lib/components/realtime/interactive-component/component-spec-content.d.ts +19 -0
  96. package/dist/lib/components/realtime/interactive-component/component-spec-content.d.ts.map +1 -0
  97. package/dist/lib/components/realtime/interactive-component/component-spec-content.js +39 -0
  98. package/dist/lib/components/realtime/interactive-component/component-spec-content.js.map +1 -0
  99. package/dist/lib/components/realtime/interactive-component/interactive-component-channel.d.ts +183 -0
  100. package/dist/lib/components/realtime/interactive-component/interactive-component-channel.d.ts.map +1 -0
  101. package/dist/lib/components/realtime/interactive-component/interactive-component-channel.js +761 -0
  102. package/dist/lib/components/realtime/interactive-component/interactive-component-channel.js.map +1 -0
  103. package/dist/lib/components/realtime/interactive-component/interactive-component-config.d.ts +25 -0
  104. package/dist/lib/components/realtime/interactive-component/interactive-component-config.d.ts.map +1 -0
  105. package/dist/lib/components/realtime/interactive-component/interactive-component-config.js +57 -0
  106. package/dist/lib/components/realtime/interactive-component/interactive-component-config.js.map +1 -0
  107. package/dist/lib/components/realtime/interactive-component/interactive-component-host.component.d.ts +40 -0
  108. package/dist/lib/components/realtime/interactive-component/interactive-component-host.component.d.ts.map +1 -0
  109. package/dist/lib/components/realtime/interactive-component/interactive-component-host.component.js +97 -0
  110. package/dist/lib/components/realtime/interactive-component/interactive-component-host.component.js.map +1 -0
  111. package/dist/lib/components/realtime/interactive-component/interactive-component-types.d.ts +144 -0
  112. package/dist/lib/components/realtime/interactive-component/interactive-component-types.d.ts.map +1 -0
  113. package/dist/lib/components/realtime/interactive-component/interactive-component-types.js +57 -0
  114. package/dist/lib/components/realtime/interactive-component/interactive-component-types.js.map +1 -0
  115. package/dist/lib/components/realtime/interactive-component/react-component-handle.d.ts +36 -0
  116. package/dist/lib/components/realtime/interactive-component/react-component-handle.d.ts.map +1 -0
  117. package/dist/lib/components/realtime/interactive-component/react-component-handle.js +55 -0
  118. package/dist/lib/components/realtime/interactive-component/react-component-handle.js.map +1 -0
  119. package/dist/lib/components/realtime/interactive-component/realtime-interactive-component-surface.component.d.ts +55 -0
  120. package/dist/lib/components/realtime/interactive-component/realtime-interactive-component-surface.component.d.ts.map +1 -0
  121. package/dist/lib/components/realtime/interactive-component/realtime-interactive-component-surface.component.js +210 -0
  122. package/dist/lib/components/realtime/interactive-component/realtime-interactive-component-surface.component.js.map +1 -0
  123. package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.d.ts +32 -0
  124. package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.d.ts.map +1 -0
  125. package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.js +90 -0
  126. package/dist/lib/components/realtime/interactive-component/run-view-component-artifact-source.js.map +1 -0
  127. package/dist/lib/components/realtime/media/media-channel.d.ts +7 -0
  128. package/dist/lib/components/realtime/media/media-channel.d.ts.map +1 -1
  129. package/dist/lib/components/realtime/media/media-channel.js +28 -1
  130. package/dist/lib/components/realtime/media/media-channel.js.map +1 -1
  131. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts +8 -1
  132. package/dist/lib/components/realtime/realtime-agent-banner.component.d.ts.map +1 -1
  133. package/dist/lib/components/realtime/realtime-agent-banner.component.js +89 -71
  134. package/dist/lib/components/realtime/realtime-agent-banner.component.js.map +1 -1
  135. package/dist/lib/components/realtime/realtime-agent-orb.component.d.ts +21 -0
  136. package/dist/lib/components/realtime/realtime-agent-orb.component.d.ts.map +1 -0
  137. package/dist/lib/components/realtime/realtime-agent-orb.component.js +49 -0
  138. package/dist/lib/components/realtime/realtime-agent-orb.component.js.map +1 -0
  139. package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts +44 -11
  140. package/dist/lib/components/realtime/realtime-agent-picker.component.d.ts.map +1 -1
  141. package/dist/lib/components/realtime/realtime-agent-picker.component.js +162 -50
  142. package/dist/lib/components/realtime/realtime-agent-picker.component.js.map +1 -1
  143. package/dist/lib/components/realtime/realtime-audio-visuals.d.ts +8 -2
  144. package/dist/lib/components/realtime/realtime-audio-visuals.d.ts.map +1 -1
  145. package/dist/lib/components/realtime/realtime-audio-visuals.js +14 -18
  146. package/dist/lib/components/realtime/realtime-audio-visuals.js.map +1 -1
  147. package/dist/lib/components/realtime/realtime-composer.component.d.ts +42 -2
  148. package/dist/lib/components/realtime/realtime-composer.component.d.ts.map +1 -1
  149. package/dist/lib/components/realtime/realtime-composer.component.js +137 -102
  150. package/dist/lib/components/realtime/realtime-composer.component.js.map +1 -1
  151. package/dist/lib/components/realtime/realtime-perception-chip.component.d.ts +71 -0
  152. package/dist/lib/components/realtime/realtime-perception-chip.component.d.ts.map +1 -0
  153. package/dist/lib/components/realtime/realtime-perception-chip.component.js +221 -0
  154. package/dist/lib/components/realtime/realtime-perception-chip.component.js.map +1 -0
  155. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts +264 -22
  156. package/dist/lib/components/realtime/realtime-session-overlay.component.d.ts.map +1 -1
  157. package/dist/lib/components/realtime/realtime-session-overlay.component.js +851 -135
  158. package/dist/lib/components/realtime/realtime-session-overlay.component.js.map +1 -1
  159. package/dist/lib/components/realtime/realtime-surface-placement-prefs.d.ts +14 -0
  160. package/dist/lib/components/realtime/realtime-surface-placement-prefs.d.ts.map +1 -0
  161. package/dist/lib/components/realtime/realtime-surface-placement-prefs.js +14 -0
  162. package/dist/lib/components/realtime/realtime-surface-placement-prefs.js.map +1 -0
  163. package/dist/lib/components/realtime/realtime-surface-stage.model.d.ts +74 -0
  164. package/dist/lib/components/realtime/realtime-surface-stage.model.d.ts.map +1 -0
  165. package/dist/lib/components/realtime/realtime-surface-stage.model.js +171 -0
  166. package/dist/lib/components/realtime/realtime-surface-stage.model.js.map +1 -0
  167. package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts +71 -13
  168. package/dist/lib/components/realtime/realtime-surface-tabs.component.d.ts.map +1 -1
  169. package/dist/lib/components/realtime/realtime-surface-tabs.component.js +232 -73
  170. package/dist/lib/components/realtime/realtime-surface-tabs.component.js.map +1 -1
  171. package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts +5 -0
  172. package/dist/lib/components/realtime/realtime-surface-tabs.model.d.ts.map +1 -1
  173. package/dist/lib/components/realtime/realtime-surface-tabs.model.js +8 -0
  174. package/dist/lib/components/realtime/realtime-surface-tabs.model.js.map +1 -1
  175. package/dist/lib/components/realtime/realtime-ui-config.d.ts +12 -2
  176. package/dist/lib/components/realtime/realtime-ui-config.d.ts.map +1 -1
  177. package/dist/lib/components/realtime/realtime-ui-config.js +5 -1
  178. package/dist/lib/components/realtime/realtime-ui-config.js.map +1 -1
  179. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts +10 -1
  180. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.d.ts.map +1 -1
  181. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js +42 -2
  182. package/dist/lib/components/realtime/remote-browser/remote-browser-channel.js.map +1 -1
  183. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.d.ts +20 -3
  184. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.d.ts.map +1 -1
  185. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.js +44 -10
  186. package/dist/lib/components/realtime/remote-browser/remote-browser-surface.component.js.map +1 -1
  187. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts +28 -44
  188. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.d.ts.map +1 -1
  189. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js +76 -162
  190. package/dist/lib/components/realtime/whiteboard/whiteboard-channel.js.map +1 -1
  191. package/dist/lib/components/search/search-panel.component.d.ts +2 -0
  192. package/dist/lib/components/search/search-panel.component.d.ts.map +1 -1
  193. package/dist/lib/components/search/search-panel.component.js +25 -12
  194. package/dist/lib/components/search/search-panel.component.js.map +1 -1
  195. package/dist/lib/components/sidebar/routines-section.component.js +1 -1
  196. package/dist/lib/components/sidebar/routines-section.component.js.map +1 -1
  197. package/dist/lib/components/task/tasks-full-view.component.d.ts +152 -31
  198. package/dist/lib/components/task/tasks-full-view.component.d.ts.map +1 -1
  199. package/dist/lib/components/task/tasks-full-view.component.js +2227 -214
  200. package/dist/lib/components/task/tasks-full-view.component.js.map +1 -1
  201. package/dist/lib/components/tasks/tasks-dropdown.component.js +4 -4
  202. package/dist/lib/components/tasks/tasks-dropdown.component.js.map +1 -1
  203. package/dist/lib/components/workspace/conversation-workspace.component.d.ts +33 -32
  204. package/dist/lib/components/workspace/conversation-workspace.component.d.ts.map +1 -1
  205. package/dist/lib/components/workspace/conversation-workspace.component.js +72 -88
  206. package/dist/lib/components/workspace/conversation-workspace.component.js.map +1 -1
  207. package/dist/lib/conversations.module.d.ts +30 -29
  208. package/dist/lib/conversations.module.d.ts.map +1 -1
  209. package/dist/lib/conversations.module.js +27 -5
  210. package/dist/lib/conversations.module.js.map +1 -1
  211. package/dist/lib/events/chat-events.d.ts +25 -0
  212. package/dist/lib/events/chat-events.d.ts.map +1 -1
  213. package/dist/lib/events/chat-events.js +36 -0
  214. package/dist/lib/events/chat-events.js.map +1 -1
  215. package/dist/lib/models/agent-turn.model.d.ts +5 -0
  216. package/dist/lib/models/agent-turn.model.d.ts.map +1 -1
  217. package/dist/lib/models/agent-turn.model.js.map +1 -1
  218. package/dist/lib/services/agent-state.service.d.ts +34 -8
  219. package/dist/lib/services/agent-state.service.d.ts.map +1 -1
  220. package/dist/lib/services/agent-state.service.js +90 -37
  221. package/dist/lib/services/agent-state.service.js.map +1 -1
  222. package/dist/lib/services/artifact-state.service.d.ts +0 -9
  223. package/dist/lib/services/artifact-state.service.d.ts.map +1 -1
  224. package/dist/lib/services/artifact-state.service.js +1 -32
  225. package/dist/lib/services/artifact-state.service.js.map +1 -1
  226. package/dist/lib/services/browser-realtime-media-host.d.ts +19 -7
  227. package/dist/lib/services/browser-realtime-media-host.d.ts.map +1 -1
  228. package/dist/lib/services/browser-realtime-media-host.js +21 -72
  229. package/dist/lib/services/browser-realtime-media-host.js.map +1 -1
  230. package/dist/lib/services/conversation-agent.service.d.ts +48 -16
  231. package/dist/lib/services/conversation-agent.service.d.ts.map +1 -1
  232. package/dist/lib/services/conversation-agent.service.js +110 -35
  233. package/dist/lib/services/conversation-agent.service.js.map +1 -1
  234. package/dist/lib/services/conversation-detail-window.store.d.ts +22 -4
  235. package/dist/lib/services/conversation-detail-window.store.d.ts.map +1 -1
  236. package/dist/lib/services/conversation-detail-window.store.js +50 -9
  237. package/dist/lib/services/conversation-detail-window.store.js.map +1 -1
  238. package/dist/lib/services/conversation-naming.d.ts +72 -22
  239. package/dist/lib/services/conversation-naming.d.ts.map +1 -1
  240. package/dist/lib/services/conversation-naming.js +93 -12
  241. package/dist/lib/services/conversation-naming.js.map +1 -1
  242. package/dist/lib/services/conversation-tasks-filter.d.ts +15 -0
  243. package/dist/lib/services/conversation-tasks-filter.d.ts.map +1 -0
  244. package/dist/lib/services/conversation-tasks-filter.js +69 -0
  245. package/dist/lib/services/conversation-tasks-filter.js.map +1 -0
  246. package/dist/lib/services/data-cache.service.d.ts +13 -5
  247. package/dist/lib/services/data-cache.service.d.ts.map +1 -1
  248. package/dist/lib/services/data-cache.service.js +39 -19
  249. package/dist/lib/services/data-cache.service.js.map +1 -1
  250. package/dist/lib/services/export.service.d.ts +26 -9
  251. package/dist/lib/services/export.service.d.ts.map +1 -1
  252. package/dist/lib/services/export.service.js +61 -18
  253. package/dist/lib/services/export.service.js.map +1 -1
  254. package/dist/lib/services/realtime-audio-recorder.d.ts +115 -79
  255. package/dist/lib/services/realtime-audio-recorder.d.ts.map +1 -1
  256. package/dist/lib/services/realtime-audio-recorder.js +273 -186
  257. package/dist/lib/services/realtime-audio-recorder.js.map +1 -1
  258. package/dist/lib/services/realtime-pairing.d.ts +10 -5
  259. package/dist/lib/services/realtime-pairing.d.ts.map +1 -1
  260. package/dist/lib/services/realtime-pairing.js +15 -6
  261. package/dist/lib/services/realtime-pairing.js.map +1 -1
  262. package/dist/lib/services/realtime-session.service.d.ts +31 -2
  263. package/dist/lib/services/realtime-session.service.d.ts.map +1 -1
  264. package/dist/lib/services/realtime-session.service.js +34 -2
  265. package/dist/lib/services/realtime-session.service.js.map +1 -1
  266. package/dist/lib/services/recording/libopus-wasm-binary.d.ts +3 -0
  267. package/dist/lib/services/recording/libopus-wasm-binary.d.ts.map +1 -0
  268. package/dist/lib/services/recording/libopus-wasm-binary.js +489 -0
  269. package/dist/lib/services/recording/libopus-wasm-binary.js.map +1 -0
  270. package/dist/lib/services/recording/libopus-worker-source.d.ts +48 -0
  271. package/dist/lib/services/recording/libopus-worker-source.d.ts.map +1 -0
  272. package/dist/lib/services/recording/libopus-worker-source.js +170 -0
  273. package/dist/lib/services/recording/libopus-worker-source.js.map +1 -0
  274. package/dist/lib/services/recording/linear-resampler.d.ts +45 -0
  275. package/dist/lib/services/recording/linear-resampler.d.ts.map +1 -0
  276. package/dist/lib/services/recording/linear-resampler.js +85 -0
  277. package/dist/lib/services/recording/linear-resampler.js.map +1 -0
  278. package/dist/lib/services/recording/opus-packet-encoder.d.ts +50 -0
  279. package/dist/lib/services/recording/opus-packet-encoder.d.ts.map +1 -0
  280. package/dist/lib/services/recording/opus-packet-encoder.js +41 -0
  281. package/dist/lib/services/recording/opus-packet-encoder.js.map +1 -0
  282. package/dist/lib/services/recording/wasm-opus-encoder.d.ts +86 -0
  283. package/dist/lib/services/recording/wasm-opus-encoder.d.ts.map +1 -0
  284. package/dist/lib/services/recording/wasm-opus-encoder.js +232 -0
  285. package/dist/lib/services/recording/wasm-opus-encoder.js.map +1 -0
  286. package/dist/lib/services/recording/webcodecs-opus-encoder.d.ts +39 -0
  287. package/dist/lib/services/recording/webcodecs-opus-encoder.d.ts.map +1 -0
  288. package/dist/lib/services/recording/webcodecs-opus-encoder.js +101 -0
  289. package/dist/lib/services/recording/webcodecs-opus-encoder.js.map +1 -0
  290. package/dist/lib/services/search.service.d.ts +7 -2
  291. package/dist/lib/services/search.service.d.ts.map +1 -1
  292. package/dist/lib/services/search.service.js +16 -20
  293. package/dist/lib/services/search.service.js.map +1 -1
  294. package/dist/lib/utils/conversation-branching.d.ts +4 -0
  295. package/dist/lib/utils/conversation-branching.d.ts.map +1 -0
  296. package/dist/lib/utils/conversation-branching.js +5 -0
  297. package/dist/lib/utils/conversation-branching.js.map +1 -0
  298. package/dist/lib/utils/conversation-forks.d.ts +315 -0
  299. package/dist/lib/utils/conversation-forks.d.ts.map +1 -0
  300. package/dist/lib/utils/conversation-forks.js +456 -0
  301. package/dist/lib/utils/conversation-forks.js.map +1 -0
  302. package/dist/lib/utils/distinct-artifacts.d.ts +9 -3
  303. package/dist/lib/utils/distinct-artifacts.d.ts.map +1 -1
  304. package/dist/lib/utils/distinct-artifacts.js +24 -5
  305. package/dist/lib/utils/distinct-artifacts.js.map +1 -1
  306. package/dist/public-api.d.ts +23 -1
  307. package/dist/public-api.d.ts.map +1 -1
  308. package/dist/public-api.js +30 -1
  309. package/dist/public-api.js.map +1 -1
  310. package/package.json +37 -33
  311. package/dist/lib/components/thread/thread-panel.component.d.ts +0 -126
  312. package/dist/lib/components/thread/thread-panel.component.d.ts.map +0 -1
  313. package/dist/lib/components/thread/thread-panel.component.js +0 -440
  314. package/dist/lib/components/thread/thread-panel.component.js.map +0 -1
  315. package/dist/lib/services/realtime-pcm-wav.d.ts +0 -79
  316. package/dist/lib/services/realtime-pcm-wav.d.ts.map +0 -1
  317. package/dist/lib/services/realtime-pcm-wav.js +0 -213
  318. package/dist/lib/services/realtime-pcm-wav.js.map +0 -1
@@ -1,440 +0,0 @@
1
- import { Component, Input, Output, EventEmitter } from '@angular/core';
2
- import { BaseAngularComponent } from '@memberjunction/ng-base-types';
3
- import { RunView } from '@memberjunction/core';
4
- import { Subject } from 'rxjs';
5
- import * as i0 from "@angular/core";
6
- import * as i1 from "../../services/data-cache.service";
7
- import * as i2 from "@angular/forms";
8
- const _forTrack0 = ($index, $item) => $item.ID;
9
- function ThreadPanelComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
10
- i0.ɵɵelementStart(0, "div", 7);
11
- i0.ɵɵelement(1, "i", 9);
12
- i0.ɵɵelementStart(2, "span");
13
- i0.ɵɵtext(3, "Loading thread...");
14
- i0.ɵɵelementEnd()();
15
- } }
16
- function ThreadPanelComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
17
- i0.ɵɵelementStart(0, "div", 8);
18
- i0.ɵɵelement(1, "i", 10);
19
- i0.ɵɵelementStart(2, "span");
20
- i0.ɵɵtext(3);
21
- i0.ɵɵelementEnd()();
22
- } if (rf & 2) {
23
- const ctx_r0 = i0.ɵɵnextContext();
24
- i0.ɵɵadvance(3);
25
- i0.ɵɵtextInterpolate(ctx_r0.errorMessage);
26
- } }
27
- function ThreadPanelComponent_Conditional_11_Conditional_14_Template(rf, ctx) { if (rf & 1) {
28
- i0.ɵɵelementStart(0, "div", 20);
29
- i0.ɵɵelement(1, "i", 27);
30
- i0.ɵɵelementStart(2, "span");
31
- i0.ɵɵtext(3, "No replies yet. Be the first to reply!");
32
- i0.ɵɵelementEnd()();
33
- } }
34
- function ThreadPanelComponent_Conditional_11_For_16_Template(rf, ctx) { if (rf & 1) {
35
- i0.ɵɵelementStart(0, "div", 28)(1, "div", 29)(2, "span", 30);
36
- i0.ɵɵtext(3);
37
- i0.ɵɵelementEnd();
38
- i0.ɵɵelementStart(4, "span", 31);
39
- i0.ɵɵtext(5);
40
- i0.ɵɵelementEnd()();
41
- i0.ɵɵelementStart(6, "div", 32);
42
- i0.ɵɵtext(7);
43
- i0.ɵɵelementEnd()();
44
- } if (rf & 2) {
45
- const reply_r3 = ctx.$implicit;
46
- const ctx_r0 = i0.ɵɵnextContext(2);
47
- i0.ɵɵclassProp("ai-reply", reply_r3.Role === "AI");
48
- i0.ɵɵadvance(3);
49
- i0.ɵɵtextInterpolate(ctx_r0.getSenderName(reply_r3));
50
- i0.ɵɵadvance(2);
51
- i0.ɵɵtextInterpolate(ctx_r0.getMessageTime(reply_r3));
52
- i0.ɵɵadvance(2);
53
- i0.ɵɵtextInterpolate1(" ", ctx_r0.getMessageText(reply_r3), " ");
54
- } }
55
- function ThreadPanelComponent_Conditional_11_Template(rf, ctx) { if (rf & 1) {
56
- const _r2 = i0.ɵɵgetCurrentView();
57
- i0.ɵɵelementStart(0, "div", 11)(1, "div", 12)(2, "div", 13)(3, "span", 14);
58
- i0.ɵɵtext(4);
59
- i0.ɵɵelementEnd();
60
- i0.ɵɵelementStart(5, "span", 15);
61
- i0.ɵɵtext(6);
62
- i0.ɵɵelementEnd()();
63
- i0.ɵɵelementStart(7, "div", 16);
64
- i0.ɵɵtext(8);
65
- i0.ɵɵelementEnd();
66
- i0.ɵɵelementStart(9, "div", 17);
67
- i0.ɵɵelement(10, "i", 18);
68
- i0.ɵɵelementStart(11, "span");
69
- i0.ɵɵtext(12);
70
- i0.ɵɵelementEnd()()();
71
- i0.ɵɵelementStart(13, "div", 19);
72
- i0.ɵɵconditionalCreate(14, ThreadPanelComponent_Conditional_11_Conditional_14_Template, 4, 0, "div", 20);
73
- i0.ɵɵrepeaterCreate(15, ThreadPanelComponent_Conditional_11_For_16_Template, 8, 5, "div", 21, _forTrack0);
74
- i0.ɵɵelementEnd()();
75
- i0.ɵɵelementStart(17, "div", 22)(18, "textarea", 23);
76
- i0.ɵɵtwoWayListener("ngModelChange", function ThreadPanelComponent_Conditional_11_Template_textarea_ngModelChange_18_listener($event) { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); i0.ɵɵtwoWayBindingSet(ctx_r0.replyText, $event) || (ctx_r0.replyText = $event); return i0.ɵɵresetView($event); });
77
- i0.ɵɵlistener("keydown.control.enter", function ThreadPanelComponent_Conditional_11_Template_textarea_keydown_control_enter_18_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onSendReply()); })("keydown.meta.enter", function ThreadPanelComponent_Conditional_11_Template_textarea_keydown_meta_enter_18_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onSendReply()); });
78
- i0.ɵɵtext(19, " ");
79
- i0.ɵɵelementEnd();
80
- i0.ɵɵelementStart(20, "div", 24)(21, "button", 25);
81
- i0.ɵɵlistener("click", function ThreadPanelComponent_Conditional_11_Template_button_click_21_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.onSendReply()); });
82
- i0.ɵɵelement(22, "i", 26);
83
- i0.ɵɵelementStart(23, "span");
84
- i0.ɵɵtext(24);
85
- i0.ɵɵelementEnd()()()();
86
- } if (rf & 2) {
87
- const ctx_r0 = i0.ɵɵnextContext();
88
- i0.ɵɵadvance(4);
89
- i0.ɵɵtextInterpolate(ctx_r0.getSenderName(ctx_r0.parentMessage));
90
- i0.ɵɵadvance(2);
91
- i0.ɵɵtextInterpolate(ctx_r0.getMessageTime(ctx_r0.parentMessage));
92
- i0.ɵɵadvance(2);
93
- i0.ɵɵtextInterpolate1(" ", ctx_r0.getMessageText(ctx_r0.parentMessage), " ");
94
- i0.ɵɵadvance(4);
95
- i0.ɵɵtextInterpolate(ctx_r0.replyCountText);
96
- i0.ɵɵadvance(2);
97
- i0.ɵɵconditional(ctx_r0.replies.length === 0 ? 14 : -1);
98
- i0.ɵɵadvance();
99
- i0.ɵɵrepeater(ctx_r0.replies);
100
- i0.ɵɵadvance(3);
101
- i0.ɵɵtwoWayProperty("ngModel", ctx_r0.replyText);
102
- i0.ɵɵproperty("disabled", ctx_r0.isSending);
103
- i0.ɵɵadvance(3);
104
- i0.ɵɵproperty("disabled", !ctx_r0.canSendReply);
105
- i0.ɵɵadvance(3);
106
- i0.ɵɵtextInterpolate(ctx_r0.isSending ? "Sending..." : "Reply");
107
- } }
108
- /**
109
- * Side panel component for displaying and managing threaded message replies
110
- * Shows parent message at top with all replies in chronological order
111
- */
112
- export class ThreadPanelComponent extends BaseAngularComponent {
113
- dataCache;
114
- cdRef;
115
- ParentMessageId;
116
- /** @deprecated Use {@link ParentMessageId}. */
117
- set parentMessageId(value) {
118
- this.ParentMessageId = value;
119
- }
120
- /** @deprecated Use {@link ParentMessageId}. */
121
- get parentMessageId() {
122
- return this.ParentMessageId;
123
- }
124
- ConversationId;
125
- /** @deprecated Use {@link ConversationId}. */
126
- set conversationId(value) {
127
- this.ConversationId = value;
128
- }
129
- /** @deprecated Use {@link ConversationId}. */
130
- get conversationId() {
131
- return this.ConversationId;
132
- }
133
- CurrentUser;
134
- /** @deprecated Use {@link CurrentUser}. */
135
- set currentUser(value) {
136
- this.CurrentUser = value;
137
- }
138
- /** @deprecated Use {@link CurrentUser}. */
139
- get currentUser() {
140
- return this.CurrentUser;
141
- }
142
- Closed = new EventEmitter();
143
- /**
144
- * @deprecated Use {@link Closed}.
145
- *
146
- * The same emitter under the old binding name, so a template still binding
147
- * (closed) keeps working. Must stay AFTER Closed: class fields
148
- * initialise in order, and the other way round this captures undefined.
149
- */
150
- closed = this.Closed;
151
- ReplyAdded = new EventEmitter();
152
- /**
153
- * @deprecated Use {@link ReplyAdded}.
154
- *
155
- * The same emitter under the old binding name, so a template still binding
156
- * (replyAdded) keeps working. Must stay AFTER ReplyAdded: class fields
157
- * initialise in order, and the other way round this captures undefined.
158
- */
159
- replyAdded = this.ReplyAdded;
160
- ParentMessage = null;
161
- /** @deprecated Use {@link ParentMessage}. */
162
- get parentMessage() {
163
- return this.ParentMessage;
164
- }
165
- /** @deprecated Use {@link ParentMessage}. */
166
- set parentMessage(value) {
167
- this.ParentMessage = value;
168
- }
169
- Replies = [];
170
- /** @deprecated Use {@link Replies}. */
171
- get replies() {
172
- return this.Replies;
173
- }
174
- /** @deprecated Use {@link Replies}. */
175
- set replies(value) {
176
- this.Replies = value;
177
- }
178
- ReplyText = '';
179
- /** @deprecated Use {@link ReplyText}. */
180
- get replyText() {
181
- return this.ReplyText;
182
- }
183
- /** @deprecated Use {@link ReplyText}. */
184
- set replyText(value) {
185
- this.ReplyText = value;
186
- }
187
- isLoading = false;
188
- IsSending = false;
189
- /** @deprecated Use {@link IsSending}. */
190
- get isSending() {
191
- return this.IsSending;
192
- }
193
- /** @deprecated Use {@link IsSending}. */
194
- set isSending(value) {
195
- this.IsSending = value;
196
- }
197
- errorMessage = '';
198
- destroy$ = new Subject();
199
- constructor(dataCache, cdRef) {
200
- super();
201
- this.dataCache = dataCache;
202
- this.cdRef = cdRef;
203
- }
204
- async ngOnInit() {
205
- this.dataCache.Provider = this.ProviderToUse;
206
- await this.loadThreadData();
207
- }
208
- ngOnDestroy() {
209
- this.destroy$.next();
210
- this.destroy$.complete();
211
- }
212
- /**
213
- * Loads the parent message and all replies
214
- */
215
- async loadThreadData() {
216
- this.isLoading = true;
217
- this.errorMessage = '';
218
- try {
219
- // Load parent message from cache
220
- const parent = await this.dataCache.getConversationDetail(this.ParentMessageId, this.CurrentUser);
221
- if (!parent) {
222
- this.errorMessage = 'Failed to load parent message';
223
- this.isLoading = false;
224
- return;
225
- }
226
- this.ParentMessage = parent;
227
- // Load all replies
228
- await this.loadReplies();
229
- }
230
- catch (error) {
231
- console.error('Error loading thread data:', error);
232
- this.errorMessage = 'Error loading thread. Please try again.';
233
- }
234
- finally {
235
- this.isLoading = false;
236
- this.cdRef.detectChanges();
237
- }
238
- }
239
- /**
240
- * Loads all replies for the parent message
241
- */
242
- async loadReplies() {
243
- try {
244
- const rv = RunView.FromMetadataProvider(this.ProviderToUse);
245
- const result = await rv.RunView({
246
- EntityName: 'MJ: Conversation Details',
247
- ExtraFilter: `ParentID='${this.ParentMessageId}'`,
248
- OrderBy: '__mj_CreatedAt ASC',
249
- ResultType: 'entity_object'
250
- }, this.CurrentUser);
251
- if (result.Success) {
252
- this.Replies = result.Results || [];
253
- }
254
- else {
255
- console.error('Failed to load replies:', result.ErrorMessage);
256
- this.errorMessage = 'Failed to load replies';
257
- }
258
- }
259
- catch (error) {
260
- console.error('Error loading replies:', error);
261
- this.errorMessage = 'Error loading replies';
262
- }
263
- }
264
- /**
265
- * Handles sending a new reply
266
- */
267
- async OnSendReply() {
268
- if (!this.CanSendReply)
269
- return;
270
- this.IsSending = true;
271
- this.errorMessage = '';
272
- try {
273
- const reply = await this.dataCache.createConversationDetail(this.CurrentUser);
274
- reply.ConversationID = this.ConversationId;
275
- reply.ParentID = this.ParentMessageId;
276
- reply.Message = this.ReplyText.trim();
277
- reply.Role = 'User';
278
- const saved = await reply.Save();
279
- if (saved) {
280
- // Add to local list
281
- this.Replies = [...this.Replies, reply];
282
- this.ReplyText = '';
283
- // Emit event to parent
284
- this.ReplyAdded.emit(reply);
285
- // Update parent message thread count
286
- if (this.ParentMessage) {
287
- this.ParentMessage.ThreadCount = (this.ParentMessage.ThreadCount || 0) + 1; // TODO: ThreadCount field doesn't exist on MJConversationDetailEntity yet
288
- }
289
- this.cdRef.detectChanges();
290
- }
291
- else {
292
- console.error('Failed to save reply:', reply.LatestResult?.Message);
293
- this.errorMessage = 'Failed to send reply. Please try again.';
294
- }
295
- }
296
- catch (error) {
297
- console.error('Error sending reply:', error);
298
- this.errorMessage = 'Error sending reply. Please try again.';
299
- }
300
- finally {
301
- this.IsSending = false;
302
- this.cdRef.detectChanges();
303
- }
304
- }
305
- /** @deprecated Use {@link OnSendReply}. */
306
- async onSendReply() {
307
- return this.OnSendReply();
308
- }
309
- /**
310
- * Handles closing the thread panel
311
- */
312
- OnClose() {
313
- this.Closed.emit();
314
- }
315
- /** @deprecated Use {@link OnClose}. */
316
- onClose() {
317
- return this.OnClose();
318
- }
319
- /**
320
- * Gets the display text for a message
321
- */
322
- GetMessageText(message) {
323
- return message.Message || '';
324
- }
325
- /** @deprecated Use {@link GetMessageText}. */
326
- getMessageText(message) {
327
- return this.GetMessageText(message);
328
- }
329
- /**
330
- * Gets the timestamp display for a message
331
- */
332
- GetMessageTime(message) {
333
- if (!message.__mj_CreatedAt)
334
- return '';
335
- const date = new Date(message.__mj_CreatedAt);
336
- const now = new Date();
337
- const diffMs = now.getTime() - date.getTime();
338
- const diffMins = Math.floor(diffMs / 60000);
339
- const diffHours = Math.floor(diffMs / 3600000);
340
- const diffDays = Math.floor(diffMs / 86400000);
341
- if (diffMins < 1)
342
- return 'Just now';
343
- if (diffMins < 60)
344
- return `${diffMins}m ago`;
345
- if (diffHours < 24)
346
- return `${diffHours}h ago`;
347
- if (diffDays < 7)
348
- return `${diffDays}d ago`;
349
- return date.toLocaleDateString();
350
- }
351
- /** @deprecated Use {@link GetMessageTime}. */
352
- getMessageTime(message) {
353
- return this.GetMessageTime(message);
354
- }
355
- /**
356
- * Gets the sender name for a message
357
- */
358
- GetSenderName(message) {
359
- if (message.Role === 'AI')
360
- return 'AI Assistant';
361
- return message.User || 'User';
362
- }
363
- /** @deprecated Use {@link GetSenderName}. */
364
- getSenderName(message) {
365
- return this.GetSenderName(message);
366
- }
367
- /**
368
- * Checks if current user can send reply
369
- */
370
- get CanSendReply() {
371
- return !this.IsSending && !this.isLoading && this.ReplyText.trim().length > 0;
372
- }
373
- /** @deprecated Use {@link CanSendReply}. */
374
- get canSendReply() {
375
- return this.CanSendReply;
376
- }
377
- /**
378
- * Gets the reply count text
379
- */
380
- get ReplyCountText() {
381
- const count = this.Replies.length;
382
- return count === 1 ? '1 reply' : `${count} replies`;
383
- }
384
- /** @deprecated Use {@link ReplyCountText}. */
385
- get replyCountText() {
386
- return this.ReplyCountText;
387
- }
388
- static ɵfac = function ThreadPanelComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || ThreadPanelComponent)(i0.ɵɵdirectiveInject(i1.DataCacheService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
389
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: ThreadPanelComponent, selectors: [["mj-thread-panel"]], inputs: { ParentMessageId: "ParentMessageId", parentMessageId: "parentMessageId", ConversationId: "ConversationId", conversationId: "conversationId", CurrentUser: "CurrentUser", currentUser: "currentUser" }, outputs: { Closed: "Closed", closed: "closed", ReplyAdded: "ReplyAdded", replyAdded: "replyAdded" }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 12, vars: 3, consts: [[1, "thread-panel-overlay", 3, "click"], [1, "thread-panel"], [1, "thread-header"], [1, "thread-title"], [1, "fa-solid", "fa-comments"], ["title", "Close thread", 1, "close-btn", 3, "click"], [1, "fa-solid", "fa-times"], [1, "thread-loading"], [1, "thread-error"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-exclamation-circle"], [1, "thread-content"], [1, "parent-message"], [1, "message-header"], [1, "message-sender"], [1, "message-time"], [1, "message-body"], [1, "reply-count"], [1, "fa-solid", "fa-reply"], [1, "replies-container"], [1, "no-replies"], [1, "reply-item", 3, "ai-reply"], [1, "reply-input-container"], ["placeholder", "Reply to thread...", "rows", "3", 1, "reply-input", 3, "ngModelChange", "keydown.control.enter", "keydown.meta.enter", "ngModel", "disabled"], [1, "reply-actions"], [1, "btn-send-reply", 3, "click", "disabled"], [1, "fa-solid", "fa-paper-plane"], [1, "fa-solid", "fa-message"], [1, "reply-item"], [1, "reply-header"], [1, "reply-sender"], [1, "reply-time"], [1, "reply-body"]], template: function ThreadPanelComponent_Template(rf, ctx) { if (rf & 1) {
390
- i0.ɵɵelementStart(0, "div", 0);
391
- i0.ɵɵlistener("click", function ThreadPanelComponent_Template_div_click_0_listener() { return ctx.onClose(); });
392
- i0.ɵɵelementEnd();
393
- i0.ɵɵelementStart(1, "div", 1)(2, "div", 2)(3, "div", 3);
394
- i0.ɵɵelement(4, "i", 4);
395
- i0.ɵɵelementStart(5, "span");
396
- i0.ɵɵtext(6, "Thread");
397
- i0.ɵɵelementEnd()();
398
- i0.ɵɵelementStart(7, "button", 5);
399
- i0.ɵɵlistener("click", function ThreadPanelComponent_Template_button_click_7_listener() { return ctx.onClose(); });
400
- i0.ɵɵelement(8, "i", 6);
401
- i0.ɵɵelementEnd()();
402
- i0.ɵɵconditionalCreate(9, ThreadPanelComponent_Conditional_9_Template, 4, 0, "div", 7);
403
- i0.ɵɵconditionalCreate(10, ThreadPanelComponent_Conditional_10_Template, 4, 1, "div", 8);
404
- i0.ɵɵconditionalCreate(11, ThreadPanelComponent_Conditional_11_Template, 25, 9);
405
- i0.ɵɵelementEnd();
406
- } if (rf & 2) {
407
- i0.ɵɵadvance(9);
408
- i0.ɵɵconditional(ctx.isLoading ? 9 : -1);
409
- i0.ɵɵadvance();
410
- i0.ɵɵconditional(ctx.errorMessage && !ctx.isLoading ? 10 : -1);
411
- i0.ɵɵadvance();
412
- i0.ɵɵconditional(!ctx.isLoading && !ctx.errorMessage && ctx.parentMessage ? 11 : -1);
413
- } }, dependencies: [i2.DefaultValueAccessor, i2.NgControlStatus, i2.NgModel], styles: ["\n.thread-panel-overlay[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 999;\n animation: _ngcontent-%COMP%_fadeIn 200ms ease;\n}\n\n@keyframes _ngcontent-%COMP%_fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n\n.thread-panel[_ngcontent-%COMP%] {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 450px;\n max-width: 90vw;\n background: var(--mj-bg-surface-card);\n box-shadow: -2px 0 8px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\n z-index: 1000;\n display: flex;\n flex-direction: column;\n animation: _ngcontent-%COMP%_slideIn 250ms ease;\n}\n\n@keyframes _ngcontent-%COMP%_slideIn {\n from {\n transform: translateX(100%);\n }\n to {\n transform: translateX(0);\n }\n}\n\n\n.thread-header[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n}\n\n.thread-title[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.thread-title[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n color: var(--mj-text-secondary);\n}\n\n.close-btn[_ngcontent-%COMP%] {\n padding: 6px;\n background: transparent;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 18px;\n transition: all 150ms ease;\n}\n\n.close-btn[_ngcontent-%COMP%]:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n\n.thread-loading[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 40px;\n color: var(--mj-text-secondary);\n}\n\n.thread-loading[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 24px;\n}\n\n\n.thread-error[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 16px 20px;\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-left: 3px solid var(--mj-status-error);\n color: var(--mj-status-error);\n margin: 16px 20px;\n border-radius: 4px;\n}\n\n\n.thread-content[_ngcontent-%COMP%] {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n}\n\n\n.parent-message[_ngcontent-%COMP%] {\n padding: 16px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n margin-bottom: 20px;\n}\n\n.message-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.message-sender[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n font-size: 14px;\n}\n\n.message-time[_ngcontent-%COMP%] {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.message-body[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n line-height: 1.6;\n white-space: pre-wrap;\n word-break: break-word;\n font-size: 14px;\n margin-bottom: 12px;\n}\n\n.reply-count[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding-top: 12px;\n border-top: 1px solid var(--mj-border-default);\n font-size: 13px;\n color: var(--mj-text-secondary);\n font-weight: 500;\n}\n\n.reply-count[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n.replies-container[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.no-replies[_ngcontent-%COMP%] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding: 40px 20px;\n color: var(--mj-text-muted);\n text-align: center;\n}\n\n.no-replies[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 32px;\n opacity: 0.5;\n}\n\n.no-replies[_ngcontent-%COMP%] span[_ngcontent-%COMP%] {\n font-size: 14px;\n}\n\n\n.reply-item[_ngcontent-%COMP%] {\n padding: 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n transition: all 150ms ease;\n}\n\n.reply-item[_ngcontent-%COMP%]:hover {\n border-color: var(--mj-border-strong);\n box-shadow: 0 1px 3px color-mix(in srgb, var(--mj-text-primary) 5%, transparent);\n}\n\n.reply-item.ai-reply[_ngcontent-%COMP%] {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 20%, var(--mj-bg-surface));\n}\n\n.reply-header[_ngcontent-%COMP%] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 6px;\n}\n\n.reply-sender[_ngcontent-%COMP%] {\n font-weight: 600;\n color: var(--mj-text-primary);\n font-size: 13px;\n}\n\n.reply-time[_ngcontent-%COMP%] {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.reply-body[_ngcontent-%COMP%] {\n color: var(--mj-text-primary);\n line-height: 1.5;\n white-space: pre-wrap;\n word-break: break-word;\n font-size: 13px;\n}\n\n\n.reply-input-container[_ngcontent-%COMP%] {\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.reply-input[_ngcontent-%COMP%] {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n resize: vertical;\n font-family: inherit;\n font-size: 14px;\n min-height: 60px;\n transition: all 150ms ease;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-primary);\n}\n\n.reply-input[_ngcontent-%COMP%]:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.reply-input[_ngcontent-%COMP%]:disabled {\n background: var(--mj-bg-surface-sunken);\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.reply-actions[_ngcontent-%COMP%] {\n display: flex;\n justify-content: flex-end;\n margin-top: 10px;\n}\n\n.btn-send-reply[_ngcontent-%COMP%] {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 6px;\n cursor: pointer;\n font-weight: 600;\n font-size: 13px;\n transition: all 150ms ease;\n}\n\n.btn-send-reply[_ngcontent-%COMP%]:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n transform: translateY(-1px);\n box-shadow: 0 2px 4px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n.btn-send-reply[_ngcontent-%COMP%]:disabled {\n background: var(--mj-border-default);\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.btn-send-reply[_ngcontent-%COMP%] i[_ngcontent-%COMP%] {\n font-size: 12px;\n}\n\n\n.thread-content[_ngcontent-%COMP%]::-webkit-scrollbar {\n width: 6px;\n}\n\n.thread-content[_ngcontent-%COMP%]::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-sunken);\n}\n\n.thread-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb {\n background: var(--mj-border-default);\n border-radius: 3px;\n}\n\n.thread-content[_ngcontent-%COMP%]::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-muted);\n}"] });
414
- }
415
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ThreadPanelComponent, [{
416
- type: Component,
417
- args: [{ standalone: false, selector: 'mj-thread-panel', template: "<div class=\"thread-panel-overlay\" (click)=\"onClose()\"></div>\n\n<div class=\"thread-panel\">\n <div class=\"thread-header\">\n <div class=\"thread-title\">\n <i class=\"fa-solid fa-comments\"></i>\n <span>Thread</span>\n </div>\n <button class=\"close-btn\" (click)=\"onClose()\" title=\"Close thread\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n @if (isLoading) {\n <div class=\"thread-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading thread...</span>\n </div>\n }\n\n @if (errorMessage && !isLoading) {\n <div class=\"thread-error\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <span>{{ errorMessage }}</span>\n </div>\n }\n\n @if (!isLoading && !errorMessage && parentMessage) {\n <div class=\"thread-content\">\n <!-- Parent Message -->\n <div class=\"parent-message\">\n <div class=\"message-header\">\n <span class=\"message-sender\">{{ getSenderName(parentMessage) }}</span>\n <span class=\"message-time\">{{ getMessageTime(parentMessage) }}</span>\n </div>\n <div class=\"message-body\">\n {{ getMessageText(parentMessage) }}\n </div>\n <div class=\"reply-count\">\n <i class=\"fa-solid fa-reply\"></i>\n <span>{{ replyCountText }}</span>\n </div>\n </div>\n\n <!-- Replies List -->\n <div class=\"replies-container\">\n @if (replies.length === 0) {\n <div class=\"no-replies\">\n <i class=\"fa-solid fa-message\"></i>\n <span>No replies yet. Be the first to reply!</span>\n </div>\n }\n\n @for (reply of replies; track reply.ID) {\n <div class=\"reply-item\" [class.ai-reply]=\"reply.Role === 'AI'\">\n <div class=\"reply-header\">\n <span class=\"reply-sender\">{{ getSenderName(reply) }}</span>\n <span class=\"reply-time\">{{ getMessageTime(reply) }}</span>\n </div>\n <div class=\"reply-body\">\n {{ getMessageText(reply) }}\n </div>\n </div>\n }\n </div>\n </div>\n\n <!-- Reply Input -->\n <div class=\"reply-input-container\">\n <textarea\n class=\"reply-input\"\n [(ngModel)]=\"replyText\"\n [disabled]=\"isSending\"\n placeholder=\"Reply to thread...\"\n rows=\"3\"\n (keydown.control.enter)=\"onSendReply()\"\n (keydown.meta.enter)=\"onSendReply()\">\n </textarea>\n <div class=\"reply-actions\">\n <button\n class=\"btn-send-reply\"\n [disabled]=\"!canSendReply\"\n (click)=\"onSendReply()\">\n <i class=\"fa-solid fa-paper-plane\"></i>\n <span>{{ isSending ? 'Sending...' : 'Reply' }}</span>\n </button>\n </div>\n </div>\n }\n</div>\n", styles: ["/* Thread Panel Overlay */\n.thread-panel-overlay {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: var(--mj-bg-overlay);\n z-index: 999;\n animation: fadeIn 200ms ease;\n}\n\n@keyframes fadeIn {\n from { opacity: 0; }\n to { opacity: 1; }\n}\n\n/* Thread Panel Container */\n.thread-panel {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n width: 450px;\n max-width: 90vw;\n background: var(--mj-bg-surface-card);\n box-shadow: -2px 0 8px color-mix(in srgb, var(--mj-text-primary) 15%, transparent);\n z-index: 1000;\n display: flex;\n flex-direction: column;\n animation: slideIn 250ms ease;\n}\n\n@keyframes slideIn {\n from {\n transform: translateX(100%);\n }\n to {\n transform: translateX(0);\n }\n}\n\n/* Header */\n.thread-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 16px 20px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-sunken);\n}\n\n.thread-title {\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 16px;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.thread-title i {\n color: var(--mj-text-secondary);\n}\n\n.close-btn {\n padding: 6px;\n background: transparent;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n color: var(--mj-text-secondary);\n font-size: 18px;\n transition: all 150ms ease;\n}\n\n.close-btn:hover {\n background: var(--mj-border-default);\n color: var(--mj-text-primary);\n}\n\n/* Loading State */\n.thread-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 40px;\n color: var(--mj-text-secondary);\n}\n\n.thread-loading i {\n font-size: 24px;\n}\n\n/* Error State */\n.thread-error {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 16px 20px;\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-left: 3px solid var(--mj-status-error);\n color: var(--mj-status-error);\n margin: 16px 20px;\n border-radius: 4px;\n}\n\n/* Content Container */\n.thread-content {\n flex: 1;\n overflow-y: auto;\n padding: 20px;\n}\n\n/* Parent Message */\n.parent-message {\n padding: 16px;\n background: var(--mj-bg-surface-sunken);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n margin-bottom: 20px;\n}\n\n.message-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 8px;\n}\n\n.message-sender {\n font-weight: 600;\n color: var(--mj-text-primary);\n font-size: 14px;\n}\n\n.message-time {\n font-size: 12px;\n color: var(--mj-text-secondary);\n}\n\n.message-body {\n color: var(--mj-text-primary);\n line-height: 1.6;\n white-space: pre-wrap;\n word-break: break-word;\n font-size: 14px;\n margin-bottom: 12px;\n}\n\n.reply-count {\n display: flex;\n align-items: center;\n gap: 6px;\n padding-top: 12px;\n border-top: 1px solid var(--mj-border-default);\n font-size: 13px;\n color: var(--mj-text-secondary);\n font-weight: 500;\n}\n\n.reply-count i {\n font-size: 12px;\n}\n\n/* Replies Container */\n.replies-container {\n display: flex;\n flex-direction: column;\n gap: 12px;\n}\n\n.no-replies {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding: 40px 20px;\n color: var(--mj-text-muted);\n text-align: center;\n}\n\n.no-replies i {\n font-size: 32px;\n opacity: 0.5;\n}\n\n.no-replies span {\n font-size: 14px;\n}\n\n/* Reply Item */\n.reply-item {\n padding: 12px;\n background: var(--mj-bg-surface-card);\n border: 1px solid var(--mj-border-default);\n border-radius: 8px;\n transition: all 150ms ease;\n}\n\n.reply-item:hover {\n border-color: var(--mj-border-strong);\n box-shadow: 0 1px 3px color-mix(in srgb, var(--mj-text-primary) 5%, transparent);\n}\n\n.reply-item.ai-reply {\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n border-color: color-mix(in srgb, var(--mj-brand-primary) 20%, var(--mj-bg-surface));\n}\n\n.reply-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 6px;\n}\n\n.reply-sender {\n font-weight: 600;\n color: var(--mj-text-primary);\n font-size: 13px;\n}\n\n.reply-time {\n font-size: 11px;\n color: var(--mj-text-muted);\n}\n\n.reply-body {\n color: var(--mj-text-primary);\n line-height: 1.5;\n white-space: pre-wrap;\n word-break: break-word;\n font-size: 13px;\n}\n\n/* Reply Input */\n.reply-input-container {\n padding: 16px 20px;\n border-top: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface-card);\n}\n\n.reply-input {\n width: 100%;\n padding: 10px 12px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n resize: vertical;\n font-family: inherit;\n font-size: 14px;\n min-height: 60px;\n transition: all 150ms ease;\n background: var(--mj-bg-surface-card);\n color: var(--mj-text-primary);\n}\n\n.reply-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 10%, transparent);\n}\n\n.reply-input:disabled {\n background: var(--mj-bg-surface-sunken);\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.reply-actions {\n display: flex;\n justify-content: flex-end;\n margin-top: 10px;\n}\n\n.btn-send-reply {\n display: flex;\n align-items: center;\n gap: 6px;\n padding: 8px 16px;\n background: var(--mj-brand-primary);\n color: var(--mj-text-inverse);\n border: none;\n border-radius: 6px;\n cursor: pointer;\n font-weight: 600;\n font-size: 13px;\n transition: all 150ms ease;\n}\n\n.btn-send-reply:hover:not(:disabled) {\n background: var(--mj-brand-primary-hover);\n transform: translateY(-1px);\n box-shadow: 0 2px 4px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n}\n\n.btn-send-reply:disabled {\n background: var(--mj-border-default);\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.btn-send-reply i {\n font-size: 12px;\n}\n\n/* Scrollbar Styling */\n.thread-content::-webkit-scrollbar {\n width: 6px;\n}\n\n.thread-content::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-sunken);\n}\n\n.thread-content::-webkit-scrollbar-thumb {\n background: var(--mj-border-default);\n border-radius: 3px;\n}\n\n.thread-content::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-muted);\n}\n"] }]
418
- }], () => [{ type: i1.DataCacheService }, { type: i0.ChangeDetectorRef }], { ParentMessageId: [{
419
- type: Input
420
- }], parentMessageId: [{
421
- type: Input
422
- }], ConversationId: [{
423
- type: Input
424
- }], conversationId: [{
425
- type: Input
426
- }], CurrentUser: [{
427
- type: Input
428
- }], currentUser: [{
429
- type: Input
430
- }], Closed: [{
431
- type: Output
432
- }], closed: [{
433
- type: Output
434
- }], ReplyAdded: [{
435
- type: Output
436
- }], replyAdded: [{
437
- type: Output
438
- }] }); })();
439
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(ThreadPanelComponent, { className: "ThreadPanelComponent", filePath: "src/lib/components/thread/thread-panel.component.ts", lineNumber: 19 }); })();
440
- //# sourceMappingURL=thread-panel.component.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"thread-panel.component.js","sourceRoot":"","sources":["../../../../src/lib/components/thread/thread-panel.component.ts","../../../../src/lib/components/thread/thread-panel.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nimport { MJConversationDetailEntity } from '@memberjunction/core-entities';\nimport { UserInfo, RunView, Metadata } from '@memberjunction/core';\nimport { DataCacheService } from '../../services/data-cache.service';\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\n\n/**\n * Side panel component for displaying and managing threaded message replies\n * Shows parent message at top with all replies in chronological order\n */\n@Component({\n standalone: false,\n selector: 'mj-thread-panel',\n templateUrl: './thread-panel.component.html',\n styleUrls: ['./thread-panel.component.css']\n})\nexport class ThreadPanelComponent extends BaseAngularComponent implements OnInit, OnDestroy {\n @Input() ParentMessageId!: string;\n\n /** @deprecated Use {@link ParentMessageId}. */\n @Input() set parentMessageId(value: string) {\n this.ParentMessageId = value;\n }\n /** @deprecated Use {@link ParentMessageId}. */\n get parentMessageId(): string {\n return this.ParentMessageId;\n }\n @Input() ConversationId!: string;\n\n /** @deprecated Use {@link ConversationId}. */\n @Input() set conversationId(value: string) {\n this.ConversationId = value;\n }\n /** @deprecated Use {@link ConversationId}. */\n get conversationId(): string {\n return this.ConversationId;\n }\n @Input() CurrentUser!: UserInfo;\n\n /** @deprecated Use {@link CurrentUser}. */\n @Input() set currentUser(value: UserInfo) {\n this.CurrentUser = value;\n }\n /** @deprecated Use {@link CurrentUser}. */\n get currentUser(): UserInfo {\n return this.CurrentUser;\n }\n\n @Output() Closed = new EventEmitter<void>();\n\n /**\n * @deprecated Use {@link Closed}.\n *\n * The same emitter under the old binding name, so a template still binding\n * (closed) keeps working. Must stay AFTER Closed: class fields\n * initialise in order, and the other way round this captures undefined.\n */\n @Output() closed = this.Closed;\n @Output() ReplyAdded = new EventEmitter<MJConversationDetailEntity>();\n\n /**\n * @deprecated Use {@link ReplyAdded}.\n *\n * The same emitter under the old binding name, so a template still binding\n * (replyAdded) keeps working. Must stay AFTER ReplyAdded: class fields\n * initialise in order, and the other way round this captures undefined.\n */\n @Output() replyAdded = this.ReplyAdded;\n\n public ParentMessage: MJConversationDetailEntity | null = null;\n\n /** @deprecated Use {@link ParentMessage}. */\n public get parentMessage(): MJConversationDetailEntity | null {\n return this.ParentMessage;\n }\n /** @deprecated Use {@link ParentMessage}. */\n public set parentMessage(value: MJConversationDetailEntity | null) {\n this.ParentMessage = value;\n }\n public Replies: MJConversationDetailEntity[] = [];\n\n /** @deprecated Use {@link Replies}. */\n public get replies(): MJConversationDetailEntity[] {\n return this.Replies;\n }\n /** @deprecated Use {@link Replies}. */\n public set replies(value: MJConversationDetailEntity[]) {\n this.Replies = value;\n }\n public ReplyText: string = '';\n\n /** @deprecated Use {@link ReplyText}. */\n public get replyText(): string {\n return this.ReplyText;\n }\n /** @deprecated Use {@link ReplyText}. */\n public set replyText(value: string) {\n this.ReplyText = value;\n }\n public isLoading: boolean = false;\n public IsSending: boolean = false;\n\n /** @deprecated Use {@link IsSending}. */\n public get isSending(): boolean {\n return this.IsSending;\n }\n /** @deprecated Use {@link IsSending}. */\n public set isSending(value: boolean) {\n this.IsSending = value;\n }\n public errorMessage: string = '';\n\n private destroy$ = new Subject<void>();\n\n constructor(\n private dataCache: DataCacheService,\n private cdRef: ChangeDetectorRef\n ) {\n super();}\n\n async ngOnInit() {\n this.dataCache.Provider = this.ProviderToUse;\n await this.loadThreadData();\n }\n\n ngOnDestroy() {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n /**\n * Loads the parent message and all replies\n */\n private async loadThreadData(): Promise<void> {\n this.isLoading = true;\n this.errorMessage = '';\n\n try {\n // Load parent message from cache\n const parent = await this.dataCache.getConversationDetail(this.ParentMessageId, this.CurrentUser);\n\n if (!parent) {\n this.errorMessage = 'Failed to load parent message';\n this.isLoading = false;\n return;\n }\n\n this.ParentMessage = parent;\n\n // Load all replies\n await this.loadReplies();\n } catch (error) {\n console.error('Error loading thread data:', error);\n this.errorMessage = 'Error loading thread. Please try again.';\n } finally {\n this.isLoading = false;\n this.cdRef.detectChanges();\n }\n }\n\n /**\n * Loads all replies for the parent message\n */\n private async loadReplies(): Promise<void> {\n try {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJConversationDetailEntity>(\n {\n EntityName: 'MJ: Conversation Details',\n ExtraFilter: `ParentID='${this.ParentMessageId}'`,\n OrderBy: '__mj_CreatedAt ASC',\n ResultType: 'entity_object'\n },\n this.CurrentUser\n );\n\n if (result.Success) {\n this.Replies = result.Results || [];\n } else {\n console.error('Failed to load replies:', result.ErrorMessage);\n this.errorMessage = 'Failed to load replies';\n }\n } catch (error) {\n console.error('Error loading replies:', error);\n this.errorMessage = 'Error loading replies';\n }\n }\n\n /**\n * Handles sending a new reply\n */\n async OnSendReply(): Promise<void> {\n if (!this.CanSendReply) return;\n\n this.IsSending = true;\n this.errorMessage = '';\n\n try {\n const reply = await this.dataCache.createConversationDetail(this.CurrentUser);\n\n reply.ConversationID = this.ConversationId;\n reply.ParentID = this.ParentMessageId;\n reply.Message = this.ReplyText.trim();\n reply.Role = 'User';\n\n const saved = await reply.Save();\n\n if (saved) {\n // Add to local list\n this.Replies = [...this.Replies, reply];\n this.ReplyText = '';\n\n // Emit event to parent\n this.ReplyAdded.emit(reply);\n\n // Update parent message thread count\n if (this.ParentMessage) {\n (this.ParentMessage as any).ThreadCount = ((this.ParentMessage as any).ThreadCount || 0) + 1; // TODO: ThreadCount field doesn't exist on MJConversationDetailEntity yet\n }\n\n this.cdRef.detectChanges();\n } else {\n console.error('Failed to save reply:', reply.LatestResult?.Message);\n this.errorMessage = 'Failed to send reply. Please try again.';\n }\n } catch (error) {\n console.error('Error sending reply:', error);\n this.errorMessage = 'Error sending reply. Please try again.';\n } finally {\n this.IsSending = false;\n this.cdRef.detectChanges();\n }\n }\n\n /** @deprecated Use {@link OnSendReply}. */\n async onSendReply(): Promise<void> {\n return this.OnSendReply();\n }\n\n /**\n * Handles closing the thread panel\n */\n OnClose(): void {\n this.Closed.emit();\n }\n\n /** @deprecated Use {@link OnClose}. */\n onClose(): void {\n return this.OnClose();\n }\n\n /**\n * Gets the display text for a message\n */\n GetMessageText(message: MJConversationDetailEntity): string {\n return message.Message || '';\n }\n\n /** @deprecated Use {@link GetMessageText}. */\n getMessageText(message: MJConversationDetailEntity): string {\n return this.GetMessageText(message);\n }\n\n /**\n * Gets the timestamp display for a message\n */\n GetMessageTime(message: MJConversationDetailEntity): string {\n if (!message.__mj_CreatedAt) return '';\n\n const date = new Date(message.__mj_CreatedAt);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMs / 3600000);\n const diffDays = Math.floor(diffMs / 86400000);\n\n if (diffMins < 1) return 'Just now';\n if (diffMins < 60) return `${diffMins}m ago`;\n if (diffHours < 24) return `${diffHours}h ago`;\n if (diffDays < 7) return `${diffDays}d ago`;\n\n return date.toLocaleDateString();\n }\n\n /** @deprecated Use {@link GetMessageTime}. */\n getMessageTime(message: MJConversationDetailEntity): string {\n return this.GetMessageTime(message);\n }\n\n /**\n * Gets the sender name for a message\n */\n GetSenderName(message: MJConversationDetailEntity): string {\n if (message.Role === 'AI') return 'AI Assistant';\n return message.User || 'User';\n }\n\n /** @deprecated Use {@link GetSenderName}. */\n getSenderName(message: MJConversationDetailEntity): string {\n return this.GetSenderName(message);\n }\n\n /**\n * Checks if current user can send reply\n */\n get CanSendReply(): boolean {\n return !this.IsSending && !this.isLoading && this.ReplyText.trim().length > 0;\n }\n\n /** @deprecated Use {@link CanSendReply}. */\n get canSendReply(): boolean {\n return this.CanSendReply;\n }\n\n /**\n * Gets the reply count text\n */\n get ReplyCountText(): string {\n const count = this.Replies.length;\n return count === 1 ? '1 reply' : `${count} replies`;\n }\n\n /** @deprecated Use {@link ReplyCountText}. */\n get replyCountText(): string {\n return this.ReplyCountText;\n }\n}\n","<div class=\"thread-panel-overlay\" (click)=\"onClose()\"></div>\n\n<div class=\"thread-panel\">\n <div class=\"thread-header\">\n <div class=\"thread-title\">\n <i class=\"fa-solid fa-comments\"></i>\n <span>Thread</span>\n </div>\n <button class=\"close-btn\" (click)=\"onClose()\" title=\"Close thread\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n\n @if (isLoading) {\n <div class=\"thread-loading\">\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n <span>Loading thread...</span>\n </div>\n }\n\n @if (errorMessage && !isLoading) {\n <div class=\"thread-error\">\n <i class=\"fa-solid fa-exclamation-circle\"></i>\n <span>{{ errorMessage }}</span>\n </div>\n }\n\n @if (!isLoading && !errorMessage && parentMessage) {\n <div class=\"thread-content\">\n <!-- Parent Message -->\n <div class=\"parent-message\">\n <div class=\"message-header\">\n <span class=\"message-sender\">{{ getSenderName(parentMessage) }}</span>\n <span class=\"message-time\">{{ getMessageTime(parentMessage) }}</span>\n </div>\n <div class=\"message-body\">\n {{ getMessageText(parentMessage) }}\n </div>\n <div class=\"reply-count\">\n <i class=\"fa-solid fa-reply\"></i>\n <span>{{ replyCountText }}</span>\n </div>\n </div>\n\n <!-- Replies List -->\n <div class=\"replies-container\">\n @if (replies.length === 0) {\n <div class=\"no-replies\">\n <i class=\"fa-solid fa-message\"></i>\n <span>No replies yet. Be the first to reply!</span>\n </div>\n }\n\n @for (reply of replies; track reply.ID) {\n <div class=\"reply-item\" [class.ai-reply]=\"reply.Role === 'AI'\">\n <div class=\"reply-header\">\n <span class=\"reply-sender\">{{ getSenderName(reply) }}</span>\n <span class=\"reply-time\">{{ getMessageTime(reply) }}</span>\n </div>\n <div class=\"reply-body\">\n {{ getMessageText(reply) }}\n </div>\n </div>\n }\n </div>\n </div>\n\n <!-- Reply Input -->\n <div class=\"reply-input-container\">\n <textarea\n class=\"reply-input\"\n [(ngModel)]=\"replyText\"\n [disabled]=\"isSending\"\n placeholder=\"Reply to thread...\"\n rows=\"3\"\n (keydown.control.enter)=\"onSendReply()\"\n (keydown.meta.enter)=\"onSendReply()\">\n </textarea>\n <div class=\"reply-actions\">\n <button\n class=\"btn-send-reply\"\n [disabled]=\"!canSendReply\"\n (click)=\"onSendReply()\">\n <i class=\"fa-solid fa-paper-plane\"></i>\n <span>{{ isSending ? 'Sending...' : 'Reply' }}</span>\n </button>\n </div>\n </div>\n }\n</div>\n"]}
@@ -1,79 +0,0 @@
1
- /**
2
- * @fileoverview Pure, browser-and-node-safe helpers for the CLIENT-DIRECT realtime recorder:
3
- * encoding accumulated Float32 PCM into a seekable 16-bit PCM **WAV** container and computing a
4
- * bounded, downsampled waveform **peak** array at capture time.
5
- *
6
- * These functions are deliberately free of any browser API (`AudioContext`, `Blob`, …) so they can
7
- * be unit-tested in a plain Node environment. {@link RealtimeAudioRecorder} owns the live audio
8
- * graph and feeds the captured samples here.
9
- *
10
- * Why WAV (PCM) over webm/opus: a RIFF/WAVE header carries the exact duration and maps a byte
11
- * offset linearly to a time offset, so HTTP-range seeking is exact (no client-side duration nudge),
12
- * and peak extraction is trivial. The tradeoff is size — PCM WAV is larger than opus — which is
13
- * acceptable for these short session recordings.
14
- *
15
- * @module @memberjunction/ng-conversations/realtime-pcm-wav
16
- */
17
- /** Canonical WAV/PCM header size in bytes (RIFF + fmt + data chunk headers). */
18
- export declare const WAV_HEADER_BYTES = 44;
19
- /**
20
- * Encodes mono Float32 PCM samples as a canonical single-chunk 16-bit PCM WAV (RIFF/WAVE).
21
- * The returned `ArrayBuffer` is `WAV_HEADER_BYTES + samples.length * 2` bytes — a proper
22
- * 44-byte header followed by little-endian PCM16 data, so it is seekable and self-describing.
23
- *
24
- * @param samples Mono Float32 PCM in `[-1, 1]` (downmixed by the caller).
25
- * @param sampleRate Sample rate in Hz (from the capturing `AudioContext`).
26
- * @returns A standalone `ArrayBuffer` containing the full WAV file.
27
- */
28
- export declare function EncodePcm16Wav(samples: Float32Array, sampleRate: number): ArrayBuffer;
29
- /** @deprecated Use {@link EncodePcm16Wav}. */
30
- export declare function encodePcm16Wav(samples: Float32Array, sampleRate: number): ArrayBuffer;
31
- /**
32
- * A bounded, streaming waveform-peak accumulator. It maintains a fixed number of buckets
33
- * (`targetBuckets`) of max-absolute amplitude across the WHOLE recording regardless of length:
34
- * once every bucket has absorbed `samplesPerBucket` samples, the buckets are halved (pairwise
35
- * max-merged) and the per-bucket capacity doubles — so memory + cost stay O(targetBuckets) for an
36
- * arbitrarily long call. {@link Normalize} returns the final 0..1 peaks.
37
- */
38
- export declare class PeakAccumulator {
39
- /** Target (max) number of buckets in the produced peak array. */
40
- private readonly targetBuckets;
41
- /** Current max-abs amplitude per bucket (length grows up to `2 * targetBuckets` before folding). */
42
- private buckets;
43
- /** How many samples each bucket currently absorbs before a new bucket opens. */
44
- private samplesPerBucket;
45
- /** Samples absorbed into the current (last) bucket so far. */
46
- private samplesInCurrent;
47
- /**
48
- * @param targetBuckets Desired bucket count (waveform resolution). Clamped to >= 1.
49
- * ~600 gives a smooth overview waveform at trivial cost.
50
- */
51
- constructor(targetBuckets?: number);
52
- /** Number of buckets currently held (for tests/inspection). */
53
- get BucketCount(): number;
54
- /** Absorbs a block of Float32 PCM samples, updating the running per-bucket max-abs. */
55
- Push(samples: Float32Array): void;
56
- /** Absorbs one sample into the current bucket, opening/folding buckets as capacity is reached. */
57
- private pushSample;
58
- /** Pairwise max-merges adjacent buckets, halving the count and doubling per-bucket capacity. */
59
- private fold;
60
- /**
61
- * Produces the final normalized peak array (each value 0..1, divided by the global max).
62
- * Trailing empty buckets are trimmed; an all-silent / empty recording yields `[]`.
63
- */
64
- Normalize(): number[];
65
- }
66
- /**
67
- * One-shot peak downsampling of a complete Float32 PCM buffer into `targetBuckets` normalized
68
- * max-abs peaks (0..1). The streaming {@link PeakAccumulator} is the production path; this is the
69
- * direct, allocation-light equivalent used where the whole buffer is already in hand (and in tests).
70
- *
71
- * @param samples The full mono Float32 PCM buffer.
72
- * @param targetBuckets Desired bucket count (clamped to >= 1). Buckets beyond the sample count are
73
- * not produced — a short buffer yields at most `samples.length` peaks.
74
- * @returns Normalized peaks; `[]` for an empty or all-silent buffer.
75
- */
76
- export declare function DownsamplePeaks(samples: Float32Array, targetBuckets?: number): number[];
77
- /** @deprecated Use {@link DownsamplePeaks}. */
78
- export declare function downsamplePeaks(samples: Float32Array, targetBuckets?: number): number[];
79
- //# sourceMappingURL=realtime-pcm-wav.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"realtime-pcm-wav.d.ts","sourceRoot":"","sources":["../../../src/lib/services/realtime-pcm-wav.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAMH,gFAAgF;AAChF,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAcnC;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,CAkCrF;AAED,8CAA8C;AAC9C,wBAAgB,cAAc,CAAC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,CAErF;AASD;;;;;;GAMG;AACH,qBAAa,eAAe;IACxB,iEAAiE;IACjE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,oGAAoG;IACpG,OAAO,CAAC,OAAO,CAAgB;IAC/B,gFAAgF;IAChF,OAAO,CAAC,gBAAgB,CAAK;IAC7B,8DAA8D;IAC9D,OAAO,CAAC,gBAAgB,CAAK;IAE7B;;;OAGG;gBACS,aAAa,SAAM;IAI/B,+DAA+D;IAC/D,IAAW,WAAW,IAAI,MAAM,CAE/B;IAED,uFAAuF;IAChF,IAAI,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAMxC,kGAAkG;IAClG,OAAO,CAAC,UAAU;IAsBlB,gGAAgG;IAChG,OAAO,CAAC,IAAI;IAYZ;;;OAGG;IACI,SAAS,IAAI,MAAM,EAAE;CAgB/B;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,EAAE,aAAa,SAAM,GAAG,MAAM,EAAE,CA4BpF;AAED,+CAA+C;AAC/C,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,EAAE,aAAa,SAAM,GAAG,MAAM,EAAE,CAEpF"}