feat: vod display (#686)

* feat: preview for html5 supported videos

* fix: handle out of limit tags

* feat: support preview on the donwload screen

* refactor: rework meta and preview handling to be more general

* fix: missing meta

* fix: do not allow maybe or probably types

* fix: make the media check more strict

---------

Co-authored-by: Levente Kiss <levente.kiss@solarpunk.bzz>
This commit is contained in:
Levente Kiss
2025-02-12 11:35:46 +01:00
committed by GitHub
parent f695ac3a1c
commit bcd3d50b42
12 changed files with 170 additions and 93 deletions
+7 -2
View File
@@ -1,3 +1,6 @@
import { isSupportedImageType } from './image'
import { isSupportedVideoType } from './video'
const indexHtmls = ['index.html', 'index.htm']
interface DetectedIndex {
@@ -83,12 +86,14 @@ export function getAssetNameFromFiles(files: FilePath[]): string {
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
const isWebsite = Boolean(detectIndexHtml(files))
const isVideo = isSupportedVideoType(type)
const isImage = isSupportedImageType(type)
return { size, name, type, isWebsite, count }
return { size, name, type, isWebsite, count, isVideo, isImage }
}
export function getPath(file: FilePath): string {
+23 -10
View File
@@ -25,6 +25,28 @@ export function getDimensions(imgWidth: number, imgHeight: number, maxWidth?: nu
return { width: imgWidth / ratio, height: imgHeight / ratio }
}
function getAllowedTypes(): string[] {
return [
'image/bmp',
'image/gif',
'image/vnd.microsoft.icon',
'image/jpeg',
'image/png',
'image/svg+xml',
'image/tiff',
'image/webp',
]
}
/**
* Check if the image type is supported
*
* @param type Image MIME type
*
* @returns True if the type is supported, false otherwise
*/
export const isSupportedImageType = (type: string): boolean => getAllowedTypes().includes(type)
/**
* Resize image passed to fit in the bounding box defined with maxWidth and maxHeight.
* Note that one or both of the bounding box dimensions may be omitted
@@ -37,16 +59,7 @@ export function getDimensions(imgWidth: number, imgHeight: number, maxWidth?: nu
*/
export function resize(file: File, maxWidth?: number, maxHeight?: number): Promise<Blob> {
return new Promise((resolve, reject) => {
const allowedTypes = [
'image/bmp',
'image/gif',
'image/vnd.microsoft.icon',
'image/jpeg',
'image/png',
'image/svg+xml',
'image/tiff',
'image/webp',
]
const allowedTypes = getAllowedTypes()
if (!file.size || !file.type || !allowedTypes.includes(file.type)) return reject('File not supported!')
+8 -2
View File
@@ -50,14 +50,20 @@ export class ManifestJs {
/**
* Retrieves all paths with the associated hashes from a Swarm manifest
*/
public async getHashes(hash: string): Promise<Record<string, string>> {
public async getHashes(hash: string, options?: { exclude: string[] }): Promise<Record<string, string>> {
const data = await this.bee.downloadData(hash)
const node = new MantarayNode()
node.deserialize(data)
await loadAllNodes(this.load.bind(this), node)
const result = {}
const result: Record<string, string> = {}
this.extractHashes(result, node)
if (options?.exclude) {
for (const path of options.exclude) {
delete result[path]
}
}
return result
}
+8
View File
@@ -0,0 +1,8 @@
export function isSupportedVideoType(type: string) {
const video = document.createElement('video')
const result = video.canPlayType(type)
const isDefinitelySupported = result && result !== 'maybe'
return Boolean(isDefinitelySupported)
}