Media dashboard fixes + improvements

This commit is contained in:
Elio Struyf
2022-04-20 20:58:03 +02:00
parent b232c55843
commit 070fc53685
6 changed files with 8605 additions and 54 deletions
+4 -1
View File
@@ -11,11 +11,14 @@
### ⚡️ Optimizations
- [#316](https://github.com/estruyf/vscode-front-matter/issues/316): Surpress file parsing errors when closing the dashboard
- [#316](https://github.com/estruyf/vscode-front-matter/issues/316): Suppress file parsing errors when closing the dashboard
### 🐞 Fixes
- Hide the view mode action from the Front Matter panel if no custom modes are defined
- Fix in decode base64 uploaded video files
- Fix for a lightbox on other types of documents (pdf, etc.)
- Fix for hiding the image preview on slide-over for none image documents
## [7.1.2] - 2022-04-11
+8552 -24
View File
File diff suppressed because it is too large Load Diff
@@ -18,12 +18,13 @@ export interface IDetailsSlideOverProps {
folder: string;
media: MediaInfo;
showForm: boolean;
isImageFile: boolean;
onEdit: () => void;
onEditClose: () => void;
onDismiss: () => void;
}
export const DetailsSlideOver: React.FunctionComponent<IDetailsSlideOverProps> = ({ imgSrc, size, dimensions, media, folder, showForm, onEdit, onEditClose, onDismiss }: React.PropsWithChildren<IDetailsSlideOverProps>) => {
export const DetailsSlideOver: React.FunctionComponent<IDetailsSlideOverProps> = ({ imgSrc, size, dimensions, media, folder, showForm, onEdit, onEditClose, onDismiss, isImageFile }: React.PropsWithChildren<IDetailsSlideOverProps>) => {
const [ filename, setFilename ] = React.useState<string>(media.filename);
const [ caption, setCaption ] = React.useState<string | undefined>(media.caption);
const [ alt, setAlt ] = React.useState(media.alt);
@@ -93,9 +94,13 @@ export const DetailsSlideOver: React.FunctionComponent<IDetailsSlideOverProps> =
<div className="relative mt-6 flex-1 px-4 sm:px-6">
<div className="absolute inset-0 px-4 sm:px-6 space-y-8">
<div>
<div className="block w-full aspect-w-10 aspect-h-7 overflow-hidden border-gray-200 dark:border-vulcan-200 border">
<img src={imgSrc} alt={media.filename} className="object-cover" />
</div>
{
isImageFile && (
<div className="block w-full aspect-w-10 aspect-h-7 overflow-hidden border-gray-200 dark:border-vulcan-200 border">
<img src={imgSrc} alt={media.filename} className="object-cover" />
</div>
)
}
<div className="mt-4 flex items-start justify-between">
<div>
<h2 className="text-lg font-medium text-vulcan-300 dark:text-whisper-500"><span className="sr-only">Details for </span>{media.filename}</h2>
+28 -17
View File
@@ -181,7 +181,7 @@ export const Item: React.FunctionComponent<IItemProps> = ({media}: React.PropsWi
};
const openLightbox = useCallback(() => {
if (!isVideoFile() && !isAudioFile()) {
if (isImageFile) {
setLightbox(media.vsPath || "");
}
}, [media.vsPath]);
@@ -200,21 +200,21 @@ export const Item: React.FunctionComponent<IItemProps> = ({media}: React.PropsWi
))
}
const isVideoFile = useCallback(() => {
const isVideoFile = useMemo(() => {
if (media.mimeType?.startsWith("video/")) {
return true;
}
return false;
}, [media]);
const isAudioFile = useCallback(() => {
const isAudioFile = useMemo(() => {
if (media.mimeType?.startsWith("audio/")) {
return true;
}
return false;
}, [media]);
const isImageFile = useCallback(() => {
const isImageFile = useMemo(() => {
if (media.mimeType?.startsWith("image/")) {
return true;
}
@@ -222,27 +222,37 @@ export const Item: React.FunctionComponent<IItemProps> = ({media}: React.PropsWi
}, [media]);
const renderMediaIcon = useMemo(() => {
if (isVideoFile()) {
return <VideoCameraIcon className={`h-1/2 text-gray-300 dark:text-vulcan-200`} />;
}
if (isAudioFile()) {
return <MusicNoteIcon className={`h-1/2 text-gray-300 dark:text-vulcan-200`} />;
}
const path = media.fsPath;
const extension = path.split('.').pop();
if (isImageFile()) {
if (isImageFile) {
return <PhotographIcon className={`h-1/2 text-gray-300 dark:text-vulcan-200`} />;
}
return <DocumentIcon className={`h-1/2 text-gray-300 dark:text-vulcan-200`} />;
}, [media]);
let icon = <DocumentIcon className={`h-4/6 text-gray-300 dark:text-vulcan-200`} />;
if (isVideoFile) {
icon = <VideoCameraIcon className={`h-4/6 text-gray-300 dark:text-vulcan-200`} />;
}
if (isAudioFile) {
icon = <MusicNoteIcon className={`h-4/6 text-gray-300 dark:text-vulcan-200`} />;
}
return (
<div className='w-full h-full flex justify-center items-center'>
{icon}
<span className='text-2xl font-bold absolute top-0 right-0 bottom-0 left-0 flex justify-center items-center'>{extension}</span>
</div>
);
}, [media, isImageFile, isVideoFile, isAudioFile]);
const renderMedia = useMemo(() => {
if (isVideoFile() || isAudioFile()) {
if (isVideoFile || isAudioFile) {
return null;
}
if (isImageFile()) {
if (isImageFile) {
return <img src={media.vsPath} alt={basename(media.fsPath)} className="mx-auto object-cover" />;
}
@@ -271,7 +281,7 @@ export const Item: React.FunctionComponent<IItemProps> = ({media}: React.PropsWi
return (
<>
<li className="group relative bg-gray-50 dark:bg-vulcan-200 shadow-md hover:shadow-xl dark:shadow-none dark:hover:bg-vulcan-100 border border-gray-200 dark:border-vulcan-50">
<button className="relative bg-gray-200 dark:bg-vulcan-300 block w-full aspect-w-10 aspect-h-7 overflow-hidden cursor-pointer h-48" onClick={openLightbox}>
<button className={`relative bg-gray-200 dark:bg-vulcan-300 block w-full aspect-w-10 aspect-h-7 overflow-hidden h-48 ${isImageFile ? "cursor-pointer" : "cursor-default"}`} onClick={openLightbox}>
<div className={`absolute top-0 right-0 bottom-0 left-0 flex items-center justify-center`}>
{
renderMediaIcon
@@ -424,6 +434,7 @@ export const Item: React.FunctionComponent<IItemProps> = ({media}: React.PropsWi
folder={getFolder()}
media={media}
showForm={showForm}
isImageFile={isImageFile}
onEdit={() => setShowForm(true)}
onEditClose={() => setShowForm(false)}
onDismiss={() => { setShowDetails(false); setShowForm(false); }} />
+2 -2
View File
@@ -1,4 +1,4 @@
import { decodeBase64Image, Extension, MediaLibrary, Notifications, parseWinPath, Settings, Sorting } from ".";
import { decodeBase64, Extension, MediaLibrary, Notifications, parseWinPath, Settings, Sorting } from ".";
import { Dashboard } from "../commands/Dashboard";
import { Folders } from "../commands/Folders";
import { DEFAULT_CONTENT_TYPE, ExtensionState, HOME_PAGE_NAVIGATION_ID, SETTING_CONTENT_STATIC_FOLDER, SETTING_MEDIA_SUPPORTED_MIMETYPES } from "../constants";
@@ -228,7 +228,7 @@ export class MediaHelpers {
}
const staticPath = join(absFolderPath, fileName);
const imgData = decodeBase64Image(contents);
const imgData = decodeBase64(contents);
if (imgData) {
writeFileSync(staticPath, imgData.data);
+10 -6
View File
@@ -1,13 +1,17 @@
export const decodeBase64Image = (dataString: string) => {
const matches = dataString.match(/^data:([A-Za-z-+\/]+);base64,(.+)$/);
let response: any = {};
export const decodeBase64 = (dataString: string) => {
const dataParts = dataString.split(';base64,');
if (matches?.length !== 3) {
if (dataParts?.length < 2) {
return null;
}
response.type = matches[1];
response.data = Buffer.from(matches[2], 'base64');
const typePart = dataParts[0].split(':').pop() as string;
const dataPart = dataParts.pop() as string;
let response: any = {};
response.type = typePart;
response.data = Buffer.from(dataPart, 'base64');
return response;
}