mirror of
				https://github.com/smartfrigde/armcord.git
				synced 2024-08-14 23:56:58 +00:00 
			
		
		
		
	Add theme manager
This commit is contained in:
		
							parent
							
								
									9ff515b07b
								
							
						
					
					
						commit
						a07546f28e
					
				
					 12 changed files with 496 additions and 11 deletions
				
			
		|  | @ -29,3 +29,9 @@ | ||||||
| [class|="listItem"]:has(+ [class|="listItem"] [data-list-item-id="guildsnav___app-download-button"]) { | [class|="listItem"]:has(+ [class|="listItem"] [data-list-item-id="guildsnav___app-download-button"]) { | ||||||
|     display: none; |     display: none; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | div#themes:after, | ||||||
|  | div#armcord:after { | ||||||
|  |     content: url("https://raw.githubusercontent.com/ArmCord/BrandingStuff/main/ac_white_plug16x.png"); | ||||||
|  |     margin-right: 5px; | ||||||
|  | } | ||||||
|  |  | ||||||
										
											Binary file not shown.
										
									
								
							|  | @ -36,7 +36,7 @@ | ||||||
| .titlebar #window-controls-container #quit { | .titlebar #window-controls-container #quit { | ||||||
|     float: left; |     float: left; | ||||||
|     height: 100%; |     height: 100%; | ||||||
|     width: 33.1%; |     width: 33.3%; | ||||||
|     text-align: center; |     text-align: center; | ||||||
|     color: var(--interactive-normal); |     color: var(--interactive-normal); | ||||||
|     cursor: default; |     cursor: default; | ||||||
|  |  | ||||||
|  | @ -16,6 +16,7 @@ import {customTitlebar} from "./main"; | ||||||
| import {createSettingsWindow} from "./settings/main"; | import {createSettingsWindow} from "./settings/main"; | ||||||
| import os from "os"; | import os from "os"; | ||||||
| import path from "path"; | import path from "path"; | ||||||
|  | import {createTManagerWindow} from "./themeManager/main"; | ||||||
| export function registerIpc(): void { | export function registerIpc(): void { | ||||||
|     ipcMain.on("get-app-path", (event) => { |     ipcMain.on("get-app-path", (event) => { | ||||||
|         event.reply("app-path", app.getAppPath()); |         event.reply("app-path", app.getAppPath()); | ||||||
|  | @ -142,6 +143,9 @@ export function registerIpc(): void { | ||||||
|     ipcMain.on("openSettingsWindow", () => { |     ipcMain.on("openSettingsWindow", () => { | ||||||
|         createSettingsWindow(); |         createSettingsWindow(); | ||||||
|     }); |     }); | ||||||
|  |     ipcMain.on("openManagerWindow", () => { | ||||||
|  |         createTManagerWindow(); | ||||||
|  |     }); | ||||||
|     ipcMain.on("setting-armcordCSP", async (event) => { |     ipcMain.on("setting-armcordCSP", async (event) => { | ||||||
|         if (await getConfig("armcordCSP")) { |         if (await getConfig("armcordCSP")) { | ||||||
|             event.returnValue = true; |             event.returnValue = true; | ||||||
|  |  | ||||||
|  | @ -59,6 +59,13 @@ export async function setMenu(): Promise<void> { | ||||||
|                         createSettingsWindow(); |                         createSettingsWindow(); | ||||||
|                     } |                     } | ||||||
|                 }, |                 }, | ||||||
|  |                 { | ||||||
|  |                     label: "Fullscreen", | ||||||
|  |                     accelerator: "F11", | ||||||
|  |                     click() { | ||||||
|  |                         mainWindow.fullScreen = !mainWindow.fullScreen; | ||||||
|  |                     } | ||||||
|  |                 }, | ||||||
|                 { |                 { | ||||||
|                     label: "Reload", |                     label: "Reload", | ||||||
|                     accelerator: "CmdOrCtrl+R", |                     accelerator: "CmdOrCtrl+R", | ||||||
|  |  | ||||||
							
								
								
									
										9
									
								
								src/preload/optimizer.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/preload/optimizer.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,9 @@ | ||||||
|  | const optimize = (orig: Function) => | ||||||
|  |     function (this: any, ...args: any[]) { | ||||||
|  |         if (typeof args[0]?.className === "string" && args[0].className.indexOf("activity") !== -1) | ||||||
|  |             return setTimeout(() => orig.apply(this, args), 100); | ||||||
|  | 
 | ||||||
|  |         return orig.apply(this, args); | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  | Element.prototype.removeChild = optimize(Element.prototype.removeChild); | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| import "./bridge"; | import "./bridge"; | ||||||
| import "./patch"; | import "./patch"; | ||||||
|  | import "./optimizer"; | ||||||
| 
 | 
 | ||||||
| import {ipcRenderer} from "electron"; | import {ipcRenderer} from "electron"; | ||||||
| import * as fs from "fs"; | import * as fs from "fs"; | ||||||
|  | @ -78,12 +79,33 @@ if (window.location.href.indexOf("splash.html") > -1) { | ||||||
| 
 | 
 | ||||||
| // Settings info version injection
 | // Settings info version injection
 | ||||||
| setInterval(() => { | setInterval(() => { | ||||||
|     const host = document.querySelector("nav > [class|=side] [class|=info]"); |     const host = document.querySelector<HTMLDivElement>("nav > [class|=side] [class|=info]"); | ||||||
|     if (!host || host.querySelector("#ac-ver")) return; |     if (!host || host.querySelector("#ac-ver")) { | ||||||
|     const el = host.firstChild!.cloneNode() as HTMLSpanElement; |         return; | ||||||
|     el.id = "ac-ver"; |     } | ||||||
| 
 | 
 | ||||||
|  |     const el = host.firstElementChild!.cloneNode() as HTMLSpanElement; | ||||||
|  |     el.id = "ac-ver"; | ||||||
|     el.textContent = `ArmCord Version: ${version}`; |     el.textContent = `ArmCord Version: ${version}`; | ||||||
|     el.onclick = () => ipcRenderer.send("openSettingsWindow"); |     el.onclick = () => ipcRenderer.send("openSettingsWindow"); | ||||||
|     host.append(el); |     host.append(el); | ||||||
| }, 2000); |     let advanced = document | ||||||
|  |         .querySelector('[class*="socialLinks-"]')! | ||||||
|  |         .parentElement!.querySelector( | ||||||
|  |             '[class*="header"] + [class*="item"] + [class*="item"] + [class*="item"] + [class*="item"] + [class*="item"] + [class*="item"] + [class*="item"] + [class*="item"] + [class*="item"]' | ||||||
|  |         ); | ||||||
|  |     if (!advanced) return; | ||||||
|  |     if (advanced.nextSibling instanceof Element && advanced.nextSibling.className.includes("item")) { | ||||||
|  |         advanced = advanced.nextSibling; | ||||||
|  |     } | ||||||
|  |     const acSettings = advanced.cloneNode(true) as HTMLElement; | ||||||
|  |     const tManager = advanced.cloneNode(true) as HTMLElement; | ||||||
|  |     acSettings.textContent = "ArmCord"; | ||||||
|  |     acSettings.id = "armcord"; | ||||||
|  |     acSettings.onclick = () => ipcRenderer.send("openSettingsWindow"); | ||||||
|  |     tManager.textContent = "Themes"; | ||||||
|  |     tManager.id = "themes"; | ||||||
|  |     tManager.onclick = () => ipcRenderer.send("openManagerWindow"); | ||||||
|  |     advanced.insertAdjacentElement("afterend", acSettings); | ||||||
|  |     advanced.insertAdjacentElement("afterend", tManager); | ||||||
|  | }, 1000); | ||||||
|  |  | ||||||
|  | @ -50,6 +50,9 @@ export function createSettingsWindow(): void { | ||||||
|             fs.mkdirSync(themesFolder); |             fs.mkdirSync(themesFolder); | ||||||
|             console.log("Created missing theme folder"); |             console.log("Created missing theme folder"); | ||||||
|         } |         } | ||||||
|  |         if (!fs.existsSync(`${userDataPath}/disabled.txt`)) { | ||||||
|  |             fs.writeFileSync(path.join(userDataPath, "/disabled.txt"), ""); | ||||||
|  |         } | ||||||
|         settingsWindow.webContents.on("did-finish-load", () => { |         settingsWindow.webContents.on("did-finish-load", () => { | ||||||
|             fs.readdirSync(themesFolder).forEach((file) => { |             fs.readdirSync(themesFolder).forEach((file) => { | ||||||
|                 try { |                 try { | ||||||
|  |  | ||||||
							
								
								
									
										181
									
								
								src/themeManager/main.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										181
									
								
								src/themeManager/main.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,181 @@ | ||||||
|  | import {BrowserWindow, app, ipcMain, shell, dialog} from "electron"; | ||||||
|  | import {sleep} from "../utils"; | ||||||
|  | import path from "path"; | ||||||
|  | import fs from "fs"; | ||||||
|  | import {mainWindow} from "../window"; | ||||||
|  | let themeWindow: BrowserWindow; | ||||||
|  | let instance = 0; | ||||||
|  | interface ThemeManifest { | ||||||
|  |     name?: string; | ||||||
|  |     author?: string; | ||||||
|  |     description?: string; | ||||||
|  |     version?: string; | ||||||
|  |     invite?: string; | ||||||
|  |     authorId?: string; | ||||||
|  |     theme: string; | ||||||
|  |     authorLink?: string; | ||||||
|  |     donate?: string; | ||||||
|  |     patreon?: string; | ||||||
|  |     website?: string; | ||||||
|  |     source?: string; | ||||||
|  | } | ||||||
|  | function parseBDManifest(content: string) { | ||||||
|  |     const metaReg = /@([^ ]*) (.*)/g; | ||||||
|  |     if (!content.startsWith("/**")) { | ||||||
|  |         throw new Error("Not a manifest."); | ||||||
|  |     } | ||||||
|  |     let manifest: ThemeManifest = {theme: "src.css"}; | ||||||
|  | 
 | ||||||
|  |     let match; | ||||||
|  |     while ((match = metaReg.exec(content)) !== null) { | ||||||
|  |         let [_, key, value] = match; | ||||||
|  |         if (key === "import") break; | ||||||
|  | 
 | ||||||
|  |         value = value.trim(); | ||||||
|  | 
 | ||||||
|  |         //console.log(key, value);
 | ||||||
|  | 
 | ||||||
|  |         switch (key) { | ||||||
|  |             case "name": | ||||||
|  |                 manifest.name = value; | ||||||
|  |                 break; | ||||||
|  | 
 | ||||||
|  |             case "description": | ||||||
|  |                 manifest.description = value; | ||||||
|  |                 break; | ||||||
|  | 
 | ||||||
|  |             case "version": | ||||||
|  |                 manifest.version = value; | ||||||
|  |                 break; | ||||||
|  | 
 | ||||||
|  |             case "author": | ||||||
|  |                 manifest.author = value; | ||||||
|  |                 break; | ||||||
|  | 
 | ||||||
|  |             case "invite": | ||||||
|  |                 manifest.invite = value; | ||||||
|  |                 break; | ||||||
|  | 
 | ||||||
|  |             case "authorId": | ||||||
|  |                 manifest.authorId = value; | ||||||
|  |                 break; | ||||||
|  | 
 | ||||||
|  |             case "authorLink": | ||||||
|  |                 manifest.authorLink = value; | ||||||
|  |                 break; | ||||||
|  | 
 | ||||||
|  |             case "donate": | ||||||
|  |                 manifest.donate = value; | ||||||
|  |                 break; | ||||||
|  | 
 | ||||||
|  |             case "patreon": | ||||||
|  |                 manifest.patreon = value; | ||||||
|  |                 break; | ||||||
|  | 
 | ||||||
|  |             case "website": | ||||||
|  |                 manifest.website = value; | ||||||
|  |                 break; | ||||||
|  | 
 | ||||||
|  |             case "source": | ||||||
|  |                 manifest.source = value; | ||||||
|  |                 break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return manifest; | ||||||
|  | } | ||||||
|  | const userDataPath = app.getPath("userData"); | ||||||
|  | const themesPath = path.join(userDataPath, "/themes/"); | ||||||
|  | export function createTManagerWindow(): void { | ||||||
|  |     console.log("Creating theme manager window."); | ||||||
|  |     instance += 1; | ||||||
|  |     if (instance > 1) { | ||||||
|  |         if (themeWindow) { | ||||||
|  |             themeWindow.show(); | ||||||
|  |             themeWindow.restore(); | ||||||
|  |         } | ||||||
|  |     } else { | ||||||
|  |         themeWindow = new BrowserWindow({ | ||||||
|  |             width: 700, | ||||||
|  |             height: 600, | ||||||
|  |             title: `ArmCord Theme Manager`, | ||||||
|  |             darkTheme: true, | ||||||
|  |             frame: true, | ||||||
|  |             backgroundColor: "#2f3136", | ||||||
|  |             autoHideMenuBar: true, | ||||||
|  |             webPreferences: { | ||||||
|  |                 sandbox: false, | ||||||
|  |                 preload: path.join(__dirname, "preload.js") | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |         async function managerLoadPage(): Promise<void> { | ||||||
|  |             themeWindow.loadFile(`${__dirname}/manager.html`); | ||||||
|  |         } | ||||||
|  |         const userDataPath = app.getPath("userData"); | ||||||
|  |         const themesFolder = `${userDataPath}/themes/`; | ||||||
|  |         if (!fs.existsSync(themesFolder)) { | ||||||
|  |             fs.mkdirSync(themesFolder); | ||||||
|  |             console.log("Created missing theme folder"); | ||||||
|  |         } | ||||||
|  |         if (!fs.existsSync(`${userDataPath}/disabled.txt`)) { | ||||||
|  |             fs.writeFileSync(path.join(userDataPath, "/disabled.txt"), ""); | ||||||
|  |         } | ||||||
|  |         ipcMain.on("openThemesFolder", async () => { | ||||||
|  |             shell.showItemInFolder(themesPath); | ||||||
|  |             await sleep(1000); | ||||||
|  |         }); | ||||||
|  |         ipcMain.on("reloadMain", async () => { | ||||||
|  |             mainWindow.webContents.reload(); | ||||||
|  |         }); | ||||||
|  |         ipcMain.on("addToDisabled", async (_event, name: string) => { | ||||||
|  |             fs.appendFileSync(path.join(userDataPath, "/disabled.txt"), name + "\n"); | ||||||
|  |         }); | ||||||
|  |         ipcMain.on("disabled", async (e) => { | ||||||
|  |             e.returnValue = fs.readFileSync(path.join(userDataPath, "/disabled.txt")).toString(); | ||||||
|  |         }); | ||||||
|  |         ipcMain.on("removeFromDisabled", async (_event, name: string) => { | ||||||
|  |             var e = await fs.readFileSync(path.join(userDataPath, "/disabled.txt")).toString(); | ||||||
|  |             fs.writeFileSync(path.join(userDataPath, "/disabled.txt"), e.replace(name + "\n", "")); | ||||||
|  |         }); | ||||||
|  |         ipcMain.on("installBDTheme", async (_event, link: string) => { | ||||||
|  |             try { | ||||||
|  |                 var code = await (await fetch(link)).text(); | ||||||
|  |                 var manifest = parseBDManifest(code); | ||||||
|  |                 var themePath = path.join(themesFolder, manifest.name?.replace(" ", "-") + "-BD"); | ||||||
|  |                 if (!fs.existsSync(themePath)) { | ||||||
|  |                     fs.mkdirSync(themePath); | ||||||
|  |                     console.log(`Created ${manifest.name} folder`); | ||||||
|  |                 } | ||||||
|  |                 fs.writeFileSync(path.join(themePath, "manifest.json"), JSON.stringify(manifest)); | ||||||
|  |                 fs.writeFileSync(path.join(themePath, "src.css"), code); | ||||||
|  |                 dialog.showMessageBoxSync({ | ||||||
|  |                     type: "info", | ||||||
|  |                     title: "BD Theme import success", | ||||||
|  |                     message: "Successfully imported theme from link." | ||||||
|  |                 }); | ||||||
|  |                 themeWindow.webContents.reload(); | ||||||
|  |                 mainWindow.webContents.reload(); | ||||||
|  |             } catch (e) { | ||||||
|  |                 dialog.showErrorBox( | ||||||
|  |                     "BD Theme import fail", | ||||||
|  |                     "Failed to import theme from link. Please make sure that it's a valid BetterDiscord Theme." | ||||||
|  |                 ); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |         themeWindow.webContents.on("did-finish-load", () => { | ||||||
|  |             fs.readdirSync(themesFolder).forEach((file) => { | ||||||
|  |                 try { | ||||||
|  |                     const manifest = fs.readFileSync(`${themesFolder}/${file}/manifest.json`, "utf8"); | ||||||
|  |                     console.log(manifest); | ||||||
|  |                     themeWindow.webContents.send("themeManifest", manifest); | ||||||
|  |                 } catch (err) { | ||||||
|  |                     console.error(err); | ||||||
|  |                 } | ||||||
|  |             }); | ||||||
|  |         }); | ||||||
|  |         managerLoadPage(); | ||||||
|  |         themeWindow.on("close", () => { | ||||||
|  |             instance = 0; | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										198
									
								
								src/themeManager/manager.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										198
									
								
								src/themeManager/manager.html
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,198 @@ | ||||||
|  | <!DOCTYPE html> | ||||||
|  | <html> | ||||||
|  |     <head> | ||||||
|  |         <style> | ||||||
|  |             :root { | ||||||
|  |                 --background-secondary: #2f3136; | ||||||
|  |                 --background-secondary-alt: #292b2f; | ||||||
|  |                 --background-floating: #18191c; | ||||||
|  |                 --background-modifier-hover: rgba(106, 116, 128, 0.16); | ||||||
|  |                 --brand-experiment: #7289da; | ||||||
|  |                 --brand-experiment-560: #5c6fb1; | ||||||
|  |                 --brand-experiment-600: #4e5d94; | ||||||
|  |                 --interactive-normal: #b9bbbe; | ||||||
|  |                 --interactive-hover: #dcddde; | ||||||
|  |                 --text-muted: #72767d; | ||||||
|  |                 --font-primary: "Whitney"; | ||||||
|  |                 --header-primary: #fff; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             html { | ||||||
|  |                 font-size: 22px; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             body { | ||||||
|  |                 padding: 1rem; | ||||||
|  | 
 | ||||||
|  |                 background: var(--background-secondary); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             @font-face { | ||||||
|  |                 font-family: Whitney; | ||||||
|  |                 font-weight: 200; | ||||||
|  |                 font-style: normal; | ||||||
|  |                 src: url(https://armcord.xyz/whitney_400.woff) format("woff"); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             * { | ||||||
|  |                 font-family: "Whitney", sans-serif; | ||||||
|  |                 box-sizing: border-box; | ||||||
|  |                 margin: 0; | ||||||
|  |                 padding: 0; | ||||||
|  |                 cursor: default; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             .card { | ||||||
|  |                 background-color: var(--background-floating); | ||||||
|  |                 color: white; | ||||||
|  |                 padding: 1rem; | ||||||
|  |                 border-color: var(--background-floating); | ||||||
|  |                 border-style: solid; | ||||||
|  |                 border-radius: 10px; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             .cards { | ||||||
|  |                 max-width: 1200px; | ||||||
|  |                 margin: 0 auto; | ||||||
|  |                 display: grid; | ||||||
|  |                 grid-gap: 1rem; | ||||||
|  |                 justify-content: space-evenly; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /* Screen larger than 600px? 2 column */ | ||||||
|  |             @media (min-width: 600px) { | ||||||
|  |                 .cards { | ||||||
|  |                     grid-template-columns: repeat(2, 1fr); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /* Screen larger than 900px? 3 columns */ | ||||||
|  |             @media (min-width: 900px) { | ||||||
|  |                 .cards { | ||||||
|  |                     grid-template-columns: repeat(3, 1fr); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             .flex-box { | ||||||
|  |                 display: flex; | ||||||
|  |                 justify-content: space-between; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             /* switches */ | ||||||
|  |             .tgl { | ||||||
|  |                 display: none; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             .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: 3em; | ||||||
|  |                 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: 1px; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             .tgl + .tgl-btn:before { | ||||||
|  |                 display: none; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             .tgl:checked + .tgl-btn:after { | ||||||
|  |                 left: 56%; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             .tgl-light + .tgl-btn { | ||||||
|  |                 background: var(--text-muted); | ||||||
|  |                 border-radius: 25px; | ||||||
|  |                 padding: 4px; | ||||||
|  |                 transition: all 0.4s ease; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             .tgl-light + .tgl-btn:after { | ||||||
|  |                 border-radius: 50px; | ||||||
|  |                 position: relative; | ||||||
|  |                 top: 50%; | ||||||
|  |                 transform: translateY(-50%); | ||||||
|  |                 width: 24px; | ||||||
|  |                 height: 24px; | ||||||
|  |                 background: rgb(255, 255, 255); | ||||||
|  |                 transition: all 0.2s ease; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             .tgl-light:checked + .tgl-btn { | ||||||
|  |                 background: var(--brand-experiment); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             input[type="text"], | ||||||
|  |             select { | ||||||
|  |                 width: 100%; | ||||||
|  |                 padding: 12px 20px; | ||||||
|  |                 margin: 8px 0; | ||||||
|  |                 display: inline-block; | ||||||
|  |                 border: 1px solid #72767d; | ||||||
|  |                 background-color: #46484d; | ||||||
|  |                 color: white; | ||||||
|  |                 border-radius: 4px; | ||||||
|  |                 box-sizing: border-box; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             #download { | ||||||
|  |                 margin-top: 3px; | ||||||
|  |                 height: 50px; | ||||||
|  |                 vertical-align: middle; | ||||||
|  |                 text-align: right; | ||||||
|  |                 z-index: 99; | ||||||
|  |             } | ||||||
|  |         </style> | ||||||
|  |     </head> | ||||||
|  | 
 | ||||||
|  |     <body> | ||||||
|  |         <div class="flex-box"> | ||||||
|  |             <input | ||||||
|  |                 type="text" | ||||||
|  |                 id="themeLink" | ||||||
|  |                 name="themeLink" | ||||||
|  |                 title="BetterDiscord theme format" | ||||||
|  |                 placeholder="https://raw.githubusercontent.com/... [.css]" | ||||||
|  |             /> | ||||||
|  |             <img id="download" src="https://raw.githubusercontent.com/ArmCord/BrandingStuff/main/Download.png" /> | ||||||
|  |         </div> | ||||||
|  |         <br /> | ||||||
|  |         <div class="cards" id="cardBox"></div> | ||||||
|  |     </body> | ||||||
|  | </html> | ||||||
							
								
								
									
										43
									
								
								src/themeManager/preload.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/themeManager/preload.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,43 @@ | ||||||
|  | import {ipcRenderer} from "electron"; | ||||||
|  | import {sleep} from "../utils"; | ||||||
|  | ipcRenderer.on("themeManifest", (_event, json) => { | ||||||
|  |     var manifest = JSON.parse(json); | ||||||
|  |     console.log(manifest); | ||||||
|  |     sleep(1000); | ||||||
|  |     var e = document.getElementById("cardBox"); | ||||||
|  | 
 | ||||||
|  |     e?.insertAdjacentHTML( | ||||||
|  |         "beforeend", | ||||||
|  |         ` | ||||||
|  |         <div class="card"> | ||||||
|  |             <div class="flex-box"> | ||||||
|  |                 <h3>${manifest.name}</h3> | ||||||
|  |                 <input id="${manifest.name.replace(" ", "-")}" class="tgl tgl-light left" type="checkbox" /> | ||||||
|  |                 <label class="tgl-btn left" for="${manifest.name.replace(" ", "-")}"></label> | ||||||
|  |             </div> | ||||||
|  |             <p>${manifest.description}</p> | ||||||
|  | 
 | ||||||
|  |         </div> | ||||||
|  |         ` | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     if (!ipcRenderer.sendSync("disabled").includes(manifest.name.replace(" ", "-"))) { | ||||||
|  |         (<HTMLInputElement>document.getElementById(manifest.name.replace(" ", "-"))).checked = true; | ||||||
|  |     } | ||||||
|  |     (<HTMLInputElement>document.getElementById(manifest.name.replace(" ", "-")))!.addEventListener( | ||||||
|  |         "input", | ||||||
|  |         function (evt) { | ||||||
|  |             ipcRenderer.send("reloadMain"); | ||||||
|  |             if (this.checked) { | ||||||
|  |                 ipcRenderer.send("removeFromDisabled", manifest.name.replace(" ", "-")); | ||||||
|  |             } else { | ||||||
|  |                 ipcRenderer.send("addToDisabled", manifest.name.replace(" ", "-")); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     ); | ||||||
|  | }); | ||||||
|  | document.addEventListener("DOMContentLoaded", () => { | ||||||
|  |     document.getElementById("download")!.addEventListener("click", () => { | ||||||
|  |         ipcRenderer.send("installBDTheme", (<HTMLInputElement>document.getElementById("themeLink"))!.value); | ||||||
|  |     }); | ||||||
|  | }); | ||||||
|  | @ -179,16 +179,28 @@ async function doAfterDefiningTheWindow(): Promise<void> { | ||||||
|         fs.mkdirSync(themesFolder); |         fs.mkdirSync(themesFolder); | ||||||
|         console.log("Created missing theme folder"); |         console.log("Created missing theme folder"); | ||||||
|     } |     } | ||||||
|  |     if (!fs.existsSync(`${userDataPath}/disabled.txt`)) { | ||||||
|  |         fs.writeFileSync(path.join(userDataPath, "/disabled.txt"), ""); | ||||||
|  |     } | ||||||
|     mainWindow.webContents.on("did-finish-load", () => { |     mainWindow.webContents.on("did-finish-load", () => { | ||||||
|         fs.readdirSync(themesFolder).forEach((file) => { |         fs.readdirSync(themesFolder).forEach((file) => { | ||||||
|             try { |             try { | ||||||
|                 const manifest = fs.readFileSync(`${themesFolder}/${file}/manifest.json`, "utf8"); |                 const manifest = fs.readFileSync(`${themesFolder}/${file}/manifest.json`, "utf8"); | ||||||
|                 let themeFile = JSON.parse(manifest); |                 let themeFile = JSON.parse(manifest); | ||||||
|  |                 if ( | ||||||
|  |                     fs | ||||||
|  |                         .readFileSync(path.join(userDataPath, "/disabled.txt")) | ||||||
|  |                         .toString() | ||||||
|  |                         .includes(themeFile.name.replace(" ", "-")) | ||||||
|  |                 ) { | ||||||
|  |                     console.log(`%cSkipped ${themeFile.name} made by ${themeFile.author}`, "color:red"); | ||||||
|  |                 } else { | ||||||
|                     mainWindow.webContents.send( |                     mainWindow.webContents.send( | ||||||
|                         "themeLoader", |                         "themeLoader", | ||||||
|                         fs.readFileSync(`${themesFolder}/${file}/${themeFile.theme}`, "utf-8") |                         fs.readFileSync(`${themesFolder}/${file}/${themeFile.theme}`, "utf-8") | ||||||
|                     ); |                     ); | ||||||
|                     console.log(`%cLoaded ${themeFile.name} made by ${themeFile.author}`, "color:red"); |                     console.log(`%cLoaded ${themeFile.name} made by ${themeFile.author}`, "color:red"); | ||||||
|  |                 } | ||||||
|             } catch (err) { |             } catch (err) { | ||||||
|                 console.error(err); |                 console.error(err); | ||||||
|             } |             } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue