@page "/drive" @page "/drive/{Id}" @attribute [Authorize] @using Iceshrimp.Frontend.Localization @using Microsoft.AspNetCore.Components.Sections @using Microsoft.Extensions.Localization @using Iceshrimp.Assets.PhosphorIcons @using Iceshrimp.Frontend.Core.Miscellaneous @using Iceshrimp.Frontend.Core.Services @using Iceshrimp.Shared.Schemas.Web @using Microsoft.AspNetCore.Authorization @using Iceshrimp.Frontend.Components @inject ApiService Api; @inject GlobalComponentSvc Global; @inject IJSRuntime Js; @inject IStringLocalizer Loc; @inject ILogger Logger; @inject NavigationManager Nav; @if (State == State.Loaded && Folder is { Id: not null, Name: not null }) { @Folder.Name } else { @Loc["Drive"] } @if (State == State.Loaded && Folder is not null) { @if (Folder is { Id: not null, Files: [], Folders: [] }) { } }
Upload!
@if (State == State.Loaded && Folder != null) {
    @foreach (var el in Folder.Folders) {
  1. } @foreach (var el in Folder.Files) {
  2. }
} @if (State == State.Loading) {
} @if (State == State.NotFound) {
This folder does not exist
} @if (State == State.Error) {
An error occured while loading the drive folder. Please inspect logs.
} @code { [Parameter] public string? Id { get; set; } private DriveFolderResponse? Folder { get; set; } private State State { get; set; } private InputFile UploadInput { get; set; } = null!; private IJSObjectReference _module = null!; private async Task Load() { Logger.LogTrace($"Opening drive folder: {Id ?? "root"}"); State = State.Loading; try { Folder = await Api.Drive.GetFolderAsync(Id); } catch (ApiException e) { Logger.LogWarning($"Failed to load folder '{Id ?? "root"}' due to API Exception: {e.Message}"); State = State.Error; return; } if (Folder == null) { State = State.NotFound; return; } State = State.Loaded; } protected override async Task OnInitializedAsync() { await Load(); _module = await Js.InvokeAsync("import", "./Pages/DrivePage.razor.js"); } protected override async Task OnParametersSetAsync() { await Load(); } private void NavigateToParent() { Nav.NavigateTo(Folder?.ParentId != null ? $"/drive/{Folder.ParentId}" : "/drive"); } private async Task CreateFolder() => await Global.PromptDialog?.Prompt(new EventCallback(this, CreateFolderCallback), Loc["Create folder"], Loc["Folder name"], null, buttonText: Loc["Create"])!; private async Task CreateFolderCallback(string? name) { if (string.IsNullOrWhiteSpace(name)) return; try { var res = await Api.Drive.CreateFolderAsync(new DriveFolderRequest { Name = name, ParentId = Folder!.Id }); if (res != null) { Folder.Folders.Add(res); StateHasChanged(); } } catch (ApiException e) { await Global.NoticeDialog?.Display(e.Response.Message ?? Loc["An unknown error occurred"], NoticeDialog.NoticeType.Error)!; } } // The Component is hidden, and triggered by a sepperate button. // That way we get it's functionality, without the styling limitations of the InputFile component private async Task OpenUpload() { await _module.InvokeVoidAsync("openUpload", UploadInput.Element); } private async Task Upload(InputFileChangeEventArgs e) { var res = Folder?.Id != null ? await Api.Drive.UploadFileToFolderAsync(e.File, Folder.Id) : await Api.Drive.UploadFileAsync(e.File); Folder!.Files.Insert(0, res); StateHasChanged(); } private async Task DeleteFolder() { if (Folder is not { Id: not null, Files: [], Folders: [] }) return; await Global.ConfirmDialog?.Confirm(new EventCallback(this, DeleteFolderCallback), Loc["Delete {0}?", Folder.Name ?? ""], Icons.Trash, Loc["Delete"])!; } private async Task DeleteFolderCallback(bool delete) { if (Folder is not { Id: not null, Files: [], Folders: [] }) return; if (!delete) return; try { await Api.Drive.DeleteFolderAsync(Folder.Id); NavigateToParent(); } catch (ApiException e) { await Global.NoticeDialog?.Display(e.Response.Message ?? Loc["An unknown error occurred"], NoticeDialog.NoticeType.Error)!; } } }