From 339980a31df3522a9e1dcd673c5cd9a08a457226 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=96=C2=96AsTroLog?= Date: Sun, 3 Dec 2023 20:46:08 +0000 Subject: [PATCH 1/9] SA-201/ fix bags with frame --- .../Pages/Cards.razor | 2 +- .../Pages/Index.razor | 23 ++++++++++++++++--- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/ShoppingAssistantWebClient.Web/Pages/Cards.razor b/ShoppingAssistantWebClient.Web/Pages/Cards.razor index 4bd8442..ec83fce 100644 --- a/ShoppingAssistantWebClient.Web/Pages/Cards.razor +++ b/ShoppingAssistantWebClient.Web/Pages/Cards.razor @@ -96,7 +96,7 @@
- +
} diff --git a/ShoppingAssistantWebClient.Web/Pages/Index.razor b/ShoppingAssistantWebClient.Web/Pages/Index.razor index 2ac3083..18f5001 100644 --- a/ShoppingAssistantWebClient.Web/Pages/Index.razor +++ b/ShoppingAssistantWebClient.Web/Pages/Index.razor @@ -30,25 +30,28 @@
-
+ - +
@@ -121,6 +124,20 @@ } + + public void ClickTopic(int input) + { + if (input == 1){ + inputValue ="I need a present for a date"; + } + if (input == 2){ + inputValue ="I need a present for halloween"; + } + if (input == 3){ + inputValue ="I need a present for a birthday"; + } + CreateNewChat(); + } private void InputChanged(ChangeEventArgs e) { // Оновіть значення поля введення при кожному введенні тексту From a2a4929a21852e01af3303a89b7135e659155a6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=96=C2=96AsTroLog?= Date: Fri, 8 Dec 2023 23:28:58 +0000 Subject: [PATCH 2/9] fix bugs --- .../Pages/Chat.razor | 30 +++++++++++--- .../Pages/Chat.razor.css | 39 ++++++++++++++++++- 2 files changed, 62 insertions(+), 7 deletions(-) diff --git a/ShoppingAssistantWebClient.Web/Pages/Chat.razor b/ShoppingAssistantWebClient.Web/Pages/Chat.razor index bdef32e..da2462f 100644 --- a/ShoppingAssistantWebClient.Web/Pages/Chat.razor +++ b/ShoppingAssistantWebClient.Web/Pages/Chat.razor @@ -19,6 +19,8 @@
@name
+ +
@@ -33,9 +35,27 @@ if (item.Role != "User") { -
  • -

    @item.Text

    -
  • + if (@item.Text == "Waiting for response") + { + +
    Waiting for response + +
    + +
    + + + + } + else + { + +
  • +

    @item.Text

    +
  • + + } + } else @@ -105,7 +125,7 @@ }; function myJavaScriptFunction(wishlistId) { - UpdateMenu(wishlistId); + UpdateMenu(wishlistId); } document.getElementById('button_open').addEventListener('click', changetyle); @@ -114,7 +134,7 @@ [Parameter] public string chatId { get; set; } - public string inputValue = ""; + public string inputValue = ""; protected override async Task OnParametersSetAsync() { diff --git a/ShoppingAssistantWebClient.Web/Pages/Chat.razor.css b/ShoppingAssistantWebClient.Web/Pages/Chat.razor.css index ef44028..972c4c4 100644 --- a/ShoppingAssistantWebClient.Web/Pages/Chat.razor.css +++ b/ShoppingAssistantWebClient.Web/Pages/Chat.razor.css @@ -117,7 +117,7 @@ .chat_message { position: relative; overflow-y: auto; - height: calc(100% - 8em); + height: calc(100% - 8.5em); width: 100%; } .chat_message::-webkit-scrollbar { @@ -150,6 +150,19 @@ .chat_incoming{ display: flex; } + .chat_incoming_wait { + display: inline-flex; /* Использовать inline-flex-контейнер */ + align-items: center; /* Выравнивание по центру */ + font-size: 0.9em; + background-color: #EAEAEA; + border-radius: 10px; + color: black; + padding: 10px; + margin-bottom: 20px; + margin-top: 20px; + max-width: 70%; /* Максимальная ширина по вашему усмотрению */ + } + .chat_box .chat_outgoing p { margin-left: auto; background-color: #009FFF; @@ -167,4 +180,26 @@ width: 60%; margin-bottom: 20px ; margin-top: 20px ; - } \ No newline at end of file + } + + @keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } + } + + .loading-spinner { + border: 4px solid rgba(0, 82, 204, 0.1); + border-top: 4px solid #0052CC; + border-radius: 50%; + width: 20px; + height: 20px; + animation: spin 1s linear infinite; + margin-left: 10px; /* Добавлен отступ для разделения текста и загрузки */ + } + .gradient{ + background: linear-gradient(rgb(255, 255, 255), rgba(0, 0, 0, 0)); + position: absolute; + height: 50px; + width: 100%; + z-index: 1; + } \ No newline at end of file From 544154b9834ee2a32ce3417fb3c174f60fe1dcf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=96=C2=96AsTroLog?= Date: Fri, 8 Dec 2023 23:30:33 +0000 Subject: [PATCH 3/9] fix font size --- ShoppingAssistantWebClient.Web/Pages/Chat.razor.css | 1 - 1 file changed, 1 deletion(-) diff --git a/ShoppingAssistantWebClient.Web/Pages/Chat.razor.css b/ShoppingAssistantWebClient.Web/Pages/Chat.razor.css index 972c4c4..20a4466 100644 --- a/ShoppingAssistantWebClient.Web/Pages/Chat.razor.css +++ b/ShoppingAssistantWebClient.Web/Pages/Chat.razor.css @@ -153,7 +153,6 @@ .chat_incoming_wait { display: inline-flex; /* Использовать inline-flex-контейнер */ align-items: center; /* Выравнивание по центру */ - font-size: 0.9em; background-color: #EAEAEA; border-radius: 10px; color: black; From f933e31be4f7545c5116cf28ca674fe9c92f0c39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=96=C2=96AsTroLog?= Date: Sun, 10 Dec 2023 11:33:24 +0000 Subject: [PATCH 4/9] fix UI --- .../Pages/Chat.razor | 2 +- .../Pages/Chat.razor.css | 204 +++++++++++------- .../Pages/Index.razor.css | 37 +++- .../Shared/NavMenu.razor | 73 ++++--- .../Shared/NavMenu.razor.css | 6 + .../wwwroot/css/MainLayout.css | 4 +- .../wwwroot/images/avatar.jpg | Bin 45213 -> 0 bytes .../wwwroot/images/avatar.svg | 34 +++ 8 files changed, 253 insertions(+), 107 deletions(-) delete mode 100644 ShoppingAssistantWebClient.Web/wwwroot/images/avatar.jpg create mode 100644 ShoppingAssistantWebClient.Web/wwwroot/images/avatar.svg diff --git a/ShoppingAssistantWebClient.Web/Pages/Chat.razor b/ShoppingAssistantWebClient.Web/Pages/Chat.razor index da2462f..4f07e36 100644 --- a/ShoppingAssistantWebClient.Web/Pages/Chat.razor +++ b/ShoppingAssistantWebClient.Web/Pages/Chat.razor @@ -51,7 +51,7 @@ {
  • -

    @item.Text

    + @item.Text
  • } diff --git a/ShoppingAssistantWebClient.Web/Pages/Chat.razor.css b/ShoppingAssistantWebClient.Web/Pages/Chat.razor.css index 20a4466..a7a69bf 100644 --- a/ShoppingAssistantWebClient.Web/Pages/Chat.razor.css +++ b/ShoppingAssistantWebClient.Web/Pages/Chat.razor.css @@ -7,7 +7,7 @@ width: 100%; } - + .button_open_menu { z-index: 2; width: 1.43em; @@ -17,6 +17,10 @@ left: 1.56em; cursor: pointer; visibility: hidden; + + @media screen and (max-width: 900px) { + visibility: visible; + } } .button_open_menu span { @@ -38,23 +42,42 @@ } .title_one_frame { + white-space: nowrap; /* Запобігає переносу тексту на новий рядок */ + overflow: hidden; /* Сховує текст, який не влазить в блок */ + text-overflow: ellipsis; /* Додає три крапки на кінці обрізаного тексту */ + margin-left: 4em; + margin-right: 4em; padding-top: 1.25em; color: #0052CC; font-size: 1.0625em; text-align: center; } - + .chat_input { background-color: #EAEAEA; position: absolute; - display: flex; + display: inline-flex; + /* Использовать inline-flex-контейнер */ align-items: center; bottom: 2em; margin-left: 25%; width: 50%; border-radius: 0.6em; + + @media screen and (max-width: 750px) { + margin-left: 15%; + width: 70%; + + } + + @media screen and (max-width: 480px) { + margin-left: 2%; + width: 96%; + + } } + .possible_options { position: absolute; bottom: 5.5em; @@ -62,28 +85,30 @@ width: 50%; border-radius: 0.6em; } -.tite_options{ + +.tite_options { font-size: 0.9em; color: #ADADAD; margin-bottom: 0.5em; } -.options{ + +.options { justify-content: space-between; align-items: center; font-size: 1em; } -.topic_options -{ - display: inline-block; - padding: 0.5em; - border: 0.09em solid; - border-color: #009FFF; - border-radius: 0.6em; - margin: 0em 0.6em; - flex: 1; - text-align: center; - cursor: pointer; + +.topic_options { + display: inline-block; + padding: 0.5em; + border: 0.09em solid; + border-color: #009FFF; + border-radius: 0.6em; + margin: 0em 0.6em; + flex: 1; + text-align: center; + cursor: pointer; } .input_messages { @@ -120,6 +145,7 @@ height: calc(100% - 8.5em); width: 100%; } + .chat_message::-webkit-scrollbar { border-radius: 20px; width: 0.2em; @@ -134,71 +160,99 @@ } - .chat_box{ - border-radius: 10px; - position: absolute; - margin-left: 25%; - margin-top: 35px; - width: 50%; - list-style: none; - padding:0; - - } - .chat_outgoing{ - display: flex; - } - .chat_incoming{ - display: flex; - } - .chat_incoming_wait { - display: inline-flex; /* Использовать inline-flex-контейнер */ - align-items: center; /* Выравнивание по центру */ - background-color: #EAEAEA; - border-radius: 10px; - color: black; - padding: 10px; - margin-bottom: 20px; - margin-top: 20px; - max-width: 70%; /* Максимальная ширина по вашему усмотрению */ - } - - .chat_box .chat_outgoing p { - margin-left: auto; - background-color: #009FFF; - border-radius: 10px; - color: white; - padding: 10px; - max-width: 60%; - - } - .chat_box .chat_incoming p { - background-color: #EAEAEA; - border-radius: 10px; - color: black; - padding: 10px; - width: 60%; - margin-bottom: 20px ; - margin-top: 20px ; +.chat_box { + border-radius: 10px; + position: absolute; + margin-left: 25%; + margin-top: 35px; + width: 50%; + list-style: none; + padding: 0; + + @media screen and (max-width: 750px) { + margin-left: 15%; + width: 70%; + } - @keyframes spin { - 0% { transform: rotate(0deg); } - 100% { transform: rotate(360deg); } + @media screen and (max-width: 480px) { + margin-left: 4%; + width: 92%; + } - - .loading-spinner { - border: 4px solid rgba(0, 82, 204, 0.1); - border-top: 4px solid #0052CC; - border-radius: 50%; - width: 20px; - height: 20px; - animation: spin 1s linear infinite; - margin-left: 10px; /* Добавлен отступ для разделения текста и загрузки */ +} + +.chat_outgoing { + display: flex; +} + +.chat_incoming { + display: inline-flex; + /* Использовать inline-flex-контейнер */ + align-items: center; + /* Выравнивание по центру */ + background-color: #EAEAEA; + border-radius: 10px; + color: black; + padding: 10px; + margin-bottom: 20px; + margin-top: 20px; + max-width: 70%; + /* Максимальная ширина по вашему усмотрению */ + min-width: 155px; + /* Максимальная ширина по вашему усмотрению */ +} + +.chat_incoming_wait { + display: inline-flex; /* Использовать inline-flex-контейнер */ + align-items: center; /* Выравнивание по центру */ + background-color: #EAEAEA; + border-radius: 10px; + color: black; + padding: 10px; + margin-bottom: 20px; + margin-top: 20px; + max-width: 70%; /* Максимальная ширина по вашему усмотрению */ + min-width: 155px; /* Максимальная ширина по вашему усмотрению */ +} + +.chat_box .chat_outgoing p { + margin-left: auto; + background-color: #009FFF; + border-radius: 10px; + color: white; + padding: 10px; + max-width: 60%; + +} + + +@keyframes spin { + 0% { + transform: rotate(0deg); } - .gradient{ + + 100% { + transform: rotate(360deg); + } +} + +.loading-spinner { + border: 4px solid rgba(0, 82, 204, 0.1); + border-top: 4px solid #0052CC; + border-radius: 50%; + width: 20px; + height: 20px; + animation: spin 1s linear infinite; + margin-left: 10px; + /* Добавлен отступ для разделения текста и загрузки */ +} + +.gradient { background: linear-gradient(rgb(255, 255, 255), rgba(0, 0, 0, 0)); position: absolute; height: 50px; width: 100%; z-index: 1; - } \ No newline at end of file + margin-top: -0.2em; +} \ No newline at end of file diff --git a/ShoppingAssistantWebClient.Web/Pages/Index.razor.css b/ShoppingAssistantWebClient.Web/Pages/Index.razor.css index 0a7fe71..6459264 100644 --- a/ShoppingAssistantWebClient.Web/Pages/Index.razor.css +++ b/ShoppingAssistantWebClient.Web/Pages/Index.razor.css @@ -16,7 +16,6 @@ left: 1.56em; cursor: pointer; visibility: hidden; - @media screen and (max-width: 900px) { visibility: visible; } @@ -62,6 +61,11 @@ font-size: 2.5em; text-align: center; font-weight: 600; + @media screen and (max-width: 480px) { + + font-size: 1.7125em; + + } } .title_three_frame { @@ -71,6 +75,13 @@ font-size: 1.25em; text-align: center; font-weight: 400; + @media screen and (max-width: 480px) { + + font-size: 1.0125em; + padding-left: 4%; + padding-right: 4%; + + } } .topic { @@ -80,6 +91,12 @@ color: #009FFF; width: 15.625em; margin: 0 auto; + @media screen and (max-width: 480px) { + + width: 11.875em; + font-size: 0.9125em; + + } } .topic div { @@ -106,6 +123,11 @@ border-radius: 0.6em; text-align: center; position: relative; + @media screen and (max-width: 480px) { + height: 2.4125em; + width: 16.875em; + + } } .switch_product { @@ -148,14 +170,25 @@ .chat_input { background-color: #EAEAEA; position: absolute; - display: flex; + display: inline-flex; /* Использовать inline-flex-контейнер */ align-items: center; bottom: 2em; margin-left: 25%; width: 50%; border-radius: 0.6em; + @media screen and (max-width: 750px) { + margin-left: 15%; + width: 70%; + + } + @media screen and (max-width: 480px) { + margin-left: 2%; + width: 96%; + + } } + .input_messages { width: 100%; height: 2.5em; diff --git a/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor b/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor index d88d10a..963a337 100644 --- a/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor +++ b/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor @@ -52,9 +52,9 @@
    - Avatar user + Avatar user - @GlobalUser.Id + Unknown user
    @@ -76,42 +76,57 @@ var button_open = document.querySelector('.button_open_menu'); if (transformValue === 'matrix(1, 0, 0, 1, 0, 0)') { - left_frame.style.transform = 'translateX(-110%)'; - button_open.style.visibility = 'visible'; - right_frame.style.left = '1.25em'; - amazonAssociate.style.left ='calc(50% - 12.5em)'; + + // меню закрите + if (window.innerWidth < 1100) { + right_frame.style.left = '1.25em'; + amazonAssociate.style.left ='calc(50% - 12.5em)'; + right_frame.style.zIndex = '0'; + left_frame.style.transform = 'translateX(-110%)'; + button_open.style.visibility = 'visible'; + }else{ + amazonAssociate.style.left ='calc(50% - 12.5em)'; + left_frame.style.transform = 'translateX(-110%)'; + button_open.style.visibility = 'visible'; + right_frame.style.left = '1.25em'; + } + } else { - left_frame.style.transform = 'translateX(0)'; - button_open.style.visibility = 'hidden'; - right_frame.style. left = '23.25em'; - amazonAssociate.style.left ='50%'; + + // меню відкрите + if (window.innerWidth < 1100) { + right_frame.style.left = '1.25em'; + amazonAssociate.style.left ='calc(50% - 12.5em)'; + right_frame.style.zIndex = '0'; + left_frame.style.zIndex = '1'; + left_frame.style.transform = 'translateX(0)'; + button_open.style.visibility = 'hidden'; + }else{ + amazonAssociate.style.left ='50%'; + left_frame.style.transform = 'translateX(0)'; + button_open.style.visibility = 'hidden'; + right_frame.style. left = '23.25em'; + } + + } } document.getElementById('button_close').addEventListener('click', changetyle); -/* - window.getScrollTop = function (element) { - return element.scrollTop; - }; - - window.getOffsetHeight = function (element) { - return element.offsetHeight; - }; - - window.getScrollHeight = function (element) { - return element.scrollHeight; - }; - - window.setScrollTop = function (element, scrollTop) { - element.scrollTop = scrollTop; - }; -*/ @code { diff --git a/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor.css b/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor.css index bc5c52c..8cee536 100644 --- a/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor.css +++ b/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor.css @@ -11,6 +11,10 @@ display: flex; align-items: center; padding-bottom: 1.5%; + background-color: white; + margin-left: 0.3em; + border-radius: 0.6em 0 0em 0em; + } .menu { @@ -22,6 +26,7 @@ border-color: #0052CC; border-radius: 0.6em; padding-top: 1.5%; + background-color: white; } .elements_wishlisht { @@ -222,6 +227,7 @@ border-radius: 50%; width: 2.3em; height: 2.3em; + } .button_close_menu { diff --git a/ShoppingAssistantWebClient.Web/wwwroot/css/MainLayout.css b/ShoppingAssistantWebClient.Web/wwwroot/css/MainLayout.css index f8a61e4..552d123 100644 --- a/ShoppingAssistantWebClient.Web/wwwroot/css/MainLayout.css +++ b/ShoppingAssistantWebClient.Web/wwwroot/css/MainLayout.css @@ -9,10 +9,12 @@ .sidebar-menu { position: absolute; width: 20em; - top: 1.25em; + top: 1.33em; bottom: 0em; margin-right: 1.5em; + transition: 1s; + border-radius: 0.7em; @media screen and (max-width: 900px) { transform: translateX(-110%); diff --git a/ShoppingAssistantWebClient.Web/wwwroot/images/avatar.jpg b/ShoppingAssistantWebClient.Web/wwwroot/images/avatar.jpg deleted file mode 100644 index 63b9f5a6eefb734d5c739be0d55230208605e83f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45213 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 z 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 VeO$P4&i|G4H0TRA^4$L%{eN{s^#T9@ diff --git a/ShoppingAssistantWebClient.Web/wwwroot/images/avatar.svg b/ShoppingAssistantWebClient.Web/wwwroot/images/avatar.svg new file mode 100644 index 0000000..dd1e234 --- /dev/null +++ b/ShoppingAssistantWebClient.Web/wwwroot/images/avatar.svg @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 7852e9735390c00cfa4b0848ade4e8cdeb1b3af5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=96=C2=96AsTroLog?= Date: Tue, 12 Dec 2023 23:48:09 +0000 Subject: [PATCH 5/9] Sa-227 Fix suggestions --- .../Pages/Chat.razor | 54 ++++++++++++------- .../Pages/Chat.razor.cs | 5 +- .../Pages/Chat.razor.css | 14 ++++- 3 files changed, 52 insertions(+), 21 deletions(-) diff --git a/ShoppingAssistantWebClient.Web/Pages/Chat.razor b/ShoppingAssistantWebClient.Web/Pages/Chat.razor index 4f07e36..e938d12 100644 --- a/ShoppingAssistantWebClient.Web/Pages/Chat.razor +++ b/ShoppingAssistantWebClient.Web/Pages/Chat.razor @@ -72,34 +72,34 @@ +
    +
    -
    + @if (Suggestion.Count != 0) + { +
    Several possible options
    -
    - - @if (Suggestion.Count != 0) - { - -
    Several possible options
    - -
    +
    - @foreach (var item in Suggestion) - { + @foreach (var item in Suggestion) + { -
    - @item -
    - } +
    + @item +
    + } + + +
    + } + +
    -
    - } -
    @@ -127,9 +127,24 @@ function myJavaScriptFunction(wishlistId) { UpdateMenu(wishlistId); } + + + document.getElementById('button_open').addEventListener('click', changetyle); + + @code { [Parameter] public string chatId { get; set; } @@ -159,7 +174,9 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { + await JSRuntime.InvokeVoidAsync("myJavaScriptHeight"); await JSRuntime.InvokeVoidAsync("scrollToBottom", chatMessageRef); + } private async Task UpdateSideMenu(string wishlistId) @@ -171,6 +188,7 @@ private void ClickOption(string item) { inputValue = item; + AddNewMessage(inputValue); } } \ No newline at end of file diff --git a/ShoppingAssistantWebClient.Web/Pages/Chat.razor.cs b/ShoppingAssistantWebClient.Web/Pages/Chat.razor.cs index 99eee0a..a9ed1c5 100644 --- a/ShoppingAssistantWebClient.Web/Pages/Chat.razor.cs +++ b/ShoppingAssistantWebClient.Web/Pages/Chat.razor.cs @@ -210,8 +210,9 @@ public partial class Chat : ComponentBase Products.Add(input); } else if(sseEvent.Event == SearchEventType.Suggestion){ - - Suggestion.Add(result); + if(Suggestion.Count<6){ + Suggestion.Add(result); + } } } diff --git a/ShoppingAssistantWebClient.Web/Pages/Chat.razor.css b/ShoppingAssistantWebClient.Web/Pages/Chat.razor.css index a7a69bf..0fb9912 100644 --- a/ShoppingAssistantWebClient.Web/Pages/Chat.razor.css +++ b/ShoppingAssistantWebClient.Web/Pages/Chat.razor.css @@ -84,6 +84,18 @@ margin-left: 25%; width: 50%; border-radius: 0.6em; + + @media screen and (max-width: 750px) { + margin-left: 15%; + width: 70%; + + } + + @media screen and (max-width: 480px) { + margin-left: 2%; + width: 96%; + + } } .tite_options { @@ -105,7 +117,7 @@ border: 0.09em solid; border-color: #009FFF; border-radius: 0.6em; - margin: 0em 0.6em; + margin: 0.2em 0.2em; flex: 1; text-align: center; cursor: pointer; From 8fa2ee1e5e963fa71f6d61a68d109679f098c2e4 Mon Sep 17 00:00:00 2001 From: Mykhailo Bilodid <99915575+Mikhail-Beloded@users.noreply.github.com> Date: Wed, 13 Dec 2023 02:22:56 +0200 Subject: [PATCH 6/9] Update Chat.razor.cs --- ShoppingAssistantWebClient.Web/Pages/Chat.razor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ShoppingAssistantWebClient.Web/Pages/Chat.razor.cs b/ShoppingAssistantWebClient.Web/Pages/Chat.razor.cs index a9ed1c5..482ce17 100644 --- a/ShoppingAssistantWebClient.Web/Pages/Chat.razor.cs +++ b/ShoppingAssistantWebClient.Web/Pages/Chat.razor.cs @@ -210,7 +210,7 @@ public partial class Chat : ComponentBase Products.Add(input); } else if(sseEvent.Event == SearchEventType.Suggestion){ - if(Suggestion.Count<6){ + if(Suggestion.Count<3){ Suggestion.Add(result); } } From 61473fe8a999f45b941cfb5947d66fa1f100b727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=96=C2=96AsTroLog?= Date: Sat, 16 Dec 2023 20:47:27 +0000 Subject: [PATCH 7/9] SA-216 Add coming soon --- .../Pages/Index.razor | 41 ++++++++----------- .../Pages/Index.razor.cs | 1 - .../Pages/Index.razor.css | 34 +++++++++++++++ 3 files changed, 51 insertions(+), 25 deletions(-) diff --git a/ShoppingAssistantWebClient.Web/Pages/Index.razor b/ShoppingAssistantWebClient.Web/Pages/Index.razor index 18f5001..f2cadad 100644 --- a/ShoppingAssistantWebClient.Web/Pages/Index.razor +++ b/ShoppingAssistantWebClient.Web/Pages/Index.razor @@ -11,18 +11,18 @@
    -
    +
    New chat
    What you're looking for
    -
    +
    -
    - Gift -
    + +
    @@ -53,13 +53,13 @@
    - + Send message
    - +
    @@ -73,11 +73,11 @@ var choose = "Product"; function switchGift() { - choose_gift.style.backgroundColor = "#0052CC"; - choose_product.style.backgroundColor = "transparent"; - switchGi.style.color = "white"; - switchProd.style.color = "#202124"; - choose = "Gift"; + // choose_gift.style.backgroundColor = "#0052CC"; + // choose_product.style.backgroundColor = "transparent"; + // switchGi.style.color = "white"; + //switchProd.style.color = "#202124"; + //choose = "Gift"; } @@ -91,17 +91,10 @@ } function myJavaScriptFunction(wishlistId) { - UpdateMenu(wishlistId); + UpdateMenu(wishlistId); } - - - - - - - document.getElementById('choose_gift').addEventListener('click', switchGift); document.getElementById('choose_product').addEventListener('click', switchProduct); @@ -113,14 +106,14 @@ private void Сhoose_product() { selectedChoice = "Product"; } - private void Сhoose_gift() { + private void Сhoose_gift() { selectedChoice = "Gift"; } private async Task UpdateSideMenu(string wishlistId) { - await JSRuntime.InvokeVoidAsync("myJavaScriptFunction", wishlistId); + await JSRuntime.InvokeVoidAsync("myJavaScriptFunction", wishlistId); } diff --git a/ShoppingAssistantWebClient.Web/Pages/Index.razor.cs b/ShoppingAssistantWebClient.Web/Pages/Index.razor.cs index c6cd6ab..7fd361c 100644 --- a/ShoppingAssistantWebClient.Web/Pages/Index.razor.cs +++ b/ShoppingAssistantWebClient.Web/Pages/Index.razor.cs @@ -26,7 +26,6 @@ namespace ShoppingAssistantWebClient.Web.Pages private MessageCreateDto messageCreateDto; private string inputValue = ""; - private async Task CreateNewChat() { try diff --git a/ShoppingAssistantWebClient.Web/Pages/Index.razor.css b/ShoppingAssistantWebClient.Web/Pages/Index.razor.css index 6459264..863df0f 100644 --- a/ShoppingAssistantWebClient.Web/Pages/Index.razor.css +++ b/ShoppingAssistantWebClient.Web/Pages/Index.razor.css @@ -159,7 +159,41 @@ transition: 0.8s; color: #202124; } +button::before { + content: attr(text); +} + +button:hover::before { + content: attr(hover-text); +} +button { + outline: none; /* Для синий ободки */ + border: 0; + background: transparent; +} +.message { + right: 0; + position: absolute; + border-radius: 0.6em; + margin: 0.3125em; + width: calc(50% - 0.625em); + height: calc(100% - 0.625em); + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: 0.8s; + color: #202124; + padding: 4px; /* Добавьте подходящий отступ, если необходимо */ +} +.hidden { + display: none; +} + +.show { + display: block; +} .chat_message { position: relative; overflow-y: auto; From 20d24b8738c5d1ebb446490f0734556e803539f7 Mon Sep 17 00:00:00 2001 From: shchoholiev Date: Sat, 16 Dec 2023 22:37:38 +0000 Subject: [PATCH 8/9] SA-240 Display messages writing in realtime - Change SSE handling to display them as soon as they come - Change AddNewMessage() to disply messages and suggestions in realtime --- .../Network/ApiClient.cs | 21 +- .../Pages/Chat.razor.cs | 319 ++++++++++-------- 2 files changed, 183 insertions(+), 157 deletions(-) diff --git a/ShoppingAssistantWebClient.Web/Network/ApiClient.cs b/ShoppingAssistantWebClient.Web/Network/ApiClient.cs index a4a6f24..1c8d77f 100644 --- a/ShoppingAssistantWebClient.Web/Network/ApiClient.cs +++ b/ShoppingAssistantWebClient.Web/Network/ApiClient.cs @@ -101,17 +101,24 @@ public class ApiClient await SetAuthenticationAsync(); var count = 0; // 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); + var jsonBody = JsonConvert.SerializeObject(obj); - SearchEventType eventType = SearchEventType.Message; - while (!cancellationToken.IsCancellationRequested) + var body = new StringContent(jsonBody, Encoding.UTF8, "application/json"); + var request = new HttpRequestMessage(HttpMethod.Post, requestUrl) { - var jsonChunk = await reader.ReadLineAsync(cancellationToken); + Content = body + }; + request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("text/event-stream")); + + using var httpResponse = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken); + using var streamReader = new StreamReader(await httpResponse.Content.ReadAsStreamAsync(cancellationToken)); + var eventType = SearchEventType.Message; + while (!streamReader.EndOfStream) + { + var jsonChunk = await streamReader.ReadLineAsync(cancellationToken); count += 1; // if (count >=5 ){ // - break; // + yield break; // }; // if (jsonChunk == null) continue; if (jsonChunk.StartsWith("event: ")) diff --git a/ShoppingAssistantWebClient.Web/Pages/Chat.razor.cs b/ShoppingAssistantWebClient.Web/Pages/Chat.razor.cs index 482ce17..b59a8c1 100644 --- a/ShoppingAssistantWebClient.Web/Pages/Chat.razor.cs +++ b/ShoppingAssistantWebClient.Web/Pages/Chat.razor.cs @@ -15,100 +15,107 @@ namespace ShoppingAssistantWebClient.Web.Pages; public partial class Chat : ComponentBase { - [Inject] - private ApiClient _apiClient { get; set; } - [Inject] - private NavigationManager Navigation { get; set; } - [Inject] - private SearchService _searchServise { get; set; } + [Inject] + private ApiClient _apiClient { get; set; } + [Inject] + private NavigationManager Navigation { get; set; } + [Inject] + private SearchService _searchServise { get; set; } - public List Messages { get; set; } + public List Messages { get; set; } - public List Products { get; set; } = new List(); + public List Products { get; set; } = new List(); - public List Suggestion { get; set; } = new List(); - - public Messages Message { get; set; } - public Messages MessageBot { get; set; } + public List Suggestion { get; set; } = new List(); - private CancellationTokenSource cancelTokenSource; - private bool isWaitingForResponse = false; - private MessageCreateDto messageCreateDto; - public bool isLoading = true; - private string name = ""; - protected override async Task OnInitializedAsync() + public Messages Message { get; set; } + public Messages MessageBot { get; set; } + + private CancellationTokenSource cancelTokenSource; + private bool isWaitingForResponse = false; + private MessageCreateDto messageCreateDto; + public bool isLoading = true; + private string name = ""; + protected override async Task OnInitializedAsync() + { + try { - try{ - var input = _searchServise.FirstMessage; + var input = _searchServise.FirstMessage; - if (input!=null){ + if (input != null) + { - await LoadMessages(); + await LoadMessages(); - await AddNewMessage(input); + await AddNewMessage(input); - string wishlistId = chatId; - var request = new GraphQLRequest - { - Query = @"mutation GenerateNameForPersonalWishlist($wishlistId: String!) { + string wishlistId = chatId; + var request = new GraphQLRequest + { + Query = @"mutation GenerateNameForPersonalWishlist($wishlistId: String!) { generateNameForPersonalWishlist(wishlistId: $wishlistId) { id name } }", - Variables = new - { - wishlistId + Variables = new + { + wishlistId - } - }; - - var response = await _apiClient.QueryAsync(request); - _searchServise.SetFirstMessage(null); - isLoading = false; - await UpdateSideMenu(wishlistId); - StateHasChanged(); - - }else{ - await LoadMessages(); } - }catch(Exception ex){ - Console.WriteLine($"Error OnInitializedAsync: {ex.Message}"); + }; + + var response = await _apiClient.QueryAsync(request); + _searchServise.SetFirstMessage(null); + isLoading = false; + await UpdateSideMenu(wishlistId); + StateHasChanged(); + } - + else + { + await LoadMessages(); + } + } + catch (Exception ex) + { + Console.WriteLine($"Error OnInitializedAsync: {ex.Message}"); } + } - private async Task LoadMessages() + + private async Task LoadMessages() + { + try { - try{ - string wishlistId = chatId; - - var request = new GraphQLRequest - { - Query = @"query PersonalWishlist( $wishlistId: String!) { + string wishlistId = chatId; + + var request = new GraphQLRequest + { + Query = @"query PersonalWishlist( $wishlistId: String!) { personalWishlist(wishlistId: $wishlistId) { name } }", - Variables = new - { - wishlistId, - } - }; + Variables = new + { + wishlistId, + } + }; var response = await _apiClient.QueryAsync(request); var responseData = response.Data; name = responseData.personalWishlist.name; - isLoading = true; - int pageNumber = 1; - request = new GraphQLRequest - { - Query = @"query MessagesPageFromPersonalWishlist($wishlistId: String!, $pageNumber: Int!, $pageSize: Int!) { + isLoading = true; + int pageNumber = 1; + request = new GraphQLRequest + { + Query = @"query MessagesPageFromPersonalWishlist($wishlistId: String!, $pageNumber: Int!, $pageSize: Int!) { messagesPageFromPersonalWishlist( wishlistId: $wishlistId, pageNumber: $pageNumber, pageSize: $pageSize) { items { @@ -120,113 +127,125 @@ public partial class Chat : ComponentBase } }", - Variables = new - { - wishlistId, - pageNumber, - pageSize = 200 - } - }; - - - - response = await _apiClient.QueryAsync(request); - responseData = response.Data; - var jsonCategoriesResponse = JsonConvert.SerializeObject(responseData.messagesPageFromPersonalWishlist.items); - this.Messages = JsonConvert.DeserializeObject>(jsonCategoriesResponse); - Messages.Reverse(); - isLoading = false; + Variables = new + { + wishlistId, + pageNumber, + pageSize = 200 + } + }; + + + + response = await _apiClient.QueryAsync(request); + responseData = response.Data; + var jsonCategoriesResponse = JsonConvert.SerializeObject(responseData.messagesPageFromPersonalWishlist.items); + this.Messages = JsonConvert.DeserializeObject>(jsonCategoriesResponse); + Messages.Reverse(); + isLoading = false; - }catch(Exception ex){ - Console.WriteLine($"Error : {ex.Message}"); - } } + catch (Exception ex) + { + Console.WriteLine($"Error : {ex.Message}"); + } + } private async Task AddNewMessage(string inputMessage) { - if (!isWaitingForResponse && !string.IsNullOrWhiteSpace(inputMessage)) + if (!isWaitingForResponse && !string.IsNullOrWhiteSpace(inputMessage)) { JSRuntime.InvokeVoidAsync("clearInput"); isWaitingForResponse = true; - try{ - messageCreateDto = new MessageCreateDto { Text = inputMessage };; - Message = new Messages(); - Message.Text = inputMessage; - Message.Role = "User"; - Message.Id = ""; - Message.CreatedById = ""; - - Suggestion = new List(); - Products = new List(); - Messages.Add(Message); - StateHasChanged(); - - cancelTokenSource = new CancellationTokenSource(); - var cancellationToken = cancelTokenSource.Token; - - var serverSentEvent = _apiClient.GetServerSentEventStreamed($"ProductsSearch/search/{chatId}", messageCreateDto, cancellationToken); - bool first = true; - - MessageBot = new Messages(); - MessageBot.Role = "bot"; - MessageBot.Id = ""; - MessageBot.CreatedById = ""; - MessageBot.Text = "Waiting for response"; - Messages.Add(MessageBot); - var lengt = Messages.Count(); - StateHasChanged(); - - await foreach (var sseEvent in serverSentEvent.WithCancellation(cancellationToken)) - { - Console.WriteLine($"Received SSE Event: {sseEvent.Event}, Data: {sseEvent.Data}"); - - string input = sseEvent.Data; - Regex regex = new Regex("\"(.*?)\""); - Match match = regex.Match(input); - string result = match.Groups[1].Value; - - if(sseEvent.Event == SearchEventType.Message){ - - - if (first) - { - Messages[lengt-1].Text = result; - first = false; - } - else - { - Messages[lengt-1].Text += result; - } + try + { + messageCreateDto = new MessageCreateDto { Text = inputMessage }; ; + Message = new Messages(); + Message.Text = inputMessage; + Message.Role = "User"; + Message.Id = ""; + Message.CreatedById = ""; + Suggestion = new List(); + Products = new List(); + Messages.Add(Message); StateHasChanged(); - - } else if(sseEvent.Event == SearchEventType.Product){ - - string pattern = "[\\\\\"]"; - input = Regex.Replace(input, pattern, ""); + cancelTokenSource = new CancellationTokenSource(); + var cancellationToken = cancelTokenSource.Token; - Products.Add(input); + var serverSentEvent = _apiClient.GetServerSentEventStreamed($"ProductsSearch/search/{chatId}", messageCreateDto, cancellationToken); + bool first = true; - } else if(sseEvent.Event == SearchEventType.Suggestion){ - if(Suggestion.Count<3){ - Suggestion.Add(result); + MessageBot = new Messages(); + MessageBot.Role = "bot"; + MessageBot.Id = ""; + MessageBot.CreatedById = ""; + MessageBot.Text = "Waiting for response"; + Messages.Add(MessageBot); + var lengt = Messages.Count(); + StateHasChanged(); + + await foreach (var sseEvent in serverSentEvent.WithCancellation(cancellationToken)) + { + Console.WriteLine($"Received SSE Event: {sseEvent.Event}, Data: {sseEvent.Data}"); + + string input = sseEvent.Data; + Regex regex = new Regex("\"(.*?)\""); + Match match = regex.Match(input); + string result = match.Groups[1].Value; + + if (sseEvent.Event == SearchEventType.Message) + { + if (first) + { + Messages[lengt - 1].Text = result; + first = false; + } + else + { + Messages[lengt - 1].Text += result; + } + + StateHasChanged(); + + } + else if (sseEvent.Event == SearchEventType.Product) + { + + string pattern = "[\\\\\"]"; + + input = Regex.Replace(input, pattern, ""); + + Products.Add(input); + + } + else if (sseEvent.Event == SearchEventType.Suggestion) + { + if (Suggestion.Count < 3) + { + Suggestion.Add(result); + StateHasChanged(); + } + } } - } - } - if(Products.Count!=0) { - string n = name; - _searchServise.SetProducts(Products); - Products = null; - var url = $"/cards/{name}/{chatId}"; - Navigation.NavigateTo(url); + if (Products.Count != 0) + { + string n = name; + _searchServise.SetProducts(Products); + Products = null; + var url = $"/cards/{name}/{chatId}"; + Navigation.NavigateTo(url); + } + isWaitingForResponse = false; + } - isWaitingForResponse = false; - } catch(Exception ex){ + catch (Exception ex) + { Console.WriteLine($"Error : {ex.Message}"); + } } } - } } From 6a373fb9d338c02053de64b787c298264ac8443b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=96=C2=96AsTroLog?= Date: Sun, 17 Dec 2023 20:40:56 +0000 Subject: [PATCH 9/9] SA-223 Add user settings --- .../Shared/NavMenu.razor | 3 +- .../Shared/NavMenu.razor.css | 14 ++++---- .../wwwroot/images/avatar.svg | 33 ++----------------- 3 files changed, 12 insertions(+), 38 deletions(-) diff --git a/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor b/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor index 963a337..e47d234 100644 --- a/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor +++ b/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor @@ -53,8 +53,7 @@
    Avatar user - - Unknown user + User Settings
    diff --git a/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor.css b/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor.css index 8cee536..f055940 100644 --- a/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor.css +++ b/ShoppingAssistantWebClient.Web/Shared/NavMenu.razor.css @@ -51,7 +51,6 @@ display: flex; align-items: center; border-radius: 0 0 0.6em 0.6em; - background-color: rgb(255, 255, 255); height: 3.6em; left: 0; bottom: 0; @@ -60,6 +59,9 @@ padding-right: 1.25em; border-top: 1px solid #0165FF; } +.info_user:hover{ + background-color: #e6e6e6; +} .logo_name { padding-top: 0.5em; @@ -216,17 +218,17 @@ } .user_name { - padding-left: 0.4375em; - font-size: 1em; + padding-left: 0.4em; + font-size: 1.2em; justify-content: center; align-items: center; } .info_user img { float: left; - border-radius: 50%; - width: 2.3em; - height: 2.3em; + width: 2.4em; + height: 2.4em; + margin-left: 3.3em; } diff --git a/ShoppingAssistantWebClient.Web/wwwroot/images/avatar.svg b/ShoppingAssistantWebClient.Web/wwwroot/images/avatar.svg index dd1e234..ca72e08 100644 --- a/ShoppingAssistantWebClient.Web/wwwroot/images/avatar.svg +++ b/ShoppingAssistantWebClient.Web/wwwroot/images/avatar.svg @@ -1,34 +1,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + +