diff --git a/Iceshrimp.Backend/Controllers/AdminController.cs b/Iceshrimp.Backend/Controllers/AdminController.cs index af2f217..ef82b6c 100644 --- a/Iceshrimp.Backend/Controllers/AdminController.cs +++ b/Iceshrimp.Backend/Controllers/AdminController.cs @@ -2,7 +2,7 @@ using System.Diagnostics.CodeAnalysis; using System.Net.Mime; using Iceshrimp.Backend.Controllers.Attributes; using Iceshrimp.Backend.Controllers.Federation; -using Iceshrimp.Backend.Controllers.Schemas; +using Iceshrimp.Shared.Schemas; using Iceshrimp.Backend.Core.Database; using Iceshrimp.Backend.Core.Database.Tables; using Iceshrimp.Backend.Core.Extensions; diff --git a/Iceshrimp.Backend/Controllers/AuthController.cs b/Iceshrimp.Backend/Controllers/AuthController.cs index f19acdc..11edec7 100644 --- a/Iceshrimp.Backend/Controllers/AuthController.cs +++ b/Iceshrimp.Backend/Controllers/AuthController.cs @@ -1,7 +1,7 @@ using System.Diagnostics.CodeAnalysis; using System.Net.Mime; using Iceshrimp.Backend.Controllers.Renderers; -using Iceshrimp.Backend.Controllers.Schemas; +using Iceshrimp.Shared.Schemas; using Iceshrimp.Backend.Core.Database; using Iceshrimp.Backend.Core.Database.Tables; using Iceshrimp.Backend.Core.Helpers; diff --git a/Iceshrimp.Backend/Controllers/FallbackController.cs b/Iceshrimp.Backend/Controllers/FallbackController.cs index ec3d114..84d90e6 100644 --- a/Iceshrimp.Backend/Controllers/FallbackController.cs +++ b/Iceshrimp.Backend/Controllers/FallbackController.cs @@ -1,6 +1,6 @@ using System.Net; using System.Net.Mime; -using Iceshrimp.Backend.Controllers.Schemas; +using Iceshrimp.Shared.Schemas; using Iceshrimp.Backend.Core.Middleware; using Microsoft.AspNetCore.Mvc; diff --git a/Iceshrimp.Backend/Controllers/Federation/ActivityPubController.cs b/Iceshrimp.Backend/Controllers/Federation/ActivityPubController.cs index 6896092..9d2d92b 100644 --- a/Iceshrimp.Backend/Controllers/Federation/ActivityPubController.cs +++ b/Iceshrimp.Backend/Controllers/Federation/ActivityPubController.cs @@ -1,7 +1,7 @@ using System.Text; using Iceshrimp.Backend.Controllers.Attributes; using Iceshrimp.Backend.Controllers.Federation.Attributes; -using Iceshrimp.Backend.Controllers.Schemas; +using Iceshrimp.Shared.Schemas; using Iceshrimp.Backend.Core.Configuration; using Iceshrimp.Backend.Core.Database; using Iceshrimp.Backend.Core.Extensions; diff --git a/Iceshrimp.Backend/Controllers/Federation/WellKnownController.cs b/Iceshrimp.Backend/Controllers/Federation/WellKnownController.cs index a89317f..c0525b4 100644 --- a/Iceshrimp.Backend/Controllers/Federation/WellKnownController.cs +++ b/Iceshrimp.Backend/Controllers/Federation/WellKnownController.cs @@ -4,7 +4,7 @@ using System.Text; using System.Xml.Serialization; using Iceshrimp.Backend.Controllers.Federation.Attributes; using Iceshrimp.Backend.Controllers.Federation.Schemas; -using Iceshrimp.Backend.Controllers.Schemas; +using Iceshrimp.Shared.Schemas; using Iceshrimp.Backend.Core.Configuration; using Iceshrimp.Backend.Core.Database; using Iceshrimp.Backend.Core.Database.Tables; diff --git a/Iceshrimp.Backend/Controllers/NoteController.cs b/Iceshrimp.Backend/Controllers/NoteController.cs index 23cfdbd..04ce53f 100644 --- a/Iceshrimp.Backend/Controllers/NoteController.cs +++ b/Iceshrimp.Backend/Controllers/NoteController.cs @@ -3,7 +3,7 @@ using System.ComponentModel.DataAnnotations; using System.Net.Mime; using Iceshrimp.Backend.Controllers.Attributes; using Iceshrimp.Backend.Controllers.Renderers; -using Iceshrimp.Backend.Controllers.Schemas; +using Iceshrimp.Shared.Schemas; using Iceshrimp.Backend.Core.Database; using Iceshrimp.Backend.Core.Database.Tables; using Iceshrimp.Backend.Core.Extensions; @@ -74,7 +74,7 @@ public class NoteController( [HttpGet("{id}/descendants")] [Authenticate] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(NoteResponse))] + [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable))] [ProducesResponseType(StatusCodes.Status404NotFound, Type = typeof(ErrorResponse))] public async Task GetNoteDescendants( string id, [FromQuery] [DefaultValue(20)] [Range(1, 100)] int? depth diff --git a/Iceshrimp.Backend/Controllers/NotificationController.cs b/Iceshrimp.Backend/Controllers/NotificationController.cs index 3711119..8c642a4 100644 --- a/Iceshrimp.Backend/Controllers/NotificationController.cs +++ b/Iceshrimp.Backend/Controllers/NotificationController.cs @@ -2,6 +2,7 @@ using System.Net.Mime; using Iceshrimp.Backend.Controllers.Attributes; using Iceshrimp.Backend.Controllers.Renderers; using Iceshrimp.Backend.Controllers.Schemas; +using Iceshrimp.Shared.Schemas; using Iceshrimp.Backend.Core.Database; using Iceshrimp.Backend.Core.Extensions; using Iceshrimp.Backend.Core.Middleware; diff --git a/Iceshrimp.Backend/Controllers/Renderers/NoteRenderer.cs b/Iceshrimp.Backend/Controllers/Renderers/NoteRenderer.cs index 5f4c9fc..9688eac 100644 --- a/Iceshrimp.Backend/Controllers/Renderers/NoteRenderer.cs +++ b/Iceshrimp.Backend/Controllers/Renderers/NoteRenderer.cs @@ -1,4 +1,4 @@ - using Iceshrimp.Backend.Controllers.Schemas; + using Iceshrimp.Shared.Schemas; using Iceshrimp.Backend.Core.Database; using Iceshrimp.Backend.Core.Database.Tables; using Iceshrimp.Backend.Core.Extensions; diff --git a/Iceshrimp.Backend/Controllers/Renderers/NotificationRenderer.cs b/Iceshrimp.Backend/Controllers/Renderers/NotificationRenderer.cs index 3a0d798..7ef8b82 100644 --- a/Iceshrimp.Backend/Controllers/Renderers/NotificationRenderer.cs +++ b/Iceshrimp.Backend/Controllers/Renderers/NotificationRenderer.cs @@ -1,4 +1,4 @@ -using Iceshrimp.Backend.Controllers.Schemas; +using Iceshrimp.Shared.Schemas; using Iceshrimp.Backend.Core.Database.Tables; using Iceshrimp.Backend.Core.Extensions; diff --git a/Iceshrimp.Backend/Controllers/Renderers/UserProfileRenderer.cs b/Iceshrimp.Backend/Controllers/Renderers/UserProfileRenderer.cs index 7d0d8e5..9b75c85 100644 --- a/Iceshrimp.Backend/Controllers/Renderers/UserProfileRenderer.cs +++ b/Iceshrimp.Backend/Controllers/Renderers/UserProfileRenderer.cs @@ -1,4 +1,4 @@ -using Iceshrimp.Backend.Controllers.Schemas; +using Iceshrimp.Shared.Schemas; using Iceshrimp.Backend.Core.Database; using Iceshrimp.Backend.Core.Database.Tables; using Iceshrimp.Backend.Core.Extensions; @@ -28,12 +28,19 @@ public class UserProfileRenderer(DatabaseContext db) _ => throw new ArgumentOutOfRangeException() }; + var fields = user.UserProfile?.Fields.Select(p => new UserProfileField + { + Name = p.Name, + Value = p.Value, + IsVerified = p.IsVerified + }); + return new UserProfileResponse { Id = user.Id, Bio = user.UserProfile?.Description, Birthday = user.UserProfile?.Birthday, - Fields = user.UserProfile?.Fields, + Fields = fields?.ToList(), Location = user.UserProfile?.Location, Followers = followers, Following = following diff --git a/Iceshrimp.Backend/Controllers/Renderers/UserRenderer.cs b/Iceshrimp.Backend/Controllers/Renderers/UserRenderer.cs index e9c5a8b..f7fbc26 100644 --- a/Iceshrimp.Backend/Controllers/Renderers/UserRenderer.cs +++ b/Iceshrimp.Backend/Controllers/Renderers/UserRenderer.cs @@ -1,4 +1,4 @@ -using Iceshrimp.Backend.Controllers.Schemas; +using Iceshrimp.Shared.Schemas; using Iceshrimp.Backend.Core.Configuration; using Iceshrimp.Backend.Core.Database; using Iceshrimp.Backend.Core.Database.Tables; diff --git a/Iceshrimp.Backend/Controllers/Schemas/UserProfileResponse.cs b/Iceshrimp.Backend/Controllers/Schemas/UserProfileResponse.cs deleted file mode 100644 index 8d3a6e7..0000000 --- a/Iceshrimp.Backend/Controllers/Schemas/UserProfileResponse.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Iceshrimp.Backend.Core.Database.Tables; -using J = System.Text.Json.Serialization.JsonPropertyNameAttribute; - -namespace Iceshrimp.Backend.Controllers.Schemas; - -public class UserProfileResponse -{ - [J("id")] public required string Id { get; set; } - [J("birthday")] public required string? Birthday { get; set; } - [J("location")] public required string? Location { get; set; } - [J("fields")] public required UserProfile.Field[]? Fields { get; set; } - [J("bio")] public required string? Bio { get; set; } - [J("followers")] public required int? Followers { get; set; } - [J("following")] public required int? Following { get; set; } -} \ No newline at end of file diff --git a/Iceshrimp.Backend/Controllers/TimelineController.cs b/Iceshrimp.Backend/Controllers/TimelineController.cs index 3f8df48..dd2ddba 100644 --- a/Iceshrimp.Backend/Controllers/TimelineController.cs +++ b/Iceshrimp.Backend/Controllers/TimelineController.cs @@ -2,6 +2,7 @@ using System.Net.Mime; using Iceshrimp.Backend.Controllers.Attributes; using Iceshrimp.Backend.Controllers.Renderers; using Iceshrimp.Backend.Controllers.Schemas; +using Iceshrimp.Shared.Schemas; using Iceshrimp.Backend.Core.Database; using Iceshrimp.Backend.Core.Extensions; using Iceshrimp.Backend.Core.Middleware; diff --git a/Iceshrimp.Backend/Controllers/UserController.cs b/Iceshrimp.Backend/Controllers/UserController.cs index fdf1bda..2b1cd2e 100644 --- a/Iceshrimp.Backend/Controllers/UserController.cs +++ b/Iceshrimp.Backend/Controllers/UserController.cs @@ -2,6 +2,7 @@ using System.Net.Mime; using Iceshrimp.Backend.Controllers.Attributes; using Iceshrimp.Backend.Controllers.Renderers; using Iceshrimp.Backend.Controllers.Schemas; +using Iceshrimp.Shared.Schemas; using Iceshrimp.Backend.Core.Database; using Iceshrimp.Backend.Core.Extensions; using Iceshrimp.Backend.Core.Middleware; diff --git a/Iceshrimp.Backend/Core/Database/Tables/UserProfile.cs b/Iceshrimp.Backend/Core/Database/Tables/UserProfile.cs index 88ff3ee..8a21971 100644 --- a/Iceshrimp.Backend/Core/Database/Tables/UserProfile.cs +++ b/Iceshrimp.Backend/Core/Database/Tables/UserProfile.cs @@ -180,8 +180,8 @@ public class UserProfile public class Field { - [J("name")] public required string Name { get; set; } - [J("value")] public required string Value { get; set; } - [J("verified")] public bool? IsVerified { get; set; } + public required string Name { get; set; } + public required string Value { get; set; } + public bool? IsVerified { get; set; } } } \ No newline at end of file diff --git a/Iceshrimp.Backend/Core/Extensions/QueryableExtensions.cs b/Iceshrimp.Backend/Core/Extensions/QueryableExtensions.cs index 444def9..92e6cd9 100644 --- a/Iceshrimp.Backend/Core/Extensions/QueryableExtensions.cs +++ b/Iceshrimp.Backend/Core/Extensions/QueryableExtensions.cs @@ -5,6 +5,7 @@ using Iceshrimp.Backend.Controllers.Mastodon.Renderers; using Iceshrimp.Backend.Controllers.Mastodon.Schemas; using Iceshrimp.Backend.Controllers.Mastodon.Schemas.Entities; using Iceshrimp.Backend.Controllers.Schemas; +using Iceshrimp.Shared.Schemas; using Iceshrimp.Backend.Core.Database; using Iceshrimp.Backend.Core.Database.Tables; using Iceshrimp.Backend.Core.Middleware; diff --git a/Iceshrimp.Backend/Core/Extensions/ServiceExtensions.cs b/Iceshrimp.Backend/Core/Extensions/ServiceExtensions.cs index 49b8d2f..2bf5da4 100644 --- a/Iceshrimp.Backend/Core/Extensions/ServiceExtensions.cs +++ b/Iceshrimp.Backend/Core/Extensions/ServiceExtensions.cs @@ -2,7 +2,7 @@ using System.Threading.RateLimiting; using Iceshrimp.Backend.Controllers.Federation; using Iceshrimp.Backend.Controllers.Mastodon.Renderers; using Iceshrimp.Backend.Controllers.Renderers; -using Iceshrimp.Backend.Controllers.Schemas; +using Iceshrimp.Shared.Schemas; using Iceshrimp.Backend.Core.Configuration; using Iceshrimp.Backend.Core.Database; using Iceshrimp.Backend.Core.Federation.WebFinger; diff --git a/Iceshrimp.Backend/Core/Middleware/ErrorHandlerMiddleware.cs b/Iceshrimp.Backend/Core/Middleware/ErrorHandlerMiddleware.cs index d30c92a..94413e5 100644 --- a/Iceshrimp.Backend/Core/Middleware/ErrorHandlerMiddleware.cs +++ b/Iceshrimp.Backend/Core/Middleware/ErrorHandlerMiddleware.cs @@ -2,7 +2,7 @@ using System.Diagnostics.CodeAnalysis; using System.Net; using Iceshrimp.Backend.Controllers.Mastodon.Attributes; using Iceshrimp.Backend.Controllers.Mastodon.Schemas; -using Iceshrimp.Backend.Controllers.Schemas; +using Iceshrimp.Shared.Schemas; using Iceshrimp.Backend.Core.Configuration; using Microsoft.Extensions.Options; diff --git a/Iceshrimp.Backend/Hubs/ExampleHub.cs b/Iceshrimp.Backend/Hubs/ExampleHub.cs new file mode 100644 index 0000000..2fc057b --- /dev/null +++ b/Iceshrimp.Backend/Hubs/ExampleHub.cs @@ -0,0 +1,10 @@ +using Microsoft.AspNetCore.SignalR; +namespace Iceshrimp.Backend.Hubs; + +public class ExampleHub : Hub +{ + public async Task SendMessage(string user, string message) + { + await Clients.All.SendAsync("ReceiveMessage", user, message); + } +} \ No newline at end of file diff --git a/Iceshrimp.Backend/Iceshrimp.Backend.csproj b/Iceshrimp.Backend/Iceshrimp.Backend.csproj index 7a4a179..02fc847 100644 --- a/Iceshrimp.Backend/Iceshrimp.Backend.csproj +++ b/Iceshrimp.Backend/Iceshrimp.Backend.csproj @@ -33,6 +33,7 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -59,6 +60,7 @@ + diff --git a/Iceshrimp.Backend/Startup.cs b/Iceshrimp.Backend/Startup.cs index 41fc623..a51d728 100644 --- a/Iceshrimp.Backend/Startup.cs +++ b/Iceshrimp.Backend/Startup.cs @@ -1,4 +1,5 @@ using Iceshrimp.Backend.Core.Extensions; +using Iceshrimp.Backend.Hubs; var builder = WebApplication.CreateBuilder(args); @@ -16,6 +17,8 @@ builder.Services.AddLogging(logging => logging.AddCustomConsoleFormatter()); builder.Services.AddDatabaseContext(builder.Configuration); builder.Services.AddSlidingWindowRateLimiter(); builder.Services.AddCorsPolicies(); +builder.Services.AddSignalR().AddMessagePackProtocol(); +builder.Services.AddResponseCompression(); if (builder.Environment.IsDevelopment()) builder.Services.AddRazorPages().AddRazorRuntimeCompilation(); @@ -31,6 +34,9 @@ var app = builder.Build(); var config = await app.Initialize(args); // This determines the order of middleware execution in the request pipeline +if (!app.Environment.IsDevelopment()) + app.UseResponseCompression(); + app.UseRouting(); app.UseSwaggerWithOptions(); app.UseBlazorFrameworkFiles(); @@ -43,6 +49,7 @@ app.UseCustomMiddleware(); app.MapControllers(); app.MapFallbackToController("/api/{**slug}", "FallbackAction", "Fallback"); +app.MapHub("/hubs/example"); app.MapRazorPages(); app.MapFallbackToPage("/Shared/FrontendSPA"); diff --git a/Iceshrimp.Frontend/Core/ControllerModels/NoteControllerModel.cs b/Iceshrimp.Frontend/Core/ControllerModels/NoteControllerModel.cs new file mode 100644 index 0000000..573af15 --- /dev/null +++ b/Iceshrimp.Frontend/Core/ControllerModels/NoteControllerModel.cs @@ -0,0 +1,26 @@ +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using Iceshrimp.Frontend.Core.Extensions; +using Iceshrimp.Shared.Schemas; +using Microsoft.AspNetCore.Http; + +namespace Iceshrimp.Frontend.Core.ControllerModels; + +internal class NoteControllerModel(HttpClient api) +{ + public Task GetNote(string id) => api.CallNullable(HttpMethod.Get, $"/note/{id}"); + + public Task GetNoteAscendants(string id, [DefaultValue(20)] [Range(1, 100)] int? limit) + { + var query = new QueryString(); + if (limit.HasValue) query.Add("limit", limit.ToString()); + return api.CallNullable(HttpMethod.Get, $"/note/{id}/ascendants", query); + } + + public Task GetNoteDescendants(string id, [DefaultValue(20)] [Range(1, 100)] int? depth) + { + var query = new QueryString(); + if (depth.HasValue) query.Add("depth", depth.ToString()); + return api.CallNullable(HttpMethod.Get, $"/note/{id}/descendants", query); + } +} \ No newline at end of file diff --git a/Iceshrimp.Frontend/Core/Extensions/HttpClientExtensions.cs b/Iceshrimp.Frontend/Core/Extensions/HttpClientExtensions.cs new file mode 100644 index 0000000..85160e9 --- /dev/null +++ b/Iceshrimp.Frontend/Core/Extensions/HttpClientExtensions.cs @@ -0,0 +1,59 @@ +using System.Net.Http.Json; +using System.Net.Mime; +using System.Text; +using Iceshrimp.Frontend.Core.Miscellaneous; +using Iceshrimp.Shared.Schemas; +using Microsoft.AspNetCore.Http; + +namespace Iceshrimp.Frontend.Core.Extensions; + +internal static class HttpClientExtensions +{ + public static async Task Call( + this HttpClient client, HttpMethod method, string path, QueryString? query = null, string? body = null + ) where T : class + { + var res = await CallInternal(client, method, path, query, body); + if (res.result != null) + return res.result; + throw new ApiException(res.error ?? throw new Exception("Deserialized API error was null")); + } + + public static async Task CallNullable( + this HttpClient client, HttpMethod method, string path, QueryString? query = null, string? body = null + ) where T : class + { + var res = await CallInternal(client, method, path, query, body); + if (res.result != null) + return res.result; + + var err = res.error ?? throw new Exception("Deserialized API error was null"); + if (err.StatusCode == 404) + return null; + + throw new ApiException(err); + } + + private static async Task<(T? result, ErrorResponse? error)> CallInternal( + this HttpClient client, HttpMethod method, string path, QueryString? query = null, string? body = null + ) where T : class + { + var request = new HttpRequestMessage(method, "/api/iceshrimp/" + path.TrimStart('/') + query); + request.Headers.Accept.ParseAdd(MediaTypeNames.Application.Json); + if (body != null) request.Content = new StringContent(body, Encoding.UTF8, MediaTypeNames.Application.Json); + + var res = await client.SendAsync(request); + if (res.IsSuccessStatusCode) + { + var deserialized = await res.Content.ReadFromJsonAsync(); + if (deserialized == null) + throw new Exception("Deserialized API response was null"); + return (deserialized, null); + } + + var error = await res.Content.ReadFromJsonAsync(); + if (error == null) + throw new Exception("Deserialized API error was null"); + return (null, error); + } +} \ No newline at end of file diff --git a/Iceshrimp.Frontend/Core/Extensions/HttpResponseMessageExtensions.cs b/Iceshrimp.Frontend/Core/Extensions/HttpResponseMessageExtensions.cs new file mode 100644 index 0000000..fa1a3ac --- /dev/null +++ b/Iceshrimp.Frontend/Core/Extensions/HttpResponseMessageExtensions.cs @@ -0,0 +1,6 @@ +namespace Iceshrimp.Frontend.Core.Extensions; + +public class HttpResponseMessageExtensions +{ + +} \ No newline at end of file diff --git a/Iceshrimp.Frontend/Core/Miscellaneous/ApiException.cs b/Iceshrimp.Frontend/Core/Miscellaneous/ApiException.cs new file mode 100644 index 0000000..125a804 --- /dev/null +++ b/Iceshrimp.Frontend/Core/Miscellaneous/ApiException.cs @@ -0,0 +1,8 @@ +using Iceshrimp.Shared.Schemas; + +namespace Iceshrimp.Frontend.Core.Miscellaneous; + +internal class ApiException(ErrorResponse error) : Exception +{ + public ErrorResponse Response => error; +} \ No newline at end of file diff --git a/Iceshrimp.Frontend/Core/Services/ApiService.cs b/Iceshrimp.Frontend/Core/Services/ApiService.cs new file mode 100644 index 0000000..e8ef81d --- /dev/null +++ b/Iceshrimp.Frontend/Core/Services/ApiService.cs @@ -0,0 +1,8 @@ +using Iceshrimp.Frontend.Core.ControllerModels; + +namespace Iceshrimp.Frontend.Core.Services; + +internal class ApiService(HttpClient client) +{ + internal NoteControllerModel Notes = new(client); +} \ No newline at end of file diff --git a/Iceshrimp.Frontend/Iceshrimp.Frontend.csproj b/Iceshrimp.Frontend/Iceshrimp.Frontend.csproj index c9ab3cf..6d4a5a9 100644 --- a/Iceshrimp.Frontend/Iceshrimp.Frontend.csproj +++ b/Iceshrimp.Frontend/Iceshrimp.Frontend.csproj @@ -5,6 +5,7 @@ enable enable true + true @@ -13,6 +14,9 @@ + + + @@ -24,4 +28,9 @@ <_ContentIncludedByDefault Remove="wwwroot\assets\transparent.png" /> + + + + + diff --git a/Iceshrimp.Frontend/Pages/Counter.razor b/Iceshrimp.Frontend/Pages/Counter.razor index d66f697..70d4668 100644 --- a/Iceshrimp.Frontend/Pages/Counter.razor +++ b/Iceshrimp.Frontend/Pages/Counter.razor @@ -4,7 +4,7 @@

Counter

-

Current count: @_currentCount

+

Current count (edited): @_currentCount

diff --git a/Iceshrimp.Frontend/Pages/Hub.razor b/Iceshrimp.Frontend/Pages/Hub.razor new file mode 100644 index 0000000..0bb6dd8 --- /dev/null +++ b/Iceshrimp.Frontend/Pages/Hub.razor @@ -0,0 +1,72 @@ +@page "/hub" +@using Microsoft.AspNetCore.SignalR.Client +@inject NavigationManager Navigation +@implements IAsyncDisposable + +Home + +
+ +
+
+ +
+ + +
+ +
    + @foreach (var message in messages) + { +
  • @message
  • + } +
+ +@code { + private HubConnection? hubConnection; + private List messages = []; + private string? userInput; + private string? messageInput; + + protected override async Task OnInitializedAsync() + { + hubConnection = new HubConnectionBuilder() + .WithUrl(Navigation.ToAbsoluteUri("/hubs/example")) + .AddMessagePackProtocol() + .Build(); + + hubConnection.On("ReceiveMessage", (user, message) => + { + var encodedMsg = $"{user}: {message}"; + messages.Add(encodedMsg); + InvokeAsync(StateHasChanged); + }); + + await hubConnection.StartAsync(); + } + + private async Task Send() + { + if (hubConnection is not null) + { + await hubConnection.SendAsync("SendMessage", userInput, messageInput); + } + } + + public bool IsConnected => + hubConnection?.State == HubConnectionState.Connected; + + public async ValueTask DisposeAsync() + { + if (hubConnection is not null) + { + await hubConnection.DisposeAsync(); + } + } +} \ No newline at end of file diff --git a/Iceshrimp.Frontend/Pages/TestNote.razor b/Iceshrimp.Frontend/Pages/TestNote.razor new file mode 100644 index 0000000..a628604 --- /dev/null +++ b/Iceshrimp.Frontend/Pages/TestNote.razor @@ -0,0 +1,44 @@ +@page "/TestNote/{id}" +@using Iceshrimp.Frontend.Core.Miscellaneous +@using Iceshrimp.Frontend.Core.Services +@using Iceshrimp.Shared.Schemas +@inject ApiService Api +

TestNote

+ +@if (_note != null) +{ +

@_note.Text

+} +else if (_error != null) +{ +

Error!: @_error.Error

+} +else +{ +

Fetching note...

+} + +@code { + [Parameter] + public string Id { get; set; } = null!; + + private ErrorResponse? _error; + private NoteResponse? _note; + + protected override async Task OnInitializedAsync() + { + try + { + _note = await Api.Notes.GetNote(Id) ?? throw new ApiException(new ErrorResponse + { + StatusCode = 404, + Error = "Note not found", + RequestId = "-" + }); + } + catch (ApiException e) + { + _error = e.Response; + } + } +} \ No newline at end of file diff --git a/Iceshrimp.Frontend/Program.cs b/Iceshrimp.Frontend/Program.cs index edd29dc..491fcad 100644 --- a/Iceshrimp.Frontend/Program.cs +++ b/Iceshrimp.Frontend/Program.cs @@ -1,11 +1,13 @@ using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using Iceshrimp.Frontend; +using Iceshrimp.Frontend.Core.Services; var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add("#app"); builder.RootComponents.Add("head::after"); builder.Services.AddScoped(_ => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); +builder.Services.AddScoped(); await builder.Build().RunAsync(); \ No newline at end of file diff --git a/Iceshrimp.NET.sln b/Iceshrimp.NET.sln index 344e22c..bb20a25 100644 --- a/Iceshrimp.NET.sln +++ b/Iceshrimp.NET.sln @@ -8,6 +8,8 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "Iceshrimp.Parsing", "Iceshr EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Iceshrimp.Frontend", "Iceshrimp.Frontend\Iceshrimp.Frontend.csproj", "{8BAF3DEB-19A7-4044-A3F3-75C8B9B51863}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Iceshrimp.Shared", "Iceshrimp.Shared\Iceshrimp.Shared.csproj", "{25E8E423-D2F7-437B-8E9B-5277BA5CE3CD}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -30,5 +32,9 @@ Global {8BAF3DEB-19A7-4044-A3F3-75C8B9B51863}.Debug|Any CPU.Build.0 = Debug|Any CPU {8BAF3DEB-19A7-4044-A3F3-75C8B9B51863}.Release|Any CPU.ActiveCfg = Release|Any CPU {8BAF3DEB-19A7-4044-A3F3-75C8B9B51863}.Release|Any CPU.Build.0 = Release|Any CPU + {25E8E423-D2F7-437B-8E9B-5277BA5CE3CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {25E8E423-D2F7-437B-8E9B-5277BA5CE3CD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {25E8E423-D2F7-437B-8E9B-5277BA5CE3CD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {25E8E423-D2F7-437B-8E9B-5277BA5CE3CD}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/Iceshrimp.Shared/Iceshrimp.Shared.csproj b/Iceshrimp.Shared/Iceshrimp.Shared.csproj new file mode 100644 index 0000000..3a63532 --- /dev/null +++ b/Iceshrimp.Shared/Iceshrimp.Shared.csproj @@ -0,0 +1,9 @@ + + + + net8.0 + enable + enable + + + diff --git a/Iceshrimp.Backend/Controllers/Schemas/AuthRequest.cs b/Iceshrimp.Shared/Schemas/AuthRequest.cs similarity index 91% rename from Iceshrimp.Backend/Controllers/Schemas/AuthRequest.cs rename to Iceshrimp.Shared/Schemas/AuthRequest.cs index f691928..35b8265 100644 --- a/Iceshrimp.Backend/Controllers/Schemas/AuthRequest.cs +++ b/Iceshrimp.Shared/Schemas/AuthRequest.cs @@ -1,6 +1,6 @@ using J = System.Text.Json.Serialization.JsonPropertyNameAttribute; -namespace Iceshrimp.Backend.Controllers.Schemas; +namespace Iceshrimp.Shared.Schemas; public class AuthRequest { diff --git a/Iceshrimp.Backend/Controllers/Schemas/AuthResponse.cs b/Iceshrimp.Shared/Schemas/AuthResponse.cs similarity index 93% rename from Iceshrimp.Backend/Controllers/Schemas/AuthResponse.cs rename to Iceshrimp.Shared/Schemas/AuthResponse.cs index 6e2f78b..ec11bdd 100644 --- a/Iceshrimp.Backend/Controllers/Schemas/AuthResponse.cs +++ b/Iceshrimp.Shared/Schemas/AuthResponse.cs @@ -3,7 +3,7 @@ using System.Text.Json.Serialization; using J = System.Text.Json.Serialization.JsonPropertyNameAttribute; using JE = System.Runtime.Serialization.EnumMemberAttribute; -namespace Iceshrimp.Backend.Controllers.Schemas; +namespace Iceshrimp.Shared.Schemas; public class AuthStatusConverter() : JsonStringEnumConverter(JsonNamingPolicy.SnakeCaseLower); diff --git a/Iceshrimp.Backend/Controllers/Schemas/ErrorResponse.cs b/Iceshrimp.Shared/Schemas/ErrorResponse.cs similarity index 93% rename from Iceshrimp.Backend/Controllers/Schemas/ErrorResponse.cs rename to Iceshrimp.Shared/Schemas/ErrorResponse.cs index 781bffa..d1fe69e 100644 --- a/Iceshrimp.Backend/Controllers/Schemas/ErrorResponse.cs +++ b/Iceshrimp.Shared/Schemas/ErrorResponse.cs @@ -2,7 +2,7 @@ using System.Text.Json.Serialization; using J = System.Text.Json.Serialization.JsonPropertyNameAttribute; using JI = System.Text.Json.Serialization.JsonIgnoreAttribute; -namespace Iceshrimp.Backend.Controllers.Schemas; +namespace Iceshrimp.Shared.Schemas; public class ErrorResponse { diff --git a/Iceshrimp.Backend/Controllers/Schemas/InviteResponse.cs b/Iceshrimp.Shared/Schemas/InviteResponse.cs similarity index 76% rename from Iceshrimp.Backend/Controllers/Schemas/InviteResponse.cs rename to Iceshrimp.Shared/Schemas/InviteResponse.cs index b81d27e..5b3db50 100644 --- a/Iceshrimp.Backend/Controllers/Schemas/InviteResponse.cs +++ b/Iceshrimp.Shared/Schemas/InviteResponse.cs @@ -1,6 +1,6 @@ using J = System.Text.Json.Serialization.JsonPropertyNameAttribute; -namespace Iceshrimp.Backend.Controllers.Schemas; +namespace Iceshrimp.Shared.Schemas; public class InviteResponse { diff --git a/Iceshrimp.Backend/Controllers/Schemas/NoteCreateRequest.cs b/Iceshrimp.Shared/Schemas/NoteCreateRequest.cs similarity index 88% rename from Iceshrimp.Backend/Controllers/Schemas/NoteCreateRequest.cs rename to Iceshrimp.Shared/Schemas/NoteCreateRequest.cs index b89a1bd..c2d1390 100644 --- a/Iceshrimp.Backend/Controllers/Schemas/NoteCreateRequest.cs +++ b/Iceshrimp.Shared/Schemas/NoteCreateRequest.cs @@ -1,6 +1,6 @@ using J = System.Text.Json.Serialization.JsonPropertyNameAttribute; -namespace Iceshrimp.Backend.Controllers.Schemas; +namespace Iceshrimp.Shared.Schemas; public class NoteCreateRequest { diff --git a/Iceshrimp.Backend/Controllers/Schemas/NoteResponse.cs b/Iceshrimp.Shared/Schemas/NoteResponse.cs similarity index 97% rename from Iceshrimp.Backend/Controllers/Schemas/NoteResponse.cs rename to Iceshrimp.Shared/Schemas/NoteResponse.cs index bc649ee..445073f 100644 --- a/Iceshrimp.Backend/Controllers/Schemas/NoteResponse.cs +++ b/Iceshrimp.Shared/Schemas/NoteResponse.cs @@ -1,7 +1,7 @@ using J = System.Text.Json.Serialization.JsonPropertyNameAttribute; using JI = System.Text.Json.Serialization.JsonIgnoreAttribute; -namespace Iceshrimp.Backend.Controllers.Schemas; +namespace Iceshrimp.Shared.Schemas; public class NoteResponse : NoteWithQuote { diff --git a/Iceshrimp.Backend/Controllers/Schemas/NotificationResponse.cs b/Iceshrimp.Shared/Schemas/NotificationResponse.cs similarity index 91% rename from Iceshrimp.Backend/Controllers/Schemas/NotificationResponse.cs rename to Iceshrimp.Shared/Schemas/NotificationResponse.cs index c60f06c..780f774 100644 --- a/Iceshrimp.Backend/Controllers/Schemas/NotificationResponse.cs +++ b/Iceshrimp.Shared/Schemas/NotificationResponse.cs @@ -1,6 +1,6 @@ using J = System.Text.Json.Serialization.JsonPropertyNameAttribute; -namespace Iceshrimp.Backend.Controllers.Schemas; +namespace Iceshrimp.Shared.Schemas; public class NotificationResponse { diff --git a/Iceshrimp.Shared/Schemas/UserProfileResponse.cs b/Iceshrimp.Shared/Schemas/UserProfileResponse.cs new file mode 100644 index 0000000..289048c --- /dev/null +++ b/Iceshrimp.Shared/Schemas/UserProfileResponse.cs @@ -0,0 +1,21 @@ +using J = System.Text.Json.Serialization.JsonPropertyNameAttribute; + +namespace Iceshrimp.Shared.Schemas; + +public class UserProfileResponse +{ + [J("id")] public required string Id { get; set; } + [J("birthday")] public required string? Birthday { get; set; } + [J("location")] public required string? Location { get; set; } + [J("fields")] public required List? Fields { get; set; } + [J("bio")] public required string? Bio { get; set; } + [J("followers")] public required int? Followers { get; set; } + [J("following")] public required int? Following { get; set; } +} + +public class UserProfileField +{ + [J("name")] public required string Name { get; set; } + [J("value")] public required string Value { get; set; } + [J("verified")] public bool? IsVerified { get; set; } +} \ No newline at end of file diff --git a/Iceshrimp.Backend/Controllers/Schemas/UserResponse.cs b/Iceshrimp.Shared/Schemas/UserResponse.cs similarity index 92% rename from Iceshrimp.Backend/Controllers/Schemas/UserResponse.cs rename to Iceshrimp.Shared/Schemas/UserResponse.cs index e6acf81..630bc55 100644 --- a/Iceshrimp.Backend/Controllers/Schemas/UserResponse.cs +++ b/Iceshrimp.Shared/Schemas/UserResponse.cs @@ -1,6 +1,6 @@ using J = System.Text.Json.Serialization.JsonPropertyNameAttribute; -namespace Iceshrimp.Backend.Controllers.Schemas; +namespace Iceshrimp.Shared.Schemas; public class UserResponse { diff --git a/Iceshrimp.Backend/Controllers/Schemas/ValueResponse.cs b/Iceshrimp.Shared/Schemas/ValueResponse.cs similarity index 77% rename from Iceshrimp.Backend/Controllers/Schemas/ValueResponse.cs rename to Iceshrimp.Shared/Schemas/ValueResponse.cs index f41f51b..276503b 100644 --- a/Iceshrimp.Backend/Controllers/Schemas/ValueResponse.cs +++ b/Iceshrimp.Shared/Schemas/ValueResponse.cs @@ -1,6 +1,6 @@ using J = System.Text.Json.Serialization.JsonPropertyNameAttribute; -namespace Iceshrimp.Backend.Controllers.Schemas; +namespace Iceshrimp.Shared.Schemas; public class ValueResponse(long count) {