Fixed a lot of server-side bugs, /list-rooms page bugs. Added favicon, finished /chat-members page

This commit is contained in:
Андреев Григорий 2024-09-02 12:34:49 +03:00
parent 3a8bdb99ec
commit fc721d7f5c
18 changed files with 163 additions and 51 deletions

View File

@ -4,6 +4,7 @@
<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">
<link rel="icon" type="image/png" href="/assets/img/favicon.png">
<link rel="stylesheet" href="/assets/css/common.css"> <link rel="stylesheet" href="/assets/css/common.css">
<link rel="stylesheet" href="/assets/css/common-popup.css"> <link rel="stylesheet" href="/assets/css/common-popup.css">
<link rel="stylesheet" href="/assets/css/chat-members.css"> <link rel="stylesheet" href="/assets/css/chat-members.css">

View File

@ -13,6 +13,7 @@
<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">
<link rel="icon" type="image/png" href="/assets/img/favicon.png">
<link rel="stylesheet" href="/assets/css/common.css"> <link rel="stylesheet" href="/assets/css/common.css">
<link rel="stylesheet" href="/assets/css/chat.css"> <link rel="stylesheet" href="/assets/css/chat.css">
<title>Chat </title> <title>Chat </title>

View File

@ -4,6 +4,7 @@
<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">
<link rel="icon" type="image/png" href="/assets/img/favicon.png">
<link rel="stylesheet" href="/assets/css/common.css"> <link rel="stylesheet" href="/assets/css/common.css">
<link rel="stylesheet" href="/assets/css/edit-profile.css"> <link rel="stylesheet" href="/assets/css/edit-profile.css">
<title>Edit user Profile</title> <title>Edit user Profile</title>

View File

@ -2,6 +2,7 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<link rel="icon" type="image/png" href="/assets/img/favicon.png">
<title>Not found</title> <title>Not found</title>
</head> </head>
<body> <body>

View File

@ -5,6 +5,7 @@
<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>List of chat rooms</title> <title>List of chat rooms</title>
<link rel="icon" type="image/png" href="/assets/img/favicon.png">
<link rel="stylesheet" href="/assets/css/common.css"> <link rel="stylesheet" href="/assets/css/common.css">
<link rel="stylesheet" href="/assets/css/common-popup.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">

View File

@ -4,6 +4,7 @@
<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">
<link rel="icon" type="image/png" href="/assets/img/favicon.png">
<link rel="stylesheet" href="/assets/css/common.css"> <link rel="stylesheet" href="/assets/css/common.css">
<link rel="stylesheet" href="/assets/css/login.css"> <link rel="stylesheet" href="/assets/css/login.css">
<title>Login Page</title> <title>Login Page</title>

View File

@ -4,6 +4,7 @@
<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">
<link rel="icon" type="image/png" href="/assets/img/favicon.png">
<link rel="stylesheet" href="/assets/css/common.css"> <link rel="stylesheet" href="/assets/css/common.css">
<!-- This page is so simple, that it does not even have it's separate css file --> <!-- This page is so simple, that it does not even have it's separate css file -->
<title>User Profile</title> <title>User Profile</title>

View File

@ -1,6 +1,7 @@
#CM-btn-add { #CM-btn-add {
margin-top: 6px; margin-top: 6px;
margin-bottom: 4px; margin-bottom: 4px;
display: none;
} }
.CM-member-box { .CM-member-box {

BIN
assets/img/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 824 B

View File

@ -3,7 +3,8 @@ let LocalHistoryId = 0;
function genSentBase(){ function genSentBase(){
return { return {
'chatUpdReq': { 'chatUpdReq': {
'LocalHistoryId': LocalHistoryId 'LocalHistoryId': LocalHistoryId,
'chatId': openedchat.id
} }
}; };
} }
@ -15,7 +16,7 @@ let myRoleHere = null; // Dung local state updates should be updated first
let userDeletionWinStoredUId = -1; let userDeletionWinStoredUId = -1;
function shouldShowDeleteButton(memberSt){ function shouldShowDeleteButton(memberSt){
return userinfo.uid !== memberSt.userId && myRoleHere === userChatRoleAdmin; return userinfo.uid !== memberSt.userId && myRoleHere === userChatRoleAdmin && memberSt.roleHere !== userChatRoleDeleted;
} }
function updateBoxWithSt(box, memberSt){ function updateBoxWithSt(box, memberSt){
@ -60,9 +61,9 @@ function convertMemberStToBox(memberSt){
if (ev.button !== 0) if (ev.button !== 0)
return; return;
userDeletionWinStoredUId = ID; userDeletionWinStoredUId = ID;
activatePopupWindowById("user-deletion-win");
document.getElementById("user-deletion-win-title").innerText = document.getElementById("user-deletion-win-title").innerText =
"Do you really want to kick user " + memberSt.nickname + "?"; "Do you really want to kick user " + memberSt.nickname + "?";
activatePopupWindowById("user-deletion-win");
}; };
box.querySelector(".CM-member-box-leave-btn").style.display = box.querySelector(".CM-member-box-leave-btn").style.display =
(shouldShowDeleteButton(memberSt) ? "block" : "none"); (shouldShowDeleteButton(memberSt) ? "block" : "none");
@ -77,29 +78,114 @@ function updateLocalStateFromChatUpdResp(chatUpdResp){
// We ignore messages and everything related to them. Dang, I really should add an argument to disable message lookup here // We ignore messages and everything related to them. Dang, I really should add an argument to disable message lookup here
// let haveToUpdateAllBoxes = false; // let haveToUpdateAllBoxes = false;
for (let memberSt of chatUpdResp.members){ for (let memberSt of chatUpdResp.members){
if (memberSt.id === userinfo.uid && myRoleHere !== memberSt.roleHere){ console.log([memberSt, userinfo.uid, myRoleHere]);
if (memberSt.userId === userinfo.uid && myRoleHere !== memberSt.roleHere){
myRoleHere = memberSt.roleHere; myRoleHere = memberSt.roleHere;
// haveToUpdateAllBoxes = true; // haveToUpdateAllBoxes = true;
for (let [id, memberSt] of members){ for (let [id, memberSt] of members){
let box = memberBoxes.get(id); let box = memberBoxes.get(id);
updateBoxWithSt(box, memberSt); updateBoxWithSt(box, memberSt);
} }
document.getElementById("CM-btn-add").style.display =
(memberSt.roleHere === userChatRoleAdmin ? "block" : "none");
console.log("DEBUG " + (memberSt.roleHere === userChatRoleAdmin ? "block" : "none"));
break; break;
} }
} }
for (let memberSt of chatUpdResp.members){ for (let memberSt of chatUpdResp.members){
let id = memberSt.userId; let id = memberSt.userId;
// todo: CONTINUE FROM HERE WHEN YOU WAKE UP if (members.has(id)){
updateBoxWithSt(memberBoxes.get(id), memberSt);
} else {
if (memberSt.roleHere !== userChatRoleDeleted){
members.set(id, memberSt);
let box = convertMemberStToBox(memberSt);
memberBoxes.set(id, box);
literalMemberList.appendChild(box);
}
}
} }
} }
function updateLocalStateFromRecv(Recv){
updateLocalStateFromChatUpdResp(Recv.chatUpdResp);
}
function configureSummonUserInterface(){
document.getElementById("user-summoning-yes").onclick = function(ev ){
if (ev.button !==0)
return;
let nickname = document.getElementById("summoned-user-nickname").value;
let isReadOnly = document.getElementById("summoned-user-is-read-only").checked;
deactivateActivePopup();
let Sent = genSentBase();
Sent.nickname = nickname;
Sent.makeReadOnly = Boolean(isReadOnly);
apiRequest("addMemberToChat", Sent).
then((Recv) => {
updateLocalStateFromRecv(Recv);
}).catch((e) => {
console.log(e);
alert("Failed to add user to chat");
});
};
document.getElementById("user-summoning-no").onclick = function (ev) {
if (ev.button !== 0)
return;
deactivateActivePopup();
};
document.getElementById("CM-btn-add").onclick = function(ev) {
if (ev.button !== 0)
return;
document.getElementById("summoned-user-nickname").value = "";
// read-only flag persists throughout user summoning sessions, and IT IS NOT A BUG
activatePopupWindowById("user-summoning-win");
};
}
/* Popup activation button is configured for each box separately */
function configureKickUserInterfaceWinPart(){
document.getElementById("user-deletion-yes").onclick = function (ev){
if (ev.button !== 0)
return;
deactivateActivePopup();
if (userDeletionWinStoredUId < 0)
throw new Error("Karaul");
let Sent = genSentBase();
Sent.userId = userDeletionWinStoredUId;
apiRequest("removeMemberFromChat", Sent).
then((Recv) => {
updateLocalStateFromRecv(Recv);
}).catch((e) => {
console.log(e);
alert("Failed to kick user from chat");
});
}
document.getElementById("user-deletion-no").onclick = function (ev) {
if (ev.button !== 0)
return;
deactivateActivePopup();
};
}
__mainloopDelayMS = 5000; __mainloopDelayMS = 5000;
__guestMainloopPollerAction = function (){ __guestMainloopPollerAction = function (){
console.log("Hello, world"); console.log("Hello, world");
let Sent = genSentBase();
apiRequest("chatPollEvents", Sent).
then((Recv) => {
console.log(Recv);
updateLocalStateFromRecv(Recv);
});
} }
window.onload = function(){ window.onload = function(){
console.log("Page loaded"); console.log("Page loaded");
configureSummonUserInterface();
configureKickUserInterfaceWinPart();
updateLocalStateFromChatUpdResp(initial_chatUpdResp); updateLocalStateFromChatUpdResp(initial_chatUpdResp);
mainloopPoller(); mainloopPoller();
} }

View File

@ -19,6 +19,10 @@ function youAreXHere(myRoleHere){
let chatRenunciationWinStoredId = -1; let chatRenunciationWinStoredId = -1;
function shouldShowDeleteButton(myMembershipSt){
return myMembershipSt.myRoleHere === userChatRoleDeleted;
}
/* Updating chat html box after myMembershipSt in it was updated */ /* Updating chat html box after myMembershipSt in it was updated */
function updateBoxWithNewSt(box, myMembershipSt){ function updateBoxWithNewSt(box, myMembershipSt){
let ID = myMembershipSt.chatId; let ID = myMembershipSt.chatId;
@ -26,10 +30,10 @@ function updateBoxWithNewSt(box, myMembershipSt){
roleP.innerText = youAreXHere(myMembershipSt.myRoleHere); roleP.innerText = youAreXHere(myMembershipSt.myRoleHere);
box.style.backgroundColor = roleToColor(myMembershipSt.myRoleHere); box.style.backgroundColor = roleToColor(myMembershipSt.myRoleHere);
box.querySelector(".CL-my-chat-box-leave-btn").style.display = box.querySelector(".CL-my-chat-box-leave-btn").style.display =
(myMembershipSt.myRoleHere === userChatRoleDeleted ? "none" : "block"); (shouldShowDeleteButton(myMembershipSt) ? "none" : "block");
} }
function convertStToBox(myMembershipSt){ function convertMyMembershipStToBox(myMembershipSt){
let chatURI = "/chat/" + myMembershipSt.chatNickname; let chatURI = "/chat/" + myMembershipSt.chatNickname;
let ID = myMembershipSt.chatId; let ID = myMembershipSt.chatId;
@ -62,13 +66,12 @@ function convertStToBox(myMembershipSt){
if (ev.button !== 0) if (ev.button !== 0)
return; return;
chatRenunciationWinStoredId = ID; chatRenunciationWinStoredId = ID;
activatePopupWindowById("chat-renunciation-win");
document.getElementById("chat-renunciation-win-title").innerText = document.getElementById("chat-renunciation-win-title").innerText =
"Do you really want to leave chat " + myMembershipSt.chatNickname + "?"; "Do you really want to leave chat " + myMembershipSt.chatNickname + "?";
activatePopupWindowById("chat-renunciation-win");
}; };
box.querySelector(".CL-my-chat-box-leave-btn").style.display = box.querySelector(".CL-my-chat-box-leave-btn").style.display =
(myMembershipSt.myRoleHere === userChatRoleDeleted ? "none" : "block"); (shouldShowDeleteButton(myMembershipSt) ? "none" : "block");
return box; return box;
} }
@ -87,7 +90,7 @@ function updateLocalStateFromChatListUpdResp(chatListUpdResp){
if (myMembershipSt.myRoleHere === userChatRoleDeleted) if (myMembershipSt.myRoleHere === userChatRoleDeleted)
continue; continue;
myChats.set(chatId, myMembershipSt); myChats.set(chatId, myMembershipSt);
let box = convertStToBox(myMembershipSt) let box = convertMyMembershipStToBox(myMembershipSt)
chatBoxes.set(chatId, box); chatBoxes.set(chatId, box);
literalChatList.appendChild(box); literalChatList.appendChild(box);
} }

View File

@ -3,16 +3,32 @@
#include <assert.h> #include <assert.h>
namespace iu9cawebchat { namespace iu9cawebchat {
void make_her_a_member_of_the_midnight_crew(SqliteConnection& conn, int64_t chatId, int64_t alienUserId, int64_t role) { bool is_membership_row_present(SqliteConnection& conn, int64_t chatId, int64_t alienUserId) {
assert(role != user_chat_role_deleted); SqliteStatement req(conn,
"SELECT EXISTS(SELECT 1 FROM `user_chat_membership` WHERE `chatId` = ?1 AND `userId` = ?2)",
{{1, chatId}, {2, alienUserId}}, {});
fsql_integer_or_null r{true, 0};
int status = sqlite_stmt_step(req, {{0, &r}}, {});
return (bool)r.value;
}
void alter_user_chat_role(SqliteConnection& conn, int64_t chatId, int64_t alienUserId, int64_t role) {
int64_t chat_HistoryId_BEFORE_EV = get_current_history_id_of_chat(conn, chatId); int64_t chat_HistoryId_BEFORE_EV = get_current_history_id_of_chat(conn, chatId);
int64_t alien_chatlist_HistoryId_BEFORE_EV = get_current_history_id_of_user_chatList(conn, alienUserId); int64_t alien_chatlist_HistoryId_BEFORE_EV = get_current_history_id_of_user_chatList(conn, alienUserId);
sqlite_nooutput(conn, if (!is_membership_row_present(conn, chatId, alienUserId)) {
"INSERT INTO `user_chat_membership` (`userId`, `chatId`, `user_chatList_IncHistoryId`," sqlite_nooutput(conn,
"`chat_IncHistoryId`, `role`) VALUES (?1, ?2, ?3, ?4, ?5)", "INSERT INTO `user_chat_membership` (`userId`, `chatId`, `user_chatList_IncHistoryId`,"
{{1, alienUserId}, {2, chatId}, {3, alien_chatlist_HistoryId_BEFORE_EV + 1}, "`chat_IncHistoryId`, `role`) VALUES (?1, ?2, ?3, ?4, ?5)",
{4, chat_HistoryId_BEFORE_EV + 1}, {5, role}}, {}); {{1, alienUserId}, {2, chatId}, {3, alien_chatlist_HistoryId_BEFORE_EV + 1},
{4, chat_HistoryId_BEFORE_EV + 1}, {5, role}}, {});
} else {
sqlite_nooutput(conn,
"UPDATE `user_chat_membership` SET `user_chatList_IncHistoryId` = ?3,`chat_IncHistoryId` = ?4,"
"`role` = ?5 WHERE `userId` = ?1 AND `chatId` = ?2",
{{1, alienUserId}, {2, chatId}, {3, alien_chatlist_HistoryId_BEFORE_EV + 1},
{4, chat_HistoryId_BEFORE_EV + 1}, {5, role}}, {});
}
sqlite_nooutput(conn, sqlite_nooutput(conn,
"UPDATE `chat` SET `it_HistoryId` = ?1 WHERE `id` = ?2", {{1, chat_HistoryId_BEFORE_EV + 1}, "UPDATE `chat` SET `it_HistoryId` = ?1 WHERE `id` = ?2", {{1, chat_HistoryId_BEFORE_EV + 1},
{2, chatId}}, {}); {2, chatId}}, {});
@ -22,6 +38,12 @@ namespace iu9cawebchat {
{{1, alien_chatlist_HistoryId_BEFORE_EV + 1}, {2, alienUserId}}, {}); {{1, alien_chatlist_HistoryId_BEFORE_EV + 1}, {2, alienUserId}}, {});
} }
void make_her_a_member_of_the_midnight_crew(SqliteConnection& conn, int64_t chatId, int64_t alienUserId, int64_t role) {
assert(role != user_chat_role_deleted);
// int64_t old_role = get_role_of_user_in_chat(conn, alienUserId, chatId);
alter_user_chat_role(conn, chatId, alienUserId, role);
}
json::JSON internalapi_addMemberToChat(SqliteConnection& conn, int64_t uid, const json::JSON& Sent) { json::JSON internalapi_addMemberToChat(SqliteConnection& conn, int64_t uid, const json::JSON& Sent) {
int64_t chatId = Sent["chatUpdReq"]["chatId"].asInteger().get_int(); int64_t chatId = Sent["chatUpdReq"]["chatId"].asInteger().get_int();
int64_t my_role_here = get_role_of_user_in_chat(conn, uid, chatId); int64_t my_role_here = get_role_of_user_in_chat(conn, uid, chatId);
@ -33,12 +55,17 @@ namespace iu9cawebchat {
try { try {
alien = lookup_user_content_by_nickname(conn, alien_nickname); alien = lookup_user_content_by_nickname(conn, alien_nickname);
} catch (std::exception& e) { } catch (std::exception& e) {
return json::JSON(json::jdict{{"status", json::JSON(-1l)}}); return at_api_error_gen_bad_recv(-1l);
} }
bool makeReadOnly = Sent["makeReadOnly"].toBool();
int64_t aliens_old_role = get_role_of_user_in_chat(conn, alien.id, chatId); int64_t aliens_old_role = get_role_of_user_in_chat(conn, alien.id, chatId);
if (aliens_old_role == user_chat_role_deleted) { if (aliens_old_role == user_chat_role_deleted) {
make_her_a_member_of_the_midnight_crew(conn, chatId, alien.id, user_chat_role_regular); make_her_a_member_of_the_midnight_crew(conn, chatId, alien.id,
makeReadOnly ? user_chat_role_read_only : user_chat_role_regular);
} else {
return at_api_error_gen_bad_recv(-2l);
} }
json::JSON Recv; json::JSON Recv;

View File

@ -7,11 +7,11 @@ namespace iu9cawebchat {
std::string new_chat_name = Sent["content"]["name"].asString(); std::string new_chat_name = Sent["content"]["name"].asString();
std::string new_chat_nickname = Sent["content"]["nickname"].asString(); std::string new_chat_nickname = Sent["content"]["nickname"].asString();
if (!check_nickname(new_chat_nickname) || !check_name(new_chat_name)) if (!check_nickname(new_chat_nickname) || !check_name(new_chat_name))
return json::JSON(json::jdict{{"status", json::JSON(-1l)}}); return at_api_error_gen_bad_recv(-1l);
if (is_nickname_taken(conn, new_chat_nickname)) if (is_nickname_taken(conn, new_chat_nickname))
return json::JSON(json::jdict{{"status", json::JSON(-2l)}}); return at_api_error_gen_bad_recv(-2l);
if (is_nickname_taken(conn, new_chat_nickname)) if (is_nickname_taken(conn, new_chat_nickname))
return json::JSON(json::jdict{{"status", json::JSON(-3l)}}); return at_api_error_gen_bad_recv(-3l);
reserve_nickname(conn, new_chat_nickname); reserve_nickname(conn, new_chat_nickname);
sqlite_nooutput(conn, sqlite_nooutput(conn,

View File

@ -6,7 +6,7 @@ namespace iu9cawebchat {
int64_t chatId = Sent["chatId"].asInteger().get_int(); int64_t chatId = Sent["chatId"].asInteger().get_int();
if (get_role_of_user_in_chat(conn, uid, chatId) == user_chat_role_deleted) if (get_role_of_user_in_chat(conn, uid, chatId) == user_chat_role_deleted)
een9_THROW("Not a member"); een9_THROW("Not a member");
kick_from_chat(conn, uid, chatId); kick_from_chat(conn, chatId, uid);
json::JSON Recv; json::JSON Recv;
poll_update_chat_list(conn, uid, Sent, Recv); poll_update_chat_list(conn, uid, Sent, Recv);
return Recv; return Recv;

View File

@ -2,34 +2,17 @@
#include <engine_engine_number_9/baza_throw.h> #include <engine_engine_number_9/baza_throw.h>
namespace iu9cawebchat { namespace iu9cawebchat {
void kick_from_chat(SqliteConnection& conn, int64_t alienUserId, int64_t chatId) { void kick_from_chat(SqliteConnection& conn, int64_t chatId, int64_t alienUserId) {
if (get_role_of_user_in_chat(conn, alienUserId, chatId) == user_chat_role_deleted) alter_user_chat_role(conn, chatId, alienUserId, user_chat_role_deleted);
een9_THROW("Can't delete a deleted member");
int64_t chat_HistoryId_BEFORE_EV = get_current_history_id_of_chat(conn, chatId);
int64_t alien_chatlist_HistoryId_BEFORE_EV = get_current_history_id_of_user_chatList(conn, alienUserId);
sqlite_nooutput(conn,
"UPDATE `user_chat_membership` SET `user_chatList_IncHistoryId` = ?3,"
"`chat_IncHistoryId` = ?4, `role` = ?5 WHERE `userId` = ?1 AND `chatId` = ?2",
{{1, alienUserId}, {2, chatId}, {3, alien_chatlist_HistoryId_BEFORE_EV + 1},
{4, chat_HistoryId_BEFORE_EV + 1}, {5, user_chat_role_deleted}}, {});
sqlite_nooutput(conn,
"UPDATE `chat` SET `it_HistoryId` = ?1 WHERE `id` = ?2", {{1, chat_HistoryId_BEFORE_EV + 1},
{2, chatId}}, {});
sqlite_nooutput(conn,
"UPDATE `user` SET `chatList_HistoryId` = ?1 WHERE `id` = ?2",
{{1, alien_chatlist_HistoryId_BEFORE_EV + 1}, {2, alienUserId}}, {});
} }
json::JSON internalapi_removeMemberFromChat(SqliteConnection& conn, int64_t uid, const json::JSON& Sent) { json::JSON internalapi_removeMemberFromChat(SqliteConnection& conn, int64_t uid, const json::JSON& Sent) {
int64_t chatId = Sent["chatUpdReq"]["chatId"].asInteger().get_int(); int64_t chatId = Sent["chatUpdReq"]["chatId"].asInteger().get_int();
int64_t my_role_here = get_role_of_user_in_chat(conn, uid, chatId); int64_t my_role_here = get_role_of_user_in_chat(conn, uid, chatId);
if (my_role_here != user_chat_role_deleted) if (my_role_here != user_chat_role_admin)
een9_THROW("Only admin can delete members of chat"); een9_THROW("Only admin can delete members of chat");
int64_t badAlienId = Sent["chatUpdReq"]["userId"].asInteger().get_int(); int64_t badAlienId = Sent["userId"].asInteger().get_int();
kick_from_chat(conn, badAlienId, chatId); kick_from_chat(conn, chatId, badAlienId);
json::JSON Recv; json::JSON Recv;
poll_update_chat(conn, Sent, Recv); poll_update_chat(conn, Sent, Recv);
return Recv; return Recv;

View File

@ -33,7 +33,6 @@ namespace iu9cawebchat {
void poll_update_chat_list(SqliteConnection& conn, int64_t userId, const json::JSON& Sent, json::JSON& Recv) { void poll_update_chat_list(SqliteConnection& conn, int64_t userId, const json::JSON& Sent, json::JSON& Recv) {
Recv["status"].asInteger() = json::Integer(0l); Recv["status"].asInteger() = json::Integer(0l);
// todo: in libjsonincpp: get rid of Integer // todo: in libjsonincpp: get rid of Integer
printf("%s\n", json::generate_str(Sent, json::print_pretty).c_str());
Recv["chatListUpdResp"] = poll_update_chat_list_resp(conn, userId, Sent["chatListUpdReq"]["LocalHistoryId"].asInteger().get_int()); Recv["chatListUpdResp"] = poll_update_chat_list_resp(conn, userId, Sent["chatListUpdReq"]["LocalHistoryId"].asInteger().get_int());
} }
@ -54,7 +53,7 @@ namespace iu9cawebchat {
json::jarr messages; json::jarr messages;
SqliteStatement messages_changes(conn, SqliteStatement messages_changes(conn,
"SELECT `id`, `senderUserId`, `exists`, `isSystem`, `text` FROM `messages` " "SELECT `id`, `senderUserId`, `exists`, `isSystem`, `text` FROM `message` "
"WHERE `chatId` = ?1 AND ( `chat_IncHistoryId` > ?2 OR ( ?3 <= `id` AND `id` <= ?4 ) )", "WHERE `chatId` = ?1 AND ( `chat_IncHistoryId` > ?2 OR ( ?3 <= `id` AND `id` <= ?4 ) )",
{{1, chatId}, {2, LocalHistoryId}, {3, QSEG_A}, {4, QSEG_B}}, {}); {{1, chatId}, {2, LocalHistoryId}, {3, QSEG_A}, {4, QSEG_B}}, {});
while (true) { while (true) {
@ -139,7 +138,7 @@ namespace iu9cawebchat {
int64_t QSEG_A, int64_t QSEG_B) { int64_t QSEG_A, int64_t QSEG_B) {
Recv["status"].asInteger() = json::Integer(0l); Recv["status"].asInteger() = json::Integer(0l);
Recv["charUpdResp"] = poll_update_chat_important_segment_resp(conn, Recv["chatUpdResp"] = poll_update_chat_important_segment_resp(conn,
Sent["chatUpdReq"]["chatId"].asInteger().get_int(), Sent["chatUpdReq"]["chatId"].asInteger().get_int(),
Sent["chatUpdReq"]["LocalHistoryId"].asInteger().get_int(), QSEG_A, QSEG_B); Sent["chatUpdReq"]["LocalHistoryId"].asInteger().get_int(), QSEG_A, QSEG_B);
} }
@ -160,7 +159,6 @@ namespace iu9cawebchat {
json::JSON internalapi_chatListPollEvents(SqliteConnection& conn, int64_t uid, const json::JSON& Sent) { json::JSON internalapi_chatListPollEvents(SqliteConnection& conn, int64_t uid, const json::JSON& Sent) {
json::JSON Recv; json::JSON Recv;
poll_update_chat_list(conn, uid, Sent, Recv); poll_update_chat_list(conn, uid, Sent, Recv);
printf("%s\n", json::generate_str(Recv, json::print_pretty).c_str());
return Recv; return Recv;
} }

View File

@ -5,6 +5,10 @@
#include "../str_fields.h" #include "../str_fields.h"
namespace iu9cawebchat { namespace iu9cawebchat {
json::JSON at_api_error_gen_bad_recv(int64_t code) {
return json::JSON(json::jdict{{"status", json::JSON(code)}});
}
const char* stringify_user_chat_role(int64_t role) { const char* stringify_user_chat_role(int64_t role) {
if (role == user_chat_role_admin) if (role == user_chat_role_admin)
return "admin"; return "admin";

View File

@ -8,6 +8,8 @@
#include <jsonincpp/string_representation.h> #include <jsonincpp/string_representation.h>
namespace iu9cawebchat { namespace iu9cawebchat {
json::JSON at_api_error_gen_bad_recv(int64_t code = -1);
constexpr int64_t user_chat_role_admin = 1; constexpr int64_t user_chat_role_admin = 1;
constexpr int64_t user_chat_role_regular = 2; constexpr int64_t user_chat_role_regular = 2;
constexpr int64_t user_chat_role_read_only = 3; constexpr int64_t user_chat_role_read_only = 3;
@ -61,8 +63,9 @@ namespace iu9cawebchat {
json::JSON poll_update_chat_ONE_MSG_resp(SqliteConnection& conn, int64_t chatId, int64_t selectedMsg); json::JSON poll_update_chat_ONE_MSG_resp(SqliteConnection& conn, int64_t chatId, int64_t selectedMsg);
void poll_update_chat(SqliteConnection& conn, const json::JSON& Sent, json::JSON& Recv); void poll_update_chat(SqliteConnection& conn, const json::JSON& Sent, json::JSON& Recv);
void alter_user_chat_role(SqliteConnection& conn, int64_t chatId, int64_t alienUserId, int64_t role);
void make_her_a_member_of_the_midnight_crew(SqliteConnection& conn, int64_t chatId, int64_t alienUserId, int64_t role); void make_her_a_member_of_the_midnight_crew(SqliteConnection& conn, int64_t chatId, int64_t alienUserId, int64_t role);
void kick_from_chat(SqliteConnection& conn, int64_t alienUserId, int64_t chatId); void kick_from_chat(SqliteConnection& conn, int64_t chatId, int64_t alienUserId);
bool is_nickname_taken(SqliteConnection& conn, const std::string& nickname); bool is_nickname_taken(SqliteConnection& conn, const std::string& nickname);
void reserve_nickname(SqliteConnection& conn, const std::string& nickname); void reserve_nickname(SqliteConnection& conn, const std::string& nickname);