Skip to content

Commit de4b8ea

Browse files
committed
fix: icons not showing on M cpus without rosetta
Closes Browser icons not loading #539
1 parent a23b646 commit de4b8ea

File tree

5 files changed

+157
-31
lines changed

5 files changed

+157
-31
lines changed

.ncurc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"reject": ["file-icon"]
2+
"reject": []
33
}

forge.config.cjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module.exports = {
22
packagerConfig: {
33
appBundleId: 'com.browserosaurus',
4-
asar: true,
4+
asar: false,
55
appCategoryType: 'public.app-category.developer-tools',
66
packageManager: 'npm',
77
extendInfo: 'plist/Info.plist',
@@ -61,7 +61,7 @@ module.exports = {
6161
'@timfish/forge-externals-plugin',
6262
{
6363
externals: ['file-icon'],
64-
includeDeps: true,
64+
includeDeps: false,
6565
},
6666
],
6767
],

package-lock.json

Lines changed: 122 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
"clsx": "^1.2.1",
5050
"electron-log": "^4.4.8",
5151
"fast-deep-equal": "^3.1.3",
52-
"file-icon": "^4.0.0",
52+
"file-icon": "^5.1.0",
5353
"immer": "^9.0.15",
5454
"lowdb": "^3.0.0",
5555
"picocolors": "^1.0.0",

src/main/utils/get-app-icons.ts

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,49 @@
11
import log from 'electron-log'
2-
// @ts-expect-error -- no types provided for file-icon
3-
import fileIcon from 'file-icon'
2+
import { execFile } from 'node:child_process'
3+
import path from 'node:path'
4+
import { promisify } from 'node:util'
45

56
import type { AppId } from '../../config/apps'
67
import type { Storage } from '../../shared/state/reducer.storage'
78
import { gotAppIcons } from '../state/actions'
89
import { dispatch } from '../state/store'
910

11+
const execFileP = promisify(execFile)
12+
13+
const binary = path.join(
14+
__dirname,
15+
'..',
16+
'..',
17+
'node_modules',
18+
'file-icon',
19+
'file-icon',
20+
)
21+
22+
const HUNDRED_MEGABYTES = 1024 * 1024 * 100
23+
24+
async function getIconDataURI(file: string, size: number): Promise<string> {
25+
const { stdout: buffer } = await execFileP(
26+
binary,
27+
[JSON.stringify([{ appOrPID: file, size }])],
28+
{ encoding: null, maxBuffer: HUNDRED_MEGABYTES },
29+
)
30+
31+
return `data:image/png;base64,${buffer.toString('base64')}`
32+
}
33+
1034
export async function getAppIcons(apps: Storage['apps']): Promise<void> {
1135
try {
12-
const buffers: (Buffer | null)[] = []
36+
const icons: Partial<Record<AppId, string>> = {}
1337

1438
for await (const app of apps) {
1539
try {
16-
const buffer = await fileIcon.buffer(app.id, { size: 64 })
17-
buffers.push(buffer)
18-
} catch {
19-
buffers.push(null)
40+
const dataURI = await getIconDataURI(app.id, 64)
41+
icons[app.id] = dataURI
42+
} catch (error: unknown) {
43+
log.warn(error)
2044
}
2145
}
2246

23-
const icons: Partial<Record<AppId, string>> = {}
24-
25-
for (const [index, buffer] of Object.entries(buffers)) {
26-
icons[apps[Number(index)].id] = buffer
27-
? `data:image/png;base64,${buffer.toString('base64')}`
28-
: ''
29-
}
30-
3147
dispatch(gotAppIcons(icons))
3248
} catch (error: unknown) {
3349
log.error(error)

0 commit comments

Comments
 (0)