feat(Editor): add return value on file upload callback#534
Conversation
Reviewer's guide (collapsed on small PRs)Reviewer's GuideThis PR enhances the editor’s file upload flow by allowing the OnFileUpload callback to return a URL, which is then used for the inserted image instead of a temporary blob. It updates both the JS initialization logic to await and apply the returned URL, and the C# interop signature to propagate the string result. Sequence diagram for updated file upload and image insertion flowsequenceDiagram
participant JS as Editor.razor.js
participant CSharp as Editor.razor.cs
participant Callback as OnFileUpload
actor User
User->>JS: Selects file(s) to upload
JS->>CSharp: ImageUpload(name, type, size, stream)
CSharp->>Callback: OnFileUpload(file)
Callback-->>CSharp: Returns image URL
CSharp-->>JS: Returns image URL
JS->>JS: createImage(file, url)
JS->>JS: Insert image node with URL into editor
Class diagram for updated Editor file upload callbackclassDiagram
class Editor {
+Func<EditorUploadFile, Task<string>>? OnFileUpload
+Task<string> ImageUpload(string name, string contentType, long size, IJSStreamReference stream)
}
class EditorUploadFile {
+string Name
+string ContentType
+long Size
+Stream Data
}
Editor --> EditorUploadFile: uses
Editor : OnFileUpload returns Task<string> (URL)
Editor : ImageUpload returns string (URL)
Flow diagram for new image insertion using returned URLflowchart TD
A[User selects file] --> B[JS receives file]
B --> C[JS calls C# ImageUpload]
C --> D[C# calls OnFileUpload]
D --> E[OnFileUpload returns URL]
E --> F[JS creates image with URL]
F --> G[Image inserted into editor]
File-Level Changes
Assessment against linked issues
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey there - I've reviewed your changes and they look great!
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location> `src/components/BootstrapBlazor.SummerNote/Components/Editor/Editor.razor.js:222` </location>
<code_context>
}
-const createImage = file => {
+const createImage = (file, url) => {
const element = document.createElement('img');
- element.src = URL.createObjectURL(file);
+ element.src = url || URL.createObjectURL(file);
return element;
}
</code_context>
<issue_to_address>
The fallback to URL.createObjectURL may leak object URLs if not revoked.
Add logic to revoke the object URL after the image loads to prevent memory leaks when using the fallback.
</issue_to_address>
### Comment 2
<location> `src/components/BootstrapBlazor.SummerNote/Components/Editor/Editor.razor.cs:282` </location>
<code_context>
- await OnFileUpload(file);
+ ret = await OnFileUpload(file);
}
+ return ret ?? "";
}
</code_context>
<issue_to_address>
Returning an empty string may mask upload failures.
Consider returning null or a distinct error value instead, so client-side code can reliably detect upload failures and handle them appropriately.
</issue_to_address>
<suggested_fix>
<<<<<<< SEARCH
public async Task<string> ImageUpload(string name, string contentType, long size, IJSStreamReference stream)
{
string? ret = null;
await using var data = await stream.OpenReadStreamAsync(size);
var file = new EditorUploadFile(name, contentType, size, data);
if (OnFileUpload != null)
{
ret = await OnFileUpload(file);
}
return ret ?? "";
}
=======
public async Task<string?> ImageUpload(string name, string contentType, long size, IJSStreamReference stream)
{
string? ret = null;
await using var data = await stream.OpenReadStreamAsync(size);
var file = new EditorUploadFile(name, contentType, size, data);
if (OnFileUpload != null)
{
ret = await OnFileUpload(file);
}
return ret;
}
>>>>>>> REPLACE
</suggested_fix>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| const createImage = (file, url) => { | ||
| const element = document.createElement('img'); | ||
| element.src = URL.createObjectURL(file); | ||
| element.src = url || URL.createObjectURL(file); |
There was a problem hiding this comment.
suggestion (bug_risk): The fallback to URL.createObjectURL may leak object URLs if not revoked.
Add logic to revoke the object URL after the image loads to prevent memory leaks when using the fallback.
| public async Task<string> ImageUpload(string name, string contentType, long size, IJSStreamReference stream) | ||
| { | ||
| var data = await stream.OpenReadStreamAsync(size); | ||
| string? ret = null; | ||
| await using var data = await stream.OpenReadStreamAsync(size); | ||
| var file = new EditorUploadFile(name, contentType, size, data); | ||
| if (OnFileUpload != null) | ||
| { | ||
| await OnFileUpload(file); | ||
| ret = await OnFileUpload(file); | ||
| } | ||
| return ret ?? ""; | ||
| } |
There was a problem hiding this comment.
suggestion (bug_risk): Returning an empty string may mask upload failures.
Consider returning null or a distinct error value instead, so client-side code can reliably detect upload failures and handle them appropriately.
| public async Task<string> ImageUpload(string name, string contentType, long size, IJSStreamReference stream) | |
| { | |
| var data = await stream.OpenReadStreamAsync(size); | |
| string? ret = null; | |
| await using var data = await stream.OpenReadStreamAsync(size); | |
| var file = new EditorUploadFile(name, contentType, size, data); | |
| if (OnFileUpload != null) | |
| { | |
| await OnFileUpload(file); | |
| ret = await OnFileUpload(file); | |
| } | |
| return ret ?? ""; | |
| } | |
| public async Task<string?> ImageUpload(string name, string contentType, long size, IJSStreamReference stream) | |
| { | |
| string? ret = null; | |
| await using var data = await stream.OpenReadStreamAsync(size); | |
| var file = new EditorUploadFile(name, contentType, size, data); | |
| if (OnFileUpload != null) | |
| { | |
| ret = await OnFileUpload(file); | |
| } | |
| return ret; | |
| } |
Link issues
fixes #533
Summary By Copilot
Regression?
Risk
Verification
Packaging changes reviewed?
☑️ Self Check before Merge
Summary by Sourcery
Allow the file upload callback to return a custom URL and use it for inserting uploaded images into the editor
New Features:
Bug Fixes:
Enhancements: