@@ -77,6 +77,22 @@ const exportBtn = document.getElementById('exportBtn');
7777const importBtn = document . getElementById ( 'importBtn' ) ;
7878const importFile = document . getElementById ( 'importFile' ) ;
7979
80+ async function generatePdfThumbnail ( pdfDataURL ) {
81+ const pdf = await pdfjsLib . getDocument ( { url : pdfDataURL } ) . promise ;
82+ const page = await pdf . getPage ( 1 ) ;
83+
84+ const viewport = page . getViewport ( { scale : 1 } ) ;
85+ const canvas = document . createElement ( "canvas" ) ;
86+ const ctx = canvas . getContext ( "2d" ) ;
87+
88+ canvas . width = viewport . width ;
89+ canvas . height = viewport . height ;
90+
91+ await page . render ( { canvasContext : ctx , viewport } ) . promise ;
92+
93+ return canvas . toDataURL ( ) ;
94+ }
95+
8096function renderFile ( doc ) {
8197 if ( ! doc . file ) return ;
8298
@@ -90,7 +106,6 @@ function renderFile(doc) {
90106 img . style . display = "block" ;
91107 img . style . cursor = "pointer" ;
92108
93- // --- OPEN POPUP MODAL ---
94109 img . addEventListener ( "click" , ( ) => {
95110 imgModalContent . src = doc . file . data ;
96111 imgModal . style . display = "flex" ;
@@ -106,19 +121,93 @@ function renderFile(doc) {
106121 downloadLink . style . marginTop = "6px" ;
107122 downloadLink . style . color = "#8ab4ff" ;
108123 chatbox . appendChild ( downloadLink ) ;
124+ return ;
125+ }
109126
110- } else {
111- const link = document . createElement ( "a" ) ;
112- link . href = doc . file . data ;
113- link . download = doc . file . name ;
114- link . textContent = `Download ${ doc . file . name } ` ;
115- link . style . display = "inline-block" ;
116- link . style . marginTop = "6px" ;
117- link . style . color = "#8ab4ff" ;
118- chatbox . appendChild ( link ) ;
127+ // PDF
128+ if ( doc . file . type === "application/pdf" ) {
129+ const canvas = document . createElement ( "canvas" ) ;
130+ canvas . style . width = "180px" ;
131+ canvas . style . borderRadius = "10px" ;
132+ canvas . style . marginTop = "6px" ;
133+ canvas . style . cursor = "pointer" ;
134+ chatbox . appendChild ( canvas ) ;
135+
136+ // If thumbnail already cached use it
137+ if ( doc . pdfThumb ) {
138+ const img = new Image ( ) ;
139+ img . src = doc . pdfThumb ;
140+
141+ img . onload = ( ) => {
142+ const ctx = canvas . getContext ( "2d" ) ;
143+ canvas . width = img . width ;
144+ canvas . height = img . height ;
145+ ctx . drawImage ( img , 0 , 0 ) ;
146+ } ;
147+
148+ } else {
149+ // Generate thumbnail and cache it
150+ const loadingTask = pdfjsLib . getDocument ( {
151+ data : atob ( doc . file . data . split ( "," ) [ 1 ] )
152+ } ) ;
153+
154+ loadingTask . promise . then ( pdf => {
155+ pdf . getPage ( 1 ) . then ( page => {
156+ const viewport = page . getViewport ( { scale : 0.3 } ) ;
157+ const ctx = canvas . getContext ( "2d" ) ;
158+ canvas . height = viewport . height ;
159+ canvas . width = viewport . width ;
160+
161+ page . render ( { canvasContext : ctx , viewport : viewport } ) . promise . then ( ( ) => {
162+ // SAVE THUMBNAIL
163+ const thumbData = canvas . toDataURL ( "image/png" ) ;
164+ doc . pdfThumb = thumbData ; // cached
165+ updateDocument ( doc . id , { pdfThumb : thumbData } ) ; // DB update
166+ } ) ;
167+ } ) ;
168+ } ) ;
169+ }
170+
171+ // Download Link
172+ const downloadLink = document . createElement ( "a" ) ;
173+ downloadLink . href = doc . file . data ;
174+ downloadLink . download = doc . file . name ;
175+ downloadLink . textContent = `Download ${ doc . file . name } ` ;
176+ downloadLink . style . display = "inline-block" ;
177+ downloadLink . style . marginTop = "6px" ;
178+ downloadLink . style . color = "#8ab4ff" ;
179+ chatbox . appendChild ( downloadLink ) ;
180+
181+ return ;
119182 }
183+
184+ const link = document . createElement ( "a" ) ;
185+ link . href = doc . file . data ;
186+ link . download = doc . file . name ;
187+ link . textContent = `Download ${ doc . file . name } ` ;
188+ link . style . display = "inline-block" ;
189+ link . style . marginTop = "6px" ;
190+ link . style . color = "#8ab4ff" ;
191+ chatbox . appendChild ( link ) ;
120192}
121193
194+ function updateDocument ( id , updates ) {
195+ const request = indexedDB . open ( DB_NAME , DB_VERSION ) ;
196+
197+ request . onsuccess = ( ) => {
198+ const db = request . result ;
199+ const tx = db . transaction ( STORE_NAME , "readwrite" ) ;
200+ const store = tx . objectStore ( STORE_NAME ) ;
201+
202+ const getReq = store . get ( id ) ;
203+
204+ getReq . onsuccess = ( ) => {
205+ const doc = getReq . result ;
206+ Object . assign ( doc , updates ) ;
207+ store . put ( doc ) ;
208+ } ;
209+ } ;
210+ }
122211
123212// Helper Functions
124213function addMessage ( content , sender ) {
0 commit comments