Skip to content

Commit eaf2c3e

Browse files
committed
Default PDF imports to preview view
1 parent 939cf05 commit eaf2c3e

6 files changed

Lines changed: 43 additions & 14 deletions

File tree

components/PromptEditor.tsx

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ interface DocumentEditorProps {
2626
formatTrigger: number;
2727
}
2828

29+
const resolveDefaultViewMode = (mode: ViewMode | null | undefined, languageHint: string | null | undefined): ViewMode => {
30+
if (mode) return mode;
31+
const normalizedHint = languageHint?.toLowerCase();
32+
return normalizedHint === 'pdf' || normalizedHint === 'application/pdf' ? 'preview' : 'edit';
33+
};
34+
2935
const DocumentEditor: React.FC<DocumentEditorProps> = ({ documentNode, onSave, onCommitVersion, onDelete, settings, onShowHistory, onLanguageChange, onViewModeChange, formatTrigger }) => {
3036
const [title, setTitle] = useState(documentNode.title);
3137
const [content, setContent] = useState(documentNode.content || '');
@@ -39,7 +45,7 @@ const DocumentEditor: React.FC<DocumentEditorProps> = ({ documentNode, onSave, o
3945
const [isSaving, setIsSaving] = useState(false);
4046
const [isGeneratingTitle, setIsGeneratingTitle] = useState(false);
4147
const [isCopied, setIsCopied] = useState(false);
42-
const [viewMode, setViewMode] = useState<ViewMode>(documentNode.default_view_mode || 'edit');
48+
const [viewMode, setViewMode] = useState<ViewMode>(resolveDefaultViewMode(documentNode.default_view_mode, documentNode.language_hint));
4349
const [splitSize, setSplitSize] = useState(50);
4450
const { addLog } = useLogger();
4551
const { skipNextAutoSave } = useDocumentAutoSave({
@@ -108,7 +114,7 @@ const DocumentEditor: React.FC<DocumentEditorProps> = ({ documentNode, onSave, o
108114
setTitle(documentNode.title);
109115
setContent(nextContent);
110116
setBaselineContent(nextContent);
111-
setViewMode(documentNode.default_view_mode || 'edit');
117+
setViewMode(resolveDefaultViewMode(documentNode.default_view_mode, documentNode.language_hint));
112118
setSplitSize(50);
113119
isContentInitialized.current = true;
114120
setIsDirty(false);
@@ -126,7 +132,7 @@ const DocumentEditor: React.FC<DocumentEditorProps> = ({ documentNode, onSave, o
126132
setContent(nextContent);
127133
}
128134
}
129-
}, [documentNode.id, documentNode.content, documentNode.default_view_mode, documentNode.title, isDirty]);
135+
}, [documentNode.id, documentNode.content, documentNode.default_view_mode, documentNode.language_hint, documentNode.title, isDirty]);
130136

131137
useEffect(() => {
132138
setTitle(documentNode.title);
@@ -138,6 +144,13 @@ const DocumentEditor: React.FC<DocumentEditorProps> = ({ documentNode, onSave, o
138144
}
139145
}, [viewMode, isDiffMode]);
140146

147+
useEffect(() => {
148+
const normalizedHint = documentNode.language_hint?.toLowerCase();
149+
if ((normalizedHint === 'pdf' || normalizedHint === 'application/pdf') && !documentNode.default_view_mode && viewMode === 'edit') {
150+
setViewMode('preview');
151+
}
152+
}, [documentNode.language_hint, documentNode.default_view_mode, viewMode]);
153+
141154
useEffect(() => {
142155
// Only mark as dirty after the initial content has been loaded.
143156
if (isContentInitialized.current) {

electron/database.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ const mapExtensionToLanguageId_local = (extension: string | null): string => {
4040
case 'fmx':
4141
case 'ini':
4242
return 'ini';
43+
case 'application/pdf':
44+
case 'pdf':
45+
return 'pdf';
4346
default: return 'plaintext';
4447
}
4548
};
@@ -208,7 +211,7 @@ export const databaseService = {
208211
}
209212

210213
// Insert Documents and Versions
211-
const docStmt = db.prepare('INSERT INTO documents (node_id, doc_type, language_hint) VALUES (?, ?, ?)');
214+
const docStmt = db.prepare('INSERT INTO documents (node_id, doc_type, language_hint, default_view_mode) VALUES (?, ?, ?, ?)');
212215
const versionStmt = db.prepare('INSERT INTO doc_versions (document_id, created_at, content_id) VALUES (?, ?, ?)');
213216
const updateDocStmt = db.prepare('UPDATE documents SET current_version_id = ? WHERE document_id = ?');
214217

@@ -219,7 +222,7 @@ export const databaseService = {
219222
}
220223

221224
for (const doc of data.documents) {
222-
const docResult = docStmt.run(doc.node_id, doc.doc_type, doc.language_hint);
225+
const docResult = docStmt.run(doc.node_id, doc.doc_type, doc.language_hint, doc.default_view_mode ?? null);
223226
const docId = Number(docResult.lastInsertRowid);
224227

225228
const versions = docVersionsByNode.get(doc.node_id) || [];
@@ -296,9 +299,9 @@ export const databaseService = {
296299
const originalDoc = db.prepare('SELECT * FROM documents WHERE node_id = ?').get(nodeId) as Document;
297300
if (originalDoc) {
298301
const newDocResult = db.prepare(`
299-
INSERT INTO documents (node_id, doc_type, language_hint, current_version_id)
300-
VALUES (?, ?, ?, NULL)
301-
`).run(newNodeId, originalDoc.doc_type, originalDoc.language_hint);
302+
INSERT INTO documents (node_id, doc_type, language_hint, default_view_mode, current_version_id)
303+
VALUES (?, ?, ?, ?, NULL)
304+
`).run(newNodeId, originalDoc.doc_type, originalDoc.language_hint, originalDoc.default_view_mode);
302305
const newDocId = newDocResult.lastInsertRowid;
303306

304307
// Fix: Cast the result to DocVersion array.
@@ -456,11 +459,20 @@ export const databaseService = {
456459
const maxSortOrderResult = db.prepare(`SELECT MAX(sort_order) as max_order FROM nodes WHERE parent_id ${currentParentId ? '= ?' : 'IS NULL'}`).get(currentParentId) as { max_order: number | null };
457460
const sortOrder = (maxSortOrderResult?.max_order ?? -1) + 1;
458461
const extension = file.name.split('.').pop() || null;
459-
const languageHint = mapExtensionToLanguageId_local(extension);
462+
let languageHint = mapExtensionToLanguageId_local(extension);
460463

461464
db.prepare(`INSERT INTO nodes (node_id, parent_id, node_type, title, sort_order, created_at, updated_at) VALUES (?, ?, 'document', ?, ?, ?, ?)`).run(newNodeId, currentParentId, file.name, sortOrder, now, now);
462465

463-
const docResult = db.prepare(`INSERT INTO documents (node_id, doc_type, language_hint) VALUES (?, ?, ?)`).run(newNodeId, 'source_code', languageHint);
466+
const trimmedContent = file.content.trim();
467+
const isPdf = languageHint === 'pdf' || languageHint === 'application/pdf' || trimmedContent.startsWith('data:application/pdf');
468+
if (isPdf) {
469+
languageHint = 'pdf';
470+
}
471+
const docType = isPdf ? 'pdf' : 'source_code';
472+
const defaultViewMode = isPdf ? 'preview' : null;
473+
474+
const docResult = db.prepare(`INSERT INTO documents (node_id, doc_type, language_hint, default_view_mode) VALUES (?, ?, ?, ?)`)
475+
.run(newNodeId, docType, languageHint, defaultViewMode);
464476
const documentId = Number(docResult.lastInsertRowid);
465477

466478
const contentId = getContentId(file.content);

hooks/usePrompts.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,13 @@ export const useDocuments = () => {
5858
const items: DocumentOrFolder[] = useMemo(() => allNodesFlat.map(nodeToDocumentOrFolder), [allNodesFlat]);
5959

6060
const addDocument = useCallback(async ({ parentId, title = 'New Document', content = '', doc_type = 'prompt', language_hint = 'markdown' }: { parentId: string | null, title?: string, content?: string, doc_type?: DocType, language_hint?: string | null }) => {
61+
const resolvedLanguage = mapExtensionToLanguageId(language_hint);
62+
const defaultViewMode = doc_type === 'pdf' || resolvedLanguage === 'pdf' ? 'preview' : undefined;
6163
const newNode = await addNode({
6264
parent_id: parentId,
6365
node_type: 'document',
6466
title,
65-
document: { content, doc_type, language_hint: mapExtensionToLanguageId(language_hint) } as any,
67+
document: { content, doc_type, language_hint: resolvedLanguage, default_view_mode: defaultViewMode } as any,
6668
});
6769
return nodeToDocumentOrFolder(newNode);
6870
}, [addNode]);

services/languageService.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ export const mapExtensionToLanguageId = (extension: string | null): string => {
7676
case 'fmx':
7777
case 'ini':
7878
return 'ini';
79+
case 'application/pdf':
80+
return 'pdf';
7981
case 'pdf':
8082
return 'pdf';
8183
default:

services/repository.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -561,8 +561,8 @@ export const repository = {
561561

562562
if (nodeData.node_type === 'document' && nodeData.document) {
563563
const docRes = await window.electronAPI!.dbRun(
564-
`INSERT INTO documents (node_id, doc_type, language_hint) VALUES (?, ?, ?)`,
565-
[newNodeId, nodeData.document.doc_type, nodeData.document.language_hint]
564+
`INSERT INTO documents (node_id, doc_type, language_hint, default_view_mode) VALUES (?, ?, ?, ?)`,
565+
[newNodeId, nodeData.document.doc_type, nodeData.document.language_hint, nodeData.document.default_view_mode ?? null]
566566
);
567567
const documentId = docRes.lastInsertRowid;
568568

types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ declare global {
6464
// =================================================================
6565

6666
export type NodeType = 'folder' | 'document';
67-
export type DocType = 'prompt' | 'source_code';
67+
export type DocType = 'prompt' | 'source_code' | 'pdf';
6868
export type ViewMode = 'edit' | 'preview' | 'split-vertical' | 'split-horizontal';
6969

7070
export type PythonExecutionStatus = 'pending' | 'running' | 'succeeded' | 'failed' | 'canceled';

0 commit comments

Comments
 (0)