Skip to content

Commit

Permalink
more or less finished with the chat window
Browse files Browse the repository at this point in the history
  • Loading branch information
NielsPilgaard committed Aug 17, 2023
1 parent e848b2c commit d95239f
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 72 deletions.
73 changes: 30 additions & 43 deletions src/web/Client/Features/Chat/LargeChatComponent.razor
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
@using System.Globalization
@using System.Linq.Expressions
@using System.Security.Claims
@using MassTransit
@using Microsoft.VisualBasic.CompilerServices
@inject IChatClient ChatClient
@inject IProfileCache ProfileCache
@inject AuthenticationStateProvider AuthenticationStateProvider
Expand Down Expand Up @@ -28,7 +30,7 @@
- Fetch all messages now found in cache
- Fetch all chats not found in cache
- Virtualize chat (load at the top with scroll listener)
*@
*@
<MudListItem OnClick="@(() => SelectChat(chat))" Dense="true" Class="chat-selector">

<MudAvatar Size="Size.Large" Class="mr-3">
Expand All @@ -47,14 +49,12 @@
<MudDivider Vertical DividerType="DividerType.FullWidth" />
</MudItem>

<MudItem Class="chat-message-window" md="8" lg="8" xl="8" xxl="8" @onscroll="HandleScroll">
<MudItem id="chat-message-window" Class="chat-message-window" md="8" lg="8" xl="8" xxl="8">
@if (_activeChat != null)
{
<MudList Class="chat-message-list" DisablePadding Dense>

@foreach (var message in _activeChat.Messages)
{
@if (IsMessageFromSelf(message))
<Virtualize Items="_activeChat.Messages" Context="message" OverscanCount="8" ItemSize="80">
@if (IsMessageFromSelf(message))
{
<MudListItem Class="message-from-self">
<MudChip Text="@message.Text"
Expand All @@ -72,21 +72,23 @@
</MudChip>
</MudListItem>
}
}

</Virtualize>
<MudTextField @bind-Value="_userText"
FullWidth
Immediate
AutoFocus
id="chat-message-input"
Class="chat-message-input"
Adornment="Adornment.End"
TextUpdateSuppression="false"
OnKeyDown="SendMessageOnEnter"
AdornmentIcon="@Icons.Material.Filled.Send"
AdornmentColor="@(string.IsNullOrEmpty(_userText) ? Color.Default : Color.Primary)"
OnAdornmentClick="SendMessage" />
</MudList>
<MudTextField @bind-Value="_userText"
FullWidth
Immediate
AutoFocus
Class="chat-message-input"
Adornment="Adornment.End"
TextUpdateSuppression="false"
OnKeyDown="SendMessageOnEnter"
AdornmentIcon="@Icons.Material.Filled.Send"
AdornmentColor="@(string.IsNullOrEmpty(_userText) ? Color.Default : Color.Primary)"
OnAdornmentClick="SendMessage" />
}

</MudItem>
</MudGrid>

Expand All @@ -96,14 +98,12 @@
private UserSlim _currentUserSlim = null!;
private List<ChatDto> _chats = new();
private ChatDto? _activeChat;

private string _userText = string.Empty;

private bool _enableScrollListener = false;
private bool _isActiveChatPublished = true;
private bool _isLoading = true;

private ElementReference _chatContainer;

// TODO: Select currently displayed chat using this, when we update to dotnet 8
[SupplyParameterFromQuery]
Expand Down Expand Up @@ -147,11 +147,13 @@
return;
}

var response = await ChatClient.GetChatMessages(_activeChat.Id, _activeChat.Messages.Count);
var response = await ChatClient.GetChatMessages(_activeChat.Id, _activeChat.Messages.Count, int.MaxValue);
switch (response.StatusCode)
{
case var _ when response.IsSuccessStatusCode:
_activeChat.Messages.InsertRange(0, response.Content!);
_activeChat.Messages.AddRange(response.Content!);
StateHasChanged();
await ScrollToBottom();
break;

case HttpStatusCode.TooManyRequests:
Expand All @@ -166,18 +168,15 @@

private async Task SelectChat(ChatDto chat)
{
_enableScrollListener = false;
_activeChat = chat;
if (_activeChat.Messages.Count is 0 && _isActiveChatPublished)
if (_isActiveChatPublished)
{
await LoadMessages();
}

await JsRuntime.InvokeVoidAsync("scrollFunctions.scrollToTheBottomOfChat");

_enableScrollListener = true;
}

private async Task ScrollToBottom() => await JsRuntime.InvokeVoidAsync("scrollFunctions.scrollToTheBottomOfChat");

private void BackToList() => _activeChat = null;

private async Task SendMessage()
Expand Down Expand Up @@ -209,6 +208,8 @@
// TODO: Error handling
await ChatClient.StartChat(_activeChat);
}

await ScrollToBottom();
}

private async Task SendMessageOnEnter(KeyboardEventArgs keyboardEventArgs)
Expand Down Expand Up @@ -260,18 +261,4 @@

await SelectChat(newChat);
}

private async Task HandleScroll()
{
if (!_enableScrollListener)
{
return;
}

var isAtTheTop = await JsRuntime.InvokeAsync<bool>("scrollFunctions.isChatContainerAtTheTop");
if (isAtTheTop)
{
await LoadMessages();
}
}
}
15 changes: 1 addition & 14 deletions src/web/Client/wwwroot/css/chat.css
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,7 @@
display: flex !important;
}

.chat-message-window {
.chat-message-window, .chat-selector-window {
overflow: auto;
height: 100%;
}

.chat-selector-window {
overflow: auto;
height: 100%;
}

.chat-message-list {
overflow-anchor: none;
}

.chat-message-input {
overflow-anchor: auto;
}
15 changes: 1 addition & 14 deletions src/web/Client/wwwroot/js/scroll.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,10 @@ window.scrollFunctions = {
}, 500);
},
scrollToTheBottomOfChat: function () {

setTimeout(function () {
const chatContainer = document.querySelector('.chat-message-window');

if (!chatContainer) return;

chatContainer.scrollTo({
top: chatContainer.scrollHeight,
behavior: 'smooth'
});
}, 500);
},
isChatContainerAtTheTop: function () {
const chatContainer = document.querySelector('.chat-message-window');

if (!chatContainer) return;

return chatContainer.scrollTop === 0;
chatContainer.scrollTop = chatContainer.scrollHeight;
}
};
3 changes: 2 additions & 1 deletion src/web/Server/Features/Chat/ChatApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ async Task<bool> CurrentUserIsNotPartOfChat()
var chatMessages = await context.ChatMessages
.AsNoTracking()
.Where(message => message.ChatId == chatId)
.OrderByDescending(message => message.SentUtc)
// Oldest messages first, so we get the right order in the chat
.OrderBy(message => message.SentUtc)
.Skip(skip)
.Take(take)
.Select(message => message.ToChatMessageDto(new UserSlim
Expand Down

0 comments on commit d95239f

Please sign in to comment.