jupyterlab-chat 0.15.0 → 0.17.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/model.d.ts +29 -1
- package/lib/widget.d.ts +2 -2
- package/lib/widget.js +19 -2
- package/lib/ychat.d.ts +9 -0
- package/lib/ychat.js +21 -3
- package/package.json +2 -2
- package/src/model.ts +2 -2
- package/src/widget.tsx +20 -2
- package/src/ychat.ts +21 -6
package/lib/model.d.ts
CHANGED
|
@@ -17,6 +17,33 @@ export declare namespace LabChatModel {
|
|
|
17
17
|
languagePreference?: string;
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* A data model class that represents a user and implements the `IUser` interface.
|
|
22
|
+
* Currently, this just just ensures that `user.mention_name` is always
|
|
23
|
+
* accessible by defining it as a getter property.
|
|
24
|
+
*
|
|
25
|
+
* The constructor accepts an `identity: User.IIdentity | IUser | null` object.
|
|
26
|
+
* If `identity == null`, this class provides default values for each required
|
|
27
|
+
* field.
|
|
28
|
+
*
|
|
29
|
+
* TODO: should `identity` (from `LabChatModel.IOptions.user`) ever be `null`?
|
|
30
|
+
*
|
|
31
|
+
* TODO: should this be lifted up into `packages/jupyter-chat`?
|
|
32
|
+
*/
|
|
33
|
+
declare class LabChatUser implements IUser {
|
|
34
|
+
constructor(identity: User.IIdentity | IUser | null);
|
|
35
|
+
get mention_name(): string;
|
|
36
|
+
toJSON(): this & {
|
|
37
|
+
mention_name: string;
|
|
38
|
+
};
|
|
39
|
+
username: string;
|
|
40
|
+
name?: string;
|
|
41
|
+
display_name?: string;
|
|
42
|
+
initials?: string;
|
|
43
|
+
color?: string;
|
|
44
|
+
avatar_url?: string;
|
|
45
|
+
bot?: boolean;
|
|
46
|
+
}
|
|
20
47
|
/**
|
|
21
48
|
* The chat document model.
|
|
22
49
|
*/
|
|
@@ -86,5 +113,6 @@ export declare class LabChatContext extends AbstractChatContext {
|
|
|
86
113
|
/**
|
|
87
114
|
* The list of users who have connected to this chat.
|
|
88
115
|
*/
|
|
89
|
-
get users():
|
|
116
|
+
get users(): LabChatUser[];
|
|
90
117
|
}
|
|
118
|
+
export {};
|
package/lib/widget.d.ts
CHANGED
|
@@ -59,9 +59,9 @@ export declare class ChatPanel extends SidePanel {
|
|
|
59
59
|
*/
|
|
60
60
|
openIfExists(path: string): boolean;
|
|
61
61
|
/**
|
|
62
|
-
* A message handler invoked on an `'after-
|
|
62
|
+
* A message handler invoked on an `'after-attach'` message.
|
|
63
63
|
*/
|
|
64
|
-
protected
|
|
64
|
+
protected onAfterAttach(msg: Message): void;
|
|
65
65
|
/**
|
|
66
66
|
* Return the index of the chat in the list (-1 if not opened).
|
|
67
67
|
*
|
package/lib/widget.js
CHANGED
|
@@ -123,6 +123,23 @@ export class ChatPanel extends SidePanel {
|
|
|
123
123
|
this.toolbar.addItem('openChat', this._openChat);
|
|
124
124
|
const content = this.content;
|
|
125
125
|
content.expansionToggled.connect(this._onExpansionToggled, this);
|
|
126
|
+
this._contentsManager.fileChanged.connect((_, args) => {
|
|
127
|
+
var _a, _b;
|
|
128
|
+
if (args.type === 'delete') {
|
|
129
|
+
this.widgets.forEach(widget => {
|
|
130
|
+
var _a;
|
|
131
|
+
if (widget.path === ((_a = args.oldValue) === null || _a === void 0 ? void 0 : _a.path)) {
|
|
132
|
+
widget.dispose();
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
this.updateChatList();
|
|
136
|
+
}
|
|
137
|
+
const updateActions = ['new', 'rename'];
|
|
138
|
+
if (updateActions.includes(args.type) &&
|
|
139
|
+
((_b = (_a = args.newValue) === null || _a === void 0 ? void 0 : _a.path) === null || _b === void 0 ? void 0 : _b.endsWith(chatFileType.extensions[0]))) {
|
|
140
|
+
this.updateChatList();
|
|
141
|
+
}
|
|
142
|
+
});
|
|
126
143
|
}
|
|
127
144
|
/**
|
|
128
145
|
* Getter and setter of the defaultDirectory.
|
|
@@ -192,9 +209,9 @@ export class ChatPanel extends SidePanel {
|
|
|
192
209
|
return index > -1;
|
|
193
210
|
}
|
|
194
211
|
/**
|
|
195
|
-
* A message handler invoked on an `'after-
|
|
212
|
+
* A message handler invoked on an `'after-attach'` message.
|
|
196
213
|
*/
|
|
197
|
-
|
|
214
|
+
onAfterAttach(msg) {
|
|
198
215
|
var _a;
|
|
199
216
|
// Wait for the component to be rendered.
|
|
200
217
|
(_a = this._openChat.renderPromise) === null || _a === void 0 ? void 0 : _a.then(() => this.updateChatList());
|
package/lib/ychat.d.ts
CHANGED
|
@@ -78,6 +78,15 @@ export declare class YChat extends YDocument<IChatChanges> {
|
|
|
78
78
|
getMessageIndex(id: string): number;
|
|
79
79
|
deleteMessage(index: number): void;
|
|
80
80
|
getAttachment(id: string): IAttachment | undefined;
|
|
81
|
+
/**
|
|
82
|
+
* Adds or modifies an attachment in the chat, and returns the ID of the
|
|
83
|
+
* attachment.
|
|
84
|
+
*
|
|
85
|
+
* NOTE: this method does not add an attachment to any message. It merely adds
|
|
86
|
+
* the attachment data to the chat file and returns an attachment ID. To add
|
|
87
|
+
* an attachment to a new message, consumers should call this method & add the
|
|
88
|
+
* returned ID to `NewMessage.attachments`.
|
|
89
|
+
*/
|
|
81
90
|
setAttachment(attachment: IAttachment): string;
|
|
82
91
|
private _usersObserver;
|
|
83
92
|
private _messagesObserver;
|
package/lib/ychat.js
CHANGED
|
@@ -211,10 +211,28 @@ export class YChat extends YDocument {
|
|
|
211
211
|
getAttachment(id) {
|
|
212
212
|
return this._attachments.get(id);
|
|
213
213
|
}
|
|
214
|
+
/**
|
|
215
|
+
* Adds or modifies an attachment in the chat, and returns the ID of the
|
|
216
|
+
* attachment.
|
|
217
|
+
*
|
|
218
|
+
* NOTE: this method does not add an attachment to any message. It merely adds
|
|
219
|
+
* the attachment data to the chat file and returns an attachment ID. To add
|
|
220
|
+
* an attachment to a new message, consumers should call this method & add the
|
|
221
|
+
* returned ID to `NewMessage.attachments`.
|
|
222
|
+
*/
|
|
214
223
|
setAttachment(attachment) {
|
|
215
|
-
|
|
216
|
-
//
|
|
217
|
-
const
|
|
224
|
+
// Use the existing ID if the attachment already exists, otherwise create a
|
|
225
|
+
// new ID
|
|
226
|
+
const attachmentJson = JSON.stringify(attachment);
|
|
227
|
+
let existingId;
|
|
228
|
+
for (const [id, att] of this._attachments.entries()) {
|
|
229
|
+
if (JSON.stringify(att) === attachmentJson) {
|
|
230
|
+
existingId = id;
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
const id = existingId || UUID.uuid4();
|
|
235
|
+
// Set the attachment using the computed ID, then return the ID
|
|
218
236
|
this.transact(() => {
|
|
219
237
|
this._attachments.set(id, attachment);
|
|
220
238
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jupyterlab-chat",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.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.
|
|
45
|
+
"@jupyter/chat": "^0.17.0",
|
|
46
46
|
"@jupyter/collaborative-drive": "^4.0.2",
|
|
47
47
|
"@jupyter/ydoc": "^2.0.0 || ^3.0.0",
|
|
48
48
|
"@jupyterlab/application": "^4.2.0",
|
package/src/model.ts
CHANGED
|
@@ -509,9 +509,9 @@ export class LabChatContext extends AbstractChatContext {
|
|
|
509
509
|
/**
|
|
510
510
|
* The list of users who have connected to this chat.
|
|
511
511
|
*/
|
|
512
|
-
get users():
|
|
512
|
+
get users(): LabChatUser[] {
|
|
513
513
|
const model = this._model as LabChatModel;
|
|
514
|
-
const users: Record<string,
|
|
514
|
+
const users: Record<string, LabChatUser> = {};
|
|
515
515
|
|
|
516
516
|
// Add existing users from the YChat
|
|
517
517
|
// This only includes users who have sent a message in the chat.
|
package/src/widget.tsx
CHANGED
|
@@ -137,6 +137,24 @@ export class ChatPanel extends SidePanel {
|
|
|
137
137
|
|
|
138
138
|
const content = this.content as AccordionPanel;
|
|
139
139
|
content.expansionToggled.connect(this._onExpansionToggled, this);
|
|
140
|
+
|
|
141
|
+
this._contentsManager.fileChanged.connect((_, args) => {
|
|
142
|
+
if (args.type === 'delete') {
|
|
143
|
+
this.widgets.forEach(widget => {
|
|
144
|
+
if ((widget as ChatSection).path === args.oldValue?.path) {
|
|
145
|
+
widget.dispose();
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
this.updateChatList();
|
|
149
|
+
}
|
|
150
|
+
const updateActions = ['new', 'rename'];
|
|
151
|
+
if (
|
|
152
|
+
updateActions.includes(args.type) &&
|
|
153
|
+
args.newValue?.path?.endsWith(chatFileType.extensions[0])
|
|
154
|
+
) {
|
|
155
|
+
this.updateChatList();
|
|
156
|
+
}
|
|
157
|
+
});
|
|
140
158
|
}
|
|
141
159
|
|
|
142
160
|
/**
|
|
@@ -236,9 +254,9 @@ export class ChatPanel extends SidePanel {
|
|
|
236
254
|
}
|
|
237
255
|
|
|
238
256
|
/**
|
|
239
|
-
* A message handler invoked on an `'after-
|
|
257
|
+
* A message handler invoked on an `'after-attach'` message.
|
|
240
258
|
*/
|
|
241
|
-
protected
|
|
259
|
+
protected onAfterAttach(msg: Message): void {
|
|
242
260
|
// Wait for the component to be rendered.
|
|
243
261
|
this._openChat.renderPromise?.then(() => this.updateChatList());
|
|
244
262
|
}
|
package/src/ychat.ts
CHANGED
|
@@ -197,14 +197,29 @@ export class YChat extends YDocument<IChatChanges> {
|
|
|
197
197
|
return this._attachments.get(id);
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
+
/**
|
|
201
|
+
* Adds or modifies an attachment in the chat, and returns the ID of the
|
|
202
|
+
* attachment.
|
|
203
|
+
*
|
|
204
|
+
* NOTE: this method does not add an attachment to any message. It merely adds
|
|
205
|
+
* the attachment data to the chat file and returns an attachment ID. To add
|
|
206
|
+
* an attachment to a new message, consumers should call this method & add the
|
|
207
|
+
* returned ID to `NewMessage.attachments`.
|
|
208
|
+
*/
|
|
200
209
|
setAttachment(attachment: IAttachment): string {
|
|
201
|
-
//
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
210
|
+
// Use the existing ID if the attachment already exists, otherwise create a
|
|
211
|
+
// new ID
|
|
212
|
+
const attachmentJson = JSON.stringify(attachment);
|
|
213
|
+
let existingId: string | undefined;
|
|
214
|
+
for (const [id, att] of this._attachments.entries()) {
|
|
215
|
+
if (JSON.stringify(att) === attachmentJson) {
|
|
216
|
+
existingId = id;
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
const id = existingId || UUID.uuid4();
|
|
207
221
|
|
|
222
|
+
// Set the attachment using the computed ID, then return the ID
|
|
208
223
|
this.transact(() => {
|
|
209
224
|
this._attachments.set(id, attachment);
|
|
210
225
|
});
|