mirror of
https://github.com/mue/mue.git
synced 2026-07-16 21:44:22 +02:00
refactor: Convert pure components to functional components
Co-authored-by: David Ralph <me@davidcralph.co.uk> Co-authored-by: Isaac <contact@eartharoid.me>
This commit is contained in:
@@ -15,6 +15,7 @@ import { FileUpload, Text, Switch, Dropdown } from 'components/Form/Settings';
|
||||
import { ResetModal, Button } from 'components/Elements';
|
||||
|
||||
import { Header, Section, Row, Content, Action } from 'components/Layout/Settings';
|
||||
import { useTab } from 'components/Elements/MainModal/backend/TabContext';
|
||||
|
||||
import time_zones from 'features/time/timezones.json';
|
||||
|
||||
@@ -22,6 +23,7 @@ function AdvancedOptions() {
|
||||
const [resetModal, setResetModal] = useState(false);
|
||||
const [data, setData] = useState(false);
|
||||
const ADVANCED_SECTION = 'modals.main.settings.sections.advanced';
|
||||
const { subSection } = useTab();
|
||||
|
||||
const Data = () => {
|
||||
return localStorage.getItem('welcomePreview') !== 'true' ? (
|
||||
@@ -93,7 +95,7 @@ function AdvancedOptions() {
|
||||
return (
|
||||
<>
|
||||
{header}
|
||||
{data ? (
|
||||
{subSection === "data" ? (
|
||||
<>
|
||||
<Data />
|
||||
<Modal
|
||||
@@ -110,6 +112,7 @@ function AdvancedOptions() {
|
||||
) : (
|
||||
<>
|
||||
<Section
|
||||
id="data"
|
||||
title={variables.getMessage(`${ADVANCED_SECTION}.data`)}
|
||||
subtitle={variables.getMessage(`${ADVANCED_SECTION}.data_subtitle`)}
|
||||
onClick={() => setData(true)}
|
||||
|
||||
@@ -4,6 +4,7 @@ import variables from 'config/variables';
|
||||
|
||||
import { Checkbox, Dropdown, Radio, Slider, Text } from 'components/Form/Settings';
|
||||
import { Header, Section, Row, Content, Action } from 'components/Layout/Settings';
|
||||
import { useTab } from 'components/Elements/MainModal/backend/TabContext';
|
||||
|
||||
import { MdAccessibility } from 'react-icons/md';
|
||||
|
||||
@@ -11,6 +12,7 @@ import values from 'utils/data/slider_values.json';
|
||||
|
||||
function AppearanceOptions() {
|
||||
const [accessibility, setAccessibility] = useState(false);
|
||||
const { subSection } = useTab();
|
||||
|
||||
const ThemeSelection = () => {
|
||||
return (
|
||||
@@ -262,11 +264,12 @@ function AppearanceOptions() {
|
||||
return (
|
||||
<>
|
||||
{header}
|
||||
{accessibility ? (
|
||||
{subSection === "accessibility" ? (
|
||||
<AccessibilityOptions />
|
||||
) : (
|
||||
<>
|
||||
<Section
|
||||
id="accessibility"
|
||||
title={variables.getMessage(
|
||||
'modals.main.settings.sections.appearance.accessibility.title',
|
||||
)}
|
||||
|
||||
@@ -1,56 +1,27 @@
|
||||
import variables from 'config/variables';
|
||||
import { PureComponent, createRef } from 'react';
|
||||
import { useState, createRef, useEffect } from 'react';
|
||||
import Markdown from 'markdown-to-jsx';
|
||||
import { MdOutlineWifiOff } from 'react-icons/md';
|
||||
|
||||
class Changelog extends PureComponent {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
title: null,
|
||||
};
|
||||
this.offlineMode = localStorage.getItem('offlineMode') === 'true';
|
||||
this.controller = new AbortController();
|
||||
this.changelog = createRef();
|
||||
}
|
||||
function Changelog() {
|
||||
const [title, setTitle] = useState(null);
|
||||
const [error, setError] = useState(false);
|
||||
const [content, setContent] = useState(null);
|
||||
const [date, setDate] = useState(null);
|
||||
|
||||
parseMarkdown = (text) => {
|
||||
if (typeof text !== 'string') {
|
||||
throw new Error('Input must be a string');
|
||||
}
|
||||
const offlineMode = localStorage.getItem('offlineMode') === 'true';
|
||||
const controller = new AbortController();
|
||||
const changelog = createRef();
|
||||
|
||||
// Replace markdown syntax
|
||||
text = text
|
||||
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
|
||||
.replace(/^## (.*$)/gm, '<span class="title">$1</span>')
|
||||
.replace(
|
||||
/((http|https):\/\/[^\s]+)/g,
|
||||
'<a href="$1" target="_blank" rel="noopener noreferrer">$1</a>',
|
||||
)
|
||||
// resolve @ to github user link
|
||||
.replace(
|
||||
/@([a-zA-Z0-9-_]+)/g,
|
||||
'<a href="https://github.com/$1" target="_blank" class="changelogAt">@$1</a>',
|
||||
);
|
||||
|
||||
// Replace list items
|
||||
text = text.replace(/^\* (.*$)/gm, '<li>$1</li>');
|
||||
|
||||
// Wrap list items in <ul></ul>
|
||||
text = text.replace(/((<li>.*<\/li>\s*)+)/g, '<ul>$1</ul>');
|
||||
|
||||
return text;
|
||||
};
|
||||
|
||||
async getUpdate() {
|
||||
const getUpdate = async () => {
|
||||
const releases = await fetch(
|
||||
`https://api.github.com/repos/${variables.constants.ORG_NAME}/${variables.constants.REPO_NAME}/releases`,
|
||||
{
|
||||
signal: this.controller.signal,
|
||||
signal: controller.signal,
|
||||
},
|
||||
);
|
||||
|
||||
if (this.controller.signal.aborted === true) {
|
||||
if (controller.signal.aborted === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -63,92 +34,88 @@ class Changelog extends PureComponent {
|
||||
}
|
||||
|
||||
// request the changelog
|
||||
const res = await fetch(release.url, { signal: this.controller.signal });
|
||||
const res = await fetch(release.url, { signal: controller.signal });
|
||||
|
||||
if (res.status === 404) {
|
||||
this.setState({ error: true });
|
||||
setError(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.controller.signal.aborted === true) {
|
||||
if (controller.signal.aborted === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
const changelog = await res.json();
|
||||
this.setState({
|
||||
title: changelog.name,
|
||||
content: changelog.body,
|
||||
date: new Date(changelog.published_at).toLocaleDateString(),
|
||||
});
|
||||
setTitle(changelog.name);
|
||||
setContent(changelog.body);
|
||||
setDate(new Date(changelog.published_at).toLocaleDateString());
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (navigator.onLine === false || this.offlineMode) {
|
||||
useEffect(() => {
|
||||
if (navigator.onLine === false || offlineMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.getUpdate();
|
||||
}
|
||||
getUpdate();
|
||||
}, []);
|
||||
|
||||
componentWillUnmount() {
|
||||
useEffect(() => {
|
||||
// stop making requests
|
||||
this.controller.abort();
|
||||
}
|
||||
|
||||
render() {
|
||||
const errorMessage = (msg) => {
|
||||
return (
|
||||
<div className="emptyItems">
|
||||
<div className="emptyMessage">{msg}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
if (navigator.onLine === false || this.offlineMode) {
|
||||
return errorMessage(
|
||||
<>
|
||||
<MdOutlineWifiOff />
|
||||
<h1>{variables.getMessage('modals.main.marketplace.offline.title')}</h1>
|
||||
<p className="description">
|
||||
{variables.getMessage('modals.main.marketplace.offline.description')}
|
||||
</p>
|
||||
</>,
|
||||
);
|
||||
}
|
||||
|
||||
if (this.state.error === true) {
|
||||
return errorMessage(
|
||||
<>
|
||||
<MdOutlineWifiOff />
|
||||
<span className="title">{variables.getMessage('modals.main.error_boundary.title')}</span>
|
||||
<span className="subtitle">
|
||||
{variables.getMessage('modals.main.error_boundary.message')}
|
||||
</span>
|
||||
</>,
|
||||
);
|
||||
}
|
||||
|
||||
if (!this.state.title) {
|
||||
return errorMessage(
|
||||
<div className="loaderHolder">
|
||||
<div id="loader"></div>
|
||||
<span className="subtitle">{variables.getMessage('modals.main.loading')}</span>
|
||||
</div>,
|
||||
);
|
||||
}
|
||||
return () => controller.abort();
|
||||
}, []);
|
||||
|
||||
const errorMessage = (msg) => {
|
||||
return (
|
||||
<article className="changelogtab prose dark:prose-invert" ref={this.changelog}>
|
||||
<div className="not-prose">
|
||||
<span className="mainTitle">{this.state.title}</span>
|
||||
<span className="subtitle">Released on {this.state.date}</span>
|
||||
</div>
|
||||
<Markdown options={{ overrides: { a: { props: { target: '_blank' } } } }}>
|
||||
{this.state.content}
|
||||
</Markdown>
|
||||
</article>
|
||||
<div className="emptyItems">
|
||||
<div className="emptyMessage">{msg}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
if (navigator.onLine === false || offlineMode) {
|
||||
return errorMessage(
|
||||
<>
|
||||
<MdOutlineWifiOff />
|
||||
<h1>{variables.getMessage('modals.main.marketplace.offline.title')}</h1>
|
||||
<p className="description">
|
||||
{variables.getMessage('modals.main.marketplace.offline.description')}
|
||||
</p>
|
||||
</>,
|
||||
);
|
||||
}
|
||||
|
||||
if (error === true) {
|
||||
return errorMessage(
|
||||
<>
|
||||
<MdOutlineWifiOff />
|
||||
<span className="title">{variables.getMessage('modals.main.error_boundary.title')}</span>
|
||||
<span className="subtitle">
|
||||
{variables.getMessage('modals.main.error_boundary.message')}
|
||||
</span>
|
||||
</>,
|
||||
);
|
||||
}
|
||||
|
||||
if (!title) {
|
||||
return errorMessage(
|
||||
<div className="loaderHolder">
|
||||
<div id="loader"></div>
|
||||
<span className="subtitle">{variables.getMessage('modals.main.loading')}</span>
|
||||
</div>,
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<article className="changelogtab prose dark:prose-invert" ref={changelog}>
|
||||
<div className="not-prose">
|
||||
<span className="mainTitle">{title}</span>
|
||||
<span className="subtitle">Released on {date}</span>
|
||||
</div>
|
||||
<Markdown options={{ overrides: { a: { props: { target: '_blank' } } } }}>
|
||||
{content}
|
||||
</Markdown>
|
||||
</article>
|
||||
);
|
||||
}
|
||||
|
||||
export { Changelog as default, Changelog };
|
||||
|
||||
@@ -29,6 +29,7 @@ const SortableItem = sortableElement(({ value }) => (
|
||||
</li>
|
||||
));
|
||||
|
||||
|
||||
const SortableContainer = sortableContainer(({ children }) => (
|
||||
<ul className="sortableContainer">{children}</ul>
|
||||
));
|
||||
|
||||
Reference in New Issue
Block a user