Unified the copy to clipboard functionality

This commit is contained in:
Peer Schütt 2025-07-25 10:58:23 +02:00
parent 609be6ad5d
commit 87bc18b8f9
6 changed files with 72 additions and 65 deletions

View File

@ -1315,9 +1315,6 @@ UI_TEXT_CONTENT["AISTUDIO::CHAT::CHATROLEEXTENSIONS::T601166687"] = "AI"
-- Edit Message -- Edit Message
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1183581066"] = "Edit Message" UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1183581066"] = "Edit Message"
-- Copies the content to the clipboard
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T12948066"] = "Copies the content to the clipboard"
-- Do you really want to remove this message? -- Do you really want to remove this message?
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1347427447"] = "Do you really want to remove this message?" UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T1347427447"] = "Do you really want to remove this message?"
@ -1351,9 +1348,6 @@ UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T3587744975"] = "Regener
-- Do you really want to regenerate this message? -- Do you really want to regenerate this message?
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T3878878761"] = "Do you really want to regenerate this message?" UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T3878878761"] = "Do you really want to regenerate this message?"
-- Cannot copy this content type to clipboard!
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T4021525742"] = "Cannot copy this content type to clipboard!"
-- Remove Message -- Remove Message
UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T4070211974"] = "Remove Message" UI_TEXT_CONTENT["AISTUDIO::CHAT::CONTENTBLOCKCOMPONENT::T4070211974"] = "Remove Message"
@ -1591,11 +1585,8 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::MOTIVATION::T843057510"] = "Cross-Platfor
-- Copies the content to the clipboard -- Copies the content to the clipboard
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::MUDCOPYCLIPBOARDBUTTON::T12948066"] = "Copies the content to the clipboard" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::MUDCOPYCLIPBOARDBUTTON::T12948066"] = "Copies the content to the clipboard"
-- Successfully copied the content to your clipboard -- Cannot copy this content type to clipboard!
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::MUDCOPYCLIPBOARDBUTTON::T2721950880"] = "Successfully copied the content to your clipboard" UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::MUDCOPYCLIPBOARDBUTTON::T4021525742"] = "Cannot copy this content type to clipboard!"
-- Failed to copy the content to your clipboard
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::MUDCOPYCLIPBOARDBUTTON::T424495418"] = "Failed to copy the content to your clipboard"
-- Alpha phase means that we are working on the last details before the beta phase. -- Alpha phase means that we are working on the last details before the beta phase.
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::PREVIEWALPHA::T166807685"] = "Alpha phase means that we are working on the last details before the beta phase." UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::PREVIEWALPHA::T166807685"] = "Alpha phase means that we are working on the last details before the beta phase."

View File

@ -1,5 +1,7 @@
@using System.Runtime.CompilerServices
@using AIStudio.Tools @using AIStudio.Tools
@using MudBlazor @using MudBlazor
@using AIStudio.Components
@inherits AIStudio.Components.MSGComponentBase @inherits AIStudio.Components.MSGComponentBase
<MudCard Class="@this.CardClasses" Outlined="@true"> <MudCard Class="@this.CardClasses" Outlined="@true">
<MudCardHeader> <MudCardHeader>
@ -38,9 +40,8 @@
<MudIconButton Icon="@Icons.Material.Filled.Delete" Color="Color.Error" OnClick="@this.RemoveBlock"/> <MudIconButton Icon="@Icons.Material.Filled.Delete" Color="Color.Error" OnClick="@this.RemoveBlock"/>
</MudTooltip> </MudTooltip>
} }
<MudTooltip Text="@T("Copies the content to the clipboard")" Placement="Placement.Bottom"> <MudCopyClipboardButton Content="@this.Content" Type="@this.Type"/>
<MudIconButton Icon="@Icons.Material.Filled.ContentCopy" Color="Color.Default" OnClick="@this.CopyToClipboard"/>
</MudTooltip>
</CardHeaderActions> </CardHeaderActions>
</MudCardHeader> </MudCardHeader>
<MudCardContent> <MudCardContent>

View File

@ -1,5 +1,4 @@
using AIStudio.Components; using AIStudio.Components;
using AIStudio.Tools.Services;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
@ -61,12 +60,6 @@ public partial class ContentBlockComponent : MSGComponentBase
[Parameter] [Parameter]
public Func<bool> RegenerateEnabled { get; set; } = () => false; public Func<bool> RegenerateEnabled { get; set; } = () => false;
[Inject]
private RustService RustService { get; init; } = null!;
[Inject]
private ISnackbar Snackbar { get; init; } = null!;
[Inject] [Inject]
private IDialogService DialogService { get; init; } = null!; private IDialogService DialogService { get; init; } = null!;
@ -115,29 +108,6 @@ public partial class ContentBlockComponent : MSGComponentBase
} }
#endregion #endregion
/// <summary>
/// Copy this block's content to the clipboard.
/// </summary>
private async Task CopyToClipboard()
{
switch (this.Type)
{
case ContentType.TEXT:
var textContent = (ContentText) this.Content;
await this.RustService.CopyText2Clipboard(this.Snackbar, textContent.Text);
break;
default:
this.Snackbar.Add(T("Cannot copy this content type to clipboard!"), Severity.Error, config =>
{
config.Icon = Icons.Material.Filled.ContentCopy;
config.IconSize = Size.Large;
config.IconColor = Color.Error;
});
break;
}
}
private string CardClasses => $"my-2 rounded-lg {this.Class}"; private string CardClasses => $"my-2 rounded-lg {this.Class}";

View File

@ -1,5 +1,6 @@
<MudTooltip Text=@ToolTipMessage> @using AIStudio.Chat
<MudTooltip Text="@this.ToolTipMessage" Placement="Placement.Bottom">
<MudIconButton Icon="@Icons.Material.Filled.ContentCopy" <MudIconButton Icon="@Icons.Material.Filled.ContentCopy"
Size="Size.Small" Size="Size.Small"
OnClick="@(() => CopyToClipboard(this.CopyableContent))"/> OnClick="@(() => HandleCopyClick())"/>
</MudTooltip> </MudTooltip>

View File

@ -1,5 +1,7 @@
using AIStudio.Pages; using AIStudio.Chat;
using AIStudio.Pages;
using AIStudio.Tools.PluginSystem; using AIStudio.Tools.PluginSystem;
using AIStudio.Tools.Services;
using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components;
namespace AIStudio.Components; namespace AIStudio.Components;
@ -7,12 +9,24 @@ namespace AIStudio.Components;
public partial class MudCopyClipboardButton : ComponentBase public partial class MudCopyClipboardButton : ComponentBase
{ {
private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(About).Namespace, nameof(About)); private static string TB(string fallbackEN) => I18N.I.T(fallbackEN, typeof(About).Namespace, nameof(About));
/// <summary> /// <summary>
/// The string that will be copied when the button is clicked. /// The string, if you want to copy a string.
/// </summary> /// </summary>
[Parameter] [Parameter]
public required string CopyableContent { get; set; } public string StringContent { get; set; } = string.Empty;
/// <summary>
/// The content, if you want to copy content.
/// </summary>
[Parameter]
public IContent? Content { get; init; }
/// <summary>
/// The content type, if you want to copy Content.
/// </summary>
[Parameter]
public ContentType Type { get; init; } = ContentType.NONE;
/// <summary> /// <summary>
/// The tooltip that should be shown to the user. /// The tooltip that should be shown to the user.
@ -20,22 +34,52 @@ public partial class MudCopyClipboardButton : ComponentBase
[Parameter] [Parameter]
public string ToolTipMessage { get; set; } = TB("Copies the content to the clipboard"); public string ToolTipMessage { get; set; } = TB("Copies the content to the clipboard");
[Inject]
private IJSRuntime JsRuntime { get; set; } = null!;
[Inject] [Inject]
private ISnackbar Snackbar { get; init; } = null!; private ISnackbar Snackbar { get; init; } = null!;
private async Task CopyToClipboard(string text) [Inject]
private RustService RustService { get; init; } = null!;
private async Task HandleCopyClick()
{ {
try if (this.Type == ContentType.NONE)
{ {
await this.JsRuntime.InvokeVoidAsync("navigator.clipboard.writeText", text); await this.CopyToClipboard(this.StringContent);
this.Snackbar.Add(TB("Successfully copied the content to your clipboard"), Severity.Success);
} }
catch (Exception) else
{ {
this.Snackbar.Add(TB("Failed to copy the content to your clipboard"), Severity.Error); await this.CopyToClipboard(this.Content!);
}
}
/// <summary>
/// Copy this the string to the clipboard.
/// </summary>
private async Task CopyToClipboard(string textContent)
{
await this.RustService.CopyText2Clipboard(this.Snackbar, textContent);
}
/// <summary>
/// Copy this block's content to the clipboard.
/// </summary>
private async Task CopyToClipboard(IContent contentToCopy)
{
switch (this.Type)
{
case ContentType.TEXT:
var textContent = (ContentText) contentToCopy;
await this.RustService.CopyText2Clipboard(this.Snackbar, textContent.Text);
break;
default:
this.Snackbar.Add(TB("Cannot copy this content type to clipboard!"), Severity.Error, config =>
{
config.Icon = Icons.Material.Filled.ContentCopy;
config.IconSize = Size.Large;
config.IconColor = Color.Error;
});
break;
} }
} }

View File

@ -33,7 +33,7 @@
<MudText>@T("AI Studio runs with an enterprise configuration using the configuration plugin, without central configuration management.")</MudText> <MudText>@T("AI Studio runs with an enterprise configuration using the configuration plugin, without central configuration management.")</MudText>
<MudCollapse Expanded="@showConfigDetails"> <MudCollapse Expanded="@showConfigDetails">
<MudText>@T("Configuration Plugin ID:") @configPlug!.Id <MudText>@T("Configuration Plugin ID:") @configPlug!.Id
<MudCopyClipboardButton CopyableContent=@configPlug!.Id.ToString()/> <MudCopyClipboardButton StringContent=@configPlug!.Id.ToString()/>
</MudText> </MudText>
</MudCollapse> </MudCollapse>
break; break;
@ -41,11 +41,11 @@
<MudText>@T("AI Studio runs with an enterprise configuration and a configuration server. The configuration plugin is not yet available.")</MudText> <MudText>@T("AI Studio runs with an enterprise configuration and a configuration server. The configuration plugin is not yet available.")</MudText>
<MudCollapse Expanded="@showConfigDetails"> <MudCollapse Expanded="@showConfigDetails">
<MudText>@T("Enterprise Configuration ID:") @currentEnvironment.ConfigurationId <MudText>@T("Enterprise Configuration ID:") @currentEnvironment.ConfigurationId
<MudCopyClipboardButton ToolTipMessage="@T("Copies the config ID to the clipboard")" CopyableContent=@currentEnvironment.ConfigurationId.ToString()/> <MudCopyClipboardButton ToolTipMessage="@T("Copies the config ID to the clipboard")" StringContent=@currentEnvironment.ConfigurationId.ToString()/>
</MudText> </MudText>
<MudText>@T("Configuration Server:") @currentEnvironment.ConfigurationServerUrl <MudText>@T("Configuration Server:") @currentEnvironment.ConfigurationServerUrl
<MudCopyClipboardButton ToolTipMessage="@T("Copies the server URL to the clipboard")" CopyableContent=@currentEnvironment.ConfigurationServerUrl/> <MudCopyClipboardButton ToolTipMessage="@T("Copies the server URL to the clipboard")" StringContent=@currentEnvironment.ConfigurationServerUrl/>
</MudText> </MudText>
</MudCollapse> </MudCollapse>
break; break;
@ -53,11 +53,11 @@
<MudText>@T("AI Studio runs with an enterprise configuration and a configuration server. The configuration plugin is active.")</MudText> <MudText>@T("AI Studio runs with an enterprise configuration and a configuration server. The configuration plugin is active.")</MudText>
<MudCollapse Expanded="@showConfigDetails"> <MudCollapse Expanded="@showConfigDetails">
<MudText Class="ml-4">@T("Enterprise Configuration ID:") @currentEnvironment.ConfigurationId <MudText Class="ml-4">@T("Enterprise Configuration ID:") @currentEnvironment.ConfigurationId
<MudCopyClipboardButton ToolTipMessage="@T("Copies the config ID to the clipboard")" CopyableContent=@currentEnvironment.ConfigurationId.ToString()/> <MudCopyClipboardButton ToolTipMessage="@T("Copies the config ID to the clipboard")" StringContent=@currentEnvironment.ConfigurationId.ToString()/>
</MudText> </MudText>
<MudText Class="ml-4">@T("Configuration Server:") @currentEnvironment.ConfigurationServerUrl <MudText Class="ml-4">@T("Configuration Server:") @currentEnvironment.ConfigurationServerUrl
<MudCopyClipboardButton ToolTipMessage="@T("Copies the server URL to the clipboard")" CopyableContent=@currentEnvironment.ConfigurationServerUrl/> <MudCopyClipboardButton ToolTipMessage="@T("Copies the server URL to the clipboard")" StringContent=@currentEnvironment.ConfigurationServerUrl/>
</MudText> </MudText>
</MudCollapse> </MudCollapse>
break; break;