Skip to content

Conversation

malinajirka
Copy link
Contributor

@malinajirka malinajirka commented Jun 20, 2019

Fixes #9560

Note:
- This PR is dependant on wordpress-mobile/WordPress-FluxC-Android#1289 which needs to be merged first

Adds support for uploading post featured images asynchronously - without blocking the UI.

To test:
Initial steps for all test cases

  1. Create a draft
  2. Click on the overflow menu in the editor -> Post settings
  3. Set a featured image from a local storage

Successful upload
4. Notice the local image and a progress bar is shown during the upload
5. Notice the progress bar and it's overlay disappears when the upload finishes


Failed upload with retry
4. Notice the local image and a progress bar is shown during the upload
5. Turn on airplane mode before the upload finishes
6. Notice the "tap for options" message
7. Turn off airplane mode
8. Click on the image and choose "Retry uploading"
9. Notice the local image and a progress bar is shown during the upload
10. Notice the progress bar and it's overlay disappears when the upload finishes


Failed upload with remove
4. Notice the local image and a progress bar is shown during the upload
5. Turn on airplane mode before the upload finishes
6. Notice the "tap for options" message
7. Click on the image and choose "Remove"
8. Notice the image is removed, upload canceled and the error system notification dismissed


Cancel ongoing upload
4. Notice the local image and a progress bar is shown during the upload
5. Click on the image and choose remove
6. Notice the image is removed, upload canceled and the error system notification dismissed


Choose another image during ongoing upload
4. Notice the local image and a progress bar is shown during the upload
5. Click on the image and choose featured image option
6. Notice the previous image is removed, upload canceled and the error system notification dismissed
7. The newly picked image is being uploaded


Post List label
4. Notice the local image and a progress bar is shown during the upload
5. Go back to the post list and notice "Uploading media" label is shown


Remove all media dialog (test this for both Gutenberg and Aztec)
4. Notice the local image and a progress bar is shown during the upload
5. Turn on airplane mode
6. Go back to the editor and click on Update/Save/Publish
7. Publish confirmation dialog is shown -> click on Publish now
8. Notice another dialog is shown -> Click on "Remove all failed media"
9. The failed upload is removed and the error notification dismissed
10. Click on Update/Save/Publish again and notice the post gets published
(Note: It might be worth showing a snackbar message when we remove all the media - the flow seems a bit broken now, since nothing visible happens when you click on "Remove all failed media")

Update release notes:

  • [ x ] If there are user facing changes, I have added an item to RELEASE-NOTES.txt.

Known issues:
- If you cancel the upload when the "error uploading media" notification is shown, the notification doesn't get canceled.

Before After
featured-image fixed-featured-image

@malinajirka malinajirka marked this pull request as ready for review June 23, 2019 12:01
@malinajirka
Copy link
Contributor Author

@osullivanchris I've added a support for adding a featured image to a post in offline (see before/after gifs). When the user picks a new image, the image is queued and uploaded later.

When the upload fails, the current solution displays a system notification, but keeps showing a circular progress bar in place of the featured image. When the user clicks on the progress bar, they can cancel the upload. I didn't want to replace the circular progress bar with "retry/cancel" buttons or similar as it might look like the user can't leave the screen. However, the current solution doesn't feel great either. Any suggestions?

cancel-featured-image

@maxme maxme self-assigned this Jun 24, 2019
@maxme
Copy link
Contributor

maxme commented Jun 24, 2019

However, the current solution doesn't feel great either.

I agree, the infinite progress bar feels wrong.

Could we show the local image instead of the progress bar? Since it's supposed to "just work" when the draft is uploaded. We could replace the "Cancel upload" popover menu by the other "Choose / Remove" menu.

@maxme
Copy link
Contributor

maxme commented Jun 24, 2019

Something wrong just happened when I was testing with an existing draft:

  • Airplane mode ON
  • Open an existing draft
  • Click on the overflow menu in the editor -> Post settings
  • Set a featured image from a local storage
  • Notice a progress bar is shown in place of the featured image
  • Go back to Post List and notice the post upload error
  • Edit that draft again
  • Turn OFF airplane mode
  • Click on the overflow menu in the editor -> Post settings
  • Notice a progress bar is shown in place of the featured image
  • Back to the editor
  • Click on Update
  • Wait until the draft is uploaded
  • Notice the featured image is not shown in the post list
  • Edit that draft again
  • Click on the overflow menu in the editor -> Post settings
  • Notice the button "Set featured image" 💥

demo video

@osullivanchris
Copy link

Hey @malinajirka I know this issue is in review so I don't want to hold it up too much. However I think there are a few clarifications needed.

  1. In the existing version, and while online, there is a blocking loading animation over the gallery (choose photo) view. In the proposed version, the loading takes place on the 'Post settings' screen. I think this is an improvement. I just want to check that you're changing that for both online and offline?
  2. Doing it on the post settings screen is good because it doesn't block the user, they can do some other things while the upload takes place. My question is whether the user can leave the 'Post settings' view while uploading is taking place? If the user can leave the post settings screen, we should have an uploading and failed state for the post card on the 'posts' screen like we do for other uploads.

Here is a quick mock for something close to what you currently have. I am using the same linear indeterminate indicator that we have on the posts screen, rather than the circular spinner. I don't think tapping the spinner to bring up a cancel option is intuitive. In this mock, the option is visible on the screen.
upload media fail

Happy to work on this further but showing you as quick as possible to get your input and make sure I understand all aspects.

@iamthomasbishop
Copy link

At first glance, I don't dislike your approach here, @osullivanchris. I do however think we might want to consider using an existing pattern – in this case, perhaps replicate what exists during upload/error states on the editor canvas itself.

Essentially, that means show the progress indicator docked to the top of the upload in-progress, and if there is an error, show the messaging/actions in an overlay. Example:

IMG_0490

@malinajirka
Copy link
Contributor Author

Thank you so much for the quick input @osullivanchris !!

In the existing version, and while online, there is a blocking loading animation over the gallery (choose photo) view. In the proposed version, the loading takes place on the 'Post settings' screen. I think this is an improvement. I just want to check that you're changing that for both online and offline?

yes, I moved the upload to the background for both online and offline.

Doing it on the post settings screen is good because it doesn't block the user, they can do some other things while the upload takes place. My question is whether the user can leave the 'Post settings' view while uploading is taking place? If the user can leave the post settings screen, we should have an uploading and failed state for the post card on the 'posts' screen like we do for other uploads.

Yes, the user can leave the screen. The error/retry state on the posts screen is without a change - the app doesn't differentiate between an image in the post content and a featured image (if either fails, the "error uploading media + retry" is shown). You can see the post list screen on the "after" gif in the description of the PR.

Here is a quick mock for something close to what you currently have. I am using the same linear indeterminate indicator that we have on the posts screen, rather than the circular spinner. I don't think tapping the spinner to bring up a cancel option is intuitive. In this mock, the option is visible on the screen.

Awesome, thanks! The only thing I'm a bit concerned about is that in offline the user will see the "Upload failed" right away -> I'm not sure they'll realize they can freely leave the screen and continue writing the post content. Wdyt?

@osullivanchris
Copy link

osullivanchris commented Jun 24, 2019

@malinajirka thanks for the clarifications that all makes sense.

Awesome, thanks! The only thing I'm a bit concerned about is that in offline the user will see the "Upload failed" right away -> I'm not sure they'll realize they can freely leave the screen and continue writing the post content. Wdyt?

I'm not too worried about that. We aren't blocking the UI with an overlay or anything. And if the user is has just done a task of trying to upload an image and it failed, they would want to know about it. Is there anything there I'm missing?

I chatted to @iamthomasbishop to get a review and you'll see his sketch above too. Thanks for bringing this pattern to my attention Thomas!

@malinajirka I think both my mock and Thomas' sketch have more or less the same functionality with different layout. We show the image the user is attempting to upload, a loading progress bar, and the ability to retry or remove if the upload failed. Does this seem do-able from your side, and is there anything you spot with either approach that would be an issue here?

If you're happy to build this, I can do a final high fidelity mock of Thomas' sketch to clarify

@malinajirka
Copy link
Contributor Author

Thank you both!

I'm not too worried about that. We aren't blocking the UI with an overlay or anything. And if the user is has just done a task of trying to upload an image and it failed, they would want to know about it.

👍

Does this seem do-able from your side, and is there anything you spot with either approach that would be an issue here?
If you're happy to build this, I can do a final high fidelity mock of Thomas' sketch to clarify

Sounds good, thanks!

@osullivanchris
Copy link

Having another crack at this. Let me know what you think @malinajirka @iamthomasbishop

In both the below I have the same actions and states, just different layout. Its tricky because we have this kind of successful or expected-failed state. Where we grab the image, but its not uploaded yet, only queued. I wanted to make this state distinct from something breaking. State 1 is in-progress. State 2 is successfully queued while offline (the aim of this ticket). State 3 is if something breaks or any other generic fail state, and allows the user to retry.

For the mock first I tried what Thomas said. Consistency is a good thing. But I feel like the layout is too rigid of this kind of button lock up

  • The layout breaks with truncation and we can't put longer strings in
  • actions above images is hard to get perfect because the image can be different heights
  • actions above the image may lead to the text being illegible in some cases
    I have mocked it up all the same
    option1

Then I tried to make my original approach work, while using patterns we have elsewhere in the app as much as possible (if not specific to media upload flows)
option2

I also had a look at what corresponding information we could display on the post cards for each of these states
card states

@malinajirka
Copy link
Contributor Author

malinajirka commented Jun 26, 2019

Thank you so much for looking into this @osullivanchris ! I really like the direction this is going;).

Its tricky because we have this kind of successful or expected-failed state. Where we grab the image, but its not uploaded yet, only queued. I wanted to make this state distinct from something breaking.

We currently don't have this state in the app. We always try to upload the post (even in offline). We could theoretically check if the device is online and start the upload when it is online and only enqueue the post when it's offline, but I'm not sure it's worth the effort since we probably wouldn't use it in any other part of the app.
Moreover, we also had a discussion if it makes sense not to even try to perform an action in offline just because the OS told us it doesn't have an internet connection (I think the internet availability check is quite reliable on Android, but AFAIR it's not reliable on iOS. So we'd be never able to duplicate the same behavior/UX on iOS.).

Then I tried to make my original approach work, while using patterns we have elsewhere in the app as much as possible (if not specific to media upload flows)

Just a couple of thoughts and implementation limitations.

  • I'm a bit concerned the actions (retry, delete) might be too small -> If I recall correctly the recommended dimensions for a clickable area is 48dp x 48dp. Wdyt?
  • The way the actions line-break in "State 3 alt layout" isn't easy to implement. It's not impossible, but not natively supported. We can line-break the text before the actions or line-break the text of the actions, but not move both the actions to the next line when they don't fit on the previous line.
    line-break

I also had a look at what corresponding information we could display on the post cards for each of these states

Looks good ;), but I'd suggest implementing this in a low priority ticket. I think the current labels should do the job for now and we can improve it later - "Local Changes", "Uploading media" and "Unable to upload this post's media". Wdyt?

@loremattei loremattei added this to the 12.9 milestone Jul 1, 2019
@loremattei
Copy link
Contributor

Hey! I'm moving this to 12.9 since 12.8 has been cut. If you want this to make it into 12.8, please feel free to move it back, target the release/12.8 branch and ping me to build a new beta.

@peril-wordpress-mobile
Copy link

Warnings
⚠️ PR has more than 500 lines of code changing. Consider splitting into smaller PRs if possible.

Generated by 🚫 dangerJS

@malinajirka
Copy link
Contributor Author

@maxme It's ready for another round, thank you 🙇.

I've done a lot of changes. The issue you've mentioned got fixed via another PR. I also added a check so we show the "Retry all/Remove all failed media" dialog in this scenario to keep consistency with the editor.

The PR contains too many changes :(. Let me know if reviewing it is to difficult and I'll try to cherry-pick some of the changes and divide it into more PRs. (not sure if it's worth it and if it's even feasible)

@maxme
Copy link
Contributor

maxme commented Jul 4, 2019

The issue you've mentioned got fixed via another PR.

Was it fixed via another PR and is also fixed in this branch? I'm asking this because I found a similar issue:

  • In airplane mode, create a new post.
  • Add a featured image.
  • Tap publish.
  • Wait for the error (not sure why the post is uploading for so long since the device is in airplaine mode?)
  • Turn airplane mode off, and tap "retry" on the failed upload.
  • Wait for the post to be published.
  • Open the published post and notice the featured image disappeared.

Demo video

@malinajirka
Copy link
Contributor Author

@maxme I've just tested this several times on a Pixel 2 emulator (Android 9) and Pixel 3 hw device and it worked as expected. Do you have any more info which might be relevant to the issue?

P.S. What I encountered one time was that the upload never failed/timed out so I had to restart the app. But I don't think it's relevant to this issue and I'm not able to reproduce it.

@peril-wordpress-mobile
Copy link

Warnings
⚠️ PR has more than 500 lines of code changing. Consider splitting into smaller PRs if possible.

Generated by 🚫 dangerJS

@malinajirka
Copy link
Contributor Author

malinajirka commented Jul 10, 2019

As we discussed on Slack I'm still not able to reproduce this issue without a debugger. However, when I put a breakpoint at the right spot, I can reproduce it sometimes.

I think the issue is that we sometimes start the UploadService with "Retry upload" intent more than once. The first invocation will

  1. Get failed media uploads from the database
  2. Set their upload state to QUEUED

However, when the second invocation tries to get the failed media uploads from the database, the database returns an empty set as all the media are already in QUEUED state (not FAILED). Therefore, the post is enqueued for upload ignoring its media.
I've added this simple check to prevent this issue from happening. I consider fixing the issue on the level of LocalDraftUploadStarter, however, I think this solution is actually more robust. As it also fixes case when the user clicked on "Retry" multiple times (it's usually not possible, as when the user clicks on retry, the retry button disappears - however, I was able to reproduce it on a slow device).

@maxme It's ready for another round. The issue wasn't related to the changes made in this PR, however, it made the bug easier to reproduce. It should be fixed in 3ffcb23. This fix should also fix the following issue -> #9704.

Thank you for helping me reproducing the issue and finding the main cause 🙇

@malinajirka
Copy link
Contributor Author

We found another scenario under which the post was uploaded and the featured image got removed.
Steps

  1. Turn on airplane mode
  2. Create a draft and add a featured image
  3. Create a second draft and the same featured image
  4. Go back to Post list
  5. Turn off airplane mode
  6. Notice the second draft gets uploaded without its featured image

This issue should be fixed in #10204

However, there is one more issue we'll need to fix when 10204 is merged into this branch.

  1. Turn on airplane mode
  2. Create a draft
  3. add an image into the content of the post
  4. Set the same image as featured image
  5. Go back to Post list
  6. Turn off airplane mode
  7. Notice the draft gets uploaded without its featured image

Copy link
Contributor

@maxme maxme left a comment

Choose a reason for hiding this comment

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

Just a minor comment. The feature works as expected (if we ignore the issues with media uploads).

if (resultCode == RESULT_OK && data.hasExtra(PhotoPickerActivity.EXTRA_MEDIA_ID)) {
long mediaId = data.getLongExtra(PhotoPickerActivity.EXTRA_MEDIA_ID, 0);
setFeaturedImageId(mediaId);
if (resultCode == RESULT_OK) {
Copy link
Contributor

Choose a reason for hiding this comment

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

resultCode == RESULT_OK is always true here (tested above on line 3095).

Side note: I guess we can improve this when we revamp this file, but this is quite unclear why PHOTO_PICKER and STOCK_MEDIA_PICKER_SINGLE_SELECT codes are specific to the featured image (I had to check where ActivityLauncher.showPhotoPickerForResult was called).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 5f63df8

HashSet<Integer> mediaIds = new HashSet<>();
for (MediaModel media : failedMedia) {
mediaIds.add(media.getId());
// featured image isn't in the editor but in the Post Settings fragment, so we want to skip it
Copy link
Contributor

Choose a reason for hiding this comment

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

👍

@malinajirka
Copy link
Contributor Author

malinajirka commented Jul 12, 2019

The feature works as expected (if we ignore the issues with media uploads).

The issue with media uploads should be fixed now. I've merged develop into the branch + add this fix. It'd be great if you tested it as I can't reproduce it without a debugger. 🤞 Thanks!

Copy link
Contributor

@maxme maxme left a comment

Choose a reason for hiding this comment

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

:shipit:

@maxme maxme merged commit 90e6552 into develop Jul 12, 2019
@oguzkocer oguzkocer deleted the issue/9560-offline-featured-image branch April 15, 2020 12:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Offline Support: Can't Set a Featured Image while offline.

6 participants