mirror of
				https://github.com/smartfrigde/armcord.git
				synced 2024-08-14 23:56:58 +00:00 
			
		
		
		
	Settings, Electron 17 and much more
This commit is contained in:
		
							parent
							
								
									fcdb247601
								
							
						
					
					
						commit
						c98b6016ca
					
				
					 24 changed files with 1226 additions and 244 deletions
				
			
		
							
								
								
									
										633
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										633
									
								
								package-lock.json
									
										
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -4,7 +4,7 @@ | ||||||
|   "description": "ArmCord is a custom client designed to enhance your Discord experience while keeping everything lightweight.", |   "description": "ArmCord is a custom client designed to enhance your Discord experience while keeping everything lightweight.", | ||||||
|   "main": "ts-out/main.js", |   "main": "ts-out/main.js", | ||||||
|   "scripts": { |   "scripts": { | ||||||
|     "build": "tsc && copyfiles -u 1 src/**/*.html src/**/*.css ts-out/ && copyfiles package.json ts-out/ && copyfiles assets/** ts-out/", |     "build": "tsc && copyfiles -u 1 src/**/*.html src/**/**/*.css ts-out/ && copyfiles package.json ts-out/ && copyfiles assets/** ts-out/", | ||||||
|     "watch": "tsc -w", |     "watch": "tsc -w", | ||||||
|     "start": "npm run build && electron ./ts-out/main.js", |     "start": "npm run build && electron ./ts-out/main.js", | ||||||
|     "package": "npm run build && electron-builder" |     "package": "npm run build && electron-builder" | ||||||
|  | @ -23,12 +23,15 @@ | ||||||
|     "@types/electron-json-storage": "^4.5.0", |     "@types/electron-json-storage": "^4.5.0", | ||||||
|     "@types/node": "^14.18.2", |     "@types/node": "^14.18.2", | ||||||
|     "copyfiles": "^2.4.1", |     "copyfiles": "^2.4.1", | ||||||
|     "electron": "^16.0.7", |     "electron": "^17.1.0", | ||||||
|     "electron-builder": "^22.14.5", |     "electron-builder": "^22.14.13", | ||||||
|     "typescript": "^4.5.4" |     "typescript": "^4.5.4" | ||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|  |     "electron-context-menu": "^3.1.2", | ||||||
|     "electron-json-storage": "^4.5.0", |     "electron-json-storage": "^4.5.0", | ||||||
|  |     "electron-tabs": "^0.15.0", | ||||||
|  |     "glasstron": "^0.1.1", | ||||||
|     "v8-compile-cache": "^2.3.0" |     "v8-compile-cache": "^2.3.0" | ||||||
|   }, |   }, | ||||||
|   "build": { |   "build": { | ||||||
|  |  | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| .info-1sUqUG:last-child:before { | .info-3pQQBb:last-child:before { | ||||||
|   content: "ArmCord Version: 3.1.0"!important; |   content: "ArmCord Version: 3.1.0"!important; | ||||||
|   height: auto; |   height: auto; | ||||||
|   line-height: 16px; |   line-height: 16px; | ||||||
|  |  | ||||||
							
								
								
									
										53
									
								
								src/content/css/tabs.css
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								src/content/css/tabs.css
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,53 @@ | ||||||
|  | @import url("https://kckarnige.github.io/femboi_owo/discord-font.css"); | ||||||
|  | :root { | ||||||
|  |   --window-buttons: var(--header-secondary); | ||||||
|  |   --cord-color: var(--header-primary); | ||||||
|  |   --armcord-color: #7289da; | ||||||
|  |   --titlebar-color: var(--background-tertiary); | ||||||
|  | } | ||||||
|  | .tabs { | ||||||
|  |   display: block; | ||||||
|  |   top: 0; | ||||||
|  |   left: 0; | ||||||
|  |   right: 0; | ||||||
|  |   flex-shrink: 0; | ||||||
|  |   overflow: hidden; | ||||||
|  |   zoom: 1; | ||||||
|  |   box-sizing: border-box; | ||||||
|  |   width: 100%; | ||||||
|  |   clear: both; | ||||||
|  |   height: 30px; | ||||||
|  |   line-height: 30px; | ||||||
|  |   background-color: #202225; | ||||||
|  |   -webkit-app-region: drag; | ||||||
|  |   width: 100%; | ||||||
|  |   user-select: none; | ||||||
|  |   -webkit-user-select: none; | ||||||
|  |   position: fixed; | ||||||
|  |   z-index: 99999; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .tabs #tabs-controls-container { | ||||||
|  |   float: left; | ||||||
|  |   width: 150px; | ||||||
|  |   height: 100%; | ||||||
|  |   line-height: 30px; | ||||||
|  |   background-color: #202225; | ||||||
|  |   -webkit-app-region: no-drag; | ||||||
|  | } | ||||||
|  | .tabs-buttons { | ||||||
|  |   color: white; | ||||||
|  |   background-color: inherit; | ||||||
|  |   float: left; | ||||||
|  |   border: none; | ||||||
|  |   outline: none; | ||||||
|  |   cursor: pointer; | ||||||
|  |   transition: 0.3s; | ||||||
|  |   font-size: 20px; | ||||||
|  | } | ||||||
|  | .tabs-buttons:hover { | ||||||
|  |   background-color: #4e515a; | ||||||
|  | } | ||||||
|  | .withFrame-haYltI { | ||||||
|  |   height: 30px !important; | ||||||
|  | } | ||||||
|  | @ -1,4 +1,4 @@ | ||||||
| @import url("https://kckarnige.github.io/femboi_owo/discord-font.css"); | @import url("https://armcord.smartfridge.space/logofont.css"); | ||||||
| :root { | :root { | ||||||
|   --window-buttons: var(--header-secondary); |   --window-buttons: var(--header-secondary); | ||||||
|   --cord-color: var(--header-primary); |   --cord-color: var(--header-primary); | ||||||
|  |  | ||||||
|  | @ -1 +0,0 @@ | ||||||
| <h1>settings, really cool</h1> |  | ||||||
|  | @ -1,3 +1,4 @@ | ||||||
|  | <!--- This is awful and should be replaced in later versions. Possibly based of current settings as of 3.1.0 version. If you have time please PR a better setup screen. ---> | ||||||
| <!DOCTYPE html> | <!DOCTYPE html> | ||||||
| <html lang="en"> | <html lang="en"> | ||||||
|   <head> |   <head> | ||||||
|  | @ -42,7 +43,7 @@ | ||||||
|       } else { |       } else { | ||||||
|         console.log("Starting ArmCord Setup..."); |         console.log("Starting ArmCord Setup..."); | ||||||
|         document.getElementById("express").addEventListener("click", function () { |         document.getElementById("express").addEventListener("click", function () { | ||||||
|           window.armcordinternal.saveSettings(true, "stable", true, "cumcord"); |           window.armcordinternal.saveSettings("default", "stable", true, true, false, "cumcord", "acrylic"); | ||||||
|           fade(document.getElementById("setup")); |           fade(document.getElementById("setup")); | ||||||
|                 setTimeout(function () { |                 setTimeout(function () { | ||||||
|                   window.armcordinternal.restart() |                   window.armcordinternal.restart() | ||||||
|  | @ -90,15 +91,15 @@ | ||||||
|                   .getElementById("next") |                   .getElementById("next") | ||||||
|                   .addEventListener("click", function () { |                   .addEventListener("click", function () { | ||||||
|                     var mod = document.getElementById("mod").value; |                     var mod = document.getElementById("mod").value; | ||||||
|                     window.armcordinternal.saveSettings(true, branch, true, mod); |                     window.armcordinternal.saveSettings("default", branch, true,true,false, mod, "acrylic"); | ||||||
|                     fade(document.getElementById("setup")); |                     fade(document.getElementById("setup")); | ||||||
|                     setTimeout(function () { |                     setTimeout(function () { | ||||||
|                       window.armcordinternal.restart(); |                       window.armcordinternal.restart(); | ||||||
|                     }, 5000); |                     }, 5000); | ||||||
|                   }); |                   }); | ||||||
|               } else { |               } else { | ||||||
|                 //saveSettings(customTitlebarSetting: boolean, channelSetting: string, armcordCSPSetting: boolean, modsSetting: string) |                 //saveSettings(windowStyle: string, channelSetting: string, armcordCSPSetting: boolean, minimizeToTray:boolean, modsSetting: string) | ||||||
|                 window.armcordinternal.saveSettings(true, branch, true, "none"); |                 window.armcordinternal.saveSettings("default", branch, true,true,false, "none", "acrylic"); | ||||||
|                 fade(document.getElementById("setup")); |                 fade(document.getElementById("setup")); | ||||||
|                 setTimeout(function () { |                 setTimeout(function () { | ||||||
|                   window.armcordinternal.restart() |                   window.armcordinternal.restart() | ||||||
|  |  | ||||||
							
								
								
									
										22
									
								
								src/ipc.ts
									
										
									
									
									
								
							
							
						
						
									
										22
									
								
								src/ipc.ts
									
										
									
									
									
								
							|  | @ -1,13 +1,16 @@ | ||||||
| //ipc stuff
 | //ipc stuff
 | ||||||
| import { app, ipcMain, shell, desktopCapturer } from "electron"; | import { app, ipcMain, shell, desktopCapturer } from "electron"; | ||||||
| import { mainWindow } from "./window"; | import { createTabsGuest, mainWindow } from "./window"; | ||||||
| import { saveSettings, getVersion } from "./utils"; | import { saveSettings, getVersion } from "./utils"; | ||||||
| import { settings, customTitlebar } 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) => { | ||||||
|     event.reply("app-path", app.getAppPath()); |     event.reply("app-path", app.getAppPath()); | ||||||
|   }); |   }); | ||||||
|  |   ipcMain.on("openTab", (event, number: number) => { | ||||||
|  |     createTabsGuest(number); | ||||||
|  |   }); | ||||||
|   ipcMain.on("open-external-link", (event, href: string) => { |   ipcMain.on("open-external-link", (event, href: string) => { | ||||||
|     shell.openExternal(href); |     shell.openExternal(href); | ||||||
|   }); |   }); | ||||||
|  | @ -29,6 +32,9 @@ export function registerIpc() { | ||||||
|   ipcMain.on("win-hide", (event, arg) => { |   ipcMain.on("win-hide", (event, arg) => { | ||||||
|     mainWindow.hide(); |     mainWindow.hide(); | ||||||
|   }); |   }); | ||||||
|  |   ipcMain.on("win-quit", (event, arg) => { | ||||||
|  |     app.exit(); | ||||||
|  |   }); | ||||||
|   ipcMain.on("get-app-version", (event) => { |   ipcMain.on("get-app-version", (event) => { | ||||||
|     event.returnValue = getVersion(); |     event.returnValue = getVersion(); | ||||||
|   }); |   }); | ||||||
|  | @ -39,11 +45,14 @@ export function registerIpc() { | ||||||
|     app.relaunch(); |     app.relaunch(); | ||||||
|     app.exit(); |     app.exit(); | ||||||
|   }); |   }); | ||||||
| 
 |  | ||||||
|   ipcMain.on("saveSettings", (event, ...args) => { |   ipcMain.on("saveSettings", (event, ...args) => { | ||||||
|     //@ts-ignore
 |     //@ts-ignore
 | ||||||
|     saveSettings(...args); |     saveSettings(...args); | ||||||
|   }); |   }); | ||||||
|  |   ipcMain.on("minimizeToTray", (event) => { | ||||||
|  |     console.log(settings.minimizeToTray); | ||||||
|  |     event.returnValue = settings.minimizeToTray; | ||||||
|  |   }); | ||||||
|   ipcMain.on("channel", (event) => { |   ipcMain.on("channel", (event) => { | ||||||
|     event.returnValue = settings.channel; |     event.returnValue = settings.channel; | ||||||
|   }); |   }); | ||||||
|  | @ -53,6 +62,12 @@ export function registerIpc() { | ||||||
|   ipcMain.on("titlebar", (event, arg) => { |   ipcMain.on("titlebar", (event, arg) => { | ||||||
|     event.returnValue = customTitlebar; |     event.returnValue = customTitlebar; | ||||||
|   }); |   }); | ||||||
|  |   ipcMain.on("tabs", (event, arg) => { | ||||||
|  |     event.returnValue = tabs; | ||||||
|  |   }); | ||||||
|  |   ipcMain.on("shouldPatch", (event, arg) => { | ||||||
|  |     event.returnValue = settings.automaticPatches; | ||||||
|  |   }); | ||||||
|   ipcMain.on("openSettingsWindow", (event, arg) => { |   ipcMain.on("openSettingsWindow", (event, arg) => { | ||||||
|     createSettingsWindow(); |     createSettingsWindow(); | ||||||
|   }); |   }); | ||||||
|  | @ -66,5 +81,4 @@ export function registerIpc() { | ||||||
|   ipcMain.handle("DESKTOP_CAPTURER_GET_SOURCES", (event, opts) => |   ipcMain.handle("DESKTOP_CAPTURER_GET_SOURCES", (event, opts) => | ||||||
|     desktopCapturer.getSources(opts) |     desktopCapturer.getSources(opts) | ||||||
|   ); |   ); | ||||||
|    |  | ||||||
| } | } | ||||||
|  |  | ||||||
							
								
								
									
										72
									
								
								src/main.ts
									
										
									
									
									
								
							
							
						
						
									
										72
									
								
								src/main.ts
									
										
									
									
									
								
							|  | @ -11,13 +11,21 @@ import { getConfigUnsafe, setup } from "./utils"; | ||||||
| import "./extensions/mods"; | import "./extensions/mods"; | ||||||
| import "./extensions/plugin"; | import "./extensions/plugin"; | ||||||
| import "./tray"; | import "./tray"; | ||||||
| import { mainWindow, createCustomWindow, createNativeWindow } from "./window"; | import { mainWindow, createCustomWindow, createNativeWindow, createGlasstronWindow, createTabsHost } from "./window"; | ||||||
| import "./shortcuts"; | import "./shortcuts"; | ||||||
| export var contentPath: string; | export var contentPath: string; | ||||||
| var channel: string; | var channel: string; | ||||||
| export var settings: any; | export var settings: any; | ||||||
| export var customTitlebar: boolean; | export var customTitlebar: boolean; | ||||||
| storage.has("settings", function (error, hasKey) { | 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; |     if (error) throw error; | ||||||
| 
 | 
 | ||||||
|     if (!hasKey) { |     if (!hasKey) { | ||||||
|  | @ -34,7 +42,7 @@ storage.has("settings", function (error, hasKey) { | ||||||
|         contentPath = path.join(__dirname, "/ts-out/content/splash.html"); |         contentPath = path.join(__dirname, "/ts-out/content/splash.html"); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| }); |   }); | ||||||
| storage.get("settings", function (error, data: any) { | storage.get("settings", function (error, data: any) { | ||||||
|   if (error) throw error; |   if (error) throw error; | ||||||
|   console.log(data); |   console.log(data); | ||||||
|  | @ -42,19 +50,33 @@ storage.get("settings", function (error, data: any) { | ||||||
|   settings = data; |   settings = data; | ||||||
| }); | }); | ||||||
| app.whenReady().then(async () => { | app.whenReady().then(async () => { | ||||||
|   if (await getConfigUnsafe("customTitlebar") == true) { |   switch (await getConfigUnsafe("windowStyle")) { | ||||||
|     console.log("Creating custom titlebar window."); |     case "default": | ||||||
|     customTitlebar = true; |  | ||||||
|       createCustomWindow(); |       createCustomWindow(); | ||||||
|   } else if (await getConfigUnsafe("customTitlebar") == "setup") { |  | ||||||
|     //rare case of setup window
 |  | ||||||
|     console.log("Creating setup window."); |  | ||||||
|       customTitlebar = true; |       customTitlebar = true; | ||||||
|     createCustomWindow(); |       break; | ||||||
|   } else { |     case "native": | ||||||
|     console.log("Creating native titlebar window."); |  | ||||||
|     customTitlebar = false; |  | ||||||
|       createNativeWindow(); |       createNativeWindow(); | ||||||
|  |       break; | ||||||
|  |     case "glasstron": | ||||||
|  |       setTimeout( | ||||||
|  |         createGlasstronWindow, | ||||||
|  |         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.
 | ||||||
|  |       ); | ||||||
|  |       break; | ||||||
|  |     case "tabs": | ||||||
|  |       createTabsHost(); | ||||||
|  |       tabs = true; | ||||||
|  |       break; | ||||||
|  |     default: | ||||||
|  |       createCustomWindow(); | ||||||
|  |       customTitlebar = true; | ||||||
|  |       break; | ||||||
|   } |   } | ||||||
|   session |   session | ||||||
|     .fromPartition("some-partition") |     .fromPartition("some-partition") | ||||||
|  | @ -68,19 +90,21 @@ app.whenReady().then(async () => { | ||||||
|         callback(true); |         callback(true); | ||||||
|       } |       } | ||||||
|     }); |     }); | ||||||
|   mainWindow.webContents.session.webRequest.onBeforeRequest( |   app.on("activate", async function () { | ||||||
|     (details, callback) => { |  | ||||||
|       if (/api\/v\d\/science$/g.test(details.url)) |  | ||||||
|         return callback({ cancel: true }); |  | ||||||
|       return callback({}); |  | ||||||
|     } |  | ||||||
|   ); |  | ||||||
|   app.on("activate", function () { |  | ||||||
|     if (BrowserWindow.getAllWindows().length === 0) |     if (BrowserWindow.getAllWindows().length === 0) | ||||||
|       if (!settings.customTitlebar) { |       switch (await getConfigUnsafe("windowStyle")) { | ||||||
|         createNativeWindow(); |         case "default": | ||||||
|       } else { |  | ||||||
|           createCustomWindow(); |           createCustomWindow(); | ||||||
|  |           break; | ||||||
|  |         case "native": | ||||||
|  |           createNativeWindow(); | ||||||
|  |           break; | ||||||
|  |         case "glasstron": | ||||||
|  |           createGlasstronWindow(); | ||||||
|  |           break; | ||||||
|  |         default: | ||||||
|  |           createCustomWindow(); | ||||||
|  |           break; | ||||||
|       } |       } | ||||||
|   }); |   }); | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | @ -15,6 +15,7 @@ contextBridge.exposeInMainWorld("armcord", { | ||||||
|   }, |   }, | ||||||
|   electron: process.versions.electron, |   electron: process.versions.electron, | ||||||
|   channel: ipcRenderer.sendSync("channel"), |   channel: ipcRenderer.sendSync("channel"), | ||||||
|  |   openTab: (number: number) => ipcRenderer.sendSync("openTab", number), | ||||||
|   version: ipcRenderer.sendSync("get-app-version", "app-version"), |   version: ipcRenderer.sendSync("get-app-version", "app-version"), | ||||||
|   getDisplayMediaSelector: getDisplayMediaSelector, |   getDisplayMediaSelector: getDisplayMediaSelector, | ||||||
|   openSettingsWindow: () => ipcRenderer.send("openSettingsWindow"), |   openSettingsWindow: () => ipcRenderer.send("openSettingsWindow"), | ||||||
|  |  | ||||||
|  | @ -1,8 +1,11 @@ | ||||||
| //Fixed context isolation version https://github.com/getferdi/ferdi/blob/develop/src/webview/screenshare.ts
 | //Fixed context isolation version https://github.com/getferdi/ferdi/blob/develop/src/webview/screenshare.ts
 | ||||||
| //original https://github.com/electron/electron/issues/16513#issuecomment-602070250
 | //original https://github.com/electron/electron/issues/16513#issuecomment-602070250
 | ||||||
| import { desktopCapturer } from 'electron'; | import { ipcRenderer } from 'electron'; | ||||||
| import {addStyle, addScript} from '../utils'; | import {addStyle, addScript} from '../utils'; | ||||||
| 
 | const desktopCapturer = { | ||||||
|  |   getSources: (opts: any) => | ||||||
|  |     ipcRenderer.invoke("DESKTOP_CAPTURER_GET_SOURCES", opts), | ||||||
|  | }; | ||||||
| const CANCEL_ID = 'desktop-capturer-selection__cancel'; | const CANCEL_ID = 'desktop-capturer-selection__cancel'; | ||||||
| 
 | 
 | ||||||
| export async function getDisplayMediaSelector() { | export async function getDisplayMediaSelector() { | ||||||
|  | @ -12,7 +15,7 @@ export async function getDisplayMediaSelector() { | ||||||
|   return `<div class="desktop-capturer-selection__scroller">
 |   return `<div class="desktop-capturer-selection__scroller">
 | ||||||
|   <ul class="desktop-capturer-selection__list"> |   <ul class="desktop-capturer-selection__list"> | ||||||
|     ${sources |     ${sources | ||||||
|       .map( |       .map( //@ts-ignore i know it works
 | ||||||
|         ({ id, name, thumbnail }) => ` |         ({ id, name, thumbnail }) => ` | ||||||
|       <li class="desktop-capturer-selection__item"> |       <li class="desktop-capturer-selection__item"> | ||||||
|         <button class="desktop-capturer-selection__btn" data-id="${id}" title="${name}"> |         <button class="desktop-capturer-selection__btn" data-id="${id}" title="${name}"> | ||||||
|  |  | ||||||
							
								
								
									
										22
									
								
								src/preload/patch.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/preload/patch.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,22 @@ | ||||||
|  | // What does this do?
 | ||||||
|  | // In case of faulty update of ArmCord we can quickly push an update to the user and possibly try to fix it
 | ||||||
|  | // This is completely optional and is disabled by default in settings
 | ||||||
|  | import { ipcRenderer } from "electron"; | ||||||
|  | import { injectJS } from "../utils"; | ||||||
|  | 
 | ||||||
|  | var patchEndpoint = "https://patch.armcord.xyz/"; | ||||||
|  | var version = ipcRenderer.sendSync("get-app-version", "app-version"); | ||||||
|  | if (ipcRenderer.sendSync("shouldPatch")) { | ||||||
|  |   document.addEventListener("DOMContentLoaded", function () { | ||||||
|  |     fetch(patchEndpoint + version + "/info.json", {cache: "no-store"}) //lmao
 | ||||||
|  |       .then((res) => res.json()) | ||||||
|  |       .then((res) => { | ||||||
|  |         if (res.patch == true) { | ||||||
|  |             console.log("Found a patch. Injecting..."); | ||||||
|  |             injectJS(patchEndpoint + version + "/patch.js"); | ||||||
|  |         } else { | ||||||
|  |             console.log("No patches have been found.") | ||||||
|  |         } | ||||||
|  |       }); | ||||||
|  |   }); | ||||||
|  | } | ||||||
|  | @ -1,11 +1,12 @@ | ||||||
| import "./bridge"; | import "./bridge"; | ||||||
| import "./capturer"; | import "./capturer"; | ||||||
|  | import "./patch" | ||||||
| import * as fs from "fs"; | import * as fs from "fs"; | ||||||
| import * as path from "path"; | import * as path from "path"; | ||||||
| import { injectTitlebar } from "./titlebar"; | import { injectTitlebar } from "./titlebar"; | ||||||
| import { sleep, addStyle } from "../utils"; | import { sleep, addStyle, injectJS } from "../utils"; | ||||||
| import { ipcRenderer } from "electron"; | import { ipcRenderer } from "electron"; | ||||||
| 
 | import { injectTabs } from "./tabs"; | ||||||
| declare global { | declare global { | ||||||
|   interface Window { |   interface Window { | ||||||
|     armcord: any; |     armcord: any; | ||||||
|  | @ -17,15 +18,6 @@ const clientMods = { | ||||||
|     "https://raw.githubusercontent.com/Cumcord/Cumcord/stable/dist/build.js", |     "https://raw.githubusercontent.com/Cumcord/Cumcord/stable/dist/build.js", | ||||||
|   flicker: "https://raw.githubusercontent.com/FlickerMod/dist/main/build.js", |   flicker: "https://raw.githubusercontent.com/FlickerMod/dist/main/build.js", | ||||||
| }; | }; | ||||||
| async function injectJS(inject: string) { |  | ||||||
|   const js = await (await fetch(`${inject}`)).text(); |  | ||||||
| 
 |  | ||||||
|   const el = document.createElement("script"); |  | ||||||
| 
 |  | ||||||
|   el.appendChild(document.createTextNode(js)); |  | ||||||
| 
 |  | ||||||
|   document.body.appendChild(el); |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| console.log("ArmCord"); | console.log("ArmCord"); | ||||||
| if (window.location.href.indexOf("splash.html") > -1) { | if (window.location.href.indexOf("splash.html") > -1) { | ||||||
|  | @ -34,6 +26,9 @@ if (window.location.href.indexOf("splash.html") > -1) { | ||||||
|   if (ipcRenderer.sendSync("titlebar")) { |   if (ipcRenderer.sendSync("titlebar")) { | ||||||
|     injectTitlebar(); |     injectTitlebar(); | ||||||
|   } |   } | ||||||
|  |   if (ipcRenderer.sendSync("tabs")) { | ||||||
|  |     injectTabs(); | ||||||
|  |   } | ||||||
|   sleep(5000).then(() => { |   sleep(5000).then(() => { | ||||||
|     const cssPath = path.join(__dirname, "../", "/content/css/discord.css"); |     const cssPath = path.join(__dirname, "../", "/content/css/discord.css"); | ||||||
|     addStyle(fs.readFileSync(cssPath, "utf8")); |     addStyle(fs.readFileSync(cssPath, "utf8")); | ||||||
|  |  | ||||||
							
								
								
									
										25
									
								
								src/preload/tabs.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/preload/tabs.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,25 @@ | ||||||
|  | import { addStyle } from "../utils"; | ||||||
|  | import * as fs from "fs"; | ||||||
|  | import * as path from "path"; | ||||||
|  | export function injectTabs() { | ||||||
|  |   document.addEventListener("DOMContentLoaded", function (event) { | ||||||
|  |     var elem = document.createElement("div"); | ||||||
|  |     elem.innerHTML = `<nav class="tabs">
 | ||||||
|  |           <div id="tabs-controls-container"> | ||||||
|  |               <button class="tabs-buttons" onclick="armcord.openTab(1)">1</button> | ||||||
|  |               <button class="tabs-buttons" onclick="armcord.openTab(2)">2</button> | ||||||
|  |               <button class="tabs-buttons" onclick="armcord.openTab(3)">3</button> | ||||||
|  |               <button class="tabs-buttons" onclick="armcord.openTab(4)">4</button> | ||||||
|  |               <button class="tabs-buttons" onclick="armcord.openTab(5)">5</button> | ||||||
|  |               <p class="experimental">Experimental</p> | ||||||
|  |           </div> | ||||||
|  |         </nav>`;
 | ||||||
|  |     elem.classList.add("withFrame-haYltI"); | ||||||
|  |     if (document.getElementById("app-mount") == null) { | ||||||
|  |       document.body.appendChild(elem); | ||||||
|  |     } else { | ||||||
|  |       document.getElementById("app-mount")!.prepend(elem); | ||||||
|  |     } | ||||||
|  |     const cssPath = path.join(__dirname, "../", "/content/css/tabs.css"); | ||||||
|  |     addStyle(fs.readFileSync(cssPath, "utf8"));  | ||||||
|  | })} | ||||||
|  | @ -39,7 +39,11 @@ export function injectTitlebar() { | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     quit!.addEventListener("click", () => { |     quit!.addEventListener("click", () => { | ||||||
|  |       if (ipcRenderer.sendSync("minimizeToTray") === true) { | ||||||
|         ipcRenderer.send("win-hide"); |         ipcRenderer.send("win-hide"); | ||||||
|  |       } else if (ipcRenderer.sendSync("minimizeToTray") === false) { | ||||||
|  |         ipcRenderer.send("win-quit"); | ||||||
|  |       } | ||||||
|     }); |     }); | ||||||
|   }); |   }); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,25 +1,46 @@ | ||||||
| import { BrowserWindow, shell } from "electron"; | import { BrowserWindow, shell, ipcMain } from "electron"; | ||||||
|  | import * as storage from "electron-json-storage";  | ||||||
|  | import {getConfigUnsafe, saveSettings} from "../utils"; | ||||||
| import path from "path"; | import path from "path"; | ||||||
| 
 | var settings:any; | ||||||
| var settingsWindow; | var isAlreadyCreated:boolean = false; | ||||||
|  | storage.get("settings", function (error, data: any) { | ||||||
|  |   if (error) throw error; | ||||||
|  |   console.log(data); | ||||||
|  |   settings = data; | ||||||
|  | }); | ||||||
|  | var settingsWindow:BrowserWindow; | ||||||
| export function createSettingsWindow() { | export function createSettingsWindow() { | ||||||
|  |   if (isAlreadyCreated) { | ||||||
|  |     settingsWindow.show(); | ||||||
|  |   } else { | ||||||
|   settingsWindow = new BrowserWindow({ |   settingsWindow = new BrowserWindow({ | ||||||
|     width: 500, |     width: 500, | ||||||
|     height: 600, |     height: 500, | ||||||
|     title: "ArmCord Settings", |     title: "ArmCord Settings", | ||||||
|     darkTheme: true, |     darkTheme: true, | ||||||
|     icon: path.join(__dirname, "/assets/icon_transparent.png"), |     frame: true, | ||||||
|     frame: false, |  | ||||||
|     autoHideMenuBar: true, |     autoHideMenuBar: true, | ||||||
|     webPreferences: { |     webPreferences: { | ||||||
|       preload: path.join(__dirname, "preload/preload.js"), |       preload: path.join(__dirname, "preload.js"), | ||||||
|     }, |     }, | ||||||
|   }); |   }); | ||||||
| 
 |   ipcMain.on("saveSettings", (event, ...args) => { | ||||||
|  |     //@ts-ignore
 | ||||||
|  |     saveSettings(...args); | ||||||
|  |   }); | ||||||
|  |   ipcMain.handle("getSetting", (event, toGet: string) => { | ||||||
|  |     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.loadFile("settings.html"); |   settingsWindow.on("close", async (e) => { | ||||||
|  |     e.preventDefault() | ||||||
|  |     settingsWindow.hide() | ||||||
|  |   }); | ||||||
|  |   isAlreadyCreated = true; | ||||||
|  | } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1 +1,6 @@ | ||||||
| console.log("test") | import {contextBridge, ipcRenderer} from "electron"; | ||||||
|  | console.log("ArmCord Settings") | ||||||
|  | contextBridge.exposeInMainWorld("settings", { | ||||||
|  |   save: (...args: any) => ipcRenderer.send("saveSettings", ...args), | ||||||
|  |   get: (toGet: string) => ipcRenderer.invoke('getSetting', toGet).then((result) => {return result}) //jank but works
 | ||||||
|  | }); | ||||||
							
								
								
									
										157
									
								
								src/settings/settings.css
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								src/settings/settings.css
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,157 @@ | ||||||
|  | /*MIT License | ||||||
|  | 
 | ||||||
|  | Copyright (c) 2021 GooseMod | ||||||
|  | 
 | ||||||
|  | Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  | of this software and associated documentation files (the "Software"), to deal | ||||||
|  | in the Software without restriction, including without limitation the rights | ||||||
|  | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  | copies of the Software, and to permit persons to whom the Software is | ||||||
|  | furnished to do so, subject to the following conditions: | ||||||
|  | 
 | ||||||
|  | The above copyright notice and this permission notice shall be included in all | ||||||
|  | copies or substantial portions of 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.*/ | ||||||
|  | :root { | ||||||
|  |   --background-primary: #282b30; | ||||||
|  |   --background-secondary: rgba(255, 255, 255, 0.1); | ||||||
|  |   --brand-experiment: #5865f2; | ||||||
|  |   --header-primary: #fff; | ||||||
|  |   --text-muted: #72767d; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | @font-face { | ||||||
|  |   font-family: Whitney; | ||||||
|  |   font-weight: 400; | ||||||
|  |   font-style: normal; | ||||||
|  |   src: url(https://armcord.smartfridge.space/whitney_400.woff) format("woff"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | html, | ||||||
|  | body { | ||||||
|  |   overflow: hidden; | ||||||
|  | 
 | ||||||
|  |   margin: 0; | ||||||
|  |   padding: 0; | ||||||
|  |   margin: 2%; | ||||||
|  |   background: var(--background-primary); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | * { | ||||||
|  |   font-family: "Whitney", sans-serif; | ||||||
|  | 
 | ||||||
|  |   box-sizing: border-box; | ||||||
|  |   cursor: default; | ||||||
|  | } | ||||||
|  | .left { | ||||||
|  |     float:right; | ||||||
|  |     vertical-align: right!important; | ||||||
|  | } | ||||||
|  | .switch { | ||||||
|  |   vertical-align: middle; | ||||||
|  | } | ||||||
|  | .header { | ||||||
|  |   color: white; | ||||||
|  |   font-size: 1.5em; | ||||||
|  | } | ||||||
|  | .center { | ||||||
|  |   text-align: center; | ||||||
|  | } | ||||||
|  | /*buttons*/ | ||||||
|  | button { | ||||||
|  |     background-color: #7289da; | ||||||
|  |     font-family: Whitney, "Helvetica Neue", Helvetica, Arial, sans-serif; | ||||||
|  |     color: #ffffff; | ||||||
|  |     padding: 4px; | ||||||
|  |     border-radius: 5px; | ||||||
|  |     margin-top: 5px; | ||||||
|  |      | ||||||
|  |     text-align: center; | ||||||
|  |     border-style: none; | ||||||
|  |     outline: none; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | button:hover { | ||||||
|  |     background-color: #687dc6; | ||||||
|  |     border-style: none; | ||||||
|  |     outline: none; | ||||||
|  |     cursor: pointer; | ||||||
|  | } | ||||||
|  | .tgl { | ||||||
|  |   display: none; | ||||||
|  | } | ||||||
|  | .tgl, .tgl:after, .tgl:before, .tgl *, .tgl *:after, .tgl *:before, .tgl + .tgl-btn { | ||||||
|  |   box-sizing: border-box; | ||||||
|  | } | ||||||
|  | .tgl::-moz-selection, .tgl:after::-moz-selection, .tgl:before::-moz-selection, .tgl *::-moz-selection, .tgl *:after::-moz-selection, .tgl *:before::-moz-selection, .tgl + .tgl-btn::-moz-selection { | ||||||
|  |   background: none; | ||||||
|  | } | ||||||
|  | .tgl::selection, .tgl:after::selection, .tgl:before::selection, .tgl *::selection, .tgl *:after::selection, .tgl *:before::selection, .tgl + .tgl-btn::selection { | ||||||
|  |   background: none; | ||||||
|  | } | ||||||
|  | .tgl + .tgl-btn { | ||||||
|  |   outline: 0; | ||||||
|  |   display: block; | ||||||
|  |   width: 4em; | ||||||
|  |   height: 2em; | ||||||
|  |   position: relative; | ||||||
|  |   cursor: pointer; | ||||||
|  |   -webkit-user-select: none; | ||||||
|  |      -moz-user-select: none; | ||||||
|  |       -ms-user-select: none; | ||||||
|  |           user-select: none; | ||||||
|  | } | ||||||
|  | .tgl + .tgl-btn:after, .tgl + .tgl-btn:before { | ||||||
|  |   position: relative; | ||||||
|  |   display: block; | ||||||
|  |   content: ""; | ||||||
|  |   width: 50%; | ||||||
|  |   height: 100%; | ||||||
|  | } | ||||||
|  | .tgl + .tgl-btn:after { | ||||||
|  |   left: 0; | ||||||
|  | } | ||||||
|  | .tgl + .tgl-btn:before { | ||||||
|  |   display: none; | ||||||
|  | } | ||||||
|  | .tgl:checked + .tgl-btn:after { | ||||||
|  |   left: 50%; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .tgl-light + .tgl-btn { | ||||||
|  |   background: #5c5757; | ||||||
|  |   border-radius: 2em; | ||||||
|  |   padding: 2px; | ||||||
|  |   transition: all 0.4s ease; | ||||||
|  | } | ||||||
|  | .tgl-light + .tgl-btn:after { | ||||||
|  |   border-radius: 50%; | ||||||
|  |   background: rgb(255, 255, 255); | ||||||
|  |   transition: all 0.2s ease; | ||||||
|  | } | ||||||
|  | .tgl-light:checked + .tgl-btn { | ||||||
|  |   background: #47ca5a; | ||||||
|  | } | ||||||
|  | select { | ||||||
|  |   -webkit-appearance: button; | ||||||
|  |   -moz-appearance: button; | ||||||
|  |   background-color: #2c2f33; | ||||||
|  |   background-position: center right; | ||||||
|  |   background-repeat: no-repeat; | ||||||
|  |   border: 1px solid #aaa; | ||||||
|  |   border-radius: 2px; | ||||||
|  |   box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1); | ||||||
|  |   color: #fff; | ||||||
|  |   font-size: 1.2em; | ||||||
|  |   margin: 0; | ||||||
|  |   overflow: hidden; | ||||||
|  |   text-overflow: ellipsis; | ||||||
|  |   white-space: nowrap; | ||||||
|  | } | ||||||
							
								
								
									
										88
									
								
								src/settings/settings.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								src/settings/settings.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,88 @@ | ||||||
|  | <!DOCTYPE html> | ||||||
|  | <html lang="en"> | ||||||
|  | 
 | ||||||
|  | <head> | ||||||
|  |   <meta charset="UTF-8" /> | ||||||
|  |   <title>ArmCord Settings</title> | ||||||
|  |   <style> | ||||||
|  |     @import url("settings.css"); | ||||||
|  |   </style> | ||||||
|  | </head> | ||||||
|  | 
 | ||||||
|  | <body> | ||||||
|  | 
 | ||||||
|  | <div class="switch"> | ||||||
|  |     <select name="theme" id="theme" class="left"> | ||||||
|  |       <option value="default">Default</option> | ||||||
|  |       <option value="native">Native</option> | ||||||
|  |       <option value="glasstron">Glasstron (experimental)</option> | ||||||
|  |       <option value="tabs">Tabs (experimental)</option> | ||||||
|  |     </select> | ||||||
|  |     <p class="header">ArmCord theme:</p> | ||||||
|  |   </div> | ||||||
|  |   </br> | ||||||
|  |   <div class="switch"> | ||||||
|  |     <label class="header">ArmCord CSP</label> | ||||||
|  |     <input class="tgl tgl-light left" id="csp" type="checkbox" /> | ||||||
|  |     <label class="tgl-btn left" for="csp"></label> | ||||||
|  |   </div> | ||||||
|  |   </br> | ||||||
|  |   <div class="switch"> | ||||||
|  |     <label class="header">Minimize to tray</label> | ||||||
|  |     <input class="tgl tgl-light left" id="tray" type="checkbox" /> | ||||||
|  |     <label class="tgl-btn left" for="tray"></label> | ||||||
|  |   </div> | ||||||
|  |   </br> | ||||||
|  |   <div class="switch"> | ||||||
|  |     <label class="header">Automatic Patches</label> | ||||||
|  |     <input class="tgl tgl-light left" id="patches" type="checkbox" /> | ||||||
|  |     <label class="tgl-btn left" for="patches"></label> | ||||||
|  |   </div> | ||||||
|  |   <div class="switch"> | ||||||
|  |     <select name="channel" id="channel" class="left"> | ||||||
|  |       <option value="stable">Stable</option> | ||||||
|  |       <option value="canary">Canary</option> | ||||||
|  |       <option value="ptb">PTB</option> | ||||||
|  |       <option value="foss">Fosscord</option> | ||||||
|  |     </select> | ||||||
|  |     <p class="header">Discord channel:</p> | ||||||
|  |   </div> | ||||||
|  |   <div class="switch"> | ||||||
|  |     <select name="mod" id="mod" class="left"> | ||||||
|  |       <option value="cumcord">Cumcord</option> | ||||||
|  |       <option value="goosemod">GooseMod</option> | ||||||
|  |       <option value="flicker">Flicker</option> | ||||||
|  |     </select> | ||||||
|  |     <p class="header">Client mod:</p> | ||||||
|  |   </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> | ||||||
|  |    | ||||||
|  | </body> | ||||||
|  | 
 | ||||||
|  | <script> | ||||||
|  |   async function loadSettings() { | ||||||
|  |     document.getElementById("csp").checked = await settings.get("armcordCSP"); | ||||||
|  |     document.getElementById("tray").checked = await settings.get("minimizeToTray"); | ||||||
|  |     document.getElementById("patches").value = await settings.get("automaticPatches"); | ||||||
|  |     document.getElementById("mod").value = await settings.get("mods"); | ||||||
|  |     document.getElementById("channel").value = await settings.get("channel"); | ||||||
|  |     document.getElementById("theme").value = await settings.get("windowStyle"); | ||||||
|  |     document.getElementById("blurType").value = await settings.get("blurType"); | ||||||
|  |   } | ||||||
|  |   loadSettings() | ||||||
|  |   document.getElementById("save").addEventListener("click", function() { | ||||||
|  |     //function saveSettings(windowStyle: string, channelSetting: string, armcordCSPSetting: boolean, minimizeToTray: boolean, automaticPatches: boolean,modsSetting: string, blurType: string)  | ||||||
|  |     settings.save(document.getElementById("theme").value, document.getElementById("channel").value, document.getElementById("csp").checked, document.getElementById("tray").checked, document.getElementById("patches").checked, document.getElementById("mod").value, document.getElementById("blurType").value); | ||||||
|  |   }); | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | </html> | ||||||
|  | @ -1,6 +1,7 @@ | ||||||
| import { app, Menu, Tray } from 'electron'; | import { app, Menu, Tray } from 'electron'; | ||||||
| import {mainWindow} from './window'; | import {mainWindow} from './window'; | ||||||
| import * as path from 'path' | import * as path from 'path' | ||||||
|  | import { createSettingsWindow } from './settings/main'; | ||||||
| let tray = null | let tray = null | ||||||
| app.whenReady().then(() => { | app.whenReady().then(() => { | ||||||
|   tray = new Tray(path.join(__dirname, "../", "/assets/ac_plug.png")) |   tray = new Tray(path.join(__dirname, "../", "/assets/ac_plug.png")) | ||||||
|  | @ -11,6 +12,12 @@ app.whenReady().then(() => { | ||||||
|         mainWindow.show(); |         mainWindow.show(); | ||||||
|       }, |       }, | ||||||
|     }, |     }, | ||||||
|  |     { | ||||||
|  |       label: "Open Settings", | ||||||
|  |       click: function () { | ||||||
|  |         createSettingsWindow(); | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|     { |     { | ||||||
|       label: "Support Discord Server", |       label: "Support Discord Server", | ||||||
|       click: function () { |       click: function () { | ||||||
|  |  | ||||||
							
								
								
									
										86
									
								
								src/types/glasstron.d.ts
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								src/types/glasstron.d.ts
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,86 @@ | ||||||
|  | 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; | ||||||
|  | } | ||||||
							
								
								
									
										33
									
								
								src/utils.ts
									
										
									
									
									
								
							
							
						
						
									
										33
									
								
								src/utils.ts
									
										
									
									
									
								
							|  | @ -17,15 +17,18 @@ export function addScript(scriptString: string) { | ||||||
|   document.body.append(script); |   document.body.append(script); | ||||||
| } | } | ||||||
| export function setup() { | export function setup() { | ||||||
|   console.log("Setting up ArmCord settings."); |   console.log("Setting up temporary ArmCord settings."); | ||||||
|   storage.set( |   storage.set( | ||||||
|     "settings", |     "settings", | ||||||
|     { |     { | ||||||
|       customTitlebar: true, |       windowStyle: "default", | ||||||
|       channel: "stable", |       channel: "stable", | ||||||
|       doneSetup: true, |       doneSetup: true, | ||||||
|       armcordCSP: true, |       armcordCSP: true, | ||||||
|  |       minimizeToTray: true, | ||||||
|  |       automaticPatches: false, | ||||||
|       mods: "cumcord", |       mods: "cumcord", | ||||||
|  |       blurType: "acrylic", | ||||||
|     }, |     }, | ||||||
|     function (error) { |     function (error) { | ||||||
|       if (error) throw error; |       if (error) throw error; | ||||||
|  | @ -35,21 +38,32 @@ export function setup() { | ||||||
| export async function sleep(ms: number) { | export async function sleep(ms: number) { | ||||||
|   return new Promise((resolve) => setTimeout(resolve, ms)); |   return new Promise((resolve) => setTimeout(resolve, ms)); | ||||||
| } | } | ||||||
|  | export async function checkIfConfigIsNew() { | ||||||
|  |   if (await getConfigUnsafe("automaticPatches") == undefined) { | ||||||
|  |     firstRun = true; | ||||||
|  |   } | ||||||
|  | } | ||||||
| export function saveSettings( | export function saveSettings( | ||||||
|   customTitlebarSetting: boolean, |   windowStyle: string, | ||||||
|   channelSetting: string, |   channelSetting: string, | ||||||
|   armcordCSPSetting: boolean, |   armcordCSPSetting: boolean, | ||||||
|   modsSetting: string |   minimizeToTray: boolean, | ||||||
|  |   automaticPatches: boolean, | ||||||
|  |   modsSetting: string, | ||||||
|  |   blurType: string | ||||||
| ) { | ) { | ||||||
|   console.log("Setting up ArmCord settings."); |   console.log("Setting up ArmCord settings."); | ||||||
|   storage.set( |   storage.set( | ||||||
|     "settings", |     "settings", | ||||||
|     { |     { | ||||||
|       customTitlebar: customTitlebarSetting, |       windowStyle: windowStyle, | ||||||
|       channel: channelSetting, |       channel: channelSetting, | ||||||
|       doneSetup: true, |       doneSetup: true, | ||||||
|       armcordCSP: armcordCSPSetting, |       armcordCSP: armcordCSPSetting, | ||||||
|  |       minimizeToTray: minimizeToTray, | ||||||
|  |       automaticPatches: automaticPatches, | ||||||
|       mods: modsSetting, |       mods: modsSetting, | ||||||
|  |       blurType: blurType | ||||||
|     }, |     }, | ||||||
|     function (error) { |     function (error) { | ||||||
|       if (error) throw error; |       if (error) throw error; | ||||||
|  | @ -74,3 +88,12 @@ 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"; | ||||||
| } | } | ||||||
|  | export async function injectJS(inject: string) { | ||||||
|  |   const js = await (await fetch(`${inject}`)).text(); | ||||||
|  | 
 | ||||||
|  |   const el = document.createElement("script"); | ||||||
|  | 
 | ||||||
|  |   el.appendChild(document.createTextNode(js)); | ||||||
|  | 
 | ||||||
|  |   document.body.appendChild(el); | ||||||
|  | } | ||||||
							
								
								
									
										129
									
								
								src/window.ts
									
										
									
									
									
								
							
							
						
						
									
										129
									
								
								src/window.ts
									
										
									
									
									
								
							|  | @ -2,22 +2,49 @@ | ||||||
| // 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 } from "electron"; | import { BrowserWindow, shell, app, ipcMain } from "electron"; | ||||||
| import path from "path"; | import path from "path"; | ||||||
| import { contentPath } from "./main"; | import { contentPath } from "./main"; | ||||||
| import { firstRun } from "./utils"; | import { checkIfConfigIsNew, firstRun, getConfigUnsafe } from "./utils"; | ||||||
| import { registerIpc } from "./ipc"; | import { registerIpc } from "./ipc"; | ||||||
|  | import contextMenu from "electron-context-menu"; | ||||||
| export let mainWindow: BrowserWindow; | export let mainWindow: BrowserWindow; | ||||||
|  | import * as glasstron from "glasstron"; | ||||||
|  | 
 | ||||||
|  | let guestWindows: BrowserWindow [] = []; | ||||||
|  | contextMenu({ | ||||||
|  |   showSaveImageAs: true, | ||||||
|  |   showCopyImageAddress: true, | ||||||
|  |   showSearchWithGoogle: true, | ||||||
|  | 
 | ||||||
|  | }); | ||||||
| 
 | 
 | ||||||
| function doAfterDefiningTheWindow() { | function doAfterDefiningTheWindow() { | ||||||
|  |   checkIfConfigIsNew(); | ||||||
|   registerIpc(); |   registerIpc(); | ||||||
|   mainWindow.webContents.userAgent = |   mainWindow.webContents.userAgent = | ||||||
|     "Mozilla/5.0 (X11; Linux x86) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 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
 | ||||||
|   mainWindow.webContents.setWindowOpenHandler(({ url }) => { |   mainWindow.webContents.setWindowOpenHandler(({ url }) => { | ||||||
|     shell.openExternal(url); |     shell.openExternal(url); | ||||||
|     return { action: "deny" }; |     return { action: "deny" }; | ||||||
|   }); |   }); | ||||||
| 
 |   mainWindow.webContents.session.webRequest.onBeforeRequest( | ||||||
|  |     (details, callback) => { | ||||||
|  |       if (/api\/v\d\/science$/g.test(details.url)) | ||||||
|  |         return callback({ cancel: true }); | ||||||
|  |       return callback({}); | ||||||
|  |     } | ||||||
|  |   ); | ||||||
|  |   mainWindow.on("close", async (e) => { | ||||||
|  |     if (await getConfigUnsafe("minimizeToTray")) { | ||||||
|  |       e.preventDefault(); | ||||||
|  |       mainWindow.hide(); | ||||||
|  |     } else if (!await getConfigUnsafe("minimizeToTray")) { | ||||||
|  |       e.preventDefault(); | ||||||
|  |       app.exit(); | ||||||
|  |       app.quit() | ||||||
|  |     } | ||||||
|  |   }); | ||||||
|   console.log(contentPath); |   console.log(contentPath); | ||||||
|   try { |   try { | ||||||
|     mainWindow.loadFile(contentPath); |     mainWindow.loadFile(contentPath); | ||||||
|  | @ -52,6 +79,7 @@ export function createCustomWindow() { | ||||||
|     autoHideMenuBar: true, |     autoHideMenuBar: true, | ||||||
|     webPreferences: { |     webPreferences: { | ||||||
|       preload: path.join(__dirname, "preload/preload.js"), |       preload: path.join(__dirname, "preload/preload.js"), | ||||||
|  |       spellcheck: true, | ||||||
|     }, |     }, | ||||||
|   }); |   }); | ||||||
|   doAfterDefiningTheWindow(); |   doAfterDefiningTheWindow(); | ||||||
|  | @ -67,7 +95,100 @@ export function createNativeWindow() { | ||||||
|     autoHideMenuBar: true, |     autoHideMenuBar: true, | ||||||
|     webPreferences: { |     webPreferences: { | ||||||
|       preload: path.join(__dirname, "preload/preload.js"), |       preload: path.join(__dirname, "preload/preload.js"), | ||||||
|  |       spellcheck: true, | ||||||
|     }, |     }, | ||||||
|   }); |   }); | ||||||
|   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() { | ||||||
|  |   guestWindows[1] = mainWindow; | ||||||
|  |   mainWindow = new 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"), | ||||||
|  |     }, | ||||||
|  |   }); | ||||||
|  |   doAfterDefiningTheWindow(); | ||||||
|  | } | ||||||
|  | export function createTabsGuest(number: number) { | ||||||
|  |   console.log(guestWindows) | ||||||
|  |   if (guestWindows[number] !== undefined || null) { | ||||||
|  |   try { | ||||||
|  |       console.log("Showing Guest Window " + number); | ||||||
|  |       mainWindow.hide() | ||||||
|  |       guestWindows[number].show(); | ||||||
|  |       mainWindow = guestWindows[number]; | ||||||
|  |     } catch (e) { | ||||||
|  |       console.error(e); | ||||||
|  |     } | ||||||
|  |   } else { | ||||||
|  |   console.log("Creating Guest Window " + number); | ||||||
|  |   mainWindow.hide(); | ||||||
|  | 
 | ||||||
|  |   guestWindows[number] = new BrowserWindow({ | ||||||
|  |     width: 800, | ||||||
|  |     height: 600, | ||||||
|  |     title: "ArmCord Guest Window " + number, | ||||||
|  |     darkTheme: true, | ||||||
|  |     icon: path.join(__dirname, "/assets/icon_transparent.png"), | ||||||
|  |     frame: true, | ||||||
|  |     autoHideMenuBar: true, | ||||||
|  |     webPreferences: { | ||||||
|  |       preload: path.join(__dirname, "preload/preload.js"), | ||||||
|  |     }, | ||||||
|  |   }); | ||||||
|  |    | ||||||
|  |   mainWindow = guestWindows[number]; | ||||||
|  |   ipcMain.on("tab" + number, (event) => { | ||||||
|  |     event.returnValue = true; //return true so we know the tab exists
 | ||||||
|  |   }); | ||||||
|  |    | ||||||
|  |   guestWindows[number].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
 | ||||||
|  |    | ||||||
|  |   guestWindows[number].webContents.setWindowOpenHandler(({ url }) => { | ||||||
|  |     shell.openExternal(url); | ||||||
|  |     return { action: "deny" }; | ||||||
|  |   }); | ||||||
|  |    | ||||||
|  |   guestWindows[number].webContents.session.webRequest.onBeforeRequest( | ||||||
|  |     ( | ||||||
|  |       details: { url: string }, | ||||||
|  |       callback: (arg0: { cancel?: boolean }) => any | ||||||
|  |     ) => { | ||||||
|  |       if (/api\/v\d\/science$/g.test(details.url)) | ||||||
|  |         return callback({ cancel: true }); | ||||||
|  |       return callback({}); | ||||||
|  |     } | ||||||
|  |   ); | ||||||
|  |    | ||||||
|  |   guestWindows[number].loadURL("https://discord.com/app"); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | @ -26,7 +26,6 @@ | ||||||
|         "declaration": false, // Exports declaration files in addition, used for exporting a module. |         "declaration": false, // Exports declaration files in addition, used for exporting a module. | ||||||
|         "declarationMap": false, // Allows the user to go to the source file when hitting a go-to-implementation key like F12 in VSCode for example. |         "declarationMap": false, // Allows the user to go to the source file when hitting a go-to-implementation key like F12 in VSCode for example. | ||||||
|         //"declarationDir": "typings", // declarationDir allows you to separate the compiled code from the declaration files, used in conjunction with package.json's "types" property. |         //"declarationDir": "typings", // declarationDir allows you to separate the compiled code from the declaration files, used in conjunction with package.json's "types" property. | ||||||
| 
 |  | ||||||
|         // Web Compatibility // |         // Web Compatibility // | ||||||
|         "target": "ES2020", // ES2017 supports async/await, reducing the amount of compiled code, especially for async-heavy projects. ES2020 is from the Node 14 base (https://github.com/tsconfig/bases/blob/master/bases/node14.json) |         "target": "ES2020", // ES2017 supports async/await, reducing the amount of compiled code, especially for async-heavy projects. ES2020 is from the Node 14 base (https://github.com/tsconfig/bases/blob/master/bases/node14.json) | ||||||
|         "downlevelIteration": false, // This flag adds extra support when targeting ES3, but adds extra bloat otherwise. |         "downlevelIteration": false, // This flag adds extra support when targeting ES3, but adds extra bloat otherwise. | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue