diff --git a/assets/lang/en-US.json b/assets/lang/en-US.json index 4950903..1ce755b 100644 --- a/assets/lang/en-US.json +++ b/assets/lang/en-US.json @@ -2,9 +2,7 @@ "loading_screen_start": "Starting ArmCord…", "loading_screen_offline": "You appear to be offline. Please connect to the Internet and try again.", "loading_screen_update": "A new version of ArmCord is available. Please update to the latest version.", - "setup_question1": "Select what kind of setup you want to perform:", - "setup_question1_answer1": "Express Setup", - "setup_question1_answer2": "Full Setup", + "setup_question1": "Welcome to the ArmCord Setup", "setup_offline": "You appear to be offline. Please connect to the internet and restart ArmCord.", "setup_question2": "Choose your Discord channel/instance:", "setup_question3": "Should ArmCord handle client mods installation?", @@ -12,7 +10,7 @@ "no": "No", "next": "Next", "setup_question4": "Select a client mod you want to install:", - "setup_question4_clientmodnotice": "Why not all of them? Having many client mods at the same time can cause issues. If you really want to do it though, check our Discord.", + "setup_question5": "Do you want to use a tray icon?", "settings-theme": "ArmCord theme", "settings-theme-desc1": "ArmCord \"themes\" manage apps behaviour and looks.", "settings-theme-desc2": "this is how ArmCord looks when you first launch it. It includes recreation of Discord's\n custom titlebar and ArmCord specific styles injected into Discord.", @@ -21,8 +19,8 @@ "settings-theme-native": "Native", "settings-theme-transparent": "Transparent (Experimental)", "settings-csp-desc": "ArmCord CSP is our system that manages loading custom content loading into the Discord app. Stuff like\n client mods and themes depend on it. Disable if you want to get rid of mods and custom styles.", - "settings-tray": "Minimize to tray", - "settings-tray-desc": "When disabled, ArmCord will close like any other window when closed, otherwise it'll sit back and relax\n in your system tray for later.", + "settings-mintoTray": "Minimize to tray", + "settings-mintoTray-desc": "When disabled, ArmCord will close like any other window when closed, otherwise it'll sit back and relax\n in your system tray for later.", "settings-startMinimized": "Start minimized", "settings-startMinimized-desc": "ArmCord starts in background and remains out of your way.", "settings-patches": "Automatic Patches", @@ -35,6 +33,8 @@ "settings-dynamicIcon-desc": "Following Discord's behaviour on Windows, this shows unread messages/pings count on ArmCord's icon instead of it's tray.", "settings-spellcheck": "Spellcheck", "settings-spellcheck-desc": "Helps you correct misspelled words by highlighting them.", + "settings-tray": "Tray", + "settings-tray-desc": "ArmCord's tray menu is a place where you can easily and quickly access ArmCord's settings and allows you to quickly show up Discord window.", "settings-channel": "Discord channel", "settings-channel-desc1": "You can use this setting to change current instance of Discord:", "settings-channel-desc2": "you're probably most familiar with this one. It's the one you see in default Discord\n client!", diff --git a/src/preload/bridge.ts b/src/preload/bridge.ts index 2bd710a..8b7b0f4 100644 --- a/src/preload/bridge.ts +++ b/src/preload/bridge.ts @@ -74,7 +74,6 @@ ipcRenderer.on("rpc", (_event, data: object) => { if (window.location.href.indexOf("splash.html") > -1 || window.location.href.indexOf("setup.html") > -1) { contextBridge.exposeInMainWorld("armcordinternal", { restart: () => ipcRenderer.send("restart"), - installState: ipcRenderer.sendSync("modInstallState"), - saveSettings: (...args: any) => ipcRenderer.send("saveSettings", ...args) + installState: ipcRenderer.sendSync("modInstallState") }); } diff --git a/src/preload/preload.ts b/src/preload/preload.ts index e5bddeb..2b1dd5c 100644 --- a/src/preload/preload.ts +++ b/src/preload/preload.ts @@ -18,13 +18,9 @@ if (ipcRenderer.sendSync("legacyCapturer")) { const version = ipcRenderer.sendSync("displayVersion"); async function updateLang(): Promise { - if (window.location.href.indexOf("setup.html") > -1) { - console.log("Setup, skipping lang update"); - } else { - const value = `; ${document.cookie}`; - const parts: any = value.split(`; locale=`); - if (parts.length === 2) ipcRenderer.send("setLang", parts.pop().split(";").shift()); - } + const value = `; ${document.cookie}`; + const parts: any = value.split(`; locale=`); + if (parts.length === 2) ipcRenderer.send("setLang", parts.pop().split(";").shift()); } declare global { interface Window { diff --git a/src/preload/titlebar.ts b/src/preload/titlebar.ts index 5b516ff..e8e48fb 100644 --- a/src/preload/titlebar.ts +++ b/src/preload/titlebar.ts @@ -33,7 +33,11 @@ export function injectTitlebar(): void { const quit = document.getElementById("quit"); minimize!.addEventListener("click", () => { - ipcRenderer.send("win-minimize"); + if (window.location.href.indexOf("setup.html") > -1) { + ipcRenderer.send("setup-minimize"); + } else { + ipcRenderer.send("win-minimize"); + } }); maximize!.addEventListener("click", () => { @@ -46,10 +50,14 @@ export function injectTitlebar(): void { }); quit!.addEventListener("click", () => { - if (ipcRenderer.sendSync("minimizeToTray") === true) { - ipcRenderer.send("win-hide"); - } else if (ipcRenderer.sendSync("minimizeToTray") === false) { - ipcRenderer.send("win-quit"); + if (window.location.href.indexOf("setup.html") > -1) { + ipcRenderer.send("setup-quit"); + } else { + if (ipcRenderer.sendSync("minimizeToTray") === true) { + ipcRenderer.send("win-hide"); + } else if (ipcRenderer.sendSync("minimizeToTray") === false) { + ipcRenderer.send("win-quit"); + } } }); }); diff --git a/src/settings/settings.html b/src/settings/settings.html index 2a73d6f..50a3c98 100644 --- a/src/settings/settings.html +++ b/src/settings/settings.html @@ -45,10 +45,10 @@
- - + + -

+


@@ -60,6 +60,14 @@
+
+ + + +

+
+
+
diff --git a/src/setup/main.ts b/src/setup/main.ts new file mode 100644 index 0000000..5815797 --- /dev/null +++ b/src/setup/main.ts @@ -0,0 +1,42 @@ +import {BrowserWindow, app, ipcMain} from "electron"; +import path from "path"; +import * as fs from "fs"; +import * as os from "os"; +import {iconPath} from "../main"; +import {Settings, getConfigLocation, setConfigBulk} from "../utils"; +let setupWindow: BrowserWindow; +export function createSetupWindow(): void { + setupWindow = new BrowserWindow({ + width: 390, + height: 470, + title: "ArmCord Setup", + darkTheme: true, + icon: iconPath, + frame: false, + autoHideMenuBar: true, + webPreferences: { + sandbox: false, + spellcheck: false, + preload: path.join(__dirname, "preload.js") + } + }); + ipcMain.on("saveSettings", (_event, args: Settings) => { + console.log(args); + setConfigBulk(args); + }); + ipcMain.on("setup-minimize", () => { + setupWindow.minimize(); + }); + ipcMain.on("setup-getOS", (event) => { + event.returnValue = process.platform; + }); + ipcMain.on("setup-quit", async () => { + fs.unlink(await getConfigLocation(), (err) => { + if (err) throw err; + + console.log('Closed during setup. "settings.json" was deleted'); + app.quit(); + }); + }); + setupWindow.loadURL(`file://${__dirname}/setup.html`); +} diff --git a/src/setup/preload.ts b/src/setup/preload.ts new file mode 100644 index 0000000..96f1174 --- /dev/null +++ b/src/setup/preload.ts @@ -0,0 +1,12 @@ +import {contextBridge, ipcRenderer} from "electron"; +import {injectTitlebar} from "../preload/titlebar"; +injectTitlebar(); +contextBridge.exposeInMainWorld("armcordinternal", { + restart: () => ipcRenderer.send("restart"), + getOS: ipcRenderer.sendSync("setup-getOS"), + saveSettings: (...args: any) => ipcRenderer.send("saveSettings", ...args), + getLang: (toGet: string) => + ipcRenderer.invoke("getLang", toGet).then((result) => { + return result; + }) +}); diff --git a/src/content/setup.html b/src/setup/setup.html similarity index 55% rename from src/content/setup.html rename to src/setup/setup.html index 6e82af8..277ad54 100644 --- a/src/content/setup.html +++ b/src/setup/setup.html @@ -7,9 +7,10 @@ ArmCord Setup +
@@ -57,32 +48,36 @@
-

- Why not all of them? Having many client mods at the same time can cause issues. If you really - want to do it though, check our Discord ;) -

- + +
+
+ @@ -108,68 +103,31 @@ let page2 = document.getElementById("page2"); let page3 = document.getElementById("page3"); + let page4 = document.getElementById("page4"); // }}} - // Express - page1.buttons[0].addEventListener("click", () => { - window.armcordinternal.saveSettings({ - windowStyle: "default", - channel: "stable", - armcordCSP: true, - minimizeToTray: true, - alternativePaste: false, - automaticPatches: false, - mods: "none", - useLegacyCapturer: false, - inviteWebsocket: true, - mobileMode: false, - dynamicIcon: false, - trayIcon: "default", - startMinimized: false, - spellcheck: true, - performanceMode: "none" - }); - setTimeout(() => window.armcordinternal.restart(), 500); - }); - // Full - page1.buttons[1].addEventListener("click", () => { + page1.buttons[0].addEventListener("click", () => { page1.classList.add("hidden"); page2.classList.remove("hidden"); }); - page2.buttons = document.querySelectorAll("#page2 > #buttons > button"); - page2.buttons[0].addEventListener("click", () => { + document.getElementById("next-page2").addEventListener("click", () => { options.channel = document.getElementById("channel").value; - options.csp = document.getElementById("csp").value; + options.mod = document.getElementById("mod").value; page2.classList.add("hidden"); - - page3.buttons = document.querySelectorAll("#page3 > #buttons > button"); - if (options.csp === "true") { - page3.classList.remove("hidden"); - page3.buttons[0].addEventListener("click", () => { - options.mod = document.getElementById("mod").value; - window.armcordinternal.saveSettings({ - windowStyle: "default", - channel: options.channel, - armcordCSP: true, - minimizeToTray: true, - mobileMode: false, - automaticPatches: false, - performanceMode: "none", - useLegacyCapturer: false, - alternativePaste: false, - dynamicIcon: false, - spellcheck: true, - disableAutogain: false, - startMinimized: false, - trayIcon: "default", - mods: options.mod, - inviteWebsocket: true - }); - setTimeout(() => window.armcordinternal.restart(), 500); - }); - } else { + page3.classList.remove("hidden"); + document.getElementById("next-page3").addEventListener("click", () => { + page3.classList.add("hidden"); + page4.classList.remove("hidden"); + }); + if (window.armcordinternal.getOS == "win32") { + document.getElementById("tray").value = "false"; + document.getElementById( + "linuxNotice" + ).innerHTML = `Linux may not work well with tray icons. Depending on your system configuration, you may not be able to see the tray icon. Enable at your own risk. Can be changed later.`; + } + document.getElementById("next-page4").addEventListener("click", () => { window.armcordinternal.saveSettings({ windowStyle: "default", channel: options.channel, @@ -179,9 +137,10 @@ mobileMode: false, spellcheck: true, disableAutogain: false, - mods: "none", + mods: options.mod, dynamicIcon: false, useLegacyCapturer: false, + tray: /true/i.test(document.getElementById("tray").value), startMinimized: false, alternativePaste: false, performanceMode: "none", @@ -189,7 +148,7 @@ inviteWebsocket: true }); setTimeout(() => window.armcordinternal.restart(), 500); - } + }); }); document.body.setAttribute("insetup", ""); diff --git a/src/tray.ts b/src/tray.ts index 3de53b3..f88fb00 100644 --- a/src/tray.ts +++ b/src/tray.ts @@ -1,7 +1,7 @@ import * as fs from "fs"; -import {Menu, Tray, app, nativeImage} from "electron"; +import {Menu, Tray, app, dialog, nativeImage} from "electron"; import {createInviteWindow, mainWindow} from "./window"; -import {getConfig, getConfigLocation, getDisplayVersion, setWindowState} from "./utils"; +import {getConfig, getConfigLocation, getDisplayVersion, setConfig, setWindowState} from "./utils"; import * as path from "path"; import {createSettingsWindow} from "./settings/main"; export let tray: any = null; @@ -25,13 +25,61 @@ app.whenReady().then(async () => { }; if (process.platform == "darwin" && trayPath.getSize().height > 22) trayPath = trayPath.resize({height: 22}); + if (await getConfig("tray")) { + let clientName = (await getConfig("clientName")) ?? "ArmCord"; + if ((await getConfig("windowStyle")) == "basic") { + tray = new Tray(trayPath); + function contextMenu(): Electron.Menu { + if (finishedSetup == false) { + return Menu.buildFromTemplate([ + { + label: `Finish the setup first!`, + enabled: false + }, + { + label: `Quit ${clientName}`, + async click() { + fs.unlink(await getConfigLocation(), (err) => { + if (err) throw err; - let clientName = (await getConfig("clientName")) ?? "ArmCord"; - if ((await getConfig("windowStyle")) == "basic") { - tray = new Tray(trayPath); - function contextMenu(): Electron.Menu { + console.log('Closed during setup. "settings.json" was deleted'); + app.quit(); + }); + } + } + ]); + } else { + return Menu.buildFromTemplate([ + { + label: `Open ${clientName}`, + click() { + mainWindow.show(); + } + }, + { + label: `Quit ${clientName}`, + click() { + let [width, height] = mainWindow.getSize(); + setWindowState({ + width, + height, + isMaximized: mainWindow.isMaximized(), + x: mainWindow.getPosition()[0], + y: mainWindow.getPosition()[1] + }); + app.quit(); + } + } + ]); + } + } + + tray.setToolTip(clientName); + tray.setContextMenu(contextMenu); + } else { + tray = new Tray(trayPath); if (finishedSetup == false) { - return Menu.buildFromTemplate([ + const contextMenu = Menu.buildFromTemplate([ { label: `Finish the setup first!`, enabled: false @@ -48,98 +96,78 @@ app.whenReady().then(async () => { } } ]); + tray.setContextMenu(contextMenu); } else { - return Menu.buildFromTemplate([ + const contextMenu = Menu.buildFromTemplate([ + { + label: `${clientName} ${getDisplayVersion()}`, + icon: trayVerIcon(), + enabled: false + }, + { + type: "separator" + }, { label: `Open ${clientName}`, click() { mainWindow.show(); } }, + { + label: "Open Settings", + click() { + createSettingsWindow(); + } + }, + { + label: "Support Discord Server", + click() { + createInviteWindow("TnhxcqynZ2"); + } + }, + { + type: "separator" + }, { label: `Quit ${clientName}`, click() { - let [width, height] = mainWindow.getSize(); - setWindowState({ - width, - height, - isMaximized: mainWindow.isMaximized(), - x: mainWindow.getPosition()[0], - y: mainWindow.getPosition()[1] - }); app.quit(); } } ]); + tray.setContextMenu(contextMenu); } } - tray.setToolTip(clientName); - tray.setContextMenu(contextMenu); + tray.on("click", function () { + mainWindow.show(); + }); } else { - tray = new Tray(trayPath); - if (finishedSetup == false) { - const contextMenu = Menu.buildFromTemplate([ - { - label: `Finish the setup first!`, - enabled: false - }, - { - label: `Quit ${clientName}`, - async click() { - fs.unlink(await getConfigLocation(), (err) => { - if (err) throw err; + if ((await getConfig("tray")) == undefined) { + if (process.platform == "win32") { + const options = { + type: "question", + buttons: ["Yes, please", "No, I don't"], + defaultId: 1, + title: "Tray icon choice", + message: `Do you want to use tray icons?`, + detail: "Linux may not work well with tray icons. Depending on your system configuration, you may not be able to see the tray icon. Enable at your own risk. Can be changed later." + }; - console.log('Closed during setup. "settings.json" was deleted'); - app.quit(); - }); + dialog.showMessageBox(mainWindow, options).then(({response}) => { + if (response == 0) { + setConfig("tray", true); + } else { + setConfig("tray", false); } - } - ]); - tray.setContextMenu(contextMenu); - } else { - const contextMenu = Menu.buildFromTemplate([ - { - label: `${clientName} ${getDisplayVersion()}`, - icon: trayVerIcon(), - enabled: false - }, - { - type: "separator" - }, - { - label: `Open ${clientName}`, - click() { - mainWindow.show(); - } - }, - { - label: "Open Settings", - click() { - createSettingsWindow(); - } - }, - { - label: "Support Discord Server", - click() { - createInviteWindow("TnhxcqynZ2"); - } - }, - { - type: "separator" - }, - { - label: `Quit ${clientName}`, - click() { - app.quit(); - } - } - ]); - tray.setContextMenu(contextMenu); + app.relaunch(); + app.exit(); + }); + } else { + setConfig("tray", true); + app.relaunch(); + app.exit(); + } } } - tray.setToolTip(clientName); - tray.on("click", function () { - mainWindow.show(); - }); }); diff --git a/src/utils.ts b/src/utils.ts index c39603f..ab5bb88 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -52,6 +52,7 @@ export function setup(): void { inviteWebsocket: true, startMinimized: false, dynamicIcon: false, + tray: true, disableAutogain: false, useLegacyCapturer: false, mobileMode: false, @@ -260,6 +261,7 @@ export interface Settings { performanceMode: string; startMinimized: boolean; useLegacyCapturer: boolean; + tray: boolean; inviteWebsocket: boolean; disableAutogain: boolean; trayIcon: string; diff --git a/src/window.ts b/src/window.ts index 81c8270..6ae65bc 100644 --- a/src/window.ts +++ b/src/window.ts @@ -23,6 +23,7 @@ import contextMenu from "electron-context-menu"; import os from "os"; import {tray} from "./tray"; import {iconPath} from "./main"; +import {createSetupWindow} from "./setup/main"; export let mainWindow: BrowserWindow; export let inviteWindow: BrowserWindow; @@ -256,12 +257,8 @@ async function doAfterDefiningTheWindow(): Promise { } if (firstRun) { await setLang(new Intl.DateTimeFormat().resolvedOptions().locale); - mainWindow.setSize(390, 470); - await mainWindow.loadFile(path.join(__dirname, "/content/setup.html")); - let trayPath = nativeImage.createFromPath(path.join(__dirname, "../", `/assets/ac_plug_colored.png`)); - if (process.platform === "darwin" && trayPath.getSize().height > 22) trayPath = trayPath.resize({height: 22}); - if (process.platform === "win32" && trayPath.getSize().height > 32) trayPath = trayPath.resize({height: 32}); - tray.setImage(trayPath); + createSetupWindow(); + mainWindow.close(); } else if ((await getConfig("skipSplash")) == true) { // It's modified elsewhere. // eslint-disable-next-line no-unmodified-loop-condition