@signalcore/ui 0.1.0 → 1.0.0-beta.1

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 (611) hide show
  1. package/README.md +896 -513
  2. package/dist/AgentAbout.d.ts +186 -0
  3. package/dist/AgentAbout.js +1020 -0
  4. package/dist/AgentAbout.js.map +1 -0
  5. package/dist/AgentCard.d.ts +49 -0
  6. package/dist/AgentCard.js +77 -0
  7. package/dist/AgentCard.js.map +1 -0
  8. package/dist/AgentChat.d.ts +233 -0
  9. package/dist/AgentChat.js +1127 -0
  10. package/dist/AgentChat.js.map +1 -0
  11. package/dist/AgentSpace.d.ts +112 -0
  12. package/dist/AgentSpace.js +339 -0
  13. package/dist/AgentSpace.js.map +1 -0
  14. package/dist/AgentTasks.d.ts +48 -0
  15. package/dist/AgentTasks.js +120 -0
  16. package/dist/AgentTasks.js.map +1 -0
  17. package/dist/BrowserView.d.ts +52 -0
  18. package/dist/BrowserView.js +328 -0
  19. package/dist/BrowserView.js.map +1 -0
  20. package/dist/FileView.d.ts +63 -0
  21. package/dist/FileView.js +449 -0
  22. package/dist/FileView.js.map +1 -0
  23. package/dist/Modes.d.ts +13 -0
  24. package/dist/Modes.js +75 -0
  25. package/dist/Modes.js.map +1 -0
  26. package/dist/VoiceCall.d.ts +91 -0
  27. package/dist/VoiceCall.js +302 -0
  28. package/dist/VoiceCall.js.map +1 -0
  29. package/dist/about.d.ts +212 -0
  30. package/dist/about.js +136 -0
  31. package/dist/about.js.map +1 -0
  32. package/dist/agentIcons.d.ts +33 -0
  33. package/dist/agentIcons.js +36 -0
  34. package/dist/agentIcons.js.map +1 -0
  35. package/dist/automation/Automation.d.ts +35 -0
  36. package/dist/automation/Automation.js +268 -0
  37. package/dist/automation/Automation.js.map +1 -0
  38. package/dist/automation/RunView.d.ts +25 -0
  39. package/dist/automation/RunView.js +187 -0
  40. package/dist/automation/RunView.js.map +1 -0
  41. package/dist/automation/cron.d.ts +41 -0
  42. package/dist/automation/cron.js +169 -0
  43. package/dist/automation/cron.js.map +1 -0
  44. package/dist/automation/marks.js +121 -0
  45. package/dist/automation/marks.js.map +1 -0
  46. package/dist/automation/messages.d.ts +113 -0
  47. package/dist/automation/messages.js +113 -0
  48. package/dist/automation/messages.js.map +1 -0
  49. package/dist/automation/record.d.ts +47 -0
  50. package/dist/automation/record.js +177 -0
  51. package/dist/automation/record.js.map +1 -0
  52. package/dist/automation/types.d.ts +143 -0
  53. package/dist/automation/when.d.ts +36 -0
  54. package/dist/automation/when.js +168 -0
  55. package/dist/automation/when.js.map +1 -0
  56. package/dist/blocks.d.ts +185 -0
  57. package/dist/browser.js +292 -0
  58. package/dist/browser.js.map +1 -0
  59. package/dist/call.d.ts +89 -0
  60. package/dist/call.js +218 -0
  61. package/dist/call.js.map +1 -0
  62. package/dist/channelParts.js +26 -0
  63. package/dist/channelParts.js.map +1 -0
  64. package/dist/classes.js +8 -3
  65. package/dist/classes.js.map +1 -0
  66. package/dist/client.d.ts +146 -54
  67. package/dist/client.js +204 -1
  68. package/dist/client.js.map +1 -0
  69. package/dist/conversationFiles.js +46 -0
  70. package/dist/conversationFiles.js.map +1 -0
  71. package/dist/credentials.d.ts +45 -0
  72. package/dist/credentials.js +98 -0
  73. package/dist/credentials.js.map +1 -0
  74. package/dist/dev.js +17 -0
  75. package/dist/dev.js.map +1 -0
  76. package/dist/es.d.ts +17 -0
  77. package/dist/es.js +382 -0
  78. package/dist/es.js.map +1 -0
  79. package/dist/files.d.ts +21 -0
  80. package/dist/files.js +214 -0
  81. package/dist/files.js.map +1 -0
  82. package/dist/frames.d.ts +115 -0
  83. package/dist/frames.js +219 -0
  84. package/dist/frames.js.map +1 -0
  85. package/dist/icons.js +29 -0
  86. package/dist/icons.js.map +1 -0
  87. package/dist/index.d.ts +63 -60
  88. package/dist/index.js +59 -45
  89. package/dist/kit/AudioPlayer.d.ts +20 -0
  90. package/dist/kit/AudioPlayer.js +116 -0
  91. package/dist/kit/AudioPlayer.js.map +1 -0
  92. package/dist/kit/Button.d.ts +29 -0
  93. package/dist/kit/Button.js +59 -0
  94. package/dist/kit/Button.js.map +1 -0
  95. package/dist/kit/Card.d.ts +16 -0
  96. package/dist/kit/Card.js +36 -0
  97. package/dist/kit/Card.js.map +1 -0
  98. package/dist/kit/Chart.js +152 -0
  99. package/dist/kit/Chart.js.map +1 -0
  100. package/dist/kit/Choices.d.ts +21 -0
  101. package/dist/kit/Choices.js +99 -0
  102. package/dist/kit/Choices.js.map +1 -0
  103. package/dist/kit/Combobox.d.ts +26 -0
  104. package/dist/kit/Combobox.js +190 -0
  105. package/dist/kit/Combobox.js.map +1 -0
  106. package/dist/kit/DateField.d.ts +17 -0
  107. package/dist/kit/DateField.js +133 -0
  108. package/dist/kit/DateField.js.map +1 -0
  109. package/dist/kit/Field.d.ts +40 -0
  110. package/dist/kit/Field.js +98 -0
  111. package/dist/kit/Field.js.map +1 -0
  112. package/dist/kit/FileField.d.ts +113 -0
  113. package/dist/kit/FileField.js +341 -0
  114. package/dist/kit/FileField.js.map +1 -0
  115. package/dist/kit/FileMark.d.ts +15 -0
  116. package/dist/kit/FileMark.js +39 -0
  117. package/dist/kit/FileMark.js.map +1 -0
  118. package/dist/kit/Inputs.d.ts +59 -0
  119. package/dist/kit/Inputs.js +205 -0
  120. package/dist/kit/Inputs.js.map +1 -0
  121. package/dist/kit/List.d.ts +47 -0
  122. package/dist/kit/List.js +85 -0
  123. package/dist/kit/List.js.map +1 -0
  124. package/dist/kit/Mark.d.ts +30 -0
  125. package/dist/kit/Mark.js +27 -0
  126. package/dist/kit/Mark.js.map +1 -0
  127. package/dist/kit/MarkStack.d.ts +15 -0
  128. package/dist/kit/MarkStack.js +26 -0
  129. package/dist/kit/MarkStack.js.map +1 -0
  130. package/dist/kit/Note.d.ts +11 -0
  131. package/dist/kit/Note.js +31 -0
  132. package/dist/kit/Note.js.map +1 -0
  133. package/dist/kit/Popover.js +90 -0
  134. package/dist/kit/Popover.js.map +1 -0
  135. package/dist/kit/RangeField.d.ts +14 -0
  136. package/dist/kit/RangeField.js +47 -0
  137. package/dist/kit/RangeField.js.map +1 -0
  138. package/dist/kit/RatingField.d.ts +14 -0
  139. package/dist/kit/RatingField.js +50 -0
  140. package/dist/kit/RatingField.js.map +1 -0
  141. package/dist/kit/Stat.d.ts +26 -0
  142. package/dist/kit/Stat.js +46 -0
  143. package/dist/kit/Stat.js.map +1 -0
  144. package/dist/kit/Switch.d.ts +14 -0
  145. package/dist/kit/Switch.js +21 -0
  146. package/dist/kit/Switch.js.map +1 -0
  147. package/dist/kit/Tag.d.ts +16 -0
  148. package/dist/kit/Tag.js +20 -0
  149. package/dist/kit/Tag.js.map +1 -0
  150. package/dist/kit/Tile.d.ts +34 -0
  151. package/dist/kit/Tile.js +52 -0
  152. package/dist/kit/Tile.js.map +1 -0
  153. package/dist/kit/TimeField.d.ts +31 -0
  154. package/dist/kit/TimeField.js +109 -0
  155. package/dist/kit/TimeField.js.map +1 -0
  156. package/dist/kit/context.d.ts +22 -0
  157. package/dist/kit/context.js +46 -0
  158. package/dist/kit/context.js.map +1 -0
  159. package/dist/kit/dates.d.ts +14 -0
  160. package/dist/kit/dates.js +129 -0
  161. package/dist/kit/dates.js.map +1 -0
  162. package/dist/kit/messages.d.ts +99 -0
  163. package/dist/kit/messages.js +66 -0
  164. package/dist/kit/messages.js.map +1 -0
  165. package/dist/kit/numbers.d.ts +12 -0
  166. package/dist/kit/numbers.js +40 -0
  167. package/dist/kit/numbers.js.map +1 -0
  168. package/dist/kit/options.d.ts +10 -0
  169. package/dist/kit/options.js +23 -0
  170. package/dist/kit/options.js.map +1 -0
  171. package/dist/kit/uploads.d.ts +42 -0
  172. package/dist/kit/uploads.js +165 -0
  173. package/dist/kit/uploads.js.map +1 -0
  174. package/dist/kit/waveform.js +76 -0
  175. package/dist/kit/waveform.js.map +1 -0
  176. package/dist/locale.d.ts +1 -0
  177. package/dist/locale.js +1 -0
  178. package/dist/markdown.js +84 -0
  179. package/dist/markdown.js.map +1 -0
  180. package/dist/marks.js +217 -0
  181. package/dist/marks.js.map +1 -0
  182. package/dist/reveal.js +48 -0
  183. package/dist/reveal.js.map +1 -0
  184. package/dist/stepGlyphs.js +62 -0
  185. package/dist/stepGlyphs.js.map +1 -0
  186. package/dist/surface/Form.js +264 -0
  187. package/dist/surface/Form.js.map +1 -0
  188. package/dist/surface/Markdown.js +42 -0
  189. package/dist/surface/Markdown.js.map +1 -0
  190. package/dist/surface/Surface.d.ts +31 -17
  191. package/dist/surface/Surface.js +480 -57
  192. package/dist/surface/Surface.js.map +1 -0
  193. package/dist/surface/scope.d.ts +32 -0
  194. package/dist/surface/scope.js +23 -0
  195. package/dist/surface/scope.js.map +1 -0
  196. package/dist/surface/values.d.ts +44 -0
  197. package/dist/surface/values.js +237 -0
  198. package/dist/surface/values.js.map +1 -0
  199. package/dist/tint.d.ts +10 -0
  200. package/dist/tint.js +19 -0
  201. package/dist/tint.js.map +1 -0
  202. package/dist/types.d.ts +541 -0
  203. package/dist/types.js +16 -0
  204. package/dist/types.js.map +1 -0
  205. package/dist/useAgentFace.d.ts +18 -0
  206. package/dist/useAgentFace.js +45 -0
  207. package/dist/useAgentFace.js.map +1 -0
  208. package/dist/useCall.d.ts +39 -0
  209. package/dist/useCall.js +273 -0
  210. package/dist/useCall.js.map +1 -0
  211. package/dist/useConversation.d.ts +77 -0
  212. package/dist/useConversation.js +523 -0
  213. package/dist/useConversation.js.map +1 -0
  214. package/dist/useDictation.d.ts +17 -0
  215. package/dist/useDictation.js +68 -0
  216. package/dist/useDictation.js.map +1 -0
  217. package/dist/useLive.d.ts +26 -0
  218. package/dist/useLive.js +88 -0
  219. package/dist/useLive.js.map +1 -0
  220. package/dist/usePolled.js +68 -0
  221. package/dist/usePolled.js.map +1 -0
  222. package/dist/voice/Orb.d.ts +10 -9
  223. package/dist/voice/Orb.js +43 -39
  224. package/dist/voice/Orb.js.map +1 -0
  225. package/dist/voice/StillOrb.js +33 -0
  226. package/dist/voice/StillOrb.js.map +1 -0
  227. package/dist/voice/WebGLOrb.js +98 -0
  228. package/dist/voice/WebGLOrb.js.map +1 -0
  229. package/dist/voice/fluidDots.js +161 -0
  230. package/dist/voice/fluidDots.js.map +1 -0
  231. package/dist/voice/motion.js +84 -0
  232. package/dist/voice/motion.js.map +1 -0
  233. package/dist/voice/orbs.d.ts +32 -0
  234. package/dist/voice/orbs.js +16 -0
  235. package/dist/voice/orbs.js.map +1 -0
  236. package/dist/voice/useReducedMotion.js +16 -16
  237. package/dist/voice/useReducedMotion.js.map +1 -0
  238. package/dist/voice/wave.js +116 -0
  239. package/dist/voice/wave.js.map +1 -0
  240. package/dist/voice/webgl.js +177 -0
  241. package/dist/voice/webgl.js.map +1 -0
  242. package/dist/widget.js +284 -8
  243. package/package.json +49 -39
  244. package/src/AgentAbout.tsx +1621 -0
  245. package/src/AgentCard.tsx +123 -0
  246. package/src/AgentChat.tsx +1812 -0
  247. package/src/AgentSpace.tsx +540 -0
  248. package/src/AgentTasks.tsx +163 -0
  249. package/src/BrowserView.tsx +442 -0
  250. package/src/FileView.tsx +620 -0
  251. package/src/Modes.tsx +112 -0
  252. package/src/VoiceCall.tsx +411 -0
  253. package/src/about.ts +355 -0
  254. package/src/agentIcons.ts +56 -0
  255. package/src/automation/Automation.tsx +308 -0
  256. package/src/automation/RunView.tsx +213 -0
  257. package/src/automation/cron.ts +196 -0
  258. package/src/automation/marks.tsx +144 -0
  259. package/src/automation/messages.ts +231 -0
  260. package/src/automation/record.ts +206 -0
  261. package/src/automation/types.ts +146 -0
  262. package/src/automation/when.ts +195 -0
  263. package/src/blocks.ts +249 -0
  264. package/src/browser.ts +334 -0
  265. package/src/call.ts +300 -0
  266. package/src/channelParts.ts +17 -0
  267. package/src/classes.ts +10 -0
  268. package/src/client.ts +397 -0
  269. package/src/conversationFiles.ts +54 -0
  270. package/src/credentials.ts +158 -0
  271. package/src/dev.ts +20 -0
  272. package/src/es.ts +423 -0
  273. package/src/files.ts +238 -0
  274. package/src/frames.ts +291 -0
  275. package/src/icons.tsx +49 -0
  276. package/src/index.ts +271 -0
  277. package/src/kit/AudioPlayer.tsx +129 -0
  278. package/src/kit/Button.tsx +97 -0
  279. package/src/kit/Card.tsx +47 -0
  280. package/src/kit/Chart.tsx +129 -0
  281. package/src/kit/Choices.tsx +131 -0
  282. package/src/kit/Combobox.tsx +247 -0
  283. package/src/kit/DateField.tsx +156 -0
  284. package/src/kit/Field.tsx +137 -0
  285. package/src/kit/FileField.tsx +492 -0
  286. package/src/kit/FileMark.tsx +56 -0
  287. package/src/kit/Inputs.tsx +250 -0
  288. package/src/kit/List.tsx +135 -0
  289. package/src/kit/Mark.tsx +64 -0
  290. package/src/kit/MarkStack.tsx +29 -0
  291. package/src/kit/Note.tsx +42 -0
  292. package/src/kit/Popover.tsx +121 -0
  293. package/src/kit/RangeField.tsx +53 -0
  294. package/src/kit/RatingField.tsx +62 -0
  295. package/src/kit/Stat.tsx +60 -0
  296. package/src/kit/Switch.tsx +28 -0
  297. package/src/kit/Tag.tsx +32 -0
  298. package/src/kit/Tile.tsx +74 -0
  299. package/src/kit/TimeField.tsx +157 -0
  300. package/src/kit/context.tsx +246 -0
  301. package/src/kit/dates.ts +150 -0
  302. package/src/kit/messages.ts +160 -0
  303. package/src/kit/numbers.ts +44 -0
  304. package/src/kit/options.ts +30 -0
  305. package/src/kit/uploads.ts +244 -0
  306. package/src/kit/waveform.ts +84 -0
  307. package/src/locale.ts +6 -0
  308. package/src/markdown.ts +69 -0
  309. package/src/marks.tsx +328 -0
  310. package/src/reveal.ts +52 -0
  311. package/src/stepGlyphs.ts +83 -0
  312. package/src/styles.css +6970 -0
  313. package/src/surface/Form.tsx +299 -0
  314. package/src/surface/Markdown.tsx +55 -0
  315. package/src/surface/Surface.tsx +605 -0
  316. package/src/surface/scope.ts +82 -0
  317. package/src/surface/values.ts +361 -0
  318. package/src/tint.ts +14 -0
  319. package/src/types.ts +604 -0
  320. package/src/useAgentFace.ts +47 -0
  321. package/src/useCall.ts +292 -0
  322. package/src/useConversation.ts +627 -0
  323. package/src/useDictation.ts +83 -0
  324. package/src/useLive.ts +115 -0
  325. package/src/usePolled.ts +60 -0
  326. package/src/voice/Orb.tsx +45 -0
  327. package/src/voice/StillOrb.tsx +29 -0
  328. package/src/voice/WebGLOrb.tsx +98 -0
  329. package/src/voice/fluidDots.tsx +171 -0
  330. package/src/voice/motion.ts +112 -0
  331. package/src/voice/orbs.ts +39 -0
  332. package/src/voice/useReducedMotion.ts +24 -0
  333. package/src/voice/wave.tsx +129 -0
  334. package/src/voice/webgl.ts +209 -0
  335. package/src/widget/css.d.ts +5 -0
  336. package/src/widget/element.tsx +535 -0
  337. package/src/widget/index.ts +10 -0
  338. package/src/widget/mount.ts +27 -0
  339. package/src/widget/widget.css +253 -0
  340. package/dist/SignalcoreProvider.d.ts +0 -113
  341. package/dist/SignalcoreProvider.js +0 -84
  342. package/dist/automations/AppMarks.d.ts +0 -11
  343. package/dist/automations/AppMarks.js +0 -18
  344. package/dist/automations/AutomationCard.d.ts +0 -27
  345. package/dist/automations/AutomationCard.js +0 -53
  346. package/dist/automations/AutomationsWindow.d.ts +0 -38
  347. package/dist/automations/AutomationsWindow.js +0 -57
  348. package/dist/automations/Card.d.ts +0 -46
  349. package/dist/automations/Card.js +0 -45
  350. package/dist/automations/ScheduleMarks.d.ts +0 -13
  351. package/dist/automations/ScheduleMarks.js +0 -24
  352. package/dist/automations/presentationIcons.d.ts +0 -7
  353. package/dist/automations/presentationIcons.js +0 -67
  354. package/dist/automations/schedule.d.ts +0 -25
  355. package/dist/automations/schedule.js +0 -59
  356. package/dist/automations/time.d.ts +0 -3
  357. package/dist/automations/time.js +0 -25
  358. package/dist/browser/BrowserView.d.ts +0 -43
  359. package/dist/browser/BrowserView.js +0 -94
  360. package/dist/browser/room.d.ts +0 -21
  361. package/dist/browser/room.js +0 -33
  362. package/dist/browser/useBrowserSession.d.ts +0 -17
  363. package/dist/browser/useBrowserSession.js +0 -67
  364. package/dist/builder/BuilderChat.d.ts +0 -32
  365. package/dist/builder/BuilderChat.js +0 -41
  366. package/dist/builder/BuilderTranscript.d.ts +0 -49
  367. package/dist/builder/BuilderTranscript.js +0 -62
  368. package/dist/builder/StatusLine.d.ts +0 -8
  369. package/dist/builder/StatusLine.js +0 -17
  370. package/dist/builder/answer.d.ts +0 -7
  371. package/dist/builder/answer.js +0 -8
  372. package/dist/builder/blocks.d.ts +0 -31
  373. package/dist/builder/blocks.js +0 -74
  374. package/dist/builder/items.d.ts +0 -15
  375. package/dist/builder/items.js +0 -21
  376. package/dist/builder/steps.d.ts +0 -20
  377. package/dist/builder/steps.js +0 -120
  378. package/dist/builder/time.d.ts +0 -4
  379. package/dist/builder/time.js +0 -24
  380. package/dist/builder/useBuildSession.d.ts +0 -36
  381. package/dist/builder/useBuildSession.js +0 -130
  382. package/dist/builder/workingOn.d.ts +0 -7
  383. package/dist/builder/workingOn.js +0 -15
  384. package/dist/chat/AgentChat.d.ts +0 -37
  385. package/dist/chat/AgentChat.js +0 -21
  386. package/dist/chat/ChatView.d.ts +0 -25
  387. package/dist/chat/ChatView.js +0 -34
  388. package/dist/chat/Composer.d.ts +0 -20
  389. package/dist/chat/Composer.js +0 -22
  390. package/dist/chat/MessageRow.d.ts +0 -22
  391. package/dist/chat/MessageRow.js +0 -32
  392. package/dist/chat/arrival.d.ts +0 -15
  393. package/dist/chat/arrival.js +0 -25
  394. package/dist/chat/history.d.ts +0 -24
  395. package/dist/chat/history.js +0 -45
  396. package/dist/chat/moments.d.ts +0 -25
  397. package/dist/chat/moments.js +0 -72
  398. package/dist/chat/types.d.ts +0 -12
  399. package/dist/chat/types.js +0 -1
  400. package/dist/chat/useComposer.d.ts +0 -46
  401. package/dist/chat/useComposer.js +0 -62
  402. package/dist/chat/useConversation.d.ts +0 -35
  403. package/dist/chat/useConversation.js +0 -71
  404. package/dist/chat/useStickToBottom.d.ts +0 -9
  405. package/dist/chat/useStickToBottom.js +0 -33
  406. package/dist/chat/useTurns.d.ts +0 -49
  407. package/dist/chat/useTurns.js +0 -111
  408. package/dist/classes.d.ts +0 -2
  409. package/dist/development.d.ts +0 -5
  410. package/dist/development.js +0 -8
  411. package/dist/flow/FlowWindow.d.ts +0 -42
  412. package/dist/flow/FlowWindow.js +0 -126
  413. package/dist/flow/index.d.ts +0 -16
  414. package/dist/flow/index.js +0 -16
  415. package/dist/flow/kinds.d.ts +0 -23
  416. package/dist/flow/kinds.js +0 -48
  417. package/dist/flow/map.d.ts +0 -44
  418. package/dist/flow/map.js +0 -225
  419. package/dist/flow/nodePaths.d.ts +0 -7
  420. package/dist/flow/nodePaths.js +0 -17
  421. package/dist/flow/relations.d.ts +0 -42
  422. package/dist/flow/relations.js +0 -174
  423. package/dist/host.d.ts +0 -124
  424. package/dist/host.js +0 -1
  425. package/dist/live/LiveView.d.ts +0 -28
  426. package/dist/live/LiveView.js +0 -55
  427. package/dist/live/capture.d.ts +0 -20
  428. package/dist/live/capture.js +0 -100
  429. package/dist/live/follow.d.ts +0 -26
  430. package/dist/live/follow.js +0 -72
  431. package/dist/live/paint.d.ts +0 -13
  432. package/dist/live/paint.js +0 -77
  433. package/dist/live/useLiveStream.d.ts +0 -16
  434. package/dist/live/useLiveStream.js +0 -57
  435. package/dist/look.d.ts +0 -33
  436. package/dist/look.js +0 -241
  437. package/dist/messages/en.d.ts +0 -3
  438. package/dist/messages/en.js +0 -251
  439. package/dist/messages/es.d.ts +0 -3
  440. package/dist/messages/es.js +0 -251
  441. package/dist/messages/index.d.ts +0 -16
  442. package/dist/messages/index.js +0 -33
  443. package/dist/messages/types.d.ts +0 -246
  444. package/dist/messages/types.js +0 -1
  445. package/dist/parts/Button.d.ts +0 -18
  446. package/dist/parts/Button.js +0 -17
  447. package/dist/parts/Icon.d.ts +0 -39
  448. package/dist/parts/Icon.js +0 -37
  449. package/dist/parts/Input.d.ts +0 -6
  450. package/dist/parts/Input.js +0 -11
  451. package/dist/parts/Spinner.d.ts +0 -2
  452. package/dist/parts/Spinner.js +0 -7
  453. package/dist/patterns.d.ts +0 -15
  454. package/dist/patterns.js +0 -5
  455. package/dist/presets.d.ts +0 -82
  456. package/dist/presets.js +0 -81
  457. package/dist/primitives.d.ts +0 -22
  458. package/dist/primitives.js +0 -58
  459. package/dist/request/RequestCard.d.ts +0 -34
  460. package/dist/request/RequestCard.js +0 -101
  461. package/dist/request/approval/ApprovalPreview.d.ts +0 -5
  462. package/dist/request/approval/ApprovalPreview.js +0 -27
  463. package/dist/request/approval/shapes.d.ts +0 -32
  464. package/dist/request/approval/shapes.js +0 -68
  465. package/dist/request/apps.d.ts +0 -11
  466. package/dist/request/apps.js +0 -27
  467. package/dist/request/cards.d.ts +0 -12
  468. package/dist/request/cards.js +0 -24
  469. package/dist/request/deliver.d.ts +0 -12
  470. package/dist/request/deliver.js +0 -21
  471. package/dist/request/handOver.d.ts +0 -18
  472. package/dist/request/handOver.js +0 -33
  473. package/dist/request/kinds/Approval.d.ts +0 -3
  474. package/dist/request/kinds/Approval.js +0 -9
  475. package/dist/request/kinds/Choice.d.ts +0 -3
  476. package/dist/request/kinds/Choice.js +0 -8
  477. package/dist/request/kinds/Connect.d.ts +0 -9
  478. package/dist/request/kinds/Connect.js +0 -119
  479. package/dist/request/kinds/FreeText.d.ts +0 -3
  480. package/dist/request/kinds/FreeText.js +0 -20
  481. package/dist/request/kinds/HandOver.d.ts +0 -13
  482. package/dist/request/kinds/HandOver.js +0 -20
  483. package/dist/request/kinds/Secret.d.ts +0 -7
  484. package/dist/request/kinds/Secret.js +0 -49
  485. package/dist/request/kinds/Upload.d.ts +0 -6
  486. package/dist/request/kinds/Upload.js +0 -47
  487. package/dist/request/types.d.ts +0 -83
  488. package/dist/request/types.js +0 -1
  489. package/dist/safeUrl.d.ts +0 -6
  490. package/dist/safeUrl.js +0 -8
  491. package/dist/stream/builder.d.ts +0 -176
  492. package/dist/stream/builder.js +0 -202
  493. package/dist/stream/reduce.d.ts +0 -51
  494. package/dist/stream/reduce.js +0 -58
  495. package/dist/stream/untilAborted.d.ts +0 -7
  496. package/dist/stream/untilAborted.js +0 -32
  497. package/dist/stream/useRunStream.d.ts +0 -26
  498. package/dist/stream/useRunStream.js +0 -137
  499. package/dist/styles.css +0 -2318
  500. package/dist/surface/HostNode.d.ts +0 -14
  501. package/dist/surface/HostNode.js +0 -30
  502. package/dist/surface/Node.d.ts +0 -7
  503. package/dist/surface/Node.js +0 -49
  504. package/dist/surface/SurfaceBoundary.d.ts +0 -26
  505. package/dist/surface/SurfaceBoundary.js +0 -20
  506. package/dist/surface/bindings.d.ts +0 -14
  507. package/dist/surface/bindings.js +0 -37
  508. package/dist/surface/check.d.ts +0 -27
  509. package/dist/surface/check.js +0 -102
  510. package/dist/surface/format.d.ts +0 -10
  511. package/dist/surface/format.js +0 -32
  512. package/dist/surface/hosts.d.ts +0 -6
  513. package/dist/surface/hosts.js +0 -11
  514. package/dist/surface/scene.d.ts +0 -21
  515. package/dist/surface/scene.js +0 -8
  516. package/dist/surface/templates/Browser.d.ts +0 -6
  517. package/dist/surface/templates/Browser.js +0 -11
  518. package/dist/surface/templates/Chart.d.ts +0 -6
  519. package/dist/surface/templates/Chart.js +0 -13
  520. package/dist/surface/templates/Choices.d.ts +0 -3
  521. package/dist/surface/templates/Choices.js +0 -12
  522. package/dist/surface/templates/Form.d.ts +0 -3
  523. package/dist/surface/templates/Form.js +0 -44
  524. package/dist/surface/templates/KeyValue.d.ts +0 -3
  525. package/dist/surface/templates/KeyValue.js +0 -7
  526. package/dist/surface/templates/Layout.d.ts +0 -5
  527. package/dist/surface/templates/Layout.js +0 -16
  528. package/dist/surface/templates/Live.d.ts +0 -6
  529. package/dist/surface/templates/Live.js +0 -9
  530. package/dist/surface/templates/Media.d.ts +0 -5
  531. package/dist/surface/templates/Media.js +0 -13
  532. package/dist/surface/templates/Slots.d.ts +0 -3
  533. package/dist/surface/templates/Slots.js +0 -19
  534. package/dist/surface/templates/Table.d.ts +0 -3
  535. package/dist/surface/templates/Table.js +0 -12
  536. package/dist/surface/templates/Text.d.ts +0 -4
  537. package/dist/surface/templates/Text.js +0 -15
  538. package/dist/surface/templates/index.d.ts +0 -7
  539. package/dist/surface/templates/index.js +0 -32
  540. package/dist/surface/types.d.ts +0 -68
  541. package/dist/surface/types.js +0 -6
  542. package/dist/theme.d.ts +0 -62
  543. package/dist/theme.js +0 -9
  544. package/dist/useTokens.d.ts +0 -7
  545. package/dist/useTokens.js +0 -41
  546. package/dist/voice/VoiceWindow.d.ts +0 -18
  547. package/dist/voice/VoiceWindow.js +0 -35
  548. package/dist/voice/index.d.ts +0 -13
  549. package/dist/voice/index.js +0 -12
  550. package/dist/voice/meter.d.ts +0 -16
  551. package/dist/voice/meter.js +0 -52
  552. package/dist/voice/orbColors.d.ts +0 -16
  553. package/dist/voice/orbColors.js +0 -75
  554. package/dist/voice/pushable.d.ts +0 -16
  555. package/dist/voice/pushable.js +0 -56
  556. package/dist/voice/useDictation.d.ts +0 -24
  557. package/dist/voice/useDictation.js +0 -60
  558. package/dist/voice/useReducedMotion.d.ts +0 -5
  559. package/dist/voice/useVoice.d.ts +0 -70
  560. package/dist/voice/useVoice.js +0 -197
  561. package/dist/voice/useVoicePrimitives.d.ts +0 -7
  562. package/dist/voice/useVoicePrimitives.js +0 -11
  563. package/dist/voice/voice.d.ts +0 -55
  564. package/dist/voice/voice.js +0 -9
  565. package/dist/voice/webSpeech.d.ts +0 -33
  566. package/dist/voice/webSpeech.js +0 -258
  567. package/dist/widget.js.map +0 -1
  568. package/dist/windows/AgentSpace.d.ts +0 -78
  569. package/dist/windows/AgentSpace.js +0 -135
  570. package/dist/windows/Captions.d.ts +0 -13
  571. package/dist/windows/Captions.js +0 -22
  572. package/dist/windows/Dock.d.ts +0 -37
  573. package/dist/windows/Dock.js +0 -22
  574. package/dist/windows/Journal.d.ts +0 -15
  575. package/dist/windows/Journal.js +0 -19
  576. package/dist/windows/KindMark.d.ts +0 -7
  577. package/dist/windows/KindMark.js +0 -31
  578. package/dist/windows/Pending.d.ts +0 -8
  579. package/dist/windows/Pending.js +0 -17
  580. package/dist/windows/Stage.d.ts +0 -18
  581. package/dist/windows/Stage.js +0 -21
  582. package/dist/windows/StatusLabel.d.ts +0 -9
  583. package/dist/windows/StatusLabel.js +0 -7
  584. package/dist/windows/Strip.d.ts +0 -17
  585. package/dist/windows/Strip.js +0 -42
  586. package/dist/windows/SurfaceWindow.d.ts +0 -20
  587. package/dist/windows/SurfaceWindow.js +0 -12
  588. package/dist/windows/WindowFrame.d.ts +0 -23
  589. package/dist/windows/WindowFrame.js +0 -22
  590. package/dist/windows/hearing.d.ts +0 -11
  591. package/dist/windows/hearing.js +0 -26
  592. package/dist/windows/kinds.d.ts +0 -47
  593. package/dist/windows/kinds.js +0 -28
  594. package/dist/windows/reduce.d.ts +0 -98
  595. package/dist/windows/reduce.js +0 -151
  596. package/dist/windows/registry.d.ts +0 -18
  597. package/dist/windows/registry.js +0 -61
  598. package/dist/windows/reveal.d.ts +0 -9
  599. package/dist/windows/reveal.js +0 -6
  600. package/dist/windows/space.d.ts +0 -21
  601. package/dist/windows/space.js +0 -6
  602. package/dist/windows/status.d.ts +0 -11
  603. package/dist/windows/status.js +0 -30
  604. package/dist/windows/types.d.ts +0 -15
  605. package/dist/windows/types.js +0 -1
  606. package/dist/windows/useLoaded.d.ts +0 -44
  607. package/dist/windows/useLoaded.js +0 -58
  608. package/dist/windows/useUnread.d.ts +0 -7
  609. package/dist/windows/useUnread.js +0 -21
  610. package/dist/windows/useWindows.d.ts +0 -70
  611. package/dist/windows/useWindows.js +0 -60
package/src/Modes.tsx ADDED
@@ -0,0 +1,112 @@
1
+ import { ChatCircleTextIcon, WaveformIcon, type Icon } from "@phosphor-icons/react";
2
+ import { useEffect, useRef, type KeyboardEvent } from "react";
3
+
4
+ import { classes } from "./classes";
5
+
6
+ /** How the person talks to the agent in its space: writing, or on a call. */
7
+ export type SpaceMode = "text" | "voice";
8
+
9
+ /** The modes' words: the group's name for screen readers, and each mode's. */
10
+ export interface ModeMessages {
11
+ label: string;
12
+ text: string;
13
+ voice: string;
14
+ }
15
+
16
+ /** The modes' parts, by the class each carries. */
17
+ export type ModePart =
18
+ "sc-space__modes" | "sc-space__mode" | "sc-space__mode--text" | "sc-space__mode--voice";
19
+
20
+ const MODES: readonly { mode: SpaceMode; glyph: Icon }[] = [
21
+ { mode: "text", glyph: ChatCircleTextIcon },
22
+ { mode: "voice", glyph: WaveformIcon },
23
+ ];
24
+
25
+ /** Where an arrow key moves among the modes, by how many; Home and End go to either end. */
26
+ const STEPS: Readonly<Record<string, number>> = {
27
+ ArrowRight: 1,
28
+ ArrowDown: 1,
29
+ ArrowLeft: -1,
30
+ ArrowUp: -1,
31
+ };
32
+
33
+ /**
34
+ * The two ways to talk, side by side in one small segmented control: a radio group, the mode on
35
+ * reachable by Tab and the arrows moving to the other and choosing it (Home and End too), each
36
+ * named by its glyph and its word. `focus` takes the keyboard as it is drawn, for a control drawn
37
+ * anew after a switch made from it (the chat's and the call's are two).
38
+ */
39
+ export function Modes({
40
+ mode,
41
+ onChange,
42
+ words,
43
+ classNames,
44
+ focus = false,
45
+ }: {
46
+ mode: SpaceMode;
47
+ onChange: (mode: SpaceMode) => void;
48
+ words: ModeMessages;
49
+ classNames?: Partial<Record<ModePart, string>> | undefined;
50
+ focus?: boolean | undefined;
51
+ }) {
52
+ const buttons = useRef<(HTMLButtonElement | null)[]>([]);
53
+ const on = MODES.findIndex((each) => each.mode === mode);
54
+
55
+ useEffect(() => {
56
+ if (focus) buttons.current[on]?.focus();
57
+ // Only as it is drawn: a mode chosen later keeps the focus where the keys put it.
58
+ }, []);
59
+
60
+ const onKeyDown = (event: KeyboardEvent<HTMLButtonElement>, index: number) => {
61
+ const step = STEPS[event.key];
62
+ const to =
63
+ event.key === "Home"
64
+ ? 0
65
+ : event.key === "End"
66
+ ? MODES.length - 1
67
+ : step === undefined
68
+ ? null
69
+ : (index + step + MODES.length) % MODES.length;
70
+ if (to === null) return;
71
+ event.preventDefault();
72
+ buttons.current[to]?.focus();
73
+ const next = MODES[to];
74
+ if (next && next.mode !== mode) onChange(next.mode);
75
+ };
76
+
77
+ return (
78
+ <div
79
+ role="radiogroup"
80
+ aria-label={words.label}
81
+ part="modes"
82
+ className={classes(classNames, "sc-space__modes")}
83
+ >
84
+ {MODES.map(({ mode: each, glyph: Glyph }, index) => {
85
+ const chosen = index === on;
86
+ return (
87
+ <button
88
+ key={each}
89
+ ref={(button) => {
90
+ buttons.current[index] = button;
91
+ }}
92
+ type="button"
93
+ role="radio"
94
+ aria-checked={chosen}
95
+ tabIndex={chosen ? 0 : -1}
96
+ onClick={() => {
97
+ if (!chosen) onChange(each);
98
+ }}
99
+ onKeyDown={(event) => {
100
+ onKeyDown(event, index);
101
+ }}
102
+ part={chosen ? `mode mode-${each} mode-selected` : `mode mode-${each}`}
103
+ className={classes(classNames, "sc-space__mode", `sc-space__mode--${each}`)}
104
+ >
105
+ <Glyph aria-hidden weight={chosen ? "fill" : "regular"} />
106
+ <span>{words[each]}</span>
107
+ </button>
108
+ );
109
+ })}
110
+ </div>
111
+ );
112
+ }
@@ -0,0 +1,411 @@
1
+ import {
2
+ MicrophoneIcon,
3
+ MicrophoneSlashIcon,
4
+ PhoneDisconnectIcon,
5
+ SpeakerHighIcon,
6
+ } from "@phosphor-icons/react";
7
+ import { useEffect, useRef, useState, type ReactNode, type RefObject } from "react";
8
+
9
+ import {
10
+ durationOf,
11
+ keyBelongsElsewhere,
12
+ lookOf,
13
+ orbOf,
14
+ type CallEndedBy,
15
+ type CallLook,
16
+ type CallProblem,
17
+ type CallState,
18
+ } from "./call";
19
+ import { classes } from "./classes";
20
+ import { Button } from "./kit/Button";
21
+ import { KitProvider, type KitClassNames, type KitPart } from "./kit/context";
22
+ import type { AgentTint } from "./tint";
23
+ import { useCall, type CallJoin } from "./useCall";
24
+ import { Orb } from "./voice/Orb";
25
+ import type { OrbStyle } from "./voice/orbs";
26
+
27
+ /** How big the orb is drawn: large, in the middle, with room for it to grow when the voice is loud. */
28
+ const ORB_SIZE = 280;
29
+
30
+ /** The orb's level where nobody it follows is speaking. */
31
+ const SILENT = (): number => 0;
32
+
33
+ /** The words a call says; a host gives its own, in its language. */
34
+ export interface VoiceCallMessages {
35
+ /** The call's name, for those who can't see it. */
36
+ call: (name: string) => string;
37
+ /** What the call is doing, in a word or two. */
38
+ states: Readonly<Record<Exclude<CallLook, "problem">, string>>;
39
+ /** Under the state while the call connects. */
40
+ calling: (name: string) => string;
41
+ /** Why the call ended, before how long it lasted. */
42
+ ended: Readonly<Record<CallEndedBy, (name: string) => string>>;
43
+ /** Why the call never began, and what the person can do about it. */
44
+ problems: Readonly<Record<CallProblem, { title: (name: string) => string; help: string }>>;
45
+ mute: string;
46
+ hangUp: string;
47
+ /** Under the controls, where there is a keyboard. */
48
+ keys: string;
49
+ /** Under the controls while the microphone is off. */
50
+ muted: string;
51
+ /** The browser held the agent's voice until a press: the button that lets it play. */
52
+ hear: (name: string) => string;
53
+ }
54
+
55
+ export const VOICE_CALL_MESSAGES: VoiceCallMessages = {
56
+ call: (name) => `Call with ${name}`,
57
+ states: {
58
+ connecting: "Connecting…",
59
+ listening: "Listening",
60
+ thinking: "Thinking",
61
+ speaking: "Speaking",
62
+ reconnecting: "Reconnecting…",
63
+ ended: "Call ended",
64
+ },
65
+ calling: (name) => `Calling ${name}`,
66
+ ended: {
67
+ person: () => "You hung up",
68
+ agent: (name) => `${name} hung up`,
69
+ limit: () => "It reached its longest time",
70
+ dropped: () => "The line dropped",
71
+ },
72
+ problems: {
73
+ denied: {
74
+ title: () => "The microphone isn't allowed",
75
+ help: "Allow the microphone for this page (the icon beside the address) and call again.",
76
+ },
77
+ nomic: {
78
+ title: () => "No microphone",
79
+ help: "Plug one in, or pick another in your system's sound settings, and call again.",
80
+ },
81
+ inuse: {
82
+ title: () => "The microphone is busy",
83
+ help: "Another app is using it. Close it and call again.",
84
+ },
85
+ unsupported: {
86
+ title: () => "This browser can't call",
87
+ help: "Open this page over https in a recent Chrome, Edge, Safari or Firefox.",
88
+ },
89
+ off: {
90
+ title: () => "Calls aren't set up",
91
+ help: "Calls are turned on where your agents work. Ask whoever set it up.",
92
+ },
93
+ builder: {
94
+ title: (name) => `${name} doesn't take calls`,
95
+ help: "A squad's builder only writes. Call one of the squad's agents.",
96
+ },
97
+ refused: {
98
+ title: (name) => `${name} can't take this call`,
99
+ help: "Try again in a moment.",
100
+ },
101
+ failed: {
102
+ title: (name) => `Couldn't call ${name}`,
103
+ help: "Check your connection and try again.",
104
+ },
105
+ unanswered: {
106
+ title: (name) => `${name} isn't answering`,
107
+ help: "Calls aren't being taken right now. Try again in a moment.",
108
+ },
109
+ },
110
+ mute: "Mute",
111
+ hangUp: "Hang up",
112
+ keys: "Space mutes and unmutes",
113
+ muted: "Your microphone is off",
114
+ hear: (name) => `Hear ${name}`,
115
+ };
116
+
117
+ /** The call's parts, by the class each carries; `classNames` adds a host's own under the same keys. */
118
+ export type VoiceCallPart =
119
+ | "sc-call"
120
+ | `sc-call--${CallLook}`
121
+ | `sc-call--${AgentTint}`
122
+ | "sc-call--on"
123
+ | "sc-call--muted"
124
+ | "sc-call__stage"
125
+ | "sc-call__orb"
126
+ | "sc-call__state"
127
+ | "sc-call__line"
128
+ | "sc-call__sound"
129
+ | "sc-call__controls"
130
+ | "sc-call__control"
131
+ | "sc-call__mute"
132
+ | "sc-call__hangup"
133
+ | "sc-call__hint"
134
+ | "sc-call__captions"
135
+ | "sc-call__after";
136
+
137
+ export interface VoiceCallProps {
138
+ /**
139
+ * Where to join: LiveKit's address and a token for the call's room (our API's
140
+ * `client.conversations.call(agentId)` answers both, `client.agents.call(id)` for the owner's
141
+ * test). Called once, when the call starts, after the microphone is open.
142
+ */
143
+ connect: () => Promise<CallJoin>;
144
+ /** The agent's name, for the words that say it. */
145
+ name: string;
146
+ /**
147
+ * The agent's own tint (`agentTint(id)`), worn by the call's chrome: the orb's shader paints its
148
+ * own colours, and the still orb that stands in where there is no WebGL wears it.
149
+ */
150
+ tint?: AgentTint | undefined;
151
+ /** How the orb is drawn: `"wave"` (the default) or `"fluid-dots"`. */
152
+ orb?: OrbStyle | undefined;
153
+ /** The orb's diameter in pixels: 280 by default, less for a call in a small panel. */
154
+ orbSize?: number | undefined;
155
+ /**
156
+ * Why the call ended as the API keeps it, once the host has read it (`endedByReason` of its
157
+ * conversation's call): what the end says when the agent's side closed the room (its goodbye,
158
+ * or its longest time), which the room doesn't tell. Until then the end says how long it was.
159
+ */
160
+ endedBy?: CallEndedBy | null | undefined;
161
+ messages?: Partial<VoiceCallMessages> | undefined;
162
+ /** The host's classes for the call's parts and the kit's (the orb's `sc-orb…`, the buttons'). */
163
+ classNames?: Partial<Record<VoiceCallPart | KitPart, string>> | undefined;
164
+ /**
165
+ * The call is over, once: it ended (`answered`: the agent took it; `problem` null), or it
166
+ * couldn't begin (`problem`: why, which the call shows until the host takes it away).
167
+ */
168
+ onEnd?: ((answered: boolean, problem: CallProblem | null) => void) | undefined;
169
+ /** The agent took the call: its time counts from now. Once. */
170
+ onAnswer?: (() => void) | undefined;
171
+ /** What the host offers once the call is over, in place of the controls: call again, write. */
172
+ after?: ReactNode;
173
+ /** What is being said, drawn by the host under the orb while the call is on (`sc-call__captions`). */
174
+ captions?: ReactNode;
175
+ }
176
+
177
+ /**
178
+ * A voice call with an agent, the one a customer has on the phone: the call starts when it
179
+ * mounts and ends when it unmounts. The orb, large in the middle, rests while the line is found,
180
+ * moves with whoever speaks (the agent's voice while it speaks, the person's while it listens),
181
+ * calms while the agent thinks, and fades once the call is over; under it what the call
182
+ * is doing in a word, its time, and the two controls a phone has, mute and hang up. A microphone
183
+ * that can't be used, or a call that can't be made (the API's refusal among them), says why in
184
+ * words and what to do; an end says who ended it (the room's own word, or the API's: `endedBy`)
185
+ * and how long it lasted.
186
+ *
187
+ * Space mutes and unmutes from anywhere that isn't a field or a control of the page's own.
188
+ * Escape never hangs up: it is the key that closes things, pressed by reflex, and a call ended
189
+ * by accident can't be taken back, so ending one is the red button's alone. The orb stands
190
+ * still under reduced motion, one frame per state: the words say the rest.
191
+ */
192
+ export function VoiceCall(props: VoiceCallProps) {
193
+ return (
194
+ <KitProvider classNames={props.classNames as KitClassNames}>
195
+ <Call {...props} />
196
+ </KitProvider>
197
+ );
198
+ }
199
+
200
+ function Call({
201
+ connect,
202
+ name,
203
+ tint = "sky",
204
+ orb: style,
205
+ orbSize = ORB_SIZE,
206
+ endedBy,
207
+ messages,
208
+ classNames,
209
+ onEnd,
210
+ onAnswer,
211
+ after,
212
+ captions,
213
+ }: VoiceCallProps) {
214
+ const words = { ...VOICE_CALL_MESSAGES, ...messages };
215
+ const root = useRef<HTMLElement>(null);
216
+ const sink = useRef<HTMLDivElement>(null);
217
+ const call = useCall(connect, { sink });
218
+ const { state } = call;
219
+ const look = lookOf(state);
220
+ const orb = orbOf(look);
221
+ const over = state.stage === "over";
222
+ const seconds = useSeconds(state);
223
+
224
+ useSpace(root, !over, () => {
225
+ call.mute();
226
+ });
227
+ // The call takes the keyboard as it opens, so Space is its from the start; and again once over,
228
+ // when the control that had it is gone, so the host's offers are the next stop.
229
+ useEffect(() => {
230
+ root.current?.focus({ preventScroll: true });
231
+ }, [over]);
232
+ // The host's ears as it last gave them.
233
+ const told = useRef({ onEnd, onAnswer });
234
+ useEffect(() => {
235
+ told.current = { onEnd, onAnswer };
236
+ });
237
+ const answered = state.answeredAt !== null;
238
+ useEffect(() => {
239
+ if (answered) told.current.onAnswer?.();
240
+ }, [answered]);
241
+ useEffect(() => {
242
+ if (over) told.current.onEnd?.(answered, state.problem);
243
+ }, [over]);
244
+
245
+ const { headline, line } = wordsOf(state, look, seconds, words, name, endedBy ?? null);
246
+ const modifiers: VoiceCallPart[] = [`sc-call--${look}`, `sc-call--${tint}`];
247
+ if (!over) modifiers.push("sc-call--on");
248
+ if (state.muted && !over) modifiers.push("sc-call--muted");
249
+
250
+ return (
251
+ <section
252
+ ref={root}
253
+ tabIndex={-1}
254
+ aria-label={words.call(name)}
255
+ part="call"
256
+ className={`sc ${classes(classNames, "sc-call", ...modifiers)}`}
257
+ >
258
+ <div className={classes(classNames, "sc-call__stage")}>
259
+ <Orb
260
+ state={orb.state}
261
+ level={orb.follows === null ? SILENT : call.meter[orb.follows]}
262
+ size={orbSize}
263
+ style={style}
264
+ label={headline}
265
+ className={classes(classNames, "sc-call__orb")}
266
+ />
267
+ <p role="status" part="call-state" className={classes(classNames, "sc-call__state")}>
268
+ <span key={headline}>{headline}</span>
269
+ </p>
270
+ <p part="call-line" className={classes(classNames, "sc-call__line")}>
271
+ {line}
272
+ </p>
273
+ </div>
274
+ {captions !== undefined && !over && (
275
+ <div part="captions" className={classes(classNames, "sc-call__captions")}>
276
+ {captions}
277
+ </div>
278
+ )}
279
+ {state.silenced && !over && (
280
+ <Button
281
+ size="sm"
282
+ icon={SpeakerHighIcon}
283
+ onClick={call.hear}
284
+ className={classes(classNames, "sc-call__sound")}
285
+ >
286
+ {words.hear(name)}
287
+ </Button>
288
+ )}
289
+ {over ? (
290
+ after !== undefined && (
291
+ <div part="call-after" className={classes(classNames, "sc-call__after")}>
292
+ {after}
293
+ </div>
294
+ )
295
+ ) : (
296
+ <>
297
+ <div part="call-controls" className={classes(classNames, "sc-call__controls")}>
298
+ <div className={classes(classNames, "sc-call__control")}>
299
+ <Button
300
+ icon={state.muted ? MicrophoneSlashIcon : MicrophoneIcon}
301
+ aria-label={words.mute}
302
+ aria-pressed={state.muted}
303
+ disabled={state.stage === "opening"}
304
+ onClick={() => {
305
+ call.mute();
306
+ }}
307
+ part="mute"
308
+ className={classes(classNames, "sc-call__mute")}
309
+ />
310
+ <span aria-hidden>{words.mute}</span>
311
+ </div>
312
+ <div className={classes(classNames, "sc-call__control")}>
313
+ <Button
314
+ tone="danger"
315
+ icon={PhoneDisconnectIcon}
316
+ aria-label={words.hangUp}
317
+ onClick={call.hangUp}
318
+ part="hang-up"
319
+ className={classes(classNames, "sc-call__hangup")}
320
+ />
321
+ <span aria-hidden>{words.hangUp}</span>
322
+ </div>
323
+ </div>
324
+ <p
325
+ data-keys={state.muted ? undefined : ""}
326
+ className={classes(classNames, "sc-call__hint")}
327
+ >
328
+ {state.muted ? words.muted : words.keys}
329
+ </p>
330
+ </>
331
+ )}
332
+ {/* The agent's voice plays from here. */}
333
+ <div ref={sink} hidden />
334
+ </section>
335
+ );
336
+ }
337
+
338
+ /**
339
+ * What the call says: what it is doing (or why it couldn't begin), and under it who is being
340
+ * called, the time, how it ended (as the room knows it, else as the API said: `endedBy`) and how
341
+ * long it lasted, or what to do.
342
+ */
343
+ function wordsOf(
344
+ state: CallState,
345
+ look: CallLook,
346
+ seconds: number,
347
+ words: VoiceCallMessages,
348
+ name: string,
349
+ endedBy: CallEndedBy | null,
350
+ ): { headline: string; line: string } {
351
+ if (look === "problem" && state.problem !== null) {
352
+ const problem = words.problems[state.problem];
353
+ return { headline: problem.title(name), line: problem.help };
354
+ }
355
+ const headline = look === "problem" ? "" : words.states[look];
356
+ if (state.end !== null) {
357
+ const by = state.end.by ?? endedBy;
358
+ const lasted = durationOf(state.end.seconds);
359
+ // Why it ended says it ended; how long it lasted, under it.
360
+ return { headline: by === null ? headline : words.ended[by](name), line: lasted };
361
+ }
362
+ return {
363
+ headline,
364
+ line: state.answeredAt === null ? words.calling(name) : durationOf(seconds),
365
+ };
366
+ }
367
+
368
+ /** The call's time in whole seconds: counting while it is on, held once it is over. */
369
+ function useSeconds(state: CallState): number {
370
+ const [now, setNow] = useState(() => Date.now());
371
+ const counting = state.answeredAt !== null && state.stage !== "over";
372
+ useEffect(() => {
373
+ if (!counting) return undefined;
374
+ const tick = setInterval(() => {
375
+ setNow(Date.now());
376
+ }, 500);
377
+ return () => {
378
+ clearInterval(tick);
379
+ };
380
+ }, [counting]);
381
+ if (state.end !== null) return state.end.seconds;
382
+ if (state.answeredAt === null) return 0;
383
+ return Math.max(0, Math.floor((now - state.answeredAt) / 1000));
384
+ }
385
+
386
+ /**
387
+ * Space mutes and unmutes while `active`, wherever it doesn't belong to something else (a field,
388
+ * a control of the page's own). Taken whole, down and up: the page doesn't scroll, and a control
389
+ * of the call that has the focus is not pressed by it.
390
+ */
391
+ function useSpace(root: RefObject<HTMLElement | null>, active: boolean, toggle: () => void) {
392
+ const latest = useRef(toggle);
393
+ useEffect(() => {
394
+ latest.current = toggle;
395
+ });
396
+ useEffect(() => {
397
+ if (!active) return undefined;
398
+ const onKey = (event: KeyboardEvent) => {
399
+ if (event.key !== " " || event.ctrlKey || event.metaKey || event.altKey) return;
400
+ if (event.defaultPrevented || keyBelongsElsewhere(event.target, root.current)) return;
401
+ event.preventDefault();
402
+ if (event.type === "keydown" && !event.repeat) latest.current();
403
+ };
404
+ window.addEventListener("keydown", onKey);
405
+ window.addEventListener("keyup", onKey);
406
+ return () => {
407
+ window.removeEventListener("keydown", onKey);
408
+ window.removeEventListener("keyup", onKey);
409
+ };
410
+ }, [active, root]);
411
+ }