@k2b/ui 0.27.0 → 0.29.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/README.md +1 -1
- package/dist/base.css +147 -2
- package/dist/browser/actions/ContextMenu.js +35 -4
- package/dist/browser/actions/ContextMenu.js.map +1 -1
- package/dist/browser/actions/DragAndDrop.js +89 -0
- package/dist/browser/actions/DragAndDrop.js.map +1 -0
- package/dist/browser/actions/Dropdown.js +184 -158
- package/dist/browser/actions/Dropdown.js.map +1 -1
- package/dist/browser/actions/GestureMenu.js +95 -139
- package/dist/browser/actions/GestureMenu.js.map +1 -1
- package/dist/browser/actions/Toolbar.js +379 -48
- package/dist/browser/actions/Toolbar.js.map +1 -1
- package/dist/browser/actions/drag-and-drop-messages.js +75 -0
- package/dist/browser/actions/drag-and-drop-messages.js.map +1 -0
- package/dist/browser/actions/drag-and-drop.js +692 -0
- package/dist/browser/actions/drag-and-drop.js.map +1 -0
- package/dist/browser/actions/index.js +1 -0
- package/dist/browser/actions/index.js.map +1 -1
- package/dist/browser/actions/menu-rows.js +15 -0
- package/dist/browser/actions/menu-rows.js.map +1 -0
- package/dist/browser/actions/menu-sheet.js +154 -0
- package/dist/browser/actions/menu-sheet.js.map +1 -0
- package/dist/browser/actions/toolbar-messages.js +20 -0
- package/dist/browser/actions/toolbar-messages.js.map +1 -0
- package/dist/browser/chart-inspection.js +3 -0
- package/dist/browser/chart-inspection.js.map +1 -0
- package/dist/browser/chat/ChatComposer.js +714 -410
- package/dist/browser/chat/ChatComposer.js.map +1 -1
- package/dist/browser/chat/ChatDecision.js +778 -0
- package/dist/browser/chat/ChatDecision.js.map +1 -0
- package/dist/browser/chat/ChatPrimitives.js +34 -28
- package/dist/browser/chat/ChatPrimitives.js.map +1 -1
- package/dist/browser/chat/ChatTimeline.js.map +1 -1
- package/dist/browser/chat/chat-messages.js +25 -1
- package/dist/browser/chat/chat-messages.js.map +1 -1
- package/dist/browser/chat/command-search.js +13 -3
- package/dist/browser/chat/command-search.js.map +1 -1
- package/dist/browser/chat/index.js +8 -1
- package/dist/browser/chat/index.js.map +1 -1
- package/dist/browser/chat/reaction-people.js +15 -0
- package/dist/browser/chat/reaction-people.js.map +1 -0
- package/dist/browser/chat/types.js.map +1 -1
- package/dist/browser/content/Calendar.js +3 -3
- package/dist/browser/content/Calendar.js.map +1 -1
- package/dist/browser/content/Chart.js +60 -86
- package/dist/browser/content/Chart.js.map +1 -1
- package/dist/browser/content/ChartSnapshotView.js +7 -10
- package/dist/browser/content/ChartSnapshotView.js.map +1 -1
- package/dist/browser/content/FileBrowser.js +2 -2
- package/dist/browser/content/FileBrowser.js.map +1 -1
- package/dist/browser/content/FileTree.js +42 -36
- package/dist/browser/content/FileTree.js.map +1 -1
- package/dist/browser/content/FileTypeIcon.js +72 -0
- package/dist/browser/content/FileTypeIcon.js.map +1 -0
- package/dist/browser/content/FileView.js +2 -2
- package/dist/browser/content/FileView.js.map +1 -1
- package/dist/browser/content/MessageRow.js +330 -448
- package/dist/browser/content/MessageRow.js.map +1 -1
- package/dist/browser/content/ReactionBar.js +419 -0
- package/dist/browser/content/ReactionBar.js.map +1 -0
- package/dist/browser/content/ReferenceChip.js +162 -0
- package/dist/browser/content/ReferenceChip.js.map +1 -0
- package/dist/browser/content/calendar-pointer.js +9 -0
- package/dist/browser/content/calendar-pointer.js.map +1 -1
- package/dist/browser/content/calendar-time-view.js +6 -3
- package/dist/browser/content/calendar-time-view.js.map +1 -1
- package/dist/browser/content/chart-inspection-core.js +557 -0
- package/dist/browser/content/chart-inspection-core.js.map +1 -0
- package/dist/browser/content/chart-inspection.js +10 -445
- package/dist/browser/content/chart-inspection.js.map +1 -1
- package/dist/browser/content/chart-line-gaps.js +1 -1
- package/dist/browser/content/chart-line-gaps.js.map +1 -1
- package/dist/browser/content/chart-snapshot.js +1 -1
- package/dist/browser/content/chart-snapshot.js.map +1 -1
- package/dist/browser/content/index.js +3 -0
- package/dist/browser/content/index.js.map +1 -1
- package/dist/browser/feedback/dialog-core.js +135 -23
- package/dist/browser/feedback/dialog-core.js.map +1 -1
- package/dist/browser/index.js +1 -0
- package/dist/browser/index.js.map +1 -1
- package/dist/browser/input-mode.js +40 -0
- package/dist/browser/input-mode.js.map +1 -0
- package/dist/browser/inputs/FileDropTarget.js +24 -9
- package/dist/browser/inputs/FileDropTarget.js.map +1 -1
- package/dist/browser/inputs/FileInputs.js +2 -2
- package/dist/browser/inputs/FileInputs.js.map +1 -1
- package/dist/browser/inputs/SelectChip.js +9 -0
- package/dist/browser/inputs/SelectChip.js.map +1 -1
- package/dist/browser/inputs/emoji/EmojiPicker.js +13 -0
- package/dist/browser/inputs/emoji/EmojiPicker.js.map +1 -1
- package/dist/browser/inputs/file-drop.js.map +1 -1
- package/dist/browser/layout/AppOverview.js +1 -1
- package/dist/browser/layout/AppOverview.js.map +1 -1
- package/dist/browser/layout/AppWorkspace.js +644 -445
- package/dist/browser/layout/AppWorkspace.js.map +1 -1
- package/dist/browser/layout/DetailPanel.js +283 -197
- package/dist/browser/layout/DetailPanel.js.map +1 -1
- package/dist/browser/layout/Discussion.js +233 -185
- package/dist/browser/layout/Discussion.js.map +1 -1
- package/dist/browser/layout/PanelDialog.js +88 -86
- package/dist/browser/layout/PanelDialog.js.map +1 -1
- package/dist/browser/layout/ResizeSeparator.js +81 -0
- package/dist/browser/layout/ResizeSeparator.js.map +1 -0
- package/dist/browser/layout/SidebarSwitcher.js +9 -2
- package/dist/browser/layout/SidebarSwitcher.js.map +1 -1
- package/dist/browser/layout/TabBar.js +15 -12
- package/dist/browser/layout/TabBar.js.map +1 -1
- package/dist/browser/layout/TableOfContents.js +10 -2
- package/dist/browser/layout/TableOfContents.js.map +1 -1
- package/dist/browser/layout/app-workspace-controller.js +130 -17
- package/dist/browser/layout/app-workspace-controller.js.map +1 -1
- package/dist/browser/layout/detail-panel-messages.js +35 -0
- package/dist/browser/layout/detail-panel-messages.js.map +1 -0
- package/dist/browser/layout/index.js +3 -1
- package/dist/browser/layout/index.js.map +1 -1
- package/dist/browser/layout/resize-separator.js +90 -0
- package/dist/browser/layout/resize-separator.js.map +1 -0
- package/dist/browser/layout/workspace-messages.js +12 -2
- package/dist/browser/layout/workspace-messages.js.map +1 -1
- package/dist/browser/surfaces/Avatar.js +50 -20
- package/dist/browser/surfaces/Avatar.js.map +1 -1
- package/dist/browser/surfaces/AvatarStack.js +406 -0
- package/dist/browser/surfaces/AvatarStack.js.map +1 -0
- package/dist/browser/surfaces/LinkCard.js +1 -1
- package/dist/browser/surfaces/LinkCard.js.map +1 -1
- package/dist/browser/surfaces/Placeholder.js +14 -3
- package/dist/browser/surfaces/Placeholder.js.map +1 -1
- package/dist/browser/surfaces/StatCell.js +23 -0
- package/dist/browser/surfaces/StatCell.js.map +1 -1
- package/dist/browser/surfaces/avatar-messages.js +8 -2
- package/dist/browser/surfaces/avatar-messages.js.map +1 -1
- package/dist/browser/surfaces/index.js +1 -0
- package/dist/browser/surfaces/index.js.map +1 -1
- package/dist/browser/widgets/Widget.js +1 -1
- package/dist/browser/widgets/Widget.js.map +1 -1
- package/dist/ssr/actions/ContextMenu.js +26 -3
- package/dist/ssr/actions/ContextMenu.js.map +1 -1
- package/dist/ssr/actions/DragAndDrop.js +63 -0
- package/dist/ssr/actions/DragAndDrop.js.map +1 -0
- package/dist/ssr/actions/Dropdown.js +140 -72
- package/dist/ssr/actions/Dropdown.js.map +1 -1
- package/dist/ssr/actions/GestureMenu.js +76 -107
- package/dist/ssr/actions/GestureMenu.js.map +1 -1
- package/dist/ssr/actions/Toolbar.js +294 -14
- package/dist/ssr/actions/Toolbar.js.map +1 -1
- package/dist/ssr/actions/drag-and-drop-messages.js +75 -0
- package/dist/ssr/actions/drag-and-drop-messages.js.map +1 -0
- package/dist/ssr/actions/drag-and-drop.js +692 -0
- package/dist/ssr/actions/drag-and-drop.js.map +1 -0
- package/dist/ssr/actions/index.js +1 -0
- package/dist/ssr/actions/index.js.map +1 -1
- package/dist/ssr/actions/menu-rows.js +15 -0
- package/dist/ssr/actions/menu-rows.js.map +1 -0
- package/dist/ssr/actions/menu-sheet.js +138 -0
- package/dist/ssr/actions/menu-sheet.js.map +1 -0
- package/dist/ssr/actions/toolbar-messages.js +20 -0
- package/dist/ssr/actions/toolbar-messages.js.map +1 -0
- package/dist/ssr/chart-inspection.js +3 -0
- package/dist/ssr/chart-inspection.js.map +1 -0
- package/dist/ssr/chat/ChatComposer.js +393 -102
- package/dist/ssr/chat/ChatComposer.js.map +1 -1
- package/dist/ssr/chat/ChatDecision.js +465 -0
- package/dist/ssr/chat/ChatDecision.js.map +1 -0
- package/dist/ssr/chat/ChatPrimitives.js +2 -2
- package/dist/ssr/chat/ChatPrimitives.js.map +1 -1
- package/dist/ssr/chat/ChatTimeline.js.map +1 -1
- package/dist/ssr/chat/chat-messages.js +25 -1
- package/dist/ssr/chat/chat-messages.js.map +1 -1
- package/dist/ssr/chat/command-search.js +13 -3
- package/dist/ssr/chat/command-search.js.map +1 -1
- package/dist/ssr/chat/index.js +8 -1
- package/dist/ssr/chat/index.js.map +1 -1
- package/dist/ssr/chat/reaction-people.js +15 -0
- package/dist/ssr/chat/reaction-people.js.map +1 -0
- package/dist/ssr/chat/types.js.map +1 -1
- package/dist/ssr/content/Calendar.js +3 -3
- package/dist/ssr/content/Calendar.js.map +1 -1
- package/dist/ssr/content/Chart.js +25 -38
- package/dist/ssr/content/Chart.js.map +1 -1
- package/dist/ssr/content/ChartSnapshotView.js +7 -10
- package/dist/ssr/content/ChartSnapshotView.js.map +1 -1
- package/dist/ssr/content/FileBrowser.js +2 -2
- package/dist/ssr/content/FileBrowser.js.map +1 -1
- package/dist/ssr/content/FileTree.js +21 -14
- package/dist/ssr/content/FileTree.js.map +1 -1
- package/dist/ssr/content/FileTypeIcon.js +50 -0
- package/dist/ssr/content/FileTypeIcon.js.map +1 -0
- package/dist/ssr/content/FileView.js +2 -2
- package/dist/ssr/content/FileView.js.map +1 -1
- package/dist/ssr/content/MessageRow.js +98 -152
- package/dist/ssr/content/MessageRow.js.map +1 -1
- package/dist/ssr/content/ReactionBar.js +304 -0
- package/dist/ssr/content/ReactionBar.js.map +1 -0
- package/dist/ssr/content/ReferenceChip.js +121 -0
- package/dist/ssr/content/ReferenceChip.js.map +1 -0
- package/dist/ssr/content/calendar-pointer.js +9 -0
- package/dist/ssr/content/calendar-pointer.js.map +1 -1
- package/dist/ssr/content/calendar-time-view.js +6 -3
- package/dist/ssr/content/calendar-time-view.js.map +1 -1
- package/dist/ssr/content/chart-inspection-core.js +557 -0
- package/dist/ssr/content/chart-inspection-core.js.map +1 -0
- package/dist/ssr/content/chart-inspection.js +10 -445
- package/dist/ssr/content/chart-inspection.js.map +1 -1
- package/dist/ssr/content/chart-line-gaps.js +1 -1
- package/dist/ssr/content/chart-line-gaps.js.map +1 -1
- package/dist/ssr/content/chart-snapshot.js +1 -1
- package/dist/ssr/content/chart-snapshot.js.map +1 -1
- package/dist/ssr/content/index.js +3 -0
- package/dist/ssr/content/index.js.map +1 -1
- package/dist/ssr/feedback/dialog-core.js +135 -23
- package/dist/ssr/feedback/dialog-core.js.map +1 -1
- package/dist/ssr/index.js +1 -0
- package/dist/ssr/index.js.map +1 -1
- package/dist/ssr/input-mode.js +40 -0
- package/dist/ssr/input-mode.js.map +1 -0
- package/dist/ssr/inputs/FileDropTarget.js +17 -5
- package/dist/ssr/inputs/FileDropTarget.js.map +1 -1
- package/dist/ssr/inputs/FileInputs.js +2 -2
- package/dist/ssr/inputs/FileInputs.js.map +1 -1
- package/dist/ssr/inputs/SelectChip.js +9 -0
- package/dist/ssr/inputs/SelectChip.js.map +1 -1
- package/dist/ssr/inputs/emoji/EmojiPicker.js +12 -0
- package/dist/ssr/inputs/emoji/EmojiPicker.js.map +1 -1
- package/dist/ssr/inputs/file-drop.js.map +1 -1
- package/dist/ssr/layout/AppOverview.js +1 -1
- package/dist/ssr/layout/AppOverview.js.map +1 -1
- package/dist/ssr/layout/AppWorkspace.js +272 -95
- package/dist/ssr/layout/AppWorkspace.js.map +1 -1
- package/dist/ssr/layout/DetailPanel.js +112 -58
- package/dist/ssr/layout/DetailPanel.js.map +1 -1
- package/dist/ssr/layout/Discussion.js +63 -36
- package/dist/ssr/layout/Discussion.js.map +1 -1
- package/dist/ssr/layout/PanelDialog.js +7 -6
- package/dist/ssr/layout/PanelDialog.js.map +1 -1
- package/dist/ssr/layout/ResizeSeparator.js +45 -0
- package/dist/ssr/layout/ResizeSeparator.js.map +1 -0
- package/dist/ssr/layout/SidebarSwitcher.js +9 -2
- package/dist/ssr/layout/SidebarSwitcher.js.map +1 -1
- package/dist/ssr/layout/TabBar.js +1 -1
- package/dist/ssr/layout/TabBar.js.map +1 -1
- package/dist/ssr/layout/TableOfContents.js +10 -2
- package/dist/ssr/layout/TableOfContents.js.map +1 -1
- package/dist/ssr/layout/app-workspace-controller.js +130 -17
- package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
- package/dist/ssr/layout/detail-panel-messages.js +35 -0
- package/dist/ssr/layout/detail-panel-messages.js.map +1 -0
- package/dist/ssr/layout/index.js +3 -1
- package/dist/ssr/layout/index.js.map +1 -1
- package/dist/ssr/layout/resize-separator.js +90 -0
- package/dist/ssr/layout/resize-separator.js.map +1 -0
- package/dist/ssr/layout/workspace-messages.js +12 -2
- package/dist/ssr/layout/workspace-messages.js.map +1 -1
- package/dist/ssr/surfaces/Avatar.js +20 -2
- package/dist/ssr/surfaces/Avatar.js.map +1 -1
- package/dist/ssr/surfaces/AvatarStack.js +286 -0
- package/dist/ssr/surfaces/AvatarStack.js.map +1 -0
- package/dist/ssr/surfaces/LinkCard.js +1 -1
- package/dist/ssr/surfaces/LinkCard.js.map +1 -1
- package/dist/ssr/surfaces/Placeholder.js +4 -2
- package/dist/ssr/surfaces/Placeholder.js.map +1 -1
- package/dist/ssr/surfaces/StatCell.js +23 -0
- package/dist/ssr/surfaces/StatCell.js.map +1 -1
- package/dist/ssr/surfaces/avatar-messages.js +8 -2
- package/dist/ssr/surfaces/avatar-messages.js.map +1 -1
- package/dist/ssr/surfaces/index.js +1 -0
- package/dist/ssr/surfaces/index.js.map +1 -1
- package/dist/ssr/widgets/Widget.js +1 -1
- package/dist/ssr/widgets/Widget.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types/actions/ContextMenu.d.ts +9 -0
- package/dist/types/actions/DragAndDrop.d.ts +29 -0
- package/dist/types/actions/Dropdown.d.ts +12 -5
- package/dist/types/actions/GestureMenu.d.ts +6 -4
- package/dist/types/actions/Toolbar.d.ts +20 -0
- package/dist/types/actions/drag-and-drop-messages.d.ts +35 -0
- package/dist/types/actions/drag-and-drop.d.ts +36 -0
- package/dist/types/actions/index.d.ts +3 -1
- package/dist/types/actions/menu-rows.d.ts +5 -0
- package/dist/types/actions/menu-sheet.d.ts +22 -0
- package/dist/types/actions/toolbar-messages.d.ts +8 -0
- package/dist/types/chart-inspection.d.ts +2 -0
- package/dist/types/chat/ChatComposer.d.ts +26 -1
- package/dist/types/chat/ChatDecision.d.ts +133 -0
- package/dist/types/chat/ChatPrimitives.d.ts +4 -1
- package/dist/types/chat/ChatTimeline.d.ts +2 -1
- package/dist/types/chat/chat-messages.d.ts +13 -2
- package/dist/types/chat/command-search.d.ts +5 -0
- package/dist/types/chat/index.d.ts +25 -1
- package/dist/types/chat/reaction-people.d.ts +9 -0
- package/dist/types/chat/types.d.ts +54 -1
- package/dist/types/content/Chart.d.ts +11 -5
- package/dist/types/content/FileTypeIcon.d.ts +27 -0
- package/dist/types/content/MessageRow.d.ts +3 -10
- package/dist/types/content/ReactionBar.d.ts +32 -0
- package/dist/types/content/ReferenceChip.d.ts +49 -0
- package/dist/types/content/calendar-pointer.d.ts +6 -0
- package/dist/types/content/chart-inspection-core.d.ts +61 -0
- package/dist/types/content/chart-inspection.d.ts +4 -20
- package/dist/types/content/chart-snapshot.d.ts +1 -1
- package/dist/types/content/index.d.ts +5 -1
- package/dist/types/feedback/dialog-core.d.ts +16 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/input-mode.d.ts +7 -0
- package/dist/types/inputs/FileDropTarget.d.ts +6 -3
- package/dist/types/inputs/SelectChip.d.ts +2 -0
- package/dist/types/inputs/file-drop.d.ts +2 -0
- package/dist/types/layout/AppWorkspace.d.ts +5 -3
- package/dist/types/layout/DetailPanel.d.ts +11 -0
- package/dist/types/layout/Discussion.d.ts +8 -0
- package/dist/types/layout/ResizeSeparator.d.ts +9 -0
- package/dist/types/layout/TabBar.d.ts +7 -0
- package/dist/types/layout/TableOfContents.d.ts +2 -0
- package/dist/types/layout/app-workspace-controller.d.ts +2 -0
- package/dist/types/layout/detail-panel-messages.d.ts +15 -0
- package/dist/types/layout/index.d.ts +3 -1
- package/dist/types/layout/resize-separator.d.ts +18 -0
- package/dist/types/layout/workspace-messages.d.ts +5 -0
- package/dist/types/surfaces/Avatar.d.ts +12 -0
- package/dist/types/surfaces/AvatarStack.d.ts +41 -0
- package/dist/types/surfaces/StatCell.d.ts +6 -0
- package/dist/types/surfaces/avatar-messages.d.ts +3 -0
- package/dist/types/surfaces/index.d.ts +3 -1
- package/package.json +7 -2
|
@@ -18,41 +18,43 @@ var _tmpl$ = ["<span><strong", ">", "</strong></span>"],
|
|
|
18
18
|
_tmpl$1 = ["<div class=\"k2b-chat-composer__input\" role=\"group\"", ">", "<textarea class=\"", "\" rows=\"1\"", "", "></textarea>", "</div>"],
|
|
19
19
|
_tmpl$10 = ["<span class=\"", "\">", "</span>"],
|
|
20
20
|
_tmpl$11 = ["<small", ">", "</small>"],
|
|
21
|
-
_tmpl$12 = ["<
|
|
22
|
-
_tmpl$13 = ["<
|
|
23
|
-
_tmpl$14 = ["<
|
|
24
|
-
_tmpl$15 = ["<div
|
|
25
|
-
_tmpl$16 = ["<div role=\"status\"><i class=\"ti ti-
|
|
26
|
-
_tmpl$17 = ["<div role=\"status\">", "</div>"],
|
|
27
|
-
_tmpl$18 = ["<div
|
|
28
|
-
_tmpl$19 = ["<div class=\"k2b-chat-composer-
|
|
29
|
-
_tmpl$20 = ["<div class=\"k2b-chat-
|
|
30
|
-
_tmpl$21 = ["<div class=\"k2b-chat-
|
|
31
|
-
_tmpl$22 = ["<div class=\"k2b-chat-
|
|
32
|
-
_tmpl$23 = ["<div class=\"k2b-chat-
|
|
33
|
-
_tmpl$24 = ["<div class=\"k2b-chat-
|
|
34
|
-
_tmpl$25 = ["<
|
|
35
|
-
_tmpl$26 = ["<
|
|
36
|
-
_tmpl$27 = "<
|
|
37
|
-
_tmpl$28 = "<
|
|
38
|
-
_tmpl$29 =
|
|
39
|
-
_tmpl$30 = ["<
|
|
40
|
-
_tmpl$31 = ["<span class=\"k2b-chat-
|
|
41
|
-
_tmpl$32 = ["<
|
|
42
|
-
_tmpl$33 = ["<button type=\"button\" class=\"k2b-chat-
|
|
43
|
-
_tmpl$34 = ["<
|
|
44
|
-
_tmpl$35 = ["<
|
|
45
|
-
_tmpl$36 = ["<
|
|
46
|
-
_tmpl$37 = ["<
|
|
47
|
-
_tmpl$38 = ["<
|
|
48
|
-
_tmpl$39 = ["<
|
|
49
|
-
_tmpl$40 = ["<
|
|
50
|
-
_tmpl$41 = ["<div class=\"k2b-chat-
|
|
51
|
-
_tmpl$42 = ["<
|
|
52
|
-
_tmpl$43 = ["<
|
|
53
|
-
_tmpl$44 = ["<
|
|
21
|
+
_tmpl$12 = ["<span class=\"k2b-chat-composer__command-end\"><i class=\"ti ti-check\" aria-hidden=\"true\"></i><span class=\"k2b-sr-only\">", "</span></span>"],
|
|
22
|
+
_tmpl$13 = ["<button class=\"k2b-chat-composer__command\"", " type=\"button\" role=\"option\" tabindex=\"-1\"", "><i", " aria-hidden=\"true\"></i><span class=\"k2b-chat-composer__command-text\"><strong>", "</strong>", "</span>", "</button>"],
|
|
23
|
+
_tmpl$14 = ["<b>", "</b>"],
|
|
24
|
+
_tmpl$15 = ["<div class=\"k2b-chat-composer-accessory\"><div", " class=\"k2b-chat-composer__commands\" role=\"listbox\"", ">", "</div></div>"],
|
|
25
|
+
_tmpl$16 = ["<div role=\"status\" class=\"k2b-chat-composer__loading\"><i class=\"ti ti-loader-2 k2b-spin\" aria-hidden=\"true\"></i><strong>", "</strong></div>"],
|
|
26
|
+
_tmpl$17 = ["<div role=\"status\"><i class=\"ti ti-alert-circle\"></i> ", "</div>"],
|
|
27
|
+
_tmpl$18 = ["<div role=\"status\">", "</div>"],
|
|
28
|
+
_tmpl$19 = ["<div class=\"k2b-chat-composer-accessory\" data-commands><div", " class=\"k2b-chat-composer__commands\" role=\"listbox\"", ">", "", "", "", "", "</div></div>"],
|
|
29
|
+
_tmpl$20 = ["<div class=\"k2b-chat-composer-slot\"", "><div style=\"", "\"", ">", "</div>", "", "</div>"],
|
|
30
|
+
_tmpl$21 = ["<div class=\"k2b-chat-composer__hint\" aria-live=\"polite\">", "</div>"],
|
|
31
|
+
_tmpl$22 = ["<div class=\"k2b-chat-composer__attachments\" role=\"list\"", " tabindex=\"0\">", "</div>"],
|
|
32
|
+
_tmpl$23 = ["<div class=\"k2b-chat-composer__error\" role=\"alert\"><i class=\"ti ti-alert-circle\" aria-hidden=\"true\"></i>", "</div>"],
|
|
33
|
+
_tmpl$24 = ["<div class=\"k2b-chat-composer__row\">", "", "<div class=\"k2b-chat-composer__field\">", "<div class=\"k2b-chat-composer__field-tools\">", "", "", "</div></div>", "</div>"],
|
|
34
|
+
_tmpl$25 = ["<div class=\"k2b-chat-composer-shell\">", "<section class=\"", "\"", " role=\"group\"", ">", "", "", "", "</section><div class=\"k2b-sr-only\" role=\"status\" aria-live=\"polite\">", "</div><div class=\"k2b-chat-composer__status\" role=\"status\">", "", "</div></div>"],
|
|
35
|
+
_tmpl$26 = ["<button id=\"", "\" type=\"button\" role=\"option\" tabindex=\"-1\"", "><span class=\"k2b-chat-composer__emoji-glyph\" aria-hidden=\"true\">", "</span><strong>", "</strong>", "</button>"],
|
|
36
|
+
_tmpl$27 = ["<small>:", ":</small>"],
|
|
37
|
+
_tmpl$28 = "<i class=\"ti ti-loader-2 k2b-spin\" aria-hidden=\"true\"></i>",
|
|
38
|
+
_tmpl$29 = "<div class=\"k2b-chat-composer__command-placeholder\" aria-hidden=\"true\"><span></span><span><span></span><span></span></span></div>",
|
|
39
|
+
_tmpl$30 = ["<div class=\"k2b-chat-composer__command-group\" role=\"group\"", "><div class=\"k2b-chat-composer__command-heading\"", " role=\"presentation\"><span>", "</span>", "</div>", "", "</div>"],
|
|
40
|
+
_tmpl$31 = ["<span class=\"k2b-chat-composer__hint-text\">", "</span>"],
|
|
41
|
+
_tmpl$32 = ["<span class=\"k2b-chat-composer__dictation\"", "><i", " aria-hidden=\"true\"></i><span>", "</span></span>"],
|
|
42
|
+
_tmpl$33 = ["<button type=\"button\" class=\"k2b-chat-composer__hint-action\"", ">", "</button>"],
|
|
43
|
+
_tmpl$34 = ["<button type=\"button\" class=\"k2b-chat-composer__attachment-remove\"", "", "><i class=\"ti ti-x\" aria-hidden=\"true\"></i></button>"],
|
|
44
|
+
_tmpl$35 = ["<div class=\"k2b-chat-composer__attachment\" role=\"listitem\"><div class=\"", "\">", "", "</div>", "</div>"],
|
|
45
|
+
_tmpl$36 = ["<img", ">"],
|
|
46
|
+
_tmpl$37 = ["<div class=\"k2b-chat-composer__attachment-identity\">", "", "</div>"],
|
|
47
|
+
_tmpl$38 = ["<a class=\"k2b-chat-composer__attachment-link\"", " target=\"_blank\" rel=\"noopener noreferrer\"", ">", "", "</a>"],
|
|
48
|
+
_tmpl$39 = ["<button type=\"button\" class=\"k2b-chat-composer__attachment-action\"", ">", "", "</button>"],
|
|
49
|
+
_tmpl$40 = ["<footer class=\"k2b-chat-composer__footer\">", "</footer>"],
|
|
50
|
+
_tmpl$41 = ["<div class=\"k2b-chat-composer__tools\">", "", "", "", "", "", "", "</div>"],
|
|
51
|
+
_tmpl$42 = ["<div class=\"k2b-chat-composer__submit\">", "", "", "", "", "</div>"],
|
|
52
|
+
_tmpl$43 = ["<span>", "</span>"],
|
|
53
|
+
_tmpl$44 = ["<div class=\"k2b-chat-composer__status-line\"", "><i aria-hidden=\"true\"", "></i><span>", "</span></div>"],
|
|
54
|
+
_tmpl$45 = ["<span class=\"k2b-sr-only\">", "</span>"];
|
|
54
55
|
import { batch, children, createEffect, createMemo, createSignal, createUniqueId, For, onCleanup, onMount, Show, untrack } from "solid-js";
|
|
55
56
|
import { Dropdown } from "../actions/Dropdown";
|
|
57
|
+
import { dialogHistorySettled, holdDialogHistory } from "../feedback/dialog-core";
|
|
56
58
|
import { Tooltip } from "../feedback/Tooltip";
|
|
57
59
|
import { replaceTextareaRange } from "../inputs/editor-dom";
|
|
58
60
|
import { completedEmojiShortcode, emojiInTone, emojiName, emojiShortcodeQuery, loadEmojiIndex, suggestEmoji } from "../inputs/emoji/emoji-index";
|
|
@@ -76,7 +78,10 @@ const emojiSuggestionLimit = 8;
|
|
|
76
78
|
// Keep editor undo text within approximately 2 MiB, plus the current edit.
|
|
77
79
|
const composerUndoBudgetChars = 1_000_000;
|
|
78
80
|
|
|
79
|
-
/**
|
|
81
|
+
/**
|
|
82
|
+
* An action can cancel and restore its token, report a short completion message, or hand back a reference chosen in a
|
|
83
|
+
* dialog: `mention` takes the token's place exactly as a `mention` row does, and Ctrl/⌘+Z brings the token back.
|
|
84
|
+
*/
|
|
80
85
|
|
|
81
86
|
/** A fixed place in the slash list. Sections keep the given order, also while searching. */
|
|
82
87
|
|
|
@@ -114,12 +119,40 @@ const isTouchOnly = () => typeof matchMedia === "function" && matchMedia(touchOn
|
|
|
114
119
|
const microphoneHoldMs = 500;
|
|
115
120
|
/** Keeps the field focused (and a phone's keyboard open) when a composer button is pressed with a mouse or finger. */
|
|
116
121
|
const keepFieldFocus = event => event.preventDefault();
|
|
122
|
+
/**
|
|
123
|
+
* Keeps one tap from reaching the page: its pointer, touch and mouse events stop at the window, and neither focus nor a
|
|
124
|
+
* click happens. A finger's tap ends with `touchend`, a scroll with `pointercancel`, a mouse's press with `click`.
|
|
125
|
+
*/
|
|
126
|
+
const swallowTap = down => {
|
|
127
|
+
const blocked = ["pointerup", "pointercancel", "touchstart", "touchend", "mousedown", "mouseup", "click", "contextmenu"];
|
|
128
|
+
const stop = () => {
|
|
129
|
+
window.removeEventListener("pointerdown", next, true);
|
|
130
|
+
for (const type of blocked) window.removeEventListener(type, block, true);
|
|
131
|
+
};
|
|
132
|
+
const block = event => {
|
|
133
|
+
event.stopPropagation();
|
|
134
|
+
if (event.type !== "pointercancel" && event.type !== "touchstart" && event.type !== "pointerup") event.preventDefault();
|
|
135
|
+
if (event.type === "click" || event.type === "touchend" || event.type === "pointercancel") stop();
|
|
136
|
+
};
|
|
137
|
+
// The next press is a new gesture, whatever became of this one.
|
|
138
|
+
const next = event => {
|
|
139
|
+
if (event !== down) stop();
|
|
140
|
+
};
|
|
141
|
+
down.stopPropagation();
|
|
142
|
+
down.preventDefault();
|
|
143
|
+
window.addEventListener("pointerdown", next, true);
|
|
144
|
+
for (const type of blocked) window.addEventListener(type, block, {
|
|
145
|
+
capture: true,
|
|
146
|
+
passive: false
|
|
147
|
+
});
|
|
148
|
+
};
|
|
117
149
|
const attachmentIcon = attachment => attachment.icon ?? (attachment.kind === "image" ? "ti ti-photo" : attachment.kind === "resource" ? "ti ti-link" : "ti ti-file");
|
|
118
150
|
const hasContent = items => items.some(item => item != null && typeof item !== "boolean" && item !== "");
|
|
119
151
|
export function ChatComposer(props) {
|
|
120
152
|
const accessory = children(() => props.accessory);
|
|
121
153
|
const hasAccessory = () => hasContent(accessory.toArray());
|
|
122
154
|
const hint = children(() => props.hint);
|
|
155
|
+
const footer = children(() => props.footerContent);
|
|
123
156
|
const messages = useUiMessages();
|
|
124
157
|
const markdownToolbarMessages = useMarkdownToolbarMessages();
|
|
125
158
|
const chatMessages = useChatMessages();
|
|
@@ -140,6 +173,7 @@ export function ChatComposer(props) {
|
|
|
140
173
|
const [closedAt, setClosedAt] = createSignal();
|
|
141
174
|
// Where the pending native edit starts; a selection replaced as a whole starts at its beginning.
|
|
142
175
|
let inputStart;
|
|
176
|
+
let inputEnd;
|
|
143
177
|
const [commandStatus, setCommandStatus] = createSignal();
|
|
144
178
|
const [announcement, setAnnouncement] = createSignal();
|
|
145
179
|
let statusTimer;
|
|
@@ -158,6 +192,7 @@ export function ChatComposer(props) {
|
|
|
158
192
|
});
|
|
159
193
|
const [addingFiles, setAddingFiles] = createSignal(false);
|
|
160
194
|
const [submitting, setSubmitting] = createSignal(false);
|
|
195
|
+
let shellRef;
|
|
161
196
|
let composerRef;
|
|
162
197
|
let textareaRef;
|
|
163
198
|
let fileInputRef;
|
|
@@ -185,6 +220,45 @@ export function ChatComposer(props) {
|
|
|
185
220
|
const [searching, setSearching] = createSignal(false);
|
|
186
221
|
const [searchError, setSearchError] = createSignal(false);
|
|
187
222
|
const [executing, setExecuting] = createSignal(false);
|
|
223
|
+
const [modelOpen, setModelOpen] = createSignal();
|
|
224
|
+
const [choosingModel, setChoosingModel] = createSignal(false);
|
|
225
|
+
let resolveModel;
|
|
226
|
+
const finishModelSelection = id => {
|
|
227
|
+
const resolve = resolveModel;
|
|
228
|
+
resolveModel = undefined;
|
|
229
|
+
if (choosingModel()) {
|
|
230
|
+
setModelOpen(false);
|
|
231
|
+
// Let the controlled close reach Dropdown before returning normal clicks to its own state.
|
|
232
|
+
queueMicrotask(() => {
|
|
233
|
+
if (!choosingModel()) setModelOpen(undefined);
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
setChoosingModel(false);
|
|
237
|
+
resolve?.(id);
|
|
238
|
+
};
|
|
239
|
+
const blockedBesidesCommand = () => Boolean(props.disabled || stopping() || state() === "submitting" || addingFiles() || submitting());
|
|
240
|
+
const usableModelControl = () => !conversation() && !footer() && !blockedBesidesCommand() && !running() && Boolean(props.models?.length && props.onModelChange);
|
|
241
|
+
const openModelSelection = () => {
|
|
242
|
+
if (!usableModelControl()) return Promise.resolve(null);
|
|
243
|
+
finishModelSelection(null);
|
|
244
|
+
return new Promise(resolve => {
|
|
245
|
+
resolveModel = resolve;
|
|
246
|
+
setChoosingModel(true);
|
|
247
|
+
setModelOpen(true);
|
|
248
|
+
queueMicrotask(() => {
|
|
249
|
+
if (!choosingModel() || !modelOpen()) return;
|
|
250
|
+
// Start on the current model, as a click on the chip would show it checked.
|
|
251
|
+
const menu = composerRef?.querySelector(".k2b-chat-composer__model");
|
|
252
|
+
(menu?.querySelector('[role="menuitemradio"][aria-checked="true"]:not(:disabled)') ?? menu?.querySelector('[role="menuitemradio"]:not(:disabled)'))?.focus();
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
};
|
|
256
|
+
createEffect(() => {
|
|
257
|
+
if (!usableModelControl()) finishModelSelection(null);
|
|
258
|
+
});
|
|
259
|
+
onCleanup(() => finishModelSelection(null));
|
|
260
|
+
const [commandOpening, setCommandOpening] = createSignal(0);
|
|
261
|
+
let retrySearch = false;
|
|
188
262
|
let highlightRef;
|
|
189
263
|
let commandListRef;
|
|
190
264
|
const mentions = () => props.mentions ?? [];
|
|
@@ -218,7 +292,21 @@ export function ChatComposer(props) {
|
|
|
218
292
|
const token = caretCommandToken();
|
|
219
293
|
return dismissed() || composing() || token?.start === closedAt() ? null : token;
|
|
220
294
|
});
|
|
295
|
+
const openingStart = createMemo(() => commandQuery()?.start);
|
|
296
|
+
createEffect(() => {
|
|
297
|
+
props.draftKey;
|
|
298
|
+
const start = openingStart();
|
|
299
|
+
if (start !== undefined) setCommandOpening(opening => opening + 1);
|
|
300
|
+
});
|
|
221
301
|
const parsedCommandQuery = createMemo(() => parseChatCommandQuery(commandQuery()?.query ?? "", props.commandScopes ?? []));
|
|
302
|
+
const commandFallbackRow = createMemo(() => {
|
|
303
|
+
const parsed = parsedCommandQuery();
|
|
304
|
+
const query = parsed.query.trim();
|
|
305
|
+
return commandQuery() && (query || parsed.scope) ? props.commandFallback?.({
|
|
306
|
+
query,
|
|
307
|
+
scope: parsed.scope?.id
|
|
308
|
+
}) : undefined;
|
|
309
|
+
});
|
|
222
310
|
const currentCommandScope = createMemo(() => parsedCommandQuery().scope?.id);
|
|
223
311
|
createEffect(() => {
|
|
224
312
|
currentCommandScope();
|
|
@@ -234,9 +322,12 @@ export function ChatComposer(props) {
|
|
|
234
322
|
searchResults: searchResultsScope() === parsedCommandQuery().scope?.id ? searchResults() : [],
|
|
235
323
|
searchResultsFresh: searchResultsQuery() === commandQuery()?.query && searchResultsScope() === parsedCommandQuery().scope?.id,
|
|
236
324
|
searchSettled: searchResultsQuery() !== undefined && searchResultsScope() === parsedCommandQuery().scope?.id,
|
|
237
|
-
searching: searching()
|
|
325
|
+
searching: searching(),
|
|
326
|
+
fallback: commandFallbackRow()
|
|
238
327
|
}));
|
|
239
328
|
const commandMatches = createMemo(() => commandQuery() ? commandModel().rows.map(row => row.command) : []);
|
|
329
|
+
/** Rows that matched; an unscoped fallback row only follows them. */
|
|
330
|
+
const foundCommandCount = () => commandMatches().length - (commandModel().fallback ? 1 : 0);
|
|
240
331
|
const currentCommandQuery = createMemo(() => caretCommandToken()?.query);
|
|
241
332
|
// Arrow marking belongs to one token in one draft; another draft or `/` starts at the top row again.
|
|
242
333
|
createEffect(() => {
|
|
@@ -245,21 +336,46 @@ export function ChatComposer(props) {
|
|
|
245
336
|
currentCommandQuery();
|
|
246
337
|
setCommandMoved(false);
|
|
247
338
|
});
|
|
248
|
-
const commandsOpen = () => Boolean(!emojiOpen() && commandQuery() && (localCommands().length || props.searchCommands));
|
|
339
|
+
const commandsOpen = () => Boolean(!emojiOpen() && commandQuery() && (localCommands().length || props.searchCommands || commandFallbackRow()));
|
|
340
|
+
const commandSheetHeld = createMemo(() => commandsOpen() && isTouchOnly());
|
|
341
|
+
createEffect(() => {
|
|
342
|
+
if (!commandSheetHeld()) return;
|
|
343
|
+
onCleanup(holdDialogHistory(() => setClosedAt(commandQuery()?.start)));
|
|
344
|
+
});
|
|
249
345
|
const suggestionsOpen = () => commandsOpen() || emojiOpen();
|
|
250
346
|
createEffect(() => {
|
|
251
347
|
if (!suggestionsOpen()) return;
|
|
252
348
|
let disposed = false;
|
|
253
349
|
const measure = () => {
|
|
254
350
|
if (disposed || !commandListRef) return;
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
351
|
+
const accessory = commandListRef.parentElement;
|
|
352
|
+
const viewportTop = window.visualViewport?.offsetTop ?? 0;
|
|
353
|
+
let top = viewportTop;
|
|
354
|
+
// The column a phone sheet spans: the nearest ancestor that clips sideways, or the page.
|
|
355
|
+
let column;
|
|
356
|
+
for (let parent = accessory.parentElement; parent; parent = parent.parentElement) {
|
|
357
|
+
const style = window.getComputedStyle(parent);
|
|
358
|
+
if (/(auto|scroll|hidden|clip)/.test(style.overflowY)) {
|
|
258
359
|
top = Math.max(top, parent.getBoundingClientRect().top);
|
|
259
360
|
}
|
|
361
|
+
if (!column && /(auto|scroll|hidden|clip)/.test(style.overflowX)) {
|
|
362
|
+
const left = parent.getBoundingClientRect().left + parent.clientLeft;
|
|
363
|
+
column = {
|
|
364
|
+
left,
|
|
365
|
+
right: left + parent.clientWidth
|
|
366
|
+
};
|
|
367
|
+
}
|
|
260
368
|
}
|
|
261
|
-
const
|
|
369
|
+
const page = document.documentElement.clientWidth;
|
|
370
|
+
const left = Math.max(0, column?.left ?? 0);
|
|
371
|
+
const right = Math.min(page, column?.right ?? page);
|
|
372
|
+
const slot = accessory.parentElement.getBoundingClientRect();
|
|
373
|
+
const bottom = accessory.getBoundingClientRect().bottom;
|
|
262
374
|
commandListRef.style.setProperty("--k2b-chat-command-space", `${Math.max(40, bottom - top - 8)}px`);
|
|
375
|
+
// Only a list that reaches the screen's top edge keeps clear of a notch or the status bar.
|
|
376
|
+
commandListRef.style.setProperty("--k2b-chat-command-safe-top", top === viewportTop ? "env(safe-area-inset-top, 0px)" : "0px");
|
|
377
|
+
accessory.style.setProperty("--k2b-chat-command-reach-left", `${Math.max(0, slot.left - left)}px`);
|
|
378
|
+
accessory.style.setProperty("--k2b-chat-command-reach-right", `${Math.max(0, right - slot.right)}px`);
|
|
263
379
|
};
|
|
264
380
|
queueMicrotask(measure);
|
|
265
381
|
window.addEventListener("resize", measure);
|
|
@@ -272,6 +388,20 @@ export function ChatComposer(props) {
|
|
|
272
388
|
window.visualViewport?.removeEventListener("resize", measure);
|
|
273
389
|
});
|
|
274
390
|
});
|
|
391
|
+
// A press outside the command list and the field closes the list, as Escape does; the text stays. With a mouse or a
|
|
392
|
+
// trackpad the press then acts as usual. On a touch-only device a tap outside the composer closes only the list: it
|
|
393
|
+
// reaches nothing beneath, and the field keeps focus, so the keyboard stays open.
|
|
394
|
+
createEffect(() => {
|
|
395
|
+
if (!commandsOpen()) return;
|
|
396
|
+
const onPointerDown = event => {
|
|
397
|
+
const target = event.target;
|
|
398
|
+
if (!(target instanceof Node) || commandListRef?.contains(target) || textareaRef?.parentElement?.contains(target)) return;
|
|
399
|
+
setClosedAt(commandQuery()?.start);
|
|
400
|
+
if (isTouchOnly() && !shellRef?.contains(target)) swallowTap(event);
|
|
401
|
+
};
|
|
402
|
+
window.addEventListener("pointerdown", onPointerDown, true);
|
|
403
|
+
onCleanup(() => window.removeEventListener("pointerdown", onPointerDown, true));
|
|
404
|
+
});
|
|
275
405
|
createEffect(() => {
|
|
276
406
|
props.draftKey;
|
|
277
407
|
const token = commandQuery();
|
|
@@ -280,12 +410,17 @@ export function ChatComposer(props) {
|
|
|
280
410
|
setSearching(false);
|
|
281
411
|
return;
|
|
282
412
|
}
|
|
413
|
+
running();
|
|
283
414
|
const parsed = parsedCommandQuery();
|
|
415
|
+
const opening = commandOpening();
|
|
284
416
|
const abort = new AbortController();
|
|
285
417
|
setSearching(true);
|
|
418
|
+
const delay = retrySearch ? 0 : 120;
|
|
419
|
+
retrySearch = false;
|
|
286
420
|
const timer = setTimeout(() => {
|
|
287
421
|
Promise.resolve().then(() => props.searchCommands(parsed.query, abort.signal, {
|
|
288
|
-
scope: parsed.scope?.id
|
|
422
|
+
scope: parsed.scope?.id,
|
|
423
|
+
opening
|
|
289
424
|
})).then(results => {
|
|
290
425
|
if (!abort.signal.aborted) {
|
|
291
426
|
batch(() => {
|
|
@@ -303,7 +438,7 @@ export function ChatComposer(props) {
|
|
|
303
438
|
}).finally(() => {
|
|
304
439
|
if (!abort.signal.aborted) setSearching(false);
|
|
305
440
|
});
|
|
306
|
-
},
|
|
441
|
+
}, delay);
|
|
307
442
|
onCleanup(() => {
|
|
308
443
|
clearTimeout(timer);
|
|
309
444
|
abort.abort();
|
|
@@ -362,6 +497,7 @@ export function ChatComposer(props) {
|
|
|
362
497
|
untrack(() => {
|
|
363
498
|
history.length = 0;
|
|
364
499
|
historyIndex = -1;
|
|
500
|
+
finishModelSelection(null);
|
|
365
501
|
setDismissed(true);
|
|
366
502
|
setClosedAt(undefined);
|
|
367
503
|
setSearchResults([]);
|
|
@@ -387,6 +523,13 @@ export function ChatComposer(props) {
|
|
|
387
523
|
};
|
|
388
524
|
const edit = (value, nextMentions = reconcileChatMentions(props.value, value, mentions())) => {
|
|
389
525
|
if (commandStatus()?.tone === "error") showCommandStatus();
|
|
526
|
+
// Replacing `/` can leave its position and query identical, but starts a new opening.
|
|
527
|
+
if (inputStart !== undefined && inputEnd !== undefined && props.value.slice(inputStart, inputEnd).includes("/")) {
|
|
528
|
+
setCommandOpening(opening => opening + 1);
|
|
529
|
+
setSearchResults([]);
|
|
530
|
+
setSearchResultsQuery(undefined);
|
|
531
|
+
setCommandMoved(false);
|
|
532
|
+
}
|
|
390
533
|
// An edit that starts at or before the closed `/` (select all, then type `/`) replaces it; the new `/` may open again.
|
|
391
534
|
const closed = closedAt();
|
|
392
535
|
if (closed !== undefined) {
|
|
@@ -395,6 +538,7 @@ export function ChatComposer(props) {
|
|
|
395
538
|
if (Math.min(same, inputStart ?? same) <= closed) setClosedAt(undefined);
|
|
396
539
|
}
|
|
397
540
|
inputStart = undefined;
|
|
541
|
+
inputEnd = undefined;
|
|
398
542
|
record();
|
|
399
543
|
props.onValueChange(value);
|
|
400
544
|
props.onMentionsChange?.(nextMentions);
|
|
@@ -438,7 +582,9 @@ export function ChatComposer(props) {
|
|
|
438
582
|
/** The conversation field stays editable while a message is sent, so it keeps the focus and a phone its keyboard. */
|
|
439
583
|
const editBlocked = () => conversation() ? busy() : blocked();
|
|
440
584
|
const hasDraft = () => Boolean(props.value.trim() || !running() && attachments().length > 0);
|
|
441
|
-
|
|
585
|
+
/** The draft may go out now, apart from a submission that is already on its way. */
|
|
586
|
+
const submittable = () => !busy() && hasDraft() && !(running() && runningSubmitIntent() === "steer" && mentions().length);
|
|
587
|
+
const canSubmit = () => !submitting() && submittable();
|
|
442
588
|
const canSelectFiles = () => Boolean(props.fileSelection && !props.fileSelection.disabled && !running() && !blocked());
|
|
443
589
|
const hasAddMenu = () => Boolean(props.fileSelection || props.menuActions?.length);
|
|
444
590
|
const hasContextUsage = () => {
|
|
@@ -534,12 +680,78 @@ export function ChatComposer(props) {
|
|
|
534
680
|
});
|
|
535
681
|
const setAttachments = next => props.onAttachmentsChange?.(next);
|
|
536
682
|
const renderAttachmentCopy = attachment => _$ssr(_tmpl$, _$ssrAttribute("title", _$escape(attachment.name, true), false), _$escape(attachment.name));
|
|
537
|
-
|
|
683
|
+
|
|
684
|
+
/** `onNothing` runs when the person closes the selection without a file. */
|
|
685
|
+
const chooseFiles = onNothing => {
|
|
538
686
|
const selection = props.fileSelection;
|
|
539
|
-
if (!selection?.choose)
|
|
540
|
-
|
|
687
|
+
if (!selection?.choose) {
|
|
688
|
+
const input = fileInputRef;
|
|
689
|
+
if (input && onNothing) {
|
|
690
|
+
const done = new AbortController();
|
|
691
|
+
input.addEventListener("cancel", () => {
|
|
692
|
+
done.abort();
|
|
693
|
+
onNothing();
|
|
694
|
+
}, {
|
|
695
|
+
signal: done.signal
|
|
696
|
+
});
|
|
697
|
+
input.addEventListener("change", () => done.abort(), {
|
|
698
|
+
signal: done.signal
|
|
699
|
+
});
|
|
700
|
+
}
|
|
701
|
+
return input?.click();
|
|
702
|
+
}
|
|
703
|
+
const failed = error => {
|
|
704
|
+
onNothing?.();
|
|
705
|
+
(props.fileSelection?.onError ?? props.onError)?.(error);
|
|
706
|
+
};
|
|
707
|
+
let chosen;
|
|
708
|
+
try {
|
|
709
|
+
chosen = selection.choose();
|
|
710
|
+
} catch (error) {
|
|
711
|
+
failed(error);
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
chosen.then(
|
|
541
715
|
// A single-file composer keeps the first chosen file, as its file dialog and drops do.
|
|
542
|
-
files =>
|
|
716
|
+
files => {
|
|
717
|
+
if (files.length === 0) onNothing?.();else void runFiles(selection.multiple === false ? files.slice(0, 1) : files);
|
|
718
|
+
}, failed);
|
|
719
|
+
};
|
|
720
|
+
|
|
721
|
+
/**
|
|
722
|
+
* "Attach files" from the slash list: the token leaves as one edit, and the selection opens synchronously, inside the
|
|
723
|
+
* key or click that chose the row, because the device's file dialog needs that activation. Closing the selection
|
|
724
|
+
* without a file brings the token back, unless the draft changed meanwhile.
|
|
725
|
+
*/
|
|
726
|
+
const attachFilesFromCommand = token => {
|
|
727
|
+
if (!canSelectFiles()) return;
|
|
728
|
+
const key = props.draftKey;
|
|
729
|
+
const previous = snapshot();
|
|
730
|
+
const previousHistory = {
|
|
731
|
+
entries: [...history],
|
|
732
|
+
index: historyIndex
|
|
733
|
+
};
|
|
734
|
+
const nextValue = props.value.slice(0, token.start) + props.value.slice(token.end);
|
|
735
|
+
edit(nextValue, reconcileChatMentions(props.value, nextValue, mentions()));
|
|
736
|
+
setDismissed(true);
|
|
737
|
+
chooseFiles(() => {
|
|
738
|
+
if (props.draftKey !== key || props.value !== nextValue) return;
|
|
739
|
+
setDismissed(true);
|
|
740
|
+
props.onValueChange(previous.value);
|
|
741
|
+
props.onMentionsChange?.(previous.mentions);
|
|
742
|
+
history.splice(0, history.length, ...previousHistory.entries);
|
|
743
|
+
historyIndex = previousHistory.index;
|
|
744
|
+
queueMicrotask(() => {
|
|
745
|
+
textareaRef?.setSelectionRange(token.end, token.end);
|
|
746
|
+
syncCaret();
|
|
747
|
+
focus();
|
|
748
|
+
});
|
|
749
|
+
});
|
|
750
|
+
queueMicrotask(() => {
|
|
751
|
+
if (props.draftKey !== key || props.value !== nextValue) return;
|
|
752
|
+
textareaRef?.setSelectionRange(token.start, token.start);
|
|
753
|
+
syncCaret();
|
|
754
|
+
});
|
|
543
755
|
};
|
|
544
756
|
const runFiles = async files => {
|
|
545
757
|
if (!canSelectFiles()) return;
|
|
@@ -558,18 +770,26 @@ export function ChatComposer(props) {
|
|
|
558
770
|
};
|
|
559
771
|
const submit = async () => {
|
|
560
772
|
if (!canSubmit()) return;
|
|
561
|
-
const
|
|
562
|
-
const previousValue = props.value;
|
|
563
|
-
const previousAttachments = attachments();
|
|
564
|
-
const previousMentions = mentions();
|
|
565
|
-
const input = {
|
|
566
|
-
intent,
|
|
567
|
-
text: previousValue,
|
|
568
|
-
mentions: previousMentions,
|
|
569
|
-
attachments: intent !== "steer" ? previousAttachments : []
|
|
570
|
-
};
|
|
773
|
+
const key = props.draftKey;
|
|
571
774
|
setSubmitting(true);
|
|
572
775
|
try {
|
|
776
|
+
if (isTouchOnly()) {
|
|
777
|
+
if (commandSheetHeld()) setClosedAt(commandQuery()?.start);
|
|
778
|
+
// The sheet's Back entry leaves first, so a submit handler that navigates finds the history settled.
|
|
779
|
+
await dialogHistorySettled();
|
|
780
|
+
// A draft that another one replaced, or that may no longer go out, is not sent and keeps its text.
|
|
781
|
+
if (disposed || props.draftKey !== key || !submittable()) return;
|
|
782
|
+
}
|
|
783
|
+
const intent = running() ? runningSubmitIntent() : "send";
|
|
784
|
+
const previousValue = props.value;
|
|
785
|
+
const previousAttachments = attachments();
|
|
786
|
+
const previousMentions = mentions();
|
|
787
|
+
const input = {
|
|
788
|
+
intent,
|
|
789
|
+
text: previousValue,
|
|
790
|
+
mentions: previousMentions,
|
|
791
|
+
attachments: intent !== "steer" ? previousAttachments : []
|
|
792
|
+
};
|
|
573
793
|
await runChatSubmission({
|
|
574
794
|
clear: () => {
|
|
575
795
|
props.onValueChange("");
|
|
@@ -612,6 +832,7 @@ export function ChatComposer(props) {
|
|
|
612
832
|
};
|
|
613
833
|
const executeCommand = async (command, tab = false) => {
|
|
614
834
|
const token = commandQuery();
|
|
835
|
+
const heldHistory = commandSheetHeld();
|
|
615
836
|
if (!token || blocked()) return;
|
|
616
837
|
if (command.disabled || command.reason) {
|
|
617
838
|
// A new object each time, so choosing the same row again inserts and announces its reason again.
|
|
@@ -620,7 +841,16 @@ export function ChatComposer(props) {
|
|
|
620
841
|
} : undefined);
|
|
621
842
|
return;
|
|
622
843
|
}
|
|
623
|
-
if (command.
|
|
844
|
+
if (command.searchAgain) {
|
|
845
|
+
retrySearch = true;
|
|
846
|
+
setCommandOpening(opening => opening + 1);
|
|
847
|
+
return;
|
|
848
|
+
}
|
|
849
|
+
if (command.scope && (tab || !command.action && !command.mention && !command.attachFiles) && narrowCommand(command)) return;
|
|
850
|
+
if (command.attachFiles) {
|
|
851
|
+
attachFilesFromCommand(token);
|
|
852
|
+
return;
|
|
853
|
+
}
|
|
624
854
|
const previous = snapshot();
|
|
625
855
|
const key = props.draftKey;
|
|
626
856
|
const replacement = command.mention ? command.mention.name + " " : "";
|
|
@@ -641,6 +871,7 @@ export function ChatComposer(props) {
|
|
|
641
871
|
setExecuting(true);
|
|
642
872
|
let submitRequested = false;
|
|
643
873
|
let restored = false;
|
|
874
|
+
let mentioned;
|
|
644
875
|
const restore = () => {
|
|
645
876
|
if (props.draftKey !== key || props.value !== nextValue) return;
|
|
646
877
|
setDismissed(true);
|
|
@@ -655,17 +886,50 @@ export function ChatComposer(props) {
|
|
|
655
886
|
text: command.busyLabel
|
|
656
887
|
} : undefined);
|
|
657
888
|
try {
|
|
889
|
+
// The sheet's Back entry leaves first, so an action that navigates or opens a dialog finds the history settled.
|
|
890
|
+
if (heldHistory && command.action) {
|
|
891
|
+
await dialogHistorySettled();
|
|
892
|
+
// Another draft or no composer any more: the command does not run against it.
|
|
893
|
+
if (disposed || props.draftKey !== key) return;
|
|
894
|
+
}
|
|
658
895
|
const result = await command.action?.({
|
|
659
896
|
setValue: value => edit(value),
|
|
660
897
|
submit: () => {
|
|
661
898
|
submitRequested = true;
|
|
662
899
|
},
|
|
663
|
-
focus
|
|
900
|
+
focus,
|
|
901
|
+
openModelSelection
|
|
664
902
|
});
|
|
665
903
|
if (result === "cancelled") {
|
|
666
904
|
submitRequested = false;
|
|
667
905
|
restore();
|
|
668
906
|
showCommandStatus();
|
|
907
|
+
} else if (result && "mention" in result) {
|
|
908
|
+
// One undo step from the token to the reference, as if the row had been a reference itself.
|
|
909
|
+
if (props.draftKey === key && props.value === nextValue) {
|
|
910
|
+
restore();
|
|
911
|
+
restored = false;
|
|
912
|
+
const name = result.mention.name;
|
|
913
|
+
const withMention = previous.value.slice(0, token.start) + name + " " + previous.value.slice(token.end);
|
|
914
|
+
edit(withMention, [...reconcileChatMentions(previous.value, withMention, previous.mentions), {
|
|
915
|
+
start: token.start,
|
|
916
|
+
end: token.start + name.length,
|
|
917
|
+
attachment: result.mention
|
|
918
|
+
}]);
|
|
919
|
+
setDismissed(true);
|
|
920
|
+
mentioned = {
|
|
921
|
+
value: withMention,
|
|
922
|
+
caret: token.start + name.length + 1
|
|
923
|
+
};
|
|
924
|
+
showCommandStatus();
|
|
925
|
+
} else {
|
|
926
|
+
// The pick is lost; say so, also when the draft moved to another key meanwhile (such as a new chat saved
|
|
927
|
+
// while the dialog was open), so it never ends in silence.
|
|
928
|
+
showCommandStatus({
|
|
929
|
+
tone: "error",
|
|
930
|
+
text: chatMessages().commandDraftChanged
|
|
931
|
+
});
|
|
932
|
+
}
|
|
669
933
|
} else if (result) {
|
|
670
934
|
showCommandStatus({
|
|
671
935
|
tone: "done",
|
|
@@ -687,8 +951,8 @@ export function ChatComposer(props) {
|
|
|
687
951
|
if (submitRequested && props.draftKey === key) await submit();
|
|
688
952
|
queueMicrotask(() => {
|
|
689
953
|
if (props.draftKey !== key) return;
|
|
690
|
-
if (restored || props.value === nextValue) {
|
|
691
|
-
const position = restored ? token.end : token.start + replacement.length;
|
|
954
|
+
if (restored || props.value === nextValue || mentioned && props.value === mentioned.value) {
|
|
955
|
+
const position = restored ? token.end : mentioned?.caret ?? token.start + replacement.length;
|
|
692
956
|
textareaRef?.setSelectionRange(position, position);
|
|
693
957
|
}
|
|
694
958
|
syncCaret();
|
|
@@ -940,7 +1204,7 @@ export function ChatComposer(props) {
|
|
|
940
1204
|
get disabled() {
|
|
941
1205
|
return !canSelectFiles();
|
|
942
1206
|
},
|
|
943
|
-
onClick: chooseFiles,
|
|
1207
|
+
onClick: () => chooseFiles(),
|
|
944
1208
|
get children() {
|
|
945
1209
|
return _$ssr(_tmpl$3, _$ssrAttribute("class", addingFiles() ? "ti ti-loader-2 k2b-spin" : "ti ti-plus", false));
|
|
946
1210
|
}
|
|
@@ -1216,14 +1480,14 @@ export function ChatComposer(props) {
|
|
|
1216
1480
|
const renderCommandRow = command => {
|
|
1217
1481
|
const highlight = () => commandRowMap().get(command)?.highlight;
|
|
1218
1482
|
const title = () => command.label ?? command.name;
|
|
1219
|
-
return _$ssr(_tmpl$
|
|
1483
|
+
return _$ssr(_tmpl$13, _$ssrAttribute("id", _$escape(commandOptionId(command), true), false), _$ssrAttribute("aria-selected", _$escape(selectedCommand(), true) === _$escape(command, true), false) + _$ssrAttribute("aria-disabled", _$escape(Boolean(command.disabled || command.reason), true), false) + _$ssrAttribute("aria-describedby", command.reason ? `${_$escape(commandOptionId(command), true)}-reason` : _$escape(undefined, true), false) + _$ssrAttribute("data-reason", command.reason ? "true" : _$escape(undefined, true), false) + _$ssrAttribute("data-active", selectedCommand() === command ? "true" : _$escape(undefined, true), false), _$ssrAttribute("class", _$escape(command.icon ?? "ti ti-slash", true), false), _$escape(_$createComponent(Show, {
|
|
1220
1484
|
get when() {
|
|
1221
1485
|
return highlight();
|
|
1222
1486
|
},
|
|
1223
1487
|
get fallback() {
|
|
1224
1488
|
return title();
|
|
1225
1489
|
},
|
|
1226
|
-
children: range => [title().slice(0, range()[0]), _$ssr(_tmpl$
|
|
1490
|
+
children: range => [title().slice(0, range()[0]), _$ssr(_tmpl$14, _$escape(title().slice(range()[0], range()[1]))), title().slice(range()[1])]
|
|
1227
1491
|
})), _$escape(_$createComponent(Show, {
|
|
1228
1492
|
get when() {
|
|
1229
1493
|
return command.reason ?? command.description;
|
|
@@ -1231,27 +1495,34 @@ export function ChatComposer(props) {
|
|
|
1231
1495
|
get children() {
|
|
1232
1496
|
return _$ssr(_tmpl$11, _$ssrAttribute("id", command.reason ? `${_$escape(commandOptionId(command), true)}-reason` : _$escape(undefined, true), false), _$escape(command.reason ?? command.description));
|
|
1233
1497
|
}
|
|
1498
|
+
})), _$escape(_$createComponent(Show, {
|
|
1499
|
+
get when() {
|
|
1500
|
+
return command.selected;
|
|
1501
|
+
},
|
|
1502
|
+
get children() {
|
|
1503
|
+
return _$ssr(_tmpl$12, _$escape(chatMessages().commandSelected));
|
|
1504
|
+
}
|
|
1234
1505
|
})));
|
|
1235
1506
|
};
|
|
1236
|
-
return _$ssr(_tmpl$
|
|
1507
|
+
return _$ssr(_tmpl$25, _$escape(_$createComponent(Show, {
|
|
1237
1508
|
get when() {
|
|
1238
1509
|
return suggestionsOpen() || hasAccessory();
|
|
1239
1510
|
},
|
|
1240
1511
|
get children() {
|
|
1241
|
-
return _$ssr(_tmpl$
|
|
1512
|
+
return _$ssr(_tmpl$20, _$ssrAttribute("data-overlay", hasAccessory() ? _$escape(undefined, true) : "true", false), _$ssrStyleProperty("visibility:", suggestionsOpen() ? "hidden" : _$escape(undefined, true)), _$ssrAttribute("inert", suggestionsOpen(), true), _$escape(accessory()), _$escape(_$createComponent(Show, {
|
|
1242
1513
|
get when() {
|
|
1243
1514
|
return emojiOpen();
|
|
1244
1515
|
},
|
|
1245
1516
|
get children() {
|
|
1246
|
-
return _$ssr(_tmpl$
|
|
1517
|
+
return _$ssr(_tmpl$15, _$ssrAttribute("id", _$escape(commandListId, true), false), _$ssrAttribute("aria-label", _$escape(chatMessages().emojiSuggestions, true), false), _$escape(_$createComponent(For, {
|
|
1247
1518
|
get each() {
|
|
1248
1519
|
return emojiMatches();
|
|
1249
1520
|
},
|
|
1250
|
-
children: (entry, index) => _$ssr(_tmpl$
|
|
1521
|
+
children: (entry, index) => _$ssr(_tmpl$26, `${_$escape(commandListId, true)}-${_$escape(index(), true)}`, _$ssrAttribute("aria-selected", _$escape(index(), true) === _$escape(selectedCommandIndex(), true), false) + _$ssrAttribute("aria-label", _$escape(emojiName(entry, locale()), true), false) + _$ssrAttribute("data-active", index() === selectedCommandIndex() ? "true" : _$escape(undefined, true), false), _$escape(emojiInTone(entry, props.emoji?.skinTone ?? 0)), _$escape(emojiName(entry, locale())), _$escape(_$createComponent(Show, {
|
|
1251
1522
|
get when() {
|
|
1252
1523
|
return entry.shortcodes[0];
|
|
1253
1524
|
},
|
|
1254
|
-
children: code => _$ssr(_tmpl$
|
|
1525
|
+
children: code => _$ssr(_tmpl$27, _$escape(code()))
|
|
1255
1526
|
})))
|
|
1256
1527
|
})));
|
|
1257
1528
|
}
|
|
@@ -1260,7 +1531,7 @@ export function ChatComposer(props) {
|
|
|
1260
1531
|
return commandsOpen();
|
|
1261
1532
|
},
|
|
1262
1533
|
get children() {
|
|
1263
|
-
return _$ssr(_tmpl$
|
|
1534
|
+
return _$ssr(_tmpl$19, _$ssrAttribute("id", _$escape(commandListId, true), false), _$ssrAttribute("aria-label", _$escape(chatMessages().commands, true), false) + _$ssrAttribute("aria-busy", searching() ? "true" : _$escape(undefined, true), false), _$escape(_$createComponent(For, {
|
|
1264
1535
|
get each() {
|
|
1265
1536
|
return commandModel().groups.map(commandGroupKey);
|
|
1266
1537
|
},
|
|
@@ -1279,12 +1550,12 @@ export function ChatComposer(props) {
|
|
|
1279
1550
|
});
|
|
1280
1551
|
},
|
|
1281
1552
|
get children() {
|
|
1282
|
-
return _$ssr(_tmpl$
|
|
1553
|
+
return _$ssr(_tmpl$30, _$ssrAttribute("aria-labelledby", _$escape(headingId(), true), false), _$ssrAttribute("id", _$escape(headingId(), true), false), _$escape(group()?.scopeTitle ?? group()?.section?.label), _$escape(_$createComponent(Show, {
|
|
1283
1554
|
get when() {
|
|
1284
1555
|
return group()?.loading;
|
|
1285
1556
|
},
|
|
1286
1557
|
get children() {
|
|
1287
|
-
return _$ssr(_tmpl$
|
|
1558
|
+
return _$ssr(_tmpl$28);
|
|
1288
1559
|
}
|
|
1289
1560
|
})), _$escape(_$createComponent(For, {
|
|
1290
1561
|
get each() {
|
|
@@ -1296,7 +1567,7 @@ export function ChatComposer(props) {
|
|
|
1296
1567
|
return group()?.placeholder;
|
|
1297
1568
|
},
|
|
1298
1569
|
get children() {
|
|
1299
|
-
return _$ssr(_tmpl$
|
|
1570
|
+
return _$ssr(_tmpl$29);
|
|
1300
1571
|
}
|
|
1301
1572
|
})));
|
|
1302
1573
|
}
|
|
@@ -1304,27 +1575,33 @@ export function ChatComposer(props) {
|
|
|
1304
1575
|
}
|
|
1305
1576
|
})), _$escape(_$createComponent(Show, {
|
|
1306
1577
|
get when() {
|
|
1307
|
-
return _$memo(() => !!(searching() &&
|
|
1578
|
+
return _$memo(() => !!(searching() && foundCommandCount() === 0))() && !commandModel().groups.some(group => group.section || group.scopeTitle);
|
|
1308
1579
|
},
|
|
1309
1580
|
get children() {
|
|
1310
|
-
return _$ssr(_tmpl$
|
|
1581
|
+
return _$ssr(_tmpl$16, _$escape(messages().loading));
|
|
1311
1582
|
}
|
|
1312
1583
|
})), _$escape(_$createComponent(Show, {
|
|
1313
1584
|
get when() {
|
|
1314
1585
|
return searchError();
|
|
1315
1586
|
},
|
|
1316
1587
|
get children() {
|
|
1317
|
-
return _$ssr(_tmpl$
|
|
1588
|
+
return _$ssr(_tmpl$17, _$escape(messages().error));
|
|
1318
1589
|
}
|
|
1319
1590
|
})), _$escape(_$createComponent(Show, {
|
|
1320
1591
|
get when() {
|
|
1321
|
-
return _$memo(() => !!(!searching() && !searchError()))() &&
|
|
1592
|
+
return _$memo(() => !!(!searching() && !searchError()))() && foundCommandCount() === 0;
|
|
1322
1593
|
},
|
|
1323
1594
|
get children() {
|
|
1324
|
-
return _$ssr(_tmpl$
|
|
1595
|
+
return _$ssr(_tmpl$18, !parsedCommandQuery().query.trim() ? _$escape(messages().noResults) : _$escape(chatMessages().commandsNothingFound({
|
|
1325
1596
|
query: parsedCommandQuery().query.trim()
|
|
1326
1597
|
})));
|
|
1327
1598
|
}
|
|
1599
|
+
})), _$escape(_$createComponent(Show, {
|
|
1600
|
+
get when() {
|
|
1601
|
+
return commandModel().fallback?.command;
|
|
1602
|
+
},
|
|
1603
|
+
keyed: true,
|
|
1604
|
+
children: command => renderCommandRow(command)
|
|
1328
1605
|
})));
|
|
1329
1606
|
}
|
|
1330
1607
|
})));
|
|
@@ -1334,18 +1611,18 @@ export function ChatComposer(props) {
|
|
|
1334
1611
|
return showHint();
|
|
1335
1612
|
},
|
|
1336
1613
|
get children() {
|
|
1337
|
-
return _$ssr(_tmpl$
|
|
1614
|
+
return _$ssr(_tmpl$21, _$escape(_$createComponent(Show, {
|
|
1338
1615
|
get when() {
|
|
1339
1616
|
return dictationStatus();
|
|
1340
1617
|
},
|
|
1341
1618
|
get fallback() {
|
|
1342
|
-
return _$ssr(_tmpl$
|
|
1619
|
+
return _$ssr(_tmpl$31, _$escape(hint()));
|
|
1343
1620
|
},
|
|
1344
|
-
children: status => [_$ssr(_tmpl$
|
|
1621
|
+
children: status => [_$ssr(_tmpl$32, _$ssrAttribute("data-state", _$escape(dictation() ?? undefined, true), false), _$ssrAttribute("class", _$escape(status().icon, true), false), _$escape(status().text)), _$createComponent(Show, {
|
|
1345
1622
|
get when() {
|
|
1346
1623
|
return _$memo(() => dictation() === "refined")() ? props.microphone?.onRestoreOriginal : undefined;
|
|
1347
1624
|
},
|
|
1348
|
-
children: restore => _$ssr(_tmpl$
|
|
1625
|
+
children: restore => _$ssr(_tmpl$33, _$ssrAttribute("disabled", microphoneDisabled(), true), _$escape(chatMessages().restoreOriginal))
|
|
1349
1626
|
})]
|
|
1350
1627
|
})));
|
|
1351
1628
|
}
|
|
@@ -1354,16 +1631,16 @@ export function ChatComposer(props) {
|
|
|
1354
1631
|
return attachments().length > 0;
|
|
1355
1632
|
},
|
|
1356
1633
|
get children() {
|
|
1357
|
-
return _$ssr(_tmpl$
|
|
1634
|
+
return _$ssr(_tmpl$22, _$ssrAttribute("aria-label", _$escape(chatMessages().attachments, true), false), _$escape(_$createComponent(For, {
|
|
1358
1635
|
get each() {
|
|
1359
1636
|
return attachments();
|
|
1360
1637
|
},
|
|
1361
|
-
children: attachment => _$ssr(_tmpl$
|
|
1638
|
+
children: attachment => _$ssr(_tmpl$35, `k2b-chat-composer__attachment-content ${Boolean(attachment.action) ? "k2b-chat-composer__attachment-content--action" : ""}`, _$escape(_$createComponent(Show, {
|
|
1362
1639
|
get when() {
|
|
1363
1640
|
return attachment.href;
|
|
1364
1641
|
},
|
|
1365
1642
|
get fallback() {
|
|
1366
|
-
return _$ssr(_tmpl$
|
|
1643
|
+
return _$ssr(_tmpl$37, _$escape(_$createComponent(Show, {
|
|
1367
1644
|
get when() {
|
|
1368
1645
|
return _$memo(() => attachment.kind === "image")() && attachment.previewUrl;
|
|
1369
1646
|
},
|
|
@@ -1371,11 +1648,11 @@ export function ChatComposer(props) {
|
|
|
1371
1648
|
return _$ssr(_tmpl$3, _$ssrAttribute("class", _$escape(attachmentIcon(attachment), true), false));
|
|
1372
1649
|
},
|
|
1373
1650
|
get children() {
|
|
1374
|
-
return _$ssr(_tmpl$
|
|
1651
|
+
return _$ssr(_tmpl$36, _$ssrAttribute("src", _$escape(attachment.previewUrl, true), false) + _$ssrAttribute("alt", _$escape(attachment.alt ?? "", true), false));
|
|
1375
1652
|
}
|
|
1376
1653
|
})), _$escape(renderAttachmentCopy(attachment)));
|
|
1377
1654
|
},
|
|
1378
|
-
children: href => _$ssr(_tmpl$
|
|
1655
|
+
children: href => _$ssr(_tmpl$38, _$ssrAttribute("href", _$escape(href(), true), false), _$ssrAttribute("aria-label", _$escape(chatMessages().openInNewTab({
|
|
1379
1656
|
name: attachment.name
|
|
1380
1657
|
}), true), false), _$escape(_$createComponent(Show, {
|
|
1381
1658
|
get when() {
|
|
@@ -1385,14 +1662,14 @@ export function ChatComposer(props) {
|
|
|
1385
1662
|
return _$ssr(_tmpl$3, _$ssrAttribute("class", _$escape(attachmentIcon(attachment), true), false));
|
|
1386
1663
|
},
|
|
1387
1664
|
get children() {
|
|
1388
|
-
return _$ssr(_tmpl$
|
|
1665
|
+
return _$ssr(_tmpl$36, _$ssrAttribute("src", _$escape(attachment.previewUrl, true), false) + _$ssrAttribute("alt", _$escape(attachment.alt ?? "", true), false));
|
|
1389
1666
|
}
|
|
1390
1667
|
})), _$escape(renderAttachmentCopy(attachment)))
|
|
1391
1668
|
})), _$escape(_$createComponent(Show, {
|
|
1392
1669
|
get when() {
|
|
1393
1670
|
return attachment.action;
|
|
1394
1671
|
},
|
|
1395
|
-
children: action => _$ssr(_tmpl$
|
|
1672
|
+
children: action => _$ssr(_tmpl$39, _$ssrAttribute("disabled", blocked() || action().disabled, true), _$escape(_$createComponent(Show, {
|
|
1396
1673
|
get when() {
|
|
1397
1674
|
return action().icon;
|
|
1398
1675
|
},
|
|
@@ -1403,7 +1680,7 @@ export function ChatComposer(props) {
|
|
|
1403
1680
|
return props.onAttachmentsChange;
|
|
1404
1681
|
},
|
|
1405
1682
|
get children() {
|
|
1406
|
-
return _$ssr(_tmpl$
|
|
1683
|
+
return _$ssr(_tmpl$34, _$ssrAttribute("aria-label", _$escape(selectMessages().removeNamed({
|
|
1407
1684
|
name: attachment.name
|
|
1408
1685
|
}), true), false), _$ssrAttribute("disabled", blocked(), true));
|
|
1409
1686
|
}
|
|
@@ -1420,14 +1697,14 @@ export function ChatComposer(props) {
|
|
|
1420
1697
|
return props.error;
|
|
1421
1698
|
},
|
|
1422
1699
|
get children() {
|
|
1423
|
-
return _$ssr(_tmpl$
|
|
1700
|
+
return _$ssr(_tmpl$23, _$escape(props.error));
|
|
1424
1701
|
}
|
|
1425
|
-
}), formatRow(), _$ssr(_tmpl$
|
|
1702
|
+
}), formatRow(), _$ssr(_tmpl$40, _$escape(_$createComponent(Show, {
|
|
1426
1703
|
get when() {
|
|
1427
|
-
return
|
|
1704
|
+
return footer();
|
|
1428
1705
|
},
|
|
1429
1706
|
get fallback() {
|
|
1430
|
-
return [_$ssr(_tmpl$
|
|
1707
|
+
return [_$ssr(_tmpl$41, _$escape(props.footerTools), _$escape(_$createComponent(Show, {
|
|
1431
1708
|
get when() {
|
|
1432
1709
|
return hasAddMenu();
|
|
1433
1710
|
},
|
|
@@ -1459,16 +1736,28 @@ export function ChatComposer(props) {
|
|
|
1459
1736
|
image: model.image
|
|
1460
1737
|
}));
|
|
1461
1738
|
},
|
|
1739
|
+
get open() {
|
|
1740
|
+
return modelOpen();
|
|
1741
|
+
},
|
|
1742
|
+
onOpenChange: open => {
|
|
1743
|
+
if (!choosingModel()) return;
|
|
1744
|
+
setModelOpen(open);
|
|
1745
|
+
// Dropdown closes before committing the choice; let onValueChange settle it first.
|
|
1746
|
+
if (!open) queueMicrotask(() => {
|
|
1747
|
+
if (!modelOpen()) finishModelSelection(null);
|
|
1748
|
+
});
|
|
1749
|
+
},
|
|
1462
1750
|
get disabled() {
|
|
1463
|
-
return blocked() || running() || !props.onModelChange;
|
|
1751
|
+
return (choosingModel() ? blockedBesidesCommand() : blocked()) || running() || !props.onModelChange;
|
|
1464
1752
|
},
|
|
1465
1753
|
onValueChange: modelId => {
|
|
1466
1754
|
props.onModelChange?.(modelId);
|
|
1755
|
+
finishModelSelection(modelId);
|
|
1467
1756
|
queueMicrotask(focus);
|
|
1468
1757
|
}
|
|
1469
1758
|
});
|
|
1470
1759
|
}
|
|
1471
|
-
})), _$escape(props.modelDetails)), _$ssr(_tmpl$
|
|
1760
|
+
})), _$escape(props.modelDetails)), _$ssr(_tmpl$42, _$escape(_$createComponent(For, {
|
|
1472
1761
|
get each() {
|
|
1473
1762
|
return props.contextActions;
|
|
1474
1763
|
},
|
|
@@ -1509,7 +1798,9 @@ export function ChatComposer(props) {
|
|
|
1509
1798
|
}))
|
|
1510
1799
|
})), _$escape(props.submitTools), _$escape(microphoneControl()), _$escape(sendControl()))];
|
|
1511
1800
|
},
|
|
1512
|
-
children
|
|
1801
|
+
get children() {
|
|
1802
|
+
return footer();
|
|
1803
|
+
}
|
|
1513
1804
|
})))];
|
|
1514
1805
|
},
|
|
1515
1806
|
get children() {
|
|
@@ -1518,9 +1809,9 @@ export function ChatComposer(props) {
|
|
|
1518
1809
|
return props.error;
|
|
1519
1810
|
},
|
|
1520
1811
|
get children() {
|
|
1521
|
-
return _$ssr(_tmpl$
|
|
1812
|
+
return _$ssr(_tmpl$23, _$escape(props.error));
|
|
1522
1813
|
}
|
|
1523
|
-
}), formatRow(), _$ssr(_tmpl$
|
|
1814
|
+
}), formatRow(), _$ssr(_tmpl$24, _$escape(attachControl()), _$escape(fileInput()), _$escape(field()), _$escape(formatToggle()), _$escape(emojiButton()), _$escape(microphoneControl()), _$escape(sendControl()))];
|
|
1524
1815
|
}
|
|
1525
1816
|
})), _$escape(_$createComponent(Show, {
|
|
1526
1817
|
get when() {
|
|
@@ -1546,18 +1837,18 @@ export function ChatComposer(props) {
|
|
|
1546
1837
|
return suggestionAnnouncement();
|
|
1547
1838
|
},
|
|
1548
1839
|
keyed: true,
|
|
1549
|
-
children: announced => _$ssr(_tmpl$
|
|
1840
|
+
children: announced => _$ssr(_tmpl$43, _$escape(announced.text))
|
|
1550
1841
|
})), _$escape(_$createComponent(Show, {
|
|
1551
1842
|
get when() {
|
|
1552
1843
|
return _$memo(() => !!!suggestionsOpen())() && commandStatus();
|
|
1553
1844
|
},
|
|
1554
|
-
children: status => _$ssr(_tmpl$
|
|
1845
|
+
children: status => _$ssr(_tmpl$44, _$ssrAttribute("data-tone", _$escape(status().tone, true), false), _$ssrAttribute("class", status().tone === "busy" ? "ti ti-loader-2 k2b-spin" : status().tone === "done" ? "ti ti-check" : "ti ti-alert-circle", false), _$escape(status().text))
|
|
1555
1846
|
})), _$escape(_$createComponent(Show, {
|
|
1556
1847
|
get when() {
|
|
1557
1848
|
return _$memo(() => !!suggestionsOpen())() && announcement();
|
|
1558
1849
|
},
|
|
1559
1850
|
keyed: true,
|
|
1560
|
-
children: announced => _$ssr(_tmpl$
|
|
1851
|
+
children: announced => _$ssr(_tmpl$45, _$escape(announced.text))
|
|
1561
1852
|
})));
|
|
1562
1853
|
}
|
|
1563
1854
|
//# sourceMappingURL=ChatComposer.js.map
|