Skip to content

fix: Wait for upload and refresh the view afterwards #7252

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

Open
wants to merge 23 commits into
base: v5/develop
Choose a base branch
from

Conversation

bastianallgeier
Copy link
Member

@bastianallgeier bastianallgeier commented May 28, 2025

Changelog

Enhancements

  • New async TextareaInput.restoreSelection() method
  • Various TextareaInput methods have been turned into async methods for more stable async/await control throughout all TextareaInput methods.
    • insert
    • insertFile
    • insertUpload
    • prepend
    • toggle
    • wrap
  • The upload module now sends a file.upload.error event for every file that could not be uploaded.
  • New upload.announce() method, which sends the success notification and model.update event after uploads have successfully completed.

Fixes

  • panel.content.save() now calls panel.content.cancelSaving() to make sure that any old scheduled save requests are properly cancelled. This could have lead to potential race conditions before.
  • The FilesField no longer sends unnecessary file.upload and model.update emitters after upload. Those lead to duplicate section reload requests so far. After uploads, the panel.upload.done() already takes care of reloading the current view and all its sections.
  • The TextareaInput.insertUpload() method now uses await panel.content.update() to push text value changes directly to the changes API and to reload the view correctly. This fixes [v5] Uploading a file by dragging it over the textarea field doesn't work #7249
  • The upload module sends the file.upload event directly when a file has been uploaded and passes the file object correctly. Before this change, the file.upload event was only called in the FilesField and FilesSection components when all uploads finished.
  • Both the upload.done() and upload.cancel() handlers now properly emit the complete event if there are any completed uploads.

Refactoring

  • TextareaInput.selectionRange and TextareaInput.restoreSelection() are used to replace the old restoreSelectionCallback method in dialog events for better async control.
  • Removed unnecessary complete handler in FilesSection. The upload module already takes care of the notifications and events.

Deprecated

  • TextareaInput.restoreSelectionCallback() Use TextareaInput.restoreSelection().

Breaking changes

None

Sandbox

There's a new "Uploads" tab in the Textarea setup in the sandbox.

Ready?

  • In-code documentation (wherever needed)
  • Tests and CI checks all pass

For review team

  • Add lab and/or sandbox examples (wherever helpful)
  • Add changes & docs to release notes draft in Notion

@afbora
Copy link
Member

afbora commented May 28, 2025

@bastianallgeier Still doesn't work :(

@bastianallgeier
Copy link
Member Author

That's very weird. Works perfectly for me now. Ok, then I need to double-check again.

@distantnative
Copy link
Member

It does work for me. @afbora sure there aren't any old files cached, e.g. in media/panel if you're running it via npm run build not npm run dev?

@afbora
Copy link
Member

afbora commented May 29, 2025

@distantnative I'm testing always via build. The issue still valid for me. Sometimes works sometime not. With this PR better but it's not completely fixed.

@distantnative
Copy link
Member

@afbora Very weird. Any insights on the preconditions to have it succeed vs. when it fails?

@afbora
Copy link
Member

afbora commented May 29, 2025

@distantnative I can reproduce it with every request via browser's slow 4G or 3G network throttling feature.

Not sure but I think this content lost happens when pages/field/files request done after save request.

@distantnative
Copy link
Member

distantnative commented May 29, 2025

@afbora You mention "save request" - so it's not just uploading what you are trying to do (as described in the original issue) but some combination with uploading and directly saving (and if you say slow connection, maybe you are trying to super quickly save before the upload request is actually done)?

But then I would think this fix might still be right, but we have in addition still problems with a race condition between content.save and content.publish (or similar).

@afbora
Copy link
Member

afbora commented May 29, 2025

I mean /save request after uploading done (automaticly and after modal closed) with "save request" not page save request via manual clicking.

@distantnative
Copy link
Member

Mmm ok. Couldn't reproduce it. Even when throttling speed.

One thought could be if insertFile takes longer than the update call. There is a setTimeout involved. So maybe that.

@afbora
Copy link
Member

afbora commented May 29, 2025

@distantnative Here the screencast:

Kayit.2025-05-30.010557.mp4

@bastianallgeier
Copy link
Member Author

I think our main issue really is the view reloading in the done event of the uploader. I have an idea.

@bastianallgeier bastianallgeier force-pushed the v5/fix/7249-textarea-upload branch from 1e6d038 to 7300ab4 Compare May 30, 2025 12:09
@bastianallgeier bastianallgeier force-pushed the v5/fix/7249-textarea-upload branch from 7300ab4 to 0c76efa Compare May 30, 2025 12:58
@bastianallgeier
Copy link
Member Author

@distantnative @afbora I've refactored the code quite a bit and I hope this PR is not getting too big.

  • We had a couple places in the TextareaInput component that made race conditions possible. I've refactored them with async/await to be more in control of what we actually do
  • The upload module had a few weird inconsistencies with event emitting. I've cleaned it up to better see what we are doing at which point
  • We only need to emit the model.update event once all file uploads are finished. This will trigger all sections to be reloaded. A full panel.view.reload() is not necessary here and will always lead to issues with open drawers.

Sandbox

I've added a new "Others > Uploads" examples page where we can test textarea, structure, blocks and files fields with uploads and we can also see if a files section updates accordingly.

@afbora
Copy link
Member

afbora commented May 30, 2025

@bastianallgeier I've tested now. There is restore selection issue at first glance.

Click/select to random place of the paragraph text and try to drag/drop items to selected area. You can repeat this with selecting random places of the text with drag/drop an item. You'll see the issue that dragtexts are inserted always same places instead of selected area.

Copy link
Member

@distantnative distantnative left a comment

Choose a reason for hiding this comment

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

I also experienced what @afbora writes. Not always consistently but multiple times the selection would e.g. not be restored when canceling an upload or other dialog.

I think the issue is that the selectionRange gets stored inside the computed property. But the computed property actually does not get refreshed each time the selection changes. So it ends up restoring always the first state when the computed property got generated.

bastianallgeier and others added 2 commits June 2, 2025 12:22
Co-authored-by: Nico Hoffmann  ෴. <me@nhoffmann.com>
@bastianallgeier bastianallgeier force-pushed the v5/fix/7249-textarea-upload branch from 7e84c0a to cbb1cf6 Compare June 2, 2025 10:45
@bastianallgeier bastianallgeier force-pushed the v5/fix/7249-textarea-upload branch from 6c495a2 to bb504ff Compare June 2, 2025 12:08
@bastianallgeier
Copy link
Member Author

Your tests and comments made me realize that I had a logical issue in the way the selectionRange was stored but not updated when dialogs are opened. This makes no sense and leads to the issues that you describe. Then I realized that we can use the onselectionchange event of the input perfectly to always store the latest selection range and restore that one if it exists. This works really well and cleans up the code some more.

I've tested everything in Firefox, Chrome and Safari and it seems to run smoothly now, but I would want to wait for another round of tests from your side.

@afbora
Copy link
Member

afbora commented Jun 2, 2025

@bastianallgeier I tried hundreds of times in different ways, but on one of my first attempts, the file disappeared once. Then I couldn't reproduce the problem again. I think it was cache related. So everything seems to be working fine 🎉

@bastianallgeier
Copy link
Member Author

@afbora that's great. I think we should wait for another look from @distantnative before we give it a go. I guess it's ok if we put it into rc.4

@bastianallgeier bastianallgeier modified the milestones: 5.0.0-rc.3, 5.0.0-rc.4 Jun 3, 2025
@distantnative
Copy link
Member

Haven't had much chance to test it myself, but no further comments on the code and totally fine for me to have it merged if you two tested it successfully 👍

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

Successfully merging this pull request may close these issues.

[v5] Uploading a file by dragging it over the textarea field doesn't work
3 participants