Convert various remaining components
This commit is contained in:
parent
717c9026f4
commit
001a50e762
|
@ -3,24 +3,19 @@ import Extension from "./icons/extension";
|
|||
import ThemeIcon from "./icons/theme";
|
||||
import Divider from "./divider";
|
||||
|
||||
|
||||
const Parser = Object(WebpackModules.getByProps("defaultRules", "parse")).defaultRules;
|
||||
const {useState, useCallback, useMemo} = React;
|
||||
|
||||
const joinClassNames = (...classNames) => classNames.filter(e => e).join(" ");
|
||||
|
||||
class AddonError extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
function AddonError({err, index}) {
|
||||
const [expanded, setExpanded] = useState(false);
|
||||
const toggle = useCallback(() => setExpanded(!expanded), [expanded]);
|
||||
|
||||
this.state = {
|
||||
expanded: false
|
||||
};
|
||||
}
|
||||
toggle() {
|
||||
this.setState({expanded: !this.state.expanded});
|
||||
}
|
||||
renderErrorBody(err) {
|
||||
function renderErrorBody() {
|
||||
const stack = err?.error?.stack ?? err.stack;
|
||||
if (!this.state.expanded || !stack) return null;
|
||||
if (!expanded || !stack) return null;
|
||||
return <div className="bd-addon-error-body">
|
||||
<Divider />
|
||||
<div className="bd-addon-error-stack">
|
||||
|
@ -28,92 +23,57 @@ class AddonError extends React.Component {
|
|||
</div>
|
||||
</div>;
|
||||
}
|
||||
render() {
|
||||
const err = this.props.err;
|
||||
return <div key={`${err.type}-${this.props.index}`} className={joinClassNames("bd-addon-error", (this.state.expanded) ? "expanded" : "collapsed")}>
|
||||
<div className="bd-addon-error-header" onClick={() => {this.toggle();}} >
|
||||
<div className="bd-addon-error-icon">
|
||||
{err.type == "plugin" ? <Extension /> : <ThemeIcon />}
|
||||
</div>
|
||||
<div className="bd-addon-error-header-inner">
|
||||
<h3 className={`bd-addon-error-file ${DiscordClasses.Text.colorHeaderPrimary} ${DiscordClasses.Integrations.secondaryHeader} ${DiscordClasses.Text.size16}`}>{err.name}</h3>
|
||||
<div className={`bd-addon-error-details ${DiscordClasses.Integrations.detailsWrapper}`}>
|
||||
<svg className={DiscordClasses.Integrations.detailsIcon} aria-hidden="false" width="16" height="16" viewBox="0 0 12 12">
|
||||
<path fill="currentColor" d="M6 1C3.243 1 1 3.244 1 6c0 2.758 2.243 5 5 5s5-2.242 5-5c0-2.756-2.243-5-5-5zm0 2.376a.625.625 0 110 1.25.625.625 0 010-1.25zM7.5 8.5h-3v-1h1V6H5V5h1a.5.5 0 01.5.5v2h1v1z"></path>
|
||||
</svg>
|
||||
<div className={`${DiscordClasses.Text.colorHeaderSecondary} ${DiscordClasses.Text.size12}`}>{err.message}</div>
|
||||
</div>
|
||||
</div>
|
||||
<svg className="bd-addon-error-expander" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" d="M7 10L12 15 17 10" aria-hidden="true"></path>
|
||||
</svg>
|
||||
|
||||
return <div key={`${err.type}-${index}`} className={joinClassNames("bd-addon-error", (expanded) ? "expanded" : "collapsed")}>
|
||||
<div className="bd-addon-error-header" onClick={toggle} >
|
||||
<div className="bd-addon-error-icon">
|
||||
{err.type == "plugin" ? <Extension /> : <ThemeIcon />}
|
||||
</div>
|
||||
{this.renderErrorBody(err)}
|
||||
</div>;
|
||||
}
|
||||
<div className="bd-addon-error-header-inner">
|
||||
<h3 className={`bd-addon-error-file ${DiscordClasses.Text.colorHeaderPrimary} ${DiscordClasses.Integrations.secondaryHeader} ${DiscordClasses.Text.size16}`}>{err.name}</h3>
|
||||
<div className={`bd-addon-error-details ${DiscordClasses.Integrations.detailsWrapper}`}>
|
||||
<svg className={DiscordClasses.Integrations.detailsIcon} aria-hidden="false" width="16" height="16" viewBox="0 0 12 12">
|
||||
<path fill="currentColor" d="M6 1C3.243 1 1 3.244 1 6c0 2.758 2.243 5 5 5s5-2.242 5-5c0-2.756-2.243-5-5-5zm0 2.376a.625.625 0 110 1.25.625.625 0 010-1.25zM7.5 8.5h-3v-1h1V6H5V5h1a.5.5 0 01.5.5v2h1v1z"></path>
|
||||
</svg>
|
||||
<div className={`${DiscordClasses.Text.colorHeaderSecondary} ${DiscordClasses.Text.size12}`}>{err.message}</div>
|
||||
</div>
|
||||
</div>
|
||||
<svg className="bd-addon-error-expander" width="24" height="24" viewBox="0 0 24 24">
|
||||
<path fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" d="M7 10L12 15 17 10" aria-hidden="true"></path>
|
||||
</svg>
|
||||
</div>
|
||||
{renderErrorBody(err)}
|
||||
</div>;
|
||||
}
|
||||
|
||||
export default class AddonErrorModal extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const tabs = this.getTabs();
|
||||
|
||||
this.state = {
|
||||
selectedTab: tabs[0].id,
|
||||
};
|
||||
}
|
||||
function generateTab(id, errors) {
|
||||
return {id, errors, name: Strings.Panels[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;
|
||||
}
|
||||
export default function AddonErrorModal({pluginErrors, themeErrors}) {
|
||||
const tabs = useMemo(() => {
|
||||
return [
|
||||
pluginErrors.length && generateTab("plugins", pluginErrors),
|
||||
themeErrors.length && generateTab("themes", themeErrors)
|
||||
].filter(e => e);
|
||||
}, [pluginErrors, themeErrors]);
|
||||
|
||||
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();
|
||||
}
|
||||
const [tabId, setTab] = useState(tabs[0].id);
|
||||
const switchToTab = useCallback((id) => setTab(id), [tabId]);
|
||||
const selectedTab = tabs.find(e => e.id === tabId);
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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-error-modal-header ${DiscordClasses.Modal.header} ${DiscordClasses.Modal.separator}`}>
|
||||
<h4 className={`${DiscordClasses.Titles.defaultColor} ${DiscordClasses.Text.size14} ${DiscordClasses.Titles.h4} ${DiscordClasses.Margins.marginBottom8}`}>{Strings.Modals.addonErrors}</h4>
|
||||
<div className="bd-tab-bar">
|
||||
{tabs.map(tab => <div onClick={() => {this.switchToTab(tab.id);}} className={joinClassNames("bd-tab-item", tab.id === selectedTab.id && "selected")}>{tab.name}</div>)}
|
||||
</div>
|
||||
return <>
|
||||
<div className={`bd-error-modal-header ${DiscordClasses.Modal.header} ${DiscordClasses.Modal.separator}`}>
|
||||
<h4 className={`${DiscordClasses.Titles.defaultColor} ${DiscordClasses.Text.size14} ${DiscordClasses.Titles.h4} ${DiscordClasses.Margins.marginBottom8}`}>{Strings.Modals.addonErrors}</h4>
|
||||
<div className="bd-tab-bar">
|
||||
{tabs.map(tab => <div onClick={() => {switchToTab(tab.id);}} className={joinClassNames("bd-tab-item", tab.id === selectedTab.id && "selected")}>{tab.name}</div>)}
|
||||
</div>
|
||||
<div className={`bd-error-modal-content ${DiscordClasses.Modal.content} ${DiscordClasses.Scrollers.thin}`}>
|
||||
<div className="bd-addon-errors">
|
||||
{selectedTab.errors.map((error, index) => <AddonError index={index} err={error} />)}
|
||||
</div>
|
||||
</div>
|
||||
<div className={`bd-error-modal-content ${DiscordClasses.Modal.content} ${DiscordClasses.Scrollers.thin}`}>
|
||||
<div className="bd-addon-errors">
|
||||
{selectedTab.errors.map((error, index) => <AddonError index={index} err={error} />)}
|
||||
</div>
|
||||
</>;
|
||||
}
|
||||
</div>
|
||||
</>;
|
||||
}
|
|
@ -1,70 +1,62 @@
|
|||
import {React, Strings} from "modules";
|
||||
|
||||
const badge = <div className="flowerStarContainer-3zDVtj verified-1eC5dy background-2uufRq guildBadge-RlDbED"
|
||||
style={{width: "16px", height: "16px"}}>
|
||||
<svg aria-label="Verified & Partnered" className="flowerStar-1GeTsn"
|
||||
aria-hidden="false" width="16" height="16" viewBox="0 0 16 15.2">
|
||||
<path fill="currentColor" fillRule="evenodd"
|
||||
d="m16 7.6c0 .79-1.28 1.38-1.52 2.09s.44 2 0 2.59-1.84.35-2.46.8-.79 1.84-1.54 2.09-1.67-.8-2.47-.8-1.75 1-2.47.8-.92-1.64-1.54-2.09-2-.18-2.46-.8.23-1.84 0-2.59-1.54-1.3-1.54-2.09 1.28-1.38 1.52-2.09-.44-2 0-2.59 1.85-.35 2.48-.8.78-1.84 1.53-2.12 1.67.83 2.47.83 1.75-1 2.47-.8.91 1.64 1.53 2.09 2 .18 2.46.8-.23 1.84 0 2.59 1.54 1.3 1.54 2.09z">
|
||||
</path>
|
||||
</svg>
|
||||
<div className="childContainer-1wxZNh">
|
||||
<svg className="icon-1ihkOt" aria-hidden="false" width="16" height="16" viewBox="0 0 16 15.2">
|
||||
<path d="M7.4,11.17,4,8.62,5,7.26l2,1.53L10.64,4l1.36,1Z" fill="currentColor"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>;
|
||||
const {useState, useCallback, useMemo} = React;
|
||||
|
||||
export default class ServerCard extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
if (!this.props.server.iconUrl) this.props.server.iconUrl = this.props.defaultAvatar();
|
||||
this.state = {
|
||||
joined: this.props.joined
|
||||
};
|
||||
this.join = this.join.bind(this);
|
||||
this.handleError = this.handleError.bind(this);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {server} = this.props;
|
||||
const addedDate = new Date(server.insertDate * 1000); // Convert from unix timestamp
|
||||
const buttonText = typeof(this.state.joined) == "string" ? `${Strings.PublicServers.joining}...` : this.state.joined ? Strings.PublicServers.joined : Strings.PublicServers.join;
|
||||
|
||||
return <div className="bd-server-card" role="button" tabIndex="0" onClick={this.join}>
|
||||
<div className="bd-server-header">
|
||||
<div className="bd-server-splash-container"><img src={server.iconUrl} onError={this.handleError} className="bd-server-splash" /></div>
|
||||
<img src={server.iconUrl} onError={this.handleError} className="bd-server-icon" />
|
||||
</div>
|
||||
<div className="bd-server-info">
|
||||
<div className="bd-server-title">
|
||||
{server.pinned && badge}
|
||||
<div className="bd-server-name">{server.name}</div>
|
||||
{this.state.joined && <div className="bd-server-tag">{buttonText}</div>}
|
||||
</div>
|
||||
<div className="bd-server-description">{server.description}</div>
|
||||
<div className="bd-server-footer">
|
||||
<div className="bd-server-count">
|
||||
<div className="bd-server-count-dot"></div>
|
||||
<div className="bd-server-count-text">{server.members.toLocaleString()} Members</div>
|
||||
</div>
|
||||
<div className="bd-server-count">
|
||||
<div className="bd-server-count-dot"></div>
|
||||
<div className="bd-server-count-text">Added {addedDate.toLocaleDateString()}</div>
|
||||
</div>
|
||||
</div>
|
||||
const badge = <div className="flowerStarContainer-1QeD-L verified-1Jv_7P background-3Da2vZ rowIcon-2tDEcE" style={{width: "16px", height: "16px"}}>
|
||||
<svg aria-label="Verified & Partnered" className="flowerStar-2tNFCR" aria-hidden="false" width="16" height="16" viewBox="0 0 16 15.2">
|
||||
<path fill="currentColor" fillRule="evenodd" d="m16 7.6c0 .79-1.28 1.38-1.52 2.09s.44 2 0 2.59-1.84.35-2.46.8-.79 1.84-1.54 2.09-1.67-.8-2.47-.8-1.75 1-2.47.8-.92-1.64-1.54-2.09-2-.18-2.46-.8.23-1.84 0-2.59-1.54-1.3-1.54-2.09 1.28-1.38 1.52-2.09-.44-2 0-2.59 1.85-.35 2.48-.8.78-1.84 1.53-2.12 1.67.83 2.47.83 1.75-1 2.47-.8.91 1.64 1.53 2.09 2 .18 2.46.8-.23 1.84 0 2.59 1.54 1.3 1.54 2.09z"></path>
|
||||
</svg>
|
||||
<div className="childContainer-U_a6Yh">
|
||||
<svg className="icon-3BYlXK" aria-hidden="false" width="16" height="16" viewBox="0 0 16 15.2">
|
||||
<path d="M7.4,11.17,4,8.62,5,7.26l2,1.53L10.64,4l1.36,1Z" fill="currentColor"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
|
||||
handleError() {
|
||||
this.props.server.iconUrl = this.props.defaultAvatar();
|
||||
}
|
||||
|
||||
async join() {
|
||||
if (this.state.joined) return this.props.navigateTo(this.props.server.identifier);
|
||||
this.setState({joined: "joining"});
|
||||
const didJoin = await this.props.join(this.props.server.identifier, this.props.server.nativejoin);
|
||||
this.setState({joined: didJoin});
|
||||
}
|
||||
export default function ServerCard({server, joined, join, navigateTo, defaultAvatar}) {
|
||||
const [isError, setError] = useState(false);
|
||||
const handleError = useCallback(() => {
|
||||
setError(true);
|
||||
}, []);
|
||||
|
||||
const [hasJoined, setJoined] = useState(joined);
|
||||
const doJoin = useCallback(async () => {
|
||||
if (hasJoined) return navigateTo(server.identifier);
|
||||
setJoined("joining");
|
||||
const didJoin = await join(server.identifier, server.nativeJoin);
|
||||
setJoined(didJoin);
|
||||
}, [hasJoined]);
|
||||
|
||||
const defaultIcon = useMemo(() => defaultAvatar(), []);
|
||||
const currentIcon = !server.iconUrl || isError ? defaultIcon : server.iconUrl;
|
||||
|
||||
const addedDate = new Date(server.insertDate * 1000); // Convert from unix timestamp
|
||||
const buttonText = typeof(hasJoined) == "string" ? `${Strings.PublicServers.joining}...` : hasJoined ? Strings.PublicServers.joined : Strings.PublicServers.join;
|
||||
|
||||
return <div className="bd-server-card" role="button" tabIndex="0" onClick={doJoin}>
|
||||
<div className="bd-server-header">
|
||||
<div className="bd-server-splash-container"><img src={currentIcon} onError={handleError} className="bd-server-splash" /></div>
|
||||
<img src={currentIcon} onError={handleError} className="bd-server-icon" />
|
||||
</div>
|
||||
<div className="bd-server-info">
|
||||
<div className="bd-server-title">
|
||||
{server.pinned && badge}
|
||||
<div className="bd-server-name">{server.name}</div>
|
||||
{hasJoined && <div className="bd-server-tag">{buttonText}</div>}
|
||||
</div>
|
||||
<div className="bd-server-description">{server.description}</div>
|
||||
<div className="bd-server-footer">
|
||||
<div className="bd-server-count">
|
||||
<div className="bd-server-count-dot"></div>
|
||||
<div className="bd-server-count-text">{server.members.toLocaleString()} Members</div>
|
||||
</div>
|
||||
<div className="bd-server-count">
|
||||
<div className="bd-server-count-dot"></div>
|
||||
<div className="bd-server-count-text">Added {addedDate.toLocaleDateString()}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>;
|
||||
}
|
|
@ -7,6 +7,8 @@ import Toasts from "./toasts";
|
|||
|
||||
import Checkmark from "./icons/check";
|
||||
|
||||
const {useState, useCallback, useEffect} = React;
|
||||
|
||||
function CoreUpdaterPanel(props) {
|
||||
return <Drawer name="BetterDiscord" collapsible={true}>
|
||||
<SettingItem name={`Core v${Config.version}`} note={props.hasUpdate ? Strings.Updater.versionAvailable.format({version: props.remoteVersion}) : Strings.Updater.noUpdatesAvailable} inline={true} id={"core-updater"}>
|
||||
|
@ -37,88 +39,72 @@ function AddonUpdaterPanel(props) {
|
|||
</Drawer>;
|
||||
}
|
||||
|
||||
export default class UpdaterPanel extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
export default function UpdaterPanel(props) {
|
||||
const [hasCoreUpdate, setCoreUpdate] = useState(props.coreUpdater.hasUpdate);
|
||||
const [updates, setUpdates] = useState({plugins: props.pluginUpdater.pending.slice(0), themes: props.themeUpdater.pending.slice(0)});
|
||||
|
||||
this.state = {
|
||||
hasCoreUpdate: this.props.coreUpdater.hasUpdate,
|
||||
plugins: this.props.pluginUpdater.pending.slice(0),
|
||||
themes: this.props.themeUpdater.pending.slice(0)
|
||||
};
|
||||
|
||||
this.checkForUpdates = this.checkForUpdates.bind(this);
|
||||
this.updateAddon = this.updateAddon.bind(this);
|
||||
this.updateCore = this.updateCore.bind(this);
|
||||
this.updateAllAddons = this.updateAllAddons.bind(this);
|
||||
this.update = this.update.bind(this);
|
||||
}
|
||||
|
||||
update() {
|
||||
this.checkAddons("plugins");
|
||||
this.checkAddons("themes");
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
Events.on(`plugin-loaded`, this.update);
|
||||
Events.on(`plugin-unloaded`, this.update);
|
||||
Events.on(`theme-loaded`, this.update);
|
||||
Events.on(`theme-unloaded`, this.update);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
Events.off(`plugin-loaded`, this.update);
|
||||
Events.off(`plugin-unloaded`, this.update);
|
||||
Events.off(`theme-loaded`, this.update);
|
||||
Events.off(`theme-unloaded`, this.update);
|
||||
}
|
||||
|
||||
async checkForUpdates() {
|
||||
Toasts.info(Strings.Updater.checking);
|
||||
await this.checkCoreUpdate();
|
||||
await this.checkAddons("plugins");
|
||||
await this.checkAddons("themes");
|
||||
Toasts.info(Strings.Updater.finishedChecking);
|
||||
}
|
||||
|
||||
async checkCoreUpdate() {
|
||||
await this.props.coreUpdater.checkForUpdate(false);
|
||||
this.setState({hasCoreUpdate: this.props.coreUpdater.hasUpdate});
|
||||
}
|
||||
|
||||
async updateCore() {
|
||||
await this.props.coreUpdater.update();
|
||||
this.setState({hasCoreUpdate: false});
|
||||
}
|
||||
|
||||
async checkAddons(type) {
|
||||
const updater = type === "plugins" ? this.props.pluginUpdater : this.props.themeUpdater;
|
||||
const checkAddons = useCallback(async (type) => {
|
||||
const updater = type === "plugins" ? props.pluginUpdater : props.themeUpdater;
|
||||
await updater.checkAll(false);
|
||||
this.setState({[type]: updater.pending.slice(0)});
|
||||
}
|
||||
setUpdates({...updates, [type]: updater.pending.slice(0)});
|
||||
}, []);
|
||||
|
||||
async updateAddon(type, filename) {
|
||||
const updater = type === "plugins" ? this.props.pluginUpdater : this.props.themeUpdater;
|
||||
const update = useCallback(() => {
|
||||
checkAddons("plugins");
|
||||
checkAddons("themes");
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
Events.on(`plugin-loaded`, update);
|
||||
Events.on(`plugin-unloaded`, update);
|
||||
Events.on(`theme-loaded`, update);
|
||||
Events.on(`theme-unloaded`, update);
|
||||
return () => {
|
||||
Events.off(`plugin-loaded`, update);
|
||||
Events.off(`plugin-unloaded`, update);
|
||||
Events.off(`theme-loaded`, update);
|
||||
Events.off(`theme-unloaded`, update);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const checkCoreUpdate = useCallback(async () => {
|
||||
await props.coreUpdater.checkForUpdate(false);
|
||||
setCoreUpdate(props.coreUpdater.hasUpdate);
|
||||
}, []);
|
||||
|
||||
const checkForUpdates = useCallback(async () => {
|
||||
Toasts.info(Strings.Updater.checking);
|
||||
await checkCoreUpdate();
|
||||
await checkAddons("plugins");
|
||||
await checkAddons("themes");
|
||||
Toasts.info(Strings.Updater.finishedChecking);
|
||||
});
|
||||
|
||||
const updateCore = useCallback(async () => {
|
||||
await props.coreUpdater.update();
|
||||
setCoreUpdate(false);
|
||||
}, []);
|
||||
|
||||
const updateAddon = useCallback(async (type, filename) => {
|
||||
const updater = type === "plugins" ? props.pluginUpdater : props.themeUpdater;
|
||||
await updater.updateAddon(filename);
|
||||
this.setState(prev => {
|
||||
setUpdates(prev => {
|
||||
prev[type].splice(prev[type].indexOf(filename), 1);
|
||||
return prev;
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
async updateAllAddons(type) {
|
||||
const toUpdate = this.state[type].slice(0);
|
||||
const updateAllAddons = useCallback(async (type) => {
|
||||
const toUpdate = updates[type].slice(0);
|
||||
for (const filename of toUpdate) {
|
||||
await this.updateAddon(type, filename);
|
||||
await updateAddon(type, filename);
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
render() {
|
||||
return [
|
||||
<SettingsTitle text={Strings.Panels.updates} button={{title: Strings.Updater.checkForUpdates, onClick: this.checkForUpdates}} />,
|
||||
<CoreUpdaterPanel remoteVersion={this.props.coreUpdater.remoteVersion} hasUpdate={this.state.hasCoreUpdate} update={this.updateCore} />,
|
||||
<AddonUpdaterPanel type="plugins" pending={this.state.plugins} update={this.updateAddon} updateAll={this.updateAllAddons} updater={this.props.pluginUpdater} />,
|
||||
<AddonUpdaterPanel type="themes" pending={this.state.themes} update={this.updateAddon} updateAll={this.updateAllAddons} updater={this.props.themeUpdater} />,
|
||||
];
|
||||
}
|
||||
return [
|
||||
<SettingsTitle text={Strings.Panels.updates} button={{title: Strings.Updater.checkForUpdates, onClick: checkForUpdates}} />,
|
||||
<CoreUpdaterPanel remoteVersion={props.coreUpdater.remoteVersion} hasUpdate={hasCoreUpdate} update={updateCore} />,
|
||||
<AddonUpdaterPanel type="plugins" pending={updates.plugins} update={updateAddon} updateAll={updateAllAddons} updater={props.pluginUpdater} />,
|
||||
<AddonUpdaterPanel type="themes" pending={updates.themes} update={updateAddon} updateAll={updateAllAddons} updater={props.themeUpdater} />,
|
||||
];
|
||||
}
|
Loading…
Reference in New Issue