SHA256
UI: добавить журнал загрузок Arweave
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
import { renderHeader } from '../components/header.js';
|
||||
import {
|
||||
clearArweaveAttachmentHistory,
|
||||
formatArweaveHistoryDateTime,
|
||||
getArweaveAttachmentAvailability,
|
||||
openArweaveAttachmentManager,
|
||||
readArweaveAttachmentHistory,
|
||||
} from '../components/arweave-attachment-manager.js';
|
||||
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' };
|
||||
|
||||
function setStatusBadge(node, status, label) {
|
||||
if (!node) return;
|
||||
node.className = `ar-attachment-status ar-attachment-status--${status || 'pending'}`;
|
||||
node.textContent = label || 'Проверяем...';
|
||||
}
|
||||
|
||||
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.textContent = item.name;
|
||||
|
||||
const status = document.createElement('span');
|
||||
status.className = 'ar-attachment-status ar-attachment-status--pending';
|
||||
status.dataset.statusIndex = String(index);
|
||||
status.textContent = 'Проверяем...';
|
||||
|
||||
const meta = document.createElement('div');
|
||||
meta.className = 'meta-muted';
|
||||
meta.textContent = `${formatBytes(item.size)} · ${formatArweaveHistoryDateTime(item.uploadedAtMs)}`;
|
||||
|
||||
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);
|
||||
return tile;
|
||||
}
|
||||
|
||||
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.innerHTML = `
|
||||
<button class="primary-btn" type="button" data-action="upload">Добавить файл</button>
|
||||
<button class="secondary-btn" type="button" data-action="clear">Очистить историю</button>
|
||||
`;
|
||||
|
||||
const statusLine = document.createElement('p');
|
||||
statusLine.className = 'meta-muted inline-error';
|
||||
|
||||
const list = document.createElement('div');
|
||||
list.className = 'ar-attachment-history-tiles arweave-uploads-list';
|
||||
|
||||
function renderHistory() {
|
||||
const rows = readArweaveAttachmentHistory(state.session.login).slice().reverse();
|
||||
list.innerHTML = '';
|
||||
statusLine.textContent = rows.length ? `Файлов в журнале: ${rows.length}` : 'Журнал пока пуст.';
|
||||
|
||||
if (!rows.length) {
|
||||
const empty = document.createElement('div');
|
||||
empty.className = 'card meta-muted';
|
||||
empty.textContent = 'Загруженные в этой сессии файлы появятся здесь.';
|
||||
list.append(empty);
|
||||
return;
|
||||
}
|
||||
|
||||
rows.forEach((item, index) => {
|
||||
list.append(renderTile(item, index));
|
||||
const statusEl = list.querySelector(`[data-status-index="${index}"]`);
|
||||
void getArweaveAttachmentAvailability({
|
||||
gateway: state.entrySettings.arweaveServer,
|
||||
attachment: item,
|
||||
})
|
||||
.then((result) => setStatusBadge(statusEl, result.status, result.label))
|
||||
.catch(() => setStatusBadge(statusEl, 'unavailable', 'Недоступен'));
|
||||
});
|
||||
|
||||
window.setTimeout(() => {
|
||||
list.scrollTop = list.scrollHeight;
|
||||
}, 0);
|
||||
}
|
||||
|
||||
controls.querySelector('[data-action="upload"]')?.addEventListener('click', async () => {
|
||||
statusLine.textContent = '';
|
||||
try {
|
||||
await openArweaveAttachmentManager({
|
||||
login: state.session.login,
|
||||
storagePwd: state.session.storagePwdInMemory,
|
||||
gateway: state.entrySettings.arweaveServer,
|
||||
});
|
||||
renderHistory();
|
||||
} catch (error) {
|
||||
statusLine.textContent = toUserMessage(error, 'Не удалось загрузить файл.');
|
||||
}
|
||||
});
|
||||
|
||||
controls.querySelector('[data-action="clear"]')?.addEventListener('click', () => {
|
||||
const confirmed = window.confirm('Очистить журнал загруженных файлов этой сессии?');
|
||||
if (!confirmed) return;
|
||||
clearArweaveAttachmentHistory(state.session.login);
|
||||
renderHistory();
|
||||
});
|
||||
|
||||
screen.append(intro, controls, statusLine, list);
|
||||
renderHistory();
|
||||
return screen;
|
||||
}
|
||||
Reference in New Issue
Block a user