feat: add metadata and preview (#292)
* chore: upload flow uses metadata object and has preview * chore: remove SwarmFile * feat: upload metadata and file preview * feat: add metadata and preview on download * fix: package the meta and preview files * fix: upload websites that are inside a folder (#296) * fix: upload websites that are inside a folder * docs: few comments to clarify what is going on * refactor: decrease local variables and fix state order to detect websites properly Co-authored-by: Cafe137 <aron@aronsoos.com>
This commit is contained in:
+53
-37
@@ -1,28 +1,32 @@
|
||||
import { FileData } from '@ethersphere/bee-js'
|
||||
import { SwarmFile } from './SwarmFile'
|
||||
|
||||
const indexHtmls = ['index.html', 'index.htm']
|
||||
|
||||
export function detectIndexHtml(files: SwarmFile[]): string | false {
|
||||
if (!files.length) {
|
||||
interface DetectedIndex {
|
||||
indexPath: string
|
||||
commonPrefix?: string
|
||||
}
|
||||
|
||||
export function detectIndexHtml(files: FilePath[]): DetectedIndex | false {
|
||||
const paths = files.map(getPath)
|
||||
|
||||
if (!paths.length) {
|
||||
return false
|
||||
}
|
||||
|
||||
const exactMatch = files.find(x => indexHtmls.includes(x.path))
|
||||
const exactMatch = paths.find(x => indexHtmls.includes(x))
|
||||
|
||||
if (exactMatch) {
|
||||
return exactMatch.name
|
||||
return { indexPath: exactMatch }
|
||||
}
|
||||
|
||||
const prefix = files[0].path.split('/')[0] + '/'
|
||||
const prefix = paths[0].split('/')[0] + '/'
|
||||
|
||||
const allStartWithSamePrefix = files.every(x => x.path.startsWith(prefix))
|
||||
const allStartWithSamePrefix = paths.every(x => x.startsWith(prefix))
|
||||
|
||||
if (allStartWithSamePrefix) {
|
||||
const match = files.find(x => indexHtmls.map(y => prefix + y).includes(x.path))
|
||||
const match = paths.find(x => indexHtmls.map(y => prefix + y).includes(x))
|
||||
|
||||
if (match) {
|
||||
return match.name
|
||||
return { indexPath: match, commonPrefix: prefix }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,38 +57,50 @@ export function getHumanReadableFileSize(bytes: number): string {
|
||||
return bytes + ' bytes'
|
||||
}
|
||||
|
||||
export function convertBeeFileToBrowserFile(file: FileData<ArrayBuffer>): Partial<File> {
|
||||
return {
|
||||
name: file.name,
|
||||
size: file.data.byteLength,
|
||||
type: file.contentType,
|
||||
arrayBuffer: () => new Promise(resolve => resolve(file.data)),
|
||||
}
|
||||
}
|
||||
|
||||
export function convertManifestToFiles(files: Record<string, string>): SwarmFile[] {
|
||||
return Object.entries(files).map(
|
||||
x =>
|
||||
({
|
||||
name: x[0],
|
||||
path: x[0],
|
||||
type: 'n/a',
|
||||
size: 0,
|
||||
webkitRelativePath: x[0],
|
||||
arrayBuffer: () => new Promise(resolve => resolve(new ArrayBuffer(0))),
|
||||
} as SwarmFile),
|
||||
)
|
||||
}
|
||||
|
||||
export function getAssetNameFromFiles(files: SwarmFile[]): string {
|
||||
export function getAssetNameFromFiles(files: FilePath[]): string {
|
||||
if (files.length === 1) return files[0].name
|
||||
|
||||
if (files.length > 0) {
|
||||
const prefix = files[0].path.split('/')[0]
|
||||
const prefix = getPath(files[0]).split('/')[0]
|
||||
|
||||
// Only if all files have a common prefix we can use it as a folder name
|
||||
if (files.every(f => f.path.split('/')[0] === prefix)) return prefix
|
||||
if (files.every(f => getPath(f).split('/')[0] === prefix)) return prefix
|
||||
}
|
||||
|
||||
return 'unknown'
|
||||
}
|
||||
|
||||
export function getMetadata(files: FilePath[]): Metadata {
|
||||
const size = files.reduce((total, item) => total + item.size, 0)
|
||||
const isWebsite = Boolean(detectIndexHtml(files))
|
||||
const name = getAssetNameFromFiles(files)
|
||||
const type = files.length === 1 ? files[0].type : 'folder'
|
||||
const count = files.length
|
||||
|
||||
return { size, name, type, isWebsite, count }
|
||||
}
|
||||
|
||||
export function getPath(file: FilePath): string {
|
||||
return (file.path || file.webkitRelativePath || file.name).replace(/^\//g, '') // remove the starting slash
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function that is needed to have correct directory structure as webkitRelativePath is read only
|
||||
*/
|
||||
export function packageFile(file: FilePath): FilePath {
|
||||
const path = getPath(file)
|
||||
|
||||
return {
|
||||
path: path,
|
||||
fullPath: path,
|
||||
webkitRelativePath: path,
|
||||
lastModified: file.lastModified,
|
||||
name: file.name,
|
||||
size: file.size,
|
||||
type: file.type,
|
||||
stream: file.stream,
|
||||
slice: file.slice,
|
||||
text: file.text,
|
||||
arrayBuffer: async () => await file.arrayBuffer(), // This is needed for successful upload and can not simply be { arrayBuffer: file.arrayBuffer }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user