Skip to content

Undo Chat History Deletion#181

Open
lk340 wants to merge 3 commits intomainfrom
history-delete-undo
Open

Undo Chat History Deletion#181
lk340 wants to merge 3 commits intomainfrom
history-delete-undo

Conversation

@lk340
Copy link
Collaborator

@lk340 lk340 commented Apr 4, 2025

Task

  • Designs

  • Add ability to undo history deletion.

Notes

  • The current window for undoing chat history deletion is 3 seconds before the chance to undo expires.
  • Added slight modifications to original design for potentially better UX. Looking for feedback on this.
    1. Can undo multiple deletions in the case of rapid consecutive deletions.
    2. Add chat names to differentiate different deletion cards on consecutive deletions.
    3. Add decaying progress bar (a new component that can be customized in various ways) for a visual indication on undo countdown.
  • Applied fixes to some text truncation issues in history view rows.

Update chat history deletion to track failed deletion individually on a chat-by-chat level.

Fix long chat name truncation in history view.
@lk340 lk340 requested a review from timlenardo April 4, 2025 18:50
@lk340 lk340 self-assigned this Apr 4, 2025
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Summary

This PR introduces undo functionality for chat history deletion by using delayed deletion tasks, visual progress feedback, and updated UI components to support multiple rapid deletion actions.

  • macos/Onit/Data/Model/Model+History.swift: Implements async deletion with a delay, cancellation checks, and separates queues for normal and failed deletions.
  • macos/Onit/Data/Model/OnitModel.swift: Defines deletion state types and manages multiple deletion tasks with a 3-second undo window.
  • macos/Onit/UI/History/HistoryDeleteNotification.swift: Adds an animated undo notification with a 60fps timer and decaying progress bar.
  • macos/Onit/UI/History/HistoryRowView.swift: Adjusts deletion button behavior with improved text truncation.
  • macos/Onit/UI/Components/ProgressBar.swift: Provides a reusable progress component for undo countdown visuals.

8 file(s) reviewed, 2 comment(s)
Edit PR Review Bot Settings | Greptile

Comment on lines 20 to 31
func deleteChat(chat: Chat) async {
do {
deleteChatFailed = false
await removeChatFromDeleteFailedQueue(chatId: chat.id, waitSeconds: 0)

try await Task.sleep(for: .seconds(deleteChatDurationSeconds))
try Task.checkCancellation()

removeChatFromDeleteQueue(chatId: chat.id)

container.mainContext.delete(chat)
try container.mainContext.save()
} catch {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

logic: Cancellation in deleteChat is always treated as a failure (adding the chat to the failed queue). Consider distinguishing CancellationError from other errors to avoid mislabeling intentional undos as failures.

Comment on lines 50 to 55
GeometryReader { geometry in
HStack {}
.frame(maxHeight: .infinity)
.frame(width: geometry.size.width * progressPercentage)
.background(.white)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: Consider using a Rectangle() instead of an empty HStack for the progress fill for better semantic clarity.

lk340 added 2 commits April 4, 2025 15:02
…rrors, preventing Onit from mistaking the undoing of chat history deletion as being a legitimate error.

Update empty HStacks in ProgressBar to Rectangle for better semantic clarity.
Copy link
Contributor

@timlenardo timlenardo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes due to the issues I've mentioned in Slack:

  • If you’re in an active chat, and delete that chat from history, the chat still stays open in the OnitPanel. I found that weird. I think it should probably disappear and start a new chat.
  • If I delete a chat, it’s still accessible in history via the up and down arrows.
  • I saw one weird case where I deleted a chat from history, then relaunched the app. The chat I deleted was still in my history, but a different chat had lost its responses. I haven't been able to reproduce this, but I do think there's something funky going on with the deletion that needs to be debugged.

I've looked at the code, and the delete() function seems correct, so I suspect the issues are coming from the timeout, and storing the Chat to be deleted in chatQueuedForDeletion. Is it possible this becomes the wrong Chat? chatQueuedForDeletion is only a single Chat, so what happens if you delete a bunch simultaneously? Or, is it possible that the HistoryRowView gets recycled and the wrong Chat gets selected? Either way, can you test this extensively to see if you can trigger these edge cases? Some of my testing is coming back fishy 🤨

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants