1
0
mirror of https://github.com/spacebarchat/client.git synced 2024-11-25 19:52:31 +01:00

better file type detection, and util functions for files

This commit is contained in:
Puyodead1 2023-09-10 23:08:47 -04:00
parent c272d97453
commit ec564739a1
No known key found for this signature in database
GPG Key ID: A4FA4FEC0DD353FC
3 changed files with 48 additions and 18 deletions

View File

@ -1,7 +1,7 @@
import { observer } from "mobx-react-lite"; import { observer } from "mobx-react-lite";
import React, { Fragment } from "react"; import React, { Fragment } from "react";
import styled from "styled-components"; import styled from "styled-components";
import { bytesToSize } from "../../../utils/Utils"; import { bytesToSize, getFileDetails, getFileIcon } from "../../../utils/Utils";
import { HorizontalDivider } from "../../Divider"; import { HorizontalDivider } from "../../Divider";
import Icon from "../../Icon"; import Icon from "../../Icon";
import IconButton from "../../IconButton"; import IconButton from "../../IconButton";
@ -102,23 +102,12 @@ interface FileProps {
function File({ file, remove }: FileProps) { function File({ file, remove }: FileProps) {
const generatePreviewElement = React.useCallback(() => { const generatePreviewElement = React.useCallback(() => {
const previewUrl = URL.createObjectURL(file); const previewUrl = URL.createObjectURL(file);
console.log(file.type); const fileDetails = getFileDetails(file);
if (file.type.startsWith("image")) return <Image src={previewUrl} />; if (fileDetails.isEmbeddable) {
// these are the only supported video formats by most browsers (safari doesn't support ogg) if (fileDetails.isVideo) return <Video preload="metadata" aria-hidden="true" src={previewUrl}></Video>;
else if (["video/webm", "video/ogg", "video/mp4"].includes(file.type.toLowerCase())) if (fileDetails.isImage) return <Image src={previewUrl} />;
return <Video preload="metadata" aria-hidden="true" src={previewUrl}></Video>; }
else if (file.type.startsWith("audio")) { return <Icon size={5} icon={getFileIcon(file)} />;
return (
<div>
<Icon size="48px" icon="mdiVolumeHigh" />
</div>
);
} else
return (
<div>
<Icon size="48px" icon="mdiFile" />
</div>
);
}, [file]); }, [file]);
return ( return (

View File

@ -1,3 +1,6 @@
import * as Icons from "@mdi/js";
import { ARCHIVE_MIMES, EMBEDDABLE_IMAGE_MIMES, EMBEDDABLE_VIDEO_MIMES } from "./constants";
export const decimalColorToHex = (decimal: number) => { export const decimalColorToHex = (decimal: number) => {
return `#${decimal.toString(16)}`; return `#${decimal.toString(16)}`;
}; };
@ -9,3 +12,38 @@ export const bytesToSize = (bytes: number) => {
const i = Math.floor(Math.log(bytes) / Math.log(1024)); const i = Math.floor(Math.log(bytes) / Math.log(1024));
return `${Math.round(bytes / Math.pow(1024, i))} ${sizes[i]}`; return `${Math.round(bytes / Math.pow(1024, i))} ${sizes[i]}`;
}; };
type IconsType = keyof typeof Icons;
// returns the icon for a file based on its mimetype
export const getFileIcon = (file: File): IconsType => {
const isImage = file.type.startsWith("image/");
const isVideo = file.type.startsWith("video/");
const isAudio = file.type.startsWith("audio/");
// check if the file is an archive based on its extension
const isArchive = ARCHIVE_MIMES.includes(file.name.split(".").pop() || "");
if (isImage) return "mdiFileImage";
if (isVideo) return "mdiFileVideo";
if (isAudio) return "mdiFileMusic";
if (isArchive) return "mdiFolderZip";
return "mdiFile";
};
export const isFileEmbeddable = (file: File) => {
return (
(file.type.startsWith("image/") &&
EMBEDDABLE_IMAGE_MIMES.includes(file.type.toLowerCase().split("/").pop() || "")) ||
(file.type.startsWith("video/") &&
EMBEDDABLE_VIDEO_MIMES.includes(file.type.toLowerCase().split("/").pop() || ""))
);
};
export const getFileDetails = (file: File) => {
return {
icon: getFileIcon(file),
isEmbeddable: isFileEmbeddable(file),
isVideo: file.type.startsWith("video/"),
isImage: file.type.startsWith("image/"),
isAudio: file.type.startsWith("audio/"),
};
};

View File

@ -31,3 +31,6 @@ export const USER_JOIN_MESSAGES = [
// TODO: this should come from the server // TODO: this should come from the server
export const MAX_UPLOAD_SIZE = 1024 * 1024 * 1024; // 1GB, taken from spacebar server default export const MAX_UPLOAD_SIZE = 1024 * 1024 * 1024; // 1GB, taken from spacebar server default
export const EMBEDDABLE_VIDEO_MIMES = ["webm", "ogg", "mp4"]; // list of the mimetypes that can be used in a video element
export const EMBEDDABLE_IMAGE_MIMES = ["png", "jpg", "jpeg", "gif", "webp"]; // list of mimetypes that can be used in an image element
export const ARCHIVE_MIMES = ["zip", "tar", "tar.gz", "tar.xz", "tar.bz2", "rar", "7z"]; // list of mimetypes to associate with archives