diff --git a/src/ErrorBoundary.jsx b/src/ErrorBoundary.jsx new file mode 100644 index 00000000..202f4e85 --- /dev/null +++ b/src/ErrorBoundary.jsx @@ -0,0 +1,23 @@ +import React, { Component } from 'react'; + +class ErrorBoundary extends Component { + constructor(props) { + super(props); + this.state = { hasError: false }; + } + + componentDidCatch(error, errorInfo) { + this.setState({ hasError: true }); + console.error('Error boundary caught an error:', error, errorInfo); + } + + render() { + if (this.state.hasError) { + return
Mue has broken horribly
; + } + + return this.props.children; + } +} + +export default ErrorBoundary; diff --git a/src/components/modals/main/marketplace/Item.jsx b/src/components/modals/main/marketplace/Item.jsx index 5a1d847d..0f2d1202 100644 --- a/src/components/modals/main/marketplace/Item.jsx +++ b/src/components/modals/main/marketplace/Item.jsx @@ -18,6 +18,8 @@ import { } from 'react-icons/md'; import Modal from 'react-modal'; +import Header from '../settings/Header'; + import { install, uninstall } from 'modules/helpers/marketplace'; import ShareModal from 'components/helpers/sharemodal/ShareModal'; @@ -104,14 +106,12 @@ class Item extends PureComponent { modalClose={() => this.setState({ shareModal: false })} /> -
- - - {variables.getMessage('modals.main.navbar.marketplace')} - - {this.props.data.data.display_name} - -
+
{this.props.data.data.photos && ( diff --git a/src/components/modals/main/marketplace/sections/Added.jsx b/src/components/modals/main/marketplace/sections/Added.jsx index a0343994..442c5ac2 100644 --- a/src/components/modals/main/marketplace/sections/Added.jsx +++ b/src/components/modals/main/marketplace/sections/Added.jsx @@ -9,6 +9,7 @@ import FileUpload from '../../settings/FileUpload'; import Item from '../Item'; import Items from '../Items'; import Dropdown from '../../settings/Dropdown'; +import Header from '../../settings/Header'; import { install, uninstall, urlParser } from 'modules/helpers/marketplace'; @@ -70,6 +71,19 @@ export default class Added extends PureComponent { variables.stats.postEvent('marketplace', 'Sideload'); } + getSideloadButton() { + return ( + + ); + } + toggle(type, data) { if (type === 'item') { const installed = JSON.parse(localStorage.getItem('installed')); @@ -193,18 +207,9 @@ export default class Added extends PureComponent { if (this.state.installed.length === 0) { return ( <> -
- {variables.getMessage('modals.main.navbar.addons')} - {sideLoadBackendElements()} - -
+
+ {this.getSideloadButton()} +
@@ -232,7 +237,7 @@ export default class Added extends PureComponent { return ( <> -
+
{variables.getMessage('modals.main.addons.added')}
{sideLoadBackendElements()} diff --git a/src/components/modals/main/marketplace/sections/Marketplace.jsx b/src/components/modals/main/marketplace/sections/Marketplace.jsx index 1121c6f1..04c9821d 100644 --- a/src/components/modals/main/marketplace/sections/Marketplace.jsx +++ b/src/components/modals/main/marketplace/sections/Marketplace.jsx @@ -13,6 +13,7 @@ import { import Item from '../Item'; import Items from '../Items'; import Dropdown from '../../settings/Dropdown'; +import Header from '../../settings/Header'; import { install, urlParser, uninstall } from 'modules/helpers/marketplace'; @@ -325,15 +326,12 @@ class Marketplace extends PureComponent { <> {this.state.collection === true ? ( <> -
- this.returnToMain()}> - - {variables.getMessage('modals.main.navbar.marketplace')} - - {' '} - {variables.getMessage('modals.main.marketplace.collection')} - -
+
this.returnToMain()} + />
{ + const [setting, setSetting] = useState(localStorage.getItem(props.setting) === 'true'); -class Header extends PureComponent { - constructor(props) { - super(props); - this.state = { - [this.props.setting]: localStorage.getItem(this.props.setting) === 'true', - }; - } + useEffect(() => { + setSetting(localStorage.getItem(props.setting) === 'true'); + }, [props.setting]); - changeSetting() { - if (localStorage.getItem(this.props.setting) === 'true') { - localStorage.setItem(this.props.setting, false); - this.setState({ [this.props.setting]: false }); - EventBus.emit('toggle', this.props.setting); - } else { - localStorage.setItem(this.props.setting, true); - this.setState({ [this.props.setting]: true }); - EventBus.emit('toggle', this.props.setting); - } + const changeSetting = () => { + const toggle = localStorage.getItem(props.setting) === 'true'; + localStorage.setItem(props.setting, !toggle); + setSetting(!toggle); variables.stats.postEvent( 'setting', - `${this.props.name} ${this.state.checked === true ? 'enabled' : 'disabled'}`, + `${props.name} ${setting === true ? 'enabled' : 'disabled'}`, ); - if (this.props.element) { - if (!document.querySelector(this.props.element)) { + EventBus.emit('toggle', props.setting); + + if (props.element) { + if (!document.querySelector(props.element)) { document.querySelector('.reminder-info').style.display = 'flex'; return localStorage.setItem('showReminder', true); } } - EventBus.emit('refresh', this.props.category); - } + EventBus.emit('refresh', props.category); + }; - render() { + const VisibilityToggle = () => ( + + ); + + const ReportButton = () => { return ( - <> -
- {this.props.backButton && ( -
- - - -
- )} - {this.props.title} -
- {this.props.switch && ( - - )} - -
-
- + ); - } -} + }; + + return ( + <> +
+ + {props.secondaryTitle ? ( + <> + + {props.title} + + + {props.secondaryTitle} + + ) : ( + <>{props.title} + )} + +
+ {props.switch && } + {props.report !== false && } + {props.children} +
+
+ + ); +}; export default Header; diff --git a/src/components/modals/main/settings/sections/Advanced.jsx b/src/components/modals/main/settings/sections/Advanced.jsx index e2226071..ea4f0666 100644 --- a/src/components/modals/main/settings/sections/Advanced.jsx +++ b/src/components/modals/main/settings/sections/Advanced.jsx @@ -17,6 +17,7 @@ import Text from '../Text'; import Switch from '../Switch'; import ResetModal from '../ResetModal'; import Dropdown from '../Dropdown'; +import Header from '../Header'; import { Row, Content, Action } from '../SettingsItem'; import Section from '../Section'; @@ -64,18 +65,15 @@ export default function AdvancedSettings() { let header; if (data) { header = ( - - setData(false)}> - {variables.getMessage(`${ADVANCED_SECTION}.title`)} - - - {variables.getMessage(`${ADVANCED_SECTION}.data`)} - +
setData(false)} + report={false} + /> ); } else { - header = ( - {variables.getMessage(`${ADVANCED_SECTION}.title`)} - ); + header =
; } return ( diff --git a/src/components/modals/main/settings/sections/Appearance.jsx b/src/components/modals/main/settings/sections/Appearance.jsx index 8bbe84c1..c51947ac 100644 --- a/src/components/modals/main/settings/sections/Appearance.jsx +++ b/src/components/modals/main/settings/sections/Appearance.jsx @@ -7,6 +7,7 @@ import Dropdown from '../Dropdown'; import Radio from '../Radio'; import Slider from '../Slider'; import Text from '../Text'; +import Header from '../Header'; import { Row, Content, Action } from '../SettingsItem'; @@ -234,20 +235,21 @@ function AppearanceSettings() { let header; if (accessibility) { header = ( - - setAccessibility(false)}> - {variables.getMessage('modals.main.settings.sections.appearance.title')} - - - {variables.getMessage('modals.main.settings.sections.appearance.accessibility.title')} - +
setAccessibility(false)} + report={false} + /> ); } else { header = ( - - {' '} - {variables.getMessage('modals.main.settings.sections.appearance.title')} - +
); } return ( diff --git a/src/components/modals/main/settings/sections/Language.jsx b/src/components/modals/main/settings/sections/Language.jsx index d215edca..4de0b07c 100644 --- a/src/components/modals/main/settings/sections/Language.jsx +++ b/src/components/modals/main/settings/sections/Language.jsx @@ -69,7 +69,7 @@ export default class LanguageSettings extends PureComponent { render() { return ( <> -
+
{variables.getMessage('modals.main.settings.sections.language.title')} diff --git a/src/components/modals/main/settings/sections/Quote.jsx b/src/components/modals/main/settings/sections/Quote.jsx index 77d396e2..1fa6dd7a 100644 --- a/src/components/modals/main/settings/sections/Quote.jsx +++ b/src/components/modals/main/settings/sections/Quote.jsx @@ -247,11 +247,14 @@ export default class QuoteSettings extends PureComponent { return ( <> {this.state.sourceSection ? ( - this.setState({ sourceSection: false })}> - {variables.getMessage(`${QUOTE_SECTION}.title`)} - {' '} - {variables.getMessage('modals.main.settings.sections.background.source.title')} - +
this.setState({ sourceSection: false })} + report={false} + /> ) : (
this.setState({ effects: false })}> - - {variables.getMessage('modals.main.settings.sections.background.title')} - - {' '} - {variables.getMessage('modals.main.settings.sections.background.effects.title')} - +
this.setState({ effects: false })} + /> ); } else if (this.state.backgroundSettingsSection === true) { header = ( - this.setState({ backgroundSettingsSection: false })} - > - - {variables.getMessage('modals.main.settings.sections.background.title')}{' '} - - {' '} - {variables.getMessage('modals.main.settings.sections.background.source.title')} - +
this.setState({ backgroundSettingsSection: false })} + /> ); } else { header = ( diff --git a/src/components/modals/main/tabs/backend/Tabs.jsx b/src/components/modals/main/tabs/backend/Tabs.jsx index abb401fa..631d2b97 100644 --- a/src/components/modals/main/tabs/backend/Tabs.jsx +++ b/src/components/modals/main/tabs/backend/Tabs.jsx @@ -75,48 +75,44 @@ class Tabs extends PureComponent { {reminderInfo}
- -
- - - -
- {this.props.children.map((tab) => { - if (tab.props.label !== this.state.currentTab) { - return undefined; +
+ + + +
+ {this.props.children.map((tab) => { + if (tab.props.label !== this.state.currentTab) { + return undefined; + } - return tab.props.children; - })} -
+ return {tab.props.children}; + })}
); diff --git a/src/index.jsx b/src/index.jsx index 8cc7ca83..717c7075 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -3,6 +3,7 @@ import { createRoot } from 'react-dom/client'; import * as Sentry from '@sentry/react'; import App from './App'; +import ErrorBoundary from './ErrorBoundary'; import variables from './modules/variables'; import './scss/index.scss'; @@ -27,4 +28,8 @@ Sentry.init({ const container = document.getElementById('root'); const root = createRoot(container); -root.render(); +root.render( + + + , +);