Remove usage of userInfo in app.js; make storage aware of connection status to avoid connecting to the server in offline mode; fix updateChaInList querying for non-existent elements and using them blindly; make websocket also check connection status on reload.

This commit is contained in:
天クマ 2026-07-16 19:36:25 -03:00
commit a021ca821f
4 changed files with 66 additions and 39 deletions

View file

@ -3,14 +3,14 @@ import { waha } from "./waha.js";
import { ui, elements } from "./ui.js"; import { ui, elements } from "./ui.js";
import { websocket } from "./websocket.js"; import { websocket } from "./websocket.js";
import { compensateMessageOrdering, formatTime } from "./utils.js"; import { compensateMessageOrdering, formatTime } from "./utils.js";
import { fetchChats, getAppUser, getChatMessages, getChats } from "./storage.js"; import { fetchChats, getAppUser, getChatMessages, getChats, updateOnlineStatus } from "./storage.js";
import { upsertMessages } from "./db.js"; import { upsertMessages } from "./db.js";
let activeChatState = null; let activeChatState = null;
let userInfo;
const messageTone = new Audio("./message.ogg"); const messageTone = new Audio("./message.ogg");
document.addEventListener('DOMContentLoaded', async () => { document.addEventListener('DOMContentLoaded', async () => {
await updateOnlineStatus();
setupEventListeners(); setupEventListeners();
try { try {
elements.loggedUserName.textContent = await getAppUser().pushName; elements.loggedUserName.textContent = await getAppUser().pushName;
@ -137,7 +137,7 @@ function handleIncomingMessage(msg) {
} }
// console.log('[WS] Resolved msgChatId:', msgChatId, '| activeChatState:', activeChatState?.id); // console.log('[WS] Resolved msgChatId:', msgChatId, '| activeChatState:', activeChatState?.id);
if (msg.fromMe) { if (!msg.fromMe) {
messageTone.play(); messageTone.play();
} }
@ -145,7 +145,7 @@ function handleIncomingMessage(msg) {
const msgId = normalizeChatId(msg.id) || msg.id; const msgId = normalizeChatId(msg.id) || msg.id;
const exists = document.getElementById(msgId); const exists = document.getElementById(msgId);
if (!exists) { if (!exists) {
ui.appendSingleMessage({ ...msg, chatId: msgChatId }, activeChatState.name, userInfo.id); ui.appendSingleMessage({ ...msg, chatId: msgChatId }, activeChatState.name, getAppUser().id);
ui.scrollToBottom(); ui.scrollToBottom();
} }
} }
@ -215,7 +215,7 @@ async function sendMessage() {
status: 'sending' status: 'sending'
}; };
ui.appendSingleMessage(tempMsg, activeChatState.name, userInfo.id); ui.appendSingleMessage(tempMsg, activeChatState.name, getAppUser().id);
ui.scrollToBottom(); ui.scrollToBottom();
try { try {
@ -284,11 +284,12 @@ async function sendFileMessage(file) {
} }
}; };
ui.appendSingleMessage(tempMsg, activeChatState.name, userInfo.id, activeChatState.id, true); ui.appendSingleMessage(tempMsg, activeChatState.name, getAppUser().id, activeChatState.id, true);
ui.scrollToBottom(); ui.scrollToBottom();
const result = await waha.sendFileMessage(activeChatState.id, file); const result = await waha.sendFileMessage(activeChatState.id, file);
ui.updateMessageTick(tempId, result.status); ui.removeChatMessage(tempId);
ui.appendSingleMessage(result.id, activeChatState.name, getAppUser().id, activeChatState.id);
} catch (error) { } catch (error) {
console.error(error.message); console.error(error.message);
} }

View file

@ -1,16 +1,23 @@
import { loadChatsSorted, loadLatestMessages, loadMedia, upsertChats, upsertMedia, upsertMessages } from "./db.js"; import { loadChatsSorted, loadLatestMessages, loadMedia, upsertChats, upsertMedia, upsertMessages } from "./db.js";
import { waha } from "./waha.js"; import { waha } from "./waha.js";
let user; let online = false;
let chats = []; let chats = [];
export async function fetchChats() { export async function updateOnlineStatus() {
try { try {
await getRemoteChats() await waha.getVersion();
online = true;
} catch (error) { } catch (error) {
console.log(error);
online = false;
} }
}
export async function fetchChats() {
if (online) {
await getRemoteChats()
}
chats = await loadChatsSorted(); chats = await loadChatsSorted();
} }
@ -45,27 +52,25 @@ export function getChats() {
} }
export async function getAppUser() { export async function getAppUser() {
if (user) { if (online) {
return user; const info = await waha.getMyInfo();
localStorage.setItem('pandora-last-username', info.name);
localStorage.setItem('pandora-last-userid', info.id);
return info;
} else { } else {
try { return {
return await waha.getMyInfo(); pushName: localStorage.getItem('pandora-last-username') || 'Unknown',
} catch (error) { id: localStorage.getItem('pandora-last-userid') || 'Unknown'
console.error(error);
return {
pushName: "Unknown",
id: "Unknown"
} }
}
} }
} }
export async function getMessage(chatId, msgId, downloadMedia) { export async function getMessage(chatId, msgId, downloadMedia) {
try { if (online) {
const newMessage = await waha.getSingleChatMessage(chatId, msgId, downloadMedia); const newMessage = await waha.getSingleChatMessage(chatId, msgId, downloadMedia);
upsertMessages([newMessage]); upsertMessages([newMessage]);
return newMessage; return newMessage;
} catch (error) { } else {
return { return {
id: `${Date.now()}-temp`, id: `${Date.now()}-temp`,
body: "You're offline", body: "You're offline",
@ -76,33 +81,40 @@ export async function getMessage(chatId, msgId, downloadMedia) {
} }
export async function getMedia(reqId) { export async function getMedia(reqId) {
try {
const media = await waha.downloadMedia(reqId);
upsertMedia(reqId, media.blob, media.filename);
return media;
} catch (error) {
const cached = await loadMedia(reqId); const cached = await loadMedia(reqId);
if (cached) { if (cached) {
return cached; return cached;
} }
throw error;
} try {
if (online) {
const media = await waha.downloadMedia(reqId);
upsertMedia(reqId, media.blob, media.filename);
return media;
}
} catch (error) {
return;
}
} }
export async function getChatMessages(chatId) { export async function getChatMessages(chatId) {
try { if (online) {
const newMessages = await waha.getChatMessages(chatId); const newMessages = await waha.getChatMessages(chatId);
upsertMessages(newMessages); upsertMessages(newMessages);
return newMessages; return newMessages;
} catch (error) { } else {
return await loadLatestMessages(chatId); return await loadLatestMessages(chatId);
} }
} }
export async function getChatPicture(chatId) { export async function getChatPicture(chatId) {
try { if (online) {
return await waha.getChatPicture(chatId); return await waha.getChatPicture(chatId);
} catch (error) { } else {
return ""; return { url: "" };
} }
} }
export function isOnline() {
return online;
}

View file

@ -110,7 +110,7 @@ export const ui = {
<span class="chat-item-time">${timeStr}</span> <span class="chat-item-time">${timeStr}</span>
</div> </div>
<div class="chat-item-preview"> <div class="chat-item-preview">
<span class="chat-item-msg">${chat.lastMessage || 'No messages yet'}</span> <span class="chat-item-msg" data-chatid="${chat.id}">${chat.lastMessage || 'No messages yet'}</span>
${hasUnread ? `<span class="unread-badge">${chat.unreadCount}</span>` : ''} ${hasUnread ? `<span class="unread-badge">${chat.unreadCount}</span>` : ''}
</div> </div>
</div> </div>
@ -122,8 +122,10 @@ export const ui = {
}, },
async updateChatInChatList(msg) { async updateChatInChatList(msg) {
const li = document.getElementById(msg.from); const span = document.querySelector(`.chat-item-msg[data-chatid="${msg.from}"]`);
li.querySelector(".chat-item-msg").innerText = msg.body; if (span) {
span.innerText = msg.body;
}
}, },
/** /**
@ -170,7 +172,6 @@ export const ui = {
}, },
generateMessage(msg, activeChatName, userID, chatId, isLocal = false) { generateMessage(msg, activeChatName, userID, chatId, isLocal = false) {
console.log(msg);
const isOutgoing = msg.fromMe || msg.sender === 'me'; const isOutgoing = msg.fromMe || msg.sender === 'me';
function getPrevMessageElem() { function getPrevMessageElem() {
@ -239,6 +240,11 @@ export const ui = {
a.removeEventListener('click', clickListener); a.removeEventListener('click', clickListener);
a.innerText = `[Downloading]`; a.innerText = `[Downloading]`;
const mediaMsg = msg.media ? msg : await getMessage(chatId, msg.id, true); const mediaMsg = msg.media ? msg : await getMessage(chatId, msg.id, true);
if (!mediaMsg.media.url) {
a.addEventListener('click', clickListener);
a.innerText = `[Error, click to try again]`
return;
}
const url = new URL(mediaMsg.media.url); const url = new URL(mediaMsg.media.url);
const reqID = url.pathname.split('/').filter(Boolean).pop(); const reqID = url.pathname.split('/').filter(Boolean).pop();
@ -319,5 +325,10 @@ export const ui = {
toggleChatBottomBar() { toggleChatBottomBar() {
elements.chatBottomBar.classList.toggle("collapsed"); elements.chatBottomBar.classList.toggle("collapsed");
},
removeChatMessage(msgId) {
const message = document.getElementById(msgId);
if (message) message.remove();
} }
}; };

View file

@ -1,4 +1,5 @@
import { config } from "./config.js"; import { config } from "./config.js";
import { isOnline, updateOnlineStatus } from "./storage.js";
let socket = null; let socket = null;
let reconnectTimer = null; let reconnectTimer = null;
@ -6,6 +7,7 @@ let currentOnMessageCallback = null;
export const websocket = { export const websocket = {
connect(onMessageCallback) { connect(onMessageCallback) {
if (!isOnline) return;
currentOnMessageCallback = onMessageCallback; currentOnMessageCallback = onMessageCallback;
this.disconnect(false); this.disconnect(false);
@ -64,6 +66,7 @@ export const websocket = {
socket = null; socket = null;
reconnectTimer = setTimeout(() => { reconnectTimer = setTimeout(() => {
updateOnlineStatus();
this.connect(currentOnMessageCallback); this.connect(currentOnMessageCallback);
}, 5000); }, 5000);
}; };