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 | node_modules | ||||||
| .env | .env | ||||||
| .DS_Store | .DS_Store | ||||||
|  |  | ||||||
|  | @ -50,6 +50,8 @@ | ||||||
|         "eslint-plugin-simple-import-sort": "^12.1.1", |         "eslint-plugin-simple-import-sort": "^12.1.1", | ||||||
|         "eslint-plugin-unused-imports": "^3.2.0", |         "eslint-plugin-unused-imports": "^3.2.0", | ||||||
|         "prettier": "^3.3.3", |         "prettier": "^3.3.3", | ||||||
|  |         "sharp": "^0.33.0", | ||||||
|  |         "sharp-ico": "^0.1.5", | ||||||
|         "source-map-support": "^0.5.21", |         "source-map-support": "^0.5.21", | ||||||
|         "tsx": "^4.16.2", |         "tsx": "^4.16.2", | ||||||
|         "type-fest": "^4.23.0", |         "type-fest": "^4.23.0", | ||||||
|  |  | ||||||
							
								
								
									
										304
									
								
								pnpm-lock.yaml
									
									
									
									
									
								
							
							
						
						
									
										304
									
								
								pnpm-lock.yaml
									
									
									
									
									
								
							|  | @ -81,6 +81,12 @@ importers: | ||||||
|       prettier: |       prettier: | ||||||
|         specifier: ^3.3.3 |         specifier: ^3.3.3 | ||||||
|         version: 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: |       source-map-support: | ||||||
|         specifier: ^0.5.21 |         specifier: ^0.5.21 | ||||||
|         version: 0.5.21 |         version: 0.5.21 | ||||||
|  | @ -102,6 +108,9 @@ packages: | ||||||
|   7zip-bin@5.2.0: |   7zip-bin@5.2.0: | ||||||
|     resolution: {integrity: sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A==} |     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': |   '@develar/schema-utils@2.6.5': | ||||||
|     resolution: {integrity: sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==} |     resolution: {integrity: sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==} | ||||||
|     engines: {node: '>= 8.9.0'} |     engines: {node: '>= 8.9.0'} | ||||||
|  | @ -146,6 +155,9 @@ packages: | ||||||
|     resolution: {integrity: sha512-fKpv9kg4SPmt+hY7SVBnIYULE9QJl8L3sCfcBsnqbJwwBwAeTLokJ9TRt9y7bK0JAzIW2y78TVVjvnQEms/yyA==} |     resolution: {integrity: sha512-fKpv9kg4SPmt+hY7SVBnIYULE9QJl8L3sCfcBsnqbJwwBwAeTLokJ9TRt9y7bK0JAzIW2y78TVVjvnQEms/yyA==} | ||||||
|     engines: {node: '>=16.4'} |     engines: {node: '>=16.4'} | ||||||
| 
 | 
 | ||||||
|  |   '@emnapi/runtime@1.2.0': | ||||||
|  |     resolution: {integrity: sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==} | ||||||
|  | 
 | ||||||
|   '@esbuild/aix-ppc64@0.20.2': |   '@esbuild/aix-ppc64@0.20.2': | ||||||
|     resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} |     resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} | ||||||
|     engines: {node: '>=12'} |     engines: {node: '>=12'} | ||||||
|  | @ -459,6 +471,119 @@ packages: | ||||||
|     resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} |     resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} | ||||||
|     deprecated: Use @eslint/object-schema instead |     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': |   '@isaacs/cliui@8.0.2': | ||||||
|     resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} |     resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} | ||||||
|     engines: {node: '>=12'} |     engines: {node: '>=12'} | ||||||
|  | @ -963,10 +1088,17 @@ packages: | ||||||
|   color-name@1.1.4: |   color-name@1.1.4: | ||||||
|     resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} |     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: |   color-support@1.1.3: | ||||||
|     resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} |     resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} | ||||||
|     hasBin: true |     hasBin: true | ||||||
| 
 | 
 | ||||||
|  |   color@4.2.3: | ||||||
|  |     resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} | ||||||
|  |     engines: {node: '>=12.5.0'} | ||||||
|  | 
 | ||||||
|   combined-stream@1.0.8: |   combined-stream@1.0.8: | ||||||
|     resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} |     resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} | ||||||
|     engines: {node: '>= 0.8'} |     engines: {node: '>= 0.8'} | ||||||
|  | @ -1064,6 +1196,14 @@ packages: | ||||||
|       supports-color: |       supports-color: | ||||||
|         optional: true |         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: |   decode-uri-component@0.2.2: | ||||||
|     resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} |     resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} | ||||||
|     engines: {node: '>=0.10'} |     engines: {node: '>=0.10'} | ||||||
|  | @ -1660,6 +1800,9 @@ packages: | ||||||
|   humanize-ms@1.2.1: |   humanize-ms@1.2.1: | ||||||
|     resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} |     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: |   iconv-corefoundation@1.1.7: | ||||||
|     resolution: {integrity: sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==} |     resolution: {integrity: sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==} | ||||||
|     engines: {node: ^8.11.2 || >=10} |     engines: {node: ^8.11.2 || >=10} | ||||||
|  | @ -1717,6 +1860,9 @@ packages: | ||||||
|     resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} |     resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} | ||||||
|     engines: {node: '>= 0.4'} |     engines: {node: '>= 0.4'} | ||||||
| 
 | 
 | ||||||
|  |   is-arrayish@0.3.2: | ||||||
|  |     resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} | ||||||
|  | 
 | ||||||
|   is-bigint@1.0.4: |   is-bigint@1.0.4: | ||||||
|     resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} |     resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} | ||||||
| 
 | 
 | ||||||
|  | @ -2488,6 +2634,13 @@ packages: | ||||||
|     resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} |     resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} | ||||||
|     engines: {node: '>=0.10.0'} |     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: |   shebang-command@2.0.0: | ||||||
|     resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} |     resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} | ||||||
|     engines: {node: '>=8'} |     engines: {node: '>=8'} | ||||||
|  | @ -2507,6 +2660,9 @@ packages: | ||||||
|     resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} |     resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} | ||||||
|     engines: {node: '>=14'} |     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: |   simple-update-notifier@2.0.0: | ||||||
|     resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} |     resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} | ||||||
|     engines: {node: '>=10'} |     engines: {node: '>=10'} | ||||||
|  | @ -2661,6 +2817,9 @@ packages: | ||||||
|     resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} |     resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} | ||||||
|     engines: {node: '>=14.14'} |     engines: {node: '>=14.14'} | ||||||
| 
 | 
 | ||||||
|  |   to-data-view@1.1.0: | ||||||
|  |     resolution: {integrity: sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==} | ||||||
|  | 
 | ||||||
|   to-object-path@0.3.0: |   to-object-path@0.3.0: | ||||||
|     resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==} |     resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==} | ||||||
|     engines: {node: '>=0.10.0'} |     engines: {node: '>=0.10.0'} | ||||||
|  | @ -2875,6 +3034,8 @@ snapshots: | ||||||
| 
 | 
 | ||||||
|   7zip-bin@5.2.0: {} |   7zip-bin@5.2.0: {} | ||||||
| 
 | 
 | ||||||
|  |   '@canvas/image-data@1.0.0': {} | ||||||
|  | 
 | ||||||
|   '@develar/schema-utils@2.6.5': |   '@develar/schema-utils@2.6.5': | ||||||
|     dependencies: |     dependencies: | ||||||
|       ajv: 6.12.6 |       ajv: 6.12.6 | ||||||
|  | @ -2982,6 +3143,11 @@ snapshots: | ||||||
|     transitivePeerDependencies: |     transitivePeerDependencies: | ||||||
|       - supports-color |       - supports-color | ||||||
| 
 | 
 | ||||||
|  |   '@emnapi/runtime@1.2.0': | ||||||
|  |     dependencies: | ||||||
|  |       tslib: 2.6.3 | ||||||
|  |     optional: true | ||||||
|  | 
 | ||||||
|   '@esbuild/aix-ppc64@0.20.2': |   '@esbuild/aix-ppc64@0.20.2': | ||||||
|     optional: true |     optional: true | ||||||
| 
 | 
 | ||||||
|  | @ -3159,6 +3325,81 @@ snapshots: | ||||||
| 
 | 
 | ||||||
|   '@humanwhocodes/object-schema@2.0.3': {} |   '@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': |   '@isaacs/cliui@8.0.2': | ||||||
|     dependencies: |     dependencies: | ||||||
|       string-width: 5.1.2 |       string-width: 5.1.2 | ||||||
|  | @ -3891,8 +4132,18 @@ snapshots: | ||||||
| 
 | 
 | ||||||
|   color-name@1.1.4: {} |   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-support@1.1.3: {} | ||||||
| 
 | 
 | ||||||
|  |   color@4.2.3: | ||||||
|  |     dependencies: | ||||||
|  |       color-convert: 2.0.1 | ||||||
|  |       color-string: 1.9.1 | ||||||
|  | 
 | ||||||
|   combined-stream@1.0.8: |   combined-stream@1.0.8: | ||||||
|     dependencies: |     dependencies: | ||||||
|       delayed-stream: 1.0.0 |       delayed-stream: 1.0.0 | ||||||
|  | @ -3981,6 +4232,17 @@ snapshots: | ||||||
|     dependencies: |     dependencies: | ||||||
|       ms: 2.1.2 |       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: {} |   decode-uri-component@0.2.2: {} | ||||||
| 
 | 
 | ||||||
|   decompress-response@6.0.0: |   decompress-response@6.0.0: | ||||||
|  | @ -4818,6 +5080,8 @@ snapshots: | ||||||
|     dependencies: |     dependencies: | ||||||
|       ms: 2.1.3 |       ms: 2.1.3 | ||||||
| 
 | 
 | ||||||
|  |   ico-endec@0.1.6: {} | ||||||
|  | 
 | ||||||
|   iconv-corefoundation@1.1.7: |   iconv-corefoundation@1.1.7: | ||||||
|     dependencies: |     dependencies: | ||||||
|       cli-truncate: 2.1.0 |       cli-truncate: 2.1.0 | ||||||
|  | @ -4873,6 +5137,8 @@ snapshots: | ||||||
|       call-bind: 1.0.7 |       call-bind: 1.0.7 | ||||||
|       get-intrinsic: 1.2.4 |       get-intrinsic: 1.2.4 | ||||||
| 
 | 
 | ||||||
|  |   is-arrayish@0.3.2: {} | ||||||
|  | 
 | ||||||
|   is-bigint@1.0.4: |   is-bigint@1.0.4: | ||||||
|     dependencies: |     dependencies: | ||||||
|       has-bigints: 1.0.2 |       has-bigints: 1.0.2 | ||||||
|  | @ -5648,6 +5914,38 @@ snapshots: | ||||||
|       is-plain-object: 2.0.4 |       is-plain-object: 2.0.4 | ||||||
|       split-string: 3.1.0 |       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: |   shebang-command@2.0.0: | ||||||
|     dependencies: |     dependencies: | ||||||
|       shebang-regex: 3.0.0 |       shebang-regex: 3.0.0 | ||||||
|  | @ -5665,6 +5963,10 @@ snapshots: | ||||||
| 
 | 
 | ||||||
|   signal-exit@4.1.0: {} |   signal-exit@4.1.0: {} | ||||||
| 
 | 
 | ||||||
|  |   simple-swizzle@0.2.2: | ||||||
|  |     dependencies: | ||||||
|  |       is-arrayish: 0.3.2 | ||||||
|  | 
 | ||||||
|   simple-update-notifier@2.0.0: |   simple-update-notifier@2.0.0: | ||||||
|     dependencies: |     dependencies: | ||||||
|       semver: 7.6.3 |       semver: 7.6.3 | ||||||
|  | @ -5849,6 +6151,8 @@ snapshots: | ||||||
| 
 | 
 | ||||||
|   tmp@0.2.3: {} |   tmp@0.2.3: {} | ||||||
| 
 | 
 | ||||||
|  |   to-data-view@1.1.0: {} | ||||||
|  | 
 | ||||||
|   to-object-path@0.3.0: |   to-object-path@0.3.0: | ||||||
|     dependencies: |     dependencies: | ||||||
|       kind-of: 3.2.2 |       kind-of: 3.2.2 | ||||||
|  |  | ||||||
|  | @ -7,6 +7,7 @@ | ||||||
| import { BuildContext, BuildOptions, context } from "esbuild"; | import { BuildContext, BuildOptions, context } from "esbuild"; | ||||||
| import { copyFile } from "fs/promises"; | import { copyFile } from "fs/promises"; | ||||||
| 
 | 
 | ||||||
|  | import { composeTrayIcons } from "./composeTrayIcons.mts"; | ||||||
| import vencordDep from "./vencordDep.mjs"; | import vencordDep from "./vencordDep.mjs"; | ||||||
| 
 | 
 | ||||||
| const isDev = process.argv.includes("--dev"); | const isDev = process.argv.includes("--dev"); | ||||||
|  | @ -49,8 +50,20 @@ async function copyVenmic() { | ||||||
|     ]).catch(() => console.warn("Failed to copy venmic. Building without venmic support")); |     ]).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([ | await Promise.all([ | ||||||
|     copyVenmic(), |     copyVenmic(), | ||||||
|  |     composeTrayIconsIfSupported(), | ||||||
|     createContext({ |     createContext({ | ||||||
|         ...NodeCommonOpts, |         ...NodeCommonOpts, | ||||||
|         entryPoints: ["src/main/index.ts"], |         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 { app, NativeImage, nativeImage } from "electron"; | ||||||
| import { join } from "path"; | 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>(); | const imgCache = new Map<string, NativeImage>(); | ||||||
| function loadBadge(index: number) { | 
 | ||||||
|     const cached = imgCache.get(index); | function loadImg(path: string) { | ||||||
|  |     const cached = imgCache.get(path); | ||||||
|     if (cached) return cached; |     if (cached) return cached; | ||||||
| 
 | 
 | ||||||
|     const img = nativeImage.createFromPath(join(BADGE_DIR, `${index}.ico`)); |     const img = nativeImage.createFromPath(path); | ||||||
|     imgCache.set(index, img); |     imgCache.set(path, img); | ||||||
| 
 | 
 | ||||||
|     return 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; | let lastIndex: null | number = -1; | ||||||
| 
 | 
 | ||||||
| export function setBadgeCount(count: number) { | 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) { |     switch (process.platform) { | ||||||
|         case "linux": |         case "linux": | ||||||
|             if (count === -1) count = 0; |             if (count === -1) count = 0; | ||||||
|             app.setBadgeCount(count); |             app.setBadgeCount(count); // Only works if libunity is installed
 | ||||||
|             break; |             break; | ||||||
|         case "darwin": |         case "darwin": | ||||||
|             if (count === 0) { |             if (count === 0) { | ||||||
|  | @ -35,13 +54,10 @@ export function setBadgeCount(count: number) { | ||||||
|             app.dock.setBadge(count === -1 ? "•" : count.toString()); |             app.dock.setBadge(count === -1 ? "•" : count.toString()); | ||||||
|             break; |             break; | ||||||
|         case "win32": |         case "win32": | ||||||
|             const [index, description] = getBadgeIndexAndDescription(count); |  | ||||||
|             if (lastIndex === index) break; |             if (lastIndex === index) break; | ||||||
| 
 | 
 | ||||||
|             lastIndex = index; |             lastIndex = index; | ||||||
| 
 | 
 | ||||||
|             // circular import shenanigans
 |  | ||||||
|             const { mainWin } = require("./mainWindow") as typeof import("./mainWindow"); |  | ||||||
|             mainWin.setOverlayIcon(index === null ? null : loadBadge(index), description); |             mainWin.setOverlayIcon(index === null ? null : loadBadge(index), description); | ||||||
|             break; |             break; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -6,6 +6,7 @@ | ||||||
| 
 | 
 | ||||||
| if (process.platform === "linux") import("./venmic"); | if (process.platform === "linux") import("./venmic"); | ||||||
| 
 | 
 | ||||||
|  | // eslint-disable-next-line simple-import-sort/imports
 | ||||||
| import { execFile } from "child_process"; | import { execFile } from "child_process"; | ||||||
| import { app, BrowserWindow, clipboard, dialog, nativeImage, RelaunchOptions, session, shell } from "electron"; | import { app, BrowserWindow, clipboard, dialog, nativeImage, RelaunchOptions, session, shell } from "electron"; | ||||||
| import { mkdirSync, readFileSync, watch } from "fs"; | import { mkdirSync, readFileSync, watch } from "fs"; | ||||||
|  | @ -15,11 +16,11 @@ import { join } from "path"; | ||||||
| import { debounce } from "shared/utils/debounce"; | import { debounce } from "shared/utils/debounce"; | ||||||
| 
 | 
 | ||||||
| import { IpcEvents } from "../shared/IpcEvents"; | import { IpcEvents } from "../shared/IpcEvents"; | ||||||
| import { setBadgeCount } from "./appBadge"; |  | ||||||
| import { autoStart } from "./autoStart"; | import { autoStart } from "./autoStart"; | ||||||
| import { VENCORD_FILES_DIR, VENCORD_QUICKCSS_FILE, VENCORD_THEMES_DIR } from "./constants"; | import { VENCORD_FILES_DIR, VENCORD_QUICKCSS_FILE, VENCORD_THEMES_DIR } from "./constants"; | ||||||
| import { mainWin } from "./mainWindow"; | import { mainWin } from "./mainWindow"; | ||||||
| import { Settings, State } from "./settings"; | import { Settings, State } from "./settings"; | ||||||
|  | import { setBadgeCount } from "./appBadge"; | ||||||
| import { handle, handleSync } from "./utils/ipcWrappers"; | import { handle, handleSync } from "./utils/ipcWrappers"; | ||||||
| import { PopoutWindows } from "./utils/popout"; | import { PopoutWindows } from "./utils/popout"; | ||||||
| import { isDeckGameMode, showGamePage } from "./utils/steamOS"; | import { isDeckGameMode, showGamePage } from "./utils/steamOS"; | ||||||
|  |  | ||||||
|  | @ -23,7 +23,7 @@ import { isTruthy } from "shared/utils/guards"; | ||||||
| import { once } from "shared/utils/once"; | import { once } from "shared/utils/once"; | ||||||
| import type { SettingsStore } from "shared/utils/SettingsStore"; | 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 { createAboutWindow } from "./about"; | ||||||
| import { initArRPC } from "./arrpc"; | import { initArRPC } from "./arrpc"; | ||||||
| import { | import { | ||||||
|  | @ -43,7 +43,6 @@ import { applyDeckKeyboardFix, askToApplySteamLayout, isDeckGameMode } from "./u | ||||||
| import { downloadVencordFiles, ensureVencordFiles } from "./utils/vencordLoader"; | import { downloadVencordFiles, ensureVencordFiles } from "./utils/vencordLoader"; | ||||||
| 
 | 
 | ||||||
| let isQuitting = false; | let isQuitting = false; | ||||||
| let tray: Tray; |  | ||||||
| 
 | 
 | ||||||
| applyDeckKeyboardFix(); | applyDeckKeyboardFix(); | ||||||
| 
 | 
 | ||||||
|  | @ -52,6 +51,7 @@ app.on("before-quit", () => { | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| export let mainWin: BrowserWindow; | export let mainWin: BrowserWindow; | ||||||
|  | export let tray: Tray | null = null; | ||||||
| 
 | 
 | ||||||
| function makeSettingsListenerHelpers<O extends object>(o: SettingsStore<O>) { | function makeSettingsListenerHelpers<O extends object>(o: SettingsStore<O>) { | ||||||
|     const listeners = new Map<(data: any) => void, PropertyKey>(); |     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.setToolTip("Vesktop"); | ||||||
|     tray.setContextMenu(trayMenu); |     tray.setContextMenu(trayMenu); | ||||||
|     tray.on("click", onTrayClick); |     tray.on("click", onTrayClick); | ||||||
|  | @ -330,8 +330,12 @@ function initWindowBoundsListeners(win: BrowserWindow) { | ||||||
| 
 | 
 | ||||||
| function initSettingsListeners(win: BrowserWindow) { | function initSettingsListeners(win: BrowserWindow) { | ||||||
|     addSettingsListener("tray", enable => { |     addSettingsListener("tray", enable => { | ||||||
|         if (enable) initTray(win); |         if (enable) { | ||||||
|         else tray?.destroy(); |             initTray(win); | ||||||
|  |         } else if (tray) { | ||||||
|  |             tray.destroy(); | ||||||
|  |             tray = null; | ||||||
|  |         } | ||||||
|     }); |     }); | ||||||
|     addSettingsListener("disableMinSize", disable => { |     addSettingsListener("disableMinSize", disable => { | ||||||
|         if (disable) { |         if (disable) { | ||||||
|  |  | ||||||
|  | @ -13,8 +13,6 @@ let GuildReadStateStore: any; | ||||||
| let NotificationSettingsStore: any; | let NotificationSettingsStore: any; | ||||||
| 
 | 
 | ||||||
| export function setBadge() { | export function setBadge() { | ||||||
|     if (Settings.store.appBadge === false) return; |  | ||||||
| 
 |  | ||||||
|     try { |     try { | ||||||
|         const mentionCount = GuildReadStateStore.getTotalMentionCount(); |         const mentionCount = GuildReadStateStore.getTotalMentionCount(); | ||||||
|         const pendingRequests = RelationshipStore.getPendingCount(); |         const pendingRequests = RelationshipStore.getPendingCount(); | ||||||
|  | @ -24,7 +22,9 @@ export function setBadge() { | ||||||
|         let totalCount = mentionCount + pendingRequests; |         let totalCount = mentionCount + pendingRequests; | ||||||
|         if (!totalCount && hasUnread && !disableUnreadBadge) totalCount = -1; |         if (!totalCount && hasUnread && !disableUnreadBadge) totalCount = -1; | ||||||
| 
 | 
 | ||||||
|         VesktopNative.app.setBadgeCount(totalCount); |         if (Settings.store.appBadge || Settings.store.trayBadge) { | ||||||
|  |             VesktopNative.app.setBadgeCount(totalCount); | ||||||
|  |         } | ||||||
|     } catch (e) { |     } catch (e) { | ||||||
|         console.error(e); |         console.error(e); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -14,6 +14,7 @@ import { isMac, isWindows } from "renderer/utils"; | ||||||
| import { AutoStartToggle } from "./AutoStartToggle"; | import { AutoStartToggle } from "./AutoStartToggle"; | ||||||
| import { DiscordBranchPicker } from "./DiscordBranchPicker"; | import { DiscordBranchPicker } from "./DiscordBranchPicker"; | ||||||
| import { NotificationBadgeToggle } from "./NotificationBadgeToggle"; | import { NotificationBadgeToggle } from "./NotificationBadgeToggle"; | ||||||
|  | import { TrayNotificationBadgeToggle } from "./TrayNotificationBadgeToggle"; | ||||||
| import { VencordLocationPicker } from "./VencordLocationPicker"; | import { VencordLocationPicker } from "./VencordLocationPicker"; | ||||||
| import { WindowsTransparencyControls } from "./WindowsTransparencyControls"; | import { WindowsTransparencyControls } from "./WindowsTransparencyControls"; | ||||||
| 
 | 
 | ||||||
|  | @ -102,7 +103,7 @@ const SettingsOptions: Record<string, Array<BooleanSetting | SettingsComponent>> | ||||||
|             defaultValue: false |             defaultValue: false | ||||||
|         } |         } | ||||||
|     ], |     ], | ||||||
|     Notifications: [NotificationBadgeToggle], |     Notifications: [NotificationBadgeToggle, TrayNotificationBadgeToggle], | ||||||
|     Miscelleanous: [ |     Miscelleanous: [ | ||||||
|         { |         { | ||||||
|             key: "arRPC", |             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 VIEW_DIR = /* @__PURE__ */ join(STATIC_DIR, "views"); | ||||||
| export const BADGE_DIR = /* @__PURE__ */ join(STATIC_DIR, "badges"); | export const BADGE_DIR = /* @__PURE__ */ join(STATIC_DIR, "badges"); | ||||||
| export const ICON_PATH = /* @__PURE__ */ join(STATIC_DIR, "icon.png"); | 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"; |     discordBranch?: "stable" | "canary" | "ptb"; | ||||||
|     transparencyOption?: "none" | "mica" | "tabbed" | "acrylic"; |     transparencyOption?: "none" | "mica" | "tabbed" | "acrylic"; | ||||||
|     tray?: boolean; |     tray?: boolean; | ||||||
|  |     trayBadge?: boolean; | ||||||
|     minimizeToTray?: boolean; |     minimizeToTray?: boolean; | ||||||
|     openLinksWithElectron?: boolean; |     openLinksWithElectron?: boolean; | ||||||
|     staticTitle?: boolean; |     staticTitle?: boolean; | ||||||
|  |  | ||||||
							
								
								
									
										1
									
								
								static/dist/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								static/dist/.gitignore
									
									
									
									
										vendored
									
									
								
							|  | @ -1,2 +1,3 @@ | ||||||
| * | * | ||||||
| !.gitignore | !.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 | ||||||
		Loading…
	
		Reference in a new issue
	
	 Albert Zhang
						Albert Zhang