#124 - Add support to specify preview image

This commit is contained in:
Elio Struyf
2021-09-30 16:26:21 +02:00
parent 8199ab964e
commit 5f28e145c4
7 changed files with 47 additions and 17 deletions
+4
View File
@@ -294,6 +294,10 @@
"multiSelect": {
"type": "boolean",
"description": "Do you allow to select multiple values?"
},
"isPreviewImage": {
"type": "boolean",
"description": "Specify if the image field can be used as preview. Be aware, you can only have one preview image per content type."
}
},
"additionalProperties": false,
+2 -1
View File
@@ -1,4 +1,4 @@
import { SETTINGS_CONTENT_STATIC_FOLDERS, SETTING_DATE_FIELD, SETTING_SEO_DESCRIPTION_FIELD, SETTINGS_DASHBOARD_OPENONSTART, SETTINGS_DASHBOARD_MEDIA_SNIPPET } from './../constants/settings';
import { SETTINGS_CONTENT_STATIC_FOLDERS, SETTING_DATE_FIELD, SETTING_SEO_DESCRIPTION_FIELD, SETTINGS_DASHBOARD_OPENONSTART, SETTINGS_DASHBOARD_MEDIA_SNIPPET, SETTING_TAXONOMY_CONTENT_TYPES } from './../constants/settings';
import { ArticleHelper } from './../helpers/ArticleHelper';
import { basename, dirname, extname, join, parse } from "path";
import { existsSync, renameSync, statSync, unlinkSync, writeFileSync } from "fs";
@@ -239,6 +239,7 @@ export class Dashboard {
versionInfo: ext.getVersion(),
pageViewType: await ext.getState<ViewType | undefined>(EXTENSION_STATE_PAGES_VIEW),
mediaSnippet: SettingsHelper.get<string[]>(SETTINGS_DASHBOARD_MEDIA_SNIPPET) || [],
contentTypes: SettingsHelper.get(SETTING_TAXONOMY_CONTENT_TYPES) || [],
} as Settings
});
}
@@ -3,15 +3,20 @@ import { useRecoilValue } from 'recoil';
import { MarkdownIcon } from '../../../panelWebView/components/Icons/MarkdownIcon';
import { DashboardMessage } from '../../DashboardMessage';
import { Page } from '../../models/Page';
import { ViewSelector, ViewType } from '../../state';
import { SettingsSelector, ViewSelector, ViewType } from '../../state';
import { DateField } from '../DateField';
import { Status } from '../Status';
import { Messenger } from '@estruyf/vscode/dist/client';
import useContentType from '../../../hooks/useContentType';
export interface IItemProps extends Page {}
export const Item: React.FunctionComponent<IItemProps> = ({ fmFilePath, date, title, draft, description, preview }: React.PropsWithChildren<IItemProps>) => {
export const Item: React.FunctionComponent<IItemProps> = ({ fmFilePath, date, title, draft, description, type, ...pageData }: React.PropsWithChildren<IItemProps>) => {
const view = useRecoilValue(ViewSelector);
const settings = useRecoilValue(SettingsSelector);
const contentType = useContentType(settings, { type });
const previewField = contentType.fields.find(field => field.isPreviewImage && field.type === "image")?.name || "preview";
const openFile = () => {
Messenger.send(DashboardMessage.openFile, fmFilePath);
@@ -24,8 +29,8 @@ export const Item: React.FunctionComponent<IItemProps> = ({ fmFilePath, date, ti
onClick={openFile}>
<div className="relative h-36 w-full overflow-hidden border-b border-gray-100 dark:border-vulcan-100 dark:group-hover:border-vulcan-200">
{
preview ? (
<img src={`${preview}`} alt={title} className="absolute inset-0 h-full w-full object-cover" loading="lazy" />
previewField && pageData[previewField] ? (
<img src={`${pageData[previewField]}`} alt={title} className="absolute inset-0 h-full w-full object-cover" loading="lazy" />
) : (
<div className={`flex items-center justify-center bg-whisper-500 dark:bg-vulcan-200 dark:group-hover:bg-vulcan-100`}>
<MarkdownIcon className={`h-32 text-vulcan-100 dark:text-whisper-100`} />
+2
View File
@@ -1,6 +1,7 @@
import { VersionInfo } from '../../models/VersionInfo';
import { ViewType } from '../state';
import { ContentFolder } from '../../models/ContentFolder';
import { ContentType } from '../../models';
export interface Settings {
beta: boolean;
@@ -14,4 +15,5 @@ export interface Settings {
versionInfo: VersionInfo;
pageViewType: ViewType | undefined;
mediaSnippet: string[];
contentTypes: ContentType[];
}
+27
View File
@@ -0,0 +1,27 @@
import { useState, useEffect } from 'react';
import { DEFAULT_CONTENT_TYPE, DEFAULT_CONTENT_TYPE_NAME } from '../constants/ContentType';
import { Settings } from '../dashboardWebView/models';
import { ContentType, PanelSettings } from '../models';
export default function useContentType(settings: PanelSettings | Settings | undefined | null, metadata: any) {
const [contentType, setContentType] = useState<ContentType>(DEFAULT_CONTENT_TYPE);
useEffect(() => {
if (settings) {
const contentTypeName = metadata.type as string || DEFAULT_CONTENT_TYPE_NAME;
let ct = settings.contentTypes.find(ct => ct.name === contentTypeName);
if (!ct) {
ct = settings.contentTypes.find(ct => ct.name === DEFAULT_CONTENT_TYPE_NAME);
}
if (!ct || !ct.fields) {
ct = DEFAULT_CONTENT_TYPE;
}
setContentType(ct || DEFAULT_CONTENT_TYPE)
}
}, [settings?.contentTypes, metadata?.data]);
return contentType;
}
+1
View File
@@ -31,6 +31,7 @@ export interface Field {
choices?: string[] | Choice[];
single?: boolean;
multiSelect?: boolean;
isPreviewImage?: boolean;
}
export interface DateInfo {
+2 -12
View File
@@ -13,10 +13,10 @@ import { DateTimeField } from './Fields/DateTimeField';
import { TextField } from './Fields/TextField';
import "react-datepicker/dist/react-datepicker.css";
import { PreviewImageField } from './Fields/PreviewImageField';
import { DEFAULT_CONTENT_TYPE, DEFAULT_CONTENT_TYPE_NAME } from '../../constants/ContentType';
import { ListUnorderedIcon } from './Icons/ListUnorderedIcon';
import { NumberField } from './Fields/NumberField';
import { ChoiceField } from './Fields/ChoiceField';
import useContentType from '../../hooks/useContentType';
export interface IMetadataProps {
settings: PanelSettings | undefined;
@@ -26,6 +26,7 @@ export interface IMetadataProps {
}
export const Metadata: React.FunctionComponent<IMetadataProps> = ({settings, metadata, focusElm, unsetFocus}: React.PropsWithChildren<IMetadataProps>) => {
const contentType = useContentType(settings, metadata);
const sendUpdate = (field: string | undefined, value: any) => {
if (!field) {
@@ -49,17 +50,6 @@ export const Metadata: React.FunctionComponent<IMetadataProps> = ({settings, met
return null;
}
const contentTypeName = metadata.type as string || DEFAULT_CONTENT_TYPE_NAME;
let contentType = settings.contentTypes.find(ct => ct.name === contentTypeName);
if (!contentType) {
contentType = settings.contentTypes.find(ct => ct.name === DEFAULT_CONTENT_TYPE_NAME);
}
if (!contentType || !contentType.fields) {
contentType = DEFAULT_CONTENT_TYPE;
}
const renderFields = (ctFields: Field[]) => {
if (!ctFields) {
return;