2024-07-13 08:37:57 +00:00
using System.Text ;
using System.Text.Json ;
using AIStudio.Chat ;
2024-08-21 06:30:01 +00:00
using AIStudio.Dialogs ;
2024-07-13 08:37:57 +00:00
using AIStudio.Settings ;
using Microsoft.AspNetCore.Components ;
2024-08-21 06:30:01 +00:00
using DialogOptions = AIStudio . Dialogs . DialogOptions ;
2024-07-13 08:37:57 +00:00
2024-08-21 06:30:01 +00:00
namespace AIStudio.Components ;
2024-07-13 08:37:57 +00:00
2025-04-27 07:06:05 +00:00
public partial class Workspaces : MSGComponentBase
2024-07-13 08:37:57 +00:00
{
[Inject]
2024-08-01 19:53:28 +00:00
private IDialogService DialogService { get ; init ; } = null ! ;
2024-07-13 08:37:57 +00:00
[Inject]
2024-08-01 19:53:28 +00:00
private ThreadSafeRandom RNG { get ; init ; } = null ! ;
2024-07-13 08:37:57 +00:00
2024-09-01 18:10:03 +00:00
[Inject]
private ILogger < Workspaces > Logger { get ; init ; } = null ! ;
2024-07-13 08:37:57 +00:00
[Parameter]
public ChatThread ? CurrentChatThread { get ; set ; }
[Parameter]
public EventCallback < ChatThread > CurrentChatThreadChanged { get ; set ; }
2024-11-02 21:53:02 +00:00
[Parameter]
public bool ExpandRootNodes { get ; set ; } = true ;
2024-07-13 08:37:57 +00:00
private const Placement WORKSPACE_ITEM_TOOLTIP_PLACEMENT = Placement . Bottom ;
2024-07-24 13:17:45 +00:00
private readonly List < TreeItemData < ITreeItem > > treeItems = new ( ) ;
2024-07-13 08:37:57 +00:00
#region Overrides of ComponentBase
protected override async Task OnInitializedAsync ( )
{
2025-04-27 14:13:15 +00:00
await base . OnInitializedAsync ( ) ;
2024-07-13 08:37:57 +00:00
//
// Notice: In order to get the server-based loading to work, we need to respect the following rules:
// - We must have initial tree items
// - Those initial tree items cannot have children
// - When assigning the tree items to the MudTreeViewItem component, we must set the Value property to the value of the item
//
await this . LoadTreeItems ( ) ;
}
#endregion
private async Task LoadTreeItems ( )
{
2024-11-02 21:53:02 +00:00
var workspacesNode = new TreeItemData < ITreeItem >
2024-07-13 08:37:57 +00:00
{
2024-11-02 21:53:02 +00:00
Expanded = this . ExpandRootNodes ,
2024-07-13 08:37:57 +00:00
Expandable = true ,
2024-07-24 13:17:45 +00:00
Value = new TreeItemData
{
Depth = 0 ,
Branch = WorkspaceBranch . WORKSPACES ,
2025-04-27 07:06:05 +00:00
Text = T ( "Workspaces" ) ,
2024-07-24 13:17:45 +00:00
Icon = Icons . Material . Filled . Folder ,
Expandable = true ,
Path = "root" ,
Children = await this . LoadWorkspaces ( ) ,
} ,
2024-11-02 21:53:02 +00:00
} ;
2024-07-13 08:37:57 +00:00
2024-11-02 21:53:02 +00:00
var tempChatNode = new TreeItemData < ITreeItem >
2024-07-13 08:37:57 +00:00
{
2024-11-02 21:53:02 +00:00
Expanded = this . ExpandRootNodes ,
2024-07-13 08:37:57 +00:00
Expandable = true ,
2024-07-24 13:17:45 +00:00
Value = new TreeItemData
{
Depth = 0 ,
Branch = WorkspaceBranch . TEMPORARY_CHATS ,
2025-04-27 07:06:05 +00:00
Text = T ( "Disappearing Chats" ) ,
2024-07-24 13:17:45 +00:00
Icon = Icons . Material . Filled . Timer ,
Expandable = true ,
Path = "temp" ,
Children = await this . LoadTemporaryChats ( ) ,
} ,
2024-11-02 21:53:02 +00:00
} ;
this . treeItems . Clear ( ) ;
this . treeItems . Add ( workspacesNode ) ;
this . treeItems . Add ( new TreeItemData < ITreeItem >
{
Expandable = false ,
Value = new TreeDivider ( ) ,
2024-07-13 08:37:57 +00:00
} ) ;
2024-11-02 21:53:02 +00:00
this . treeItems . Add ( tempChatNode ) ;
2024-07-13 08:37:57 +00:00
}
2024-07-24 13:17:45 +00:00
private async Task < IReadOnlyCollection < TreeItemData < ITreeItem > > > LoadTemporaryChats ( )
2024-07-13 08:37:57 +00:00
{
2024-08-19 18:19:55 +00:00
var tempChildren = new List < TreeItemData > ( ) ;
// Get the temp root directory:
2024-07-13 08:37:57 +00:00
var temporaryDirectories = Path . Join ( SettingsManager . DataDirectory , "tempChats" ) ;
// Ensure the directory exists:
Directory . CreateDirectory ( temporaryDirectories ) ;
2024-08-19 18:19:55 +00:00
// Enumerate the chat directories:
2024-07-13 08:37:57 +00:00
foreach ( var tempChatDirPath in Directory . EnumerateDirectories ( temporaryDirectories ) )
{
// Read the `name` file:
var chatNamePath = Path . Join ( tempChatDirPath , "name" ) ;
var chatName = await File . ReadAllTextAsync ( chatNamePath , Encoding . UTF8 ) ;
2024-08-19 18:19:55 +00:00
// Read the last change time of the chat:
var chatThreadPath = Path . Join ( tempChatDirPath , "thread.json" ) ;
var lastEditTime = File . GetLastWriteTimeUtc ( chatThreadPath ) ;
tempChildren . Add ( new TreeItemData
2024-07-13 08:37:57 +00:00
{
2024-08-19 18:19:55 +00:00
Type = TreeItemType . CHAT ,
Depth = 1 ,
Branch = WorkspaceBranch . TEMPORARY_CHATS ,
Text = chatName ,
Icon = Icons . Material . Filled . Timer ,
2024-07-13 08:37:57 +00:00
Expandable = false ,
2024-08-19 18:19:55 +00:00
Path = tempChatDirPath ,
LastEditTime = lastEditTime ,
2024-07-13 08:37:57 +00:00
} ) ;
}
2024-08-19 18:19:55 +00:00
var result = new List < TreeItemData < ITreeItem > > ( tempChildren . OrderByDescending ( n = > n . LastEditTime ) . Select ( n = > new TreeItemData < ITreeItem >
{
Expandable = false ,
Value = n ,
} ) ) ;
return result ;
2024-07-13 08:37:57 +00:00
}
2024-07-24 13:17:45 +00:00
private async Task < IReadOnlyCollection < TreeItemData < ITreeItem > > > LoadWorkspaces ( )
2024-07-13 08:37:57 +00:00
{
2024-07-24 13:17:45 +00:00
var workspaces = new List < TreeItemData < ITreeItem > > ( ) ;
2024-07-13 08:37:57 +00:00
//
// Search for workspace folders in the data directory:
//
// Get the workspace root directory:
var workspaceDirectories = Path . Join ( SettingsManager . DataDirectory , "workspaces" ) ;
// Ensure the directory exists:
Directory . CreateDirectory ( workspaceDirectories ) ;
// Enumerate the workspace directories:
foreach ( var workspaceDirPath in Directory . EnumerateDirectories ( workspaceDirectories ) )
{
// Read the `name` file:
var workspaceNamePath = Path . Join ( workspaceDirPath , "name" ) ;
var workspaceName = await File . ReadAllTextAsync ( workspaceNamePath , Encoding . UTF8 ) ;
2024-07-24 13:17:45 +00:00
workspaces . Add ( new TreeItemData < ITreeItem >
2024-07-13 08:37:57 +00:00
{
Expandable = true ,
2024-07-24 13:17:45 +00:00
Value = new TreeItemData
{
Type = TreeItemType . WORKSPACE ,
Depth = 1 ,
Branch = WorkspaceBranch . WORKSPACES ,
Text = workspaceName ,
Icon = Icons . Material . Filled . Description ,
Expandable = true ,
Path = workspaceDirPath ,
Children = await this . LoadWorkspaceChats ( workspaceDirPath ) ,
} ,
2024-07-13 08:37:57 +00:00
} ) ;
}
2024-07-24 13:17:45 +00:00
workspaces . Add ( new TreeItemData < ITreeItem >
{
Expandable = false ,
2025-04-27 07:06:05 +00:00
Value = new TreeButton ( WorkspaceBranch . WORKSPACES , 1 , T ( "Add workspace" ) , Icons . Material . Filled . LibraryAdd , this . AddWorkspace ) ,
2024-07-24 13:17:45 +00:00
} ) ;
2024-07-13 08:37:57 +00:00
return workspaces ;
}
2024-07-24 13:17:45 +00:00
private async Task < IReadOnlyCollection < TreeItemData < ITreeItem > > > LoadWorkspaceChats ( string workspacePath )
2024-07-13 08:37:57 +00:00
{
2024-08-19 18:19:55 +00:00
var workspaceChats = new List < TreeItemData > ( ) ;
2024-07-13 08:37:57 +00:00
// Enumerate the workspace directory:
foreach ( var chatPath in Directory . EnumerateDirectories ( workspacePath ) )
{
// Read the `name` file:
var chatNamePath = Path . Join ( chatPath , "name" ) ;
var chatName = await File . ReadAllTextAsync ( chatNamePath , Encoding . UTF8 ) ;
2024-08-19 18:19:55 +00:00
// Read the last change time of the chat:
var chatThreadPath = Path . Join ( chatPath , "thread.json" ) ;
var lastEditTime = File . GetLastWriteTimeUtc ( chatThreadPath ) ;
2024-07-13 08:37:57 +00:00
2024-08-19 18:19:55 +00:00
workspaceChats . Add ( new TreeItemData
2024-07-13 08:37:57 +00:00
{
2024-08-19 18:19:55 +00:00
Type = TreeItemType . CHAT ,
Depth = 2 ,
Branch = WorkspaceBranch . WORKSPACES ,
Text = chatName ,
Icon = Icons . Material . Filled . Chat ,
2024-07-13 08:37:57 +00:00
Expandable = false ,
2024-08-19 18:19:55 +00:00
Path = chatPath ,
LastEditTime = lastEditTime ,
2024-07-13 08:37:57 +00:00
} ) ;
}
2024-08-19 18:19:55 +00:00
var result = new List < TreeItemData < ITreeItem > > ( workspaceChats . OrderByDescending ( n = > n . LastEditTime ) . Select ( n = > new TreeItemData < ITreeItem >
{
Expandable = false ,
Value = n ,
} ) ) ;
result . Add ( new ( )
2024-07-24 13:17:45 +00:00
{
Expandable = false ,
2025-04-27 07:06:05 +00:00
Value = new TreeButton ( WorkspaceBranch . WORKSPACES , 2 , T ( "Add chat" ) , Icons . Material . Filled . AddComment , ( ) = > this . AddChat ( workspacePath ) ) ,
2024-07-24 13:17:45 +00:00
} ) ;
2024-08-19 18:19:55 +00:00
return result ;
2024-07-13 08:37:57 +00:00
}
2024-10-28 14:41:00 +00:00
public async Task StoreChat ( ChatThread chat , bool reloadTreeItems = true )
2024-07-13 08:37:57 +00:00
{
2024-11-15 20:22:57 +00:00
await WorkspaceBehaviour . StoreChat ( chat ) ;
2024-07-13 08:37:57 +00:00
// Reload the tree items:
2024-10-28 14:41:00 +00:00
if ( reloadTreeItems )
await this . LoadTreeItems ( ) ;
2024-07-13 08:37:57 +00:00
this . StateHasChanged ( ) ;
}
private async Task < ChatThread ? > LoadChat ( string? chatPath , bool switchToChat )
{
if ( string . IsNullOrWhiteSpace ( chatPath ) )
return null ;
if ( ! Directory . Exists ( chatPath ) )
return null ;
// Check if the chat has unsaved changes:
if ( switchToChat & & await MessageBus . INSTANCE . SendMessageUseFirstResult < bool , bool > ( this , Event . HAS_CHAT_UNSAVED_CHANGES ) )
{
var dialogParameters = new DialogParameters
{
2025-04-27 07:06:05 +00:00
{ "Message" , T ( "Are you sure you want to load another chat? All unsaved changes will be lost." ) } ,
2024-07-13 08:37:57 +00:00
} ;
2025-04-27 07:06:05 +00:00
var dialogReference = await this . DialogService . ShowAsync < ConfirmDialog > ( T ( "Load Chat" ) , dialogParameters , DialogOptions . FULLSCREEN ) ;
2024-07-13 08:37:57 +00:00
var dialogResult = await dialogReference . Result ;
2024-07-24 13:17:45 +00:00
if ( dialogResult is null | | dialogResult . Canceled )
2024-07-13 08:37:57 +00:00
return null ;
}
try
{
var chatData = await File . ReadAllTextAsync ( Path . Join ( chatPath , "thread.json" ) , Encoding . UTF8 ) ;
2024-11-15 20:22:57 +00:00
var chat = JsonSerializer . Deserialize < ChatThread > ( chatData , WorkspaceBehaviour . JSON_OPTIONS ) ;
2024-07-13 08:37:57 +00:00
if ( switchToChat )
{
this . CurrentChatThread = chat ;
await this . CurrentChatThreadChanged . InvokeAsync ( this . CurrentChatThread ) ;
2025-01-02 12:16:47 +00:00
await MessageBus . INSTANCE . SendMessage < bool > ( this , Event . WORKSPACE_LOADED_CHAT_CHANGED ) ;
2024-07-13 08:37:57 +00:00
}
return chat ;
}
catch ( Exception e )
{
2024-09-01 18:10:03 +00:00
this . Logger . LogError ( $"Failed to load chat from '{chatPath}': {e.Message}" ) ;
2024-07-13 08:37:57 +00:00
}
return null ;
}
public async Task DeleteChat ( string? chatPath , bool askForConfirmation = true , bool unloadChat = true )
{
var chat = await this . LoadChat ( chatPath , false ) ;
if ( chat is null )
return ;
if ( askForConfirmation )
{
2024-11-15 20:22:57 +00:00
var workspaceName = await WorkspaceBehaviour . LoadWorkspaceName ( chat . WorkspaceId ) ;
2024-07-13 08:37:57 +00:00
var dialogParameters = new DialogParameters
{
{
"Message" , ( chat . WorkspaceId = = Guid . Empty ) switch
{
2025-04-27 07:06:05 +00:00
true = > string . Format ( T ( "Are you sure you want to delete the temporary chat '{0}'?" ) , chat . Name ) ,
false = > string . Format ( T ( "Are you sure you want to delete the chat '{0}' in the workspace '{1}'?" ) , chat . Name , workspaceName ) ,
2024-07-13 08:37:57 +00:00
}
} ,
} ;
2025-04-27 07:06:05 +00:00
var dialogReference = await this . DialogService . ShowAsync < ConfirmDialog > ( T ( "Delete Chat" ) , dialogParameters , DialogOptions . FULLSCREEN ) ;
2024-07-13 08:37:57 +00:00
var dialogResult = await dialogReference . Result ;
2024-07-24 13:17:45 +00:00
if ( dialogResult is null | | dialogResult . Canceled )
2024-07-13 08:37:57 +00:00
return ;
}
string chatDirectory ;
if ( chat . WorkspaceId = = Guid . Empty )
chatDirectory = Path . Join ( SettingsManager . DataDirectory , "tempChats" , chat . ChatId . ToString ( ) ) ;
else
chatDirectory = Path . Join ( SettingsManager . DataDirectory , "workspaces" , chat . WorkspaceId . ToString ( ) , chat . ChatId . ToString ( ) ) ;
Directory . Delete ( chatDirectory , true ) ;
await this . LoadTreeItems ( ) ;
if ( unloadChat & & this . CurrentChatThread ? . ChatId = = chat . ChatId )
{
this . CurrentChatThread = null ;
await this . CurrentChatThreadChanged . InvokeAsync ( this . CurrentChatThread ) ;
2025-01-02 12:16:47 +00:00
await MessageBus . INSTANCE . SendMessage < bool > ( this , Event . WORKSPACE_LOADED_CHAT_CHANGED ) ;
2024-07-13 08:37:57 +00:00
}
}
private async Task RenameChat ( string? chatPath )
{
var chat = await this . LoadChat ( chatPath , false ) ;
if ( chat is null )
return ;
var dialogParameters = new DialogParameters
{
2025-04-27 07:06:05 +00:00
{ "Message" , string . Format ( T ( "Please enter a new or edit the name for your chat '{0}':" ) , chat . Name ) } ,
2024-07-13 08:37:57 +00:00
{ "UserInput" , chat . Name } ,
2025-04-27 07:06:05 +00:00
{ "ConfirmText" , T ( "Rename" ) } ,
2024-07-13 08:37:57 +00:00
{ "ConfirmColor" , Color . Info } ,
} ;
2025-04-27 07:06:05 +00:00
var dialogReference = await this . DialogService . ShowAsync < SingleInputDialog > ( T ( "Rename Chat" ) , dialogParameters , DialogOptions . FULLSCREEN ) ;
2024-07-13 08:37:57 +00:00
var dialogResult = await dialogReference . Result ;
2024-07-24 13:17:45 +00:00
if ( dialogResult is null | | dialogResult . Canceled )
2024-07-13 08:37:57 +00:00
return ;
chat . Name = ( dialogResult . Data as string ) ! ;
await this . StoreChat ( chat ) ;
await this . LoadTreeItems ( ) ;
}
private async Task RenameWorkspace ( string? workspacePath )
{
if ( workspacePath is null )
return ;
var workspaceId = Guid . Parse ( Path . GetFileName ( workspacePath ) ) ;
2024-11-15 20:22:57 +00:00
var workspaceName = await WorkspaceBehaviour . LoadWorkspaceName ( workspaceId ) ;
2024-07-13 08:37:57 +00:00
var dialogParameters = new DialogParameters
{
2025-04-27 07:06:05 +00:00
{ "Message" , string . Format ( T ( "Please enter a new or edit the name for your workspace '{0}':" ) , workspaceName ) } ,
2024-07-13 08:37:57 +00:00
{ "UserInput" , workspaceName } ,
2025-04-27 07:06:05 +00:00
{ "ConfirmText" , T ( "Rename" ) } ,
2024-07-13 08:37:57 +00:00
{ "ConfirmColor" , Color . Info } ,
} ;
2025-04-27 07:06:05 +00:00
var dialogReference = await this . DialogService . ShowAsync < SingleInputDialog > ( T ( "Rename Workspace" ) , dialogParameters , DialogOptions . FULLSCREEN ) ;
2024-07-13 08:37:57 +00:00
var dialogResult = await dialogReference . Result ;
2024-07-24 13:17:45 +00:00
if ( dialogResult is null | | dialogResult . Canceled )
2024-07-13 08:37:57 +00:00
return ;
var alteredWorkspaceName = ( dialogResult . Data as string ) ! ;
var workspaceNamePath = Path . Join ( workspacePath , "name" ) ;
await File . WriteAllTextAsync ( workspaceNamePath , alteredWorkspaceName , Encoding . UTF8 ) ;
await this . LoadTreeItems ( ) ;
}
private async Task AddWorkspace ( )
{
var dialogParameters = new DialogParameters
{
2025-04-27 07:06:05 +00:00
{ "Message" , T ( "Please name your workspace:" ) } ,
2024-07-13 08:37:57 +00:00
{ "UserInput" , string . Empty } ,
2025-04-27 07:06:05 +00:00
{ "ConfirmText" , T ( "Add workspace" ) } ,
2024-07-13 08:37:57 +00:00
{ "ConfirmColor" , Color . Info } ,
} ;
2025-04-27 07:06:05 +00:00
var dialogReference = await this . DialogService . ShowAsync < SingleInputDialog > ( T ( "Add Workspace" ) , dialogParameters , DialogOptions . FULLSCREEN ) ;
2024-07-13 08:37:57 +00:00
var dialogResult = await dialogReference . Result ;
2024-07-24 13:17:45 +00:00
if ( dialogResult is null | | dialogResult . Canceled )
2024-07-13 08:37:57 +00:00
return ;
var workspaceId = Guid . NewGuid ( ) ;
var workspacePath = Path . Join ( SettingsManager . DataDirectory , "workspaces" , workspaceId . ToString ( ) ) ;
Directory . CreateDirectory ( workspacePath ) ;
var workspaceNamePath = Path . Join ( workspacePath , "name" ) ;
await File . WriteAllTextAsync ( workspaceNamePath , ( dialogResult . Data as string ) ! , Encoding . UTF8 ) ;
await this . LoadTreeItems ( ) ;
}
2024-10-28 14:41:00 +00:00
2024-07-13 08:37:57 +00:00
private async Task DeleteWorkspace ( string? workspacePath )
{
if ( workspacePath is null )
return ;
var workspaceId = Guid . Parse ( Path . GetFileName ( workspacePath ) ) ;
2024-11-15 20:22:57 +00:00
var workspaceName = await WorkspaceBehaviour . LoadWorkspaceName ( workspaceId ) ;
2024-07-13 08:37:57 +00:00
// Determine how many chats are in the workspace:
var chatCount = Directory . EnumerateDirectories ( workspacePath ) . Count ( ) ;
var dialogParameters = new DialogParameters
{
2025-04-27 07:06:05 +00:00
{ "Message" , string . Format ( T ( "Are you sure you want to delete the workspace '{0}'? This will also delete {1} chat(s) in this workspace." ) , workspaceName , chatCount ) } ,
2024-07-13 08:37:57 +00:00
} ;
2025-04-27 07:06:05 +00:00
var dialogReference = await this . DialogService . ShowAsync < ConfirmDialog > ( T ( "Delete Workspace" ) , dialogParameters , DialogOptions . FULLSCREEN ) ;
2024-07-13 08:37:57 +00:00
var dialogResult = await dialogReference . Result ;
2024-07-24 13:17:45 +00:00
if ( dialogResult is null | | dialogResult . Canceled )
2024-07-13 08:37:57 +00:00
return ;
Directory . Delete ( workspacePath , true ) ;
await this . LoadTreeItems ( ) ;
}
private async Task MoveChat ( string? chatPath )
{
var chat = await this . LoadChat ( chatPath , false ) ;
if ( chat is null )
return ;
var dialogParameters = new DialogParameters
{
2025-04-27 07:06:05 +00:00
{ "Message" , T ( "Please select the workspace where you want to move the chat to." ) } ,
2024-07-13 08:37:57 +00:00
{ "SelectedWorkspace" , chat . WorkspaceId } ,
2025-04-27 07:06:05 +00:00
{ "ConfirmText" , T ( "Move chat" ) } ,
2024-07-13 08:37:57 +00:00
} ;
2025-04-27 07:06:05 +00:00
var dialogReference = await this . DialogService . ShowAsync < WorkspaceSelectionDialog > ( T ( "Move Chat to Workspace" ) , dialogParameters , DialogOptions . FULLSCREEN ) ;
2024-07-13 08:37:57 +00:00
var dialogResult = await dialogReference . Result ;
2024-07-24 13:17:45 +00:00
if ( dialogResult is null | | dialogResult . Canceled )
2024-07-13 08:37:57 +00:00
return ;
2025-04-27 07:06:05 +00:00
var workspaceId = dialogResult . Data is Guid id ? id : Guid . Empty ;
2024-07-13 08:37:57 +00:00
if ( workspaceId = = Guid . Empty )
return ;
// Delete the chat from the current workspace or the temporary storage:
if ( chat . WorkspaceId = = Guid . Empty )
{
// Case: The chat is stored in the temporary storage:
await this . DeleteChat ( Path . Join ( SettingsManager . DataDirectory , "tempChats" , chat . ChatId . ToString ( ) ) , askForConfirmation : false , unloadChat : false ) ;
}
else
{
// Case: The chat is stored in a workspace.
await this . DeleteChat ( Path . Join ( SettingsManager . DataDirectory , "workspaces" , chat . WorkspaceId . ToString ( ) , chat . ChatId . ToString ( ) ) , askForConfirmation : false , unloadChat : false ) ;
}
// Update the chat's workspace:
chat . WorkspaceId = workspaceId ;
// Handle the case where the chat is the active chat:
if ( this . CurrentChatThread ? . ChatId = = chat . ChatId )
{
this . CurrentChatThread = chat ;
await this . CurrentChatThreadChanged . InvokeAsync ( this . CurrentChatThread ) ;
2025-01-02 12:16:47 +00:00
await MessageBus . INSTANCE . SendMessage < bool > ( this , Event . WORKSPACE_LOADED_CHAT_CHANGED ) ;
2024-07-13 08:37:57 +00:00
}
await this . StoreChat ( chat ) ;
}
private async Task AddChat ( string workspacePath )
{
// Check if the chat has unsaved changes:
if ( await MessageBus . INSTANCE . SendMessageUseFirstResult < bool , bool > ( this , Event . HAS_CHAT_UNSAVED_CHANGES ) )
{
var dialogParameters = new DialogParameters
{
2025-04-27 07:06:05 +00:00
{ "Message" , T ( "Are you sure you want to create a another chat? All unsaved changes will be lost." ) } ,
2024-07-13 08:37:57 +00:00
} ;
2025-04-27 07:06:05 +00:00
var dialogReference = await this . DialogService . ShowAsync < ConfirmDialog > ( T ( "Create Chat" ) , dialogParameters , DialogOptions . FULLSCREEN ) ;
2024-07-13 08:37:57 +00:00
var dialogResult = await dialogReference . Result ;
2024-07-24 13:17:45 +00:00
if ( dialogResult is null | | dialogResult . Canceled )
2024-07-13 08:37:57 +00:00
return ;
}
var workspaceId = Guid . Parse ( Path . GetFileName ( workspacePath ) ) ;
var chat = new ChatThread
{
WorkspaceId = workspaceId ,
ChatId = Guid . NewGuid ( ) ,
Name = string . Empty ,
Seed = this . RNG . Next ( ) ,
2024-11-15 20:22:57 +00:00
SystemPrompt = SystemPrompts . DEFAULT ,
2024-07-13 08:37:57 +00:00
Blocks = [ ] ,
} ;
var chatPath = Path . Join ( workspacePath , chat . ChatId . ToString ( ) ) ;
await this . StoreChat ( chat ) ;
await this . LoadChat ( chatPath , switchToChat : true ) ;
await this . LoadTreeItems ( ) ;
}
2025-04-27 14:13:15 +00:00
#region Overrides of MSGComponentBase
protected override async Task ProcessIncomingMessage < T > ( ComponentBase ? sendingComponent , Event triggeredEvent , T ? data ) where T : default
{
switch ( triggeredEvent )
{
case Event . PLUGINS_RELOADED :
await this . LoadTreeItems ( ) ;
await this . InvokeAsync ( this . StateHasChanged ) ;
break ;
}
}
#endregion
2024-07-13 08:37:57 +00:00
}