Skip to content

Commit 59eda76

Browse files
committed
Add a setting to show the deleted messages in chat
1 parent e319244 commit 59eda76

File tree

4 files changed

+76
-44
lines changed

4 files changed

+76
-44
lines changed

packages/jupyter-chat/src/components/messages/messages.tsx

Lines changed: 65 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ import { Navigation } from './navigation';
1515
import { WelcomeMessage } from './welcome';
1616
import { ScrollContainer } from '../scroll-container';
1717
import { useChatContext } from '../../context';
18-
import { IChatMessage } from '../../types';
18+
import { IChatMessage, IConfig } from '../../types';
19+
import { IChatModel } from '../../model';
1920

2021
export const MESSAGE_CLASS = 'jp-chat-message';
2122
const MESSAGES_BOX_CLASS = 'jp-chat-messages-container';
@@ -31,6 +32,9 @@ export function ChatMessages(): JSX.Element {
3132
const [messages, setMessages] = useState<IChatMessage[]>(model.messages);
3233
const refMsgBox = useRef<HTMLDivElement>(null);
3334
const [allRendered, setAllRendered] = useState<boolean>(false);
35+
const [showDeleted, setShowDeleted] = useState<boolean>(
36+
model.config.showDeleted ?? false
37+
);
3438

3539
// The list of message DOM and their rendered promises.
3640
const listRef = useRef<(HTMLDivElement | null)[]>([]);
@@ -60,14 +64,29 @@ export function ChatMessages(): JSX.Element {
6064
function handleChatEvents() {
6165
setMessages([...model.messages]);
6266
}
63-
6467
model.messagesUpdated.connect(handleChatEvents);
6568

66-
return function cleanup() {
69+
return () => {
6770
model.messagesUpdated.disconnect(handleChatEvents);
6871
};
6972
}, [model]);
7073

74+
/**
75+
* Effect: Listen to the config change.
76+
*/
77+
useEffect(() => {
78+
function handleConfigChange(_: IChatModel, config: IConfig) {
79+
if (config.showDeleted !== showDeleted) {
80+
setShowDeleted(config.showDeleted ?? false);
81+
}
82+
}
83+
model.configChanged.connect(handleConfigChange);
84+
85+
return () => {
86+
model.configChanged.disconnect(handleConfigChange);
87+
};
88+
}, [model, showDeleted]);
89+
7190
/**
7291
* Observe the messages to update the current viewport and the unread messages.
7392
*/
@@ -148,47 +167,49 @@ export function ChatMessages(): JSX.Element {
148167
ref={refMsgBox}
149168
className={clsx(MESSAGES_BOX_CLASS)}
150169
>
151-
{messages
152-
.filter(message => !message.deleted)
153-
.map((message, i) => {
154-
renderedPromise.current[i] = new PromiseDelegate();
155-
const isCurrentUser =
156-
model.user !== undefined &&
157-
model.user.username === message.sender.username;
158-
return (
159-
// extra div needed to ensure each bubble is on a new line
160-
<Box
161-
key={i}
162-
sx={{
163-
...(isCurrentUser && {
164-
marginLeft: area === 'main' ? '25%' : '10%',
165-
backgroundColor: 'var(--jp-layout-color2)',
166-
border: 'none',
167-
borderRadius: 2,
168-
padding: 2
169-
})
170-
}}
171-
className={clsx(
172-
MESSAGE_CLASS,
173-
message.stacked ? MESSAGE_STACKED_CLASS : ''
174-
)}
175-
>
176-
<ChatMessageHeader
177-
message={message}
178-
isCurrentUser={isCurrentUser}
179-
/>
180-
<ChatMessage
181-
message={message}
182-
index={i}
183-
renderedPromise={renderedPromise.current[i]}
184-
ref={el => (listRef.current[i] = el)}
185-
/>
186-
{messageFooterRegistry && (
187-
<MessageFooterComponent message={message} />
188-
)}
189-
</Box>
190-
);
191-
})}
170+
{/* Filter the deleted message if user don't expect to see it. */}
171+
{(showDeleted
172+
? messages
173+
: messages.filter(message => !message.deleted)
174+
).map((message, i) => {
175+
renderedPromise.current[i] = new PromiseDelegate();
176+
const isCurrentUser =
177+
model.user !== undefined &&
178+
model.user.username === message.sender.username;
179+
return (
180+
// extra div needed to ensure each bubble is on a new line
181+
<Box
182+
key={i}
183+
sx={{
184+
...(isCurrentUser && {
185+
marginLeft: area === 'main' ? '25%' : '10%',
186+
backgroundColor: 'var(--jp-layout-color2)',
187+
border: 'none',
188+
borderRadius: 2,
189+
padding: 2
190+
})
191+
}}
192+
className={clsx(
193+
MESSAGE_CLASS,
194+
message.stacked ? MESSAGE_STACKED_CLASS : ''
195+
)}
196+
>
197+
<ChatMessageHeader
198+
message={message}
199+
isCurrentUser={isCurrentUser}
200+
/>
201+
<ChatMessage
202+
message={message}
203+
index={i}
204+
renderedPromise={renderedPromise.current[i]}
205+
ref={el => (listRef.current[i] = el)}
206+
/>
207+
{messageFooterRegistry && (
208+
<MessageFooterComponent message={message} />
209+
)}
210+
</Box>
211+
);
212+
})}
192213
</Box>
193214
</ScrollContainer>
194215
<Navigation refMsgBox={refMsgBox} allRendered={allRendered} />

packages/jupyter-chat/src/types.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ export interface IConfig {
5252
* Whether to send typing notification.
5353
*/
5454
sendTypingNotification?: boolean;
55+
/**
56+
* Whether to display deleted messages or not
57+
*/
58+
showDeleted?: boolean;
5559
}
5660

5761
/**

packages/jupyterlab-chat-extension/schema/factory.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@
3737
"default": true,
3838
"readOnly": false
3939
},
40+
"showDeleted": {
41+
"description": "Show the deleted messages.",
42+
"type": "boolean",
43+
"default": false,
44+
"readOnly": false
45+
},
4046
"defaultDirectory": {
4147
"description": "Default directory where to create and look for chat, the jupyter root directory if empty.",
4248
"type": "string",

packages/jupyterlab-chat-extension/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ const docFactories: JupyterFrontEndPlugin<IChatFactory> = {
282282
.composite as boolean,
283283
sendTypingNotification: setting.get('sendTypingNotification')
284284
.composite as boolean,
285+
showDeleted: setting.get('showDeleted').composite as boolean,
285286
defaultDirectory: currentDirectory
286287
};
287288
});

0 commit comments

Comments
 (0)