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:
parent
c272d97453
commit
ec564739a1
@ -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 (
|
||||||
|
@ -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/"),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user