jupyterlab-chat 0.11.0 → 0.13.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 +10 -0
- package/lib/factory.js +12 -0
- package/lib/model.d.ts +10 -3
- package/lib/model.js +25 -6
- package/lib/token.d.ts +6 -0
- package/lib/token.js +6 -0
- package/lib/widget.d.ts +5 -3
- package/lib/widget.js +6 -4
- package/package.json +3 -3
- package/src/factory.ts +15 -0
- package/src/model.ts +31 -7
- package/src/token.ts +9 -0
- package/src/widget.tsx +11 -7
package/lib/factory.d.ts
CHANGED
|
@@ -48,12 +48,20 @@ export declare class ChatWidgetFactory extends ABCWidgetFactory<LabChatPanel, La
|
|
|
48
48
|
* @returns The widget
|
|
49
49
|
*/
|
|
50
50
|
protected createNewWidget(context: ChatWidgetFactory.IContext): LabChatPanel;
|
|
51
|
+
/**
|
|
52
|
+
* IMPORTANT: this property must be defined to use the `RtcContentProvider`
|
|
53
|
+
* registered by `jupyter_collaboration`. Without this, the chat document
|
|
54
|
+
* widgets will not connect.
|
|
55
|
+
*/
|
|
56
|
+
get contentProviderId(): string;
|
|
57
|
+
set contentProviderId(_value: string | undefined);
|
|
51
58
|
private _themeManager;
|
|
52
59
|
private _rmRegistry;
|
|
53
60
|
private _chatCommandRegistry?;
|
|
54
61
|
private _attachmentOpenerRegistry?;
|
|
55
62
|
private _inputToolbarFactory?;
|
|
56
63
|
private _messageFooterRegistry?;
|
|
64
|
+
private _welcomeMessage?;
|
|
57
65
|
}
|
|
58
66
|
export declare namespace ChatWidgetFactory {
|
|
59
67
|
interface IContext extends DocumentRegistry.IContext<LabChatModel> {
|
|
@@ -64,6 +72,7 @@ export declare namespace ChatWidgetFactory {
|
|
|
64
72
|
attachmentOpenerRegistry?: IAttachmentOpenerRegistry;
|
|
65
73
|
inputToolbarRegistry?: IInputToolbarRegistry;
|
|
66
74
|
messageFooterRegistry?: IMessageFooterRegistry;
|
|
75
|
+
welcomeMessage?: string;
|
|
67
76
|
}
|
|
68
77
|
interface IOptions<T extends LabChatPanel> extends DocumentRegistry.IWidgetFactoryOptions<T> {
|
|
69
78
|
themeManager: IThemeManager | null;
|
|
@@ -72,6 +81,7 @@ export declare namespace ChatWidgetFactory {
|
|
|
72
81
|
attachmentOpenerRegistry?: IAttachmentOpenerRegistry;
|
|
73
82
|
inputToolbarFactory?: IInputToolbarRegistryFactory;
|
|
74
83
|
messageFooterRegistry?: IMessageFooterRegistry;
|
|
84
|
+
welcomeMessage?: string;
|
|
75
85
|
}
|
|
76
86
|
}
|
|
77
87
|
export declare class LabChatModelFactory implements DocumentRegistry.IModelFactory<LabChatModel> {
|
package/lib/factory.js
CHANGED
|
@@ -54,6 +54,7 @@ export class ChatWidgetFactory extends ABCWidgetFactory {
|
|
|
54
54
|
this._attachmentOpenerRegistry = options.attachmentOpenerRegistry;
|
|
55
55
|
this._inputToolbarFactory = options.inputToolbarFactory;
|
|
56
56
|
this._messageFooterRegistry = options.messageFooterRegistry;
|
|
57
|
+
this._welcomeMessage = options.welcomeMessage;
|
|
57
58
|
}
|
|
58
59
|
/**
|
|
59
60
|
* Create a new widget given a context.
|
|
@@ -67,6 +68,7 @@ export class ChatWidgetFactory extends ABCWidgetFactory {
|
|
|
67
68
|
context.chatCommandRegistry = this._chatCommandRegistry;
|
|
68
69
|
context.attachmentOpenerRegistry = this._attachmentOpenerRegistry;
|
|
69
70
|
context.messageFooterRegistry = this._messageFooterRegistry;
|
|
71
|
+
context.welcomeMessage = this._welcomeMessage;
|
|
70
72
|
if (this._inputToolbarFactory) {
|
|
71
73
|
context.inputToolbarRegistry = this._inputToolbarFactory.create();
|
|
72
74
|
}
|
|
@@ -75,6 +77,16 @@ export class ChatWidgetFactory extends ABCWidgetFactory {
|
|
|
75
77
|
content: new ChatWidget(context)
|
|
76
78
|
});
|
|
77
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* IMPORTANT: this property must be defined to use the `RtcContentProvider`
|
|
82
|
+
* registered by `jupyter_collaboration`. Without this, the chat document
|
|
83
|
+
* widgets will not connect.
|
|
84
|
+
*/
|
|
85
|
+
get contentProviderId() {
|
|
86
|
+
return 'rtc';
|
|
87
|
+
}
|
|
88
|
+
// Must override both getter and setter from ABCFactory for type compatibility.
|
|
89
|
+
set contentProviderId(_value) { }
|
|
78
90
|
}
|
|
79
91
|
export class LabChatModelFactory {
|
|
80
92
|
constructor(options) {
|
package/lib/model.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AbstractChatModel, AbstractChatContext, IChatContext, IChatMessage, IChatModel,
|
|
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
|
|
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: (
|
|
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
|
|
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 = (
|
|
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
|
-
|
|
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,5 +1,5 @@
|
|
|
1
1
|
import { ChatWidget, IAttachmentOpenerRegistry, IChatCommandRegistry, IChatModel, IMessageFooterRegistry } from '@jupyter/chat';
|
|
2
|
-
import {
|
|
2
|
+
import { Contents } from '@jupyterlab/services';
|
|
3
3
|
import { IThemeManager } from '@jupyterlab/apputils';
|
|
4
4
|
import { DocumentWidget } from '@jupyterlab/docregistry';
|
|
5
5
|
import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
|
|
@@ -84,7 +84,7 @@ export declare class ChatPanel extends SidePanel {
|
|
|
84
84
|
private _chatNamesChanged;
|
|
85
85
|
private _commands;
|
|
86
86
|
private _defaultDirectory;
|
|
87
|
-
private
|
|
87
|
+
private _contentsManager;
|
|
88
88
|
private _openChat;
|
|
89
89
|
private _rmRegistry;
|
|
90
90
|
private _themeManager;
|
|
@@ -92,6 +92,7 @@ export declare class ChatPanel extends SidePanel {
|
|
|
92
92
|
private _attachmentOpenerRegistry?;
|
|
93
93
|
private _inputToolbarFactory?;
|
|
94
94
|
private _messageFooterRegistry?;
|
|
95
|
+
private _welcomeMessage?;
|
|
95
96
|
}
|
|
96
97
|
/**
|
|
97
98
|
* The chat panel namespace.
|
|
@@ -102,7 +103,7 @@ export declare namespace ChatPanel {
|
|
|
102
103
|
*/
|
|
103
104
|
interface IOptions extends SidePanel.IOptions {
|
|
104
105
|
commands: CommandRegistry;
|
|
105
|
-
|
|
106
|
+
contentsManager: Contents.IManager;
|
|
106
107
|
rmRegistry: IRenderMimeRegistry;
|
|
107
108
|
themeManager: IThemeManager | null;
|
|
108
109
|
defaultDirectory: string;
|
|
@@ -110,6 +111,7 @@ export declare namespace ChatPanel {
|
|
|
110
111
|
attachmentOpenerRegistry?: IAttachmentOpenerRegistry;
|
|
111
112
|
inputToolbarFactory?: IInputToolbarRegistryFactory;
|
|
112
113
|
messageFooterRegistry?: IMessageFooterRegistry;
|
|
114
|
+
welcomeMessage?: string;
|
|
113
115
|
}
|
|
114
116
|
}
|
|
115
117
|
/**
|
package/lib/widget.js
CHANGED
|
@@ -69,9 +69,9 @@ export class ChatPanel extends SidePanel {
|
|
|
69
69
|
*/
|
|
70
70
|
this.updateChatList = async () => {
|
|
71
71
|
const extension = chatFileType.extensions[0];
|
|
72
|
-
this.
|
|
72
|
+
this._contentsManager
|
|
73
73
|
.get(this._defaultDirectory)
|
|
74
|
-
.then(contentModel => {
|
|
74
|
+
.then((contentModel) => {
|
|
75
75
|
const chatsNames = {};
|
|
76
76
|
contentModel.content
|
|
77
77
|
.filter(f => f.type === 'file' && f.name.endsWith(extension))
|
|
@@ -101,7 +101,7 @@ export class ChatPanel extends SidePanel {
|
|
|
101
101
|
this._chatNamesChanged = new Signal(this);
|
|
102
102
|
this.addClass(SIDEPANEL_CLASS);
|
|
103
103
|
this._commands = options.commands;
|
|
104
|
-
this.
|
|
104
|
+
this._contentsManager = options.contentsManager;
|
|
105
105
|
this._rmRegistry = options.rmRegistry;
|
|
106
106
|
this._themeManager = options.themeManager;
|
|
107
107
|
this._defaultDirectory = options.defaultDirectory;
|
|
@@ -109,6 +109,7 @@ export class ChatPanel extends SidePanel {
|
|
|
109
109
|
this._attachmentOpenerRegistry = options.attachmentOpenerRegistry;
|
|
110
110
|
this._inputToolbarFactory = options.inputToolbarFactory;
|
|
111
111
|
this._messageFooterRegistry = options.messageFooterRegistry;
|
|
112
|
+
this._welcomeMessage = options.welcomeMessage;
|
|
112
113
|
const addChat = new CommandToolbarButton({
|
|
113
114
|
commands: this._commands,
|
|
114
115
|
id: CommandIDs.createChat,
|
|
@@ -166,7 +167,8 @@ export class ChatPanel extends SidePanel {
|
|
|
166
167
|
chatCommandRegistry: this._chatCommandRegistry,
|
|
167
168
|
attachmentOpenerRegistry: this._attachmentOpenerRegistry,
|
|
168
169
|
inputToolbarRegistry,
|
|
169
|
-
messageFooterRegistry: this._messageFooterRegistry
|
|
170
|
+
messageFooterRegistry: this._messageFooterRegistry,
|
|
171
|
+
welcomeMessage: this._welcomeMessage
|
|
170
172
|
});
|
|
171
173
|
this.addWidget(new ChatSection({
|
|
172
174
|
widget,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jupyterlab-chat",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "The library to build a chat based on shared document",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jupyter",
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"watch:src": "tsc -w --sourceMap"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@jupyter/chat": "^0.
|
|
46
|
-
"@jupyter/collaborative-drive": "^
|
|
45
|
+
"@jupyter/chat": "^0.13.0",
|
|
46
|
+
"@jupyter/collaborative-drive": "^4.0.2",
|
|
47
47
|
"@jupyter/ydoc": "^2.0.0 || ^3.0.0",
|
|
48
48
|
"@jupyterlab/application": "^4.2.0",
|
|
49
49
|
"@jupyterlab/apputils": "^4.3.0",
|
package/src/factory.ts
CHANGED
|
@@ -86,6 +86,7 @@ export class ChatWidgetFactory extends ABCWidgetFactory<
|
|
|
86
86
|
this._attachmentOpenerRegistry = options.attachmentOpenerRegistry;
|
|
87
87
|
this._inputToolbarFactory = options.inputToolbarFactory;
|
|
88
88
|
this._messageFooterRegistry = options.messageFooterRegistry;
|
|
89
|
+
this._welcomeMessage = options.welcomeMessage;
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
/**
|
|
@@ -100,6 +101,7 @@ export class ChatWidgetFactory extends ABCWidgetFactory<
|
|
|
100
101
|
context.chatCommandRegistry = this._chatCommandRegistry;
|
|
101
102
|
context.attachmentOpenerRegistry = this._attachmentOpenerRegistry;
|
|
102
103
|
context.messageFooterRegistry = this._messageFooterRegistry;
|
|
104
|
+
context.welcomeMessage = this._welcomeMessage;
|
|
103
105
|
if (this._inputToolbarFactory) {
|
|
104
106
|
context.inputToolbarRegistry = this._inputToolbarFactory.create();
|
|
105
107
|
}
|
|
@@ -109,12 +111,23 @@ export class ChatWidgetFactory extends ABCWidgetFactory<
|
|
|
109
111
|
});
|
|
110
112
|
}
|
|
111
113
|
|
|
114
|
+
/**
|
|
115
|
+
* IMPORTANT: this property must be defined to use the `RtcContentProvider`
|
|
116
|
+
* registered by `jupyter_collaboration`. Without this, the chat document
|
|
117
|
+
* widgets will not connect.
|
|
118
|
+
*/
|
|
119
|
+
get contentProviderId(): string {
|
|
120
|
+
return 'rtc';
|
|
121
|
+
}
|
|
122
|
+
// Must override both getter and setter from ABCFactory for type compatibility.
|
|
123
|
+
set contentProviderId(_value: string | undefined) {}
|
|
112
124
|
private _themeManager: IThemeManager | null;
|
|
113
125
|
private _rmRegistry: IRenderMimeRegistry;
|
|
114
126
|
private _chatCommandRegistry?: IChatCommandRegistry;
|
|
115
127
|
private _attachmentOpenerRegistry?: IAttachmentOpenerRegistry;
|
|
116
128
|
private _inputToolbarFactory?: IInputToolbarRegistryFactory;
|
|
117
129
|
private _messageFooterRegistry?: IMessageFooterRegistry;
|
|
130
|
+
private _welcomeMessage?: string;
|
|
118
131
|
}
|
|
119
132
|
|
|
120
133
|
export namespace ChatWidgetFactory {
|
|
@@ -126,6 +139,7 @@ export namespace ChatWidgetFactory {
|
|
|
126
139
|
attachmentOpenerRegistry?: IAttachmentOpenerRegistry;
|
|
127
140
|
inputToolbarRegistry?: IInputToolbarRegistry;
|
|
128
141
|
messageFooterRegistry?: IMessageFooterRegistry;
|
|
142
|
+
welcomeMessage?: string;
|
|
129
143
|
}
|
|
130
144
|
|
|
131
145
|
export interface IOptions<T extends LabChatPanel>
|
|
@@ -136,6 +150,7 @@ export namespace ChatWidgetFactory {
|
|
|
136
150
|
attachmentOpenerRegistry?: IAttachmentOpenerRegistry;
|
|
137
151
|
inputToolbarFactory?: IInputToolbarRegistryFactory;
|
|
138
152
|
messageFooterRegistry?: IMessageFooterRegistry;
|
|
153
|
+
welcomeMessage?: string;
|
|
139
154
|
}
|
|
140
155
|
}
|
|
141
156
|
|
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
|
|
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 = (
|
|
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:
|
|
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
|
-
|
|
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
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
IMessageFooterRegistry,
|
|
13
13
|
readIcon
|
|
14
14
|
} from '@jupyter/chat';
|
|
15
|
-
import {
|
|
15
|
+
import { Contents } from '@jupyterlab/services';
|
|
16
16
|
import { IThemeManager } from '@jupyterlab/apputils';
|
|
17
17
|
import { PathExt } from '@jupyterlab/coreutils';
|
|
18
18
|
import { DocumentWidget } from '@jupyterlab/docregistry';
|
|
@@ -105,7 +105,7 @@ export class ChatPanel extends SidePanel {
|
|
|
105
105
|
super(options);
|
|
106
106
|
this.addClass(SIDEPANEL_CLASS);
|
|
107
107
|
this._commands = options.commands;
|
|
108
|
-
this.
|
|
108
|
+
this._contentsManager = options.contentsManager;
|
|
109
109
|
this._rmRegistry = options.rmRegistry;
|
|
110
110
|
this._themeManager = options.themeManager;
|
|
111
111
|
this._defaultDirectory = options.defaultDirectory;
|
|
@@ -113,6 +113,7 @@ export class ChatPanel extends SidePanel {
|
|
|
113
113
|
this._attachmentOpenerRegistry = options.attachmentOpenerRegistry;
|
|
114
114
|
this._inputToolbarFactory = options.inputToolbarFactory;
|
|
115
115
|
this._messageFooterRegistry = options.messageFooterRegistry;
|
|
116
|
+
this._welcomeMessage = options.welcomeMessage;
|
|
116
117
|
|
|
117
118
|
const addChat = new CommandToolbarButton({
|
|
118
119
|
commands: this._commands,
|
|
@@ -183,7 +184,8 @@ export class ChatPanel extends SidePanel {
|
|
|
183
184
|
chatCommandRegistry: this._chatCommandRegistry,
|
|
184
185
|
attachmentOpenerRegistry: this._attachmentOpenerRegistry,
|
|
185
186
|
inputToolbarRegistry,
|
|
186
|
-
messageFooterRegistry: this._messageFooterRegistry
|
|
187
|
+
messageFooterRegistry: this._messageFooterRegistry,
|
|
188
|
+
welcomeMessage: this._welcomeMessage
|
|
187
189
|
});
|
|
188
190
|
|
|
189
191
|
this.addWidget(
|
|
@@ -203,9 +205,9 @@ export class ChatPanel extends SidePanel {
|
|
|
203
205
|
*/
|
|
204
206
|
updateChatList = async (): Promise<void> => {
|
|
205
207
|
const extension = chatFileType.extensions[0];
|
|
206
|
-
this.
|
|
208
|
+
this._contentsManager
|
|
207
209
|
.get(this._defaultDirectory)
|
|
208
|
-
.then(contentModel => {
|
|
210
|
+
.then((contentModel: Contents.IModel) => {
|
|
209
211
|
const chatsNames: { [name: string]: string } = {};
|
|
210
212
|
(contentModel.content as any[])
|
|
211
213
|
.filter(f => f.type === 'file' && f.name.endsWith(extension))
|
|
@@ -298,7 +300,7 @@ export class ChatPanel extends SidePanel {
|
|
|
298
300
|
);
|
|
299
301
|
private _commands: CommandRegistry;
|
|
300
302
|
private _defaultDirectory: string;
|
|
301
|
-
private
|
|
303
|
+
private _contentsManager: Contents.IManager;
|
|
302
304
|
private _openChat: ReactWidget;
|
|
303
305
|
private _rmRegistry: IRenderMimeRegistry;
|
|
304
306
|
private _themeManager: IThemeManager | null;
|
|
@@ -306,6 +308,7 @@ export class ChatPanel extends SidePanel {
|
|
|
306
308
|
private _attachmentOpenerRegistry?: IAttachmentOpenerRegistry;
|
|
307
309
|
private _inputToolbarFactory?: IInputToolbarRegistryFactory;
|
|
308
310
|
private _messageFooterRegistry?: IMessageFooterRegistry;
|
|
311
|
+
private _welcomeMessage?: string;
|
|
309
312
|
}
|
|
310
313
|
|
|
311
314
|
/**
|
|
@@ -317,7 +320,7 @@ export namespace ChatPanel {
|
|
|
317
320
|
*/
|
|
318
321
|
export interface IOptions extends SidePanel.IOptions {
|
|
319
322
|
commands: CommandRegistry;
|
|
320
|
-
|
|
323
|
+
contentsManager: Contents.IManager;
|
|
321
324
|
rmRegistry: IRenderMimeRegistry;
|
|
322
325
|
themeManager: IThemeManager | null;
|
|
323
326
|
defaultDirectory: string;
|
|
@@ -325,6 +328,7 @@ export namespace ChatPanel {
|
|
|
325
328
|
attachmentOpenerRegistry?: IAttachmentOpenerRegistry;
|
|
326
329
|
inputToolbarFactory?: IInputToolbarRegistryFactory;
|
|
327
330
|
messageFooterRegistry?: IMessageFooterRegistry;
|
|
331
|
+
welcomeMessage?: string;
|
|
328
332
|
}
|
|
329
333
|
}
|
|
330
334
|
|