mirror of
https://github.com/smartfrigde/armcord.git
synced 2024-08-14 23:56:58 +00:00
Compare commits
No commits in common. "bac604a7cc4a8a52cc7338644e245d68afc7c110" and "5801aed6e6766cd84c62da702baead8847202c12" have entirely different histories.
bac604a7cc
...
5801aed6e6
14 changed files with 2308 additions and 1148 deletions
3023
package-lock.json
generated
3023
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -26,14 +26,16 @@
|
||||||
"@types/node": "^17.0.24",
|
"@types/node": "^17.0.24",
|
||||||
"copyfiles": "^2.4.1",
|
"copyfiles": "^2.4.1",
|
||||||
"electron": "^18.0.4",
|
"electron": "^18.0.4",
|
||||||
"electron-builder": "^22.5.1",
|
"electron-builder": "^23.0.3",
|
||||||
"husky": "^7.0.4",
|
"husky": "^7.0.4",
|
||||||
"prettier": "^2.5.1",
|
"prettier": "^2.5.1",
|
||||||
"typescript": "^4.5.4"
|
"typescript": "^4.5.4"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"electron-context-menu": "^3.1.2",
|
"electron-context-menu": "^3.1.2",
|
||||||
|
"electron-json-storage": "^4.5.0",
|
||||||
"electron-tabs": "^0.17.0",
|
"electron-tabs": "^0.17.0",
|
||||||
|
"glasstron": "^0.1.1",
|
||||||
"v8-compile-cache": "^2.3.0"
|
"v8-compile-cache": "^2.3.0"
|
||||||
},
|
},
|
||||||
"build": {
|
"build": {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*CSS ONLY FOR INTERNAL USE (setup and loading)*/
|
/*CSS ONLY FOR INTERNAL USE (setup and loading)*/
|
||||||
@import url("https://armcord.smartfridge.space/logofont.css");
|
@import url("https://kckarnige.github.io/femboi_owo/discord-font.css");
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
background-color: #2c2f33 !important;
|
background-color: #2c2f33 !important;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@import url("https://armcord.smartfridge.space/logofont.css");
|
@import url("https://kckarnige.github.io/femboi_owo/discord-font.css");
|
||||||
:root {
|
:root {
|
||||||
--window-buttons: var(--header-secondary);
|
--window-buttons: var(--header-secondary);
|
||||||
--cord-color: var(--header-primary);
|
--cord-color: var(--header-primary);
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
text.innerHTML = "You appear to be offline. Please connect to the internet and try again.";
|
text.innerHTML = "You appear to be offline. Please connect to the internet and try again.";
|
||||||
} else {
|
} else {
|
||||||
text.innerHTML = "Starting ArmCord...";
|
text.innerHTML = "Starting ArmCord...";
|
||||||
fetch("https://armcord.xyz/latest.json")
|
fetch("https://armcord.smartfridge.space/latest.json")
|
||||||
.then((response) => response.json())
|
.then((response) => response.json())
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
if (data.version !== window.armcord.version) {
|
if (data.version !== window.armcord.version) {
|
||||||
|
|
|
@ -9,7 +9,7 @@ The above copyright notice and this permission notice shall be included in all c
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
import electron from "electron";
|
import electron from "electron";
|
||||||
import {getConfig} from "../utils";
|
import * as storage from "electron-json-storage";
|
||||||
const otherMods = {
|
const otherMods = {
|
||||||
generic: {
|
generic: {
|
||||||
electronProxy: require("util").types.isProxy(electron) // Many modern mods overwrite electron with a proxy with a custom BrowserWindow (copied from PowerCord)
|
electronProxy: require("util").types.isProxy(electron) // Many modern mods overwrite electron with a proxy with a custom BrowserWindow (copied from PowerCord)
|
||||||
|
@ -55,9 +55,9 @@ const unstrictCSP = () => {
|
||||||
done({responseHeaders});
|
done({responseHeaders});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
storage.get("settings", function (error, data: any) {
|
||||||
electron.app.whenReady().then(async () => {
|
if (error) throw error;
|
||||||
if (await getConfig("armcordCSP")) {
|
if (data.armcordCSP) {
|
||||||
unstrictCSP();
|
unstrictCSP();
|
||||||
} else {
|
} else {
|
||||||
console.log("ArmCord CSP is disabled. The CSP should be managed by third-party plugin.");
|
console.log("ArmCord CSP is disabled. The CSP should be managed by third-party plugin.");
|
||||||
|
|
27
src/ipc.ts
27
src/ipc.ts
|
@ -1,8 +1,8 @@
|
||||||
//ipc stuff
|
//ipc stuff
|
||||||
import {app, ipcMain, shell, desktopCapturer} from "electron";
|
import {app, ipcMain, shell, desktopCapturer} from "electron";
|
||||||
import {createTabsGuest, mainWindow} from "./window";
|
import {createTabsGuest, mainWindow} from "./window";
|
||||||
import {setConfigBulk, getVersion, getConfig} from "./utils";
|
import {saveSettings, getVersion} from "./utils";
|
||||||
import {customTitlebar, tabs} from "./main";
|
import {settings, customTitlebar, tabs} from "./main";
|
||||||
import {createSettingsWindow} from "./settings/main";
|
import {createSettingsWindow} from "./settings/main";
|
||||||
export function registerIpc() {
|
export function registerIpc() {
|
||||||
ipcMain.on("get-app-path", (event, arg) => {
|
ipcMain.on("get-app-path", (event, arg) => {
|
||||||
|
@ -46,16 +46,17 @@ export function registerIpc() {
|
||||||
app.exit();
|
app.exit();
|
||||||
});
|
});
|
||||||
ipcMain.on("saveSettings", (event, args) => {
|
ipcMain.on("saveSettings", (event, args) => {
|
||||||
setConfigBulk(args);
|
saveSettings(args);
|
||||||
});
|
});
|
||||||
ipcMain.on("minimizeToTray", async (event) => {
|
ipcMain.on("minimizeToTray", (event) => {
|
||||||
event.returnValue = await getConfig("minimizeToTray");
|
console.log(settings.minimizeToTray);
|
||||||
|
event.returnValue = settings.minimizeToTray;
|
||||||
});
|
});
|
||||||
ipcMain.on("channel", async (event) => {
|
ipcMain.on("channel", (event) => {
|
||||||
event.returnValue = await getConfig("channel");
|
event.returnValue = settings.channel;
|
||||||
});
|
});
|
||||||
ipcMain.on("clientmod", async (event, arg) => {
|
ipcMain.on("clientmod", (event, arg) => {
|
||||||
event.returnValue = await getConfig("mods");
|
event.returnValue = settings.mods;
|
||||||
});
|
});
|
||||||
ipcMain.on("titlebar", (event, arg) => {
|
ipcMain.on("titlebar", (event, arg) => {
|
||||||
event.returnValue = customTitlebar;
|
event.returnValue = customTitlebar;
|
||||||
|
@ -63,14 +64,14 @@ export function registerIpc() {
|
||||||
ipcMain.on("tabs", (event, arg) => {
|
ipcMain.on("tabs", (event, arg) => {
|
||||||
event.returnValue = tabs;
|
event.returnValue = tabs;
|
||||||
});
|
});
|
||||||
ipcMain.on("shouldPatch", async (event, arg) => {
|
ipcMain.on("shouldPatch", (event, arg) => {
|
||||||
event.returnValue = await getConfig("automaticPatches");
|
event.returnValue = settings.automaticPatches;
|
||||||
});
|
});
|
||||||
ipcMain.on("openSettingsWindow", (event, arg) => {
|
ipcMain.on("openSettingsWindow", (event, arg) => {
|
||||||
createSettingsWindow();
|
createSettingsWindow();
|
||||||
});
|
});
|
||||||
ipcMain.on("setting-armcordCSP", async (event) => {
|
ipcMain.on("setting-armcordCSP", (event) => {
|
||||||
if (await getConfig("armcordCSP")) {
|
if (settings.armcordCSP) {
|
||||||
event.returnValue = true;
|
event.returnValue = true;
|
||||||
} else {
|
} else {
|
||||||
event.returnValue = false;
|
event.returnValue = false;
|
||||||
|
|
69
src/main.ts
69
src/main.ts
|
@ -1,21 +1,52 @@
|
||||||
// Modules to control application life and create native browser window
|
// Modules to control application life and create native browser window
|
||||||
import {app, BrowserWindow, session, dialog} from "electron";
|
import {app, BrowserWindow, session} from "electron";
|
||||||
|
import * as path from "path";
|
||||||
import "v8-compile-cache";
|
import "v8-compile-cache";
|
||||||
import {getConfig, setup, checkIfConfigExists} from "./utils";
|
import * as storage from "electron-json-storage";
|
||||||
|
import {getConfigUnsafe, setup} from "./utils";
|
||||||
import "./extensions/mods";
|
import "./extensions/mods";
|
||||||
import "./extensions/plugin";
|
import "./extensions/plugin";
|
||||||
import "./tray";
|
import "./tray";
|
||||||
import {createCustomWindow, createNativeWindow, createTabsHost} from "./window";
|
import {mainWindow, createCustomWindow, createNativeWindow, createGlasstronWindow, createTabsHost} from "./window";
|
||||||
import "./shortcuts";
|
import "./shortcuts";
|
||||||
|
export var contentPath: string;
|
||||||
|
var channel: string;
|
||||||
export var settings: any;
|
export var settings: any;
|
||||||
export var customTitlebar: boolean;
|
export var customTitlebar: boolean;
|
||||||
export var tabs: boolean;
|
export var tabs: boolean;
|
||||||
|
async function appendSwitch() {
|
||||||
|
if ((await getConfigUnsafe("windowStyle")) == "glasstron") {
|
||||||
|
console.log("Enabling transparency visuals.");
|
||||||
|
app.commandLine.appendSwitch("enable-transparent-visuals");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
appendSwitch();
|
||||||
|
storage.has("settings", function (error, hasKey) {
|
||||||
|
if (error) throw error;
|
||||||
|
|
||||||
checkIfConfigExists();
|
if (!hasKey) {
|
||||||
|
console.log("First run of the ArmCord. Starting setup.");
|
||||||
|
setup();
|
||||||
|
contentPath = path.join(__dirname, "/content/setup.html");
|
||||||
|
if (!contentPath.includes("ts-out")) {
|
||||||
|
contentPath = path.join(__dirname, "/ts-out/content/setup.html");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log("ArmCord has been run before. Skipping setup.");
|
||||||
|
contentPath = path.join(__dirname, "/content/splash.html");
|
||||||
|
if (!contentPath.includes("ts-out")) {
|
||||||
|
contentPath = path.join(__dirname, "/ts-out/content/splash.html");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
storage.get("settings", function (error, data: any) {
|
||||||
|
if (error) throw error;
|
||||||
|
console.log(data);
|
||||||
|
channel = data.channel;
|
||||||
|
settings = data;
|
||||||
|
});
|
||||||
app.whenReady().then(async () => {
|
app.whenReady().then(async () => {
|
||||||
switch (await getConfig("windowStyle")) {
|
switch (await getConfigUnsafe("windowStyle")) {
|
||||||
case "default":
|
case "default":
|
||||||
createCustomWindow();
|
createCustomWindow();
|
||||||
customTitlebar = true;
|
customTitlebar = true;
|
||||||
|
@ -24,11 +55,15 @@ app.whenReady().then(async () => {
|
||||||
createNativeWindow();
|
createNativeWindow();
|
||||||
break;
|
break;
|
||||||
case "glasstron":
|
case "glasstron":
|
||||||
dialog.showErrorBox(
|
setTimeout(
|
||||||
"Glasstron is unsupported.",
|
createGlasstronWindow,
|
||||||
"This build doesn't include Glasstron functionality, please edit windowStyle value in your settings.json to something different (default for example)"
|
process.platform == "linux" ? 1000 : 0
|
||||||
|
// Electron has a bug on linux where it
|
||||||
|
// won't initialize properly when using
|
||||||
|
// transparency. To work around that, it
|
||||||
|
// is necessary to delay the window
|
||||||
|
// spawn function.
|
||||||
);
|
);
|
||||||
app.quit();
|
|
||||||
break;
|
break;
|
||||||
case "tabs":
|
case "tabs":
|
||||||
createTabsHost();
|
createTabsHost();
|
||||||
|
@ -51,7 +86,7 @@ app.whenReady().then(async () => {
|
||||||
});
|
});
|
||||||
app.on("activate", async function () {
|
app.on("activate", async function () {
|
||||||
if (BrowserWindow.getAllWindows().length === 0)
|
if (BrowserWindow.getAllWindows().length === 0)
|
||||||
switch (await getConfig("windowStyle")) {
|
switch (await getConfigUnsafe("windowStyle")) {
|
||||||
case "default":
|
case "default":
|
||||||
createCustomWindow();
|
createCustomWindow();
|
||||||
break;
|
break;
|
||||||
|
@ -59,15 +94,7 @@ app.whenReady().then(async () => {
|
||||||
createNativeWindow();
|
createNativeWindow();
|
||||||
break;
|
break;
|
||||||
case "glasstron":
|
case "glasstron":
|
||||||
dialog.showErrorBox(
|
createGlasstronWindow();
|
||||||
"Glasstron is unsupported.",
|
|
||||||
"This build doesn't include Glasstron functionality, please edit windowStyle value in your settings.json to something different (default for example)"
|
|
||||||
);
|
|
||||||
app.quit();
|
|
||||||
break;
|
|
||||||
case "tabs":
|
|
||||||
createTabsHost();
|
|
||||||
tabs = true;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
createCustomWindow();
|
createCustomWindow();
|
||||||
|
|
|
@ -1,17 +1,18 @@
|
||||||
import {BrowserWindow, shell, ipcMain} from "electron";
|
import {BrowserWindow, shell, ipcMain} from "electron";
|
||||||
import {getConfig, setConfigBulk, Settings} from "../utils";
|
import * as storage from "electron-json-storage";
|
||||||
|
import {getConfigUnsafe, saveSettings, Settings} from "../utils";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
var settings: any;
|
||||||
|
var isAlreadyCreated: boolean = false;
|
||||||
|
storage.get("settings", function (error, data: any) {
|
||||||
|
if (error) throw error;
|
||||||
|
console.log(data);
|
||||||
|
settings = data;
|
||||||
|
});
|
||||||
var settingsWindow: BrowserWindow;
|
var settingsWindow: BrowserWindow;
|
||||||
var instance: number = 0;
|
|
||||||
|
|
||||||
export function createSettingsWindow() {
|
export function createSettingsWindow() {
|
||||||
console.log("Creating a settings window.");
|
if (isAlreadyCreated) {
|
||||||
instance = instance + 1;
|
settingsWindow.show();
|
||||||
if (instance > 1) {
|
|
||||||
if (settingsWindow) {
|
|
||||||
settingsWindow.show();
|
|
||||||
settingsWindow.restore();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
settingsWindow = new BrowserWindow({
|
settingsWindow = new BrowserWindow({
|
||||||
width: 500,
|
width: 500,
|
||||||
|
@ -26,20 +27,20 @@ export function createSettingsWindow() {
|
||||||
});
|
});
|
||||||
ipcMain.on("saveSettings", (event, args: Settings) => {
|
ipcMain.on("saveSettings", (event, args: Settings) => {
|
||||||
console.log(args);
|
console.log(args);
|
||||||
setConfigBulk(args);
|
saveSettings(args);
|
||||||
});
|
});
|
||||||
ipcMain.handle("getSetting", (event, toGet: string) => {
|
ipcMain.handle("getSetting", (event, toGet: string) => {
|
||||||
return getConfig(toGet);
|
return getConfigUnsafe(toGet);
|
||||||
});
|
});
|
||||||
settingsWindow.webContents.setWindowOpenHandler(({url}) => {
|
settingsWindow.webContents.setWindowOpenHandler(({url}) => {
|
||||||
shell.openExternal(url);
|
shell.openExternal(url);
|
||||||
return {action: "deny"};
|
return {action: "deny"};
|
||||||
});
|
});
|
||||||
settingsWindow.loadURL(`file://${__dirname}/settings.html`);
|
settingsWindow.loadURL(`file://${__dirname}/settings.html`);
|
||||||
settingsWindow.on("close", (event: Event) => {
|
settingsWindow.on("close", async (e) => {
|
||||||
ipcMain.removeHandler("getSetting");
|
e.preventDefault();
|
||||||
ipcMain.removeAllListeners("saveSettings");
|
settingsWindow.hide();
|
||||||
instance = 0;
|
|
||||||
});
|
});
|
||||||
|
isAlreadyCreated = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<title>ArmCord Settings</title>
|
<title>ArmCord Settings</title>
|
||||||
<style>
|
<style>
|
||||||
@import url("../content/css/settings.css");
|
@import url("settings.css");
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
@ -13,6 +13,8 @@
|
||||||
<select name="theme" id="theme" class="left">
|
<select name="theme" id="theme" class="left">
|
||||||
<option value="default">Default</option>
|
<option value="default">Default</option>
|
||||||
<option value="native">Native</option>
|
<option value="native">Native</option>
|
||||||
|
<option value="glasstron">Glasstron (experimental)</option>
|
||||||
|
<option value="tabs">Tabs (experimental)</option>
|
||||||
</select>
|
</select>
|
||||||
<p class="header">ArmCord theme:</p>
|
<p class="header">ArmCord theme:</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -51,7 +53,15 @@
|
||||||
</select>
|
</select>
|
||||||
<p class="header">Client mod:</p>
|
<p class="header">Client mod:</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="switch">
|
||||||
|
<select name="blurType" id="blurType" class="left">
|
||||||
|
<option value="acrylic">Acrylic</option>
|
||||||
|
<option value="blurbehind">Blur Behind</option>
|
||||||
|
<option value="transparent">Transparent</option>
|
||||||
|
<option value="none">None</option>
|
||||||
|
</select>
|
||||||
|
<p class="header">Glasstron blur type:</p>
|
||||||
|
</div>
|
||||||
<button id="save" class="center">Save settings</button>
|
<button id="save" class="center">Save settings</button>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
@ -63,19 +73,20 @@
|
||||||
document.getElementById("mod").value = await settings.get("mods");
|
document.getElementById("mod").value = await settings.get("mods");
|
||||||
document.getElementById("channel").value = await settings.get("channel");
|
document.getElementById("channel").value = await settings.get("channel");
|
||||||
document.getElementById("theme").value = await settings.get("windowStyle");
|
document.getElementById("theme").value = await settings.get("windowStyle");
|
||||||
|
document.getElementById("blurType").value = await settings.get("blurType");
|
||||||
}
|
}
|
||||||
loadSettings();
|
loadSettings();
|
||||||
document.getElementById("save").addEventListener("click", function () {
|
document.getElementById("save").addEventListener("click", function () {
|
||||||
//function saveSettings(windowStyle: string, channelSetting: string, armcordCSPSetting: boolean, minimizeToTray: boolean, automaticPatches: boolean,modsSetting: string, blurType: string)
|
//function saveSettings(windowStyle: string, channelSetting: string, armcordCSPSetting: boolean, minimizeToTray: boolean, automaticPatches: boolean,modsSetting: string, blurType: string)
|
||||||
settings.save({
|
settings.save(
|
||||||
windowStyle: document.getElementById("theme").value,
|
document.getElementById("theme").value,
|
||||||
channel: document.getElementById("channel").value,
|
document.getElementById("channel").value,
|
||||||
armcordCSP: document.getElementById("csp").checked,
|
document.getElementById("csp").checked,
|
||||||
minimizeToTray: document.getElementById("tray").checked,
|
document.getElementById("tray").checked,
|
||||||
automaticPatches: document.getElementById("patches").checked,
|
document.getElementById("patches").checked,
|
||||||
mods: document.getElementById("mod").value,
|
document.getElementById("mod").value,
|
||||||
blurType: "acrylic"
|
document.getElementById("blurType").value
|
||||||
});
|
);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</html>
|
</html>
|
||||||
|
|
70
src/types/glasstron.d.ts
vendored
Normal file
70
src/types/glasstron.d.ts
vendored
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
declare module "glasstron" {
|
||||||
|
export class BrowserWindow extends Electron.BrowserWindow {
|
||||||
|
getBlur(): Promise<boolean>;
|
||||||
|
setBlur(value: boolean): Promise<boolean>;
|
||||||
|
blurType: WindowsBlurType;
|
||||||
|
setVibrancy(vibrancy: MacOSVibrancy): void;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
export function init(): void;
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
export function update(
|
||||||
|
window: Electron.BrowserWindow,
|
||||||
|
values: {
|
||||||
|
windows?: {
|
||||||
|
blurType: WindowsBlurType;
|
||||||
|
};
|
||||||
|
macos?: {
|
||||||
|
vibrancy: MacOSVibrancy;
|
||||||
|
};
|
||||||
|
linux?: {
|
||||||
|
requestBlur: boolean;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
): void;
|
||||||
|
export class Hacks {
|
||||||
|
static injectOnElectron(): void;
|
||||||
|
static delayReadyEvent(): void;
|
||||||
|
}
|
||||||
|
export type WindowsBlurType = "acrylic" | "blurbehind" | "transparent" | "none";
|
||||||
|
export type MacOSVibrancy =
|
||||||
|
| (
|
||||||
|
| "appearance-based"
|
||||||
|
| "light"
|
||||||
|
| "dark"
|
||||||
|
| "titlebar"
|
||||||
|
| "selection"
|
||||||
|
| "menu"
|
||||||
|
| "popover"
|
||||||
|
| "sidebar"
|
||||||
|
| "medium-light"
|
||||||
|
| "ultra-dark"
|
||||||
|
| "header"
|
||||||
|
| "sheet"
|
||||||
|
| "window"
|
||||||
|
| "hud"
|
||||||
|
| "fullscreen-ui"
|
||||||
|
| "tooltip"
|
||||||
|
| "content"
|
||||||
|
| "under-window"
|
||||||
|
| "under-page"
|
||||||
|
)
|
||||||
|
| null;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "glasstron/src/utils" {
|
||||||
|
class Utils {
|
||||||
|
static getSavePath(): string;
|
||||||
|
static copyToPath(innerFile: string, outerFilename?: string, flags?: number): void;
|
||||||
|
static removeFromPath(filename: string): void;
|
||||||
|
static isInPath(filename: string): boolean;
|
||||||
|
static getPlatform(): any;
|
||||||
|
static parseKeyValString(string: string, keyvalSeparator?: string, pairSeparator?: string): any;
|
||||||
|
static makeKeyValString(object: any, keyvalSeparator?: string, pairSeparator?: string): string;
|
||||||
|
}
|
||||||
|
export = Utils;
|
||||||
|
}
|
144
src/utils.ts
144
src/utils.ts
|
@ -1,8 +1,9 @@
|
||||||
|
import * as storage from "electron-json-storage";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import {app, dialog} from "electron";
|
import {app} from "electron";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
export var firstRun: boolean;
|
export var firstRun: boolean;
|
||||||
export var contentPath: string;
|
|
||||||
//utillity functions that are used all over the codebase or just too obscure to be put in the file used in
|
//utillity functions that are used all over the codebase or just too obscure to be put in the file used in
|
||||||
export function addStyle(styleString: string) {
|
export function addStyle(styleString: string) {
|
||||||
const style = document.createElement("style");
|
const style = document.createElement("style");
|
||||||
|
@ -20,17 +21,21 @@ export async function sleep(ms: number) {
|
||||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function checkIfConfigIsBroken() {
|
export async function checkIfConfigIsNew() {
|
||||||
if ((await getConfig("0")) == "d") {
|
if ((await getConfigUnsafe("automaticPatches")) == undefined) {
|
||||||
console.log("Detected a corrupted config");
|
firstRun = true;
|
||||||
setup();
|
|
||||||
dialog.showErrorBox(
|
|
||||||
"Oops, something went wrong.",
|
|
||||||
"ArmCord has detected that your configuration file is corrupted, please restart the app and set your settings again. If this issue persists, report it on the support server/Github issues."
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Settings {
|
||||||
|
windowStyle: string;
|
||||||
|
channel: string;
|
||||||
|
armcordCSP: boolean;
|
||||||
|
minimizeToTray: boolean;
|
||||||
|
automaticPatches: boolean;
|
||||||
|
mods: string;
|
||||||
|
blurType: string;
|
||||||
|
}
|
||||||
export function setup() {
|
export function setup() {
|
||||||
console.log("Setting up temporary ArmCord settings.");
|
console.log("Setting up temporary ArmCord settings.");
|
||||||
const defaults: Settings = {
|
const defaults: Settings = {
|
||||||
|
@ -40,14 +45,47 @@ export function setup() {
|
||||||
minimizeToTray: true,
|
minimizeToTray: true,
|
||||||
automaticPatches: false,
|
automaticPatches: false,
|
||||||
mods: "cumcord",
|
mods: "cumcord",
|
||||||
blurType: "acrylic",
|
blurType: "acrylic"
|
||||||
doneSetup: false
|
|
||||||
};
|
};
|
||||||
setConfigBulk({
|
storage.set(
|
||||||
...defaults
|
"settings",
|
||||||
});
|
{
|
||||||
|
...defaults,
|
||||||
|
doneSetup: false
|
||||||
|
},
|
||||||
|
function (error) {
|
||||||
|
if (error) throw error;
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function saveSettings(settings: Settings) {
|
||||||
|
console.log("Setting up ArmCord settings.");
|
||||||
|
storage.set(
|
||||||
|
"settings",
|
||||||
|
{
|
||||||
|
...settings,
|
||||||
|
doneSetup: true
|
||||||
|
},
|
||||||
|
function (error) {
|
||||||
|
if (error) throw error;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
export async function getConfigUnsafe(object: string) {
|
||||||
|
try {
|
||||||
|
const userDataPath = app.getPath("userData");
|
||||||
|
const storagePath = path.join(userDataPath, "/storage/");
|
||||||
|
let rawdata = fs.readFileSync(storagePath + "settings.json", "utf-8");
|
||||||
|
let returndata = JSON.parse(rawdata);
|
||||||
|
console.log(returndata[object]);
|
||||||
|
return returndata[object];
|
||||||
|
} catch (e) {
|
||||||
|
console.log("Config probably doesn't exist yet. Returning setup value.");
|
||||||
|
firstRun = true;
|
||||||
|
return "setup";
|
||||||
|
}
|
||||||
|
}
|
||||||
export function getVersion() {
|
export function getVersion() {
|
||||||
//to-do better way of doing this
|
//to-do better way of doing this
|
||||||
return "3.1.0";
|
return "3.1.0";
|
||||||
|
@ -61,79 +99,3 @@ export async function injectJS(inject: string) {
|
||||||
|
|
||||||
document.body.appendChild(el);
|
document.body.appendChild(el);
|
||||||
}
|
}
|
||||||
|
|
||||||
//ArmCord Settings/Storage manager
|
|
||||||
|
|
||||||
export interface Settings {
|
|
||||||
windowStyle: string;
|
|
||||||
channel: string;
|
|
||||||
armcordCSP: boolean;
|
|
||||||
minimizeToTray: boolean;
|
|
||||||
automaticPatches: boolean;
|
|
||||||
mods: string;
|
|
||||||
blurType: string;
|
|
||||||
doneSetup: boolean;
|
|
||||||
}
|
|
||||||
export async function getConfig(object: string) {
|
|
||||||
try {
|
|
||||||
const userDataPath = app.getPath("userData");
|
|
||||||
const storagePath = path.join(userDataPath, "/storage/");
|
|
||||||
const settingsFile = storagePath + "settings.json";
|
|
||||||
let rawdata = fs.readFileSync(settingsFile, "utf-8");
|
|
||||||
let returndata = JSON.parse(rawdata);
|
|
||||||
console.log(returndata[object]);
|
|
||||||
return returndata[object];
|
|
||||||
} catch (e) {
|
|
||||||
console.log("Config probably doesn't exist yet. Returning setup value.");
|
|
||||||
firstRun = true;
|
|
||||||
return "setup";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export async function setConfig(object: string, toSet: any) {
|
|
||||||
try {
|
|
||||||
const userDataPath = app.getPath("userData");
|
|
||||||
const storagePath = path.join(userDataPath, "/storage/");
|
|
||||||
const settingsFile = storagePath + "settings.json";
|
|
||||||
let rawdata = fs.readFileSync(settingsFile, "utf-8");
|
|
||||||
let parsed = JSON.parse(rawdata);
|
|
||||||
parsed[object] = toSet;
|
|
||||||
let toSave = JSON.stringify(parsed);
|
|
||||||
fs.writeFileSync(settingsFile, toSave, "utf-8");
|
|
||||||
} catch (e) {
|
|
||||||
console.log("Config probably doesn't exist yet. Returning setup value.");
|
|
||||||
firstRun = true;
|
|
||||||
return "setup";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export async function setConfigBulk(object: Settings) {
|
|
||||||
try {
|
|
||||||
const userDataPath = app.getPath("userData");
|
|
||||||
const storagePath = path.join(userDataPath, "/storage/");
|
|
||||||
const settingsFile = storagePath + "settings.json";
|
|
||||||
let toSave = JSON.stringify(object);
|
|
||||||
fs.writeFileSync(settingsFile, toSave, "utf-8");
|
|
||||||
} catch (e) {
|
|
||||||
console.log("Config probably doesn't exist yet. Returning setup value.");
|
|
||||||
firstRun = true;
|
|
||||||
return "setup";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
export async function checkIfConfigExists() {
|
|
||||||
const userDataPath = app.getPath("userData");
|
|
||||||
const storagePath = path.join(userDataPath, "/storage/");
|
|
||||||
const settingsFile = storagePath + "settings.json";
|
|
||||||
if (!fs.existsSync(settingsFile)) {
|
|
||||||
console.log("First run of the ArmCord. Starting setup.");
|
|
||||||
setup();
|
|
||||||
contentPath = path.join(__dirname, "/content/setup.html");
|
|
||||||
if (!contentPath.includes("ts-out")) {
|
|
||||||
contentPath = path.join(__dirname, "/ts-out/content/setup.html");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log("ArmCord has been run before. Skipping setup.");
|
|
||||||
contentPath = path.join(__dirname, "/content/splash.html");
|
|
||||||
if (!contentPath.includes("ts-out")) {
|
|
||||||
contentPath = path.join(__dirname, "/ts-out/content/splash.html");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,12 +2,14 @@
|
||||||
// I had to add most of the window creation code here to split both into seperete functions
|
// I had to add most of the window creation code here to split both into seperete functions
|
||||||
// WHY? Because I can't use the same code for both due to annoying bug with value `frame` not responding to variables
|
// WHY? Because I can't use the same code for both due to annoying bug with value `frame` not responding to variables
|
||||||
// I'm sorry for this mess but I'm not sure how to fix it.
|
// I'm sorry for this mess but I'm not sure how to fix it.
|
||||||
import {BrowserWindow, shell, app, ipcMain, dialog} from "electron";
|
import {BrowserWindow, shell, app, ipcMain} from "electron";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import {checkIfConfigIsBroken, firstRun, getConfig, contentPath} from "./utils";
|
import {contentPath} from "./main";
|
||||||
|
import {checkIfConfigIsNew, firstRun, getConfigUnsafe} from "./utils";
|
||||||
import {registerIpc} from "./ipc";
|
import {registerIpc} from "./ipc";
|
||||||
import contextMenu from "electron-context-menu";
|
import contextMenu from "electron-context-menu";
|
||||||
export let mainWindow: BrowserWindow;
|
export let mainWindow: BrowserWindow;
|
||||||
|
import * as glasstron from "glasstron";
|
||||||
|
|
||||||
let guestWindows: BrowserWindow[] = [];
|
let guestWindows: BrowserWindow[] = [];
|
||||||
contextMenu({
|
contextMenu({
|
||||||
|
@ -17,7 +19,7 @@ contextMenu({
|
||||||
});
|
});
|
||||||
|
|
||||||
function doAfterDefiningTheWindow() {
|
function doAfterDefiningTheWindow() {
|
||||||
checkIfConfigIsBroken();
|
checkIfConfigIsNew();
|
||||||
registerIpc();
|
registerIpc();
|
||||||
mainWindow.webContents.userAgent =
|
mainWindow.webContents.userAgent =
|
||||||
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36"; //fake useragent for screenshare to work
|
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36"; //fake useragent for screenshare to work
|
||||||
|
@ -30,11 +32,12 @@ function doAfterDefiningTheWindow() {
|
||||||
return callback({});
|
return callback({});
|
||||||
});
|
});
|
||||||
mainWindow.on("close", async (e) => {
|
mainWindow.on("close", async (e) => {
|
||||||
if (await getConfig("minimizeToTray")) {
|
if (await getConfigUnsafe("minimizeToTray")) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
mainWindow.hide();
|
mainWindow.hide();
|
||||||
} else if (!(await getConfig("minimizeToTray"))) {
|
} else if (!(await getConfigUnsafe("minimizeToTray"))) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
app.exit();
|
||||||
app.quit();
|
app.quit();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -93,12 +96,28 @@ export function createNativeWindow() {
|
||||||
});
|
});
|
||||||
doAfterDefiningTheWindow();
|
doAfterDefiningTheWindow();
|
||||||
}
|
}
|
||||||
|
export function createGlasstronWindow() {
|
||||||
|
mainWindow = new glasstron.BrowserWindow({
|
||||||
|
width: 300,
|
||||||
|
height: 350,
|
||||||
|
title: "ArmCord",
|
||||||
|
darkTheme: true,
|
||||||
|
icon: path.join(__dirname, "/assets/icon_transparent.png"),
|
||||||
|
frame: true,
|
||||||
|
autoHideMenuBar: true,
|
||||||
|
webPreferences: {
|
||||||
|
preload: path.join(__dirname, "preload/preload.js"),
|
||||||
|
spellcheck: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//@ts-expect-error
|
||||||
|
mainWindow.blurType = getConfigUnsafe("blurType");
|
||||||
|
//@ts-expect-error
|
||||||
|
mainWindow.setBlur(true);
|
||||||
|
doAfterDefiningTheWindow();
|
||||||
|
}
|
||||||
export function createTabsHost() {
|
export function createTabsHost() {
|
||||||
dialog.showErrorBox(
|
|
||||||
"READ THIS BEFORE USING THE APP",
|
|
||||||
"ArmCord Tabs are highly experimental and should be only used for strict testing purposes. Please don't ask for support, however you can still report bugs!"
|
|
||||||
);
|
|
||||||
guestWindows[1] = mainWindow;
|
guestWindows[1] = mainWindow;
|
||||||
mainWindow = new BrowserWindow({
|
mainWindow = new BrowserWindow({
|
||||||
width: 300,
|
width: 300,
|
||||||
|
|
Loading…
Reference in a new issue