This commit is contained in:
Mopsgamer 2024-04-16 11:40:43 +00:00 committed by GitHub
commit c43de38b5d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 315 additions and 95 deletions

View File

@ -1,6 +1,5 @@
import require from "./polyfill"; // eslint-disable-line no-unused-vars
import secure from "./secure";
import LoadingIcon from "./loadingicon";
import BetterDiscord from "@modules/core";
import BdApi from "@modules/api/index";
@ -13,6 +12,4 @@ Object.defineProperty(window, "BdApi", {
});
window.global = window;
// Add loading icon at the bottom right
LoadingIcon.show();
BetterDiscord.startup();

128
renderer/src/loading.js Normal file
View File

@ -0,0 +1,128 @@
import {version} from "@modules/api/legacy";
import DOMManager from "@modules/dommanager";
import LoadingStyles from "@styles/loading.css";
/** Don't forget to call {@link show} method. */
class ElementManager {
/** @type {HTMLDivElement} */
#elementContainer;
/** @type {HTMLDivElement} */
#element;
/**
* @param {HTMLDivElement} element
* @param {HTMLDivElement} container
*/
constructor(element, container) {
this.#element = element;
this.#elementContainer = container;
}
show() {
this.#elementContainer.appendChild(this.#element);
}
hide() {
this.#element.remove();
}
}
/** Don't forget to call {@link show} method. */
class ElementValueManager extends ElementManager {
/** @type {(value: unknown, element: HTMLDivElement) => void} */
#changer;
/**
* @param {HTMLDivElement} element
* @param {HTMLDivElement} container
* @param {(value: unknown, element: HTMLDivElement) => void} changer
*/
constructor(element, container, changer) {
super(element, container);
this.#changer = changer;
}
set(value) {
this.#changer(value);
}
}
/** Element manager with all loading info elemets. Now we have note and status block with progress bar and status label. Don't forget to call {@link show} and {@link hide} methods. */
class LoadingManager {
/** @type {HTMLElement} */
#elementContainer;
/** @type {HTMLDivElement} */
#element;
note;
status;
constructor() {
const layout = DOMManager.createElement("div", {className: "bd-loaderv3"});
const container = DOMManager.createElement("div", {className: "bd-loading-container", target: layout});
const leftside = DOMManager.createElement("div", {className: "bd-loading-left-side", target: container});
DOMManager.createElement("div", {className: "bd-loading-icon", target: leftside});
DOMManager.createElement("div", {className: "bd-loading-icon-note", target: leftside}, "v" + version);
const rightside = DOMManager.createElement("div", {className: "bd-loading-right-side", target: container});
this.#elementContainer = document.body;
this.#element = layout;
this.status = new LoadingStatusManager(rightside);
}
async show() {
this.#element.style.pointerEvents = "none";
DOMManager.injectStyle("bd-loading", LoadingStyles.toString());
this.#elementContainer.appendChild(this.#element);
await this.#element.animate([{opacity: 0}, {opacity: 1}], {duration: 500}).finished;
this.#element.style.pointerEvents = "";
}
async hide() {
this.#element.style.pointerEvents = "none";
await this.#element.animate([{opacity: 1}, {opacity: 0}], {duration: 500}).finished;
this.#element.remove();
DOMManager.removeStyle("bd-loading");
}
}
/** Status element manager with progress elements, e.g.: progress bar and status label. Don't forget to call {@link show} method. */
class LoadingStatusManager extends ElementManager {
/** @type {HTMLDivElement} */
#elementContainer;
/** @type {HTMLDivElement} */
#element;
/** @type {HTMLDivElement} */
#elementProgress;
/** @type {HTMLDivElement} */
#elementProgressBar;
/** @type {HTMLDivElement} */
#elementStatus;
label;
progress;
/** @param {HTMLDivElement} container */
constructor(container) {
const element = DOMManager.createElement("div", {className: "bd-loading-item"});
super(element, container);
this.#elementContainer = container;
this.#element = element;
this.#elementProgress = DOMManager.createElement("div", {className: "bd-loading-progress", target: this.#element});
this.#elementProgressBar = DOMManager.createElement("div", {className: "bd-loading-progress-bar", target: this.#elementProgress});
this.#elementStatus = DOMManager.createElement("div", {className: "bd-loading-status", target: this.#element});
this.label = new ElementValueManager(this.#elementStatus, this.#elementContainer, (value) => this.#elementStatus.innerText = value);
this.progress = new ElementValueManager(this.#elementProgress, this.#elementContainer, (value) => this.#elementProgressBar.style.width = Math.min(Math.max(0, value), 100) + "%");
}
}
const Loading = new LoadingManager();
export default Loading;

View File

@ -1,45 +0,0 @@
const css = `/* BEGIN V2 LOADER */
/* =============== */
#bd-loading-icon {
background-image: url(data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgMjAwMCAyMDAwIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAyMDAwIDIwMDAiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxnPjxwYXRoIGZpbGw9IiMzRTgyRTUiIGQ9Ik0xNDAyLjIsNjMxLjdjLTkuNy0zNTMuNC0yODYuMi00OTYtNjQyLjYtNDk2SDY4LjR2NzE0LjFsNDQyLDM5OFY0OTAuN2gyNTdjMjc0LjUsMCwyNzQuNSwzNDQuOSwwLDM0NC45SDU5Ny42djMyOS41aDE2OS44YzI3NC41LDAsMjc0LjUsMzQ0LjgsMCwzNDQuOGgtNjk5djM1NC45aDY5MS4yYzM1Ni4zLDAsNjMyLjgtMTQyLjYsNjQyLjYtNDk2YzAtMTYyLjYtNDQuNS0yODQuMS0xMjIuOS0zNjguNkMxMzU3LjcsOTE1LjgsMTQwMi4yLDc5NC4zLDE0MDIuMiw2MzEuN3oiLz48cGF0aCBmaWxsPSIjRkZGRkZGIiBkPSJNMTI2Mi41LDEzNS4yTDEyNjIuNSwxMzUuMmwtNzYuOCwwYzI2LjYsMTMuMyw1MS43LDI4LjEsNzUsNDQuM2M3MC43LDQ5LjEsMTI2LjEsMTExLjUsMTY0LjYsMTg1LjNjMzkuOSw3Ni42LDYxLjUsMTY1LjYsNjQuMywyNjQuNmwwLDEuMnYxLjJjMCwxNDEuMSwwLDU5Ni4xLDAsNzM3LjF2MS4ybDAsMS4yYy0yLjcsOTktMjQuMywxODgtNjQuMywyNjQuNmMtMzguNSw3My44LTkzLjgsMTM2LjItMTY0LjYsMTg1LjNjLTIyLjYsMTUuNy00Ni45LDMwLjEtNzIuNiw0My4xaDcyLjVjMzQ2LjIsMS45LDY3MS0xNzEuMiw2NzEtNTY3LjlWNzE2LjdDMTkzMy41LDMxMi4yLDE2MDguNywxMzUuMiwxMjYyLjUsMTM1LjJ6Ii8+PC9nPjwvc3ZnPg==);
}
#bd-loading-icon {
position: fixed;
bottom:5px;
right:5px;
z-index: 2147483647;
display: block;
width: 20px;
height: 20px;
background-size: 100% 100%;
animation: bd-loading-animation 1.5s ease-in-out infinite;
}
@keyframes bd-loading-animation {
0% { opacity: 0.05; }
50% { opacity: 0.6; }
100% { opacity: 0.05; }
}
/* =============== */
/* END V2 LOADER */`;
const iconStyle = document.createElement("style");
iconStyle.textContent = css;
const loadingIcon = document.createElement("div");
loadingIcon.id = "bd-loading-icon";
loadingIcon.className = "bd-loaderv2";
loadingIcon.title = "BetterDiscord is loading...";
export default class {
static show() {
document.body.appendChild(iconStyle);
document.body.appendChild(loadingIcon);
}
static hide() {
if (iconStyle) iconStyle.remove();
if (loadingIcon) loadingIcon.remove();
}
}

View File

@ -90,7 +90,7 @@ export default class AddonManager {
Logger.warn(this.name, `Duplicate files found: ${filename} and ${newFilename}`);
return;
}
// Rename the file and let it go on
try {
fs.renameSync(absolutePath, path.resolve(this.addonFolder, newFilename));
@ -215,7 +215,7 @@ export default class AddonManager {
}
return e;
}
const error = this.initializeAddon(addon);
if (error) {
@ -227,7 +227,7 @@ export default class AddonManager {
if (shouldToast) Toasts.success(Strings.Addons.wasLoaded.format({name: addon.name, version: addon.version}));
this.emit("loaded", addon);
if (!this.state[addon.id]) return this.state[addon.id] = false;
return this.startAddon(addon);
}
@ -329,7 +329,7 @@ export default class AddonManager {
for (const name of results.removed) this.unloadAddon(name);
}
loadAllAddons() {
async loadAllAddons() {
this.loadState();
const errors = [];
const files = fs.readdirSync(this.addonFolder);
@ -353,7 +353,7 @@ export default class AddonManager {
Logger.warn("AddonManager", `Duplicate files found: ${filename} and ${newFilename}`);
continue;
}
// Rename the file and let it go on
fs.renameSync(absolutePath, path.resolve(this.addonFolder, newFilename));
}

View File

@ -5,8 +5,6 @@ import Changelog from "@data/changelog";
import * as Builtins from "@builtins/builtins";
import LoadingIcon from "../loadingicon";
import LocaleManager from "./localemanager";
import DOMManager from "./dommanager";
import PluginManager from "./pluginmanager";
@ -16,6 +14,7 @@ import DataStore from "./datastore";
import DiscordModules from "./discordmodules";
import IPC from "./ipc";
import Loading from "../loading";
import Editor from "./editor";
import Updater from "./updater";
@ -34,52 +33,86 @@ export default new class Core {
Config.userData = process.env.DISCORD_USER_DATA;
Config.dataPath = process.env.BETTERDISCORD_DATA_PATH;
Loading.show();
Loading.status.show();
IPC.getSystemAccentColor().then(value => DOMManager.injectStyle("bd-os-values", `:root {--os-accent-color: #${value};}`));
// Load css early
Logger.log("Startup", "Injecting BD Styles");
DOMManager.injectStyle("bd-stylesheet", Styles.toString());
let pluginErrors, themeErrors;
Logger.log("Startup", "Initializing DataStore");
DataStore.initialize();
const clusters = [
async () => {
Logger.log("Startup", "Injecting BD Styles");
Loading.status.label.set("Initialization...");
DOMManager.injectStyle("bd-stylesheet", Styles.toString());
},
async () => {
Logger.log("Startup", "Initializing DataStore");
DataStore.initialize();
},
async () => {
Logger.log("Startup", "Initializing LocaleManager");
LocaleManager.initialize();
},
async () => {
Logger.log("Startup", "Initializing Settings");
Settings.initialize();
},
async () => {
Logger.log("Startup", "Initializing DOMManager");
DOMManager.initialize();
},
async () => {
Logger.log("Startup", "Waiting for connection...");
await this.waitForConnection();
},
async () => {
Logger.log("Startup", "Initializing Editor");
await Editor.initialize();
},
async () => {
Logger.log("Startup", "Initializing Modals");
await Modals.initialize();
},
async () => {
Logger.log("Startup", "Initializing Floating windows");
FloatingWindows.initialize();
},
async () => {
Logger.log("Startup", "Initializing Builtins");
for (const module in Builtins) {
Builtins[module].initialize();
}
},
async () => {
Logger.log("Startup", "Loading Plugins");
// const pluginErrors = [];
Loading.status.label.set("Loading plugins...");
pluginErrors = await PluginManager.initialize();
},
async () => {
Logger.log("Startup", "Loading Themes");
// const themeErrors = [];
Loading.status.label.set("Loading themes...");
themeErrors = await ThemeManager.initialize();
},
async () => {
Logger.log("Startup", "Initializing Updater");
Loading.status.label.set("Getting things ready...");
Updater.initialize();
},
async () => {
Logger.log("Startup", "Removing Loading Interface");
Loading.status.label.set("Done");
Loading.hide();
}
];
Logger.log("Startup", "Initializing LocaleManager");
LocaleManager.initialize();
Logger.log("Startup", "Initializing Settings");
Settings.initialize();
Logger.log("Startup", "Initializing DOMManager");
DOMManager.initialize();
Logger.log("Startup", "Waiting for connection...");
await this.waitForConnection();
Logger.log("Startup", "Initializing Editor");
await Editor.initialize();
Modals.initialize();
FloatingWindows.initialize();
Logger.log("Startup", "Initializing Builtins");
for (const module in Builtins) {
Builtins[module].initialize();
for (let clusterIndex = 0; clusterIndex < clusters.length; clusterIndex++) {
Loading.status.progress.set(clusterIndex / (clusters.length - 1) * 100);
await clusters[clusterIndex]();
}
Logger.log("Startup", "Loading Plugins");
// const pluginErrors = [];
const pluginErrors = PluginManager.initialize();
Logger.log("Startup", "Loading Themes");
// const themeErrors = [];
const themeErrors = ThemeManager.initialize();
Logger.log("Startup", "Initializing Updater");
Updater.initialize();
Logger.log("Startup", "Removing Loading Icon");
LoadingIcon.hide();
// Show loading errors
Logger.log("Startup", "Collecting Startup Errors");
Modals.showAddonErrors({plugins: pluginErrors, themes: themeErrors});

View File

@ -0,0 +1,107 @@
.bd-loaderv3 {
pointer-events: none;
display: flex;
flex-direction: row;
align-items: flex-end;
justify-content: flex-end;
box-sizing: border-box;
padding: 20px;
z-index: 2147483647;
position: absolute;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
}
.bd-loading-container {
pointer-events: all;
display: flex;
flex-direction: row;
box-sizing: border-box;
gap: 5px;
background: var(--background-floating);
box-shadow: var(--elevation-high);
border-radius: 5px;
padding: 10px;
width: fit-content;
min-width: 30vh;
}
.theme-dark .bd-loading-icon {
background-image: url(data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgMjAwMCAyMDAwIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAyMDAwIDIwMDAiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxnPjxwYXRoIGZpbGw9IiMzRTgyRTUiIGQ9Ik0xNDAyLjIsNjMxLjdjLTkuNy0zNTMuNC0yODYuMi00OTYtNjQyLjYtNDk2SDY4LjR2NzE0LjFsNDQyLDM5OFY0OTAuN2gyNTdjMjc0LjUsMCwyNzQuNSwzNDQuOSwwLDM0NC45SDU5Ny42djMyOS41aDE2OS44YzI3NC41LDAsMjc0LjUsMzQ0LjgsMCwzNDQuOGgtNjk5djM1NC45aDY5MS4yYzM1Ni4zLDAsNjMyLjgtMTQyLjYsNjQyLjYtNDk2YzAtMTYyLjYtNDQuNS0yODQuMS0xMjIuOS0zNjguNkMxMzU3LjcsOTE1LjgsMTQwMi4yLDc5NC4zLDE0MDIuMiw2MzEuN3oiLz48cGF0aCBmaWxsPSIjRkZGRkZGIiBkPSJNMTI2Mi41LDEzNS4yTDEyNjIuNSwxMzUuMmwtNzYuOCwwYzI2LjYsMTMuMyw1MS43LDI4LjEsNzUsNDQuM2M3MC43LDQ5LjEsMTI2LjEsMTExLjUsMTY0LjYsMTg1LjNjMzkuOSw3Ni42LDYxLjUsMTY1LjYsNjQuMywyNjQuNmwwLDEuMnYxLjJjMCwxNDEuMSwwLDU5Ni4xLDAsNzM3LjF2MS4ybDAsMS4yYy0yLjcsOTktMjQuMywxODgtNjQuMywyNjQuNmMtMzguNSw3My44LTkzLjgsMTM2LjItMTY0LjYsMTg1LjNjLTIyLjYsMTUuNy00Ni45LDMwLjEtNzIuNiw0My4xaDcyLjVjMzQ2LjIsMS45LDY3MS0xNzEuMiw2NzEtNTY3LjlWNzE2LjdDMTkzMy41LDMxMi4yLDE2MDguNywxMzUuMiwxMjYyLjUsMTM1LjJ6Ii8+PC9nPjwvc3ZnPg==);
}
.theme-light .bd-loading-icon {
background-image: url(data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgMjAwMCAyMDAwIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAyMDAwIDIwMDAiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxnPjxwYXRoIGZpbGw9IiMzRTgyRTUiIGQ9Ik0xNDAyLjIsNjMxLjdjLTkuNy0zNTMuNC0yODYuMi00OTYtNjQyLjYtNDk2SDY4LjR2NzE0LjFsNDQyLDM5OFY0OTAuN2gyNTdjMjc0LjUsMCwyNzQuNSwzNDQuOSwwLDM0NC45SDU5Ny42djMyOS41aDE2OS44YzI3NC41LDAsMjc0LjUsMzQ0LjgsMCwzNDQuOGgtNjk5djM1NC45aDY5MS4yYzM1Ni4zLDAsNjMyLjgtMTQyLjYsNjQyLjYtNDk2YzAtMTYyLjYtNDQuNS0yODQuMS0xMjIuOS0zNjguNkMxMzU3LjcsOTE1LjgsMTQwMi4yLDc5NC4zLDE0MDIuMiw2MzEuN3oiLz48cGF0aCBmaWxsPSIjMDAwMDAwIiBkPSJNMTI2Mi41LDEzNS4yTDEyNjIuNSwxMzUuMmwtNzYuOCwwYzI2LjYsMTMuMyw1MS43LDI4LjEsNzUsNDQuM2M3MC43LDQ5LjEsMTI2LjEsMTExLjUsMTY0LjYsMTg1LjNjMzkuOSw3Ni42LDYxLjUsMTY1LjYsNjQuMywyNjQuNmwwLDEuMnYxLjJjMCwxNDEuMSwwLDU5Ni4xLDAsNzM3LjF2MS4ybDAsMS4yYy0yLjcsOTktMjQuMywxODgtNjQuMywyNjQuNmMtMzguNSw3My44LTkzLjgsMTM2LjItMTY0LjYsMTg1LjNjLTIyLjYsMTUuNy00Ni45LDMwLjEtNzIuNiw0My4xaDcyLjVjMzQ2LjIsMS45LDY3MS0xNzEuMiw2NzEtNTY3LjlWNzE2LjdDMTkzMy41LDMxMi4yLDE2MDguNywxMzUuMiwxMjYyLjUsMTM1LjJ6Ii8+PC9nPjwvc3ZnPg==);
}
.bd-loading-left-side, .bd-loading-right-side {
display: flex;
flex-direction: column;
gap: 5px;
position: relative;
width: fit-content;
}
.bd-loading-right-side {
width: 100%;
}
.bd-loading-icon {
bottom: 15px;
right: 5px;
display: block;
width: 25px;
height: 25px;
background-size: 100% 100%;
animation: bd-loading-animation 1.5s ease-in-out infinite;
}
.bd-loading-icon-note {
font-size: 12px;
color: var(--header-secondary);
}
.bd-loading-item {
display: flex;
flex-direction: column;
gap: 5px;
position: relative;
width: 100%;
}
.bd-loading-progress {
width: 100%;
height: 5px;
margin: 10px 0;
border-radius: 3px;
background-color: var(--background-secondary);
overflow: hidden;
}
.bd-loading-progress-bar {
background-color: #3E82E5;
height: 100%;
}
.bd-loading-status {
white-space: nowrap;
text-align: right;
font-weight: 600;
color: var(--header-primary);
}
@keyframes bd-loading-animation {
0% {
opacity: 0.05;
}
50% {
opacity: 0.6;
}
100% {
opacity: 0.05;
}
}