@@ -10,62 +10,120 @@ namespace Blazor.AdminLte
10
10
{
11
11
public partial class FileUploader
12
12
{
13
- [ Inject ] IFilesManager ? FilesManager { get ; set ; }
13
+ [ Inject ]
14
+ private IFilesManager FilesManager { get ; set ; }
15
+
14
16
private bool isUploading = false ;
15
17
private string ErrorMessage = string . Empty ;
16
18
private string dropClass = string . Empty ;
17
- private int maxAllowedFiles = 25 ;
18
- List < FileUploadProgress > filesQueue = new ( ) ;
19
-
19
+ private List < FileUploadProgress > _filesQueue = new ( ) ;
20
+
21
+ [ Parameter ]
22
+ public EventCallback < UploadResultDto > OnUploadFinished { get ; set ; }
23
+
24
+ [ Parameter ]
25
+ public int MaxAllowedFiles { get ; set ; } = 25 ;
26
+
27
+ [ Parameter ]
28
+ public long ? MaximumFileSizeInBytes { get ; set ; }
29
+
30
+ /// <summary>
31
+ /// Allowed extensions to upload. Must be specified with dot
32
+ /// </summary>
33
+ /// <example>
34
+ /// .json
35
+ /// </example>
36
+ [ Parameter ]
37
+ public string [ ] AllowedExtensions { get ; set ; }
20
38
21
39
private void AddFilesToQueue ( InputFileChangeEventArgs e )
22
40
{
23
41
dropClass = string . Empty ;
24
42
ErrorMessage = string . Empty ;
25
43
26
- if ( e . FileCount > maxAllowedFiles )
44
+ if ( e . FileCount > MaxAllowedFiles )
45
+ {
46
+ ErrorMessage = $ "A maximum of { MaxAllowedFiles } is allowed, you have selected { e . FileCount } files!";
47
+ return ;
48
+ }
49
+
50
+ if ( _filesQueue . Count > MaxAllowedFiles )
27
51
{
28
- ErrorMessage = $ "A maximum of { maxAllowedFiles } is allowed, you have selected { e . FileCount } files!";
52
+ ErrorMessage = $ "Queue already contains maximum number of items ({ MaxAllowedFiles } )! Clear the queue to continue.";
53
+ return ;
29
54
}
30
- else
55
+
56
+ var files = e . GetMultipleFiles ( MaxAllowedFiles ) ;
57
+ var fileCount = _filesQueue . Count ;
58
+
59
+ // Validate allowed extensions
60
+ if ( AllowedExtensions ? . Any ( ) == true )
31
61
{
32
- var files = e . GetMultipleFiles ( maxAllowedFiles ) ;
33
- var fileCount = filesQueue . Count ;
62
+ var filesValid =
63
+ files . All ( x => AllowedExtensions . Any (
64
+ ext => string . Equals ( ext , Path . GetExtension ( x . Name ) , StringComparison . InvariantCultureIgnoreCase ) ) ) ;
34
65
35
- foreach ( var file in files )
66
+ if ( ! filesValid )
36
67
{
37
- var progress = new FileUploadProgress ( file , file . Name , file . Size , fileCount ) ;
38
- filesQueue . Add ( progress ) ;
39
- fileCount ++ ;
68
+ ErrorMessage = $ "Uploaded file(s) has invalid extension. Allowed extensions: { string . Join ( ", " , AllowedExtensions ) } .";
69
+ return ;
40
70
}
41
71
}
42
- } //PlaceFilesInQue
43
72
73
+ if ( MaximumFileSizeInBytes . HasValue &&
74
+ files . Any ( x => x . Size > MaximumFileSizeInBytes ) )
75
+ {
76
+ ErrorMessage = $ "Reached maximum file size! Please select file(s) smaller than { ToReadableUnits ( ) } ";
77
+ return ;
78
+ }
79
+
80
+ foreach ( var file in files )
81
+ {
82
+ var progress = new FileUploadProgress ( file , file . Name , file . Size , fileCount ) ;
83
+ _filesQueue . Add ( progress ) ;
84
+ fileCount ++ ;
85
+ }
86
+ }
87
+
88
+ private string ToReadableUnits ( )
89
+ {
90
+ var kb = Math . Round ( MaximumFileSizeInBytes . Value / 1024.00 ) ;
91
+
92
+ // TODO: Convert to MB if too big
93
+ return $ "{ kb } kB";
94
+ }
44
95
45
96
private async Task UploadFileQueue ( )
46
97
{
47
98
isUploading = true ;
48
99
await InvokeAsync ( StateHasChanged ) ;
49
100
50
- foreach ( var file in filesQueue . OrderByDescending ( x => x . FileId ) )
101
+ foreach ( var file in _filesQueue . OrderByDescending ( x => x . FileId ) )
51
102
{
52
103
if ( ! file . HasBeenUploaded )
53
104
{
54
105
await UploadChunks ( file ) ;
55
106
file . HasBeenUploaded = true ;
107
+ if ( OnUploadFinished . HasDelegate )
108
+ {
109
+ await OnUploadFinished . InvokeAsync ( new UploadResultDto
110
+ {
111
+ FileName = file . FileName ,
112
+ Uid = file . Uid
113
+ } ) ;
114
+ }
56
115
}
57
116
}
58
117
59
118
isUploading = false ;
60
- } //UploadFileQueue
61
-
119
+ }
62
120
63
121
private async Task UploadChunks ( FileUploadProgress file )
64
122
{
65
- var TotalBytes = file . Size ;
123
+ var totalBytes = file . Size ;
66
124
long chunkSize = 400000 ;
67
- long numChunks = TotalBytes / chunkSize ;
68
- long remainder = TotalBytes % chunkSize ;
125
+ long numChunks = totalBytes / chunkSize ;
126
+ long remainder = totalBytes % chunkSize ;
69
127
70
128
string nameOnly = Path . GetFileNameWithoutExtension ( file . FileName ) ;
71
129
var extension = Path . GetExtension ( file . FileName ) ;
@@ -83,15 +141,16 @@ private async Task UploadChunks(FileUploadProgress file)
83
141
{
84
142
Data = buffer ,
85
143
FileName = newFileNameWithoutPath ,
86
- Offset = filesQueue [ file . FileId ] . UploadedBytes ,
87
- FirstChunk = firstChunk
144
+ Offset = _filesQueue [ file . FileId ] . UploadedBytes ,
145
+ FirstChunk = firstChunk ,
146
+ Uid = file . Uid
88
147
} ;
89
148
90
- await FilesManager . UploadFileChunk ( chunk ) ;
149
+ await FilesManager . UploadFileChunkAsync ( chunk ) ;
91
150
firstChunk = false ;
92
151
93
152
// Update our progress data and UI
94
- filesQueue [ file . FileId ] . UploadedBytes += chunkSize ;
153
+ _filesQueue [ file . FileId ] . UploadedBytes += chunkSize ;
95
154
await InvokeAsync ( StateHasChanged ) ;
96
155
}
97
156
@@ -104,53 +163,53 @@ private async Task UploadChunks(FileUploadProgress file)
104
163
{
105
164
Data = buffer ,
106
165
FileName = newFileNameWithoutPath ,
107
- Offset = filesQueue [ file . FileId ] . UploadedBytes ,
108
- FirstChunk = firstChunk
166
+ Offset = _filesQueue [ file . FileId ] . UploadedBytes ,
167
+ FirstChunk = firstChunk ,
168
+ Uid = file . Uid
109
169
} ;
110
- await FilesManager . UploadFileChunk ( chunk ) ;
170
+
171
+ await FilesManager . UploadFileChunkAsync ( chunk ) ;
111
172
112
173
// Update our progress data and UI
113
- filesQueue [ file . FileId ] . UploadedBytes += remainder ;
114
- //await ListFiles();
174
+ _filesQueue [ file . FileId ] . UploadedBytes += remainder ;
115
175
await InvokeAsync ( StateHasChanged ) ;
116
176
}
117
177
}
118
- } //UploadChunks
119
-
178
+ }
120
179
121
180
private void RemoveFromQueue ( int fileId )
122
181
{
123
- var itemToRemove = filesQueue . SingleOrDefault ( x => x . FileId == fileId ) ;
182
+ var itemToRemove = _filesQueue . SingleOrDefault ( x => x . FileId == fileId ) ;
124
183
if ( itemToRemove != null )
125
- filesQueue . Remove ( itemToRemove ) ;
126
- } //RemoveFromQueue
127
-
184
+ {
185
+ _filesQueue . Remove ( itemToRemove ) ;
186
+ }
187
+ }
128
188
129
- private void ClearFileQueue ( )
189
+ public void ClearFileQueue ( )
130
190
{
131
- filesQueue . Clear ( ) ;
132
- } //ClearFileQueue
133
-
191
+ _filesQueue . Clear ( ) ;
192
+ }
134
193
135
- record FileUploadProgress ( IBrowserFile File , string FileName , long Size , int FileId )
194
+ public record FileUploadProgress ( IBrowserFile File , string FileName , long Size , int FileId )
136
195
{
137
196
public IBrowserFile FileData { get ; set ; } = File ;
138
197
public int FileId { get ; set ; } = FileId ;
139
198
public long UploadedBytes { get ; set ; }
140
199
public double UploadedPercentage => ( double ) UploadedBytes / ( double ) Size * 100d ;
141
200
public bool HasBeenUploaded { get ; set ; } = false ;
142
- } //FileUploadProgress
143
-
201
+ public Guid Uid { get ; set ; } = Guid . NewGuid ( ) ;
202
+ }
144
203
145
- void HandleDragEnter ( )
204
+ private void HandleDragEnter ( )
146
205
{
147
206
dropClass = "dropzone-active" ;
148
- } //HandleDragEnter
149
- void HandleDragLeave ( )
207
+ }
208
+
209
+ private void HandleDragLeave ( )
150
210
{
151
211
dropClass = string . Empty ;
152
- } //HandleDragLeave
153
-
212
+ }
154
213
155
214
/*
156
215
protected override async Task OnInitializedAsync()
@@ -164,8 +223,5 @@ private async Task ListFiles()
164
223
await InvokeAsync(StateHasChanged);
165
224
}
166
225
*/
167
-
168
-
169
-
170
226
}
171
227
}
0 commit comments