mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-03-22 22:11:36 +00:00
Added formatting options to the chat (#690)
Some checks are pending
Build and Release / Read metadata (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
Some checks are pending
Build and Release / Read metadata (push) Waiting to run
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis updater) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage deb updater) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Publish release (push) Blocked by required conditions
This commit is contained in:
parent
2f5a300e74
commit
24e72de9a2
@ -1591,6 +1591,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T1133040906"] = "Move chat
|
||||
-- Are you sure you want to move this chat? All unsaved changes will be lost.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T1142475422"] = "Are you sure you want to move this chat? All unsaved changes will be lost."
|
||||
|
||||
-- Bold
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T1165397398"] = "Bold"
|
||||
|
||||
-- Stop generation
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T1317408357"] = "Stop generation"
|
||||
|
||||
@ -1603,9 +1606,18 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T1849313532"] = "Type your
|
||||
-- Your Prompt (use selected instance '{0}', provider '{1}')
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T1967611328"] = "Your Prompt (use selected instance '{0}', provider '{1}')"
|
||||
|
||||
-- Code
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T2036185364"] = "Code"
|
||||
|
||||
-- Italic
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T2377171085"] = "Italic"
|
||||
|
||||
-- Profile usage is disabled according to your chat template settings.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T2670286472"] = "Profile usage is disabled according to your chat template settings."
|
||||
|
||||
-- Bulleted List
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T2957125464"] = "Bulleted List"
|
||||
|
||||
-- Delete this chat & start a new one.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T2991985411"] = "Delete this chat & start a new one."
|
||||
|
||||
@ -1624,6 +1636,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T3928697643"] = "Start new
|
||||
-- Start temporary chat
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T4113970938"] = "Start temporary chat"
|
||||
|
||||
-- Heading
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T4231005109"] = "Heading"
|
||||
|
||||
-- Please select the workspace where you want to move the chat to.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T474393241"] = "Please select the workspace where you want to move the chat to."
|
||||
|
||||
|
||||
@ -54,7 +54,8 @@
|
||||
Class="@this.UserInputClass"
|
||||
Style="@this.UserInputStyle"/>
|
||||
</MudElement>
|
||||
<MudToolBar WrapContent="true" Gutters="@false" Class="border border-solid rounded" Style="border-color: lightgrey;">
|
||||
<MudToolBar WrapContent="true" Gutters="@false" Class="border border-solid rounded" Style="border-color: lightgrey; gap: 2px;">
|
||||
|
||||
@if (
|
||||
this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is not WorkspaceStorageBehavior.DISABLE_WORKSPACES
|
||||
&& this.SettingsManager.ConfigurationData.Workspace.DisplayBehavior is WorkspaceDisplayBehavior.TOGGLE_OVERLAY)
|
||||
@ -81,9 +82,9 @@
|
||||
<MudIconButton Icon="@Icons.Material.Filled.CommentBank" OnClick="@(() => this.StartNewChat(useSameWorkspace: true))"/>
|
||||
</MudTooltip>
|
||||
}
|
||||
|
||||
<ChatTemplateSelection MarginLeft="" CanChatThreadBeUsedForTemplate="@this.CanThreadBeSaved" CurrentChatThread="@this.ChatThread" CurrentChatTemplate="@this.currentChatTemplate" CurrentChatTemplateChanged="@this.ChatTemplateWasChanged"/>
|
||||
|
||||
<ChatTemplateSelection CanChatThreadBeUsedForTemplate="@this.CanThreadBeSaved" CurrentChatThread="@this.ChatThread" CurrentChatTemplate="@this.currentChatTemplate" CurrentChatTemplateChanged="@this.ChatTemplateWasChanged"/>
|
||||
<AttachDocuments Name="File Attachments" Layer="@DropLayers.PAGES" @bind-DocumentPaths="@this.chatDocumentPaths" CatchAllDocuments="true" UseSmallForm="true" Provider="@this.Provider"/>
|
||||
|
||||
@if (this.SettingsManager.ConfigurationData.Workspace.StorageBehavior is WorkspaceStorageBehavior.STORE_CHATS_AUTOMATICALLY)
|
||||
{
|
||||
@ -98,7 +99,36 @@
|
||||
<MudIconButton Icon="@Icons.Material.Filled.MoveToInbox" Disabled="@(!this.CanThreadBeSaved)" OnClick="@(() => this.MoveChatToWorkspace())"/>
|
||||
</MudTooltip>
|
||||
}
|
||||
|
||||
|
||||
<AttachDocuments Name="File Attachments" Layer="@DropLayers.PAGES" @bind-DocumentPaths="@this.chatDocumentPaths" CatchAllDocuments="true" UseSmallForm="true" Provider="@this.Provider"/>
|
||||
|
||||
<MudDivider Vertical="true" Style="height: 24px; align-self: center;"/>
|
||||
|
||||
<MudTooltip Text="@T("Bold")" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
|
||||
<MudIconButton Icon="@Icons.Material.Filled.FormatBold" OnClick="() => this.ApplyMarkdownFormat(MARKDOWN_BOLD)" Disabled="@this.IsInputForbidden()"/>
|
||||
</MudTooltip>
|
||||
<MudTooltip Text="@T("Italic")" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
|
||||
<MudIconButton Icon="@Icons.Material.Filled.FormatItalic" OnClick="() => this.ApplyMarkdownFormat(MARKDOWN_ITALIC)" Disabled="@this.IsInputForbidden()"/>
|
||||
</MudTooltip>
|
||||
<MudTooltip Text="@T("Heading")" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
|
||||
<MudIconButton Icon="@Icons.Material.Filled.TextFields" OnClick="() => this.ApplyMarkdownFormat(MARKDOWN_HEADING)" Disabled="@this.IsInputForbidden()"/>
|
||||
</MudTooltip>
|
||||
<MudTooltip Text="@T("Bulleted List")" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
|
||||
<MudIconButton Icon="@Icons.Material.Filled.FormatListBulleted" OnClick="() => this.ApplyMarkdownFormat(MARKDOWN_BULLET_LIST)" Disabled="@this.IsInputForbidden()"/>
|
||||
</MudTooltip>
|
||||
<MudTooltip Text="@T("Code")" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Code" OnClick="() => this.ApplyMarkdownFormat(MARKDOWN_CODE)" Disabled="@this.IsInputForbidden()"/>
|
||||
</MudTooltip>
|
||||
|
||||
<MudDivider Vertical="true" Style="height: 24px; align-self: center;"/>
|
||||
|
||||
<ProfileSelection MarginLeft="" CurrentProfile="@this.currentProfile" CurrentProfileChanged="@this.ProfileWasChanged" Disabled="@(!this.currentChatTemplate.AllowProfileUsage)" DisabledText="@T("Profile usage is disabled according to your chat template settings.")"/>
|
||||
|
||||
@if (PreviewFeatures.PRE_RAG_2024.IsEnabled(this.SettingsManager))
|
||||
{
|
||||
<DataSourceSelection @ref="@this.dataSourceSelectionComponent" PopoverTriggerMode="PopoverTriggerMode.BUTTON" LLMProvider="@this.Provider" DataSourceOptions="@this.GetCurrentDataSourceOptions()" DataSourceOptionsChanged="@(async options => await this.SetCurrentDataSourceOptions(options))" DataSourcesAISelected="@this.GetAgentSelectedDataSources()"/>
|
||||
}
|
||||
|
||||
@if (this.SettingsManager.ConfigurationData.LLMProviders.ShowProviderConfidence)
|
||||
{
|
||||
<ConfidenceInfo Mode="PopoverTriggerMode.ICON" LLMProvider="@this.Provider.UsedLLMProvider"/>
|
||||
@ -110,14 +140,8 @@
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Stop" Color="Color.Error" OnClick="@(() => this.CancelStreaming())"/>
|
||||
</MudTooltip>
|
||||
}
|
||||
|
||||
<ProfileSelection CurrentProfile="@this.currentProfile" CurrentProfileChanged="@this.ProfileWasChanged" Disabled="@(!this.currentChatTemplate.AllowProfileUsage)" DisabledText="@T("Profile usage is disabled according to your chat template settings.")"/>
|
||||
|
||||
@if (PreviewFeatures.PRE_RAG_2024.IsEnabled(this.SettingsManager))
|
||||
{
|
||||
<DataSourceSelection @ref="@this.dataSourceSelectionComponent" PopoverTriggerMode="PopoverTriggerMode.BUTTON" PopoverButtonClasses="ma-3" LLMProvider="@this.Provider" DataSourceOptions="@this.GetCurrentDataSourceOptions()" DataSourceOptionsChanged="@(async options => await this.SetCurrentDataSourceOptions(options))" DataSourcesAISelected="@this.GetAgentSelectedDataSources()"/>
|
||||
}
|
||||
|
||||
|
||||
@if (!this.ChatThread.IsLLMProviderAllowed(this.Provider))
|
||||
{
|
||||
<MudTooltip Text="@T("The selected provider is not allowed in this chat due to data security reasons.")" Placement="@TOOLBAR_TOOLTIP_PLACEMENT">
|
||||
@ -129,4 +153,4 @@
|
||||
<HalluzinationReminder ContainerClass="my-0 ml-2 me-2"/>
|
||||
</MudToolBar>
|
||||
</FooterContent>
|
||||
</InnerScrolling>
|
||||
</InnerScrolling>
|
||||
|
||||
@ -13,6 +13,13 @@ namespace AIStudio.Components;
|
||||
|
||||
public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
||||
{
|
||||
private const string CHAT_INPUT_ID = "chat-user-input";
|
||||
private const string MARKDOWN_CODE = "code";
|
||||
private const string MARKDOWN_BOLD = "bold";
|
||||
private const string MARKDOWN_ITALIC = "italic";
|
||||
private const string MARKDOWN_HEADING = "heading";
|
||||
private const string MARKDOWN_BULLET_LIST = "bullet_list";
|
||||
|
||||
[Parameter]
|
||||
public ChatThread? ChatThread { get; set; }
|
||||
|
||||
@ -36,6 +43,9 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
||||
|
||||
[Inject]
|
||||
private IDialogService DialogService { get; init; } = null!;
|
||||
|
||||
[Inject]
|
||||
private IJSRuntime JsRuntime { get; init; } = null!;
|
||||
|
||||
private const Placement TOOLBAR_TOOLTIP_PLACEMENT = Placement.Top;
|
||||
private static readonly Dictionary<string, object?> USER_INPUT_ATTRIBUTES = new();
|
||||
@ -73,6 +83,7 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
||||
|
||||
// Configure the spellchecking for the user input:
|
||||
this.SettingsManager.InjectSpellchecking(USER_INPUT_ATTRIBUTES);
|
||||
USER_INPUT_ATTRIBUTES["id"] = CHAT_INPUT_ID;
|
||||
|
||||
// Get the preselected profile:
|
||||
this.currentProfile = this.SettingsManager.GetPreselectedProfile(Tools.Components.CHAT);
|
||||
@ -463,6 +474,18 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ApplyMarkdownFormat(string formatType)
|
||||
{
|
||||
if (this.IsInputForbidden())
|
||||
return;
|
||||
|
||||
if(this.dataSourceSelectionComponent?.IsVisible ?? false)
|
||||
this.dataSourceSelectionComponent.Hide();
|
||||
|
||||
this.userInput = await this.JsRuntime.InvokeAsync<string>("formatChatInputMarkdown", CHAT_INPUT_ID, formatType);
|
||||
this.hasUnsavedChanges = true;
|
||||
}
|
||||
|
||||
private async Task SendMessage(bool reuseLastUserPrompt = false)
|
||||
{
|
||||
@ -1018,4 +1041,4 @@ public partial class ChatComponent : MSGComponentBase, IAsyncDisposable
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
<MudIconButton Size="Size.Small" Icon="@Icons.Material.Filled.Person4" />
|
||||
<MudIconButton Icon="@Icons.Material.Filled.Person4" Color="Color.Default" />
|
||||
}
|
||||
</ActivatorContent>
|
||||
<ChildContent>
|
||||
@ -25,4 +25,4 @@
|
||||
}
|
||||
</ChildContent>
|
||||
</MudMenu>
|
||||
</MudTooltip>
|
||||
</MudTooltip>
|
||||
|
||||
@ -1593,6 +1593,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T1133040906"] = "Chat vers
|
||||
-- Are you sure you want to move this chat? All unsaved changes will be lost.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T1142475422"] = "Sind Sie sicher, dass Sie diesen Chat verschieben möchten? Alle ungespeicherten Änderungen gehen verloren."
|
||||
|
||||
-- Bold
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T1165397398"] = "Fett"
|
||||
|
||||
-- Stop generation
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T1317408357"] = "Generierung stoppen"
|
||||
|
||||
@ -1605,9 +1608,18 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T1849313532"] = "Geben Sie
|
||||
-- Your Prompt (use selected instance '{0}', provider '{1}')
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T1967611328"] = "Ihr Prompt (verwendete Instanz: '{0}', Anbieter: '{1}')"
|
||||
|
||||
-- Code
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T2036185364"] = "Code"
|
||||
|
||||
-- Italic
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T2377171085"] = "Kursiv"
|
||||
|
||||
-- Profile usage is disabled according to your chat template settings.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T2670286472"] = "Die Profilnutzung ist gemäß den Einstellungen ihrer Chat-Vorlage deaktiviert."
|
||||
|
||||
-- Bulleted List
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T2957125464"] = "Aufzählungszeichen"
|
||||
|
||||
-- Delete this chat & start a new one.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T2991985411"] = "Diesen Chat löschen & einen neuen beginnen."
|
||||
|
||||
@ -1626,6 +1638,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T3928697643"] = "Neuen Cha
|
||||
-- New disappearing chat
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T4113970938"] = "Neuen selbstlöschenden Chat starten"
|
||||
|
||||
-- Heading
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T4231005109"] = "Überschrift"
|
||||
|
||||
-- Please select the workspace where you want to move the chat to.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T474393241"] = "Bitte wählen Sie den Arbeitsbereich aus, in den Sie den Chat verschieben möchten."
|
||||
|
||||
|
||||
@ -1593,6 +1593,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T1133040906"] = "Move chat
|
||||
-- Are you sure you want to move this chat? All unsaved changes will be lost.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T1142475422"] = "Are you sure you want to move this chat? All unsaved changes will be lost."
|
||||
|
||||
-- Bold
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T1165397398"] = "Bold"
|
||||
|
||||
-- Stop generation
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T1317408357"] = "Stop generation"
|
||||
|
||||
@ -1605,9 +1608,18 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T1849313532"] = "Type your
|
||||
-- Your Prompt (use selected instance '{0}', provider '{1}')
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T1967611328"] = "Your Prompt (use selected instance '{0}', provider '{1}')"
|
||||
|
||||
-- Code
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T2036185364"] = "Code"
|
||||
|
||||
-- Italic
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T2377171085"] = "Italic"
|
||||
|
||||
-- Profile usage is disabled according to your chat template settings.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T2670286472"] = "Profile usage is disabled according to your chat template settings."
|
||||
|
||||
-- Bulleted List
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T2957125464"] = "Bulleted List"
|
||||
|
||||
-- Delete this chat & start a new one.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T2991985411"] = "Delete this chat & start a new one."
|
||||
|
||||
@ -1626,6 +1638,9 @@ UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T3928697643"] = "Start new
|
||||
-- New disappearing chat
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T4113970938"] = "New disappearing chat"
|
||||
|
||||
-- Heading
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T4231005109"] = "Heading"
|
||||
|
||||
-- Please select the workspace where you want to move the chat to.
|
||||
UI_TEXT_CONTENT["AISTUDIO::COMPONENTS::CHATCOMPONENT::T474393241"] = "Please select the workspace where you want to move the chat to."
|
||||
|
||||
|
||||
@ -25,4 +25,109 @@ window.clearDiv = function (divName) {
|
||||
|
||||
window.scrollToBottom = function(element) {
|
||||
element.scrollIntoView({ behavior: 'smooth', block: 'end', inline: 'nearest' });
|
||||
}
|
||||
}
|
||||
|
||||
window.formatChatInputMarkdown = function (inputId, formatType) {
|
||||
let input = document.getElementById(inputId)
|
||||
if (input && input.tagName !== 'TEXTAREA' && input.tagName !== 'INPUT')
|
||||
input = input.querySelector('textarea, input')
|
||||
|
||||
if (!input)
|
||||
return ''
|
||||
|
||||
input.focus()
|
||||
|
||||
const value = input.value ?? ''
|
||||
const start = input.selectionStart ?? value.length
|
||||
const end = input.selectionEnd ?? value.length
|
||||
const hasSelection = end > start
|
||||
const selectedText = value.substring(start, end)
|
||||
|
||||
let insertedText = ''
|
||||
let selectionStart = start
|
||||
let selectionEnd = start
|
||||
|
||||
switch (formatType) {
|
||||
case 'bold': {
|
||||
const text = hasSelection ? selectedText : ''
|
||||
insertedText = `**${text}**`
|
||||
selectionStart = start + 2
|
||||
selectionEnd = selectionStart + text.length
|
||||
break
|
||||
}
|
||||
|
||||
case 'italic': {
|
||||
const text = hasSelection ? selectedText : ''
|
||||
insertedText = `*${text}*`
|
||||
selectionStart = start + 1
|
||||
selectionEnd = selectionStart + text.length
|
||||
break
|
||||
}
|
||||
|
||||
case 'heading': {
|
||||
if (hasSelection) {
|
||||
insertedText = selectedText
|
||||
.split('\n')
|
||||
.map(line => line.startsWith('# ') ? line : `# ${line}`)
|
||||
.join('\n')
|
||||
|
||||
selectionStart = start
|
||||
selectionEnd = start + insertedText.length
|
||||
} else {
|
||||
const text = ''
|
||||
insertedText = `# ${text}`
|
||||
selectionStart = start + 2
|
||||
selectionEnd = selectionStart + text.length
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
case 'bullet_list': {
|
||||
if (hasSelection) {
|
||||
insertedText = selectedText
|
||||
.split('\n')
|
||||
.map(line => line.startsWith('- ') ? line : `- ${line}`)
|
||||
.join('\n')
|
||||
|
||||
selectionStart = start
|
||||
selectionEnd = start + insertedText.length
|
||||
} else {
|
||||
insertedText = '- '
|
||||
selectionStart = start + 2
|
||||
selectionEnd = start + insertedText.length
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
case 'code':
|
||||
default: {
|
||||
if (hasSelection) {
|
||||
if (selectedText.includes('\n')) {
|
||||
insertedText = `\`\`\`\n${selectedText}\n\`\`\``
|
||||
selectionStart = start + 4
|
||||
selectionEnd = selectionStart + selectedText.length
|
||||
} else {
|
||||
insertedText = `\`${selectedText}\``
|
||||
selectionStart = start + 1
|
||||
selectionEnd = selectionStart + selectedText.length
|
||||
}
|
||||
} else {
|
||||
const text = ''
|
||||
insertedText = `\`${text}\``
|
||||
selectionStart = start + 1
|
||||
selectionEnd = selectionStart + text.length
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
const nextValue = value.slice(0, start) + insertedText + value.slice(end)
|
||||
input.value = nextValue
|
||||
input.setSelectionRange(selectionStart, selectionEnd)
|
||||
input.dispatchEvent(new Event('input', { bubbles: true }))
|
||||
|
||||
return nextValue
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
# v26.3.1, build 235 (2026-03-xx xx:xx UTC)
|
||||
- Added support for the new Qwen 3.5 model family.
|
||||
- Added a reminder in chats and assistants that LLMs can make mistakes, helping you double-check important information more easily.
|
||||
- Added the ability to format your user prompt in the chat using icons instead of typing Markdown directly.
|
||||
- Improved the performance by caching the OS language detection and requesting the user language only once per app start.
|
||||
- Improved the chat performance by reducing unnecessary UI updates, making chats smoother and more responsive, especially in longer conversations.
|
||||
- Improved the workspace loading experience: when opening the chat for the first time, your workspaces now appear faster and load step by step in the background, with placeholder rows so the app feels responsive right away.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user