mirror of
https://github.com/estruyf/vscode-front-matter.git
synced 2026-06-22 19:15:10 +02:00
125 lines
4.6 KiB
TypeScript
125 lines
4.6 KiB
TypeScript
import * as React from 'react';
|
|
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 { DateField } from '../DateField';
|
|
import { Status } from '../Status';
|
|
import { Messenger } from '@estruyf/vscode/dist/client';
|
|
import { DashboardViewType } from '../../models';
|
|
import { ContentActions } from './ContentActions';
|
|
import { useMemo } from 'react';
|
|
|
|
export interface IItemProps extends Page {}
|
|
|
|
const PREVIEW_IMAGE_FIELD = 'fmPreviewImage';
|
|
|
|
export const Item: React.FunctionComponent<IItemProps> = ({ fmFilePath, date, title, description, type, ...pageData }: React.PropsWithChildren<IItemProps>) => {
|
|
const view = useRecoilValue(ViewSelector);
|
|
const settings = useRecoilValue(SettingsSelector);
|
|
const draftField = useMemo(() => settings?.draftField, [settings]);
|
|
|
|
const openFile = () => {
|
|
Messenger.send(DashboardMessage.openFile, fmFilePath);
|
|
};
|
|
|
|
const tags: string[] | undefined = React.useMemo(() => {
|
|
if (!settings?.dashboardState?.contents?.tags) {
|
|
return undefined;
|
|
}
|
|
|
|
const tagField = settings.dashboardState.contents.tags;
|
|
let tagsValue = [];
|
|
|
|
if (tagField === "tags") {
|
|
tagsValue = pageData.fmTags;
|
|
} else if (tagField === "categories") {
|
|
tagsValue = pageData.fmCategories;
|
|
} else {
|
|
tagsValue = pageData[tagField] || [];
|
|
}
|
|
|
|
if (typeof tagsValue === "string") {
|
|
return [tagsValue];
|
|
} else if (Array.isArray(tagsValue)) {
|
|
return tagsValue;
|
|
}
|
|
|
|
return [];
|
|
}, [settings, pageData]);
|
|
|
|
if (view === DashboardViewType.Grid) {
|
|
return (
|
|
<li className="relative">
|
|
<button className={`group cursor-pointer flex flex-wrap items-start content-start h-full w-full bg-gray-50 dark:bg-vulcan-200 text-vulcan-500 dark:text-whisper-500 text-left shadow-md dark:shadow-none hover:shadow-xl dark:hover:bg-vulcan-100 border border-gray-200 dark:border-vulcan-50`}
|
|
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">
|
|
{
|
|
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`} />
|
|
</div>
|
|
)
|
|
}
|
|
</div>
|
|
|
|
<div className="relative p-4 w-full">
|
|
<div className={`flex justify-between items-center`}>
|
|
{ draftField && draftField.name && <Status draft={pageData[draftField.name]} /> }
|
|
|
|
<DateField className={`mr-4`} value={date} />
|
|
|
|
<ContentActions
|
|
title={title}
|
|
path={fmFilePath}
|
|
scripts={settings?.scripts}
|
|
onOpen={openFile} />
|
|
</div>
|
|
|
|
<h2 className="mt-2 mb-2 font-bold">{title}</h2>
|
|
|
|
<p className="text-xs text-vulcan-200 dark:text-whisper-800">{description}</p>
|
|
|
|
{
|
|
tags && tags.length > 0 && (
|
|
<div className="mt-2">
|
|
{
|
|
tags.map((tag, index) => (
|
|
<span
|
|
key={index}
|
|
className="inline-block mr-1 mt-1 text-[#5D561D] dark:text-[#F0ECD0] text-xs">
|
|
#{tag}
|
|
</span>
|
|
))
|
|
}
|
|
</div>
|
|
)
|
|
}
|
|
</div>
|
|
</button>
|
|
</li>
|
|
);
|
|
} else if (view === DashboardViewType.List) {
|
|
return (
|
|
<li className="relative">
|
|
<button className={`px-5 cursor-pointer w-full text-left grid grid-cols-12 gap-x-4 sm:gap-x-6 xl:gap-x-8 py-2 border-b border-gray-300 hover:bg-gray-200 dark:border-vulcan-50 dark:hover:bg-vulcan-50 hover:bg-opacity-70`} onClick={openFile}>
|
|
<div className="col-span-8 font-bold truncate">
|
|
{title}
|
|
</div>
|
|
<div className="col-span-2">
|
|
<DateField value={date} />
|
|
</div>
|
|
<div className="col-span-2">
|
|
{ draftField && draftField.name && <Status draft={pageData[draftField.name]} /> }
|
|
</div>
|
|
</button>
|
|
</li>
|
|
);
|
|
}
|
|
|
|
return null;
|
|
}; |