Merge 879b1fd58e
into 24fbf35542
This commit is contained in:
commit
52593bf74f
15 changed files with 628 additions and 23 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,4 +1,5 @@
|
|||
dist
|
||||
/dist/
|
||||
|
||||
node_modules
|
||||
.env
|
||||
.DS_Store
|
||||
|
|
|
@ -50,6 +50,8 @@
|
|||
"eslint-plugin-simple-import-sort": "^12.1.1",
|
||||
"eslint-plugin-unused-imports": "^3.2.0",
|
||||
"prettier": "^3.3.3",
|
||||
"sharp": "^0.33.0",
|
||||
"sharp-ico": "^0.1.5",
|
||||
"source-map-support": "^0.5.21",
|
||||
"tsx": "^4.16.2",
|
||||
"type-fest": "^4.23.0",
|
||||
|
|
304
pnpm-lock.yaml
304
pnpm-lock.yaml
|
@ -81,6 +81,12 @@ importers:
|
|||
prettier:
|
||||
specifier: ^3.3.3
|
||||
version: 3.3.3
|
||||
sharp:
|
||||
specifier: ^0.33.0
|
||||
version: 0.33.4
|
||||
sharp-ico:
|
||||
specifier: ^0.1.5
|
||||
version: 0.1.5
|
||||
source-map-support:
|
||||
specifier: ^0.5.21
|
||||
version: 0.5.21
|
||||
|
@ -102,6 +108,9 @@ packages:
|
|||
7zip-bin@5.2.0:
|
||||
resolution: {integrity: sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A==}
|
||||
|
||||
'@canvas/image-data@1.0.0':
|
||||
resolution: {integrity: sha512-BxOqI5LgsIQP1odU5KMwV9yoijleOPzHL18/YvNqF9KFSGF2K/DLlYAbDQsWqd/1nbaFuSkYD/191dpMtNh4vw==}
|
||||
|
||||
'@develar/schema-utils@2.6.5':
|
||||
resolution: {integrity: sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==}
|
||||
engines: {node: '>= 8.9.0'}
|
||||
|
@ -146,6 +155,9 @@ packages:
|
|||
resolution: {integrity: sha512-fKpv9kg4SPmt+hY7SVBnIYULE9QJl8L3sCfcBsnqbJwwBwAeTLokJ9TRt9y7bK0JAzIW2y78TVVjvnQEms/yyA==}
|
||||
engines: {node: '>=16.4'}
|
||||
|
||||
'@emnapi/runtime@1.2.0':
|
||||
resolution: {integrity: sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==}
|
||||
|
||||
'@esbuild/aix-ppc64@0.20.2':
|
||||
resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==}
|
||||
engines: {node: '>=12'}
|
||||
|
@ -459,6 +471,119 @@ packages:
|
|||
resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==}
|
||||
deprecated: Use @eslint/object-schema instead
|
||||
|
||||
'@img/sharp-darwin-arm64@0.33.4':
|
||||
resolution: {integrity: sha512-p0suNqXufJs9t3RqLBO6vvrgr5OhgbWp76s5gTRvdmxmuv9E1rcaqGUsl3l4mKVmXPkTkTErXediAui4x+8PSA==}
|
||||
engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-darwin-x64@0.33.4':
|
||||
resolution: {integrity: sha512-0l7yRObwtTi82Z6ebVI2PnHT8EB2NxBgpK2MiKJZJ7cz32R4lxd001ecMhzzsZig3Yv9oclvqqdV93jo9hy+Dw==}
|
||||
engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-libvips-darwin-arm64@1.0.2':
|
||||
resolution: {integrity: sha512-tcK/41Rq8IKlSaKRCCAuuY3lDJjQnYIW1UXU1kxcEKrfL8WR7N6+rzNoOxoQRJWTAECuKwgAHnPvqXGN8XfkHA==}
|
||||
engines: {macos: '>=11', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-libvips-darwin-x64@1.0.2':
|
||||
resolution: {integrity: sha512-Ofw+7oaWa0HiiMiKWqqaZbaYV3/UGL2wAPeLuJTx+9cXpCRdvQhCLG0IH8YGwM0yGWGLpsF4Su9vM1o6aer+Fw==}
|
||||
engines: {macos: '>=10.13', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-libvips-linux-arm64@1.0.2':
|
||||
resolution: {integrity: sha512-x7kCt3N00ofFmmkkdshwj3vGPCnmiDh7Gwnd4nUwZln2YjqPxV1NlTyZOvoDWdKQVDL911487HOueBvrpflagw==}
|
||||
engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linux-arm@1.0.2':
|
||||
resolution: {integrity: sha512-iLWCvrKgeFoglQxdEwzu1eQV04o8YeYGFXtfWU26Zr2wWT3q3MTzC+QTCO3ZQfWd3doKHT4Pm2kRmLbupT+sZw==}
|
||||
engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linux-s390x@1.0.2':
|
||||
resolution: {integrity: sha512-cmhQ1J4qVhfmS6szYW7RT+gLJq9dH2i4maq+qyXayUSn9/3iY2ZeWpbAgSpSVbV2E1JUL2Gg7pwnYQ1h8rQIog==}
|
||||
engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linux-x64@1.0.2':
|
||||
resolution: {integrity: sha512-E441q4Qdb+7yuyiADVi5J+44x8ctlrqn8XgkDTwr4qPJzWkaHwD489iZ4nGDgcuya4iMN3ULV6NwbhRZJ9Z7SQ==}
|
||||
engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-arm64@1.0.2':
|
||||
resolution: {integrity: sha512-3CAkndNpYUrlDqkCM5qhksfE+qSIREVpyoeHIU6jd48SJZViAmznoQQLAv4hVXF7xyUB9zf+G++e2v1ABjCbEQ==}
|
||||
engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-x64@1.0.2':
|
||||
resolution: {integrity: sha512-VI94Q6khIHqHWNOh6LLdm9s2Ry4zdjWJwH56WoiJU7NTeDwyApdZZ8c+SADC8OH98KWNQXnE01UdJ9CSfZvwZw==}
|
||||
engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linux-arm64@0.33.4':
|
||||
resolution: {integrity: sha512-2800clwVg1ZQtxwSoTlHvtm9ObgAax7V6MTAB/hDT945Tfyy3hVkmiHpeLPCKYqYR1Gcmv1uDZ3a4OFwkdBL7Q==}
|
||||
engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linux-arm@0.33.4':
|
||||
resolution: {integrity: sha512-RUgBD1c0+gCYZGCCe6mMdTiOFS0Zc/XrN0fYd6hISIKcDUbAW5NtSQW9g/powkrXYm6Vzwd6y+fqmExDuCdHNQ==}
|
||||
engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linux-s390x@0.33.4':
|
||||
resolution: {integrity: sha512-h3RAL3siQoyzSoH36tUeS0PDmb5wINKGYzcLB5C6DIiAn2F3udeFAum+gj8IbA/82+8RGCTn7XW8WTFnqag4tQ==}
|
||||
engines: {glibc: '>=2.31', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linux-x64@0.33.4':
|
||||
resolution: {integrity: sha512-GoR++s0XW9DGVi8SUGQ/U4AeIzLdNjHka6jidVwapQ/JebGVQIpi52OdyxCNVRE++n1FCLzjDovJNozif7w/Aw==}
|
||||
engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linuxmusl-arm64@0.33.4':
|
||||
resolution: {integrity: sha512-nhr1yC3BlVrKDTl6cO12gTpXMl4ITBUZieehFvMntlCXFzH2bvKG76tBL2Y/OqhupZt81pR7R+Q5YhJxW0rGgQ==}
|
||||
engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-linuxmusl-x64@0.33.4':
|
||||
resolution: {integrity: sha512-uCPTku0zwqDmZEOi4ILyGdmW76tH7dm8kKlOIV1XC5cLyJ71ENAAqarOHQh0RLfpIpbV5KOpXzdU6XkJtS0daw==}
|
||||
engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
'@img/sharp-wasm32@0.33.4':
|
||||
resolution: {integrity: sha512-Bmmauh4sXUsUqkleQahpdNXKvo+wa1V9KhT2pDA4VJGKwnKMJXiSTGphn0gnJrlooda0QxCtXc6RX1XAU6hMnQ==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [wasm32]
|
||||
|
||||
'@img/sharp-win32-ia32@0.33.4':
|
||||
resolution: {integrity: sha512-99SJ91XzUhYHbx7uhK3+9Lf7+LjwMGQZMDlO/E/YVJ7Nc3lyDFZPGhjwiYdctoH2BOzW9+TnfqcaMKt0jHLdqw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@img/sharp-win32-x64@0.33.4':
|
||||
resolution: {integrity: sha512-3QLocdTRVIrFNye5YocZl+KKpYKP+fksi1QhmOArgx7GyhIbQp/WrJRu176jm8IxromS7RIkzMiMINVdBtC8Aw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@isaacs/cliui@8.0.2':
|
||||
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
|
||||
engines: {node: '>=12'}
|
||||
|
@ -963,10 +1088,17 @@ packages:
|
|||
color-name@1.1.4:
|
||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||
|
||||
color-string@1.9.1:
|
||||
resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
|
||||
|
||||
color-support@1.1.3:
|
||||
resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==}
|
||||
hasBin: true
|
||||
|
||||
color@4.2.3:
|
||||
resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
|
||||
engines: {node: '>=12.5.0'}
|
||||
|
||||
combined-stream@1.0.8:
|
||||
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
@ -1064,6 +1196,14 @@ packages:
|
|||
supports-color:
|
||||
optional: true
|
||||
|
||||
decode-bmp@0.2.1:
|
||||
resolution: {integrity: sha512-NiOaGe+GN0KJqi2STf24hfMkFitDUaIoUU3eKvP/wAbLe8o6FuW5n/x7MHPR0HKvBokp6MQY/j7w8lewEeVCIA==}
|
||||
engines: {node: '>=8.6.0'}
|
||||
|
||||
decode-ico@0.4.1:
|
||||
resolution: {integrity: sha512-69NZfbKIzux1vBOd31al3XnMnH+2mqDhEgLdpygErm4d60N+UwA5Sq5WFjmEDQzumgB9fElojGwWG0vybVfFmA==}
|
||||
engines: {node: '>=8.6'}
|
||||
|
||||
decode-uri-component@0.2.2:
|
||||
resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==}
|
||||
engines: {node: '>=0.10'}
|
||||
|
@ -1660,6 +1800,9 @@ packages:
|
|||
humanize-ms@1.2.1:
|
||||
resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==}
|
||||
|
||||
ico-endec@0.1.6:
|
||||
resolution: {integrity: sha512-ZdLU38ZoED3g1j3iEyzcQj+wAkY2xfWNkymszfJPoxucIUhK7NayQ+/C4Kv0nDFMIsbtbEHldv3V8PU494/ueQ==}
|
||||
|
||||
iconv-corefoundation@1.1.7:
|
||||
resolution: {integrity: sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==}
|
||||
engines: {node: ^8.11.2 || >=10}
|
||||
|
@ -1717,6 +1860,9 @@ packages:
|
|||
resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-arrayish@0.3.2:
|
||||
resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
|
||||
|
||||
is-bigint@1.0.4:
|
||||
resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==}
|
||||
|
||||
|
@ -2488,6 +2634,13 @@ packages:
|
|||
resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
sharp-ico@0.1.5:
|
||||
resolution: {integrity: sha512-a3jODQl82NPp1d5OYb0wY+oFaPk7AvyxipIowCHk7pBsZCWgbe0yAkU2OOXdoH0ENyANhyOQbs9xkAiRHcF02Q==}
|
||||
|
||||
sharp@0.33.4:
|
||||
resolution: {integrity: sha512-7i/dt5kGl7qR4gwPRD2biwD2/SvBn3O04J77XKFgL2OnZtQw+AG9wnuS/csmu80nPRHLYE9E41fyEiG8nhH6/Q==}
|
||||
engines: {libvips: '>=8.15.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
|
||||
shebang-command@2.0.0:
|
||||
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
|
||||
engines: {node: '>=8'}
|
||||
|
@ -2507,6 +2660,9 @@ packages:
|
|||
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
simple-swizzle@0.2.2:
|
||||
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
|
||||
|
||||
simple-update-notifier@2.0.0:
|
||||
resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==}
|
||||
engines: {node: '>=10'}
|
||||
|
@ -2661,6 +2817,9 @@ packages:
|
|||
resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==}
|
||||
engines: {node: '>=14.14'}
|
||||
|
||||
to-data-view@1.1.0:
|
||||
resolution: {integrity: sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==}
|
||||
|
||||
to-object-path@0.3.0:
|
||||
resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
@ -2875,6 +3034,8 @@ snapshots:
|
|||
|
||||
7zip-bin@5.2.0: {}
|
||||
|
||||
'@canvas/image-data@1.0.0': {}
|
||||
|
||||
'@develar/schema-utils@2.6.5':
|
||||
dependencies:
|
||||
ajv: 6.12.6
|
||||
|
@ -2982,6 +3143,11 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@emnapi/runtime@1.2.0':
|
||||
dependencies:
|
||||
tslib: 2.6.3
|
||||
optional: true
|
||||
|
||||
'@esbuild/aix-ppc64@0.20.2':
|
||||
optional: true
|
||||
|
||||
|
@ -3159,6 +3325,81 @@ snapshots:
|
|||
|
||||
'@humanwhocodes/object-schema@2.0.3': {}
|
||||
|
||||
'@img/sharp-darwin-arm64@0.33.4':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-darwin-arm64': 1.0.2
|
||||
optional: true
|
||||
|
||||
'@img/sharp-darwin-x64@0.33.4':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-darwin-x64': 1.0.2
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-darwin-arm64@1.0.2':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-darwin-x64@1.0.2':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-arm64@1.0.2':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-arm@1.0.2':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-s390x@1.0.2':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-x64@1.0.2':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-arm64@1.0.2':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-x64@1.0.2':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-arm64@0.33.4':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-arm64': 1.0.2
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-arm@0.33.4':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-arm': 1.0.2
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-s390x@0.33.4':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-s390x': 1.0.2
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-x64@0.33.4':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-x64': 1.0.2
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linuxmusl-arm64@0.33.4':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linuxmusl-arm64': 1.0.2
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linuxmusl-x64@0.33.4':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linuxmusl-x64': 1.0.2
|
||||
optional: true
|
||||
|
||||
'@img/sharp-wasm32@0.33.4':
|
||||
dependencies:
|
||||
'@emnapi/runtime': 1.2.0
|
||||
optional: true
|
||||
|
||||
'@img/sharp-win32-ia32@0.33.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-win32-x64@0.33.4':
|
||||
optional: true
|
||||
|
||||
'@isaacs/cliui@8.0.2':
|
||||
dependencies:
|
||||
string-width: 5.1.2
|
||||
|
@ -3891,8 +4132,18 @@ snapshots:
|
|||
|
||||
color-name@1.1.4: {}
|
||||
|
||||
color-string@1.9.1:
|
||||
dependencies:
|
||||
color-name: 1.1.4
|
||||
simple-swizzle: 0.2.2
|
||||
|
||||
color-support@1.1.3: {}
|
||||
|
||||
color@4.2.3:
|
||||
dependencies:
|
||||
color-convert: 2.0.1
|
||||
color-string: 1.9.1
|
||||
|
||||
combined-stream@1.0.8:
|
||||
dependencies:
|
||||
delayed-stream: 1.0.0
|
||||
|
@ -3981,6 +4232,17 @@ snapshots:
|
|||
dependencies:
|
||||
ms: 2.1.2
|
||||
|
||||
decode-bmp@0.2.1:
|
||||
dependencies:
|
||||
'@canvas/image-data': 1.0.0
|
||||
to-data-view: 1.1.0
|
||||
|
||||
decode-ico@0.4.1:
|
||||
dependencies:
|
||||
'@canvas/image-data': 1.0.0
|
||||
decode-bmp: 0.2.1
|
||||
to-data-view: 1.1.0
|
||||
|
||||
decode-uri-component@0.2.2: {}
|
||||
|
||||
decompress-response@6.0.0:
|
||||
|
@ -4818,6 +5080,8 @@ snapshots:
|
|||
dependencies:
|
||||
ms: 2.1.3
|
||||
|
||||
ico-endec@0.1.6: {}
|
||||
|
||||
iconv-corefoundation@1.1.7:
|
||||
dependencies:
|
||||
cli-truncate: 2.1.0
|
||||
|
@ -4873,6 +5137,8 @@ snapshots:
|
|||
call-bind: 1.0.7
|
||||
get-intrinsic: 1.2.4
|
||||
|
||||
is-arrayish@0.3.2: {}
|
||||
|
||||
is-bigint@1.0.4:
|
||||
dependencies:
|
||||
has-bigints: 1.0.2
|
||||
|
@ -5648,6 +5914,38 @@ snapshots:
|
|||
is-plain-object: 2.0.4
|
||||
split-string: 3.1.0
|
||||
|
||||
sharp-ico@0.1.5:
|
||||
dependencies:
|
||||
decode-ico: 0.4.1
|
||||
ico-endec: 0.1.6
|
||||
sharp: 0.33.4
|
||||
|
||||
sharp@0.33.4:
|
||||
dependencies:
|
||||
color: 4.2.3
|
||||
detect-libc: 2.0.3
|
||||
semver: 7.6.3
|
||||
optionalDependencies:
|
||||
'@img/sharp-darwin-arm64': 0.33.4
|
||||
'@img/sharp-darwin-x64': 0.33.4
|
||||
'@img/sharp-libvips-darwin-arm64': 1.0.2
|
||||
'@img/sharp-libvips-darwin-x64': 1.0.2
|
||||
'@img/sharp-libvips-linux-arm': 1.0.2
|
||||
'@img/sharp-libvips-linux-arm64': 1.0.2
|
||||
'@img/sharp-libvips-linux-s390x': 1.0.2
|
||||
'@img/sharp-libvips-linux-x64': 1.0.2
|
||||
'@img/sharp-libvips-linuxmusl-arm64': 1.0.2
|
||||
'@img/sharp-libvips-linuxmusl-x64': 1.0.2
|
||||
'@img/sharp-linux-arm': 0.33.4
|
||||
'@img/sharp-linux-arm64': 0.33.4
|
||||
'@img/sharp-linux-s390x': 0.33.4
|
||||
'@img/sharp-linux-x64': 0.33.4
|
||||
'@img/sharp-linuxmusl-arm64': 0.33.4
|
||||
'@img/sharp-linuxmusl-x64': 0.33.4
|
||||
'@img/sharp-wasm32': 0.33.4
|
||||
'@img/sharp-win32-ia32': 0.33.4
|
||||
'@img/sharp-win32-x64': 0.33.4
|
||||
|
||||
shebang-command@2.0.0:
|
||||
dependencies:
|
||||
shebang-regex: 3.0.0
|
||||
|
@ -5665,6 +5963,10 @@ snapshots:
|
|||
|
||||
signal-exit@4.1.0: {}
|
||||
|
||||
simple-swizzle@0.2.2:
|
||||
dependencies:
|
||||
is-arrayish: 0.3.2
|
||||
|
||||
simple-update-notifier@2.0.0:
|
||||
dependencies:
|
||||
semver: 7.6.3
|
||||
|
@ -5849,6 +6151,8 @@ snapshots:
|
|||
|
||||
tmp@0.2.3: {}
|
||||
|
||||
to-data-view@1.1.0: {}
|
||||
|
||||
to-object-path@0.3.0:
|
||||
dependencies:
|
||||
kind-of: 3.2.2
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
import { BuildContext, BuildOptions, context } from "esbuild";
|
||||
import { copyFile } from "fs/promises";
|
||||
|
||||
import { composeTrayIcons } from "./composeTrayIcons.mts";
|
||||
import vencordDep from "./vencordDep.mjs";
|
||||
|
||||
const isDev = process.argv.includes("--dev");
|
||||
|
@ -49,8 +50,20 @@ async function copyVenmic() {
|
|||
]).catch(() => console.warn("Failed to copy venmic. Building without venmic support"));
|
||||
}
|
||||
|
||||
async function composeTrayIconsIfSupported() {
|
||||
if (process.platform === "darwin") return;
|
||||
|
||||
return composeTrayIcons({
|
||||
icon: "./static/icon.png",
|
||||
badgeDir: "./static/badges/",
|
||||
outDir: "./static/dist/tray_icons",
|
||||
createEmpty: true
|
||||
});
|
||||
}
|
||||
|
||||
await Promise.all([
|
||||
copyVenmic(),
|
||||
composeTrayIconsIfSupported(),
|
||||
createContext({
|
||||
...NodeCommonOpts,
|
||||
entryPoints: ["src/main/index.ts"],
|
||||
|
|
231
scripts/build/composeTrayIcons.mts
Normal file
231
scripts/build/composeTrayIcons.mts
Normal file
|
@ -0,0 +1,231 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: GPL-3.0
|
||||
* Vesktop, a desktop app aiming to give you a snappier Discord Experience
|
||||
* Copyright (c) 2023 Vendicated and Vencord contributors
|
||||
*/
|
||||
|
||||
import { readdir, stat } from "node:fs/promises";
|
||||
import { format as pathFormat, join, parse as pathParse } from "node:path";
|
||||
|
||||
import sharp from "sharp";
|
||||
import { type ImageData, sharpsFromIco } from "sharp-ico";
|
||||
|
||||
interface BadgePosition {
|
||||
left?: number;
|
||||
top?: number;
|
||||
anchorX?: "left" | "right" | "center";
|
||||
anchorY?: "top" | "bottom" | "center";
|
||||
}
|
||||
|
||||
interface BadgeOptions extends BadgePosition {
|
||||
width?: number;
|
||||
height?: number;
|
||||
resizeOptions?: sharp.ResizeOptions;
|
||||
}
|
||||
|
||||
const DEFAULT_BADGE_OPTIONS: Required<BadgeOptions> = {
|
||||
width: 0.5,
|
||||
height: 0.5,
|
||||
left: 0.8,
|
||||
top: 0.8,
|
||||
anchorX: "center",
|
||||
anchorY: "center",
|
||||
resizeOptions: {
|
||||
kernel: sharp.kernel.cubic
|
||||
}
|
||||
};
|
||||
|
||||
export async function composeTrayIcons({
|
||||
icon: iconPath,
|
||||
badgeDir,
|
||||
outDir,
|
||||
outExt = ".png",
|
||||
createEmpty = false,
|
||||
iconOptions = { width: 64, height: 64 },
|
||||
badgeOptions = undefined
|
||||
}: {
|
||||
icon: string | Buffer | sharp.Sharp;
|
||||
badgeDir: string;
|
||||
outDir: string;
|
||||
outExt?: string;
|
||||
createEmpty?: boolean;
|
||||
iconOptions?: ImageDim;
|
||||
badgeOptions?: BadgeOptions;
|
||||
}) {
|
||||
const badges: string[] = [];
|
||||
for (const filename of await readdir(badgeDir)) {
|
||||
const path = join(badgeDir, filename);
|
||||
if (!(await stat(path)).isDirectory()) {
|
||||
badges.push(path);
|
||||
}
|
||||
}
|
||||
|
||||
const badgeOptionsFilled = { ...DEFAULT_BADGE_OPTIONS, ...badgeOptions };
|
||||
const { data: iconData, info: iconInfo } = await resolveImageOrIco(iconPath, iconOptions);
|
||||
const iconName = typeof iconPath === "string" ? pathParse(iconPath).name : "tray_icon";
|
||||
|
||||
const resizedBadgeDim = {
|
||||
height: Math.round(badgeOptionsFilled.height * iconInfo.height),
|
||||
width: Math.round(badgeOptionsFilled.width * iconInfo.width)
|
||||
};
|
||||
|
||||
async function doCompose(badgePath: string | sharp.Sharp, ensureSize?: ImageDim | false) {
|
||||
const { data: badgeData, info: badgeInfo } = await resolveImageOrIco(badgePath, resizedBadgeDim);
|
||||
if (ensureSize && (badgeInfo.height !== ensureSize.height || badgeInfo.width !== ensureSize.width)) {
|
||||
throw new Error(
|
||||
`Badge loaded from ${badgePath} has size ${badgeInfo.height}x${badgeInfo.height} != ${ensureSize.height}x${ensureSize.height}`
|
||||
);
|
||||
}
|
||||
|
||||
const savePath = pathFormat({
|
||||
name: iconName + (typeof badgePath === "string" ? "_" + pathParse(badgePath).name : ""),
|
||||
dir: outDir,
|
||||
ext: outExt,
|
||||
base: undefined
|
||||
});
|
||||
const out = composeTrayIcon(iconData, iconInfo, badgeData, badgeInfo, badgeOptionsFilled);
|
||||
const outputInfo = await out.toFile(savePath);
|
||||
return {
|
||||
iconInfo,
|
||||
badgeInfo,
|
||||
outputInfo
|
||||
};
|
||||
}
|
||||
|
||||
if (createEmpty) {
|
||||
const firstComposition = await doCompose(badges[0]);
|
||||
return await Promise.all([
|
||||
firstComposition,
|
||||
...badges.map(badge => doCompose(badge, firstComposition.badgeInfo)),
|
||||
doCompose(emptyImage(firstComposition.badgeInfo).png())
|
||||
]);
|
||||
} else {
|
||||
return await Promise.all(badges.map(badge => doCompose(badge)));
|
||||
}
|
||||
}
|
||||
|
||||
type SharpInput = string | Buffer;
|
||||
|
||||
interface ImageDim {
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
async function resolveImageOrIco(...args: Parameters<typeof loadFromImageOrIco>) {
|
||||
const image = await loadFromImageOrIco(...args);
|
||||
const { data, info } = await image.toBuffer({ resolveWithObject: true });
|
||||
return {
|
||||
data,
|
||||
info: validDim(info)
|
||||
};
|
||||
}
|
||||
|
||||
async function loadFromImageOrIco(
|
||||
path: string | Buffer | sharp.Sharp,
|
||||
sizeOptions?: ImageDim & { resizeICO?: boolean }
|
||||
): Promise<sharp.Sharp> {
|
||||
if (typeof path === "string" && path.endsWith(".ico")) {
|
||||
const icos = sharpsFromIco(path, undefined, true) as unknown as ImageData[];
|
||||
let icoInfo;
|
||||
if (sizeOptions == null) {
|
||||
icoInfo = icos[icos.length - 1];
|
||||
} else {
|
||||
icoInfo = icos.reduce((best, ico) =>
|
||||
Math.abs(ico.width - sizeOptions.width) < Math.abs(ico.width - best.width) ? ico : best
|
||||
);
|
||||
}
|
||||
|
||||
if (icoInfo.image == null) {
|
||||
throw new Error("Bug: sharps-ico found no image in ICO");
|
||||
}
|
||||
|
||||
const icoImage = icoInfo.image.png();
|
||||
if (sizeOptions?.resizeICO) {
|
||||
return icoImage.resize(sizeOptions);
|
||||
} else {
|
||||
return icoImage;
|
||||
}
|
||||
} else {
|
||||
let image = typeof path !== "string" && "toBuffer" in path ? path : sharp(path);
|
||||
if (sizeOptions) {
|
||||
image = image.resize(sizeOptions);
|
||||
}
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
||||
function validDim<T extends Partial<ImageDim>>(meta: T): T & ImageDim {
|
||||
if (meta?.width == null || meta?.height == null) {
|
||||
throw new Error("Failed getting icon dimensions");
|
||||
}
|
||||
return meta as T & ImageDim;
|
||||
}
|
||||
|
||||
function emptyImage(dim: ImageDim) {
|
||||
return sharp({
|
||||
create: {
|
||||
width: dim.width,
|
||||
height: dim.height,
|
||||
channels: 4,
|
||||
background: { r: 0, b: 0, g: 0, alpha: 0 }
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function composeTrayIcon(
|
||||
icon: SharpInput,
|
||||
iconDim: ImageDim,
|
||||
badge: SharpInput,
|
||||
badgeDim: ImageDim,
|
||||
badgeOptions: Required<BadgeOptions>
|
||||
): sharp.Sharp {
|
||||
let badgeLeft = badgeOptions.left * iconDim.width;
|
||||
switch (badgeOptions.anchorX) {
|
||||
case "left":
|
||||
break;
|
||||
case "right":
|
||||
badgeLeft -= badgeDim.width;
|
||||
break;
|
||||
case "center":
|
||||
badgeLeft -= badgeDim.width / 2;
|
||||
break;
|
||||
}
|
||||
let badgeTop = badgeOptions.top * iconDim.height;
|
||||
switch (badgeOptions.anchorY) {
|
||||
case "top":
|
||||
break;
|
||||
case "bottom":
|
||||
badgeTop -= badgeDim.height / 2;
|
||||
break;
|
||||
case "center":
|
||||
badgeTop -= badgeDim.height / 2;
|
||||
break;
|
||||
}
|
||||
|
||||
badgeTop = Math.round(badgeTop);
|
||||
badgeLeft = Math.round(badgeLeft);
|
||||
|
||||
const padding = Math.max(
|
||||
0,
|
||||
-badgeLeft,
|
||||
badgeLeft + badgeDim.width - iconDim.width,
|
||||
-badgeTop,
|
||||
badgeTop + badgeDim.height - iconDim.height
|
||||
);
|
||||
|
||||
return emptyImage({
|
||||
width: iconDim.width + 2 * padding,
|
||||
height: iconDim.height + 2 * padding
|
||||
}).composite([
|
||||
{
|
||||
input: icon,
|
||||
left: padding,
|
||||
top: padding
|
||||
},
|
||||
{
|
||||
input: badge,
|
||||
left: badgeLeft + padding,
|
||||
top: badgeTop + padding
|
||||
}
|
||||
]);
|
||||
}
|
|
@ -6,26 +6,45 @@
|
|||
|
||||
import { app, NativeImage, nativeImage } from "electron";
|
||||
import { join } from "path";
|
||||
import { BADGE_DIR } from "shared/paths";
|
||||
import { BADGE_DIR, TRAY_ICON_DIR, TRAY_ICON_PATH } from "shared/paths";
|
||||
import { tray, mainWin } from "./mainWindow";
|
||||
import { Settings } from "./settings";
|
||||
|
||||
const imgCache = new Map<number, NativeImage>();
|
||||
function loadBadge(index: number) {
|
||||
const cached = imgCache.get(index);
|
||||
const imgCache = new Map<string, NativeImage>();
|
||||
|
||||
function loadImg(path: string) {
|
||||
const cached = imgCache.get(path);
|
||||
if (cached) return cached;
|
||||
|
||||
const img = nativeImage.createFromPath(join(BADGE_DIR, `${index}.ico`));
|
||||
imgCache.set(index, img);
|
||||
const img = nativeImage.createFromPath(path);
|
||||
imgCache.set(path, img);
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
function loadBadge(index: number) {
|
||||
return loadImg(join(BADGE_DIR, `${index}.ico`));
|
||||
}
|
||||
|
||||
function loadTrayIcon(index: number) {
|
||||
return loadImg(index === 0 ? TRAY_ICON_PATH : join(TRAY_ICON_DIR, `icon_${index}.png`));
|
||||
}
|
||||
|
||||
let lastIndex: null | number = -1;
|
||||
|
||||
export function setBadgeCount(count: number) {
|
||||
const [index, description] = getBadgeIndexAndDescription(count);
|
||||
|
||||
if (Settings.store.trayBadge) {
|
||||
tray?.setImage(loadTrayIcon(index ?? 0));
|
||||
}
|
||||
|
||||
if (!Settings.store.appBadge) return;
|
||||
|
||||
switch (process.platform) {
|
||||
case "linux":
|
||||
if (count === -1) count = 0;
|
||||
app.setBadgeCount(count);
|
||||
app.setBadgeCount(count); // Only works if libunity is installed
|
||||
break;
|
||||
case "darwin":
|
||||
if (count === 0) {
|
||||
|
@ -35,13 +54,10 @@ export function setBadgeCount(count: number) {
|
|||
app.dock.setBadge(count === -1 ? "•" : count.toString());
|
||||
break;
|
||||
case "win32":
|
||||
const [index, description] = getBadgeIndexAndDescription(count);
|
||||
if (lastIndex === index) break;
|
||||
|
||||
lastIndex = index;
|
||||
|
||||
// circular import shenanigans
|
||||
const { mainWin } = require("./mainWindow") as typeof import("./mainWindow");
|
||||
mainWin.setOverlayIcon(index === null ? null : loadBadge(index), description);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
if (process.platform === "linux") import("./venmic");
|
||||
|
||||
// eslint-disable-next-line simple-import-sort/imports
|
||||
import { execFile } from "child_process";
|
||||
import { app, BrowserWindow, clipboard, dialog, nativeImage, RelaunchOptions, session, shell } from "electron";
|
||||
import { mkdirSync, readFileSync, watch } from "fs";
|
||||
|
@ -15,11 +16,11 @@ import { join } from "path";
|
|||
import { debounce } from "shared/utils/debounce";
|
||||
|
||||
import { IpcEvents } from "../shared/IpcEvents";
|
||||
import { setBadgeCount } from "./appBadge";
|
||||
import { autoStart } from "./autoStart";
|
||||
import { VENCORD_FILES_DIR, VENCORD_QUICKCSS_FILE, VENCORD_THEMES_DIR } from "./constants";
|
||||
import { mainWin } from "./mainWindow";
|
||||
import { Settings, State } from "./settings";
|
||||
import { setBadgeCount } from "./appBadge";
|
||||
import { handle, handleSync } from "./utils/ipcWrappers";
|
||||
import { PopoutWindows } from "./utils/popout";
|
||||
import { isDeckGameMode, showGamePage } from "./utils/steamOS";
|
||||
|
|
|
@ -23,7 +23,7 @@ import { isTruthy } from "shared/utils/guards";
|
|||
import { once } from "shared/utils/once";
|
||||
import type { SettingsStore } from "shared/utils/SettingsStore";
|
||||
|
||||
import { ICON_PATH } from "../shared/paths";
|
||||
import { ICON_PATH, TRAY_ICON_PATH } from "../shared/paths";
|
||||
import { createAboutWindow } from "./about";
|
||||
import { initArRPC } from "./arrpc";
|
||||
import {
|
||||
|
@ -43,7 +43,6 @@ import { applyDeckKeyboardFix, askToApplySteamLayout, isDeckGameMode } from "./u
|
|||
import { downloadVencordFiles, ensureVencordFiles } from "./utils/vencordLoader";
|
||||
|
||||
let isQuitting = false;
|
||||
let tray: Tray;
|
||||
|
||||
applyDeckKeyboardFix();
|
||||
|
||||
|
@ -52,6 +51,7 @@ app.on("before-quit", () => {
|
|||
});
|
||||
|
||||
export let mainWin: BrowserWindow;
|
||||
export let tray: Tray | null = null;
|
||||
|
||||
function makeSettingsListenerHelpers<O extends object>(o: SettingsStore<O>) {
|
||||
const listeners = new Map<(data: any) => void, PropertyKey>();
|
||||
|
@ -123,7 +123,7 @@ function initTray(win: BrowserWindow) {
|
|||
}
|
||||
]);
|
||||
|
||||
tray = new Tray(ICON_PATH);
|
||||
tray = new Tray(TRAY_ICON_PATH);
|
||||
tray.setToolTip("Vesktop");
|
||||
tray.setContextMenu(trayMenu);
|
||||
tray.on("click", onTrayClick);
|
||||
|
@ -330,8 +330,12 @@ function initWindowBoundsListeners(win: BrowserWindow) {
|
|||
|
||||
function initSettingsListeners(win: BrowserWindow) {
|
||||
addSettingsListener("tray", enable => {
|
||||
if (enable) initTray(win);
|
||||
else tray?.destroy();
|
||||
if (enable) {
|
||||
initTray(win);
|
||||
} else if (tray) {
|
||||
tray.destroy();
|
||||
tray = null;
|
||||
}
|
||||
});
|
||||
addSettingsListener("disableMinSize", disable => {
|
||||
if (disable) {
|
||||
|
|
|
@ -13,8 +13,6 @@ let GuildReadStateStore: any;
|
|||
let NotificationSettingsStore: any;
|
||||
|
||||
export function setBadge() {
|
||||
if (Settings.store.appBadge === false) return;
|
||||
|
||||
try {
|
||||
const mentionCount = GuildReadStateStore.getTotalMentionCount();
|
||||
const pendingRequests = RelationshipStore.getPendingCount();
|
||||
|
@ -24,7 +22,9 @@ export function setBadge() {
|
|||
let totalCount = mentionCount + pendingRequests;
|
||||
if (!totalCount && hasUnread && !disableUnreadBadge) totalCount = -1;
|
||||
|
||||
VesktopNative.app.setBadgeCount(totalCount);
|
||||
if (Settings.store.appBadge || Settings.store.trayBadge) {
|
||||
VesktopNative.app.setBadgeCount(totalCount);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import { isMac, isWindows } from "renderer/utils";
|
|||
import { AutoStartToggle } from "./AutoStartToggle";
|
||||
import { DiscordBranchPicker } from "./DiscordBranchPicker";
|
||||
import { NotificationBadgeToggle } from "./NotificationBadgeToggle";
|
||||
import { TrayNotificationBadgeToggle } from "./TrayNotificationBadgeToggle";
|
||||
import { VencordLocationPicker } from "./VencordLocationPicker";
|
||||
import { WindowsTransparencyControls } from "./WindowsTransparencyControls";
|
||||
|
||||
|
@ -102,7 +103,7 @@ const SettingsOptions: Record<string, Array<BooleanSetting | SettingsComponent>>
|
|||
defaultValue: false
|
||||
}
|
||||
],
|
||||
Notifications: [NotificationBadgeToggle],
|
||||
Notifications: [NotificationBadgeToggle, TrayNotificationBadgeToggle],
|
||||
Miscelleanous: [
|
||||
{
|
||||
key: "arRPC",
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* SPDX-License-Identifier: GPL-3.0
|
||||
* Vesktop, a desktop app aiming to give you a snappier Discord Experience
|
||||
* Copyright (c) 2023 Vendicated and Vencord contributors
|
||||
*/
|
||||
|
||||
import { Switch } from "@vencord/types/webpack/common";
|
||||
import { setBadge } from "renderer/appBadge";
|
||||
|
||||
import { SettingsComponent } from "./Settings";
|
||||
|
||||
export const TrayNotificationBadgeToggle: SettingsComponent = ({ settings }) => {
|
||||
return (
|
||||
<Switch
|
||||
value={settings.trayBadge ?? true}
|
||||
onChange={v => {
|
||||
settings.trayBadge = v;
|
||||
if (v) setBadge();
|
||||
else VesktopNative.app.setBadgeCount(0);
|
||||
}}
|
||||
note="Show mention badge on the tray icon"
|
||||
>
|
||||
Tray Notification Badge
|
||||
</Switch>
|
||||
);
|
||||
};
|
|
@ -10,3 +10,5 @@ export const STATIC_DIR = /* @__PURE__ */ join(__dirname, "..", "..", "static");
|
|||
export const VIEW_DIR = /* @__PURE__ */ join(STATIC_DIR, "views");
|
||||
export const BADGE_DIR = /* @__PURE__ */ join(STATIC_DIR, "badges");
|
||||
export const ICON_PATH = /* @__PURE__ */ join(STATIC_DIR, "icon.png");
|
||||
export const TRAY_ICON_DIR = /* @__PURE__ */ join(STATIC_DIR, "dist", "tray_icons");
|
||||
export const TRAY_ICON_PATH = /* @__PURE__ */ join(TRAY_ICON_DIR, "icon.png");
|
||||
|
|
1
src/shared/settings.d.ts
vendored
1
src/shared/settings.d.ts
vendored
|
@ -10,6 +10,7 @@ export interface Settings {
|
|||
discordBranch?: "stable" | "canary" | "ptb";
|
||||
transparencyOption?: "none" | "mica" | "tabbed" | "acrylic";
|
||||
tray?: boolean;
|
||||
trayBadge?: boolean;
|
||||
minimizeToTray?: boolean;
|
||||
openLinksWithElectron?: boolean;
|
||||
staticTitle?: boolean;
|
||||
|
|
1
static/dist/.gitignore
vendored
1
static/dist/.gitignore
vendored
|
@ -1,2 +1,3 @@
|
|||
*
|
||||
!.gitignore
|
||||
!tray_icons/
|
||||
|
|
2
static/dist/tray_icons/.gitignore
vendored
Normal file
2
static/dist/tray_icons/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
*
|
||||
!.gitignore
|
Reference in a new issue