Skip to content

Commit

Permalink
Removes Task.Delay from file count (#192)
Browse files Browse the repository at this point in the history
* Removes Task.Delay from file count by using a promise to block GetFile only for dataTransfers

* Add Promise for datatransfers

* Some cleanup, build verif
  • Loading branch information
Tewr authored Jul 4, 2023
1 parent 0374882 commit c4e4504
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 132 deletions.
22 changes: 1 addition & 21 deletions src/Blazor.FileReader/FileReaderRef.cs
Original file line number Diff line number Diff line change
Expand Up @@ -215,32 +215,12 @@ internal class FileReaderRef : IFileReaderRef
{
public async Task<IEnumerable<IFileReference>> EnumerateFilesAsync()
{
var count = await GetFileCount();
var count = await FileReaderJsInterop.GetFileCount(ElementRef);
var result = Enumerable.Range(0, Math.Max(0, count))
.Select(index => (IFileReference)new FileReference(this, index));
return result;
}

// Get the count twice. Ensure that both numbers are the same. if not, keep getting until the number is stable.
// This is a workaround for the event handler firing off before the AfterDrop event.
public async Task<int> GetFileCount()
{
var lastCount = -10;
while (true)
{
var currentCount = await FileReaderJsInterop.GetFileCount(ElementRef);

if (lastCount == currentCount)
{
break;
}

lastCount = currentCount;
await Task.Delay(500);
}

return lastCount;
}
public async Task RegisterDropEventsAsync(bool additive) =>
await RegisterDropEventsAsync(new DropEventsOptions { Additive = additive });

Expand Down
29 changes: 19 additions & 10 deletions src/Blazor.FileReader/script/Clipboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,29 @@ import { ConcatFileList } from "./ConcatFileList"
function RegisterPasteEvent(this: FileReaderComponent, element: HTMLElement, registerOptions: PasteEventOptions): boolean {
this.LogIfNull(element);

const pasteHandler = (ev: ClipboardEvent) => {
const pasteHandler = async (ev: ClipboardEvent) => {
if (ev.target instanceof HTMLElement) {
let list = ev.clipboardData.files;
if (list.length > 0) {
ev.preventDefault();
if (registerOptions.additive) {
const existing = this.elementDataTransfers.get(element);
if (existing !== undefined && existing.length > 0) {
list = new ConcatFileList(existing, list);
const listPromise = new Promise<FileList>(async (resolve, reject) => {
try {
let list = ev.clipboardData.files;
if (list.length > 0) {
ev.preventDefault();
if (registerOptions.additive) {
const existing = await this.elementDataTransfers.get(element);
if (existing !== undefined && existing.length > 0) {
list = new ConcatFileList(existing, list);
}
}
}

resolve(list);
}
catch (e) {
reject(e);
}
}
});

this.elementDataTransfers.set(element, list);
this.elementDataTransfers.set(element, listPromise);
}
};

Expand Down
25 changes: 16 additions & 9 deletions src/Blazor.FileReader/script/DragnDrop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,19 +146,26 @@ function RegisterDropEvents(this: FileReaderComponent, element: HTMLElement, reg
this.LogIfNull(element);

const onAfterDropHandler = BuildDragEventHandler(registerOptions.onDropMethod, registerOptions.onDropScript, dropEvent);
const dropHandler = async (ev: DragEvent) => {
const dropHandler = (ev: DragEvent) => {
ev.preventDefault();
this.elementDataTransfers.clear();

if (ev.target instanceof HTMLElement) {
let files = await getFilesAsync((ev.dataTransfer));
if (registerOptions.additive) {
const existing = this.elementDataTransfers.get(element) ?? new FileList();
if (existing.length > 0) {
files = new ConcatFileList(existing, files);
const filePromise = new Promise<FileList>(async (resolve, reject) => {
try {
let files = await getFilesAsync(ev.dataTransfer);
if (registerOptions.additive) {
const existing = await this.elementDataTransfers.get(element) ?? new FileList();
if (existing.length > 0) {
files = new ConcatFileList(existing, files);
}
}
resolve(files);
} catch (e) {
reject(e);
}
}
});

this.elementDataTransfers.set(element, files);
this.elementDataTransfers.set(element, filePromise);
}

onAfterDropHandler(ev, element, this);
Expand Down
22 changes: 11 additions & 11 deletions src/Blazor.FileReader/script/FileReaderComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class FileReaderComponent {

protected readonly dragElements = new Map<HTMLElement, DragEvents>();
protected readonly pasteElements = new Map<HTMLElement, EventListenerOrEventListenerObject>();
protected readonly elementDataTransfers = new Map<HTMLElement, FileList>();
protected readonly elementDataTransfers = new Map<HTMLElement, Promise<FileList>>();
private readonly readResultByTaskId = new Map<number, IReadFileData>();

protected LogIfNull(element: HTMLElement) {
Expand All @@ -29,29 +29,29 @@ class FileReaderComponent {

public UnregisterPasteEvent = UnregisterPasteEvent;

private GetFiles(element: HTMLElement): FileList {
private async GetFiles(element: HTMLElement): Promise<FileList> {
let files: FileList = null;
if (element instanceof HTMLInputElement) {
files = (element as HTMLInputElement).files;
} else {
const dataTransfer = this.elementDataTransfers.get(element);
if (dataTransfer) {
files = dataTransfer;
files = await dataTransfer;
}
}

return files;
}

public GetJSObjectReference(element: HTMLElement, fileIndex: number): File {
public async GetJSObjectReference(element: HTMLElement, fileIndex: number): Promise<File> {
this.LogIfNull(element);
const files = this.GetFiles(element);
const files = await this.GetFiles(element);
return files.item(fileIndex);
}

public GetFileCount = (element: HTMLElement): number => {
public async GetFileCount(element: HTMLElement): Promise<number> {
this.LogIfNull(element);
const files = this.GetFiles(element);
const files = await this.GetFiles(element);
if (!files) {
return -1;
}
Expand All @@ -71,9 +71,9 @@ class FileReaderComponent {
};

// Called from cs.
public GetFileInfoFromElement = (element: HTMLElement, index: number): IFileInfo => {
public async GetFileInfoFromElement(element: HTMLElement, index: number): Promise<IFileInfo> {
this.LogIfNull(element);
const files = this.GetFiles(element);
const files = await this.GetFiles(element);
if (!files) {
return null;
}
Expand Down Expand Up @@ -112,10 +112,10 @@ class FileReaderComponent {
return result;
}

public OpenRead = (element: HTMLElement, fileIndex: number, useWasmSharedBuffer: boolean): number => {
public async OpenRead(element: HTMLElement, fileIndex: number, useWasmSharedBuffer: boolean): Promise<number> {
this.LogIfNull(element);

const files = this.GetFiles(element);
const files = await this.GetFiles(element);
if (!files) {
throw 'No FileList available.';
}
Expand Down
Loading

0 comments on commit c4e4504

Please sign in to comment.