> {
- if (isImagePreviewEntry(entry)) return ImageSquare
+ const previewKind = filePreviewKind(entry)
+ if (previewKind === 'image') return ImageSquare
+ if (previewKind === 'pdf') return FilePdf
if (entry.fileKind && entry.fileKind !== 'markdown') return getFileKindIcon(entry.fileKind)
return getTypeIcon(entry.isA, customIcon)
}
@@ -232,11 +234,11 @@ function StandardNoteContent({
}) {
const te = typeEntryMap[entry.isA ?? '']
const TypeIcon = resolveNoteTypeIcon(entry, te?.icon)
- const filePreviewKind = isImagePreviewEntry(entry) ? 'image' : undefined
+ const previewKind = filePreviewKind(entry) ?? undefined
return (
<>
-
+
{isBinary ? (
& {
- isImagePreview: boolean
+ previewKind: FilePreviewKind | null
}) {
if (isMultiSelected) return 'multi-selected-item'
- if (isImagePreview) return 'image-file-item'
+ if (previewKind) return `${previewKind}-file-item`
return isUnavailableBinary ? 'binary-file-item' : undefined
}
function resolveNoteItemTitle({
- isImagePreview,
+ previewKind,
isUnavailableBinary,
}: Pick & {
- isImagePreview: boolean
+ previewKind: FilePreviewKind | null
}) {
- if (isImagePreview) return 'Open image preview'
+ if (previewKind === 'image') return 'Open image preview'
+ if (previewKind === 'pdf') return 'Open PDF preview'
return isUnavailableBinary ? 'Cannot open this file type' : undefined
}
function resolveNoteItemSurfaceProps({
entry,
isUnavailableBinary,
- isImagePreview,
+ previewKind,
isSelected,
isMultiSelected,
isHighlighted,
@@ -394,7 +397,7 @@ function resolveNoteItemSurfaceProps({
typeLightColor,
}: NoteItemVisualState & {
entry: VaultEntry
- isImagePreview: boolean
+ previewKind: FilePreviewKind | null
onClickNote: NoteItemProps['onClickNote']
onPrefetch?: NoteItemProps['onPrefetch']
onContextMenu?: NoteItemProps['onContextMenu']
@@ -407,8 +410,8 @@ function resolveNoteItemSurfaceProps({
onClick: createNoteItemClickHandler(entry, isUnavailableBinary, onClickNote),
onContextMenu: onContextMenu ? (event) => onContextMenu(entry, event) : undefined,
onMouseEnter: entry.fileKind !== 'binary' && onPrefetch ? () => onPrefetch(entry.path) : undefined,
- testId: resolveNoteItemTestId({ isMultiSelected, isImagePreview, isUnavailableBinary }),
- title: resolveNoteItemTitle({ isImagePreview, isUnavailableBinary }),
+ testId: resolveNoteItemTestId({ isMultiSelected, previewKind, isUnavailableBinary }),
+ title: resolveNoteItemTitle({ previewKind, isUnavailableBinary }),
}
}
@@ -497,16 +500,17 @@ function NoteItemContent({
export function NoteItem({ entry, isSelected, isMultiSelected = false, isHighlighted = false, noteStatus = 'clean', changeStatus, typeEntryMap, allEntries, displayPropsOverride, onClickNote, onPrefetch, onContextMenu }: NoteItemProps) {
const isBinary = entry.fileKind === 'binary'
- const isImagePreview = isImagePreviewEntry(entry)
- const isUnavailableBinary = isBinary && !isImagePreview
+ const previewKind = filePreviewKind(entry)
+ const isPreviewableFile = previewKind !== null
+ const isUnavailableBinary = isBinary && !isPreviewableFile
const te = typeEntryMap[entry.isA ?? '']
const displayProps = resolveDisplayProps(entry, typeEntryMap, displayPropsOverride)
- const typeColor = isImagePreview ? 'var(--accent-blue)' : isBinary ? 'var(--muted-foreground)' : getTypeColor(entry.isA ?? 'Note', te?.color)
+ const typeColor = isPreviewableFile ? 'var(--accent-blue)' : isBinary ? 'var(--muted-foreground)' : getTypeColor(entry.isA ?? 'Note', te?.color)
const typeLightColor = getTypeLightColor(entry.isA ?? 'Note', te?.color)
const surfaceProps = resolveNoteItemSurfaceProps({
entry,
isUnavailableBinary,
- isImagePreview,
+ previewKind,
isSelected,
isMultiSelected,
isHighlighted,
diff --git a/src/utils/filePreview.ts b/src/utils/filePreview.ts
index 5b38eac2..4719b702 100644
--- a/src/utils/filePreview.ts
+++ b/src/utils/filePreview.ts
@@ -1,5 +1,7 @@
import type { VaultEntry } from '../types'
+export type FilePreviewKind = 'image' | 'pdf'
+
const IMAGE_PREVIEW_EXTENSIONS = new Set([
'apng',
'avif',
@@ -14,6 +16,7 @@ const IMAGE_PREVIEW_EXTENSIONS = new Set([
'tiff',
'webp',
])
+const PDF_PREVIEW_EXTENSIONS = new Set(['pdf'])
function extensionFromFilename(filename: string): string | null {
const lastSegment = filename.split(/[\\/]/u).pop() ?? filename
@@ -27,9 +30,25 @@ export function previewExtension(entry: Pick):
}
export function isImagePreviewEntry(entry: Pick): boolean {
- if (entry.fileKind !== 'binary') return false
+ return filePreviewKind(entry) === 'image'
+}
+
+export function isPdfPreviewEntry(entry: Pick): boolean {
+ return filePreviewKind(entry) === 'pdf'
+}
+
+export function filePreviewKind(entry: Pick): FilePreviewKind | null {
+ if (entry.fileKind && entry.fileKind !== 'binary') return null
+
const extension = previewExtension(entry)
- return extension ? IMAGE_PREVIEW_EXTENSIONS.has(extension) : false
+ if (!extension) return null
+ if (IMAGE_PREVIEW_EXTENSIONS.has(extension)) return 'image'
+ if (PDF_PREVIEW_EXTENSIONS.has(extension)) return 'pdf'
+ return null
+}
+
+export function isFilePreviewEntry(entry: Pick): boolean {
+ return filePreviewKind(entry) !== null
}
export function previewFileTypeLabel(entry: Pick): string {