Add stop/cancel action for message sending loading indicator #130

Closed
opened 2025-12-15 17:06:17 +00:00 by rwachters · 0 comments
rwachters commented 2025-12-15 17:06:17 +00:00 (Migrated from github.com)

The loading indicator currently shows while a message is being sent, but users cannot cancel the operation. This change adds a stop/cancel action to the loading indicator which cancels the coroutine job that runs the SendMessageUseCase, resetting the UI to a non-sending state.

Motivation

  • Improve UX by allowing users to stop long-running or stuck message sends.
  • Prevent users from being stuck on an indefinite loading state.

Implementation plan (high level)

  1. Add coroutine Job tracking in ChatViewModel (file: app/src/commonMain/kotlin/eu/torvian/chatbot/app/viewmodel/chat/ChatViewModel.kt): store the active message sending Job? and add cancelSendMessage() which cancels the job and ensures the sending state is reset.
  2. Update sendMessage() in ChatViewModel: capture the launched coroutine Job and store it in the tracking field; clear it on completion (e.g., in finally).
  3. Add onCancelSendMessage callback to ChatAreaActions (file: app/src/commonMain/kotlin/eu/torvian/chatbot/app/compose/chatarea/ChatAreaActions.kt).
  4. Wire action in ChatScreen: implement onCancelSendMessage in the chatAreaActions object to call chatViewModel.cancelSendMessage().
  5. Update InputArea (file: app/src/commonMain/kotlin/eu/torvian/chatbot/app/compose/chatarea/InputArea.kt): add parameter onCancelSendMessage: () -> Unit and change the loading indicator button onClick to call it.
  6. Thread callback through ChatArea (file: app/src/commonMain/kotlin/eu/torvian/chatbot/app/compose/chatarea/ChatArea.kt): add onCancelSendMessage parameter and pass it to InputArea.

Further considerations

  • Icon/UX: consider using a stop/close icon or updating tooltip to "Sending... (click to cancel)".
  • UX feedback: optionally show a snackbar "Message sending cancelled" on cancel.
  • SendMessageUseCase already calls state.setIsSending(false) in a finally block; test that cancellation leads to the expected state transitions.

Acceptance criteria

  • When sending a message, the loading indicator shows a clickable stop control.
  • Clicking the stop control cancels the in-progress send coroutine and sets isSendingMessage to false.
  • No crashes or resource leaks occur after cancellation.

Files likely touched

  • app/src/commonMain/kotlin/eu/torvian/chatbot/app/viewmodel/chat/ChatViewModel.kt
  • app/src/commonMain/kotlin/eu/torvian/chatbot/app/compose/chatarea/ChatAreaActions.kt
  • app/src/commonMain/kotlin/eu/torvian/chatbot/app/compose/ChatScreen.kt
  • app/src/commonMain/kotlin/eu/torvian/chatbot/app/compose/chatarea/ChatArea.kt
  • app/src/commonMain/kotlin/eu/torvian/chatbot/app/compose/chatarea/InputArea.kt

Notes

  • Please assign to relevant maintainers for implementation; I suggest the labels enhancement and ux and assignee rwachters.
The loading indicator currently shows while a message is being sent, but users cannot cancel the operation. This change adds a stop/cancel action to the loading indicator which cancels the coroutine job that runs the `SendMessageUseCase`, resetting the UI to a non-sending state. Motivation - Improve UX by allowing users to stop long-running or stuck message sends. - Prevent users from being stuck on an indefinite loading state. Implementation plan (high level) 1. Add coroutine Job tracking in `ChatViewModel` (file: `app/src/commonMain/kotlin/eu/torvian/chatbot/app/viewmodel/chat/ChatViewModel.kt`): store the active message sending `Job?` and add `cancelSendMessage()` which cancels the job and ensures the sending state is reset. 2. Update `sendMessage()` in `ChatViewModel`: capture the launched coroutine `Job` and store it in the tracking field; clear it on completion (e.g., in `finally`). 3. Add `onCancelSendMessage` callback to `ChatAreaActions` (file: `app/src/commonMain/kotlin/eu/torvian/chatbot/app/compose/chatarea/ChatAreaActions.kt`). 4. Wire action in `ChatScreen`: implement `onCancelSendMessage` in the `chatAreaActions` object to call `chatViewModel.cancelSendMessage()`. 5. Update `InputArea` (file: `app/src/commonMain/kotlin/eu/torvian/chatbot/app/compose/chatarea/InputArea.kt`): add parameter `onCancelSendMessage: () -> Unit` and change the loading indicator button onClick to call it. 6. Thread callback through `ChatArea` (file: `app/src/commonMain/kotlin/eu/torvian/chatbot/app/compose/chatarea/ChatArea.kt`): add `onCancelSendMessage` parameter and pass it to `InputArea`. Further considerations - Icon/UX: consider using a stop/close icon or updating tooltip to "Sending... (click to cancel)". - UX feedback: optionally show a snackbar "Message sending cancelled" on cancel. - `SendMessageUseCase` already calls `state.setIsSending(false)` in a `finally` block; test that cancellation leads to the expected state transitions. Acceptance criteria - When sending a message, the loading indicator shows a clickable stop control. - Clicking the stop control cancels the in-progress send coroutine and sets `isSendingMessage` to false. - No crashes or resource leaks occur after cancellation. Files likely touched - app/src/commonMain/kotlin/eu/torvian/chatbot/app/viewmodel/chat/ChatViewModel.kt - app/src/commonMain/kotlin/eu/torvian/chatbot/app/compose/chatarea/ChatAreaActions.kt - app/src/commonMain/kotlin/eu/torvian/chatbot/app/compose/ChatScreen.kt - app/src/commonMain/kotlin/eu/torvian/chatbot/app/compose/chatarea/ChatArea.kt - app/src/commonMain/kotlin/eu/torvian/chatbot/app/compose/chatarea/InputArea.kt Notes - Please assign to relevant maintainers for implementation; I suggest the labels `enhancement` and `ux` and assignee `rwachters`.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Torvian.eu/chatbot#130
No description provided.