The v3.3.103 log (real 2464-job, 4-hoster batch ramping to 95 concurrent) confirmed the statSync fix held (batch-start main spike 336→231ms with 10× more jobs) and the whole 90s ramp to 95 active was pristine (event-loop mean ~11ms, fps=32, longtasks=0). The one residual: rapidly clicking tabs DURING the 95-active upload produced 210-221ms renderer long-tasks (proc=0ms → layout/paint, not JS). Cause: the Recent-uploads panel rendered every sessionFilesData row (up to 2000) into the DOM non-virtualized — the exact analog of the History table before it was virtualized in v3.3.102. Switching to that view laid out ~2000 rows (~210ms on the RDP VM). Fix — virtualize renderRecentUploadsPanel, mirroring the queue/History pattern: - The tbody gets only the visible rows plus top/bottom spacer <tr> sized from VIRTUAL_ROW_HEIGHT. A rAF-coalesced scroll handler and a ResizeObserver on .recent-files-table-wrap re-render the visible window (the ResizeObserver also serves as the show-trigger when the hidden panel gains size). _recentWorking holds the sorted set. The insertAdjacentHTML append-only fast path is dropped — a ~40-row window re-render is cheap, so every render just re-renders the window; on prepend (date desc) the scroll position is preserved (scrollTop=0 at top, else += added*ROW_HEIGHT). - Selection stays correct: _buildRecentRowHtml already stamps the selected class from selectedRecentIds.has(row.order) per row, so an off-screen-selected row renders selected when scrolled into view; selectedRecentIds remains the source of truth and shift-select already reads the sort cache, not the DOM. - styles.css gives .recent-file-row a fixed 28px height so the virtualization math is exact (the table already had table-layout:fixed, so no column-jump fix needed). - _renderRecentVirtualRows returns early when there are no rows, so it never wipes the empty-state message. Verified with Playwright at 2000 rows (bounded container): view-show layout drops from ~118ms to ~2.4ms, the DOM stays at 29-39 rows, scrolling maps to the correct rows, the scrollbar height is exact, an off-screen-selected row renders with the selected class, and the row height is exactly 28. Every large table (Queue, History, Recent) is now virtualized. 407 tests pass; clean Electron boot. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
57 lines
1.4 KiB
JSON
57 lines
1.4 KiB
JSON
{
|
|
"name": "multi-hoster-uploader",
|
|
"version": "3.3.104",
|
|
"description": "Upload files to doodstream, voe, vidmoly, byse simultaneously",
|
|
"main": "main.js",
|
|
"scripts": {
|
|
"start": "electron .",
|
|
"test": "node --test tests/*.test.js tests/ui-smoke.js",
|
|
"dist": "electron-builder --win",
|
|
"release:win": "electron-builder --publish never --win nsis portable",
|
|
"release:gitea": "node scripts/release_gitea.mjs"
|
|
},
|
|
"dependencies": {
|
|
"chokidar": "^3.6.0",
|
|
"undici": "^7.16.0",
|
|
"ws": "^8.19.0"
|
|
},
|
|
"devDependencies": {
|
|
"electron": "^41.3.0",
|
|
"electron-builder": "^26.8.1",
|
|
"eslint": "^10.1.0",
|
|
"eslint-plugin-security": "^4.0.0",
|
|
"rcedit": "^4.0.1"
|
|
},
|
|
"build": {
|
|
"appId": "com.multihoster.uploader",
|
|
"productName": "Multi-Hoster-Upload",
|
|
"directories": {
|
|
"buildResources": "assets",
|
|
"output": "release"
|
|
},
|
|
"files": [
|
|
"main.js",
|
|
"preload.js",
|
|
"lib/**/*",
|
|
"renderer/**/*",
|
|
"assets/app_icon.ico",
|
|
"assets/app_icon.png"
|
|
],
|
|
"win": {
|
|
"target": [
|
|
"nsis",
|
|
"portable"
|
|
],
|
|
"icon": "assets/app_icon.ico",
|
|
"signAndEditExecutable": false
|
|
},
|
|
"nsis": {
|
|
"oneClick": false,
|
|
"perMachine": false,
|
|
"allowToChangeInstallationDirectory": true,
|
|
"createDesktopShortcut": true
|
|
},
|
|
"afterPack": "scripts/afterPack.cjs"
|
|
}
|
|
}
|