diff --git a/packages/desktop/electron-builder.yml b/packages/desktop/electron-builder.yml new file mode 100644 index 00000000..abc30b12 --- /dev/null +++ b/packages/desktop/electron-builder.yml @@ -0,0 +1,12 @@ +appId: com.ragestudio.comty +productName: Comty +copyright: Copyright © RageStudio +directories: + output: dist + buildResources: resources +files: + - from: . + filter: + - package.json + - app +publish: null diff --git a/packages/desktop/main/configs/config.js b/packages/desktop/main/configs/config.js new file mode 100644 index 00000000..2dbfdd50 --- /dev/null +++ b/packages/desktop/main/configs/config.js @@ -0,0 +1,3 @@ +const Config = require('electron-config') + +module.exports = new Config({ name: 'config' }); \ No newline at end of file diff --git a/packages/desktop/main/icon.png b/packages/desktop/main/icon.png new file mode 100644 index 00000000..4a3d53b5 Binary files /dev/null and b/packages/desktop/main/icon.png differ diff --git a/packages/desktop/main/index.js b/packages/desktop/main/index.js new file mode 100644 index 00000000..e331ca7f --- /dev/null +++ b/packages/desktop/main/index.js @@ -0,0 +1,234 @@ +const path = require("path") +const { + app, + BrowserWindow, + ipcMain, + Tray, + Menu, + MenuItem, + dialog, + shell, + screen, + BrowserView, + systemPreferences, + Notification, + globalShortcut +} = require("electron") +const log = require("electron-log") +const packagejson = require("../../../package.json") +const is = require("electron-is") +const waitOn = require("wait-on") + +console.log(is.dev()) + +let app_path = is.dev() ? "https://indev.comty.pw" : `file://${path.join(__dirname, "..", "renderer")}/index.html`; +let mainWindow; +let tray; +let watcher; + +// This gets rid of this: https://github.com/electron/electron/issues/13186 +process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = true +// app.commandLine.appendSwitch("disable-web-security") +//app.commandLine.appendSwitch("disable-gpu-vsync=gpu") +app.commandLine.appendSwitch("disable-features", "OutOfBlinkCors") + +const gotTheLock = app.requestSingleInstanceLock() +const notifySupport = Notification.isSupported() + +// Prevent multiple instances +if (!gotTheLock) { + app.quit() +} + +function relaunchApp() { + mainWindow.close() + app.relaunch() +} + +function resumeApp() { + if (mainWindow) { + mainWindow.show() + mainWindow.focus() + } else { + createWindow() + } +} + +function notify(params) { + if (!notifySupport || !params) return false + let options = { + title: "", + body: "", + icon: null, + timeoutType: "default" + } + + const keys = Object.keys(params) + const values = Object.values(params) + + for (let i = 0; i < keys.length; i++) { + options[keys[i]] = values[i] + } + + new Notification(options).show() +} + +function createWindow() { + mainWindow = new BrowserWindow({ + title: packagejson.title, + icon: path.join(__dirname, "./icon.png"), + width: 1100, + height: 700, + minWidth: 1256, + minHeight: 755, + show: true, + frame: false, + transparent: false, + hasShadow: true, + //webgl: true, + visualEffectState: "followWindow", + backgroundColor: "#00ffffff", + webPreferences: { + //enableRemoteModule: true, + enableBlinkFeatures: true, + experimentalFeatures: true, + nodeIntegration: true, + // Disable in dev since I think hot reload is messing with it + webSecurity: !is.dev() + } + }) + + if (is.dev()) { + app.commandLine.appendSwitch("remote-debugging-port", "9222") + globalShortcut.register("CommandOrControl+R", () => { + mainWindow.reload() + }) + + globalShortcut.register("F5", () => { + mainWindow.reload() + }) + } + + mainWindow.webContents.session.webRequest.onHeadersReceived( + { + urls: ["http://*/*", "https://*/*"] + }, + (details, callback) => { + delete details.responseHeaders["Access-Control-Allow-Origin"] + delete details.responseHeaders["access-control-allow-origin"] + if (details.url.includes("www.google-analytics.com")) { + details.responseHeaders["Access-Control-Allow-Origin"] = [app_path] + } else { + details.responseHeaders["Access-Control-Allow-Origin"] = ["*"] + } + callback({ + cancel: false, + responseHeaders: details.responseHeaders + }) + } + ) + + mainWindow.loadURL(app_path) + mainWindow.focus() + + if (is.dev()) { + mainWindow.webContents.openDevTools() + } + + // const handleRedirect = (e, url) => { + // if (url !== mainWindow.webContents.getURL()) { + // e.preventDefault() + // shell.openExternal(url) + // } + // }; + + // mainWindow.webContents.on("will-navigate", handleRedirect) + // mainWindow.webContents.on("new-window", handleRedirect) +} + +app.on("ready", () => { + if (is.dev()) { + loadWindow = new BrowserWindow({ + width: 700, + height: 500, + frame: false, + resizable: false, + center: true, + transparent: true, + backgroundColor: "#00000000", + }); + + loadWindow.loadURL(`file://${__dirname}/statics/loading_dev.html`) + + notify({ title: "Starting development server..." }) + + // waitOn({ resources: [app_path] }, function (err) { + // if (err) { + // return log.log(err) + // } + // }) + + createWindow() + loadWindow.close() + } else { + createWindow() + } +}) + +app.on("window-all-closed", () => { + mainWindow = null; +}) + +app.on("before-quit", async () => { + mainWindow.removeAllListeners("close"); + mainWindow = null; +}) + +ipcMain.handle("update-progress-bar", (event, p) => { + mainWindow.setProgressBar(p); +}) + +ipcMain.handle("hide-window", () => { + if (mainWindow) { + mainWindow.hide(); + } +}) + +ipcMain.handle("show-window", () => { + if (mainWindow) { + mainWindow.show(); + mainWindow.focus(); + } +}) + +ipcMain.handle("min-max-window", () => { + if (mainWindow.isMaximized()) { + mainWindow.unmaximize(); + } else if (mainWindow.maximizable) { + mainWindow.maximize(); + } +}) + +ipcMain.handle("getSystemPreferences", () => { + return systemPreferences +}) + +ipcMain.handle("minimize-window", () => { + mainWindow.minimize(); +}) + +ipcMain.handle("quit-app", () => { + app.quit(); +}) + +ipcMain.handle("open-devtools", () => { + mainWindow.webContents.openDevTools({ mode: "undocked" }); +}) + +ipcMain.handle("appRelaunch", () => { + relaunchApp() +}) + +ipcMain.handle("inspectElement", (event, payload) => { + mainWindow.inspectElement(payload.x, payload.y) +}) \ No newline at end of file diff --git a/packages/desktop/main/statics/loading.css b/packages/desktop/main/statics/loading.css new file mode 100644 index 00000000..8b3d3063 --- /dev/null +++ b/packages/desktop/main/statics/loading.css @@ -0,0 +1,112 @@ + body { + background-color: transparent; + border-radius: 12px; + font-family: 'Alata', sans-serif; + width: 100vw; + height: 100vh; + overflow: hidden; + user-select: none; + -webkit-app-region: drag; + } + + .wrapper { + position: absolute; + top: 0; + right: 0; + + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + background-color: #efefef; + color: #2d2d2d; + border-radius: 12px; + text-align: center; + + width: 100%; + height: 100%; + } + + .bouncy-logo{ + width: 100%; + height: auto; + margin: auto; + } + + .bouncy-logo .ball { + height: auto; + width: 100%; + transform: translate(-10px, 0); + } + + .bouncy-logo .ball svg { + width: 200px; + height: 200px; + margin: auto; + + -webkit-animation-direction: alternate; + -webkit-animation-duration: 1s; + -webkit-animation-name: my-bounce; + -webkit-animation-iteration-count: infinite; + animation-direction: alternate; + animation-duration: 1s; + animation-name: my-bounce; + animation-iteration-count: infinite; + } + + .shadow{ + width: 100%; + height: auto; + } + + .bouncy-logo .ball-shadow { + margin: auto; + background: radial-gradient(50% 50%, rgba(204, 204, 204, 0.45) 0%, transparent 100%); + height: 50px; + width: 200px; + -webkit-animation-direction: alternate; + -webkit-animation-duration: 1s; + -webkit-animation-name: my-grow; + -webkit-animation-iteration-count: infinite; + animation-direction: alternate; + animation-duration: 1s; + animation-name: my-grow; + animation-iteration-count: infinite; + } + + @-webkit-keyframes my-grow { + from { + width: 200px; + height: 50px; + } + to { + width: 150px; + height: 10px; + } + } + @keyframes my-grow { + from { + width: 200px; + height: 50px; + } + to { + width: 150px; + height: 10px; + } + } + @-webkit-keyframes my-bounce { + from { + top: 0; + } + to { + top: 10%; + } + } + @keyframes my-bounce { + from { + top: 0; + } + to { + top: 10%; + } + } \ No newline at end of file diff --git a/packages/desktop/main/statics/loading.html b/packages/desktop/main/statics/loading.html new file mode 100644 index 00000000..039634a8 --- /dev/null +++ b/packages/desktop/main/statics/loading.html @@ -0,0 +1,23 @@ + + + + +
+ +
+ + \ No newline at end of file diff --git a/packages/desktop/main/statics/loading_dev.html b/packages/desktop/main/statics/loading_dev.html new file mode 100644 index 00000000..d45f8e69 --- /dev/null +++ b/packages/desktop/main/statics/loading_dev.html @@ -0,0 +1,24 @@ + + + + +
+ +

Starting the development server...

+
+ + \ No newline at end of file diff --git a/packages/desktop/package.json b/packages/desktop/package.json new file mode 100644 index 00000000..19c7ca94 --- /dev/null +++ b/packages/desktop/package.json @@ -0,0 +1,15 @@ +{ + "name": "comty-desktop", + "version": "0.0.1", + "main": "main/index.js", + "license": "MIT", + "scripts": { + "start": "electron ." + }, + "dependencies": { + "electron": "17.1.2", + "electron-log": "^3.0.0", + "electron-is": "^1.0.0", + "wait-on": "^2.0.0" + } +}