diff --git a/src/files-ui/FilesUiProvider/FilesUiContextType.ts b/src/files-ui/FilesUiProvider/FilesUiContextType.ts index 948a29589a96e14dbc77b270a9a8005f1dc7758b..4f848a918a5af42e965ce39cc439101083ec7d95 100644 --- a/src/files-ui/FilesUiProvider/FilesUiContextType.ts +++ b/src/files-ui/FilesUiProvider/FilesUiContextType.ts @@ -1,3 +1,8 @@ +import { IconsMap } from "../core"; + export type FilesUiConfig = { darkMode?:boolean; -} \ No newline at end of file + icons?:IconsConfig; +} + +export type IconsConfig=IconsMap; \ No newline at end of file diff --git a/src/files-ui/components/file-card/FileCard.tsx b/src/files-ui/components/file-card/FileCard.tsx index c0cbd0584a8c9984a22efca606e51a0d5ad19203..25a19eb1c9ae26949db62a0bde2191c24a229f12 100644 --- a/src/files-ui/components/file-card/FileCard.tsx +++ b/src/files-ui/components/file-card/FileCard.tsx @@ -109,7 +109,7 @@ const FileCard: React.FC<FileCardProps> = (props: FileCardProps) => { //} = mergeProps(props, FileCardPropsDefault); } = props; //context -const { darkMode: darkModeContext } = React.useContext(FilesUiContext); +const { darkMode: darkModeContext , icons} = React.useContext(FilesUiContext); const darkMode: boolean | undefined = darkModeProp !== undefined ? darkModeProp : darkModeContext; @@ -150,7 +150,8 @@ const darkMode: boolean | undefined = valid, preview as boolean, imageUrl, - videoUrl + videoUrl, + icons ); //The size formatted and rounded in 2 decimals const sizeFormatted: string | undefined = fileSizeFormater(localSize); diff --git a/src/files-ui/components/file-mosaic/components/file-mosaic/FileMosaic.tsx b/src/files-ui/components/file-mosaic/components/file-mosaic/FileMosaic.tsx index 2f4564fdc507708c99c2fbe7fa78265f9e2f9c7b..8700e9195d4d07e40a640522e50ba8da3e38e2b7 100644 --- a/src/files-ui/components/file-mosaic/components/file-mosaic/FileMosaic.tsx +++ b/src/files-ui/components/file-mosaic/components/file-mosaic/FileMosaic.tsx @@ -71,10 +71,10 @@ const FileMosaic: React.FC<FileMosaicProps> = (props: FileMosaicProps) => { } = props; //context - const { darkMode: darkModeContext } = React.useContext(FilesUiContext); + const { darkMode: darkModeContext, icons } = React.useContext(FilesUiContext); const darkMode: boolean | undefined = darkModeProp !== undefined ? darkModeProp : darkModeContext; - console.log("globalConfig", darkMode); + console.log("globalConfig", darkMode, icons); //localizers @@ -120,7 +120,8 @@ const FileMosaic: React.FC<FileMosaicProps> = (props: FileMosaicProps) => { valid, preview as boolean, imageUrl, - videoUrl + videoUrl, + icons ); //The size formatted and rounded in 2 decimals diff --git a/src/files-ui/components/file-mosaic/hooks/useFileMosaicInitializer.ts b/src/files-ui/components/file-mosaic/hooks/useFileMosaicInitializer.ts index b28c2ce32da74459a98b4c8e6bca07de6518db28..c2ed8416fc445410ddd95b24c1a7fbcd578ea588 100644 --- a/src/files-ui/components/file-mosaic/hooks/useFileMosaicInitializer.ts +++ b/src/files-ui/components/file-mosaic/hooks/useFileMosaicInitializer.ts @@ -1,6 +1,7 @@ import * as React from "react"; import { getURLFileIco, readAsDataURL } from "../../../core"; import { getURLFileIcoFromNameAndType } from "../../../core/mime/mime"; +import { IconsConfig } from "../../../FilesUiProvider/FilesUiContextType"; /** * Initializer hook for FileItemNeo @@ -20,6 +21,7 @@ const useFileMosaicInitializer = ( preview: boolean, imageUrl: string | undefined, videoUrl: string | undefined, + customIcons?:IconsConfig, xhr?: XMLHttpRequest, ): [boolean, boolean, boolean, string, string | undefined, File | string | undefined] => { @@ -40,6 +42,7 @@ const useFileMosaicInitializer = ( preview: boolean, imageUrl: string | undefined, videoUrl: string | undefined, + customIcons?:IconsConfig, xhr?: XMLHttpRequest, progress?: number ) => { @@ -48,8 +51,8 @@ const useFileMosaicInitializer = ( if (!file && (!name && !type)) return; - const { url } = file ? getURLFileIco(file) : - getURLFileIcoFromNameAndType(name, type); + const { url } = file ? getURLFileIco(file,customIcons) : + getURLFileIcoFromNameAndType(name, type,customIcons); //console.log("init", url); @@ -107,7 +110,7 @@ const useFileMosaicInitializer = ( ////// CLEAN UP React.useEffect(() => { - init(file, name, type, valid, preview || false, imageUrl, videoUrl); + init(file, name, type, valid, preview || false, imageUrl, videoUrl,customIcons); return () => { setImageSource(undefined); setIsImage(false); @@ -115,7 +118,7 @@ const useFileMosaicInitializer = ( setIsReady(false); }; // eslint-disable-next-line - }, [file, name, type, valid, preview, imageUrl, videoUrl]); + }, [file, name, type, valid, preview, imageUrl, videoUrl,customIcons]); return [isReady, isImage, isVideo, url, imageSource, videoSource]; } diff --git a/src/files-ui/core/index.ts b/src/files-ui/core/index.ts index f59b94970f6bef21c7eb757bcf23957a6b96d2e5..260fef37ba46d68b848c5dd7ebcbffc7f99d8d21 100644 --- a/src/files-ui/core/index.ts +++ b/src/files-ui/core/index.ts @@ -87,7 +87,8 @@ export type { UploadPromiseResponse, UploadResponse, UploadConfig, - UPLOADSTATUS + UPLOADSTATUS, + IconsMap } from "./types"; export { diff --git a/src/files-ui/core/mime/mime.ts b/src/files-ui/core/mime/mime.ts index 73ac85f110b792e9a41697616a3f3589a94e8431..cf8eccba71153b542505238f2473e87e28daa460 100644 --- a/src/files-ui/core/mime/mime.ts +++ b/src/files-ui/core/mime/mime.ts @@ -19,14 +19,15 @@ import { zip } from "./icons"; import { getExt } from "../utils/getExt"; +import { IconsMap } from "../types"; -const DEF_GEN_MIME: string = "octet"; +const DEF_GEN_MIME: keyof IconsMap = "octet"; /** * * @param tailMime * @returns */ -export const audioSelector = (tailMime: string): string => { +export const audioSelector = (tailMime: string): keyof IconsMap => { switch (tailMime) { case "aac": return "aac"; case "midi": return "midi"; @@ -43,7 +44,7 @@ export const audioSelector = (tailMime: string): string => { default: return DEF_GEN_MIME; } } -export const textSelector = (tailMime: string): string => { +export const textSelector = (tailMime: string): keyof IconsMap => { switch (tailMime) { case "css": return "css"; case "csv": return "csv"; @@ -57,12 +58,12 @@ export const textSelector = (tailMime: string): string => { } } -export const imageSelector = (tailMime: string): string => { +export const imageSelector = (tailMime: string): keyof IconsMap => { switch (tailMime) { case "bmp": return "bmp"; case "gif": return "gif"; // case "vnd.microsoft.icon": return "ico"; - case "ico": return "ico"; + //case "ico": return "ico"; case "jpg": return "jpeg"; case "jpeg": return "jpeg"; case "png": return "png"; @@ -74,7 +75,7 @@ export const imageSelector = (tailMime: string): string => { } } -export const fontSelector = (tailMime: string): string => { +export const fontSelector = (tailMime: string): keyof IconsMap => { switch (tailMime) { case "otf": return "otf"; case "ttf": return "ttf"; @@ -85,7 +86,7 @@ export const fontSelector = (tailMime: string): string => { } } -export const videoSelector = (tailMime: string): string => { +export const videoSelector = (tailMime: string): keyof IconsMap => { switch (tailMime) { case "x-msvideo": return "avi"; case "msvideo": return "avi"; @@ -108,7 +109,7 @@ export const videoSelector = (tailMime: string): string => { * @param tailMime * @returns */ -export const applicationSelector = (tailMime: string): string => { +export const applicationSelector = (tailMime: string): keyof IconsMap => { switch (tailMime) { case "x-abiword": return "abw"; case "abiword": return "abw"; @@ -164,7 +165,7 @@ export const applicationSelector = (tailMime: string): string => { * @returns the generic type, if not found it return "octet" that means generic binary file */ -export const mimeSelector = (mimeType?: string): string => { +export const mimeSelector = (mimeType?: string): keyof IconsMap => { // let genericMime: string | undefined = undefined; if (!mimeType || !mimeType.includes("/")) { return DEF_GEN_MIME; @@ -194,8 +195,8 @@ export const mimeSelector = (mimeType?: string): string => { * @param extension * @returns */ -export const extensionSelector = (extension?: string): string => { - let genericMime: string = "octet"; +export const extensionSelector = (extension?: string): keyof IconsMap => { + let genericMime: keyof IconsMap = "octet"; if (extension && extension !== "") { if (extension.includes("zip") || extension.includes("rar")) { @@ -219,7 +220,7 @@ export const extensionSelector = (extension?: string): string => { } else if (extension === "java") { genericMime = "java"; } else if (extension === "ts") { - genericMime = "ts"; + genericMime = "typescript"; } else if (extension === "sass" || extension === "scss") { genericMime = "sass"; } @@ -232,8 +233,8 @@ export const extensionSelector = (extension?: string): string => { * @param extension * @returns */ -export const checkIsCode = (extension?: string): string => { - let genericMime = "text"; +export const checkIsCode = (extension?: string): keyof IconsMap => { + let genericMime: keyof IconsMap = "text"; if (extension && extension !== "") { if (extension === "jsx") { genericMime = "react"; @@ -258,17 +259,22 @@ export const checkIsCode = (extension?: string): string => { /** * Looks for a suitable file icon + * If not found, returns octet-stream url * @param props mime and extension from file to search - * @returns the result file ico, if not found, turns octet-stream url + * @returns the result file ico */ export const getURLFileIco = ( - file: File | undefined + file: File | undefined, + customIcons: IconsMap | undefined ): ResultFileIco => { - let result = ""; + let result: keyof IconsMap = "fallBack"; //if not file, return octet if (!file) { result = DEF_GEN_MIME; + if (customIcons?.fallBack) + return { url: customIcons?.fallBack, mimeResume: result }; + return { url: mimeUrlList[result], mimeResume: result }; } else { result = mimeSelector(file.type); @@ -285,6 +291,11 @@ export const getURLFileIco = ( result = extensionSelector(extention); } + const customUrl = customIcons?.[result]; + if (customUrl !== undefined) + return { url: customUrl, mimeResume: result }; + + return { url: mimeUrlList[result], mimeResume: result }; } /** @@ -295,12 +306,15 @@ export const getURLFileIco = ( export const getURLFileIcoFromNameAndType = ( name: string | undefined, type: string | undefined, + customIcons: IconsMap | undefined ): ResultFileIco => { - let result = ""; + let result: keyof IconsMap = "octet"; //if not nam and type, return octet if (!name) { result = DEF_GEN_MIME; + if (customIcons?.fallBack) + return { url: customIcons?.fallBack, mimeResume: result }; return { url: mimeUrlList[result], mimeResume: result }; } else { result = mimeSelector(type); @@ -316,12 +330,15 @@ export const getURLFileIcoFromNameAndType = ( if (result === DEF_GEN_MIME) { result = extensionSelector(extention); } + const customUrl = customIcons?.[result]; + if (customUrl !== undefined) + return { url: customUrl, mimeResume: result }; return { url: mimeUrlList[result], mimeResume: result }; } interface ResultFileIco { url: string; - mimeResume: string; + mimeResume: keyof IconsMap; } /** * set of registered mimes on MDN @@ -333,9 +350,6 @@ interface MimeSelector { } const mimeUrlList: MimeSelector = { - img: "https://ssl.gstatic.com/docs/doclist/images/mediatype/icon_1_image_x16.png", - video: "https://ssl.gstatic.com/docs/doclist/images/mediatype/icon_1_video_x16.png", - audio: "https://ssl.gstatic.com/docs/doclist/images/mediatype/icon_1_audio_x16.png", aac: aac, accdb: accdb, abw: abw, @@ -416,4 +430,6 @@ const mimeUrlList: MimeSelector = { react: react, vue: vue, + + fallBack: octet, }; \ No newline at end of file diff --git a/src/files-ui/core/types/IconsMap.ts b/src/files-ui/core/types/IconsMap.ts new file mode 100644 index 0000000000000000000000000000000000000000..1e258c3083fcd0e7b50b234066d826f2bed2f3b3 --- /dev/null +++ b/src/files-ui/core/types/IconsMap.ts @@ -0,0 +1,84 @@ + +export type IconsMap = { + aac?: string; + accdb?: string; + abw?: string; + arc?: string; + avi?: string; + azw?: string; + octet?: string; + bmp?: string; + bz?: string; + bz2?: string; + cda?: string; + csh?: string; + css?: string; + csv?: string; + docx?: string; + drawio?: string; + eot?: string; + epub?: string; + gzip?: string; + gif?: string; + html?: string; + //ico: ico, + icalendar?: string; + jar?: string; + jpeg?: string; + javascript?: string; + json?: string; + jsonld?: string; + midi?: string; + // js: js, + mp3?: string; + mp4?: string; + mpeg?: string; + mpkg?: string; + mp2t?: string; + odp?: string; + ods?: string; + odt?: string; + oga?: string; + ogv?: string; + ogx?: string; + opus?: string; + otf?: string; + png?: string; + pdf?: string; + php?: string; + pptx?: string; + psd?: string; + rar?: string; + rtf?: string; + sass?: string; + sh?: string; + //svg: svg, + swf?: string; + tar?: string; + tiff?: string; + ttf?: string; + //ts: ts, + typescript?: string; + text?: string; + vsd?: string; + wav?: string; + weba?: string; + webm?: string; + webp?: string; + woff?: string; + wma?: string; + wmv?: string; + xhtml?: string; + xlsx?: string; + xml?: string; + xul?: string; + zip?: string; + // threegp: threegp, + sevenzip?: string; + python?: string; + java?: string; + react?: string; + vue?: string; + + fallBack?: string; +} \ No newline at end of file diff --git a/src/files-ui/core/types/index.ts b/src/files-ui/core/types/index.ts index ede58789ad8bff145c0a905e19ae1cb28f0d1a7e..98e17c5b953f390c86ba9e5a89454db17f5e5bc7 100644 --- a/src/files-ui/core/types/index.ts +++ b/src/files-ui/core/types/index.ts @@ -21,4 +21,7 @@ export type { ServerResponse, UploadPromiseResponse, UploadResponse } from "./up export type { ValidateFileResponse, FileValidatorProps } from "./validation"; export type { UploadConfig } from "./UploadConfig"; -export { createUploadConfig } from "./UploadConfig"; \ No newline at end of file + +export { createUploadConfig } from "./UploadConfig"; + +export type { IconsMap } from "./IconsMap"; \ No newline at end of file