Skip to content

Commit d17e0e9

Browse files
committed
Add user avatar in command suggestion
1 parent ae2a69d commit d17e0e9

File tree

3 files changed

+21
-10
lines changed

3 files changed

+21
-10
lines changed

packages/jupyter-chat/src/chat-commands/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export type ChatCommand = {
2323
* If set, this will be rendered as the icon for the command in the chat
2424
* commands menu. Jupyter Chat will choose a default if this is unset.
2525
*/
26-
icon?: LabIcon | string;
26+
icon?: LabIcon | JSX.Element | string;
2727

2828
/**
2929
* If set, this will be rendered as the description for the command in the

packages/jupyter-chat/src/components/input/use-chat-commands.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
* Distributed under the terms of the Modified BSD License.
44
*/
55

6-
import React from 'react';
7-
import { useEffect, useState } from 'react';
6+
import { LabIcon } from '@jupyterlab/ui-components';
87
import type {
98
AutocompleteChangeReason,
109
AutocompleteProps as GenericAutocompleteProps
1110
} from '@mui/material';
1211
import { Box } from '@mui/material';
12+
import React, { useEffect, useState } from 'react';
1313

1414
import { ChatCommand, IChatCommandRegistry } from '../../chat-commands';
1515
import { IInputModel } from '../../input-model';
@@ -133,9 +133,11 @@ export function useChatCommands(
133133
___: unknown
134134
) => {
135135
const { key, ...listItemProps } = defaultProps;
136-
const commandIcon: JSX.Element = (
136+
const commandIcon: JSX.Element = React.isValidElement(command.icon) ? (
137+
command.icon
138+
) : (
137139
<span>
138-
{typeof command.icon === 'object' ? (
140+
{command.icon instanceof LabIcon ? (
139141
<command.icon.react />
140142
) : (
141143
command.icon

python/jupyterlab-chat/src/chat-commands/providers/user-mention.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
* Distributed under the terms of the Modified BSD License.
44
*/
55

6-
import { JupyterFrontEndPlugin } from '@jupyterlab/application';
76
import {
87
IChatCommandProvider,
98
IChatCommandRegistry,
109
ChatCommand,
11-
IInputModel
10+
IInputModel,
11+
Avatar
1212
} from '@jupyter/chat';
13+
import { JupyterFrontEndPlugin } from '@jupyterlab/application';
14+
import { User } from '@jupyterlab/services';
1315
import { LabChatModel } from 'jupyterlab-chat';
1416
import { JSONObject } from '@lumino/coreutils';
1517

@@ -25,10 +27,15 @@ export class MentionCommandProvider implements IChatCommandProvider {
2527
return [];
2628
}
2729

30+
const icons: { [user: string]: JSX.Element | undefined } = {};
2831
// Get the user list from the chat file.
2932
const users = Object.values(chatModel.sharedModel.users).map(user => {
3033
user = user as JSONObject;
31-
return (user.display_name ?? user.name ?? user.username) as string;
34+
const username = (user.display_name ??
35+
user.name ??
36+
user.username) as string;
37+
icons[username] = Avatar({ user: user as User.IIdentity }) ?? undefined;
38+
return username;
3239
});
3340

3441
// Add the users connected to the chat (even if they never sent a message).
@@ -41,19 +48,21 @@ export class MentionCommandProvider implements IChatCommandProvider {
4148
user.name ??
4249
user.username) as string;
4350
if (username && !users.includes(username)) {
51+
icons[username] = Avatar({ user: user as User.IIdentity }) ?? undefined;
4452
users.push(username);
4553
}
4654
});
4755

4856
// Build the commands for each user.
49-
const commands = users
57+
const commands: ChatCommand[] = users
5058
.sort()
5159
.filter(user => `@${user.replace(/ /g, '-')}`.startsWith(match))
5260
.map(user => {
5361
return {
5462
name: `@${user.replace(/ /g, '-')}`,
5563
replaceWith: `@${user}`,
56-
providerId: this.id
64+
providerId: this.id,
65+
icon: icons[user]
5766
};
5867
});
5968
return commands;

0 commit comments

Comments
 (0)