@jupyter/chat 0.9.0 → 0.10.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.
@@ -0,0 +1,9 @@
1
+ import { AbstractChatContext, AbstractChatModel, IChatModel, IChatContext } from '../model';
2
+ import { INewMessage } from '../types';
3
+ export declare class MockChatContext extends AbstractChatContext implements IChatContext {
4
+ get users(): never[];
5
+ }
6
+ export declare class MockChatModel extends AbstractChatModel implements IChatModel {
7
+ sendMessage(message: INewMessage): Promise<boolean | void> | boolean | void;
8
+ createChatContext(): IChatContext;
9
+ }
@@ -0,0 +1,18 @@
1
+ /*
2
+ * Copyright (c) Jupyter Development Team.
3
+ * Distributed under the terms of the Modified BSD License.
4
+ */
5
+ import { AbstractChatContext, AbstractChatModel } from '../model';
6
+ export class MockChatContext extends AbstractChatContext {
7
+ get users() {
8
+ return [];
9
+ }
10
+ }
11
+ export class MockChatModel extends AbstractChatModel {
12
+ sendMessage(message) {
13
+ // No-op
14
+ }
15
+ createChatContext() {
16
+ return new MockChatContext({ model: this });
17
+ }
18
+ }
@@ -5,25 +5,32 @@
5
5
  /**
6
6
  * Example of [Jest](https://jestjs.io/docs/getting-started) unit tests
7
7
  */
8
- import { ChatModel } from '../model';
8
+ import { AbstractChatModel } from '../model';
9
+ import { MockChatModel, MockChatContext } from './mocks';
9
10
  describe('test chat model', () => {
10
11
  describe('model instantiation', () => {
11
- it('should create a ChatModel', () => {
12
- const model = new ChatModel();
13
- expect(model).toBeInstanceOf(ChatModel);
12
+ it('should create an AbstractChatModel', () => {
13
+ const model = new MockChatModel();
14
+ expect(model).toBeInstanceOf(AbstractChatModel);
14
15
  });
15
- it('should dispose a ChatModel', () => {
16
- const model = new ChatModel();
16
+ it('should dispose an AbstractChatModel', () => {
17
+ const model = new MockChatModel();
17
18
  model.dispose();
18
19
  expect(model.isDisposed).toBeTruthy();
19
20
  });
20
21
  });
21
22
  describe('incoming message', () => {
22
- class TestChat extends ChatModel {
23
+ class TestChat extends AbstractChatModel {
23
24
  formatChatMessage(message) {
24
25
  message.body = 'formatted msg';
25
26
  return message;
26
27
  }
28
+ sendMessage(message) {
29
+ // No-op
30
+ }
31
+ createChatContext() {
32
+ return new MockChatContext({ model: this });
33
+ }
27
34
  }
28
35
  let model;
29
36
  let messages;
@@ -38,7 +45,7 @@ describe('test chat model', () => {
38
45
  messages = [];
39
46
  });
40
47
  it('should signal incoming message', () => {
41
- model = new ChatModel();
48
+ model = new MockChatModel();
42
49
  model.messagesUpdated.connect((sender) => {
43
50
  expect(sender).toBe(model);
44
51
  messages = model.messages;
@@ -61,11 +68,11 @@ describe('test chat model', () => {
61
68
  });
62
69
  describe('model config', () => {
63
70
  it('should have empty config', () => {
64
- const model = new ChatModel();
71
+ const model = new MockChatModel();
65
72
  expect(model.config.sendWithShiftEnter).toBeUndefined();
66
73
  });
67
74
  it('should allow config', () => {
68
- const model = new ChatModel({ config: { sendWithShiftEnter: true } });
75
+ const model = new MockChatModel({ config: { sendWithShiftEnter: true } });
69
76
  expect(model.config.sendWithShiftEnter).toBeTruthy();
70
77
  });
71
78
  });
@@ -6,21 +6,21 @@
6
6
  * Example of [Jest](https://jestjs.io/docs/getting-started) unit tests
7
7
  */
8
8
  import { RenderMimeRegistry } from '@jupyterlab/rendermime';
9
- import { ChatModel } from '../model';
10
9
  import { ChatWidget } from '../widgets/chat-widget';
10
+ import { MockChatModel } from './mocks';
11
11
  describe('test chat widget', () => {
12
12
  let model;
13
13
  let rmRegistry;
14
14
  beforeEach(() => {
15
- model = new ChatModel();
15
+ model = new MockChatModel();
16
16
  rmRegistry = new RenderMimeRegistry();
17
17
  });
18
18
  describe('model instantiation', () => {
19
- it('should create a ChatModel', () => {
19
+ it('should create an AbstractChatModel', () => {
20
20
  const widget = new ChatWidget({ model, rmRegistry });
21
21
  expect(widget).toBeInstanceOf(ChatWidget);
22
22
  });
23
- it('should dispose a ChatModel', () => {
23
+ it('should dispose an AbstractChatModel', () => {
24
24
  const widget = new ChatWidget({ model, rmRegistry });
25
25
  widget.dispose();
26
26
  expect(widget.isDisposed).toBeTruthy();
@@ -1,3 +1,4 @@
1
+ /// <reference types="react" />
1
2
  import { LabIcon } from '@jupyterlab/ui-components';
2
3
  import { IInputModel } from '../input-model';
3
4
  export type ChatCommand = {
@@ -14,7 +15,7 @@ export type ChatCommand = {
14
15
  * If set, this will be rendered as the icon for the command in the chat
15
16
  * commands menu. Jupyter Chat will choose a default if this is unset.
16
17
  */
17
- icon?: LabIcon | string;
18
+ icon?: LabIcon | JSX.Element | string | null;
18
19
  /**
19
20
  * If set, this will be rendered as the description for the command in the
20
21
  * chat commands menu. Jupyter Chat will choose a default if this is unset.
@@ -13,7 +13,7 @@ export declare namespace ChatInput {
13
13
  */
14
14
  interface IProps {
15
15
  /**
16
- * The chat model.
16
+ * The input model.
17
17
  */
18
18
  model: IInputModel;
19
19
  /**
@@ -13,6 +13,7 @@ import { ChatInput } from './chat-input';
13
13
  import { MarkdownRenderer } from './markdown-renderer';
14
14
  import { ScrollContainer } from './scroll-container';
15
15
  import { InputModel } from '../input-model';
16
+ import { replaceSpanToMention } from '../utils';
16
17
  const MESSAGES_BOX_CLASS = 'jp-chat-messages-container';
17
18
  const MESSAGE_CLASS = 'jp-chat-message';
18
19
  const MESSAGE_STACKED_CLASS = 'jp-chat-message-stacked';
@@ -246,16 +247,27 @@ export const ChatMessage = forwardRef((props, ref) => {
246
247
  // Create an input model only if the message is edited.
247
248
  useEffect(() => {
248
249
  if (edit && canEdit) {
249
- setInputModel(new InputModel({
250
- onSend: (input, model) => updateMessage(message.id, input, model),
251
- onCancel: () => cancelEdition(),
252
- value: message.body,
253
- config: {
254
- sendWithShiftEnter: model.config.sendWithShiftEnter
255
- },
256
- attachments: message.attachments,
257
- documentManager: model.documentManager
258
- }));
250
+ setInputModel(() => {
251
+ var _a;
252
+ let body = message.body;
253
+ (_a = message.mentions) === null || _a === void 0 ? void 0 : _a.forEach(user => {
254
+ body = replaceSpanToMention(body, user);
255
+ });
256
+ return new InputModel({
257
+ chatContext: model.createChatContext(),
258
+ onSend: (input, model) => updateMessage(message.id, input, model),
259
+ onCancel: () => cancelEdition(),
260
+ value: body,
261
+ activeCellManager: model.activeCellManager,
262
+ selectionWatcher: model.selectionWatcher,
263
+ documentManager: model.documentManager,
264
+ config: {
265
+ sendWithShiftEnter: model.config.sendWithShiftEnter
266
+ },
267
+ attachments: message.attachments,
268
+ mentions: message.mentions
269
+ });
270
+ });
259
271
  }
260
272
  else {
261
273
  setInputModel(null);
@@ -274,6 +286,7 @@ export const ChatMessage = forwardRef((props, ref) => {
274
286
  const updatedMessage = { ...message };
275
287
  updatedMessage.body = input;
276
288
  updatedMessage.attachments = inputModel.attachments;
289
+ updatedMessage.mentions = inputModel.mentions;
277
290
  model.updateMessage(id, updatedMessage);
278
291
  setEdit(false);
279
292
  };
@@ -2,9 +2,9 @@
2
2
  * Copyright (c) Jupyter Development Team.
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
- import React from 'react';
6
- import { useEffect, useState } from 'react';
5
+ import { LabIcon } from '@jupyterlab/ui-components';
7
6
  import { Box } from '@mui/material';
7
+ import React, { useEffect, useState } from 'react';
8
8
  /**
9
9
  * A hook which automatically returns the list of command options given the
10
10
  * current input and chat command registry.
@@ -83,7 +83,7 @@ export function useChatCommands(inputModel, chatCommandRegistry) {
83
83
  getOptionLabel: (command) => command.name,
84
84
  renderOption: (defaultProps, command, __, ___) => {
85
85
  const { key, ...listItemProps } = defaultProps;
86
- const commandIcon = (React.createElement("span", null, typeof command.icon === 'object' ? (React.createElement(command.icon.react, null)) : (command.icon)));
86
+ const commandIcon = React.isValidElement(command.icon) ? (command.icon) : (React.createElement("span", null, command.icon instanceof LabIcon ? (React.createElement(command.icon.react, null)) : (command.icon)));
87
87
  return (React.createElement(Box, { key: key, component: "li", ...listItemProps },
88
88
  commandIcon,
89
89
  React.createElement("p", { className: "jp-chat-command-name" }, command.name),
package/lib/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from './active-cell-manager';
2
+ export * from './chat-commands';
2
3
  export * from './components';
3
4
  export * from './icons';
4
5
  export * from './input-model';
@@ -9,4 +10,3 @@ export * from './types';
9
10
  export * from './widgets/chat-error';
10
11
  export * from './widgets/chat-sidebar';
11
12
  export * from './widgets/chat-widget';
12
- export * from './chat-commands';
package/lib/index.js CHANGED
@@ -3,6 +3,7 @@
3
3
  * Distributed under the terms of the Modified BSD License.
4
4
  */
5
5
  export * from './active-cell-manager';
6
+ export * from './chat-commands';
6
7
  export * from './components';
7
8
  export * from './icons';
8
9
  export * from './input-model';
@@ -13,4 +14,3 @@ export * from './types';
13
14
  export * from './widgets/chat-error';
14
15
  export * from './widgets/chat-sidebar';
15
16
  export * from './widgets/chat-widget';
16
- export * from './chat-commands';
@@ -1,13 +1,18 @@
1
+ import { IDocumentManager } from '@jupyterlab/docmanager';
1
2
  import { IDisposable } from '@lumino/disposable';
2
3
  import { ISignal } from '@lumino/signaling';
3
4
  import { IActiveCellManager } from './active-cell-manager';
4
5
  import { ISelectionWatcher } from './selection-watcher';
5
- import { IAttachment } from './types';
6
- import { IDocumentManager } from '@jupyterlab/docmanager';
6
+ import { IChatContext } from './model';
7
+ import { IAttachment, IUser } from './types';
7
8
  /**
8
9
  * The chat input interface.
9
10
  */
10
11
  export interface IInputModel extends IDisposable {
12
+ /**
13
+ * The chat context (a readonly subset of the chat model).
14
+ */
15
+ readonly chatContext: IChatContext;
11
16
  /**
12
17
  * Function to send a message.
13
18
  */
@@ -93,12 +98,32 @@ export interface IInputModel extends IDisposable {
93
98
  * Replace the current word in the input with a new one.
94
99
  */
95
100
  replaceCurrentWord(newWord: string): void;
101
+ /**
102
+ * The mentioned user list.
103
+ */
104
+ readonly mentions: IUser[];
105
+ /**
106
+ * Add user mention.
107
+ */
108
+ addMention?(user: IUser): void;
109
+ /**
110
+ * Remove a user mention.
111
+ */
112
+ removeMention(user: IUser): void;
113
+ /**
114
+ * Clear mentions list.
115
+ */
116
+ clearMentions(): void;
96
117
  }
97
118
  /**
98
119
  * The input model.
99
120
  */
100
121
  export declare class InputModel implements IInputModel {
101
122
  constructor(options: InputModel.IOptions);
123
+ /**
124
+ * The chat context (a readonly subset of the chat model);
125
+ */
126
+ get chatContext(): IChatContext;
102
127
  /**
103
128
  * Function to send a message.
104
129
  */
@@ -186,6 +211,22 @@ export declare class InputModel implements IInputModel {
186
211
  * Replace the current word in the input with a new one.
187
212
  */
188
213
  replaceCurrentWord(newWord: string): void;
214
+ /**
215
+ * The mentioned user list.
216
+ */
217
+ get mentions(): IUser[];
218
+ /**
219
+ * Add a user mention.
220
+ */
221
+ addMention(user: IUser): void;
222
+ /**
223
+ * Remove a user mention.
224
+ */
225
+ removeMention(user: IUser): void;
226
+ /**
227
+ * Clear mentions list.
228
+ */
229
+ clearMentions: () => void;
189
230
  /**
190
231
  * Dispose the input model.
191
232
  */
@@ -195,10 +236,12 @@ export declare class InputModel implements IInputModel {
195
236
  */
196
237
  get isDisposed(): boolean;
197
238
  private _onSend;
239
+ private _chatContext;
198
240
  private _value;
199
241
  private _cursorIndex;
200
242
  private _currentWord;
201
243
  private _attachments;
244
+ private _mentions;
202
245
  private _activeCellManager;
203
246
  private _selectionWatcher;
204
247
  private _documentManager;
@@ -213,6 +256,10 @@ export declare class InputModel implements IInputModel {
213
256
  }
214
257
  export declare namespace InputModel {
215
258
  interface IOptions {
259
+ /**
260
+ * The chat context (a readonly subset of the chat model).
261
+ */
262
+ chatContext: IChatContext;
216
263
  /**
217
264
  * The function that should send the message.
218
265
  * @param content - the content of the message.
@@ -231,6 +278,10 @@ export declare namespace InputModel {
231
278
  * The initial attachments.
232
279
  */
233
280
  attachments?: IAttachment[];
281
+ /**
282
+ * The initial mentions.
283
+ */
284
+ mentions?: IUser[];
234
285
  /**
235
286
  * The current cursor index.
236
287
  * This refers to the index of the character in front of the cursor.
@@ -46,6 +46,12 @@ export class InputModel {
46
46
  this._attachments = [];
47
47
  this._attachmentsChanged.emit([]);
48
48
  };
49
+ /**
50
+ * Clear mentions list.
51
+ */
52
+ this.clearMentions = () => {
53
+ this._mentions = [];
54
+ };
49
55
  this._cursorIndex = null;
50
56
  this._currentWord = null;
51
57
  this._valueChanged = new Signal(this);
@@ -56,8 +62,10 @@ export class InputModel {
56
62
  this._attachmentsChanged = new Signal(this);
57
63
  this._isDisposed = false;
58
64
  this._onSend = options.onSend;
65
+ this._chatContext = options.chatContext;
59
66
  this._value = options.value || '';
60
67
  this._attachments = options.attachments || [];
68
+ this._mentions = options.mentions || [];
61
69
  this.cursorIndex = options.cursorIndex || this.value.length;
62
70
  this._activeCellManager = (_a = options.activeCellManager) !== null && _a !== void 0 ? _a : null;
63
71
  this._selectionWatcher = (_b = options.selectionWatcher) !== null && _b !== void 0 ? _b : null;
@@ -67,6 +75,12 @@ export class InputModel {
67
75
  };
68
76
  this.cancel = options.onCancel;
69
77
  }
78
+ /**
79
+ * The chat context (a readonly subset of the chat model);
80
+ */
81
+ get chatContext() {
82
+ return this._chatContext;
83
+ }
70
84
  /**
71
85
  * The entire input value.
72
86
  */
@@ -190,6 +204,30 @@ export class InputModel {
190
204
  const [start, end] = Private.getCurrentWordBoundaries(this.value, this.cursorIndex);
191
205
  this.value = this.value.slice(0, start) + newWord + this.value.slice(end);
192
206
  }
207
+ /**
208
+ * The mentioned user list.
209
+ */
210
+ get mentions() {
211
+ return this._mentions;
212
+ }
213
+ /**
214
+ * Add a user mention.
215
+ */
216
+ addMention(user) {
217
+ const usernames = this._mentions.map(user => user.username);
218
+ if (!usernames.includes(user.username)) {
219
+ this._mentions.push(user);
220
+ }
221
+ }
222
+ /**
223
+ * Remove a user mention.
224
+ */
225
+ removeMention(user) {
226
+ const index = this._mentions.indexOf(user);
227
+ if (index > -1) {
228
+ this._mentions.splice(index, 1);
229
+ }
230
+ }
193
231
  /**
194
232
  * Dispose the input model.
195
233
  */
package/lib/model.d.ts CHANGED
@@ -2,10 +2,10 @@ import { IDocumentManager } from '@jupyterlab/docmanager';
2
2
  import { CommandRegistry } from '@lumino/commands';
3
3
  import { IDisposable } from '@lumino/disposable';
4
4
  import { ISignal } from '@lumino/signaling';
5
- import { IChatHistory, INewMessage, IChatMessage, IConfig, IUser } from './types';
6
5
  import { IActiveCellManager } from './active-cell-manager';
7
- import { ISelectionWatcher } from './selection-watcher';
8
6
  import { IInputModel } from './input-model';
7
+ import { ISelectionWatcher } from './selection-watcher';
8
+ import { IChatHistory, INewMessage, IChatMessage, IConfig, IUser } from './types';
9
9
  /**
10
10
  * The chat model interface.
11
11
  */
@@ -131,17 +131,22 @@ export interface IChatModel extends IDisposable {
131
131
  * Update the current writers list.
132
132
  */
133
133
  updateWriters(writers: IUser[]): void;
134
+ /**
135
+ * Create the chat context that will be passed to the input model.
136
+ */
137
+ createChatContext(): IChatContext;
134
138
  }
135
139
  /**
136
- * The default chat model implementation.
137
- * It is not able to send or update a message by itself, since it depends on the
138
- * chosen technology.
140
+ * An abstract implementation of IChatModel.
141
+ *
142
+ * The class inheriting from it must implement at least:
143
+ * - sendMessage(message: INewMessage)
139
144
  */
140
- export declare class ChatModel implements IChatModel {
145
+ export declare abstract class AbstractChatModel implements IChatModel {
141
146
  /**
142
147
  * Create a new chat model.
143
148
  */
144
- constructor(options?: ChatModel.IOptions);
149
+ constructor(options?: IChatModel.IOptions);
145
150
  /**
146
151
  * The chat model id.
147
152
  */
@@ -219,7 +224,7 @@ export declare class ChatModel implements IChatModel {
219
224
  * @param message - the message to send.
220
225
  * @returns whether the message has been sent or not.
221
226
  */
222
- sendMessage(message: INewMessage): Promise<boolean | void> | boolean | void;
227
+ abstract sendMessage(message: INewMessage): Promise<boolean | void> | boolean | void;
223
228
  /**
224
229
  * Clear the message list.
225
230
  */
@@ -262,6 +267,10 @@ export declare class ChatModel implements IChatModel {
262
267
  * This implementation only propagate the list via a signal.
263
268
  */
264
269
  updateWriters(writers: IUser[]): void;
270
+ /**
271
+ * Create the chat context that will be passed to the input model.
272
+ */
273
+ abstract createChatContext(): IChatContext;
265
274
  /**
266
275
  * Add unread messages to the list.
267
276
  * @param indexes - list of new indexes.
@@ -299,7 +308,7 @@ export declare class ChatModel implements IChatModel {
299
308
  /**
300
309
  * The chat model namespace.
301
310
  */
302
- export declare namespace ChatModel {
311
+ export declare namespace IChatModel {
303
312
  /**
304
313
  * The instantiation options for a ChatModel.
305
314
  */
@@ -330,3 +339,39 @@ export declare namespace ChatModel {
330
339
  documentManager?: IDocumentManager | null;
331
340
  }
332
341
  }
342
+ /**
343
+ * Interface of the chat context, a 'subset' of the model with readonly attribute,
344
+ * which can be passed to the input model.
345
+ * This allows third party extensions to get some attribute of the model without
346
+ * exposing the method that can modify it.
347
+ */
348
+ export interface IChatContext {
349
+ /**
350
+ * The name of the chat.
351
+ */
352
+ readonly name: string;
353
+ /**
354
+ * A copy of the messages.
355
+ */
356
+ readonly messages: IChatMessage[];
357
+ /**
358
+ * A list of all users who have connected to this chat.
359
+ */
360
+ readonly users: IUser[];
361
+ }
362
+ /**
363
+ * An abstract base class implementing `IChatContext`. This can be extended into
364
+ * a complete implementation, as done in `jupyterlab-chat`.
365
+ */
366
+ export declare abstract class AbstractChatContext implements IChatContext {
367
+ constructor(options: {
368
+ model: IChatModel;
369
+ });
370
+ get name(): string;
371
+ get messages(): IChatMessage[];
372
+ /**
373
+ * ABSTRACT: Should return a list of users who have connected to this chat.
374
+ */
375
+ abstract get users(): IUser[];
376
+ protected _model: IChatModel;
377
+ }
package/lib/model.js CHANGED
@@ -4,12 +4,14 @@
4
4
  */
5
5
  import { Signal } from '@lumino/signaling';
6
6
  import { InputModel } from './input-model';
7
+ import { replaceMentionToSpan } from './utils';
7
8
  /**
8
- * The default chat model implementation.
9
- * It is not able to send or update a message by itself, since it depends on the
10
- * chosen technology.
9
+ * An abstract implementation of IChatModel.
10
+ *
11
+ * The class inheriting from it must implement at least:
12
+ * - sendMessage(message: INewMessage)
11
13
  */
12
- export class ChatModel {
14
+ export class AbstractChatModel {
13
15
  /**
14
16
  * Create a new chat model.
15
17
  */
@@ -37,6 +39,7 @@ export class ChatModel {
37
39
  ...config
38
40
  };
39
41
  this._inputModel = new InputModel({
42
+ chatContext: this.createChatContext(),
40
43
  activeCellManager: options.activeCellManager,
41
44
  selectionWatcher: options.selectionWatcher,
42
45
  documentManager: options.documentManager,
@@ -220,14 +223,6 @@ export class ChatModel {
220
223
  get writersChanged() {
221
224
  return this._writersChanged;
222
225
  }
223
- /**
224
- * Send a message, to be defined depending on the chosen technology.
225
- * Default to no-op.
226
- *
227
- * @param message - the message to send.
228
- * @returns whether the message has been sent or not.
229
- */
230
- sendMessage(message) { }
231
226
  /**
232
227
  * Clear the message list.
233
228
  */
@@ -255,6 +250,10 @@ export class ChatModel {
255
250
  * Can be useful if some actions are required on the message.
256
251
  */
257
252
  formatChatMessage(message) {
253
+ var _a;
254
+ (_a = message.mentions) === null || _a === void 0 ? void 0 : _a.forEach(user => {
255
+ message.body = replaceMentionToSpan(message.body, user);
256
+ });
258
257
  return message;
259
258
  }
260
259
  /**
@@ -379,3 +378,18 @@ export class ChatModel {
379
378
  }
380
379
  }
381
380
  }
381
+ /**
382
+ * An abstract base class implementing `IChatContext`. This can be extended into
383
+ * a complete implementation, as done in `jupyterlab-chat`.
384
+ */
385
+ export class AbstractChatContext {
386
+ constructor(options) {
387
+ this._model = options.model;
388
+ }
389
+ get name() {
390
+ return this._model.name;
391
+ }
392
+ get messages() {
393
+ return [...this._model.messages];
394
+ }
395
+ }
package/lib/types.d.ts CHANGED
@@ -8,6 +8,10 @@ export interface IUser {
8
8
  initials?: string;
9
9
  color?: string;
10
10
  avatar_url?: string;
11
+ /**
12
+ * The string to use to mention a user in the chat.
13
+ */
14
+ mention_name?: string;
11
15
  }
12
16
  /**
13
17
  * The configuration interface.
@@ -44,6 +48,7 @@ export interface IChatMessage<T = IUser, U = IAttachment> {
44
48
  time: number;
45
49
  sender: T;
46
50
  attachments?: U[];
51
+ mentions?: T[];
47
52
  raw_time?: boolean;
48
53
  deleted?: boolean;
49
54
  edited?: boolean;
package/lib/utils.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { CodeMirrorEditor } from '@jupyterlab/codemirror';
2
2
  import { Notebook } from '@jupyterlab/notebook';
3
3
  import { Widget } from '@lumino/widgets';
4
+ import { IUser } from './types';
4
5
  /**
5
6
  * Gets the editor instance used by a document widget. Returns `null` if unable.
6
7
  */
@@ -9,3 +10,17 @@ export declare function getEditor(widget: Widget | null): CodeMirrorEditor | nul
9
10
  * Gets the index of the cell associated with `cellId`.
10
11
  */
11
12
  export declare function getCellIndex(notebook: Notebook, cellId: string): number;
13
+ /**
14
+ * Replace a mention to user (@someone) to a span, for markdown renderer.
15
+ *
16
+ * @param content - the content to update.
17
+ * @param user - the user mentioned.
18
+ */
19
+ export declare function replaceMentionToSpan(content: string, user: IUser): string;
20
+ /**
21
+ * Replace a span to a mentioned to user string (@someone).
22
+ *
23
+ * @param content - the content to update.
24
+ * @param user - the user mentioned.
25
+ */
26
+ export declare function replaceSpanToMention(content: string, user: IUser): string;