Add button to mark chat read on chat-bottom-bar; make icon-btn icon color change to ensure visibility with hover effects; make waha show in-app notification for errors.

This commit is contained in:
天クマ 2026-07-19 11:23:08 -03:00
commit 932e63e299
7 changed files with 38 additions and 3 deletions

View file

@ -106,6 +106,7 @@
</footer>
<!-- Bottom Bar -->
<footer id="chat-bottom-bar" class="chat-expanded-panel alternate-panel collapsed">
<button id="markread-btn" class="icon-btn send-btn mif-done_all mif-2x" title="Mark read"></button>
<input id="attachment-input" style="display: none;" type="file">
<button id="attachment-btn" class="icon-btn send-btn mif-attachment mif-2x" title="Attach file"></button>
</footer>

View file

@ -3,7 +3,7 @@ import { waha } from "./waha.js";
import { ui, elements } from "./ui.js";
import { websocket } from "./websocket.js";
import { compensateMessageOrdering, debounce, formatTime, normalizeId } from "./utils.js";
import { fetchChats, getAppUser, getChatMessages, getChatPicture, getChats, getUser, getUserAbout, sendStatus, updateOnlineStatus } from "./storage.js";
import { fetchChats, getAppUser, getChatMessages, getChatPicture, getChats, getUser, getUserAbout, markRead, sendStatus, updateOnlineStatus } from "./storage.js";
import { upsertMessages } from "./db.js";
import { showNotification } from "./notification.js";
@ -181,6 +181,9 @@ function setupEventListeners() {
if (e.target == e.currentTarget) ui.toggleChatBottomBar();
});
elements.markreadBtn.addEventListener('click', () => {
markRead(activeChatState.id);
})
elements.attachmentBtn.addEventListener('click', () => {
elements.attachmentInput.click();
})

View file

@ -107,6 +107,19 @@ export async function loadChatsSorted() {
});
}
export async function loadChat(chatId) {
const db = await openDb();
return new Promise((resolve, reject) => {
const tx = db.transaction("chats", "readonly");
const store = tx.objectStore("chats");
const req = store.get(chatId);
tx.oncomplete = () => resolve(req.result)
tx.onerror = () => reject(req.error);
});
}
function mapMessage(m) {
const from = normalizeId(m.from);
const to = normalizeId(m.to);

View file

@ -1,4 +1,4 @@
import { loadChatsSorted, loadLatestMessages, loadMedia, loadOlderMessages, upsertChats, upsertMedia, upsertMessages } from "./db.js";
import { loadChat, loadChatsSorted, loadLatestMessages, loadMedia, loadOlderMessages, upsertChats, upsertMedia, upsertMessages } from "./db.js";
import { waha } from "./waha.js";
let online = false;
@ -147,4 +147,14 @@ export async function sendStatus(text) {
success: false
}
}
}
export async function markRead(chatId) {
if (online) {
await waha.readChat(chatId);
}
const chat = await loadChat(chatId);
chat.unreadCount = 0;
upsertMessages([chat]);
}

View file

@ -32,6 +32,7 @@ export const elements = {
chatInputPanel: document.getElementById('chat-input-panel'),
attachmentInput: document.getElementById('attachment-input'),
attachmentBtn: document.getElementById('attachment-btn'),
markreadBtn: document.getElementById('markread-btn'),
extraPages: document.querySelectorAll('.extra-page'),
desktopSidebarButtons: document.querySelectorAll("#desktop-aside button"),
contentUserName: document.querySelectorAll('[data-content="app-user"]'),

View file

@ -1,4 +1,5 @@
import { config } from "./config.js";
import { showNotification } from "./notification.js";
import { getBase64 } from "./utils.js";
async function request(path, options = {}) {
@ -24,6 +25,8 @@ async function request(path, options = {}) {
} catch (_) {
errorDetail = await response.text().catch(() => '');
}
showNotification("API Error", `WAHA API returned ${response.status}: ${response.statusText}${errorDetail}`, 2000);
throw new Error(`WAHA API returned ${response.status}: ${response.statusText}${errorDetail}`);
}
return response.json();

View file

@ -233,10 +233,14 @@ input:focus {
.icon-btn:hover {
background: rgba(255, 255, 255, 0.08);
color: var(--text-primary);
color: var(--bg-main);
border-color: var(--border-hover);
}
.icon-btn:hover::before {
color: var(--bg-main);
}
.icon-btn:active {
transform: translateY(0);
}