more cleanup + dommanager

This commit is contained in:
Zack Rauen 2019-06-18 23:09:49 -04:00
parent ed145df94b
commit e3ce238440
23 changed files with 383 additions and 288 deletions

View File

@ -16,16 +16,18 @@
}
},
"rules": {
"semi": 2,
"space-infix-ops": ["error", {"int32Hint": false}],
"semi": "error",
"space-infix-ops": "error",
"quotes": ["error", "double", {"allowTemplateLiterals": true}],
"no-console": 2,
"no-console": "error",
"no-shadow": ["warn", { "builtinGlobals": false, "hoist": "functions", "allow": [] }],
"no-redeclare": ["error", { "builtinGlobals": true }],
"brace-style": ["error", "stroustrup", {"allowSingleLine": true}],
"keyword-spacing": 2,
"no-else-return": 2,
"keyword-spacing": "error",
"no-else-return": "error",
"curly": ["error", "multi-line", "consistent"],
"dot-notation": 2,
"yoda": 2,
"dot-notation": "error",
"yoda": "error",
"linebreak-style": ["error", "windows"],
"quote-props": ["error", "consistent-as-needed", {"keywords": true}],
"object-curly-spacing": ["error", "never", { "objectsInObjects": false }],
@ -33,19 +35,60 @@
"prefer-const": "error",
"react/jsx-uses-react": "error",
"react/jsx-uses-vars": "error",
"react/prop-types": 0,
"react/prop-types": "off",
"react/jsx-no-target-blank": "error",
"react/jsx-key": 0
"react/jsx-key": "off"
},
"globals": {
"webpackJsonp": false,
"Proxy": false,
"Set": false,
"WeakMap": false,
"Promise": false,
"ace": false,
"Reflect": false,
"DiscordNative": false,
"__non_webpack_require__": false
"webpackJsonp": "readonly",
"Proxy": "readonly",
"Set": "readonly",
"WeakMap": "readonly",
"Promise": "readonly",
"ace": "readonly",
"Reflect": "readonly",
"DiscordNative": "readonly",
"__non_webpack_require__": "readonly",
"alert": "off",
"atob": "off",
"blur": "off",
"btoa": "off",
"caches": "off",
"close": "off",
"closed": "off",
"confirm": "off",
"crypto": "off",
"defaultstatus": "off",
"event": "off",
"external": "off",
"fetch": "off",
"find": "off",
"focus": "off",
"frames": "off",
"history": "off",
"length": "off",
"location": "off",
"locationbar": "off",
"menubar": "off",
"name": "off",
"navigator": "off",
"open": "off",
"opener": "off",
"origin": "off",
"parent": "off",
"performance": "off",
"personalbar": "off",
"print": "off",
"prompt": "off",
"screen": "off",
"scroll": "off",
"scrollbars": "off",
"self": "off",
"status": "off",
"statusbar": "off",
"stop": "off",
"toolbar": "off",
"top": "off"
}
}

View File

@ -123,6 +123,10 @@
z-index: 1001;
}
.floating-window.modal-open {
z-index: 999;
}
.floating-window.resizable {
overflow: auto;
resize: both;

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,5 @@
import Builtin from "../structs/builtin";
import {Settings, DataStore, React, Utilities, WebpackModules, Events} from "modules";
import {Settings, DataStore, React, Utilities, WebpackModules, Events, DOMManager} from "modules";
import CSSEditor from "../ui/customcss/csseditor";
import FloatingWindowContainer from "../ui/floating/container";
import SettingsTitle from "../ui/settings/title";
@ -57,8 +57,7 @@ export default new class CustomCSS extends Builtin {
Settings.removePanel(this.id);
this.unwatchContent();
}
//* {outline: 1px solid red;}
//DataStore.customCSS
watchContent() {
if (this.watcher) return this.error("Already watching content.");
const timeCache = {};
@ -107,10 +106,11 @@ export default new class CustomCSS extends Builtin {
insertCSS(newCss) {
if (typeof(newCss) === "undefined") newCss = this.insertedCss;
else this.insertedCss = newCss;
if ($("#customcss").length == 0) {
$("head").append("<style id=\"customcss\"></style>");
}
$("#customcss").text(newCss).detach().appendTo(document.head);
// if ($("#customcss").length == 0) {
// $("head").append("<style id=\"customcss\"></style>");
// }
// $("#customcss").text(newCss).detach().appendTo(document.head);
DOMManager.updateCustomCSS(newCss);
}
saveCSS(newCss) {
@ -126,7 +126,7 @@ export default new class CustomCSS extends Builtin {
const editorRef = React.createRef();
const editor = React.createElement(CSSEditor, {
id: "bd-floating-editor",
editorRef: editorRef,
ref: editorRef,
css: currentCSS,
save: this.saveCSS.bind(this),
update: this.insertCSS.bind(this),
@ -135,7 +135,9 @@ export default new class CustomCSS extends Builtin {
});
FloatingWindowContainer.open({
onClose: () => {this.isDetached = false;},
onClose: () => {
this.isDetached = false;
},
onResize: () => {
if (!editorRef || !editorRef.current || !editorRef.current.resize) return;
editorRef.current.resize();
@ -146,7 +148,12 @@ export default new class CustomCSS extends Builtin {
width: 410,
center: true,
resizable: true,
children: editor
children: editor,
confirmClose: () => {
if (!editorRef || !editorRef.current) return false;
return editorRef.current.hasUnsavedChanges;
},
confirmationText: "You have unsaved changes to your Custom CSS. Closing this window will lose all those changes."
});
this.isDetached = true;
UserSettings.close();

View File

@ -51,8 +51,8 @@ export default new class DeveloperMode extends Builtin {
cm.remove();
$(document).off(".bdDevModeCtx");
});
$(document).on("keyup.bdDevModeCtx", (e) => {
if (e.keyCode === 27) {
$(document).on("keyup.bdDevModeCtx", (event) => {
if (event.keyCode === 27) {
cm.remove();
$(document).off(".bdDevModeCtx");
}

View File

@ -70,7 +70,7 @@ export default new class EmoteMenu extends Builtin {
initialize() {
super.initialize();
const fe = DataStore.getBDData("bdfavemotes");
if (fe !== "" && fe !== null) this.favoriteEmotes = JSON.parse(atob(fe));
if (fe !== "" && fe !== null) this.favoriteEmotes = JSON.parse(window.atob(fe));
this.updateFavorites();
}
@ -115,16 +115,16 @@ export default new class EmoteMenu extends Builtin {
left: e.pageX - $("#bda-qem-favourite-container").offset().left
});
$(em).parent().append(menu);
menu.on("click", (e) => {
e.preventDefault();
e.stopPropagation();
menu.on("click", (event) => {
event.preventDefault();
event.stopPropagation();
$(em).remove();
delete this.favoriteEmotes[$(em).attr("title")];
this.updateFavorites();
$(document).off("mousedown.emotemenu");
});
$(document).on("mousedown.emotemenu", function(e) {
if (e.target.id == "removemenu") return;
$(document).on("mousedown.emotemenu", function(event) {
if (event.target.id == "removemenu") return;
$("#removemenu").remove();
$(document).off("mousedown.emotemenu");
});
@ -200,7 +200,7 @@ export default new class EmoteMenu extends Builtin {
const emoteElement = makeEmote(emote, url, {onClick: this.insertEmote.bind(this, emote), onContextMenu: this.favContext.bind(this)});
this.faContainerInner.append(emoteElement);
}
DataStore.setBDData("bdfavemotes", btoa(JSON.stringify(this.favoriteEmotes)));
DataStore.setBDData("bdfavemotes", window.btoa(JSON.stringify(this.favoriteEmotes)));
}
};

View File

@ -84,8 +84,8 @@ export default new class EmoteModule extends Builtin {
patchMessageContent() {
if (this.cancelEmoteRender) return;
this.cancelEmoteRender = Utilities.monkeyPatch(this.MessageContentComponent.prototype, "render", {after: ({returnValue}) => {
Utilities.monkeyPatch(returnValue.props, "children", {silent: true, after: ({returnValue}) => {
this.cancelEmoteRender = Utilities.monkeyPatch(this.MessageContentComponent.prototype, "render", {after: ({retVal}) => {
Utilities.monkeyPatch(retVal.props, "children", {silent: true, after: ({returnValue}) => {
if (this.categories.length == 0) return;
const markup = returnValue.props.children[1];
if (!markup.props.children) return;
@ -162,10 +162,10 @@ export default new class EmoteModule extends Builtin {
Utilities.log("Emotes", "Loading emotes from local cache.");
const data = await new Promise(resolve => {
_fs.readFile(file, "utf8", (err, data) => {
_fs.readFile(file, "utf8", (err, content) => {
Utilities.log("Emotes", "Emotes loaded from cache.");
if (err) data = {};
resolve(data);
if (err) content = {};
resolve(content);
});
});

View File

@ -3,6 +3,7 @@ import Utilities from "./utilities";
import {Config} from "data";
// import EmoteModule from "./emotes";
// import QuickEmoteMenu from "../builtins/emotemenu";
import DOMManager from "./dommanager";
import PluginManager from "./pluginmanager";
import ThemeManager from "./thememanager";
import Settings from "./settingsmanager";
@ -42,6 +43,7 @@ Core.prototype.init = async function() {
// this.injectExternals();
DOMManager.initialize();
await this.checkForGuilds();
BDV2.initialize();
Utilities.log("Startup", "Updating Settings");
@ -53,7 +55,7 @@ Core.prototype.init = async function() {
Utilities.log("Startup", "Loading Themes");
const themeErrors = ThemeManager.loadAllThemes();
$("#customcss").detach().appendTo(document.head);
// $("#customcss").detach().appendTo(document.head);
// PublicServers.initialize();
// EmoteModule.autoCapitalize();

59
src/modules/dommanager.js Normal file
View File

@ -0,0 +1,59 @@
export default class DOMManager {
static get bdHead() { return this.getElement("bd-head"); }
static get bdBody() { return this.getElement("bd-body"); }
static get bdStyles() { return this.getElement("bd-styles"); }
static get bdThemes() { return this.getElement("bd-themes"); }
static get bdCustomCSS() { return this.getElement("#customcss"); }
static get bdTooltips() { return this.getElement("bd-tooltips") || this.createElement("bd-tooltips").appendTo(this.bdBody); }
static get bdModals() { return this.getElement("bd-modals") || this.createElement("bd-modals").appendTo(this.bdBody); }
static get bdToasts() { return this.getElement("bd-toasts") || this.createElement("bd-toasts").appendTo(this.bdBody); }
static initialize() {
this.createElement("bd-head", {target: document.head});
this.createElement("bd-body", {target: document.body});
this.createElement("bd-styles", {target: this.bdHead});
this.createElement("bd-themes", {target: this.bdHead});
this.createElement("style", {id: "customcss", target: this.bdHead});
}
static getElement(e, baseElement = document) {
if (e instanceof Node) return e;
return baseElement.querySelector(e);
}
static createElement(tag, options = {}) {
const {className, id, target} = options;
const element = document.createElement(tag);
if (className) element.className = className;
if (id) element.id = id;
if (target) this.getElement(target).append(element);
return element;
}
static removeStyle(id) {
const exists = this.getElement(id, this.bdStyles);
if (exists) exists.remove();
}
static injectStyle(id, css) {
const style = this.getElement(id, this.bdStyles) || this.createElement("style", {id});
style.textContent = css;
this.bdStyles.append(style);
}
static removeTheme(id) {
const exists = this.getElement(id, this.bdThemes);
if (exists) exists.remove();
}
static injectTheme(id, css) {
const style = this.getElement(id, this.bdThemes) || this.createElement("style", {id});
style.textContent = css;
this.bdThemes.append(style);
}
static updateCustomCSS(css) {
this.bdCustomCSS.textContent = css;
}
}

View File

@ -16,10 +16,11 @@ import PluginManager from "./pluginmanager";
// import PublicServers from "./publicservers";
import ThemeManager from "./thememanager";
import Settings from "./settingsmanager";
import DOMManager from "./dommanager";
export const React = DiscordModules.React;
export const ReactDOM = DiscordModules.ReactDOM;
export {BDV2, BdApi, Core, ContentManager, DataStore,
Events, PluginManager, /*PublicServers,*/ ThemeManager,
Events, PluginManager, DOMManager, ThemeManager,
Utilities, WebpackModules, DiscordModules, Settings};

View File

@ -1,6 +1,7 @@
import Utilities from "./utilities";
import WebpackModules, {DiscordModules} from "./webpackmodules";
import DataStore from "./datastore";
import DOMManager from "./dommanager";
import {Toasts, Modals} from "ui";
const BdApi = {
@ -44,13 +45,15 @@ BdApi.setWindowPreference = function(key, value) {
//id = id of element
//css = custom css
BdApi.injectCSS = function (id, css) {
$("head").append($("<style>", {id: Utilities.escapeID(id), text: css}));
DOMManager.injectStyle(Utilities.escapeID(id), css);
// $("head").append($("<style>", {id: Utilities.escapeID(id), text: css}));
};
//Clear css/remove any element
//id = id of element
BdApi.clearCSS = function (id) {
$("#" + Utilities.escapeID(id)).remove();
DOMManager.removeStyle(Utilities.escapeID(id));
// $("#" + Utilities.escapeID(id)).remove();
};
//Inject CSS to document head

View File

@ -66,8 +66,8 @@ export default new class SettingsManager {
const collection = this.collections[c];
const categories = this.collections[c].settings;
if (!this.state[collection.id]) this.state[collection.id] = {};
for (let s = 0; s < categories.length; s++) {
const category = categories[s];
for (let cc = 0; cc < categories.length; cc++) {
const category = categories[cc];
if (category.type != "category") {if (!this.state[collection.id].hasOwnProperty(category.id)) this.state[collection.id][category.id] = category.value;}
else {
if (!this.state[collection.id].hasOwnProperty(category.id)) this.state[collection.id][category.id] = {};

View File

@ -3,6 +3,7 @@ import ContentManager from "./contentmanager";
import Utilities from "./utilities";
import {Modals} from "ui";
import Settings from "./settingsmanager";
import DOMManager from "./dommanager";
import {SettingsPanel as SettingsRenderer} from "ui";
const path = require("path");
@ -54,17 +55,19 @@ export default new class ThemeManager extends ContentManager {
addTheme(idOrContent) {
const content = typeof(idOrContent) == "string" ? this.contentList.find(p => p.id == idOrContent) : idOrContent;
if (!content) return;
const style = document.createElement("style");
style.id = Utilities.escapeID(content.id);
style.textContent = unescape(content.css);
document.head.append(style);
content.element = style;
// const style = document.createElement("style");
// style.id = Utilities.escapeID(content.id);
// style.textContent = unescape(content.css);
// document.head.append(style);
// content.element = style;
DOMManager.injectTheme(Utilities.escapeID(content.id), unescape(content.css));
}
removeTheme(idOrContent) {
const content = typeof(idOrContent) == "string" ? this.contentList.find(p => p.id == idOrContent) : idOrContent;
if (!content) return;
const element = content.element || document.getElementById(Utilities.escapeID(content.id));
if (element) element.remove();
// const element = content.element || document.getElementById(Utilities.escapeID(content.id));
// if (element) element.remove();
DOMManager.removeTheme(Utilities.escapeID(content.id));
}
};

View File

@ -47,7 +47,7 @@ export default class Utilities {
}
static escapeID(id) {
return id.replace(/^[^a-z]+|[^\w-]+/gi, "");
return id.replace(/^[^a-z]+|[^\w-]+/gi, "-");
}
static log(moduleName, message) {

View File

@ -369,9 +369,9 @@ export default class WebpackModules {
if (this._require) return this._require;
const id = "bbd-webpackmodules";
const __webpack_require__ = typeof(window.webpackJsonp) == "function" ? window.webpackJsonp([], {
[id]: (module, exports, __webpack_require__) => exports.default = __webpack_require__
[id]: (module, exports, __internal_require__) => exports.default = __internal_require__
}, [id]).default : window.webpackJsonp.push([[], {
[id]: (module, exports, __webpack_require__) => module.exports = __webpack_require__
[id]: (module, exports, __internal_require__) => module.exports = __internal_require__
}, [[id]]]);
delete __webpack_require__.m[id];
delete __webpack_require__.c[id];

6
src/structs/screen.js Normal file
View File

@ -0,0 +1,6 @@
export default class Screen {
/** Document/window width */
static get width() { return Math.max(document.documentElement.clientWidth, window.innerWidth || 0); }
/** Document/window height */
static get height() { return Math.max(document.documentElement.clientHeight, window.innerHeight || 0); }
}

View File

@ -13,6 +13,9 @@ export default class CssEditor extends React.Component {
constructor(props) {
super(props);
this.hasUnsavedChanges = false;
this.onChange = this.onChange.bind(this);
this.toggleLiveUpdate = this.toggleLiveUpdate.bind(this);
this.updateCss = this.updateCss.bind(this);
this.saveCss = this.saveCss.bind(this);
@ -43,14 +46,27 @@ export default class CssEditor extends React.Component {
this.editor.value = newCSS;
}
get value() {return this.editor.session.getValue();}
set value(newValue) {
this.editor.setValue(newValue);
}
showSettings() {return this.editor.keyBinding.$defaultHandler.commands.showSettingsMenu.exec(this.editor);}
resize() {return this.editor.resize();}
setEditorRef(editor) {
this.editor = editor;
if (this.props.editorRef && typeof(this.props.editorRef.current) !== "undefined") this.props.editorRef.current = editor;
else if (this.props.editorRef) this.props.editorRef = editor;
}
onChange() {
this.hasUnsavedChanges = true;
if (this.props.onChange) this.props.onChange(...arguments);
}
render() {
return <Editor ref={this.setEditorRef.bind(this)} readOnly={this.props.readOnly} id={this.props.id || "bd-customcss-editor"} onChange={this.props.onChange} controls={this.controls} value={this.props.css} />;
return <Editor ref={this.setEditorRef.bind(this)} readOnly={this.props.readOnly} id={this.props.id || "bd-customcss-editor"} onChange={this.onChange} controls={this.controls} value={this.props.css} />;
}
toggleLiveUpdate(checked) {
@ -62,6 +78,7 @@ export default class CssEditor extends React.Component {
}
saveCss(event, newCss) {
this.hasUnsavedChanges = false;
if (this.props.save) this.props.save(newCss);
}

View File

@ -1,7 +1,7 @@
import {BDV2, DiscordModules, Settings} from "modules";
import {BDV2, Settings, React} from "modules";
import EmoteMenu from "../builtins/emotemenu";
export default class BDEmote extends DiscordModules.React.Component {
export default class BDEmote extends React.Component {
constructor(props) {
super(props);
@ -43,26 +43,26 @@ export default class BDEmote extends DiscordModules.React.Component {
}
render() {
return DiscordModules.React.createElement(BDV2.TooltipWrapper, {
return React.createElement(BDV2.TooltipWrapper, {
color: "black",
position: "top",
text: this.label,
delay: 750
},
DiscordModules.React.createElement("div", {
React.createElement("div", {
className: "emotewrapper" + (this.props.jumboable ? " jumboable" : ""),
onMouseEnter: this.onMouseEnter,
onMouseLeave: this.onMouseLeave,
onClick: this.onClick
},
DiscordModules.React.createElement("img", {
React.createElement("img", {
draggable: false,
className: "emote" + this.modifierClass + (this.props.jumboable ? " jumboable" : "") + (!this.state.shouldAnimate ? " stop-animation" : ""),
dataModifier: this.props.modifier,
alt: this.label,
src: this.props.url
}),
DiscordModules.React.createElement("input", {
React.createElement("input", {
className: "fav" + (this.state.isFavorite ? " active" : ""),
title: "Favorite!",
type: "button",

View File

@ -11,7 +11,8 @@ class FloatingWindowContainer extends React.Component {
render() {
return this.state.windows.map(window =>
<FloatingWindow onResize={window.onResize} close={this.close.bind(this, window.id)} title={window.title} id={window.id} height={window.height} width={window.width} center={window.center} resizable={window.resizable}>
// <FloatingWindow onResize={window.onResize} close={this.close.bind(this, window.id)} title={window.title} id={window.id} height={window.height} width={window.width} center={window.center} resizable={window.resizable}>
<FloatingWindow {...window} close={this.close.bind(this, window.id)}>
{window.children}
</FloatingWindow>
);

View File

@ -1,22 +1,16 @@
import {React} from "modules";
import Screen from "../../structs/screen";
import CloseButton from "../icons/close";
class Screen {
/** Document/window width */
static get width() { return Math.max(document.documentElement.clientWidth, window.innerWidth || 0); }
/** Document/window height */
static get height() { return Math.max(document.documentElement.clientHeight, window.innerHeight || 0); }
}
import Modals from "../modals";
export default class FloatingWindow extends React.Component {
constructor(props) {
super(props);
this.props.forceTheme = "dont-transform";
this.state = {modalOpen: false};
// this.state = {x: 0, y: 0};
this.offX = 0;
this.offY = 0;
@ -31,15 +25,6 @@ export default class FloatingWindow extends React.Component {
}
componentDidMount() {
if (this.props.isPopout) {
// console.log(this);
const popout = this._reactInternalFiber.return.return.return.return.stateNode;//_reactInternalFiber.return.return.return.return.stateNode
setImmediate(() => {
document.removeEventListener("click", popout.close, true);
if (!this.props.close) this.props.close = popout.close;
});
}
this.window.current.addEventListener("mousedown", this.onResizeStart, false);
this.titlebar.current.addEventListener("mousedown", this.onDragStart, false);
document.addEventListener("mouseup", this.onDragStop, false);
@ -51,8 +36,6 @@ export default class FloatingWindow extends React.Component {
}
onDragStop() {
// e.preventDefault();
// e.stopPropagation();
document.removeEventListener("mousemove", this.onDrag, true);
if (this.props.onResize) {
const width = this.window.current.style.width;
@ -64,19 +47,13 @@ export default class FloatingWindow extends React.Component {
}
onDragStart(e) {
// e.preventDefault();
// e.stopPropagation();
const div = this.window.current;
// console.log(div.offsetTop, div.offsetLeft);
this.offY = e.clientY - parseInt(div.offsetTop);
this.offX = e.clientX - parseInt(div.offsetLeft);
document.addEventListener("mousemove", this.onDrag, true);
}
onDrag(e) {
// e.preventDefault();
// e.stopPropagation();
const div = this.window.current;
div.style.position = "fixed";
div.style.top = (e.clientY - this.offY) + "px";
@ -92,7 +69,7 @@ export default class FloatingWindow extends React.Component {
const top = this.props.center ? (Screen.height / 2) - (this.props.height / 2) : this.props.top;
const left = this.props.center ? (Screen.width / 2) - (this.props.width / 2) : this.props.left ;
// console.log(top, left);
const className = `floating-window ${this.props.className || ""} ${this.props.resizable ? "resizable" : ""}`;
const className = `floating-window${` ${this.props.className}` || ""}${this.props.resizable ? " resizable" : ""}${this.state.modalOpen ? " modal-open" : ""}`;
const styles = {height: this.props.height, width: this.props.width, left: left || 0, top: top || 0};
return <div id={this.props.id} className={className} ref={this.window} style={styles}>
<div className="floating-window-titlebar" ref={this.titlebar}>
@ -109,68 +86,25 @@ export default class FloatingWindow extends React.Component {
</div>;
}
close() {
// console.log("click close");
if (this.props.close) this.props.close();
async close() {
let shouldClose = true;
const confirmClose = typeof(this.props.confirmClose) == "function" ? this.props.confirmClose() : this.props.confirmClose;
if (confirmClose) {
this.setState({modalOpen: true});
shouldClose = await this.confirmClose();
this.setState({modalOpen: false});
}
if (this.props.close && shouldClose) this.props.close();
}
}
//target, props (with render), key, event
// function addListeners(){
// document.getElementById('test').addEventListener('mousedown', mouseDown, false);
// window.addEventListener('mouseup', mouseUp, false);
// }
// function mouseUp()
// {
// window.removeEventListener('mousemove', divMove, true);
// }
// function mouseDown(e){
// var div = document.getElementById('test');
// offY= e.clientY-parseInt(div.offsetTop);
// offX= e.clientX-parseInt(div.offsetLeft);
// window.addEventListener('mousemove', divMove, true);
// }
// function divMove(e){
// var div = document.getElementById('test');
// div.style.position = 'absolute';
// div.style.top = (e.clientY-offY) + 'px';
// div.style.left = (e.clientX-offX) + 'px';
// }
// const test = {
// animationType: "default",
// arrowAlignment: "top",
// backdrop: false,
// clickPos: 74,
// closeOnScroll: false,
// containerClass: undefined,
// dependsOn: undefined,
// forceTheme: undefined,
// key: "floating-window",
// offsetX: 15,
// offsetY: 0,
// position: "left",
// preventCloseFromModal: false,
// preventClickPropagation: true,
// preventInvert: false,
// render: function() {
// console.log(arguments);
// return DiscordModules.React.createElement("div", Object.assign({}, arguments[0], {className: "testme", id: "test"}));
// },
// shadow: false,
// showArrow: false,
// target: $("div.memberOnline-1CIh-0.member-3W1lQa.da-memberOnline.da-member")[0],
// targetHeight: 40,
// targetWidth: 224,
// x: 1211,
// y: 357,
// zIndexBoost: 0
// }
// modaltest = function() {
// console.log(arguments);
// return DiscordModules.React.createElement("div", Object.assign({}, arguments[0], {className: "testme", id: "test"}));
// }
confirmClose() {
return new Promise(resolve => {
Modals.showConfirmationModal("Are You Sure?", this.props.confirmationText, {
danger: true,
confirmText: "Close",
onConfirm: () => {resolve(true);},
onCancel: () => {resolve(false);}
});
});
}
}

View File

@ -69,8 +69,8 @@ export default class Modals {
if (!this.ModalStack || !this.ConfirmationModal || !this.TextElement) return this.alert(title, content);
const {onConfirm, onCancel, confirmText, cancelText, danger = false} = options;
if (typeof(content) == "string") content = TextElement({color: TextElement.Colors.PRIMARY, children: [content]});
else if (Array.isArray(content)) content = TextElement({color: TextElement.Colors.PRIMARY, children: content});
if (typeof(content) == "string") content = TextElement.default({color: TextElement.Colors.PRIMARY, children: [content]});
else if (Array.isArray(content)) content = TextElement.default({color: TextElement.Colors.PRIMARY, children: content});
content = [content];
const emptyFunction = () => {};

View File

@ -1,16 +1,26 @@
import {React, WebpackModules} from "modules";
import SidebarView from "./sidebarview";
import Tools from "./exitbutton";
import TabBar from "./tabbar";
import SettingsTitle from "../settings/title";
import ServerCard from "./card";
const AvatarDefaults = WebpackModules.getByProps("getUserAvatarURL", "DEFAULT_AVATARS");
const InviteActions = WebpackModules.getByProps("acceptInvite");
const SortedGuildStore = WebpackModules.getByProps("getSortedGuilds");
const SettingsView = WebpackModules.getByDisplayName("SettingsView");
//SettingsView
//onClose pop layer
//onSetSection dispatch user settings modal set section section subsection
//section selected one
//sections []
//theme dark
export default class PublicServers extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedCategory: -1,
selectedCategory: "All",
title: "Loading...",
loading: true,
servers: [],
@ -27,11 +37,6 @@ export default class PublicServers extends React.Component {
this.checkConnection = this.checkConnection.bind(this);
this.join = this.join.bind(this);
this.connect = this.connect.bind(this);
this.GuildStore = WebpackModules.getByProps("getGuilds");
this.AvatarDefaults = WebpackModules.getByProps("getUserAvatarURL", "DEFAULT_AVATARS");
this.InviteActions = WebpackModules.getByProps("acceptInvite");
this.SortedGuildStore = WebpackModules.getByProps("getSortedGuilds");
}
componentDidMount() {
@ -43,39 +48,39 @@ export default class PublicServers extends React.Component {
}
search(query, clear) {
const self = this;
$.ajax({
method: "GET",
url: `${self.endPoint}${query}${query ? "&schema=new" : "?schema=new"}`,
url: `${this.endPoint}${query}${query ? "&schema=new" : "?schema=new"}`,
success: data => {
let servers = data.results.reduce((arr, server) => {
server.joined = false;
arr.push(server);
// arr.push(<ServerCard server={server} join={self.join}/>);
// arr.push(<ServerCard server={server} join={this.join}/>);
return arr;
}, []);
if (!clear) {
servers = self.state.servers.concat(servers);
servers = this.state.servers.concat(servers);
}
else {
//servers.unshift(self.bdServer);
//servers.unshift(this.bdServer);
}
console.log(data);
let end = data.size + data.from;
data.next = `?from=${end}`;
if (self.state.term) data.next += `&term=${self.state.term}`;
if (self.state.selectedCategory) data.next += `&category=${self.categoryButtons[self.state.selectedCategory]}`;
if (this.state.term) data.next += `&term=${this.state.term}`;
if (this.state.selectedCategory) data.next += `&category=${this.state.selectedCategory}`;
if (end >= data.total) {
end = data.total;
data.next = null;
}
let title = `Showing 1-${end} of ${data.total} results in ${self.categoryButtons[self.state.selectedCategory]}`;
if (self.state.term) title += ` for ${self.state.term}`;
let title = `Showing 1-${end} of ${data.total} results in ${this.state.selectedCategory}`;
if (this.state.term) title += ` for ${this.state.term}`;
self.setState({
this.setState({
loading: false,
title: title,
servers: servers,
@ -83,12 +88,12 @@ export default class PublicServers extends React.Component {
});
if (clear) {
//console.log(self);
self.refs.sbv.refs.contentScroller.scrollTop = 0;
//console.log(this);
// this.refs.sbv.refs.contentScroller.scrollTop = 0;
}
},
error: () => {
self.setState({
this.setState({
loading: false,
title: "Failed to load servers. Check console for details"
});
@ -97,7 +102,7 @@ export default class PublicServers extends React.Component {
}
join(serverCard) {
if (serverCard.props.pinned) return this.InviteActions.acceptInvite(serverCard.props.invite_code);
if (serverCard.props.pinned) return InviteActions.acceptInvite(serverCard.props.invite_code);
$.ajax({
method: "GET",
url: `${this.joinEndPoint}/${serverCard.props.server.identifier}`,
@ -123,8 +128,8 @@ export default class PublicServers extends React.Component {
this.joinWindow = new (window.require("electron").remote.BrowserWindow)(options);
const url = "https://auth.discordservers.com/connect?scopes=guilds.join&previousUrl=https://auth.discordservers.com/info";
this.joinWindow.webContents.on("did-navigate", (event, url) => {
if (url != "https://auth.discordservers.com/info") return;
this.joinWindow.webContents.on("did-navigate", (event, navUrl) => {
if (navUrl != "https://auth.discordservers.com/info") return;
this.joinWindow.close();
this.checkConnection();
});
@ -162,8 +167,8 @@ export default class PublicServers extends React.Component {
invite_code: "0Tmfo5ZbORCRqbAd",
pinned: true
};
const guildList = this.SortedGuildStore.guildPositions;
const defaultList = this.AvatarDefaults.DEFAULT_AVATARS;
const guildList = SortedGuildStore.guildPositions;
const defaultList = AvatarDefaults.DEFAULT_AVATARS;
return React.createElement(ServerCard, {server: server, pinned: true, join: this.join, guildList: guildList, fallback: defaultList[Math.floor(Math.random() * 5)]});
}
@ -180,7 +185,6 @@ export default class PublicServers extends React.Component {
}
checkConnection() {
const self = this;
try {
$.ajax({
method: "GET",
@ -195,21 +199,21 @@ export default class PublicServers extends React.Component {
},
success: data => {
// Utils.log("PublicServer", "Got data: " + JSON.stringify(data));
self.setState({
selectedCategory: 0,
this.setState({
selectedCategory: "All",
connection: {
state: 2,
user: data
}
});
self.search("", true);
this.search("", true);
},
error: () => {
self.setState({
this.setState({
title: "Not connected to discordservers.com!",
loading: true,
selectedCategory: -1,
selectedCategory: "All",
connection: {
state: 1,
user: null
@ -219,10 +223,10 @@ export default class PublicServers extends React.Component {
});
}
catch (error) {
self.setState({
this.setState({
title: "Not connected to discordservers.com!",
loading: true,
selectedCategory: -1,
selectedCategory: "All",
connection: {
state: 1,
user: null
@ -231,8 +235,37 @@ export default class PublicServers extends React.Component {
}
}
//SettingsView
//onClose pop layer
//onSetSection dispatch user settings modal set section section subsection
//section selected one
//sections []
//theme dark
render() {
return React.createElement(SidebarView, {id: "pubslayer", ref: "sbv"}, this.component);
const categories = this.categoryButtons.map(name => {
const section = {
section: name,//.toLowerCase().replace(" ", "_"),
label: name
};
if (name == "All") section.element = () => this.content;
else section.onClick = () => this.changeCategory(name);
return section;
});
return React.createElement(SettingsView, {
onClose: this.close,
onSetSection: (e, ee, eee) => {console.log(e, ee, eee);this.changeCategory(e);},
section: this.state.selectedCategory,
sections: [
{section: "HEADER", label: "Public Servers"},
{section: "CUSTOM", element: () => this.searchInput},
{section: "HEADER", label: "Categories"},
...categories
],
theme: "dark"
});
// return React.createElement(StandardSidebarView, {id: "pubslayer", ref: "sbv", notice: null, theme: "dark", closeAction: this.close, content: this.content, sidebar: this.sidebar});
}
get component() {
@ -251,9 +284,6 @@ export default class PublicServers extends React.Component {
get sidebar() {
return React.createElement(
"div",
{className: "sidebar-CFHs9e da-sidebar sidebar", key: "ps"},
React.createElement(
"div",
{className: "ui-tab-bar SIDE"},
React.createElement(
@ -271,8 +301,7 @@ export default class PublicServers extends React.Component {
React.createElement(TabBar.Separator, null),
this.footer,
this.connection
)
);
);
}
get searchInput() {
@ -282,24 +311,23 @@ export default class PublicServers extends React.Component {
React.createElement(
"div",
{className: "ui-text-input flex-vertical", style: {width: "172px", marginLeft: "10px"}},
React.createElement("input", {ref: "searchinput", onKeyDown: this.searchKeyDown, onChange: () => {}, type: "text", className: "input default", placeholder: "Search...", maxLength: "50"})
React.createElement("input", {onKeyDown: this.searchKeyDown, onChange: () => {}, type: "text", className: "input default", placeholder: "Search...", maxLength: "50"})
)
);
}
searchKeyDown(e) {
const self = this;
if (self.state.loading || e.which !== 13) return;
self.setState({
if (this.state.loading || e.which !== 13) return;
this.setState({
loading: true,
title: "Loading...",
term: e.target.value
});
let query = `?term=${e.target.value}`;
if (self.state.selectedCategory !== 0) {
query += `&category=${self.categoryButtons[self.state.selectedCategory]}`;
if (this.state.selectedCategory !== 0) {
query += `&category=${this.state.selectedCategory}`;
}
self.search(query, true);
this.search(query, true);
}
get categoryButtons() {
@ -307,64 +335,54 @@ export default class PublicServers extends React.Component {
}
changeCategory(id) {
const self = this;
if (self.state.loading) return;
self.refs.searchinput.value = "";
self.setState({
if (this.state.loading) return;
// this.refs.searchinput.value = "";
this.setState({
loading: true,
selectedCategory: id,
title: "Loading...",
term: null
});
if (id === 0) {
self.search("", true);
this.search("", true);
return;
}
self.search(`?category=${self.categoryButtons[id]}`, true);
this.search(`?category=${this.state.selectedCategory.replace(" ", "%20")}`, true);
}
get content() {
const self = this;
const guildList = this.SortedGuildStore.guildPositions;
const defaultList = this.AvatarDefaults.DEFAULT_AVATARS;
if (self.state.connection.state === 1) return self.notConnected;
return [React.createElement(
"div",
{ref: "content", key: "pc", className: "contentColumn-2hrIYH contentColumnDefault-1VQkGM content-column default"},
React.createElement(SettingsTitle, {text: self.state.title}),
self.bdServer,
self.state.servers.map((server) => {
return React.createElement(ServerCard, {key: server.identifier, server: server, join: self.join, guildList: guildList, fallback: defaultList[Math.floor(Math.random() * 5)]});
const guildList = SortedGuildStore.guildPositions;
const defaultList = AvatarDefaults.DEFAULT_AVATARS;
if (this.state.connection.state === 1) return this.notConnected;
return [React.createElement(SettingsTitle, {text: this.state.title}),
this.state.selectedCategory == "All" && this.bdServer,
this.state.servers.map((server) => {
return React.createElement(ServerCard, {key: server.identifier, server: server, join: this.join, guildList: guildList, fallback: defaultList[Math.floor(Math.random() * 5)]});
}),
self.state.next && React.createElement(
this.state.next && React.createElement(
"button",
{type: "button", onClick: () => {
if (self.state.loading) return;self.setState({loading: true}); self.search(self.state.next, false);
if (this.state.loading) return;this.setState({loading: true}); this.search(this.state.next, false);
}, className: "ui-button filled brand small grow", style: {width: "100%", marginTop: "10px", marginBottom: "10px"}},
React.createElement(
"div",
{className: "ui-button-contents"},
self.state.loading ? "Loading" : "Load More"
this.state.loading ? "Loading" : "Load More"
)
),
self.state.servers.length > 0 && React.createElement(SettingsTitle, {text: self.state.title})
)];
this.state.servers.length > 0 && React.createElement(SettingsTitle, {text: this.state.title})];
}
get notConnected() {
const self = this;
//return React.createElement(SettingsTitle, { text: self.state.title });
//return React.createElement(SettingsTitle, { text: this.state.title });
return [React.createElement(
"div",
{key: "ncc", ref: "content", className: "contentColumn-2hrIYH contentColumnDefault-1VQkGM content-column default"},
React.createElement(
"h2",
{className: "ui-form-title h2 margin-reset margin-bottom-20"},
"Not connected to discordservers.com!",
React.createElement(
"button",
{
onClick: self.connect,
onClick: this.connect,
type: "button",
className: "ui-button filled brand small grow",
style: {
@ -380,8 +398,7 @@ export default class PublicServers extends React.Component {
"Connect"
)
)
), self.bdServer
)];
), this.bdServer];
}
get footer() {
@ -397,8 +414,7 @@ export default class PublicServers extends React.Component {
}
get connection() {
const self = this;
const {connection} = self.state;
const {connection} = this.state;
if (connection.state !== 2) return React.createElement("span", null);
return React.createElement(
@ -419,7 +435,7 @@ export default class PublicServers extends React.Component {
{style: {width: "100%", minHeight: "20px"}, type: "button", className: "ui-button filled brand small grow"},
React.createElement(
"div",
{className: "ui-button-contents", onClick: self.connect},
{className: "ui-button-contents", onClick: this.connect},
"Reconnect"
)
)

View File

@ -45,11 +45,11 @@ export default class PluginCard extends React.Component {
return (eTop < cTop || eBottom > cBottom);
};
const self = $(this.panelRef.current);
const container = self.parents(".scroller-2FKFPG");
if (!isHidden(container[0], self[0])) return;
const panel = $(this.panelRef.current);
const container = panel.parents(".scroller-2FKFPG");
if (!isHidden(container[0], panel[0])) return;
container.animate({
scrollTop: self.offset().top - container.offset().top + container.scrollTop() - 30
scrollTop: panel.offset().top - container.offset().top + container.scrollTop() - 30
}, 300);
}
}
@ -59,7 +59,6 @@ export default class PluginCard extends React.Component {
}
render() {
const self = this;
const {content} = this.props;
const name = this.getString(content.name);
const author = this.getString(content.author);
@ -69,7 +68,7 @@ export default class PluginCard extends React.Component {
const source = content.source;
if (this.state.settingsOpen) {
try { self.settingsPanel = content.plugin.getSettingsPanel(); }
try { this.settingsPanel = content.plugin.getSettingsPanel(); }
catch (err) { Utilities.err("Plugins", "Unable to get settings panel for " + content.name + ".", err); }
const props = {id: `plugin-settings-${name}`, className: "plugin-settings", ref: this.panelRef};
@ -78,7 +77,7 @@ export default class PluginCard extends React.Component {
return React.createElement("li", {className: "settings-open ui-switch-item"},
React.createElement("div", {style: {"float": "right", "cursor": "pointer"}, onClick: () => {
this.panelRef.current.innerHTML = "";
self.setState({settingsOpen: false});
this.setState({settingsOpen: false});
}},
React.createElement(CloseButton, null)
),