Implemented file upload and improved ui. Fixed file upload bug in ticket service

This commit is contained in:
Marcel Baumgartner 2023-11-06 17:41:24 +01:00
parent 1c96f9d13c
commit f5501f77fe
5 changed files with 106 additions and 37 deletions

View file

@ -60,17 +60,17 @@ public class TicketChatService
return Task.CompletedTask;
}
public async Task SendMessage(string content, Stream? attachmentStream = null, string? attachmentString = null)
public async Task SendMessage(string content, Stream? attachmentStream = null, string? attachmentName = null)
{
if(string.IsNullOrEmpty(content))
return;
string? attachmentName = null;
string? attachmentBucketName = null;
// Check and download attachments
if (attachmentStream != null && attachmentName != null)
{
attachmentName = await BucketService.Store(
attachmentBucketName = await BucketService.Store(
"ticketAttachments",
attachmentStream,
attachmentName
@ -81,7 +81,7 @@ public class TicketChatService
var message = new TicketMessage()
{
Content = content,
Attachment = attachmentName,
Attachment = attachmentBucketName,
CreatedAt = DateTime.UtcNow,
Sender = IdentityService.CurrentUser,
IsSupport = IsSupporter

View file

@ -0,0 +1,56 @@
@using Microsoft.AspNetCore.Components.Forms
@inject ToastService ToastService
@{
var id = $"fileUpload{GetHashCode()}";
}
<InputFile OnChange="OnFileChanged" type="file" id="@id" hidden=""/>
@if (SelectedFile != null)
{
<button @onclick="RemoveSelection" class="btn btn-icon btn-bg-light btn-color-danger rounded-start rounded-end">
<i class="bx bx-sm bx-x"></i>
</button>
}
else
{
<label for="@id" class="btn btn-icon btn-bg-light btn-color-primary rounded-start rounded-end">
<i class="bx bx-sm bx-upload"></i>
</label>
}
@code
{
[Parameter]
public IBrowserFile? SelectedFile { get; set; }
[Parameter]
public int MaxFileSize { get; set; } = 1024 * 1024 * 5;
private async Task OnFileChanged(InputFileChangeEventArgs arg)
{
if (arg.FileCount > 0)
{
if (arg.File.Size < MaxFileSize)
{
SelectedFile = arg.File;
await InvokeAsync(StateHasChanged);
return;
}
await ToastService.Danger($"The uploaded file should not be bigger than {Formatter.FormatSize(MaxFileSize)}");
}
SelectedFile = null;
await InvokeAsync(StateHasChanged);
}
public async Task RemoveSelection()
{
SelectedFile = null;
await InvokeAsync(StateHasChanged);
}
}

View file

@ -33,7 +33,7 @@
{
if (arg.FileCount > 0)
{
if (arg.File.Size < 1024 * 1024 * 5)
if (arg.File.Size < MaxFileSize)
{
SelectedFile = arg.File;
@ -41,7 +41,7 @@
return;
}
await ToastService.Danger("The uploaded file should not be bigger than 5MB");
await ToastService.Danger($"The uploaded file should not be bigger than {Formatter.FormatSize(MaxFileSize)}");
}
SelectedFile = null;

View file

@ -32,30 +32,7 @@
{
<a href="#" @onclick="() => LiveChatMain.OpenTicket(ticket)" @onclick:preventDefault class="d-flex flex-stack py-4">
<div class="d-flex align-items-center">
<div class="symbol symbol-45px symbol-circle">
@{
string color = "";
switch (ticket.Priority)
{
case TicketPriority.Critical:
color = "danger";
break;
case TicketPriority.High:
color = "warning";
break;
case TicketPriority.Medium:
color = "primary";
break;
case TicketPriority.Low:
color = "secondary";
break;
}
}
<span class="symbol-label bg-@(color) text-white fs-6 fw-bolder">@(ticket.Priority.ToString().First())</span>
</div>
<div class="ms-5">
<div>
<a href="#" class="fs-5 fw-bold text-gray-900 text-hover-primary mb-2">@(ticket.Name)</a>
<div class="fw-semibold text-muted">@(ticket.Description.Length > 100 ? string.Concat(ticket.Description.Take(97)) : ticket.Description)</div>
</div>

View file

@ -1,4 +1,5 @@
@using Moonlight.App.Services.Ticketing
@using System.Text.RegularExpressions
@implements IDisposable
@ -33,23 +34,44 @@
</div>
</div>
<div class="p-5 rounded bg-light-@(message.IsSupport ? "info" : "primary") text-dark fw-semibold mw-lg-400px text-@(orientation)">
@(message.Content)
@(Formatter.FormatLineBreaks(message.Content))
@if (message.Attachment != null)
{
<div class="mt-3">
@if (Regex.IsMatch(message.Attachment, @"\.(jpg|jpeg|png|gif|bmp)$"))
{
<img src="/api/bucket/ticketAttachments/@(message.Attachment)" class="img-fluid" alt="Attachment"/>
}
else
{
<a href="/api/bucket/ticketAttachments/@(message.Attachment)" target="_blank" class="btn btn-secondary">
<i class="me-2 bx bx-download"></i> @(message.Attachment)
</a>
}
</div>
}
</div>
</div>
</div>
}
else
{
@* System msgs here *@
<div class="separator separator-content">@(message.Content)</div>
}
}
</div>
</LazyLoader>
</div>
<div class="card-footer">
<div class="input-group">
<input @bind="MyMessageContent" class="form-control" placeholder="Type a message"/>
<WButton OnClick="SendMessage" Text="Send" CssClasses="btn btn-secondary"></WButton>
<div class="row">
<div class="input-group">
<textarea @bind="MyMessageContent" class="form-control form-control-solid-bg rounded-end me-3" placeholder="Type a message" style="height: 1vh"></textarea>
<ChatFileSelect @ref="FileSelect"/>
<WButton OnClick="SendMessage" CssClasses="ms-2 btn btn-icon btn-bg-light btn-color-white">
<i class="bx bx-sm bx-send"></i>
</WButton>
</div>
</div>
</div>
@ -58,6 +80,8 @@
[CascadingParameter]
public LiveChatMain LiveChatMain { get; set; }
private ChatFileSelect FileSelect;
private bool HasStarted = false;
private string MyMessageContent = "";
@ -81,13 +105,25 @@
private async Task SendMessage()
{
if (string.IsNullOrEmpty(MyMessageContent))
if (string.IsNullOrEmpty(MyMessageContent) && FileSelect.SelectedFile == null)
return;
if (!HasStarted)
return;
await TicketService.Chat.SendMessage(MyMessageContent);
if (FileSelect.SelectedFile == null)
await TicketService.Chat.SendMessage(MyMessageContent);
else
{
await TicketService.Chat.SendMessage(
string.IsNullOrEmpty(MyMessageContent) ? $"Upload of {FileSelect.SelectedFile.Name}" : MyMessageContent,
FileSelect.SelectedFile.OpenReadStream(1024 * 1024 * 5),
FileSelect.SelectedFile.Name
);
await FileSelect.RemoveSelection();
}
MyMessageContent = "";
await InvokeAsync(StateHasChanged);
}