Переделана страница профиля, добавлена страница просмотра чужого профиля, страница настроек чата
This commit is contained in:
		
							parent
							
								
									29e06059d5
								
							
						
					
					
						commit
						24e11e0d3d
					
				
							
								
								
									
										61
									
								
								assets/HypertextPages/chat-members.nytl.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								assets/HypertextPages/chat-members.nytl.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,61 @@ | |||||||
|  | {% ELDEF main JSON pres JSON userinfo JSON openedchat JSON initial_chatUpdResp %} | ||||||
|  | <!DOCTYPE html> | ||||||
|  | <html lang="ru"> | ||||||
|  | <head> | ||||||
|  |     <meta charset="UTF-8"> | ||||||
|  |     <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||||
|  |     <link rel="icon" type="image/png" href="/assets/img/favicon.png"> | ||||||
|  |     <link rel="stylesheet" href="/assets/css/common.css"> | ||||||
|  |     <link rel="stylesheet" href="/assets/css/common-popup.css"> | ||||||
|  |     <link rel="stylesheet" href="/assets/css/chat-members.css"> | ||||||
|  |     <title>{%w pres.chat-members.members-of %} {%w openedchat.name %}</title> | ||||||
|  | </head> | ||||||
|  | <body> | ||||||
|  | {% PUT chat.pass pres userinfo openedchat initial_chatUpdResp %} | ||||||
|  | 
 | ||||||
|  | <div id="user-summoning-win" class="popup-window"> | ||||||
|  |     <h1 class="popup-window-msg">{%w pres.chat-members.summon-label-nickname %}</h1> | ||||||
|  |     <input class="one-line-input" id="summoned-user-nickname"> | ||||||
|  |     <input type="checkbox" id="summoned-user-is-read-only"> | ||||||
|  |     <label>{%w pres.chat-members.summon-label-ro %}</label><br> | ||||||
|  |     <button class="popup-window-btn-yes" id="user-summoning-yes">{%w pres.chat-members.yes-summon %}</button> | ||||||
|  |     <button class="popup-window-btn-no" id="user-summoning-no">{%w pres.chat-members.no-summon %}</button> | ||||||
|  | </div> | ||||||
|  | 
 | ||||||
|  | <div id="user-deletion-win" class="popup-window"> | ||||||
|  |     <!-- header will actually be rewritten before showing the window to include user nickname --> | ||||||
|  |     <h1 id="user-deletion-win-title" class="popup-window-msg"> ||||||||| </h1> | ||||||
|  |     <button class="popup-window-btn-yes" id="user-deletion-yes">{%w pres.chat-members.yes-kick %}</button> | ||||||
|  |     <button class="popup-window-btn-no" id="user-deletion-no">{%w pres.chat-members.no-kick %}</button> | ||||||
|  | </div> | ||||||
|  | 
 | ||||||
|  | <div class="document-container resp-container"> | ||||||
|  |     <div id="navigation-panel" class="panel"> | ||||||
|  |         <a href="/list-rooms" id="go-to-chat-list" class="panel-thing"> | ||||||
|  |             <img alt="Go to list of chats" src="/assets/img/list-rooms.svg" width="32px"> | ||||||
|  |         </a> | ||||||
|  |         <a href="/user/{% W userinfo.nickname %}" id="go-to-my-profile" class="panel-thing"> | ||||||
|  |             <img alt="Go to my profile" src="/assets/img/user.svg" width="32px"> | ||||||
|  |         </a> | ||||||
|  |         <p class="panel-thing panel-header-txt"> | ||||||
|  |             {%w pres.chat-members.members-list-of %} {% W openedchat.name %} ({% W openedchat.nickname %}) | ||||||
|  |         </p> | ||||||
|  |         <a href="/chat/{% W openedchat.nickname %}" id="go-to-chat-settings" class="panel-thing"> | ||||||
|  |             <img alt="Back to chat" src="/assets/img/return.svg" width="32px"> | ||||||
|  |         </a> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |     <div class="dynamic-block-list"> | ||||||
|  |         <img id="CM-btn-add" class="button-add centered-block-el" alt="New chat" src="/assets/img/add.svg"> | ||||||
|  |         <div class="dynamic-block-list-el-container" id="CM-list"> | ||||||
|  | 
 | ||||||
|  |         </div> | ||||||
|  |     </div> | ||||||
|  | </div> | ||||||
|  | 
 | ||||||
|  | <script src="/assets/js/common.js"></script> | ||||||
|  | <script src="/assets/js/common-popup.js"></script> | ||||||
|  | <script src="/assets/js/chat-members.js"></script> | ||||||
|  | </body> | ||||||
|  | </html> | ||||||
|  | {% ENDELDEF %} | ||||||
| @ -1,46 +0,0 @@ | |||||||
| {% ELDEF main JSON pres JSON userinfo %} |  | ||||||
| <!DOCTYPE html> |  | ||||||
| <html lang="en"> |  | ||||||
| <head> |  | ||||||
|     <meta charset="UTF-8"> |  | ||||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0"> |  | ||||||
|     <link rel="stylesheet" href="/assets/css/chatSettings.css"> |  | ||||||
|     <title>Настройки комнаты</title> |  | ||||||
| </head> |  | ||||||
| <body> |  | ||||||
| <div class="chat-settings-container"> |  | ||||||
|     <div class="chat-settings-container-header"> |  | ||||||
|         <input class="room-name" id="room-name" placeholder="Введите название комнаты..." value="Название комнаты"> |  | ||||||
|         <button class="changeName" onclick="handleChangeName()">Изменить название</button> |  | ||||||
|     </div> |  | ||||||
|     <div class="chat-settings-container-body"> |  | ||||||
|         <ul id="chat-settings-container-body"> |  | ||||||
|             <!-- Пример списка участников --> |  | ||||||
|             <li id="member-1">Участник 1<button class="remove-member-button" onclick="handleRemoveMember(1)">Удалить</button></li> |  | ||||||
|             <li id="member-2">Участник 2<button class="remove-member-button" onclick="handleRemoveMember(2)">Удалить</button></li> |  | ||||||
|             <li id="member-3">Участник 3<button class="remove-member-button" onclick="handleRemoveMember(3)">Удалить</button></li> |  | ||||||
|         </ul> |  | ||||||
|     </div> |  | ||||||
|     <div class="chat-settings-container-invite"> |  | ||||||
|         <button class="invite-member" onclick="openInvite()">Добавить участника</button> |  | ||||||
|     </div> |  | ||||||
| </div> |  | ||||||
| 
 |  | ||||||
| <div class="overlay" id="add_members"> |  | ||||||
|     <div class="add-members"> |  | ||||||
|         <div class="add-members-header"> |  | ||||||
|             <span class="close" onclick="closeAdd()">×</span> |  | ||||||
|             <h2>Добавить участников</h2> |  | ||||||
|         </div> |  | ||||||
|         <div class="add-members-body"> |  | ||||||
|             <input type="text" id="newMemberLogin" placeholder="Логин пользователя"> |  | ||||||
|         </div> |  | ||||||
|         <div class="add-members-footer"> |  | ||||||
|             <button class="add-member-button" onclick="handleAddMember()">Добавить</button> |  | ||||||
|         </div> |  | ||||||
|     </div> |  | ||||||
| </div> |  | ||||||
| <script src="/assets/js/chatSettings.js"></script> |  | ||||||
| </body> |  | ||||||
| </html> |  | ||||||
| {% ENDELDEF%} |  | ||||||
							
								
								
									
										71
									
								
								assets/HypertextPages/edit-profile.nytl.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								assets/HypertextPages/edit-profile.nytl.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,71 @@ | |||||||
|  | {% ELDEF main JSON pres JSON userinfo JSON alienprofile JSON errors %} | ||||||
|  | <!DOCTYPE html> | ||||||
|  | <html lang="en"> | ||||||
|  | <head> | ||||||
|  |     <meta charset="UTF-8"> | ||||||
|  |     <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||||
|  |     <link rel="icon" type="image/png" href="/assets/img/favicon.png"> | ||||||
|  |     <link rel="stylesheet" href="/assets/css/common.css"> | ||||||
|  |     <link rel="stylesheet" href="/assets/css/edit-profile.css"> | ||||||
|  |     <title>{%w pres.edit-profile.header-profile-of %} {%w alienprofile.name %}</title> | ||||||
|  | </head> | ||||||
|  | <body> | ||||||
|  | 
 | ||||||
|  | <div class="document-container"> | ||||||
|  |     <div id="navigation-panel" class="panel"> | ||||||
|  |         <a href="/list-rooms" id="go-to-chat-list" class="panel-thing"> | ||||||
|  |             <img alt="Go to list of chats" src="/assets/img/list-rooms.svg" width="32px"> | ||||||
|  |         </a> | ||||||
|  |         <a href="/user/{% W userinfo.nickname %}" id="go-to-my-profile" class="panel-thing"> | ||||||
|  |             <img alt="Go to my profile" src="/assets/img/user.svg" width="32px"> | ||||||
|  |         </a> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |     {% FOR error IN errors %} | ||||||
|  |     <div class="server-notif-error-msg-box"> | ||||||
|  |         {% W error.text %} | ||||||
|  |     </div> | ||||||
|  |     {% ENDFOR %} | ||||||
|  | 
 | ||||||
|  |     <div class="profile-container"> | ||||||
|  |         <h2 class="profile-name-text">{% W alienprofile.name %}</h2> | ||||||
|  |         <h3 class="profile-nickname-text">{%w pres.edit-profile.directive-nickname %} {% W alienprofile.nickname %}</h3> | ||||||
|  |         <p class="profile-bio-text"> | ||||||
|  |             {% W alienprofile.bio %} | ||||||
|  |         </p> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |     <div class="profile-container"> | ||||||
|  |         <h1 class="wide-centered-header">{%w pres.edit-profile.change-user-attributes %}</h1> | ||||||
|  |         <form action = "/user/{% W alienprofile.nickname %}" method="post" enctype="application/x-www-form-urlencoded"> | ||||||
|  |             <table class="logins-input-table"> | ||||||
|  |                 <tr> | ||||||
|  |                     <td class="logins-input-td1"> | ||||||
|  |                         <label for="new-name-input">{%w pres.edit-profile.directive-name %}</label> | ||||||
|  |                     </td> | ||||||
|  |                     <td class="logins-input-td2"> | ||||||
|  |                         <input name="name" id="new-name-input" type="text" | ||||||
|  |                                placeholder="{%w pres.edit-profile.placeholder-name %}" class="one-line-input"> | ||||||
|  |                     </td> | ||||||
|  |                 </tr> | ||||||
|  |                 <tr> | ||||||
|  |                     <td class="logins-input-td1"> | ||||||
|  |                         <label for="new-password-input">{%w pres.edit-profile.directive-password %}</label> | ||||||
|  |                     </td> | ||||||
|  |                     <td class="logins-input-td2"> | ||||||
|  |                         <input name="password" id="new-password-input" type="password" | ||||||
|  |                                placeholder="{%w pres.edit-profile.placeholder-password %}" class="one-line-input"> | ||||||
|  |                     </td> | ||||||
|  |                 </tr> | ||||||
|  |             </table> | ||||||
|  |             <label for="input-change-bio">{%w pres.edit-profile.directive-bio %}</label> | ||||||
|  |             <br> | ||||||
|  |             <textarea name="bio" id="input-change-bio" class="multiline-input"></textarea> | ||||||
|  |             <button class="action-button centered-block-el" type="submit">{%w pres.edit-profile.act-submit %}</button> | ||||||
|  |         </form> | ||||||
|  |     </div> | ||||||
|  | </div> | ||||||
|  | 
 | ||||||
|  | </body> | ||||||
|  | </html> | ||||||
|  | {% ENDELDEF%} | ||||||
| @ -1,6 +0,0 @@ | |||||||
| {% ELDEF main JSON pres JSON userinfo %} |  | ||||||
| <script> |  | ||||||
|     let pres = {% PUT jsinsert pres %}; |  | ||||||
|     let userinfo = {% PUT jsinsert userinfo %}; |  | ||||||
| </script> |  | ||||||
| {% ENDELDEF %} |  | ||||||
| @ -1,39 +0,0 @@ | |||||||
| {% ELDEF main JSON pres JSON userinfo %} |  | ||||||
| <!DOCTYPE html> |  | ||||||
| <html lang="en"> |  | ||||||
| <head> |  | ||||||
|     <meta charset="UTF-8"> |  | ||||||
|     <link rel="stylesheet" href="/assets/css/profile.css"> |  | ||||||
|     <title>Профиль</title> |  | ||||||
| </head> |  | ||||||
| <body> |  | ||||||
| <div class="main-container"> |  | ||||||
|     <div class="profile-header"> |  | ||||||
|         <h1 style="color: white; text-align: center;">Профиль пользователя</h1> |  | ||||||
|         <a class="return" href="chat.nytl.html">Назад</a> |  | ||||||
|     </div> |  | ||||||
|     <form> |  | ||||||
|         <div class="columns"> |  | ||||||
|             <div class="column"> |  | ||||||
|                 <img class="avatar" src="/assets/img/empty_avatar.png" id="avatar" height="200" width="200"><br> |  | ||||||
|                 <input type="file" id="fileInput" style="display:none"> |  | ||||||
|                 <button class="add" type="button" onclick="document.getElementById('fileInput').click();">Изменить фото</button><br> |  | ||||||
|             </div> |  | ||||||
|             <div class="column"> |  | ||||||
|                 <input type="text" name="username" placeholder = "Имя пользователя" value="Some Name" id="username"><br> |  | ||||||
|                 <input type="text" name="login" placeholder="Логин" value="some_login123" id="login" readonly><br> |  | ||||||
|             </div> |  | ||||||
|         </div> |  | ||||||
|         <h3 style="color:#007bb5;">О себе</h3> |  | ||||||
|         <div class="additional-info"> |  | ||||||
|             <textarea name="bio" placeholder="Напишите о себе..." id="bio"></textarea> |  | ||||||
|         </div> |  | ||||||
|         <button class="save" type="submit">Сохранить изменения</button> |  | ||||||
|     </form> |  | ||||||
| </div> |  | ||||||
| 
 |  | ||||||
| <script src="/assets/js/list-rooms.js"> </script> |  | ||||||
| 
 |  | ||||||
| </body> |  | ||||||
| </html> |  | ||||||
| {% ENDELDEF%} |  | ||||||
| @ -1,27 +0,0 @@ | |||||||
| {% ELDEF main JSON pres JSON userinfo %} |  | ||||||
| <!DOCTYPE html> |  | ||||||
| <html lang="ru"> |  | ||||||
| <head> |  | ||||||
|     <meta charset="UTF-8"> |  | ||||||
|     <meta name="viewport" content="width=device-width, initial-scale=1.0"> |  | ||||||
|     <title>Страница Регистрации</title> |  | ||||||
|     <link rel="stylesheet" href="/assets/css/registration.css"> |  | ||||||
| 
 |  | ||||||
| </head> |  | ||||||
| 
 |  | ||||||
| <body> |  | ||||||
| <div class="form-container"> |  | ||||||
|     <h1 class="hide-cursor no-select">Вход</h1> |  | ||||||
|     <form action="assets/html/list-rooms.html" method="post"> |  | ||||||
|         <input type="text" name="username" placeholder="Имя пользователя" id="username"><br> |  | ||||||
|         <input type="text" name="login" placeholder="Логин" id="login"><br> |  | ||||||
|         <input type="password" name="password" placeholder="Пароль" id="password"><br> |  | ||||||
|         <button type="submit" class="hide-cursor no-select">Зарегистрироваться</button> |  | ||||||
|         <div id="error"></div> |  | ||||||
|     </form> |  | ||||||
| </div> |  | ||||||
| 
 |  | ||||||
| <script src="assets/js/registration.js"></script> |  | ||||||
| </body> |  | ||||||
| </html> |  | ||||||
| {% ENDELDEF %} |  | ||||||
							
								
								
									
										36
									
								
								assets/HypertextPages/view-profile.nytl.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								assets/HypertextPages/view-profile.nytl.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,36 @@ | |||||||
|  | {% ELDEF main JSON pres JSON userinfo JSON alienprofile %} | ||||||
|  | <!DOCTYPE html> | ||||||
|  | <html lang="en"> | ||||||
|  | <head> | ||||||
|  |     <meta charset="UTF-8"> | ||||||
|  |     <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||||
|  |     <link rel="icon" type="image/png" href="/assets/img/favicon.png"> | ||||||
|  |     <link rel="stylesheet" href="/assets/css/common.css"> | ||||||
|  |     <!-- This page is so simple, that it does not even have it's separate css file --> | ||||||
|  |     <title>{%w pres.view-profile.header-profile-of %} {%w alienprofile.name %}</title> | ||||||
|  | </head> | ||||||
|  | <body> | ||||||
|  | 
 | ||||||
|  | <div class="document-container resp-container"> | ||||||
|  |     <div id="navigation-panel" class="panel"> | ||||||
|  |         <a href="/list-rooms" id="go-to-chat-list" class="panel-thing"> | ||||||
|  |             <img alt="Go to list of chats" src="/assets/img/list-rooms.svg" width="32px"> | ||||||
|  |         </a> | ||||||
|  |         <a href="/user/{% W userinfo.nickname %}" id="go-to-my-profile" class="panel-thing"> | ||||||
|  |             <img alt="Go to my profile" src="/assets/img/user.svg" width="32px"> | ||||||
|  |         </a> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|  |     <div class="profile-container"> | ||||||
|  |         <h2 class="profile-name-text">{%w alienprofile.name %}</h2> | ||||||
|  |         <h3 class="profile-nickname-text">{%w pres.view-profile.directive-nickname%} {%w alienprofile.nickname %}</h3> | ||||||
|  |         <p class="profile-bio-text"> | ||||||
|  |             {%w alienprofile.bio %} | ||||||
|  |         </p> | ||||||
|  |     </div> | ||||||
|  | </div> | ||||||
|  | 
 | ||||||
|  | </body> | ||||||
|  | </html> | ||||||
|  | 
 | ||||||
|  | {% ENDELDEF%} | ||||||
							
								
								
									
										33
									
								
								assets/css/chat-members.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								assets/css/chat-members.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | |||||||
|  | #CM-btn-add { | ||||||
|  |     margin-top: 6px; | ||||||
|  |     margin-bottom: 4px; | ||||||
|  |     display: none; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .CM-member-box { | ||||||
|  |     display: flex; | ||||||
|  |     flex-direction: row; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .CL-member-box-nickname { | ||||||
|  |     margin-left: 8px; | ||||||
|  |     justify-self: flex-start; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .CM-member-box-name { | ||||||
|  |     margin-left: 14px; | ||||||
|  |     justify-self: flex-start; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .CM-member-box-role { | ||||||
|  |     margin-left: auto; | ||||||
|  |     justify-self: flex-end; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .CM-member-box-leave-btn { | ||||||
|  |     margin-left: 10px; | ||||||
|  |     margin-right: 8px; | ||||||
|  |     justify-self: flex-end; | ||||||
|  |     width: 16px; | ||||||
|  |     cursor: pointer; | ||||||
|  | } | ||||||
| @ -1,163 +0,0 @@ | |||||||
| body { |  | ||||||
|     font-family: Arial, sans-serif; |  | ||||||
|     display: flex; |  | ||||||
|     justify-content: center; |  | ||||||
|     align-items: center; |  | ||||||
|     height: 100vh; |  | ||||||
|     margin: 0; |  | ||||||
|     background-color: #e5e5e5; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .chat-settings-container { |  | ||||||
|     width: 100%; |  | ||||||
|     max-width: 800px; |  | ||||||
|     background-color: white; |  | ||||||
|     box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); |  | ||||||
|     display: flex; |  | ||||||
|     flex-direction: column; |  | ||||||
|     border-radius: 8px; |  | ||||||
|     overflow: hidden; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .chat-settings-container-header { |  | ||||||
|     background-color: #007bb5; |  | ||||||
|     color: white; |  | ||||||
|     padding: 25px; |  | ||||||
|     display: flex; |  | ||||||
|     justify-content: center; |  | ||||||
|     align-items: center; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .room-name { |  | ||||||
|     font-size: 24px; |  | ||||||
|     width: 80%; |  | ||||||
|     text-align: center; |  | ||||||
|     border-radius: 10px; |  | ||||||
|     border: none; |  | ||||||
| } |  | ||||||
| .changeName { |  | ||||||
|     padding: 8px 10px; |  | ||||||
|     background-color: #28a745; |  | ||||||
|     color: white; |  | ||||||
|     border-radius: 20px; |  | ||||||
|     border: none; |  | ||||||
|     cursor: pointer; |  | ||||||
| } |  | ||||||
| .changeName:hover { |  | ||||||
|     background-color: #005f8c; |  | ||||||
| } |  | ||||||
| .chat-settings-container-body { |  | ||||||
|     padding: 15px; |  | ||||||
|     background-color: #f7f7f7; |  | ||||||
|     flex: 1; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #chat-settings-container-body { |  | ||||||
|     list-style-type: none; |  | ||||||
|     padding: 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #chat-settings-container-body li { |  | ||||||
|     margin-bottom: 10px; |  | ||||||
|     background-color: white; |  | ||||||
|     padding: 10px; |  | ||||||
|     border-radius: 8px; |  | ||||||
|     box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); |  | ||||||
| } |  | ||||||
| .remove-member-button { |  | ||||||
|     background-color: red; |  | ||||||
|     color: white; |  | ||||||
|     border: none; |  | ||||||
|     padding: 5px 10px; |  | ||||||
|     cursor: pointer; |  | ||||||
|     margin-left: 10px; |  | ||||||
|     border-radius: 4px; |  | ||||||
| } |  | ||||||
| .remove-member-button:hover { |  | ||||||
|     background-color: darkred; |  | ||||||
| } |  | ||||||
| .chat-settings-container-invite { |  | ||||||
|     padding: 15px; |  | ||||||
|     background-color: white; |  | ||||||
|     text-align: center; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .invite-member { |  | ||||||
|     padding: 10px 20px; |  | ||||||
|     border: none; |  | ||||||
|     background-color: #28a745; |  | ||||||
|     color: white; |  | ||||||
|     border-radius: 20px; |  | ||||||
|     cursor: pointer; |  | ||||||
|     transition: background-color 0.3s ease; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .invite-member: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; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .add-members { |  | ||||||
|     background-color: white; |  | ||||||
|     padding: 30px; |  | ||||||
|     border-radius: 8px; |  | ||||||
|     box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); |  | ||||||
|     width: 100%; |  | ||||||
|     max-width: 400px; |  | ||||||
|     text-align: center; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .add-members-header { |  | ||||||
|     position: relative; |  | ||||||
|     margin-bottom: 20px; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .add-members-header h2 { |  | ||||||
|     margin: 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .close { |  | ||||||
|     position: absolute; |  | ||||||
|     right: 10px; |  | ||||||
|     top: 0; |  | ||||||
|     font-size: 24px; |  | ||||||
|     font-weight: bold; |  | ||||||
|     cursor: pointer; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .add-members-body input { |  | ||||||
|     width: 95%; |  | ||||||
|     padding: 10px; |  | ||||||
|     margin-bottom: 20px; |  | ||||||
|     border: 1px solid #ddd; |  | ||||||
|     border-radius: 4px; |  | ||||||
|     margin-right: 15%; |  | ||||||
|     outline: none; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .add-member-button { |  | ||||||
|     padding: 10px 20px; |  | ||||||
|     border: none; |  | ||||||
|     background-color: #007bb5; |  | ||||||
|     color: white; |  | ||||||
|     border-radius: 20px; |  | ||||||
|     cursor: pointer; |  | ||||||
|     outline: none; |  | ||||||
|     transition: background-color 0.3s ease; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .add-member-button:hover { |  | ||||||
|     background-color: #005f8c; |  | ||||||
| } |  | ||||||
							
								
								
									
										50
									
								
								assets/css/common-popup.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								assets/css/common-popup.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,50 @@ | |||||||
|  | .popup-overlay-veil { | ||||||
|  |     position: fixed; | ||||||
|  |     top: 0; | ||||||
|  |     left: 0; | ||||||
|  |     width: 100%; | ||||||
|  |     height: 100%; | ||||||
|  |     background-color: rgba(0, 0, 0, 0.6); | ||||||
|  | 
 | ||||||
|  |     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; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .popup-window-btn-yes { | ||||||
|  |     background-color: #0c7f0e; | ||||||
|  |     border-radius: 5px; | ||||||
|  |     padding: 12px; | ||||||
|  |     color: white; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .popup-window-btn-no { | ||||||
|  |     background-color: #ff0005; | ||||||
|  |     border-radius: 5px; | ||||||
|  |     padding: 12px; | ||||||
|  |     color: white; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .popup-window-msg { | ||||||
|  |     padding-left: 20px; | ||||||
|  |     font-weight: bold; | ||||||
|  |     font-size: 1.3em; | ||||||
|  | } | ||||||
							
								
								
									
										206
									
								
								assets/css/common.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										206
									
								
								assets/css/common.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,206 @@ | |||||||
|  | /* 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; | ||||||
|  |     align-items: center; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .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 */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @media (orientation: landscape) { | ||||||
|  |     .resp-container{ | ||||||
|  |         width: 80%; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @media (orientation: portrait){ | ||||||
|  |     .resp-container{ | ||||||
|  |         width: 100%; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 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; | ||||||
|  | } | ||||||
							
								
								
									
										23
									
								
								assets/css/edit-profile.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								assets/css/edit-profile.css
									
									
									
									
									
										Normal file
									
								
							| @ -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; | ||||||
|  | } | ||||||
| @ -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; |  | ||||||
| } |  | ||||||
| @ -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; |  | ||||||
| } |  | ||||||
							
								
								
									
										20
									
								
								assets/img/add.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								assets/img/add.svg
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||||
|  | <svg | ||||||
|  |    width="128" | ||||||
|  |    height="128" | ||||||
|  |    viewBox="0 0 3.84 3.84" | ||||||
|  |    fill="none" | ||||||
|  |    version="1.1" | ||||||
|  |    id="svg1" | ||||||
|  |    xmlns="http://www.w3.org/2000/svg" | ||||||
|  |    xmlns:svg="http://www.w3.org/2000/svg"> | ||||||
|  |   <defs | ||||||
|  |      id="defs1" /> | ||||||
|  |   <path | ||||||
|  |      fill-rule="evenodd" | ||||||
|  |      clip-rule="evenodd" | ||||||
|  |      d="m 1.9142674,3.7842088 c -0.8814997,0 -1.32224859,0 -1.59609402,-0.2738529 C 0.04432607,3.2365216 0.04432607,2.7957577 0.04432607,1.9142674 c 0,-0.8814997 0,-1.32224859 0.27384731,-1.59609402 C 0.59201881,0.04432607 1.0327677,0.04432607 1.9142674,0.04432607 c 0.8814903,0 1.3222542,0 1.5960885,0.27384731 0.2738529,0.27384543 0.2738529,0.71459432 0.2738529,1.59609402 0,0.8814903 0,1.3222542 -0.2738529,1.5960885 C 3.2365216,3.7842088 2.7957577,3.7842088 1.9142674,3.7842088 Z m 0,-2.5711694 c 0.077453,0 0.1402457,0.062791 0.1402457,0.1402456 v 0.4207368 h 0.4207367 c 0.077453,0 0.1402456,0.062793 0.1402456,0.1402456 0,0.077453 -0.062793,0.1402457 -0.1402456,0.1402457 H 2.0545131 v 0.4207367 c 0,0.077453 -0.062793,0.1402456 -0.1402457,0.1402456 -0.077453,0 -0.1402456,-0.062793 -0.1402456,-0.1402456 V 2.0545131 H 1.353285 c -0.077455,0 -0.1402456,-0.062793 -0.1402456,-0.1402457 0,-0.077453 0.062791,-0.1402456 0.1402456,-0.1402456 H 1.7740218 V 1.353285 c 0,-0.077455 0.062793,-0.1402456 0.1402456,-0.1402456 z" | ||||||
|  |      fill="#1c274c" | ||||||
|  |      id="path1" | ||||||
|  |      style="stroke-width:0.186994" /> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 1.4 KiB | 
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 81 KiB | 
							
								
								
									
										
											BIN
										
									
								
								assets/img/favicon.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assets/img/favicon.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 824 B | 
							
								
								
									
										28
									
								
								assets/img/list-rooms.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								assets/img/list-rooms.svg
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||||
|  | 
 | ||||||
|  | <svg | ||||||
|  |    width="127.99999" | ||||||
|  |    height="127.99999" | ||||||
|  |    viewBox="0 0 33.866664 33.866664" | ||||||
|  |    version="1.1" | ||||||
|  |    id="svg1" | ||||||
|  |    xmlns="http://www.w3.org/2000/svg" | ||||||
|  |    xmlns:svg="http://www.w3.org/2000/svg"> | ||||||
|  |   <defs | ||||||
|  |      id="defs1" /> | ||||||
|  |   <g | ||||||
|  |      id="layer1"> | ||||||
|  |     <path | ||||||
|  |        style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1" | ||||||
|  |        d="M 6.2911505,3.4844006 V 6.6404405 H 3.0362141 V 28.776832 h 4.7418555 v 2.929792 H 0.58956039 V 3.438992 Z" | ||||||
|  |        id="path63" /> | ||||||
|  |     <path | ||||||
|  |        style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1" | ||||||
|  |        d="m 27.557741,31.386555 v -3.15604 h 3.254937 V 6.0941238 h -4.741856 v -2.929792 h 7.188509 V 31.431963 Z" | ||||||
|  |        id="path63-2" /> | ||||||
|  |     <path | ||||||
|  |        id="rect63" | ||||||
|  |        style="fill:#fdffff;fill-opacity:1;fill-rule:nonzero;stroke:#e1e1e1;stroke-width:0.529167;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1" | ||||||
|  |        d="m 8.7183307,8.3901854 c -2.467802,0 -4.4545084,1.9867066 -4.4545084,4.4545086 v 5.357812 c 0,2.467802 1.9867064,4.454509 4.4545084,4.454509 0,0 6.6668103,0 10.2365843,0 1.184667,0 1.8523,1.573101 2.973462,1.946651 1.827305,0.608823 5.758305,0.474906 5.758305,0.474906 0,0 -1.204106,-0.984163 -2.336589,-2.042039 -0.307888,-0.287603 -0.182877,-1.488944 0.134028,-1.896921 0.674916,-0.868872 0.918918,-1.680982 0.918918,-2.937106 v -5.357812 c 0,-2.467802 -1.986706,-4.4545086 -4.454508,-4.4545086 z" /> | ||||||
|  |   </g> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 1.6 KiB | 
							
								
								
									
										20
									
								
								assets/img/return.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								assets/img/return.svg
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||||
|  | 
 | ||||||
|  | <svg | ||||||
|  |    width="128" | ||||||
|  |    height="127.99999" | ||||||
|  |    viewBox="0 0 33.866667 33.866664" | ||||||
|  |    version="1.1" | ||||||
|  |    id="svg1" | ||||||
|  |    xmlns="http://www.w3.org/2000/svg" | ||||||
|  |    xmlns:svg="http://www.w3.org/2000/svg"> | ||||||
|  |   <defs | ||||||
|  |      id="defs1" /> | ||||||
|  |   <g | ||||||
|  |      id="layer1"> | ||||||
|  |     <path | ||||||
|  |        style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:0.294159;stroke-linejoin:round;stroke-opacity:1" | ||||||
|  |        d="m 0.65443061,23.377766 10.20536539,-7.351693 -0.06427,3.749871 c 0,0 6.384296,0.115304 9.607291,0.115304 1.824632,0 4.010317,0.117998 5.361398,-1.065432 0.797635,-0.698657 1.041209,-1.943308 0.954461,-2.97946 -0.118465,-1.414973 -0.417733,-2.830021 -1.492491,-3.799298 -0.964892,-0.870193 -2.338758,-1.449022 -3.659301,-1.465666 -1.347581,-0.01698 -4.311633,-0.01476 -4.311633,-0.01476 l 0.02678,-6.0468658 c 0,0 5.209174,-0.1269759 7.836958,-0.1269759 2.090574,0 3.730335,0.2813604 5.374446,1.5274776 1.165995,0.8837399 2.874757,2.1212447 2.874757,3.8971142 0,3.5737799 -0.03341,6.8479459 -0.03341,10.6502529 0,3.155641 -2.159421,4.126978 -3.036427,4.888332 -1.783594,1.548393 -4.069763,1.553329 -6.468859,1.553329 -4.709142,0 -13.295569,0 -13.295569,0 v 3.244296 z" | ||||||
|  |        id="path1" /> | ||||||
|  |   </g> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 1.2 KiB | 
							
								
								
									
										24
									
								
								assets/img/user.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								assets/img/user.svg
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | ||||||
|  | 
 | ||||||
|  | <svg | ||||||
|  |    width="127.99999" | ||||||
|  |    height="127.99999" | ||||||
|  |    viewBox="0 0 33.866664 33.866664" | ||||||
|  |    version="1.1" | ||||||
|  |    id="svg1" | ||||||
|  |    xmlns="http://www.w3.org/2000/svg" | ||||||
|  |    xmlns:svg="http://www.w3.org/2000/svg"> | ||||||
|  |   <defs | ||||||
|  |      id="defs1" /> | ||||||
|  |   <g | ||||||
|  |      id="layer1"> | ||||||
|  |     <path | ||||||
|  |        style="fill:#000080;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.465;stroke-linejoin:round;stroke-dasharray:none" | ||||||
|  |        d="M 9.3745975,32.81176 H 25.632941 c 0,0 0.08996,-6.044498 -0.03778,-10.988966 0.0321,-3.524476 -1.327193,-6.290541 -8.363226,-6.155275 -7.036034,0.135265 -7.7455423,2.805955 -7.7693511,5.331649 -0.034594,3.669826 -0.087981,11.812592 -0.087981,11.812592 z" | ||||||
|  |        id="path7" /> | ||||||
|  |     <path | ||||||
|  |        id="path8" | ||||||
|  |        style="fill:#000080;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.965;stroke-linejoin:round;stroke-dasharray:none" | ||||||
|  |        d="M 17.963761,1.3260172 A 11.612947,6.192831 0 0 0 6.3510334,7.5189208 11.612947,6.192831 0 0 0 17.963761,13.711824 11.612947,6.192831 0 0 0 29.576489,7.5189208 11.612947,6.192831 0 0 0 17.963761,1.3260172 Z m -3.947046,2.876827 a 1.5186517,3.4351659 0 0 1 1.518771,3.4349323 1.5186517,3.4351659 0 0 1 -1.518771,3.4354495 1.5186517,3.4351659 0 0 1 -1.518253,-3.4354495 1.5186517,3.4351659 0 0 1 1.518253,-3.4349323 z m 6.47299,0.2160074 a 1.5186517,3.4351659 0 0 1 1.518254,3.4349324 1.5186517,3.4351659 0 0 1 -1.518254,3.435449 1.5186517,3.4351659 0 0 1 -1.51877,-3.435449 1.5186517,3.4351659 0 0 1 1.51877,-3.4349324 z" /> | ||||||
|  |   </g> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 1.5 KiB | 
							
								
								
									
										188
									
								
								assets/js/chat-members.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								assets/js/chat-members.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,188 @@ | |||||||
|  | let LocalHistoryId = 0; | ||||||
|  | 
 | ||||||
|  | function genSentBase(){ | ||||||
|  |     return { | ||||||
|  |         'chatUpdReq': { | ||||||
|  |             'LocalHistoryId': LocalHistoryId, | ||||||
|  |             'chatId': openedchat.id | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | let members = new Map(); | ||||||
|  | let memberBoxes = new Map(); | ||||||
|  | let myRoleHere = null;  // Dung local state updates should be updated first
 | ||||||
|  | 
 | ||||||
|  | let userDeletionWinStoredUId = -1; | ||||||
|  | 
 | ||||||
|  | function shouldShowDeleteButton(memberSt){ | ||||||
|  |     return userinfo.uid !== memberSt.userId && myRoleHere === userChatRoleAdmin && memberSt.roleHere !== userChatRoleDeleted; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function updateBoxWithSt(box, memberSt){ | ||||||
|  |     let ID = memberSt.userId; | ||||||
|  |     let roleP = box.querySelector(".CM-member-box-role"); | ||||||
|  |     roleP.innerText = memberSt.roleHere; | ||||||
|  |     box.style.backgroundColor = roleToColor(memberSt.roleHere); | ||||||
|  |     box.querySelector(".CM-member-box-leave-btn").style.display = | ||||||
|  |         (shouldShowDeleteButton(memberSt) ? "block" : "none"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function convertMemberStToBox(memberSt){ | ||||||
|  |     let ID = memberSt.userId; | ||||||
|  |     let userProfileURI = "/user/" + memberSt.nickname; | ||||||
|  | 
 | ||||||
|  |     let box = document.createElement("div"); | ||||||
|  |     box.className = "dynamic-block-list-el CM-member-box"; | ||||||
|  |     box.style.backgroundColor = roleToColor(memberSt.roleHere); | ||||||
|  | 
 | ||||||
|  |     let inBoxNickname = document.createElement("a"); | ||||||
|  |     box.appendChild(inBoxNickname); | ||||||
|  |     inBoxNickname.className = "entity-nickname-txt CM-member-box-nickname"; | ||||||
|  |     inBoxNickname.innerText = memberSt.nickname; | ||||||
|  |     inBoxNickname.href = userProfileURI; | ||||||
|  | 
 | ||||||
|  |     let inBoxName = document.createElement("a"); | ||||||
|  |     box.appendChild(inBoxName); | ||||||
|  |     inBoxName.className = "entity-reg-field-txt CM-member-box-name"; | ||||||
|  |     inBoxName.innerText = memberSt.name; | ||||||
|  |     inBoxName.href = userProfileURI; | ||||||
|  | 
 | ||||||
|  |     let inBoxUserRoleHere = document.createElement("p"); | ||||||
|  |     box.appendChild(inBoxUserRoleHere); | ||||||
|  |     inBoxUserRoleHere.className = "entity-reg-field-txt CM-member-box-role"; | ||||||
|  |     inBoxUserRoleHere.innerText = memberSt.roleHere; | ||||||
|  | 
 | ||||||
|  |     let inBoxLeaveBtn = document.createElement("img"); | ||||||
|  |     box.appendChild(inBoxLeaveBtn); | ||||||
|  |     inBoxLeaveBtn.className = "CM-member-box-leave-btn"; | ||||||
|  |     inBoxLeaveBtn.src = "/assets/img/delete.svg"; | ||||||
|  |     inBoxLeaveBtn.onclick = function (ev) { | ||||||
|  |         if (ev.button !== 0) | ||||||
|  |             return; | ||||||
|  |         userDeletionWinStoredUId = ID; | ||||||
|  |         document.getElementById("user-deletion-win-title").innerText = | ||||||
|  |             pres['chat-members']['reask-kick-user-X'] + " " + memberSt.nickname + "?"; | ||||||
|  |         activatePopupWindowById("user-deletion-win"); | ||||||
|  |     }; | ||||||
|  |     box.querySelector(".CM-member-box-leave-btn").style.display = | ||||||
|  |         (shouldShowDeleteButton(memberSt) ? "block" : "none"); | ||||||
|  | 
 | ||||||
|  |     return box; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function updateLocalStateFromChatUpdResp(chatUpdResp){ | ||||||
|  |     LocalHistoryId = chatUpdResp.HistoryId; | ||||||
|  |     // If my role is updated, we need to update all the boes of already set users (kick button can appear and disappear)
 | ||||||
|  |     let literalMemberList = document.getElementById("CM-list"); | ||||||
|  |     // We ignore messages and everything related to them. Dang, I really should add an argument to disable message lookup here
 | ||||||
|  |     for (let memberSt of chatUpdResp.members){ | ||||||
|  |         console.log([memberSt, userinfo.uid, myRoleHere]); | ||||||
|  |         if (memberSt.userId === userinfo.uid && myRoleHere !== memberSt.roleHere){ | ||||||
|  |             myRoleHere = memberSt.roleHere; | ||||||
|  |             for (let [id, memberSt] of members){ | ||||||
|  |                 let box = memberBoxes.get(id); | ||||||
|  |                 updateBoxWithSt(box, memberSt); | ||||||
|  |             } | ||||||
|  |             document.getElementById("CM-btn-add").style.display = | ||||||
|  |                 (memberSt.roleHere === userChatRoleAdmin ? "block" : "none"); | ||||||
|  |             console.log("DEBUG " + (memberSt.roleHere === userChatRoleAdmin ? "block" : "none")); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     for (let memberSt of chatUpdResp.members){ | ||||||
|  |         let id = memberSt.userId; | ||||||
|  |         if (members.has(id)){ | ||||||
|  |             updateBoxWithSt(memberBoxes.get(id), memberSt); | ||||||
|  |         } else { | ||||||
|  |             if (memberSt.roleHere !== userChatRoleDeleted){ | ||||||
|  |                 members.set(id, memberSt); | ||||||
|  |                 let box = convertMemberStToBox(memberSt); | ||||||
|  |                 memberBoxes.set(id, box); | ||||||
|  |                 literalMemberList.appendChild(box); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function updateLocalStateFromRecv(Recv){ | ||||||
|  |     updateLocalStateFromChatUpdResp(Recv.chatUpdResp); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function configureSummonUserInterface(){ | ||||||
|  |     document.getElementById("user-summoning-yes").onclick = function(ev ){ | ||||||
|  |         if (ev.button !==0) | ||||||
|  |             return; | ||||||
|  |         let nickname = String(document.getElementById("summoned-user-nickname").value); | ||||||
|  |         let isReadOnly = document.getElementById("summoned-user-is-read-only").checked; | ||||||
|  |         deactivateActivePopup(); | ||||||
|  |         let Sent = genSentBase(); | ||||||
|  |         Sent.nickname = nickname; | ||||||
|  |         Sent.makeReadOnly = Boolean(isReadOnly); | ||||||
|  |         apiRequest("addMemberToChat", Sent). | ||||||
|  |         then((Recv) => { | ||||||
|  |             updateLocalStateFromRecv(Recv); | ||||||
|  |         }).catch((e) => { | ||||||
|  |            console.log(e); | ||||||
|  |            alert(pres['chat-members']["failed-summon-member"]); | ||||||
|  |         }); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     document.getElementById("user-summoning-no").onclick = function (ev) { | ||||||
|  |         if (ev.button !== 0) | ||||||
|  |             return; | ||||||
|  |         deactivateActivePopup(); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     document.getElementById("CM-btn-add").onclick = function(ev) { | ||||||
|  |         if (ev.button !== 0) | ||||||
|  |             return; | ||||||
|  |         document.getElementById("summoned-user-nickname").value = ""; | ||||||
|  |         // read-only flag persists throughout user summoning sessions, and IT IS NOT A BUG
 | ||||||
|  |         activatePopupWindowById("user-summoning-win"); | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Popup activation button is configured for each box separately */ | ||||||
|  | function configureKickUserInterfaceWinPart(){ | ||||||
|  |     document.getElementById("user-deletion-yes").onclick = function (ev){ | ||||||
|  |         if (ev.button !== 0) | ||||||
|  |             return; | ||||||
|  |         deactivateActivePopup(); | ||||||
|  |         if (userDeletionWinStoredUId < 0) | ||||||
|  |             throw new Error("Karaul"); | ||||||
|  |         let Sent = genSentBase(); | ||||||
|  |         Sent.userId = userDeletionWinStoredUId; | ||||||
|  |         apiRequest("removeMemberFromChat", Sent). | ||||||
|  |         then((Recv) => { | ||||||
|  |             updateLocalStateFromRecv(Recv); | ||||||
|  |         }).catch((e) => { | ||||||
|  |             console.log(e); | ||||||
|  |             alert(pres['chat-members']["failed-kick-member"]); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     document.getElementById("user-deletion-no").onclick = function (ev) { | ||||||
|  |         if (ev.button !== 0) | ||||||
|  |             return; | ||||||
|  |         deactivateActivePopup(); | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | __mainloopDelayMS = 5000; | ||||||
|  | __guestMainloopPollerAction = function (){ | ||||||
|  |     console.log("Hello, world"); | ||||||
|  |     apiRequest("chatPollEvents", genSentBase()). | ||||||
|  |     then((Recv) => { | ||||||
|  |         console.log(Recv); | ||||||
|  |         updateLocalStateFromRecv(Recv); | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | window.onload = function(){ | ||||||
|  |     console.log("Page loaded"); | ||||||
|  |     configureSummonUserInterface(); | ||||||
|  |     configureKickUserInterfaceWinPart(); | ||||||
|  |     updateLocalStateFromChatUpdResp(initial_chatUpdResp); | ||||||
|  |     mainloopPoller(); | ||||||
|  | } | ||||||
| @ -1,146 +0,0 @@ | |||||||
| const chatId = 123; |  | ||||||
| let localHistoryId = 0; |  | ||||||
| 
 |  | ||||||
| function handleChangeName() { |  | ||||||
|     const newName = document.getElementById('room-name').value; |  | ||||||
|     changeChatName(chatId, localHistoryId, newName).then(() => { |  | ||||||
|     }); |  | ||||||
| } |  | ||||||
| function handleAddMember() { |  | ||||||
|     const login = document.getElementById('newMemberLogin').value; |  | ||||||
|     if (login) { |  | ||||||
|         addMemberToChat(chatId, localHistoryId, login).then(() => { |  | ||||||
|             const list = document.getElementById("chat-settings-container-body"); |  | ||||||
|             const listItem = document.createElement("li"); |  | ||||||
|             listItem.textContent = login; |  | ||||||
|             list.appendChild(listItem); |  | ||||||
|             closeAdd(); |  | ||||||
|         }); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| function handleRemoveMember(userId) { |  | ||||||
|     removeMemberFromChat(chatId, localHistoryId, userId).then(() => { |  | ||||||
|         const listItem = document.getElementById(`member-${userId}`); |  | ||||||
|         if (listItem) { |  | ||||||
|             listItem.remove(); |  | ||||||
|         } |  | ||||||
|     }); |  | ||||||
| } |  | ||||||
| function openInvite() { |  | ||||||
|     document.getElementById("add_members").style.display = "flex"; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function closeAdd() { |  | ||||||
|     document.getElementById("add_members").style.display = "none"; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| function updateChat() { |  | ||||||
|     pollChatEvents(chatId, localHistoryId).then(() => { |  | ||||||
|     }); |  | ||||||
| } |  | ||||||
| document.addEventListener('DOMContentLoaded', () => { |  | ||||||
|     updateChat(); |  | ||||||
| }); |  | ||||||
| async function changeChatName(chatId, localHistoryId, newName) { |  | ||||||
|     try { |  | ||||||
|         const response = await fetch('/api/changeChatName', { |  | ||||||
|             method: 'POST', |  | ||||||
|             headers: { |  | ||||||
|                 'Content-Type': 'application/json', |  | ||||||
|             }, |  | ||||||
|             body: JSON.stringify({ |  | ||||||
|                 chatUpdReq: { |  | ||||||
|                     chatId: chatId, |  | ||||||
|                     LocalHistoryId: localHistoryId |  | ||||||
|                 }, |  | ||||||
|                 content: { |  | ||||||
|                     name: newName |  | ||||||
|                 } |  | ||||||
|             }) |  | ||||||
|         }); |  | ||||||
|         const data = await response.json(); |  | ||||||
|         if (data.status === 0) { |  | ||||||
|             console.log('Название комнаты успешно изменено'); |  | ||||||
|         } else { |  | ||||||
|             console.error('Ошибка при изменении названия комнаты:', data.error); |  | ||||||
|         } |  | ||||||
|     } catch (error) { |  | ||||||
|         console.error('Ошибка сети при изменении названия комнаты:', error); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| async function addMemberToChat(chatId, localHistoryId, nickname) { |  | ||||||
|     try { |  | ||||||
|         const response = await fetch('/api/addMemberToChat', { |  | ||||||
|             method: 'POST', |  | ||||||
|             headers: { |  | ||||||
|                 'Content-Type': 'application/json', |  | ||||||
|             }, |  | ||||||
|             body: JSON.stringify({ |  | ||||||
|                 chatUpdReq: { |  | ||||||
|                     chatId: chatId, |  | ||||||
|                     LocalHistoryId: localHistoryId |  | ||||||
|                 }, |  | ||||||
|                 nickname: nickname |  | ||||||
|             }) |  | ||||||
|         }); |  | ||||||
|         const data = await response.json(); |  | ||||||
|         if (data.status === 0) { |  | ||||||
|             console.log('Участник успешно добавлен'); |  | ||||||
|         } else { |  | ||||||
|             console.error('Ошибка при добавлении участника:', data.error); |  | ||||||
|         } |  | ||||||
|     } catch (error) { |  | ||||||
|         console.error('Ошибка сети при добавлении участника:', error); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| async function removeMemberFromChat(chatId, localHistoryId, userId) { |  | ||||||
|     try { |  | ||||||
|         const response = await fetch('/api/removeMemberFromChat', { |  | ||||||
|             method: 'POST', |  | ||||||
|             headers: { |  | ||||||
|                 'Content-Type': 'application/json', |  | ||||||
|             }, |  | ||||||
|             body: JSON.stringify({ |  | ||||||
|                 chatUpdReq: { |  | ||||||
|                     chatId: chatId, |  | ||||||
|                     LocalHistoryId: localHistoryId |  | ||||||
|                 }, |  | ||||||
|                 userId: userId |  | ||||||
|             }) |  | ||||||
|         }); |  | ||||||
|         const data = await response.json(); |  | ||||||
|         if (data.status === 0) { |  | ||||||
|             console.log('Участник успешно удален'); |  | ||||||
|         } else { |  | ||||||
|             console.error('Ошибка при удалении участника:', data.error); |  | ||||||
|         } |  | ||||||
|     } catch (error) { |  | ||||||
|         console.error('Ошибка сети при удалении участника:', error); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| async function pollChatEvents(chatId, localHistoryId) { |  | ||||||
|     try { |  | ||||||
|         const response = await fetch('/api/chatPollEvents', { |  | ||||||
|             method: 'POST', |  | ||||||
|             headers: { |  | ||||||
|                 'Content-Type': 'application/json', |  | ||||||
|             }, |  | ||||||
|             body: JSON.stringify({ |  | ||||||
|                 chatUpdReq: { |  | ||||||
|                     chatId: chatId, |  | ||||||
|                     LocalHistoryId: localHistoryId |  | ||||||
|                 } |  | ||||||
|             }) |  | ||||||
|         }); |  | ||||||
|         const data = await response.json(); |  | ||||||
|         if (data.status === 0) { |  | ||||||
|             console.log('События чата успешно обновлены'); |  | ||||||
|         } else { |  | ||||||
|             console.error('Ошибка при обновлении событий чата:', data.error); |  | ||||||
|         } |  | ||||||
|     } catch (error) { |  | ||||||
|         console.error('Ошибка сети при обновлении событий чата:', error); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
							
								
								
									
										26
									
								
								assets/js/common-popup.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								assets/js/common-popup.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | |||||||
|  | let activePopupWinId = ""; | ||||||
|  | 
 | ||||||
|  | function activatePopupWindow__(el){ | ||||||
|  |     let veil = document.createElement("div"); | ||||||
|  |     veil.id = "popup-overlay-veil-OBJ" | ||||||
|  |     veil.className = "popup-overlay-veil"; | ||||||
|  |     veil.style.display = "block"; | ||||||
|  |     document.body.appendChild(veil); | ||||||
|  |     el.style.display = "block"; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function activatePopupWindowById(id){ | ||||||
|  |     if (activePopupWinId !== "") | ||||||
|  |         return; | ||||||
|  |     /* Lmao, this thing is just... SO unsafe */ | ||||||
|  |     activePopupWinId = id; | ||||||
|  |     activatePopupWindow__(document.getElementById(id)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function deactivateActivePopup(){ | ||||||
|  |     if (activePopupWinId === "") | ||||||
|  |         return | ||||||
|  |     document.getElementById("popup-overlay-veil-OBJ").remove(); | ||||||
|  |     document.getElementById(activePopupWinId).style.display = "none"; | ||||||
|  |     activePopupWinId = ""; | ||||||
|  | } | ||||||
							
								
								
									
										77
									
								
								assets/js/common.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								assets/js/common.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,77 @@ | |||||||
|  | let dopDopYesYes = (ign) => {}; | ||||||
|  | 
 | ||||||
|  | function sleep(ms){ | ||||||
|  |     return new Promise(res => setTimeout(res, ms)); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | async function apiRequest(type, req){ | ||||||
|  |     let A = await fetch("/api/" + type, | ||||||
|  |         {method: 'POST', body: JSON.stringify(req)}); | ||||||
|  |     let B = await A.json(); | ||||||
|  |     if (B.status !== 0) | ||||||
|  |         throw Error("Server returned non-zero status"); | ||||||
|  |     return B; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Framework for pages with mainloop (it can be npt only polling, but also literally anything else */ | ||||||
|  | let __mainloopDelayMs = 3000; | ||||||
|  | let mainloopTimeout = null; | ||||||
|  | let __guestMainloopPollerAction = null; | ||||||
|  | function setMainloopTimeout(){ | ||||||
|  |     if (mainloopTimeout !== null) | ||||||
|  |         return; | ||||||
|  |     mainloopTimeout = setTimeout(mainloopPoller, __mainloopDelayMs); | ||||||
|  | } | ||||||
|  | function cancelMainloopTimeout(){ | ||||||
|  |     if (mainloopTimeout === null){ | ||||||
|  |         console.log("cancelling nothing") | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |     clearTimeout(mainloopTimeout); | ||||||
|  |     mainloopTimeout = null; | ||||||
|  | } | ||||||
|  | function mainloopPoller(){ | ||||||
|  |     mainloopTimeout = null; | ||||||
|  |     try { | ||||||
|  |         if (__guestMainloopPollerAction) | ||||||
|  |             __guestMainloopPollerAction(); | ||||||
|  |     } catch (error){ | ||||||
|  |         console.log(error) | ||||||
|  |     } | ||||||
|  |     setMainloopTimeout(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // 1
 | ||||||
|  | const userChatRoleAdmin = "admin"; | ||||||
|  | // 2
 | ||||||
|  | const userChatRoleRegular = "regular"; | ||||||
|  | // 3
 | ||||||
|  | const userChatRoleReadOnly = "read-only"; | ||||||
|  | // 4
 | ||||||
|  | const userChatRoleDeleted = "not-a-member"; | ||||||
|  | 
 | ||||||
|  | function roleToColor(role) { | ||||||
|  |     if (role === userChatRoleAdmin) { | ||||||
|  |         return "#aafff3"; | ||||||
|  |     } else if (role === userChatRoleRegular){ | ||||||
|  |         return "#ffffff"; | ||||||
|  | 
 | ||||||
|  |     } else if (role === userChatRoleReadOnly){ | ||||||
|  |         return "#bfb2b2"; | ||||||
|  |     } else if (role === userChatRoleDeleted) { | ||||||
|  |         return "#fb4a4a"; | ||||||
|  |     } | ||||||
|  |     return "#286500"  // Bug
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function hideHTMLElement(el){ | ||||||
|  |     el.style.display = "none"; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function showHTMLElement(el){ | ||||||
|  |     el.style.display = "block"; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function setElementVisibility(el, isVisible, howVisible = "block"){ | ||||||
|  |     el.style.display = isVisible ? howVisible : "none"; | ||||||
|  | } | ||||||
| @ -1,10 +0,0 @@ | |||||||
| document.getElementById('fileInput').addEventListener('change', function(event) { |  | ||||||
|     const file = event.target.files[0]; |  | ||||||
|     if (file) { |  | ||||||
|         const reader = new FileReader(); |  | ||||||
|         reader.onload = function(e) { |  | ||||||
|             document.getElementById('avatar').src = e.target.result; |  | ||||||
|         }; |  | ||||||
|         reader.readAsDataURL(file); |  | ||||||
|     } |  | ||||||
| }); |  | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 yakovlevanton
						yakovlevanton