UI: уплотнить журнал загрузок Arweave

This commit is contained in:
AidarKC
2026-07-31 13:50:17 +04:00
parent 98eba54621
commit cd67176b41
9 changed files with 219 additions and 67 deletions
+42 -28
View File
@@ -1,7 +1,6 @@
import { renderHeader } from '../components/header.js';
import {
clearArweaveAttachmentHistory,
formatArweaveHistoryDateTime,
formatArweaveHistoryTime,
getArweaveAttachmentAvailability,
openArweaveAttachmentManager,
readArweaveAttachmentHistory,
@@ -10,7 +9,7 @@ import { formatBytes } from '../services/attachment-format.js';
import { toUserMessage } from '../services/ui-error-texts.js';
import { state } from '../state.js';
export const pageMeta = { id: 'arweave-uploads-view', title: 'Загрузки в Arweave' };
export const pageMeta = { id: 'arweave-uploads-view', title: 'Загрузить файлы в блокчейн' };
function setStatusBadge(node, status, label) {
if (!node) return;
@@ -22,10 +21,8 @@ function renderTile(item, index) {
const tile = document.createElement('article');
tile.className = 'ar-attachment-history-tile ar-attachment-history-tile--page';
const head = document.createElement('div');
head.className = 'ar-attachment-history-tile-head';
const name = document.createElement('strong');
name.className = 'ar-attachment-history-name';
name.textContent = item.name;
const status = document.createElement('span');
@@ -34,15 +31,24 @@ function renderTile(item, index) {
status.textContent = 'Проверяем...';
const meta = document.createElement('div');
meta.className = 'meta-muted';
meta.textContent = `${formatBytes(item.size)} · ${formatArweaveHistoryDateTime(item.uploadedAtMs)}`;
meta.className = 'ar-attachment-history-meta-row';
const size = document.createElement('span');
size.textContent = formatBytes(item.size);
const time = document.createElement('span');
time.textContent = formatArweaveHistoryTime(item.uploadedAtMs);
meta.append(size, time, status);
if (item.pendingPlacement) {
const flag = document.createElement('span');
flag.className = 'ar-attachment-placement-flag';
flag.textContent = 'Не добавлен в SHiNE';
meta.append(flag);
}
const txId = document.createElement('div');
txId.className = 'mono-cell ar-attachment-history-txid';
txId.textContent = item.ar;
head.append(name, status);
tile.append(head, meta, txId);
tile.append(name, meta, txId);
return tile;
}
@@ -50,25 +56,16 @@ export function render({ navigate }) {
const screen = document.createElement('section');
screen.className = 'stack arweave-uploads-screen';
screen.append(
renderHeader({
title: 'Загрузки в Arweave',
leftAction: { label: '←', onClick: () => navigate('settings-view') },
}),
);
const intro = document.createElement('div');
intro.className = 'card stack';
intro.innerHTML = `
<p class="field-label">Журнал файлов этой сессии</p>
<p class="meta-muted">Здесь можно заранее загрузить файл в Arweave. Он попадёт только в журнал, а в сообщение его потом можно добавить из истории загрузок.</p>
`;
const controls = document.createElement('div');
controls.className = 'card arweave-uploads-toolbar';
controls.className = 'arweave-uploads-toolbar';
controls.innerHTML = `
<button class="secondary-btn arweave-uploads-back" type="button" data-action="back" aria-label="Назад">←</button>
<button class="primary-btn" type="button" data-action="upload">Добавить файл</button>
<button class="secondary-btn" type="button" data-action="clear">Очистить историю</button>
<button class="secondary-btn arweave-uploads-menu-btn" type="button" data-action="menu" aria-label="Меню">⋯</button>
<div class="arweave-uploads-menu" data-menu="true" hidden>
<button class="text-btn" type="button" data-action="clear">Очистить историю</button>
<button class="text-btn" type="button" data-action="help">Справка</button>
</div>
`;
const statusLine = document.createElement('p');
@@ -80,7 +77,7 @@ export function render({ navigate }) {
function renderHistory() {
const rows = readArweaveAttachmentHistory(state.session.login).slice().reverse();
list.innerHTML = '';
statusLine.textContent = rows.length ? `Файлов в журнале: ${rows.length}` : 'Журнал пока пуст.';
statusLine.textContent = '';
if (!rows.length) {
const empty = document.createElement('div');
@@ -113,6 +110,7 @@ export function render({ navigate }) {
login: state.session.login,
storagePwd: state.session.storagePwdInMemory,
gateway: state.entrySettings.arweaveServer,
historyOnly: true,
});
renderHistory();
} catch (error) {
@@ -120,14 +118,30 @@ export function render({ navigate }) {
}
});
controls.querySelector('[data-action="back"]')?.addEventListener('click', () => navigate('settings-view'));
controls.querySelector('[data-action="menu"]')?.addEventListener('click', () => {
const menu = controls.querySelector('[data-menu="true"]');
if (menu) menu.hidden = !menu.hidden;
});
controls.querySelector('[data-action="clear"]')?.addEventListener('click', () => {
const menu = controls.querySelector('[data-menu="true"]');
if (menu) menu.hidden = true;
const confirmed = window.confirm('Очистить журнал загруженных файлов этой сессии?');
if (!confirmed) return;
clearArweaveAttachmentHistory(state.session.login);
renderHistory();
});
controls.querySelector('[data-action="help"]')?.addEventListener('click', () => {
const menu = controls.querySelector('[data-menu="true"]');
if (menu) menu.hidden = true;
window.alert(
'Здесь вы можете заранее добавить файл в Arweave. Файл загрузится в блокчейн-хранилище и сохранится в журнале только этой браузерной сессии.\n\n'
+ 'Потом при создании сообщения можно открыть историю загрузок и выбрать уже загруженный файл по txId. '
+ 'Если файл только что загружен, gateway может несколько минут его не отдавать, поэтому статус может быть “ещё обновляется”.'
);
});
screen.append(intro, controls, statusLine, list);
screen.append(controls, statusLine, list);
renderHistory();
return screen;
}