@peers-app/peers-ui 0.14.0 → 0.15.0
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.
- package/.github/workflows/publish.yml +8 -5
- package/babel.config.js +4 -4
- package/biome.json +191 -0
- package/dist/command-palette/command-palette-ui.d.ts +1 -2
- package/dist/command-palette/command-palette-ui.js +175 -244
- package/dist/command-palette/command-palette.js +65 -64
- package/dist/components/chat-overlay.d.ts +2 -2
- package/dist/components/chat-overlay.js +160 -217
- package/dist/components/checkbox.d.ts +5 -4
- package/dist/components/checkbox.js +4 -7
- package/dist/components/group-switcher.d.ts +1 -2
- package/dist/components/group-switcher.js +119 -159
- package/dist/components/input-date.d.ts +3 -3
- package/dist/components/input-date.js +6 -6
- package/dist/components/input-number.d.ts +7 -6
- package/dist/components/input-number.js +25 -20
- package/dist/components/input.d.ts +5 -4
- package/dist/components/input.js +4 -7
- package/dist/components/inverse-lazy-list.d.ts +3 -3
- package/dist/components/inverse-lazy-list.js +13 -47
- package/dist/components/io-schema-values.d.ts +5 -6
- package/dist/components/io-schema-values.js +28 -65
- package/dist/components/io-schema.d.ts +4 -5
- package/dist/components/io-schema.js +42 -79
- package/dist/components/lazy-list.d.ts +3 -3
- package/dist/components/lazy-list.js +38 -58
- package/dist/components/list-screen.d.ts +3 -8
- package/dist/components/list-screen.js +28 -23
- package/dist/components/loading-indicator.d.ts +1 -2
- package/dist/components/loading-indicator.js +2 -6
- package/dist/components/markdown-editor/autolink-plugin.js +5 -8
- package/dist/components/markdown-editor/editor-inline.d.ts +2 -3
- package/dist/components/markdown-editor/editor-inline.js +2 -6
- package/dist/components/markdown-editor/editor.d.ts +6 -6
- package/dist/components/markdown-editor/editor.js +9 -19
- package/dist/components/markdown-editor/markdown-plugin.d.ts +1 -1
- package/dist/components/markdown-editor/markdown-plugin.js +20 -21
- package/dist/components/markdown-editor/mention-node.d.ts +2 -2
- package/dist/components/markdown-editor/mention-node.js +24 -24
- package/dist/components/markdown-editor/mentions-plugin.d.ts +2 -2
- package/dist/components/markdown-editor/mentions-plugin.js +61 -62
- package/dist/components/markdown-editor/theme.js +28 -28
- package/dist/components/markdown-editor/toolbar.d.ts +2 -3
- package/dist/components/markdown-editor/toolbar.js +32 -49
- package/dist/components/markdown-with-mentions.d.ts +1 -1
- package/dist/components/markdown-with-mentions.js +43 -43
- package/dist/components/message-logs/message-logs.d.ts +1 -2
- package/dist/components/message-logs/message-logs.js +91 -116
- package/dist/components/messages/avatar.d.ts +3 -4
- package/dist/components/messages/avatar.js +37 -46
- package/dist/components/messages/channel-message-list.d.ts +5 -6
- package/dist/components/messages/channel-message-list.js +34 -34
- package/dist/components/messages/channel-view.d.ts +1 -2
- package/dist/components/messages/channel-view.js +23 -57
- package/dist/components/messages/message-compose.d.ts +3 -4
- package/dist/components/messages/message-compose.js +27 -38
- package/dist/components/messages/message-display.d.ts +2 -3
- package/dist/components/messages/message-display.js +42 -95
- package/dist/components/messages/thread-message-list.d.ts +4 -5
- package/dist/components/messages/thread-message-list.js +29 -29
- package/dist/components/router.d.ts +1 -2
- package/dist/components/router.js +58 -66
- package/dist/components/save-button.d.ts +3 -3
- package/dist/components/save-button.js +23 -33
- package/dist/components/sortable-list.d.ts +11 -12
- package/dist/components/sortable-list.js +42 -22
- package/dist/components/tabs.d.ts +3 -3
- package/dist/components/tabs.js +16 -47
- package/dist/components/tooltip.d.ts +4 -4
- package/dist/components/tooltip.js +4 -9
- package/dist/components/trust-level-badge.d.ts +2 -3
- package/dist/components/trust-level-badge.js +16 -16
- package/dist/components/trust-level-dropdown.d.ts +3 -4
- package/dist/components/trust-level-dropdown.js +32 -55
- package/dist/components/typeahead.d.ts +3 -3
- package/dist/components/typeahead.js +48 -89
- package/dist/components/voice-indicator.d.ts +2 -2
- package/dist/components/voice-indicator.js +93 -106
- package/dist/components/voice-subscribe-events.d.ts +32 -0
- package/dist/components/voice-subscribe-events.js +2 -0
- package/dist/globals.d.ts +3 -5
- package/dist/globals.js +22 -33
- package/dist/hooks.d.ts +5 -5
- package/dist/hooks.js +22 -12
- package/dist/hooks.test.js +129 -145
- package/dist/index.d.ts +9 -8
- package/dist/index.js +13 -12
- package/dist/mention-configs.d.ts +2 -2
- package/dist/mention-configs.js +55 -42
- package/dist/screens/assistants/assistant-config.d.ts +2 -3
- package/dist/screens/assistants/assistant-config.js +9 -22
- package/dist/screens/assistants/assistant-details.d.ts +1 -2
- package/dist/screens/assistants/assistant-details.js +13 -28
- package/dist/screens/assistants/assistant-info.d.ts +2 -3
- package/dist/screens/assistants/assistant-info.js +3 -17
- package/dist/screens/assistants/assistant-list.d.ts +1 -2
- package/dist/screens/assistants/assistant-list.js +15 -56
- package/dist/screens/assistants/assistant-tools.d.ts +2 -3
- package/dist/screens/assistants/assistant-tools.js +10 -24
- package/dist/screens/console-logs/console-logs-list.d.ts +1 -2
- package/dist/screens/console-logs/console-logs-list.js +130 -134
- package/dist/screens/console-logs/log-display.d.ts +2 -3
- package/dist/screens/console-logs/log-display.js +40 -42
- package/dist/screens/console-logs/log-filters.d.ts +1 -2
- package/dist/screens/console-logs/log-filters.js +2 -24
- package/dist/screens/console-logs/mobile-log-card.d.ts +2 -3
- package/dist/screens/console-logs/mobile-log-card.js +64 -67
- package/dist/screens/console-logs/resizable-table-header.d.ts +1 -2
- package/dist/screens/console-logs/resizable-table-header.js +31 -67
- package/dist/screens/contacts/contact-details.d.ts +1 -2
- package/dist/screens/contacts/contact-details.js +16 -46
- package/dist/screens/contacts/contact-list.d.ts +1 -2
- package/dist/screens/contacts/contact-list.js +44 -103
- package/dist/screens/contacts/index.d.ts +4 -4
- package/dist/screens/contacts/index.js +1 -1
- package/dist/screens/contacts/user-connect.d.ts +1 -2
- package/dist/screens/contacts/user-connect.js +85 -186
- package/dist/screens/data-explorer/data-explorer.d.ts +1 -2
- package/dist/screens/data-explorer/data-explorer.js +61 -181
- package/dist/screens/data-explorer/index.d.ts +2 -2
- package/dist/screens/data-explorer/query-executor.d.ts +1 -2
- package/dist/screens/data-explorer/query-executor.js +56 -166
- package/dist/screens/groups/group-details.d.ts +1 -2
- package/dist/screens/groups/group-details.js +27 -122
- package/dist/screens/groups/group-invite-listener.d.ts +2 -3
- package/dist/screens/groups/group-invite-listener.js +8 -104
- package/dist/screens/groups/group-list.d.ts +1 -2
- package/dist/screens/groups/group-list.js +56 -133
- package/dist/screens/groups/group-members.d.ts +2 -3
- package/dist/screens/groups/group-members.js +62 -132
- package/dist/screens/groups/index.d.ts +4 -4
- package/dist/screens/groups/index.js +1 -1
- package/dist/screens/join-group/index.d.ts +2 -2
- package/dist/screens/join-group/join-group.d.ts +1 -2
- package/dist/screens/join-group/join-group.js +9 -109
- package/dist/screens/network-viewer/connection-troubleshooter.d.ts +2 -3
- package/dist/screens/network-viewer/connection-troubleshooter.js +89 -193
- package/dist/screens/network-viewer/cpu-usage-graph.d.ts +1 -2
- package/dist/screens/network-viewer/cpu-usage-graph.js +60 -99
- package/dist/screens/network-viewer/device-details-modal.d.ts +1 -2
- package/dist/screens/network-viewer/device-details-modal.js +25 -177
- package/dist/screens/network-viewer/group-details-modal.d.ts +1 -2
- package/dist/screens/network-viewer/group-details-modal.js +31 -142
- package/dist/screens/network-viewer/index.d.ts +4 -4
- package/dist/screens/network-viewer/index.js +3 -3
- package/dist/screens/network-viewer/network-viewer-ipc.d.ts +22 -0
- package/dist/screens/network-viewer/network-viewer-ipc.js +6 -0
- package/dist/screens/network-viewer/network-viewer.d.ts +1 -2
- package/dist/screens/network-viewer/network-viewer.js +91 -296
- package/dist/screens/network-viewer/usage-graph.d.ts +1 -2
- package/dist/screens/network-viewer/usage-graph.js +78 -110
- package/dist/screens/packages/package-details.d.ts +1 -2
- package/dist/screens/packages/package-details.js +35 -41
- package/dist/screens/packages/package-info.d.ts +2 -2
- package/dist/screens/packages/package-info.js +33 -86
- package/dist/screens/packages/package-list.d.ts +1 -2
- package/dist/screens/packages/package-list.js +42 -106
- package/dist/screens/packages/package-new-local.d.ts +1 -2
- package/dist/screens/packages/package-new-local.js +13 -19
- package/dist/screens/packages/package-versions.d.ts +2 -3
- package/dist/screens/packages/package-versions.js +29 -96
- package/dist/screens/peer-types/peer-type-details.d.ts +3 -4
- package/dist/screens/peer-types/peer-type-details.js +26 -78
- package/dist/screens/peer-types/peer-type-list.d.ts +1 -2
- package/dist/screens/peer-types/peer-type-list.js +13 -24
- package/dist/screens/search/global-search.d.ts +1 -2
- package/dist/screens/search/global-search.js +104 -182
- package/dist/screens/settings/color-mode-dropdown.d.ts +3 -4
- package/dist/screens/settings/color-mode-dropdown.js +18 -37
- package/dist/screens/settings/settings-page.d.ts +1 -1
- package/dist/screens/settings/settings-page.js +86 -213
- package/dist/screens/settings/voice-settings-agent.d.ts +1 -1
- package/dist/screens/settings/voice-settings-agent.js +7 -44
- package/dist/screens/settings/voice-settings-api-keys.d.ts +2 -2
- package/dist/screens/settings/voice-settings-api-keys.js +2 -29
- package/dist/screens/settings/voice-settings-output.d.ts +2 -2
- package/dist/screens/settings/voice-settings-output.js +2 -40
- package/dist/screens/settings/voice-settings-providers.d.ts +2 -2
- package/dist/screens/settings/voice-settings-providers.js +2 -19
- package/dist/screens/settings/voice-settings-types.d.ts +4 -4
- package/dist/screens/settings/voice-settings-types.js +31 -31
- package/dist/screens/settings/voice-settings-wake-word.d.ts +2 -2
- package/dist/screens/settings/voice-settings-wake-word.js +2 -33
- package/dist/screens/settings/voice-settings.d.ts +1 -1
- package/dist/screens/settings/voice-settings.js +35 -112
- package/dist/screens/setup-user.d.ts +1 -2
- package/dist/screens/setup-user.js +38 -116
- package/dist/screens/tools/tool-code.d.ts +2 -3
- package/dist/screens/tools/tool-code.js +9 -13
- package/dist/screens/tools/tool-details.d.ts +1 -2
- package/dist/screens/tools/tool-details.js +26 -39
- package/dist/screens/tools/tool-info.d.ts +2 -3
- package/dist/screens/tools/tool-info.js +9 -48
- package/dist/screens/tools/tool-list.d.ts +1 -2
- package/dist/screens/tools/tool-list.js +33 -65
- package/dist/screens/tools/tool-schema.d.ts +2 -3
- package/dist/screens/tools/tool-schema.js +2 -13
- package/dist/screens/tools/tool-test-details.d.ts +1 -2
- package/dist/screens/tools/tool-test-details.js +12 -28
- package/dist/screens/tools/tool-test-list.d.ts +1 -2
- package/dist/screens/tools/tool-test-list.js +17 -56
- package/dist/screens/variables/variable-details.d.ts +1 -2
- package/dist/screens/variables/variable-details.js +19 -86
- package/dist/screens/variables/variable-list.d.ts +1 -2
- package/dist/screens/variables/variable-list.js +16 -27
- package/dist/screens/welcome-modal.d.ts +1 -2
- package/dist/screens/welcome-modal.js +44 -111
- package/dist/screens/workflows/workflow-details.d.ts +1 -2
- package/dist/screens/workflows/workflow-details.js +17 -31
- package/dist/screens/workflows/workflow-info.d.ts +2 -3
- package/dist/screens/workflows/workflow-info.js +2 -9
- package/dist/screens/workflows/workflow-instructions.d.ts +2 -3
- package/dist/screens/workflows/workflow-instructions.js +23 -55
- package/dist/screens/workflows/workflow-list.d.ts +1 -2
- package/dist/screens/workflows/workflow-list.js +23 -62
- package/dist/setupTests.d.ts +1 -1
- package/dist/setupTests.js +10 -11
- package/dist/system-apps/assistants.app.d.ts +1 -1
- package/dist/system-apps/assistants.app.js +3 -3
- package/dist/system-apps/console-logs.app.d.ts +1 -1
- package/dist/system-apps/console-logs.app.js +3 -3
- package/dist/system-apps/contacts.app.d.ts +1 -1
- package/dist/system-apps/contacts.app.js +4 -4
- package/dist/system-apps/data-explorer.app.d.ts +1 -1
- package/dist/system-apps/data-explorer.app.js +4 -4
- package/dist/system-apps/groups.app.d.ts +1 -1
- package/dist/system-apps/groups.app.js +4 -4
- package/dist/system-apps/index.d.ts +17 -17
- package/dist/system-apps/index.js +52 -52
- package/dist/system-apps/join-group.app.d.ts +1 -1
- package/dist/system-apps/join-group.app.js +4 -4
- package/dist/system-apps/mobile-settings.app.d.ts +1 -1
- package/dist/system-apps/mobile-settings.app.js +3 -3
- package/dist/system-apps/network-viewer.app.d.ts +1 -1
- package/dist/system-apps/network-viewer.app.js +4 -4
- package/dist/system-apps/packages.app.d.ts +1 -1
- package/dist/system-apps/packages.app.js +3 -3
- package/dist/system-apps/search.app.d.ts +1 -1
- package/dist/system-apps/search.app.js +4 -4
- package/dist/system-apps/settings.app.d.ts +1 -1
- package/dist/system-apps/settings.app.js +3 -3
- package/dist/system-apps/threads.app.d.ts +1 -1
- package/dist/system-apps/threads.app.js +3 -3
- package/dist/system-apps/tools.app.d.ts +1 -1
- package/dist/system-apps/tools.app.js +3 -3
- package/dist/system-apps/types.app.d.ts +1 -1
- package/dist/system-apps/types.app.js +3 -3
- package/dist/system-apps/variables.app.d.ts +1 -1
- package/dist/system-apps/variables.app.js +3 -3
- package/dist/system-apps/workflows.app.d.ts +1 -1
- package/dist/system-apps/workflows.app.js +3 -3
- package/dist/tabs-layout/tabs-layout.d.ts +2 -3
- package/dist/tabs-layout/tabs-layout.js +215 -246
- package/dist/tabs-layout/tabs-state.d.ts +2 -2
- package/dist/tabs-layout/tabs-state.js +73 -61
- package/dist/ui-defaults/index.d.ts +2 -2
- package/dist/ui-defaults/list-screen.d.ts +2 -3
- package/dist/ui-defaults/list-screen.js +33 -37
- package/dist/ui-defaults/markdown-field.js +24 -56
- package/dist/ui-router/routes-loader.d.ts +1 -1
- package/dist/ui-router/routes-loader.js +17 -13
- package/dist/ui-router/ui-loader.d.ts +6 -6
- package/dist/ui-router/ui-loader.js +172 -268
- package/dist/utils.js +49 -39
- package/jest.config.js +16 -16
- package/package.json +16 -14
- package/src/command-palette/command-palette-ui.tsx +261 -237
- package/src/command-palette/command-palette.ts +81 -78
- package/src/components/chat-overlay.tsx +366 -261
- package/src/components/checkbox.tsx +15 -12
- package/src/components/group-switcher.tsx +150 -105
- package/src/components/input-date.tsx +17 -16
- package/src/components/input-number.tsx +47 -31
- package/src/components/input.tsx +15 -12
- package/src/components/inverse-lazy-list.tsx +14 -13
- package/src/components/io-schema-values.tsx +51 -69
- package/src/components/io-schema.tsx +94 -69
- package/src/components/lazy-list.tsx +51 -34
- package/src/components/list-screen.tsx +51 -35
- package/src/components/loading-indicator.tsx +2 -4
- package/src/components/markdown-editor/autolink-plugin.tsx +4 -11
- package/src/components/markdown-editor/editor-inline.tsx +3 -4
- package/src/components/markdown-editor/editor.tsx +53 -51
- package/src/components/markdown-editor/markdown-plugin.tsx +48 -40
- package/src/components/markdown-editor/mention-node.ts +39 -38
- package/src/components/markdown-editor/mentions-plugin.tsx +99 -101
- package/src/components/markdown-editor/theme.ts +28 -29
- package/src/components/markdown-editor/toolbar.tsx +53 -47
- package/src/components/markdown-with-mentions.tsx +56 -46
- package/src/components/message-logs/message-logs.tsx +225 -165
- package/src/components/messages/avatar.tsx +70 -52
- package/src/components/messages/channel-message-list.tsx +80 -68
- package/src/components/messages/channel-view.tsx +34 -33
- package/src/components/messages/message-compose.tsx +84 -67
- package/src/components/messages/message-display.tsx +103 -89
- package/src/components/messages/thread-message-list.tsx +53 -44
- package/src/components/router.tsx +42 -43
- package/src/components/save-button.tsx +43 -39
- package/src/components/sortable-list.tsx +77 -49
- package/src/components/tabs.tsx +31 -31
- package/src/components/tooltip.tsx +21 -28
- package/src/components/trust-level-badge.tsx +15 -11
- package/src/components/trust-level-dropdown.tsx +49 -19
- package/src/components/typeahead.tsx +57 -59
- package/src/components/voice-indicator.tsx +158 -141
- package/src/components/voice-subscribe-events.ts +20 -0
- package/src/globals.tsx +42 -40
- package/src/hooks.test.tsx +141 -134
- package/src/hooks.ts +80 -48
- package/src/index.tsx +17 -10
- package/src/mention-configs.ts +122 -68
- package/src/screens/assistants/assistant-config.tsx +28 -18
- package/src/screens/assistants/assistant-details.tsx +35 -36
- package/src/screens/assistants/assistant-info.tsx +16 -11
- package/src/screens/assistants/assistant-list.tsx +37 -34
- package/src/screens/assistants/assistant-tools.tsx +41 -20
- package/src/screens/console-logs/console-logs-list.tsx +173 -140
- package/src/screens/console-logs/log-display.tsx +65 -38
- package/src/screens/console-logs/log-filters.tsx +4 -3
- package/src/screens/console-logs/mobile-log-card.tsx +78 -71
- package/src/screens/console-logs/resizable-table-header.tsx +29 -21
- package/src/screens/contacts/contact-details.tsx +29 -30
- package/src/screens/contacts/contact-list.tsx +71 -60
- package/src/screens/contacts/index.ts +5 -5
- package/src/screens/contacts/user-connect.tsx +177 -171
- package/src/screens/data-explorer/data-explorer.tsx +134 -98
- package/src/screens/data-explorer/index.ts +2 -3
- package/src/screens/data-explorer/query-executor.tsx +90 -80
- package/src/screens/groups/group-details.tsx +120 -101
- package/src/screens/groups/group-invite-listener.tsx +34 -37
- package/src/screens/groups/group-list.tsx +119 -103
- package/src/screens/groups/group-members.tsx +225 -164
- package/src/screens/groups/index.ts +5 -6
- package/src/screens/join-group/index.ts +2 -2
- package/src/screens/join-group/join-group.tsx +41 -39
- package/src/screens/network-viewer/connection-troubleshooter.tsx +145 -104
- package/src/screens/network-viewer/cpu-usage-graph.tsx +39 -43
- package/src/screens/network-viewer/device-details-modal.tsx +46 -59
- package/src/screens/network-viewer/group-details-modal.tsx +68 -49
- package/src/screens/network-viewer/index.ts +4 -5
- package/src/screens/network-viewer/network-viewer-ipc.ts +23 -0
- package/src/screens/network-viewer/network-viewer.tsx +261 -236
- package/src/screens/network-viewer/usage-graph.tsx +57 -49
- package/src/screens/packages/package-details.tsx +43 -35
- package/src/screens/packages/package-info.tsx +107 -66
- package/src/screens/packages/package-list.tsx +175 -98
- package/src/screens/packages/package-new-local.tsx +28 -26
- package/src/screens/packages/package-versions.tsx +102 -77
- package/src/screens/peer-types/peer-type-details.tsx +60 -50
- package/src/screens/peer-types/peer-type-list.tsx +20 -30
- package/src/screens/search/global-search.tsx +153 -137
- package/src/screens/settings/color-mode-dropdown.tsx +52 -35
- package/src/screens/settings/settings-page.tsx +215 -141
- package/src/screens/settings/voice-settings-agent.tsx +13 -12
- package/src/screens/settings/voice-settings-api-keys.tsx +14 -12
- package/src/screens/settings/voice-settings-output.tsx +12 -11
- package/src/screens/settings/voice-settings-providers.tsx +7 -3
- package/src/screens/settings/voice-settings-types.ts +52 -49
- package/src/screens/settings/voice-settings-wake-word.tsx +25 -9
- package/src/screens/settings/voice-settings.tsx +66 -43
- package/src/screens/setup-user.tsx +88 -41
- package/src/screens/tools/tool-code.tsx +12 -17
- package/src/screens/tools/tool-details.tsx +28 -28
- package/src/screens/tools/tool-info.tsx +14 -19
- package/src/screens/tools/tool-list.tsx +58 -40
- package/src/screens/tools/tool-schema.tsx +16 -9
- package/src/screens/tools/tool-test-details.tsx +11 -22
- package/src/screens/tools/tool-test-list.tsx +29 -30
- package/src/screens/variables/variable-details.tsx +63 -51
- package/src/screens/variables/variable-list.tsx +29 -30
- package/src/screens/welcome-modal.tsx +68 -48
- package/src/screens/workflows/workflow-details.tsx +40 -30
- package/src/screens/workflows/workflow-info.tsx +4 -11
- package/src/screens/workflows/workflow-instructions.tsx +35 -28
- package/src/screens/workflows/workflow-list.tsx +50 -40
- package/src/setupTests.ts +14 -13
- package/src/system-apps/assistants.app.ts +5 -5
- package/src/system-apps/console-logs.app.ts +4 -4
- package/src/system-apps/contacts.app.ts +6 -6
- package/src/system-apps/data-explorer.app.ts +5 -5
- package/src/system-apps/groups.app.ts +6 -6
- package/src/system-apps/index.ts +49 -49
- package/src/system-apps/join-group.app.ts +5 -5
- package/src/system-apps/mobile-settings.app.ts +4 -5
- package/src/system-apps/network-viewer.app.ts +5 -5
- package/src/system-apps/packages.app.ts +5 -5
- package/src/system-apps/search.app.ts +6 -6
- package/src/system-apps/settings.app.ts +5 -5
- package/src/system-apps/threads.app.ts +5 -5
- package/src/system-apps/tools.app.ts +5 -5
- package/src/system-apps/types.app.ts +5 -5
- package/src/system-apps/variables.app.ts +5 -5
- package/src/system-apps/workflows.app.ts +5 -5
- package/src/tabs-layout/tabs-layout.tsx +345 -254
- package/src/tabs-layout/tabs-state.ts +100 -81
- package/src/ui-defaults/index.ts +2 -3
- package/src/ui-defaults/list-screen.tsx +45 -40
- package/src/ui-defaults/markdown-field.tsx +22 -26
- package/src/ui-router/routes-loader.ts +40 -24
- package/src/ui-router/ui-loader.tsx +312 -214
- package/src/utils.ts +68 -81
- package/tsconfig.json +5 -10
- package/dist/components/input-datetime.d.ts +0 -7
- package/dist/components/input-datetime.js +0 -35
- package/dist/components/lazy-sortable-list.d.ts +0 -29
- package/dist/components/lazy-sortable-list.js +0 -12
- package/dist/components/left-bar.d.ts +0 -5
- package/dist/components/left-bar.js +0 -207
- package/dist/components/main-content-container.d.ts +0 -2
- package/dist/components/main-content-container.js +0 -92
- package/dist/components/messages/thread-view.d.ts +0 -6
- package/dist/components/messages/thread-view.js +0 -174
- package/dist/components/off-canvas.d.ts +0 -13
- package/dist/components/off-canvas.js +0 -89
- package/dist/components/text-list-editor.tsx/text-list-editor.d.ts +0 -6
- package/dist/components/text-list-editor.tsx/text-list-editor.js +0 -13
- package/dist/components/top-bar.d.ts +0 -2
- package/dist/components/top-bar.js +0 -51
- package/dist/components/typeahead/mentions-plugin.d.ts +0 -7
- package/dist/components/typeahead/mentions-plugin.js +0 -203
- package/dist/components/typeahead/typeahead-editor.d.ts +0 -15
- package/dist/components/typeahead/typeahead-editor.js +0 -134
- package/dist/components/typeahead/typeahead.d.ts +0 -12
- package/dist/components/typeahead/typeahead.js +0 -94
- package/dist/screens/profile.d.ts +0 -2
- package/dist/screens/profile.js +0 -76
- package/src/components/input-datetime.tsx +0 -41
- package/src/components/lazy-sortable-list.tsx +0 -51
- package/src/components/left-bar.tsx +0 -322
- package/src/components/main-content-container.tsx +0 -79
- package/src/components/messages/thread-view.tsx +0 -214
- package/src/components/off-canvas.tsx +0 -83
- package/src/components/text-list-editor.tsx/text-list-editor.tsx +0 -13
- package/src/components/top-bar.tsx +0 -119
- package/src/components/typeahead/mentions-plugin.tsx +0 -265
- package/src/components/typeahead/typeahead-editor.tsx +0 -140
- package/src/components/typeahead/typeahead.tsx +0 -77
- package/src/screens/profile.tsx +0 -75
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import { Tooltip } from
|
|
3
|
-
import {
|
|
1
|
+
import type React from "react";
|
|
2
|
+
import { Tooltip } from "../../components/tooltip";
|
|
3
|
+
import {
|
|
4
|
+
PICOVOICE_KEY_ERROR_MESSAGES,
|
|
5
|
+
type PicovoiceKeyError,
|
|
6
|
+
type VoiceSettings,
|
|
7
|
+
} from "./voice-settings-types";
|
|
4
8
|
|
|
5
9
|
interface ApiKeysProps {
|
|
6
10
|
settings: VoiceSettings;
|
|
@@ -26,22 +30,22 @@ export const VoiceSettingsApiKeys: React.FC<ApiKeysProps> = ({
|
|
|
26
30
|
<label className="form-label">
|
|
27
31
|
Picovoice Access Key
|
|
28
32
|
<Tooltip markdownContent="Required for wake word detection. Get a free key at [console.picovoice.ai](https://console.picovoice.ai)" />
|
|
29
|
-
{settings.picovoiceAccessKeySet &&
|
|
30
|
-
<span className="badge bg-success ms-2">Set</span>
|
|
31
|
-
)}
|
|
33
|
+
{settings.picovoiceAccessKeySet && <span className="badge bg-success ms-2">Set</span>}
|
|
32
34
|
</label>
|
|
33
35
|
<input
|
|
34
36
|
type="password"
|
|
35
37
|
className="form-control"
|
|
36
38
|
value={picovoiceKey}
|
|
37
39
|
onChange={(e) => onPicovoiceKeyChange(e.target.value)}
|
|
38
|
-
placeholder={
|
|
40
|
+
placeholder={
|
|
41
|
+
settings.picovoiceAccessKeySet ? "••••••••••••••••" : "Enter your Picovoice access key"
|
|
42
|
+
}
|
|
39
43
|
/>
|
|
40
44
|
<small className="text-muted">
|
|
41
45
|
<a href="https://console.picovoice.ai" target="_blank" rel="noopener noreferrer">
|
|
42
46
|
Get a free access key
|
|
43
47
|
</a>
|
|
44
|
-
{settings.picovoiceAccessKeySet &&
|
|
48
|
+
{settings.picovoiceAccessKeySet && " (leave blank to keep existing key)"}
|
|
45
49
|
</small>
|
|
46
50
|
</div>
|
|
47
51
|
|
|
@@ -70,16 +74,14 @@ export const VoiceSettingsApiKeys: React.FC<ApiKeysProps> = ({
|
|
|
70
74
|
<label className="form-label">
|
|
71
75
|
OpenAI API Key
|
|
72
76
|
<Tooltip markdownContent="Required for cloud STT (Whisper) and cloud TTS. Leave empty to use local/browser alternatives." />
|
|
73
|
-
{settings.openaiApiKeySet &&
|
|
74
|
-
<span className="badge bg-success ms-2">Set</span>
|
|
75
|
-
)}
|
|
77
|
+
{settings.openaiApiKeySet && <span className="badge bg-success ms-2">Set</span>}
|
|
76
78
|
</label>
|
|
77
79
|
<input
|
|
78
80
|
type="password"
|
|
79
81
|
className="form-control"
|
|
80
82
|
value={openaiKey}
|
|
81
83
|
onChange={(e) => onOpenaiKeyChange(e.target.value)}
|
|
82
|
-
placeholder={settings.openaiApiKeySet ?
|
|
84
|
+
placeholder={settings.openaiApiKeySet ? "••••••••••••••••" : "sk-..."}
|
|
83
85
|
/>
|
|
84
86
|
{settings.openaiApiKeySet && (
|
|
85
87
|
<small className="text-muted">Leave blank to keep existing key</small>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import {
|
|
1
|
+
import type React from "react";
|
|
2
|
+
import { OPENAI_TTS_VOICES, type VoiceSettings } from "./voice-settings-types";
|
|
3
3
|
|
|
4
4
|
interface OutputProps {
|
|
5
5
|
settings: VoiceSettings;
|
|
@@ -27,16 +27,16 @@ export const VoiceSettingsOutput: React.FC<OutputProps> = ({
|
|
|
27
27
|
onTestRecording,
|
|
28
28
|
}) => (
|
|
29
29
|
<>
|
|
30
|
-
{localSettings.ttsProvider ===
|
|
30
|
+
{localSettings.ttsProvider === "cloud" && (
|
|
31
31
|
<div className="mb-3">
|
|
32
32
|
<label className="form-label">Voice</label>
|
|
33
33
|
<select
|
|
34
34
|
className="form-select"
|
|
35
|
-
value={localSettings.ttsVoice ||
|
|
35
|
+
value={localSettings.ttsVoice || "nova"}
|
|
36
36
|
onChange={(e) => onChange({ ttsVoice: e.target.value })}
|
|
37
37
|
disabled={saving}
|
|
38
38
|
>
|
|
39
|
-
{OPENAI_TTS_VOICES.map(voice => (
|
|
39
|
+
{OPENAI_TTS_VOICES.map((voice) => (
|
|
40
40
|
<option key={voice.id} value={voice.id}>
|
|
41
41
|
{voice.name} - {voice.description}
|
|
42
42
|
</option>
|
|
@@ -46,9 +46,7 @@ export const VoiceSettingsOutput: React.FC<OutputProps> = ({
|
|
|
46
46
|
)}
|
|
47
47
|
|
|
48
48
|
<div className="mb-4">
|
|
49
|
-
<label className="form-label">
|
|
50
|
-
Speaking Speed: {localSettings.ttsSpeed.toFixed(1)}x
|
|
51
|
-
</label>
|
|
49
|
+
<label className="form-label">Speaking Speed: {localSettings.ttsSpeed.toFixed(1)}x</label>
|
|
52
50
|
<input
|
|
53
51
|
type="range"
|
|
54
52
|
className="form-range"
|
|
@@ -78,14 +76,16 @@ export const VoiceSettingsOutput: React.FC<OutputProps> = ({
|
|
|
78
76
|
className="btn btn-outline-primary"
|
|
79
77
|
type="button"
|
|
80
78
|
onClick={onTestTTS}
|
|
81
|
-
disabled={
|
|
79
|
+
disabled={
|
|
80
|
+
!settings.enabled && localSettings.ttsProvider === "cloud" && !settings.openaiApiKeySet
|
|
81
|
+
}
|
|
82
82
|
>
|
|
83
83
|
<i className="bi bi-play-fill me-1"></i>
|
|
84
84
|
Speak
|
|
85
85
|
</button>
|
|
86
86
|
</div>
|
|
87
87
|
<small className="text-muted">
|
|
88
|
-
{hasUnsavedChanges &&
|
|
88
|
+
{hasUnsavedChanges && "Save changes first to test with new settings"}
|
|
89
89
|
</small>
|
|
90
90
|
</div>
|
|
91
91
|
|
|
@@ -94,7 +94,8 @@ export const VoiceSettingsOutput: React.FC<OutputProps> = ({
|
|
|
94
94
|
<div className="mb-4">
|
|
95
95
|
<h6 className="mb-3">Test Voice Input</h6>
|
|
96
96
|
<p className="text-muted small">
|
|
97
|
-
Click the button below to test voice recording. Speak and it will stop when silence is
|
|
97
|
+
Click the button below to test voice recording. Speak and it will stop when silence is
|
|
98
|
+
detected.
|
|
98
99
|
</p>
|
|
99
100
|
<button
|
|
100
101
|
className="btn btn-primary"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import {
|
|
1
|
+
import type React from "react";
|
|
2
|
+
import type { STTProvider, TTSProvider, VoiceSettings } from "./voice-settings-types";
|
|
3
3
|
|
|
4
4
|
interface ProvidersProps {
|
|
5
5
|
localSettings: VoiceSettings;
|
|
@@ -7,7 +7,11 @@ interface ProvidersProps {
|
|
|
7
7
|
onChange: (patch: Partial<VoiceSettings>) => void;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
export const VoiceSettingsProviders: React.FC<ProvidersProps> = ({
|
|
10
|
+
export const VoiceSettingsProviders: React.FC<ProvidersProps> = ({
|
|
11
|
+
localSettings,
|
|
12
|
+
saving,
|
|
13
|
+
onChange,
|
|
14
|
+
}) => (
|
|
11
15
|
<>
|
|
12
16
|
<h6 className="mb-3">Speech to Text (STT)</h6>
|
|
13
17
|
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
export type STTProvider =
|
|
2
|
-
export type TTSProvider =
|
|
3
|
-
export type PicovoiceKeyError =
|
|
1
|
+
export type STTProvider = "auto" | "cloud" | "local";
|
|
2
|
+
export type TTSProvider = "browser" | "cloud";
|
|
3
|
+
export type PicovoiceKeyError = "refused" | "invalid" | "limit" | "throttled";
|
|
4
4
|
export type BuiltinWakeWord =
|
|
5
|
-
|
|
|
6
|
-
|
|
|
7
|
-
|
|
|
8
|
-
|
|
|
9
|
-
|
|
|
10
|
-
|
|
|
11
|
-
|
|
|
12
|
-
|
|
|
13
|
-
|
|
|
14
|
-
|
|
|
15
|
-
|
|
|
16
|
-
|
|
|
17
|
-
|
|
|
18
|
-
|
|
|
5
|
+
| "ALEXA"
|
|
6
|
+
| "AMERICANO"
|
|
7
|
+
| "BLUEBERRY"
|
|
8
|
+
| "BUMBLEBEE"
|
|
9
|
+
| "COMPUTER"
|
|
10
|
+
| "GRAPEFRUIT"
|
|
11
|
+
| "GRASSHOPPER"
|
|
12
|
+
| "HEY_GOOGLE"
|
|
13
|
+
| "HEY_SIRI"
|
|
14
|
+
| "JARVIS"
|
|
15
|
+
| "OK_GOOGLE"
|
|
16
|
+
| "PICOVOICE"
|
|
17
|
+
| "PORCUPINE"
|
|
18
|
+
| "TERMINATOR";
|
|
19
19
|
|
|
20
20
|
export interface VoiceSettingsData {
|
|
21
21
|
enabled: boolean;
|
|
@@ -37,55 +37,58 @@ export interface VoiceSettings extends VoiceSettingsData {
|
|
|
37
37
|
export const DEFAULT_SETTINGS: VoiceSettingsData = {
|
|
38
38
|
enabled: false,
|
|
39
39
|
voiceOutputEnabled: true,
|
|
40
|
-
wakeWord:
|
|
40
|
+
wakeWord: "COMPUTER",
|
|
41
41
|
wakeWordSensitivity: 0.5,
|
|
42
42
|
speechSensitivity: 0.7,
|
|
43
|
-
sttProvider:
|
|
44
|
-
ttsProvider:
|
|
43
|
+
sttProvider: "auto",
|
|
44
|
+
ttsProvider: "browser",
|
|
45
45
|
ttsSpeed: 1.0,
|
|
46
46
|
};
|
|
47
47
|
|
|
48
48
|
export const BUILTIN_WAKE_WORDS: { id: BuiltinWakeWord; name: string }[] = [
|
|
49
|
-
{ id:
|
|
50
|
-
{ id:
|
|
51
|
-
{ id:
|
|
52
|
-
{ id:
|
|
53
|
-
{ id:
|
|
54
|
-
{ id:
|
|
55
|
-
{ id:
|
|
56
|
-
{ id:
|
|
57
|
-
{ id:
|
|
58
|
-
{ id:
|
|
59
|
-
{ id:
|
|
60
|
-
{ id:
|
|
61
|
-
{ id:
|
|
62
|
-
{ id:
|
|
49
|
+
{ id: "ALEXA", name: "Alexa" },
|
|
50
|
+
{ id: "AMERICANO", name: "Americano" },
|
|
51
|
+
{ id: "BLUEBERRY", name: "Blueberry" },
|
|
52
|
+
{ id: "BUMBLEBEE", name: "Bumblebee" },
|
|
53
|
+
{ id: "COMPUTER", name: "Computer" },
|
|
54
|
+
{ id: "GRAPEFRUIT", name: "Grapefruit" },
|
|
55
|
+
{ id: "GRASSHOPPER", name: "Grasshopper" },
|
|
56
|
+
{ id: "HEY_GOOGLE", name: "Hey Google" },
|
|
57
|
+
{ id: "HEY_SIRI", name: "Hey Siri" },
|
|
58
|
+
{ id: "JARVIS", name: "Jarvis" },
|
|
59
|
+
{ id: "OK_GOOGLE", name: "Ok Google" },
|
|
60
|
+
{ id: "PICOVOICE", name: "Picovoice" },
|
|
61
|
+
{ id: "PORCUPINE", name: "Porcupine" },
|
|
62
|
+
{ id: "TERMINATOR", name: "Terminator" },
|
|
63
63
|
];
|
|
64
64
|
|
|
65
|
-
export const PICOVOICE_KEY_ERROR_MESSAGES: Record<
|
|
65
|
+
export const PICOVOICE_KEY_ERROR_MESSAGES: Record<
|
|
66
|
+
PicovoiceKeyError,
|
|
67
|
+
{ heading: string; body: string }
|
|
68
|
+
> = {
|
|
66
69
|
refused: {
|
|
67
|
-
heading:
|
|
68
|
-
body:
|
|
70
|
+
heading: "Picovoice access key refused",
|
|
71
|
+
body: "Your key was rejected — it may have been revoked or banned. Generate a new key at console.picovoice.ai and paste it below.",
|
|
69
72
|
},
|
|
70
73
|
invalid: {
|
|
71
|
-
heading:
|
|
72
|
-
body:
|
|
74
|
+
heading: "Picovoice access key invalid",
|
|
75
|
+
body: "Your key is malformed or expired. Generate a new key at console.picovoice.ai and paste it below.",
|
|
73
76
|
},
|
|
74
77
|
limit: {
|
|
75
|
-
heading:
|
|
76
|
-
body:
|
|
78
|
+
heading: "Picovoice device limit reached",
|
|
79
|
+
body: "Your key has been activated on too many devices. Go to console.picovoice.ai to deactivate old devices, generate a new key, or upgrade your plan.",
|
|
77
80
|
},
|
|
78
81
|
throttled: {
|
|
79
|
-
heading:
|
|
80
|
-
body:
|
|
82
|
+
heading: "Picovoice activation throttled",
|
|
83
|
+
body: "Too many activation attempts. Please wait a moment, then save your settings again to retry.",
|
|
81
84
|
},
|
|
82
85
|
};
|
|
83
86
|
|
|
84
87
|
export const OPENAI_TTS_VOICES = [
|
|
85
|
-
{ id:
|
|
86
|
-
{ id:
|
|
87
|
-
{ id:
|
|
88
|
-
{ id:
|
|
89
|
-
{ id:
|
|
90
|
-
{ id:
|
|
88
|
+
{ id: "alloy", name: "Alloy", description: "Neutral and balanced" },
|
|
89
|
+
{ id: "echo", name: "Echo", description: "Warm and clear" },
|
|
90
|
+
{ id: "fable", name: "Fable", description: "Expressive and dynamic" },
|
|
91
|
+
{ id: "onyx", name: "Onyx", description: "Deep and authoritative" },
|
|
92
|
+
{ id: "nova", name: "Nova", description: "Friendly and upbeat" },
|
|
93
|
+
{ id: "shimmer", name: "Shimmer", description: "Soft and gentle" },
|
|
91
94
|
];
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import React from
|
|
2
|
-
import { Tooltip } from
|
|
3
|
-
import {
|
|
1
|
+
import type React from "react";
|
|
2
|
+
import { Tooltip } from "../../components/tooltip";
|
|
3
|
+
import {
|
|
4
|
+
BUILTIN_WAKE_WORDS,
|
|
5
|
+
type BuiltinWakeWord,
|
|
6
|
+
type VoiceSettings,
|
|
7
|
+
} from "./voice-settings-types";
|
|
4
8
|
|
|
5
9
|
interface WakeWordProps {
|
|
6
10
|
localSettings: VoiceSettings;
|
|
@@ -8,7 +12,11 @@ interface WakeWordProps {
|
|
|
8
12
|
onChange: (patch: Partial<VoiceSettings>) => void;
|
|
9
13
|
}
|
|
10
14
|
|
|
11
|
-
export const VoiceSettingsWakeWord: React.FC<WakeWordProps> = ({
|
|
15
|
+
export const VoiceSettingsWakeWord: React.FC<WakeWordProps> = ({
|
|
16
|
+
localSettings,
|
|
17
|
+
saving,
|
|
18
|
+
onChange,
|
|
19
|
+
}) => (
|
|
12
20
|
<>
|
|
13
21
|
<div className="mb-4">
|
|
14
22
|
<label className="form-label">
|
|
@@ -21,7 +29,7 @@ export const VoiceSettingsWakeWord: React.FC<WakeWordProps> = ({ localSettings,
|
|
|
21
29
|
onChange={(e) => onChange({ wakeWord: e.target.value as BuiltinWakeWord })}
|
|
22
30
|
disabled={saving}
|
|
23
31
|
>
|
|
24
|
-
{BUILTIN_WAKE_WORDS.map(word => (
|
|
32
|
+
{BUILTIN_WAKE_WORDS.map((word) => (
|
|
25
33
|
<option key={word.id} value={word.id}>
|
|
26
34
|
{word.name}
|
|
27
35
|
</option>
|
|
@@ -68,10 +76,18 @@ export const VoiceSettingsWakeWord: React.FC<WakeWordProps> = ({ localSettings,
|
|
|
68
76
|
<small className="text-muted">Quiet / Close mic</small>
|
|
69
77
|
</div>
|
|
70
78
|
<div className="d-flex justify-content-between px-1">
|
|
71
|
-
<small className="text-muted" style={{ fontSize:
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
<small className="text-muted" style={{ fontSize:
|
|
79
|
+
<small className="text-muted" style={{ fontSize: "0.7rem" }}>
|
|
80
|
+
0.2 — Shout
|
|
81
|
+
</small>
|
|
82
|
+
<small className="text-muted" style={{ fontSize: "0.7rem" }}>
|
|
83
|
+
0.5 — Normal
|
|
84
|
+
</small>
|
|
85
|
+
<small className="text-muted" style={{ fontSize: "0.7rem" }}>
|
|
86
|
+
0.7 — Desk
|
|
87
|
+
</small>
|
|
88
|
+
<small className="text-muted" style={{ fontSize: "0.7rem" }}>
|
|
89
|
+
0.9 — Whisper
|
|
90
|
+
</small>
|
|
75
91
|
</div>
|
|
76
92
|
</div>
|
|
77
93
|
</>
|
|
@@ -1,24 +1,36 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Voice Settings Component
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Settings panel for voice input configuration.
|
|
5
5
|
* Settings are stored directly via pvars (auto-synced).
|
|
6
6
|
* Keys are stored as secure pvars (write-only).
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
9
|
+
import { rpcServerCalls, userVar } from "@peers-app/peers-sdk";
|
|
10
|
+
import type React from "react";
|
|
11
|
+
import { useCallback, useEffect, useState } from "react";
|
|
12
|
+
import { VoiceSettingsAgent } from "./voice-settings-agent";
|
|
13
|
+
import { VoiceSettingsApiKeys } from "./voice-settings-api-keys";
|
|
14
|
+
import { VoiceSettingsOutput } from "./voice-settings-output";
|
|
15
|
+
import { VoiceSettingsProviders } from "./voice-settings-providers";
|
|
16
|
+
import {
|
|
17
|
+
BUILTIN_WAKE_WORDS,
|
|
18
|
+
DEFAULT_SETTINGS,
|
|
19
|
+
type PicovoiceKeyError,
|
|
20
|
+
type VoiceSettingsData,
|
|
21
|
+
type VoiceSettings as VoiceSettingsType,
|
|
22
|
+
} from "./voice-settings-types";
|
|
23
|
+
import { VoiceSettingsWakeWord } from "./voice-settings-wake-word";
|
|
17
24
|
|
|
18
25
|
// Pvars - shared with voice service (writes here trigger service updates)
|
|
19
|
-
const voiceSettingsPvar = userVar<VoiceSettingsData>(
|
|
20
|
-
|
|
21
|
-
|
|
26
|
+
const voiceSettingsPvar = userVar<VoiceSettingsData>("voiceSettings", {
|
|
27
|
+
defaultValue: DEFAULT_SETTINGS,
|
|
28
|
+
});
|
|
29
|
+
const picovoiceKeyPvar = userVar<string>("PICOVOICE_ACCESS_KEY", {
|
|
30
|
+
isSecret: true,
|
|
31
|
+
defaultValue: "",
|
|
32
|
+
});
|
|
33
|
+
const openaiKeyPvar = userVar<string>("OPENAI_API_KEY", { isSecret: true, defaultValue: "" });
|
|
22
34
|
|
|
23
35
|
export const VoiceSettings: React.FC = () => {
|
|
24
36
|
const [settings, setSettings] = useState<VoiceSettingsType>({ ...DEFAULT_SETTINGS });
|
|
@@ -28,14 +40,14 @@ export const VoiceSettings: React.FC = () => {
|
|
|
28
40
|
const [success, setSuccess] = useState<string | null>(null);
|
|
29
41
|
const [audioDevices, setAudioDevices] = useState<string[]>([]);
|
|
30
42
|
const [keyError, setKeyError] = useState<PicovoiceKeyError | null>(null);
|
|
31
|
-
|
|
43
|
+
|
|
32
44
|
// Local state for unsaved changes
|
|
33
45
|
const [localSettings, setLocalSettings] = useState<VoiceSettingsType>(settings);
|
|
34
|
-
const [picovoiceKey, setPicovoiceKey] = useState(
|
|
35
|
-
const [openaiKey, setOpenaiKey] = useState(
|
|
46
|
+
const [picovoiceKey, setPicovoiceKey] = useState("");
|
|
47
|
+
const [openaiKey, setOpenaiKey] = useState("");
|
|
36
48
|
const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
|
|
37
|
-
|
|
38
|
-
const [testText, setTestText] = useState(
|
|
49
|
+
|
|
50
|
+
const [testText, setTestText] = useState("Hello, this is a test of the text to speech system.");
|
|
39
51
|
|
|
40
52
|
// Load initial settings from pvars
|
|
41
53
|
useEffect(() => {
|
|
@@ -44,20 +56,20 @@ export const VoiceSettings: React.FC = () => {
|
|
|
44
56
|
await voiceSettingsPvar.loadingPromise;
|
|
45
57
|
await picovoiceKeyPvar.loadingPromise;
|
|
46
58
|
await openaiKeyPvar.loadingPromise;
|
|
47
|
-
|
|
59
|
+
|
|
48
60
|
const savedSettings = voiceSettingsPvar() || DEFAULT_SETTINGS;
|
|
49
61
|
const picovoiceKeyValue = picovoiceKeyPvar();
|
|
50
62
|
const openaiKeyValue = openaiKeyPvar();
|
|
51
|
-
|
|
63
|
+
|
|
52
64
|
const loadedSettings: VoiceSettingsType = {
|
|
53
65
|
...savedSettings,
|
|
54
|
-
picovoiceAccessKeySet: !!picovoiceKeyValue && picovoiceKeyValue !==
|
|
55
|
-
openaiApiKeySet: !!openaiKeyValue && openaiKeyValue !==
|
|
66
|
+
picovoiceAccessKeySet: !!picovoiceKeyValue && picovoiceKeyValue !== "",
|
|
67
|
+
openaiApiKeySet: !!openaiKeyValue && openaiKeyValue !== "",
|
|
56
68
|
};
|
|
57
|
-
|
|
69
|
+
|
|
58
70
|
setSettings(loadedSettings);
|
|
59
71
|
setLocalSettings(loadedSettings);
|
|
60
|
-
|
|
72
|
+
|
|
61
73
|
try {
|
|
62
74
|
const devices = await rpcServerCalls.voiceGetAudioDevices();
|
|
63
75
|
setAudioDevices(devices || []);
|
|
@@ -72,8 +84,8 @@ export const VoiceSettings: React.FC = () => {
|
|
|
72
84
|
// voiceGetState not available - leave null
|
|
73
85
|
}
|
|
74
86
|
} catch (err) {
|
|
75
|
-
console.error(
|
|
76
|
-
setError(
|
|
87
|
+
console.error("Failed to load voice settings:", err);
|
|
88
|
+
setError("Failed to load voice settings.");
|
|
77
89
|
} finally {
|
|
78
90
|
setLoading(false);
|
|
79
91
|
}
|
|
@@ -92,18 +104,18 @@ export const VoiceSettings: React.FC = () => {
|
|
|
92
104
|
setSaving(true);
|
|
93
105
|
setError(null);
|
|
94
106
|
setSuccess(null);
|
|
95
|
-
|
|
107
|
+
|
|
96
108
|
try {
|
|
97
109
|
if (picovoiceKey) {
|
|
98
110
|
await picovoiceKeyPvar.loadingPromise;
|
|
99
111
|
picovoiceKeyPvar(picovoiceKey);
|
|
100
|
-
setPicovoiceKey(
|
|
112
|
+
setPicovoiceKey("");
|
|
101
113
|
setKeyError(null);
|
|
102
114
|
}
|
|
103
115
|
if (openaiKey) {
|
|
104
116
|
await openaiKeyPvar.loadingPromise;
|
|
105
117
|
openaiKeyPvar(openaiKey);
|
|
106
|
-
setOpenaiKey(
|
|
118
|
+
setOpenaiKey("");
|
|
107
119
|
}
|
|
108
120
|
|
|
109
121
|
await voiceSettingsPvar.loadingPromise;
|
|
@@ -126,11 +138,11 @@ export const VoiceSettings: React.FC = () => {
|
|
|
126
138
|
};
|
|
127
139
|
setSettings(updatedSettings);
|
|
128
140
|
setLocalSettings(updatedSettings);
|
|
129
|
-
|
|
130
|
-
setSuccess(
|
|
141
|
+
|
|
142
|
+
setSuccess("Settings saved successfully!");
|
|
131
143
|
setTimeout(() => setSuccess(null), 3000);
|
|
132
144
|
} catch (err) {
|
|
133
|
-
console.error(
|
|
145
|
+
console.error("Failed to save voice settings:", err);
|
|
134
146
|
setError((err as Error).message);
|
|
135
147
|
} finally {
|
|
136
148
|
setSaving(false);
|
|
@@ -139,10 +151,10 @@ export const VoiceSettings: React.FC = () => {
|
|
|
139
151
|
|
|
140
152
|
const handleToggleEnabled = useCallback(async () => {
|
|
141
153
|
if (!localSettings.picovoiceAccessKeySet && !picovoiceKey && !localSettings.enabled) {
|
|
142
|
-
setError(
|
|
154
|
+
setError("Please enter and save a Picovoice Access Key first");
|
|
143
155
|
return;
|
|
144
156
|
}
|
|
145
|
-
setLocalSettings(prev => ({ ...prev, enabled: !prev.enabled }));
|
|
157
|
+
setLocalSettings((prev) => ({ ...prev, enabled: !prev.enabled }));
|
|
146
158
|
}, [localSettings.enabled, localSettings.picovoiceAccessKeySet, picovoiceKey]);
|
|
147
159
|
|
|
148
160
|
const handleTestTTS = useCallback(async () => {
|
|
@@ -150,8 +162,8 @@ export const VoiceSettings: React.FC = () => {
|
|
|
150
162
|
setError(null);
|
|
151
163
|
await rpcServerCalls.voiceTestTTS(testText);
|
|
152
164
|
} catch (err) {
|
|
153
|
-
console.error(
|
|
154
|
-
setError(
|
|
165
|
+
console.error("TTS test failed:", err);
|
|
166
|
+
setError(`TTS test failed: ${(err as Error).message}`);
|
|
155
167
|
}
|
|
156
168
|
}, [testText]);
|
|
157
169
|
|
|
@@ -160,13 +172,13 @@ export const VoiceSettings: React.FC = () => {
|
|
|
160
172
|
setError(null);
|
|
161
173
|
await rpcServerCalls.voiceStartRecording();
|
|
162
174
|
} catch (err) {
|
|
163
|
-
console.error(
|
|
175
|
+
console.error("Recording test failed:", err);
|
|
164
176
|
setError((err as Error).message);
|
|
165
177
|
}
|
|
166
178
|
}, []);
|
|
167
179
|
|
|
168
180
|
const handleSettingsChange = useCallback((patch: Partial<VoiceSettingsType>) => {
|
|
169
|
-
setLocalSettings(prev => ({ ...prev, ...patch }));
|
|
181
|
+
setLocalSettings((prev) => ({ ...prev, ...patch }));
|
|
170
182
|
}, []);
|
|
171
183
|
|
|
172
184
|
if (loading) {
|
|
@@ -193,7 +205,7 @@ export const VoiceSettings: React.FC = () => {
|
|
|
193
205
|
disabled={saving}
|
|
194
206
|
/>
|
|
195
207
|
<label className="form-check-label" htmlFor="voiceEnabled">
|
|
196
|
-
{localSettings.enabled ?
|
|
208
|
+
{localSettings.enabled ? "Enabled" : "Disabled"}
|
|
197
209
|
</label>
|
|
198
210
|
</div>
|
|
199
211
|
<button
|
|
@@ -201,7 +213,7 @@ export const VoiceSettings: React.FC = () => {
|
|
|
201
213
|
onClick={handleSaveAll}
|
|
202
214
|
disabled={saving || !hasUnsavedChanges}
|
|
203
215
|
>
|
|
204
|
-
{saving ?
|
|
216
|
+
{saving ? "Saving..." : "Save"}
|
|
205
217
|
</button>
|
|
206
218
|
</div>
|
|
207
219
|
|
|
@@ -218,7 +230,7 @@ export const VoiceSettings: React.FC = () => {
|
|
|
218
230
|
disabled={saving}
|
|
219
231
|
/>
|
|
220
232
|
<label className="form-check-label" htmlFor="voiceOutputEnabled">
|
|
221
|
-
{localSettings.voiceOutputEnabled !== false ?
|
|
233
|
+
{localSettings.voiceOutputEnabled !== false ? "On" : "Off"}
|
|
222
234
|
</label>
|
|
223
235
|
</div>
|
|
224
236
|
<small className="text-muted ms-2">Speak assistant responses aloud</small>
|
|
@@ -289,9 +301,20 @@ export const VoiceSettings: React.FC = () => {
|
|
|
289
301
|
</h6>
|
|
290
302
|
<ol className="mb-0 small">
|
|
291
303
|
<li>Get a free Picovoice access key from the link above</li>
|
|
292
|
-
<li>
|
|
293
|
-
|
|
294
|
-
|
|
304
|
+
<li>
|
|
305
|
+
Enter the key and click <strong>Save</strong>
|
|
306
|
+
</li>
|
|
307
|
+
<li>
|
|
308
|
+
Enable voice input and click <strong>Save</strong> again
|
|
309
|
+
</li>
|
|
310
|
+
<li>
|
|
311
|
+
Say{" "}
|
|
312
|
+
<strong>
|
|
313
|
+
"{BUILTIN_WAKE_WORDS.find((w) => w.id === localSettings.wakeWord)?.name || "Computer"}
|
|
314
|
+
"
|
|
315
|
+
</strong>{" "}
|
|
316
|
+
to activate voice recording
|
|
317
|
+
</li>
|
|
295
318
|
<li>Speak your message - recording stops automatically when you pause</li>
|
|
296
319
|
<li>Your message will be sent to the assistant and the response will be spoken</li>
|
|
297
320
|
</ol>
|