Skip to content

Commit 1932890

Browse files
init
0 parents  commit 1932890

11 files changed

Lines changed: 6933 additions & 0 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
dist

assets/background.png

26.1 KB
Loading

icon.png

18.7 KB
Loading

main.js

Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
const {app, screen, shell, BrowserWindow, BrowserView, ipcMain, dialog, clipboard } = require('electron')
2+
const Store = require('electron-store');
3+
const windowStateKeeper = require('electron-window-state');
4+
const fs = require('fs')
5+
const path = require("path")
6+
const Pinokiod = require("pinokiod")
7+
const is_mac = process.platform.startsWith("darwin")
8+
var mainWindow;
9+
var root_url;
10+
var wins = {}
11+
var pinned = {}
12+
var launched
13+
const PORT = 4200
14+
const store = new Store();
15+
const pinokiod = new Pinokiod({
16+
port: PORT,
17+
agent: "electron",
18+
store
19+
})
20+
const titleBarOverlay = (theme) => {
21+
if (is_mac) {
22+
return false
23+
} else {
24+
if (theme === "dark") {
25+
return {
26+
color: "#111",
27+
symbolColor: "white"
28+
}
29+
} else if (theme === "default") {
30+
if (launched) {
31+
return {
32+
color: "#F5F4FA",
33+
symbolColor: "black"
34+
}
35+
} else {
36+
return {
37+
color: "royalblue",
38+
symbolColor: "white"
39+
}
40+
}
41+
}
42+
return {
43+
color: "white",
44+
symbolColor: "black"
45+
}
46+
}
47+
}
48+
const attach = (event, webContents) => {
49+
let wc = webContents
50+
webContents.on('will-navigate', (event, url) => {
51+
if (!webContents.opened) {
52+
// The first time this view is being used, set the "opened" to true, and don't do anything
53+
// The next time the view navigates, "the "opened" is already true, so trigger the URL open logic
54+
// - if the new URL has the same host as the app's url, open in app
55+
// - if it's a remote host, open in external browser
56+
webContents.opened = true
57+
} else {
58+
let host = new URL(url).host
59+
let localhost = new URL(root_url).host
60+
if (host !== localhost) {
61+
event.preventDefault()
62+
shell.openExternal(url);
63+
}
64+
}
65+
})
66+
// webContents.on("did-create-window", (parentWindow, details) => {
67+
// const view = new BrowserView();
68+
// parentWindow.setBrowserView(view);
69+
// view.setBounds({ x: 0, y: 30, width: parentWindow.getContentBounds().width, height: parentWindow.getContentBounds().height - 30 });
70+
// view.setAutoResize({ width: true, height: true });
71+
// view.webContents.loadURL(details.url);
72+
// })
73+
webContents.on('did-navigate', (event, url) => {
74+
let win = webContents.getOwnerBrowserWindow()
75+
if (win && win.setTitleBarOverlay && typeof win.setTitleBarOverlay === "function") {
76+
const overlay = titleBarOverlay("default")
77+
win.setTitleBarOverlay(overlay)
78+
}
79+
launched = true
80+
81+
})
82+
webContents.setWindowOpenHandler((config) => {
83+
let url = config.url
84+
let features = config.features
85+
let params = new URLSearchParams(features.split(",").join("&"))
86+
let win = wc.getOwnerBrowserWindow()
87+
let [width, height] = win.getSize()
88+
let [x,y] = win.getPosition()
89+
90+
if (features) {
91+
if (features.startsWith("app") || features.startsWith("self")) {
92+
return {
93+
action: 'allow',
94+
outlivesOpener: true,
95+
overrideBrowserWindowOptions: {
96+
width: (params.get("width") ? parseInt(params.get("width")) : width),
97+
height: (params.get("height") ? parseInt(params.get("height")) : height),
98+
x: x + 30,
99+
y: y + 30,
100+
101+
parent: null,
102+
titleBarStyle : "hidden",
103+
titleBarOverlay : titleBarOverlay("default"),
104+
}
105+
}
106+
} else if (features.startsWith("file")) {
107+
let u = features.replace("file://", "")
108+
shell.showItemInFolder(u)
109+
return { action: 'deny' };
110+
} else {
111+
return { action: 'deny' };
112+
}
113+
} else {
114+
shell.openExternal(url);
115+
return { action: 'deny' };
116+
}
117+
});
118+
}
119+
const getWinState = (url, options) => {
120+
let filename
121+
try {
122+
let pathname = new URL(url).pathname.slice(1)
123+
filename = pathname.slice("/").join("-")
124+
} catch {
125+
filename = "index.json"
126+
}
127+
let state = windowStateKeeper({
128+
file: filename,
129+
...options
130+
});
131+
return state
132+
}
133+
const createWindow = (port) => {
134+
135+
136+
let mainWindowState = windowStateKeeper({
137+
// file: "index.json",
138+
defaultWidth: 1000,
139+
defaultHeight: 800
140+
});
141+
142+
mainWindow = new BrowserWindow({
143+
titleBarStyle : "hidden",
144+
titleBarOverlay : titleBarOverlay("default"),
145+
x: mainWindowState.x,
146+
y: mainWindowState.y,
147+
width: mainWindowState.width,
148+
height: mainWindowState.height,
149+
minWidth: 190,
150+
webPreferences: {
151+
nativeWindowOpen: true
152+
// preload: path.join(__dirname, 'preload.js')
153+
},
154+
})
155+
root_url = `http://localhost:${port}`
156+
mainWindow.loadURL(root_url)
157+
// mainWindow.maximize();
158+
mainWindowState.manage(mainWindow);
159+
160+
}
161+
162+
163+
if (process.defaultApp) {
164+
if (process.argv.length >= 2) {
165+
app.setAsDefaultProtocolClient('pinokio', process.execPath, [path.resolve(process.argv[1])])
166+
}
167+
} else {
168+
app.setAsDefaultProtocolClient('pinokio')
169+
}
170+
171+
const gotTheLock = app.requestSingleInstanceLock()
172+
173+
if (!gotTheLock) {
174+
app.quit()
175+
} else {
176+
app.on('second-instance', (event, argv) => {
177+
178+
if (mainWindow) {
179+
if (mainWindow.isMinimized()) mainWindow.restore()
180+
mainWindow.focus()
181+
}
182+
let url = argv.pop()
183+
let u = new URL(url).search
184+
mainWindow.loadURL(`${root_url}${u}`)
185+
})
186+
187+
// Create mainWindow, load the rest of the app, etc...
188+
app.whenReady().then(async () => {
189+
const WIDTH = 300;
190+
const HEIGHT = 300;
191+
let bounds = screen.getPrimaryDisplay().bounds;
192+
let x = Math.ceil(bounds.x + ((bounds.width - WIDTH) / 2));
193+
let y = Math.ceil(bounds.y + ((bounds.height - HEIGHT) / 2));
194+
195+
196+
// splash window
197+
const splash = new BrowserWindow({
198+
width: WIDTH,
199+
height: HEIGHT,
200+
// transparent: true,
201+
frame: false,
202+
alwaysOnTop: true,
203+
x,
204+
y,
205+
show: false
206+
});
207+
splash.type = "splash"
208+
splash.loadFile('splash.html');
209+
splash.once('ready-to-show', () => {
210+
splash.show()
211+
})
212+
213+
await pinokiod.start(PORT)
214+
splash.hide();
215+
216+
app.on('web-contents-created', attach)
217+
app.on('activate', function () {
218+
if (BrowserWindow.getAllWindows().length === 0) createWindow(PORT)
219+
})
220+
app.on('window-all-closed', function () {
221+
if (process.platform !== 'darwin') app.quit()
222+
})
223+
app.on('browser-window-created', (event, win) => {
224+
if (win.type !== "splash") {
225+
if (win.setTitleBarOverlay) {
226+
const overlay = titleBarOverlay("default")
227+
try {
228+
win.setTitleBarOverlay(overlay)
229+
} catch (e) {
230+
// console.log("ERROR", e)
231+
}
232+
}
233+
}
234+
})
235+
236+
let all = BrowserWindow.getAllWindows()
237+
for(win of all) {
238+
try {
239+
if (win.setTitleBarOverlay) {
240+
const overlay = titleBarOverlay("default")
241+
win.setTitleBarOverlay(overlay)
242+
}
243+
} catch (e) {
244+
// console.log("E2", e)
245+
}
246+
}
247+
createWindow(PORT)
248+
splash.close();
249+
})
250+
251+
app.on('open-url', (event, url) => {
252+
let u = new URL(url).search
253+
mainWindow.loadURL(`${root_url}${u}`)
254+
})
255+
}

0 commit comments

Comments
 (0)