From 07711a93b0aeb959b791650b37f97cc8e4b6d5c7 Mon Sep 17 00:00:00 2001 From: Andreev Gregory Date: Sun, 1 Sep 2024 01:29:32 +0300 Subject: [PATCH] Fixed some bugs in nytl, een9 ad chat, wrote a skeleton for list-rooms, chat pages, finished login, view-profile, edit-profile-pages. chat-members page still needs attention --- assets/HypertextPages/chat-members.nytl.html | 17 +- assets/HypertextPages/chat.nytl.html | 29 +- assets/HypertextPages/edit-profile.nytl.html | 82 ++++-- assets/HypertextPages/list-rooms.nytl.html | 95 +++---- assets/HypertextPages/login.nytl.html | 45 +-- assets/HypertextPages/view-profile.nytl.html | 37 ++- assets/css/chat.css | 72 +++++ assets/css/common-popup.css | 30 ++ assets/css/common.css | 193 +++++++++++++ assets/css/edit-profile.css | 23 ++ assets/css/list-rooms.css | 258 ++---------------- assets/css/login.css | 65 ++--- assets/css/profile.css | 129 --------- assets/css/registration.css | 77 ------ assets/js/chat.js | 227 +++++++++++++++ .../js/{chat-members.js => common-popup.js} | 0 assets/js/list-rooms.js | 218 ++++----------- .../http_structures/client_request_parse.cpp | 4 + .../new_york_transit_line/parser.cpp | 70 +++-- .../new_york_transit_line/rendering.cpp | 6 +- .../backend_logic/polling.cpp | 4 +- .../backend_logic/when_chat.cpp | 12 +- .../backend_logic/when_list_rooms.cpp | 1 + .../backend_logic/when_login.cpp | 6 +- .../backend_logic/when_user.cpp | 8 +- .../iu9_ca_web_chat_service/service.cpp | 3 +- 26 files changed, 881 insertions(+), 830 deletions(-) create mode 100644 assets/css/common-popup.css create mode 100644 assets/css/common.css create mode 100644 assets/css/edit-profile.css delete mode 100644 assets/css/profile.css delete mode 100644 assets/css/registration.css rename assets/js/{chat-members.js => common-popup.js} (100%) diff --git a/assets/HypertextPages/chat-members.nytl.html b/assets/HypertextPages/chat-members.nytl.html index 176acab..ed6aba7 100644 --- a/assets/HypertextPages/chat-members.nytl.html +++ b/assets/HypertextPages/chat-members.nytl.html @@ -5,25 +5,12 @@ Веб-Чат Members - {% PUT chat.pass pres userinfo openedchat initial_chatUpdResp %} -
-
-
- × -

Все участники

-
-
-
    - -
-
-
-
- +

Chat member list page for {% WRITE openedchat.nickname%}, not ready yet

+ {% ENDELDEF %} diff --git a/assets/HypertextPages/chat.nytl.html b/assets/HypertextPages/chat.nytl.html index 869e8e9..e362d55 100644 --- a/assets/HypertextPages/chat.nytl.html +++ b/assets/HypertextPages/chat.nytl.html @@ -9,17 +9,36 @@ {% ELDEF main JSON pres JSON userinfo JSON openedchat JSON initial_chatUpdResp %} - + - Веб-Чат + + Chat -{% PUT chat.pass pres userinfo openedchat initial_chatUpdResp %} - - + + +
+ +
+
+
+
+ +
{% ENDELDEF %} diff --git a/assets/HypertextPages/edit-profile.nytl.html b/assets/HypertextPages/edit-profile.nytl.html index 63cfe07..3a7b202 100644 --- a/assets/HypertextPages/edit-profile.nytl.html +++ b/assets/HypertextPages/edit-profile.nytl.html @@ -1,42 +1,68 @@ -{% ELDEF main JSON pres JSON userprofile JSON errors %} +{% ELDEF main JSON pres JSON userinfo JSON alienprofile JSON errors %} - - Профиль + + + + Edit user Profile -
+ +
+ + {% FOR error IN errors %} -
-

{% WRITE error.text %}

+
+ {% WRITE error.text %}
{% ENDFOR %} -
-

Редактирование профиля

+ +
+

{% WRITE alienprofile.name %}

+

Nickname: {% WRITE alienprofile.nickname %}

+

+ {% WRITE alienprofile.bio %} +

+
+ +
+

Change user attributes

+
+ + + + + + + + + +
+ + + +
+ + + +
+ +
+ + +
-
-
-
-

{% WRITE userprofile.name %} ( {% WRITE userprofile.nickname %} )

- - -
- - -
-
-
-
-

О себе

-

{% WRITE userprofile.bio %}


- - -
- -
+ {% ENDELDEF%} diff --git a/assets/HypertextPages/list-rooms.nytl.html b/assets/HypertextPages/list-rooms.nytl.html index ff71a87..7f2eec9 100644 --- a/assets/HypertextPages/list-rooms.nytl.html +++ b/assets/HypertextPages/list-rooms.nytl.html @@ -4,69 +4,48 @@ - Список Чат-Комнат + List of chat rooms + + - -
-

Выберите Чат-Комнату

-
    - -
- -
+ + + - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - +x +
+ + +
+ New chat +
+ +
+
+
+ {% ENDELDEF %} \ No newline at end of file diff --git a/assets/HypertextPages/login.nytl.html b/assets/HypertextPages/login.nytl.html index 4089ae1..bbc1372 100644 --- a/assets/HypertextPages/login.nytl.html +++ b/assets/HypertextPages/login.nytl.html @@ -1,29 +1,40 @@ {% ELDEF main JSON pres JSON userinfo JSON errors %} - + - {% WRITE pres.phr.decl.page-login %} + + Login Page - -{% FOR msg IN errors %} -
- {% WRITE msg.text %} + {% FOR error IN errors %} +
+ {% WRITE error.text %} +
+ {% ENDFOR %} + +
+

Login

+
+ + + + + + + + + +
+ +
+ +
+ +
-{% ENDFOR %} -
-

{% WRITE pres.phr.decl.enter %}

-
- -
- -
- -
-
diff --git a/assets/HypertextPages/view-profile.nytl.html b/assets/HypertextPages/view-profile.nytl.html index ccfc0db..f2a81ec 100644 --- a/assets/HypertextPages/view-profile.nytl.html +++ b/assets/HypertextPages/view-profile.nytl.html @@ -1,26 +1,35 @@ -{% ELDEF main JSON pres JSON userprofile %} +{% ELDEF main JSON pres JSON userinfo JSON alienprofile %} - - Профиль + + + + User Profile -
-
-

Профиль пользователя

+ +
+ -
-
-

{% WRITE userprofile.name %} ( {% WRITE userprofile.nickname %} )

-
-
-
-

О себе

-

{% WRITE userprofile.bio %}


+ +
+

{% WRITE alienprofile.name %}

+

Nickname: {% WRITE alienprofile.nickname %}

+

+ {% WRITE alienprofile.bio %} +

+ + {% ENDELDEF%} diff --git a/assets/css/chat.css b/assets/css/chat.css index e69de29..96b05f1 100644 --- a/assets/css/chat.css +++ b/assets/css/chat.css @@ -0,0 +1,72 @@ +body, html { + height: 100%; +} + +#navigation-info-panel { + align-items: center; +} + +#chat-widget { + position: relative; + flex: 1; + background-color: #f1f1f1; + color: black; + overflow: hidden; +} + +#chat-widget .message-box { + position: absolute; + right: 5px; + max-width: 300px; + border: 2px solid dimgrey; + padding: 5px; + background-color: white; + color: black; +} + +/* in #chat-widget .message-box */ +.message-box-top{ + /* You see, each message contains a 20+2+2 px high icon that HAS TO BE LOADED FIRST. + This happens after window.onload, so I added a crutch: loading won't update height in + unpredictable moment. cause it will be already high enough. BUGA-GA-GA!! */ + min-height: 30px; + display: block; +} + +.message-box-sender-name{ + font-weight: bold; + color: black; + text-decoration: none; + padding: 2px; + display: inline; +} + +.message-box-sender-name:hover{ + color: #1060ff +} + +.message-box-button{ + width: 20px; + padding: 2px; + cursor: pointer; +} + +.message-box-msg{ + word-wrap: break-word; +} + +#input-panel { + +} + +#input-panel #message-input{ + padding: 15px; + height: auto; + width: 100%; + display: inline-block; + background-color: white; + border: 1px solid #1000d0; + border-radius : 7px; + font-size: .9rem; + margin: 10px; +} diff --git a/assets/css/common-popup.css b/assets/css/common-popup.css new file mode 100644 index 0000000..c90e6ce --- /dev/null +++ b/assets/css/common-popup.css @@ -0,0 +1,30 @@ +#popup-overlay-veil { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + + z-index: 99; + display: none; /* Hidden by default */ +} + +.popup-window { + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background: white; + padding: 20px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); + + z-index: 100; + display: none; +} + +.popup-btn { + display: inline; + padding: 5px; + border-bottom: 3px; +} \ No newline at end of file diff --git a/assets/css/common.css b/assets/css/common.css new file mode 100644 index 0000000..465e239 --- /dev/null +++ b/assets/css/common.css @@ -0,0 +1,193 @@ +/* Profile view elements */ +.profile-container { + background: white; + border-radius: 5px; + padding: 20px; + margin-top: 60px; /* Space below the fixed panel */ + box-shadow: 0 10px 15px rgba(0, 0, 0, 0.3); +} + +.profile-name-text { + color: black; +} + +.profile-nickname-text{ + color: #444; + text-align: left; +} + +.profile-bio-text { + padding-top: 40px; + text-align: left; + line-height: 1.6; + color: black; +} + +/* Panels */ +.panel { + width: 100%; + border: 2px solid blue; + background-color: #54b3ff; + display: flex; + flex-direction: row; +} + +.panel-thing { + padding: 6px; +} + +.panel-header-txt{ + color: white; + font-size: 1.9em; + flex: 1; + text-align: center; +} + + +/* Containers for the whole document */ + +* { + margin: 0; + padding: 0; + box-sizing: border-box; + font-family: Arial, sans-serif; +} + +#document-container { + width: 80%; /* Full width of the viewport */ + margin: 0 auto; /* Center the container horizontally */ +} + +#fullscreen-container { + width: 80%; /* Full width of the viewport */ + height: 100vh; /* Full height of the viewport */ + display: flex; + flex-direction: column; /* Stack children vertically */ + margin: 0 auto; /* Center the container horizontally */ +} + +body { + background-color: #f000f0; + background-image: url("/assets/img/clavicle-transparent.png"), url("/assets/img/broken-clavicle.png"); + background-repeat: revert; + background-size: 10%, 25%; +} + +/* Notifications, returned from server and embedded into html page at render-time */ + +.server-notif-error-msg-box{ + font-size: 1.3em; + text-align: center; + padding: 10px; + border: 2px solid red; + border-radius: 30px; + background-color: #ff5050; + max-width: 40%; + margin: 15px auto; +} + +/* Centered headers */ + +.wide-centered-header { + width: 100%; + text-align: center; + font-size: 1.4em; +} +/* Cool buttons with text */ + +.action-button { + padding: 10px 15px; + background-color: #007bff; + color: white; + border: none; + border-radius: 5px; + cursor: pointer; + transition: background-color 0.3s; +} + + +.action-button:hover { + background-color: #0056b3; /* Darker blue on hover */ +} + +/* This is for centering non-100%wide block */ + +.centered-block-el { + display: block; + margin-left: auto; + margin-right: auto; +} + +/* Beautiful text input */ + +.one-line-input { + width: 100%; + padding: 8px; + margin: 8px 0; + border: 1px solid #ccc; + border-radius: 4px; +} + +.multiline-input { + width: 100%; + /*max-width: 600px;*/ + height: 200px; + padding: 10px; + font-size: 1.15em; + border: 2px solid #ccc; + border-radius: 5px; + box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1); /* Subtle shadow */ + outline: none; /* Remove default outline on focus */ + resize: vertical; /* Allow resizing vertically */ + transition: border-color 0.15s, box-shadow 0.15s; /* Smooth transition for border color and shadow */ +} + +.multiline-input:focus { + border-color: #007bff; /* Change border color on focus */ + box-shadow: 0 0 5px rgba(0, 123, 255, 0.5); /* Shadow on focus */ +} + +/* Handles the case of list of elements with dickanme, name, role and delete button + For list of chats and list of users in chat */ +.dynamic-block-list { + margin-top:12px; + display: flex; + flex-direction: column; + background-color: white; + border: 1px solid #c7c7c7; + align-items: stretch; + padding-left: 8px; + padding-right: 8px; + padding-bottom: 8px; +} + +.dynamic-block-list-el { + margin-top: 8px; + background-color: white; + border: 1px solid #c7c7c7; + color: black; + padding: 5px; +} + +.button-add{ + width: 50px; + cursor: pointer; +} + +.dynamic-block-list-el-container{ + width: 100%; +} + +.entity-nickname-txt { + font-weight: bold; + color: black; + text-decoration: none; + font-size: 1.5em; +} + +.entity-reg-field-txt { + /* For name and role */ + color: #242424; + text-decoration: none; + font-size: 1.5em; +} diff --git a/assets/css/edit-profile.css b/assets/css/edit-profile.css new file mode 100644 index 0000000..ae0932d --- /dev/null +++ b/assets/css/edit-profile.css @@ -0,0 +1,23 @@ +/* The morbid thing */ +table.logins-input-table { + width: 100%; + border-collapse: collapse; /* Combine borders */ +} +.logins-input-td1, .logins-input-td2 { + border: none; +} +.logins-input-td1 { + text-align: left; + padding-right: 5px; + white-space: nowrap; /* Prevent text wrap, keeping it in one line */ + overflow: hidden; /* Hide overflow content */ + text-overflow: ellipsis; /* Show ellipsis for overflowing text */ +} +.logins-input-td2 { + width: 100%; +} + +#input-change-bio{ + margin-top: 5px; + margin-bottom: 5px; +} diff --git a/assets/css/list-rooms.css b/assets/css/list-rooms.css index 0fa8ff2..78936a5 100644 --- a/assets/css/list-rooms.css +++ b/assets/css/list-rooms.css @@ -1,253 +1,35 @@ -body { - font-family: Arial, sans-serif; - background-color: #f0f0f0; - margin: 0; - padding: 0; +#navigation-panel { + align-items: center; } -.container { - max-width: 800px; - margin: 30px auto; - padding: 20px; - background-color: #007bff; - box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); - border-radius: 8px; +#CL-bacbe { + margin: 6px; } -h1 { - text-align: center; - color: #fff; -} - -.room-list { - list-style-type: none; - padding: 0; -} - -.room-item { +.CL-my-chat-box { display: flex; - justify-content: space-between; - align-items: center; - padding: 15px; - margin: 10px 0; - background-color: #fafafa; - border: 1px solid #ddd; - border-radius: 5px; - transition: background-color 0.3s ease; + flex-direction: row; } -.room-item:hover { - background-color: #eaeaea; +.CL-my-chat-box-nickname { + margin-left: 8px; + justify-self: flex-start; } -.room-name { - font-size: 18px; - color: #555; +.CL-my-chat-box-name { + margin-left: 14px; + justify-self: flex-start; } -.join-button { - padding: 10px 15px; - font-size: 16px; - color: white; - background-color: #007bff; - border: none; - border-radius: 5px; - cursor: pointer; - transition: background-color 0.3s ease; -} -.add-members-header { - text-align: center; -} -.add-members-footer { - text-align: right; - margin-top: 5px; -} -.add-members-button { - background-color: #218838; - padding: 10px 15px; - font-size: 16px; - color: white; - border: none; - border-radius: 5px; - position: absolute; - margin-left: 502px; - cursor: pointer; - transition: background-color 0.3s ease; -} -.add-members-button:hover { - background-color: #006509 -} -.delete-chat-button { - background-color: #dc2e45; - border: none; - color: white; - font-size: 16px; - border-radius: 5px; - position: absolute; - cursor: pointer; - transition: background-color 0.3s ease; - padding: 10px 15px; - margin-left: 380px; -} -.delete-chat-button:hover { - background-color: #881527; -} -#newMemberLogin { - width: 93.5%; - padding: 10px; - margin: 10px 0; - border: 1px solid #ddd; - border-radius: 5px; -} -.add-member-button { - background-color: #218838; - padding: 10px 15px; - font-size: 16px; - color: white; - border: none; - border-radius: 5px; - position: absolute; - margin-left: -105px; - cursor: pointer; - transition: background-color 0.3s ease; -} -.join-button:hover { - background-color: #0056b3; +.CL-my-chat-box-my-role { + margin-left: auto; + justify-self: flex-end; } -.modal { - display: none; - position: fixed; - z-index: 1; - left: 0; - top: 0; - width: 100%; - height: 100%; - overflow: auto; - background-color: rgba(0, 0, 0, 0.4); -} - -.modal-content { - background-color: #fff; - margin: 10% auto; - padding: 20px; - border: 1px solid #888; - width: 80%; - max-width: 400px; - border-radius: 10px; - box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); -} - -.modal-header, .modal-footer { - padding: 10px; - color: #333; -} - -.modal-header { - text-align: center; -} - -.modal-footer { - text-align: right; -} - -.modal input { - width: 93.5%; - padding: 10px; - margin: 10px 0; - border: 1px solid #ddd; - border-radius: 5px; -} - -.create-room-button { - display: block; - width: 100%; - padding: 10px; - font-size: 16px; - color: white; - background-color: #1609ab; - border: none; - border-radius: 5px; - cursor: pointer; - transition: background-color 0.3s ease; - margin-top: 20px; -} - -.create-room-button:hover { - background-color: #218838; -} - -.overlay { - display: none; - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - background-color: rgba(0, 0, 0, 0.5); - justify-content: center; - align-items: center; - z-index: 1000; -} - -.overlay .add-members { - background-color: white; - padding: 30px; - border-radius: 10px; - box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); - max-width: 400px; - width: 100%; - height: 18%; - position: fixed; -} -.overlay .delete-chat { - background-color: white; - padding: 30px; - border-radius: 10px; - box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); - max-width: 400px; - width: 100%; - height: 18%; - position: fixed; -} -.delete-close { - color: #aaa; - float: right; - font-size: 28px; - font-weight: bold; +.CL-my-chat-box-leave-btn { + margin-left: 10px; + margin-right: 8px; + justify-self: flex-end; + width: 16px; cursor: pointer; } -.delete-chat-header { - text-align: center; -} -.confirm { - background-color: #1609ab; - padding: 20px 70px; - font-size: 16px; - color: white; - border: none; - border-radius: 5px; - position: absolute; - margin-left: 20px; - cursor: pointer; - transition: background-color 0.3s ease; -} -.cancel { - background-color: #1609ab; - padding: 20px 70px; - font-size: 16px; - color: white; - border: none; - border-radius: 5px; - position: absolute; - margin-left: 220px; - cursor: pointer; - transition: background-color 0.3s ease; -} -.close { - color: #aaa; - float: right; - font-size: 28px; - font-weight: bold; - cursor: pointer; -} \ No newline at end of file diff --git a/assets/css/login.css b/assets/css/login.css index dd5f02d..1d35fbb 100644 --- a/assets/css/login.css +++ b/assets/css/login.css @@ -1,59 +1,34 @@ -/* I have no idea what is going on here */ body { - font-family: Arial, sans-serif; display: flex; + flex-direction: column; justify-content: center; align-items: center; - height: 100vh; + height: 100vh; /* Full viewport height */ margin: 0; - background-color: #e5e5e5; } .form-container { - width: 100%; - max-width: 400px; - background-color: white; - box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); - display: flex; - flex-direction: column; - border-radius: 8px; - padding: 40px; - text-align: center; + background-color: #ffffff; /* Brighter box color */ + padding: 20px; + border-radius: 10px; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); + width: 50%; /* Set width of the form */ } -h1 { - margin-bottom: 20px; - color: #2F4F4F; -} - -input { +/* The morbid thing */ +table.logins-input-table { width: 100%; - background: #f7f7f7; - font-size: 16px; - padding: 10px; - border: 1px solid #ddd; - border-radius: 20px; - margin-bottom: 15px; - outline: none; + border-collapse: collapse; /* Combine borders */ } - -button { - width: 100%; - padding: 15px; +.logins-input-td1, .logins-input-td2 { border: none; - background-color: #0088cc; - color: white; - border-radius: 20px; - cursor: pointer; - outline: none; - font-size: 16px; - font-weight: bold; - transition: background-color 0.3s; } - -.error-msg { - color: red; - background-color: #ffc0c0; - border-color: red; - border-radius: 5px; -} \ No newline at end of file +.logins-input-td1 { + padding-right: 5px; + white-space: nowrap; /* Prevent text wrap, keeping it in one line */ + overflow: hidden; /* Hide overflow content */ + text-overflow: ellipsis; /* Show ellipsis for overflowing text */ +} +.logins-input-td2 { + width: 100%; +} diff --git a/assets/css/profile.css b/assets/css/profile.css deleted file mode 100644 index c60dbf5..0000000 --- a/assets/css/profile.css +++ /dev/null @@ -1,129 +0,0 @@ -body { - display: flex; - justify-content: center; - align-items: center; - height: 90vh; - background-color: #e5e5e5; - font-family: Arial, sans-serif; -} -.main-container { - width: 700px; - height: 700px; - border-color: antiquewhite; - background-color: white; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - text-align: center; - border-radius: 10px; -} -.profile-header { - width: 700px; - height: 160px; - border-color: antiquewhite; - background-color: #0088cc; - border-radius: 10px; - position: relative; -} -.return { - background-color: #f0f0f0; - cursor: pointer; - width: 100px; - text-decoration: none; - color: black; - display: flex; - justify-content: center; - align-items: center; - height: 30px; - border-radius: 10px; - position: absolute; - left: 20px; - top: 25px; - border: none; -} -.return:hover{ - text-decoration: underline; - color: #0088cc; -} -form { - display: flex; - flex-direction: column; - align-items: center; -} - -.columns { - display: flex; - justify-content: center; - align-items: flex-start; - gap: 20px; - margin-bottom: 20px; -} - -.column { - display: flex; - flex-direction: column; - align-items: center; -} -.add { - width: 100px; - height: 40px; - border-width: 2px; - cursor: pointer; - font-size: 16px; - border-radius: 10px; -} -.add:hover { - background-color: #007bb5; -} -.image-button:hover { - opacity: 0.8; -} - -.image-button:active { - transform: scale(0.95); -} -#login { - font-family: Arial, sans-serif; - font-size:16px; - width: 150px; - height: 20px; - border-radius: 10px; - border-color: #2F4F4F; -} -#username { - font-family: Arial, sans-serif; - font-size:16px; - width: 150px; - height: 20px; - margin-bottom: 1px; - margin-top: 50px; - border-radius: 10px; - border-color: #2F4F4F; -} -#bio { - height: 150px; - width: 500px; - padding: 10px; - box-sizing: border-box; - font-family: Arial, sans-serif; - font-size:14px; - text-align: left; - vertical-align: top; - margin-bottom: 5px; -} -.save { - cursor:pointer; - font-size: 16px; - border-radius: 15px; - border-color: #2F4F4F; - height: 40px; - width: 150px; -} -.save:hover { - background-color: #007bb5; -} -.avatar { - border-radius: 50%; - object-fit: cover; -} \ No newline at end of file diff --git a/assets/css/registration.css b/assets/css/registration.css deleted file mode 100644 index b42c992..0000000 --- a/assets/css/registration.css +++ /dev/null @@ -1,77 +0,0 @@ -dy { - font-family: Arial, sans-serif; - display: flex; - justify-content: center; - align-items: center; - height: 100vh; - margin: 0; - background-color: #e5e5e5; -} - -.form-container { - width: 100%; - max-width: 400px; - background-color: white; - box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); - display: flex; - flex-direction: column; - border-radius: 8px; - padding: 40px; - text-align: center; -} - -h1 { - margin-bottom: 20px; - color: #2F4F4F; -} - -input { - width: 100%; - background: #f7f7f7; - font-size: 16px; - padding: 10px; - border: 1px solid #ddd; - border-radius: 20px; - margin-bottom: 15px; - outline: none; -} - -button { - width: 100%; - padding: 15px; - border: none; - background-color: #0088cc; - color: white; - border-radius: 20px; - cursor: pointer; - outline: none; - font-size: 16px; - font-weight: bold; - transition: background-color 0.3s; -} - -button:hover, -button:focus-visible { - background-color: #007bb5; -} - -.hide-cursor::placeholder { - color: #000; -} - -.hide-cursor { - caret-color: transparent; -} - -.no-select { - -webkit-user-select: none; /* Для Safari */ - -moz-user-select: none; /* Для Firefox */ - user-select: none; /* Для всех остальных браузеров */ -} - -div { - color: red; - font-size: 15px; - margin-top: 10px; - display: none; -} diff --git a/assets/js/chat.js b/assets/js/chat.js index e69de29..6ce80db 100644 --- a/assets/js/chat.js +++ b/assets/js/chat.js @@ -0,0 +1,227 @@ +// In real world, I would get this variables from server through nytl +let pres = {lang: ''} +let userinfo = {id: 2, nickname: 'pv', name: 'Pavlov Vladimir'}; +let openedchat = {id: 100, name: "Some chat", nickname: 'chat'}; +let initial_chatUpdResp = { + LocalHistoryId: 0, + lastMsgId: -1, + messages: [], + members: [ + {id: 1, name: 'grisha', nickname: 'gri', role: 'admin'}, + {id: 2, name: 'Pavlov Vladimir', nickname: 'pv', role: 'regular'}, + {id: 3, name: 'Ivan', nickname: 'ivan', role: 'read-only'} + ] +}; + +let loadedMessages = new Map(); // messageSt objects +let visibleMessages = new Map(); // HTMLElement objects + +let anchoredMsg = -1; +let visibleMsgSegStart = -1; +let visibleMsgSegEnd = -2; +let offsetOfAnchor = 100; + +// Would start with true if opened `/chat/<>` +let bumpedAtTheBottom = false; + +let members = new Map(); +for (let memberSt of initial_chatUpdResp.members){ + members.set(memberSt.id, memberSt); +} +// members.set(1, {id: 1, name: 'grisha', nickname: 'gri', role: 'admin'}); +// members.set(2, {id: 2, name: 'Pavlov Vladimir', nickname: 'pv', role: 'regular'}); +// members.set(3, {id: 3, name: 'Ivan', nickname: 'ivan', role: 'read-only'}); + +function updateOffsetOfVisibleMsg(msgId, offset){ + visibleMessages.get(msgId).style.bottom = String(offset) + "px"; +} + +function updateOffsetsUpToTop(){ + let offset = offsetOfAnchor; + for (let curMsg = anchoredMsg; curMsg >= visibleMsgSegStart; curMsg--){ + updateOffsetOfVisibleMsg(curMsg, offset); + let height = visibleMessages.get(curMsg).offsetHeight; + offset += height + 5; + } + return offset; +} + +function updateOffsetsDown(){ + let offset = offsetOfAnchor; + for (let curMsg = anchoredMsg + 1; curMsg <= visibleMsgSegEnd; curMsg++){ + let height = visibleMessages.get(curMsg).offsetHeight; + offset -= (height + 5); + updateOffsetOfVisibleMsg(curMsg, offset); + } + return offset; +} + +function updateOffsetsSane(){ + let highest_point = updateOffsetsUpToTop(); + let lowest_point = updateOffsetsDown(); + return [highest_point, lowest_point]; +} + +function updateOffsets(){ + if (anchoredMsg < 0) + return; + let [highest_point, lowest_point] = updateOffsetsSane(); + let winTop = document.getElementById("chat-widget").offsetHeight; + if (lowest_point > 5 || (highest_point - lowest_point) <= winTop){ + bumpedAtTheBottom = true; + anchoredMsg = visibleMsgSegEnd; + offsetOfAnchor = 5; + updateOffsetsSane(); + } else if (highest_point < winTop - 5){ + console.log("Adancing by " + (winTop - 5 - highest_point)) + offsetOfAnchor += (winTop - 5 - highest_point); + updateOffsetsSane(); + } +} + +function makeMessageBox(messageSt){ + if (!messageSt.exists || messageSt.isSystem) + throw new Error("Not ready for this"); + const parentDiv = document.getElementById("chat-widget"); + let box = document.createElement("div"); + parentDiv.appendChild(box); + box.className = "message-box"; + + let topPart = document.createElement("div"); + box.appendChild(topPart); + topPart.className = "message-box-top"; + + let inTopPartSenderName = document.createElement("a"); + topPart.appendChild(inTopPartSenderName); + inTopPartSenderName.className = "message-box-sender-name"; + if (!members.has(messageSt.senderUserId)) + throw new Error("MMMHMMMMGMHMMMM. First - update members. Then messages"); + let memberSt = members.get(messageSt.senderUserId); + inTopPartSenderName.innerText = memberSt.name + " (" + memberSt.nickname + ")"; + inTopPartSenderName.href = "/user/" + memberSt.nickname; + + let ID = messageSt.id; + + let inTopPartButtonDelete = document.createElement("img"); + topPart.appendChild(inTopPartButtonDelete); + inTopPartButtonDelete.className = "message-box-button"; + inTopPartButtonDelete.src = "/assets/img/delete.svg"; + inTopPartButtonDelete.onclick = (ev) => { + if (ev.button === 0){ + console.log("Tried to delete message " + ID); + } + }; + + let inTopPartButtonGetLink = document.createElement("img"); + topPart.appendChild(inTopPartButtonGetLink); + inTopPartButtonGetLink.className = "message-box-button"; + inTopPartButtonGetLink.src = "/assets/img/link.svg"; + inTopPartButtonGetLink.onclick = (ev) => { + if (ev.button === 0){ + console.log("Tried to get link on message " + ID); + } + }; + + + let msgPart = document.createElement("p"); + box.appendChild(msgPart); + msgPart.className = "message-box-msg"; + msgPart.innerText = messageSt.text; + return box; +} + +function makeVisible(msgId){ + visibleMessages.set(msgId, makeMessageBox(loadedMessages.get(msgId))) +} + +function opaNewMessage(messageSt){ + let msgId = messageSt.id; + let text = messageSt.text; + const chatWin = document.getElementById("chat-widget"); + if (loadedMessages.has(msgId)){ + throw new Error("Not ready yet"); + // loadedMessages.get(msgId).text = text; + // if (visibleMessages.has(msgId)){ + // visibleMessages.get(msgId).textContent = text; + // updateOffsets(); + // } + } else { + loadedMessages.set(msgId, messageSt); + if (anchoredMsg < 0){ + anchoredMsg = msgId; + visibleMsgSegStart = msgId; + visibleMsgSegEnd = msgId; + makeVisible(msgId); + updateOffsets(); + } else if (msgId + 1 === visibleMsgSegStart) { + visibleMsgSegStart--; + makeVisible(msgId); + while (loadedMessages.has(visibleMsgSegStart - 1)){ + visibleMsgSegStart--; + makeVisible(visibleMsgSegStart); + } + updateOffsets(); + } else if (msgId - 1 === visibleMsgSegEnd){ + visibleMsgSegEnd++; + makeVisible(msgId); + while (loadedMessages.has(visibleMsgSegEnd + 1)){ + visibleMsgSegEnd++; + makeVisible(visibleMsgSegEnd); + } + updateOffsets(); + } + } +} + +function test(id, uid){ + opaNewMessage({ + id: id, text: "Message number " + String(id), senderUserId: uid, exists: true, isSystem: false} + ); +} + +let mainloopTimeout = null; + +let mainloopPoller = null; + +function setMainloopTimeout(){ + mainloopTimeout = setTimeout(mainloopPoller, 1000); +} + +mainloopPoller = function(){ + try { + console.log("Hello, World!"); + } catch (error){} + setMainloopTimeout(); +} + + +window.onload = function (){ + console.log("Everything was loaded"); + test(6, 1); + test(1, 2); + test(3, 3); + test(2, 1); + test(4, 2); + test(0, 3); + test(5, 2); + test(8, 1); + test(9, 2); + test(7, 3); + for (let i = 10; i < 30; i++){ + test(i, 2); + } + document.body.addEventListener("wheel", (event) => { + event.preventDefault(); + bumpedAtTheBottom = false; + console.log("Scroll of " + String(event.deltaY)); + offsetOfAnchor += event.deltaY / 5; + updateOffsets(); + }); + mainloopPoller(); + document.getElementById("message-input").addEventListener("keyup", (event) => { + if (event.ctrlKey && event.key === 'Enter'){ + let textarea = document.getElementById("message-input"); + console.log(textarea.value); + } + }); +} diff --git a/assets/js/chat-members.js b/assets/js/common-popup.js similarity index 100% rename from assets/js/chat-members.js rename to assets/js/common-popup.js diff --git a/assets/js/list-rooms.js b/assets/js/list-rooms.js index bf2b8c0..599450d 100644 --- a/assets/js/list-rooms.js +++ b/assets/js/list-rooms.js @@ -1,186 +1,72 @@ -let rooms = {}; -let roomToDelete = null; -let currentRoom = null; -let currentHistoryId = 0; +let LocalHistoryId = 0; -function openRoom(currentRoom) { - alert('Вы вошли в комнату: ' + currentRoom); -} +let myChats = new Map(); +let chatBoxes = new Map(); -function closeAdd() { - document.getElementById('add_members').style.display = 'none'; -} +const roleDeleted = "not-a-member"; -function openAdd() { - document.getElementById('add_members').style.display = 'flex'; -} +function convertStToBox(myMembershipSt){ + let chatURI = "/user/" + myMembershipSt.chatNickname; -function openConfirm(roomNickname) { - roomToDelete = roomNickname; - document.getElementById("delete-chat").style.display = "flex"; -} + let box = document.createElement("div"); + chatBoxes.set(myMembershipSt.chatId, box); + box.className = "dynamic-block-list-el CL-my-chat-box"; -function closeConfirm() { - roomToDelete = null; - document.getElementById("delete-chat").style.display = "none"; -} + let inBoxNickname = document.createElement("a"); + box.appendChild(inBoxNickname); + inBoxNickname.className = "entity-nickname-txt CL-my-chat-box-nickname"; + console.log(myMembershipSt); + console.log(myMembershipSt.chatNickname); + inBoxNickname.innerText = myMembershipSt.chatNickname; + inBoxNickname.href = chatURI; -function deleteChat() { - if (roomToDelete && rooms[roomToDelete]) { - delete rooms[roomToDelete]; - removeRoomFromList(roomToDelete); - closeConfirm(); - } else { - alert("Не удалось найти выбранную комнату."); - } -} + let inBoxName = document.createElement("a"); + box.appendChild(inBoxName); + inBoxName.className = "entity-reg-field-txt CL-my-chat-box-name"; + inBoxName.innerText = myMembershipSt.chatName; + inBoxName.href = chatURI; -function addMember() { - const login = document.getElementById('newMemberLogin').value; - if (login) { - alert(`Участник с никнеймом '${login}' добавлен`); - closeAdd(); - } else { - alert('Пожалуйста, введите логин участника'); - } -} + let inBoxMyRoleHere = document.createElement("p"); + box.appendChild(inBoxMyRoleHere); + inBoxMyRoleHere.className = "entity-reg-field-txt CL-my-chat-box-my-role"; + inBoxMyRoleHere.innerText = "You are " + myMembershipSt.myRoleHere + " here"; -function openCreateRoomModal() { - document.getElementById('createRoomModal').style.display = 'block'; -} + let ID = myMembershipSt.chatId; -function closeCreateRoomModal() { - document.getElementById('createRoomModal').style.display = 'none'; -} - -async function createRoom() { - const errorElement = document.getElementById('error'); - const roomName = document.getElementById('newRoomName').value.trim(); - const roomNickname = document.getElementById('newRoomNickname').value.trim(); - - - errorElement.style.display = 'none'; - errorElement.textContent = ''; - - if (roomName === '' || roomNickname === '') { - errorElement.textContent = 'Пожалуйста, заполните все поля'; - errorElement.style.display = 'block'; - return; - } - - const request = { - LocalHistoryId: currentHistoryId, - content: { - name: roomName, - nickname: roomNickname + let inBoxLeaveBtn = document.createElement("img"); + box.appendChild(inBoxLeaveBtn); + inBoxLeaveBtn.className = "CL-my-chat-box-leave-btn"; + inBoxLeaveBtn.src = "/assets/img/delete.svg"; + inBoxLeaveBtn.onclick = function (ev) { + if (ev.button === 0){ + console.log("Tried to leave chat" + ID); } }; - try { - const response = await fetch('/internalapi/createChat', { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify(request) - }); - - const res = await response.json(); - - if (res.status === 0) { - addRoomToList(roomName, roomNickname); - rooms[roomNickname] = true; - closeCreateRoomModal(); - currentHistoryId = res.update.LocalHistoryId; - window.location.href = '/chat/' + roomNickname; - } else { - throw new Error(res.error || 'Ошибка'); - } - } catch (error) { - alert('Ошибка создания чата: ' + error.message); - } + return box; } -function addRoomToList(roomName) { - const roomList = document.querySelector('.room-list'); - const existingRoomItem = Array.from(roomList.children).find(item => item.querySelector('.room-name').textContent === roomName); - if (existingRoomItem) { - existingRoomItem.remove(); - } +window.onload = function () { + console.log("Loading complete"); + LocalHistoryId = initial_chatListUpdResp.HistoryId; - const roomItem = document.createElement('li'); - roomItem.classList.add('room-item'); + console.log(initial_chatListUpdResp); - roomItem.innerHTML = ` - ${roomName} - - - - `; + let literalChatList = document.getElementById("CL-dblec"); - roomList.appendChild(roomItem); -} - -function removeRoomFromList(roomName, roomNickname) { - const roomList = document.querySelector('.room-list'); - const roomItem = Array.from(roomList.children).find(item => item.querySelector('.room-name').textContent === roomName); - if (roomItem) { - roomList.removeChild(roomItem); - } -} - -async function initializeRoomList() { - try { - const response = await fetch('/internalapi/getChatList', { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify({}) - }); - - const res = await response.json(); - - if (res.status === 0) { - res.chats.forEach(chat => { - addRoomToList(chat.content.name, chat.content.nickname); - }); - } else { - throw new Error(res.error || 'Неизвестная ошибка'); - } - } catch (error) { - alert('Ошибка загрузки списка чатов: ' + error.message); - } -} - - -async function getChatID() { - const chatNickname = window.location.pathname.split('/').pop(); - const response = await fetch('/internalapi/getChatList', { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify({}) - }); - - const res = await response.json(); - for (const chat of res.chats) { - if (chat.content.nickname === chatNickname) { - return chat.id; + for (let myMembershipSt of initial_chatListUpdResp.myChats){ + console.log(myMembershipSt); + if (myMembershipSt.myRoleHere !== roleDeleted){ + myChats.set(myMembershipSt.chatId, myMembershipSt); + let box = convertStToBox(myMembershipSt) + chatBoxes.set(myMembershipSt.chatId, box); + literalChatList.appendChild(box); } } - return -1; -} -window.onclick = function(event) { - if (event.target === document.getElementById('createRoomModal')) { - closeCreateRoomModal(); - } -} -document.getElementById('newRoomName').addEventListener('keydown', function(event) { - if (event.key === 'Enter') { - createRoom(); - } -}); -document.addEventListener('DOMContentLoaded', initializeRoomList); \ No newline at end of file + document.getElementById("CL-bacbe").onclick = function (ev){ + if (ev.button === 0){ + + } + }; +}; diff --git a/src/http_server/engine_engine_number_9/http_structures/client_request_parse.cpp b/src/http_server/engine_engine_number_9/http_structures/client_request_parse.cpp index fb2f5e6..bfae1dd 100644 --- a/src/http_server/engine_engine_number_9/http_structures/client_request_parse.cpp +++ b/src/http_server/engine_engine_number_9/http_structures/client_request_parse.cpp @@ -112,6 +112,10 @@ namespace een9 { return status; } res.body.reserve(std::min(100000ul, body_size)); + if (body_size == 0) { + status = 1; + } + break; } } if (!res.has_body) { diff --git a/src/http_server/new_york_transit_line/parser.cpp b/src/http_server/new_york_transit_line/parser.cpp index 808bd26..c87335a 100644 --- a/src/http_server/new_york_transit_line/parser.cpp +++ b/src/http_server/new_york_transit_line/parser.cpp @@ -55,13 +55,16 @@ namespace nytl { } char skip(ParsingContext& ctx) { - ASSERT(ctx.pos < ctx.text.size(), "Unexpected EOF"); + if (ctx.pos >= ctx.text.size()) + THROW("Unexpected EOF"); return advance(ctx); } void skip(ParsingContext& ctx, char ch) { - ASSERT(ctx.pos < ctx.text.size(), "Unexpected EOF"); - ASSERT(ctx.text[ctx.pos] == ch, "Unexpected character"); + if (ctx.pos >= ctx.text.size()) + THROW("Unexpected EOF"); + if (ctx.text[ctx.pos] != ch) + THROW("Unexpected character"); advance(ctx); } @@ -150,7 +153,8 @@ namespace nytl { void parse_bare_file(const std::string& filename, const std::string& content, global_elem_set_t& result) { - ASSERT(result.count(filename) == 0, "Repeated element " + filename); + if (result.count(filename) != 0) + THROW("Repeated element " + filename); std::string txt = clement_lstrip(content); rstrip(txt); size_t cut = 9999999999999; @@ -170,13 +174,15 @@ namespace nytl { uptr toMe(bool returned, ParsingContext& ctx) { if (!returned) { std::string nm = readName(ctx); - ASSERT(!nm.empty(), "Type specification expected"); + if (nm.empty()) + THROW("Type specification expected"); nm = make_uppercase(nm); if (nm == "JSON") { result = json::JSON(true); return NULL; } - ASSERT(nm == "EL", "Type of argument variable is either JSON or EL(...signature)") + if (nm != "EL") + THROW("Type of argument variable is either JSON or EL(...signature)"); skip(ctx, '('); result.asArray(); assert(result.isArray()); @@ -217,8 +223,10 @@ namespace nytl { uptr toMe(bool returned, ParsingContext& ctx, const arg_name_list_t& local_var_names) { if (!returned) { std::string first = readName(ctx); - ASSERT(!first.empty(), "Expression should start with 'root' name of global package or local variable"); - ASSERT(first != "_", "_ ??? ARE YOU KIDDING???"); + if (first.empty()) + THROW("Expression should start with 'root' name of global package or local variable"); + if (first == "_") + THROW("Expression root can't be _"); if (local_var_names.count(first) == 1) { result["V"].asInteger() = json::Integer((int64_t)local_var_names.at(first)); } else { @@ -243,7 +251,8 @@ namespace nytl { t = readUint(ctx); if (!t.empty()) { size_t v = std::stoul(t); - ASSERT(v < INT64_MAX, "Index is too big"); + if (v >= INT64_MAX) + THROW("Index is too big"); chain.back() = json::JSON((int64_t)v); continue; } @@ -352,7 +361,8 @@ namespace nytl { ElementPart::when_for_put_S& P = result.parts.back().when_for_put; skipWhitespace(ctx); std::string V1 = readName(ctx); - ASSERT(!V1.empty(), "Expected variable name"); + if (V1.empty()) + THROW("Expected variable name"); skipWhitespace(ctx); bool have_colon_and_2 = false; std::string V2; @@ -364,7 +374,8 @@ namespace nytl { skipWhitespace(ctx); } op = make_uppercase(readName(ctx)); - ASSERT(op == "IN", "Expected IN"); + if (op != "IN") + THROW("Expected IN"); skipWhitespace(ctx); P.ref_over = parse_expression(ctx, local_var_names); P.internal_element = el_name + ".~" + std::to_string(free_hidden++); @@ -372,13 +383,15 @@ namespace nytl { newborn.is_hidden = true; arg_name_list_t local_var_names_of_nxt = local_var_names; if (V1 != "_") { - ASSERT(local_var_names_of_nxt.count(V1) == 0, "Repeated local variable"); + if (local_var_names_of_nxt.count(V1) != 0) + THROW("Repeated local variable"); size_t k = local_var_names_of_nxt.size(); local_var_names_of_nxt.emplace(V1, k); (have_colon_and_2 ? P.where_key_var : P.where_value_var) = (ssize_t)k; } if (have_colon_and_2 && V2 != "_") { - ASSERT(local_var_names_of_nxt.count(V2) == 0, "Repeated local variable"); + if (local_var_names_of_nxt.count(V2) != 0) + THROW("Repeated local variable"); size_t k = local_var_names_of_nxt.size(); local_var_names_of_nxt.emplace(V2, k); P.where_value_var = (ssize_t)k; @@ -395,11 +408,12 @@ namespace nytl { ElementPart::when_ref_put_S& P = result.parts.back().when_ref_put; skipWhitespace(ctx); std::string Vn = readName(ctx); - ASSERT(!Vn.empty(), "Expected variable name"); - ASSERT(Vn != "_", "Are you kidding???"); + if (Vn.empty() || Vn == "_") + THROW("REF: expected variable name"); skipWhitespace(ctx); op = make_uppercase(readName(ctx)); - ASSERT(op == "AS", "Expected AS"); + if (op != "AS") + THROW("Expected AS"); skipWhitespace(ctx); P.ref_over = parse_expression(ctx, local_var_names); P.internal_element = el_name + ".~" + std::to_string(free_hidden++); @@ -467,13 +481,15 @@ namespace nytl { } }; if (op == "ENDELDEF") { - ASSERT(myself == gone_for_nothing, "Unexpected end of element"); + if (myself != gone_for_nothing) + THROW("Unexpected ENDELDEF"); skip_magic_block_end(ctx, syntax); prepare_to_depart_parts(); return NULL; } if (op == "ENDFOR") { - ASSERT(myself == gone_for_for, "Unexpected end of for cycle"); + if (myself != gone_for_for) + THROW("Unexpected ENDFOR"); skipWhitespace(ctx); /* Here I am using ret_data_int to return info about NOLF(1)/LF(2) decision */ ret_data_int = 2; // Default is to do LF @@ -491,7 +507,8 @@ namespace nytl { return NULL; } if (op == "ENDREF") { - assert(myself == gone_for_ref); + if (myself != gone_for_ref) + THROW("Unexpected ENDREF"); skip_magic_block_end(ctx, syntax); prepare_to_depart_parts(); return NULL; @@ -525,12 +542,15 @@ namespace nytl { if (peep(ctx) == EOFVAL) break; skip_magic_block_start(ctx, syntax); - ASSERT(make_uppercase(readName(ctx)) == "ELDEF", "Expected ELDEF"); + if (make_uppercase(readName(ctx)) != "ELDEF") + THROW("Expected ELDEF"); skipWhitespace(ctx); std::string elname_postfix = readName(ctx); - ASSERT(elname_postfix != "_", "please don't"); + if (elname_postfix == "_") + THROW("Can't use _ as element name"); std::string fullname = elname_postfix == "main" ? filename : filename + "." + elname_postfix; - ASSERT(result.count(fullname) == 0, "Element " + fullname + " has been already defined"); + if (result.count(fullname) != 0) + THROW("Element " + fullname + " has been already defined"); Element& newborn = result[fullname]; arg_name_list_t arglist; while (true) { @@ -540,9 +560,11 @@ namespace nytl { newborn.arguments.push_back(parse_type(ctx)); skipWhitespace(ctx); std::string argname = readName(ctx); - ASSERT(!argname.empty(), "Expected argument name"); + if (argname.empty()) + THROW("Expected argument name"); if (argname != "_") { - ASSERT(arglist.count(argname) == 0, "Repeated argument (" + argname + ")"); + if (arglist.count(argname) != 0) + THROW("Repeated argument (" + argname + ")"); size_t k = arglist.size(); arglist[argname] = k; } diff --git a/src/http_server/new_york_transit_line/rendering.cpp b/src/http_server/new_york_transit_line/rendering.cpp index bbbf1c7..c6583a9 100644 --- a/src/http_server/new_york_transit_line/rendering.cpp +++ b/src/http_server/new_york_transit_line/rendering.cpp @@ -212,7 +212,7 @@ namespace nytl { const std::function &escape) { if (!returned) if (elem_ns.count(name) != 1) - THROW("No such element"); + THROW("No such element (" + name + ")"); const Element& el = elem_ns.at(name); if (!returned) { /* Continue to do checks */ @@ -227,7 +227,9 @@ namespace nytl { // If not json is expected, element must be expected assert(el.arguments[i].isArray()); ASSERT(!passed_args[i].is_json, "Expected element element arguemnt, got json"); - ASSERT(elem_ns.count(passed_args[i].EL_name), "No such element, can't compare signatures of argument value"); + const std::string& passed_el_as_arg = passed_args[i].EL_name; + if (elem_ns.count(passed_el_as_arg) != 1) + THROW("No such element, can't compare signatures of argument value (" + passed_el_as_arg + ")"); const Element& arg_element = elem_ns.at(passed_args[i].EL_name); // ASSERT(passed_args); if(el.arguments[i].asArray() != arg_element.arguments) diff --git a/src/web_chat/iu9_ca_web_chat_lib/backend_logic/polling.cpp b/src/web_chat/iu9_ca_web_chat_lib/backend_logic/polling.cpp index 83902ff..ade7044 100644 --- a/src/web_chat/iu9_ca_web_chat_lib/backend_logic/polling.cpp +++ b/src/web_chat/iu9_ca_web_chat_lib/backend_logic/polling.cpp @@ -8,7 +8,7 @@ namespace iu9cawebchat { SqliteStatement my_membership_changes(conn, "SELECT `chatId`, `role` FROM `user_chat_membership` WHERE `userId` = ?1 " "AND `user_chatList_IncHistoryId` > ?2", {{1, userId}, {2, LocalHistoryId}}); - json::jarr myChats = chatListUpdResp["myChats"].asArray(); + json::jarr& myChats = chatListUpdResp["myChats"].asArray(); while (true) { fsql_integer_or_null ev_chatId, usersRoleHere; int status = sqlite_stmt_step(my_membership_changes, {{0, &ev_chatId}, {1, &usersRoleHere}}, {}); @@ -73,7 +73,7 @@ namespace iu9cawebchat { json::jarr members; SqliteStatement membership_changes(conn, - "SELECT `userId`, `role`, FROM `user_chat_membership` WHERE `chatId` = ?1 " + "SELECT `userId`, `role` FROM `user_chat_membership` WHERE `chatId` = ?1 " "AND `chat_IncHistoryId` > ?2", {{1, chatId}, {2, LocalHistoryId}}, {}); while (true) { fsql_integer_or_null alienUserId; diff --git a/src/web_chat/iu9_ca_web_chat_lib/backend_logic/when_chat.cpp b/src/web_chat/iu9_ca_web_chat_lib/backend_logic/when_chat.cpp index 7063865..d8aec4b 100644 --- a/src/web_chat/iu9_ca_web_chat_lib/backend_logic/when_chat.cpp +++ b/src/web_chat/iu9_ca_web_chat_lib/backend_logic/when_chat.cpp @@ -7,8 +7,10 @@ namespace iu9cawebchat { std::string when_page_chat(WorkerGuestData& wgd, const json::JSON& config_presentation, const een9::ClientRequest& req, const json::JSON& userinfo) { - std::vector path_segs = {""}; + std::vector path_segs = {}; path_segs.reserve(4); + if (req.uri_path.empty() || req.uri_path[0] != '/') + return page_E404(wgd); for (char ch: req.uri_path) { if (ch == '/') path_segs.emplace_back(); @@ -31,16 +33,18 @@ namespace iu9cawebchat { return page_E404(wgd); } else return page_E404(wgd); - bool chat_members = (path_segs[0] == "chat-members"); + if (userinfo.isNull()) + return een9::form_http_server_response_303("/"); + RowChat_Content chatInfo; try { chatInfo = lookup_chat_content_by_nickname(*wgd.db, chat_nickname); } catch (const std::exception& e) { return page_E404(wgd); } - if (get_role_of_user_in_chat(*wgd.db, userinfo["id"].asInteger().get_int(), chatInfo.id) == user_chat_role_deleted) { + if (get_role_of_user_in_chat(*wgd.db, userinfo["uid"].asInteger().get_int(), chatInfo.id) == user_chat_role_deleted) { return page_E404(wgd); } @@ -52,7 +56,7 @@ namespace iu9cawebchat { openedchat["selectedMessageId"].asInteger() = json::Integer(selected_message_id); json::JSON initial_chatUpdResp = poll_update_chat_ONE_MSG_resp(*wgd.db, chatInfo.id, selected_message_id); if (chat_members) - return http_R200("chat", wgd, {&config_presentation, &userinfo, &openedchat, &initial_chatUpdResp}); + return http_R200("chat-members", wgd, {&config_presentation, &userinfo, &openedchat, &initial_chatUpdResp}); return http_R200("chat", wgd, {&config_presentation, &userinfo, &openedchat, &initial_chatUpdResp}); } } diff --git a/src/web_chat/iu9_ca_web_chat_lib/backend_logic/when_list_rooms.cpp b/src/web_chat/iu9_ca_web_chat_lib/backend_logic/when_list_rooms.cpp index 27b44ed..39898ab 100644 --- a/src/web_chat/iu9_ca_web_chat_lib/backend_logic/when_list_rooms.cpp +++ b/src/web_chat/iu9_ca_web_chat_lib/backend_logic/when_list_rooms.cpp @@ -8,6 +8,7 @@ namespace iu9cawebchat { } json::JSON initial_chatListUpdResp = poll_update_chat_list_resp(*wgd.db, userinfo["uid"].asInteger().get_int(), 0); + printf("%s\n", json::generate_str(initial_chatListUpdResp, json::print_pretty).c_str()); return http_R200("list-rooms", wgd, {&config_presentation, &userinfo, &initial_chatListUpdResp}); } } diff --git a/src/web_chat/iu9_ca_web_chat_lib/backend_logic/when_login.cpp b/src/web_chat/iu9_ca_web_chat_lib/backend_logic/when_login.cpp index ba792f0..3b0749d 100644 --- a/src/web_chat/iu9_ca_web_chat_lib/backend_logic/when_login.cpp +++ b/src/web_chat/iu9_ca_web_chat_lib/backend_logic/when_login.cpp @@ -18,8 +18,10 @@ namespace iu9cawebchat { if (cmp.first == "password") password = cmp.second; } - een9_ASSERT(check_nickname(nickname), "/login/accpet-data rejected impossible nickname"); - een9_ASSERT(check_password(password), "/login/accpet-data rejected impossible password"); + if (!check_nickname(nickname)) + een9_THROW("/login/accpet-data rejected impossible nickname"); + if (!check_password(password)) + een9_THROW("/login/accpet-data rejected impossible password"); uid = find_user_by_credentials(*wgd.db, nickname, password); } catch(const std::exception& e){} diff --git a/src/web_chat/iu9_ca_web_chat_lib/backend_logic/when_user.cpp b/src/web_chat/iu9_ca_web_chat_lib/backend_logic/when_user.cpp index 96e54e0..c659b63 100644 --- a/src/web_chat/iu9_ca_web_chat_lib/backend_logic/when_user.cpp +++ b/src/web_chat/iu9_ca_web_chat_lib/backend_logic/when_user.cpp @@ -39,6 +39,8 @@ namespace iu9cawebchat { std::string when_page_user(WorkerGuestData& wgd, const json::JSON& config_presentation, const een9::ClientRequest& req, const std::vector& login_cookies, const json::JSON& userinfo) { + if (userinfo.isNull()) + return een9::form_http_server_response_303("/"); SqliteConnection& conn = *wgd.db; if (!is_page_of_certain_user(req.uri_path)) return page_E404(wgd); @@ -104,7 +106,7 @@ namespace iu9cawebchat { json::JSON msg_list = jsonify_html_message_list({{"", config_presentation["phr"]["decl"]["incorrect-profile-data"].asString()}}); json::JSON alien_userprofile = user_row_to_userprofile_obj(conn, alien); - return http_R200("edit-profile", wgd, {&config_presentation, &alien_userprofile, &msg_list}); + return http_R200("edit-profile", wgd, {&config_presentation, &userinfo, &alien_userprofile, &msg_list}); } return een9::form_http_server_response_303_spec_head("/user/" + alien_nickname, response_hlines); } @@ -112,9 +114,9 @@ namespace iu9cawebchat { json::JSON alien_userprofile = user_row_to_userprofile_obj(conn, alien); if (can_edit) { json::JSON empty_msg_list = jsonify_html_message_list({}); - return http_R200("edit-profile", wgd, {&config_presentation, &alien_userprofile, &empty_msg_list}); + return http_R200("edit-profile", wgd, {&config_presentation, &userinfo, &alien_userprofile, &empty_msg_list}); } - return http_R200("view-profile", wgd, {&config_presentation, &alien_userprofile}); + return http_R200("view-profile", wgd, {&config_presentation, &userinfo, &alien_userprofile}); } een9_THROW("Bad method"); } diff --git a/src/web_chat/iu9_ca_web_chat_service/service.cpp b/src/web_chat/iu9_ca_web_chat_service/service.cpp index fea961a..3ae6a95 100644 --- a/src/web_chat/iu9_ca_web_chat_service/service.cpp +++ b/src/web_chat/iu9_ca_web_chat_service/service.cpp @@ -36,7 +36,8 @@ int main(int argc, char** argv){ iu9cawebchat::run_website(config); } else een9_THROW("unknown action (known are 'run', 'initialize')"); - } catch (std::exception& e) { + // todo: put back execption after debug + } catch (std::bad_weak_ptr& e) { printf("System failure\n%s\n", e.what()); } return 0;