SHA256
164 lines
6.2 KiB
JavaScript
164 lines
6.2 KiB
JavaScript
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;
|
||
}
|