Updated plugin version control. Added notification system to web ui

This commit is contained in:
2025-05-06 13:11:14 +03:00
parent 2bd368dcce
commit 3a7bd53cfc
14 changed files with 313 additions and 69 deletions

View File

@@ -1,5 +1,7 @@
@inherits LayoutComponentBase
@using WebUI.Components.Notification
@inherits LayoutComponentBase
<NotificationDisplay />
<div class="page">
<div class="sidebar">
<NavMenu/>

View File

@@ -0,0 +1,55 @@
@using WebUI.Models
@using WebUI.Services
@inject NotificationService NotificationService
@rendermode InteractiveServer
<link rel="stylesheet" href="Components/Notification/NotificationDisplay.css" />
<div class="notification-container" style="position: fixed; top: 20px; right: 20px; z-index: 1050; display: flex; flex-direction: column; gap: 10px;">
@foreach (var notification in _Notifications)
{
<div class="notification-box @GetCssClass(notification.Type)">
<button class="close-button" @onclick="() => DismissNotification(notification)">×</button>
<div class="notification-message">@notification.Message</div>
</div>
}
</div>
@code {
private readonly List<Notification> _Notifications = new();
protected override void OnInitialized()
{
NotificationService.OnNotify += ShowNotification;
}
private void ShowNotification(Notification notification)
{
_ = InvokeAsync(async () =>
{
_Notifications.Add(notification);
StateHasChanged();
await Task.Delay(notification.DelayMs);
_Notifications.Remove(notification);
StateHasChanged();
});
}
private string GetCssClass(NotificationType type) => type switch
{
NotificationType.Success => "alert-success",
NotificationType.Error=> "alert-danger",
NotificationType.Warning => "alert-warning",
NotificationType.Info => "alert-info",
_ => "alert-secondary"
};
private void DismissNotification(Notification notification)
{
_Notifications.Remove(notification);
}
}

View File

@@ -1,10 +1,13 @@
@page "/"
@using DiscordBotCore.Bot
@using DiscordBotCore.PluginManagement.Loading
@using WebUI.Models
@using WebUI.Services
@inject IDiscordBotApplication DiscordBotApplication
@inject IPluginLoader PluginLoader
@inject DiscordBotCore.Logging.ILogger Logger
@inject IJSRuntime JS
@inject NotificationService NotificationService
@rendermode InteractiveServer
<h3>Console Log Viewer</h3>
@@ -78,6 +81,8 @@
Logger.Log("Loading plugins", this);
await PluginLoader.LoadPlugins();
Logger.Log("Plugins loaded", this);
NotificationService.Notify("Plugins Loaded !", NotificationType.Success);
}
private string GetLogStyle(string line)

View File

@@ -81,11 +81,11 @@
Logger.Log($"Deleting plugin {pluginName}", this);
bool result = await PluginManager.UninstallPluginByName(pluginName);
var response = await PluginManager.UninstallPluginByName(pluginName);
if (!result)
if (!response.IsSuccess)
{
Logger.Log($"Failed to delete plugin {pluginName}", this, LogType.Error);
Logger.Log(response.Message, this, LogType.Error);
return;
}
@@ -100,14 +100,14 @@
private async Task PluginDetailsButtonClick(string pluginName)
{
Logger.Log($"Getting plugin details for {pluginName}", this);
var pluginDetails = await PluginManager.GetPluginDataByName(pluginName);
if (pluginDetails == null)
var response = await PluginManager.GetPluginDataByName(pluginName);
if (!response.IsSuccess)
{
Logger.Log($"Failed to get details for plugin {pluginName}", this, LogType.Error);
Logger.Log(response.Message, this, LogType.Error);
return;
}
_selectedPluginDetails = pluginDetails;
_selectedPluginDetails = response.Data;
_showPluginDetailsModal = true;
Logger.Log($"Plugin details for {pluginName} retrieved", this);

View File

@@ -4,6 +4,11 @@
@using DiscordBotCore.Logging
@using DiscordBotCore.PluginManagement
@using WebUI.Models
@using WebUI.Services
@inject NotificationService NotificationService
<h3>Available Plugins</h3>
@if (_onlinePlugins.Any())
@@ -113,10 +118,18 @@ else
private async Task InstallPlugin(int pluginId)
{
var pluginData = await PluginManager.GetPluginDataById(pluginId);
if (pluginData == null)
var response = await PluginManager.GetPluginDataById(pluginId);
if (!response.IsSuccess)
{
Logger.Log($"Plugin data not found for ID: {pluginId}", this);
Logger.Log(response.Message, this);
return;
}
var pluginData = response.Data;
if (pluginData is null)
{
Logger.Log("Plugin data is null.", this, LogType.Error);
return;
}
@@ -132,6 +145,9 @@ else
await PluginManager.InstallPlugin(pluginData, progress);
Logger.Log($"Plugin {pluginData.Name} installed successfully.", this);
NotificationService.Notify($"Plugin {pluginData.Name} installed successfully!", NotificationType.Success);
CloseInstallPercentageModal();
StateHasChanged();
}

View File

@@ -0,0 +1,9 @@
namespace WebUI.Models;
public class Notification
{
public string Message { get; set; }
public NotificationType Type { get; set; }
public DateTime Timestamp { get; set; } = DateTime.Now;
public int DelayMs { get; set; } = 5000;
}

View File

@@ -0,0 +1,9 @@
namespace WebUI.Models;
public enum NotificationType
{
Success,
Error,
Warning,
Info
}

View File

@@ -1,5 +1,6 @@
using DiscordBotCore.WebApplication;
using WebUI.Components;
using WebUI.Services;
var builder = WebApplication.CreateBuilder(args);
@@ -7,6 +8,8 @@ var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
builder.AddDiscordBotComponents();
builder.Services.AddSingleton<NotificationService>();
var app = builder.Build();

View File

@@ -0,0 +1,12 @@
using WebUI.Models;
namespace WebUI.Services;
public class NotificationService
{
public event Action<Notification> OnNotify;
public void Notify(string message, NotificationType type = NotificationType.Info)
{
OnNotify?.Invoke(new Notification { Message = message, Type = type });
}
}

View File

@@ -0,0 +1,45 @@
.notification-box {
position: relative;
padding: 1rem 1.5rem;
border-radius: 10px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
min-width: 250px;
max-width: 400px;
color: #fff;
font-family: sans-serif;
font-size: 0.95rem;
display: flex;
flex-direction: column;
}
.notification-message {
padding-right: 1.5rem;
}
.close-button {
position: absolute;
top: 0.5rem;
right: 0.8rem;
background: none;
border: none;
color: #fff;
font-size: 1.2rem;
cursor: pointer;
}
.alert-success {
background-color: #28a745;
}
.alert-danger {
background-color: #dc3545;
}
.alert-warning {
background-color: #ffc107;
color: #212529;
}
.alert-info {
background-color: #17a2b8;
}