mirror of
https://github.com/estruyf/vscode-front-matter.git
synced 2026-08-06 17:02:54 +02:00
#308 - Supported mime types for media dashboard
This commit is contained in:
Generated
+42
-8453
File diff suppressed because it is too large
Load Diff
+33
-8
@@ -568,7 +568,10 @@
|
||||
"markdownDescription": "Specify the command you want to use to start your static site generator or framework. [Check in the docs](https://frontmatter.codes/docs/settings#frontmatter.framework.startcommand)"
|
||||
},
|
||||
"frontMatter.global.activeMode": {
|
||||
"type": ["string", "null"],
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
],
|
||||
"default": "",
|
||||
"markdownDescription": "Specify the activated mode of Front Matter. [Check in the docs](https://frontmatter.codes/docs/settings#frontmatter.global.activemode)",
|
||||
"scope": "Global"
|
||||
@@ -592,14 +595,14 @@
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"panel.globalSettings",
|
||||
"panel.globalSettings",
|
||||
"panel.seo",
|
||||
"panel.actions",
|
||||
"panel.metadata",
|
||||
"panel.recentlyModified",
|
||||
"panel.actions",
|
||||
"panel.metadata",
|
||||
"panel.recentlyModified",
|
||||
"panel.otherActions",
|
||||
"dashboard.snippets.view",
|
||||
"dashboard.snippets.manage",
|
||||
"dashboard.snippets.manage",
|
||||
"dashboard.data.view"
|
||||
]
|
||||
}
|
||||
@@ -608,7 +611,7 @@
|
||||
"required": [
|
||||
"id",
|
||||
"features"
|
||||
]
|
||||
]
|
||||
},
|
||||
"scope": "Global"
|
||||
},
|
||||
@@ -630,6 +633,19 @@
|
||||
"markdownDescription": "Specifies the notifications you want to see. By default, all notifications types will be shown. [Check in the docs](https://frontmatter.codes/docs/settings#frontmatter.global.notifications)",
|
||||
"scope": "Templates"
|
||||
},
|
||||
"frontMatter.media.supportedMimeTypes": {
|
||||
"type": "array",
|
||||
"default": [
|
||||
"image/*",
|
||||
"video/*",
|
||||
"audio/*"
|
||||
],
|
||||
"markdownDescription": "Specify the mime types to support for the media files. [Check in the docs](https://frontmatter.codes/docs/settings#frontmatter.media.supportedMimeTypes)",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"scope": "Media"
|
||||
},
|
||||
"frontMatter.media.defaultSorting": {
|
||||
"type": "string",
|
||||
"default": "",
|
||||
@@ -748,7 +764,14 @@
|
||||
"description": "Title to show in the UI"
|
||||
},
|
||||
"default": {
|
||||
"type": ["string", "number", "boolean", "array", "object", "null"],
|
||||
"type": [
|
||||
"string",
|
||||
"number",
|
||||
"boolean",
|
||||
"array",
|
||||
"object",
|
||||
"null"
|
||||
],
|
||||
"description": "Default value"
|
||||
},
|
||||
"choices": {
|
||||
@@ -1736,6 +1759,7 @@
|
||||
"@types/lodash.omit": "^4.5.6",
|
||||
"@types/lodash.uniqby": "4.7.6",
|
||||
"@types/lodash.xor": "^4.5.6",
|
||||
"@types/mime-types": "^2.1.1",
|
||||
"@types/mocha": "^5.2.6",
|
||||
"@types/mustache": "^4.1.2",
|
||||
"@types/node": "10.17.48",
|
||||
@@ -1766,6 +1790,7 @@
|
||||
"lodash.uniqby": "4.7.0",
|
||||
"lodash.xor": "^4.5.0",
|
||||
"mdast-util-from-markdown": "1.0.0",
|
||||
"mime-types": "^2.1.35",
|
||||
"mustache": "^4.2.0",
|
||||
"node-json-db": "^1.3.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
|
||||
@@ -58,6 +58,8 @@ export const SETTING_MEDIA_SORTING_DEFAULT = "content.defaultSorting";
|
||||
export const SETTING_CONTENT_DEFAULT_FILETYPE = "content.defaultFileType";
|
||||
export const SETTING_CONTENT_SUPPORTED_FILETYPES = "content.supportedFileTypes";
|
||||
|
||||
export const SETTING_MEDIA_SUPPORTED_MIMETYPES = "media.supportedMimeTypes";
|
||||
|
||||
export const SETTING_DASHBOARD_OPENONSTART = "dashboard.openOnStart";
|
||||
export const SETTING_DASHBOARD_MEDIA_SNIPPET = "dashboard.mediaSnippet";
|
||||
export const SETTING_DASHBOARD_CONTENT_TAGS = "dashboard.contentTags";
|
||||
|
||||
@@ -3,6 +3,7 @@ export enum DashboardMessage {
|
||||
reload = 'reload',
|
||||
setPageViewType = 'setPageViewType',
|
||||
getMode = 'getMode',
|
||||
showWarning = 'showWarning',
|
||||
|
||||
// Content dashboard
|
||||
getData = 'getData',
|
||||
|
||||
@@ -1,18 +1,13 @@
|
||||
import * as React from 'react';
|
||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
import { MediaTotalSelector, PageAtom, SearchAtom, SelectedMediaFolderSelector } from '../../state';
|
||||
import { Messenger } from '@estruyf/vscode/dist/client';
|
||||
import { DashboardMessage } from '../../DashboardMessage';
|
||||
import { RefreshIcon } from '@heroicons/react/outline';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { MediaTotalSelector, PageAtom } from '../../state';
|
||||
import { LIMIT } from '../../hooks/useMedia';
|
||||
|
||||
export interface IPaginationStatusProps {}
|
||||
|
||||
export const PaginationStatus: React.FunctionComponent<IPaginationStatusProps> = (props: React.PropsWithChildren<IPaginationStatusProps>) => {
|
||||
const totalMedia = useRecoilValue(MediaTotalSelector);
|
||||
const selectedFolder = useRecoilValue(SelectedMediaFolderSelector);
|
||||
const [ page, setPage ] = useRecoilState(PageAtom);
|
||||
const [ , setSearch ] = useRecoilState(SearchAtom);
|
||||
const page = useRecoilValue(PageAtom);
|
||||
|
||||
const getTotalPage = () => {
|
||||
const mediaItems = ((page + 1) * LIMIT);
|
||||
@@ -22,21 +17,8 @@ export const PaginationStatus: React.FunctionComponent<IPaginationStatusProps> =
|
||||
return mediaItems;
|
||||
};
|
||||
|
||||
const refresh = () => {
|
||||
setPage(0);
|
||||
setSearch('');
|
||||
Messenger.send(DashboardMessage.refreshMedia, { folder: selectedFolder });
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="hidden sm:flex">
|
||||
<button className={`mr-2 text-gray-500 hover:text-gray-600 dark:text-whisper-900 dark:hover:text-whisper-500`}
|
||||
title="Refresh media"
|
||||
onClick={refresh}>
|
||||
<RefreshIcon className={`h-5 w-5`} />
|
||||
<span className="sr-only">Refresh media</span>
|
||||
</button>
|
||||
|
||||
<div className="hidden sm:flex">
|
||||
<p className="text-sm text-gray-500 dark:text-whisper-900">
|
||||
Showing <span className="font-medium">{(page * LIMIT) + 1}</span> to <span className="font-medium">{getTotalPage()}</span> of{' '}
|
||||
<span className="font-medium">{totalMedia}</span> results
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
import { Messenger } from '@estruyf/vscode/dist/client';
|
||||
import { RefreshIcon } from '@heroicons/react/outline';
|
||||
import * as React from 'react';
|
||||
import { useCallback } from 'react';
|
||||
import { useRecoilState, useRecoilValue, useResetRecoilState } from 'recoil';
|
||||
import { DashboardMessage } from '../../DashboardMessage';
|
||||
import { NavigationType } from '../../models';
|
||||
import { CategoryAtom, DashboardViewAtom, FolderAtom, LoadingAtom, PageAtom, SearchAtom, SelectedMediaFolderSelector, SortingAtom, TagAtom } from '../../state';
|
||||
|
||||
export interface IRefreshDashboardDataProps {}
|
||||
|
||||
export const RefreshDashboardData: React.FunctionComponent<IRefreshDashboardDataProps> = (props: React.PropsWithChildren<IRefreshDashboardDataProps>) => {
|
||||
const view = useRecoilValue(DashboardViewAtom);
|
||||
const [, setLoading] = useRecoilState(LoadingAtom);
|
||||
const resetSearch = useResetRecoilState(SearchAtom);
|
||||
const resetSorting = useResetRecoilState(SortingAtom);
|
||||
const resetFolder = useResetRecoilState(FolderAtom);
|
||||
const resetTag = useResetRecoilState(TagAtom);
|
||||
const resetCategory = useResetRecoilState(CategoryAtom);
|
||||
// Media
|
||||
const resetPage = useResetRecoilState(PageAtom);
|
||||
const selectedFolder = useRecoilValue(SelectedMediaFolderSelector);
|
||||
|
||||
const refreshPages = () => {
|
||||
setLoading(true);
|
||||
resetSearch();
|
||||
resetSorting();
|
||||
resetFolder();
|
||||
resetTag();
|
||||
resetCategory();
|
||||
Messenger.send(DashboardMessage.refreshPages);
|
||||
};
|
||||
|
||||
const refreshMedia = () => {
|
||||
setLoading(true);
|
||||
resetPage();
|
||||
resetSearch();
|
||||
Messenger.send(DashboardMessage.refreshMedia, { folder: selectedFolder });
|
||||
};
|
||||
|
||||
const refresh = useCallback(() => {
|
||||
if (view === NavigationType.Contents) {
|
||||
refreshPages();
|
||||
} else if (view === NavigationType.Media) {
|
||||
refreshMedia();
|
||||
}
|
||||
}, [view]);
|
||||
|
||||
return (
|
||||
<button className={`mr-2 text-gray-500 hover:text-gray-600 dark:text-whisper-900 dark:hover:text-whisper-500`}
|
||||
title="Refresh dashboard"
|
||||
onClick={refresh}>
|
||||
<RefreshIcon className={`h-5 w-5`} />
|
||||
<span className="sr-only">Refresh dashboard</span>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
@@ -1,36 +0,0 @@
|
||||
import { Messenger } from '@estruyf/vscode/dist/client';
|
||||
import { RefreshIcon } from '@heroicons/react/outline';
|
||||
import * as React from 'react';
|
||||
import { useRecoilState, useResetRecoilState } from 'recoil';
|
||||
import { DashboardMessage } from '../../DashboardMessage';
|
||||
import { CategoryAtom, FolderAtom, LoadingAtom, SearchAtom, SortingAtom, TagAtom } from '../../state';
|
||||
|
||||
export interface IRefreshPagesProps {}
|
||||
|
||||
export const RefreshPages: React.FunctionComponent<IRefreshPagesProps> = (props: React.PropsWithChildren<IRefreshPagesProps>) => {
|
||||
const [, setLoading] = useRecoilState(LoadingAtom);
|
||||
const resetSearch = useResetRecoilState(SearchAtom);
|
||||
const resetSorting = useResetRecoilState(SortingAtom);
|
||||
const resetFolder = useResetRecoilState(FolderAtom);
|
||||
const resetTag = useResetRecoilState(TagAtom);
|
||||
const resetCategory = useResetRecoilState(CategoryAtom);
|
||||
|
||||
const refresh = () => {
|
||||
setLoading(true);
|
||||
resetSearch();
|
||||
resetSorting();
|
||||
resetFolder();
|
||||
resetTag();
|
||||
resetCategory();
|
||||
Messenger.send(DashboardMessage.refreshPages);
|
||||
}
|
||||
|
||||
return (
|
||||
<button className={`mr-2 text-gray-500 hover:text-gray-600 dark:text-whisper-900 dark:hover:text-whisper-500`}
|
||||
title="Refresh dashboard"
|
||||
onClick={refresh}>
|
||||
<RefreshIcon className={`h-5 w-5`} />
|
||||
<span className="sr-only">Refresh dashboard</span>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
@@ -3,7 +3,7 @@ import * as React from 'react';
|
||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
import { useDebounce } from '../../../hooks/useDebounce';
|
||||
import { SearchAtom, SearchReadyAtom } from '../../state';
|
||||
import { RefreshPages } from './RefreshPages';
|
||||
import { RefreshDashboardData } from './RefreshDashboardData';
|
||||
|
||||
export interface ISearchboxProps {
|
||||
placeholder?: string;
|
||||
@@ -63,7 +63,7 @@ export const Searchbox: React.FunctionComponent<ISearchboxProps> = ({placeholder
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<RefreshPages />
|
||||
<RefreshDashboardData />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Messenger } from '@estruyf/vscode/dist/client';
|
||||
import { Menu } from '@headlessui/react';
|
||||
import { ClipboardIcon, CodeIcon, EyeIcon, PencilIcon, PhotographIcon, PlusIcon, TrashIcon } from '@heroicons/react/outline';
|
||||
import { ClipboardIcon, CodeIcon, EyeIcon, MusicNoteIcon, PencilIcon, PhotographIcon, PlusIcon, TrashIcon, VideoCameraIcon } from '@heroicons/react/outline';
|
||||
import { basename, dirname } from 'path';
|
||||
import * as React from 'react';
|
||||
import { useEffect } from 'react';
|
||||
import { useCallback, useEffect, useMemo } from 'react';
|
||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
import { CustomScript } from '../../../helpers/CustomScript';
|
||||
import { parseWinPath } from '../../../helpers/parseWinPath';
|
||||
@@ -166,9 +166,11 @@ export const Item: React.FunctionComponent<IItemProps> = ({media}: React.PropsWi
|
||||
setShowDetails(true);
|
||||
};
|
||||
|
||||
const openLightbox = () => {
|
||||
setLightbox(media.vsPath || "");
|
||||
};
|
||||
const openLightbox = useCallback(() => {
|
||||
if (!isVideoFile() && !isAudioFile()) {
|
||||
setLightbox(media.vsPath || "");
|
||||
}
|
||||
}, [media.vsPath]);
|
||||
|
||||
const updateMetadata = () => {
|
||||
setShowForm(true);
|
||||
@@ -184,6 +186,28 @@ export const Item: React.FunctionComponent<IItemProps> = ({media}: React.PropsWi
|
||||
))
|
||||
}
|
||||
|
||||
const isVideoFile = useCallback(() => {
|
||||
if (media.mimeType?.startsWith("video/")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}, [media]);
|
||||
|
||||
const isAudioFile = useCallback(() => {
|
||||
if (media.mimeType?.startsWith("audio/")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}, [media]);
|
||||
|
||||
const renderMedia = useMemo(() => {
|
||||
if (isVideoFile() || isAudioFile()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return <img src={media.vsPath} alt={basename(media.fsPath)} className="mx-auto object-cover" />;
|
||||
}, [media]);
|
||||
|
||||
useEffect(() => {
|
||||
if (media.alt !== alt) {
|
||||
setAlt(media.alt);
|
||||
@@ -208,10 +232,20 @@ export const Item: React.FunctionComponent<IItemProps> = ({media}: React.PropsWi
|
||||
<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}>
|
||||
<div className={`absolute top-0 right-0 bottom-0 left-0 flex items-center justify-center`}>
|
||||
<PhotographIcon className={`h-1/2 text-gray-300 dark:text-vulcan-200`} />
|
||||
{
|
||||
isVideoFile() ? (
|
||||
<VideoCameraIcon className={`h-1/2 text-gray-300 dark:text-vulcan-200`} />
|
||||
) : (
|
||||
isAudioFile() ? (
|
||||
<MusicNoteIcon className={`h-1/2 text-gray-300 dark:text-vulcan-200`} />
|
||||
) : (
|
||||
<PhotographIcon className={`h-1/2 text-gray-300 dark:text-vulcan-200`} />
|
||||
)
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<div className={`absolute top-0 right-0 bottom-0 left-0 flex items-center justify-center`}>
|
||||
<img src={media.vsPath} alt={basename(media.fsPath)} className="mx-auto object-cover" />
|
||||
{ renderMedia }
|
||||
</div>
|
||||
</button>
|
||||
<div className={`relative py-4 pl-4 pr-12`}>
|
||||
|
||||
@@ -73,7 +73,10 @@ export const Media: React.FunctionComponent<IMediaProps> = (props: React.PropsWi
|
||||
|
||||
const {getRootProps, isDragActive} = useDropzone({
|
||||
onDrop,
|
||||
accept: 'image/*'
|
||||
accept: settings?.dashboardState.media.mimeTypes || ['image/*', 'video/*', 'audio/*'],
|
||||
onDropRejected: () => {
|
||||
Messenger.send(DashboardMessage.showWarning, 'Unsupported file type');
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
|
||||
@@ -46,4 +46,5 @@ export interface ContentsViewState {
|
||||
|
||||
export interface MediaViewState extends ContentsViewState {
|
||||
selectedFolder: string | null | undefined;
|
||||
mimeTypes: string[] | null | undefined;
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import { basename, join } from "path";
|
||||
import { workspace } from "vscode";
|
||||
import { Folders } from "../commands/Folders";
|
||||
import { Template } from "../commands/Template";
|
||||
import { CONTEXT, ExtensionState, SETTING_CONTENT_DRAFT_FIELD, SETTING_CONTENT_SORTING, SETTING_CONTENT_SORTING_DEFAULT, SETTING_CONTENT_STATIC_FOLDER, SETTING_DASHBOARD_MEDIA_SNIPPET, SETTING_DASHBOARD_OPENONSTART, SETTING_DATA_FILES, SETTING_DATA_FOLDERS, SETTING_DATA_TYPES, SETTING_FRAMEWORK_ID, SETTING_MEDIA_SORTING_DEFAULT, SETTING_CUSTOM_SCRIPTS, SETTING_TAXONOMY_CONTENT_TYPES, SETTING_CONTENT_SNIPPETS, SETTING_DATE_FORMAT, SETTING_DASHBOARD_CONTENT_TAGS } from "../constants";
|
||||
import { CONTEXT, ExtensionState, SETTING_CONTENT_DRAFT_FIELD, SETTING_CONTENT_SORTING, SETTING_CONTENT_SORTING_DEFAULT, SETTING_CONTENT_STATIC_FOLDER, SETTING_DASHBOARD_MEDIA_SNIPPET, SETTING_DASHBOARD_OPENONSTART, SETTING_DATA_FILES, SETTING_DATA_FOLDERS, SETTING_DATA_TYPES, SETTING_FRAMEWORK_ID, SETTING_MEDIA_SORTING_DEFAULT, SETTING_CUSTOM_SCRIPTS, SETTING_TAXONOMY_CONTENT_TYPES, SETTING_CONTENT_SNIPPETS, SETTING_DATE_FORMAT, SETTING_DASHBOARD_CONTENT_TAGS, SETTING_MEDIA_SUPPORTED_MIMETYPES } from "../constants";
|
||||
import { DashboardViewType, SortingOption, Settings as ISettings } from "../dashboardWebView/models";
|
||||
import { CustomScript, DraftField, ScriptType, Snippets, SortingSetting, TaxonomyType } from "../models";
|
||||
import { DataFile } from "../models/DataFile";
|
||||
@@ -51,7 +51,8 @@ export class DashboardSettings {
|
||||
media: {
|
||||
sorting: await ext.getState<SortingOption | undefined>(ExtensionState.Dashboard.Media.Sorting, "workspace"),
|
||||
defaultSorting: Settings.get<string>(SETTING_MEDIA_SORTING_DEFAULT),
|
||||
selectedFolder: await ext.getState<string | undefined>(ExtensionState.SelectedFolder, "workspace")
|
||||
selectedFolder: await ext.getState<string | undefined>(ExtensionState.SelectedFolder, "workspace"),
|
||||
mimeTypes: Settings.get<string[]>(SETTING_MEDIA_SUPPORTED_MIMETYPES)
|
||||
}
|
||||
},
|
||||
dataFiles: await this.getDataFiles(),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { decodeBase64Image, 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 } from "../constants";
|
||||
import { DEFAULT_CONTENT_TYPE, ExtensionState, HOME_PAGE_NAVIGATION_ID, SETTING_CONTENT_STATIC_FOLDER, SETTING_MEDIA_SUPPORTED_MIMETYPES } from "../constants";
|
||||
import { SortingOption } from "../dashboardWebView/models";
|
||||
import { MediaInfo, MediaPaths, SortOrder, SortType } from "../models";
|
||||
import { basename, extname, join, parse, dirname, relative } from "path";
|
||||
@@ -12,6 +12,7 @@ import { EditorHelper } from "@estruyf/vscode";
|
||||
import { SortOption } from "../dashboardWebView/constants/SortOption";
|
||||
import { DataListener, MediaListener } from "../listeners/panel";
|
||||
import { ArticleHelper } from "./ArticleHelper";
|
||||
import { lookup } from "mime-types";
|
||||
|
||||
|
||||
export class MediaHelpers {
|
||||
@@ -109,10 +110,12 @@ export class MediaHelpers {
|
||||
files = files.map((file) => {
|
||||
try {
|
||||
const metadata = MediaLibrary.getInstance().get(file.fsPath);
|
||||
const mimeType = lookup(file.fsPath);
|
||||
|
||||
return {
|
||||
...file,
|
||||
dimensions: imageSize(file.fsPath),
|
||||
dimensions: mimeType && mimeType.startsWith('image/') ? imageSize(file.fsPath) : undefined,
|
||||
mimeType: lookup(file.fsPath) || '',
|
||||
...metadata
|
||||
};
|
||||
} catch (e) {
|
||||
@@ -356,9 +359,16 @@ export class MediaHelpers {
|
||||
* Filter the media files
|
||||
*/
|
||||
private static filterMedia(files: Uri[]) {
|
||||
let mimeTypes = Settings.get<string[]>(SETTING_MEDIA_SUPPORTED_MIMETYPES) || ["image/*", "video/*", "audio/*"];
|
||||
mimeTypes = mimeTypes.map(type => type.toLowerCase());
|
||||
|
||||
return files.filter(file => {
|
||||
const ext = extname(file.fsPath);
|
||||
return ['.jpg', '.jpeg', '.png', '.gif', '.svg'].includes(ext.toLowerCase());
|
||||
const type = lookup(file.fsPath);
|
||||
if (type) {
|
||||
const isValid = this.acceptMimeType(type, mimeTypes);
|
||||
return isValid;
|
||||
}
|
||||
return false;
|
||||
}).map((file) => ({
|
||||
filename: basename(file.fsPath),
|
||||
fsPath: file.fsPath,
|
||||
@@ -379,4 +389,27 @@ export class MediaHelpers {
|
||||
|
||||
return Object.assign([], files);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate mimetype of the selected file
|
||||
* @param crntType
|
||||
* @param supportedTypes
|
||||
* @returns
|
||||
*/
|
||||
private static acceptMimeType(crntType: string, supportedTypes: string[]) {
|
||||
if (crntType && supportedTypes) {
|
||||
const mimeType = crntType.toLowerCase();
|
||||
const baseMimeType = mimeType.replace(/\/.*$/, '')
|
||||
|
||||
return supportedTypes.some(type => {
|
||||
const validType = type.trim().toLowerCase()
|
||||
if (validType.endsWith('/*')) {
|
||||
// This is something like a image/* mime type
|
||||
return baseMimeType === validType.replace(/\/.*$/, '')
|
||||
}
|
||||
return mimeType === validType
|
||||
})
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import { Dashboard } from "../../commands/Dashboard";
|
||||
import { ExtensionState } from "../../constants";
|
||||
import { DashboardCommand } from "../../dashboardWebView/DashboardCommand";
|
||||
import { DashboardMessage } from "../../dashboardWebView/DashboardMessage";
|
||||
import { Extension } from "../../helpers";
|
||||
import { Extension, Notifications } from "../../helpers";
|
||||
import { BaseListener } from "./BaseListener";
|
||||
|
||||
|
||||
@@ -27,6 +27,9 @@ export class DashboardListener extends BaseListener {
|
||||
case DashboardMessage.setPageViewType:
|
||||
Extension.getInstance().setState(ExtensionState.PagesView, msg.data, "workspace");
|
||||
break;
|
||||
case DashboardMessage.showWarning:
|
||||
Notifications.warning(msg.data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ export interface MediaInfo {
|
||||
dimensions?: ISizeCalculationResult | undefined;
|
||||
caption?: string | undefined;
|
||||
alt?: string | undefined;
|
||||
mimeType?: string | undefined;
|
||||
mtime?: Date;
|
||||
ctime?: Date;
|
||||
size?: number;
|
||||
|
||||
Reference in New Issue
Block a user