()
| 701 | /** |
| 702 | * Fixed preview columns per size; tile dimension scales to fill row width. |
| 703 | * S → 10 columns; M → 6 columns; L → 4 columns. |
| 704 | */ |
| 705 | function computePreviewTilePxFromWidth(availableWidth, horizontalGap = 2) { |
| 706 | const g = horizontalGap; |
| 707 | const aw = Math.max(0, availableWidth); |
| 708 | const cols = PREVIEW_COLUMNS[currentPreviewTileSize] || PREVIEW_COLUMNS.m; |
| 709 | if (cols <= 0) return PREVIEW_TILE_PX.m; |
| 710 | |
| 711 | // Use fixed column count and scale tile so the row fills available width. |
| 712 | const computed = Math.floor((aw - (cols - 1) * g) / cols); |
| 713 | return Math.max(1, computed); |
| 714 | } |
| 715 | |
| 716 | function getPreviewTileSizePx() { |
| 717 | const grid = document.querySelector('.file-grid'); |
| 718 | if ( |
| 719 | currentGridView === 'preview' && |
| 720 | grid && |
| 721 | typeof grid._previewTilePx === 'number' && |
| 722 | grid._previewTilePx > 0 |
| 723 | ) { |
| 724 | return grid._previewTilePx; |
| 725 | } |
| 726 | return PREVIEW_TILE_PX[currentPreviewTileSize] || PREVIEW_TILE_PX.m; |
| 727 | } |
| 728 | |
| 729 | function getPreviewTileDims() { |
| 730 | const tile = getPreviewTileSizePx(); |
| 731 | return { width: tile, height: tile, itemWidth: tile }; |
| 732 | } |
| 733 | |
| 734 | // Per-folder view preference (when "View Entire Library" is off): remember list/preview/detailed per scanned root |
| 735 | async function getPerFolderViewPrefs() { |
| 736 | try { |
| 737 | const raw = await window.electron.getSetting('perFolderView'); |
| 738 | if (!raw) return {}; |
| 739 | const parsed = JSON.parse(raw); |
| 740 | return typeof parsed === 'object' && parsed !== null ? parsed : {}; |
| 741 | } catch (_) { |
| 742 | return {}; |
| 743 | } |
| 744 | } |
| 745 | |
| 746 | async function getViewForFolder(folderPath) { |
| 747 | if (!folderPath) return null; |
| 748 | const prefs = await getPerFolderViewPrefs(); |
| 749 | if (prefs[folderPath] && ['list', 'preview', 'detailed'].includes(prefs[folderPath])) { |
| 750 | return prefs[folderPath]; |
| 751 | } |
| 752 | const lastUsed = await window.electron.getSetting('lastUsedView'); |
| 753 | if (lastUsed && ['list', 'preview', 'detailed'].includes(lastUsed)) return lastUsed; |
| 754 | const globalView = await window.electron.getSetting('gridView'); |
| 755 | if (globalView && ['list', 'preview', 'detailed'].includes(globalView)) return globalView === 'small' ? 'preview' : globalView; |
| 756 | return 'detailed'; |
| 757 | } |
| 758 | |
| 759 | async function savePerFolderView(folderPath, view) { |
| 760 | if (!folderPath || !['list', 'preview', 'detailed'].includes(view)) return; |
nothing calls this directly
no test coverage detected