SHA256
14-04-2026
Веб пуш работает. Дальше попробую звонки добавить.
This commit is contained in:
+1
-1
@@ -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
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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');
|
||||
|
||||
Reference in New Issue
Block a user