mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-08-11 20:12:12 +00:00
Routed all notifications through the message bus instead of the snackbar
This commit is contained in:
parent
2a29aa3f33
commit
18dc8bf9b8
@ -478,13 +478,13 @@ public partial class AssistantI18N : AssistantBaseCore<SettingsDialogI18N>
|
||||
{
|
||||
if (this.selectedLanguagePlugin is null)
|
||||
{
|
||||
this.Snackbar.Add(T("No language plugin selected."), Severity.Error);
|
||||
await this.MessageBus.SendError(new(Icons.Material.Filled.Translate, T("No language plugin selected.")));
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.finalLuaCode.Length == 0)
|
||||
{
|
||||
this.Snackbar.Add(T("No Lua code generated yet."), Severity.Error);
|
||||
await this.MessageBus.SendError(new(Icons.Material.Filled.Code, T("No Lua code generated yet.")));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -500,7 +500,7 @@ public partial class AssistantI18N : AssistantBaseCore<SettingsDialogI18N>
|
||||
if (!File.Exists(pluginFilePath))
|
||||
{
|
||||
this.Logger.LogError("Plugin file not found: {PluginFilePath}.", pluginFilePath);
|
||||
this.Snackbar.Add(T("Plugin file not found."), Severity.Error);
|
||||
await this.MessageBus.SendError(new(Icons.Material.Filled.FindInPage, T("Plugin file not found.")));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -514,7 +514,7 @@ public partial class AssistantI18N : AssistantBaseCore<SettingsDialogI18N>
|
||||
if (markerIndex == -1)
|
||||
{
|
||||
this.Logger.LogError("Could not find 'UI_TEXT_CONTENT = {{}}' marker in plugin file: {PluginFilePath}", pluginFilePath);
|
||||
this.Snackbar.Add(T("Could not find 'UI_TEXT_CONTENT = {}' marker in plugin file."), Severity.Error);
|
||||
await this.MessageBus.SendError(new(Icons.Material.Filled.FindInPage, T("Could not find 'UI_TEXT_CONTENT = {}' marker in plugin file.")));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -524,12 +524,12 @@ public partial class AssistantI18N : AssistantBaseCore<SettingsDialogI18N>
|
||||
|
||||
// Write the updated content back to the file:
|
||||
await File.WriteAllTextAsync(pluginFilePath, newContent);
|
||||
this.Snackbar.Add(T("Successfully updated plugin file."), Severity.Success);
|
||||
await this.MessageBus.SendSuccess(new(Icons.Material.Filled.Translate, T("Successfully updated plugin file.")));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.Logger.LogError(ex, "Error writing to plugin file.");
|
||||
this.Snackbar.Add(T("Error writing to plugin file."), Severity.Error);
|
||||
await this.MessageBus.SendError(new(Icons.Material.Filled.Translate, T("Error writing to plugin file.")));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -35,9 +35,6 @@ public partial class AssistantLogViewer : MSGComponentBase
|
||||
[Inject]
|
||||
private RustService RustService { get; init; } = null!;
|
||||
|
||||
[Inject]
|
||||
private ISnackbar Snackbar { get; init; } = null!;
|
||||
|
||||
[Inject]
|
||||
private NavigationManager NavigationManager { get; init; } = null!;
|
||||
|
||||
@ -215,11 +212,7 @@ public partial class AssistantLogViewer : MSGComponentBase
|
||||
var path = this.CurrentLogPath;
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
this.Snackbar.Add(T("The log file path is not available yet."), Severity.Warning, config =>
|
||||
{
|
||||
config.Icon = Icons.Material.Filled.Folder;
|
||||
config.IconSize = Size.Large;
|
||||
});
|
||||
await this.MessageBus.SendWarning(new(Icons.Material.Filled.Folder, T("The log file path is not available yet.")));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -231,30 +224,18 @@ public partial class AssistantLogViewer : MSGComponentBase
|
||||
catch (Exception e)
|
||||
{
|
||||
this.Logger.LogWarning(e, "Could not open the log file location in the file manager.");
|
||||
this.Snackbar.Add(T("Could not open the log file location."), Severity.Error, config =>
|
||||
{
|
||||
config.Icon = Icons.Material.Filled.Folder;
|
||||
config.IconSize = Size.Large;
|
||||
});
|
||||
await this.MessageBus.SendError(new(Icons.Material.Filled.Folder, T("Could not open the log file location.")));
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.Success)
|
||||
{
|
||||
this.Snackbar.Add(T("Opened the log file location."), Severity.Success, config =>
|
||||
{
|
||||
config.Icon = Icons.Material.Filled.FolderOpen;
|
||||
config.IconSize = Size.Large;
|
||||
});
|
||||
await this.MessageBus.SendSuccess(new(Icons.Material.Filled.FolderOpen, T("Opened the log file location.")));
|
||||
return;
|
||||
}
|
||||
|
||||
var issue = string.IsNullOrWhiteSpace(response.Issue) ? T("Unknown error") : response.Issue;
|
||||
this.Snackbar.Add(string.Format(T("Could not open the log file location: {0}"), issue), Severity.Error, config =>
|
||||
{
|
||||
config.Icon = Icons.Material.Filled.Folder;
|
||||
config.IconSize = Size.Large;
|
||||
});
|
||||
await this.MessageBus.SendError(new(Icons.Material.Filled.Folder, string.Format(T("Could not open the log file location: {0}"), issue)));
|
||||
}
|
||||
|
||||
private void ClearFilters()
|
||||
|
||||
@ -562,7 +562,7 @@ public partial class AssistantPromptOptimizer : AssistantBaseCore<SettingsDialog
|
||||
this.currentCustomPromptGuidePath = selected.FilePath;
|
||||
|
||||
if (files.Count > 1 || replacedPrevious)
|
||||
this.Snackbar.Add(T("Replaced the previously selected custom prompt guide file."), Severity.Info);
|
||||
await this.MessageBus.SendInfo(new(Icons.Material.Filled.SwapHoriz, T("Replaced the previously selected custom prompt guide file.")));
|
||||
|
||||
await this.LoadCustomPromptGuidelineContentAsync(selected);
|
||||
}
|
||||
@ -572,7 +572,7 @@ public partial class AssistantPromptOptimizer : AssistantBaseCore<SettingsDialog
|
||||
if (!fileAttachment.Exists)
|
||||
{
|
||||
this.customPromptingGuidelineContent = string.Empty;
|
||||
this.Snackbar.Add(T("The selected custom prompt guide file could not be found."), Severity.Warning);
|
||||
await this.MessageBus.SendWarning(new(Icons.Material.Filled.FindInPage, T("The selected custom prompt guide file could not be found.")));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -581,12 +581,12 @@ public partial class AssistantPromptOptimizer : AssistantBaseCore<SettingsDialog
|
||||
this.isLoadingCustomPromptGuide = true;
|
||||
this.customPromptingGuidelineContent = await UserFile.LoadFileData(fileAttachment.FilePath, this.RustService, this.DialogService);
|
||||
if (string.IsNullOrWhiteSpace(this.customPromptingGuidelineContent))
|
||||
this.Snackbar.Add(T("The custom prompt guide file is empty or could not be read."), Severity.Warning);
|
||||
await this.MessageBus.SendWarning(new(Icons.Material.Filled.Description, T("The custom prompt guide file is empty or could not be read.")));
|
||||
}
|
||||
catch
|
||||
{
|
||||
this.customPromptingGuidelineContent = string.Empty;
|
||||
this.Snackbar.Add(T("Failed to load custom prompt guide content."), Severity.Error);
|
||||
await this.MessageBus.SendError(new(Icons.Material.Filled.Description, T("Failed to load custom prompt guide content.")));
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -600,7 +600,7 @@ public partial class AssistantPromptOptimizer : AssistantBaseCore<SettingsDialog
|
||||
var promptingGuideline = await ReadPromptingGuidelineAsync();
|
||||
if (string.IsNullOrWhiteSpace(promptingGuideline))
|
||||
{
|
||||
this.Snackbar.Add(T("The prompting guideline file could not be loaded."), Severity.Warning);
|
||||
await this.MessageBus.SendWarning(new(Icons.Material.Filled.MenuBook, T("The prompting guideline file could not be loaded.")));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -89,7 +89,7 @@ public partial class VisualBriefingAssistant
|
||||
|
||||
terminalIssue = result.Issue;
|
||||
if (terminalStatus is not AssistantSessionStatus.CANCELED)
|
||||
this.Snackbar.Add(result.Issue, Severity.Error);
|
||||
await this.MessageBus.SendError(new(Icons.Material.Filled.AutoAwesome, result.Issue));
|
||||
|
||||
return;
|
||||
}
|
||||
@ -107,7 +107,7 @@ public partial class VisualBriefingAssistant
|
||||
this.UpdateProject(latest);
|
||||
}
|
||||
|
||||
this.Snackbar.Add(successMessage, Severity.Success);
|
||||
await this.MessageBus.SendSuccess(new(Icons.Material.Filled.AutoAwesome, successMessage));
|
||||
terminalStatus = AssistantSessionStatus.COMPLETED;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
@ -119,7 +119,7 @@ public partial class VisualBriefingAssistant
|
||||
{
|
||||
terminalIssue = unexpectedFailureMessage;
|
||||
this.Logger.LogError("Unexpected visual briefing UI failure. BriefingId={BriefingId} Mode={Mode} ExceptionType={ExceptionType}", briefingId, mode, exception.GetType().Name);
|
||||
this.Snackbar.Add(terminalIssue, Severity.Error);
|
||||
await this.MessageBus.SendError(new(Icons.Material.Filled.AutoAwesome, terminalIssue));
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@ -154,7 +154,7 @@ public partial class VisualBriefingAssistant
|
||||
var path = await this.Store.GetProjectDirectoryPathAsync(this.selectedProject.BriefingId);
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
this.Snackbar.Add(T("The visual briefing project folder is not available."), Severity.Warning);
|
||||
await this.MessageBus.SendWarning(new(Icons.Material.Filled.Folder, T("The visual briefing project folder is not available.")));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -166,18 +166,18 @@ public partial class VisualBriefingAssistant
|
||||
catch (Exception exception)
|
||||
{
|
||||
this.Logger.LogWarning(exception, "Could not open the visual briefing project folder. BriefingId={BriefingId}", this.selectedProject.BriefingId);
|
||||
this.Snackbar.Add(T("Could not open the visual briefing project folder."), Severity.Error);
|
||||
await this.MessageBus.SendError(new(Icons.Material.Filled.Folder, T("Could not open the visual briefing project folder.")));
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.Success)
|
||||
{
|
||||
this.Snackbar.Add(T("Opened the visual briefing project folder."), Severity.Success);
|
||||
await this.MessageBus.SendSuccess(new(Icons.Material.Filled.Folder, T("Opened the visual briefing project folder.")));
|
||||
return;
|
||||
}
|
||||
|
||||
var issue = string.IsNullOrWhiteSpace(response.Issue) ? T("Unknown error") : response.Issue;
|
||||
this.Snackbar.Add(string.Format(T("Could not open the visual briefing project folder: {0}"), issue), Severity.Error);
|
||||
await this.MessageBus.SendError(new(Icons.Material.Filled.Folder, string.Format(T("Could not open the visual briefing project folder: {0}"), issue)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -118,14 +118,14 @@ public partial class VisualBriefingAssistant
|
||||
|
||||
if (PathComparer().Equals(Path.GetFullPath(sourcePath), Path.GetFullPath(response.SaveFilePath)))
|
||||
{
|
||||
this.Snackbar.Add(T("Choose a different export location so the immutable briefing version is not overwritten."), Severity.Error);
|
||||
await this.MessageBus.SendError(new(Icons.Material.Filled.SaveAs, T("Choose a different export location so the immutable briefing version is not overwritten.")));
|
||||
return;
|
||||
}
|
||||
|
||||
var verified = await this.Store.OpenIntegrityCheckedVersionAsync(this.selectedBriefing.BriefingId, this.selectedRevisionId);
|
||||
if (verified is null)
|
||||
{
|
||||
this.Snackbar.Add(T("The selected briefing version failed its integrity check and cannot be exported."), Severity.Error);
|
||||
await this.MessageBus.SendError(new(Icons.Material.Filled.GppBad, T("The selected briefing version failed its integrity check and cannot be exported.")));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -146,7 +146,7 @@ public partial class VisualBriefingAssistant
|
||||
exportedVersion.DocumentHash,
|
||||
source.Length);
|
||||
|
||||
this.Snackbar.Add(T("The visual briefing was exported."), Severity.Success);
|
||||
await this.MessageBus.SendSuccess(new(Icons.Material.Filled.FileDownload, T("The visual briefing was exported.")));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -176,7 +176,7 @@ public partial class VisualBriefingAssistant
|
||||
|
||||
if (!imported.Success)
|
||||
{
|
||||
this.Snackbar.Add(imported.Issue, Severity.Error);
|
||||
await this.MessageBus.SendError(new(Icons.Material.Filled.FileUpload, imported.Issue));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -190,7 +190,7 @@ public partial class VisualBriefingAssistant
|
||||
imported.RevisionId,
|
||||
imported.WasDeduplicated);
|
||||
|
||||
this.Snackbar.Add(imported.WasDeduplicated ? T("This briefing revision was already imported.") : T("The visual briefing was imported."), Severity.Success);
|
||||
await this.MessageBus.SendSuccess(new(Icons.Material.Filled.FileUpload, imported.WasDeduplicated ? T("This briefing revision was already imported.") : T("The visual briefing was imported.")));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -217,7 +217,7 @@ public partial class VisualBriefingAssistant : MSGComponentBase
|
||||
"Could not auto-save visual briefing. BriefingId={BriefingId} ExceptionType={ExceptionType}",
|
||||
this.selectedBriefing.BriefingId,
|
||||
exception.GetType().Name);
|
||||
this.Snackbar.Add(T("The visual briefing settings could not be saved."), Severity.Error);
|
||||
await this.MessageBus.SendError(new(Icons.Material.Filled.SaveAs, T("The visual briefing settings could not be saved.")));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -77,12 +77,9 @@ public partial class MudCopyClipboardButton : ComponentBase
|
||||
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;
|
||||
});
|
||||
// This component is no MSGComponentBase, so it uses the shared bus instance the same
|
||||
// way FileExtensionValidation does:
|
||||
await MessageBus.INSTANCE.SendError(new(Icons.Material.Filled.ContentCopy, TB("Cannot copy this content type to clipboard.")));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ public abstract class SettingsPanelProviderBase : SettingsPanelBase
|
||||
else
|
||||
{
|
||||
// No encryption secret available - inform the user:
|
||||
this.Snackbar.Add(TB("Cannot export the encrypted API key: No enterprise encryption secret is configured."), Severity.Warning);
|
||||
await this.MessageBus.SendWarning(new(Icons.Material.Filled.Key, TB("Cannot export the encrypted API key: No enterprise encryption secret is configured.")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,7 +112,7 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan
|
||||
this.MessageBus.ApplyFilters(this, [],
|
||||
[
|
||||
Event.UPDATE_AVAILABLE, Event.CONFIGURATION_CHANGED, Event.COLOR_THEME_CHANGED, Event.SHOW_ERROR,
|
||||
Event.SHOW_WARNING, Event.SHOW_SUCCESS, Event.STARTUP_PLUGIN_SYSTEM, Event.PLUGINS_RELOADED,
|
||||
Event.SHOW_WARNING, Event.SHOW_SUCCESS, Event.SHOW_INFO, Event.STARTUP_PLUGIN_SYSTEM, Event.PLUGINS_RELOADED,
|
||||
Event.INSTALL_UPDATE, Event.STARTUP_COMPLETED, Event.AI_JOB_CHANGED, Event.AI_JOB_FINISHED,
|
||||
Event.CHAT_GENERATION_CHANGED, Event.ASSISTANT_SESSION_CHANGED, Event.ASSISTANT_SESSION_FINISHED,
|
||||
]);
|
||||
@ -266,6 +266,12 @@ public partial class MainLayout : LayoutComponentBase, IMessageBusReceiver, ILan
|
||||
|
||||
break;
|
||||
|
||||
case Event.SHOW_INFO:
|
||||
if (data is DataInfoMessage info)
|
||||
info.Show(this.Snackbar);
|
||||
|
||||
break;
|
||||
|
||||
case Event.STARTUP_PLUGIN_SYSTEM:
|
||||
_ = Task.Run(async () =>
|
||||
{
|
||||
|
||||
16
app/MindWork AI Studio/Tools/DataInfoMessage.cs
Normal file
16
app/MindWork AI Studio/Tools/DataInfoMessage.cs
Normal file
@ -0,0 +1,16 @@
|
||||
namespace AIStudio.Tools;
|
||||
|
||||
public readonly record struct DataInfoMessage(string Icon, string Message)
|
||||
{
|
||||
public void Show(ISnackbar snackbar)
|
||||
{
|
||||
var icon = this.Icon;
|
||||
snackbar.Add(this.Message, Severity.Info, config =>
|
||||
{
|
||||
config.Icon = icon;
|
||||
config.IconSize = Size.Large;
|
||||
config.HideTransitionDuration = 600;
|
||||
config.VisibleStateDuration = 10_000;
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -73,6 +73,11 @@ public enum Event
|
||||
/// </summary>
|
||||
SHOW_SUCCESS,
|
||||
|
||||
/// <summary>
|
||||
/// Requests display of an informational notification.
|
||||
/// </summary>
|
||||
SHOW_INFO,
|
||||
|
||||
/// <summary>
|
||||
/// Carries an event received from the Tauri runtime.
|
||||
/// </summary>
|
||||
|
||||
@ -91,6 +91,8 @@ public sealed class MessageBus
|
||||
|
||||
public Task SendSuccess(DataSuccessMessage dataSuccessMessage) => this.SendMessage(null, Event.SHOW_SUCCESS, dataSuccessMessage);
|
||||
|
||||
public Task SendInfo(DataInfoMessage dataInfoMessage) => this.SendMessage(null, Event.SHOW_INFO, dataInfoMessage);
|
||||
|
||||
public void DeferMessage<T>(ComponentBase? sendingComponent, Event triggeredEvent, T? data = default)
|
||||
{
|
||||
if (this.deferredMessages.TryGetValue(triggeredEvent, out var queue))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user