@@ -6,12 +6,14 @@ import { Upload, Loader2 } from 'lucide-react';
66 *
77 * Features:
88 * - File upload via click or drag-drop
9+ * - Uses native Tauri file dialog when available (provides full path for "Show in folder")
910 * - URL loading (remote or local bridge)
1011 * - Loading state indicator
1112 * - Respects environment flags for remote/local options
1213 */
1314const UploadZone = ( {
1415 onUpload,
16+ onLoadFromPath, // New: callback for loading via file path (Tauri)
1517 onLoadFromUrl,
1618 isLoading = false ,
1719 isDragging = false ,
@@ -22,12 +24,36 @@ const UploadZone = ({
2224 // Check environment flags
2325 const allowRemote = import . meta. env . VITE_ENABLE_REMOTE_PDFS !== 'false' ;
2426 const allowLocal = import . meta. env . VITE_ENABLE_LOCAL_BRIDGE !== 'false' ;
27+ const isTauri = ! ! window . __TAURI__ ?. core ?. invoke ;
2528
2629 let placeholder = "" ;
2730 if ( allowRemote && allowLocal ) placeholder = "https://... or folder/file.pdf" ;
2831 else if ( allowRemote ) placeholder = "https://..." ;
2932 else if ( allowLocal ) placeholder = "folder/file.pdf" ;
3033
34+ // Handle upload click - use native dialog in Tauri for full path access
35+ const handleUploadClick = async ( ) => {
36+ if ( isLoading ) return ;
37+
38+ if ( isTauri && onLoadFromPath ) {
39+ try {
40+ const dialog = window . __TAURI__ ?. dialog ;
41+ if ( dialog ?. open ) {
42+ const selected = await dialog . open ( {
43+ filters : [ { name : 'PDF' , extensions : [ 'pdf' ] } ] ,
44+ multiple : false ,
45+ } ) ;
46+ if ( selected ) {
47+ // Tauri dialog returns the full path
48+ onLoadFromPath ( selected ) ;
49+ }
50+ }
51+ } catch ( err ) {
52+ console . error ( 'Failed to open file dialog:' , err ) ;
53+ }
54+ }
55+ } ;
56+
3157 return (
3258 < div
3359 className = { `flex-1 flex flex-col items-center justify-center transition-all ${ isDragging ? 'bg-blue-50 border-4 border-dashed border-blue-400 rounded-lg m-4' : ''
@@ -36,25 +62,42 @@ const UploadZone = ({
3662 onDragLeave = { onDragLeave }
3763 onDrop = { onDrop }
3864 >
39- { /* File upload */ }
40- < label
41- className = { `cursor-pointer flex flex-col items-center gap-3 p-8 border-2 border-dashed rounded-none transition-colors ${ isLoading
42- ? 'border-gray-200 bg-gray-50 cursor-wait'
43- : 'border-gray-400 hover:border-blue-500 hover:bg-blue-50'
44- } `}
45- >
46- < Upload className = { `w-12 h-12 ${ isLoading ? 'text-gray-300' : 'text-gray-400' } ` } />
47- < span className = { `font-medium ${ isLoading ? 'text-gray-400' : 'text-gray-600' } ` } >
48- { isLoading ? 'Uploading PDF...' : 'Upload PDF' }
49- </ span >
50- < input
51- type = "file"
52- accept = "application/pdf"
53- onChange = { onUpload }
54- className = "hidden"
65+ { /* File upload - Tauri uses onClick for native dialog, web uses input */ }
66+ { isTauri ? (
67+ < button
68+ type = "button"
69+ onClick = { handleUploadClick }
5570 disabled = { isLoading }
56- />
57- </ label >
71+ className = { `cursor-pointer flex flex-col items-center gap-3 p-8 border-2 border-dashed rounded-none transition-colors ${ isLoading
72+ ? 'border-gray-200 bg-gray-50 cursor-wait'
73+ : 'border-gray-400 hover:border-blue-500 hover:bg-blue-50'
74+ } `}
75+ >
76+ < Upload className = { `w-12 h-12 ${ isLoading ? 'text-gray-300' : 'text-gray-400' } ` } />
77+ < span className = { `font-medium ${ isLoading ? 'text-gray-400' : 'text-gray-600' } ` } >
78+ { isLoading ? 'Uploading PDF...' : 'Upload PDF' }
79+ </ span >
80+ </ button >
81+ ) : (
82+ < label
83+ className = { `cursor-pointer flex flex-col items-center gap-3 p-8 border-2 border-dashed rounded-none transition-colors ${ isLoading
84+ ? 'border-gray-200 bg-gray-50 cursor-wait'
85+ : 'border-gray-400 hover:border-blue-500 hover:bg-blue-50'
86+ } `}
87+ >
88+ < Upload className = { `w-12 h-12 ${ isLoading ? 'text-gray-300' : 'text-gray-400' } ` } />
89+ < span className = { `font-medium ${ isLoading ? 'text-gray-400' : 'text-gray-600' } ` } >
90+ { isLoading ? 'Uploading PDF...' : 'Upload PDF' }
91+ </ span >
92+ < input
93+ type = "file"
94+ accept = "application/pdf"
95+ onChange = { onUpload }
96+ className = "hidden"
97+ disabled = { isLoading }
98+ />
99+ </ label >
100+ ) }
58101
59102 { /* URL loading section */ }
60103 { ( allowRemote || allowLocal ) && (
@@ -98,3 +141,4 @@ const UploadZone = ({
98141} ;
99142
100143export default UploadZone ;
144+
0 commit comments