diff --git a/src/web/Client/Features/Chat/LargeChatComponent.razor b/src/web/Client/Features/Chat/LargeChatComponent.razor index 30f5fcec..96272ad8 100644 --- a/src/web/Client/Features/Chat/LargeChatComponent.razor +++ b/src/web/Client/Features/Chat/LargeChatComponent.razor @@ -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 @@ -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) - *@ + *@ @@ -47,14 +49,12 @@ - + @if (_activeChat != null) { - - @foreach (var message in _activeChat.Messages) - { - @if (IsMessageFromSelf(message)) + + @if (IsMessageFromSelf(message)) { } - } + + - } + @@ -96,14 +98,12 @@ private UserSlim _currentUserSlim = null!; private List _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] @@ -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: @@ -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() @@ -209,6 +208,8 @@ // TODO: Error handling await ChatClient.StartChat(_activeChat); } + + await ScrollToBottom(); } private async Task SendMessageOnEnter(KeyboardEventArgs keyboardEventArgs) @@ -260,18 +261,4 @@ await SelectChat(newChat); } - - private async Task HandleScroll() - { - if (!_enableScrollListener) - { - return; - } - - var isAtTheTop = await JsRuntime.InvokeAsync("scrollFunctions.isChatContainerAtTheTop"); - if (isAtTheTop) - { - await LoadMessages(); - } - } } diff --git a/src/web/Client/wwwroot/css/chat.css b/src/web/Client/wwwroot/css/chat.css index 82b18b6e..ffe2c2b6 100644 --- a/src/web/Client/wwwroot/css/chat.css +++ b/src/web/Client/wwwroot/css/chat.css @@ -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; -} diff --git a/src/web/Client/wwwroot/js/scroll.js b/src/web/Client/wwwroot/js/scroll.js index 4fb26abb..b8e8b16c 100644 --- a/src/web/Client/wwwroot/js/scroll.js +++ b/src/web/Client/wwwroot/js/scroll.js @@ -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; } }; diff --git a/src/web/Server/Features/Chat/ChatApi.cs b/src/web/Server/Features/Chat/ChatApi.cs index d8c86229..3ed0a119 100644 --- a/src/web/Server/Features/Chat/ChatApi.cs +++ b/src/web/Server/Features/Chat/ChatApi.cs @@ -84,7 +84,8 @@ async Task 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