@docyrus/ui-pro-ai-assistant 0.0.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 (308) hide show
  1. package/dist/index.js +26161 -0
  2. package/dist/index.js.map +1 -0
  3. package/package.json +155 -0
  4. package/src/components/assistant-animations.tsx +29 -0
  5. package/src/components/assistant-dialogs.tsx +235 -0
  6. package/src/components/code-view.tsx +278 -0
  7. package/src/components/create-agent-task.tsx +104 -0
  8. package/src/components/create-new-work-version.tsx +30 -0
  9. package/src/components/extract-web.tsx +160 -0
  10. package/src/components/forward-to-agent.tsx +90 -0
  11. package/src/components/generate-chart.tsx +101 -0
  12. package/src/components/generative-action-button.tsx +122 -0
  13. package/src/components/generative-tool.tsx +685 -0
  14. package/src/components/generative-ui-object.tsx +210 -0
  15. package/src/components/input-area.tsx +1209 -0
  16. package/src/components/json-schema-layout.tsx +326 -0
  17. package/src/components/list-item-card.tsx +92 -0
  18. package/src/components/mermaid-diagram.tsx +192 -0
  19. package/src/components/preview-image.tsx +47 -0
  20. package/src/components/request-approval.tsx +48 -0
  21. package/src/components/request-user-input.tsx +270 -0
  22. package/src/components/search-web.tsx +319 -0
  23. package/src/components/sheet-command.tsx +88 -0
  24. package/src/components/shell-canvas.tsx +122 -0
  25. package/src/components/show-advanced-data-table.tsx +352 -0
  26. package/src/components/show-generated-content-options.tsx +93 -0
  27. package/src/components/show-people-cards.tsx +180 -0
  28. package/src/components/subagent-tool.tsx +180 -0
  29. package/src/components/text-editor-tool.tsx +328 -0
  30. package/src/components/work-canvas.tsx +88 -0
  31. package/src/components/work-card.tsx +42 -0
  32. package/src/declarations.d.ts +1 -0
  33. package/src/docy-assistant.tsx +1962 -0
  34. package/src/hooks/index.ts +7 -0
  35. package/src/hooks/use-assistant-api.ts +507 -0
  36. package/src/hooks/use-deployment-data.ts +162 -0
  37. package/src/hooks/use-project-state.ts +347 -0
  38. package/src/hooks/use-session-state.ts +207 -0
  39. package/src/hooks/use-speech-recognition.ts +137 -0
  40. package/src/hooks/use-ui-state.ts +185 -0
  41. package/src/hooks/use-works-state.ts +146 -0
  42. package/src/i18n/context.tsx +253 -0
  43. package/src/i18n/index.ts +19 -0
  44. package/src/i18n/locales/de.json +198 -0
  45. package/src/i18n/locales/el.json +198 -0
  46. package/src/i18n/locales/en.json +226 -0
  47. package/src/i18n/locales/es.json +198 -0
  48. package/src/i18n/locales/fr.json +198 -0
  49. package/src/i18n/locales/it.json +198 -0
  50. package/src/i18n/locales/pt.json +198 -0
  51. package/src/i18n/locales/sl.json +198 -0
  52. package/src/i18n/locales/tr.json +211 -0
  53. package/src/i18n/types.ts +23 -0
  54. package/src/i18n/use-translation.ts +17 -0
  55. package/src/index.ts +18 -0
  56. package/src/internal/plate-editor/editor/auth-context.ts +11 -0
  57. package/src/internal/plate-editor/editor/editor-base-kit.tsx +39 -0
  58. package/src/internal/plate-editor/editor/editor-kit.tsx +89 -0
  59. package/src/internal/plate-editor/editor/plate-editor.tsx +75 -0
  60. package/src/internal/plate-editor/editor/plate-types.ts +126 -0
  61. package/src/internal/plate-editor/editor/plugins/ai-kit.tsx +172 -0
  62. package/src/internal/plate-editor/editor/plugins/autoformat-kit.tsx +211 -0
  63. package/src/internal/plate-editor/editor/plugins/basic-blocks-base-kit.tsx +26 -0
  64. package/src/internal/plate-editor/editor/plugins/basic-blocks-kit.tsx +51 -0
  65. package/src/internal/plate-editor/editor/plugins/basic-marks-base-kit.tsx +24 -0
  66. package/src/internal/plate-editor/editor/plugins/basic-marks-kit.tsx +38 -0
  67. package/src/internal/plate-editor/editor/plugins/basic-nodes-kit.tsx +6 -0
  68. package/src/internal/plate-editor/editor/plugins/block-menu-kit.tsx +14 -0
  69. package/src/internal/plate-editor/editor/plugins/block-placeholder-kit.tsx +17 -0
  70. package/src/internal/plate-editor/editor/plugins/block-selection-kit.tsx +31 -0
  71. package/src/internal/plate-editor/editor/plugins/callout-base-kit.tsx +5 -0
  72. package/src/internal/plate-editor/editor/plugins/callout-kit.tsx +7 -0
  73. package/src/internal/plate-editor/editor/plugins/code-block-base-kit.tsx +23 -0
  74. package/src/internal/plate-editor/editor/plugins/code-block-kit.tsx +26 -0
  75. package/src/internal/plate-editor/editor/plugins/column-base-kit.tsx +8 -0
  76. package/src/internal/plate-editor/editor/plugins/column-kit.tsx +7 -0
  77. package/src/internal/plate-editor/editor/plugins/comment-base-kit.tsx +5 -0
  78. package/src/internal/plate-editor/editor/plugins/comment-kit.tsx +174 -0
  79. package/src/internal/plate-editor/editor/plugins/copilot-kit.tsx +68 -0
  80. package/src/internal/plate-editor/editor/plugins/cursor-overlay-kit.tsx +13 -0
  81. package/src/internal/plate-editor/editor/plugins/date-base-kit.tsx +5 -0
  82. package/src/internal/plate-editor/editor/plugins/date-kit.tsx +7 -0
  83. package/src/internal/plate-editor/editor/plugins/discussion-kit.tsx +36 -0
  84. package/src/internal/plate-editor/editor/plugins/dnd-kit.tsx +27 -0
  85. package/src/internal/plate-editor/editor/plugins/docx-export-kit.tsx +43 -0
  86. package/src/internal/plate-editor/editor/plugins/docx-kit.tsx +6 -0
  87. package/src/internal/plate-editor/editor/plugins/emoji-kit.tsx +15 -0
  88. package/src/internal/plate-editor/editor/plugins/exit-break-kit.tsx +12 -0
  89. package/src/internal/plate-editor/editor/plugins/floating-toolbar-kit.tsx +19 -0
  90. package/src/internal/plate-editor/editor/plugins/font-base-kit.tsx +36 -0
  91. package/src/internal/plate-editor/editor/plugins/font-kit.tsx +47 -0
  92. package/src/internal/plate-editor/editor/plugins/indent-base-kit.tsx +19 -0
  93. package/src/internal/plate-editor/editor/plugins/indent-kit.tsx +22 -0
  94. package/src/internal/plate-editor/editor/plugins/link-base-kit.tsx +5 -0
  95. package/src/internal/plate-editor/editor/plugins/link-kit.tsx +35 -0
  96. package/src/internal/plate-editor/editor/plugins/list-base-kit.tsx +24 -0
  97. package/src/internal/plate-editor/editor/plugins/list-kit.tsx +27 -0
  98. package/src/internal/plate-editor/editor/plugins/markdown-kit.tsx +18 -0
  99. package/src/internal/plate-editor/editor/plugins/math-base-kit.tsx +8 -0
  100. package/src/internal/plate-editor/editor/plugins/math-kit.tsx +10 -0
  101. package/src/internal/plate-editor/editor/plugins/media-base-kit.tsx +37 -0
  102. package/src/internal/plate-editor/editor/plugins/media-kit.tsx +53 -0
  103. package/src/internal/plate-editor/editor/plugins/mention-base-kit.tsx +5 -0
  104. package/src/internal/plate-editor/editor/plugins/mention-kit.tsx +36 -0
  105. package/src/internal/plate-editor/editor/plugins/slash-kit.tsx +17 -0
  106. package/src/internal/plate-editor/editor/plugins/suggestion-base-kit.tsx +5 -0
  107. package/src/internal/plate-editor/editor/plugins/suggestion-kit.tsx +95 -0
  108. package/src/internal/plate-editor/editor/plugins/table-base-kit.tsx +20 -0
  109. package/src/internal/plate-editor/editor/plugins/table-kit.tsx +22 -0
  110. package/src/internal/plate-editor/editor/plugins/toc-base-kit.tsx +5 -0
  111. package/src/internal/plate-editor/editor/plugins/toc-kit.tsx +14 -0
  112. package/src/internal/plate-editor/editor/plugins/toggle-base-kit.tsx +5 -0
  113. package/src/internal/plate-editor/editor/plugins/toggle-kit.tsx +9 -0
  114. package/src/internal/plate-editor/editor/transforms.ts +165 -0
  115. package/src/internal/plate-editor/editor/use-chat.ts +152 -0
  116. package/src/internal/plate-editor/hooks/index.ts +3 -0
  117. package/src/internal/plate-editor/hooks/use-copy-to-clipboard.ts +31 -0
  118. package/src/internal/plate-editor/hooks/use-is-touch-device.ts +26 -0
  119. package/src/internal/plate-editor/hooks/use-lock-scroll.ts +21 -0
  120. package/src/internal/plate-editor/hooks/use-media-query.ts +44 -0
  121. package/src/internal/plate-editor/hooks/use-mounted.ts +18 -0
  122. package/src/internal/plate-editor/hooks/use-on-click-outside.ts +114 -0
  123. package/src/internal/plate-editor/hooks/use-upload-file.ts +81 -0
  124. package/src/internal/plate-editor/i18n/context.tsx +58 -0
  125. package/src/internal/plate-editor/i18n/index.ts +3 -0
  126. package/src/internal/plate-editor/i18n/locales/de.json +57 -0
  127. package/src/internal/plate-editor/i18n/locales/el.json +57 -0
  128. package/src/internal/plate-editor/i18n/locales/en.json +57 -0
  129. package/src/internal/plate-editor/i18n/locales/es.json +57 -0
  130. package/src/internal/plate-editor/i18n/locales/fr.json +57 -0
  131. package/src/internal/plate-editor/i18n/locales/it.json +57 -0
  132. package/src/internal/plate-editor/i18n/locales/pt.json +57 -0
  133. package/src/internal/plate-editor/i18n/locales/sl.json +57 -0
  134. package/src/internal/plate-editor/i18n/locales/tr.json +57 -0
  135. package/src/internal/plate-editor/i18n/types.ts +59 -0
  136. package/src/internal/plate-editor/i18n/use-translation.ts +22 -0
  137. package/src/internal/plate-editor/index.ts +39 -0
  138. package/src/internal/plate-editor/lib/ai-output-converter.ts +153 -0
  139. package/src/internal/plate-editor/lib/download-file.ts +17 -0
  140. package/src/internal/plate-editor/plate-ui/ai-chat-editor.tsx +26 -0
  141. package/src/internal/plate-editor/plate-ui/ai-menu.tsx +828 -0
  142. package/src/internal/plate-editor/plate-ui/ai-node.tsx +41 -0
  143. package/src/internal/plate-editor/plate-ui/ai-toolbar-button.tsx +27 -0
  144. package/src/internal/plate-editor/plate-ui/alert-dialog.tsx +147 -0
  145. package/src/internal/plate-editor/plate-ui/align-toolbar-button.tsx +90 -0
  146. package/src/internal/plate-editor/plate-ui/avatar.tsx +3 -0
  147. package/src/internal/plate-editor/plate-ui/block-context-menu.tsx +106 -0
  148. package/src/internal/plate-editor/plate-ui/block-discussion.tsx +364 -0
  149. package/src/internal/plate-editor/plate-ui/block-draggable.tsx +556 -0
  150. package/src/internal/plate-editor/plate-ui/block-list-static.tsx +78 -0
  151. package/src/internal/plate-editor/plate-ui/block-list.tsx +85 -0
  152. package/src/internal/plate-editor/plate-ui/block-menu.tsx +557 -0
  153. package/src/internal/plate-editor/plate-ui/block-selection.tsx +47 -0
  154. package/src/internal/plate-editor/plate-ui/block-suggestion.tsx +469 -0
  155. package/src/internal/plate-editor/plate-ui/blockquote-node-static.tsx +10 -0
  156. package/src/internal/plate-editor/plate-ui/blockquote-node.tsx +11 -0
  157. package/src/internal/plate-editor/plate-ui/button.tsx +190 -0
  158. package/src/internal/plate-editor/plate-ui/calendar.tsx +3 -0
  159. package/src/internal/plate-editor/plate-ui/callout-node-static.tsx +76 -0
  160. package/src/internal/plate-editor/plate-ui/callout-node.tsx +54 -0
  161. package/src/internal/plate-editor/plate-ui/caption.tsx +48 -0
  162. package/src/internal/plate-editor/plate-ui/checkbox.tsx +3 -0
  163. package/src/internal/plate-editor/plate-ui/code-block-node-static.tsx +172 -0
  164. package/src/internal/plate-editor/plate-ui/code-block-node.tsx +228 -0
  165. package/src/internal/plate-editor/plate-ui/code-node-static.tsx +11 -0
  166. package/src/internal/plate-editor/plate-ui/code-node.tsx +12 -0
  167. package/src/internal/plate-editor/plate-ui/column-node-static.tsx +65 -0
  168. package/src/internal/plate-editor/plate-ui/column-node.tsx +24 -0
  169. package/src/internal/plate-editor/plate-ui/command.tsx +204 -0
  170. package/src/internal/plate-editor/plate-ui/comment-node-static.tsx +12 -0
  171. package/src/internal/plate-editor/plate-ui/comment-node.tsx +45 -0
  172. package/src/internal/plate-editor/plate-ui/comment-toolbar-button.tsx +24 -0
  173. package/src/internal/plate-editor/plate-ui/comment.tsx +619 -0
  174. package/src/internal/plate-editor/plate-ui/cursor-overlay.tsx +85 -0
  175. package/src/internal/plate-editor/plate-ui/date-node-static.tsx +43 -0
  176. package/src/internal/plate-editor/plate-ui/date-node.tsx +56 -0
  177. package/src/internal/plate-editor/plate-ui/dialog.tsx +426 -0
  178. package/src/internal/plate-editor/plate-ui/dropdown-menu.tsx +266 -0
  179. package/src/internal/plate-editor/plate-ui/editor-static.tsx +40 -0
  180. package/src/internal/plate-editor/plate-ui/editor.tsx +148 -0
  181. package/src/internal/plate-editor/plate-ui/emoji-node.tsx +48 -0
  182. package/src/internal/plate-editor/plate-ui/emoji-toolbar-button.tsx +626 -0
  183. package/src/internal/plate-editor/plate-ui/equation-node-static.tsx +155 -0
  184. package/src/internal/plate-editor/plate-ui/equation-node.tsx +226 -0
  185. package/src/internal/plate-editor/plate-ui/equation-toolbar-button.tsx +26 -0
  186. package/src/internal/plate-editor/plate-ui/export-toolbar-button.tsx +208 -0
  187. package/src/internal/plate-editor/plate-ui/fixed-toolbar-buttons.tsx +157 -0
  188. package/src/internal/plate-editor/plate-ui/fixed-toolbar.tsx +27 -0
  189. package/src/internal/plate-editor/plate-ui/floating-discussion.tsx +1129 -0
  190. package/src/internal/plate-editor/plate-ui/floating-toolbar-buttons.tsx +129 -0
  191. package/src/internal/plate-editor/plate-ui/floating-toolbar.tsx +99 -0
  192. package/src/internal/plate-editor/plate-ui/font-color-toolbar-button.tsx +211 -0
  193. package/src/internal/plate-editor/plate-ui/font-size-toolbar-button.tsx +154 -0
  194. package/src/internal/plate-editor/plate-ui/ghost-text.tsx +20 -0
  195. package/src/internal/plate-editor/plate-ui/heading-node-static.tsx +52 -0
  196. package/src/internal/plate-editor/plate-ui/heading-node.tsx +56 -0
  197. package/src/internal/plate-editor/plate-ui/highlight-node-static.tsx +9 -0
  198. package/src/internal/plate-editor/plate-ui/highlight-node.tsx +11 -0
  199. package/src/internal/plate-editor/plate-ui/history-toolbar-button.tsx +52 -0
  200. package/src/internal/plate-editor/plate-ui/hover-card.tsx +7 -0
  201. package/src/internal/plate-editor/plate-ui/hr-node-static.tsx +18 -0
  202. package/src/internal/plate-editor/plate-ui/hr-node.tsx +28 -0
  203. package/src/internal/plate-editor/plate-ui/import-toolbar-button.tsx +124 -0
  204. package/src/internal/plate-editor/plate-ui/indent-toolbar-button.tsx +34 -0
  205. package/src/internal/plate-editor/plate-ui/inline-combobox.tsx +409 -0
  206. package/src/internal/plate-editor/plate-ui/input.tsx +39 -0
  207. package/src/internal/plate-editor/plate-ui/insert-toolbar-button.tsx +260 -0
  208. package/src/internal/plate-editor/plate-ui/label.tsx +1 -0
  209. package/src/internal/plate-editor/plate-ui/line-height-toolbar-button.tsx +71 -0
  210. package/src/internal/plate-editor/plate-ui/link-node-static.tsx +15 -0
  211. package/src/internal/plate-editor/plate-ui/link-node.tsx +33 -0
  212. package/src/internal/plate-editor/plate-ui/link-toolbar-button.tsx +30 -0
  213. package/src/internal/plate-editor/plate-ui/link-toolbar.tsx +149 -0
  214. package/src/internal/plate-editor/plate-ui/list-toolbar-button.tsx +179 -0
  215. package/src/internal/plate-editor/plate-ui/mark-toolbar-button.tsx +36 -0
  216. package/src/internal/plate-editor/plate-ui/media-audio-node-static.tsx +21 -0
  217. package/src/internal/plate-editor/plate-ui/media-audio-node.tsx +32 -0
  218. package/src/internal/plate-editor/plate-ui/media-embed-node.tsx +103 -0
  219. package/src/internal/plate-editor/plate-ui/media-file-node-static.tsx +30 -0
  220. package/src/internal/plate-editor/plate-ui/media-file-node.tsx +52 -0
  221. package/src/internal/plate-editor/plate-ui/media-image-node-static.tsx +37 -0
  222. package/src/internal/plate-editor/plate-ui/media-image-node.tsx +183 -0
  223. package/src/internal/plate-editor/plate-ui/media-placeholder-node.tsx +441 -0
  224. package/src/internal/plate-editor/plate-ui/media-preview-dialog.tsx +127 -0
  225. package/src/internal/plate-editor/plate-ui/media-toolbar-button.tsx +229 -0
  226. package/src/internal/plate-editor/plate-ui/media-toolbar.tsx +216 -0
  227. package/src/internal/plate-editor/plate-ui/media-upload-toast.tsx +73 -0
  228. package/src/internal/plate-editor/plate-ui/media-video-node-static.tsx +35 -0
  229. package/src/internal/plate-editor/plate-ui/media-video-node.tsx +119 -0
  230. package/src/internal/plate-editor/plate-ui/mention-node-static.tsx +46 -0
  231. package/src/internal/plate-editor/plate-ui/mention-node.tsx +79 -0
  232. package/src/internal/plate-editor/plate-ui/menu.tsx +532 -0
  233. package/src/internal/plate-editor/plate-ui/mode-toolbar-button.tsx +126 -0
  234. package/src/internal/plate-editor/plate-ui/more-toolbar-button.tsx +34 -0
  235. package/src/internal/plate-editor/plate-ui/paragraph-node-static.tsx +15 -0
  236. package/src/internal/plate-editor/plate-ui/paragraph-node.tsx +16 -0
  237. package/src/internal/plate-editor/plate-ui/popover.tsx +77 -0
  238. package/src/internal/plate-editor/plate-ui/progress.tsx +1 -0
  239. package/src/internal/plate-editor/plate-ui/remote-cursor-overlay.tsx +81 -0
  240. package/src/internal/plate-editor/plate-ui/resize-handle.tsx +88 -0
  241. package/src/internal/plate-editor/plate-ui/separator.tsx +43 -0
  242. package/src/internal/plate-editor/plate-ui/slash-node.tsx +435 -0
  243. package/src/internal/plate-editor/plate-ui/spinner.tsx +1 -0
  244. package/src/internal/plate-editor/plate-ui/suggestion-node-static.tsx +35 -0
  245. package/src/internal/plate-editor/plate-ui/suggestion-node.tsx +168 -0
  246. package/src/internal/plate-editor/plate-ui/suggestion-toolbar-button.tsx +24 -0
  247. package/src/internal/plate-editor/plate-ui/table-node-static.tsx +85 -0
  248. package/src/internal/plate-editor/plate-ui/table-node.tsx +285 -0
  249. package/src/internal/plate-editor/plate-ui/table-toolbar-button.tsx +254 -0
  250. package/src/internal/plate-editor/plate-ui/tabs.tsx +3 -0
  251. package/src/internal/plate-editor/plate-ui/textarea.tsx +58 -0
  252. package/src/internal/plate-editor/plate-ui/toc-node-static.tsx +142 -0
  253. package/src/internal/plate-editor/plate-ui/toc-node.tsx +57 -0
  254. package/src/internal/plate-editor/plate-ui/toc-sidebar.tsx +50 -0
  255. package/src/internal/plate-editor/plate-ui/toggle-node-static.tsx +18 -0
  256. package/src/internal/plate-editor/plate-ui/toggle-node.tsx +33 -0
  257. package/src/internal/plate-editor/plate-ui/toggle-toolbar-button.tsx +26 -0
  258. package/src/internal/plate-editor/plate-ui/toggle.tsx +3 -0
  259. package/src/internal/plate-editor/plate-ui/toolbar.tsx +380 -0
  260. package/src/internal/plate-editor/plate-ui/tooltip.tsx +149 -0
  261. package/src/internal/plate-editor/plate-ui/turn-into-toolbar-button.tsx +177 -0
  262. package/src/internal/plate-editor/types/index.ts +22 -0
  263. package/src/internal/plate-editor/vite.ts +284 -0
  264. package/src/internal/sheets/components/univer-sheets.tsx +1104 -0
  265. package/src/internal/sheets/i18n/context.tsx +183 -0
  266. package/src/internal/sheets/i18n/index.ts +19 -0
  267. package/src/internal/sheets/i18n/locales/de.json +21 -0
  268. package/src/internal/sheets/i18n/locales/el.json +21 -0
  269. package/src/internal/sheets/i18n/locales/en.json +21 -0
  270. package/src/internal/sheets/i18n/locales/es.json +21 -0
  271. package/src/internal/sheets/i18n/locales/fr.json +21 -0
  272. package/src/internal/sheets/i18n/locales/it.json +21 -0
  273. package/src/internal/sheets/i18n/locales/pt.json +21 -0
  274. package/src/internal/sheets/i18n/locales/sl.json +21 -0
  275. package/src/internal/sheets/i18n/locales/tr.json +21 -0
  276. package/src/internal/sheets/i18n/types.ts +23 -0
  277. package/src/internal/sheets/i18n/use-translation.ts +17 -0
  278. package/src/internal/sheets/index.ts +14 -0
  279. package/src/internal/sheets/types/css.d.ts +11 -0
  280. package/src/internal/sheets/types/index.ts +260 -0
  281. package/src/internal/sheets/xlsx.ts +1169 -0
  282. package/src/lib/api-client.ts +77 -0
  283. package/src/lib/assistant-api-actions.ts +549 -0
  284. package/src/lib/assistant-config.tsx +71 -0
  285. package/src/lib/class-utils.ts +40 -0
  286. package/src/lib/index.ts +7 -0
  287. package/src/lib/message-utils.ts +131 -0
  288. package/src/tools/tools-schema.json +512 -0
  289. package/src/types/index.ts +235 -0
  290. package/src/views/assistant-view.tsx +1137 -0
  291. package/src/views/canvas-app.tsx +839 -0
  292. package/src/views/canvas-code.tsx +93 -0
  293. package/src/views/canvas-deep-research.tsx +44 -0
  294. package/src/views/canvas-image.tsx +25 -0
  295. package/src/views/canvas-record-view.tsx +285 -0
  296. package/src/views/canvas-spreadsheet.tsx +125 -0
  297. package/src/views/canvas-text.tsx +52 -0
  298. package/src/views/canvas.tsx +274 -0
  299. package/src/views/chat-panel.tsx +149 -0
  300. package/src/views/index.ts +20 -0
  301. package/src/views/memories-panel.tsx +365 -0
  302. package/src/views/message-list.tsx +370 -0
  303. package/src/views/project-detail.tsx +257 -0
  304. package/src/views/projects-panel.tsx +131 -0
  305. package/src/views/sessions-list.tsx +98 -0
  306. package/src/views/sidebar-content.tsx +256 -0
  307. package/src/views/work-detail.tsx +98 -0
  308. package/src/vite.ts +284 -0
@@ -0,0 +1,347 @@
1
+ import { useCallback, useMemo, useReducer } from 'react';
2
+
3
+ import { type AssistantSession, type Project, type Work } from '../types';
4
+
5
+ // State type
6
+ export interface ProjectState {
7
+ // View state
8
+ view: 'list' | 'create' | 'conversation';
9
+ selectedProject: Project | null;
10
+ projectContext: { name: string; id: string; message: string } | null;
11
+
12
+ // Data
13
+ projects: Project[];
14
+ projectsLoaded: boolean;
15
+ projectThreads: Record<string, AssistantSession[]>;
16
+ projectWorks: Record<string, Work[]>;
17
+
18
+ // Edit state
19
+ isEditing: boolean;
20
+ isSaving: boolean;
21
+ isDeleting: boolean;
22
+ isDeleteDialogOpen: boolean;
23
+ name: string;
24
+ description: string;
25
+
26
+ // Form state (for create)
27
+ form: { name: string; description: string };
28
+ isCreating: boolean;
29
+
30
+ // Instructions
31
+ isEditingInstructions: boolean;
32
+ instructions: string;
33
+ isSavingInstructions: boolean;
34
+ }
35
+
36
+ // Action types
37
+ type ProjectAction
38
+ = | { type: 'SET_VIEW'; payload: 'list' | 'create' | 'conversation' }
39
+ | { type: 'SELECT_PROJECT'; payload: Project | null }
40
+ | { type: 'SET_CONTEXT'; payload: { name: string; id: string; message: string } | null }
41
+ | { type: 'SET_PROJECTS'; payload: Project[] }
42
+ | { type: 'SET_PROJECTS_LOADED'; payload: boolean }
43
+ | { type: 'SET_PROJECT_THREADS'; payload: { projectId: string; threads: AssistantSession[] } }
44
+ | { type: 'SET_PROJECT_WORKS'; payload: { projectId: string; works: Work[] } }
45
+ | { type: 'START_EDITING' }
46
+ | { type: 'STOP_EDITING' }
47
+ | { type: 'SET_SAVING'; payload: boolean }
48
+ | { type: 'SET_DELETING'; payload: boolean }
49
+ | { type: 'SET_DELETE_DIALOG'; payload: boolean }
50
+ | { type: 'SET_NAME'; payload: string }
51
+ | { type: 'SET_DESCRIPTION'; payload: string }
52
+ | { type: 'SET_FORM'; payload: { name: string; description: string } }
53
+ | { type: 'SET_CREATING'; payload: boolean }
54
+ | { type: 'START_EDITING_INSTRUCTIONS' }
55
+ | { type: 'STOP_EDITING_INSTRUCTIONS' }
56
+ | { type: 'SET_INSTRUCTIONS'; payload: string }
57
+ | { type: 'SET_SAVING_INSTRUCTIONS'; payload: boolean }
58
+ | { type: 'ADD_PROJECT'; payload: Project }
59
+ | { type: 'UPDATE_PROJECT'; payload: Project }
60
+ | { type: 'REMOVE_PROJECT'; payload: string }
61
+ | { type: 'RESET' };
62
+
63
+ // Initial state
64
+ const initialState: ProjectState = {
65
+ view: 'list',
66
+ selectedProject: null,
67
+ projectContext: null,
68
+ projects: [],
69
+ projectsLoaded: false,
70
+ projectThreads: {},
71
+ projectWorks: {},
72
+ isEditing: false,
73
+ isSaving: false,
74
+ isDeleting: false,
75
+ isDeleteDialogOpen: false,
76
+ name: '',
77
+ description: '',
78
+ form: { name: '', description: '' },
79
+ isCreating: false,
80
+ isEditingInstructions: false,
81
+ instructions: '',
82
+ isSavingInstructions: false
83
+ };
84
+
85
+ // Reducer
86
+ function projectReducer(state: ProjectState, action: ProjectAction): ProjectState {
87
+ switch (action.type) {
88
+ case 'SET_VIEW':
89
+ return { ...state, view: action.payload };
90
+
91
+ case 'SELECT_PROJECT':
92
+ return {
93
+ ...state,
94
+ selectedProject: action.payload,
95
+ name: action.payload?.name || '',
96
+ description: action.payload?.description || '',
97
+ instructions: action.payload?.instructions || ''
98
+ };
99
+
100
+ case 'SET_CONTEXT':
101
+ return { ...state, projectContext: action.payload };
102
+
103
+ case 'SET_PROJECTS':
104
+ return { ...state, projects: action.payload };
105
+
106
+ case 'SET_PROJECTS_LOADED':
107
+ return { ...state, projectsLoaded: action.payload };
108
+
109
+ case 'SET_PROJECT_THREADS':
110
+ return {
111
+ ...state,
112
+ projectThreads: {
113
+ ...state.projectThreads,
114
+ [action.payload.projectId]: action.payload.threads
115
+ }
116
+ };
117
+
118
+ case 'SET_PROJECT_WORKS':
119
+ return {
120
+ ...state,
121
+ projectWorks: {
122
+ ...state.projectWorks,
123
+ [action.payload.projectId]: action.payload.works
124
+ }
125
+ };
126
+
127
+ case 'START_EDITING':
128
+ return { ...state, isEditing: true };
129
+
130
+ case 'STOP_EDITING':
131
+ return { ...state, isEditing: false };
132
+
133
+ case 'SET_SAVING':
134
+ return { ...state, isSaving: action.payload };
135
+
136
+ case 'SET_DELETING':
137
+ return { ...state, isDeleting: action.payload };
138
+
139
+ case 'SET_DELETE_DIALOG':
140
+ return { ...state, isDeleteDialogOpen: action.payload };
141
+
142
+ case 'SET_NAME':
143
+ return { ...state, name: action.payload };
144
+
145
+ case 'SET_DESCRIPTION':
146
+ return { ...state, description: action.payload };
147
+
148
+ case 'SET_FORM':
149
+ return { ...state, form: action.payload };
150
+
151
+ case 'SET_CREATING':
152
+ return { ...state, isCreating: action.payload };
153
+
154
+ case 'START_EDITING_INSTRUCTIONS':
155
+ return { ...state, isEditingInstructions: true };
156
+
157
+ case 'STOP_EDITING_INSTRUCTIONS':
158
+ return { ...state, isEditingInstructions: false };
159
+
160
+ case 'SET_INSTRUCTIONS':
161
+ return { ...state, instructions: action.payload };
162
+
163
+ case 'SET_SAVING_INSTRUCTIONS':
164
+ return { ...state, isSavingInstructions: action.payload };
165
+
166
+ case 'ADD_PROJECT':
167
+ return { ...state, projects: [...state.projects, action.payload] };
168
+
169
+ case 'UPDATE_PROJECT':
170
+ return {
171
+ ...state,
172
+ projects: state.projects.map(p => (p.id === action.payload.id ? action.payload : p)),
173
+ selectedProject: state.selectedProject?.id === action.payload.id ? action.payload : state.selectedProject
174
+ };
175
+
176
+ case 'REMOVE_PROJECT':
177
+ return {
178
+ ...state,
179
+ projects: state.projects.filter(p => p.id !== action.payload),
180
+ selectedProject: state.selectedProject?.id === action.payload ? null : state.selectedProject
181
+ };
182
+
183
+ case 'RESET':
184
+ return initialState;
185
+
186
+ default:
187
+ return state;
188
+ }
189
+ }
190
+
191
+ // Hook
192
+ export function useProjectState() {
193
+ const [state, dispatch] = useReducer(projectReducer, initialState);
194
+
195
+ const setView = useCallback((view: 'list' | 'create' | 'conversation') => {
196
+ dispatch({ type: 'SET_VIEW', payload: view });
197
+ }, []);
198
+
199
+ const selectProject = useCallback((project: Project | null) => {
200
+ dispatch({ type: 'SELECT_PROJECT', payload: project });
201
+ }, []);
202
+
203
+ const setContext = useCallback((context: { name: string; id: string; message: string } | null) => {
204
+ dispatch({ type: 'SET_CONTEXT', payload: context });
205
+ }, []);
206
+
207
+ const setProjects = useCallback((projects: Project[]) => {
208
+ dispatch({ type: 'SET_PROJECTS', payload: projects });
209
+ }, []);
210
+
211
+ const setProjectsLoaded = useCallback((loaded: boolean) => {
212
+ dispatch({ type: 'SET_PROJECTS_LOADED', payload: loaded });
213
+ }, []);
214
+
215
+ const setProjectThreads = useCallback((projectId: string, threads: AssistantSession[]) => {
216
+ dispatch({ type: 'SET_PROJECT_THREADS', payload: { projectId, threads } });
217
+ }, []);
218
+
219
+ const setProjectWorks = useCallback((projectId: string, works: Work[]) => {
220
+ dispatch({ type: 'SET_PROJECT_WORKS', payload: { projectId, works } });
221
+ }, []);
222
+
223
+ const startEditing = useCallback(() => {
224
+ dispatch({ type: 'START_EDITING' });
225
+ }, []);
226
+
227
+ const stopEditing = useCallback(() => {
228
+ dispatch({ type: 'STOP_EDITING' });
229
+ }, []);
230
+
231
+ const setSaving = useCallback((saving: boolean) => {
232
+ dispatch({ type: 'SET_SAVING', payload: saving });
233
+ }, []);
234
+
235
+ const setDeleting = useCallback((deleting: boolean) => {
236
+ dispatch({ type: 'SET_DELETING', payload: deleting });
237
+ }, []);
238
+
239
+ const setDeleteDialogOpen = useCallback((open: boolean) => {
240
+ dispatch({ type: 'SET_DELETE_DIALOG', payload: open });
241
+ }, []);
242
+
243
+ const setName = useCallback((name: string) => {
244
+ dispatch({ type: 'SET_NAME', payload: name });
245
+ }, []);
246
+
247
+ const setDescription = useCallback((description: string) => {
248
+ dispatch({ type: 'SET_DESCRIPTION', payload: description });
249
+ }, []);
250
+
251
+ const setForm = useCallback((form: { name: string; description: string }) => {
252
+ dispatch({ type: 'SET_FORM', payload: form });
253
+ }, []);
254
+
255
+ const setCreating = useCallback((creating: boolean) => {
256
+ dispatch({ type: 'SET_CREATING', payload: creating });
257
+ }, []);
258
+
259
+ const startEditingInstructions = useCallback(() => {
260
+ dispatch({ type: 'START_EDITING_INSTRUCTIONS' });
261
+ }, []);
262
+
263
+ const stopEditingInstructions = useCallback(() => {
264
+ dispatch({ type: 'STOP_EDITING_INSTRUCTIONS' });
265
+ }, []);
266
+
267
+ const setInstructions = useCallback((instructions: string) => {
268
+ dispatch({ type: 'SET_INSTRUCTIONS', payload: instructions });
269
+ }, []);
270
+
271
+ const setSavingInstructions = useCallback((saving: boolean) => {
272
+ dispatch({ type: 'SET_SAVING_INSTRUCTIONS', payload: saving });
273
+ }, []);
274
+
275
+ const addProject = useCallback((project: Project) => {
276
+ dispatch({ type: 'ADD_PROJECT', payload: project });
277
+ }, []);
278
+
279
+ const updateProject = useCallback((project: Project) => {
280
+ dispatch({ type: 'UPDATE_PROJECT', payload: project });
281
+ }, []);
282
+
283
+ const removeProject = useCallback((id: string) => {
284
+ dispatch({ type: 'REMOVE_PROJECT', payload: id });
285
+ }, []);
286
+
287
+ const reset = useCallback(() => {
288
+ dispatch({ type: 'RESET' });
289
+ }, []);
290
+
291
+ const actions = useMemo(
292
+ () => ({
293
+ setView,
294
+ selectProject,
295
+ setContext,
296
+ setProjects,
297
+ setProjectsLoaded,
298
+ setProjectThreads,
299
+ setProjectWorks,
300
+ startEditing,
301
+ stopEditing,
302
+ setSaving,
303
+ setDeleting,
304
+ setDeleteDialogOpen,
305
+ setName,
306
+ setDescription,
307
+ setForm,
308
+ setCreating,
309
+ startEditingInstructions,
310
+ stopEditingInstructions,
311
+ setInstructions,
312
+ setSavingInstructions,
313
+ addProject,
314
+ updateProject,
315
+ removeProject,
316
+ reset
317
+ }),
318
+ [
319
+ setView,
320
+ selectProject,
321
+ setContext,
322
+ setProjects,
323
+ setProjectsLoaded,
324
+ setProjectThreads,
325
+ setProjectWorks,
326
+ startEditing,
327
+ stopEditing,
328
+ setSaving,
329
+ setDeleting,
330
+ setDeleteDialogOpen,
331
+ setName,
332
+ setDescription,
333
+ setForm,
334
+ setCreating,
335
+ startEditingInstructions,
336
+ stopEditingInstructions,
337
+ setInstructions,
338
+ setSavingInstructions,
339
+ addProject,
340
+ updateProject,
341
+ removeProject,
342
+ reset
343
+ ]
344
+ );
345
+
346
+ return { state, actions };
347
+ }
@@ -0,0 +1,207 @@
1
+ import { useCallback, useMemo, useReducer } from 'react';
2
+
3
+ import { type AssistantSession } from '../types';
4
+
5
+ // State type
6
+ export interface SessionState {
7
+ sessions: AssistantSession[];
8
+ selectedSessionId: string | null;
9
+ selectedSession: AssistantSession | null;
10
+ isEditing: boolean;
11
+ isDeleting: boolean;
12
+ isDeleteDialogOpen: boolean;
13
+ name: string;
14
+ isSaving: boolean;
15
+ searchQuery: string;
16
+ }
17
+
18
+ // Action types
19
+ type SessionAction
20
+ = | { type: 'SET_SESSIONS'; payload: AssistantSession[] }
21
+ | { type: 'SELECT_SESSION_ID'; payload: string | null }
22
+ | { type: 'SELECT_SESSION'; payload: AssistantSession | null }
23
+ | { type: 'START_EDITING' }
24
+ | { type: 'STOP_EDITING' }
25
+ | { type: 'SET_DELETING'; payload: boolean }
26
+ | { type: 'SET_DELETE_DIALOG'; payload: boolean }
27
+ | { type: 'SET_NAME'; payload: string }
28
+ | { type: 'SET_SAVING'; payload: boolean }
29
+ | { type: 'SET_SEARCH_QUERY'; payload: string }
30
+ | { type: 'ADD_SESSION'; payload: AssistantSession }
31
+ | { type: 'UPDATE_SESSION'; payload: AssistantSession }
32
+ | { type: 'REMOVE_SESSION'; payload: string }
33
+ | { type: 'RESET' };
34
+
35
+ // Initial state
36
+ const initialState: SessionState = {
37
+ sessions: [],
38
+ selectedSessionId: null,
39
+ selectedSession: null,
40
+ isEditing: false,
41
+ isDeleting: false,
42
+ isDeleteDialogOpen: false,
43
+ name: '',
44
+ isSaving: false,
45
+ searchQuery: ''
46
+ };
47
+
48
+ // Reducer
49
+ function sessionReducer(state: SessionState, action: SessionAction): SessionState {
50
+ switch (action.type) {
51
+ case 'SET_SESSIONS':
52
+ return { ...state, sessions: action.payload };
53
+
54
+ case 'SELECT_SESSION_ID':
55
+ return { ...state, selectedSessionId: action.payload };
56
+
57
+ case 'SELECT_SESSION':
58
+ return {
59
+ ...state,
60
+ selectedSession: action.payload,
61
+ name: action.payload?.title || ''
62
+ };
63
+
64
+ case 'START_EDITING':
65
+ return { ...state, isEditing: true };
66
+
67
+ case 'STOP_EDITING':
68
+ return { ...state, isEditing: false };
69
+
70
+ case 'SET_DELETING':
71
+ return { ...state, isDeleting: action.payload };
72
+
73
+ case 'SET_DELETE_DIALOG':
74
+ return { ...state, isDeleteDialogOpen: action.payload };
75
+
76
+ case 'SET_NAME':
77
+ return { ...state, name: action.payload };
78
+
79
+ case 'SET_SAVING':
80
+ return { ...state, isSaving: action.payload };
81
+
82
+ case 'SET_SEARCH_QUERY':
83
+ return { ...state, searchQuery: action.payload };
84
+
85
+ case 'ADD_SESSION':
86
+ return { ...state, sessions: [action.payload, ...state.sessions] };
87
+
88
+ case 'UPDATE_SESSION':
89
+ return {
90
+ ...state,
91
+ sessions: state.sessions.map(s => (s.id === action.payload.id ? action.payload : s)),
92
+ selectedSession: state.selectedSession?.id === action.payload.id ? action.payload : state.selectedSession
93
+ };
94
+
95
+ case 'REMOVE_SESSION':
96
+ return {
97
+ ...state,
98
+ sessions: state.sessions.filter(s => s.id !== action.payload),
99
+ selectedSession: state.selectedSession?.id === action.payload ? null : state.selectedSession,
100
+ selectedSessionId: state.selectedSessionId === action.payload ? null : state.selectedSessionId
101
+ };
102
+
103
+ case 'RESET':
104
+ return initialState;
105
+
106
+ default:
107
+ return state;
108
+ }
109
+ }
110
+
111
+ // Hook
112
+ export function useSessionState() {
113
+ const [state, dispatch] = useReducer(sessionReducer, initialState);
114
+
115
+ const setSessions = useCallback((sessions: AssistantSession[]) => {
116
+ dispatch({ type: 'SET_SESSIONS', payload: sessions });
117
+ }, []);
118
+
119
+ const selectSessionId = useCallback((id: string | null) => {
120
+ dispatch({ type: 'SELECT_SESSION_ID', payload: id });
121
+ }, []);
122
+
123
+ const selectSession = useCallback((session: AssistantSession | null) => {
124
+ dispatch({ type: 'SELECT_SESSION', payload: session });
125
+ }, []);
126
+
127
+ const startEditing = useCallback(() => {
128
+ dispatch({ type: 'START_EDITING' });
129
+ }, []);
130
+
131
+ const stopEditing = useCallback(() => {
132
+ dispatch({ type: 'STOP_EDITING' });
133
+ }, []);
134
+
135
+ const setDeleting = useCallback((deleting: boolean) => {
136
+ dispatch({ type: 'SET_DELETING', payload: deleting });
137
+ }, []);
138
+
139
+ const setDeleteDialogOpen = useCallback((open: boolean) => {
140
+ dispatch({ type: 'SET_DELETE_DIALOG', payload: open });
141
+ }, []);
142
+
143
+ const setName = useCallback((name: string) => {
144
+ dispatch({ type: 'SET_NAME', payload: name });
145
+ }, []);
146
+
147
+ const setSaving = useCallback((saving: boolean) => {
148
+ dispatch({ type: 'SET_SAVING', payload: saving });
149
+ }, []);
150
+
151
+ const setSearchQuery = useCallback((query: string) => {
152
+ dispatch({ type: 'SET_SEARCH_QUERY', payload: query });
153
+ }, []);
154
+
155
+ const addSession = useCallback((session: AssistantSession) => {
156
+ dispatch({ type: 'ADD_SESSION', payload: session });
157
+ }, []);
158
+
159
+ const updateSession = useCallback((session: AssistantSession) => {
160
+ dispatch({ type: 'UPDATE_SESSION', payload: session });
161
+ }, []);
162
+
163
+ const removeSession = useCallback((id: string) => {
164
+ dispatch({ type: 'REMOVE_SESSION', payload: id });
165
+ }, []);
166
+
167
+ const reset = useCallback(() => {
168
+ dispatch({ type: 'RESET' });
169
+ }, []);
170
+
171
+ const actions = useMemo(
172
+ () => ({
173
+ setSessions,
174
+ selectSessionId,
175
+ selectSession,
176
+ startEditing,
177
+ stopEditing,
178
+ setDeleting,
179
+ setDeleteDialogOpen,
180
+ setName,
181
+ setSaving,
182
+ setSearchQuery,
183
+ addSession,
184
+ updateSession,
185
+ removeSession,
186
+ reset
187
+ }),
188
+ [
189
+ setSessions,
190
+ selectSessionId,
191
+ selectSession,
192
+ startEditing,
193
+ stopEditing,
194
+ setDeleting,
195
+ setDeleteDialogOpen,
196
+ setName,
197
+ setSaving,
198
+ setSearchQuery,
199
+ addSession,
200
+ updateSession,
201
+ removeSession,
202
+ reset
203
+ ]
204
+ );
205
+
206
+ return { state, actions };
207
+ }
@@ -0,0 +1,137 @@
1
+ 'use client';
2
+
3
+ import {
4
+ useCallback, useEffect, useRef, useState
5
+ } from 'react';
6
+
7
+ import {
8
+ type SpeechRecognitionErrorEvent,
9
+ type SpeechRecognitionEvent,
10
+ type SpeechRecognitionInstance
11
+ } from '../types';
12
+
13
+ declare global {
14
+ interface Window {
15
+ SpeechRecognition: new () => SpeechRecognitionInstance;
16
+ webkitSpeechRecognition: new () => SpeechRecognitionInstance;
17
+ }
18
+ }
19
+
20
+ interface UseSpeechRecognitionOptions {
21
+ enabled?: boolean;
22
+ language?: string;
23
+ onTranscript?: (transcript: string) => void;
24
+ onStart?: () => void;
25
+ onEnd?: () => void;
26
+ }
27
+
28
+ interface UseSpeechRecognitionReturn {
29
+ isRecording: boolean;
30
+ recognition: SpeechRecognitionInstance | null;
31
+ handleMicrophoneClick: () => void;
32
+ }
33
+
34
+ /**
35
+ * Hook for speech recognition functionality
36
+ * Handles browser speech recognition API with callbacks for transcripts
37
+ */
38
+ export function useSpeechRecognition({
39
+ enabled = false,
40
+ language = 'en-US',
41
+ onTranscript,
42
+ onStart,
43
+ onEnd
44
+ }: UseSpeechRecognitionOptions): UseSpeechRecognitionReturn {
45
+ const [isRecording, setIsRecording] = useState(false);
46
+
47
+ // Use refs to avoid re-renders and infinite loops
48
+ const recognitionRef = useRef<SpeechRecognitionInstance | null>(null);
49
+ const onTranscriptRef = useRef(onTranscript);
50
+ const onStartRef = useRef(onStart);
51
+ const onEndRef = useRef(onEnd);
52
+
53
+ // Keep callback refs updated
54
+ useEffect(() => {
55
+ onTranscriptRef.current = onTranscript;
56
+ onStartRef.current = onStart;
57
+ onEndRef.current = onEnd;
58
+ }, [onTranscript, onStart, onEnd]);
59
+
60
+ // Initialize speech recognition (only once when enabled changes)
61
+ useEffect(() => {
62
+ if (!enabled || typeof window === 'undefined') {
63
+ recognitionRef.current = null;
64
+
65
+ return;
66
+ }
67
+
68
+ try {
69
+ const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
70
+
71
+ if (SpeechRecognition) {
72
+ const recognitionInstance = new SpeechRecognition();
73
+
74
+ recognitionInstance.continuous = false;
75
+ recognitionInstance.interimResults = false;
76
+ recognitionInstance.lang = language;
77
+
78
+ recognitionInstance.onstart = () => {
79
+ setIsRecording(true);
80
+ onStartRef.current?.();
81
+ };
82
+
83
+ recognitionInstance.onresult = (event: SpeechRecognitionEvent) => {
84
+ if (event.results && event.results.length > 0) {
85
+ const { transcript } = event.results[0][0];
86
+
87
+ onTranscriptRef.current?.(transcript);
88
+ }
89
+ setIsRecording(false);
90
+ };
91
+
92
+ recognitionInstance.onerror = (event: SpeechRecognitionErrorEvent) => {
93
+ console.error('Speech recognition error:', event.error);
94
+ setIsRecording(false);
95
+ };
96
+
97
+ recognitionInstance.onend = () => {
98
+ setIsRecording(false);
99
+ onEndRef.current?.();
100
+ };
101
+
102
+ recognitionRef.current = recognitionInstance;
103
+ }
104
+ } catch (error) {
105
+ console.error('Error initializing speech recognition:', error);
106
+ }
107
+ }, [enabled, language]);
108
+
109
+ const handleMicrophoneClick = useCallback(() => {
110
+ const recognition = recognitionRef.current;
111
+
112
+ if (!recognition) return;
113
+
114
+ if (isRecording) {
115
+ try {
116
+ recognition.stop();
117
+ setIsRecording(false);
118
+ } catch (error) {
119
+ console.error('Error stopping speech recognition:', error);
120
+ setIsRecording(false);
121
+ }
122
+ } else {
123
+ try {
124
+ recognition.start();
125
+ } catch (error) {
126
+ console.error('Error starting speech recognition:', error);
127
+ setIsRecording(false);
128
+ }
129
+ }
130
+ }, [isRecording]);
131
+
132
+ return {
133
+ isRecording,
134
+ recognition: recognitionRef.current,
135
+ handleMicrophoneClick
136
+ };
137
+ }