first reactcomponents + usage
This commit is contained in:
parent
7d3403d79a
commit
6bb5808063
64
js/main.js
64
js/main.js
File diff suppressed because one or more lines are too long
|
@ -31,9 +31,9 @@ const favoritesHTML = `<div id="bda-qem-favourite-container">
|
||||||
|
|
||||||
const makeEmote = (emote, url, options = {}) => {
|
const makeEmote = (emote, url, options = {}) => {
|
||||||
const {onContextMenu, onClick} = options;
|
const {onContextMenu, onClick} = options;
|
||||||
const emoteContainer = $(`<div class="emote-container">
|
const emoteContainer = Utilities.parseHTML(`<div class="emote-container">
|
||||||
<img class="emote-icon" alt="${emote}" src="${url}" title="${emote}">
|
<img class="emote-icon" alt="${emote}" src="${url}" title="${emote}">
|
||||||
</div>`)[0];
|
</div>`);
|
||||||
if (onContextMenu) emoteContainer.addEventListener("contextmenu", onContextMenu);
|
if (onContextMenu) emoteContainer.addEventListener("contextmenu", onContextMenu);
|
||||||
emoteContainer.addEventListener("click", onClick);
|
emoteContainer.addEventListener("click", onClick);
|
||||||
return emoteContainer;
|
return emoteContainer;
|
||||||
|
@ -52,13 +52,13 @@ export default new class EmoteMenu extends Builtin {
|
||||||
this.lastTab = "bda-qem-emojis";
|
this.lastTab = "bda-qem-emojis";
|
||||||
this.favoriteEmotes = {};
|
this.favoriteEmotes = {};
|
||||||
|
|
||||||
this.qmeHeader = $(headerHTML)[0];
|
this.qmeHeader = Utilities.parseHTML(headerHTML);
|
||||||
for (const button of this.qmeHeader.getElementsByTagName("button")) button.addEventListener("click", this.switchMenu.bind(this));
|
for (const button of this.qmeHeader.getElementsByTagName("button")) button.addEventListener("click", this.switchMenu.bind(this));
|
||||||
|
|
||||||
this.teContainer = $(twitchEmoteHTML)[0];
|
this.teContainer = Utilities.parseHTML(twitchEmoteHTML);
|
||||||
this.teContainerInner = this.teContainer.querySelector(".emote-menu-inner");
|
this.teContainerInner = this.teContainer.querySelector(".emote-menu-inner");
|
||||||
|
|
||||||
this.faContainer = $(favoritesHTML)[0];
|
this.faContainer = Utilities.parseHTML(favoritesHTML);
|
||||||
this.faContainerInner = this.faContainer.querySelector(".emote-menu-inner");
|
this.faContainerInner = this.faContainer.querySelector(".emote-menu-inner");
|
||||||
|
|
||||||
this.observer = new MutationObserver(mutations => {for (const mutation of mutations) this.observe(mutation);});
|
this.observer = new MutationObserver(mutations => {for (const mutation of mutations) this.observe(mutation);});
|
||||||
|
@ -94,11 +94,13 @@ export default new class EmoteMenu extends Builtin {
|
||||||
}
|
}
|
||||||
|
|
||||||
enableHideEmojis() {
|
enableHideEmojis() {
|
||||||
$(".emojiPicker-3m1S-j").addClass("bda-qme-hidden");
|
const picker = document.querySelector(".emojiPicker-3m1S-j");
|
||||||
|
if (picker) picker.classList.add("bda-qme-hidden");
|
||||||
}
|
}
|
||||||
|
|
||||||
disableHideEmojis() {
|
disableHideEmojis() {
|
||||||
$(".emojiPicker-3m1S-j").removeClass("bda-qme-hidden");
|
const picker = document.querySelector(".emojiPicker-3m1S-j");
|
||||||
|
if (picker) picker.classList.remove("bda-qme-hidden");
|
||||||
}
|
}
|
||||||
|
|
||||||
insertEmote(emote) {
|
insertEmote(emote) {
|
||||||
|
@ -131,7 +133,7 @@ export default new class EmoteMenu extends Builtin {
|
||||||
}
|
}
|
||||||
|
|
||||||
switchMenu(e) {
|
switchMenu(e) {
|
||||||
let id = typeof(e) == "string" ? e : $(e.target).attr("id");
|
let id = typeof(e) == "string" ? e : e.target.id;
|
||||||
if (id == "bda-qem-emojis" && this.hideEmojis) id = "bda-qem-favourite";
|
if (id == "bda-qem-emojis" && this.hideEmojis) id = "bda-qem-favourite";
|
||||||
const twitch = $("#bda-qem-twitch");
|
const twitch = $("#bda-qem-twitch");
|
||||||
const fav = $("#bda-qem-favourite");
|
const fav = $("#bda-qem-favourite");
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import Builtin from "../structs/builtin";
|
import Builtin from "../structs/builtin";
|
||||||
import PSConnection from "./publicservers/connection";
|
|
||||||
import {BDV2, DiscordModules, WebpackModules} from "modules";
|
import {BDV2, DiscordModules, WebpackModules} from "modules";
|
||||||
import {PublicServersMenu} from "ui";
|
import {PublicServersMenu} from "ui";
|
||||||
|
|
||||||
|
@ -21,7 +20,7 @@ export default new class PublicServers extends Builtin {
|
||||||
}
|
}
|
||||||
|
|
||||||
openPublicServers() {
|
openPublicServers() {
|
||||||
LayerStack.pushLayer(() => DiscordModules.React.createElement(PublicServersMenu, {close: LayerStack.popLayer, connection: PSConnection}));
|
LayerStack.pushLayer(() => DiscordModules.React.createElement(PublicServersMenu, {close: LayerStack.popLayer}));
|
||||||
}
|
}
|
||||||
|
|
||||||
get button() {
|
get button() {
|
||||||
|
|
|
@ -3,13 +3,13 @@ import Core from "./modules/core";
|
||||||
import BdApi from "./modules/pluginapi";
|
import BdApi from "./modules/pluginapi";
|
||||||
import PluginManager from "./modules/pluginmanager";
|
import PluginManager from "./modules/pluginmanager";
|
||||||
import ThemeManager from "./modules/thememanager";
|
import ThemeManager from "./modules/thememanager";
|
||||||
import {bdPluginStorage} from "./modules/oldstorage";
|
|
||||||
import Events from "./modules/emitter";
|
import Events from "./modules/emitter";
|
||||||
import Settings from "./modules/settingsmanager";
|
import Settings from "./modules/settingsmanager";
|
||||||
import DataStore from "./modules/datastore";
|
import DataStore from "./modules/datastore";
|
||||||
import EmoteModule from "./builtins/emotes";
|
import EmoteModule from "./builtins/emotes";
|
||||||
import DomManager from "./modules/dommanager";
|
import DomManager from "./modules/dommanager";
|
||||||
import Utilities from "./modules/utilities";
|
import Utilities from "./modules/utilities";
|
||||||
|
import ReactComponents from "./modules/reactcomponents";
|
||||||
|
|
||||||
// Perform some setup
|
// Perform some setup
|
||||||
// proxyLocalStorage();
|
// proxyLocalStorage();
|
||||||
|
@ -30,13 +30,14 @@ window.themeModule = ThemeManager;
|
||||||
// window.bdplugins = Plugins;
|
// window.bdplugins = Plugins;
|
||||||
window.bdEmotes = EmoteModule.Emotes;
|
window.bdEmotes = EmoteModule.Emotes;
|
||||||
window.bemotes = EmoteModule.blacklist;
|
window.bemotes = EmoteModule.blacklist;
|
||||||
window.bdPluginStorage = bdPluginStorage;
|
// window.bdPluginStorage = bdPluginStorage;
|
||||||
window.settingsModule = Settings;
|
window.settingsModule = Settings;
|
||||||
window.DataStore = DataStore;
|
window.DataStore = DataStore;
|
||||||
|
|
||||||
|
|
||||||
window.DomManager = DomManager;
|
window.DomManager = DomManager;
|
||||||
window.utils = Utilities;
|
window.utils = Utilities;
|
||||||
|
window.Components = ReactComponents;
|
||||||
|
|
||||||
window.BDEvents = Events;
|
window.BDEvents = Events;
|
||||||
window.bdConfig = Config;
|
window.bdConfig = Config;
|
||||||
|
|
|
@ -1,96 +0,0 @@
|
||||||
import WebpackModules from "./webpackmodules";
|
|
||||||
import DiscordModules from "./discordmodules";
|
|
||||||
import Utilities from "./utilities";
|
|
||||||
import BDLogo from "../ui/icons/bdlogo";
|
|
||||||
|
|
||||||
const React = DiscordModules.React;
|
|
||||||
|
|
||||||
export default new class {
|
|
||||||
|
|
||||||
initialize() {
|
|
||||||
Utilities.suppressErrors(this.patchSocial.bind(this), "BD Social Patch")();
|
|
||||||
Utilities.suppressErrors(this.patchGuildPills.bind(this), "BD Guild Pills Patch")();
|
|
||||||
Utilities.suppressErrors(this.patchGuildListItems.bind(this), "BD Guild List Items Patch")();
|
|
||||||
Utilities.suppressErrors(this.patchGuildSeparator.bind(this), "BD Guild Separator Patch")();
|
|
||||||
}
|
|
||||||
|
|
||||||
patchSocial() {
|
|
||||||
if (this.socialPatch) return;
|
|
||||||
const TabBar = WebpackModules.getModule(m => m.displayName == "TabBar");
|
|
||||||
const Anchor = WebpackModules.getModule(m => m.displayName == "Anchor");
|
|
||||||
if (!TabBar || !Anchor) return;
|
|
||||||
this.socialPatch = Utilities.monkeyPatch(TabBar.prototype, "render", {after: (data) => {
|
|
||||||
const children = data.returnValue.props.children;
|
|
||||||
if (!children || !children.length) return;
|
|
||||||
if (children[children.length - 2].type.displayName !== "Separator") return;
|
|
||||||
if (!children[children.length - 1].type.toString().includes("socialLinks")) return;
|
|
||||||
const original = children[children.length - 1].type;
|
|
||||||
const newOne = function() {
|
|
||||||
const returnVal = original(...arguments);
|
|
||||||
returnVal.props.children.push(React.createElement(Anchor, {className: "bd-social-link", href: "https://github.com/rauenzi/BetterDiscordApp", rel: "author", title: "BandagedBD", target: "_blank"},
|
|
||||||
React.createElement(BDLogo, {size: "16px", className: "bd-social-logo"})
|
|
||||||
));
|
|
||||||
return returnVal;
|
|
||||||
};
|
|
||||||
children[children.length - 1].type = newOne;
|
|
||||||
}});
|
|
||||||
}
|
|
||||||
|
|
||||||
patchGuildListItems() {
|
|
||||||
if (this.guildListItemsPatch) return;
|
|
||||||
const listItemClass = this.guildClasses.listItem.split(" ")[0];
|
|
||||||
const blobClass = this.guildClasses.blobContainer.split(" ")[0];
|
|
||||||
const reactInstance = Utilities.getReactInstance(document.querySelector(`.${listItemClass} .${blobClass}`).parentElement);
|
|
||||||
const GuildComponent = reactInstance.return.type;
|
|
||||||
if (!GuildComponent) return;
|
|
||||||
this.guildListItemsPatch = Utilities.monkeyPatch(GuildComponent.prototype, "render", {after: (data) => {
|
|
||||||
const returnValue = data.returnValue;
|
|
||||||
const guildData = data.thisObject.props;
|
|
||||||
returnValue.props.className += " bd-guild";
|
|
||||||
if (guildData.unread) returnValue.props.className += " bd-unread";
|
|
||||||
if (guildData.selected) returnValue.props.className += " bd-selected";
|
|
||||||
if (guildData.audio) returnValue.props.className += " bd-audio";
|
|
||||||
if (guildData.video) returnValue.props.className += " bd-video";
|
|
||||||
if (guildData.badge) returnValue.props.className += " bd-badge";
|
|
||||||
if (guildData.animatable) returnValue.props.className += " bd-animatable";
|
|
||||||
return returnValue;
|
|
||||||
}});
|
|
||||||
}
|
|
||||||
|
|
||||||
patchGuildPills() {
|
|
||||||
if (this.guildPillPatch) return;
|
|
||||||
const guildPill = WebpackModules.getModule(m => m.default && m.default.toString && m.default.toString().includes("translate3d"));
|
|
||||||
if (!guildPill) return;
|
|
||||||
this.guildPillPatch = Utilities.monkeyPatch(guildPill, "default", {after: (data) => {
|
|
||||||
const props = data.methodArguments[0];
|
|
||||||
if (props.unread) data.returnValue.props.className += " bd-unread";
|
|
||||||
if (props.selected) data.returnValue.props.className += " bd-selected";
|
|
||||||
if (props.hovered) data.returnValue.props.className += " bd-hovered";
|
|
||||||
return data.returnValue;
|
|
||||||
}});
|
|
||||||
}
|
|
||||||
|
|
||||||
patchGuildSeparator() {
|
|
||||||
if (this.guildSeparatorPatch) return;
|
|
||||||
const Guilds = WebpackModules.getByDisplayName("Guilds");
|
|
||||||
const guildComponents = WebpackModules.getByProps("renderListItem");
|
|
||||||
if (!guildComponents || !Guilds) return;
|
|
||||||
const GuildSeparator = function() {
|
|
||||||
const returnValue = guildComponents.Separator(...arguments);
|
|
||||||
returnValue.props.className += " bd-guild-separator";
|
|
||||||
return returnValue;
|
|
||||||
};
|
|
||||||
this.guildSeparatorPatch = Utilities.monkeyPatch(Guilds.prototype, "render", {after: (data) => {
|
|
||||||
data.returnValue.props.children[1].props.children[3].type = GuildSeparator;
|
|
||||||
}});
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
// lc = WebpackModules.getByDisplayName("FluxContainer(Layers)")
|
|
||||||
// Patcher.after(lc.prototype, "render", (t,a,r) => {console.log(t,a,r);})
|
|
||||||
// return.type
|
|
||||||
// Patcher.after(temp3.prototype, "renderLayers", (t,a,r) => {
|
|
||||||
// console.log(t,a,r);
|
|
||||||
// if (t.props.layers.includes("USER_SETTINGS")) r[1].props.className = "user-settings-prop";
|
|
||||||
// })
|
|
|
@ -9,6 +9,7 @@ import ThemeManager from "./thememanager";
|
||||||
import Settings from "./settingsmanager";
|
import Settings from "./settingsmanager";
|
||||||
import * as Builtins from "builtins";
|
import * as Builtins from "builtins";
|
||||||
import {Modals} from "ui";
|
import {Modals} from "ui";
|
||||||
|
import ReactComponents from "./reactcomponents";
|
||||||
|
|
||||||
function Core() {
|
function Core() {
|
||||||
}
|
}
|
||||||
|
@ -22,7 +23,7 @@ Core.prototype.init = async function() {
|
||||||
Modals.alert("Not Supported", "BetterDiscord v" + Config.version + " (your version)" + " is not supported by the latest js (" + Config.bbdVersion + ").<br><br> Please download the latest version from <a href='https://github.com/rauenzi/BetterDiscordApp/releases/latest' target='_blank'>GitHub</a>");
|
Modals.alert("Not Supported", "BetterDiscord v" + Config.version + " (your version)" + " is not supported by the latest js (" + Config.bbdVersion + ").<br><br> Please download the latest version from <a href='https://github.com/rauenzi/BetterDiscordApp/releases/latest' target='_blank'>GitHub</a>");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
ReactComponents.initialize();
|
||||||
const latestLocalVersion = Config.updater ? Config.updater.LatestVersion : Config.latestVersion;
|
const latestLocalVersion = Config.updater ? Config.updater.LatestVersion : Config.latestVersion;
|
||||||
if (latestLocalVersion > Config.version) {
|
if (latestLocalVersion > Config.version) {
|
||||||
Modals.alert("Update Available", `
|
Modals.alert("Update Available", `
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
import Utilities from "./utilities";
|
|
||||||
import DataStore from "./datastore";
|
|
||||||
|
|
||||||
export class bdStorage {
|
|
||||||
static get(key) {
|
|
||||||
Utilities.warn("Deprecation Notice", "Please use BdApi.getBDData(). bdStorage may be removed in future versions.");
|
|
||||||
return DataStore.getBDData(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
static set(key, data) {
|
|
||||||
Utilities.warn("Deprecation Notice", "Please use BdApi.setBDData(). bdStorage may be removed in future versions.");
|
|
||||||
DataStore.setBDData(key, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class bdPluginStorage {
|
|
||||||
static get(pluginName, key) {
|
|
||||||
Utilities.warn("Deprecation Notice", `${pluginName}, please use BdApi.loadData() or BdApi.getData(). bdPluginStorage may be removed in future versions.`);
|
|
||||||
return DataStore.getPluginData(pluginName, key) || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
static set(pluginName, key, data) {
|
|
||||||
Utilities.warn("Deprecation Notice", `${pluginName}, please use BdApi.saveData() or BdApi.setData(). bdPluginStorage may be removed in future versions.`);
|
|
||||||
if (typeof(data) === "undefined") return Utilities.warn("Deprecation Notice", "Trying to set undefined value in plugin " + pluginName);
|
|
||||||
DataStore.setPluginData(pluginName, key, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static delete(pluginName, key) {
|
|
||||||
Utilities.warn("Deprecation Notice", `${pluginName}, please use BdApi.deleteData(). bdPluginStorage may be removed in future versions.`);
|
|
||||||
DataStore.deletePluginData(pluginName, key);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
import DiscordModules from "./discordmodules";
|
||||||
|
import Patcher from "./patcher";
|
||||||
|
|
||||||
|
const React = DiscordModules.React;
|
||||||
|
const components = {};
|
||||||
|
const unknownComponents = new Set();
|
||||||
|
const listeners = new Set();
|
||||||
|
|
||||||
|
export default new class ReactComponents {
|
||||||
|
|
||||||
|
get named() {return components;}
|
||||||
|
get unknown() {return unknownComponents;}
|
||||||
|
get listeners() {return listeners;}
|
||||||
|
|
||||||
|
initialize() {
|
||||||
|
this.walkReactTree(document.querySelector("#app-mount")._reactRootContainer._internalRoot.current);
|
||||||
|
Patcher.after("ReactComponents", React, "createElement", (_, __, returnValue) => {
|
||||||
|
this.walkRenderTree(returnValue);
|
||||||
|
});
|
||||||
|
Patcher.instead("ReactComponents", React.Component.prototype, "componentWillMount", (thisObject) => {
|
||||||
|
this.addComponent(thisObject.constructor);
|
||||||
|
});
|
||||||
|
Patcher.instead("ReactComponents", React.Component.prototype, "UNSAFE_componentWillMount", (thisObject) => {
|
||||||
|
this.addComponent(thisObject.constructor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get(name, filter) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
if (components[name]) return resolve(components[name]);
|
||||||
|
listeners.add({name, filter, resolve});
|
||||||
|
if (!filter) return;
|
||||||
|
for (const component of unknownComponents) {
|
||||||
|
if (!filter(component)) continue;
|
||||||
|
component.displayName = name;
|
||||||
|
unknownComponents.delete(component);
|
||||||
|
this.addNamedComponent(component);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
addNamedComponent(component) {
|
||||||
|
const name = component.displayName;
|
||||||
|
if (!components[name]) {
|
||||||
|
components[name] = component;
|
||||||
|
for (const listener of listeners) {
|
||||||
|
if (listener.name !== name) continue;
|
||||||
|
listener.resolve(component);
|
||||||
|
listeners.delete(listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addUnknownComponent(component) {
|
||||||
|
if (unknownComponents.has(component)) return;
|
||||||
|
for (const listener of listeners) {
|
||||||
|
if (!listener.filter || !listener.filter(component)) continue;
|
||||||
|
component.displayName = listener.name;
|
||||||
|
this.addNamedComponent(component);
|
||||||
|
}
|
||||||
|
if (!component.displayName) unknownComponents.add(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
addComponent(component) {
|
||||||
|
if (component.displayName) return this.addNamedComponent(component);
|
||||||
|
return this.addUnknownComponent(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
walkRenderTree(tree) {
|
||||||
|
if (!tree) return;
|
||||||
|
if (typeof(tree.type) == "function") this.addComponent(tree.type);
|
||||||
|
if (Array.isArray(tree)) for (const value of tree) this.walkRenderTree(value);
|
||||||
|
if (tree.props && tree.props.children) this.walkRenderTree(tree.props.children);
|
||||||
|
}
|
||||||
|
|
||||||
|
walkReactTree(tree) {
|
||||||
|
if (!tree) return;
|
||||||
|
if (typeof(tree.type) == "function") this.addComponent(tree.type);
|
||||||
|
if (tree.child) this.walkReactTree(tree.child);
|
||||||
|
if (tree.sibling) this.walkReactTree(tree.sibling);
|
||||||
|
}
|
||||||
|
};
|
|
@ -4,6 +4,8 @@ import DataStore from "./datastore";
|
||||||
import Events from "./emitter";
|
import Events from "./emitter";
|
||||||
import WebpackModules from "./webpackmodules";
|
import WebpackModules from "./webpackmodules";
|
||||||
import DiscordModules from "./discordmodules";
|
import DiscordModules from "./discordmodules";
|
||||||
|
import Patcher from "./patcher";
|
||||||
|
import ReactComponents from "./reactcomponents";
|
||||||
|
|
||||||
import {SettingsPanel as SettingsRenderer} from "ui";
|
import {SettingsPanel as SettingsRenderer} from "ui";
|
||||||
import Utilities from "./utilities";
|
import Utilities from "./utilities";
|
||||||
|
@ -102,17 +104,17 @@ export default new class SettingsManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
async patchSections() {
|
async patchSections() {
|
||||||
Utilities.monkeyPatch(WebpackModules.getByDisplayName("FluxContainer(GuildSettings)").prototype, "render", {after: (data) => {
|
Patcher.after("SettingsManager", WebpackModules.getByDisplayName("FluxContainer(GuildSettings)").prototype, "render", (thisObject) => {
|
||||||
data.thisObject._reactInternalFiber.return.return.return.return.return.return.memoizedProps.id = "guild-settings";
|
thisObject._reactInternalFiber.return.return.return.return.return.return.memoizedProps.id = "guild-settings";
|
||||||
}});
|
});
|
||||||
const UserSettings = await this.getUserSettings();
|
const UserSettings = await ReactComponents.get("UserSettings", m => m.prototype && m.prototype.generateSections);
|
||||||
Utilities.monkeyPatch(UserSettings.prototype, "render", {after: (data) => {
|
Patcher.after("SettingsManager", UserSettings.prototype, "render", (thisObject) => {
|
||||||
data.thisObject._reactInternalFiber.return.return.return.return.return.return.return.memoizedProps.id = "user-settings";
|
thisObject._reactInternalFiber.return.return.return.return.return.return.return.memoizedProps.id = "user-settings";
|
||||||
}});
|
});
|
||||||
Utilities.monkeyPatch(UserSettings.prototype, "generateSections", {after: (data) => {
|
Patcher.after("SettingsManager", UserSettings.prototype, "generateSections", (thisObject, args, returnValue) => {
|
||||||
let location = data.returnValue.findIndex(s => s.section.toLowerCase() == "linux") + 1;
|
let location = returnValue.findIndex(s => s.section.toLowerCase() == "linux") + 1;
|
||||||
const insert = (section) => {
|
const insert = (section) => {
|
||||||
data.returnValue.splice(location, 0, section);
|
returnValue.splice(location, 0, section);
|
||||||
location++;
|
location++;
|
||||||
};
|
};
|
||||||
insert({section: "DIVIDER"});
|
insert({section: "DIVIDER"});
|
||||||
|
@ -126,11 +128,11 @@ export default new class SettingsManager {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
for (const panel of this.panels.sort((a,b) => a.order > b.order)) {
|
for (const panel of this.panels.sort((a,b) => a.order > b.order)) {
|
||||||
if (panel.clickListener) panel.onClick = (event) => panel.clickListener(data.thisObject, event, data.returnValue);
|
if (panel.clickListener) panel.onClick = (event) => panel.clickListener(thisObject, event, returnValue);
|
||||||
insert(panel);
|
insert(panel);
|
||||||
}
|
}
|
||||||
insert({section: "CUSTOM", element: () => SettingsRenderer.attribution});
|
insert({section: "CUSTOM", element: () => SettingsRenderer.attribution});
|
||||||
}});
|
});
|
||||||
this.forceUpdate();
|
this.forceUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,16 +142,6 @@ export default new class SettingsManager {
|
||||||
Utilities.getReactInstance(node).return.return.return.return.return.return.stateNode.forceUpdate();
|
Utilities.getReactInstance(node).return.return.return.return.return.return.stateNode.forceUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
getUserSettings() {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
const cancel = Utilities.monkeyPatch(WebpackModules.getByProps("getUserSettingsSections").default.prototype, "render", {after: (data) => {
|
|
||||||
resolve(data.returnValue.type);
|
|
||||||
data.thisObject.forceUpdate();
|
|
||||||
cancel();
|
|
||||||
}});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
saveSettings() {
|
saveSettings() {
|
||||||
DataStore.setData("settings", this.state);
|
DataStore.setData("settings", this.state);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,25 @@ import Logger from "./logger";
|
||||||
|
|
||||||
export default class Utilities {
|
export default class Utilities {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a string of HTML and returns the results. If the second parameter is true,
|
||||||
|
* the parsed HTML will be returned as a document fragment {@see https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment}.
|
||||||
|
* This is extremely useful if you have a list of elements at the top level, they can then be appended all at once to another node.
|
||||||
|
*
|
||||||
|
* If the second parameter is false, then the return value will be the list of parsed
|
||||||
|
* nodes and there were multiple top level nodes, otherwise the single node is returned.
|
||||||
|
* @param {string} html - HTML to be parsed
|
||||||
|
* @param {boolean} [fragment=false] - Whether or not the return should be the raw `DocumentFragment`
|
||||||
|
* @returns {(DocumentFragment|NodeList|HTMLElement)} - The result of HTML parsing
|
||||||
|
*/
|
||||||
|
static parseHTML(html, fragment = false) {
|
||||||
|
const template = document.createElement("template");
|
||||||
|
template.innerHTML = html;
|
||||||
|
const node = template.content.cloneNode(true);
|
||||||
|
if (fragment) return node;
|
||||||
|
return node.childNodes.length > 1 ? node.childNodes : node.childNodes[0];
|
||||||
|
}
|
||||||
|
|
||||||
static getTextArea() {
|
static getTextArea() {
|
||||||
return $(".channelTextArea-1LDbYG textarea");
|
return $(".channelTextArea-1LDbYG textarea");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {Logger, WebpackModules, React, Settings} from "modules";
|
import {Logger, WebpackModules, Utilities, React, Settings} from "modules";
|
||||||
|
|
||||||
export default class Modals {
|
export default class Modals {
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ export default class Modals {
|
||||||
static get ConfirmationModal() {return WebpackModules.getModule(m => m.defaultProps && m.key && m.key() == "confirm-modal");}
|
static get ConfirmationModal() {return WebpackModules.getModule(m => m.defaultProps && m.key && m.key() == "confirm-modal");}
|
||||||
|
|
||||||
static default(title, content) {
|
static default(title, content) {
|
||||||
const modal = $(`<div class="bd-modal-wrapper theme-dark">
|
const modal = Utilities.parseHTML(`<div class="bd-modal-wrapper theme-dark">
|
||||||
<div class="bd-backdrop backdrop-1wrmKB"></div>
|
<div class="bd-backdrop backdrop-1wrmKB"></div>
|
||||||
<div class="bd-modal modal-1UGdnR">
|
<div class="bd-modal modal-1UGdnR">
|
||||||
<div class="bd-modal-inner inner-1JeGVc">
|
<div class="bd-modal-inner inner-1JeGVc">
|
||||||
|
@ -30,15 +30,15 @@ export default class Modals {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>`);
|
</div>`);
|
||||||
modal.find(".footer button").on("click", () => {
|
modal.querySelector(".footer button").addEventListener("click", () => {
|
||||||
modal.addClass("closing");
|
modal.addClass("closing");
|
||||||
setTimeout(() => { modal.remove(); }, 300);
|
setTimeout(() => { modal.remove(); }, 300);
|
||||||
});
|
});
|
||||||
modal.find(".bd-backdrop").on("click", () => {
|
modal.querySelector(".bd-backdrop").addEventListener("click", () => {
|
||||||
modal.addClass("closing");
|
modal.addClass("closing");
|
||||||
setTimeout(() => { modal.remove(); }, 300);
|
setTimeout(() => { modal.remove(); }, 300);
|
||||||
});
|
});
|
||||||
modal.appendTo("#app-mount");
|
document.querySelector("#app-mount").append(modal);
|
||||||
}
|
}
|
||||||
|
|
||||||
static alert(title, content) {
|
static alert(title, content) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import {React, WebpackModules} from "modules";
|
import {React, WebpackModules} from "modules";
|
||||||
import SettingsTitle from "../settings/title";
|
import SettingsTitle from "../settings/title";
|
||||||
import ServerCard from "./card";
|
import ServerCard from "./card";
|
||||||
|
import Connection from "../../structs/psconnection";
|
||||||
|
|
||||||
const SettingsView = WebpackModules.getByDisplayName("SettingsView");
|
const SettingsView = WebpackModules.getByDisplayName("SettingsView");
|
||||||
|
|
||||||
|
@ -37,7 +38,7 @@ export default class PublicServers extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
async checkConnection() {
|
async checkConnection() {
|
||||||
const userData = await this.props.connection.checkConnection();
|
const userData = await Connection.checkConnection();
|
||||||
if (!userData) {
|
if (!userData) {
|
||||||
return this.setState({loading: true, user: null});
|
return this.setState({loading: true, user: null});
|
||||||
}
|
}
|
||||||
|
@ -46,7 +47,7 @@ export default class PublicServers extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
async connect() {
|
async connect() {
|
||||||
await this.props.connection.connect();
|
await Connection.connect();
|
||||||
this.checkConnection();
|
this.checkConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +58,7 @@ export default class PublicServers extends React.Component {
|
||||||
|
|
||||||
async search(term = "", from = 0) {
|
async search(term = "", from = 0) {
|
||||||
this.setState({query: term, loading: true});
|
this.setState({query: term, loading: true});
|
||||||
const results = await this.props.connection.search({term, category: this.state.category == "All" ? "" : this.state.category, from});
|
const results = await Connection.search({term, category: this.state.category == "All" ? "" : this.state.category, from});
|
||||||
if (!results) {
|
if (!results) {
|
||||||
return this.setState({results: {
|
return this.setState({results: {
|
||||||
servers: [],
|
servers: [],
|
||||||
|
@ -82,7 +83,7 @@ export default class PublicServers extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
async join(id, native = false) {
|
async join(id, native = false) {
|
||||||
return await this.props.connection.join(id, native);
|
return await Connection.join(id, native);
|
||||||
}
|
}
|
||||||
|
|
||||||
get searchBox() {
|
get searchBox() {
|
||||||
|
@ -104,7 +105,7 @@ export default class PublicServers extends React.Component {
|
||||||
const connectButton = this.state.user ? null : {title: "Connect", onClick: this.connect};
|
const connectButton = this.state.user ? null : {title: "Connect", onClick: this.connect};
|
||||||
const pinned = this.state.category == "All" || !this.state.user ? this.bdServer : null;
|
const pinned = this.state.category == "All" || !this.state.user ? this.bdServer : null;
|
||||||
const servers = this.state.results.servers.map((server) => {
|
const servers = this.state.results.servers.map((server) => {
|
||||||
return React.createElement(ServerCard, {key: server.identifier, server: server, joined: this.props.connection.hasJoined(server.identifier), defaultAvatar: this.props.connection.getDefaultAvatar});
|
return React.createElement(ServerCard, {key: server.identifier, server: server, joined: Connection.hasJoined(server.identifier), defaultAvatar: Connection.getDefaultAvatar});
|
||||||
});
|
});
|
||||||
return [React.createElement(SettingsTitle, {text: this.title, button: connectButton}),
|
return [React.createElement(SettingsTitle, {text: this.title, button: connectButton}),
|
||||||
pinned,
|
pinned,
|
||||||
|
@ -139,7 +140,7 @@ export default class PublicServers extends React.Component {
|
||||||
invite_code: "0Tmfo5ZbORCRqbAd",
|
invite_code: "0Tmfo5ZbORCRqbAd",
|
||||||
pinned: true
|
pinned: true
|
||||||
};
|
};
|
||||||
return React.createElement(ServerCard, {server: server, pinned: true, joined: this.props.connection.hasJoined(server.identifier), defaultAvatar: this.props.connection.getDefaultAvatar});
|
return React.createElement(ServerCard, {server: server, pinned: true, joined: Connection.hasJoined(server.identifier), defaultAvatar: Connection.getDefaultAvatar});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
Loading…
Reference in New Issue