diff --git a/DiscordBotCore/API/Endpoints/PluginManagement/PluginInstallEndpoint.cs b/DiscordBotCore/API/Endpoints/PluginManagement/PluginInstallEndpoint.cs index 7a47d07..5ea1ac9 100644 --- a/DiscordBotCore/API/Endpoints/PluginManagement/PluginInstallEndpoint.cs +++ b/DiscordBotCore/API/Endpoints/PluginManagement/PluginInstallEndpoint.cs @@ -10,7 +10,7 @@ namespace DiscordBotCore.API.Endpoints.PluginManagement; public class PluginInstallEndpoint : IEndpoint { public string Path => "/api/plugin/install"; - public EndpointType HttpMethod => EndpointType.Put; + public EndpointType HttpMethod => EndpointType.Post; public async Task HandleRequest(string? jsonRequest) { Dictionary jsonDict = await JsonManager.ConvertFromJson>(jsonRequest); diff --git a/DiscordBotCore/API/Endpoints/PluginManagement/PluginListEndpoint.cs b/DiscordBotCore/API/Endpoints/PluginManagement/PluginListEndpoint.cs index 7258b42..1dc49a3 100644 --- a/DiscordBotCore/API/Endpoints/PluginManagement/PluginListEndpoint.cs +++ b/DiscordBotCore/API/Endpoints/PluginManagement/PluginListEndpoint.cs @@ -13,7 +13,11 @@ public class PluginListEndpoint : IEndpoint { var onlineInfos = await Application.CurrentApplication.PluginManager.GetPluginsList(); - var response = await JsonManager.ConvertToJson(onlineInfos, [nameof(PluginOnlineInfo.Name), nameof(PluginOnlineInfo.Author), nameof(PluginOnlineInfo.Version)]); + var response = await JsonManager.ConvertToJson(onlineInfos, [ + nameof(PluginOnlineInfo.Name), + nameof(PluginOnlineInfo.Author), + nameof(PluginOnlineInfo.Description) + ]); return ApiResponse.From(response, true); } diff --git a/DiscordBotCore/Online/PluginManager.cs b/DiscordBotCore/Online/PluginManager.cs index 1714835..cefdbd0 100644 --- a/DiscordBotCore/Online/PluginManager.cs +++ b/DiscordBotCore/Online/PluginManager.cs @@ -21,7 +21,7 @@ public sealed class PluginManager _PluginRepository = pluginRepository; } - public async Task?> GetPluginsList() + public async Task> GetPluginsList() { var jsonText = await _PluginRepository.JsonGetAllPlugins(); List result = await JsonManager.ConvertFromJson>(jsonText); diff --git a/DiscordBotWebUI/Components/CustomTags/Marketplace.razor b/DiscordBotWebUI/Components/CustomTags/Marketplace.razor index 2d3b798..d1f9c0c 100644 --- a/DiscordBotWebUI/Components/CustomTags/Marketplace.razor +++ b/DiscordBotWebUI/Components/CustomTags/Marketplace.razor @@ -2,12 +2,12 @@ - - - + + + diff --git a/DiscordBotWebUI/Components/Pages/SidebarPages/PluginMarket.razor b/DiscordBotWebUI/Components/Pages/SidebarPages/PluginMarket.razor index 7a1b2d4..439cdeb 100644 --- a/DiscordBotWebUI/Components/Pages/SidebarPages/PluginMarket.razor +++ b/DiscordBotWebUI/Components/Pages/SidebarPages/PluginMarket.razor @@ -1,24 +1,48 @@ @page "/plugins" @using DiscordBotWebUI.Components.CustomTags @using DiscordBotWebUI.Models +@using DiscordBotWebUI.ServerCommunication @code { private List _PluginModels; + + [Inject] + public ApiHandler ApiHandler { get; set; } + private async void OnModelSelected(string itemName) { - Console.WriteLine(itemName); - } + ApiResponse response = await ApiHandler.PostAsync("/api/plugin/install", new Dictionary() + { + {"pluginName", itemName} + }); + if(!response.Success) + { + Console.WriteLine(response.Message); + return; + } + Console.WriteLine("Plugin installed"); + } protected override async Task OnInitializedAsync() { - _PluginModels = new List() + ApiResponse response = await ApiHandler.GetAsync("/api/plugin/list/online"); + + if (!response.Success) { - new PluginModel() {PluginName = "Test", PluginAuthor = "Andrei", PluginDescription = "Interesting plugin"} - }; + return; + } + + string jsonStr = response.Message; + var result = await JsonManager.ConvertFromJson>(jsonStr); + + if (result != null) + { + _PluginModels = result; + } } } \ No newline at end of file diff --git a/DiscordBotWebUI/DiscordBotWebUI.csproj b/DiscordBotWebUI/DiscordBotWebUI.csproj index a7ce3da..af46a9e 100644 --- a/DiscordBotWebUI/DiscordBotWebUI.csproj +++ b/DiscordBotWebUI/DiscordBotWebUI.csproj @@ -38,8 +38,4 @@ <_ContentIncludedByDefault Remove="Components\Pages\Setup\SetupWizard.razor" /> - - - - diff --git a/DiscordBotWebUI/Models/PluginModel.cs b/DiscordBotWebUI/Models/PluginModel.cs index 6b79daa..3816c2b 100644 --- a/DiscordBotWebUI/Models/PluginModel.cs +++ b/DiscordBotWebUI/Models/PluginModel.cs @@ -1,8 +1,18 @@ +using System.Text.Json.Serialization; + namespace DiscordBotWebUI.Models; public class PluginModel { - public string PluginName { get; set; } - public string PluginAuthor { get; set; } - public string PluginDescription { get; set; } + public string Name { get; set; } + public string Author { get; set; } + public string Description { get; set; } + + [JsonConstructor] + public PluginModel(string name, string author, string description) + { + Name = name; + Author = author; + Description = description; + } } diff --git a/DiscordBotWebUI/Program.cs b/DiscordBotWebUI/Program.cs index 9c65a86..5d7c2ea 100644 --- a/DiscordBotWebUI/Program.cs +++ b/DiscordBotWebUI/Program.cs @@ -1,4 +1,6 @@ using DiscordBotWebUI.Components; +using DiscordBotWebUI.ServerCommunication; +using DiscordBotWebUI.ServerCommunication.ApiSettings; using Radzen; @@ -33,6 +35,9 @@ builder.Services.AddRadzenCookieThemeService(options => options.Duration = TimeSpan.FromDays(365); // The duration of the cookie }); +builder.Services.AddSingleton(new ApiSettings("http://localhost", "5000")); +builder.Services.AddSingleton(); + builder.Services.AddRadzenComponents(); var app = builder.Build(); diff --git a/DiscordBotWebUI/ServerCommunication/ApiHandler.cs b/DiscordBotWebUI/ServerCommunication/ApiHandler.cs new file mode 100644 index 0000000..99051d7 --- /dev/null +++ b/DiscordBotWebUI/ServerCommunication/ApiHandler.cs @@ -0,0 +1,55 @@ +using System.Net.Http.Headers; +using System.Text; +using DiscordBotWebUI.ServerCommunication.ApiSettings; + +namespace DiscordBotWebUI.ServerCommunication; + +public class ApiHandler +{ + private IApiSettings ApiSettings { get; } + public ApiHandler(IApiSettings apiSettings) + { + ApiSettings = apiSettings; + } + + public async Task GetAsync(string endpoint) + { + using HttpClient client = new HttpClient(); + client.BaseAddress = new Uri($"{ApiSettings.BaseUrl}:{ApiSettings.BasePort}"); + client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + HttpResponseMessage response = await client.GetAsync(endpoint); + if (response.IsSuccessStatusCode) + { + string content = await response.Content.ReadAsStringAsync(); + return await JsonManager.ConvertFromJson(content); + } + return new ApiResponse("Failed to get response", false); + } + + public async Task PostAsync(string endpoint, Dictionary jsonValues) + { + if (jsonValues.Count <= 0) + { + return new ApiResponse("No values to post", false); + } + + string jsonString = await JsonManager.ConvertToJsonString(jsonValues); + return await PostAsync(endpoint, jsonString); + } + + public async Task PostAsync(string endpoint, string json) + { + using HttpClient client = new HttpClient(); + client.BaseAddress = new Uri($"{ApiSettings.BaseUrl}:{ApiSettings.BasePort}"); + client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); + StringContent content = new StringContent(json, Encoding.UTF8, "application/json"); + HttpResponseMessage response = await client.PostAsync(endpoint, content); + if (response.IsSuccessStatusCode) + { + string responseContent = await response.Content.ReadAsStringAsync(); + return await JsonManager.ConvertFromJson(responseContent); + } + return new ApiResponse("Failed to get response", false); + } + +} diff --git a/DiscordBotWebUI/ServerCommunication/ApiResponse.cs b/DiscordBotWebUI/ServerCommunication/ApiResponse.cs new file mode 100644 index 0000000..b0fc681 --- /dev/null +++ b/DiscordBotWebUI/ServerCommunication/ApiResponse.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace DiscordBotWebUI.ServerCommunication; + +public class ApiResponse +{ + public bool Success { get; } + public string Message { get; } + + [JsonConstructor] + public ApiResponse(string message, bool success) + { + Message = message; + Success = success; + } +} diff --git a/DiscordBotWebUI/ServerCommunication/ApiSettings/ApiSettings.cs b/DiscordBotWebUI/ServerCommunication/ApiSettings/ApiSettings.cs new file mode 100644 index 0000000..f0cd858 --- /dev/null +++ b/DiscordBotWebUI/ServerCommunication/ApiSettings/ApiSettings.cs @@ -0,0 +1,13 @@ +namespace DiscordBotWebUI.ServerCommunication.ApiSettings; + +public class ApiSettings : IApiSettings +{ + public string BaseUrl { get; } + public string BasePort { get; } + + public ApiSettings(string baseUrl, string basePort) + { + BaseUrl = baseUrl; + BasePort = basePort; + } +} diff --git a/DiscordBotWebUI/ServerCommunication/ApiSettings/IApiSettings.cs b/DiscordBotWebUI/ServerCommunication/ApiSettings/IApiSettings.cs new file mode 100644 index 0000000..5fea3af --- /dev/null +++ b/DiscordBotWebUI/ServerCommunication/ApiSettings/IApiSettings.cs @@ -0,0 +1,7 @@ +namespace DiscordBotWebUI.ServerCommunication.ApiSettings; + +public interface IApiSettings +{ + public string BaseUrl { get; } + public string BasePort { get; } +} diff --git a/DiscordBotWebUI/ServerCommunication/JsonManager.cs b/DiscordBotWebUI/ServerCommunication/JsonManager.cs new file mode 100644 index 0000000..e282934 --- /dev/null +++ b/DiscordBotWebUI/ServerCommunication/JsonManager.cs @@ -0,0 +1,31 @@ +using System.Text; +using System.Text.Json; + +namespace DiscordBotWebUI.ServerCommunication; + +public class JsonManager +{ + public static async Task ConvertFromJson(string jsonString) + { + if (string.IsNullOrWhiteSpace(jsonString)) + throw new ArgumentException("JSON string cannot be null or empty.", nameof(jsonString)); + + using MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)); + try + { + return await JsonSerializer.DeserializeAsync(stream); + } + catch (JsonException ex) + { + throw new InvalidOperationException("Failed to deserialize JSON.", ex); + } + } + + public static async Task ConvertToJsonString(T data) + { + using MemoryStream stream = new MemoryStream(); + await JsonSerializer.SerializeAsync(stream, data); + return Encoding.UTF8.GetString(stream.ToArray()); + } + +}