@celljs/ta-web 4.6.1 → 4.8.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.en.md +90 -0
- package/README.md +13 -7
- package/esm/browser/chat/chat-protocol.d.ts +4 -0
- package/esm/browser/chat/chat-view.js +4 -1
- package/esm/browser/chat/chat-view.js.map +1 -1
- package/esm/browser/chat/chat.d.ts +8 -1
- package/esm/browser/chat/chat.js +34 -15
- package/esm/browser/chat/chat.js.map +1 -1
- package/esm/browser/chat/draft-model.d.ts +15 -0
- package/esm/browser/chat/draft-model.js +53 -0
- package/esm/browser/chat/draft-model.js.map +1 -0
- package/esm/browser/components/account-menu.d.ts +3 -2
- package/esm/browser/components/account-menu.js +21 -16
- package/esm/browser/components/account-menu.js.map +1 -1
- package/esm/browser/components/app-view.js +13 -4
- package/esm/browser/components/app-view.js.map +1 -1
- package/esm/browser/components/chat-list.d.ts +3 -1
- package/esm/browser/components/chat-list.js +6 -1
- package/esm/browser/components/chat-list.js.map +1 -1
- package/esm/browser/components/composer-box.d.ts +6 -0
- package/esm/browser/components/composer-box.js +50 -13
- package/esm/browser/components/composer-box.js.map +1 -1
- package/esm/browser/components/composer.js +1 -1
- package/esm/browser/components/composer.js.map +1 -1
- package/esm/browser/components/dialog-view.d.ts +4 -1
- package/esm/browser/components/dialog-view.js +11 -7
- package/esm/browser/components/dialog-view.js.map +1 -1
- package/esm/browser/components/folder-picker.d.ts +37 -6
- package/esm/browser/components/folder-picker.js +155 -33
- package/esm/browser/components/folder-picker.js.map +1 -1
- package/esm/browser/components/notice-center.js +3 -1
- package/esm/browser/components/notice-center.js.map +1 -1
- package/esm/browser/components/remote-hosts.d.ts +7 -0
- package/esm/browser/components/remote-hosts.js +94 -0
- package/esm/browser/components/remote-hosts.js.map +1 -0
- package/esm/browser/components/remote-prompts.d.ts +7 -0
- package/esm/browser/components/remote-prompts.js +72 -0
- package/esm/browser/components/remote-prompts.js.map +1 -0
- package/esm/browser/components/session-view.js +48 -4
- package/esm/browser/components/session-view.js.map +1 -1
- package/esm/browser/components/settings-view.js +8 -1
- package/esm/browser/components/settings-view.js.map +1 -1
- package/esm/browser/components/terminal-art.d.ts +7 -0
- package/esm/browser/components/terminal-art.js +12 -0
- package/esm/browser/components/terminal-art.js.map +1 -0
- package/esm/browser/components/tool-view.js +1 -1
- package/esm/browser/components/tool-view.js.map +1 -1
- package/esm/browser/components/web-composer.d.ts +4 -1
- package/esm/browser/components/web-composer.js +2 -2
- package/esm/browser/components/web-composer.js.map +1 -1
- package/esm/browser/components/working-directory.js +1 -1
- package/esm/browser/components/working-directory.js.map +1 -1
- package/esm/browser/extension/icons.js +6 -1
- package/esm/browser/extension/icons.js.map +1 -1
- package/esm/browser/extension/web-extension-api.d.ts +120 -2
- package/esm/browser/extension/web-extensions.d.ts +3 -0
- package/esm/browser/extension/web-extensions.js +33 -1
- package/esm/browser/extension/web-extensions.js.map +1 -1
- package/esm/browser/i18n/locales.d.ts +44 -1
- package/esm/browser/i18n/messages.d.ts +43 -0
- package/esm/browser/i18n/messages.js +99 -13
- package/esm/browser/i18n/messages.js.map +1 -1
- package/esm/browser/notices/notices-protocol.d.ts +3 -0
- package/esm/browser/notices/notices.d.ts +3 -0
- package/esm/browser/notices/notices.js +15 -0
- package/esm/browser/notices/notices.js.map +1 -1
- package/esm/browser/style/base.d.ts +1 -1
- package/esm/browser/style/base.js +6 -1
- package/esm/browser/style/base.js.map +1 -1
- package/esm/browser/style/conversation.d.ts +1 -1
- package/esm/browser/style/conversation.js +16 -1
- package/esm/browser/style/conversation.js.map +1 -1
- package/esm/browser/style/layout.d.ts +1 -1
- package/esm/browser/style/layout.js +53 -15
- package/esm/browser/style/layout.js.map +1 -1
- package/esm/browser/style/shell.d.ts +1 -1
- package/esm/browser/style/shell.js +1 -0
- package/esm/browser/style/shell.js.map +1 -1
- package/esm/browser/terminal/canvas-font.d.ts +10 -0
- package/esm/browser/terminal/canvas-font.js +34 -0
- package/esm/browser/terminal/canvas-font.js.map +1 -0
- package/esm/browser/terminal/terminal-links.d.ts +18 -0
- package/esm/browser/terminal/terminal-links.js +72 -0
- package/esm/browser/terminal/terminal-links.js.map +1 -0
- package/esm/browser/terminal/terminal-theme.d.ts +8 -0
- package/esm/browser/terminal/terminal-theme.js +65 -0
- package/esm/browser/terminal/terminal-theme.js.map +1 -0
- package/esm/browser/terminal/web-terminal.d.ts +74 -0
- package/esm/browser/terminal/web-terminal.js +300 -0
- package/esm/browser/terminal/web-terminal.js.map +1 -0
- package/esm/browser/terminal/xterm.d.ts +5 -0
- package/esm/browser/terminal/xterm.js +9 -0
- package/esm/browser/terminal/xterm.js.map +1 -0
- package/esm/browser/util/desktop.d.ts +43 -0
- package/esm/browser/util/desktop.js +55 -0
- package/esm/browser/util/desktop.js.map +1 -0
- package/esm/browser/util/file-drag.d.ts +26 -0
- package/esm/browser/util/file-drag.js +73 -0
- package/esm/browser/util/file-drag.js.map +1 -0
- package/esm/browser/util/message.d.ts +1 -0
- package/esm/browser/util/message.js +7 -5
- package/esm/browser/util/message.js.map +1 -1
- package/esm/browser/util/terminal-text.d.ts +33 -0
- package/esm/browser/util/terminal-text.js +209 -0
- package/esm/browser/util/terminal-text.js.map +1 -0
- package/esm/browser/util/tool.js +16 -0
- package/esm/browser/util/tool.js.map +1 -1
- package/esm/browser/workbench-protocol.d.ts +7 -1
- package/esm/browser/workbench-protocol.js.map +1 -1
- package/esm/browser/workbench.d.ts +7 -1
- package/esm/browser/workbench.js +23 -0
- package/esm/browser/workbench.js.map +1 -1
- package/lib/browser/chat/chat-protocol.d.ts +4 -0
- package/lib/browser/chat/chat-protocol.d.ts.map +1 -1
- package/lib/browser/chat/chat-view.d.ts.map +1 -1
- package/lib/browser/chat/chat-view.js +4 -1
- package/lib/browser/chat/chat-view.js.map +1 -1
- package/lib/browser/chat/chat.d.ts +8 -1
- package/lib/browser/chat/chat.d.ts.map +1 -1
- package/lib/browser/chat/chat.js +34 -15
- package/lib/browser/chat/chat.js.map +1 -1
- package/lib/browser/chat/chat.spec.js +30 -0
- package/lib/browser/chat/chat.spec.js.map +1 -1
- package/lib/browser/chat/draft-model.d.ts +16 -0
- package/lib/browser/chat/draft-model.d.ts.map +1 -0
- package/lib/browser/chat/draft-model.js +90 -0
- package/lib/browser/chat/draft-model.js.map +1 -0
- package/lib/browser/chat/draft-model.spec.d.ts +2 -0
- package/lib/browser/chat/draft-model.spec.d.ts.map +1 -0
- package/lib/browser/chat/draft-model.spec.js +31 -0
- package/lib/browser/chat/draft-model.spec.js.map +1 -0
- package/lib/browser/components/account-menu.d.ts +3 -2
- package/lib/browser/components/account-menu.d.ts.map +1 -1
- package/lib/browser/components/account-menu.js +21 -16
- package/lib/browser/components/account-menu.js.map +1 -1
- package/lib/browser/components/app-view.d.ts.map +1 -1
- package/lib/browser/components/app-view.js +13 -4
- package/lib/browser/components/app-view.js.map +1 -1
- package/lib/browser/components/chat-list.d.ts +3 -1
- package/lib/browser/components/chat-list.d.ts.map +1 -1
- package/lib/browser/components/chat-list.js +6 -1
- package/lib/browser/components/chat-list.js.map +1 -1
- package/lib/browser/components/composer-box.d.ts +6 -0
- package/lib/browser/components/composer-box.d.ts.map +1 -1
- package/lib/browser/components/composer-box.js +51 -14
- package/lib/browser/components/composer-box.js.map +1 -1
- package/lib/browser/components/composer.d.ts.map +1 -1
- package/lib/browser/components/composer.js +1 -1
- package/lib/browser/components/composer.js.map +1 -1
- package/lib/browser/components/dialog-view.d.ts +4 -1
- package/lib/browser/components/dialog-view.d.ts.map +1 -1
- package/lib/browser/components/dialog-view.js +11 -7
- package/lib/browser/components/dialog-view.js.map +1 -1
- package/lib/browser/components/folder-picker.d.ts +37 -6
- package/lib/browser/components/folder-picker.d.ts.map +1 -1
- package/lib/browser/components/folder-picker.js +156 -33
- package/lib/browser/components/folder-picker.js.map +1 -1
- package/lib/browser/components/folder-picker.spec.js +15 -0
- package/lib/browser/components/folder-picker.spec.js.map +1 -1
- package/lib/browser/components/notice-center.d.ts.map +1 -1
- package/lib/browser/components/notice-center.js +3 -1
- package/lib/browser/components/notice-center.js.map +1 -1
- package/lib/browser/components/plus-menu.spec.d.ts +2 -0
- package/lib/browser/components/plus-menu.spec.d.ts.map +1 -0
- package/lib/browser/components/plus-menu.spec.js +18 -0
- package/lib/browser/components/plus-menu.spec.js.map +1 -0
- package/lib/browser/components/remote-hosts.d.ts +8 -0
- package/lib/browser/components/remote-hosts.d.ts.map +1 -0
- package/lib/browser/components/remote-hosts.js +130 -0
- package/lib/browser/components/remote-hosts.js.map +1 -0
- package/lib/browser/components/remote-prompts.d.ts +8 -0
- package/lib/browser/components/remote-prompts.d.ts.map +1 -0
- package/lib/browser/components/remote-prompts.js +108 -0
- package/lib/browser/components/remote-prompts.js.map +1 -0
- package/lib/browser/components/session-view.d.ts.map +1 -1
- package/lib/browser/components/session-view.js +48 -4
- package/lib/browser/components/session-view.js.map +1 -1
- package/lib/browser/components/settings-view.d.ts.map +1 -1
- package/lib/browser/components/settings-view.js +7 -0
- package/lib/browser/components/settings-view.js.map +1 -1
- package/lib/browser/components/terminal-art.d.ts +8 -0
- package/lib/browser/components/terminal-art.d.ts.map +1 -0
- package/lib/browser/components/terminal-art.js +48 -0
- package/lib/browser/components/terminal-art.js.map +1 -0
- package/lib/browser/components/tool-view.js +1 -1
- package/lib/browser/components/tool-view.js.map +1 -1
- package/lib/browser/components/web-composer.d.ts +4 -1
- package/lib/browser/components/web-composer.d.ts.map +1 -1
- package/lib/browser/components/web-composer.js +2 -2
- package/lib/browser/components/web-composer.js.map +1 -1
- package/lib/browser/components/working-directory.js +1 -1
- package/lib/browser/components/working-directory.js.map +1 -1
- package/lib/browser/extension/icons.d.ts.map +1 -1
- package/lib/browser/extension/icons.js +5 -0
- package/lib/browser/extension/icons.js.map +1 -1
- package/lib/browser/extension/web-extension-api.d.ts +120 -2
- package/lib/browser/extension/web-extension-api.d.ts.map +1 -1
- package/lib/browser/extension/web-extensions.d.ts +3 -0
- package/lib/browser/extension/web-extensions.d.ts.map +1 -1
- package/lib/browser/extension/web-extensions.js +33 -1
- package/lib/browser/extension/web-extensions.js.map +1 -1
- package/lib/browser/i18n/locales.d.ts +44 -1
- package/lib/browser/i18n/locales.d.ts.map +1 -1
- package/lib/browser/i18n/messages.d.ts +43 -0
- package/lib/browser/i18n/messages.d.ts.map +1 -1
- package/lib/browser/i18n/messages.js +99 -13
- package/lib/browser/i18n/messages.js.map +1 -1
- package/lib/browser/notices/notices-protocol.d.ts +3 -0
- package/lib/browser/notices/notices-protocol.d.ts.map +1 -1
- package/lib/browser/notices/notices.d.ts +3 -0
- package/lib/browser/notices/notices.d.ts.map +1 -1
- package/lib/browser/notices/notices.js +15 -0
- package/lib/browser/notices/notices.js.map +1 -1
- package/lib/browser/notices/notices.spec.js +8 -3
- package/lib/browser/notices/notices.spec.js.map +1 -1
- package/lib/browser/style/base.d.ts +1 -1
- package/lib/browser/style/base.d.ts.map +1 -1
- package/lib/browser/style/base.js +6 -1
- package/lib/browser/style/base.js.map +1 -1
- package/lib/browser/style/conversation.d.ts +1 -1
- package/lib/browser/style/conversation.d.ts.map +1 -1
- package/lib/browser/style/conversation.js +16 -1
- package/lib/browser/style/conversation.js.map +1 -1
- package/lib/browser/style/layout.d.ts +1 -1
- package/lib/browser/style/layout.d.ts.map +1 -1
- package/lib/browser/style/layout.js +53 -15
- package/lib/browser/style/layout.js.map +1 -1
- package/lib/browser/style/shell.d.ts +1 -1
- package/lib/browser/style/shell.d.ts.map +1 -1
- package/lib/browser/style/shell.js +1 -0
- package/lib/browser/style/shell.js.map +1 -1
- package/lib/browser/terminal/canvas-font.d.ts +11 -0
- package/lib/browser/terminal/canvas-font.d.ts.map +1 -0
- package/lib/browser/terminal/canvas-font.js +37 -0
- package/lib/browser/terminal/canvas-font.js.map +1 -0
- package/lib/browser/terminal/canvas-font.spec.d.ts +2 -0
- package/lib/browser/terminal/canvas-font.spec.d.ts.map +1 -0
- package/lib/browser/terminal/canvas-font.spec.js +32 -0
- package/lib/browser/terminal/canvas-font.spec.js.map +1 -0
- package/lib/browser/terminal/terminal-links.d.ts +19 -0
- package/lib/browser/terminal/terminal-links.d.ts.map +1 -0
- package/lib/browser/terminal/terminal-links.js +75 -0
- package/lib/browser/terminal/terminal-links.js.map +1 -0
- package/lib/browser/terminal/terminal-links.spec.d.ts +2 -0
- package/lib/browser/terminal/terminal-links.spec.d.ts.map +1 -0
- package/lib/browser/terminal/terminal-links.spec.js +30 -0
- package/lib/browser/terminal/terminal-links.spec.js.map +1 -0
- package/lib/browser/terminal/terminal-theme.d.ts +9 -0
- package/lib/browser/terminal/terminal-theme.d.ts.map +1 -0
- package/lib/browser/terminal/terminal-theme.js +68 -0
- package/lib/browser/terminal/terminal-theme.js.map +1 -0
- package/lib/browser/terminal/terminal-theme.spec.d.ts +2 -0
- package/lib/browser/terminal/terminal-theme.spec.d.ts.map +1 -0
- package/lib/browser/terminal/terminal-theme.spec.js +24 -0
- package/lib/browser/terminal/terminal-theme.spec.js.map +1 -0
- package/lib/browser/terminal/web-terminal.d.ts +75 -0
- package/lib/browser/terminal/web-terminal.d.ts.map +1 -0
- package/lib/browser/terminal/web-terminal.js +304 -0
- package/lib/browser/terminal/web-terminal.js.map +1 -0
- package/lib/browser/terminal/xterm.d.ts +6 -0
- package/lib/browser/terminal/xterm.d.ts.map +1 -0
- package/lib/browser/terminal/xterm.js +16 -0
- package/lib/browser/terminal/xterm.js.map +1 -0
- package/lib/browser/util/desktop.d.ts +44 -0
- package/lib/browser/util/desktop.d.ts.map +1 -0
- package/lib/browser/util/desktop.js +58 -0
- package/lib/browser/util/desktop.js.map +1 -0
- package/lib/browser/util/desktop.spec.d.ts +2 -0
- package/lib/browser/util/desktop.spec.d.ts.map +1 -0
- package/lib/browser/util/desktop.spec.js +67 -0
- package/lib/browser/util/desktop.spec.js.map +1 -0
- package/lib/browser/util/file-drag.d.ts +27 -0
- package/lib/browser/util/file-drag.d.ts.map +1 -0
- package/lib/browser/util/file-drag.js +76 -0
- package/lib/browser/util/file-drag.js.map +1 -0
- package/lib/browser/util/file-drag.spec.d.ts +2 -0
- package/lib/browser/util/file-drag.spec.d.ts.map +1 -0
- package/lib/browser/util/file-drag.spec.js +46 -0
- package/lib/browser/util/file-drag.spec.js.map +1 -0
- package/lib/browser/util/message.d.ts +1 -0
- package/lib/browser/util/message.d.ts.map +1 -1
- package/lib/browser/util/message.js +7 -5
- package/lib/browser/util/message.js.map +1 -1
- package/lib/browser/util/message.spec.js +2 -0
- package/lib/browser/util/message.spec.js.map +1 -1
- package/lib/browser/util/terminal-text.d.ts +34 -0
- package/lib/browser/util/terminal-text.d.ts.map +1 -0
- package/lib/browser/util/terminal-text.js +212 -0
- package/lib/browser/util/terminal-text.js.map +1 -0
- package/lib/browser/util/terminal-text.spec.d.ts +2 -0
- package/lib/browser/util/terminal-text.spec.d.ts.map +1 -0
- package/lib/browser/util/terminal-text.spec.js +54 -0
- package/lib/browser/util/terminal-text.spec.js.map +1 -0
- package/lib/browser/util/tool.d.ts.map +1 -1
- package/lib/browser/util/tool.js +16 -0
- package/lib/browser/util/tool.js.map +1 -1
- package/lib/browser/util/tool.spec.js +12 -0
- package/lib/browser/util/tool.spec.js.map +1 -1
- package/lib/browser/workbench-protocol.d.ts +7 -1
- package/lib/browser/workbench-protocol.d.ts.map +1 -1
- package/lib/browser/workbench-protocol.js.map +1 -1
- package/lib/browser/workbench.d.ts +7 -1
- package/lib/browser/workbench.d.ts.map +1 -1
- package/lib/browser/workbench.js +23 -0
- package/lib/browser/workbench.js.map +1 -1
- package/package.json +11 -7
- package/src/browser/chat/chat-protocol.ts +4 -0
- package/src/browser/chat/chat-view.tsx +5 -1
- package/src/browser/chat/chat.spec.ts +31 -0
- package/src/browser/chat/chat.ts +36 -14
- package/src/browser/chat/draft-model.spec.tsx +31 -0
- package/src/browser/chat/draft-model.tsx +63 -0
- package/src/browser/components/account-menu.tsx +23 -20
- package/src/browser/components/app-view.tsx +12 -3
- package/src/browser/components/chat-list.tsx +9 -2
- package/src/browser/components/composer-box.tsx +52 -6
- package/src/browser/components/composer.tsx +1 -0
- package/src/browser/components/dialog-view.tsx +16 -7
- package/src/browser/components/folder-picker.spec.ts +17 -0
- package/src/browser/components/folder-picker.tsx +221 -39
- package/src/browser/components/notice-center.tsx +7 -1
- package/src/browser/components/plus-menu.spec.ts +16 -0
- package/src/browser/components/remote-hosts.tsx +149 -0
- package/src/browser/components/remote-prompts.tsx +111 -0
- package/src/browser/components/session-view.tsx +65 -4
- package/src/browser/components/settings-view.tsx +8 -0
- package/src/browser/components/terminal-art.tsx +21 -0
- package/src/browser/components/tool-view.tsx +1 -1
- package/src/browser/components/web-composer.tsx +18 -3
- package/src/browser/components/working-directory.tsx +1 -1
- package/src/browser/extension/icons.ts +10 -0
- package/src/browser/extension/web-extension-api.ts +134 -2
- package/src/browser/extension/web-extensions.ts +47 -2
- package/src/browser/i18n/messages.ts +99 -13
- package/src/browser/notices/notices-protocol.ts +3 -0
- package/src/browser/notices/notices.spec.ts +9 -3
- package/src/browser/notices/notices.ts +17 -1
- package/src/browser/style/base.ts +6 -1
- package/src/browser/style/conversation.ts +16 -1
- package/src/browser/style/layout.ts +53 -15
- package/src/browser/style/shell.ts +1 -0
- package/src/browser/terminal/canvas-font.spec.ts +29 -0
- package/src/browser/terminal/canvas-font.ts +32 -0
- package/src/browser/terminal/terminal-links.spec.ts +32 -0
- package/src/browser/terminal/terminal-links.ts +75 -0
- package/src/browser/terminal/terminal-theme.spec.ts +23 -0
- package/src/browser/terminal/terminal-theme.ts +66 -0
- package/src/browser/terminal/web-terminal.ts +330 -0
- package/src/browser/terminal/xterm.ts +10 -0
- package/src/browser/util/desktop.spec.ts +68 -0
- package/src/browser/util/desktop.ts +96 -0
- package/src/browser/util/file-drag.spec.ts +48 -0
- package/src/browser/util/file-drag.ts +78 -0
- package/src/browser/util/message.spec.ts +2 -0
- package/src/browser/util/message.ts +7 -4
- package/src/browser/util/terminal-text.spec.ts +60 -0
- package/src/browser/util/terminal-text.ts +223 -0
- package/src/browser/util/tool.spec.ts +12 -0
- package/src/browser/util/tool.ts +17 -0
- package/src/browser/workbench-protocol.ts +8 -0
- package/src/browser/workbench.ts +29 -0
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import { Autowired, Component, Optional, PostConstruct } from '@celljs/core';
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
TaEvent,
|
|
4
|
+
TaPackageServer,
|
|
5
|
+
TaRemoteServer,
|
|
6
|
+
TaServer,
|
|
7
|
+
TaSettingsServer,
|
|
8
|
+
TaTerminalServer,
|
|
9
|
+
TaWebExtensionInfo,
|
|
10
|
+
TaWorkspaceServer,
|
|
11
|
+
} from '@celljs/ta-protocol';
|
|
3
12
|
import * as React from 'react';
|
|
4
13
|
import { CodeEditor } from '../components/code-editor';
|
|
5
14
|
import { DiffEditor } from '../components/diff-editor';
|
|
@@ -9,9 +18,13 @@ import { TaAvatar } from '../components/ta-avatar';
|
|
|
9
18
|
import { WebComposer } from '../components/web-composer';
|
|
10
19
|
import { WebDialog } from '../components/web-dialog';
|
|
11
20
|
import { message as messageOf } from '../i18n/messages';
|
|
21
|
+
import { TaLinks } from '../links/links-protocol';
|
|
12
22
|
import { TaNotices } from '../notices/notices-protocol';
|
|
13
23
|
import { TaSettings } from '../settings/settings-protocol';
|
|
14
24
|
import { type StateSpec, StateUtil, TaState } from '../state/state-protocol';
|
|
25
|
+
import { DefaultWebTerminal } from '../terminal/web-terminal';
|
|
26
|
+
import { DesktopUtil } from '../util/desktop';
|
|
27
|
+
import { FileDragUtil } from '../util/file-drag';
|
|
15
28
|
import { TaWorkbench } from '../workbench-protocol';
|
|
16
29
|
import { WEB_ICONS } from './icons';
|
|
17
30
|
import type {
|
|
@@ -21,9 +34,12 @@ import type {
|
|
|
21
34
|
WebEditor,
|
|
22
35
|
WebExtensionAPI,
|
|
23
36
|
WebExtensionFactory,
|
|
37
|
+
WebFileDrag,
|
|
24
38
|
WebFolderPickerProps,
|
|
25
39
|
WebOpener,
|
|
26
40
|
WebStorage,
|
|
41
|
+
WebTerminal,
|
|
42
|
+
WebTerminalOptions,
|
|
27
43
|
WebTool,
|
|
28
44
|
WebView,
|
|
29
45
|
WidgetOptions,
|
|
@@ -41,6 +57,8 @@ import {
|
|
|
41
57
|
|
|
42
58
|
const DEFAULT_ORDER = 100;
|
|
43
59
|
|
|
60
|
+
const FILE_DRAG: WebFileDrag = Object.freeze({ set: FileDragUtil.set, has: FileDragUtil.has, get: FileDragUtil.get, paths: FileDragUtil.paths });
|
|
61
|
+
|
|
44
62
|
/** One web extension that runs, and what it registered. */
|
|
45
63
|
interface Running {
|
|
46
64
|
loaded: LoadedWebExtension;
|
|
@@ -125,6 +143,10 @@ export class TaWebExtensionsImpl implements TaWebExtensions {
|
|
|
125
143
|
@Autowired(TaSettings)
|
|
126
144
|
protected readonly settings: TaSettings;
|
|
127
145
|
|
|
146
|
+
/** Detached: TaLinks asks the openers of the extensions. */
|
|
147
|
+
@Autowired({ id: TaLinks, detached: true })
|
|
148
|
+
protected readonly links: TaLinks;
|
|
149
|
+
|
|
128
150
|
@Autowired(TaNotices)
|
|
129
151
|
protected readonly notices: TaNotices;
|
|
130
152
|
@Autowired(TaState)
|
|
@@ -474,11 +496,18 @@ export class TaWebExtensionsImpl implements TaWebExtensions {
|
|
|
474
496
|
protected readonly listDirectory = (directory: string) => this.workbench.workspace.listDirectory('.', directory);
|
|
475
497
|
/** The message box, whose button of the directory lists those of the server. */
|
|
476
498
|
protected readonly composer = (props: WebComposerProps) =>
|
|
477
|
-
React.createElement(WebComposer, {
|
|
499
|
+
React.createElement(WebComposer, {
|
|
500
|
+
...props,
|
|
501
|
+
notices: this.notices,
|
|
502
|
+
listDirectory: this.listDirectory,
|
|
503
|
+
serverCwd: this.workbench.state.server?.cwd,
|
|
504
|
+
remote: this.workbench,
|
|
505
|
+
});
|
|
478
506
|
protected readonly folderPicker = ({ initial, onPick, onClose }: WebFolderPickerProps) =>
|
|
479
507
|
React.createElement(FolderPicker, {
|
|
480
508
|
list: this.listDirectory,
|
|
481
509
|
initial: initial || this.workbench.state.server?.cwd || '.',
|
|
510
|
+
remote: this.workbench,
|
|
482
511
|
onPick: async (path: string) => onPick(path),
|
|
483
512
|
onClose,
|
|
484
513
|
});
|
|
@@ -508,6 +537,12 @@ export class TaWebExtensionsImpl implements TaWebExtensions {
|
|
|
508
537
|
get packages(): TaPackageServer {
|
|
509
538
|
return workbench.packages;
|
|
510
539
|
},
|
|
540
|
+
get remote(): TaRemoteServer {
|
|
541
|
+
return workbench.remote;
|
|
542
|
+
},
|
|
543
|
+
get settings(): TaSettingsServer {
|
|
544
|
+
return workbench.settings;
|
|
545
|
+
},
|
|
511
546
|
ui: {
|
|
512
547
|
setWidget: (key, component, options = {}) =>
|
|
513
548
|
register(() => (component ? run.widgets.set(key, { component, options }) : run.widgets.delete(key))),
|
|
@@ -526,6 +561,10 @@ export class TaWebExtensionsImpl implements TaWebExtensions {
|
|
|
526
561
|
get language() {
|
|
527
562
|
return settings.state.language;
|
|
528
563
|
},
|
|
564
|
+
supportsWebview: DesktopUtil.has('webview'),
|
|
565
|
+
desktop: DesktopUtil.fileManager(),
|
|
566
|
+
fileDrag: FILE_DRAG,
|
|
567
|
+
debugWebview: DesktopUtil.debugWebview(),
|
|
529
568
|
openEditor: (editor, options) => this.openEditor(run, editor, options?.preserveFocus === true, options?.preview === true),
|
|
530
569
|
closeEditor: id => this.removeEditors(editor => editor.id === id && editor.extension === run.loaded.id),
|
|
531
570
|
pinEditor: id => {
|
|
@@ -564,6 +603,12 @@ export class TaWebExtensionsImpl implements TaWebExtensions {
|
|
|
564
603
|
icons: WEB_ICONS,
|
|
565
604
|
CodeEditor: this.codeEditor,
|
|
566
605
|
DiffEditor: this.diffEditor,
|
|
606
|
+
// Ends with the extension.
|
|
607
|
+
createTerminal: (options?: WebTerminalOptions): WebTerminal => {
|
|
608
|
+
const terminal = new DefaultWebTerminal(settings, (target, open) => void this.links.open(target, open), options);
|
|
609
|
+
run.unsubscribes.push(() => terminal.dispose());
|
|
610
|
+
return terminal;
|
|
611
|
+
},
|
|
567
612
|
Composer: this.composer,
|
|
568
613
|
Markdown,
|
|
569
614
|
Dialog: WebDialog,
|
|
@@ -28,6 +28,10 @@ export const EN_MESSAGES = {
|
|
|
28
28
|
'ta.link.trustHint': 'Pages of this host open without asking from now on; the list is in Settings.',
|
|
29
29
|
'ta.link.copied': 'Link copied',
|
|
30
30
|
'ta.link.notFound': '{path} is not there.',
|
|
31
|
+
'ta.terminal.openLink': 'Ctrl + click to open',
|
|
32
|
+
'ta.terminal.openLinkMac': 'Cmd + click to open',
|
|
33
|
+
'ta.terminal.openUrl': 'Ctrl + click to open, with Shift in your browser',
|
|
34
|
+
'ta.terminal.openUrlMac': 'Cmd + click to open, with Shift in your browser',
|
|
31
35
|
'ta.link.noOpener': 'Nothing opens files: turn on the package @celljs/ta-workspace in Settings.',
|
|
32
36
|
'ta.settings.links': 'Links',
|
|
33
37
|
'ta.settings.trustedDomains': 'Trusted domains',
|
|
@@ -44,17 +48,23 @@ export const EN_MESSAGES = {
|
|
|
44
48
|
'ta.editor.discardClose': 'Close without saving',
|
|
45
49
|
'ta.online': 'Online',
|
|
46
50
|
'ta.reconnecting': 'Reconnecting',
|
|
47
|
-
'ta.unreachable': '
|
|
51
|
+
'ta.unreachable': 'The Ta service is not running. Start it with ta serve in a terminal; this page connects by itself.',
|
|
48
52
|
'ta.pwa.install': 'Install as an app',
|
|
49
|
-
// The connection to ta serve, and the notices of the page
|
|
50
|
-
'ta.connection.lost': 'The connection to
|
|
53
|
+
// The connection to the Ta service (ta serve), and the notices of the page
|
|
54
|
+
'ta.connection.lost': 'The connection to the Ta service dropped.',
|
|
51
55
|
'ta.connection.retryIn': 'Trying again in {seconds}s',
|
|
52
56
|
'ta.connection.retrying': 'Connecting…',
|
|
53
57
|
'ta.connection.retryNow': 'Retry now',
|
|
54
58
|
'ta.connection.back': 'Connected again',
|
|
55
|
-
'ta.connection.notDone': 'Not done:
|
|
59
|
+
'ta.connection.notDone': 'Not done: the Ta service is not connected',
|
|
60
|
+
'ta.error.sessionNotFound': 'This conversation is no longer open; open it again from the list',
|
|
61
|
+
'ta.error.sessionLocked': 'This conversation is open in another Ta; close it there first',
|
|
62
|
+
'ta.error.tooManySessions': 'Too many conversations are open; close one and try again',
|
|
63
|
+
'ta.error.messageConflict': 'The message was not sent: it clashed with another; send it again',
|
|
64
|
+
'ta.error.modelNotFound': 'The model is not available; pick another or sign in to its service',
|
|
56
65
|
'ta.connection.notDoneHint': 'Try again once the connection is back.',
|
|
57
66
|
'ta.notices': 'Notifications',
|
|
67
|
+
'ta.notice.picture': 'Picture of the extension, such as a QR code to scan',
|
|
58
68
|
'ta.packages.removeDetail': 'Its pages, cards and commands go with it.',
|
|
59
69
|
'ta.packages.removed': 'Removed {name}',
|
|
60
70
|
'ta.packages.reloaded': 'Extensions loaded again',
|
|
@@ -62,10 +72,10 @@ export const EN_MESSAGES = {
|
|
|
62
72
|
'ta.home': 'Home',
|
|
63
73
|
'ta.menu': 'Menu',
|
|
64
74
|
'ta.signin.title': 'Connect to Ta',
|
|
65
|
-
'ta.signin.hint': 'Run ta serve --web, which opens this page signed in, or paste the token from ~/.ta/agent/serve.json.',
|
|
75
|
+
'ta.signin.hint': 'Run ta serve --web in a terminal, which opens this page signed in, or paste the token from ~/.ta/agent/serve.json.',
|
|
66
76
|
'ta.signin.token': 'Access token',
|
|
67
77
|
'ta.signin.connect': 'Connect',
|
|
68
|
-
'ta.signin.refused': '
|
|
78
|
+
'ta.signin.refused': 'The Ta service did not accept the token, or it is not running.',
|
|
69
79
|
'ta.signin.pairHint': 'On your computer, run ta pair <relay> and paste the link it prints here. What goes through the relay is encrypted end to end.',
|
|
70
80
|
'ta.signin.pairing': 'Pairing link',
|
|
71
81
|
'ta.signin.pairRefused': 'Your Ta does not know this device: it may have been unpaired. Run ta pair again.',
|
|
@@ -197,6 +207,36 @@ export const EN_MESSAGES = {
|
|
|
197
207
|
'ta.folder.empty': 'No folders here.',
|
|
198
208
|
'ta.folder.failed': 'Cannot open {path}.',
|
|
199
209
|
'ta.folder.open': 'Use this directory',
|
|
210
|
+
'ta.remote.local': 'This computer',
|
|
211
|
+
'ta.remote.add': 'Add a host',
|
|
212
|
+
'ta.remote.addHint': 'A Host of ~/.ssh/config, user@host:port, or an ssh command',
|
|
213
|
+
'ta.remote.connected': 'Connected',
|
|
214
|
+
'ta.remote.failed': 'Cannot connect to {host}',
|
|
215
|
+
'ta.remote.title': 'Remote hosts',
|
|
216
|
+
'ta.remote.description': 'Conversations can work in directories of these machines. Ta connects with the ssh of this computer and its ~/.ssh/config.',
|
|
217
|
+
'ta.remote.none': 'No hosts yet.',
|
|
218
|
+
'ta.remote.invalid': '{host} names no host: write a Host of ~/.ssh/config, user@host:port, or ssh user@host -p port.',
|
|
219
|
+
'ta.remote.options': 'Ta takes no {options} here: put it in a Host of ~/.ssh/config, and add that Host.',
|
|
220
|
+
'ta.remote.disconnected': 'Not connected',
|
|
221
|
+
'ta.remote.fromConfig': 'From ~/.ssh/config',
|
|
222
|
+
'ta.remote.added': 'Added',
|
|
223
|
+
'ta.remote.connect': 'Connect',
|
|
224
|
+
'ta.remote.disconnect': 'Disconnect',
|
|
225
|
+
'ta.remote.connectedTo': 'Connected to {host}',
|
|
226
|
+
'ta.remote.remove': 'Remove {host}',
|
|
227
|
+
'ta.remote.port': 'Port {port} of {host}',
|
|
228
|
+
'ta.remote.closePort': 'Stop forwarding',
|
|
229
|
+
'ta.remote.connecting': 'Connecting to {host}…',
|
|
230
|
+
'ta.remote.step.connecting': 'Connecting to {host}…',
|
|
231
|
+
'ta.remote.step.checking': 'Looking at {host}…',
|
|
232
|
+
'ta.remote.step.installing-node': 'Installing Node.js {detail} on {host}…',
|
|
233
|
+
'ta.remote.step.copying-server': 'Copying Ta to {host}…',
|
|
234
|
+
'ta.remote.step.starting': 'Starting on {host}…',
|
|
235
|
+
'ta.remote.lost': 'Lost the connection to {host}; it comes back with the next step.',
|
|
236
|
+
'ta.remote.prompt.title': 'Connect to {host}',
|
|
237
|
+
'ta.remote.prompt.trust': 'Trust and connect',
|
|
238
|
+
'ta.remote.prompt.continue': 'Continue',
|
|
239
|
+
'ta.remote.forwarded': 'Port {port} of {host} is at {local} here',
|
|
200
240
|
'ta.chat.search': 'Search chats',
|
|
201
241
|
'ta.chat.all': 'All',
|
|
202
242
|
'ta.chat.noMatch': 'No chat matches.',
|
|
@@ -280,12 +320,15 @@ export const EN_MESSAGES = {
|
|
|
280
320
|
'ta.composer.image.size': '{name} is larger than 5 MB.',
|
|
281
321
|
'ta.composer.image.count': 'At most 8 images per message.',
|
|
282
322
|
'ta.composer.filesUnavailable': 'File search is not available on this server yet',
|
|
323
|
+
'ta.composer.filter': 'Search',
|
|
324
|
+
'ta.composer.noMatch': 'Nothing matches',
|
|
283
325
|
'ta.composer.noFiles': 'No matching file',
|
|
284
326
|
'ta.composer.queue.steering': 'Steer',
|
|
285
327
|
'ta.composer.queue.followUp': 'Queued',
|
|
286
328
|
'ta.composer.queue.takeBack': 'Take back',
|
|
287
329
|
'ta.composer.queue.takeBackTitle': 'Take the waiting messages back into the box',
|
|
288
330
|
'ta.account': 'Account',
|
|
331
|
+
'ta.account.service': 'Ta service',
|
|
289
332
|
// The settings view and the menu of the gear
|
|
290
333
|
'ta.manage': 'Manage',
|
|
291
334
|
'ta.manage.packages': 'Extensions',
|
|
@@ -303,7 +346,7 @@ export const EN_MESSAGES = {
|
|
|
303
346
|
'ta.settings.scopeHint.user': 'In {file}, for every project.',
|
|
304
347
|
'ta.settings.scopeHint.project': 'In {file}; overrides the user settings in this project.',
|
|
305
348
|
'ta.settings.untrusted': 'Ta does not trust this project yet, so it ignores its settings. Run ta in it once and trust it to change them here.',
|
|
306
|
-
'ta.settings.offline': 'Connect to
|
|
349
|
+
'ta.settings.offline': 'Connect to the Ta service to see these settings.',
|
|
307
350
|
'ta.settings.loading': 'Reading the settings…',
|
|
308
351
|
'ta.settings.failed': 'Not saved: {error}',
|
|
309
352
|
'ta.settings.default': 'Default ({value})',
|
|
@@ -459,6 +502,10 @@ export const ZH_MESSAGES: Record<MessageId, string> = {
|
|
|
459
502
|
'ta.link.trustHint': '以后这个域名的网页不再询问,直接打开;可在设置中管理。',
|
|
460
503
|
'ta.link.copied': '链接已复制',
|
|
461
504
|
'ta.link.notFound': '{path} 不存在。',
|
|
505
|
+
'ta.terminal.openLink': 'Ctrl + 点击打开',
|
|
506
|
+
'ta.terminal.openLinkMac': 'Cmd + 点击打开',
|
|
507
|
+
'ta.terminal.openUrl': 'Ctrl + 点击打开,加按 Shift 在系统浏览器中打开',
|
|
508
|
+
'ta.terminal.openUrlMac': 'Cmd + 点击打开,加按 Shift 在系统浏览器中打开',
|
|
462
509
|
'ta.link.noOpener': '没有能打开文件的包:请在设置中开启 @celljs/ta-workspace。',
|
|
463
510
|
'ta.settings.links': '链接',
|
|
464
511
|
'ta.settings.trustedDomains': '受信任的域名',
|
|
@@ -475,16 +522,22 @@ export const ZH_MESSAGES: Record<MessageId, string> = {
|
|
|
475
522
|
'ta.editor.discardClose': '不保存并关闭',
|
|
476
523
|
'ta.online': '在线',
|
|
477
524
|
'ta.reconnecting': '重连中',
|
|
478
|
-
'ta.unreachable': '
|
|
525
|
+
'ta.unreachable': 'Ta 服务没有在运行。在终端运行 ta serve 启动它,本页会自动连上。',
|
|
479
526
|
'ta.pwa.install': '安装为应用',
|
|
480
|
-
'ta.connection.lost': '与
|
|
527
|
+
'ta.connection.lost': '与 Ta 服务的连接断开了',
|
|
481
528
|
'ta.connection.retryIn': '{seconds} 秒后重试',
|
|
482
529
|
'ta.connection.retrying': '正在连接…',
|
|
483
530
|
'ta.connection.retryNow': '立即重试',
|
|
484
531
|
'ta.connection.back': '已重新连接',
|
|
485
|
-
'ta.connection.notDone': '
|
|
532
|
+
'ta.connection.notDone': '没有完成:未连接到 Ta 服务',
|
|
533
|
+
'ta.error.sessionNotFound': '这个对话已关闭,请从列表里重新打开',
|
|
534
|
+
'ta.error.sessionLocked': '这个对话在另一个 Ta 里打开着,请先在那里关闭',
|
|
535
|
+
'ta.error.tooManySessions': '打开的对话太多了,请关掉一个再试',
|
|
536
|
+
'ta.error.messageConflict': '消息没有发出:与另一条消息冲突,请重新发送',
|
|
537
|
+
'ta.error.modelNotFound': '这个模型不可用,请换一个模型,或先登录它的服务',
|
|
486
538
|
'ta.connection.notDoneHint': '连接恢复后再试一次。',
|
|
487
539
|
'ta.notices': '通知',
|
|
540
|
+
'ta.notice.picture': '扩展给出的图像,如要扫描的二维码',
|
|
488
541
|
'ta.packages.removeDetail': '它的页面、卡片和命令也会一起移除。',
|
|
489
542
|
'ta.packages.removed': '已移除 {name}',
|
|
490
543
|
'ta.packages.reloaded': '已重新加载扩展',
|
|
@@ -492,10 +545,10 @@ export const ZH_MESSAGES: Record<MessageId, string> = {
|
|
|
492
545
|
'ta.home': '首页',
|
|
493
546
|
'ta.menu': '菜单',
|
|
494
547
|
'ta.signin.title': '连接 Ta',
|
|
495
|
-
'ta.signin.hint': '
|
|
548
|
+
'ta.signin.hint': '在终端运行 ta serve --web,会自动打开本页并登录;也可以粘贴 ~/.ta/agent/serve.json 里的 token。',
|
|
496
549
|
'ta.signin.token': '访问 token',
|
|
497
550
|
'ta.signin.connect': '连接',
|
|
498
|
-
'ta.signin.refused': '
|
|
551
|
+
'ta.signin.refused': 'Ta 服务没有接受这个 token,或者它没有在运行。',
|
|
499
552
|
'ta.signin.pairHint': '在电脑上运行 ta pair <Relay 地址>,把它打印的链接粘贴到这里。经 Relay 的内容端到端加密。',
|
|
500
553
|
'ta.signin.pairing': '配对链接',
|
|
501
554
|
'ta.signin.pairRefused': '你的 Ta 不认识这台设备,可能已取消配对。请重新运行 ta pair。',
|
|
@@ -626,6 +679,36 @@ export const ZH_MESSAGES: Record<MessageId, string> = {
|
|
|
626
679
|
'ta.folder.empty': '这里没有子目录。',
|
|
627
680
|
'ta.folder.failed': '打不开 {path}。',
|
|
628
681
|
'ta.folder.open': '使用此目录',
|
|
682
|
+
'ta.remote.local': '本机',
|
|
683
|
+
'ta.remote.add': '添加主机',
|
|
684
|
+
'ta.remote.addHint': '~/.ssh/config 里的主机、user@host:port,或 ssh 命令',
|
|
685
|
+
'ta.remote.connected': '已连接',
|
|
686
|
+
'ta.remote.failed': '连不上 {host}',
|
|
687
|
+
'ta.remote.title': '远程主机',
|
|
688
|
+
'ta.remote.description': '对话可以在这些机器的目录里工作。Ta 用本机的 ssh 和 ~/.ssh/config 连接。',
|
|
689
|
+
'ta.remote.none': '还没有主机。',
|
|
690
|
+
'ta.remote.invalid': '{host} 不是主机:写 ~/.ssh/config 里的 Host、user@host:port,或 ssh user@host -p 端口。',
|
|
691
|
+
'ta.remote.options': '这里不支持 {options}:把它写进 ~/.ssh/config 的一个 Host 里,再添加那个 Host。',
|
|
692
|
+
'ta.remote.disconnected': '未连接',
|
|
693
|
+
'ta.remote.fromConfig': '来自 ~/.ssh/config',
|
|
694
|
+
'ta.remote.added': '手动添加',
|
|
695
|
+
'ta.remote.connect': '连接',
|
|
696
|
+
'ta.remote.disconnect': '断开',
|
|
697
|
+
'ta.remote.connectedTo': '已连接 {host}',
|
|
698
|
+
'ta.remote.remove': '移除 {host}',
|
|
699
|
+
'ta.remote.port': '{host} 的 {port} 端口',
|
|
700
|
+
'ta.remote.closePort': '停止转发',
|
|
701
|
+
'ta.remote.connecting': '正在连接 {host}…',
|
|
702
|
+
'ta.remote.step.connecting': '正在连接 {host}…',
|
|
703
|
+
'ta.remote.step.checking': '正在检查 {host}…',
|
|
704
|
+
'ta.remote.step.installing-node': '正在为 {host} 安装 Node.js {detail}…',
|
|
705
|
+
'ta.remote.step.copying-server': '正在把 Ta 复制到 {host}…',
|
|
706
|
+
'ta.remote.step.starting': '正在 {host} 上启动…',
|
|
707
|
+
'ta.remote.lost': '与 {host} 的连接断开了,下次操作时会自动重连。',
|
|
708
|
+
'ta.remote.prompt.title': '连接 {host}',
|
|
709
|
+
'ta.remote.prompt.trust': '信任并连接',
|
|
710
|
+
'ta.remote.prompt.continue': '继续',
|
|
711
|
+
'ta.remote.forwarded': '{host} 的 {port} 端口已转发到本机 {local}',
|
|
629
712
|
'ta.chat.search': '搜索对话',
|
|
630
713
|
'ta.chat.all': '全部',
|
|
631
714
|
'ta.chat.noMatch': '没有匹配的对话。',
|
|
@@ -709,12 +792,15 @@ export const ZH_MESSAGES: Record<MessageId, string> = {
|
|
|
709
792
|
'ta.composer.image.size': '{name} 超过 5 MB。',
|
|
710
793
|
'ta.composer.image.count': '每条消息最多 8 张图片。',
|
|
711
794
|
'ta.composer.filesUnavailable': '此服务暂不支持搜索文件',
|
|
795
|
+
'ta.composer.filter': '搜索',
|
|
796
|
+
'ta.composer.noMatch': '没有匹配的项',
|
|
712
797
|
'ta.composer.noFiles': '没有匹配的文件',
|
|
713
798
|
'ta.composer.queue.steering': '引导',
|
|
714
799
|
'ta.composer.queue.followUp': '排队',
|
|
715
800
|
'ta.composer.queue.takeBack': '撤回',
|
|
716
801
|
'ta.composer.queue.takeBackTitle': '把排队的消息取回输入框',
|
|
717
802
|
'ta.account': '账号',
|
|
803
|
+
'ta.account.service': 'Ta 服务',
|
|
718
804
|
// The settings view and the menu of the gear
|
|
719
805
|
'ta.manage': '管理',
|
|
720
806
|
'ta.manage.packages': '扩展',
|
|
@@ -732,7 +818,7 @@ export const ZH_MESSAGES: Record<MessageId, string> = {
|
|
|
732
818
|
'ta.settings.scopeHint.user': '保存在 {file},对所有项目生效。',
|
|
733
819
|
'ta.settings.scopeHint.project': '保存在 {file},在此项目中覆盖用户设置。',
|
|
734
820
|
'ta.settings.untrusted': 'Ta 还没有信任这个项目,因此不会读取它的设置。先在该目录运行一次 ta 并信任它,再回来修改。',
|
|
735
|
-
'ta.settings.offline': '
|
|
821
|
+
'ta.settings.offline': '连接到 Ta 服务后才能查看这些设置。',
|
|
736
822
|
'ta.settings.loading': '正在读取设置…',
|
|
737
823
|
'ta.settings.failed': '未保存:{error}',
|
|
738
824
|
'ta.settings.default': '默认({value})',
|
|
@@ -20,6 +20,8 @@ export interface NoticeOptions {
|
|
|
20
20
|
key?: string;
|
|
21
21
|
/** Stays until the user closes it. */
|
|
22
22
|
sticky?: boolean;
|
|
23
|
+
/** A picture of cells under the message, dark ones true: a QR code an extension drew with characters. */
|
|
24
|
+
art?: boolean[][];
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
export interface Notice {
|
|
@@ -30,6 +32,7 @@ export interface Notice {
|
|
|
30
32
|
action?: NoticeAction;
|
|
31
33
|
key?: string;
|
|
32
34
|
sticky?: boolean;
|
|
35
|
+
art?: boolean[][];
|
|
33
36
|
/** How many times it came. */
|
|
34
37
|
count: number;
|
|
35
38
|
}
|
|
@@ -48,14 +48,20 @@ describe('TaNoticesImpl', () => {
|
|
|
48
48
|
expect(notices.state.notices).toHaveLength(1);
|
|
49
49
|
});
|
|
50
50
|
|
|
51
|
-
it('says an error
|
|
51
|
+
it('says an error ta serve does not name with its message and hint', () => {
|
|
52
|
+
const notices = setup('zh-CN');
|
|
53
|
+
notices.error(new TaRemoteError('No such file.', TaErrorCode.COMMAND_FAILED, 'Fix it.'));
|
|
54
|
+
expect(notices.state.notices.map(({ message, detail }) => ({ message, detail }))).toEqual([{ message: 'No such file.', detail: 'Fix it.' }]);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('says a failure of ta serve in the language of the page, and a lost connection once, whatever failed', () => {
|
|
52
58
|
const notices = setup('zh-CN');
|
|
53
59
|
notices.error(new TaRemoteError('Locked.', TaErrorCode.SESSION_LOCKED, 'Close it there first.'));
|
|
54
60
|
notices.error(new TaRemoteError('Not connected to ta serve.', TaErrorCode.CONNECTION_LOST));
|
|
55
61
|
notices.error(new TaRemoteError('The connection to ta serve was lost.', TaErrorCode.CONNECTION_LOST));
|
|
56
62
|
expect(notices.state.notices.map(({ message, detail, level, count }) => ({ message, detail, level, count }))).toEqual([
|
|
57
|
-
{ message: '
|
|
58
|
-
{ message: '
|
|
63
|
+
{ message: '这个对话在另一个 Ta 里打开着,请先在那里关闭', detail: 'Locked.', level: 'error', count: 1 },
|
|
64
|
+
{ message: '没有完成:未连接到 Ta 服务', detail: '连接恢复后再试一次。', level: 'error', count: 2 },
|
|
59
65
|
]);
|
|
60
66
|
});
|
|
61
67
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Autowired, Component } from '@celljs/core';
|
|
2
2
|
import { TaErrorCode } from '@celljs/ta-protocol';
|
|
3
|
-
import { message } from '../i18n/messages';
|
|
3
|
+
import { type MessageId, message } from '../i18n/messages';
|
|
4
4
|
import { TaSettings } from '../settings/settings-protocol';
|
|
5
5
|
import {
|
|
6
6
|
type ConfirmOptions,
|
|
@@ -50,6 +50,15 @@ export namespace NoticesUtil {
|
|
|
50
50
|
return kept;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
/** The failures of ta serve the user can read about in the language of the page: what they mean. */
|
|
54
|
+
export const LOCALIZED: Partial<Record<string, MessageId>> = {
|
|
55
|
+
[TaErrorCode.SESSION_NOT_FOUND]: 'ta.error.sessionNotFound',
|
|
56
|
+
[TaErrorCode.SESSION_LOCKED]: 'ta.error.sessionLocked',
|
|
57
|
+
[TaErrorCode.TOO_MANY_SESSIONS]: 'ta.error.tooManySessions',
|
|
58
|
+
[TaErrorCode.MESSAGE_CONFLICT]: 'ta.error.messageConflict',
|
|
59
|
+
[TaErrorCode.MODEL_NOT_FOUND]: 'ta.error.modelNotFound',
|
|
60
|
+
};
|
|
61
|
+
|
|
53
62
|
/** What an error says: its message, and for a failure ta serve names (TaRemoteError) its hint. */
|
|
54
63
|
export function describe(cause: unknown): { message: string; detail?: string; code?: string } {
|
|
55
64
|
if (cause instanceof Error) {
|
|
@@ -91,6 +100,7 @@ export class TaNoticesImpl implements TaNotices {
|
|
|
91
100
|
action: options.action,
|
|
92
101
|
key,
|
|
93
102
|
sticky: options.sticky,
|
|
103
|
+
art: options.art,
|
|
94
104
|
count: same && same.message === text ? same.count + 1 : 1,
|
|
95
105
|
};
|
|
96
106
|
this.update({ notices: NoticesUtil.keep([...this.current.notices.filter(other => other !== same), notice]) });
|
|
@@ -114,6 +124,12 @@ export class TaNoticesImpl implements TaNotices {
|
|
|
114
124
|
detail: message(language, 'ta.connection.notDoneHint'),
|
|
115
125
|
});
|
|
116
126
|
}
|
|
127
|
+
const known = code ? NoticesUtil.LOCALIZED[code] : undefined;
|
|
128
|
+
if (known) {
|
|
129
|
+
// ta serve speaks English to its clients; the user reads what the error means, its words beneath.
|
|
130
|
+
const language = this.settings.state.language;
|
|
131
|
+
return this.notify(message(language, known), { ...options, level: 'error', detail: text });
|
|
132
|
+
}
|
|
117
133
|
return this.notify(text, { detail, ...options, level: 'error' });
|
|
118
134
|
}
|
|
119
135
|
|
|
@@ -80,7 +80,12 @@ export const BASE_STYLE = `
|
|
|
80
80
|
}
|
|
81
81
|
* { box-sizing: border-box; }
|
|
82
82
|
html, body, #cell-root, #root { height: 100%; margin: 0; }
|
|
83
|
-
|
|
83
|
+
/* The page and its scrolling areas do not bounce at the ends. Only scrolling areas of their own: on any
|
|
84
|
+
other element (one with overflow: hidden is a scroll container too) it stops the wheel from reaching
|
|
85
|
+
the area under it, and nothing scrolls while the pointer is over a card or a code block. */
|
|
86
|
+
html, body, .ta-scroll, .ta-chat-scroll, .ta-side-scroll, .ta-rail-items, .ta-side-view-body, .ta-editor-body,
|
|
87
|
+
.ta-workbench-launcher, .ta-workbench-menu, .ta-settings-scroll, .ta-settings-toc, .ta-plus-items, .ta-commands,
|
|
88
|
+
.ta-folder-list, .ta-auth-list { overscroll-behavior: none; }
|
|
84
89
|
body { background: var(--ta-main); color: var(--ta-text); font: 14px/1.6 var(--ta-sans); -webkit-font-smoothing: antialiased; -webkit-tap-highlight-color: transparent; }
|
|
85
90
|
button, input, select, textarea { font: inherit; color: inherit; }
|
|
86
91
|
button { cursor: pointer; }
|
|
@@ -23,7 +23,16 @@ export const CONVERSATION_STYLE = `
|
|
|
23
23
|
.ta-footer-usage { display: inline-flex; align-items: center; gap: 6px; min-height: 26px; padding: 0 6px; white-space: nowrap; }
|
|
24
24
|
.ta-footer-usage > span { display: inline-flex; align-items: center; gap: 1px; }
|
|
25
25
|
.ta-working { display: flex; align-items: center; gap: 8px; color: var(--ta-text); font-size: 13px; font-weight: 500; }
|
|
26
|
-
.ta-statusline { font-size: 11.5px; color: var(--ta-
|
|
26
|
+
.ta-statusline { display: flex; flex-wrap: wrap; gap: 6px; padding: 0 4px; font-size: 11.5px; color: var(--ta-secondary); }
|
|
27
|
+
.ta-statusline-item { display: inline-flex; align-items: center; gap: 6px; min-width: 0; max-width: 100%; height: 22px; padding: 0 9px; border-radius: 999px; background: var(--ta-chip); white-space: nowrap; }
|
|
28
|
+
.ta-statusline-label { color: var(--ta-text); font-weight: 500; }
|
|
29
|
+
.ta-statusline-part { display: inline-flex; align-items: center; gap: 4px; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
|
|
30
|
+
.ta-statusline-part + .ta-statusline-part::before { content: ''; width: 1px; height: 10px; margin-right: 2px; background: var(--ta-border-field); }
|
|
31
|
+
.ta-statusline-part.ta-tone-error { color: var(--ta-red); }
|
|
32
|
+
.ta-statusline-part > .ta-status { width: 8px; }
|
|
33
|
+
.ta-widget { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; padding: 8px 12px; border-radius: 12px; border: 1px solid var(--ta-border); background: var(--ta-side); }
|
|
34
|
+
.ta-widget-text { margin: 0; max-width: 100%; overflow-x: auto; font-family: var(--ta-mono); font-size: 12px; line-height: 1.5; color: var(--ta-secondary); white-space: pre; }
|
|
35
|
+
.ta-widget-art { width: 180px; height: auto; border-radius: 8px; }
|
|
27
36
|
.ta-console-composer { position: relative; }
|
|
28
37
|
.ta-console-box { display: flex; align-items: flex-end; gap: 8px; padding: 8px 8px 8px 14px; border-radius: 16px; border: 1px solid var(--ta-border-field); background: var(--ta-input); box-shadow: var(--ta-shadow-composer); transition: border-color 150ms; }
|
|
29
38
|
.ta-console-box:focus-within { border-color: var(--ta-border-focus); }
|
|
@@ -68,6 +77,12 @@ export const CONVERSATION_STYLE = `
|
|
|
68
77
|
.ta-code-editor { position: relative; flex: 1; width: 100%; height: 100%; min-height: 0; background: var(--ta-code); }
|
|
69
78
|
.ta-code-editor-host { position: absolute; inset: 0; }
|
|
70
79
|
.ta-code-editor-state { position: absolute; inset: 0; padding: 16px; color: var(--ta-muted); font-size: 13px; }
|
|
80
|
+
/* A terminal (WebTerminal) fills the element it is attached to, which must have a size and position: relative. */
|
|
81
|
+
.ta-terminal { position: absolute; inset: 0; background: var(--ta-code); }
|
|
82
|
+
/* The padding is the terminal's own: xterm.js fits its rows and columns inside it. */
|
|
83
|
+
.ta-terminal .xterm { height: 100%; padding: 6px 0 4px 12px; }
|
|
84
|
+
.ta-terminal .xterm-viewport { background: transparent !important; }
|
|
85
|
+
.ta-terminal .xterm-helper-textarea { caret-color: transparent; }
|
|
71
86
|
.ta-code pre { margin: 0; padding: 10px 12px; overflow-x: auto; color: var(--ta-body); }
|
|
72
87
|
.ta-code-actions { display: flex; align-items: center; gap: 2px; }
|
|
73
88
|
.ta-code-actions .ta-icon-button { width: 24px; height: 24px; border-radius: 6px; color: var(--ta-muted); }
|
|
@@ -93,6 +93,8 @@ export const LAYOUT_STYLE = `
|
|
|
93
93
|
.ta-run-tokens { display: inline-flex; align-items: center; gap: 8px; flex: none; color: var(--ta-muted); font-size: 12px; font-variant-numeric: tabular-nums; }
|
|
94
94
|
.ta-run-tokens > span { display: inline-flex; align-items: center; gap: 1px; }
|
|
95
95
|
.ta-run-line { display: flex; min-width: 0; min-height: 22px; padding-left: 6px; margin-top: -6px; }
|
|
96
|
+
/* Under the open steps of a turn the line is one more step: the same pitch, its dot on the string's line. */
|
|
97
|
+
.ta-thread-item:has(> .ta-message > .ta-process:last-child > .ta-process-steps) + .ta-run-line { margin-top: -18px; padding-left: 4.5px; }
|
|
96
98
|
.ta-status-waiting::before { background: var(--ta-yellow); }
|
|
97
99
|
/* On the head of a turn the face of ta already shows that it works. */
|
|
98
100
|
.ta-turn-head .ta-run-status > .ta-status { display: none; }
|
|
@@ -144,6 +146,9 @@ export const LAYOUT_STYLE = `
|
|
|
144
146
|
.ta-plus-line { height: 1px; margin: 5px 8px; border: 0; background: var(--ta-border-muted); flex: none; }
|
|
145
147
|
.ta-plus-back { display: flex; align-items: center; gap: 6px; width: 100%; height: 34px; margin-bottom: 4px; padding: 0 8px; border: 0; border-bottom: 1px solid var(--ta-border-muted); border-radius: 9px 9px 0 0; background: none; color: var(--ta-secondary); font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer; }
|
|
146
148
|
.ta-plus-back:hover { color: var(--ta-text); }
|
|
149
|
+
.ta-plus-search { box-sizing: border-box; width: 100%; height: 32px; margin: 0 0 6px; padding: 0 10px; border: 1px solid var(--ta-border); border-radius: 9px; background: var(--ta-main); color: var(--ta-text); font: inherit; font-size: 13px; outline: none; }
|
|
150
|
+
.ta-plus-search:focus { border-color: var(--ta-border-strong, var(--ta-secondary)); }
|
|
151
|
+
.ta-plus-empty { padding: 10px 8px; color: var(--ta-secondary); font-size: 12.5px; }
|
|
147
152
|
@keyframes ta-plus-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
|
|
148
153
|
.ta-console-composer textarea { padding: 5px 2px; }
|
|
149
154
|
/* A long placeholder stays on one line, so the empty box keeps its height beside the controls of the +. */
|
|
@@ -169,20 +174,25 @@ export const LAYOUT_STYLE = `
|
|
|
169
174
|
.ta-queue-back { align-self: flex-end; color: var(--ta-muted); }
|
|
170
175
|
.ta-queue-back:hover { color: var(--ta-text); }
|
|
171
176
|
.ta-account { position: relative; display: grid; place-items: center; width: 40px; height: 40px; flex: none; }
|
|
172
|
-
.ta-account-button { position: relative; width:
|
|
173
|
-
.ta-account-button:hover, .ta-account-button.ta-on {
|
|
174
|
-
.ta-account-
|
|
175
|
-
.ta-account-
|
|
176
|
-
.ta-account-dot
|
|
177
|
-
.ta-account-menu { position: absolute; left: calc(100% + 10px); bottom: 0; z-index: 45; width:
|
|
178
|
-
.ta-account-head { display: flex; align-items: center; gap: 10px; padding:
|
|
179
|
-
.ta-account-
|
|
180
|
-
.ta-account-
|
|
181
|
-
.ta-account-
|
|
182
|
-
.ta-account-
|
|
183
|
-
.ta-account-
|
|
177
|
+
.ta-account-button { position: relative; width: 40px; height: 40px; display: grid; place-items: center; border: 0; border-radius: 10px; background: transparent; padding: 0; transition: background 150ms; }
|
|
178
|
+
.ta-account-button:hover, .ta-account-button.ta-on { background: var(--ta-hover); }
|
|
179
|
+
.ta-account-figure { width: 28px; height: 28px; flex: none; display: grid; place-items: center; border-radius: 50%; background: color-mix(in srgb, var(--ta-green) 14%, var(--ta-main)); color: color-mix(in srgb, var(--ta-green) 75%, var(--ta-text)); font-size: 13px; font-weight: 600; line-height: 1; letter-spacing: 0; user-select: none; }
|
|
180
|
+
.ta-account-figure.ta-large { width: 36px; height: 36px; font-size: 15px; }
|
|
181
|
+
.ta-account-dot { position: absolute; right: 5px; bottom: 5px; width: 8px; height: 8px; border-radius: 50%; background: var(--ta-yellow); box-shadow: 0 0 0 2px var(--ta-side); }
|
|
182
|
+
.ta-account-menu { position: absolute; left: calc(100% + 10px); bottom: 0; z-index: 45; width: 248px; display: flex; flex-direction: column; gap: 2px; padding: 6px; border-radius: 12px; border: 1px solid var(--ta-border); background: var(--ta-side); box-shadow: var(--ta-shadow-pop); animation: ta-fade 120ms ease-out; }
|
|
183
|
+
.ta-account-head { display: flex; align-items: center; gap: 10px; padding: 8px 8px 10px; min-width: 0; }
|
|
184
|
+
.ta-account-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; line-height: 1.35; }
|
|
185
|
+
.ta-account-title { font-size: 13.5px; font-weight: 600; color: var(--ta-text); }
|
|
186
|
+
.ta-account-sub { font-size: 12px; color: var(--ta-muted); }
|
|
187
|
+
.ta-account-service { display: flex; align-items: center; gap: 8px; height: 32px; margin: 0 2px 2px; padding: 0 10px; border-radius: 8px; background: var(--ta-raised); font-size: 12.5px; color: var(--ta-secondary); }
|
|
188
|
+
.ta-account-service-name { flex: 1; min-width: 0; }
|
|
189
|
+
.ta-account-service-state { flex: none; font-size: 12px; color: var(--ta-muted); font-variant-numeric: tabular-nums; }
|
|
190
|
+
.ta-account-state { width: 7px; height: 7px; flex: none; border-radius: 50%; background: var(--ta-muted); }
|
|
191
|
+
.ta-account-state.ta-ok { background: var(--ta-green); box-shadow: 0 0 0 3px color-mix(in srgb, var(--ta-green) 18%, transparent); }
|
|
192
|
+
.ta-account-state.ta-warn { background: var(--ta-yellow); }
|
|
184
193
|
.ta-account-sep { height: 1px; margin: 4px 2px; background: var(--ta-border-muted); }
|
|
185
|
-
.ta-account-item { display: flex; align-items: center; gap: 10px; height: 32px; padding: 0
|
|
194
|
+
.ta-account-item { display: flex; align-items: center; gap: 10px; height: 32px; padding: 0 10px; border: 0; border-radius: 8px; background: transparent; text-align: left; font-size: 13px; color: var(--ta-text); }
|
|
195
|
+
.ta-account-item > svg, .ta-account-item > .ta-icon { flex: none; color: var(--ta-secondary); }
|
|
186
196
|
.ta-account-item:hover { background: var(--ta-hover); }
|
|
187
197
|
.ta-account-item.ta-danger { color: var(--ta-red); }
|
|
188
198
|
@media (max-width: 860px) {
|
|
@@ -250,7 +260,7 @@ export const LAYOUT_STYLE = `
|
|
|
250
260
|
.ta-web-dialog .ta-modal-title { font-size: 16px; }
|
|
251
261
|
.ta-folder-bar { display: flex; align-items: center; gap: 6px; }
|
|
252
262
|
.ta-folder-bar .ta-field input { font-family: var(--ta-mono); font-size: 12.5px; }
|
|
253
|
-
.ta-folder-list { list-style: none; flex:
|
|
263
|
+
.ta-folder-list { list-style: none; flex: none; height: min(340px, 44vh); overflow-y: auto; margin: 0; padding: 4px; border: 1px solid var(--ta-border-muted); border-radius: 10px; }
|
|
254
264
|
.ta-folder-item { display: flex; align-items: center; gap: 10px; width: 100%; height: 34px; padding: 0 10px; border: 0; border-radius: 8px; background: transparent; color: var(--ta-body); font-size: 13px; text-align: left; }
|
|
255
265
|
.ta-folder-item:hover { background: var(--ta-hover); color: var(--ta-text); }
|
|
256
266
|
.ta-folder-item > .ta-icon:first-child, .ta-folder-chevron { color: var(--ta-muted); }
|
|
@@ -258,7 +268,35 @@ export const LAYOUT_STYLE = `
|
|
|
258
268
|
.ta-folder-item:hover .ta-folder-chevron { opacity: 1; }
|
|
259
269
|
.ta-folder-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
260
270
|
.ta-folder-note { display: flex; justify-content: center; padding: 28px 8px; color: var(--ta-muted); font-size: 12.5px; }
|
|
261
|
-
.ta-folder-failed { color: var(--ta-red); font-size: 12.5px; }
|
|
271
|
+
.ta-folder-failed { color: var(--ta-red); font-size: 12.5px; overflow-wrap: anywhere; }
|
|
272
|
+
.ta-folder-note { gap: 8px; align-items: center; }
|
|
273
|
+
.ta-folder-step { color: var(--ta-secondary); }
|
|
274
|
+
.ta-folder-unreachable { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 36px 16px; text-align: center; font-size: 13px; color: var(--ta-text); }
|
|
275
|
+
.ta-folder-unreachable span { max-width: 100%; color: var(--ta-muted); font-family: var(--ta-mono); font-size: 12px; overflow-wrap: anywhere; }
|
|
276
|
+
/* The machines of the picker: this one, the hosts of ssh, + another */
|
|
277
|
+
.ta-modal.ta-folder { width: min(640px, 100%); }
|
|
278
|
+
.ta-folder-machines { flex-wrap: nowrap; overflow-x: auto; margin: 0; padding: 0 0 2px; gap: 6px; scrollbar-width: none; }
|
|
279
|
+
.ta-folder-machines::-webkit-scrollbar { display: none; }
|
|
280
|
+
.ta-folder-machines .ta-icon-button { flex: none; width: 28px; height: 28px; border-radius: 14px; }
|
|
281
|
+
.ta-folder-add input { width: 230px; height: 28px; padding: 0 11px; border-radius: 14px; border: 1px solid var(--ta-border-field); background: var(--ta-input); color: var(--ta-text); font-size: 12.5px; outline: none; }
|
|
282
|
+
.ta-folder-add input:focus { border-color: var(--ta-border-focus); }
|
|
283
|
+
.ta-folder-add input[aria-invalid='true'] { border-color: var(--ta-red); }
|
|
284
|
+
.ta-folder-add input { width: 300px; }
|
|
285
|
+
.ta-remote-state { display: inline-flex; align-items: center; gap: 6px; }
|
|
286
|
+
.ta-remote-light { width: 7px; height: 7px; border-radius: 50%; background: var(--ta-border-field); flex: none; }
|
|
287
|
+
.ta-remote-light.ta-on { background: var(--ta-green); }
|
|
288
|
+
.ta-remote-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--ta-green); flex: none; }
|
|
289
|
+
/* The host of a directory of another machine, before its name */
|
|
290
|
+
.ta-host-tag { display: inline-flex; align-items: center; flex: none; max-width: 120px; height: 17px; padding: 0 6px; margin-right: 5px; border-radius: 5px; background: var(--ta-hover-strong); color: var(--ta-secondary); font-size: 11px; font-weight: 500; line-height: 17px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: 1px; }
|
|
291
|
+
.ta-cwd-chip .ta-host-tag { margin: 0 0 0 2px; }
|
|
292
|
+
.ta-cwd-chip .ta-ellipsis { min-width: 0; }
|
|
293
|
+
/* What ssh asks, and the line while a host connects */
|
|
294
|
+
.ta-remote-prompt { width: min(440px, 100%); gap: 12px; }
|
|
295
|
+
.ta-remote-prompt .ta-confirm-title { display: flex; align-items: center; gap: 8px; }
|
|
296
|
+
.ta-remote-message { margin: 0; padding: 8px 10px; border-radius: 8px; background: var(--ta-hover); color: var(--ta-body); font-family: var(--ta-mono); font-size: 12px; line-height: 1.5; white-space: pre-wrap; overflow-wrap: anywhere; max-height: 160px; overflow-y: auto; }
|
|
297
|
+
.ta-remote-status { position: fixed; left: 50%; top: calc(12px + env(safe-area-inset-top) + var(--ta-titlebar, 0px)); z-index: 65; transform: translateX(-50%); display: inline-flex; align-items: center; gap: 8px; max-width: calc(100vw - 32px); height: 32px; padding: 0 14px; border-radius: 16px; border: 1px solid var(--ta-border); background: var(--ta-side); box-shadow: var(--ta-shadow-pop); color: var(--ta-secondary); font-size: 12.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; animation: ta-fade 160ms ease-out; }
|
|
298
|
+
/* The picker says it itself */
|
|
299
|
+
body:has(.ta-folder) .ta-remote-status { display: none; }
|
|
262
300
|
@media (max-width: 860px) {
|
|
263
301
|
.ta-modal-scrim { align-items: flex-end; padding: 0; }
|
|
264
302
|
.ta-modal { max-height: 88dvh; border-radius: 16px 16px 0 0; padding-bottom: calc(14px + env(safe-area-inset-bottom)); animation: ta-up 260ms var(--ta-ease); }
|
|
@@ -133,6 +133,7 @@ export const SHELL_STYLE = `
|
|
|
133
133
|
.ta-toast-message { color: var(--ta-text); overflow-wrap: anywhere; white-space: pre-wrap; }
|
|
134
134
|
.ta-toast-count { margin-left: 6px; padding: 0 5px; border-radius: 6px; background: var(--ta-chip); color: var(--ta-secondary); font-size: 11px; font-variant-numeric: tabular-nums; }
|
|
135
135
|
.ta-toast-detail { color: var(--ta-secondary); font-size: 12px; overflow-wrap: anywhere; white-space: pre-wrap; }
|
|
136
|
+
.ta-toast-art { align-self: flex-start; width: 200px; height: auto; margin-top: 8px; border-radius: 10px; }
|
|
136
137
|
.ta-toast-action { align-self: flex-start; margin-top: 6px; height: 26px; padding: 0 10px; border-radius: 7px; border: 1px solid var(--ta-border-field); background: transparent; font-size: 12px; font-weight: 500; transition: background 120ms; }
|
|
137
138
|
.ta-toast-action:hover { background: var(--ta-hover); }
|
|
138
139
|
.ta-toast .ta-toast-close { width: 24px; height: 24px; margin-top: -1px; color: var(--ta-muted); }
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { describe, expect, it } from 'bun:test';
|
|
2
|
+
import { CanvasFontFix } from './canvas-font';
|
|
3
|
+
|
|
4
|
+
/** A context that, as Chromium 156, keeps its font when the new one starts with a space. */
|
|
5
|
+
class StrictContext {
|
|
6
|
+
protected value = '10px sans-serif';
|
|
7
|
+
get font(): string {
|
|
8
|
+
return this.value;
|
|
9
|
+
}
|
|
10
|
+
set font(font: string) {
|
|
11
|
+
if (!/^\s/.test(font)) {
|
|
12
|
+
this.value = font.replace(/^(normal )+/, '');
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
describe('CanvasFontFix', () => {
|
|
18
|
+
it('sets the font xterm.js meant, and leaves a valid one as it is', () => {
|
|
19
|
+
const context = new StrictContext();
|
|
20
|
+
context.font = ' normal 24px Menlo';
|
|
21
|
+
expect(context.font).toBe('10px sans-serif');
|
|
22
|
+
CanvasFontFix.install([StrictContext.prototype, undefined]);
|
|
23
|
+
CanvasFontFix.install([StrictContext.prototype]);
|
|
24
|
+
context.font = ' normal 24px Menlo';
|
|
25
|
+
expect(context.font).toBe('24px Menlo');
|
|
26
|
+
context.font = 'italic bold 12px monospace';
|
|
27
|
+
expect(context.font).toBe('italic bold 12px monospace');
|
|
28
|
+
});
|
|
29
|
+
});
|