@jupyter/chat 0.7.0 → 0.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/lib/active-cell-manager.js +1 -4
- package/lib/chat-commands/index.d.ts +2 -0
- package/lib/chat-commands/index.js +6 -0
- package/lib/chat-commands/registry.d.ts +28 -0
- package/lib/chat-commands/registry.js +29 -0
- package/lib/chat-commands/types.d.ts +51 -0
- package/lib/chat-commands/types.js +5 -0
- package/lib/components/attachments.d.ts +23 -0
- package/lib/components/attachments.js +44 -0
- package/lib/components/chat-input.d.ts +8 -11
- package/lib/components/chat-input.js +70 -95
- package/lib/components/chat-messages.d.ts +4 -0
- package/lib/components/chat-messages.js +27 -1
- package/lib/components/chat.d.ts +11 -5
- package/lib/components/chat.js +7 -8
- package/lib/components/input/attach-button.d.ts +14 -0
- package/lib/components/input/attach-button.js +45 -0
- package/lib/components/input/index.d.ts +1 -0
- package/lib/components/input/index.js +1 -0
- package/lib/components/input/send-button.d.ts +2 -2
- package/lib/components/input/use-chat-commands.d.ts +19 -0
- package/lib/components/input/use-chat-commands.js +127 -0
- package/lib/context.d.ts +3 -0
- package/lib/context.js +6 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +2 -0
- package/lib/input-model.d.ts +221 -0
- package/lib/input-model.js +217 -0
- package/lib/model.d.ts +10 -25
- package/lib/model.js +15 -17
- package/lib/registry.d.ts +11 -64
- package/lib/registry.js +4 -72
- package/lib/types.d.ts +19 -38
- package/lib/widgets/chat-widget.js +2 -1
- package/package.json +3 -114
- package/src/active-cell-manager.ts +0 -3
- package/src/chat-commands/index.ts +7 -0
- package/src/chat-commands/registry.ts +60 -0
- package/src/chat-commands/types.ts +67 -0
- package/src/components/attachments.tsx +91 -0
- package/src/components/chat-input.tsx +97 -124
- package/src/components/chat-messages.tsx +36 -3
- package/src/components/chat.tsx +28 -19
- package/src/components/input/attach-button.tsx +68 -0
- package/src/components/input/cancel-button.tsx +1 -0
- package/src/components/input/index.ts +1 -0
- package/src/components/input/send-button.tsx +2 -2
- package/src/components/input/use-chat-commands.tsx +186 -0
- package/src/context.ts +10 -0
- package/src/index.ts +2 -0
- package/src/input-model.ts +406 -0
- package/src/model.ts +24 -35
- package/src/registry.ts +14 -108
- package/src/types.ts +19 -39
- package/src/widgets/chat-widget.tsx +2 -1
- package/style/chat.css +27 -9
- package/style/icons/include-selection.svg +3 -1
- package/style/icons/read.svg +8 -6
- package/style/icons/replace-cell.svg +10 -6
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Jupyter Development Team.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
import { Signal } from '@lumino/signaling';
|
|
6
|
+
const WHITESPACE = new Set([' ', '\n', '\t']);
|
|
7
|
+
/**
|
|
8
|
+
* The input model.
|
|
9
|
+
*/
|
|
10
|
+
export class InputModel {
|
|
11
|
+
constructor(options) {
|
|
12
|
+
var _a, _b;
|
|
13
|
+
/**
|
|
14
|
+
* Add attachment to send with next message.
|
|
15
|
+
*/
|
|
16
|
+
this.addAttachment = (attachment) => {
|
|
17
|
+
const duplicateAttachment = this._attachments.find(att => att.type === attachment.type && att.value === attachment.value);
|
|
18
|
+
if (duplicateAttachment) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
this._attachments.push(attachment);
|
|
22
|
+
this._attachmentsChanged.emit([...this._attachments]);
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Remove attachment to be sent.
|
|
26
|
+
*/
|
|
27
|
+
this.removeAttachment = (attachment) => {
|
|
28
|
+
const attachmentIndex = this._attachments.findIndex(att => att.type === attachment.type && att.value === attachment.value);
|
|
29
|
+
if (attachmentIndex === -1) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
this._attachments.splice(attachmentIndex, 1);
|
|
33
|
+
this._attachmentsChanged.emit([...this._attachments]);
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Update attachments.
|
|
37
|
+
*/
|
|
38
|
+
this.clearAttachments = () => {
|
|
39
|
+
this._attachments = [];
|
|
40
|
+
this._attachmentsChanged.emit([]);
|
|
41
|
+
};
|
|
42
|
+
this._cursorIndex = null;
|
|
43
|
+
this._currentWord = null;
|
|
44
|
+
this._valueChanged = new Signal(this);
|
|
45
|
+
this._cursorIndexChanged = new Signal(this);
|
|
46
|
+
this._currentWordChanged = new Signal(this);
|
|
47
|
+
this._configChanged = new Signal(this);
|
|
48
|
+
this._focusInputSignal = new Signal(this);
|
|
49
|
+
this._attachmentsChanged = new Signal(this);
|
|
50
|
+
this._isDisposed = false;
|
|
51
|
+
this._value = options.value || '';
|
|
52
|
+
this._attachments = options.attachments || [];
|
|
53
|
+
this.cursorIndex = options.cursorIndex || this.value.length;
|
|
54
|
+
this._activeCellManager = (_a = options.activeCellManager) !== null && _a !== void 0 ? _a : null;
|
|
55
|
+
this._selectionWatcher = (_b = options.selectionWatcher) !== null && _b !== void 0 ? _b : null;
|
|
56
|
+
this._config = {
|
|
57
|
+
...options.config
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The entire input value.
|
|
62
|
+
*/
|
|
63
|
+
get value() {
|
|
64
|
+
return this._value;
|
|
65
|
+
}
|
|
66
|
+
set value(newInput) {
|
|
67
|
+
this._value = newInput;
|
|
68
|
+
this._valueChanged.emit(newInput);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* A signal emitting when the value has changed.
|
|
72
|
+
*/
|
|
73
|
+
get valueChanged() {
|
|
74
|
+
return this._valueChanged;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The cursor position in the input.
|
|
78
|
+
*/
|
|
79
|
+
get cursorIndex() {
|
|
80
|
+
return this._cursorIndex;
|
|
81
|
+
}
|
|
82
|
+
set cursorIndex(newIndex) {
|
|
83
|
+
if (newIndex === null || newIndex > this._value.length) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
this._cursorIndex = newIndex;
|
|
87
|
+
this._cursorIndexChanged.emit(newIndex);
|
|
88
|
+
if (this._cursorIndex === null) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const currentWord = Private.getCurrentWord(this._value, this._cursorIndex);
|
|
92
|
+
if (currentWord !== this._currentWord) {
|
|
93
|
+
this._currentWord = currentWord;
|
|
94
|
+
this._currentWordChanged.emit(this._currentWord);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* A signal emitting when the cursor position has changed.
|
|
99
|
+
*/
|
|
100
|
+
get cursorIndexChanged() {
|
|
101
|
+
return this._cursorIndexChanged;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* The current word behind the user's cursor, space-separated.
|
|
105
|
+
*/
|
|
106
|
+
get currentWord() {
|
|
107
|
+
return this._currentWord;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* A signal emitting when the current word has changed.
|
|
111
|
+
*/
|
|
112
|
+
get currentWordChanged() {
|
|
113
|
+
return this._currentWordChanged;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Get the active cell manager.
|
|
117
|
+
*/
|
|
118
|
+
get activeCellManager() {
|
|
119
|
+
return this._activeCellManager;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Get the selection watcher.
|
|
123
|
+
*/
|
|
124
|
+
get selectionWatcher() {
|
|
125
|
+
return this._selectionWatcher;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* The input configuration.
|
|
129
|
+
*/
|
|
130
|
+
get config() {
|
|
131
|
+
return this._config;
|
|
132
|
+
}
|
|
133
|
+
set config(value) {
|
|
134
|
+
this._config = { ...this._config, ...value };
|
|
135
|
+
this._configChanged.emit(this._config);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* A signal emitting when the configuration is updated.
|
|
139
|
+
*/
|
|
140
|
+
get configChanged() {
|
|
141
|
+
return this._configChanged;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Function to request the focus on the input of the chat.
|
|
145
|
+
*/
|
|
146
|
+
focus() {
|
|
147
|
+
this._focusInputSignal.emit();
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* A signal emitting when the focus is requested on the input.
|
|
151
|
+
*/
|
|
152
|
+
get focusInputSignal() {
|
|
153
|
+
return this._focusInputSignal;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* The attachments list.
|
|
157
|
+
*/
|
|
158
|
+
get attachments() {
|
|
159
|
+
return this._attachments;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* A signal emitting when the input attachments changed.
|
|
163
|
+
*/
|
|
164
|
+
get attachmentsChanged() {
|
|
165
|
+
return this._attachmentsChanged;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Replace the current word in the input with a new one.
|
|
169
|
+
*/
|
|
170
|
+
replaceCurrentWord(newWord) {
|
|
171
|
+
if (this.cursorIndex === null) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
const [start, end] = Private.getCurrentWordBoundaries(this.value, this.cursorIndex);
|
|
175
|
+
this.value = this.value.slice(0, start) + newWord + this.value.slice(end);
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Dispose the input model.
|
|
179
|
+
*/
|
|
180
|
+
dispose() {
|
|
181
|
+
if (this.isDisposed) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
this._isDisposed = true;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Whether the input model is disposed.
|
|
188
|
+
*/
|
|
189
|
+
get isDisposed() {
|
|
190
|
+
return this._isDisposed;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
var Private;
|
|
194
|
+
(function (Private) {
|
|
195
|
+
function getCurrentWordBoundaries(input, cursorIndex) {
|
|
196
|
+
let start = cursorIndex;
|
|
197
|
+
let end = cursorIndex;
|
|
198
|
+
const n = input.length;
|
|
199
|
+
while (start > 0 && !WHITESPACE.has(input[start - 1])) {
|
|
200
|
+
start--;
|
|
201
|
+
}
|
|
202
|
+
while (end < n && !WHITESPACE.has(input[end])) {
|
|
203
|
+
end++;
|
|
204
|
+
}
|
|
205
|
+
return [start, end];
|
|
206
|
+
}
|
|
207
|
+
Private.getCurrentWordBoundaries = getCurrentWordBoundaries;
|
|
208
|
+
/**
|
|
209
|
+
* Gets the current (space-separated) word around the user's cursor. The current
|
|
210
|
+
* word is used to generate a list of matching chat commands.
|
|
211
|
+
*/
|
|
212
|
+
function getCurrentWord(input, cursorIndex) {
|
|
213
|
+
const [start, end] = getCurrentWordBoundaries(input, cursorIndex);
|
|
214
|
+
return input.slice(start, end);
|
|
215
|
+
}
|
|
216
|
+
Private.getCurrentWord = getCurrentWord;
|
|
217
|
+
})(Private || (Private = {}));
|
package/lib/model.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { ISignal } from '@lumino/signaling';
|
|
|
4
4
|
import { IChatHistory, INewMessage, IChatMessage, IConfig, IUser } from './types';
|
|
5
5
|
import { IActiveCellManager } from './active-cell-manager';
|
|
6
6
|
import { ISelectionWatcher } from './selection-watcher';
|
|
7
|
+
import { IInputModel } from './input-model';
|
|
7
8
|
/**
|
|
8
9
|
* The chat model interface.
|
|
9
10
|
*/
|
|
@@ -32,6 +33,10 @@ export interface IChatModel extends IDisposable {
|
|
|
32
33
|
* The chat messages list.
|
|
33
34
|
*/
|
|
34
35
|
readonly messages: IChatMessage[];
|
|
36
|
+
/**
|
|
37
|
+
* The input model.
|
|
38
|
+
*/
|
|
39
|
+
readonly input: IInputModel;
|
|
35
40
|
/**
|
|
36
41
|
* Get the active cell manager.
|
|
37
42
|
*/
|
|
@@ -60,10 +65,6 @@ export interface IChatModel extends IDisposable {
|
|
|
60
65
|
* A signal emitting when the writers change.
|
|
61
66
|
*/
|
|
62
67
|
readonly writersChanged?: ISignal<IChatModel, IUser[]>;
|
|
63
|
-
/**
|
|
64
|
-
* A signal emitting when the focus is requested on the input.
|
|
65
|
-
*/
|
|
66
|
-
readonly focusInputSignal?: ISignal<IChatModel, void>;
|
|
67
68
|
/**
|
|
68
69
|
* Send a message, to be defined depending on the chosen technology.
|
|
69
70
|
* Default to no-op.
|
|
@@ -121,14 +122,6 @@ export interface IChatModel extends IDisposable {
|
|
|
121
122
|
* Update the current writers list.
|
|
122
123
|
*/
|
|
123
124
|
updateWriters(writers: IUser[]): void;
|
|
124
|
-
/**
|
|
125
|
-
* Function to request the focus on the input of the chat.
|
|
126
|
-
*/
|
|
127
|
-
focusInput(): void;
|
|
128
|
-
/**
|
|
129
|
-
* Function called by the input on key pressed.
|
|
130
|
-
*/
|
|
131
|
-
inputChanged?(input?: string): void;
|
|
132
125
|
}
|
|
133
126
|
/**
|
|
134
127
|
* The default chat model implementation.
|
|
@@ -154,6 +147,10 @@ export declare class ChatModel implements IChatModel {
|
|
|
154
147
|
* The chat messages list.
|
|
155
148
|
*/
|
|
156
149
|
get messages(): IChatMessage[];
|
|
150
|
+
/**
|
|
151
|
+
* The input model.
|
|
152
|
+
*/
|
|
153
|
+
get input(): IInputModel;
|
|
157
154
|
/**
|
|
158
155
|
* Get the active cell manager.
|
|
159
156
|
*/
|
|
@@ -202,10 +199,6 @@ export declare class ChatModel implements IChatModel {
|
|
|
202
199
|
* A signal emitting when the writers change.
|
|
203
200
|
*/
|
|
204
201
|
get writersChanged(): ISignal<IChatModel, IUser[]>;
|
|
205
|
-
/**
|
|
206
|
-
* A signal emitting when the focus is requested on the input.
|
|
207
|
-
*/
|
|
208
|
-
get focusInputSignal(): ISignal<IChatModel, void>;
|
|
209
202
|
/**
|
|
210
203
|
* Send a message, to be defined depending on the chosen technology.
|
|
211
204
|
* Default to no-op.
|
|
@@ -252,14 +245,6 @@ export declare class ChatModel implements IChatModel {
|
|
|
252
245
|
* This implementation only propagate the list via a signal.
|
|
253
246
|
*/
|
|
254
247
|
updateWriters(writers: IUser[]): void;
|
|
255
|
-
/**
|
|
256
|
-
* Function to request the focus on the input of the chat.
|
|
257
|
-
*/
|
|
258
|
-
focusInput(): void;
|
|
259
|
-
/**
|
|
260
|
-
* Function called by the input on key pressed.
|
|
261
|
-
*/
|
|
262
|
-
inputChanged?(input?: string): void;
|
|
263
248
|
/**
|
|
264
249
|
* Add unread messages to the list.
|
|
265
250
|
* @param indexes - list of new indexes.
|
|
@@ -281,6 +266,7 @@ export declare class ChatModel implements IChatModel {
|
|
|
281
266
|
private _id;
|
|
282
267
|
private _name;
|
|
283
268
|
private _config;
|
|
269
|
+
private _inputModel;
|
|
284
270
|
private _isDisposed;
|
|
285
271
|
private _commands?;
|
|
286
272
|
private _activeCellManager;
|
|
@@ -291,7 +277,6 @@ export declare class ChatModel implements IChatModel {
|
|
|
291
277
|
private _unreadChanged;
|
|
292
278
|
private _viewportChanged;
|
|
293
279
|
private _writersChanged;
|
|
294
|
-
private _focusInputSignal;
|
|
295
280
|
}
|
|
296
281
|
/**
|
|
297
282
|
* The chat model namespace.
|
package/lib/model.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Distributed under the terms of the Modified BSD License.
|
|
4
4
|
*/
|
|
5
5
|
import { Signal } from '@lumino/signaling';
|
|
6
|
+
import { InputModel } from './input-model';
|
|
6
7
|
/**
|
|
7
8
|
* The default chat model implementation.
|
|
8
9
|
* It is not able to send or update a message by itself, since it depends on the
|
|
@@ -25,7 +26,6 @@ export class ChatModel {
|
|
|
25
26
|
this._unreadChanged = new Signal(this);
|
|
26
27
|
this._viewportChanged = new Signal(this);
|
|
27
28
|
this._writersChanged = new Signal(this);
|
|
28
|
-
this._focusInputSignal = new Signal(this);
|
|
29
29
|
if (options.id) {
|
|
30
30
|
this.id = options.id;
|
|
31
31
|
}
|
|
@@ -36,6 +36,13 @@ export class ChatModel {
|
|
|
36
36
|
sendTypingNotification: true,
|
|
37
37
|
...config
|
|
38
38
|
};
|
|
39
|
+
this._inputModel = new InputModel({
|
|
40
|
+
activeCellManager: options.activeCellManager,
|
|
41
|
+
selectionWatcher: options.selectionWatcher,
|
|
42
|
+
config: {
|
|
43
|
+
sendWithShiftEnter: config.sendWithShiftEnter
|
|
44
|
+
}
|
|
45
|
+
});
|
|
39
46
|
this._commands = options.commands;
|
|
40
47
|
this._activeCellManager = (_b = options.activeCellManager) !== null && _b !== void 0 ? _b : null;
|
|
41
48
|
this._selectionWatcher = (_c = options.selectionWatcher) !== null && _c !== void 0 ? _c : null;
|
|
@@ -64,6 +71,12 @@ export class ChatModel {
|
|
|
64
71
|
get messages() {
|
|
65
72
|
return this._messages;
|
|
66
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* The input model.
|
|
76
|
+
*/
|
|
77
|
+
get input() {
|
|
78
|
+
return this._inputModel;
|
|
79
|
+
}
|
|
67
80
|
/**
|
|
68
81
|
* Get the active cell manager.
|
|
69
82
|
*/
|
|
@@ -108,6 +121,7 @@ export class ChatModel {
|
|
|
108
121
|
this._config.unreadNotifications !== value.unreadNotifications;
|
|
109
122
|
this._config = { ...this._config, ...value };
|
|
110
123
|
this._configChanged.emit(this._config);
|
|
124
|
+
this.input.config = value;
|
|
111
125
|
// Update the stacked status of the messages and the view.
|
|
112
126
|
if (stackMessagesChanged) {
|
|
113
127
|
if (this._config.stackMessages) {
|
|
@@ -197,12 +211,6 @@ export class ChatModel {
|
|
|
197
211
|
get writersChanged() {
|
|
198
212
|
return this._writersChanged;
|
|
199
213
|
}
|
|
200
|
-
/**
|
|
201
|
-
* A signal emitting when the focus is requested on the input.
|
|
202
|
-
*/
|
|
203
|
-
get focusInputSignal() {
|
|
204
|
-
return this._focusInputSignal;
|
|
205
|
-
}
|
|
206
214
|
/**
|
|
207
215
|
* Send a message, to be defined depending on the chosen technology.
|
|
208
216
|
* Default to no-op.
|
|
@@ -306,16 +314,6 @@ export class ChatModel {
|
|
|
306
314
|
updateWriters(writers) {
|
|
307
315
|
this._writersChanged.emit(writers);
|
|
308
316
|
}
|
|
309
|
-
/**
|
|
310
|
-
* Function to request the focus on the input of the chat.
|
|
311
|
-
*/
|
|
312
|
-
focusInput() {
|
|
313
|
-
this._focusInputSignal.emit();
|
|
314
|
-
}
|
|
315
|
-
/**
|
|
316
|
-
* Function called by the input on key pressed.
|
|
317
|
-
*/
|
|
318
|
-
inputChanged(input) { }
|
|
319
317
|
/**
|
|
320
318
|
* Add unread messages to the list.
|
|
321
319
|
* @param indexes - list of new indexes.
|
package/lib/registry.d.ts
CHANGED
|
@@ -1,78 +1,25 @@
|
|
|
1
1
|
import { Token } from '@lumino/coreutils';
|
|
2
|
-
import {
|
|
2
|
+
import { IAttachment } from './types';
|
|
3
3
|
/**
|
|
4
|
-
* The token for the
|
|
4
|
+
* The token for the attachments opener registry, which can be provided by an extension
|
|
5
5
|
* using @jupyter/chat package.
|
|
6
6
|
*/
|
|
7
|
-
export declare const
|
|
7
|
+
export declare const IAttachmentOpenerRegistry: Token<IAttachmentOpenerRegistry>;
|
|
8
8
|
/**
|
|
9
|
-
* The interface of a registry to provide
|
|
9
|
+
* The interface of a registry to provide attachments opener.
|
|
10
10
|
*/
|
|
11
|
-
export interface
|
|
11
|
+
export interface IAttachmentOpenerRegistry {
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
13
|
+
* Get the function opening an attachment for a given type.
|
|
14
14
|
*/
|
|
15
|
-
|
|
15
|
+
get(type: string): ((attachment: IAttachment) => void) | undefined;
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
17
|
+
* Register a function to open an attachment type.
|
|
18
18
|
*/
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Return a registered autocomplete props.
|
|
22
|
-
*
|
|
23
|
-
* @param name - the name of the registered autocomplete props.
|
|
24
|
-
*/
|
|
25
|
-
get(name: string): IAutocompletionCommandsProps | undefined;
|
|
26
|
-
/**
|
|
27
|
-
* Register autocomplete props.
|
|
28
|
-
*
|
|
29
|
-
* @param name - the name for the registration.
|
|
30
|
-
* @param autocompletion - the autocomplete props.
|
|
31
|
-
*/
|
|
32
|
-
add(name: string, autocompletion: IAutocompletionCommandsProps): boolean;
|
|
33
|
-
/**
|
|
34
|
-
* Remove a registered autocomplete props.
|
|
35
|
-
*
|
|
36
|
-
* @param name - the name of the autocomplete props.
|
|
37
|
-
*/
|
|
38
|
-
remove(name: string): boolean;
|
|
19
|
+
set(type: string, opener: (attachment: IAttachment) => void): void;
|
|
39
20
|
}
|
|
40
21
|
/**
|
|
41
|
-
*
|
|
22
|
+
* The default registry, a Map object.
|
|
42
23
|
*/
|
|
43
|
-
export declare class
|
|
44
|
-
/**
|
|
45
|
-
* Getter and setter for the default autocompletion name.
|
|
46
|
-
*/
|
|
47
|
-
get default(): string | null;
|
|
48
|
-
set default(name: string | null);
|
|
49
|
-
/**
|
|
50
|
-
* Get the default autocompletion.
|
|
51
|
-
*/
|
|
52
|
-
getDefaultCompletion(): IAutocompletionCommandsProps | undefined;
|
|
53
|
-
/**
|
|
54
|
-
* Return a registered autocomplete props.
|
|
55
|
-
*
|
|
56
|
-
* @param name - the name of the registered autocomplete props.
|
|
57
|
-
*/
|
|
58
|
-
get(name: string): IAutocompletionCommandsProps | undefined;
|
|
59
|
-
/**
|
|
60
|
-
* Register autocomplete props.
|
|
61
|
-
*
|
|
62
|
-
* @param name - the name for the registration.
|
|
63
|
-
* @param autocompletion - the autocomplete props.
|
|
64
|
-
*/
|
|
65
|
-
add(name: string, autocompletion: IAutocompletionCommandsProps, isDefault?: boolean): boolean;
|
|
66
|
-
/**
|
|
67
|
-
* Remove a registered autocomplete props.
|
|
68
|
-
*
|
|
69
|
-
* @param name - the name of the autocomplete props.
|
|
70
|
-
*/
|
|
71
|
-
remove(name: string): boolean;
|
|
72
|
-
/**
|
|
73
|
-
* Remove all registered autocompletions.
|
|
74
|
-
*/
|
|
75
|
-
removeAll(): void;
|
|
76
|
-
private _default;
|
|
77
|
-
private _autocompletions;
|
|
24
|
+
export declare class AttachmentOpenerRegistry extends Map<string, (attachment: IAttachment) => void> implements IAttachmentOpenerRegistry {
|
|
78
25
|
}
|
package/lib/registry.js
CHANGED
|
@@ -4,80 +4,12 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { Token } from '@lumino/coreutils';
|
|
6
6
|
/**
|
|
7
|
-
* The token for the
|
|
7
|
+
* The token for the attachments opener registry, which can be provided by an extension
|
|
8
8
|
* using @jupyter/chat package.
|
|
9
9
|
*/
|
|
10
|
-
export const
|
|
10
|
+
export const IAttachmentOpenerRegistry = new Token('@jupyter/chat:IAttachmentOpenerRegistry');
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* The default registry, a Map object.
|
|
13
13
|
*/
|
|
14
|
-
export class
|
|
15
|
-
constructor() {
|
|
16
|
-
this._default = null;
|
|
17
|
-
this._autocompletions = new Map();
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Getter and setter for the default autocompletion name.
|
|
21
|
-
*/
|
|
22
|
-
get default() {
|
|
23
|
-
return this._default;
|
|
24
|
-
}
|
|
25
|
-
set default(name) {
|
|
26
|
-
if (name === null || this._autocompletions.has(name)) {
|
|
27
|
-
this._default = name;
|
|
28
|
-
}
|
|
29
|
-
else {
|
|
30
|
-
console.warn(`There is no registered completer with the name '${name}'`);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Get the default autocompletion.
|
|
35
|
-
*/
|
|
36
|
-
getDefaultCompletion() {
|
|
37
|
-
if (this._default === null) {
|
|
38
|
-
return undefined;
|
|
39
|
-
}
|
|
40
|
-
return this._autocompletions.get(this._default);
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Return a registered autocomplete props.
|
|
44
|
-
*
|
|
45
|
-
* @param name - the name of the registered autocomplete props.
|
|
46
|
-
*/
|
|
47
|
-
get(name) {
|
|
48
|
-
return this._autocompletions.get(name);
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Register autocomplete props.
|
|
52
|
-
*
|
|
53
|
-
* @param name - the name for the registration.
|
|
54
|
-
* @param autocompletion - the autocomplete props.
|
|
55
|
-
*/
|
|
56
|
-
add(name, autocompletion, isDefault = false) {
|
|
57
|
-
if (!this._autocompletions.has(name)) {
|
|
58
|
-
this._autocompletions.set(name, autocompletion);
|
|
59
|
-
if (this._autocompletions.size === 1 || isDefault) {
|
|
60
|
-
this.default = name;
|
|
61
|
-
}
|
|
62
|
-
return true;
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
console.warn(`A completer with the name '${name}' is already registered`);
|
|
66
|
-
return false;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Remove a registered autocomplete props.
|
|
71
|
-
*
|
|
72
|
-
* @param name - the name of the autocomplete props.
|
|
73
|
-
*/
|
|
74
|
-
remove(name) {
|
|
75
|
-
return this._autocompletions.delete(name);
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Remove all registered autocompletions.
|
|
79
|
-
*/
|
|
80
|
-
removeAll() {
|
|
81
|
-
this._autocompletions.clear();
|
|
82
|
-
}
|
|
14
|
+
export class AttachmentOpenerRegistry extends Map {
|
|
83
15
|
}
|
package/lib/types.d.ts
CHANGED
|
@@ -37,12 +37,13 @@ export interface IConfig {
|
|
|
37
37
|
/**
|
|
38
38
|
* The chat message description.
|
|
39
39
|
*/
|
|
40
|
-
export interface IChatMessage<T = IUser> {
|
|
40
|
+
export interface IChatMessage<T = IUser, U = IAttachment> {
|
|
41
41
|
type: 'msg';
|
|
42
42
|
body: string;
|
|
43
43
|
id: string;
|
|
44
44
|
time: number;
|
|
45
45
|
sender: T;
|
|
46
|
+
attachments?: U[];
|
|
46
47
|
raw_time?: boolean;
|
|
47
48
|
deleted?: boolean;
|
|
48
49
|
edited?: boolean;
|
|
@@ -62,16 +63,27 @@ export interface INewMessage {
|
|
|
62
63
|
id?: string;
|
|
63
64
|
}
|
|
64
65
|
/**
|
|
65
|
-
*
|
|
66
|
+
* The attachment interface.
|
|
66
67
|
*/
|
|
67
|
-
export interface
|
|
68
|
+
export interface IAttachment {
|
|
69
|
+
/**
|
|
70
|
+
* The type of the attachment (basically 'file', 'variable', 'image')
|
|
71
|
+
*/
|
|
72
|
+
type: string;
|
|
73
|
+
/**
|
|
74
|
+
* The value, i.e. the file path, the variable name or image content.
|
|
75
|
+
*/
|
|
76
|
+
value: string;
|
|
77
|
+
/**
|
|
78
|
+
* The mimetype of the attachment, optional.
|
|
79
|
+
*/
|
|
80
|
+
mimetype?: string;
|
|
68
81
|
}
|
|
69
82
|
/**
|
|
70
|
-
*
|
|
83
|
+
* An empty interface to describe optional settings that could be fetched from server.
|
|
71
84
|
*/
|
|
72
|
-
export
|
|
73
|
-
|
|
74
|
-
};
|
|
85
|
+
export interface ISettings {
|
|
86
|
+
}
|
|
75
87
|
/**
|
|
76
88
|
* Representation of a selected text.
|
|
77
89
|
*/
|
|
@@ -90,34 +102,3 @@ export type CellSelection = {
|
|
|
90
102
|
* Selection object (text or cell).
|
|
91
103
|
*/
|
|
92
104
|
export type Selection = TextSelection | CellSelection;
|
|
93
|
-
/**
|
|
94
|
-
* The properties of the autocompletion.
|
|
95
|
-
*
|
|
96
|
-
* The autocompletion component will open if the 'opener' string is typed at the
|
|
97
|
-
* beginning of the input field.
|
|
98
|
-
*/
|
|
99
|
-
export interface IAutocompletionCommandsProps {
|
|
100
|
-
/**
|
|
101
|
-
* The string that open the completer.
|
|
102
|
-
*/
|
|
103
|
-
opener: string;
|
|
104
|
-
/**
|
|
105
|
-
* The list of available commands.
|
|
106
|
-
*/
|
|
107
|
-
commands?: AutocompleteCommand[] | (() => Promise<AutocompleteCommand[]>);
|
|
108
|
-
/**
|
|
109
|
-
* The props for the Autocomplete component.
|
|
110
|
-
*
|
|
111
|
-
* Must be compatible with https://mui.com/material-ui/api/autocomplete/#props.
|
|
112
|
-
*
|
|
113
|
-
* ## NOTES:
|
|
114
|
-
* - providing `options` will overwrite the commands argument.
|
|
115
|
-
* - providing `renderInput` will overwrite the input component.
|
|
116
|
-
* - providing `renderOptions` allows to customize the rendering of the component.
|
|
117
|
-
* - some arguments should not be provided and would be overwritten:
|
|
118
|
-
* - inputValue
|
|
119
|
-
* - onInputChange
|
|
120
|
-
* - onHighlightChange
|
|
121
|
-
*/
|
|
122
|
-
props?: any;
|
|
123
|
-
}
|
|
@@ -9,10 +9,11 @@ import { chatIcon } from '../icons';
|
|
|
9
9
|
export class ChatWidget extends ReactWidget {
|
|
10
10
|
constructor(options) {
|
|
11
11
|
super();
|
|
12
|
-
this.id = 'jupyter-chat::widget';
|
|
13
12
|
this.title.icon = chatIcon;
|
|
14
13
|
this.title.caption = 'Jupyter Chat'; // TODO: i18n
|
|
15
14
|
this._chatOptions = options;
|
|
15
|
+
this.id = `jupyter-chat::widget::${options.model.name}`;
|
|
16
|
+
this.node.onclick = () => this.model.input.focus();
|
|
16
17
|
}
|
|
17
18
|
/**
|
|
18
19
|
* Get the model of the widget.
|