electrobun 0.0.19-beta.11 → 0.0.19-beta.111
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/BUILD.md +90 -0
- package/bin/electrobun.cjs +39 -14
- package/debug.js +5 -0
- package/dist/api/browser/builtinrpcSchema.ts +19 -0
- package/dist/api/browser/index.ts +409 -0
- package/dist/api/browser/rpc/webview.ts +79 -0
- package/dist/api/browser/stylesAndElements.ts +3 -0
- package/dist/api/browser/webviewtag.ts +534 -0
- package/dist/api/bun/core/ApplicationMenu.ts +66 -0
- package/dist/api/bun/core/BrowserView.ts +349 -0
- package/dist/api/bun/core/BrowserWindow.ts +191 -0
- package/dist/api/bun/core/ContextMenu.ts +67 -0
- package/dist/api/bun/core/Paths.ts +5 -0
- package/dist/api/bun/core/Socket.ts +181 -0
- package/dist/api/bun/core/Tray.ts +107 -0
- package/dist/api/bun/core/Updater.ts +680 -0
- package/dist/api/bun/core/Utils.ts +48 -0
- package/dist/api/bun/events/ApplicationEvents.ts +14 -0
- package/dist/api/bun/events/event.ts +29 -0
- package/dist/api/bun/events/eventEmitter.ts +45 -0
- package/dist/api/bun/events/trayEvents.ts +9 -0
- package/dist/api/bun/events/webviewEvents.ts +16 -0
- package/dist/api/bun/events/windowEvents.ts +12 -0
- package/dist/api/bun/index.ts +45 -0
- package/dist/api/bun/proc/linux.md +43 -0
- package/dist/api/bun/proc/native.ts +1220 -0
- package/dist/api/shared/platform.ts +48 -0
- package/dist/main.js +54 -0
- package/package.json +9 -6
- package/src/cli/index.ts +1227 -223
- package/templates/hello-world/README.md +57 -0
- package/templates/hello-world/bun.lock +63 -0
- package/templates/hello-world/electrobun.config +18 -0
- package/templates/hello-world/package.json +16 -0
- package/templates/hello-world/src/bun/index.ts +15 -0
- package/templates/hello-world/src/mainview/index.css +124 -0
- package/templates/hello-world/src/mainview/index.html +50 -0
- package/templates/hello-world/src/mainview/index.ts +24 -0
- package/templates/photo-booth/README.md +108 -0
- package/templates/photo-booth/bun.lock +225 -0
- package/templates/photo-booth/electrobun.config +28 -0
- package/templates/photo-booth/package.json +16 -0
- package/templates/photo-booth/src/bun/index.ts +91 -0
- package/templates/photo-booth/src/mainview/index.css +353 -0
- package/templates/photo-booth/src/mainview/index.html +95 -0
- package/templates/photo-booth/src/mainview/index.ts +584 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Electrobun Hello World
|
|
2
|
+
|
|
3
|
+
A simple Electrobun app to get you started with the framework.
|
|
4
|
+
|
|
5
|
+
## What You'll See
|
|
6
|
+
|
|
7
|
+
This hello world app demonstrates:
|
|
8
|
+
- **Native Window**: A cross-platform desktop window
|
|
9
|
+
- **Web-based UI**: Modern HTML, CSS, and JavaScript interface
|
|
10
|
+
- **Simple Architecture**: Clean separation between Bun process and UI
|
|
11
|
+
|
|
12
|
+
## Getting Started
|
|
13
|
+
|
|
14
|
+
1. Install dependencies:
|
|
15
|
+
```bash
|
|
16
|
+
bun install
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
2. Run in development mode:
|
|
20
|
+
```bash
|
|
21
|
+
bun run dev
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
3. Build for production:
|
|
25
|
+
```bash
|
|
26
|
+
bun run build
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Project Structure
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
src/
|
|
33
|
+
├── bun/
|
|
34
|
+
│ └── index.ts # Main process - creates and manages windows
|
|
35
|
+
└── mainview/
|
|
36
|
+
├── index.html # Your app's UI
|
|
37
|
+
├── index.css # Styles
|
|
38
|
+
└── index.ts # View logic
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Next Steps
|
|
42
|
+
|
|
43
|
+
Ready to build something more complex? Check out:
|
|
44
|
+
|
|
45
|
+
- **[Documentation](https://docs.electrobun.dev)** - Learn about all Electrobun features
|
|
46
|
+
- **[Examples](https://github.com/blackboardsh/electrobun/tree/main/playground)** - See advanced features like RPC, menus, and system tray
|
|
47
|
+
- **[GitHub](https://github.com/blackboardsh/electrobun)** - Star the repo and join the community
|
|
48
|
+
|
|
49
|
+
### Add More Features
|
|
50
|
+
|
|
51
|
+
Want to extend this app? Try adding:
|
|
52
|
+
- RPC communication between Bun and webview
|
|
53
|
+
- Native menus and system tray
|
|
54
|
+
- File dialogs and system integration
|
|
55
|
+
- Multiple windows and views
|
|
56
|
+
|
|
57
|
+
Happy building! 🚀
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"lockfileVersion": 1,
|
|
3
|
+
"workspaces": {
|
|
4
|
+
"": {
|
|
5
|
+
"name": "electrobun-hello-world",
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"electrobun": "latest",
|
|
8
|
+
},
|
|
9
|
+
"devDependencies": {
|
|
10
|
+
"@types/bun": "latest",
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
"packages": {
|
|
15
|
+
"@oneidentity/zstd-js": ["@oneidentity/zstd-js@1.0.3", "", { "dependencies": { "@types/emscripten": "^1.39.4" } }, "sha512-Jm6sawqxLzBrjC4sg2BeXToa33yPzUmq20CKsehKY2++D/gHb/oSwVjNgT+RH4vys+r8FynrgcNzGwhZWMLzfQ=="],
|
|
16
|
+
|
|
17
|
+
"@types/bun": ["@types/bun@1.2.19", "", { "dependencies": { "bun-types": "1.2.19" } }, "sha512-d9ZCmrH3CJ2uYKXQIUuZ/pUnTqIvLDS0SK7pFmbx8ma+ziH/FRMoAq5bYpRG7y+w1gl+HgyNZbtqgMq4W4e2Lg=="],
|
|
18
|
+
|
|
19
|
+
"@types/emscripten": ["@types/emscripten@1.40.1", "", {}, "sha512-sr53lnYkQNhjHNN0oJDdUm5564biioI5DuOpycufDVK7D3y+GR3oUswe2rlwY1nPNyusHbrJ9WoTyIHl4/Bpwg=="],
|
|
20
|
+
|
|
21
|
+
"@types/filesystem": ["@types/filesystem@0.0.36", "", { "dependencies": { "@types/filewriter": "*" } }, "sha512-vPDXOZuannb9FZdxgHnqSwAG/jvdGM8Wq+6N4D/d80z+D4HWH+bItqsZaVRQykAn6WEVeEkLm2oQigyHtgb0RA=="],
|
|
22
|
+
|
|
23
|
+
"@types/filewriter": ["@types/filewriter@0.0.33", "", {}, "sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g=="],
|
|
24
|
+
|
|
25
|
+
"@types/har-format": ["@types/har-format@1.2.16", "", {}, "sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A=="],
|
|
26
|
+
|
|
27
|
+
"@types/node": ["@types/node@24.1.0", "", { "dependencies": { "undici-types": "~7.8.0" } }, "sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w=="],
|
|
28
|
+
|
|
29
|
+
"@types/react": ["@types/react@19.1.9", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-WmdoynAX8Stew/36uTSVMcLJJ1KRh6L3IZRx1PZ7qJtBqT3dYTgyDTx8H1qoRghErydW7xw9mSJ3wS//tCRpFA=="],
|
|
30
|
+
|
|
31
|
+
"@types/webextension-polyfill": ["@types/webextension-polyfill@0.12.3", "", {}, "sha512-F58aDVSeN/MjUGazXo/cPsmR76EvqQhQ1v4x23hFjUX0cfAJYE+JBWwiOGW36/VJGGxoH74sVlRIF3z7SJCKyg=="],
|
|
32
|
+
|
|
33
|
+
"browser-namespace": ["browser-namespace@1.4.0", "", { "dependencies": { "@types/filesystem": "*", "@types/har-format": "*", "@types/webextension-polyfill": "*" } }, "sha512-9b4yNTNs+8HVPssSq8RSZMRunf+G4cVQ2PMtOTn+uEVFOW5C0Uo+eGXuJ5LfxS1UDph5oAdWj92thPyxVhpqXg=="],
|
|
34
|
+
|
|
35
|
+
"bun-types": ["bun-types@1.2.19", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-uAOTaZSPuYsWIXRpj7o56Let0g/wjihKCkeRqUBhlLVM/Bt+Fj9xTo+LhC1OV1XDaGkz4hNC80et5xgy+9KTHQ=="],
|
|
36
|
+
|
|
37
|
+
"chownr": ["chownr@2.0.0", "", {}, "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="],
|
|
38
|
+
|
|
39
|
+
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
|
40
|
+
|
|
41
|
+
"electrobun": ["electrobun@0.0.18", "", { "dependencies": { "@oneidentity/zstd-js": "^1.0.3", "rpc-anywhere": "1.5.0", "tar": "^6.2.1" }, "bin": { "electrobun": "dist/electrobun" } }, "sha512-RyMNGcAaHklicZlJToGfN3fVZGKHpxZv6o8S96TK9tHSY/SRze5bNPIGUnY9wr/BbWuQW5gGUGaVIWWqa5NSZQ=="],
|
|
42
|
+
|
|
43
|
+
"fs-minipass": ["fs-minipass@2.1.0", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg=="],
|
|
44
|
+
|
|
45
|
+
"minipass": ["minipass@5.0.0", "", {}, "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="],
|
|
46
|
+
|
|
47
|
+
"minizlib": ["minizlib@2.1.2", "", { "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" } }, "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg=="],
|
|
48
|
+
|
|
49
|
+
"mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="],
|
|
50
|
+
|
|
51
|
+
"rpc-anywhere": ["rpc-anywhere@1.5.0", "", { "dependencies": { "browser-namespace": "^1.4.0" } }, "sha512-ZYrB0foAM4oE7oBnUH3BL7LwtW9d6+RkzL/rFnjj8GCaFt5c81Rbw6oVl6u9AMsGONsKeJX0mL62TpbPXSO6og=="],
|
|
52
|
+
|
|
53
|
+
"tar": ["tar@6.2.1", "", { "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" } }, "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A=="],
|
|
54
|
+
|
|
55
|
+
"undici-types": ["undici-types@7.8.0", "", {}, "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw=="],
|
|
56
|
+
|
|
57
|
+
"yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="],
|
|
58
|
+
|
|
59
|
+
"fs-minipass/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
|
60
|
+
|
|
61
|
+
"minizlib/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"app": {
|
|
3
|
+
"name": "hello-world",
|
|
4
|
+
"identifier": "helloworld.electrobun.dev",
|
|
5
|
+
"version": "0.0.1"
|
|
6
|
+
},
|
|
7
|
+
"build": {
|
|
8
|
+
"mac": {
|
|
9
|
+
"bundleCEF": true
|
|
10
|
+
},
|
|
11
|
+
"linux": {
|
|
12
|
+
"bundleCEF": true
|
|
13
|
+
},
|
|
14
|
+
"win": {
|
|
15
|
+
"bundleCEF": true
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "electrobun-hello-world",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A simple Electrobun app showcasing core features",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "electrobun dev",
|
|
7
|
+
"build": "electrobun build",
|
|
8
|
+
"start": "bun run build && bun run dev"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"electrobun": "latest"
|
|
12
|
+
},
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"@types/bun": "latest"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BrowserWindow } from "electrobun/bun";
|
|
2
|
+
|
|
3
|
+
// Create the main application window
|
|
4
|
+
const mainWindow = new BrowserWindow({
|
|
5
|
+
title: "Hello Electrobun!",
|
|
6
|
+
url: "views://main/index.html",
|
|
7
|
+
frame: {
|
|
8
|
+
width: 800,
|
|
9
|
+
height: 600,
|
|
10
|
+
x: 200,
|
|
11
|
+
y: 200,
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
console.log("Hello Electrobun app started!");
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
* {
|
|
2
|
+
box-sizing: border-box;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
body {
|
|
6
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
|
7
|
+
margin: 0;
|
|
8
|
+
padding: 0;
|
|
9
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
10
|
+
color: #333;
|
|
11
|
+
min-height: 100vh;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.container {
|
|
15
|
+
max-width: 800px;
|
|
16
|
+
margin: 0 auto;
|
|
17
|
+
padding: 40px 20px;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
h1 {
|
|
21
|
+
color: white;
|
|
22
|
+
font-size: 3rem;
|
|
23
|
+
text-align: center;
|
|
24
|
+
margin-bottom: 8px;
|
|
25
|
+
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.subtitle {
|
|
29
|
+
color: rgba(255, 255, 255, 0.9);
|
|
30
|
+
font-size: 1.25rem;
|
|
31
|
+
text-align: center;
|
|
32
|
+
margin-top: 0;
|
|
33
|
+
margin-bottom: 40px;
|
|
34
|
+
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.welcome-section {
|
|
38
|
+
background: white;
|
|
39
|
+
border-radius: 12px;
|
|
40
|
+
padding: 30px;
|
|
41
|
+
margin: 30px 0;
|
|
42
|
+
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
|
|
43
|
+
line-height: 1.6;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
h2 {
|
|
47
|
+
color: #2563eb;
|
|
48
|
+
margin-top: 30px;
|
|
49
|
+
margin-bottom: 15px;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
ul {
|
|
53
|
+
margin: 20px 0;
|
|
54
|
+
padding-left: 20px;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
li {
|
|
58
|
+
margin: 8px 0;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.links {
|
|
62
|
+
display: flex;
|
|
63
|
+
gap: 15px;
|
|
64
|
+
margin: 25px 0;
|
|
65
|
+
flex-wrap: wrap;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.doc-link {
|
|
69
|
+
display: inline-block;
|
|
70
|
+
background: #2563eb;
|
|
71
|
+
color: white;
|
|
72
|
+
text-decoration: none;
|
|
73
|
+
padding: 12px 20px;
|
|
74
|
+
border-radius: 8px;
|
|
75
|
+
font-weight: 500;
|
|
76
|
+
transition: all 0.2s ease;
|
|
77
|
+
box-shadow: 0 2px 4px rgba(37, 99, 235, 0.2);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.doc-link:hover {
|
|
81
|
+
background: #1d4ed8;
|
|
82
|
+
transform: translateY(-1px);
|
|
83
|
+
box-shadow: 0 4px 8px rgba(37, 99, 235, 0.3);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
code {
|
|
87
|
+
background: #f1f5f9;
|
|
88
|
+
color: #475569;
|
|
89
|
+
padding: 2px 6px;
|
|
90
|
+
border-radius: 4px;
|
|
91
|
+
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
|
92
|
+
font-size: 0.9em;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.footer {
|
|
96
|
+
text-align: center;
|
|
97
|
+
color: rgba(255, 255, 255, 0.8);
|
|
98
|
+
margin-top: 40px;
|
|
99
|
+
padding: 20px;
|
|
100
|
+
background: rgba(255, 255, 255, 0.1);
|
|
101
|
+
border-radius: 8px;
|
|
102
|
+
backdrop-filter: blur(10px);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.footer p {
|
|
106
|
+
margin: 8px 0;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/* Dark mode support */
|
|
110
|
+
@media (prefers-color-scheme: dark) {
|
|
111
|
+
.welcome-section {
|
|
112
|
+
background: #1f2937;
|
|
113
|
+
color: #f3f4f6;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
h2 {
|
|
117
|
+
color: #60a5fa;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
code {
|
|
121
|
+
background: #374151;
|
|
122
|
+
color: #d1d5db;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Hello Electrobun!</title>
|
|
7
|
+
<link rel="stylesheet" href="index.css">
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div class="container">
|
|
11
|
+
<h1>Hello Electrobun! 🎉</h1>
|
|
12
|
+
<p class="subtitle">A fast, cross-platform desktop app framework</p>
|
|
13
|
+
|
|
14
|
+
<div class="welcome-section">
|
|
15
|
+
<p>Welcome to your first Electrobun app! This framework combines the power of Bun with native desktop capabilities.</p>
|
|
16
|
+
|
|
17
|
+
<h2>What is Electrobun?</h2>
|
|
18
|
+
<ul>
|
|
19
|
+
<li><strong>Fast:</strong> Built on Bun's lightning-fast JavaScript runtime</li>
|
|
20
|
+
<li><strong>Native:</strong> Access to system APIs like menus, trays, and file dialogs</li>
|
|
21
|
+
<li><strong>Cross-platform:</strong> Works on macOS, Windows, and Linux</li>
|
|
22
|
+
<li><strong>Web-based UI:</strong> Use familiar HTML, CSS, and JavaScript for your interface</li>
|
|
23
|
+
</ul>
|
|
24
|
+
|
|
25
|
+
<h2>Get Started</h2>
|
|
26
|
+
<p>Ready to build something amazing? Check out the documentation and examples:</p>
|
|
27
|
+
|
|
28
|
+
<div class="links">
|
|
29
|
+
<a href="https://docs.electrobun.dev" target="_blank" class="doc-link">
|
|
30
|
+
📚 Documentation
|
|
31
|
+
</a>
|
|
32
|
+
<a href="https://github.com/blackboardsh/electrobun" target="_blank" class="doc-link">
|
|
33
|
+
🐙 GitHub Repository
|
|
34
|
+
</a>
|
|
35
|
+
<a href="https://docs.electrobun.dev/examples" target="_blank" class="doc-link">
|
|
36
|
+
💡 Examples
|
|
37
|
+
</a>
|
|
38
|
+
<button id="testCameraBtn" class="doc-link" style="background: #007AFF; color: white; border: none; cursor: pointer;">
|
|
39
|
+
🎥 Test Camera Permission
|
|
40
|
+
</button>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<div class="footer">
|
|
45
|
+
<p>Edit <code>src/bun/index.ts</code> and <code>src/mainview/</code> to customize your app</p>
|
|
46
|
+
<p>Press F12 to open DevTools</p>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
</body>
|
|
50
|
+
</html>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Simple Hello World - no RPC needed for this basic template
|
|
2
|
+
console.log("Hello Electrobun view loaded!");
|
|
3
|
+
|
|
4
|
+
// Test camera permission dialog
|
|
5
|
+
document.getElementById('testCameraBtn')?.addEventListener('click', async () => {
|
|
6
|
+
console.log('Testing camera permission...');
|
|
7
|
+
try {
|
|
8
|
+
const stream = await navigator.mediaDevices.getUserMedia({
|
|
9
|
+
video: true,
|
|
10
|
+
audio: false
|
|
11
|
+
});
|
|
12
|
+
console.log('Camera permission granted:', stream);
|
|
13
|
+
alert('Camera permission granted! Check console for stream details.');
|
|
14
|
+
|
|
15
|
+
// Stop the stream immediately since we're just testing
|
|
16
|
+
stream.getTracks().forEach(track => track.stop());
|
|
17
|
+
} catch (error) {
|
|
18
|
+
console.error('Camera permission denied or failed:', error);
|
|
19
|
+
alert(`Camera permission failed: ${error.message}`);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
// You can add interactive functionality here
|
|
24
|
+
// For RPC communication with the Bun process, check out the playground example
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Photo Booth Template
|
|
2
|
+
|
|
3
|
+
A cross-platform desktop photo booth application built with Electrobun. This template demonstrates how to use the getUserMedia API to access the user's camera, capture photos, and save them to disk.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Camera Access**: Uses getUserMedia to access and display live camera feed
|
|
8
|
+
- **Photo Capture**: Take instant photos or use a 3-second timer
|
|
9
|
+
- **Camera Selection**: Switch between multiple cameras if available
|
|
10
|
+
- **Photo Gallery**: View all captured photos in a grid layout
|
|
11
|
+
- **Full-Screen Preview**: Click any photo to view it in full size
|
|
12
|
+
- **Save to Disk**: Save photos to your computer with a native file dialog
|
|
13
|
+
- **Delete Photos**: Remove unwanted photos from the gallery
|
|
14
|
+
- **Modern UI**: Clean, responsive interface with dark theme
|
|
15
|
+
|
|
16
|
+
## Project Structure
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
src/
|
|
20
|
+
├── bun/
|
|
21
|
+
│ └── index.ts # Main process - handles window creation and file operations
|
|
22
|
+
└── mainview/
|
|
23
|
+
├── index.html # Photo booth UI structure
|
|
24
|
+
├── index.css # Styling
|
|
25
|
+
└── index.ts # Camera logic and photo management
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Getting Started
|
|
29
|
+
|
|
30
|
+
### Development Mode
|
|
31
|
+
```bash
|
|
32
|
+
bun dev
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Build for Production
|
|
36
|
+
```bash
|
|
37
|
+
bun build
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Run the Built App
|
|
41
|
+
```bash
|
|
42
|
+
bun start
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## How It Works
|
|
46
|
+
|
|
47
|
+
### Camera Access
|
|
48
|
+
The app requests camera permission on startup using the Web MediaDevices API:
|
|
49
|
+
```typescript
|
|
50
|
+
const stream = await navigator.mediaDevices.getUserMedia({
|
|
51
|
+
video: { width: { ideal: 1920 }, height: { ideal: 1080 } },
|
|
52
|
+
audio: false
|
|
53
|
+
});
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Photo Capture
|
|
57
|
+
Photos are captured by drawing the current video frame to a canvas:
|
|
58
|
+
1. Video stream is displayed in a `<video>` element
|
|
59
|
+
2. When capture is triggered, the current frame is drawn to a hidden `<canvas>`
|
|
60
|
+
3. Canvas is converted to a data URL (base64 PNG)
|
|
61
|
+
4. Photo is stored in memory and displayed in the gallery
|
|
62
|
+
|
|
63
|
+
### File Saving
|
|
64
|
+
The save functionality uses Electrobun's IPC to communicate between renderer and main process:
|
|
65
|
+
1. Renderer sends the photo data URL to main process
|
|
66
|
+
2. Main process shows a native save dialog
|
|
67
|
+
3. If user confirms, the base64 data is converted to a buffer and written to disk
|
|
68
|
+
|
|
69
|
+
## Customization
|
|
70
|
+
|
|
71
|
+
### Styling
|
|
72
|
+
Modify `src/mainview/index.css` to customize the appearance. The app uses CSS variables for easy theming.
|
|
73
|
+
|
|
74
|
+
### Camera Settings
|
|
75
|
+
Adjust camera constraints in `index.ts` to change resolution or other parameters:
|
|
76
|
+
```typescript
|
|
77
|
+
const constraints = {
|
|
78
|
+
video: {
|
|
79
|
+
width: { ideal: 1920 },
|
|
80
|
+
height: { ideal: 1080 },
|
|
81
|
+
facingMode: 'user' // or 'environment' for rear camera
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Storage
|
|
87
|
+
Currently photos are stored in memory. You could extend this to:
|
|
88
|
+
- Save photos automatically to a specific folder
|
|
89
|
+
- Store photo metadata in a database
|
|
90
|
+
- Upload photos to a cloud service
|
|
91
|
+
|
|
92
|
+
## Security Considerations
|
|
93
|
+
|
|
94
|
+
- Camera permissions are requested explicitly
|
|
95
|
+
- Photos are only saved when user confirms via native dialog
|
|
96
|
+
- No network requests are made
|
|
97
|
+
- All photo data stays local to the device
|
|
98
|
+
|
|
99
|
+
## Browser Compatibility
|
|
100
|
+
|
|
101
|
+
This template uses modern web APIs that require:
|
|
102
|
+
- Secure context (HTTPS or localhost)
|
|
103
|
+
- Modern browser with getUserMedia support
|
|
104
|
+
- Camera/webcam hardware
|
|
105
|
+
|
|
106
|
+
## License
|
|
107
|
+
|
|
108
|
+
This template is part of the Electrobun project and follows the same license terms.
|