mirror of
https://github.com/estruyf/vscode-front-matter.git
synced 2026-07-05 09:21:39 +02:00
#257 - Allow preview images to be used in multi-dimensional fields
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
- [#242](https://github.com/estruyf/vscode-front-matter/issues/242): Keep comments at the root of the front matter
|
||||
- [#248](https://github.com/estruyf/vscode-front-matter/issues/248): Added support for front matter highlighting to all file types specified in `frontMatter.content.supportedFileTypes`
|
||||
- [#255](https://github.com/estruyf/vscode-front-matter/issues/255): Added support for default values on block fields / data creation
|
||||
- [#257](https://github.com/estruyf/vscode-front-matter/issues/257): Allow preview images to be used in multi-dimensional fields
|
||||
|
||||
### ⚡️ Optimizations
|
||||
|
||||
|
||||
@@ -3,21 +3,18 @@ import { useRecoilValue } from 'recoil';
|
||||
import { MarkdownIcon } from '../../../panelWebView/components/Icons/MarkdownIcon';
|
||||
import { DashboardMessage } from '../../DashboardMessage';
|
||||
import { Page } from '../../models/Page';
|
||||
import { SettingsSelector, ViewSelector } from '../../state';
|
||||
import { ViewSelector } from '../../state';
|
||||
import { DateField } from '../DateField';
|
||||
import { Status } from '../Status';
|
||||
import { Messenger } from '@estruyf/vscode/dist/client';
|
||||
import useContentType from '../../../hooks/useContentType';
|
||||
import { DashboardViewType } from '../../models';
|
||||
|
||||
export interface IItemProps extends Page {}
|
||||
|
||||
const PREVIEW_IMAGE_FIELD = 'fmPreviewImage';
|
||||
|
||||
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);
|
||||
@@ -30,8 +27,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">
|
||||
{
|
||||
previewField && pageData[previewField] ? (
|
||||
<img src={`${pageData[previewField]}`} alt={title} className="absolute inset-0 h-full w-full object-cover" loading="lazy" />
|
||||
pageData[PREVIEW_IMAGE_FIELD] ? (
|
||||
<img src={`${pageData[PREVIEW_IMAGE_FIELD]}`} 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`} />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useState, useEffect, useCallback, useMemo } from 'react';
|
||||
import { DEFAULT_CONTENT_TYPE, DEFAULT_CONTENT_TYPE_NAME } from '../constants/ContentType';
|
||||
import { Settings } from '../dashboardWebView/models';
|
||||
import { ContentType, PanelSettings } from '../models';
|
||||
import { ContentType, Field, PanelSettings } from '../models';
|
||||
|
||||
export default function useContentType(settings: PanelSettings | Settings | undefined | null, metadata: any) {
|
||||
const [contentType, setContentType] = useState<ContentType>(DEFAULT_CONTENT_TYPE);
|
||||
|
||||
@@ -13,6 +13,7 @@ import { ContentType } from "../../helpers/ContentType";
|
||||
import { DateHelper } from "../../helpers/DateHelper";
|
||||
import { Notifications } from "../../helpers/Notifications";
|
||||
import { BaseListener } from "./BaseListener";
|
||||
import { Field } from '../../models';
|
||||
|
||||
|
||||
export class PagesListener extends BaseListener {
|
||||
@@ -150,6 +151,7 @@ export class PagesListener extends BaseListener {
|
||||
fmFileName: fileName,
|
||||
fmDraft: ContentType.getDraftStatus(article?.data),
|
||||
fmYear: article?.data[dateField] ? DateHelper.tryParse(article?.data[dateField])?.getFullYear() : null,
|
||||
fmPreviewImage: "",
|
||||
// Make sure these are always set
|
||||
title: article?.data.title,
|
||||
slug: article?.data.slug,
|
||||
@@ -159,35 +161,59 @@ export class PagesListener extends BaseListener {
|
||||
};
|
||||
|
||||
const contentType = ArticleHelper.getContentType(article.data);
|
||||
const previewField = contentType.fields.find(field => field.isPreviewImage && field.type === "image")?.name || "preview";
|
||||
|
||||
if (article?.data[previewField] && wsFolder) {
|
||||
let fieldValue = article?.data[previewField];
|
||||
if (fieldValue && Array.isArray(fieldValue)) {
|
||||
if (fieldValue.length > 0) {
|
||||
fieldValue = fieldValue[0];
|
||||
let previewFieldParents = this.findPreviewField(contentType.fields);
|
||||
if (previewFieldParents.length === 0) {
|
||||
const previewField = contentType.fields.find(field => field.type === "image" && field.name === "preview");
|
||||
if (previewField) {
|
||||
previewFieldParents = ["preview"];
|
||||
}
|
||||
}
|
||||
|
||||
// Check if parent fields were retrieved, if not there was no image present
|
||||
if (previewFieldParents.length > 0) {
|
||||
let fieldValue = null;
|
||||
let crntPageData = article?.data;
|
||||
|
||||
for (let i = 0; i < previewFieldParents.length; i++) {
|
||||
const previewField = previewFieldParents[i];
|
||||
|
||||
if (i === previewFieldParents.length - 1) {
|
||||
fieldValue = crntPageData[previewField];
|
||||
} else {
|
||||
fieldValue = undefined;
|
||||
if (!crntPageData[previewField]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
crntPageData = crntPageData[previewField];
|
||||
}
|
||||
}
|
||||
|
||||
// Revalidate as the array could have been empty
|
||||
if (fieldValue) {
|
||||
const staticPath = join(wsFolder.fsPath, staticFolder || "", fieldValue);
|
||||
const contentFolderPath = join(dirname(filePath), fieldValue);
|
||||
|
||||
let previewUri = null;
|
||||
if (existsSync(staticPath)) {
|
||||
previewUri = Uri.file(staticPath);
|
||||
} else if (existsSync(contentFolderPath)) {
|
||||
previewUri = Uri.file(contentFolderPath);
|
||||
if (fieldValue && wsFolder) {
|
||||
if (fieldValue && Array.isArray(fieldValue)) {
|
||||
if (fieldValue.length > 0) {
|
||||
fieldValue = fieldValue[0];
|
||||
} else {
|
||||
fieldValue = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
if (previewUri) {
|
||||
const preview = Dashboard.getWebview()?.asWebviewUri(previewUri);
|
||||
page[previewField] = preview?.toString() || "";
|
||||
} else {
|
||||
page[previewField] = "";
|
||||
|
||||
// Revalidate as the array could have been empty
|
||||
if (fieldValue) {
|
||||
const staticPath = join(wsFolder.fsPath, staticFolder || "", fieldValue);
|
||||
const contentFolderPath = join(dirname(filePath), fieldValue);
|
||||
|
||||
let previewUri = null;
|
||||
if (existsSync(staticPath)) {
|
||||
previewUri = Uri.file(staticPath);
|
||||
} else if (existsSync(contentFolderPath)) {
|
||||
previewUri = Uri.file(contentFolderPath);
|
||||
}
|
||||
|
||||
if (previewUri) {
|
||||
const preview = Dashboard.getWebview()?.asWebviewUri(previewUri);
|
||||
page["fmPreviewImage"] = preview?.toString() || "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -197,4 +223,26 @@ export class PagesListener extends BaseListener {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the preview field in the fields
|
||||
* @param ctFields
|
||||
* @param parents
|
||||
* @returns
|
||||
*/
|
||||
private static findPreviewField(ctFields: Field[], parents: string[] = []): string[] {
|
||||
for (const field of ctFields) {
|
||||
if (field.isPreviewImage && field.type === "image") {
|
||||
parents = [...parents, field.name];
|
||||
return parents;
|
||||
} else if (field.type === "fields" && field.fields) {
|
||||
const subFields = this.findPreviewField(field.fields);
|
||||
if (subFields.length > 0) {
|
||||
return [...parents, field.name, ...subFields];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return parents;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user