Added UI support for LINUX KDE Plasma

This commit is contained in:
2023-12-27 18:03:26 +02:00
parent c8480b3c83
commit af90ae5fba
11 changed files with 259 additions and 26 deletions

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<Nullable>disable</Nullable> <Nullable>disable</Nullable>
<ApplicationIcon/> <ApplicationIcon/>
<StartupObject/> <StartupObject/>

View File

@@ -1,6 +1,10 @@
using System; using System;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using PluginManager.UX;
namespace DiscordBot; namespace DiscordBot;

View File

@@ -1,27 +1,32 @@
using System;
using PluginManager; using PluginManager;
using Spectre.Console; using Spectre.Console;
using System.Threading.Tasks;
namespace DiscordBot; namespace DiscordBot;
public static class Installer public static class Installer
{ {
public static void GenerateStartupConfig() public static async Task GenerateStartupConfig()
{ {
AnsiConsole.MarkupLine("Welcome to the [bold]SethBot[/] installer !"); string token = await PluginManager.UX.UxHandler.ShowInputBox("SethBot", "Please enter the bot token:");
AnsiConsole.MarkupLine("First, we need to configure the bot. Don't worry, it will be quick !"); string botPrefix = await PluginManager.UX.UxHandler.ShowInputBox("SethBot", "Please enter the bot prefix:");
string serverId = await PluginManager.UX.UxHandler.ShowInputBox("SethBot", "Please enter the Server ID:");
var token = AnsiConsole.Ask<string>("Please enter the bot [yellow]token[/]:");
var prefix = AnsiConsole.Ask<string>("Please enter the bot [yellow]prefix[/]:");
var serverId = AnsiConsole.Ask<string>("Please enter the [yellow]Server ID[/]:");
if (string.IsNullOrWhiteSpace(serverId)) serverId = "NULL"; if (string.IsNullOrWhiteSpace(serverId)) serverId = "NULL";
if (string.IsNullOrWhiteSpace(token) || string.IsNullOrWhiteSpace(botPrefix))
{
await PluginManager.UX.UxHandler.ShowMessageBox("SethBot", "Invalid token or prefix !", PluginManager.UX.MessageBoxType.Error);
Environment.Exit(-20);
}
Config.AppSettings.Add("token", token); Config.AppSettings.Add("token", token);
Config.AppSettings.Add("prefix", prefix); Config.AppSettings.Add("prefix", botPrefix);
Config.AppSettings.Add("ServerID", serverId); Config.AppSettings.Add("ServerID", serverId);
Config.AppSettings.SaveToFile(); await Config.AppSettings.SaveToFile();
AnsiConsole.MarkupLine("[bold]Config saved ![/]");
Config.Logger.Log("Config Saved", source: typeof(Installer)); Config.Logger.Log("Config Saved", source: typeof(Installer));
} }

View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
@@ -7,6 +8,7 @@ using DiscordBot.Utilities;
using PluginManager.Bot; using PluginManager.Bot;
using PluginManager.Others; using PluginManager.Others;
using PluginManager.Others.Actions; using PluginManager.Others.Actions;
using PluginManager.UX;
using Spectre.Console; using Spectre.Console;
using static PluginManager.Config; using static PluginManager.Config;
@@ -24,7 +26,7 @@ public class Program
PreLoadComponents(args).Wait(); PreLoadComponents(args).Wait();
if (!AppSettings.ContainsKey("ServerID") || !AppSettings.ContainsKey("token") || !AppSettings.ContainsKey("prefix")) if (!AppSettings.ContainsKey("ServerID") || !AppSettings.ContainsKey("token") || !AppSettings.ContainsKey("prefix"))
Installer.GenerateStartupConfig(); Installer.GenerateStartupConfig().Wait();
HandleInput().Wait(); HandleInput().Wait();
} }
@@ -87,7 +89,6 @@ public class Program
/// <summary> /// <summary>
/// Handle user input arguments from the startup of the application /// Handle user input arguments from the startup of the application
/// </summary> /// </summary>
/// <param name="args">The arguments</param>
private static async Task HandleInput() private static async Task HandleInput()
{ {
await StartNoGui(); await StartNoGui();
@@ -100,11 +101,9 @@ public class Program
{ {
if (ex.Message == "No process is on the other end of the pipe." || (uint)ex.HResult == 0x800700E9) if (ex.Message == "No process is on the other end of the pipe." || (uint)ex.HResult == 0x800700E9)
{ {
if (AppSettings.ContainsKey("LaunchMessage")) UxHandler.ShowMessageBox("SethBot", "An error occured while closing the bot last time. Please consider closing the bot using the &rexit&c method !\n" +
AppSettings.Add("LaunchMessage", "There is a risk of losing all data or corruption of the save file, which in some cases requires to reinstall the bot !", MessageBoxType.Error).Wait();
"An error occured while closing the bot last time. Please consider closing the bot using the &rexit&c method !\n" +
"There is a risk of losing all data or corruption of the save file, which in some cases requires to reinstall the bot !"
);
Logger.Log("An error occured while closing the bot last time. Please consider closing the bot using the &rexit&c method !\n" + Logger.Log("An error occured while closing the bot last time. Please consider closing the bot using the &rexit&c method !\n" +
"There is a risk of losing all data or corruption of the save file, which in some cases requires to reinstall the bot !", "There is a risk of losing all data or corruption of the save file, which in some cases requires to reinstall the bot !",

View File

@@ -4,6 +4,7 @@ using Discord;
using Discord.Commands; using Discord.Commands;
using Discord.WebSocket; using Discord.WebSocket;
using PluginManager.Others; using PluginManager.Others;
using PluginManager.UX;
namespace PluginManager.Bot; namespace PluginManager.Bot;
@@ -121,6 +122,7 @@ public class Boot
private Task Ready() private Task Ready()
{ {
isReady = true; isReady = true;
UxHandler.ShowNotification("SethBot", "Seth Discord Bot is now up and running !").Wait();
return Task.CompletedTask; return Task.CompletedTask;
} }

View File

@@ -1,9 +1,11 @@
using System; using System;
using System.IO; using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia.Controls.Notifications;
using PluginManager.Bot; using PluginManager.Bot;
using PluginManager.Others; using PluginManager.Others;
using PluginManager.Others.Logger; using PluginManager.Others.Logger;
using OperatingSystem = System.OperatingSystem;
namespace PluginManager; namespace PluginManager;
@@ -30,15 +32,30 @@ public class Config
AppSettings["LogFolder"] = "./Data/Logs"; AppSettings["LogFolder"] = "./Data/Logs";
if (OperatingSystem.IsLinux())
{
var windowManager = Environment.GetEnvironmentVariable("XDG_CURRENT_DESKTOP");
AppSettings["UI"] = windowManager switch
{
"KDE" => "KDE",
"GNOME" => "GNOME",
_ => "CONSOLE"
};
} else AppSettings["UI"] = "CONSOLE";
Logger = new Logger(false, true, Logger = new Logger(false, true,
AppSettings["LogFolder"] + $"/{DateTime.Today.ToShortDateString().Replace("/", "")}.log" AppSettings["LogFolder"] + $"/{DateTime.Today.ToShortDateString().Replace("/", "")}.log"
); );
ArchiveManager.Initialize(); ArchiveManager.Initialize();
UX.UxHandler.Init();
_isLoaded = true; _isLoaded = true;
Logger.Log(message: "Config initialized", source: typeof(Config)); Logger.Log(message: "Config initialized", source: typeof(Config));
} }
} }

View File

@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
@@ -12,7 +12,16 @@
<None Remove="BlankWindow1.xaml"/> <None Remove="BlankWindow1.xaml"/>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Avalonia" Version="11.0.6" />
<PackageReference Include="Discord.Net" Version="3.11.0"/> <PackageReference Include="Discord.Net" Version="3.11.0"/>
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.118"/> <PackageReference Include="System.Data.SQLite.Core" Version="1.0.118"/>
</ItemGroup> </ItemGroup>
<ItemGroup>
<UpToDateCheckInput Remove="UI\Controls\MessageBox.axaml" />
</ItemGroup>
<ItemGroup>
<Reference Include="Spectre.Console">
<HintPath>..\..\..\.nuget\packages\spectre.console\0.47.0\lib\net7.0\Spectre.Console.dll</HintPath>
</Reference>
</ItemGroup>
</Project> </Project>

View File

@@ -0,0 +1,29 @@
using System.Threading.Tasks;
namespace PluginManager.UX;
public enum MessageBoxType
{
Info,
Warning,
Error
}
public enum MessageBoxButtons
{
YesNo,
YesNoCancel,
ContinueCancel,
}
internal interface IOutputModel
{
internal Task ShowMessageBox(string title, string message, MessageBoxType type);
internal Task<string> ShowInputBox(string title, string message);
internal Task ShowMessageBox(string message);
internal Task<int> ShowMessageBox(string title, string message, MessageBoxButtons buttons, bool isWarning);
internal Task ShowNotification(string title, string message, int timeout_seconds = 5);
}

View File

@@ -0,0 +1,75 @@
using System.Diagnostics;
using System.Threading.Tasks;
namespace PluginManager.UX.Linux;
internal class KDE : IOutputModel
{
public async Task ShowMessageBox(string title, string message, MessageBoxType type)
{
var process = new Process();
process.StartInfo.FileName = "kdialog";
string typeStr = type switch
{
MessageBoxType.Info => "msgbox",
MessageBoxType.Warning => "sorry",
MessageBoxType.Error => "error",
_ => "info"
};
process.StartInfo.Arguments = $"--title \"{title}\" --{typeStr} \"{message}\"";
process.Start();
await process.WaitForExitAsync();
}
public async Task<string> ShowInputBox(string title, string message)
{
var process = new Process();
process.StartInfo.FileName = "kdialog";
process.StartInfo.Arguments = $"--title \"{title}\" --inputbox \"{message}\"";
process.StartInfo.RedirectStandardOutput = true;
process.Start();
await process.WaitForExitAsync();
return await process.StandardOutput.ReadToEndAsync();
}
public async Task ShowMessageBox(string message)
{
var process = new Process();
process.StartInfo.FileName = "kdialog";
process.StartInfo.Arguments = $"--msgbox \"{message}\"";
process.Start();
await process.WaitForExitAsync();
}
public async Task<int> ShowMessageBox(string title, string message, MessageBoxButtons buttons, bool isWarning)
{
var process = new Process();
process.StartInfo.FileName = "kdialog";
string buttonsStr = buttons switch
{
MessageBoxButtons.YesNo => "yesno",
MessageBoxButtons.YesNoCancel => "yesnocancel",
MessageBoxButtons.ContinueCancel => "continuecancel",
_ => "yesno"
};
string typeStr = isWarning ? "warning" : "";
process.StartInfo.Arguments = $"--title \"{title}\" --{typeStr}{buttonsStr} \"{message}\"";
process.Start();
await process.WaitForExitAsync();
return process.ExitCode;
}
public async Task ShowNotification(string title, string message, int timeout_seconds = 5)
{
var process = new Process();
process.StartInfo.FileName = "kdialog";
process.StartInfo.Arguments = $"--title \"{title}\" --passivepopup \"{message}\" {timeout_seconds}";
process.Start();
await process.WaitForExitAsync();
}
}

View File

@@ -0,0 +1,51 @@
using System.Threading.Tasks;
using Spectre.Console;
namespace PluginManager.UX.Other;
internal class Console : IOutputModel
{
public Task ShowMessageBox(string title, string message, MessageBoxType type)
{
AnsiConsole.Markup(title);
AnsiConsole.Markup(message);
return Task.CompletedTask;
}
public Task<string> ShowInputBox(string title, string message)
{
AnsiConsole.Markup(title);
AnsiConsole.Markup(message);
string input = AnsiConsole.Ask<string>("Please enter the value:");
return Task.FromResult(input);
}
public Task ShowMessageBox(string message)
{
AnsiConsole.Markup(message);
return Task.CompletedTask;
}
public Task<int> ShowMessageBox(string title, string message,MessageBoxButtons buttons, bool isWarning)
{
AnsiConsole.Markup(title);
AnsiConsole.Markup(message);
return Task.FromResult(0);
}
public Task ShowNotification(string title, string message, int timeout_seconds = 5)
{
AnsiConsole.Markup(title);
AnsiConsole.Markup(message);
return Task.CompletedTask;
}
}

View File

@@ -0,0 +1,42 @@
using System.Threading.Tasks;
namespace PluginManager.UX;
public static class UxHandler
{
private static IOutputModel _model;
public static void Init()
{
if (Config.AppSettings["UI"] == "KDE")
_model = new Linux.KDE();
else
_model = new Other.Console();
}
public static async Task ShowMessageBox(string title, string message, MessageBoxType type = MessageBoxType.Info)
{
await _model.ShowMessageBox(title, message, type);
}
public static async Task<string> ShowInputBox(string title, string message)
{
return await _model.ShowInputBox(title, message);
}
public static async Task ShowMessageBox(string message)
{
await _model.ShowMessageBox(message);
}
public static async Task<int> ShowMessageBox(string title, string message, MessageBoxButtons buttons, bool isWarning)
{
return await _model.ShowMessageBox(title, message, buttons, isWarning);
}
public static async Task ShowNotification(string title, string message, int timeout_seconds = 5)
{
await _model.ShowNotification(title, message, timeout_seconds);
}
}