import { renderHeader } from '../components/header.js'; import { isSessionInvalidError, refreshSessions, saveEntrySettings, setAuthError, setAuthInfo, state, terminateCurrentSession, } from '../state.js'; export const pageMeta = { id: 'remote-addblock-session-view', title: 'AddBlock через homeserver' }; const SESSION_TYPE_HOMESERVER = 100; function formatSessionTime(ms) { return new Date(ms).toLocaleString('ru-RU', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit', }); } function sessionLabel(session) { const title = String(session?.clientInfoFromClient || '').trim(); if (title) return title; return `Homeserver ${String(session?.sessionId || '').slice(0, 12)}`; } export function render({ navigate }) { const screen = document.createElement('section'); screen.className = 'stack'; screen.append( renderHeader({ title: 'AddBlock через homeserver', leftAction: { label: '←', onClick: () => navigate('settings-view') }, }), ); const actions = document.createElement('div'); actions.className = 'card stack'; actions.innerHTML = `

Если на устройстве нет локального blockchain key, UI сможет отправлять AddBlock в выбранную homeserver-сессию. Homeserver подпишет блок своим blockchain key и сам отправит обычный AddBlock на сервер.

`; const listCard = document.createElement('div'); listCard.className = 'card stack'; const buildList = () => { listCard.innerHTML = ''; const selectedId = String(state.entrySettings.remoteAddBlockSessionId || '').trim(); const sessions = (state.sessions || []) .filter((item) => Number(item?.sessionType || 0) === SESSION_TYPE_HOMESERVER) .sort((a, b) => Number(b?.lastAuthenticatedAtMs || 0) - Number(a?.lastAuthenticatedAtMs || 0)); if (sessions.length === 0) { const empty = document.createElement('p'); empty.className = 'meta-muted'; empty.textContent = 'Активных homeserver-сессий не найдено.'; listCard.append(empty); return; } sessions.forEach((session) => { const sessionId = String(session?.sessionId || '').trim(); const item = document.createElement('button'); item.className = 'session-item'; item.type = 'button'; const isSelected = sessionId && sessionId === selectedId; item.innerHTML = `
${sessionLabel(session)} ${session.geo || 'unknown'} · ${formatSessionTime(session.lastAuthenticatedAtMs || Date.now())} sessionId: ${sessionId || '-'} status: ${session.onlineOnThisServer ? 'online' : 'offline on this server'} ${isSelected ? 'Выбрана для remote AddBlock' : ''}
`; item.addEventListener('click', async () => { try { await saveEntrySettings({ ...state.entrySettings, remoteAddBlockSessionId: sessionId, }); buildList(); setAuthInfo('Homeserver-сессия для remote AddBlock сохранена.'); } catch (error) { if (isSessionInvalidError(error)) { await terminateCurrentSession({ infoMessage: 'Сессия на этом устройстве уже завершена. Выполните вход заново.', }); return; } setAuthError(error.message); window.alert(error.message); } }); listCard.append(item); }); }; actions.querySelector('#remote-addblock-refresh')?.addEventListener('click', async () => { try { await refreshSessions(); buildList(); setAuthInfo('Список homeserver-сессий обновлён.'); } catch (error) { if (isSessionInvalidError(error)) { await terminateCurrentSession({ infoMessage: 'Сессия на этом устройстве уже завершена. Выполните вход заново.', }); return; } setAuthError(error.message); window.alert(error.message); } }); actions.querySelector('#remote-addblock-clear')?.addEventListener('click', async () => { try { await saveEntrySettings({ ...state.entrySettings, remoteAddBlockSessionId: '', }); buildList(); setAuthInfo('Выбор homeserver-сессии для remote AddBlock сброшен.'); } catch (error) { if (isSessionInvalidError(error)) { await terminateCurrentSession({ infoMessage: 'Сессия на этом устройстве уже завершена. Выполните вход заново.', }); return; } setAuthError(error.message); window.alert(error.message); } }); buildList(); screen.append(actions, listCard); return screen; }