MCPcopy Create free account
hub / github.com/TechJeeper/Printventory / handleFileClick

Function handleFileClick

renderer.js:13336–13456  ·  view source on GitHub ↗
(event, filePath)

Source from the content-addressed store, hash-verified

13334 thumbnail = await generateThumbnail(model.filePath);
13335 } catch (renderError) {
13336 console.error(`Error generating 3D thumbnail for ${model.filePath}:`, renderError);
13337 }
13338 }
13339
13340 // 3. Validate and fallback to default if necessary (STL/3MF only reach here)
13341 if (!thumbnail || typeof thumbnail !== 'string' || !thumbnail.startsWith('data:image') || isFailurePlaceholderThumbnail(thumbnail)) {
13342 thumbnail = '3d.png';
13343 }
13344
13345 // 4. Save real renders only — never lock in failure placeholders
13346 if (!saved3mfEmbedsViaBatch && thumbnail !== '3d.png') {
13347 await window.electron.saveThumbnail(model.filePath, thumbnail);
13348 } else if (!saved3mfEmbedsViaBatch) {
13349 await window.electron.saveThumbnail(model.filePath, '3d.png');
13350 }
13351
13352 // 5. Hash during bulk jobs is optional (extra I/O / memory); skip in Docker headless.
13353 if (!skipHash && (!model.hash || model.hash === '')) {
13354 try {
13355 await window.electron.calculateFileHash(model.filePath);
13356 } catch (hashError) {
13357 console.error(`Error calculating hash for ${model.filePath}:`, hashError);
13358 // Continue even if hash calculation fails
13359 }
13360 }
13361
13362 thumbnail = null;
13363
13364 } catch (error) {
13365 console.error(`Failed to generate thumbnail for ${model.filePath}:`, error);
13366 // Do not persist typed STL/3MF placeholders — that blocks retries (common on Docker timeouts).
13367 try {
13368 await window.electron.saveThumbnail(model.filePath, '3d.png');
13369 } catch (saveError) {
13370 console.error(`Failed to save default thumbnail for ${model.filePath}:`, saveError);
13371 }
13372 } finally {
13373 processedInBatch++;
13374 processedCount = processedInBatch;
13375 const absoluteProcessed = progressOffset + processedInBatch;
13376 generatedThumbnailsCount = absoluteProcessed;
13377
13378 // Update progress
13379 if (hasProgressUI) {
13380 const progress = Math.floor((absoluteProcessed / progressTotal) * 100);
13381 activeProgressBar.style.width = `${progress}%`;
13382 activeProgressText.textContent = `Processing ${absoluteProcessed}/${progressTotal} (${progress}%)`;
13383 }
13384 if (overlay && !isCancelled) {
13385 overlay.update(absoluteProcessed, progressTotal);
13386 }
13387 if (!isCancelled) {
13388 await reportHeadlessProgress(absoluteProcessed, progressTotal);
13389 }
13390
13391 // Between models: yield + occasional soft GC. Soft dispose only —
13392 // never forceContextLoss (restarts GPU process → Skia OOM log storms).
13393 if (maxConcurrentThumbnails === 1) {

Callers 2

createModelItemFunction · 0.85

Calls 13

populateTagSelectFunction · 0.85
addToSelectedModelsFunction · 0.85
isInSelectedModelsFunction · 0.85
removeFromSelectedModelsFunction · 0.85
updateSelectedCountFunction · 0.85
showMultiEditPanelFunction · 0.85
exitMultiEditModeFunction · 0.85

Tested by

no test coverage detected