Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ public class BitFileInfo
[JsonPropertyName("fileId")] public string FileId { get; set; } = string.Empty;

/// <summary>
/// The index of the selected file.
/// The index of the file among the ones picked in this browser, which is what names the transfer behind
/// it. A preloaded file was never picked and has no transfer of its own, so its index is -1.
/// </summary>
[JsonPropertyName("index")] public int Index { get; set; }

Expand Down Expand Up @@ -95,6 +96,14 @@ public class BitFileInfo
/// </summary>
[JsonIgnore] public bool IsQueued { get; internal set; }

/// <summary>
/// Whether the file was handed over through the PreloadedFiles parameter of the BitFileUpload instead of
/// being picked in the browser, which is to say it is already on the server: there is no content on this
/// side to send, so it is never uploaded, and removing it deletes it from the server through the
/// RemoveUrl exactly like a file whose bytes got there through this component.
/// </summary>
[JsonIgnore] public bool IsPreloaded { get; internal set; }


// Whether a request of this file is on the wire right now. A second request for the same file would
// take over the connection of the first one and start it over from the beginning, so a repeated
Expand Down Expand Up @@ -128,9 +137,19 @@ public class BitFileInfo
/// <summary>
/// The message attached to the current <see cref="Status"/> of the file: the reason it was rejected by
/// the validations before the upload, or the body of the server response of its upload or removal.
/// A response body is truncated to its first 8 KB, since it crosses the Blazor Server circuit, whose
/// default message size limit an error page of a failing endpoint would otherwise exceed.
/// </summary>
[JsonIgnore] public string? Message { get; internal set; }

/// <summary>
/// The HTTP status code of the last upload or removal response this file received, which is what tells
/// an authorization problem from a payload that was too large or from a server that is temporarily down.
/// It is 0 when the request never reached the server at all - a network error, a timeout or an abort -
/// and null while no request of this file has come back yet.
/// </summary>
[JsonIgnore] public int? ResponseStatus { get; internal set; }

/// <summary>
/// The status of the file in the BitFileUpload.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,22 @@
}
else if (_ShowLabelButton)
{
<button @onclick="Browse"
<button @ref="_labelRef"
@onclick="Browse"
type="button"
id="@_buttonId"
disabled="@(IsEnabled is false)"
aria-label="@AriaLabel"
aria-describedby="@(_HasDescription ? _descriptionId : null)"
style="@Styles?.Label"
class="bit-upl-lbl @Classes?.Label">
@* the drop area is the one place a label reads better with a glyph than without, so it brings one
of its own; anywhere else the icon is opt-in. the text beside it already names the button. *@
@{ var labelIcon = BitIconInfo.From(LabelIcon, LabelIconName ?? (ShowDropArea ? "CloudUpload" : null)); }
@if (labelIcon is { IsEmpty: false })
{
<i style="@Styles?.LabelIcon" class="bit-upl-lic @labelIcon.GetCssClasses() @Classes?.LabelIcon" aria-hidden="true" />
}
@Label
</button>
}
Expand Down Expand Up @@ -57,7 +65,12 @@
away with them rather than staying behind as an empty landmark in the accessibility tree. *@
@if (HideFileView is false && Files.Any(f => f.Status != BitFileUploadStatus.Removed))
{
<div role="list" style="@Styles?.FileList" class="bit-upl-fl @Classes?.FileList">
@* the list is named, so that a screen reader user arriving at it is told what it holds rather than
only that it is a list of so many items. *@
<div role="list"
aria-label="@(FileListAriaLabel.HasValue() ? FileListAriaLabel : null)"
style="@Styles?.FileList"
class="bit-upl-fl @Classes?.FileList">
@* a removed file is not part of the list anymore, so it is left out of it here rather than
leaving an empty listitem behind for a custom template that renders nothing for it. *@
@foreach (var file in Files.Where(f => f.Status != BitFileUploadStatus.Removed))
Expand All @@ -77,5 +90,45 @@
</div>
}

@* the batch buttons stay where they are for as long as the list has files picked here, and the ones with
nothing to act on right now are marked aria-disabled rather than taken out or natively disabled: the
state changes on its own as uploads settle, and a focused button that vanished - or turned disabled -
under the keyboard would drop the focus on the document body. *@
@if (ShowBatchActions && _HasPickedFiles)
{
var canUploadAll = _CanUploadAll;
var canCancelAll = _CanCancelAll;
var canClear = _CanClear;
<div style="@Styles?.BatchActions" class="bit-upl-bat @Classes?.BatchActions">
@if (AutoUpload is false)
{
<button @onclick="HandleUploadAll"
type="button"
disabled="@(IsEnabled is false)"
aria-disabled="@(canUploadAll ? null : "true")"
style="@Styles?.BatchActionButton"
class="bit-upl-bab @Classes?.BatchActionButton">
@UploadAllText
</button>
}
<button @onclick="HandleCancelAll"
type="button"
disabled="@(IsEnabled is false)"
aria-disabled="@(canCancelAll ? null : "true")"
style="@Styles?.BatchActionButton"
class="bit-upl-bab @Classes?.BatchActionButton">
@CancelAllText
</button>
<button @onclick="HandleClear"
type="button"
disabled="@(IsEnabled is false)"
aria-disabled="@(canClear ? null : "true")"
style="@Styles?.BatchActionButton"
class="bit-upl-bab @Classes?.BatchActionButton">
@ClearText
</button>
</div>
}

<div role="status" aria-live="polite" aria-atomic="true" class="bit-upl-lvr">@_announcement</div>
</div>
Loading
Loading