|
82 | 82 | { |
83 | 83 | <div class="reasoning-row"> |
84 | 84 | <span class="brain-toggle" title="@(conversation.ShowReason ? "Hide reasoning" : "Show reasoning")" |
85 | | - @onclick="@(() => { _preserveScroll = true; conversation.ShowReason = !conversation.ShowReason; })"> |
| 85 | + @onclick="@(() => ToggleReasoning(conversation))"> |
86 | 86 | <FluentIcon Value="@(new Icons.Regular.Size24.Brain())" |
87 | 87 | Style="@($"fill: {(conversation.ShowReason ? "var(--accent-base-color)" : "var(--neutral-foreground-hint)")};")"/> |
88 | 88 | </span> |
|
213 | 213 | { |
214 | 214 | var theme = await JS.InvokeAsync<string>("themeManager.load"); |
215 | 215 | _accentColor = (theme == "dark" || theme == "system-dark") ? "#00ffcc" : "#00cca3"; |
216 | | - StateHasChanged(); |
217 | | - } |
218 | | - else if (!_preserveScroll) |
219 | | - { |
| 216 | + await JS.InvokeVoidAsync("scrollManager.attachScrollListener", "messages-container"); |
220 | 217 | await JS.InvokeVoidAsync("scrollManager.restoreScrollPosition", "messages-container"); |
| 218 | + StateHasChanged(); |
221 | 219 | } |
222 | | - else |
| 220 | + else if (_preserveScroll) |
223 | 221 | { |
224 | 222 | _preserveScroll = false; |
| 223 | + await JS.InvokeVoidAsync("scrollManager.restoreScrollPosition", "messages-container"); |
225 | 224 | } |
226 | 225 | } |
227 | 226 |
|
|
346 | 345 | Chat.ModelId = Utils.Model!; |
347 | 346 | Chat.Visual = Utils.Visual; |
348 | 347 |
|
| 348 | + bool wasAtBottom = await JS.InvokeAsync<bool>("scrollManager.isAtBottom", "messages-container"); |
| 349 | + |
349 | 350 | StateHasChanged(); |
350 | 351 |
|
351 | | - bool wasAtBottom = await JS.InvokeAsync<bool>("scrollManager.isAtBottom", "messages-container"); |
| 352 | + if (wasAtBottom) |
| 353 | + await JS.InvokeVoidAsync("scrollManager.scrollToBottomSmooth", "messages-container"); |
352 | 354 |
|
353 | 355 | var request = ctx!.WithMessage(msg); |
354 | 356 | if (attachments.Count != 0) |
|
379 | 381 | await InvokeAsync(StateHasChanged); |
380 | 382 | if (wasAtBottom) |
381 | 383 | { |
382 | | - await InvokeAsync(async () => await JS.InvokeVoidAsync("scrollManager.scrollToBottomSmooth", cancellationToken, _bottomElement)); |
| 384 | + await InvokeAsync(async () => await JS.InvokeVoidAsync("scrollManager.scrollToBottomSmooth", "messages-container")); |
383 | 385 | } |
384 | 386 | }, cancellationToken: cancellationToken); |
385 | 387 |
|
|
388 | 390 | var currentChat = await ctx.GetCurrentChat(); |
389 | 391 | Chat.Messages.Add(currentChat.Messages.Last()); |
390 | 392 |
|
| 393 | + await JS.InvokeVoidAsync("scrollManager.saveScrollPosition", "messages-container"); |
| 394 | + _preserveScroll = true; |
391 | 395 | RebuildMessagesWithFiles(); |
392 | 396 | _incomingReasoning = null; |
393 | 397 | _incomingMessage = null; |
394 | | - await JS.InvokeVoidAsync("scrollManager.scrollToBottomSmooth", _bottomElement); |
395 | 398 | } |
396 | 399 | catch (OperationCanceledException) |
397 | 400 | { |
|
475 | 478 | : MessageType.CloudLLM; |
476 | 479 | } |
477 | 480 |
|
| 481 | + private async Task ToggleReasoning(MessageExt conversation) |
| 482 | + { |
| 483 | + await JS.InvokeVoidAsync("scrollManager.saveScrollPosition", "messages-container"); |
| 484 | + _preserveScroll = true; |
| 485 | + conversation.ShowReason = !conversation.ShowReason; |
| 486 | + } |
| 487 | + |
478 | 488 | private void RebuildMessagesWithFiles() |
479 | 489 | { |
480 | 490 | var existingFilesMap = Messages |
|
485 | 495 | { |
486 | 496 | Message = x, |
487 | 497 | AttachedFiles = existingFilesMap.TryGetValue(x, out var files) ? files : new List<string>(), |
488 | | - ShowReason = x.Tokens.Any(t => t.Type == TokenType.Reason) |
| 498 | + ShowReason = false |
489 | 499 | }).ToList(); |
490 | 500 | } |
491 | 501 |
|
|
0 commit comments