diff --git a/ShoppingAssistantWebClient.Web/Models/Enums/SearchEventType.cs b/ShoppingAssistantWebClient.Web/Models/Enums/SearchEventType.cs new file mode 100644 index 0000000..af14ebd --- /dev/null +++ b/ShoppingAssistantWebClient.Web/Models/Enums/SearchEventType.cs @@ -0,0 +1,9 @@ +namespace ShoppingAssistantWebClient.Web.Models.Enums; + +public enum SearchEventType +{ + Wishlist = 0, + Message = 1, + Suggestion = 2, + Product = 3 +} \ No newline at end of file diff --git a/ShoppingAssistantWebClient.Web/Models/Input/MessageCreateDto.cs b/ShoppingAssistantWebClient.Web/Models/Input/MessageCreateDto.cs new file mode 100644 index 0000000..5349051 --- /dev/null +++ b/ShoppingAssistantWebClient.Web/Models/Input/MessageCreateDto.cs @@ -0,0 +1,6 @@ +namespace ShoppingAssistantWebClient.Web.Models.Input; + +public class MessageCreateDto +{ + public required string Text { get; set; } +} diff --git a/ShoppingAssistantWebClient.Web/Models/ProductSearch/ServerSentEvent.cs b/ShoppingAssistantWebClient.Web/Models/ProductSearch/ServerSentEvent.cs new file mode 100644 index 0000000..20f0df1 --- /dev/null +++ b/ShoppingAssistantWebClient.Web/Models/ProductSearch/ServerSentEvent.cs @@ -0,0 +1,10 @@ +using ShoppingAssistantWebClient.Web.Models.Enums; + +namespace ShoppingAssistantWebClient.Web.Models.ProductSearch; + +public class ServerSentEvent +{ + public SearchEventType Event { get; set; } + + public string Data { get; set; } +} diff --git a/ShoppingAssistantWebClient.Web/Network/ApiClient.cs b/ShoppingAssistantWebClient.Web/Network/ApiClient.cs index f7b6532..d87bb3a 100644 --- a/ShoppingAssistantWebClient.Web/Network/ApiClient.cs +++ b/ShoppingAssistantWebClient.Web/Network/ApiClient.cs @@ -3,6 +3,9 @@ using GraphQL; using Newtonsoft.Json; using System.Net.Http.Headers; using ShoppingAssistantWebClient.Web.Models.GlobalInstances; +using ShoppingAssistantWebClient.Web.Models.ProductSearch; +using System.Text; +using ShoppingAssistantWebClient.Web.Models.Enums; namespace ShoppingAssistantWebClient.Web.Network; @@ -93,6 +96,50 @@ public class ApiClient return model; } + public async IAsyncEnumerable GetServerSentEventStreamed(string url, Object obj, CancellationToken cancellationToken) + { + await SetAuthenticationAsync(); + + var requestUrl = $"{_httpClient.BaseAddress}{url}"; + var response = await _httpClient.PostAsJsonAsync(requestUrl, obj); + using var responseStream = await response.Content.ReadAsStreamAsync(); + using var reader = new StreamReader(responseStream, Encoding.UTF8); + + SearchEventType eventType = SearchEventType.Message; + while (!cancellationToken.IsCancellationRequested) + { + var jsonChunk = await reader.ReadLineAsync(cancellationToken); + if (jsonChunk == null) continue; + if (jsonChunk.StartsWith("event: ")) + { + var type = jsonChunk.Substring("event: ".Length); + switch(type) + { + case "Message": + eventType = SearchEventType.Message; + break; + case "Suggestion": + eventType = SearchEventType.Suggestion; + break; + case "Product": + eventType = SearchEventType.Product; + break; + case "Wishlist": + eventType = SearchEventType.Wishlist; + break; + } + } + if (jsonChunk.StartsWith("data: ")) + { + yield return new ServerSentEvent + { + Event = eventType, + Data = jsonChunk.Substring("data: ".Length), + }; + } + } + } + private MultipartFormDataContent MapIFormCollectionToForm(IFormCollection formCollection) { var formDataContent = new MultipartFormDataContent();