14-04-2026

Веб пуш работает. Дальше попробую звонки добавить.
This commit is contained in:
AidarKC
2026-04-15 00:50:25 +03:00
parent 21fbc8ffa0
commit 0b7691bdea
7 changed files with 152 additions and 6 deletions
+1 -1
View File
@@ -292,7 +292,7 @@ async function ensureSessionRuntimeStarted() {
pingIntervalId = window.setInterval(async () => {
if (!state.session.isAuthorized) return;
try {
await authService.ws.request('Ping', { timeMs: Date.now() });
await authService.ws.request('Ping', { ts: Date.now() });
} catch {
// silent keep-alive
}
+53 -1
View File
@@ -24,10 +24,12 @@ export function render({ navigate }) {
const controls = document.createElement('div');
controls.className = 'card row';
controls.style.justifyContent = 'space-between';
controls.style.justifyContent = 'flex-start';
controls.style.gap = '8px';
controls.style.flexWrap = 'wrap';
controls.innerHTML = `
<button class="ghost-btn" type="button" data-action="refresh">Обновить</button>
<button class="ghost-btn" type="button" data-action="copy-all">Скопировать всё</button>
<button class="ghost-btn" type="button" data-action="clear">Очистить</button>
`;
@@ -38,6 +40,39 @@ export function render({ navigate }) {
const list = document.createElement('div');
list.className = 'stack';
function entriesToClipboardText(entries) {
return entries
.slice()
.reverse()
.map((entry) => {
const level = String(entry.level || 'info').toUpperCase();
const source = String(entry.source || 'ui');
const header = `[${formatTime(entry.ts)}] ${level} ${source}`;
const message = String(entry.message || '');
const details = String(entry.details || '').trim();
return details ? `${header}\n${message}\n${details}` : `${header}\n${message}`;
})
.join('\n\n');
}
async function copyTextToClipboard(text) {
if (navigator?.clipboard?.writeText) {
await navigator.clipboard.writeText(text);
return true;
}
const ta = document.createElement('textarea');
ta.value = text;
ta.setAttribute('readonly', '');
ta.style.position = 'fixed';
ta.style.opacity = '0';
ta.style.pointerEvents = 'none';
document.body.append(ta);
ta.select();
const ok = document.execCommand('copy');
ta.remove();
return !!ok;
}
function renderEntries() {
const entries = getAppLogEntries();
list.innerHTML = '';
@@ -85,6 +120,23 @@ export function render({ navigate }) {
}
controls.querySelector('[data-action="refresh"]').addEventListener('click', renderEntries);
controls.querySelector('[data-action="copy-all"]').addEventListener('click', async () => {
const entries = getAppLogEntries();
if (!entries.length) {
status.className = 'status-line';
status.textContent = 'Лог пуст, копировать нечего.';
return;
}
try {
const text = entriesToClipboardText(entries);
await copyTextToClipboard(text);
status.className = 'status-line is-available';
status.textContent = `Записей: ${entries.length} · скопировано`;
} catch (e) {
status.className = 'status-line';
status.textContent = 'Ошибка копирования лога.';
}
});
controls.querySelector('[data-action="clear"]').addEventListener('click', () => {
clearAppLogEntries();
renderEntries();
+23 -2
View File
@@ -1,6 +1,6 @@
import { renderHeader } from '../components/header.js';
import { directMessages } from '../mock-data.js';
import { addChatMessage, getChatMessages, authService, state } from '../state.js';
import { addAppLogEntry, addChatMessage, getChatMessages, authService, state } from '../state.js';
export const pageMeta = { id: 'chat-view', title: 'Чат' };
@@ -66,14 +66,35 @@ export function render({ navigate, route }) {
renderLog(log, chatId);
try {
await authService.sendDirectMessage({
const result = await authService.sendDirectMessage({
login: state.session.login,
toLogin: chatId,
text,
storagePwd: state.session.storagePwdInMemory,
});
addAppLogEntry({
level: 'info',
source: 'outgoing-dm',
message: `Сообщение отправлено для ${chatId}`,
details: {
toLogin: chatId,
messageId: result?.messageId || '',
deliveredWsSessions: Number(result?.deliveredWsSessions || 0),
deliveredWebPushSessions: Number(result?.deliveredWebPushSessions || 0),
sessionNotFound: Boolean(result?.sessionNotFound),
},
});
} catch (e) {
addChatMessage(chatId, `Ошибка отправки: ${e.message || 'unknown'}`);
addAppLogEntry({
level: 'warn',
source: 'outgoing-dm',
message: 'Ошибка отправки личного сообщения',
details: {
toLogin: chatId,
error: e?.message || 'unknown',
},
});
renderLog(log, chatId);
}
});
+1 -1
View File
@@ -49,7 +49,7 @@ export function render({ navigate }) {
loginButton.addEventListener('click', () => navigate('login-password-view'));
const actions = document.createElement('div');
actions.className = 'auth-actions';
actions.className = 'auth-actions login-actions-wide';
actions.append(cameraButton, loginButton);
const backButton = document.createElement('button');