mirror of
https://github.com/ragestudio/relic.git
synced 2025-06-09 02:24:18 +00:00
301 lines
6.8 KiB
JavaScript
301 lines
6.8 KiB
JavaScript
import path from "node:path"
|
|
|
|
import { app, shell, BrowserWindow, ipcMain } from "electron"
|
|
import { electronApp, optimizer, is } from "@electron-toolkit/utils"
|
|
import isDev from "electron-is-dev"
|
|
|
|
let RelicCore = null
|
|
let Settings = null
|
|
|
|
if (isDev) {
|
|
RelicCore = require("../../../core/dist").default
|
|
Settings = global.Settings = require("../../../core/dist/classes/Settings").default
|
|
} else {
|
|
RelicCore = require("@ragestudio/relic-core").default
|
|
Settings = global.Settings = require("@ragestudio/relic-core/src/classes/Settings").default
|
|
}
|
|
|
|
import CoreAdapter from "./classes/CoreAdapter"
|
|
import sendToRender from "./utils/sendToRender"
|
|
import pkg from "../../package.json"
|
|
|
|
const { autoUpdater } = require("electron-differential-updater")
|
|
const ProtocolRegistry = require("protocol-registry")
|
|
|
|
const protocolRegistryNamespace = "relic"
|
|
|
|
class LogsViewer {
|
|
window = null
|
|
|
|
async createWindow() {
|
|
this.window = new BrowserWindow({
|
|
width: 800,
|
|
height: 600,
|
|
show: false,
|
|
resizable: true,
|
|
autoHideMenuBar: true,
|
|
icon: "../../resources/icon.png",
|
|
webPreferences: {
|
|
preload: path.join(__dirname, "../preload/index.js"),
|
|
sandbox: false,
|
|
},
|
|
})
|
|
|
|
if (is.dev && process.env["ELECTRON_RENDERER_URL"]) {
|
|
this.window.loadURL(`${process.env["ELECTRON_RENDERER_URL"]}/#logs`)
|
|
} else {
|
|
this.window.loadFile(path.join(__dirname, "../renderer/index.html"), {
|
|
hash: "#logs",
|
|
})
|
|
}
|
|
|
|
await new Promise((resolve) => this.window.once("ready-to-show", resolve))
|
|
|
|
this.window.show()
|
|
|
|
return this.window
|
|
}
|
|
|
|
closeWindow() {
|
|
if (this.window) {
|
|
this.window.close()
|
|
}
|
|
}
|
|
}
|
|
|
|
class ElectronApp {
|
|
constructor() {
|
|
this.core = new RelicCore()
|
|
this.adapter = new CoreAdapter(this, this.core)
|
|
}
|
|
|
|
window = null
|
|
|
|
logsViewer = new LogsViewer()
|
|
|
|
handlers = {
|
|
"updater:check": () => {
|
|
autoUpdater.checkForUpdates()
|
|
},
|
|
"updater:apply": () => {
|
|
setTimeout(() => {
|
|
autoUpdater.quitAndInstall()
|
|
}, 3000)
|
|
},
|
|
"settings:get": async (event, key) => {
|
|
return await Settings.get(key)
|
|
},
|
|
"settings:set": async (event, key, value) => {
|
|
return await Settings.set(key, value)
|
|
},
|
|
"settings:delete": async (event, key) => {
|
|
return await Settings.delete(key)
|
|
},
|
|
"settings:has": async (event, key) => {
|
|
return await Settings.has(key)
|
|
},
|
|
"app:open-logs": async (event) => {
|
|
const loggerWindow = await this.logsViewer.createWindow()
|
|
|
|
this.adapter.attachLogger(loggerWindow)
|
|
|
|
loggerWindow.on("closed", () => {
|
|
this.adapter.detachLogger()
|
|
})
|
|
|
|
loggerWindow.webContents.send("logger:new", {
|
|
timestamp: new Date().getTime(),
|
|
message: "Logger opened, starting watching logs",
|
|
})
|
|
},
|
|
"app:init": async (event, data) => {
|
|
try {
|
|
await this.adapter.initialize()
|
|
|
|
return {
|
|
pkg: pkg,
|
|
authorizedServices: {}
|
|
}
|
|
} catch (error) {
|
|
console.error(error)
|
|
|
|
sendToRender("app:init:failed", {
|
|
message: "Initalization failed",
|
|
error: error,
|
|
})
|
|
|
|
return {
|
|
error
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
createWindow() {
|
|
this.window = global.mainWindow = new BrowserWindow({
|
|
width: 450,
|
|
height: 670,
|
|
show: false,
|
|
resizable: false,
|
|
autoHideMenuBar: true,
|
|
icon: "../../resources/icon.png",
|
|
webPreferences: {
|
|
preload: path.join(__dirname, "../preload/index.js"),
|
|
sandbox: false
|
|
}
|
|
})
|
|
|
|
this.window.on("ready-to-show", () => {
|
|
this.window.show()
|
|
})
|
|
|
|
this.window.webContents.setWindowOpenHandler((details) => {
|
|
shell.openExternal(details.url)
|
|
|
|
return { action: "deny" }
|
|
})
|
|
|
|
if (is.dev && process.env["ELECTRON_RENDERER_URL"]) {
|
|
this.window.loadURL(process.env["ELECTRON_RENDERER_URL"])
|
|
} else {
|
|
this.window.loadFile(path.join(__dirname, "../renderer/index.html"))
|
|
}
|
|
}
|
|
|
|
handleURLProtocol(url) {
|
|
const urlStarter = `${protocolRegistryNamespace}://`
|
|
|
|
if (url.startsWith(urlStarter)) {
|
|
const urlValue = url.split(urlStarter)[1]
|
|
|
|
let explicitAction = urlValue.split("#")
|
|
|
|
// remove trailing slash for windows :(
|
|
if (explicitAction[0].endsWith("/")) {
|
|
explicitAction[0] = explicitAction[0].slice(0, -1)
|
|
}
|
|
|
|
if (explicitAction.length > 0) {
|
|
switch (explicitAction[0]) {
|
|
case "authorize": {
|
|
if (!explicitAction[2]) {
|
|
const [pkg_id, token] = explicitAction[1].split("%23")
|
|
return this.core.package.authorize(pkg_id, token)
|
|
} else {
|
|
return this.core.package.authorize(explicitAction[1], explicitAction[2])
|
|
}
|
|
}
|
|
default: {
|
|
return sendToRender("pkg:installation:invoked", explicitAction[0])
|
|
}
|
|
}
|
|
} else {
|
|
// by default if no action is specified, assume is a install action
|
|
return sendToRender("pkg:installation:invoked", urlValue)
|
|
}
|
|
}
|
|
}
|
|
|
|
handleOnSecondInstance = async (event, commandLine, workingDirectory) => {
|
|
event.preventDefault()
|
|
|
|
// Someone tried to run a second instance, we should focus our window.
|
|
if (this.window) {
|
|
if (this.window.isMinimized()) {
|
|
this.window.restore()
|
|
}
|
|
|
|
this.window.focus()
|
|
}
|
|
|
|
console.log(`Second instance >`, commandLine)
|
|
|
|
const url = commandLine.pop()
|
|
|
|
await this.handleURLProtocol(url)
|
|
}
|
|
|
|
async initialize() {
|
|
// Set app user model id for windows
|
|
electronApp.setAppUserModelId("com.electron")
|
|
|
|
const gotTheLock = await app.requestSingleInstanceLock()
|
|
|
|
if (!gotTheLock) {
|
|
return app.quit()
|
|
}
|
|
|
|
for (const key in this.handlers) {
|
|
ipcMain.handle(key, this.handlers[key])
|
|
}
|
|
|
|
app.on("second-instance", this.handleOnSecondInstance)
|
|
|
|
app.on("open-url", (event, url) => {
|
|
event.preventDefault()
|
|
|
|
this.handleURLProtocol(url)
|
|
})
|
|
|
|
app.on("browser-window-created", (_, window) => {
|
|
optimizer.watchWindowShortcuts(window)
|
|
})
|
|
|
|
app.on("activate", () => {
|
|
if (BrowserWindow.getAllWindows().length === 0) {
|
|
this.createWindow()
|
|
}
|
|
})
|
|
|
|
app.on("window-all-closed", () => {
|
|
if (process.platform !== "darwin") {
|
|
app.quit()
|
|
}
|
|
})
|
|
|
|
await app.whenReady()
|
|
|
|
if (isDev) {
|
|
if (app.isDefaultProtocolClient(protocolRegistryNamespace)) {
|
|
app.removeAsDefaultProtocolClient(protocolRegistryNamespace)
|
|
}
|
|
|
|
ProtocolRegistry.register({
|
|
protocol: protocolRegistryNamespace,
|
|
command: `"${process.execPath}" "${path.resolve(process.argv[1])}" $_URL_`,
|
|
override: true,
|
|
script: true,
|
|
terminal: false
|
|
})
|
|
} else {
|
|
if (!app.isDefaultProtocolClient(protocolRegistryNamespace)) {
|
|
app.setAsDefaultProtocolClient(protocolRegistryNamespace)
|
|
}
|
|
}
|
|
|
|
await this.createWindow()
|
|
|
|
if (!isDev) {
|
|
autoUpdater.on("update-available", (ev, info) => {
|
|
console.log(info)
|
|
sendToRender("app:checking_update_downloading", info)
|
|
})
|
|
|
|
autoUpdater.on("error", (ev, err) => {
|
|
console.error(err)
|
|
sendToRender("app:checking_update_error")
|
|
})
|
|
|
|
autoUpdater.on("update-downloaded", (ev, info) => {
|
|
console.log(info)
|
|
sendToRender("app:update_available", info)
|
|
})
|
|
|
|
sendToRender("app:checking_update")
|
|
|
|
await autoUpdater.checkForUpdates()
|
|
}
|
|
}
|
|
}
|
|
|
|
new ElectronApp().initialize() |