mirror of
https://github.com/mue/mue.git
synced 2026-07-16 21:44:22 +02:00
refactor: split quicklinks, move features to functional components
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import variables from 'config/variables';
|
||||
import { PureComponent } from 'react';
|
||||
import { useState, useEffect } from 'react';
|
||||
import Modal from 'react-modal';
|
||||
|
||||
import { MainModal } from 'components/Elements';
|
||||
@@ -11,28 +11,21 @@ import { parseDeepLink, shouldAutoOpenModal } from 'utils/deepLinking';
|
||||
|
||||
import Welcome from 'features/welcome/Welcome';
|
||||
|
||||
export default class Modals extends PureComponent {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
mainModal: false,
|
||||
updateModal: false,
|
||||
welcomeModal: false,
|
||||
appsModal: false,
|
||||
preview: false,
|
||||
deepLinkData: null,
|
||||
};
|
||||
}
|
||||
const Modals = () => {
|
||||
const [mainModal, setMainModal] = useState(false);
|
||||
const [updateModal, setUpdateModal] = useState(false);
|
||||
const [welcomeModal, setWelcomeModal] = useState(false);
|
||||
const [appsModal, setAppsModal] = useState(false);
|
||||
const [preview, setPreview] = useState(false);
|
||||
const [deepLinkData, setDeepLinkData] = useState(null);
|
||||
|
||||
componentDidMount() {
|
||||
useEffect(() => {
|
||||
// Check for deep link first (has priority)
|
||||
if (shouldAutoOpenModal()) {
|
||||
const deepLinkData = parseDeepLink();
|
||||
this.setState({
|
||||
mainModal: true,
|
||||
deepLinkData,
|
||||
});
|
||||
variables.stats.postEvent('modal', `Opened via deep link: ${deepLinkData.tab}`);
|
||||
const linkData = parseDeepLink();
|
||||
setMainModal(true);
|
||||
setDeepLinkData(linkData);
|
||||
variables.stats.postEvent('modal', `Opened via deep link: ${linkData.tab}`);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -40,9 +33,7 @@ export default class Modals extends PureComponent {
|
||||
localStorage.getItem('showWelcome') === 'true' &&
|
||||
window.location.search !== '?nointro=true'
|
||||
) {
|
||||
this.setState({
|
||||
welcomeModal: true,
|
||||
});
|
||||
setWelcomeModal(true);
|
||||
variables.stats.postEvent('modal', 'Opened welcome');
|
||||
}
|
||||
|
||||
@@ -56,71 +47,69 @@ export default class Modals extends PureComponent {
|
||||
|
||||
// hide refresh reminder once the user has refreshed the page
|
||||
localStorage.setItem('showReminder', false);
|
||||
}
|
||||
}, []);
|
||||
|
||||
closeWelcome() {
|
||||
const closeWelcome = () => {
|
||||
localStorage.setItem('showWelcome', false);
|
||||
this.setState({
|
||||
welcomeModal: false,
|
||||
});
|
||||
setWelcomeModal(false);
|
||||
EventBus.emit('refresh', 'widgetsWelcomeDone');
|
||||
EventBus.emit('refresh', 'widgets');
|
||||
EventBus.emit('refresh', 'backgroundwelcome');
|
||||
}
|
||||
};
|
||||
|
||||
previewWelcome() {
|
||||
const previewWelcome = () => {
|
||||
localStorage.setItem('showWelcome', false);
|
||||
localStorage.setItem('welcomePreview', true);
|
||||
this.setState({
|
||||
welcomeModal: false,
|
||||
preview: true,
|
||||
});
|
||||
setWelcomeModal(false);
|
||||
setPreview(true);
|
||||
EventBus.emit('refresh', 'widgetsWelcome');
|
||||
}
|
||||
};
|
||||
|
||||
toggleModal(type, action) {
|
||||
this.setState({
|
||||
[type]: action,
|
||||
});
|
||||
const toggleModal = (type, action) => {
|
||||
const modalSetters = {
|
||||
mainModal: setMainModal,
|
||||
updateModal: setUpdateModal,
|
||||
welcomeModal: setWelcomeModal,
|
||||
appsModal: setAppsModal,
|
||||
};
|
||||
|
||||
if (modalSetters[type]) {
|
||||
modalSetters[type](action);
|
||||
}
|
||||
|
||||
if (action !== false) {
|
||||
variables.stats.postEvent('modal', `Opened ${type.replace('Modal', '')}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<>
|
||||
{this.state.welcomeModal === false && (
|
||||
<Navbar openModal={(modal) => this.toggleModal(modal, true)} />
|
||||
)}
|
||||
<Modal
|
||||
closeTimeoutMS={300}
|
||||
id="modal"
|
||||
onRequestClose={() => this.toggleModal('mainModal', false)}
|
||||
isOpen={this.state.mainModal}
|
||||
className="Modal mainModal"
|
||||
overlayClassName="Overlay"
|
||||
ariaHideApp={false}
|
||||
>
|
||||
<MainModal
|
||||
modalClose={() => this.toggleModal('mainModal', false)}
|
||||
deepLinkData={this.state.deepLinkData}
|
||||
/>
|
||||
</Modal>
|
||||
<Modal
|
||||
closeTimeoutMS={300}
|
||||
onRequestClose={() => this.closeWelcome()}
|
||||
isOpen={this.state.welcomeModal}
|
||||
className="Modal welcomemodal mainModal"
|
||||
overlayClassName="Overlay mainModal"
|
||||
shouldCloseOnOverlayClick={false}
|
||||
ariaHideApp={false}
|
||||
>
|
||||
<Welcome modalClose={() => this.closeWelcome()} modalSkip={() => this.previewWelcome()} />
|
||||
</Modal>
|
||||
{this.state.preview && <Preview setup={() => window.location.reload()} />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<>
|
||||
{welcomeModal === false && <Navbar openModal={(modal) => toggleModal(modal, true)} />}
|
||||
<Modal
|
||||
closeTimeoutMS={300}
|
||||
id="modal"
|
||||
onRequestClose={() => toggleModal('mainModal', false)}
|
||||
isOpen={mainModal}
|
||||
className="Modal mainModal"
|
||||
overlayClassName="Overlay"
|
||||
ariaHideApp={false}
|
||||
>
|
||||
<MainModal modalClose={() => toggleModal('mainModal', false)} deepLinkData={deepLinkData} />
|
||||
</Modal>
|
||||
<Modal
|
||||
closeTimeoutMS={300}
|
||||
onRequestClose={() => closeWelcome()}
|
||||
isOpen={welcomeModal}
|
||||
className="Modal welcomemodal mainModal"
|
||||
overlayClassName="Overlay mainModal"
|
||||
shouldCloseOnOverlayClick={false}
|
||||
ariaHideApp={false}
|
||||
>
|
||||
<Welcome modalClose={() => closeWelcome()} modalSkip={() => previewWelcome()} />
|
||||
</Modal>
|
||||
{preview && <Preview setup={() => window.location.reload()} />}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export { Modals as default, Modals };
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
import variables from 'config/variables';
|
||||
import { PureComponent, createRef } from 'react';
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
import { MdOutlineWifiOff } from 'react-icons/md';
|
||||
import Modal from 'react-modal';
|
||||
|
||||
import Lightbox from '../../marketplace/components/Elements/Lightbox/Lightbox';
|
||||
|
||||
class Changelog extends PureComponent {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
title: null,
|
||||
showLightbox: false,
|
||||
lightboxImg: null,
|
||||
};
|
||||
this.offlineMode = localStorage.getItem('offlineMode') === 'true';
|
||||
this.controller = new AbortController();
|
||||
this.changelog = createRef();
|
||||
}
|
||||
const Changelog = () => {
|
||||
const [title, setTitle] = useState(null);
|
||||
const [content, setContent] = useState(null);
|
||||
const [date, setDate] = useState(null);
|
||||
const [image, setImage] = useState(null);
|
||||
const [error, setError] = useState(false);
|
||||
const [showLightbox, setShowLightbox] = useState(false);
|
||||
const [lightboxImg, setLightboxImg] = useState(null);
|
||||
|
||||
const offlineMode = localStorage.getItem('offlineMode') === 'true';
|
||||
const controllerRef = useRef(new AbortController());
|
||||
const changelog = useRef();
|
||||
|
||||
parseMarkdown = (text) => {
|
||||
const parseMarkdown = (text) => {
|
||||
if (typeof text !== 'string') {
|
||||
throw new Error('Input must be a string');
|
||||
}
|
||||
@@ -46,15 +46,15 @@ class Changelog extends PureComponent {
|
||||
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: controllerRef.current.signal,
|
||||
},
|
||||
);
|
||||
|
||||
if (this.controller.signal.aborted === true) {
|
||||
if (controllerRef.current.signal.aborted === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -67,109 +67,105 @@ class Changelog extends PureComponent {
|
||||
}
|
||||
|
||||
// request the changelog
|
||||
const res = await fetch(release.url, { signal: this.controller.signal });
|
||||
const res = await fetch(release.url, { signal: controllerRef.current.signal });
|
||||
|
||||
if (res.status === 404) {
|
||||
this.setState({ error: true });
|
||||
setError(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.controller.signal.aborted === true) {
|
||||
if (controllerRef.current.signal.aborted === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
const changelog = await res.json();
|
||||
this.setState({
|
||||
title: changelog.name,
|
||||
content: this.parseMarkdown(changelog.body),
|
||||
date: new Date(changelog.published_at).toLocaleDateString(),
|
||||
});
|
||||
}
|
||||
setTitle(changelog.name);
|
||||
setContent(parseMarkdown(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() {
|
||||
// stop making requests
|
||||
this.controller.abort();
|
||||
}
|
||||
|
||||
render() {
|
||||
const errorMessage = (msg) => {
|
||||
return (
|
||||
<div className="emptyItems">
|
||||
<div className="emptyMessage">{msg}</div>
|
||||
</div>
|
||||
);
|
||||
return () => {
|
||||
// stop making requests
|
||||
controllerRef.current.abort();
|
||||
};
|
||||
}, []);
|
||||
|
||||
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>,
|
||||
);
|
||||
}
|
||||
|
||||
const errorMessage = (msg) => {
|
||||
return (
|
||||
<div className="modalInfoPage changelogtab" ref={this.changelog}>
|
||||
<span className="mainTitle">{this.state.title}</span>
|
||||
<span className="subtitle">Released on {this.state.date}</span>
|
||||
{this.state.image && (
|
||||
<img
|
||||
draggable={false}
|
||||
src={this.state.image}
|
||||
alt={this.state.title}
|
||||
className="updateImage"
|
||||
/>
|
||||
)}
|
||||
<div className="updateChangelog" dangerouslySetInnerHTML={{ __html: this.state.content }} />
|
||||
<Modal
|
||||
closeTimeoutMS={100}
|
||||
onRequestClose={() => this.setState({ showLightbox: false })}
|
||||
isOpen={this.state.showLightbox}
|
||||
className="Modal lightBoxModal"
|
||||
overlayClassName="Overlay resetoverlay"
|
||||
ariaHideApp={false}
|
||||
>
|
||||
<Lightbox
|
||||
modalClose={() => this.setState({ showLightbox: false })}
|
||||
img={this.state.lightboxImg}
|
||||
/>
|
||||
</Modal>
|
||||
<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 (
|
||||
<div className="modalInfoPage changelogtab" ref={changelog}>
|
||||
<span className="mainTitle">{title}</span>
|
||||
<span className="subtitle">Released on {date}</span>
|
||||
{image && (
|
||||
<img
|
||||
draggable={false}
|
||||
src={image}
|
||||
alt={title}
|
||||
className="updateImage"
|
||||
/>
|
||||
)}
|
||||
<div className="updateChangelog" dangerouslySetInnerHTML={{ __html: content }} />
|
||||
<Modal
|
||||
closeTimeoutMS={100}
|
||||
onRequestClose={() => setShowLightbox(false)}
|
||||
isOpen={showLightbox}
|
||||
className="Modal lightBoxModal"
|
||||
overlayClassName="Overlay resetoverlay"
|
||||
ariaHideApp={false}
|
||||
>
|
||||
<Lightbox
|
||||
modalClose={() => setShowLightbox(false)}
|
||||
img={lightboxImg}
|
||||
/>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export { Changelog as default, Changelog };
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import variables from 'config/variables';
|
||||
import { PureComponent } from 'react';
|
||||
import { useState, useEffect, useRef } from 'react';
|
||||
|
||||
import { MdOutlineOpenInNew } from 'react-icons/md';
|
||||
|
||||
@@ -7,32 +7,28 @@ import { Radio } from 'components/Form/Settings';
|
||||
|
||||
import languages from '@/i18n/languages.json';
|
||||
|
||||
class LanguageOptions extends PureComponent {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
quoteLanguages: [
|
||||
{
|
||||
name: variables.getMessage('modals.main.loading'),
|
||||
value: 'loading',
|
||||
},
|
||||
],
|
||||
};
|
||||
this.controller = new AbortController();
|
||||
}
|
||||
const LanguageOptions = () => {
|
||||
const [quoteLanguages, setQuoteLanguages] = useState([
|
||||
{
|
||||
name: variables.getMessage('modals.main.loading'),
|
||||
value: 'loading',
|
||||
},
|
||||
]);
|
||||
|
||||
async getquoteLanguages() {
|
||||
const controllerRef = useRef(new AbortController());
|
||||
|
||||
const getquoteLanguages = async () => {
|
||||
const data = await (
|
||||
await fetch(variables.constants.API_URL + '/quotes/languages', {
|
||||
signal: this.controller.signal,
|
||||
signal: controllerRef.current.signal,
|
||||
})
|
||||
).json();
|
||||
|
||||
if (this.controller.signal.aborted === true) {
|
||||
if (controllerRef.current.signal.aborted === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
const quoteLanguages = data.map((language) => {
|
||||
const fetchedQuoteLanguages = data.map((language) => {
|
||||
return {
|
||||
name: languages.find((l) => l.value === language.name)
|
||||
? languages.find((l) => l.value === language.name).name
|
||||
@@ -41,69 +37,64 @@ class LanguageOptions extends PureComponent {
|
||||
};
|
||||
});
|
||||
|
||||
this.setState({
|
||||
quoteLanguages,
|
||||
});
|
||||
}
|
||||
setQuoteLanguages(fetchedQuoteLanguages);
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
useEffect(() => {
|
||||
if (navigator.onLine === false || localStorage.getItem('offlineMode') === 'true') {
|
||||
return this.setState({
|
||||
quoteLanguages: [
|
||||
{
|
||||
name: variables.getMessage('modals.main.marketplace.offline.description'),
|
||||
value: 'loading',
|
||||
},
|
||||
],
|
||||
});
|
||||
setQuoteLanguages([
|
||||
{
|
||||
name: variables.getMessage('modals.main.marketplace.offline.description'),
|
||||
value: 'loading',
|
||||
},
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
this.getquoteLanguages();
|
||||
}
|
||||
getquoteLanguages();
|
||||
|
||||
componentWillUnmount() {
|
||||
// stop making requests
|
||||
this.controller.abort();
|
||||
}
|
||||
return () => {
|
||||
// stop making requests
|
||||
controllerRef.current.abort();
|
||||
};
|
||||
}, []);
|
||||
|
||||
render() {
|
||||
return (
|
||||
<>
|
||||
<div className="modalHeader">
|
||||
<span className="mainTitle">
|
||||
{variables.getMessage('modals.main.settings.sections.language.title')}
|
||||
</span>
|
||||
<div className="headerActions">
|
||||
<a
|
||||
className="link"
|
||||
href="https://hosted.weblate.org/new-lang/mue/mue-tab/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Add translation
|
||||
<MdOutlineOpenInNew />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="languageSettings">
|
||||
<Radio name="language" options={languages} element=".other" />
|
||||
</div>
|
||||
return (
|
||||
<>
|
||||
<div className="modalHeader">
|
||||
<span className="mainTitle">
|
||||
{variables.getMessage('modals.main.settings.sections.language.quote')}
|
||||
{variables.getMessage('modals.main.settings.sections.language.title')}
|
||||
</span>
|
||||
<div className="languageSettings">
|
||||
<Radio
|
||||
name="quoteLanguage"
|
||||
options={this.state.quoteLanguages.map((language) => {
|
||||
return { name: language.name, value: language.value.name };
|
||||
})}
|
||||
defaultValue={this.state.quoteLanguages[0].name}
|
||||
category="quote"
|
||||
/>
|
||||
<div className="headerActions">
|
||||
<a
|
||||
className="link"
|
||||
href="https://hosted.weblate.org/new-lang/mue/mue-tab/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Add translation
|
||||
<MdOutlineOpenInNew />
|
||||
</a>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
</div>
|
||||
<div className="languageSettings">
|
||||
<Radio name="language" options={languages} element=".other" />
|
||||
</div>
|
||||
<span className="mainTitle">
|
||||
{variables.getMessage('modals.main.settings.sections.language.quote')}
|
||||
</span>
|
||||
<div className="languageSettings">
|
||||
<Radio
|
||||
name="quoteLanguage"
|
||||
options={quoteLanguages.map((language) => {
|
||||
return { name: language.name, value: language.value.name };
|
||||
})}
|
||||
defaultValue={quoteLanguages[0].name}
|
||||
category="quote"
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export { LanguageOptions as default, LanguageOptions };
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { PureComponent, Fragment, Suspense, lazy } from 'react';
|
||||
import { useState, useEffect, Fragment, Suspense, lazy, useMemo } from 'react';
|
||||
|
||||
import Clock from '../../time/Clock';
|
||||
import Greeting from '../../greeting/Greeting';
|
||||
@@ -17,74 +17,69 @@ import EventBus from 'utils/eventbus';
|
||||
// as seen here it is ridiculously large
|
||||
const Weather = lazy(() => import('../../weather/Weather'));
|
||||
|
||||
export default class Widgets extends PureComponent {
|
||||
online = localStorage.getItem('offlineMode') === 'false';
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
order: JSON.parse(localStorage.getItem('order')),
|
||||
welcome: localStorage.getItem('showWelcome'),
|
||||
};
|
||||
// widgets we can re-order
|
||||
this.widgets = {
|
||||
time: this.enabled('time') && <Clock />,
|
||||
greeting: this.enabled('greeting') && <Greeting />,
|
||||
quote: this.enabled('quote') && <Quote />,
|
||||
date: this.enabled('date') && <Date />,
|
||||
quicklinks: this.enabled('quicklinksenabled') && this.online ? <QuickLinks /> : null,
|
||||
message: this.enabled('message') && <Message />,
|
||||
};
|
||||
}
|
||||
const Widgets = () => {
|
||||
const online = localStorage.getItem('offlineMode') === 'false';
|
||||
const [order, setOrder] = useState(JSON.parse(localStorage.getItem('order')));
|
||||
const [welcome, setWelcome] = useState(localStorage.getItem('showWelcome'));
|
||||
|
||||
enabled(key) {
|
||||
const enabled = (key) => {
|
||||
return localStorage.getItem(key) === 'true';
|
||||
}
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
EventBus.on('refresh', (data) => {
|
||||
// widgets we can re-order
|
||||
const widgets = useMemo(
|
||||
() => ({
|
||||
time: enabled('time') && <Clock />,
|
||||
greeting: enabled('greeting') && <Greeting />,
|
||||
quote: enabled('quote') && <Quote />,
|
||||
date: enabled('date') && <Date />,
|
||||
quicklinks: enabled('quicklinksenabled') && online ? <QuickLinks /> : null,
|
||||
message: enabled('message') && <Message />,
|
||||
}),
|
||||
[order], // Re-create widgets when order changes
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const handleRefresh = (data) => {
|
||||
switch (data) {
|
||||
case 'widgets':
|
||||
return this.setState({
|
||||
order: JSON.parse(localStorage.getItem('order')),
|
||||
});
|
||||
return setOrder(JSON.parse(localStorage.getItem('order')));
|
||||
case 'widgetsWelcome':
|
||||
this.setState({
|
||||
welcome: localStorage.getItem('showWelcome'),
|
||||
});
|
||||
setWelcome(localStorage.getItem('showWelcome'));
|
||||
localStorage.setItem('showWelcome', true);
|
||||
window.onbeforeunload = () => {
|
||||
localStorage.clear();
|
||||
};
|
||||
break;
|
||||
case 'widgetsWelcomeDone':
|
||||
this.setState({
|
||||
welcome: localStorage.getItem('showWelcome'),
|
||||
});
|
||||
return (window.onbeforeunload = null);
|
||||
setWelcome(localStorage.getItem('showWelcome'));
|
||||
window.onbeforeunload = null;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
componentWillUnmount() {
|
||||
EventBus.off('refresh');
|
||||
}
|
||||
EventBus.on('refresh', handleRefresh);
|
||||
return () => {
|
||||
EventBus.off('refresh');
|
||||
};
|
||||
}, []);
|
||||
|
||||
render() {
|
||||
// don't show when welcome is there
|
||||
return this.state.welcome !== 'false' ? (
|
||||
<WidgetsLayout />
|
||||
) : (
|
||||
<WidgetsLayout>
|
||||
<Suspense fallback={<></>}>
|
||||
{this.enabled('searchBar') && <Search />}
|
||||
{this.state.order.map((element, key) => (
|
||||
<Fragment key={key}>{this.widgets[element]}</Fragment>
|
||||
))}
|
||||
{this.enabled('weatherEnabled') && this.online ? <Weather /> : null}
|
||||
</Suspense>
|
||||
</WidgetsLayout>
|
||||
);
|
||||
}
|
||||
}
|
||||
// don't show when welcome is there
|
||||
return welcome !== 'false' ? (
|
||||
<WidgetsLayout />
|
||||
) : (
|
||||
<WidgetsLayout>
|
||||
<Suspense fallback={<></>}>
|
||||
{enabled('searchBar') && <Search />}
|
||||
{order.map((element, key) => (
|
||||
<Fragment key={key}>{widgets[element]}</Fragment>
|
||||
))}
|
||||
{enabled('weatherEnabled') && online ? <Weather /> : null}
|
||||
</Suspense>
|
||||
</WidgetsLayout>
|
||||
);
|
||||
};
|
||||
|
||||
export { Widgets as default, Widgets };
|
||||
|
||||
Reference in New Issue
Block a user