Fixed annoying bugs, added reassignment of anchor. FIRST RELEASE VERSION
This commit is contained in:
parent
6813c6249d
commit
249f5e6b78
@ -39,11 +39,11 @@ regexis024_build_system.sh
|
|||||||
Помимо самого бинарника нужен файл с настройками сервиса. Формат настроек: JSON.
|
Помимо самого бинарника нужен файл с настройками сервиса. Формат настроек: JSON.
|
||||||
Комментарии не поддерживаются. Пример такого файла находится в example/config.json.
|
Комментарии не поддерживаются. Пример такого файла находится в example/config.json.
|
||||||
Вместе с бинарным фалом так же распространяются ассеты, необходимые для работы сайта.
|
Вместе с бинарным фалом так же распространяются ассеты, необходимые для работы сайта.
|
||||||
Их можно найти в папке assets. В настроках (поле `["assets"]`) указывается путь до
|
Их можно найти в папке assets. В настроках (поле `config.assets`) указывается путь до
|
||||||
папки с ассетами. Путь может быть как абсолютным, так и относительным к рабочей директории.
|
папки с ассетами. Путь может быть как абсолютным, так и относительным к рабочей директории.
|
||||||
Поле настроек `["database"]` указывает как соединиться с базой данных.
|
Поле настроек `config.database` указывает как соединиться с базой данных.
|
||||||
Поддерживается только база данных sqlite3. Поддерживается только хранение в файле.
|
Поддерживается только база данных sqlite3. Поддерживается только хранение в файле.
|
||||||
Поле `["database"]["file"]` указывает путь где хранится sqlite база данных.
|
Поле `config.database.file` указывает путь где хранится sqlite база данных.
|
||||||
|
|
||||||
Перед тем как использовать сервис нужно его проинициализировать (а точнее проинициализировать
|
Перед тем как использовать сервис нужно его проинициализировать (а точнее проинициализировать
|
||||||
базу данных):
|
базу данных):
|
||||||
@ -87,7 +87,8 @@ iu9-ca-web-chat-admin-cli <server admin-control address> <command text> [<comman
|
|||||||
- `ru-RU`
|
- `ru-RU`
|
||||||
- `en-US`
|
- `en-US`
|
||||||
|
|
||||||
Все переводы хранятся в папке `assets/lang`.
|
Все переводы хранятся в папке `assets/lang`. Для добавления своего перевода нужно форкнуть репозиторий и
|
||||||
|
сделать копию файла `assets/lang/ru-RU.lang.json` в `assets/lang/XXXXX.lang.json`.
|
||||||
|
|
||||||
# Список участников
|
# Список участников
|
||||||
|
|
||||||
|
@ -24,9 +24,11 @@ let bumpedAtBottom = false;
|
|||||||
// Persists from popup activation until popup deactivation
|
// Persists from popup activation until popup deactivation
|
||||||
let storeHiddenMsgIdForDeletionWin = -1;
|
let storeHiddenMsgIdForDeletionWin = -1;
|
||||||
|
|
||||||
|
let debugMode = false;
|
||||||
|
|
||||||
// Positive in production, negative for debug
|
// Positive in production, negative for debug
|
||||||
let softZoneSz = -150;
|
let softZoneSz = debugMode ? -150 : 300;
|
||||||
let chatPadding = 300;
|
let chatPadding = debugMode ? 300 : 5;
|
||||||
let msgGap = 5;
|
let msgGap = 5;
|
||||||
const msgErased = pres.chat.msgErased;
|
const msgErased = pres.chat.msgErased;
|
||||||
|
|
||||||
@ -41,7 +43,7 @@ function genSentBase(){
|
|||||||
|
|
||||||
function genSentBaseGMN(){
|
function genSentBaseGMN(){
|
||||||
let Sent = genSentBase();
|
let Sent = genSentBase();
|
||||||
Sent.amount = 1;
|
Sent.amount = debugMode ? 2 : 14;
|
||||||
return Sent;
|
return Sent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,8 +114,8 @@ function updateOffsets(){
|
|||||||
elSetOffsetInChat(spinnerTop, chatPadding);
|
elSetOffsetInChat(spinnerTop, chatPadding);
|
||||||
setElementVisibility(spinnerTop, isMissingPrimaryMsgHeap());
|
setElementVisibility(spinnerTop, isMissingPrimaryMsgHeap());
|
||||||
} else {
|
} else {
|
||||||
updateOffsetsSane();
|
|
||||||
let [W, H] = getChatWgSz();
|
let [W, H] = getChatWgSz();
|
||||||
|
updateOffsetsSane();
|
||||||
let lowestLowestPoint = isMissingBottomMsgHeap() ? lowestPoint - heightOfPreloadGhost(): lowestPoint;
|
let lowestLowestPoint = isMissingBottomMsgHeap() ? lowestPoint - heightOfPreloadGhost(): lowestPoint;
|
||||||
let highestHighestPoint = isMissingTopMsgHeap() ? highestPoint + heightOfPreloadGhost() : highestPoint;
|
let highestHighestPoint = isMissingTopMsgHeap() ? highestPoint + heightOfPreloadGhost() : highestPoint;
|
||||||
if (lowestLowestPoint > chatPadding || (highestHighestPoint - lowestLowestPoint) <= H - chatPadding * 2 ||
|
if (lowestLowestPoint > chatPadding || (highestHighestPoint - lowestLowestPoint) <= H - chatPadding * 2 ||
|
||||||
@ -131,6 +133,22 @@ function updateOffsets(){
|
|||||||
setElementVisibility(spinnerTop, isMissingTopMsgHeap());
|
setElementVisibility(spinnerTop, isMissingTopMsgHeap());
|
||||||
elSetOffsetInChat(spinnerBottom, lowestPoint - SbH);
|
elSetOffsetInChat(spinnerBottom, lowestPoint - SbH);
|
||||||
setElementVisibility(spinnerBottom, isMissingBottomMsgHeap());
|
setElementVisibility(spinnerBottom, isMissingBottomMsgHeap());
|
||||||
|
/* Fix anchor */
|
||||||
|
let oldAnchor = anchoredMsg;
|
||||||
|
while (true){
|
||||||
|
let h = visibleMessages.get(anchoredMsg).container.offsetHeight;
|
||||||
|
if (!(offsetOfAnchor + h < chatPadding && visibleMsgSegStart < anchoredMsg))
|
||||||
|
break
|
||||||
|
offsetOfAnchor += (msgGap + h);
|
||||||
|
anchoredMsg--;
|
||||||
|
}
|
||||||
|
while (offsetOfAnchor > H - chatPadding && anchoredMsg < visibleMsgSegEnd){
|
||||||
|
anchoredMsg++;
|
||||||
|
let h = visibleMessages.get(anchoredMsg).container.offsetHeight;
|
||||||
|
offsetOfAnchor -= (msgGap + h);
|
||||||
|
}
|
||||||
|
if (oldAnchor !== anchoredMsg)
|
||||||
|
console.log("anchoredMsg: " + String(oldAnchor) + " -> " + String(anchoredMsg))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,7 +274,7 @@ function convertMessageStToSupercontainer(messageSt){
|
|||||||
} else
|
} else
|
||||||
msgPart.innerText = msgErased;
|
msgPart.innerText = msgErased;
|
||||||
|
|
||||||
return {'container': container, 'box': box, 'offset': 0};
|
return {'container': container, 'box': box};
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeVisible(msgId){
|
function makeVisible(msgId){
|
||||||
@ -303,7 +321,6 @@ function canISendMessages(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updateLocalStateFromChatUpdRespBlind(chatUpdResp){
|
function updateLocalStateFromChatUpdRespBlind(chatUpdResp){
|
||||||
console.log(anchoredMsg, offsetOfAnchor, chatUpdResp);
|
|
||||||
LocalHistoryId = chatUpdResp.HistoryId;
|
LocalHistoryId = chatUpdResp.HistoryId;
|
||||||
for (let memberSt of chatUpdResp.members){
|
for (let memberSt of chatUpdResp.members){
|
||||||
let id = memberSt.userId;
|
let id = memberSt.userId;
|
||||||
@ -343,7 +360,6 @@ function needToLoadWhitespace(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function tryLoadWhitespaceSingle(){
|
async function tryLoadWhitespaceSingle(){
|
||||||
console.log('tryLoadWhitespaceSingle');
|
|
||||||
if (isMissingPrimaryMsgHeap()){
|
if (isMissingPrimaryMsgHeap()){
|
||||||
await requestMessageNeighbours(-1, "backward");
|
await requestMessageNeighbours(-1, "backward");
|
||||||
} else if (isMissingTopMsgHeap()){
|
} else if (isMissingTopMsgHeap()){
|
||||||
@ -359,7 +375,8 @@ async function loadWhitespaceMultitry(){
|
|||||||
do {
|
do {
|
||||||
try {
|
try {
|
||||||
await tryLoadWhitespaceSingle();
|
await tryLoadWhitespaceSingle();
|
||||||
await sleep(1100);
|
if (debugMode)
|
||||||
|
await sleep(900);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
await sleep(1500);
|
await sleep(1500);
|
||||||
@ -427,7 +444,6 @@ window.onload = function (){
|
|||||||
if (event.ctrlKey && event.key === 'Enter'){
|
if (event.ctrlKey && event.key === 'Enter'){
|
||||||
let textarea = document.getElementById("message-input");
|
let textarea = document.getElementById("message-input");
|
||||||
let text = String(textarea.innerText);
|
let text = String(textarea.innerText);
|
||||||
console.log(text);
|
|
||||||
textarea.innerText = "";
|
textarea.innerText = "";
|
||||||
let Sent = genSentBase();
|
let Sent = genSentBase();
|
||||||
Sent.content = {};
|
Sent.content = {};
|
||||||
@ -446,8 +462,10 @@ window.onload = function (){
|
|||||||
elSetOffsetInChat(document.getElementById("debug-line-top-padding"), H - chatPadding);
|
elSetOffsetInChat(document.getElementById("debug-line-top-padding"), H - chatPadding);
|
||||||
elSetOffsetInChat(document.getElementById("debug-line-bottom-padding"), chatPadding)
|
elSetOffsetInChat(document.getElementById("debug-line-bottom-padding"), chatPadding)
|
||||||
};
|
};
|
||||||
|
if (debugMode){
|
||||||
window.addEventListener("resize", chatWgDebugLinesFnc);
|
window.addEventListener("resize", chatWgDebugLinesFnc);
|
||||||
chatWgDebugLinesFnc();
|
chatWgDebugLinesFnc();
|
||||||
|
}
|
||||||
|
|
||||||
configureMsgDeletionPopupButtons();
|
configureMsgDeletionPopupButtons();
|
||||||
|
|
||||||
|
@ -18,13 +18,20 @@ let __mainloopDelayMs = 3000;
|
|||||||
let mainloopTimeout = null;
|
let mainloopTimeout = null;
|
||||||
let __guestMainloopPollerAction = null;
|
let __guestMainloopPollerAction = null;
|
||||||
function setMainloopTimeout(){
|
function setMainloopTimeout(){
|
||||||
|
if (mainloopTimeout !== null)
|
||||||
|
return;
|
||||||
mainloopTimeout = setTimeout(mainloopPoller, __mainloopDelayMs);
|
mainloopTimeout = setTimeout(mainloopPoller, __mainloopDelayMs);
|
||||||
}
|
}
|
||||||
function cancelMainloopTimeout(){
|
function cancelMainloopTimeout(){
|
||||||
|
if (mainloopTimeout === null){
|
||||||
|
console.log("cancelling nothing")
|
||||||
|
return;
|
||||||
|
}
|
||||||
clearTimeout(mainloopTimeout);
|
clearTimeout(mainloopTimeout);
|
||||||
mainloopTimeout = null;
|
mainloopTimeout = null;
|
||||||
}
|
}
|
||||||
function mainloopPoller(){
|
function mainloopPoller(){
|
||||||
|
mainloopTimeout = null;
|
||||||
try {
|
try {
|
||||||
if (__guestMainloopPollerAction)
|
if (__guestMainloopPollerAction)
|
||||||
__guestMainloopPollerAction();
|
__guestMainloopPollerAction();
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
namespace iu9cawebchat {
|
namespace iu9cawebchat {
|
||||||
json::JSON internalapi_deleteMessage(SqliteConnection& conn, int64_t uid, const json::JSON& Sent) {
|
json::JSON internalapi_deleteMessage(SqliteConnection& conn, int64_t uid, const json::JSON& Sent) {
|
||||||
// debug_print_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_deleted)
|
||||||
|
@ -31,7 +31,6 @@ namespace iu9cawebchat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
json::JSON internalapi_sendMessage(SqliteConnection& conn, int64_t uid, const json::JSON& Sent) {
|
json::JSON internalapi_sendMessage(SqliteConnection& conn, int64_t uid, const json::JSON& Sent) {
|
||||||
debug_print_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_deleted)
|
||||||
@ -46,7 +45,6 @@ namespace iu9cawebchat {
|
|||||||
|
|
||||||
json::JSON Recv;
|
json::JSON Recv;
|
||||||
poll_update_chat(conn, Sent, Recv);
|
poll_update_chat(conn, Sent, Recv);
|
||||||
debug_print_json(Recv);
|
|
||||||
return Recv;
|
return Recv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,7 +166,6 @@ namespace iu9cawebchat {
|
|||||||
|
|
||||||
/* Reznya */
|
/* Reznya */
|
||||||
json::JSON internalapi_getMessageNeighbours(SqliteConnection& conn, int64_t uid, const json::JSON& Sent) {
|
json::JSON internalapi_getMessageNeighbours(SqliteConnection& conn, int64_t uid, const json::JSON& Sent) {
|
||||||
debug_print_json(Sent);
|
|
||||||
int64_t chatId = Sent["chatUpdReq"]["chatId"].asInteger().get_int();
|
int64_t chatId = Sent["chatUpdReq"]["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("Authentication failure");
|
een9_THROW("Authentication failure");
|
||||||
@ -194,7 +193,6 @@ namespace iu9cawebchat {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
poll_update_chat_important_segment(conn, Sent, Recv, qBeg, qEnd);
|
poll_update_chat_important_segment(conn, Sent, Recv, qBeg, qEnd);
|
||||||
debug_print_json(Recv);
|
|
||||||
return Recv;
|
return Recv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,8 @@ int main(int argc, char** argv){
|
|||||||
iu9cawebchat::initialize_website(config, root_pw);
|
iu9cawebchat::initialize_website(config, root_pw);
|
||||||
} else if (cmd == "run") {
|
} else if (cmd == "run") {
|
||||||
iu9cawebchat::run_website(config);
|
iu9cawebchat::run_website(config);
|
||||||
|
} else if (cmd == "version") {
|
||||||
|
printf("IU9 Collarbone Annihilation Web Chat (service) V 1.0\n");
|
||||||
} else
|
} else
|
||||||
een9_THROW("unknown action (known are 'run', 'initialize')");
|
een9_THROW("unknown action (known are 'run', 'initialize')");
|
||||||
} catch (std::exception& e) {
|
} catch (std::exception& e) {
|
||||||
|
Loading…
Reference in New Issue
Block a user