-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Show a toast message (notice) when moving posts to trash #21724
Conversation
📲 You can test the changes from this Pull Request in WordPress Alpha by scanning the QR code below to install the corresponding build.
|
📲 You can test the changes from this Pull Request in Jetpack Alpha by scanning the QR code below to install the corresponding build.
|
Generated by 🚫 dangerJS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left a few questions.
|
||
let status = try await coreDataStack.performQuery { try $0.existingObject(with: postID).status } | ||
assert(status == .trash, "This function can only be used to delete trashed posts/pages.") | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At first I was surprised to see the assert
here and not at the start of the method. But I guess the reason is that the code above recur to find the original post, and for the same reason we want to delete the original, we want to check the status on it. Am I reading this right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. This status check doesn't exist in the original delete function in PostService
. I added it here to catch incorrect calls to this function (which may never happen).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
let postObjectID = apost.objectID | ||
@MainActor | ||
func deletePost(_ apost: AbstractPost) async { | ||
assert(apost.managedObjectContext == ContextManager.shared.mainContext) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of scope: I've been thinking about all the accesses to ContextManager.shared
that we have and the issues they sometime cause such as #21742.
Would it make sense to instantiate the view controller with a context or CoreDataStack
object? In practice, this would be ContextManager.shared.mainContext
or ContextManager.shared
but the separation would:
- Centralize the definition of the shared resource access
- Allow us to replace it in the tests
What do you think?
let message = NSLocalizedString("Post moved to trash.", comment: "A short message explaining that a post was moved to the trash bin.") | ||
let undoAction = NSLocalizedString("Undo", comment: "The title of an 'undo' button. Tapping the button moves a trashed post out of the trash folder.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be a good time to introduce reverse-DNS keys in these localized strings. For context: #19028
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These strings were copied from https://github.com/wordpress-mobile/WordPress-iOS/pull/21724/files/aedccc4558780dbd690d4e2f586536f1b0ea8a97#diff-0b401d58526d69f6fa54a6679880b35a5fc7bf7643731e9c55f5d4b7b56f8d63L34-L35. I have updated them in 58c1d44
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you
} | ||
}) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you considered moving some of the logic here into a ViewModel-like object, so that we can test it?
One point of friction I can see is that there is no such object for this VC that I can see at the moment. Another is that this is a base class, meaning that the actual subclasses the app uses at runtime might need additional behavior and might be left with having to create their own ViewModel subclasses. This would be confusing. At the same time, it would be a sign of an abstraction that no longer serves us well and we might want to update its design.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That'd be much better than this view controller's current state. But I don't want to just move this small part (trashing, deleting, restoring) out, leaving this view controller in a weird state with mixed-patterns. A large refactor on this screen also seems unnecessary at this point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
leaving this view controller in a weird state with mixed-patterns
Good point 🤔
I am a fan of sprouting (a la Working Effectively with Legacy Code) better code from existing code, even if what is added/extracted is a little portion of the total. But ☝️ having mixed patterns is a concern.
I guess it would be acceptable only if we had an agreed upon expectation that "all new and modified code should follow ." That is not the case at the moment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given this PR has been sitting idle waiting for my feedback, the least I could do was fixing the merge conflict (on RELEASE-NOTES.txt
) to unblock it's merge
For context, this change is initiated from this conversation: p1694476848843439-slack-C0180B5PRJ4
Changes
This PR changes how to present an "undo" action to users when moving a post to trash. Here is a video preview of before & after the change.
undo.mp4
toast.mp4
Problems of the "Undo" row
From design perspective, there are a couple of issues:
From implementation perspective, it's not straight-forward to implement keeping the trashed post position and placing a "undo" row in it. From a quick testing, the existing implementation has an obvious bug when trashing posts from bottom to up.
New flow
As you can see in the video, the new design is showing a toast message with an "Undo" button, which is consistent with other actions like restoring post from trash.
Implementation details
There are three parts involved in this PR
1. Removing the
restorableStatus
stored property fromAbstractPost
This property is used to kept the original post status when it's moved to trash.
One obvious issue is, this property is not a "managed" property, which means it's not stored into the Core Data database. So, its value is guaranteed to be lost if multiple context objects are used to write and read this information.
Also, this property gives a false sense of a trashed post can be "restored" to any status, but I believe in reality a trashed post can only be restored to draft.
2. Use delete, trash, restore functions in
PostRepository
These functions a newly implemented in
PostRepository
, as replacements for the ones inPostService
which are now deleted in this PR.3. Show toast messages after trashing posts
This is the UI change part of this PR.
Test Instructions
Here are a few things that I can think of:
Regression Notes
Potential unintended areas of impact
None.
What I did to test those areas of impact (or what existing automated tests I relied on)
What's described in the "Test Instructions" section.
What automated tests I added (or what prevented me from doing so)
None.
PR submission checklist:
RELEASE-NOTES.txt
if necessary.UI Changes testing checklist: