|
| 1 | +@using MudExtensions.Services |
1 | 2 | @inject CurrentUser CurrentUser
|
2 | 3 |
|
3 | 4 | @inject IChatService ChatService
|
|
6 | 7 | @inject IJSRuntime JsRuntime
|
7 | 8 | @inject ChatSignalRClient ChatSignalRClient
|
8 | 9 | @inject NavigationManager Navigation
|
| 10 | +@inject IScrollManager ScrollManager |
9 | 11 |
|
10 | 12 | @attribute [Authorize]
|
11 | 13 |
|
| 14 | +@if (ActiveChat is null && IsMobile) |
| 15 | +{ |
| 16 | + return; |
| 17 | +} |
| 18 | + |
12 | 19 | <MudItem Class="@MudItemClass" Style="@MudItemStyle" xs="12" sm="12" md="8" lg="8" xl="8" xxl="8">
|
13 | 20 |
|
14 | 21 | @switch (ActiveChat)
|
15 | 22 | {
|
16 |
| - case null when IsMobile: |
17 |
| - return; |
18 | 23 | case null when IsMobile is false:
|
19 | 24 | <MudStack Row Style="margin-left: -24px;">
|
20 | 25 | <MudIcon Icon="@Icons.Material.Filled.ArrowCircleLeft" Size="Size.Large" Color="Color.Info" />
|
|
35 | 40 | break;
|
36 | 41 | }
|
37 | 42 |
|
38 |
| - @*The elements below cannot be readonly/disabled, as it disabled the tooltips *@ |
| 43 | + @*The elements below cannot be readonly/disabled, as it disables the tooltips *@ |
39 | 44 | <MudList Class="chat-message-list" Padding="false" Dense T="RenderFragment">
|
40 | 45 | <MudSpacer />
|
41 | 46 | <MudVirtualize Items="ActiveChat?.Messages" Context="message" OverscanCount="8" ItemSize="80">
|
| 47 | + <MudListItem T="MudTooltip" Class="@(MudListItemClass(message))"> |
| 48 | + |
| 49 | + <MudTooltip Placement="@(IsMessageFromSelf(message) ? Placement.Left : Placement.Right)" |
| 50 | + Arrow |
| 51 | + Text="@(CreateTooltip(message))"> |
| 52 | + |
| 53 | + @if (IsMessageFromSelf(message)) |
| 54 | + { |
| 55 | + <MudChip Class="chat-chip" Size="Size.Large" T="MudText"> |
| 56 | + <MudText Typo="Typo.h6">@message.Text</MudText> |
| 57 | + </MudChip> |
| 58 | + } |
| 59 | + else |
| 60 | + { |
| 61 | + <MudChip Class="chat-chip" Size="Size.Large"> |
| 62 | + <AvatarContent> |
| 63 | + @if (!NextMessageIsFromSameSender(message)) |
| 64 | + { |
| 65 | + <MudLink Href="@GetRecipientsUserName(message)"> |
| 66 | + <MudAvatar> |
| 67 | + <MudImage Src="@GetRecipientsProfilePictureUrl(message)" loading="lazy" Alt="Avatar"/> |
| 68 | + </MudAvatar> |
| 69 | + </MudLink> |
| 70 | + } |
| 71 | + </AvatarContent> |
| 72 | + <ChildContent> |
| 73 | + <MudText Typo="Typo.h6">@message.Text</MudText> |
| 74 | + </ChildContent> |
| 75 | + </MudChip> |
| 76 | + } |
| 77 | + |
| 78 | + </MudTooltip> |
| 79 | + </MudListItem> |
42 | 80 |
|
43 |
| - @if (IsMessageFromSelf(message)) |
44 |
| - { |
45 |
| - <MudListItem Class="message-from-self" T="MudTooltip"> |
46 |
| - <MudTooltip Placement="Placement.Top" ShowOnClick ShowOnHover="false" ShowOnFocus="false" Arrow Text="@message.SentUtc.DisplayExactTime()"> |
47 |
| - <MudTooltip ShowOnHover Arrow Text="@message.SentUtc.DisplayTimePassed()"> |
48 |
| - <MudChip Class="chat-chip" Size="Size.Large" T="MudText"> |
49 |
| - <MudText Typo="Typo.h6">@message.Text</MudText> |
50 |
| - </MudChip> |
51 |
| - </MudTooltip> |
52 |
| - </MudTooltip> |
53 |
| - </MudListItem> |
54 |
| - } |
55 |
| - else |
56 |
| - { |
57 |
| - <MudListItem T="MudTooltip"> |
58 |
| - <MudTooltip Placement="Placement.Top" ShowOnClick ShowOnHover="false" ShowOnFocus="false" Arrow Text="@message.SentUtc.DisplayExactTime()"> |
59 |
| - <MudTooltip ShowOnHover Arrow Text="@message.SentUtc.DisplayTimePassed()"> |
60 |
| - <MudChip Class="chat-chip" Size="Size.Large" T="MudLink"> |
61 |
| - <AvatarContent> |
62 |
| - @if (!NextMessageIsFromSameSender(message)) |
63 |
| - { |
64 |
| - <MudLink Href="@GetRecipientsUserName(message)"> |
65 |
| - <MudAvatar> |
66 |
| - <MudImage Src="@GetRecipientsProfilePictureUrl(message)" loading="lazy" Alt="Avatar" /> |
67 |
| - </MudAvatar> |
68 |
| - </MudLink> |
69 |
| - } |
70 |
| - </AvatarContent> |
71 |
| - <ChildContent> |
72 |
| - <MudText Typo="Typo.h6">@message.Text</MudText> |
73 |
| - </ChildContent> |
74 |
| - </MudChip> |
75 |
| - </MudTooltip> |
76 |
| - </MudTooltip> |
77 |
| - </MudListItem> |
78 |
| - } |
79 | 81 | </MudVirtualize>
|
80 | 82 |
|
81 | 83 | @if (LastMessageWasSentSuccessfullyByCurrentUser)
|
|
102 | 104 | Lines="2"
|
103 | 105 | IconSize="Size.Large"
|
104 | 106 | Style="@($"background: {JordnaerTheme.CustomTheme.PaletteLight.BackgroundGray}")" />
|
| 107 | + |
105 | 108 | </MudList>
|
| 109 | + |
| 110 | + <ScrollToBottom Selector="@ChatMessageWindowClass"> |
| 111 | + <MudFab Color="Color.Primary" StartIcon="@Icons.Material.Filled.ArrowCircleDown" /> |
| 112 | + </ScrollToBottom> |
106 | 113 | </MudItem>
|
107 | 114 |
|
108 | 115 | @code
|
109 | 116 | {
|
| 117 | + private const string ChatMessageWindowClass = ".chat-message-window"; |
| 118 | + |
110 | 119 | [Parameter, EditorRequired]
|
111 | 120 | public required ChatDto? ActiveChat { get; set; }
|
112 | 121 |
|
|
132 | 141 | ? "padding: 0"
|
133 | 142 | : "";
|
134 | 143 |
|
| 144 | + private string MudListItemClass(ChatMessageDto message) => IsMessageFromSelf(message) |
| 145 | + ? "message-from-self" |
| 146 | + : ""; |
| 147 | + |
135 | 148 | private string GetRecipientsProfilePictureUrl(ChatMessageDto message)
|
136 |
| - => ActiveChat? |
137 |
| - .Recipients |
138 |
| - .FirstOrDefault(recipient => recipient.Id == message.SenderId)?.ProfilePictureUrl |
| 149 | + => ActiveChat?.Recipients |
| 150 | + .FirstOrDefault(recipient => recipient.Id == message.SenderId)?.ProfilePictureUrl |
139 | 151 | ?? ProfileConstants.Default_Profile_Picture;
|
140 | 152 |
|
141 | 153 | private string? GetRecipientsUserName(ChatMessageDto message)
|
142 |
| - => ActiveChat? |
143 |
| - .Recipients |
| 154 | + => ActiveChat?.Recipients |
144 | 155 | .FirstOrDefault(recipient => recipient.Id == message.SenderId)?.UserName;
|
145 | 156 |
|
146 | 157 | private bool NextMessageIsFromSameSender(ChatMessageDto message)
|
|
164 | 175 |
|
165 | 176 | protected override async Task OnAfterRenderAsync(bool firstRender)
|
166 | 177 | {
|
167 |
| - await JsRuntime.ScrollToBottomOfElement(".chat-message-window"); |
| 178 | + await ScrollManager.ScrollToBottomAsync(ChatMessageWindowClass); |
168 | 179 | }
|
169 | 180 |
|
170 | 181 | private void MarkMessageIfSuccessfullySentByCurrentUser()
|
|
222 | 233 | }
|
223 | 234 |
|
224 | 235 | await _messageInput.FocusAsync();
|
225 |
| - await JsRuntime.ScrollToBottomOfElement(".chat-message-window"); |
| 236 | + await ScrollManager.ScrollToBottomAsync(ChatMessageWindowClass); |
226 | 237 | }
|
227 | 238 |
|
228 |
| - // TODO: Add MudScrollToTop that shows when user is scrolled up in the chat window |
229 |
| -
|
230 | 239 | private async Task SendMessageOnEnter(KeyboardEventArgs keyboardEventArgs)
|
231 | 240 | {
|
232 | 241 | if (keyboardEventArgs is { Key: "Enter", ShiftKey: false })
|
233 | 242 | {
|
234 | 243 | await SendMessage();
|
235 | 244 | }
|
236 | 245 | }
|
| 246 | + |
| 247 | + private string CreateTooltip(ChatMessageDto message) |
| 248 | + => $"{message.SentUtc.DisplayTimePassed()} ({message.SentUtc.DisplayExactTime()})"; |
237 | 249 | }
|
0 commit comments