@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,101 +1,118 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Voice Indicator Component
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Floating UI element showing voice input state.
|
|
5
5
|
* Supports manual recording trigger via click.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
8
|
+
import { rpcServerCalls, subscribe } from "@peers-app/peers-sdk";
|
|
9
|
+
import React, { useCallback, useEffect, useState } from "react";
|
|
10
|
+
import type {
|
|
11
|
+
VoiceErrorPayload,
|
|
12
|
+
VoicePlayAudioPayload,
|
|
13
|
+
VoiceSpeakPayload,
|
|
14
|
+
VoiceStatePayload,
|
|
15
|
+
VoiceSubscribeEvent,
|
|
16
|
+
VoiceTranscriptionPayload,
|
|
17
|
+
VoiceVolumePayload,
|
|
18
|
+
} from "./voice-subscribe-events";
|
|
10
19
|
|
|
11
|
-
type VoiceState =
|
|
20
|
+
type VoiceState = "disabled" | "idle" | "listening" | "recording" | "processing" | "speaking";
|
|
12
21
|
|
|
13
22
|
interface VoiceIndicatorProps {
|
|
14
23
|
/** Position of the indicator */
|
|
15
|
-
position?:
|
|
24
|
+
position?: "bottom-right" | "bottom-left" | "top-right" | "top-left";
|
|
16
25
|
/** Show expanded view with transcription */
|
|
17
26
|
showTranscription?: boolean;
|
|
18
27
|
}
|
|
19
28
|
|
|
20
29
|
export const VoiceIndicator: React.FC<VoiceIndicatorProps> = ({
|
|
21
|
-
position =
|
|
30
|
+
position = "bottom-right",
|
|
22
31
|
showTranscription = true,
|
|
23
32
|
}) => {
|
|
24
|
-
const [state, setState] = useState<VoiceState>(
|
|
25
|
-
const [transcription, setTranscription] = useState<string>(
|
|
33
|
+
const [state, setState] = useState<VoiceState>("disabled");
|
|
34
|
+
const [transcription, setTranscription] = useState<string>("");
|
|
26
35
|
const [volumeLevel, setVolumeLevel] = useState<number>(0);
|
|
27
36
|
const [error, setError] = useState<string | null>(null);
|
|
28
37
|
const [isExpanded, setIsExpanded] = useState(false);
|
|
29
|
-
|
|
38
|
+
|
|
30
39
|
// Track current audio element for cloud TTS so we can stop it
|
|
31
40
|
const currentAudioRef = React.useRef<HTMLAudioElement | null>(null);
|
|
32
41
|
|
|
33
42
|
// Subscribe to voice events
|
|
34
43
|
useEffect(() => {
|
|
35
44
|
const subscriptions = [
|
|
36
|
-
subscribe(
|
|
37
|
-
setState(event.data.state);
|
|
38
|
-
if (event.data.state ===
|
|
39
|
-
setTranscription(
|
|
45
|
+
subscribe("voice:stateChanged", (event: VoiceSubscribeEvent<VoiceStatePayload>) => {
|
|
46
|
+
setState(event.data.state as VoiceState);
|
|
47
|
+
if (event.data.state === "idle") {
|
|
48
|
+
setTranscription("");
|
|
40
49
|
setError(null);
|
|
41
50
|
}
|
|
42
|
-
if (event.data.state ===
|
|
51
|
+
if (event.data.state === "recording") {
|
|
43
52
|
setIsExpanded(true);
|
|
44
53
|
}
|
|
45
54
|
}),
|
|
46
|
-
subscribe(
|
|
55
|
+
subscribe("voice:transcription", (event: VoiceSubscribeEvent<VoiceTranscriptionPayload>) => {
|
|
47
56
|
setTranscription(event.data.text);
|
|
48
57
|
}),
|
|
49
|
-
subscribe(
|
|
58
|
+
subscribe("voice:volumeLevel", (event: VoiceSubscribeEvent<VoiceVolumePayload>) => {
|
|
50
59
|
setVolumeLevel(event.data.level);
|
|
51
60
|
}),
|
|
52
|
-
subscribe(
|
|
61
|
+
subscribe("voice:error", (event: VoiceSubscribeEvent<VoiceErrorPayload>) => {
|
|
53
62
|
setError(event.data.message);
|
|
54
63
|
}),
|
|
55
64
|
];
|
|
56
65
|
|
|
57
66
|
// Load initial state
|
|
58
|
-
rpcServerCalls
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
67
|
+
rpcServerCalls
|
|
68
|
+
.voiceGetState()
|
|
69
|
+
.then(({ state }) => {
|
|
70
|
+
setState(state);
|
|
71
|
+
})
|
|
72
|
+
.catch(() => {
|
|
73
|
+
// Voice service may not be initialized yet
|
|
74
|
+
});
|
|
63
75
|
|
|
64
76
|
return () => {
|
|
65
|
-
|
|
77
|
+
for (const sub of subscriptions) {
|
|
78
|
+
sub.unsubscribe();
|
|
79
|
+
}
|
|
66
80
|
};
|
|
67
81
|
}, []);
|
|
68
82
|
|
|
69
83
|
// Handle browser TTS events
|
|
70
84
|
useEffect(() => {
|
|
71
|
-
const speakHandler = subscribe(
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const
|
|
75
|
-
if (
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
const speakHandler = subscribe(
|
|
86
|
+
"voice:speakText",
|
|
87
|
+
(event: VoiceSubscribeEvent<VoiceSpeakPayload>) => {
|
|
88
|
+
const { text, voice, rate } = event.data;
|
|
89
|
+
if ("speechSynthesis" in window) {
|
|
90
|
+
const utterance = new SpeechSynthesisUtterance(text);
|
|
91
|
+
if (voice) {
|
|
92
|
+
const voices = speechSynthesis.getVoices();
|
|
93
|
+
const selectedVoice = voices.find((v) => v.name === voice);
|
|
94
|
+
if (selectedVoice) utterance.voice = selectedVoice;
|
|
95
|
+
}
|
|
96
|
+
if (rate) utterance.rate = rate;
|
|
97
|
+
// Notify server when speech ends
|
|
98
|
+
utterance.onend = () => {
|
|
99
|
+
rpcServerCalls.voiceNotifyPlaybackComplete?.().catch(() => {});
|
|
100
|
+
};
|
|
101
|
+
utterance.onerror = () => {
|
|
102
|
+
// Still notify on error so we don't hang
|
|
103
|
+
rpcServerCalls.voiceNotifyPlaybackComplete?.().catch(() => {});
|
|
104
|
+
};
|
|
105
|
+
speechSynthesis.speak(utterance);
|
|
106
|
+
} else {
|
|
107
|
+
// No speech synthesis available, notify immediately
|
|
87
108
|
rpcServerCalls.voiceNotifyPlaybackComplete?.().catch(() => {});
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
// No speech synthesis available, notify immediately
|
|
92
|
-
rpcServerCalls.voiceNotifyPlaybackComplete?.().catch(() => {});
|
|
93
|
-
}
|
|
94
|
-
});
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
);
|
|
95
112
|
|
|
96
|
-
const stopHandler = subscribe(
|
|
113
|
+
const stopHandler = subscribe("voice:stopSpeaking", () => {
|
|
97
114
|
// Stop browser TTS
|
|
98
|
-
if (
|
|
115
|
+
if ("speechSynthesis" in window) {
|
|
99
116
|
speechSynthesis.cancel();
|
|
100
117
|
}
|
|
101
118
|
// Stop cloud TTS audio if playing
|
|
@@ -105,31 +122,34 @@ export const VoiceIndicator: React.FC<VoiceIndicatorProps> = ({
|
|
|
105
122
|
}
|
|
106
123
|
});
|
|
107
124
|
|
|
108
|
-
const playHandler = subscribe(
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
125
|
+
const playHandler = subscribe(
|
|
126
|
+
"voice:playAudio",
|
|
127
|
+
async (event: VoiceSubscribeEvent<VoicePlayAudioPayload>) => {
|
|
128
|
+
const { audioBase64, mimeType } = event.data;
|
|
129
|
+
try {
|
|
130
|
+
const audioData = Uint8Array.from(atob(audioBase64), (c) => c.charCodeAt(0));
|
|
131
|
+
const blob = new Blob([audioData], { type: mimeType });
|
|
132
|
+
const url = URL.createObjectURL(blob);
|
|
133
|
+
const audio = new Audio(url);
|
|
134
|
+
|
|
135
|
+
// Track audio element so we can stop it
|
|
136
|
+
currentAudioRef.current = audio;
|
|
137
|
+
|
|
138
|
+
audio.onended = () => {
|
|
139
|
+
URL.revokeObjectURL(url);
|
|
140
|
+
currentAudioRef.current = null;
|
|
141
|
+
// Notify server that audio playback has completed
|
|
142
|
+
rpcServerCalls.voiceNotifyPlaybackComplete?.().catch(() => {});
|
|
143
|
+
};
|
|
144
|
+
await audio.play();
|
|
145
|
+
} catch (e) {
|
|
146
|
+
console.error("Failed to play audio:", e);
|
|
121
147
|
currentAudioRef.current = null;
|
|
122
|
-
//
|
|
148
|
+
// Still notify on error so we don't hang
|
|
123
149
|
rpcServerCalls.voiceNotifyPlaybackComplete?.().catch(() => {});
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
console.error('Failed to play audio:', e);
|
|
128
|
-
currentAudioRef.current = null;
|
|
129
|
-
// Still notify on error so we don't hang
|
|
130
|
-
rpcServerCalls.voiceNotifyPlaybackComplete?.().catch(() => {});
|
|
131
|
-
}
|
|
132
|
-
});
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
);
|
|
133
153
|
|
|
134
154
|
return () => {
|
|
135
155
|
speakHandler.unsubscribe();
|
|
@@ -140,76 +160,76 @@ export const VoiceIndicator: React.FC<VoiceIndicatorProps> = ({
|
|
|
140
160
|
|
|
141
161
|
const handleClick = useCallback(async () => {
|
|
142
162
|
try {
|
|
143
|
-
if (state ===
|
|
163
|
+
if (state === "disabled") {
|
|
144
164
|
// Open settings
|
|
145
|
-
window.location.hash =
|
|
165
|
+
window.location.hash = "#/settings/voice";
|
|
146
166
|
return;
|
|
147
167
|
}
|
|
148
168
|
|
|
149
|
-
if (state ===
|
|
169
|
+
if (state === "recording") {
|
|
150
170
|
await rpcServerCalls.voiceStopRecording();
|
|
151
|
-
} else if (state ===
|
|
171
|
+
} else if (state === "speaking") {
|
|
152
172
|
await rpcServerCalls.voiceStopPlayback();
|
|
153
|
-
} else if (state ===
|
|
173
|
+
} else if (state === "idle" || state === "listening") {
|
|
154
174
|
await rpcServerCalls.voiceStartRecording();
|
|
155
175
|
}
|
|
156
176
|
} catch (e) {
|
|
157
|
-
console.error(
|
|
177
|
+
console.error("Voice action failed:", e);
|
|
158
178
|
}
|
|
159
179
|
}, [state]);
|
|
160
180
|
|
|
161
181
|
const getIcon = (): string => {
|
|
162
182
|
switch (state) {
|
|
163
|
-
case
|
|
164
|
-
return
|
|
165
|
-
case
|
|
166
|
-
return
|
|
167
|
-
case
|
|
168
|
-
return
|
|
169
|
-
case
|
|
170
|
-
return
|
|
171
|
-
case
|
|
172
|
-
return
|
|
173
|
-
case
|
|
174
|
-
return
|
|
183
|
+
case "disabled":
|
|
184
|
+
return "bi-mic-mute";
|
|
185
|
+
case "idle":
|
|
186
|
+
return "bi-mic";
|
|
187
|
+
case "listening":
|
|
188
|
+
return "bi-ear";
|
|
189
|
+
case "recording":
|
|
190
|
+
return "bi-mic-fill";
|
|
191
|
+
case "processing":
|
|
192
|
+
return "bi-hourglass-split";
|
|
193
|
+
case "speaking":
|
|
194
|
+
return "bi-volume-up-fill";
|
|
175
195
|
default:
|
|
176
|
-
return
|
|
196
|
+
return "bi-mic";
|
|
177
197
|
}
|
|
178
198
|
};
|
|
179
199
|
|
|
180
200
|
const getStateText = (): string => {
|
|
181
201
|
switch (state) {
|
|
182
|
-
case
|
|
183
|
-
return
|
|
184
|
-
case
|
|
202
|
+
case "disabled":
|
|
203
|
+
return "Voice disabled";
|
|
204
|
+
case "idle":
|
|
185
205
|
return 'Say "Porcupine" or click';
|
|
186
|
-
case
|
|
187
|
-
return
|
|
188
|
-
case
|
|
189
|
-
return
|
|
190
|
-
case
|
|
191
|
-
return
|
|
192
|
-
case
|
|
193
|
-
return
|
|
206
|
+
case "listening":
|
|
207
|
+
return "Listening...";
|
|
208
|
+
case "recording":
|
|
209
|
+
return "Recording...";
|
|
210
|
+
case "processing":
|
|
211
|
+
return "Processing...";
|
|
212
|
+
case "speaking":
|
|
213
|
+
return "Speaking... (click to stop)";
|
|
194
214
|
default:
|
|
195
|
-
return
|
|
215
|
+
return "";
|
|
196
216
|
}
|
|
197
217
|
};
|
|
198
218
|
|
|
199
219
|
const getButtonClass = (): string => {
|
|
200
|
-
const base =
|
|
220
|
+
const base = "btn rounded-circle shadow";
|
|
201
221
|
switch (state) {
|
|
202
|
-
case
|
|
222
|
+
case "disabled":
|
|
203
223
|
return `${base} btn-secondary`;
|
|
204
|
-
case
|
|
224
|
+
case "idle":
|
|
205
225
|
return `${base} btn-outline-primary`;
|
|
206
|
-
case
|
|
226
|
+
case "listening":
|
|
207
227
|
return `${base} btn-info`;
|
|
208
|
-
case
|
|
228
|
+
case "recording":
|
|
209
229
|
return `${base} btn-danger`;
|
|
210
|
-
case
|
|
230
|
+
case "processing":
|
|
211
231
|
return `${base} btn-warning`;
|
|
212
|
-
case
|
|
232
|
+
case "speaking":
|
|
213
233
|
return `${base} btn-success`;
|
|
214
234
|
default:
|
|
215
235
|
return `${base} btn-secondary`;
|
|
@@ -217,42 +237,39 @@ export const VoiceIndicator: React.FC<VoiceIndicatorProps> = ({
|
|
|
217
237
|
};
|
|
218
238
|
|
|
219
239
|
const positionStyles: React.CSSProperties = {
|
|
220
|
-
position:
|
|
240
|
+
position: "fixed",
|
|
221
241
|
zIndex: 1050,
|
|
222
|
-
...(position.includes(
|
|
223
|
-
...(position.includes(
|
|
242
|
+
...(position.includes("bottom") ? { bottom: "20px" } : { top: "70px" }),
|
|
243
|
+
...(position.includes("right") ? { right: "20px" } : { left: "20px" }),
|
|
224
244
|
};
|
|
225
245
|
|
|
226
246
|
// Don't render if disabled and not showing
|
|
227
247
|
// Actually, let's always show so users can click to enable
|
|
228
|
-
|
|
248
|
+
|
|
229
249
|
return (
|
|
230
250
|
<div style={positionStyles}>
|
|
231
251
|
{/* Expanded panel */}
|
|
232
|
-
{isExpanded && state !==
|
|
233
|
-
<div
|
|
252
|
+
{isExpanded && state !== "disabled" && (
|
|
253
|
+
<div
|
|
234
254
|
className="card shadow mb-2"
|
|
235
|
-
style={{
|
|
236
|
-
width:
|
|
237
|
-
backgroundColor:
|
|
255
|
+
style={{
|
|
256
|
+
width: "280px",
|
|
257
|
+
backgroundColor: "var(--bs-body-bg)",
|
|
238
258
|
}}
|
|
239
259
|
>
|
|
240
260
|
<div className="card-body py-2 px-3">
|
|
241
261
|
<div className="d-flex justify-content-between align-items-center mb-2">
|
|
242
262
|
<small className="text-muted">{getStateText()}</small>
|
|
243
|
-
<button
|
|
244
|
-
className="btn btn-sm btn-link p-0"
|
|
245
|
-
onClick={() => setIsExpanded(false)}
|
|
246
|
-
>
|
|
263
|
+
<button className="btn btn-sm btn-link p-0" onClick={() => setIsExpanded(false)}>
|
|
247
264
|
<i className="bi bi-x"></i>
|
|
248
265
|
</button>
|
|
249
266
|
</div>
|
|
250
|
-
|
|
267
|
+
|
|
251
268
|
{/* Volume meter */}
|
|
252
|
-
{state ===
|
|
253
|
-
<div className="progress mb-2" style={{ height:
|
|
254
|
-
<div
|
|
255
|
-
className="progress-bar bg-danger"
|
|
269
|
+
{state === "recording" && (
|
|
270
|
+
<div className="progress mb-2" style={{ height: "4px" }}>
|
|
271
|
+
<div
|
|
272
|
+
className="progress-bar bg-danger"
|
|
256
273
|
style={{ width: `${Math.min(100, volumeLevel * 500)}%` }}
|
|
257
274
|
></div>
|
|
258
275
|
</div>
|
|
@@ -280,38 +297,38 @@ export const VoiceIndicator: React.FC<VoiceIndicatorProps> = ({
|
|
|
280
297
|
{/* Main button */}
|
|
281
298
|
<button
|
|
282
299
|
className={getButtonClass()}
|
|
283
|
-
style={{
|
|
284
|
-
width:
|
|
285
|
-
height:
|
|
286
|
-
fontSize:
|
|
287
|
-
transition:
|
|
300
|
+
style={{
|
|
301
|
+
width: "56px",
|
|
302
|
+
height: "56px",
|
|
303
|
+
fontSize: "24px",
|
|
304
|
+
transition: "all 0.2s ease",
|
|
288
305
|
}}
|
|
289
306
|
onClick={handleClick}
|
|
290
307
|
title={getStateText()}
|
|
291
308
|
>
|
|
292
309
|
<i className={`bi ${getIcon()}`}></i>
|
|
293
|
-
|
|
310
|
+
|
|
294
311
|
{/* Pulsing animation for listening/recording */}
|
|
295
|
-
{(state ===
|
|
296
|
-
<span
|
|
312
|
+
{(state === "listening" || state === "recording") && (
|
|
313
|
+
<span
|
|
297
314
|
className="position-absolute"
|
|
298
315
|
style={{
|
|
299
316
|
top: 0,
|
|
300
317
|
left: 0,
|
|
301
318
|
right: 0,
|
|
302
319
|
bottom: 0,
|
|
303
|
-
borderRadius:
|
|
304
|
-
border:
|
|
305
|
-
animation:
|
|
320
|
+
borderRadius: "50%",
|
|
321
|
+
border: "2px solid currentColor",
|
|
322
|
+
animation: "pulse 1.5s ease-out infinite",
|
|
306
323
|
}}
|
|
307
324
|
></span>
|
|
308
325
|
)}
|
|
309
326
|
|
|
310
327
|
{/* Processing spinner */}
|
|
311
|
-
{state ===
|
|
312
|
-
<span
|
|
328
|
+
{state === "processing" && (
|
|
329
|
+
<span
|
|
313
330
|
className="spinner-border spinner-border-sm position-absolute"
|
|
314
|
-
style={{ top:
|
|
331
|
+
style={{ top: "4px", right: "4px" }}
|
|
315
332
|
></span>
|
|
316
333
|
)}
|
|
317
334
|
</button>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { IMessage } from "@peers-app/peers-sdk";
|
|
2
|
+
|
|
3
|
+
/** Shape passed to `subscribe` handlers for voice / chat IPC events */
|
|
4
|
+
export type VoiceSubscribeEvent<T> = { data: T };
|
|
5
|
+
|
|
6
|
+
export type ChatOpenWithMessagePayload = { message?: IMessage };
|
|
7
|
+
|
|
8
|
+
export type VoiceStatePayload = { state: string };
|
|
9
|
+
|
|
10
|
+
export type VoiceTranscriptionPayload = { text: string };
|
|
11
|
+
|
|
12
|
+
export type VoiceVolumePayload = { level: number };
|
|
13
|
+
|
|
14
|
+
export type VoiceErrorPayload = { message: string };
|
|
15
|
+
|
|
16
|
+
export type VoiceThreadPayload = { threadId: string };
|
|
17
|
+
|
|
18
|
+
export type VoiceSpeakPayload = { text: string; voice?: string; rate?: number };
|
|
19
|
+
|
|
20
|
+
export type VoicePlayAudioPayload = { audioBase64: string; mimeType: string };
|
package/src/globals.tsx
CHANGED
|
@@ -1,10 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
computed,
|
|
3
|
+
Groups,
|
|
4
|
+
getMe,
|
|
5
|
+
groupUserVar,
|
|
6
|
+
type IGroup,
|
|
7
|
+
type IMessage,
|
|
8
|
+
type IUser,
|
|
9
|
+
Messages,
|
|
10
|
+
observable,
|
|
11
|
+
reloadPackagesOnPageRefresh,
|
|
12
|
+
rpcClientCalls,
|
|
13
|
+
rpcServerCalls,
|
|
14
|
+
sleep,
|
|
15
|
+
} from "@peers-app/peers-sdk";
|
|
2
16
|
import { handleMainPathChanged, openNewTab } from "./tabs-layout/tabs-state";
|
|
3
17
|
import { stripMentions } from "./utils";
|
|
4
18
|
|
|
5
19
|
export const packageReloaded = observable(0);
|
|
6
20
|
|
|
7
|
-
export const _mainContentPath = groupUserVar(
|
|
21
|
+
export const _mainContentPath = groupUserVar("mainContentPath", { defaultValue: "" });
|
|
8
22
|
|
|
9
23
|
export const mainContentPath = computed<string>({
|
|
10
24
|
read: () => {
|
|
@@ -20,21 +34,21 @@ export const mainContentPath = computed<string>({
|
|
|
20
34
|
|
|
21
35
|
const queryParams = computed<{ [key: string]: string }>({
|
|
22
36
|
read: () => {
|
|
23
|
-
const queryStr = mainContentPath()?.split(
|
|
37
|
+
const queryStr = mainContentPath()?.split("?")[1] || "";
|
|
24
38
|
const params = new URLSearchParams(queryStr);
|
|
25
39
|
const obj: { [key: string]: string } = {};
|
|
26
40
|
for (const [key, value] of params.entries()) {
|
|
27
41
|
obj[key] = value;
|
|
28
42
|
}
|
|
29
|
-
return obj
|
|
43
|
+
return obj;
|
|
30
44
|
},
|
|
31
45
|
write: (value: { [key: string]: string }) => {
|
|
32
|
-
const queryStr = mainContentPath().split(
|
|
46
|
+
const queryStr = mainContentPath().split("?")[1] || "";
|
|
33
47
|
const params = new URLSearchParams(queryStr);
|
|
34
48
|
for (const key in value) {
|
|
35
49
|
params.set(key, value[key]);
|
|
36
50
|
}
|
|
37
|
-
mainContentPath(mainContentPath().split(
|
|
51
|
+
mainContentPath(`${mainContentPath().split("?")[0]}?${params.toString()}`);
|
|
38
52
|
},
|
|
39
53
|
});
|
|
40
54
|
|
|
@@ -44,7 +58,7 @@ export function queryParam(name: string, value?: string) {
|
|
|
44
58
|
if (params[name] === value) {
|
|
45
59
|
return value;
|
|
46
60
|
}
|
|
47
|
-
if (value === null || value ===
|
|
61
|
+
if (value === null || value === "") {
|
|
48
62
|
delete params[name];
|
|
49
63
|
} else {
|
|
50
64
|
params[name] = value;
|
|
@@ -54,28 +68,16 @@ export function queryParam(name: string, value?: string) {
|
|
|
54
68
|
return params[name];
|
|
55
69
|
}
|
|
56
70
|
|
|
57
|
-
export const openThreads: PersistentVar<(string | IMessage)[]> = groupUserVar('openThreads', { defaultValue: [] });
|
|
58
|
-
export const threadViewOpen = groupUserVar<boolean>('threadViewOpen', { defaultValue: false });
|
|
59
|
-
|
|
60
71
|
export async function openThread(thread: string | IMessage) {
|
|
61
72
|
openThreadInTab(thread);
|
|
62
|
-
// let threadId = typeof thread === 'string' ? thread : thread.messageId;
|
|
63
|
-
// const message = await Messages().get(threadId);
|
|
64
|
-
// if (message) {
|
|
65
|
-
// thread = message.messageParentId || message.messageId;
|
|
66
|
-
// }
|
|
67
|
-
// const threadsWithout = openThreads().filter(t => (typeof t === 'string' && t !== threadId) || (typeof t === 'object' && t.messageId !== threadId));
|
|
68
|
-
// openThreads([thread, ...threadsWithout]);
|
|
69
|
-
// threadViewOpen(true);
|
|
70
73
|
}
|
|
71
74
|
|
|
72
|
-
// Thread opening function for tabs system
|
|
73
75
|
export async function openThreadInTab(thread: string | IMessage) {
|
|
74
|
-
|
|
76
|
+
const threadId = typeof thread === "string" ? thread : thread.messageId;
|
|
75
77
|
const message = await Messages().get(threadId);
|
|
76
78
|
|
|
77
79
|
if (!message) {
|
|
78
|
-
console.warn(
|
|
80
|
+
console.warn("Thread message not found:", threadId);
|
|
79
81
|
return;
|
|
80
82
|
}
|
|
81
83
|
|
|
@@ -85,35 +87,35 @@ export async function openThreadInTab(thread: string | IMessage) {
|
|
|
85
87
|
// Generate thread title from message content (strip mentions and clean formatting)
|
|
86
88
|
const cleanMessage = stripMentions(message.message);
|
|
87
89
|
const messagePreview = cleanMessage.slice(0, 30);
|
|
88
|
-
const threadTitle = `${messagePreview}${cleanMessage.length > 30 ?
|
|
90
|
+
const threadTitle = `${messagePreview}${cleanMessage.length > 30 ? "..." : ""}` || `Thread`;
|
|
89
91
|
|
|
90
92
|
// // Import openNewTab dynamically to avoid circular dependency
|
|
91
93
|
// const { openNewTab } = await import('./tabs-layout/tabs-layout');
|
|
92
94
|
|
|
93
95
|
openNewTab({
|
|
94
|
-
packageId:
|
|
96
|
+
packageId: "system-apps",
|
|
95
97
|
path: `threads/${actualThreadId}`,
|
|
96
98
|
title: threadTitle,
|
|
97
|
-
iconClassName:
|
|
99
|
+
iconClassName: "bi-chat-dots",
|
|
98
100
|
});
|
|
99
101
|
}
|
|
100
102
|
|
|
101
103
|
rpcClientCalls.setClientPath = async (url: string) => {
|
|
102
|
-
mainContentPath(url && String(url).trim() ||
|
|
104
|
+
mainContentPath((url && String(url).trim()) || "");
|
|
103
105
|
};
|
|
104
106
|
|
|
105
107
|
rpcClientCalls.openThread = async (threadId: string) => {
|
|
106
|
-
console.warn(
|
|
108
|
+
console.warn("Opening thread:", threadId);
|
|
107
109
|
openThread(threadId);
|
|
108
110
|
};
|
|
109
111
|
|
|
110
112
|
export let me: IUser = null as unknown as IUser;
|
|
111
113
|
|
|
112
|
-
export const windowWidth = observable(window.innerWidth)
|
|
113
|
-
export const windowHeight = observable(window.innerHeight)
|
|
114
|
-
window.addEventListener("resize", (
|
|
115
|
-
windowWidth(window.innerWidth)
|
|
116
|
-
windowHeight(window.innerHeight)
|
|
114
|
+
export const windowWidth = observable(window.innerWidth); //.extend({ rateLimit: 500 });
|
|
115
|
+
export const windowHeight = observable(window.innerHeight); //.extend({ rateLimit: 500 });
|
|
116
|
+
window.addEventListener("resize", (_ev) => {
|
|
117
|
+
windowWidth(window.innerWidth);
|
|
118
|
+
windowHeight(window.innerHeight);
|
|
117
119
|
});
|
|
118
120
|
|
|
119
121
|
export const isDesktop = computed(() => {
|
|
@@ -131,19 +133,19 @@ export async function loadGlobals() {
|
|
|
131
133
|
me = await getMe();
|
|
132
134
|
await reloadPackagesOnPageRefresh.loadingPromise;
|
|
133
135
|
if (reloadPackagesOnPageRefresh()) {
|
|
134
|
-
await rpcServerCalls.addOrUpdatePackage(
|
|
136
|
+
await rpcServerCalls.addOrUpdatePackage("updateAll");
|
|
135
137
|
}
|
|
136
138
|
await Promise.all([
|
|
137
|
-
Groups()
|
|
139
|
+
Groups()
|
|
140
|
+
.list()
|
|
141
|
+
.then((r) => groups(r)),
|
|
138
142
|
_mainContentPath.loadingPromise,
|
|
139
|
-
openThreads.loadingPromise,
|
|
140
|
-
threadViewOpen.loadingPromise,
|
|
141
143
|
sleep(100),
|
|
142
144
|
]);
|
|
143
145
|
|
|
144
146
|
function updateWindowHash() {
|
|
145
147
|
const currentPath = window.location.hash.substring(1);
|
|
146
|
-
const expectedPath = mainContentPath() ||
|
|
148
|
+
const expectedPath = mainContentPath() || "";
|
|
147
149
|
// console.log({ expectedPath, currentPath });
|
|
148
150
|
if (currentPath !== expectedPath) {
|
|
149
151
|
window.location.hash = expectedPath;
|
|
@@ -152,12 +154,12 @@ export async function loadGlobals() {
|
|
|
152
154
|
}
|
|
153
155
|
mainContentPath.subscribe(updateWindowHash);
|
|
154
156
|
updateWindowHash();
|
|
155
|
-
window.addEventListener(
|
|
157
|
+
window.addEventListener("hashchange", () => mainContentPath(window.location.hash.substring(1)));
|
|
156
158
|
|
|
157
159
|
return true;
|
|
158
160
|
}
|
|
159
161
|
|
|
160
|
-
if (typeof window !==
|
|
161
|
-
// @ts-
|
|
162
|
+
if (typeof window !== "undefined") {
|
|
163
|
+
// @ts-expect-error
|
|
162
164
|
window.globals = module.exports;
|
|
163
|
-
}
|
|
165
|
+
}
|