master #6
| @ -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"> | ||||||
|  | |||||||
| @ -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> | ||||||
|  | |||||||
| @ -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> | ||||||
|  | |||||||
| @ -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> | ||||||
|  | |||||||
| @ -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"> | ||||||
|  | |||||||
| @ -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> | ||||||
|  | |||||||
| @ -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> | ||||||
|  | |||||||
| @ -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
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assets/img/favicon.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 824 B | 
| @ -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(); | ||||||
| } | } | ||||||
|  | |||||||
| @ -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); | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -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; | ||||||
|  | |||||||
| @ -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, | ||||||
|  | |||||||
| @ -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; | ||||||
|  | |||||||
| @ -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; | ||||||
|  | |||||||
| @ -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; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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"; | ||||||
|  | |||||||
| @ -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); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user