Fixed some problems with deletion buttons in /list-rooms, wrote a sketch for /chat-members

This commit is contained in:
Андреев Григорий 2024-09-02 01:11:28 +03:00
parent 9283590122
commit 3a8bdb99ec
15 changed files with 196 additions and 50 deletions

View File

@ -38,11 +38,11 @@ regexis024_build_system.sh
Помимо самого бинарника нужен файл с настройками сервиса. Формат настроек: JSON.
Комментарии не поддерживаются. Пример такого файла находится в example/config.json.
Вместе с бинарным фалом так же распространяются ассеты, необъходимые для работы сайта.
Вместе с бинарным фалом так же распространяются ассеты, необходимые для работы сайта.
Их можно найти в папке assets. В настроках (поле `["assets"]`) указывается путь до
папки с ассетами. Путь может быть как абсолютным, так и относительным к рабочей директории.
Поле настроек `["database"]` указывает как соединиться с базой данных.
Поддерживается только база данных sqlite. Поддерживается только хранение в файле.
Поддерживается только база данных sqlite3. Поддерживается только хранение в файле.
Поле `["database"]["file"]` указывает путь где хранится sqlite база данных.
Перед тем как использовать сервис нужно его проинициализировать (а точнее проинициализировать

View File

@ -4,13 +4,55 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Веб-Чат Members</title>
<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>Chat Members</title>
</head>
<body>
{% PUT chat.pass pres userinfo openedchat initial_chatUpdResp %}
<!--TODO: ADD SOMETHING WRITE SOMETHING AAAAAA -->
<h1> Chat member list page for {% WRITE openedchat.nickname%}, not ready yet</h1>
<!--<script src="/assets/js/chat-members.js"></script>-->
<div id="user-summoning-win" class="popup-window">
<h1 class="popup-window-msg">Nickname for summoned user</h1>
<input class="one-line-input" id="summoned-user-nickname">
<input type="checkbox" id="summoned-user-is-read-only">
<label>Make read only</label>
<button class="popup-window-btn-yes" id="user-summoning-yes">Summon</button>
<button class="popup-window-btn-no" id="user-summoning-no">No, cancel</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">Are you sure you want to ban user?</h1>
<button class="popup-window-btn-yes" id="user-deletion-yes">Yes, delete</button>
<button class="popup-window-btn-no" id="user-deletion-no">No, cancel</button>
</div>
<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>
<p class="panel-thing panel-header-txt"> Members list of {% WRITE openedchat.name %} ({% WRITE openedchat.nickname %})</p>
<a href="/chat/{% WRITE 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 %}

View File

@ -18,7 +18,7 @@
<title>Chat </title>
</head>
<body>
<!-- Write the actual chat script -->
<!-- todo: Write the actual chat script -->
<!--% PUT chat.pass pres userinfo openedchat initial_chatUpdResp %-->
<div id="fullscreen-container">
<div class="panel" id="navigation-info-panel">

View File

@ -23,7 +23,7 @@
<label for="chat-nickname-input">Enter nickname for new chat:</label>
</td>
<td class="id-str-input-td2">
<input name="name" id="chat-nickname-input" type="text" placeholder="Take a nickname" class="one-line-input" required>
<input id="chat-nickname-input" type="text" placeholder="Take a nickname" class="one-line-input" required>
</td>
</tr>
<tr>
@ -31,7 +31,7 @@
<label for="chat-name-input">Enter name for new chat:</label>
</td>
<td class="id-str-input-td2">
<input name="password" id="chat-name-input" type="text" placeholder="Come up with name" class="one-line-input" required>
<input id="chat-name-input" type="text" placeholder="Come up with name" class="one-line-input" required>
</td>
</tr>
</table>

View File

@ -0,0 +1,32 @@
#CM-btn-add {
margin-top: 6px;
margin-bottom: 4px;
}
.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;
}

View File

@ -2,10 +2,6 @@ body, html {
height: 100%;
}
#navigation-info-panel {
align-items: center;
}
#chat-widget {
position: relative;
flex: 1;
@ -55,10 +51,6 @@ body, html {
word-wrap: break-word;
}
#input-panel {
}
#input-panel #message-input{
padding: 15px;
height: auto;

View File

@ -30,6 +30,7 @@
background-color: #54b3ff;
display: flex;
flex-direction: row;
align-items: center;
}
.panel-thing {

View File

@ -1,7 +1,3 @@
#navigation-panel {
align-items: center;
}
#CL-bacbe {
margin-top: 6px;
margin-bottom: 4px;

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="127.99999"

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="128"

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="127.99999"

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -1,21 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<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
id="path11"
style="fill:#bc9a58;fill-opacity:1;stroke:#8e5843;stroke-width:0.792427;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
d="m 9.8376422,3.4995279 c -0.413454,0.04422 -0.9249931,0.2733392 -1.5859497,0.7720459 -2.15303,1.6245101 -1.0645387,2.7213368 -0.2780192,3.6576578 0.9643744,1.1480481 0.5272069,2.4297214 -0.2444295,3.5413854 -1.0846469,1.562605 -1.8094411,2.689497 -3.1812011,2.618445 -1.7185528,-0.08902 -3.2061983,0.950419 -3.1817179,2.618962 0.020151,1.373449 0.960489,2.763844 2.9987833,2.826184 1.3729571,0.04199 2.35275,1.613748 2.9993001,2.825667 0.6465497,1.211919 1.3490594,3.417259 0.6769613,4.064868 -0.989134,0.953094 -1.312826,2.263816 0.6769612,4.064868 1.2829023,1.161218 2.6693573,0.639536 3.7666953,-0.946195 1.179214,-1.70405 2.337505,-1.523233 4.127396,-1.422652 1.371435,0.07707 2.886284,-0.325958 3.858679,1.446423 0.660704,1.204262 1.722209,2.911554 3.85868,1.445906 1.132687,-0.77704 2.468135,-2.085182 0.947745,-4.010091 -0.610564,-0.773014 -0.532201,-2.186383 0.948263,-4.010607 1.255317,-1.546798 1.98091,-2.751433 3.181201,-2.618962 1.365308,0.150686 2.84107,-0.224934 3.181718,-2.618445 0.366273,-2.57357 -1.941907,-2.695322 -3.312976,-2.778641 C 28.1324,14.906856 28.128014,13.488893 26.590624,12.103137 25.053235,10.717381 25.023658,9.341954 26.190649,8.2930337 27.35764,7.2441129 27.633021,6.3291961 25.719877,4.5222045 24.596532,3.461188 23.254965,3.1719841 21.630204,4.9759236 20.911774,5.7735833 19.336054,7.1894888 17.196366,7.1086099 15.002057,7.0256665 13.838949,7.4611865 12.285555,5.8053303 11.434493,4.8981315 11.078004,3.3668691 9.8376422,3.4995279 Z m 6.7892498,6.5215661 a 7.4172139,7.0961218 0 0 1 7.417118,7.096207 7.4172139,7.0961218 0 0 1 -7.417118,7.096208 7.4172139,7.0961218 0 0 1 -7.4171184,-7.096208 7.4172139,7.0961218 0 0 1 7.4171184,-7.096207 z" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="127.99999"

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

105
assets/js/chat-members.js Normal file
View File

@ -0,0 +1,105 @@
let LocalHistoryId = 0;
function genSentBase(){
return {
'chatUpdReq': {
'LocalHistoryId': LocalHistoryId
}
};
}
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;
}
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;
activatePopupWindowById("user-deletion-win");
document.getElementById("user-deletion-win-title").innerText =
"Do you really want to kick user " + memberSt.nickname + "?";
};
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
// let haveToUpdateAllBoxes = false;
for (let memberSt of chatUpdResp.members){
if (memberSt.id === userinfo.uid && myRoleHere !== memberSt.roleHere){
myRoleHere = memberSt.roleHere;
// haveToUpdateAllBoxes = true;
for (let [id, memberSt] of members){
let box = memberBoxes.get(id);
updateBoxWithSt(box, memberSt);
}
break;
}
}
for (let memberSt of chatUpdResp.members){
let id = memberSt.userId;
// todo: CONTINUE FROM HERE WHEN YOU WAKE UP
}
}
__mainloopDelayMS = 5000;
__guestMainloopPollerAction = function (){
console.log("Hello, world");
}
window.onload = function(){
console.log("Page loaded");
updateLocalStateFromChatUpdResp(initial_chatUpdResp);
mainloopPoller();
}

View File

@ -25,22 +25,23 @@ function updateBoxWithNewSt(box, myMembershipSt){
let roleP = box.querySelector(".CL-my-chat-box-my-role");
roleP.innerText = youAreXHere(myMembershipSt.myRoleHere);
box.style.backgroundColor = roleToColor(myMembershipSt.myRoleHere);
box.querySelector(".CL-my-chat-box-leave-btn").style.display =
(myMembershipSt.myRoleHere === userChatRoleDeleted ? "none" : "block");
}
function convertStToBox(myMembershipSt){
let chatURI = "/user/" + myMembershipSt.chatNickname;
let chatURI = "/chat/" + myMembershipSt.chatNickname;
let ID = myMembershipSt.chatId;
let box = document.createElement("div");
chatBoxes.set(myMembershipSt.chatId, box);
box.className = "dynamic-block-list-el CL-my-chat-box";
box.style.backgroundColor = roleToColor(myMembershipSt.myRoleHere);
let inBoxNickname = document.createElement("a");
box.appendChild(inBoxNickname);
inBoxNickname.className = "entity-nickname-txt CL-my-chat-box-nickname";
inBoxNickname.innerText = myMembershipSt.chatNickname;
inBoxNickname.href = chatURI;
box.style.backgroundColor = roleToColor(myMembershipSt.myRoleHere);
let inBoxName = document.createElement("a");
box.appendChild(inBoxName);
@ -65,6 +66,8 @@ function convertStToBox(myMembershipSt){
document.getElementById("chat-renunciation-win-title").innerText =
"Do you really want to leave chat " + myMembershipSt.chatNickname + "?";
};
box.querySelector(".CL-my-chat-box-leave-btn").style.display =
(myMembershipSt.myRoleHere === userChatRoleDeleted ? "none" : "block");
return box;
}