master #6

Open
karimov-adel wants to merge 39 commits from master into adel_branch_2.0
9 changed files with 165 additions and 38 deletions
Showing only changes of commit 9283590122 - Show all commits

View File

@ -65,6 +65,7 @@ x
</div>
</div>
</div>
<script src="/assets/js/common.js"></script>
<script src="/assets/js/common-popup.js"></script>
<script src="/assets/js/list-rooms.js"></script>
</body>

View File

@ -3,7 +3,8 @@
}
#CL-bacbe {
margin: 6px;
margin-top: 6px;
margin-bottom: 4px;
}
.CL-my-chat-box {

View File

@ -28,9 +28,6 @@ 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";
@ -180,13 +177,10 @@ function test(id, uid){
}
let mainloopTimeout = null;
let mainloopPoller = null;
function setMainloopTimeout(){
mainloopTimeout = setTimeout(mainloopPoller, 1000);
}
mainloopPoller = function(){
try {
console.log("Hello, World!");

52
assets/js/common.js Normal file
View File

@ -0,0 +1,52 @@
async function apiRequest(type, req){
let A = await fetch("/api/" + type,
{method: 'POST', body: JSON.stringify(req)});
let B = await A.json();
if (B.status !== 0)
throw Error("Server returned non-zero status");
return B;
}
/* Framework for pages with mainloop (it can be npt only polling, but also literally anything else */
let __mainloopDelayMs = 3000;
let mainloopTimeout = null;
let mainloopPoller = null;
let __guestMainloopPollerAction = null;
function setMainloopTimeout(){
mainloopTimeout = setTimeout(mainloopPoller, __mainloopDelayMs);
}
function cancelMainloopTimeout(){
clearTimeout(mainloopTimeout);
}
mainloopPoller = function(){
try {
console.log("Hello, World!");
__guestMainloopPollerAction();
} catch (error){
console.log(error)
}
setMainloopTimeout();
}
// 1
const userChatRoleAdmin = "admin";
// 2
const userChatRoleRegular = "regular";
// 3
const userChatRoleReadOnly = "read-only";
// 4
const userChatRoleDeleted = "not-a-member";
function roleToColor(role) {
if (role === userChatRoleAdmin) {
return "#aafff3";
} else if (role === userChatRoleRegular){
return "#ffffff";
} else if (role === userChatRoleReadOnly){
return "#bfb2b2";
} else if (role === userChatRoleDeleted) {
return "#fb4a4a";
}
return "#286500" // Bug
}

View File

@ -1,12 +1,35 @@
let LocalHistoryId = 0;
function genSentBase(){
return {
'chatListUpdReq': {
'LocalHistoryId': LocalHistoryId
}
};
}
let myChats = new Map();
let chatBoxes = new Map();
const roleDeleted = "not-a-member";
/* Generate text that is displayed on the right side of chat intro box */
function youAreXHere(myRoleHere){
return "You are " + myRoleHere + " here";
}
let chatRenunciationWinStoredId = -1;
/* Updating chat html box after myMembershipSt in it was updated */
function updateBoxWithNewSt(box, myMembershipSt){
let ID = myMembershipSt.chatId;
let roleP = box.querySelector(".CL-my-chat-box-my-role");
roleP.innerText = youAreXHere(myMembershipSt.myRoleHere);
box.style.backgroundColor = roleToColor(myMembershipSt.myRoleHere);
}
function convertStToBox(myMembershipSt){
let chatURI = "/user/" + myMembershipSt.chatNickname;
let ID = myMembershipSt.chatId;
let box = document.createElement("div");
chatBoxes.set(myMembershipSt.chatId, box);
@ -15,10 +38,9 @@ function convertStToBox(myMembershipSt){
let inBoxNickname = document.createElement("a");
box.appendChild(inBoxNickname);
inBoxNickname.className = "entity-nickname-txt CL-my-chat-box-nickname";
console.log(myMembershipSt);
console.log(myMembershipSt.chatNickname);
inBoxNickname.innerText = myMembershipSt.chatNickname;
inBoxNickname.href = chatURI;
box.style.backgroundColor = roleToColor(myMembershipSt.myRoleHere);
let inBoxName = document.createElement("a");
box.appendChild(inBoxName);
@ -29,9 +51,7 @@ function convertStToBox(myMembershipSt){
let inBoxMyRoleHere = document.createElement("p");
box.appendChild(inBoxMyRoleHere);
inBoxMyRoleHere.className = "entity-reg-field-txt CL-my-chat-box-my-role";
inBoxMyRoleHere.innerText = "You are " + myMembershipSt.myRoleHere + " here";
let ID = myMembershipSt.chatId;
inBoxMyRoleHere.innerText = youAreXHere(myMembershipSt.myRoleHere);
let inBoxLeaveBtn = document.createElement("img");
box.appendChild(inBoxLeaveBtn);
@ -40,19 +60,62 @@ function convertStToBox(myMembershipSt){
inBoxLeaveBtn.onclick = function (ev) {
if (ev.button !== 0)
return;
console.log("Tried to leave chat" + ID);
chatRenunciationWinStoredId = ID;
activatePopupWindowById("chat-renunciation-win");
document.getElementById("chat-renunciation-win-title").innerText =
"Do you really want to leave chat " + myMembershipSt.chatNickname + "?";
};
return box;
}
function updateLocalStateFromChatListUpdResp(chatListUpdResp){
LocalHistoryId = chatListUpdResp.HistoryId;
let literalChatList = document.getElementById("CL-dblec");
for (let myMembershipSt of chatListUpdResp.myChats){
let chatId = myMembershipSt.chatId;
console.log(myMembershipSt);
if (myChats.has(chatId)){
myChats.set(chatId, myMembershipSt);
updateBoxWithNewSt(chatBoxes.get(chatId), myMembershipSt);
} else {
if (myMembershipSt.myRoleHere === userChatRoleDeleted)
continue;
myChats.set(chatId, myMembershipSt);
let box = convertStToBox(myMembershipSt)
chatBoxes.set(chatId, box);
literalChatList.appendChild(box);
}
}
}
/* Use it ONLY if `Recv` reported success */
function updateLocalStateFromRecv(Recv){
updateLocalStateFromChatListUpdResp(Recv.chatListUpdResp);
}
function configureChatCreationInterface(){
document.getElementById("chat-creation-win-yes").onclick = function (ev) {
if (ev.button !== 0)
return;
let chatNicknameInput = document.getElementById("chat-nickname-input");
let chatNameInput = document.getElementById("chat-name-input");
let nickname = chatNicknameInput.value;
let name = chatNameInput.value;
deactivateActivePopup();
// todo: create chat, send request
let Sent = genSentBase();
Sent.content = {};
Sent.content.nickname = nickname;
Sent.content.name = name;
apiRequest("createChat", Sent
).then((Recv) => {
updateLocalStateFromRecv(Recv);
}).catch((e) => {
alert("Failed to create chat");
console.log(e);
});
};
document.getElementById("chat-creation-win-no").onclick = function (ev) {
@ -64,6 +127,10 @@ function configureChatCreationInterface(){
document.getElementById("CL-bacbe").onclick = function (ev){
if (ev.button !== 0)
return;
let chatNicknameInput = document.getElementById("chat-nickname-input");
let chatNameInput = document.getElementById("chat-name-input");
chatNicknameInput.value = "";
chatNameInput.value = "";
activatePopupWindowById("chat-creation-win");
console.log("Tried to show chat creation window");
};
@ -74,7 +141,18 @@ function configureChatRenunciationInterfaceWinPart(){
if (ev.button !== 0)
return;
deactivateActivePopup();
// todo: actually leave chat
if (chatRenunciationWinStoredId < 0)
throw new Error("chatRenunciationWinStoredId < 0");
let chatId = chatRenunciationWinStoredId;
let Sent = genSentBase();
Sent.chatId = chatId;
apiRequest("leaveChat", Sent
).then((Recv) => {
updateLocalStateFromRecv(Recv);
}).catch((e) => {
alert("Failed to leave chat");
console.log(e);
});
}
document.getElementById("chat-renunciation-win-no").onclick = function(ev) {
@ -84,24 +162,21 @@ function configureChatRenunciationInterfaceWinPart(){
}
}
__mainloopDelayMs = 3000;
__guestMainloopPollerAction = function(){
let Sent = genSentBase();
apiRequest("chatListPollEvents", Sent
).then((Recv) => {
console.log("Got a response");
console.log(Recv);
updateLocalStateFromRecv(Recv);
});
}
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);
}
}
updateLocalStateFromChatListUpdResp(initial_chatListUpdResp);
configureChatCreationInterface();
configureChatRenunciationInterfaceWinPart();
mainloopPoller();
};

View File

@ -10,10 +10,13 @@ namespace iu9cawebchat {
return json::JSON(json::jdict{{"status", json::JSON(-1l)}});
if (is_nickname_taken(conn, new_chat_nickname))
return json::JSON(json::jdict{{"status", json::JSON(-2l)}});
if (is_nickname_taken(conn, new_chat_nickname))
return json::JSON(json::jdict{{"status", json::JSON(-3l)}});
reserve_nickname(conn, new_chat_nickname);
sqlite_nooutput(conn,
"INSERT INTO `chat` (`nickname`, `name`, `it_HistoryId`, `lastMsgId`) VALUES (?1, ?2, 0, -1)");
"INSERT INTO `chat` (`nickname`, `name`, `it_HistoryId`, `lastMsgId`) VALUES (?1, ?2, 0, -1)",
{}, {{1, new_chat_nickname}, {2, new_chat_name}});
int64_t CHAT_ID = sqlite_trsess_last_insert_rowid(conn);

View File

@ -4,6 +4,7 @@
namespace iu9cawebchat {
json::JSON poll_update_chat_list_resp(SqliteConnection& conn, int64_t userId, int64_t LocalHistoryId) {
printf("Userid: %ld\n", userId);
json::JSON chatListUpdResp;
SqliteStatement my_membership_changes(conn,
"SELECT `chatId`, `role` FROM `user_chat_membership` WHERE `userId` = ?1 "
@ -32,7 +33,8 @@ namespace iu9cawebchat {
void poll_update_chat_list(SqliteConnection& conn, int64_t userId, const json::JSON& Sent, json::JSON& Recv) {
Recv["status"].asInteger() = json::Integer(0l);
// todo: in libjsonincpp: get rid of Integer
poll_update_chat_list_resp(conn, userId, Sent["chatListUpdReq"]["LocalHistoryId"].asInteger().get_int());
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());
}
json::JSON make_messageSt_obj(int64_t id, int64_t senderUserId, bool exists, bool isSystem, const std::string& text) {
@ -158,6 +160,7 @@ namespace iu9cawebchat {
json::JSON internalapi_chatListPollEvents(SqliteConnection& conn, int64_t uid, const json::JSON& Sent) {
json::JSON Recv;
poll_update_chat_list(conn, uid, Sent, Recv);
printf("%s\n", json::generate_str(Recv, json::print_pretty).c_str());
return Recv;
}

View File

@ -144,7 +144,6 @@ namespace iu9cawebchat {
/* All the api calls processing is done in dedicated files.
* All functions related to polling are defined in api_pollevents.cpp */
// todo: move everything to dedicated files
int64_t get_current_history_id_of_chat(SqliteConnection& conn, int64_t chatId) {
SqliteStatement req(conn, "SELECT `it_HistoryId` FROM `chat` WHERE `id` = ?1", {{1, chatId}}, {});
fsql_integer_or_null HistoryId;

View File

@ -36,8 +36,7 @@ int main(int argc, char** argv){
iu9cawebchat::run_website(config);
} else
een9_THROW("unknown action (known are 'run', 'initialize')");
// todo: put back execption after debug
} catch (std::bad_weak_ptr& e) {
} catch (std::exception& e) {
printf("System failure\n%s\n", e.what());
}
return 0;