Skip to content

Commit 227ce6b

Browse files
committed
hookable delta update
1 parent dbd8731 commit 227ce6b

File tree

1 file changed

+29
-7
lines changed

1 file changed

+29
-7
lines changed

moly-kit/src/widgets/chat.rs

+29-7
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ impl ChatHook {
7272
/// access to its wrapper [ChatHook], you can modify the task before it is executed.
7373
///
7474
/// See [Chat::tasks] and [Chat::hook] for more information.
75+
// TODO: Using indexes for many uperation like `UpdateMessage` is not ideal. In the future
76+
// messages may need to have a unique identifier.
7577
#[derive(Debug)]
7678
pub enum ChatTask {
7779
/// When received back, it will send the whole chat context to the bot.
@@ -97,6 +99,9 @@ pub enum ChatTask {
9799

98100
/// When received back, it will clear the prompt input.
99101
ClearPrompt,
102+
103+
/// When received back, the chat will scroll to the bottom.
104+
ScrollToBottom,
100105
}
101106

102107
impl From<ChatTask> for Vec<ChatTask> {
@@ -319,7 +324,7 @@ impl Chat {
319324
is_writing: true,
320325
});
321326

322-
messages.scroll_to_bottom(cx);
327+
self.dispatch(cx, ChatTask::ScrollToBottom.into());
323328

324329
messages
325330
.messages
@@ -342,15 +347,22 @@ impl Chat {
342347

343348
ui.defer_with_redraw(move |me, cx, _scope| {
344349
me.messages_ref().write_with(|messages| {
345-
messages
350+
let mut body = messages
346351
.messages
347352
.last_mut()
348353
.expect("no message where to put delta")
349354
.body
350-
.push_str(&delta);
355+
.clone();
356+
357+
body.push_str(&delta);
358+
359+
me.dispatch(
360+
cx,
361+
ChatTask::UpdateMessage(messages.messages.len() - 1, body).into(),
362+
);
351363

352364
if messages.is_at_bottom() {
353-
messages.scroll_to_bottom(cx);
365+
me.dispatch(cx, ChatTask::ScrollToBottom.into());
354366
}
355367
});
356368
});
@@ -400,6 +412,15 @@ impl Chat {
400412
cx.action(action);
401413
}
402414

415+
/// Performs a set of tasks in the [Chat] widget immediately.
416+
///
417+
/// This is not hookable, no actions are emitted from this.
418+
pub fn perform(&mut self, cx: &mut Cx, tasks: &[ChatTask]) {
419+
for task in tasks {
420+
self.handle_primitive_task(cx, &task);
421+
}
422+
}
423+
403424
/// Get a reader to each [ChatTask] available in the event.
404425
///
405426
/// This yields individual tasks and not the whole set of tasks in the underlying hook.
@@ -420,9 +441,7 @@ impl Chat {
420441
self.hook(event).write_with(|hook| {
421442
hook.executed = true;
422443
if let Some(tasks) = hook.tasks.as_mut() {
423-
for task in tasks {
424-
self.handle_primitive_task(cx, task);
425-
}
444+
self.perform(cx, tasks);
426445
}
427446
});
428447
}
@@ -478,6 +497,9 @@ impl Chat {
478497
ChatTask::ClearPrompt => {
479498
self.prompt_input_ref().write().reset(cx); // `reset` comes from command text input.
480499
}
500+
ChatTask::ScrollToBottom => {
501+
self.messages_ref().write().scroll_to_bottom(cx);
502+
}
481503
}
482504
}
483505
}

0 commit comments

Comments
 (0)