BetterDiscordApp-rauenzi/renderer/src/ui/addonerrormodal.jsx

122 lines
4.4 KiB
JavaScript

import {React, Strings, WebpackModules} from "modules";
import DownArrow from "./icons/downarrow";
import Extension from "./icons/extension";
import ThemeIcon from "./icons/theme";
const Parser = Object(WebpackModules.getByProps("defaultRules", "parse")).defaultRules;
const joinClassNames = (...classNames) => classNames.filter(e => e).join(" ");
class Collapse extends React.Component {
constructor(props) {
super(props);
this.state = {opened: false};
}
toggle() {
if (!this.props.error.stack) return;
this.setState({opened: !this.state.opened});
}
render() {
const title = this.props.error.error ? this.props.error.message : this.props.error.message;
const stack = this.props.error.error && this.props.error.error.stack;
return <div className={joinClassNames("bd-addon-error-stack", this.state.opened && "opened")}>
<div onClick={() => {this.toggle();}} className="bd-addon-error-stack-header">
{!this.state.opened && title}
{stack
? <>
<DownArrow />
{this.state.opened && <div className="bd-addon-error-stack-shown">{Parser ? Parser.codeBlock.react({content: stack, lang: "js"}, null, {}) : stack}</div>}
</>
: null}
</div>
</div>;
}
}
export default class AddonErrorModal extends React.Component {
constructor(props) {
super(props);
const tabs = this.getTabs();
this.state = {
selectedTab: tabs[0].id
};
}
mergeErrors(errors1 = [], errors2 = []) {
const list = [];
const allErrors = [...errors2, ...errors1];
for (const error of allErrors) {
if (list.find(e => e.file === error.file)) continue;
list.push(error);
}
return list;
}
refreshTabs(pluginErrors, themeErrors) {
this._tabs = null;
this.props.pluginErrors = this.mergeErrors(this.props.pluginErrors, pluginErrors);
this.props.themeErrors = this.mergeErrors(this.props.themeErrors, themeErrors);
this.forceUpdate();
}
generateTab(id, errors) {
return {
id: id,
name: Strings.Panels[id],
errors: errors
};
}
getTabs() {
return this._tabs || (this._tabs = [
this.props.pluginErrors.length && this.generateTab("plugins", this.props.pluginErrors),
this.props.themeErrors.length && this.generateTab("themes", this.props.themeErrors)
].filter(e => e));
}
renderError(err) {
return <div className="bd-addon-error">
<div className="bd-addon-error-header">
{err.type == "plugin" ? <Extension /> : <ThemeIcon />}
<div className="bd-addon-error-message">{err.name} - {err.message}</div>
</div>
<div className="bd-addon-error-body">
<Collapse error={err} message={err.message} />
</div>
</div>;
}
switchToTab(id) {
this.setState({selectedTab: id});
}
render() {
const selectedTab = this.getTabs().find(e => this.state.selectedTab === e.id);
const tabs = this.getTabs();
return <div className="bd-modal bd-content-modal modal-1UGdnR">
<div className="bd-modal-inner inner-1JeGVc">
<div className="header header-1R_AjF"><div className="title">{Strings.Modals.addonErrors}</div></div>
<div className="bd-modal-body">
<div className="tab-bar-container">
<div className="tab-bar TOP">
{tabs.map(tab => <div onClick={() => {this.switchToTab(tab.id);}} className={joinClassNames("tab-bar-item", tab.id === selectedTab.id && "selected")}>{tab.name}</div>)}
</div>
</div>
<div className="scroller-wrap fade">
<div className="scroller">
{selectedTab.errors.map(error => this.renderError(error))}
</div>
</div>
</div>
<div className="footer footer-2yfCgX footer-3rDWdC footer-2gL1pp">
<button type="button" onClick={() => {this.props.onClose();}} className="bd-button">{Strings.Modals.okay}</button>
</div>
</div>
</div>;
}
}