Add fetching older messages
This commit is contained in:
parent
2e2c080df4
commit
802333a7aa
2 changed files with 88 additions and 8 deletions
|
|
@ -1838,6 +1838,9 @@ var currentDmId = null;
|
||||||
var currentDmKey = null; // AES key for encrypting/decrypting messages
|
var currentDmKey = null; // AES key for encrypting/decrypting messages
|
||||||
var dmUsernameCache = {};
|
var dmUsernameCache = {};
|
||||||
var dmPfpCache = {};
|
var dmPfpCache = {};
|
||||||
|
var loadedMessages = {};
|
||||||
|
var oldestLoadedMsgId = null;
|
||||||
|
var isLoadingOlderMessages = false;
|
||||||
|
|
||||||
async function openDm(dmId, username, targetId) {
|
async function openDm(dmId, username, targetId) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -1848,6 +1851,9 @@ async function openDm(dmId, username, targetId) {
|
||||||
throw new Error("Missing DM room key");
|
throw new Error("Missing DM room key");
|
||||||
}
|
}
|
||||||
currentDmId = dmId;
|
currentDmId = dmId;
|
||||||
|
loadedMessages = {};
|
||||||
|
oldestLoadedMsgId = null;
|
||||||
|
isLoadingOlderMessages = false;
|
||||||
|
|
||||||
let pfp = await getAvatarUrl(targetId, username);
|
let pfp = await getAvatarUrl(targetId, username);
|
||||||
let iconHtml = `<img src="${pfp}" style="width: 2.3rem; border-radius: 0.65rem; margin-right: 0.38rem; object-fit: cover; border: var(--border-width) solid rgba(255, 255, 255, 0.2);">`;
|
let iconHtml = `<img src="${pfp}" style="width: 2.3rem; border-radius: 0.65rem; margin-right: 0.38rem; object-fit: cover; border: var(--border-width) solid rgba(255, 255, 255, 0.2);">`;
|
||||||
|
|
@ -1863,6 +1869,7 @@ async function openDm(dmId, username, targetId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
await loadDmMessages(dmId);
|
await loadDmMessages(dmId);
|
||||||
|
setupChatScrollListener();
|
||||||
|
|
||||||
if (dmMessagePollInterval) clearInterval(dmMessagePollInterval);
|
if (dmMessagePollInterval) clearInterval(dmMessagePollInterval);
|
||||||
dmMessagePollInterval = setInterval(() => {
|
dmMessagePollInterval = setInterval(() => {
|
||||||
|
|
@ -1886,9 +1893,9 @@ async function openDm(dmId, username, targetId) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadDmMessages(dmId) {
|
async function loadDmMessages(dmId, startOffset = "", isPrepend = false) {
|
||||||
try {
|
try {
|
||||||
let payload = JSON.stringify({ string1: dmId, string2: "50", string3: "" });
|
let payload = JSON.stringify({ string1: dmId, string2: "50", string3: startOffset });
|
||||||
let res = await fetchEncrypted("dm/messages/get", payload);
|
let res = await fetchEncrypted("dm/messages/get", payload);
|
||||||
|
|
||||||
if (res && res.startsWith("error:")) {
|
if (res && res.startsWith("error:")) {
|
||||||
|
|
@ -1897,14 +1904,26 @@ async function loadDmMessages(dmId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
let messages = JSON.parse(res);
|
let messages = JSON.parse(res);
|
||||||
await renderMessages(messages);
|
let ids = Object.keys(messages).map(id => parseInt(id));
|
||||||
|
if (ids.length > 0) {
|
||||||
|
let minId = Math.min(...ids);
|
||||||
|
if (oldestLoadedMsgId === null || minId < oldestLoadedMsgId) {
|
||||||
|
oldestLoadedMsgId = minId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ids.length < 50 && startOffset !== "") {
|
||||||
|
oldestLoadedMsgId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(loadedMessages, messages);
|
||||||
|
await renderMessages(loadedMessages, isPrepend);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
showBlahNotification("error:dm.messages.fetch.failed");
|
showBlahNotification("error:dm.messages.fetch.failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function renderMessages(messages) {
|
async function renderMessages(messages, isPrepend = false) {
|
||||||
let container = document.getElementById("chat-messages");
|
let container = document.getElementById("chat-messages");
|
||||||
if (!container) return;
|
if (!container) return;
|
||||||
|
|
||||||
|
|
@ -1981,16 +2000,37 @@ async function renderMessages(messages) {
|
||||||
window.forceScrollToBottom = false;
|
window.forceScrollToBottom = false;
|
||||||
}
|
}
|
||||||
let oldScrollTop = container.scrollTop;
|
let oldScrollTop = container.scrollTop;
|
||||||
|
let oldScrollHeight = container.scrollHeight;
|
||||||
|
|
||||||
container.innerHTML = html;
|
container.innerHTML = html;
|
||||||
|
|
||||||
if (wasAtBottom) {
|
if (wasAtBottom) {
|
||||||
container.scrollTop = container.scrollHeight;
|
container.scrollTop = container.scrollHeight;
|
||||||
|
} else if (isPrepend) {
|
||||||
|
container.scrollTop = oldScrollTop + (container.scrollHeight - oldScrollHeight);
|
||||||
} else {
|
} else {
|
||||||
container.scrollTop = oldScrollTop;
|
container.scrollTop = oldScrollTop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setupChatScrollListener() {
|
||||||
|
let container = document.getElementById("chat-messages");
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
container.onscroll = async () => {
|
||||||
|
if (container.scrollTop === 0 && !isLoadingOlderMessages && oldestLoadedMsgId !== null && oldestLoadedMsgId > 0) {
|
||||||
|
isLoadingOlderMessages = true;
|
||||||
|
showAction("info.messages.loading.older", "messages.loading.older");
|
||||||
|
try {
|
||||||
|
await loadDmMessages(currentDmId, (oldestLoadedMsgId - 1).toString(), true);
|
||||||
|
isLoadingOlderMessages = false;
|
||||||
|
}
|
||||||
|
catch (e) {}
|
||||||
|
clearAction("messages.loading.older");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
async function sendMessage() {
|
async function sendMessage() {
|
||||||
if (!currentDmId || !currentDmKey) return;
|
if (!currentDmId || !currentDmKey) return;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1838,6 +1838,9 @@ var currentDmId = null;
|
||||||
var currentDmKey = null; // AES key for encrypting/decrypting messages
|
var currentDmKey = null; // AES key for encrypting/decrypting messages
|
||||||
var dmUsernameCache = {};
|
var dmUsernameCache = {};
|
||||||
var dmPfpCache = {};
|
var dmPfpCache = {};
|
||||||
|
var loadedMessages = {};
|
||||||
|
var oldestLoadedMsgId = null;
|
||||||
|
var isLoadingOlderMessages = false;
|
||||||
|
|
||||||
async function openDm(dmId, username, targetId) {
|
async function openDm(dmId, username, targetId) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -1848,6 +1851,9 @@ async function openDm(dmId, username, targetId) {
|
||||||
throw new Error("Missing DM room key");
|
throw new Error("Missing DM room key");
|
||||||
}
|
}
|
||||||
currentDmId = dmId;
|
currentDmId = dmId;
|
||||||
|
loadedMessages = {};
|
||||||
|
oldestLoadedMsgId = null;
|
||||||
|
isLoadingOlderMessages = false;
|
||||||
|
|
||||||
let pfp = await getAvatarUrl(targetId, username);
|
let pfp = await getAvatarUrl(targetId, username);
|
||||||
let iconHtml = `<img src="${pfp}" style="width: 2.3rem; border-radius: 0.65rem; margin-right: 0.38rem; object-fit: cover; border: var(--border-width) solid rgba(255, 255, 255, 0.2);">`;
|
let iconHtml = `<img src="${pfp}" style="width: 2.3rem; border-radius: 0.65rem; margin-right: 0.38rem; object-fit: cover; border: var(--border-width) solid rgba(255, 255, 255, 0.2);">`;
|
||||||
|
|
@ -1863,6 +1869,7 @@ async function openDm(dmId, username, targetId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
await loadDmMessages(dmId);
|
await loadDmMessages(dmId);
|
||||||
|
setupChatScrollListener();
|
||||||
|
|
||||||
if (dmMessagePollInterval) clearInterval(dmMessagePollInterval);
|
if (dmMessagePollInterval) clearInterval(dmMessagePollInterval);
|
||||||
dmMessagePollInterval = setInterval(() => {
|
dmMessagePollInterval = setInterval(() => {
|
||||||
|
|
@ -1886,9 +1893,9 @@ async function openDm(dmId, username, targetId) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadDmMessages(dmId) {
|
async function loadDmMessages(dmId, startOffset = "", isPrepend = false) {
|
||||||
try {
|
try {
|
||||||
let payload = JSON.stringify({ string1: dmId, string2: "50", string3: "" });
|
let payload = JSON.stringify({ string1: dmId, string2: "50", string3: startOffset });
|
||||||
let res = await fetchEncrypted("dm/messages/get", payload);
|
let res = await fetchEncrypted("dm/messages/get", payload);
|
||||||
|
|
||||||
if (res && res.startsWith("error:")) {
|
if (res && res.startsWith("error:")) {
|
||||||
|
|
@ -1897,14 +1904,26 @@ async function loadDmMessages(dmId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
let messages = JSON.parse(res);
|
let messages = JSON.parse(res);
|
||||||
await renderMessages(messages);
|
let ids = Object.keys(messages).map(id => parseInt(id));
|
||||||
|
if (ids.length > 0) {
|
||||||
|
let minId = Math.min(...ids);
|
||||||
|
if (oldestLoadedMsgId === null || minId < oldestLoadedMsgId) {
|
||||||
|
oldestLoadedMsgId = minId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ids.length < 50 && startOffset !== "") {
|
||||||
|
oldestLoadedMsgId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object.assign(loadedMessages, messages);
|
||||||
|
await renderMessages(loadedMessages, isPrepend);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
showBlahNotification("error:dm.messages.fetch.failed");
|
showBlahNotification("error:dm.messages.fetch.failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function renderMessages(messages) {
|
async function renderMessages(messages, isPrepend = false) {
|
||||||
let container = document.getElementById("chat-messages");
|
let container = document.getElementById("chat-messages");
|
||||||
if (!container) return;
|
if (!container) return;
|
||||||
|
|
||||||
|
|
@ -1981,16 +2000,37 @@ async function renderMessages(messages) {
|
||||||
window.forceScrollToBottom = false;
|
window.forceScrollToBottom = false;
|
||||||
}
|
}
|
||||||
let oldScrollTop = container.scrollTop;
|
let oldScrollTop = container.scrollTop;
|
||||||
|
let oldScrollHeight = container.scrollHeight;
|
||||||
|
|
||||||
container.innerHTML = html;
|
container.innerHTML = html;
|
||||||
|
|
||||||
if (wasAtBottom) {
|
if (wasAtBottom) {
|
||||||
container.scrollTop = container.scrollHeight;
|
container.scrollTop = container.scrollHeight;
|
||||||
|
} else if (isPrepend) {
|
||||||
|
container.scrollTop = oldScrollTop + (container.scrollHeight - oldScrollHeight);
|
||||||
} else {
|
} else {
|
||||||
container.scrollTop = oldScrollTop;
|
container.scrollTop = oldScrollTop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setupChatScrollListener() {
|
||||||
|
let container = document.getElementById("chat-messages");
|
||||||
|
if (!container) return;
|
||||||
|
|
||||||
|
container.onscroll = async () => {
|
||||||
|
if (container.scrollTop === 0 && !isLoadingOlderMessages && oldestLoadedMsgId !== null && oldestLoadedMsgId > 0) {
|
||||||
|
isLoadingOlderMessages = true;
|
||||||
|
showAction("info.messages.loading.older", "messages.loading.older");
|
||||||
|
try {
|
||||||
|
await loadDmMessages(currentDmId, (oldestLoadedMsgId - 1).toString(), true);
|
||||||
|
isLoadingOlderMessages = false;
|
||||||
|
}
|
||||||
|
catch (e) {}
|
||||||
|
clearAction("messages.loading.older");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
async function sendMessage() {
|
async function sendMessage() {
|
||||||
if (!currentDmId || !currentDmKey) return;
|
if (!currentDmId || !currentDmKey) return;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue