import { clearArweaveAttachmentHistory, formatArweaveHistoryTime, getArweaveAttachmentAvailability, openArweaveAttachmentManager, readArweaveAttachmentHistory, } from '../components/arweave-attachment-manager.js'; import { formatBytes } from '../services/attachment-format.js'; import { createOverflowDots } from '../components/overflow-dots.js'; import { createTopBar } from '../components/topbar.js'; import { toUserMessage } from '../services/ui-error-texts.js'; import { state } from '../state.js'; export const pageMeta = { id: 'arweave-uploads-view', title: 'Загрузка файлов' }; 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${item?.preview?.ar ? ' ar-attachment-history-tile--with-preview' : ''}`; const name = document.createElement('strong'); name.className = 'ar-attachment-history-name'; 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 = '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(status, size, time); if (item?.preview?.ar) { const previewFlag = document.createElement('span'); previewFlag.className = 'ar-attachment-placement-flag'; previewFlag.textContent = 'С превью'; meta.append(previewFlag); } 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; tile.append(name, meta, txId); return tile; } export function render({navigate, chrome}) { const screen = document.createElement('section'); screen.className = 'stack arweave-uploads-screen'; 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'; const uploadFile = async () => { statusLine.textContent = ''; try { await openArweaveAttachmentManager({ login: state.session.login, storagePwd: state.session.storagePwdInMemory, gateway: state.entrySettings.arweaveServer, historyOnly: true, }); renderHistory(); } catch (error) { statusLine.textContent = toUserMessage(error, 'Не удалось загрузить файл.'); } }; function renderHistory() { const rows = readArweaveAttachmentHistory(state.session.login).slice().reverse(); list.innerHTML = ''; statusLine.textContent = ''; 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); } const topbar = createTopBar({ title: 'Загрузка файлов в блокчейн', back: { onClick: () => navigate('settings-view') }, actions: [ { label: '+', title: 'Добавить файл', ariaLabel: 'Добавить файл', className: 'arweave-uploads-add', onClick: () => { void uploadFile(); }, }, { iconNode: createOverflowDots(), title: 'Меню', ariaLabel: 'Меню загрузок', className: 'arweave-uploads-menu-btn', menu: { minWidth: 220, items: [ { label: 'Добавить файл', action: () => uploadFile() }, { label: 'Очистить историю', action: () => { const confirmed = window.confirm('Очистить журнал загруженных файлов этой сессии?'); if (!confirmed) return; clearArweaveAttachmentHistory(state.session.login); renderHistory(); }, }, { label: 'Справка', action: () => window.alert( 'Здесь вы можете заранее добавить файл в Arweave или через Turbo. По умолчанию сразу выбрана загрузка через Turbo, а маленькие файлы пока загружаются там бесплатно.\n\n' + 'Потом при создании сообщения можно открыть историю загрузок и выбрать уже загруженный файл по txId. ' + 'Если файл только что загружен, gateway может несколько минут его не отдавать, поэтому статус может быть “ещё обновляется”.' ), }, ], }, }, ], }); chrome?.setTopbar(topbar); screen.append(statusLine, list); renderHistory(); return screen; }