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
This commit is contained in:
parent
c009b848b5
commit
07711a93b0
@ -5,25 +5,12 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Веб-Чат Members</title>
|
<title>Веб-Чат Members</title>
|
||||||
<link rel="stylesheet" href="/assets/css/chat.css">
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
{% PUT chat.pass pres userinfo openedchat initial_chatUpdResp %}
|
{% PUT chat.pass pres userinfo openedchat initial_chatUpdResp %}
|
||||||
<!--TODO: ADD SOMETHING WRITE SOMETHING AAAAAA -->
|
<!--TODO: ADD SOMETHING WRITE SOMETHING AAAAAA -->
|
||||||
<div class="overlay" id="overlay">
|
<h1> Chat member list page for {% WRITE openedchat.nickname%}, not ready yet</h1>
|
||||||
<div class="members-list" id="members-list">
|
<!--<script src="/assets/js/chat-members.js"></script>-->
|
||||||
<div class="members-list-header">
|
|
||||||
<span class="close" onclick="closeMembersList()">×</span>
|
|
||||||
<h2 class="all-members">Все участники</h2>
|
|
||||||
</div>
|
|
||||||
<div class="members-list-body">
|
|
||||||
<ul id="members-list-body">
|
|
||||||
<!-- Список участников будет добавлен динамически -->
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<script src="/assets/js/chat-members.js"></script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
{% ENDELDEF %}
|
{% ENDELDEF %}
|
||||||
|
@ -9,17 +9,36 @@
|
|||||||
|
|
||||||
{% ELDEF main JSON pres JSON userinfo JSON openedchat JSON initial_chatUpdResp %}
|
{% ELDEF main JSON pres JSON userinfo JSON openedchat JSON initial_chatUpdResp %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="ru">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Веб-Чат</title>
|
<link rel="stylesheet" href="/assets/css/common.css">
|
||||||
<link rel="stylesheet" href="/assets/css/chat.css">
|
<link rel="stylesheet" href="/assets/css/chat.css">
|
||||||
|
<title>Chat </title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
{% PUT chat.pass pres userinfo openedchat initial_chatUpdResp %}
|
<!-- Write the actual chat script -->
|
||||||
<!-- TODO AAAAA-->
|
<!--% PUT chat.pass pres userinfo openedchat initial_chatUpdResp %-->
|
||||||
|
<div id="fullscreen-container">
|
||||||
|
<div class="panel" id="navigation-info-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/{% WRITE 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"> {% WRITE openedchat.name %} ({% WRITE openedchat.nickname %})</p>
|
||||||
|
<a href="/chat-members/{% WRITE openedchat.nickname %}" id="go-to-chat-settings" class="panel-thing">
|
||||||
|
<img alt="Settings of chat. List of members" src="/assets/img/settings-iron.svg" width="32px">
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div id="chat-widget"></div>
|
||||||
|
<div class="panel" id="input-panel">
|
||||||
|
<div contentEditable id="message-input" class="panel-thing"></div>
|
||||||
|
</div>
|
||||||
<script src="/assets/js/chat.js"></script>
|
<script src="/assets/js/chat.js"></script>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
{% ENDELDEF %}
|
{% ENDELDEF %}
|
||||||
|
@ -1,42 +1,68 @@
|
|||||||
{% ELDEF main JSON pres JSON userprofile JSON errors %}
|
{% ELDEF main JSON pres JSON userinfo JSON alienprofile JSON errors %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link rel="stylesheet" href="/assets/css/profile.css">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Профиль</title>
|
<link rel="stylesheet" href="/assets/css/common.css">
|
||||||
|
<link rel="stylesheet" href="/assets/css/edit-profile.css">
|
||||||
|
<title>Edit user Profile</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="main-container">
|
|
||||||
|
<div id="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/{% WRITE 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 %}
|
{% FOR error IN errors %}
|
||||||
<div>
|
<div class="server-notif-error-msg-box">
|
||||||
<p>{% WRITE error.text %}</p>
|
{% WRITE error.text %}
|
||||||
</div>
|
</div>
|
||||||
{% ENDFOR %}
|
{% ENDFOR %}
|
||||||
<div class="profile-header">
|
|
||||||
<h1>Редактирование профиля</h1>
|
<div class="profile-container">
|
||||||
|
<h2 class="profile-name-text">{% WRITE alienprofile.name %}</h2>
|
||||||
|
<h3 class="profile-nickname-text">Nickname: {% WRITE alienprofile.nickname %}</h3>
|
||||||
|
<p class="profile-bio-text">
|
||||||
|
{% WRITE alienprofile.bio %}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<form method="post" action="/user/{% WRITE userprofile.nickname %}">
|
|
||||||
<div class="columns">
|
<div class="profile-container">
|
||||||
<div class="column">
|
<h1 class="wide-centered-header">Change user attributes</h1>
|
||||||
<p>{% WRITE userprofile.name %} ( {% WRITE userprofile.nickname %} )</p>
|
<form action = "/user/{% WRITE alienprofile.nickname %}" method="post" enctype="application/x-www-form-urlencoded">
|
||||||
<label for="name"> Изменить имя </label>
|
<table class="logins-input-table">
|
||||||
<input type="text" name="name" id="name">
|
<tr>
|
||||||
|
<td class="logins-input-td1">
|
||||||
|
<label for="new-name-input">Enter new name:</label>
|
||||||
|
</td>
|
||||||
|
<td class="logins-input-td2">
|
||||||
|
<input name="name" id="new-name-input" type="text" placeholder="New name" class="one-line-input">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="logins-input-td1">
|
||||||
|
<label for="new-password-input">Enter new password: </label>
|
||||||
|
</td>
|
||||||
|
<td class="logins-input-td2">
|
||||||
|
<input name="password" id="new-password-input" type="password" placeholder="New password" class="one-line-input">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<label for="input-change-bio">Change description:</label>
|
||||||
<br>
|
<br>
|
||||||
<label for="password"> Изменить пароль </label>
|
<textarea name="bio" id="input-change-bio" class="multiline-input"></textarea>
|
||||||
<input type="password" name="password" id="password">
|
<button class="action-button centered-block-el" type="submit">Submit changes</button>
|
||||||
<br>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="additional-info">
|
|
||||||
<p>О себе</p>
|
|
||||||
<p>{% WRITE userprofile.bio %}</p><br>
|
|
||||||
<label for="bio">Изменить</label>
|
|
||||||
<textarea name="bio" id="bio"></textarea>
|
|
||||||
</div>
|
|
||||||
<button class="save" type="submit">Сохранить изменения</button>
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
{% ENDELDEF%}
|
{% ENDELDEF%}
|
||||||
|
@ -4,7 +4,9 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Список Чат-Комнат</title>
|
<title>List of chat rooms</title>
|
||||||
|
<link rel="stylesheet" href="/assets/css/common.css">
|
||||||
|
<link rel="stylesheet" href="/assets/css/common-popup.css">
|
||||||
<link rel="stylesheet" href="/assets/css/list-rooms.css">
|
<link rel="stylesheet" href="/assets/css/list-rooms.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -13,59 +15,36 @@
|
|||||||
let userinfo = {% PUT jsinsert userinfo %};
|
let userinfo = {% PUT jsinsert userinfo %};
|
||||||
let initial_chatListUpdResp = {% PUT jsinsert initial_chatListUpdResp %};
|
let initial_chatListUpdResp = {% PUT jsinsert initial_chatListUpdResp %};
|
||||||
</script>
|
</script>
|
||||||
<div class="container">
|
<div id="popup-overlay-veil"></div>
|
||||||
<h1 style="color: white;">Выберите Чат-Комнату</h1>
|
<div id="chat-creation-win" class="popup-window">
|
||||||
<ul class="room-list">
|
<h1>Input identifying information for your new chat</h1>
|
||||||
<!-- Здесь будет список комнат -->
|
|
||||||
</ul>
|
|
||||||
<button class="create-room-button" onclick="openCreateRoomModal()">Создать Комнату</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Модальное окно для создания комнаты -->
|
<div id="chat-renunciation-win" class="popup-window">
|
||||||
<!--<div id="createRoomModal" class="modal">-->
|
<!-- header will actually be rewritten before showing the window to include chat nickname -->
|
||||||
<!-- <div class="modal-content">-->
|
<h1 id="chat-renunciation-win-title">Are you sure you want to leave chat?</h1>
|
||||||
<!-- <div class="modal-header">-->
|
<button class="chat-renunciation-win-yes">Yes, leave</button>
|
||||||
<!-- <span class="close" onclick="closeCreateRoomModal()">×</span>-->
|
<button class="chat-renunciation-win-no">No, cancel</button>
|
||||||
<!-- <h2>Создать Комнату</h2>-->
|
</div>
|
||||||
<!-- </div>-->
|
|
||||||
<!-- <div class="modal-body">-->
|
|
||||||
<!-- <input type="text" id="newRoomName" placeholder="Название комнаты">-->
|
|
||||||
<!-- <input type="password" id="newRoomNickname" placeholder="Никнейм комнаты">-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- <div id="error"></div>-->
|
|
||||||
<!-- <div class="modal-footer">-->
|
|
||||||
<!-- <button class="join-button" onclick="createRoom()">Создать</button>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!--</div>-->
|
|
||||||
|
|
||||||
<!--<!– Модальное окно для добавления участников –>-->
|
x
|
||||||
<!--<div class="overlay" id="add_members">-->
|
<div id="document-container">
|
||||||
<!-- <div class="add-members">-->
|
<div id="navigation-panel" class="panel">
|
||||||
<!-- <div class="add-members-header">-->
|
<a href="/user/{% WRITE userinfo.nickname %}" id="go-to-my-profile" class="panel-thing">
|
||||||
<!-- <span class="close" onclick="closeAdd()">×</span>-->
|
<img alt="Go to my profile" src="/assets/img/user.svg" width="32px">
|
||||||
<!-- <h2>Добавить участников</h2>-->
|
</a>
|
||||||
<!-- </div>-->
|
<p class="panel-thing panel-header-txt">
|
||||||
<!-- <div class="add-members-body">-->
|
List of available rooms
|
||||||
<!-- <input type="text" id="newMemberLogin" placeholder="Логин пользователя">-->
|
</p>
|
||||||
<!-- </div>-->
|
</div>
|
||||||
<!-- <div class="add-members-footer">-->
|
|
||||||
<!-- <button class="add-member-button" onclick="addMember()">Добавить</button>-->
|
<div class="dynamic-block-list">
|
||||||
<!-- </div>-->
|
<img id="CL-bacbe" class="button-add centered-block-el" alt="New chat" src="/assets/img/add.svg">
|
||||||
<!-- </div>-->
|
<div class="dynamic-block-list-el-container" id="CL-dblec">
|
||||||
<!--</div>-->
|
|
||||||
<!--<div class="overlay" id="delete-chat">-->
|
</div>
|
||||||
<!-- <div class="delete-chat">-->
|
</div>
|
||||||
<!-- <div class="delete-chat-header">-->
|
</div>
|
||||||
<!-- <span class="delete-close" onclick="closeConfirm()">×</span>-->
|
|
||||||
<!-- <h2>Вы уверены, что хотите удалить чат?</h2>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- <div class="delete-chat-body">-->
|
|
||||||
<!-- <button class="confirm" onclick="deleteChat()">Да</button>-->
|
|
||||||
<!-- <button class="cancel" onclick="closeConfirm()">Нет</button>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!-- </div>-->
|
|
||||||
<!--</div>-->
|
|
||||||
<script src="/assets/js/list-rooms.js"></script>
|
<script src="/assets/js/list-rooms.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,27 +1,38 @@
|
|||||||
{% ELDEF main JSON pres JSON userinfo JSON errors %}
|
{% ELDEF main JSON pres JSON userinfo JSON errors %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="{% WRITE pres.lang %}">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>{% WRITE pres.phr.decl.page-login %}</title>
|
<link rel="stylesheet" href="/assets/css/common.css">
|
||||||
<link rel="stylesheet" href="/assets/css/login.css">
|
<link rel="stylesheet" href="/assets/css/login.css">
|
||||||
|
<title>Login Page</title>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
{% FOR msg IN errors %}
|
{% FOR error IN errors %}
|
||||||
<div class="error-msg">
|
<div class="server-notif-error-msg-box">
|
||||||
{% WRITE msg.text %}
|
{% WRITE error.text %}
|
||||||
</div>
|
</div>
|
||||||
{% ENDFOR %}
|
{% ENDFOR %}
|
||||||
|
|
||||||
<div class="form-container">
|
<div class="form-container">
|
||||||
<h1 class="hide-cursor no-select">{% WRITE pres.phr.decl.enter %}</h1>
|
<h1 class="wide-centered-header">Login</h1>
|
||||||
<form action="/login" method="post" enctype="application/x-www-form-urlencoded">
|
<form action="/login" method="post" enctype="application/x-www-form-urlencoded">
|
||||||
<label for="nickname">{% WRITE pres.phr.decl.nickname %}</label>
|
<table class="logins-input-table">
|
||||||
<input type="text" name="nickname" id="nickname"><br>
|
<tr>
|
||||||
<label for="password">{% WRITE pres.phr.decl.password %}</label>
|
<td class="logins-input-td1"><label for="input-nickname">Enter user nickname:</label></td>
|
||||||
<input type="password" name="password" id="password"><br>
|
<td class="logins-input-td2">
|
||||||
<button type="submit" class="hide-cursor no-select">{% WRITE pres.phr.act.enter %}</button>
|
<input name="nickname" id="input-nickname" type="text" placeholder="Nickname" class="one-line-input" required>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="logins-input-td1"><label for="input-password">Enter password:</label></td>
|
||||||
|
<td class="logins-input-td2">
|
||||||
|
<input name="password" id="input-password" type="password" placeholder="Password" class="one-line-input" required>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<button class="action-button centered-block-el" type="submit">Login</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1,26 +1,35 @@
|
|||||||
{% ELDEF main JSON pres JSON userprofile %}
|
{% ELDEF main JSON pres JSON userinfo JSON alienprofile %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link rel="stylesheet" href="/assets/css/profile.css">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>Профиль</title>
|
<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>User Profile</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="main-container">
|
|
||||||
<div class="profile-header">
|
<div id="document-container">
|
||||||
<h1>Профиль пользователя</h1>
|
<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/{% WRITE 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>
|
||||||
<div class="columns">
|
|
||||||
<div class="column">
|
<div class="profile-container">
|
||||||
<p>{% WRITE userprofile.name %} ( {% WRITE userprofile.nickname %} )</p>
|
<h2 class="profile-name-text">{% WRITE alienprofile.name %}</h2>
|
||||||
</div>
|
<h3 class="profile-nickname-text">Nickname: {% WRITE alienprofile.nickname %}</h3>
|
||||||
</div>
|
<p class="profile-bio-text">
|
||||||
<div class="additional-info">
|
{% WRITE alienprofile.bio %}
|
||||||
<p>О себе</p>
|
</p>
|
||||||
<p>{% WRITE userprofile.bio %}</p><br>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
{% ENDELDEF%}
|
{% ENDELDEF%}
|
||||||
|
@ -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;
|
||||||
|
}
|
30
assets/css/common-popup.css
Normal file
30
assets/css/common-popup.css
Normal file
@ -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;
|
||||||
|
}
|
193
assets/css/common.css
Normal file
193
assets/css/common.css
Normal file
@ -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;
|
||||||
|
}
|
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,253 +1,35 @@
|
|||||||
body {
|
#navigation-panel {
|
||||||
font-family: Arial, sans-serif;
|
align-items: center;
|
||||||
background-color: #f0f0f0;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
#CL-bacbe {
|
||||||
max-width: 800px;
|
margin: 6px;
|
||||||
margin: 30px auto;
|
|
||||||
padding: 20px;
|
|
||||||
background-color: #007bff;
|
|
||||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
.CL-my-chat-box {
|
||||||
text-align: center;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.room-list {
|
|
||||||
list-style-type: none;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.room-item {
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
flex-direction: row;
|
||||||
align-items: center;
|
|
||||||
padding: 15px;
|
|
||||||
margin: 10px 0;
|
|
||||||
background-color: #fafafa;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
border-radius: 5px;
|
|
||||||
transition: background-color 0.3s ease;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.room-item:hover {
|
.CL-my-chat-box-nickname {
|
||||||
background-color: #eaeaea;
|
margin-left: 8px;
|
||||||
|
justify-self: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.room-name {
|
.CL-my-chat-box-name {
|
||||||
font-size: 18px;
|
margin-left: 14px;
|
||||||
color: #555;
|
justify-self: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.join-button {
|
.CL-my-chat-box-my-role {
|
||||||
padding: 10px 15px;
|
margin-left: auto;
|
||||||
font-size: 16px;
|
justify-self: flex-end;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal {
|
.CL-my-chat-box-leave-btn {
|
||||||
display: none;
|
margin-left: 10px;
|
||||||
position: fixed;
|
margin-right: 8px;
|
||||||
z-index: 1;
|
justify-self: flex-end;
|
||||||
left: 0;
|
width: 16px;
|
||||||
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;
|
|
||||||
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;
|
cursor: pointer;
|
||||||
}
|
}
|
@ -1,59 +1,34 @@
|
|||||||
/* I have no idea what is going on here */
|
|
||||||
body {
|
body {
|
||||||
font-family: Arial, sans-serif;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 100vh;
|
height: 100vh; /* Full viewport height */
|
||||||
margin: 0;
|
margin: 0;
|
||||||
background-color: #e5e5e5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-container {
|
.form-container {
|
||||||
width: 100%;
|
background-color: #ffffff; /* Brighter box color */
|
||||||
max-width: 400px;
|
padding: 20px;
|
||||||
background-color: white;
|
border-radius: 10px;
|
||||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
|
||||||
display: flex;
|
width: 50%; /* Set width of the form */
|
||||||
flex-direction: column;
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 40px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
/* The morbid thing */
|
||||||
margin-bottom: 20px;
|
table.logins-input-table {
|
||||||
color: #2F4F4F;
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
background: #f7f7f7;
|
border-collapse: collapse; /* Combine borders */
|
||||||
font-size: 16px;
|
|
||||||
padding: 10px;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
border-radius: 20px;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
outline: none;
|
|
||||||
}
|
}
|
||||||
|
.logins-input-td1, .logins-input-td2 {
|
||||||
button {
|
|
||||||
width: 100%;
|
|
||||||
padding: 15px;
|
|
||||||
border: none;
|
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;
|
|
||||||
}
|
}
|
||||||
|
.logins-input-td1 {
|
||||||
.error-msg {
|
padding-right: 5px;
|
||||||
color: red;
|
white-space: nowrap; /* Prevent text wrap, keeping it in one line */
|
||||||
background-color: #ffc0c0;
|
overflow: hidden; /* Hide overflow content */
|
||||||
border-color: red;
|
text-overflow: ellipsis; /* Show ellipsis for overflowing text */
|
||||||
border-radius: 5px;
|
}
|
||||||
|
.logins-input-td2 {
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
@ -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;
|
|
||||||
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
@ -1,186 +1,72 @@
|
|||||||
let rooms = {};
|
let LocalHistoryId = 0;
|
||||||
let roomToDelete = null;
|
|
||||||
let currentRoom = null;
|
|
||||||
let currentHistoryId = 0;
|
|
||||||
|
|
||||||
function openRoom(currentRoom) {
|
let myChats = new Map();
|
||||||
alert('Вы вошли в комнату: ' + currentRoom);
|
let chatBoxes = new Map();
|
||||||
}
|
|
||||||
|
|
||||||
function closeAdd() {
|
const roleDeleted = "not-a-member";
|
||||||
document.getElementById('add_members').style.display = 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
function openAdd() {
|
function convertStToBox(myMembershipSt){
|
||||||
document.getElementById('add_members').style.display = 'flex';
|
let chatURI = "/user/" + myMembershipSt.chatNickname;
|
||||||
}
|
|
||||||
|
|
||||||
function openConfirm(roomNickname) {
|
let box = document.createElement("div");
|
||||||
roomToDelete = roomNickname;
|
chatBoxes.set(myMembershipSt.chatId, box);
|
||||||
document.getElementById("delete-chat").style.display = "flex";
|
box.className = "dynamic-block-list-el CL-my-chat-box";
|
||||||
}
|
|
||||||
|
|
||||||
function closeConfirm() {
|
let inBoxNickname = document.createElement("a");
|
||||||
roomToDelete = null;
|
box.appendChild(inBoxNickname);
|
||||||
document.getElementById("delete-chat").style.display = "none";
|
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() {
|
let inBoxName = document.createElement("a");
|
||||||
if (roomToDelete && rooms[roomToDelete]) {
|
box.appendChild(inBoxName);
|
||||||
delete rooms[roomToDelete];
|
inBoxName.className = "entity-reg-field-txt CL-my-chat-box-name";
|
||||||
removeRoomFromList(roomToDelete);
|
inBoxName.innerText = myMembershipSt.chatName;
|
||||||
closeConfirm();
|
inBoxName.href = chatURI;
|
||||||
} else {
|
|
||||||
alert("Не удалось найти выбранную комнату.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function addMember() {
|
let inBoxMyRoleHere = document.createElement("p");
|
||||||
const login = document.getElementById('newMemberLogin').value;
|
box.appendChild(inBoxMyRoleHere);
|
||||||
if (login) {
|
inBoxMyRoleHere.className = "entity-reg-field-txt CL-my-chat-box-my-role";
|
||||||
alert(`Участник с никнеймом '${login}' добавлен`);
|
inBoxMyRoleHere.innerText = "You are " + myMembershipSt.myRoleHere + " here";
|
||||||
closeAdd();
|
|
||||||
} else {
|
|
||||||
alert('Пожалуйста, введите логин участника');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function openCreateRoomModal() {
|
let ID = myMembershipSt.chatId;
|
||||||
document.getElementById('createRoomModal').style.display = 'block';
|
|
||||||
}
|
|
||||||
|
|
||||||
function closeCreateRoomModal() {
|
let inBoxLeaveBtn = document.createElement("img");
|
||||||
document.getElementById('createRoomModal').style.display = 'none';
|
box.appendChild(inBoxLeaveBtn);
|
||||||
}
|
inBoxLeaveBtn.className = "CL-my-chat-box-leave-btn";
|
||||||
|
inBoxLeaveBtn.src = "/assets/img/delete.svg";
|
||||||
async function createRoom() {
|
inBoxLeaveBtn.onclick = function (ev) {
|
||||||
const errorElement = document.getElementById('error');
|
if (ev.button === 0){
|
||||||
const roomName = document.getElementById('newRoomName').value.trim();
|
console.log("Tried to leave chat" + ID);
|
||||||
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
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
return box;
|
||||||
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);
|
window.onload = function () {
|
||||||
|
console.log("Loading complete");
|
||||||
|
LocalHistoryId = initial_chatListUpdResp.HistoryId;
|
||||||
|
|
||||||
|
console.log(initial_chatListUpdResp);
|
||||||
|
|
||||||
|
let literalChatList = document.getElementById("CL-dblec");
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function addRoomToList(roomName) {
|
document.getElementById("CL-bacbe").onclick = function (ev){
|
||||||
const roomList = document.querySelector('.room-list');
|
if (ev.button === 0){
|
||||||
const existingRoomItem = Array.from(roomList.children).find(item => item.querySelector('.room-name').textContent === roomName);
|
|
||||||
if (existingRoomItem) {
|
|
||||||
existingRoomItem.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
const roomItem = document.createElement('li');
|
|
||||||
roomItem.classList.add('room-item');
|
|
||||||
|
|
||||||
roomItem.innerHTML = `
|
|
||||||
<span class="room-name">${roomName}</span>
|
|
||||||
<button class="delete-chat-button" onclick="openConfirm('${roomNickname}')">Удалить чат</button>
|
|
||||||
<button class="add-members-button" onclick="openAdd()">Добавить участников</button>
|
|
||||||
<button class="join-button" onclick="window.location.href = '/chat/${roomNickname}'">Войти</button>
|
|
||||||
`;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
|
@ -112,6 +112,10 @@ namespace een9 {
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
res.body.reserve(std::min(100000ul, body_size));
|
res.body.reserve(std::min(100000ul, body_size));
|
||||||
|
if (body_size == 0) {
|
||||||
|
status = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!res.has_body) {
|
if (!res.has_body) {
|
||||||
|
@ -55,13 +55,16 @@ namespace nytl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
char skip(ParsingContext& ctx) {
|
char skip(ParsingContext& ctx) {
|
||||||
ASSERT(ctx.pos < ctx.text.size(), "Unexpected EOF");
|
if (ctx.pos >= ctx.text.size())
|
||||||
|
THROW("Unexpected EOF");
|
||||||
return advance(ctx);
|
return advance(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void skip(ParsingContext& ctx, char ch) {
|
void skip(ParsingContext& ctx, char ch) {
|
||||||
ASSERT(ctx.pos < ctx.text.size(), "Unexpected EOF");
|
if (ctx.pos >= ctx.text.size())
|
||||||
ASSERT(ctx.text[ctx.pos] == ch, "Unexpected character");
|
THROW("Unexpected EOF");
|
||||||
|
if (ctx.text[ctx.pos] != ch)
|
||||||
|
THROW("Unexpected character");
|
||||||
advance(ctx);
|
advance(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +153,8 @@ namespace nytl {
|
|||||||
void parse_bare_file(const std::string& filename, const std::string& content,
|
void parse_bare_file(const std::string& filename, const std::string& content,
|
||||||
global_elem_set_t& result)
|
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);
|
std::string txt = clement_lstrip(content);
|
||||||
rstrip(txt);
|
rstrip(txt);
|
||||||
size_t cut = 9999999999999;
|
size_t cut = 9999999999999;
|
||||||
@ -170,13 +174,15 @@ namespace nytl {
|
|||||||
uptr<TPFrame> toMe(bool returned, ParsingContext& ctx) {
|
uptr<TPFrame> toMe(bool returned, ParsingContext& ctx) {
|
||||||
if (!returned) {
|
if (!returned) {
|
||||||
std::string nm = readName(ctx);
|
std::string nm = readName(ctx);
|
||||||
ASSERT(!nm.empty(), "Type specification expected");
|
if (nm.empty())
|
||||||
|
THROW("Type specification expected");
|
||||||
nm = make_uppercase(nm);
|
nm = make_uppercase(nm);
|
||||||
if (nm == "JSON") {
|
if (nm == "JSON") {
|
||||||
result = json::JSON(true);
|
result = json::JSON(true);
|
||||||
return NULL;
|
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, '(');
|
skip(ctx, '(');
|
||||||
result.asArray();
|
result.asArray();
|
||||||
assert(result.isArray());
|
assert(result.isArray());
|
||||||
@ -217,8 +223,10 @@ namespace nytl {
|
|||||||
uptr<EPFrame> toMe(bool returned, ParsingContext& ctx, const arg_name_list_t& local_var_names) {
|
uptr<EPFrame> toMe(bool returned, ParsingContext& ctx, const arg_name_list_t& local_var_names) {
|
||||||
if (!returned) {
|
if (!returned) {
|
||||||
std::string first = readName(ctx);
|
std::string first = readName(ctx);
|
||||||
ASSERT(!first.empty(), "Expression should start with 'root' name of global package or local variable");
|
if (first.empty())
|
||||||
ASSERT(first != "_", "_ ??? ARE YOU KIDDING???");
|
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) {
|
if (local_var_names.count(first) == 1) {
|
||||||
result["V"].asInteger() = json::Integer((int64_t)local_var_names.at(first));
|
result["V"].asInteger() = json::Integer((int64_t)local_var_names.at(first));
|
||||||
} else {
|
} else {
|
||||||
@ -243,7 +251,8 @@ namespace nytl {
|
|||||||
t = readUint(ctx);
|
t = readUint(ctx);
|
||||||
if (!t.empty()) {
|
if (!t.empty()) {
|
||||||
size_t v = std::stoul(t);
|
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);
|
chain.back() = json::JSON((int64_t)v);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -352,7 +361,8 @@ namespace nytl {
|
|||||||
ElementPart::when_for_put_S& P = result.parts.back().when_for_put;
|
ElementPart::when_for_put_S& P = result.parts.back().when_for_put;
|
||||||
skipWhitespace(ctx);
|
skipWhitespace(ctx);
|
||||||
std::string V1 = readName(ctx);
|
std::string V1 = readName(ctx);
|
||||||
ASSERT(!V1.empty(), "Expected variable name");
|
if (V1.empty())
|
||||||
|
THROW("Expected variable name");
|
||||||
skipWhitespace(ctx);
|
skipWhitespace(ctx);
|
||||||
bool have_colon_and_2 = false;
|
bool have_colon_and_2 = false;
|
||||||
std::string V2;
|
std::string V2;
|
||||||
@ -364,7 +374,8 @@ namespace nytl {
|
|||||||
skipWhitespace(ctx);
|
skipWhitespace(ctx);
|
||||||
}
|
}
|
||||||
op = make_uppercase(readName(ctx));
|
op = make_uppercase(readName(ctx));
|
||||||
ASSERT(op == "IN", "Expected IN");
|
if (op != "IN")
|
||||||
|
THROW("Expected IN");
|
||||||
skipWhitespace(ctx);
|
skipWhitespace(ctx);
|
||||||
P.ref_over = parse_expression(ctx, local_var_names);
|
P.ref_over = parse_expression(ctx, local_var_names);
|
||||||
P.internal_element = el_name + ".~" + std::to_string(free_hidden++);
|
P.internal_element = el_name + ".~" + std::to_string(free_hidden++);
|
||||||
@ -372,13 +383,15 @@ namespace nytl {
|
|||||||
newborn.is_hidden = true;
|
newborn.is_hidden = true;
|
||||||
arg_name_list_t local_var_names_of_nxt = local_var_names;
|
arg_name_list_t local_var_names_of_nxt = local_var_names;
|
||||||
if (V1 != "_") {
|
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();
|
size_t k = local_var_names_of_nxt.size();
|
||||||
local_var_names_of_nxt.emplace(V1, k);
|
local_var_names_of_nxt.emplace(V1, k);
|
||||||
(have_colon_and_2 ? P.where_key_var : P.where_value_var) = (ssize_t)k;
|
(have_colon_and_2 ? P.where_key_var : P.where_value_var) = (ssize_t)k;
|
||||||
}
|
}
|
||||||
if (have_colon_and_2 && V2 != "_") {
|
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();
|
size_t k = local_var_names_of_nxt.size();
|
||||||
local_var_names_of_nxt.emplace(V2, k);
|
local_var_names_of_nxt.emplace(V2, k);
|
||||||
P.where_value_var = (ssize_t)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;
|
ElementPart::when_ref_put_S& P = result.parts.back().when_ref_put;
|
||||||
skipWhitespace(ctx);
|
skipWhitespace(ctx);
|
||||||
std::string Vn = readName(ctx);
|
std::string Vn = readName(ctx);
|
||||||
ASSERT(!Vn.empty(), "Expected variable name");
|
if (Vn.empty() || Vn == "_")
|
||||||
ASSERT(Vn != "_", "Are you kidding???");
|
THROW("REF: expected variable name");
|
||||||
skipWhitespace(ctx);
|
skipWhitespace(ctx);
|
||||||
op = make_uppercase(readName(ctx));
|
op = make_uppercase(readName(ctx));
|
||||||
ASSERT(op == "AS", "Expected AS");
|
if (op != "AS")
|
||||||
|
THROW("Expected AS");
|
||||||
skipWhitespace(ctx);
|
skipWhitespace(ctx);
|
||||||
P.ref_over = parse_expression(ctx, local_var_names);
|
P.ref_over = parse_expression(ctx, local_var_names);
|
||||||
P.internal_element = el_name + ".~" + std::to_string(free_hidden++);
|
P.internal_element = el_name + ".~" + std::to_string(free_hidden++);
|
||||||
@ -467,13 +481,15 @@ namespace nytl {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (op == "ENDELDEF") {
|
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);
|
skip_magic_block_end(ctx, syntax);
|
||||||
prepare_to_depart_parts();
|
prepare_to_depart_parts();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (op == "ENDFOR") {
|
if (op == "ENDFOR") {
|
||||||
ASSERT(myself == gone_for_for, "Unexpected end of for cycle");
|
if (myself != gone_for_for)
|
||||||
|
THROW("Unexpected ENDFOR");
|
||||||
skipWhitespace(ctx);
|
skipWhitespace(ctx);
|
||||||
/* Here I am using ret_data_int to return info about NOLF(1)/LF(2) decision */
|
/* 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
|
ret_data_int = 2; // Default is to do LF
|
||||||
@ -491,7 +507,8 @@ namespace nytl {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (op == "ENDREF") {
|
if (op == "ENDREF") {
|
||||||
assert(myself == gone_for_ref);
|
if (myself != gone_for_ref)
|
||||||
|
THROW("Unexpected ENDREF");
|
||||||
skip_magic_block_end(ctx, syntax);
|
skip_magic_block_end(ctx, syntax);
|
||||||
prepare_to_depart_parts();
|
prepare_to_depart_parts();
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -525,12 +542,15 @@ namespace nytl {
|
|||||||
if (peep(ctx) == EOFVAL)
|
if (peep(ctx) == EOFVAL)
|
||||||
break;
|
break;
|
||||||
skip_magic_block_start(ctx, syntax);
|
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);
|
skipWhitespace(ctx);
|
||||||
std::string elname_postfix = readName(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;
|
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];
|
Element& newborn = result[fullname];
|
||||||
arg_name_list_t arglist;
|
arg_name_list_t arglist;
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -540,9 +560,11 @@ namespace nytl {
|
|||||||
newborn.arguments.push_back(parse_type(ctx));
|
newborn.arguments.push_back(parse_type(ctx));
|
||||||
skipWhitespace(ctx);
|
skipWhitespace(ctx);
|
||||||
std::string argname = readName(ctx);
|
std::string argname = readName(ctx);
|
||||||
ASSERT(!argname.empty(), "Expected argument name");
|
if (argname.empty())
|
||||||
|
THROW("Expected argument name");
|
||||||
if (argname != "_") {
|
if (argname != "_") {
|
||||||
ASSERT(arglist.count(argname) == 0, "Repeated argument (" + argname + ")");
|
if (arglist.count(argname) != 0)
|
||||||
|
THROW("Repeated argument (" + argname + ")");
|
||||||
size_t k = arglist.size();
|
size_t k = arglist.size();
|
||||||
arglist[argname] = k;
|
arglist[argname] = k;
|
||||||
}
|
}
|
||||||
|
@ -212,7 +212,7 @@ namespace nytl {
|
|||||||
const std::function<std::string(std::string)> &escape) {
|
const std::function<std::string(std::string)> &escape) {
|
||||||
if (!returned)
|
if (!returned)
|
||||||
if (elem_ns.count(name) != 1)
|
if (elem_ns.count(name) != 1)
|
||||||
THROW("No such element");
|
THROW("No such element (" + name + ")");
|
||||||
const Element& el = elem_ns.at(name);
|
const Element& el = elem_ns.at(name);
|
||||||
if (!returned) {
|
if (!returned) {
|
||||||
/* Continue to do checks */
|
/* Continue to do checks */
|
||||||
@ -227,7 +227,9 @@ namespace nytl {
|
|||||||
// If not json is expected, element must be expected
|
// If not json is expected, element must be expected
|
||||||
assert(el.arguments[i].isArray());
|
assert(el.arguments[i].isArray());
|
||||||
ASSERT(!passed_args[i].is_json, "Expected element element arguemnt, got json");
|
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);
|
const Element& arg_element = elem_ns.at(passed_args[i].EL_name);
|
||||||
// ASSERT(passed_args);
|
// ASSERT(passed_args);
|
||||||
if(el.arguments[i].asArray() != arg_element.arguments)
|
if(el.arguments[i].asArray() != arg_element.arguments)
|
||||||
|
@ -8,7 +8,7 @@ namespace iu9cawebchat {
|
|||||||
SqliteStatement my_membership_changes(conn,
|
SqliteStatement my_membership_changes(conn,
|
||||||
"SELECT `chatId`, `role` FROM `user_chat_membership` WHERE `userId` = ?1 "
|
"SELECT `chatId`, `role` FROM `user_chat_membership` WHERE `userId` = ?1 "
|
||||||
"AND `user_chatList_IncHistoryId` > ?2", {{1, userId}, {2, LocalHistoryId}});
|
"AND `user_chatList_IncHistoryId` > ?2", {{1, userId}, {2, LocalHistoryId}});
|
||||||
json::jarr myChats = chatListUpdResp["myChats"].asArray();
|
json::jarr& myChats = chatListUpdResp["myChats"].asArray();
|
||||||
while (true) {
|
while (true) {
|
||||||
fsql_integer_or_null ev_chatId, usersRoleHere;
|
fsql_integer_or_null ev_chatId, usersRoleHere;
|
||||||
int status = sqlite_stmt_step(my_membership_changes, {{0, &ev_chatId}, {1, &usersRoleHere}}, {});
|
int status = sqlite_stmt_step(my_membership_changes, {{0, &ev_chatId}, {1, &usersRoleHere}}, {});
|
||||||
@ -73,7 +73,7 @@ namespace iu9cawebchat {
|
|||||||
json::jarr members;
|
json::jarr members;
|
||||||
|
|
||||||
SqliteStatement membership_changes(conn,
|
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}}, {});
|
"AND `chat_IncHistoryId` > ?2", {{1, chatId}, {2, LocalHistoryId}}, {});
|
||||||
while (true) {
|
while (true) {
|
||||||
fsql_integer_or_null alienUserId;
|
fsql_integer_or_null alienUserId;
|
||||||
|
@ -7,8 +7,10 @@ namespace iu9cawebchat {
|
|||||||
std::string when_page_chat(WorkerGuestData& wgd, const json::JSON& config_presentation,
|
std::string when_page_chat(WorkerGuestData& wgd, const json::JSON& config_presentation,
|
||||||
const een9::ClientRequest& req, const json::JSON& userinfo) {
|
const een9::ClientRequest& req, const json::JSON& userinfo) {
|
||||||
|
|
||||||
std::vector<std::string> path_segs = {""};
|
std::vector<std::string> path_segs = {};
|
||||||
path_segs.reserve(4);
|
path_segs.reserve(4);
|
||||||
|
if (req.uri_path.empty() || req.uri_path[0] != '/')
|
||||||
|
return page_E404(wgd);
|
||||||
for (char ch: req.uri_path) {
|
for (char ch: req.uri_path) {
|
||||||
if (ch == '/')
|
if (ch == '/')
|
||||||
path_segs.emplace_back();
|
path_segs.emplace_back();
|
||||||
@ -31,16 +33,18 @@ namespace iu9cawebchat {
|
|||||||
return page_E404(wgd);
|
return page_E404(wgd);
|
||||||
} else
|
} else
|
||||||
return page_E404(wgd);
|
return page_E404(wgd);
|
||||||
|
|
||||||
bool chat_members = (path_segs[0] == "chat-members");
|
bool chat_members = (path_segs[0] == "chat-members");
|
||||||
|
|
||||||
|
if (userinfo.isNull())
|
||||||
|
return een9::form_http_server_response_303("/");
|
||||||
|
|
||||||
RowChat_Content chatInfo;
|
RowChat_Content chatInfo;
|
||||||
try {
|
try {
|
||||||
chatInfo = lookup_chat_content_by_nickname(*wgd.db, chat_nickname);
|
chatInfo = lookup_chat_content_by_nickname(*wgd.db, chat_nickname);
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
return page_E404(wgd);
|
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);
|
return page_E404(wgd);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +56,7 @@ namespace iu9cawebchat {
|
|||||||
openedchat["selectedMessageId"].asInteger() = json::Integer(selected_message_id);
|
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);
|
json::JSON initial_chatUpdResp = poll_update_chat_ONE_MSG_resp(*wgd.db, chatInfo.id, selected_message_id);
|
||||||
if (chat_members)
|
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});
|
return http_R200("chat", wgd, {&config_presentation, &userinfo, &openedchat, &initial_chatUpdResp});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ namespace iu9cawebchat {
|
|||||||
}
|
}
|
||||||
json::JSON initial_chatListUpdResp = poll_update_chat_list_resp(*wgd.db,
|
json::JSON initial_chatListUpdResp = poll_update_chat_list_resp(*wgd.db,
|
||||||
userinfo["uid"].asInteger().get_int(), 0);
|
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});
|
return http_R200("list-rooms", wgd, {&config_presentation, &userinfo, &initial_chatListUpdResp});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,10 @@ namespace iu9cawebchat {
|
|||||||
if (cmp.first == "password")
|
if (cmp.first == "password")
|
||||||
password = cmp.second;
|
password = cmp.second;
|
||||||
}
|
}
|
||||||
een9_ASSERT(check_nickname(nickname), "/login/accpet-data rejected impossible nickname");
|
if (!check_nickname(nickname))
|
||||||
een9_ASSERT(check_password(password), "/login/accpet-data rejected impossible password");
|
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);
|
uid = find_user_by_credentials(*wgd.db, nickname, password);
|
||||||
|
|
||||||
} catch(const std::exception& e){}
|
} catch(const std::exception& e){}
|
||||||
|
@ -39,6 +39,8 @@ namespace iu9cawebchat {
|
|||||||
|
|
||||||
std::string when_page_user(WorkerGuestData& wgd, const json::JSON& config_presentation,
|
std::string when_page_user(WorkerGuestData& wgd, const json::JSON& config_presentation,
|
||||||
const een9::ClientRequest& req, const std::vector<LoginCookie>& login_cookies, const json::JSON& userinfo) {
|
const een9::ClientRequest& req, const std::vector<LoginCookie>& login_cookies, const json::JSON& userinfo) {
|
||||||
|
if (userinfo.isNull())
|
||||||
|
return een9::form_http_server_response_303("/");
|
||||||
SqliteConnection& conn = *wgd.db;
|
SqliteConnection& conn = *wgd.db;
|
||||||
if (!is_page_of_certain_user(req.uri_path))
|
if (!is_page_of_certain_user(req.uri_path))
|
||||||
return page_E404(wgd);
|
return page_E404(wgd);
|
||||||
@ -104,7 +106,7 @@ namespace iu9cawebchat {
|
|||||||
json::JSON msg_list = jsonify_html_message_list({{"",
|
json::JSON msg_list = jsonify_html_message_list({{"",
|
||||||
config_presentation["phr"]["decl"]["incorrect-profile-data"].asString()}});
|
config_presentation["phr"]["decl"]["incorrect-profile-data"].asString()}});
|
||||||
json::JSON alien_userprofile = user_row_to_userprofile_obj(conn, alien);
|
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);
|
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);
|
json::JSON alien_userprofile = user_row_to_userprofile_obj(conn, alien);
|
||||||
if (can_edit) {
|
if (can_edit) {
|
||||||
json::JSON empty_msg_list = jsonify_html_message_list({});
|
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");
|
een9_THROW("Bad method");
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,8 @@ int main(int argc, char** argv){
|
|||||||
iu9cawebchat::run_website(config);
|
iu9cawebchat::run_website(config);
|
||||||
} else
|
} else
|
||||||
een9_THROW("unknown action (known are 'run', 'initialize')");
|
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());
|
printf("System failure\n%s\n", e.what());
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user