diff --git a/package.json b/package.json index a8bba1f..c656032 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,6 @@ "packageQuick": "pnpm run build && electron-builder --dir", "lint": "biome check", "lint:fix": "biome check --write", - "test": "node --experimental-strip-types --import ./tests/register-ts.mjs --test tests/screenshare-previews.test.ts", "postinstall": "electron-builder install-app-deps", "CIbuild": "pnpm run build && electron-builder --linux zip && electron-builder --windows zip && electron-builder --macos zip", "updateMeta": "node --experimental-strip-types scripts/utils/updateMeta.ts" @@ -45,11 +44,11 @@ "@xmldom/xmldom": "^0.9.10", "app-builder-lib": "^26.15.3", "babel-preset-solid": "^1.9.12", - "electron": "44.2.0", + "electron": "43.2.0", "electron-builder": "26.15.7", "lucide-solid": "^1.26.0", "monaco-editor": "0.56.0", - "rolldown": "1.2.7", + "rolldown": "1.2.0", "rollup-plugin-copy": "^3.5.0", "solid-js": "^1.9.14", "solid-motionone": "^1.0.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 11ef084..b6830c8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -47,7 +47,7 @@ importers: version: 2.5.5 '@rolldown-plugin/solid': specifier: ^0.1.0 - version: 0.1.0(csstype@3.2.3)(rolldown@1.2.7)(seroval@1.5.6)(solid-js@1.9.14) + version: 0.1.0(csstype@3.2.3)(rolldown@1.2.0)(seroval@1.5.6)(solid-js@1.9.14) '@rollup/plugin-esm-shim': specifier: ^0.1.8 version: 0.1.8 @@ -79,8 +79,8 @@ importers: specifier: ^1.9.12 version: 1.9.12(@babel/core@8.0.1)(solid-js@1.9.14) electron: - specifier: 44.2.0 - version: 44.2.0 + specifier: 43.2.0 + version: 43.2.0 electron-builder: specifier: 26.15.7 version: 26.15.7(electron-builder-squirrel-windows@26.15.3) @@ -91,8 +91,8 @@ importers: specifier: 0.56.0 version: 0.56.0 rolldown: - specifier: 1.2.7 - version: 1.2.7 + specifier: 1.2.0 + version: 1.2.0 rollup-plugin-copy: specifier: ^3.5.0 version: 3.5.0 @@ -613,6 +613,12 @@ packages: '@napi-rs/wasm-runtime@0.2.12': resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} + '@napi-rs/wasm-runtime@1.1.6': + resolution: {integrity: sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==} + peerDependencies: + '@emnapi/core': ^1.7.1 + '@emnapi/runtime': ^1.7.1 + '@noble/hashes@1.4.0': resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} engines: {node: '>= 16'} @@ -636,8 +642,8 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@oxc-project/types@0.148.0': - resolution: {integrity: sha512-Nm4s/jB+4FpFsPhWGEC4h7rzksesmtnMXomo6rCMcg/b8zLQuOziRgkCS1fxDCXOlJB/6Q8oABOZ/OP6RIPj9A==} + '@oxc-project/types@0.140.0': + resolution: {integrity: sha512-h5LUOzGArYemnW1NMz/DuuQhBi96J6JL2Bk8zE4kvqxB5Sg3jxmCiH4uyOWHDkiKSt5vWlG4FIwCR/DbstcNRQ==} '@parcel/watcher-android-arm64@2.6.0': resolution: {integrity: sha512-trgpLSCKRC/huFjXX/Smh+0sWe4+YtKfktIToiMl59ghz7z+qkH6kMvNnUbLyRs9N11t8l4svSCs1+5B3rOAhA==} @@ -744,14 +750,8 @@ packages: seroval: ~1.5.0 solid-js: '>=1.9.13' - '@rolldown/binding-android-arm-eabi@1.2.7': - resolution: {integrity: sha512-EypzgnYCwyVY4NDHKzGmNJT5b+XaQEBniHxsMdeIQLB/tcCzZnhqrzHpZFbX9iaxx+5RiB8caATBtfvZP7zVxQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [android] - - '@rolldown/binding-android-arm64@1.2.7': - resolution: {integrity: sha512-l17HE9EweWaqJZhuUuNBN/FzM62xw+DECVnJyvMsxn8vJFAGLy5QfLDoYAcronkAN8VxKZHezDpulHDPx95vFw==} + '@rolldown/binding-android-arm64@1.2.0': + resolution: {integrity: sha512-9yB1l95IrJuNGDFdOYe79vdApdz6WWBCObE+rQ2LUliYUlcyFwSYIb2xb5/Ifw7dAtMy2ZqNyd8QTSOc7duAKw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] @@ -761,8 +761,8 @@ packages: cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-arm64@1.2.7': - resolution: {integrity: sha512-8ED8ELFvHXc6OCETIn4gXObPiaR6bckM/ipXtbzlPVDRMBfEGjCKgO90F9YtfdpDatVx/ZQw7aZ1vUMf/+T3Mw==} + '@rolldown/binding-darwin-arm64@1.2.0': + resolution: {integrity: sha512-pexNaW9ACLUOaBITOpU6qVu4VrsOFIjTv6bzgu0YUATo4eUJx0V605PxwZfndpPOn0ilqGqvGQ0M8UW0IE24jg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] @@ -772,8 +772,8 @@ packages: cpu: [x64] os: [darwin] - '@rolldown/binding-darwin-x64@1.2.7': - resolution: {integrity: sha512-/WPripjtiAIZ2tWY7ddijORT0Ujg87wxWW/qcoFVCKAWVDPhtY0xr7Dj0M3GyNGz60jGwTElhro/mkF9dT7dDQ==} + '@rolldown/binding-darwin-x64@1.2.0': + resolution: {integrity: sha512-NqKYaq0355ZmNMG4QGpxtEDxsc7tGDhjhCm4PpE0cwnBW+5Il95LJyq414niEiaKLVjnVHBEjSo1wngKxJNiFw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] @@ -783,8 +783,8 @@ packages: cpu: [x64] os: [freebsd] - '@rolldown/binding-freebsd-x64@1.2.7': - resolution: {integrity: sha512-14DI4NcqpvbICxSnGLx3PmtDaWqRP/KGSGb6C+JLLVPeZRl6dKdHba3pGsqT3vpdTqhEYIPG0MMQ8c0xYqoJxA==} + '@rolldown/binding-freebsd-x64@1.2.0': + resolution: {integrity: sha512-3vPoHzh6eBTz9IbB0/qZdSr0Qeks2echn+I4cHu2joV74VriPDdldswksEDzrl1mBB+oPRi+67+3Ib59paxIPQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] @@ -794,8 +794,8 @@ packages: cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm-gnueabihf@1.2.7': - resolution: {integrity: sha512-bxrWIRvHWQvbJwi+VIie/kDJmQxcNE6xxWwZdqF/ExVAigtHkv54WTLQPb+QsZdnFy18fg7JPfWGL0RH6vwIlQ==} + '@rolldown/binding-linux-arm-gnueabihf@1.2.0': + resolution: {integrity: sha512-E6NNefZ1bUVmKJq2tJkf45J4Zyczj7qm9rUT7NY+Xo2474Y13qWAwc2tvBt0BAVbmtXR1llkxXg0Ou1jbDf2SQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] @@ -806,8 +806,8 @@ packages: os: [linux] libc: [glibc] - '@rolldown/binding-linux-arm64-gnu@1.2.7': - resolution: {integrity: sha512-toOY2BChBZyuxU7OYX6Tn389di4IzAqPTycVcci0O7FSfBqzRB3RZn+K5Is6ANf4tmgRd/K1yZTsNTXbkXsnLg==} + '@rolldown/binding-linux-arm64-gnu@1.2.0': + resolution: {integrity: sha512-D+TgkdgM1vu+7/Fpf8+v0ARW+RXEP9Ccazgm8zQ4JFFd9Q7SrYQ2TakU5S5ihazQDgpKyAgZDOcIFsvoHmTZ8w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] @@ -819,22 +819,22 @@ packages: os: [linux] libc: [musl] - '@rolldown/binding-linux-arm64-musl@1.2.7': - resolution: {integrity: sha512-lAIXTH/aiLRLxsTgQvfhjo4K1ydWIp00+V0voOr9beb/9ZmkUFrSIb03dXNFRgMNvkE6oGsF10ioQ6UsI+vS5Q==} + '@rolldown/binding-linux-arm64-musl@1.2.0': + resolution: {integrity: sha512-wUqdwJBbAv0APN87GecstdMUtLjjNTs0hBALpxETD73mccFxdmt/XeizXDtN5RAlBwNKmI+Tg+blect2G+8IeQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@rolldown/binding-linux-ppc64-gnu@1.2.7': - resolution: {integrity: sha512-kdnwS28Pkenp/mZMRwjXXXwxQ7pIsm+bF919LUK93BOyhcLsrVKdP2p9fxpiPNPAbNuch8ypQt0pm2P2LYCAGg==} + '@rolldown/binding-linux-ppc64-gnu@1.2.0': + resolution: {integrity: sha512-9DtF35qR9/NrfhM4oxLplCzVVjE+KKm8Pjemi0i/sdhAWkUasjmSo8WTTubNJClhSHCfyk2yeyoXDQEDPtDAAw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.2.7': - resolution: {integrity: sha512-516OdsyLdr5E65paF3yBF55t8mfm9+gmtCsK3xI7XKXIT7EfRlHhxL8K/NR6Hu8BWSgF5+1w74lTL0+nxcc8Qw==} + '@rolldown/binding-linux-s390x-gnu@1.2.0': + resolution: {integrity: sha512-RzuHrBh8X8Hntd2N4VR02QGEciq/9JhcZoTpR/Cee6otRrlILGCf3cg2ygHuih+ZebUnWmMrDX6ITI85btO6rQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] @@ -846,8 +846,8 @@ packages: os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.2.7': - resolution: {integrity: sha512-r8/z8n7GFaYRln3xmP1Cxy0HH/HLM0uBUPkEuSVEfKGDA89M0FsZRZJRSwe/tJjRx+fpH/gjorfhB8tmEbSFLA==} + '@rolldown/binding-linux-x64-gnu@1.2.0': + resolution: {integrity: sha512-MK7L0018jjh1jR3mh21G2j1zAVcpscJBlPo2z19pRjv2XOYGRhaV4LyiD8HO6nCDdZln9IFgCMIV5yt4E3klGQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] @@ -859,15 +859,15 @@ packages: os: [linux] libc: [musl] - '@rolldown/binding-linux-x64-musl@1.2.7': - resolution: {integrity: sha512-pAsE8iiDxUg1xBqdhrTfg45AVDVpirjz00sblEYClGNNcMnDb+e8beQgqIAw6LvauX/APvgxUnwrgun/YYGBhw==} + '@rolldown/binding-linux-x64-musl@1.2.0': + resolution: {integrity: sha512-gyrxLQ9NfGb/9LoVnC4kb9miUghw1mghnkfYvNHSnVIXriabnfgGPUP4RLcJm87q3KgYz4FYUG8IDiWUT+CpSw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@rolldown/binding-openharmony-arm64@1.2.7': - resolution: {integrity: sha512-lTcIYmmnQQA8Or/2DatS6oSqcdLHvendjS+zLu+FwgToynWMRSmQdpM65fTANJgIS4mjbMOo5KT2lnT9SAb96w==} + '@rolldown/binding-openharmony-arm64@1.2.0': + resolution: {integrity: sha512-/6VFMQGRmrhP77KXDC+StIxGzcNp5JOIyYtw0CQ8gPlzhpiIRucYfoM5FaFamHd5BJYIdH86yfP46l1p3WdrFA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] @@ -877,13 +877,18 @@ packages: engines: {node: '>=14.21.3'} cpu: [wasm32] + '@rolldown/binding-wasm32-wasi@1.2.0': + resolution: {integrity: sha512-rwdbUL465kisF24WEJLvP3JrEG6E5GRuIHt5wpMwHGERtHe4Wm2CIvtf5gTBgr2tGOHKh5NdKEAFS2VkOPE91g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.1': resolution: {integrity: sha512-NSccQD7+9vhEfDMc8HyODuUU1jLYEsEiICc1zwmbeg0FXx1pwpFpZZQby4bAMnK2obav7D9FfsruYWodhNdIqQ==} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-arm64-msvc@1.2.7': - resolution: {integrity: sha512-e3Gu3WxbNk/UqQhxqU7YIYO+9ZBvWNz3U+h/qRFosscMFzdRPbXYSaSWgSnklv2fz1TgzBTcti2z35c/7irsHw==} + '@rolldown/binding-win32-arm64-msvc@1.2.0': + resolution: {integrity: sha512-+5suHwRiKGmhwyUaNT8a5QbrBvLFh2DbO910TEmGRH1aSxwrCezodvGQnulv4uiWEIv1Kq4ypRsJ5+O+ry1DiA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] @@ -898,8 +903,8 @@ packages: cpu: [x64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.2.7': - resolution: {integrity: sha512-W/jg5qoRSqjsEv0+dZi4e687mcHqmVuU0P4fK6qS/xjetW2Gmc1W8j//z5nAeNcC8Ttm0hV46IjcYeuVwYhuiw==} + '@rolldown/binding-win32-x64-msvc@1.2.0': + resolution: {integrity: sha512-WfFv6/qGufotqBSBzBYwgpCkJBk8Nj7697LL9vTz/XWc67e0r3oewu8iMRwQj3AUL45GVD7wVsPjCsAAtW66Wg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -1139,12 +1144,10 @@ packages: '@xmldom/xmldom@0.8.13': resolution: {integrity: sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw==} engines: {node: '>=10.0.0'} - deprecated: this version has critical issues, please update to the latest version '@xmldom/xmldom@0.9.10': resolution: {integrity: sha512-A9gOqLdi6cV4ibazAjcQufGj0B1y/vDqYrcuP6d/6x8P27gRS8643Dj9o1dEKtB6O7fwxb2FgBmJS2mX7gpvdw==} engines: {node: '>=14.6'} - deprecated: this version has critical issues, please update to the latest version abbrev@4.0.0: resolution: {integrity: sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==} @@ -1275,6 +1278,11 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + baseline-browser-mapping@2.10.32: + resolution: {integrity: sha512-wbPvpyjJPC0zdfdKXxqEL3Ea+bOMD/87X4lftiJkkaBiuG6ALQy1SLmEd7BSmVCuwCQsBrCamgBoLyfFDD1EPg==} + engines: {node: '>=6.0.0'} + hasBin: true + baseline-browser-mapping@2.11.1: resolution: {integrity: sha512-HYXq73DDpCtNzOmrFsm9eSwCvWCql0RzqjpDzXN9EadiLJ4DNat0nsZ/Bzmy+Ud12mb4/zKDY0cQ805ZzN+i0A==} engines: {node: '>=6.0.0'} @@ -1305,6 +1313,11 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} + browserslist@4.28.2: + resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + browserslist@4.28.7: resolution: {integrity: sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -1337,6 +1350,9 @@ packages: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} + caniuse-lite@1.0.30001793: + resolution: {integrity: sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==} + caniuse-lite@1.0.30001806: resolution: {integrity: sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==} @@ -1547,6 +1563,9 @@ packages: electron-publish@26.15.3: resolution: {integrity: sha512-g/2bn8YTavY4cuS5F+jOS7zmZbXXBV8KZ8yHKfJjFPoKtzBqrpCdNPxBd3tqdBwP7BVd0lGzf7Bk2s0KesWZ4Q==} + electron-to-chromium@1.5.363: + resolution: {integrity: sha512-VjUKPyWzGnT1fujlkEGC/BvN70Hh70KXtAqcmniXviYlJC/ivcT+BWGPyxWVbJZLfvtKR6dqg1L7T7pgAMBtWA==} + electron-to-chromium@1.5.395: resolution: {integrity: sha512-7zt9Aw+SrmxLWLN0zhaTWZQiCdryLVrYTq5R7iZakLvi2UQPYMMsROYV/2qVCzMeCiSXHwKOU+sZ4zOVVlrtKA==} @@ -1557,8 +1576,8 @@ packages: resolution: {integrity: sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg==} engines: {node: '>=8.0.0'} - electron@44.2.0: - resolution: {integrity: sha512-oK1icjhapp3xsUZycO9WZaLmd3hJnA7ieobC4mpdtO1pEN+PPGWpA3m1Mgzzuc1wzSD2Wai4zcH4yfpGJqxFMA==} + electron@43.2.0: + resolution: {integrity: sha512-80zvrgG7ZRXD+tD0IyLvrnN9n+veSxadMRsMaC9wKKP3iUbtC7rGM8+dVuCmOb0Rrwwv8ESW4awnUZh9Hbp1fA==} engines: {node: '>= 22.12.0'} hasBin: true @@ -1951,6 +1970,10 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + js-yaml@4.3.0: resolution: {integrity: sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==} hasBin: true @@ -2229,6 +2252,10 @@ packages: node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + node-releases@2.0.46: + resolution: {integrity: sha512-GYVXHE2KnrzAfsAjl4uP++evGFCrAU1jta4ubEjIG7YWt/64Gqv66a30yKwWczVjA6j3bM4nBwH7Pk1JmDHaxQ==} + engines: {node: '>=18'} + node-releases@2.0.51: resolution: {integrity: sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==} engines: {node: '>=18'} @@ -2456,8 +2483,8 @@ packages: '@babel/runtime': optional: true - rolldown@1.2.7: - resolution: {integrity: sha512-g0EtLvBjTUB7jhyV0S/TCup3v/XSVl45vUIGbOGU4QPiyjTenCe4mKuFvW9fEgYmS2Fo42AUssRmNuMziXdrig==} + rolldown@1.2.0: + resolution: {integrity: sha512-u7tgm5l4Yw1iTqUL4EcYOAt7fFvCgQMLeidrnD4GALlC6aOznCjezYajgxeyKw27u0Q5N7fwgCzjVyPIWzwuBA==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -2502,6 +2529,11 @@ packages: engines: {node: '>=10'} hasBin: true + semver@7.8.1: + resolution: {integrity: sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==} + engines: {node: '>=10'} + hasBin: true + semver@7.8.5: resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} engines: {node: '>=10'} @@ -2881,7 +2913,7 @@ snapshots: import-meta-resolve: 4.2.0 json5: 2.2.3 obug: 2.1.1 - semver: 7.8.5 + semver: 7.8.1 '@babel/generator@7.29.7': dependencies: @@ -2916,9 +2948,9 @@ snapshots: dependencies: '@babel/compat-data': 8.0.0 '@babel/helper-validator-option': 8.0.0 - browserslist: 4.28.7 + browserslist: 4.28.2 lru-cache: 11.5.2 - semver: 7.8.5 + semver: 7.8.1 '@babel/helper-create-class-features-plugin@7.29.7(@babel/core@7.29.7)': dependencies: @@ -3408,6 +3440,13 @@ snapshots: '@tybys/wasm-util': 0.10.3 optional: true + '@napi-rs/wasm-runtime@1.1.6(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2)': + dependencies: + '@emnapi/core': 1.11.2 + '@emnapi/runtime': 1.11.2 + '@tybys/wasm-util': 0.10.3 + optional: true + '@noble/hashes@1.4.0': {} '@noble/hashes@2.2.0': {} @@ -3426,7 +3465,7 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 - '@oxc-project/types@0.148.0': {} + '@oxc-project/types@0.140.0': {} '@parcel/watcher-android-arm64@2.6.0': optional: true @@ -3507,7 +3546,7 @@ snapshots: tslib: 2.8.1 webcrypto-core: 1.9.2 - '@rolldown-plugin/solid@0.1.0(csstype@3.2.3)(rolldown@1.2.7)(seroval@1.5.6)(solid-js@1.9.14)': + '@rolldown-plugin/solid@0.1.0(csstype@3.2.3)(rolldown@1.2.0)(seroval@1.5.6)(solid-js@1.9.14)': dependencies: '@babel/core': 8.0.1 '@babel/helper-module-imports': 8.0.0 @@ -3519,71 +3558,68 @@ snapshots: csstype: 3.2.3 html-entities: 2.6.0 parse5: 8.0.1 - rolldown: 1.2.7 + rolldown: 1.2.0 seroval: 1.5.6 solid-js: 1.9.14 - '@rolldown/binding-android-arm-eabi@1.2.7': - optional: true - - '@rolldown/binding-android-arm64@1.2.7': + '@rolldown/binding-android-arm64@1.2.0': optional: true '@rolldown/binding-darwin-arm64@1.0.0-beta.1': optional: true - '@rolldown/binding-darwin-arm64@1.2.7': + '@rolldown/binding-darwin-arm64@1.2.0': optional: true '@rolldown/binding-darwin-x64@1.0.0-beta.1': optional: true - '@rolldown/binding-darwin-x64@1.2.7': + '@rolldown/binding-darwin-x64@1.2.0': optional: true '@rolldown/binding-freebsd-x64@1.0.0-beta.1': optional: true - '@rolldown/binding-freebsd-x64@1.2.7': + '@rolldown/binding-freebsd-x64@1.2.0': optional: true '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.1': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.2.7': + '@rolldown/binding-linux-arm-gnueabihf@1.2.0': optional: true '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.1': optional: true - '@rolldown/binding-linux-arm64-gnu@1.2.7': + '@rolldown/binding-linux-arm64-gnu@1.2.0': optional: true '@rolldown/binding-linux-arm64-musl@1.0.0-beta.1': optional: true - '@rolldown/binding-linux-arm64-musl@1.2.7': + '@rolldown/binding-linux-arm64-musl@1.2.0': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.2.7': + '@rolldown/binding-linux-ppc64-gnu@1.2.0': optional: true - '@rolldown/binding-linux-s390x-gnu@1.2.7': + '@rolldown/binding-linux-s390x-gnu@1.2.0': optional: true '@rolldown/binding-linux-x64-gnu@1.0.0-beta.1': optional: true - '@rolldown/binding-linux-x64-gnu@1.2.7': + '@rolldown/binding-linux-x64-gnu@1.2.0': optional: true '@rolldown/binding-linux-x64-musl@1.0.0-beta.1': optional: true - '@rolldown/binding-linux-x64-musl@1.2.7': + '@rolldown/binding-linux-x64-musl@1.2.0': optional: true - '@rolldown/binding-openharmony-arm64@1.2.7': + '@rolldown/binding-openharmony-arm64@1.2.0': optional: true '@rolldown/binding-wasm32-wasi@1.0.0-beta.1': @@ -3591,10 +3627,17 @@ snapshots: '@napi-rs/wasm-runtime': 0.2.12 optional: true + '@rolldown/binding-wasm32-wasi@1.2.0': + dependencies: + '@emnapi/core': 1.11.2 + '@emnapi/runtime': 1.11.2 + '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2) + optional: true + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.1': optional: true - '@rolldown/binding-win32-arm64-msvc@1.2.7': + '@rolldown/binding-win32-arm64-msvc@1.2.0': optional: true '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.1': @@ -3603,7 +3646,7 @@ snapshots: '@rolldown/binding-win32-x64-msvc@1.0.0-beta.1': optional: true - '@rolldown/binding-win32-x64-msvc@1.2.7': + '@rolldown/binding-win32-x64-msvc@1.2.0': optional: true '@rolldown/pluginutils@1.0.1': {} @@ -4012,6 +4055,8 @@ snapshots: base64-js@1.5.1: {} + baseline-browser-mapping@2.10.32: {} + baseline-browser-mapping@2.11.1: {} binary-extensions@2.3.0: {} @@ -4038,6 +4083,14 @@ snapshots: dependencies: fill-range: 7.1.1 + browserslist@4.28.2: + dependencies: + baseline-browser-mapping: 2.10.32 + caniuse-lite: 1.0.30001793 + electron-to-chromium: 1.5.363 + node-releases: 2.0.46 + update-browserslist-db: 1.2.3(browserslist@4.28.2) + browserslist@4.28.7: dependencies: baseline-browser-mapping: 2.11.1 @@ -4093,6 +4146,8 @@ snapshots: es-errors: 1.3.0 function-bind: 1.1.2 + caniuse-lite@1.0.30001793: {} + caniuse-lite@1.0.30001806: {} chalk@4.1.2: @@ -4257,7 +4312,7 @@ snapshots: app-builder-lib: 26.15.3(dmg-builder@26.15.3)(electron-builder-squirrel-windows@26.15.3) builder-util: 26.15.3 fs-extra: 10.1.0 - js-yaml: 4.3.0 + js-yaml: 4.1.1 transitivePeerDependencies: - electron-builder-squirrel-windows - supports-color @@ -4349,6 +4404,8 @@ snapshots: transitivePeerDependencies: - supports-color + electron-to-chromium@1.5.363: {} + electron-to-chromium@1.5.395: {} electron-updater@6.8.9: @@ -4376,7 +4433,7 @@ snapshots: transitivePeerDependencies: - supports-color - electron@44.2.0: + electron@43.2.0: dependencies: '@electron-internal/extract-zip': 1.0.4 '@electron/get': 5.0.0 @@ -4805,6 +4862,10 @@ snapshots: js-tokens@4.0.0: {} + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + js-yaml@4.3.0: dependencies: argparse: 2.0.1 @@ -5041,6 +5102,8 @@ snapshots: node-int64@0.4.0: {} + node-releases@2.0.46: {} + node-releases@2.0.51: {} nopt@9.0.0: @@ -5273,26 +5336,26 @@ snapshots: '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.1 '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.1 - rolldown@1.2.7: + rolldown@1.2.0: dependencies: - '@oxc-project/types': 0.148.0 + '@oxc-project/types': 0.140.0 '@rolldown/pluginutils': 1.0.1 optionalDependencies: - '@rolldown/binding-android-arm-eabi': 1.2.7 - '@rolldown/binding-android-arm64': 1.2.7 - '@rolldown/binding-darwin-arm64': 1.2.7 - '@rolldown/binding-darwin-x64': 1.2.7 - '@rolldown/binding-freebsd-x64': 1.2.7 - '@rolldown/binding-linux-arm-gnueabihf': 1.2.7 - '@rolldown/binding-linux-arm64-gnu': 1.2.7 - '@rolldown/binding-linux-arm64-musl': 1.2.7 - '@rolldown/binding-linux-ppc64-gnu': 1.2.7 - '@rolldown/binding-linux-s390x-gnu': 1.2.7 - '@rolldown/binding-linux-x64-gnu': 1.2.7 - '@rolldown/binding-linux-x64-musl': 1.2.7 - '@rolldown/binding-openharmony-arm64': 1.2.7 - '@rolldown/binding-win32-arm64-msvc': 1.2.7 - '@rolldown/binding-win32-x64-msvc': 1.2.7 + '@rolldown/binding-android-arm64': 1.2.0 + '@rolldown/binding-darwin-arm64': 1.2.0 + '@rolldown/binding-darwin-x64': 1.2.0 + '@rolldown/binding-freebsd-x64': 1.2.0 + '@rolldown/binding-linux-arm-gnueabihf': 1.2.0 + '@rolldown/binding-linux-arm64-gnu': 1.2.0 + '@rolldown/binding-linux-arm64-musl': 1.2.0 + '@rolldown/binding-linux-ppc64-gnu': 1.2.0 + '@rolldown/binding-linux-s390x-gnu': 1.2.0 + '@rolldown/binding-linux-x64-gnu': 1.2.0 + '@rolldown/binding-linux-x64-musl': 1.2.0 + '@rolldown/binding-openharmony-arm64': 1.2.0 + '@rolldown/binding-wasm32-wasi': 1.2.0 + '@rolldown/binding-win32-arm64-msvc': 1.2.0 + '@rolldown/binding-win32-x64-msvc': 1.2.0 rollup-plugin-copy@3.5.0: dependencies: @@ -5334,6 +5397,8 @@ snapshots: semver@7.7.4: {} + semver@7.8.1: {} + semver@7.8.5: {} serialize-error@7.0.1: @@ -5577,6 +5642,12 @@ snapshots: graceful-fs: 4.2.11 node-int64: 0.4.0 + update-browserslist-db@1.2.3(browserslist@4.28.2): + dependencies: + browserslist: 4.28.2 + escalade: 3.2.0 + picocolors: 1.1.1 + update-browserslist-db@1.2.3(browserslist@4.28.7): dependencies: browserslist: 4.28.7 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 508c2cf..8a1bd03 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -6,7 +6,7 @@ allowBuilds: koffi: true minimumReleaseAgeExclude: - - electron@42.3.3 || 43.2.0 || 44.2.0 + - electron@42.3.3 || 43.2.0 overrides: yauzl: "^3.3.1" # Electron still can't get their shit together https://github.com/electron/electron/issues/51619 diff --git a/src/common/config.ts b/src/common/config.ts index 5bac3cc..c54def6 100644 --- a/src/common/config.ts +++ b/src/common/config.ts @@ -113,9 +113,6 @@ export function getConfigLocation(): string { const storagePath = join(userDataPath, "/storage/"); return `${storagePath}settings.json`; } -export function getEntireConfig(): Settings { - return ensureConfigCache(); -} export function getConfig(object: K): Settings[K] { if (process.argv.includes("--safe-mode")) { diff --git a/src/discord/ipc.ts b/src/discord/ipc.ts index 74fc166..f576a4b 100644 --- a/src/discord/ipc.ts +++ b/src/discord/ipc.ts @@ -18,7 +18,7 @@ import { unblacklistGame as blacklistGameRemove, getBlacklist, } from "../common/blacklistGame.js"; -import { getConfig, getConfigLocation, getEntireConfig, setConfig, setConfigBulk } from "../common/config.js"; +import { getConfig, getConfigLocation, setConfig, setConfigBulk } from "../common/config.js"; import { addDetectable, getDetectables, removeDetectable } from "../common/detectables.js"; import { getLang, getLangName, getRawLang, setLang } from "../common/lang.js"; import { @@ -331,7 +331,8 @@ export function registerIpc(passedWindow: BrowserWindow): void { refreshGlobalKeybinds(); }); ipcMain.on("getEntireConfig", (event) => { - event.returnValue = getEntireConfig(); + const rawData = readFileSync(getConfigLocation(), "utf-8"); + event.returnValue = JSON.parse(rawData) as Settings; }); ipcMain.on("getTranslations", (event) => { event.returnValue = getRawLang(); @@ -371,7 +372,7 @@ export function registerIpc(passedWindow: BrowserWindow): void { event.returnValue = os.release(); }); ipcMain.on("copyDebugInfo", () => { - const settingsFileContent = JSON.stringify(getEntireConfig(), null, 4); + const settingsFileContent = readFileSync(getConfigLocation(), "utf-8"); clipboard.writeText( `**OS:** ${os.platform()} ${os.version()}\n**Architecture:** ${os.arch()}\n**Legcord version:** ${getVersion()}\n**Electron version:** ${ process.versions.electron diff --git a/src/discord/preload/bridge.ts b/src/discord/preload/bridge.ts index 97c2fc9..825cc27 100644 --- a/src/discord/preload/bridge.ts +++ b/src/discord/preload/bridge.ts @@ -11,8 +11,7 @@ import type { venmicListObject } from "../venmic.js"; interface IPCSources { id: string; name: string; - thumbnail: string; - appIcon?: string; + thumbnail: HTMLCanvasElement; } interface LegcordPluginInfo { id: string; diff --git a/src/discord/screenshare.ts b/src/discord/screenshare.ts index c333ed9..c4bf26a 100644 --- a/src/discord/screenshare.ts +++ b/src/discord/screenshare.ts @@ -1,6 +1,5 @@ import { desktopCapturer, ipcMain, type Streams, session } from "electron"; import { getConfig } from "../common/config.js"; -import { serializeCapturerSources } from "./screenshareSources.js"; import { mainWindows } from "./window.js"; export function registerCustomHandler(): void { @@ -10,8 +9,6 @@ export function registerCustomHandler(): void { const sources = await desktopCapturer .getSources({ types: ["window", "screen"], - thumbnailSize: { width: 320, height: 180 }, - fetchWindowIcons: true, }) .catch((err) => console.error(err)); @@ -49,9 +46,8 @@ export function registerCustomHandler(): void { } } }); - const pickerSources = serializeCapturerSources(sources); mainWindows.every((window) => { - window.webContents.send("getSources", pickerSources); + window.webContents.send("getSources", sources); return true; }); }, diff --git a/src/discord/screenshareSources.ts b/src/discord/screenshareSources.ts deleted file mode 100644 index d29c993..0000000 --- a/src/discord/screenshareSources.ts +++ /dev/null @@ -1,99 +0,0 @@ -export type NativeImageLike = { - toDataURL?: (type?: string) => string; - isEmpty?: () => boolean; -}; - -export type CapturerSourceLike = { - id: string; - name: string; - thumbnail?: NativeImageLike | string | null; - appIcon?: NativeImageLike | string | null; -}; - -export type PickerSource = { - id: string; - name: string; - thumbnail: string; - appIcon?: string; -}; - -function imageToDataUrl(image: NativeImageLike | string | null | undefined): string { - if (!image) return ""; - if (typeof image === "string") return image; - try { - if (image.isEmpty?.()) return ""; - const url = image.toDataURL?.(); - return typeof url === "string" ? url : ""; - } catch { - return ""; - } -} - -function hashString(value: string): number { - let hash = 2166136261; - for (let i = 0; i < value.length; i++) { - hash ^= value.charCodeAt(i); - hash = Math.imul(hash, 16777619); - } - return hash >>> 0; -} - -function initialsFromName(name: string): string { - const parts = name - .replace(/[()[\]{}]/g, " ") - .split(/\s+/) - .filter(Boolean); - if (parts.length === 0) return "?"; - if (parts.length === 1) return parts[0].slice(0, 2).toUpperCase(); - return `${parts[0][0] ?? ""}${parts[1][0] ?? ""}`.toUpperCase(); -} - -/** Distinct, source-specific placeholder when thumbnails/icons are missing or duplicated. */ -export function fallbackSourceVisual(id: string, name: string): string { - const hue = hashString(id || name) % 360; - const initials = initialsFromName(name || id || "Source"); - const svg = ` - -${initials} -`; - return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svg)}`; -} - -export function serializeCapturerSources(sources: CapturerSourceLike[]): PickerSource[] { - const prepared = sources.map((source) => ({ - id: source.id, - name: source.name, - thumbnailRaw: imageToDataUrl(source.thumbnail), - appIcon: imageToDataUrl(source.appIcon), - })); - - const thumbnailCounts = new Map(); - for (const source of prepared) { - if (!source.thumbnailRaw) continue; - thumbnailCounts.set(source.thumbnailRaw, (thumbnailCounts.get(source.thumbnailRaw) ?? 0) + 1); - } - - const usedVisuals = new Set(); - return prepared.map((source) => { - const thumbnailIsDuplicate = - Boolean(source.thumbnailRaw) && (thumbnailCounts.get(source.thumbnailRaw) ?? 0) > 1; - let visual = source.thumbnailRaw; - if (!visual || thumbnailIsDuplicate) { - if (source.appIcon && !usedVisuals.has(source.appIcon)) { - visual = source.appIcon; - } - } - if (!visual || usedVisuals.has(visual)) { - visual = fallbackSourceVisual(source.id, source.name); - } - usedVisuals.add(visual); - - const result: PickerSource = { - id: source.id, - name: source.name, - thumbnail: visual, - }; - if (source.appIcon) result.appIcon = source.appIcon; - return result; - }); -} diff --git a/src/main.ts b/src/main.ts index b3a7301..00f8bee 100644 --- a/src/main.ts +++ b/src/main.ts @@ -354,17 +354,13 @@ if (!app.requestSingleInstanceLock() && getConfig("multiInstance") === false) { process.on("SIGINT", () => app.quit()); process.on("SIGTERM", () => app.quit()); // Patch for linux bug to ensure things are loaded before window creation (fixes transparency on some linux systems) - if (process.platform === "linux") { - await new Promise((resolve) => - setTimeout(() => { - init().then(() => { - resolve(); - }); - }, 1500), - ); - } else { - await init(); - } + await new Promise((resolve) => + setTimeout(() => { + init().then(() => { + resolve(); + }); + }, 1500), + ); session.defaultSession.setPermissionRequestHandler(async (_webContents, permission, callback) => { switch (permission) { case "fullscreen": diff --git a/src/shelter/rpc/index.ts b/src/shelter/rpc/index.ts index 6e37c4f..b561ada 100644 --- a/src/shelter/rpc/index.ts +++ b/src/shelter/rpc/index.ts @@ -42,20 +42,33 @@ async function listen(msg: { FluxDispatcher.dispatch({ type: "LOCAL_ACTIVITY_UPDATE", ...msg }); return console.log(`Game ${gameName} (${appId}) is blacklisted, skipping...`); } - if (msg.activity?.assets) { - const { large_image, small_image } = msg.activity.assets; - - if (typeof large_image === "string") { - msg.activity.assets.large_image = large_image.startsWith("https://") - ? await fetchExternalAsset(msg.activity.application_id, large_image) - : await fetchAssetId(msg.activity.application_id, large_image); + if ( + msg.activity?.assets?.large_image?.startsWith("https://") ?? + msg.activity?.assets?.small_image?.startsWith("https://") + ) { + if (typeof msg.activity.assets.large_image === "string") { + msg.activity.assets.large_image = await fetchExternalAsset( + msg.activity.application_id, + msg.activity.assets.large_image, + ); } - - if (typeof small_image === "string") { - msg.activity.assets.small_image = small_image.startsWith("https://") - ? await fetchExternalAsset(msg.activity.application_id, small_image) - : await fetchAssetId(msg.activity.application_id, small_image); + if (typeof msg.activity.assets.small_image === "string") { + msg.activity.assets.small_image = await fetchExternalAsset( + msg.activity.application_id, + msg.activity.assets.small_image, + ); } + } else { + if (msg.activity?.assets?.large_image) + msg.activity.assets.large_image = await fetchAssetId( + msg.activity.application_id, + msg.activity.assets.large_image, + ); + if (msg.activity?.assets?.small_image) + msg.activity.assets.small_image = await fetchAssetId( + msg.activity.application_id, + msg.activity.assets.small_image, + ); } console.log("RPC activity update", msg.activity); diff --git a/src/shelter/screenshare/components/SourceCard.tsx b/src/shelter/screenshare/components/SourceCard.tsx index 5e92070..9985421 100644 --- a/src/shelter/screenshare/components/SourceCard.tsx +++ b/src/shelter/screenshare/components/SourceCard.tsx @@ -5,8 +5,7 @@ import classes from "./SourceCard.module.css"; export interface IPCSources { id: string; name: string; - thumbnail: string; - appIcon?: string; + thumbnail: HTMLCanvasElement; } interface SourceCardProps { source: IPCSources; @@ -38,7 +37,7 @@ export const SourceCard = ({ selected_name, source, onSelect }: SourceCardProps)
{source.name} diff --git a/src/shelter/settings/components/ThemesCard.tsx b/src/shelter/settings/components/ThemesCard.tsx index 068ec5e..a6db8fe 100644 --- a/src/shelter/settings/components/ThemesCard.tsx +++ b/src/shelter/settings/components/ThemesCard.tsx @@ -66,18 +66,23 @@ export const ThemesCard = (props: { theme: ThemeManifest }) => {
- - -
diff --git a/tests/register-ts.mjs b/tests/register-ts.mjs deleted file mode 100644 index e47f416..0000000 --- a/tests/register-ts.mjs +++ /dev/null @@ -1,17 +0,0 @@ -import { existsSync } from "node:fs"; -import { registerHooks } from "node:module"; -import { dirname, join } from "node:path"; -import { fileURLToPath, pathToFileURL } from "node:url"; - -registerHooks({ - resolve(specifier, context, nextResolve) { - if (typeof specifier === "string" && specifier.endsWith(".js") && specifier.startsWith(".")) { - const parent = context.parentURL ? fileURLToPath(context.parentURL) : process.cwd(); - const tsPath = join(dirname(parent), specifier.replace(/\.js$/, ".ts")); - if (existsSync(tsPath)) { - return { url: pathToFileURL(tsPath).href, shortCircuit: true }; - } - } - return nextResolve(specifier, context); - }, -}); diff --git a/tests/screenshare-previews.test.ts b/tests/screenshare-previews.test.ts deleted file mode 100644 index a0e3c68..0000000 --- a/tests/screenshare-previews.test.ts +++ /dev/null @@ -1,77 +0,0 @@ -import assert from "node:assert/strict"; -import { describe, it } from "node:test"; -import { serializeCapturerSources } from "../src/discord/screenshareSources.ts"; - -function fakeImage(dataUrl: string) { - return { - toDataURL: () => dataUrl, - isEmpty: () => dataUrl.length === 0, - }; -} - -describe("serializeCapturerSources", () => { - it("gives each source a distinct usable image and keeps names", () => { - const sources = [ - { id: "screen:0:0", name: "Entire screen", thumbnail: fakeImage("data:image/png;base64,SCREEN0") }, - { id: "window:11:0", name: "Jokel Comms DOD", thumbnail: fakeImage("data:image/png;base64,JOKEL") }, - { id: "window:22:0", name: "MSI Afterburner", thumbnail: fakeImage("data:image/png;base64,MSIAB") }, - ]; - - const result = serializeCapturerSources(sources); - assert.equal(result.length, 3); - const images = result.map((source) => source.thumbnail); - assert.equal(new Set(images).size, 3); - for (const [index, source] of result.entries()) { - assert.equal(source.id, sources[index].id); - assert.equal(source.name, sources[index].name); - assert.ok(source.thumbnail.startsWith("data:image/"), `expected data URL for ${source.name}`); - assert.ok(source.thumbnail.length > "data:image/".length); - } - }); - - it("uses a source-specific app icon when the thumbnail is missing", () => { - const sources = [ - { - id: "window:1:0", - name: "Friends List", - thumbnail: fakeImage(""), - appIcon: fakeImage("data:image/png;base64,FRIENDICON"), - }, - { - id: "window:2:0", - name: "Pull requests", - thumbnail: fakeImage(""), - appIcon: fakeImage("data:image/png;base64,PRICON"), - }, - ]; - - const result = serializeCapturerSources(sources); - assert.equal(result[0].name, "Friends List"); - assert.equal(result[0].thumbnail, "data:image/png;base64,FRIENDICON"); - assert.equal(result[1].name, "Pull requests"); - assert.equal(result[1].thumbnail, "data:image/png;base64,PRICON"); - assert.notEqual(result[0].thumbnail, result[1].thumbnail); - }); - - it("does not reuse a duplicated compositor thumbnail across unrelated sources", () => { - const sameFrame = "data:image/png;base64,SAMEFRAME"; - const sources = [ - { id: "screen:0:0", name: "Entire screen", thumbnail: fakeImage(sameFrame) }, - { - id: "window:4432:0", - name: "Jokel Comms DOD", - thumbnail: fakeImage(sameFrame), - appIcon: fakeImage("data:image/png;base64,JOKELICON"), - }, - { id: "window:9:0", name: "Legcord Screen Share Low FP", thumbnail: fakeImage(sameFrame) }, - ]; - - const result = serializeCapturerSources(sources); - const images = result.map((source) => source.thumbnail); - assert.equal(new Set(images).size, 3); - assert.equal(result[1].thumbnail, "data:image/png;base64,JOKELICON"); - for (const source of result) { - assert.ok(source.thumbnail.startsWith("data:image/")); - } - }); -});