mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2025-02-05 10:29:07 +00:00
Improved chat page by scrolling to the bottom after loading (#87)
This commit is contained in:
parent
3409872090
commit
1b3fff67ec
@ -3,6 +3,10 @@
|
||||
<div class="d-flex flex-column" style="@this.Height">
|
||||
<div class="flex-auto overflow-auto">
|
||||
@this.ChildContent
|
||||
|
||||
<div @ref="@this.AnchorAfterChildContent">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@this.FooterContent
|
||||
|
@ -26,6 +26,11 @@ public partial class InnerScrolling : MSGComponentBase
|
||||
|
||||
[CascadingParameter]
|
||||
private MainLayout MainLayout { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
private IJSRuntime JsRuntime { get; init; } = null!;
|
||||
|
||||
private ElementReference AnchorAfterChildContent { get; set; }
|
||||
|
||||
#region Overrides of ComponentBase
|
||||
|
||||
@ -59,4 +64,9 @@ public partial class InnerScrolling : MSGComponentBase
|
||||
#endregion
|
||||
|
||||
private string Height => $"height: calc(100vh - {this.HeaderHeight} - {this.MainLayout.AdditionalHeight});";
|
||||
|
||||
public async Task ScrollToBottom()
|
||||
{
|
||||
await this.AnchorAfterChildContent.ScrollIntoViewAsync(this.JsRuntime);
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
</MudText>
|
||||
|
||||
<ProviderSelection @bind-ProviderSettings="@this.providerSettings"/>
|
||||
<InnerScrolling HeaderHeight="12.3em">
|
||||
<InnerScrolling @ref="@this.scrollingArea" HeaderHeight="12.3em">
|
||||
<ChildContent>
|
||||
@if (this.chatThread is not null)
|
||||
{
|
||||
|
@ -29,6 +29,8 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
||||
|
||||
[Inject]
|
||||
public IDialogService DialogService { get; set; } = null!;
|
||||
|
||||
private InnerScrolling scrollingArea = null!;
|
||||
|
||||
private const Placement TOOLBAR_TOOLTIP_PLACEMENT = Placement.Bottom;
|
||||
private static readonly Dictionary<string, object?> USER_INPUT_ATTRIBUTES = new();
|
||||
@ -42,6 +44,7 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
||||
private Guid currentWorkspaceId = Guid.Empty;
|
||||
private bool workspacesVisible;
|
||||
private Workspaces? workspaces;
|
||||
private bool mustScrollToBottomAfterRender;
|
||||
|
||||
// Unfortunately, we need the input field reference to clear it after sending a message.
|
||||
// This is necessary because we have to handle the key events ourselves. Otherwise,
|
||||
@ -83,6 +86,17 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
||||
await base.OnInitializedAsync();
|
||||
}
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if(this.mustScrollToBottomAfterRender)
|
||||
{
|
||||
await this.scrollingArea.ScrollToBottom();
|
||||
this.mustScrollToBottomAfterRender = false;
|
||||
}
|
||||
|
||||
await base.OnAfterRenderAsync(firstRender);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private bool IsProviderSelected => this.providerSettings.UsedProvider != Providers.NONE;
|
||||
@ -372,6 +386,11 @@ public partial class Chat : MSGComponentBase, IAsyncDisposable
|
||||
this.currentWorkspaceName = this.chatThread is null ? string.Empty : await this.workspaces.LoadWorkspaceName(this.chatThread.WorkspaceId);
|
||||
|
||||
await this.inputField.Clear();
|
||||
if (this.SettingsManager.ConfigurationData.Chat.ShowLatestMessageAfterLoading)
|
||||
{
|
||||
this.mustScrollToBottomAfterRender = true;
|
||||
this.StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void ResetState()
|
||||
|
@ -77,6 +77,7 @@
|
||||
|
||||
<ExpansionPanel HeaderIcon="@Icons.Material.Filled.Chat" HeaderText="Chat Options">
|
||||
<ConfigurationSelect OptionDescription="Shortcut to send input" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Chat.ShortcutSendBehavior)" Data="@ConfigurationSelectDataFactory.GetSendBehaviorData()" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Chat.ShortcutSendBehavior = selectedValue)" OptionHelp="Do you want to use any shortcut to send your input?"/>
|
||||
<ConfigurationOption OptionDescription="Show the latest message after loading?" LabelOn="Latest message is shown, after loading a chat" LabelOff="First (oldest) message is shown, after loading a chat" State="@(() => this.SettingsManager.ConfigurationData.Chat.ShowLatestMessageAfterLoading)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.Chat.ShowLatestMessageAfterLoading = updatedState)" OptionHelp="When enabled, the latest message is shown after loading a chat. When disabled, the first (oldest) message is shown."/>
|
||||
<ConfigurationOption OptionDescription="Preselect chat options?" LabelOn="Chat options are preselected" LabelOff="No chat options are preselected" State="@(() => this.SettingsManager.ConfigurationData.Chat.PreselectOptions)" StateUpdate="@(updatedState => this.SettingsManager.ConfigurationData.Chat.PreselectOptions = updatedState)" OptionHelp="When enabled, you can preselect chat options. This is might be useful when you prefer a specific provider."/>
|
||||
<ConfigurationProviderSelection Data="@this.availableProviders" Disabled="@(() => !this.SettingsManager.ConfigurationData.Chat.PreselectOptions)" SelectedValue="@(() => this.SettingsManager.ConfigurationData.Chat.PreselectedProvider)" SelectionUpdate="@(selectedValue => this.SettingsManager.ConfigurationData.Chat.PreselectedProvider = selectedValue)"/>
|
||||
</ExpansionPanel>
|
||||
|
@ -16,4 +16,9 @@ public sealed class DataChat
|
||||
/// Should we preselect a provider for the chat?
|
||||
/// </summary>
|
||||
public string PreselectedProvider { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Should we show the latest message after loading? When false, we show the first (aka oldest) message.
|
||||
/// </summary>
|
||||
public bool ShowLatestMessageAfterLoading { get; set; } = true;
|
||||
}
|
11
app/MindWork AI Studio/Tools/ElementReferenceExtensions.cs
Normal file
11
app/MindWork AI Studio/Tools/ElementReferenceExtensions.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
|
||||
namespace AIStudio.Tools;
|
||||
|
||||
public static class ElementReferenceExtensions
|
||||
{
|
||||
public static async ValueTask ScrollIntoViewAsync(this ElementReference elementReference, IJSRuntime jsRuntime)
|
||||
{
|
||||
await jsRuntime.InvokeVoidAsync("scrollToBottom", elementReference);
|
||||
}
|
||||
}
|
@ -21,4 +21,8 @@ window.generateDiff = function (text1, text2, divDiff, divLegend) {
|
||||
window.clearDiv = function (divName) {
|
||||
let targetDiv = document.getElementById(divName);
|
||||
targetDiv.innerHTML = '';
|
||||
}
|
||||
|
||||
window.scrollToBottom = function(element) {
|
||||
element.scrollIntoView();
|
||||
}
|
@ -1,7 +1,8 @@
|
||||
# v0.8.12, build 174
|
||||
- Added an e-mail writing assistant.
|
||||
- Added the possibility to preselect some e-mail writing assistant options.
|
||||
- Improved: all assistants now have a button to copy their respective result to the clipboard.
|
||||
- Improved chat page by scrolling to the bottom after loading (configurable; default is on).
|
||||
- Improved all assistants to provide a button to copy their respective result to the clipboard.
|
||||
- Improved the content validation for the agenda assistant.
|
||||
- Improved the language handling of the agenda assistant.
|
||||
- Refactored the "send to" implementation of assistants.
|
Loading…
Reference in New Issue
Block a user