electrobun 0.0.19-beta.99 → 0.1.0
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/README.md +1 -1
- package/dist/api/browser/webviewtag.ts +54 -2
- package/dist/api/bun/ElectrobunConfig.ts +171 -0
- package/dist/api/bun/core/BrowserWindow.ts +4 -0
- package/dist/api/bun/core/Tray.ts +14 -0
- package/dist/api/bun/core/Updater.ts +4 -3
- package/dist/api/bun/index.ts +2 -0
- package/dist/api/bun/proc/native.ts +107 -5
- package/dist/main.js +5 -4
- package/package.json +4 -2
- package/src/cli/index.ts +565 -148
- package/templates/hello-world/bun.lock +164 -2
- package/templates/hello-world/electrobun.config.ts +28 -0
- package/templates/hello-world/src/bun/index.ts +2 -2
- package/templates/hello-world/src/mainview/index.html +5 -6
- package/templates/hello-world/src/mainview/index.ts +1 -5
- package/templates/interactive-playground/README.md +26 -0
- package/templates/interactive-playground/assets/tray-icon.png +0 -0
- package/templates/interactive-playground/electrobun.config.ts +36 -0
- package/templates/interactive-playground/package-lock.json +36 -0
- package/templates/interactive-playground/package.json +15 -0
- package/templates/interactive-playground/src/bun/demos/files.ts +70 -0
- package/templates/interactive-playground/src/bun/demos/menus.ts +139 -0
- package/templates/interactive-playground/src/bun/demos/rpc.ts +83 -0
- package/templates/interactive-playground/src/bun/demos/system.ts +72 -0
- package/templates/interactive-playground/src/bun/demos/updates.ts +105 -0
- package/templates/interactive-playground/src/bun/demos/windows.ts +90 -0
- package/templates/interactive-playground/src/bun/index.ts +124 -0
- package/templates/interactive-playground/src/bun/types/rpc.ts +109 -0
- package/templates/interactive-playground/src/mainview/components/EventLog.ts +107 -0
- package/templates/interactive-playground/src/mainview/components/Sidebar.ts +65 -0
- package/templates/interactive-playground/src/mainview/components/Toast.ts +57 -0
- package/templates/interactive-playground/src/mainview/demos/FileDemo.ts +211 -0
- package/templates/interactive-playground/src/mainview/demos/MenuDemo.ts +102 -0
- package/templates/interactive-playground/src/mainview/demos/RPCDemo.ts +229 -0
- package/templates/interactive-playground/src/mainview/demos/TrayDemo.ts +132 -0
- package/templates/interactive-playground/src/mainview/demos/WebViewDemo.ts +411 -0
- package/templates/interactive-playground/src/mainview/demos/WindowDemo.ts +207 -0
- package/templates/interactive-playground/src/mainview/index.css +538 -0
- package/templates/interactive-playground/src/mainview/index.html +103 -0
- package/templates/interactive-playground/src/mainview/index.ts +238 -0
- package/templates/multitab-browser/README.md +34 -0
- package/templates/multitab-browser/bun.lock +224 -0
- package/templates/multitab-browser/electrobun.config.ts +32 -0
- package/templates/multitab-browser/package-lock.json +20 -0
- package/templates/multitab-browser/package.json +12 -0
- package/templates/multitab-browser/src/bun/index.ts +144 -0
- package/templates/multitab-browser/src/bun/tabManager.ts +200 -0
- package/templates/multitab-browser/src/bun/types/rpc.ts +78 -0
- package/templates/multitab-browser/src/mainview/index.css +487 -0
- package/templates/multitab-browser/src/mainview/index.html +94 -0
- package/templates/multitab-browser/src/mainview/index.ts +634 -0
- package/templates/photo-booth/README.md +108 -0
- package/templates/photo-booth/bun.lock +239 -0
- package/templates/photo-booth/electrobun.config.ts +28 -0
- package/templates/photo-booth/package.json +16 -0
- package/templates/photo-booth/src/bun/index.ts +92 -0
- package/templates/photo-booth/src/mainview/index.css +465 -0
- package/templates/photo-booth/src/mainview/index.html +124 -0
- package/templates/photo-booth/src/mainview/index.ts +499 -0
- package/tests/bun.lock +14 -0
- package/tests/electrobun.config.ts +45 -0
- package/tests/package-lock.json +36 -0
- package/tests/package.json +13 -0
- package/tests/src/bun/index.ts +100 -0
- package/tests/src/bun/test-runner.ts +508 -0
- package/tests/src/mainview/index.html +110 -0
- package/tests/src/mainview/index.ts +458 -0
- package/tests/src/mainview/styles/main.css +451 -0
- package/tests/src/testviews/tray-test.html +57 -0
- package/tests/src/testviews/webview-mask.html +114 -0
- package/tests/src/testviews/webview-navigation.html +36 -0
- package/tests/src/testviews/window-create.html +17 -0
- package/tests/src/testviews/window-events.html +29 -0
- package/tests/src/testviews/window-focus.html +37 -0
- package/tests/src/webviewtag/index.ts +11 -0
- package/templates/hello-world/electrobun.config +0 -18
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
export class WindowDemo {
|
|
2
|
+
private windows: Array<{ id: number; title: string }> = [];
|
|
3
|
+
private rpc: any;
|
|
4
|
+
|
|
5
|
+
render() {
|
|
6
|
+
return `
|
|
7
|
+
<div class="demo-section">
|
|
8
|
+
<div class="demo-header">
|
|
9
|
+
<span class="demo-icon">🪟</span>
|
|
10
|
+
<div>
|
|
11
|
+
<h2 class="demo-title">Window Management</h2>
|
|
12
|
+
<p class="demo-description">Create and manage multiple application windows with different properties</p>
|
|
13
|
+
</div>
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<div class="demo-controls">
|
|
17
|
+
<div class="control-group">
|
|
18
|
+
<label class="control-label">Width:</label>
|
|
19
|
+
<input type="number" id="window-width" class="control-input" value="800" min="200" max="2000">
|
|
20
|
+
|
|
21
|
+
<label class="control-label">Height:</label>
|
|
22
|
+
<input type="number" id="window-height" class="control-input" value="600" min="200" max="1200">
|
|
23
|
+
|
|
24
|
+
<label class="control-label">X:</label>
|
|
25
|
+
<input type="number" id="window-x" class="control-input" value="100" min="0" max="2000">
|
|
26
|
+
|
|
27
|
+
<label class="control-label">Y:</label>
|
|
28
|
+
<input type="number" id="window-y" class="control-input" value="100" min="0" max="1200">
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
<div class="control-group">
|
|
32
|
+
<label class="control-checkbox">
|
|
33
|
+
<input type="checkbox" id="window-frameless"> Frameless
|
|
34
|
+
</label>
|
|
35
|
+
<label class="control-checkbox" title="Transparency is for webviews, not windows">
|
|
36
|
+
<input type="checkbox" id="window-transparent" disabled> Transparent (WebView only)
|
|
37
|
+
</label>
|
|
38
|
+
<label class="control-checkbox" title="Not yet implemented">
|
|
39
|
+
<input type="checkbox" id="window-always-on-top" disabled> Always on Top (Coming soon)
|
|
40
|
+
</label>
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
<div class="control-group">
|
|
44
|
+
<button class="btn btn-primary" id="create-window">Create Window</button>
|
|
45
|
+
<button class="btn btn-secondary" id="get-window-list">Refresh List</button>
|
|
46
|
+
<button class="btn btn-danger" id="close-all-windows">Close All</button>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
|
|
50
|
+
<div class="demo-results">
|
|
51
|
+
<div class="results-header">Active Windows (<span id="window-count">0</span>):</div>
|
|
52
|
+
<div class="window-grid" id="window-grid">
|
|
53
|
+
<div class="no-windows" style="grid-column: 1 / -1; text-align: center; color: #718096; padding: 2rem;">
|
|
54
|
+
No windows created yet. Use the controls above to create your first window.
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
initialize(rpc: any) {
|
|
63
|
+
this.rpc = rpc; // Store RPC reference
|
|
64
|
+
|
|
65
|
+
// Get DOM elements
|
|
66
|
+
const createBtn = document.getElementById('create-window');
|
|
67
|
+
const refreshBtn = document.getElementById('get-window-list');
|
|
68
|
+
const closeAllBtn = document.getElementById('close-all-windows');
|
|
69
|
+
|
|
70
|
+
// Event listeners
|
|
71
|
+
createBtn?.addEventListener('click', async () => {
|
|
72
|
+
const width = parseInt((document.getElementById('window-width') as HTMLInputElement).value);
|
|
73
|
+
const height = parseInt((document.getElementById('window-height') as HTMLInputElement).value);
|
|
74
|
+
const x = parseInt((document.getElementById('window-x') as HTMLInputElement).value);
|
|
75
|
+
const y = parseInt((document.getElementById('window-y') as HTMLInputElement).value);
|
|
76
|
+
const frameless = (document.getElementById('window-frameless') as HTMLInputElement).checked;
|
|
77
|
+
// Transparent and alwaysOnTop are disabled for now
|
|
78
|
+
// const transparent = (document.getElementById('window-transparent') as HTMLInputElement).checked;
|
|
79
|
+
// const alwaysOnTop = (document.getElementById('window-always-on-top') as HTMLInputElement).checked;
|
|
80
|
+
|
|
81
|
+
try {
|
|
82
|
+
const result = await rpc.request.createWindow({
|
|
83
|
+
width, height, x, y, frameless
|
|
84
|
+
});
|
|
85
|
+
console.log('Window created:', result);
|
|
86
|
+
} catch (error) {
|
|
87
|
+
console.error('Error creating window:', error);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
refreshBtn?.addEventListener('click', async () => {
|
|
92
|
+
try {
|
|
93
|
+
const windows = await rpc.request.getWindowList();
|
|
94
|
+
this.updateWindowList(windows);
|
|
95
|
+
} catch (error) {
|
|
96
|
+
console.error('Error getting window list:', error);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
closeAllBtn?.addEventListener('click', async () => {
|
|
101
|
+
for (const window of this.windows) {
|
|
102
|
+
try {
|
|
103
|
+
await rpc.request.closeWindow(window.id);
|
|
104
|
+
} catch (error) {
|
|
105
|
+
console.error(`Error closing window ${window.id}:`, error);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// Load initial window list
|
|
111
|
+
this.loadWindowList(rpc);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
private async loadWindowList(rpc: any) {
|
|
115
|
+
try {
|
|
116
|
+
const windows = await rpc.request.getWindowList();
|
|
117
|
+
this.updateWindowList(windows);
|
|
118
|
+
} catch (error) {
|
|
119
|
+
console.error('Error loading window list:', error);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
updateWindowList(windows: Array<{ id: number; title: string }>) {
|
|
124
|
+
this.windows = windows;
|
|
125
|
+
const grid = document.getElementById('window-grid');
|
|
126
|
+
const count = document.getElementById('window-count');
|
|
127
|
+
|
|
128
|
+
if (!grid || !count) return;
|
|
129
|
+
|
|
130
|
+
count.textContent = windows.length.toString();
|
|
131
|
+
|
|
132
|
+
if (windows.length === 0) {
|
|
133
|
+
grid.innerHTML = `
|
|
134
|
+
<div class="no-windows" style="grid-column: 1 / -1; text-align: center; color: #718096; padding: 2rem;">
|
|
135
|
+
No windows created yet. Use the controls above to create your first window.
|
|
136
|
+
</div>
|
|
137
|
+
`;
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
grid.innerHTML = windows.map(window => `
|
|
142
|
+
<div class="window-card" data-window-id="${window.id}">
|
|
143
|
+
<div class="window-preview">Window Preview</div>
|
|
144
|
+
<div class="window-title">${window.title}</div>
|
|
145
|
+
<div class="window-actions">
|
|
146
|
+
<button class="btn btn-small btn-secondary focus-window" data-window-id="${window.id}">Focus</button>
|
|
147
|
+
<button class="btn btn-small btn-danger close-window" data-window-id="${window.id}">×</button>
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
`).join('');
|
|
151
|
+
|
|
152
|
+
// Add event listeners for window actions
|
|
153
|
+
this.attachWindowActionListeners();
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
private attachWindowActionListeners() {
|
|
157
|
+
const focusButtons = document.querySelectorAll('.focus-window');
|
|
158
|
+
const closeButtons = document.querySelectorAll('.close-window');
|
|
159
|
+
|
|
160
|
+
focusButtons.forEach(btn => {
|
|
161
|
+
btn.addEventListener('click', async (e) => {
|
|
162
|
+
const id = parseInt((e.target as HTMLElement).getAttribute('data-window-id') || '0');
|
|
163
|
+
try {
|
|
164
|
+
await this.rpc.request.focusWindow(id);
|
|
165
|
+
console.log(`Focused window ${id}`);
|
|
166
|
+
} catch (error) {
|
|
167
|
+
console.error(`Error focusing window ${id}:`, error);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
closeButtons.forEach(btn => {
|
|
173
|
+
btn.addEventListener('click', async (e) => {
|
|
174
|
+
const id = parseInt((e.target as HTMLElement).getAttribute('data-window-id') || '0');
|
|
175
|
+
try {
|
|
176
|
+
await this.rpc.request.closeWindow(id);
|
|
177
|
+
console.log(`Closed window ${id}`);
|
|
178
|
+
// Remove from local list
|
|
179
|
+
this.windows = this.windows.filter(w => w.id !== id);
|
|
180
|
+
this.updateWindowList(this.windows);
|
|
181
|
+
} catch (error) {
|
|
182
|
+
console.error(`Error closing window ${id}:`, error);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Handle events from the backend
|
|
189
|
+
onWindowCreated(data: { id: number; title: string }) {
|
|
190
|
+
this.windows.push(data);
|
|
191
|
+
this.updateWindowList(this.windows);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
onWindowClosed(data: { id: number }) {
|
|
195
|
+
this.windows = this.windows.filter(w => w.id !== data.id);
|
|
196
|
+
this.updateWindowList(this.windows);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
onWindowFocused(data: { id: number }) {
|
|
200
|
+
// Visual feedback for focused window
|
|
201
|
+
const windowCard = document.querySelector(`[data-window-id="${data.id}"]`);
|
|
202
|
+
if (windowCard) {
|
|
203
|
+
windowCard.classList.add('focused');
|
|
204
|
+
setTimeout(() => windowCard.classList.remove('focused'), 1000);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|