From db52e4471a9519a0aca8a6fd2702a242e03d2a06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ferenc=20S=C3=A1rai?= Date: Mon, 16 Mar 2026 14:50:26 +0100 Subject: [PATCH] fix: use uploadFile for single files to support long filenames and reafactor for linter (#228) --- src/pages/files/Share.tsx | 48 ++++++++++++++++++++++++++------------ src/pages/files/Upload.tsx | 8 +++++-- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/pages/files/Share.tsx b/src/pages/files/Share.tsx index 1169bf0..a391cba 100644 --- a/src/pages/files/Share.tsx +++ b/src/pages/files/Share.tsx @@ -42,6 +42,28 @@ export function Share(): ReactElement { const isMountedRef = useRef(true) + function applyFallbackMetadata(entries: Record, indexDocument: string | null) { + const count = Object.keys(entries).length + const isVideo = Boolean(indexDocument && /.*\.(mp4|webm|ogv)$/i.test(indexDocument)) + const isAudio = Boolean(indexDocument && /.*\.(mp3|ogg|oga|wav|webm|m4a|aac|flac)$/i.test(indexDocument)) + const isImage = Boolean(indexDocument && /.*\.(jpg|jpeg|png|gif|webp|svg)$/i.test(indexDocument)) + + if (isImage || isVideo || isAudio) { + setPreview(`${apiUrl}/bzz/${hash}`) + } + + setMetadata({ + hash, + type: count > 1 ? 'folder' : 'unknown', + name: indexDocument || hash || '', + count, + isWebsite: Boolean(indexDocument && /.*\.html?$/i.test(indexDocument)), + isVideo, + isAudio, + isImage, + }) + } + async function prepare() { if (!beeApi || !status.all || !hash) { return @@ -79,21 +101,8 @@ export function Share(): ReactElement { setMetadata({ ...formattedMetadata, hash }) } catch { // if metadata is not available or invalid go with the default one - const count = Object.keys(entries).length - if (!isMountedRef.current) return - - setMetadata({ - hash, - type: count > 1 ? 'folder' : 'unknown', - name: hash, - count, - isWebsite: Boolean(indexDocument && /.*\.html?$/i.test(indexDocument)), - isVideo: Boolean(indexDocument && /.*\.(mp4|webm|ogv)$/i.test(indexDocument)), - isAudio: Boolean(indexDocument && /.*\.(mp3|ogg|oga|wav|webm|m4a|aac|flac)$/i.test(indexDocument)), - isImage: Boolean(indexDocument && /.*\.(jpg|jpeg|png|gif|webp|svg)$/i.test(indexDocument)), - // naive assumption based on indexDocument, we don't want to download the whole manifest - }) + applyFallbackMetadata(entries, indexDocument) } } catch { if (!isMountedRef.current) return @@ -106,7 +115,16 @@ export function Share(): ReactElement { } function onOpen() { - window.open(`${apiUrl}/bzz/${hash}/`, '_blank', 'noopener,noreferrer') + if (metadata?.isImage) { + const imgUrl = `${apiUrl}/bzz/${hash}` + const safeName = (metadata?.name ?? hash).replace(/[&<>"']/g, c => `&#${c.charCodeAt(0)};`) + const html = `${safeName}${safeName}` + const blob = new Blob([html], { type: 'text/html' }) + const blobUrl = URL.createObjectURL(blob) + window.open(blobUrl, '_blank', 'noopener,noreferrer') + } else { + window.open(`${apiUrl}/bzz/${hash}/`, '_blank', 'noopener,noreferrer') + } } function onClose() { diff --git a/src/pages/files/Upload.tsx b/src/pages/files/Upload.tsx index a0a8414..940ecb9 100644 --- a/src/pages/files/Upload.tsx +++ b/src/pages/files/Upload.tsx @@ -103,6 +103,7 @@ export function Upload(): ReactElement { } const lastModified = files[0].lastModified + const isSingleFile = files.length === 1 const metafile = new File([JSON.stringify(metadata)], META_FILE_NAME, { type: 'application/json', @@ -114,8 +115,11 @@ export function Upload(): ReactElement { await waitUntilStampUsable(stamp.batchID, beeApi) - beeApi - .uploadFiles(stamp.batchID, fls, { indexDocument, deferred: true }) + const uploadPromise = isSingleFile + ? beeApi.uploadFile(stamp.batchID, fls[0], fls[0].name, { deferred: true }) + : beeApi.uploadFiles(stamp.batchID, fls, { indexDocument, deferred: true }) + + uploadPromise .then(hash => { putHistory(LocalStorageKeys.uploadHistory, hash.reference.toHex(), getAssetNameFromFiles(files))