jupyterlab-chat 0.10.1 → 0.12.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/factory.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { IAttachmentOpenerRegistry, IChatCommandRegistry, IInputToolbarRegistry } from '@jupyter/chat';
1
+ import { IAttachmentOpenerRegistry, IChatCommandRegistry, IInputToolbarRegistry, IMessageFooterRegistry } from '@jupyter/chat';
2
2
  import { IThemeManager } from '@jupyterlab/apputils';
3
3
  import { IDocumentManager } from '@jupyterlab/docmanager';
4
4
  import { ABCWidgetFactory, DocumentRegistry } from '@jupyterlab/docregistry';
@@ -53,6 +53,8 @@ export declare class ChatWidgetFactory extends ABCWidgetFactory<LabChatPanel, La
53
53
  private _chatCommandRegistry?;
54
54
  private _attachmentOpenerRegistry?;
55
55
  private _inputToolbarFactory?;
56
+ private _messageFooterRegistry?;
57
+ private _welcomeMessage?;
56
58
  }
57
59
  export declare namespace ChatWidgetFactory {
58
60
  interface IContext extends DocumentRegistry.IContext<LabChatModel> {
@@ -62,6 +64,8 @@ export declare namespace ChatWidgetFactory {
62
64
  chatCommandRegistry?: IChatCommandRegistry;
63
65
  attachmentOpenerRegistry?: IAttachmentOpenerRegistry;
64
66
  inputToolbarRegistry?: IInputToolbarRegistry;
67
+ messageFooterRegistry?: IMessageFooterRegistry;
68
+ welcomeMessage?: string;
65
69
  }
66
70
  interface IOptions<T extends LabChatPanel> extends DocumentRegistry.IWidgetFactoryOptions<T> {
67
71
  themeManager: IThemeManager | null;
@@ -69,6 +73,8 @@ export declare namespace ChatWidgetFactory {
69
73
  chatCommandRegistry?: IChatCommandRegistry;
70
74
  attachmentOpenerRegistry?: IAttachmentOpenerRegistry;
71
75
  inputToolbarFactory?: IInputToolbarRegistryFactory;
76
+ messageFooterRegistry?: IMessageFooterRegistry;
77
+ welcomeMessage?: string;
72
78
  }
73
79
  }
74
80
  export declare class LabChatModelFactory implements DocumentRegistry.IModelFactory<LabChatModel> {
package/lib/factory.js CHANGED
@@ -53,6 +53,8 @@ export class ChatWidgetFactory extends ABCWidgetFactory {
53
53
  this._chatCommandRegistry = options.chatCommandRegistry;
54
54
  this._attachmentOpenerRegistry = options.attachmentOpenerRegistry;
55
55
  this._inputToolbarFactory = options.inputToolbarFactory;
56
+ this._messageFooterRegistry = options.messageFooterRegistry;
57
+ this._welcomeMessage = options.welcomeMessage;
56
58
  }
57
59
  /**
58
60
  * Create a new widget given a context.
@@ -65,6 +67,8 @@ export class ChatWidgetFactory extends ABCWidgetFactory {
65
67
  context.themeManager = this._themeManager;
66
68
  context.chatCommandRegistry = this._chatCommandRegistry;
67
69
  context.attachmentOpenerRegistry = this._attachmentOpenerRegistry;
70
+ context.messageFooterRegistry = this._messageFooterRegistry;
71
+ context.welcomeMessage = this._welcomeMessage;
68
72
  if (this._inputToolbarFactory) {
69
73
  context.inputToolbarRegistry = this._inputToolbarFactory.create();
70
74
  }
package/lib/model.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AbstractChatModel, AbstractChatContext, IChatContext, IChatMessage, IChatModel, IInputModel, INewMessage, IUser } from '@jupyter/chat';
1
+ import { AbstractChatModel, AbstractChatContext, IChatContext, IChatMessage, IChatModel, INewMessage, IUser } from '@jupyter/chat';
2
2
  import { IChangedArgs } from '@jupyterlab/coreutils';
3
3
  import { DocumentRegistry } from '@jupyterlab/docregistry';
4
4
  import { User } from '@jupyterlab/services';
@@ -48,9 +48,16 @@ export declare class LabChatModel extends AbstractChatModel implements DocumentR
48
48
  updateMessage(id: string, updatedMessage: IChatMessage): Promise<boolean | void> | boolean | void;
49
49
  deleteMessage(id: string): Promise<boolean | void> | boolean | void;
50
50
  /**
51
- * Function called by the input on key pressed.
51
+ * Function called when the input content changed.
52
+ *
53
+ * @param value - The whole input content.
54
+ * @param messageID - The ID of the message being edited, if any.
52
55
  */
53
- onInputChanged: (_: IInputModel, value: string) => void;
56
+ onInputChanged: (value: string, messageID?: string) => void;
57
+ /**
58
+ * Listen to the message edition input.
59
+ */
60
+ onMessageEditionAdded: (_: IChatModel, edition: IChatModel.IMessageEdition) => void;
54
61
  /**
55
62
  * Triggered when an awareness state changes.
56
63
  * Used to populate the writers list.
package/lib/model.js CHANGED
@@ -15,9 +15,12 @@ export class LabChatModel extends AbstractChatModel {
15
15
  super(options);
16
16
  this.collaborative = true;
17
17
  /**
18
- * Function called by the input on key pressed.
18
+ * Function called when the input content changed.
19
+ *
20
+ * @param value - The whole input content.
21
+ * @param messageID - The ID of the message being edited, if any.
19
22
  */
20
- this.onInputChanged = (_, value) => {
23
+ this.onInputChanged = (value, messageID) => {
21
24
  if (!value || !this.config.sendTypingNotification) {
22
25
  return;
23
26
  }
@@ -25,11 +28,22 @@ export class LabChatModel extends AbstractChatModel {
25
28
  if (this._timeoutWriting !== null) {
26
29
  window.clearTimeout(this._timeoutWriting);
27
30
  }
28
- awareness.setLocalStateField('isWriting', true);
31
+ awareness.setLocalStateField('isWriting', messageID !== null && messageID !== void 0 ? messageID : true);
29
32
  this._timeoutWriting = window.setTimeout(() => {
30
33
  this._resetWritingStatus();
31
34
  }, WRITING_DELAY);
32
35
  };
36
+ /**
37
+ * Listen to the message edition input.
38
+ */
39
+ this.onMessageEditionAdded = (_, edition) => {
40
+ if (edition !== null) {
41
+ const _onInputChanged = (_, value) => {
42
+ this.onInputChanged(value, edition.id);
43
+ };
44
+ edition.model.valueChanged.connect(_onInputChanged);
45
+ }
46
+ };
33
47
  /**
34
48
  * Triggered when an awareness state changes.
35
49
  * Used to populate the writers list.
@@ -42,8 +56,12 @@ export class LabChatModel extends AbstractChatModel {
42
56
  if (!state || !state.user || state.user.username === this.user.username) {
43
57
  continue;
44
58
  }
45
- if (state.isWriting) {
46
- writers.push(state.user);
59
+ if (state.isWriting !== undefined && state.isWriting !== false) {
60
+ const writer = {
61
+ user: state.user,
62
+ messageID: state.isWriting === true ? undefined : state.isWriting
63
+ };
64
+ writers.push(writer);
47
65
  }
48
66
  }
49
67
  this.updateWriters(writers);
@@ -136,7 +154,8 @@ export class LabChatModel extends AbstractChatModel {
136
154
  this.config = config;
137
155
  });
138
156
  this.sharedModel.awareness.on('change', this.onAwarenessChange);
139
- this.input.valueChanged.connect(this.onInputChanged);
157
+ this.input.valueChanged.connect((_, value) => this.onInputChanged(value));
158
+ this.messageEditionAdded.connect(this.onMessageEditionAdded);
140
159
  }
141
160
  get user() {
142
161
  return this._user;
package/lib/token.d.ts CHANGED
@@ -102,3 +102,9 @@ export interface IInputToolbarRegistryFactory {
102
102
  * The token of the factory to create an input toolbar registry.
103
103
  */
104
104
  export declare const IInputToolbarRegistryFactory: Token<IInputToolbarRegistryFactory>;
105
+ /**
106
+ * The token to add a welcome message to the chat.
107
+ * This token is not provided by default, but can be provided by third party extensions
108
+ * willing to add a welcome message to the chat.
109
+ */
110
+ export declare const IWelcomeMessage: Token<string>;
package/lib/token.js CHANGED
@@ -61,3 +61,9 @@ export const ISelectionWatcherToken = new Token('jupyterlab-chat:ISelectionWatch
61
61
  * The token of the factory to create an input toolbar registry.
62
62
  */
63
63
  export const IInputToolbarRegistryFactory = new Token('jupyterlab-chat:IInputToolbarRegistryFactory');
64
+ /**
65
+ * The token to add a welcome message to the chat.
66
+ * This token is not provided by default, but can be provided by third party extensions
67
+ * willing to add a welcome message to the chat.
68
+ */
69
+ export const IWelcomeMessage = new Token('jupyterlab-chat:IWelcomeMessage');
package/lib/widget.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ChatWidget, IAttachmentOpenerRegistry, IChatCommandRegistry, IChatModel } from '@jupyter/chat';
1
+ import { ChatWidget, IAttachmentOpenerRegistry, IChatCommandRegistry, IChatModel, IMessageFooterRegistry } from '@jupyter/chat';
2
2
  import { ICollaborativeDrive } from '@jupyter/collaborative-drive';
3
3
  import { IThemeManager } from '@jupyterlab/apputils';
4
4
  import { DocumentWidget } from '@jupyterlab/docregistry';
@@ -91,6 +91,8 @@ export declare class ChatPanel extends SidePanel {
91
91
  private _chatCommandRegistry?;
92
92
  private _attachmentOpenerRegistry?;
93
93
  private _inputToolbarFactory?;
94
+ private _messageFooterRegistry?;
95
+ private _welcomeMessage?;
94
96
  }
95
97
  /**
96
98
  * The chat panel namespace.
@@ -108,6 +110,8 @@ export declare namespace ChatPanel {
108
110
  chatCommandRegistry?: IChatCommandRegistry;
109
111
  attachmentOpenerRegistry?: IAttachmentOpenerRegistry;
110
112
  inputToolbarFactory?: IInputToolbarRegistryFactory;
113
+ messageFooterRegistry?: IMessageFooterRegistry;
114
+ welcomeMessage?: string;
111
115
  }
112
116
  }
113
117
  /**
package/lib/widget.js CHANGED
@@ -108,6 +108,8 @@ export class ChatPanel extends SidePanel {
108
108
  this._chatCommandRegistry = options.chatCommandRegistry;
109
109
  this._attachmentOpenerRegistry = options.attachmentOpenerRegistry;
110
110
  this._inputToolbarFactory = options.inputToolbarFactory;
111
+ this._messageFooterRegistry = options.messageFooterRegistry;
112
+ this._welcomeMessage = options.welcomeMessage;
111
113
  const addChat = new CommandToolbarButton({
112
114
  commands: this._commands,
113
115
  id: CommandIDs.createChat,
@@ -164,7 +166,9 @@ export class ChatPanel extends SidePanel {
164
166
  themeManager: this._themeManager,
165
167
  chatCommandRegistry: this._chatCommandRegistry,
166
168
  attachmentOpenerRegistry: this._attachmentOpenerRegistry,
167
- inputToolbarRegistry
169
+ inputToolbarRegistry,
170
+ messageFooterRegistry: this._messageFooterRegistry,
171
+ welcomeMessage: this._welcomeMessage
168
172
  });
169
173
  this.addWidget(new ChatSection({
170
174
  widget,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jupyterlab-chat",
3
- "version": "0.10.1",
3
+ "version": "0.12.0",
4
4
  "description": "The library to build a chat based on shared document",
5
5
  "keywords": [
6
6
  "jupyter",
@@ -42,7 +42,7 @@
42
42
  "watch:src": "tsc -w --sourceMap"
43
43
  },
44
44
  "dependencies": {
45
- "@jupyter/chat": "^0.10.1",
45
+ "@jupyter/chat": "^0.12.0",
46
46
  "@jupyter/collaborative-drive": "^3.0.0",
47
47
  "@jupyter/ydoc": "^2.0.0 || ^3.0.0",
48
48
  "@jupyterlab/application": "^4.2.0",
package/src/factory.ts CHANGED
@@ -9,6 +9,7 @@ import {
9
9
  IAttachmentOpenerRegistry,
10
10
  IChatCommandRegistry,
11
11
  IInputToolbarRegistry,
12
+ IMessageFooterRegistry,
12
13
  ISelectionWatcher
13
14
  } from '@jupyter/chat';
14
15
  import { IThemeManager } from '@jupyterlab/apputils';
@@ -84,6 +85,8 @@ export class ChatWidgetFactory extends ABCWidgetFactory<
84
85
  this._chatCommandRegistry = options.chatCommandRegistry;
85
86
  this._attachmentOpenerRegistry = options.attachmentOpenerRegistry;
86
87
  this._inputToolbarFactory = options.inputToolbarFactory;
88
+ this._messageFooterRegistry = options.messageFooterRegistry;
89
+ this._welcomeMessage = options.welcomeMessage;
87
90
  }
88
91
 
89
92
  /**
@@ -97,6 +100,8 @@ export class ChatWidgetFactory extends ABCWidgetFactory<
97
100
  context.themeManager = this._themeManager;
98
101
  context.chatCommandRegistry = this._chatCommandRegistry;
99
102
  context.attachmentOpenerRegistry = this._attachmentOpenerRegistry;
103
+ context.messageFooterRegistry = this._messageFooterRegistry;
104
+ context.welcomeMessage = this._welcomeMessage;
100
105
  if (this._inputToolbarFactory) {
101
106
  context.inputToolbarRegistry = this._inputToolbarFactory.create();
102
107
  }
@@ -111,6 +116,8 @@ export class ChatWidgetFactory extends ABCWidgetFactory<
111
116
  private _chatCommandRegistry?: IChatCommandRegistry;
112
117
  private _attachmentOpenerRegistry?: IAttachmentOpenerRegistry;
113
118
  private _inputToolbarFactory?: IInputToolbarRegistryFactory;
119
+ private _messageFooterRegistry?: IMessageFooterRegistry;
120
+ private _welcomeMessage?: string;
114
121
  }
115
122
 
116
123
  export namespace ChatWidgetFactory {
@@ -121,6 +128,8 @@ export namespace ChatWidgetFactory {
121
128
  chatCommandRegistry?: IChatCommandRegistry;
122
129
  attachmentOpenerRegistry?: IAttachmentOpenerRegistry;
123
130
  inputToolbarRegistry?: IInputToolbarRegistry;
131
+ messageFooterRegistry?: IMessageFooterRegistry;
132
+ welcomeMessage?: string;
124
133
  }
125
134
 
126
135
  export interface IOptions<T extends LabChatPanel>
@@ -130,6 +139,8 @@ export namespace ChatWidgetFactory {
130
139
  chatCommandRegistry?: IChatCommandRegistry;
131
140
  attachmentOpenerRegistry?: IAttachmentOpenerRegistry;
132
141
  inputToolbarFactory?: IInputToolbarRegistryFactory;
142
+ messageFooterRegistry?: IMessageFooterRegistry;
143
+ welcomeMessage?: string;
133
144
  }
134
145
  }
135
146
 
package/src/model.ts CHANGED
@@ -67,7 +67,8 @@ export class LabChatModel
67
67
 
68
68
  this.sharedModel.awareness.on('change', this.onAwarenessChange);
69
69
 
70
- this.input.valueChanged.connect(this.onInputChanged);
70
+ this.input.valueChanged.connect((_, value) => this.onInputChanged(value));
71
+ this.messageEditionAdded.connect(this.onMessageEditionAdded);
71
72
  }
72
73
 
73
74
  readonly collaborative = true;
@@ -259,9 +260,12 @@ export class LabChatModel
259
260
  }
260
261
 
261
262
  /**
262
- * Function called by the input on key pressed.
263
+ * Function called when the input content changed.
264
+ *
265
+ * @param value - The whole input content.
266
+ * @param messageID - The ID of the message being edited, if any.
263
267
  */
264
- onInputChanged = (_: IInputModel, value: string): void => {
268
+ onInputChanged = (value: string, messageID?: string): void => {
265
269
  if (!value || !this.config.sendTypingNotification) {
266
270
  return;
267
271
  }
@@ -269,26 +273,46 @@ export class LabChatModel
269
273
  if (this._timeoutWriting !== null) {
270
274
  window.clearTimeout(this._timeoutWriting);
271
275
  }
272
- awareness.setLocalStateField('isWriting', true);
276
+ awareness.setLocalStateField('isWriting', messageID ?? true);
273
277
  this._timeoutWriting = window.setTimeout(() => {
274
278
  this._resetWritingStatus();
275
279
  }, WRITING_DELAY);
276
280
  };
277
281
 
282
+ /**
283
+ * Listen to the message edition input.
284
+ */
285
+ onMessageEditionAdded = (
286
+ _: IChatModel,
287
+ edition: IChatModel.IMessageEdition
288
+ ) => {
289
+ if (edition !== null) {
290
+ const _onInputChanged = (_: IInputModel, value: string) => {
291
+ this.onInputChanged(value, edition.id);
292
+ };
293
+
294
+ edition.model.valueChanged.connect(_onInputChanged);
295
+ }
296
+ };
297
+
278
298
  /**
279
299
  * Triggered when an awareness state changes.
280
300
  * Used to populate the writers list.
281
301
  */
282
302
  onAwarenessChange = () => {
283
- const writers: IUser[] = [];
303
+ const writers: IChatModel.IWriter[] = [];
284
304
  const states = this.sharedModel.awareness.getStates();
285
305
  for (const stateID of states.keys()) {
286
306
  const state = states.get(stateID);
287
307
  if (!state || !state.user || state.user.username === this.user.username) {
288
308
  continue;
289
309
  }
290
- if (state.isWriting) {
291
- writers.push(state.user);
310
+ if (state.isWriting !== undefined && state.isWriting !== false) {
311
+ const writer: IChatModel.IWriter = {
312
+ user: state.user,
313
+ messageID: state.isWriting === true ? undefined : state.isWriting
314
+ };
315
+ writers.push(writer);
292
316
  }
293
317
  }
294
318
  this.updateWriters(writers);
package/src/token.ts CHANGED
@@ -144,3 +144,12 @@ export const IInputToolbarRegistryFactory =
144
144
  new Token<IInputToolbarRegistryFactory>(
145
145
  'jupyterlab-chat:IInputToolbarRegistryFactory'
146
146
  );
147
+
148
+ /**
149
+ * The token to add a welcome message to the chat.
150
+ * This token is not provided by default, but can be provided by third party extensions
151
+ * willing to add a welcome message to the chat.
152
+ */
153
+ export const IWelcomeMessage = new Token<string>(
154
+ 'jupyterlab-chat:IWelcomeMessage'
155
+ );
package/src/widget.tsx CHANGED
@@ -9,6 +9,7 @@ import {
9
9
  IChatCommandRegistry,
10
10
  IChatModel,
11
11
  IInputToolbarRegistry,
12
+ IMessageFooterRegistry,
12
13
  readIcon
13
14
  } from '@jupyter/chat';
14
15
  import { ICollaborativeDrive } from '@jupyter/collaborative-drive';
@@ -111,6 +112,8 @@ export class ChatPanel extends SidePanel {
111
112
  this._chatCommandRegistry = options.chatCommandRegistry;
112
113
  this._attachmentOpenerRegistry = options.attachmentOpenerRegistry;
113
114
  this._inputToolbarFactory = options.inputToolbarFactory;
115
+ this._messageFooterRegistry = options.messageFooterRegistry;
116
+ this._welcomeMessage = options.welcomeMessage;
114
117
 
115
118
  const addChat = new CommandToolbarButton({
116
119
  commands: this._commands,
@@ -180,7 +183,9 @@ export class ChatPanel extends SidePanel {
180
183
  themeManager: this._themeManager,
181
184
  chatCommandRegistry: this._chatCommandRegistry,
182
185
  attachmentOpenerRegistry: this._attachmentOpenerRegistry,
183
- inputToolbarRegistry
186
+ inputToolbarRegistry,
187
+ messageFooterRegistry: this._messageFooterRegistry,
188
+ welcomeMessage: this._welcomeMessage
184
189
  });
185
190
 
186
191
  this.addWidget(
@@ -302,6 +307,8 @@ export class ChatPanel extends SidePanel {
302
307
  private _chatCommandRegistry?: IChatCommandRegistry;
303
308
  private _attachmentOpenerRegistry?: IAttachmentOpenerRegistry;
304
309
  private _inputToolbarFactory?: IInputToolbarRegistryFactory;
310
+ private _messageFooterRegistry?: IMessageFooterRegistry;
311
+ private _welcomeMessage?: string;
305
312
  }
306
313
 
307
314
  /**
@@ -320,6 +327,8 @@ export namespace ChatPanel {
320
327
  chatCommandRegistry?: IChatCommandRegistry;
321
328
  attachmentOpenerRegistry?: IAttachmentOpenerRegistry;
322
329
  inputToolbarFactory?: IInputToolbarRegistryFactory;
330
+ messageFooterRegistry?: IMessageFooterRegistry;
331
+ welcomeMessage?: string;
323
332
  }
324
333
  }
325
334