Implemented file upload and improved ui. Fixed file upload bug in ticket service
This commit is contained in:
parent
1c96f9d13c
commit
f5501f77fe
5 changed files with 106 additions and 37 deletions
|
@ -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
|
||||
|
|
56
Moonlight/Shared/Components/Forms/ChatFileSelect.razor
Normal file
56
Moonlight/Shared/Components/Forms/ChatFileSelect.razor
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue