move UI logic from FileService to FileManager, add progressive retry logic, update file attributes if uploading a new version of a file, clean up temporary artifacts on failure, improve upload efficiency
This commit is contained in:
		| @ -2,27 +2,17 @@ using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Net; | ||||
| using System.Net.Http; | ||||
| using System.Threading; | ||||
| using System.Threading.Tasks; | ||||
| using Microsoft.JSInterop; | ||||
| using Oqtane.Documentation; | ||||
| using Oqtane.Models; | ||||
| using Oqtane.Shared; | ||||
| using Oqtane.UI; | ||||
|  | ||||
| namespace Oqtane.Services | ||||
| { | ||||
|     [PrivateApi("Don't show in the documentation, as everything should use the Interface")] | ||||
|     public class FileService : ServiceBase, IFileService | ||||
|     { | ||||
|         private readonly SiteState _siteState; | ||||
|         private readonly IJSRuntime _jsRuntime; | ||||
|  | ||||
|         public FileService(HttpClient http, SiteState siteState, IJSRuntime jsRuntime) : base(http, siteState) | ||||
|         { | ||||
|             _siteState = siteState; | ||||
|             _jsRuntime = jsRuntime; | ||||
|         } | ||||
|         public FileService(HttpClient http, SiteState siteState) : base(http, siteState) { } | ||||
|  | ||||
|         private string Apiurl => CreateApiUrl("File"); | ||||
|  | ||||
| @ -75,54 +65,6 @@ namespace Oqtane.Services | ||||
|             return await GetJsonAsync<File>($"{Apiurl}/upload?url={WebUtility.UrlEncode(url)}&folderid={folderId}&name={name}"); | ||||
|         } | ||||
|  | ||||
|         public async Task<string> UploadFilesAsync(int folderId, string[] files, string id) | ||||
|         { | ||||
|             return await UploadFilesAsync(folderId.ToString(), files, id); | ||||
|         } | ||||
|  | ||||
|         public async Task<string> UploadFilesAsync(string folder, string[] files, string id) | ||||
|         { | ||||
|             string result = ""; | ||||
|  | ||||
|             var interop = new Interop(_jsRuntime); | ||||
|             await interop.UploadFiles($"{Apiurl}/upload", folder, id, _siteState.AntiForgeryToken); | ||||
|  | ||||
|             // uploading files is asynchronous so we need to wait for the upload to complete | ||||
|             bool success = false; | ||||
|             int attempts = 0; | ||||
|             while (attempts < 5 && success == false) | ||||
|             { | ||||
|                 Thread.Sleep(2000); // wait 2 seconds | ||||
|                 result = ""; | ||||
|  | ||||
|                 List<File> fileList = await GetFilesAsync(folder); | ||||
|                 if (fileList.Count > 0) | ||||
|                 { | ||||
|                     success = true; | ||||
|                     foreach (string file in files) | ||||
|                     { | ||||
|                         if (!fileList.Exists(item => item.Name == file)) | ||||
|                         { | ||||
|                             success = false; | ||||
|                             result += file + ","; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 attempts += 1; | ||||
|             } | ||||
|  | ||||
|             await interop.SetElementAttribute(id + "ProgressInfo", "style", "display: none;"); | ||||
|             await interop.SetElementAttribute(id + "ProgressBar", "style", "display: none;"); | ||||
|  | ||||
|             if (!success) | ||||
|             { | ||||
|                 result = result.Substring(0, result.Length - 1); | ||||
|             } | ||||
|  | ||||
|             return result; | ||||
|         } | ||||
|  | ||||
|         public async Task<byte[]> DownloadFileAsync(int fileId) | ||||
|         { | ||||
|             return await GetByteArrayAsync($"{Apiurl}/download/{fileId}"); | ||||
|  | ||||
| @ -66,27 +66,6 @@ namespace Oqtane.Services | ||||
|         /// <returns></returns> | ||||
|         Task<File> UploadFileAsync(string url, int folderId, string name); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Upload one or more files. | ||||
|         /// </summary> | ||||
|         /// <param name="folderId">Target <see cref="Folder"/></param> | ||||
|         /// <param name="files">The files to upload, serialized as a string.</param> | ||||
|         /// <param name="fileUploadName">A task-identifier, to ensure communication about this upload.</param> | ||||
|         /// <returns></returns> | ||||
|         Task<string> UploadFilesAsync(int folderId, string[] files, string fileUploadName); | ||||
|  | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Upload one or more files. | ||||
|         /// </summary> | ||||
|         /// <param name="folder">Target <see cref="Folder"/> | ||||
|         /// TODO: todoc verify exactly from where the folder path must start | ||||
|         /// </param> | ||||
|         /// <param name="files">The files to upload, serialized as a string.</param> | ||||
|         /// <param name="fileUploadName">A task-identifier, to ensure communication about this upload.</param> | ||||
|         /// <returns></returns> | ||||
|         Task<string> UploadFilesAsync(string folder, string[] files, string fileUploadName); | ||||
|  | ||||
|         /// <summary> | ||||
|         /// Get / download a file (the body). | ||||
|         /// </summary> | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Shaun Walker
					Shaun Walker