Skip to content

Commit cbf360b

Browse files
authored
Implement PDF thumbnail generation and caching
Added a function to generate PDF thumbnails and update the document with the cached thumbnail.
1 parent e0df60b commit cbf360b

1 file changed

Lines changed: 99 additions & 10 deletions

File tree

js/app.js

Lines changed: 99 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,22 @@ const exportBtn = document.getElementById('exportBtn');
7777
const importBtn = document.getElementById('importBtn');
7878
const 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+
8096
function 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
124213
function addMessage(content, sender) {

0 commit comments

Comments
 (0)