refactor(welcome): Improved readability of changing tab + intro cleanup

Co-authored-by: David Ralph <me@davidcralph.co.uk>
Co-authored-by: Isaac <contact@eartharoid.me>
This commit is contained in:
alexsparkes 2024-02-21 10:47:50 +00:00
parent 90ed4d8d7c
commit a45238ea54
7 changed files with 105 additions and 141 deletions

View File

@ -38,31 +38,30 @@ fs.readdirSync('../src/i18n/locales').forEach((file) => {
fs.appendFileSync('../src/i18n/locales/' + file, '\n'); fs.appendFileSync('../src/i18n/locales/' + file, '\n');
}); });
// do the same with achievements // do the same with achievements
fs.readdirSync('../src/i18n/achievements').forEach((file) => { fs.readdirSync('../src/i18n/locales/achievements').forEach((file) => {
if (file === 'en_GB.json') { if (file === 'en_GB.json') {
return; return;
} }
const en = require('../src/i18n/achievements/en_GB.json'); const en = require('../src/i18n/locales/achievements/en_GB.json');
const newdata = merge(en, require('../src/i18n/achievements/' + file)); const newdata = merge(en, require('../src/i18n/locales/achievements/' + file));
// remove strings not in english file // remove strings not in english file
compareAndRemoveKeys(newdata, en); compareAndRemoveKeys(newdata, en);
// write new file // write new file
fs.writeFileSync('../src/i18n/achievements/' + file, JSON.stringify(newdata, null, 2)); fs.writeFileSync('../src/i18n/locales/achievements/' + file, JSON.stringify(newdata, null, 2));
// add new line // add new line
fs.appendFileSync('../src/i18n/achievements/' + file, '\n'); fs.appendFileSync('../src/i18n/locales/achievements/' + file, '\n');
// if missing translations from locales/ add them to achievements/ // if missing translations from locales/ add them to achievements/
const locales = fs.readdirSync('../src/i18n/locales'); const locales = fs.readdirSync('../src/i18n/locales');
locales.forEach((locale) => { locales.forEach((locale) => {
if (!fs.existsSync('../src/i18n/achievements/' + locale)) { if (!fs.existsSync('../src/i18n/locales/achievements/' + locale)) {
fs.writeFileSync('../src/i18n/achievements/' + locale, JSON.stringify(en, null, 2)); fs.writeFileSync('../src/i18n/locales/achievements/' + locale, JSON.stringify(en, null, 2));
fs.appendFileSync('../src/i18n/achievements/' + locale, '\n'); fs.appendFileSync('../src/i18n/locales/achievements/' + locale, '\n');
} }
}); });
}); });

View File

@ -1,80 +1,89 @@
import variables from 'config/variables'; import variables from 'config/variables';
import { useState, useEffect } from 'react'; import { useState, useEffect, useCallback } from 'react';
import { Header, Content } from '../components/Layout'; import { Header, Content } from '../components/Layout';
import { MdOutlineWavingHand, MdOpenInNew } from 'react-icons/md'; import { MdOutlineWavingHand, MdOpenInNew } from 'react-icons/md';
import { FaDiscord, FaGithub } from 'react-icons/fa'; import { FaDiscord, FaGithub } from 'react-icons/fa';
const DISCORD_LINK = 'https://discord.gg/' + variables.constants.DISCORD_SERVER;
const GITHUB_LINK =
'https://github.com/' + variables.constants.ORG_NAME + '/' + variables.constants.REPO_NAME;
function WelcomeNotice({ config }) {
const { icon: Icon, title, subtitle, link } = config;
return (
<div className="welcomeNotice">
<div className="icon">
<Icon />
</div>
<div className="text">
<span className="title">{title}</span>
<span className="subtitle">{subtitle}</span>
</div>
{link && (
<a href={link} target="_blank" rel="noopener noreferrer">
<MdOpenInNew />
{variables.getMessage('modals.welcome.sections.intro.notices.github_open')}
</a>
)}
</div>
);
}
function Intro() { function Intro() {
const [welcomeImage, setWelcomeImage] = useState(0); const [welcomeImage, setWelcomeImage] = useState(0);
useEffect(() => { const updateWelcomeImage = useCallback(() => {
const timer = setInterval(() => { setWelcomeImage((prevWelcomeImage) => (prevWelcomeImage < 3 ? prevWelcomeImage + 1 : 0));
setWelcomeImage(prevWelcomeImage => prevWelcomeImage < 3 ? prevWelcomeImage + 1 : 0); }, []);
}, 3000);
// Cleanup function to clear the interval when the component unmounts const ShareYourMue = (
<div className="examples">
<img
src={`/src/assets/welcome-images/example${welcomeImage + 1}.webp`}
alt="Example Mue setup"
draggable={false}
/>
<span className="shareYourMue">#shareyourmue</span>
</div>
);
useEffect(() => {
const timer = setInterval(updateWelcomeImage, 3000);
return () => clearInterval(timer); return () => clearInterval(timer);
}, [welcomeImage]); }, [updateWelcomeImage]);
return ( return (
<Content> <Content>
<Header title={variables.getMessage('modals.welcome.sections.intro.title')} /> <Header title={variables.getMessage('modals.welcome.sections.intro.title')} />
<div className="examples"> {ShareYourMue}
<img <WelcomeNotice
src={`/src/assets/welcome-images/example${welcomeImage + 1}.webp`} config={{
alt="Example Mue setup" icon: MdOutlineWavingHand,
draggable={false} title: variables.getMessage('modals.welcome.sections.intro.title'),
/> subtitle: variables.getMessage('modals.welcome.sections.intro.description'),
<span className="shareYourMue">#shareyourmue</span> }}
</div> />
<div className="welcomeNotice"> <WelcomeNotice
<div className="icon"> config={{
<MdOutlineWavingHand /> icon: FaDiscord,
</div> title: variables.getMessage('modals.welcome.sections.intro.notices.discord_title'),
<div className="text"> subtitle: variables.getMessage(
<span className="title"> 'modals.welcome.sections.intro.notices.discord_description',
{variables.getMessage('modals.welcome.sections.intro.title')} ),
</span> link: DISCORD_LINK,
<span className="subtitle"> }}
{variables.getMessage('modals.welcome.sections.intro.description')} />
</span> <WelcomeNotice
</div> config={{
</div> icon: FaGithub,
<div className="welcomeNotice"> title: variables.getMessage('modals.welcome.sections.intro.notices.github_title'),
<div className="icon"> subtitle: variables.getMessage(
<FaDiscord /> 'modals.welcome.sections.intro.notices.github_description',
</div> ),
<div className="text"> link: GITHUB_LINK,
<span className="title"> }}
{variables.getMessage('modals.welcome.sections.intro.notices.discord_title')} />
</span>
<span className="subtitle">
{variables.getMessage('modals.welcome.sections.intro.notices.discord_description')}
</span>
</div>
<a href="https://discord.gg/zv8C9F8" target="_blank" rel="noopener noreferrer">
<MdOpenInNew />{' '}
{variables.getMessage('modals.welcome.sections.intro.notices.discord_join')}
</a>
</div>
<div className="welcomeNotice">
<div className="icon">
<FaGithub />
</div>
<div className="text">
<span className="title">
{variables.getMessage('modals.welcome.sections.intro.notices.github_title')}
</span>
<span className="subtitle">
{variables.getMessage('modals.welcome.sections.intro.notices.github_description')}
</span>
</div>
<a href="https://github.com/mue/mue" target="_blank" rel="noopener noreferrer">
<MdOpenInNew />
{variables.getMessage('modals.welcome.sections.intro.notices.github_open')}
</a>
</div>
</Content> </Content>
); );
} }

View File

@ -4,7 +4,7 @@ import { MdArrowBackIosNew, MdArrowForwardIos, MdOutlinePreview } from 'react-ic
import EventBus from 'utils/eventbus'; import EventBus from 'utils/eventbus';
import { ProgressBar, AsideImage, Navigation } from './components/Elements'; import { ProgressBar, AsideImage } from './components/Elements';
import { Button } from 'components/Elements'; import { Button } from 'components/Elements';
import { Wrapper, Panel } from './components/Layout'; import { Wrapper, Panel } from './components/Layout';
@ -52,49 +52,41 @@ function WelcomeModal({ modalClose, modalSkip }) {
}; };
}, [currentTab, finalTab]); }, [currentTab, finalTab]);
const changeTab = (minus) => { const updateTabAndButtonText = (newTab) => {
localStorage.setItem('bgtransition', true);
localStorage.removeItem('welcomeTab');
if (minus) {
setCurrentTab(currentTab - 1);
setButtonText(variables.getMessage('modals.welcome.buttons.next'));
return;
}
if (buttonText === variables.getMessage('modals.welcome.buttons.finish')) {
modalClose();
return;
}
const newTab = currentTab + 1;
setCurrentTab(newTab); setCurrentTab(newTab);
setButtonText( setButtonText(
newTab !== finalTab newTab !== finalTab
? variables.getMessage('modals.welcome.buttons.next') ? variables.getMessage('modals.welcome.buttons.next')
: variables.getMessage('modals.welcome.buttons.finish'), : variables.getMessage('modals.welcome.buttons.finish'),
); );
};
const switchTab = (tab) => {
setCurrentTab(tab);
setButtonText(
tab !== finalTab + 1
? variables.getMessage('modals.welcome.buttons.next')
: variables.getMessage('modals.welcome.buttons.finish'),
);
localStorage.setItem('bgtransition', true); localStorage.setItem('bgtransition', true);
localStorage.removeItem('welcomeTab'); localStorage.removeItem('welcomeTab');
}; };
const goBackward = () => {
updateTabAndButtonText(currentTab - 1);
};
const goForward = () => {
if (buttonText === variables.getMessage('modals.welcome.buttons.finish')) {
modalClose();
return;
}
updateTabAndButtonText(currentTab + 1);
};
const switchToTab = (tab) => {
updateTabAndButtonText(tab);
};
const Navigation = () => { const Navigation = () => {
return ( return (
<div className="welcomeButtons"> <div className="welcomeButtons">
{currentTab !== 0 ? ( {currentTab !== 0 ? (
<Button <Button
type="settings" type="settings"
onClick={() => changeTab(true)} onClick={() => goBackward()}
icon={<MdArrowBackIosNew />} icon={<MdArrowBackIosNew />}
label={variables.getMessage('modals.welcome.buttons.previous')} label={variables.getMessage('modals.welcome.buttons.previous')}
/> />
@ -108,7 +100,7 @@ function WelcomeModal({ modalClose, modalSkip }) {
)} )}
<Button <Button
type="settings" type="settings"
onClick={() => changeTab()} onClick={() => goForward()}
icon={<MdArrowForwardIos />} icon={<MdArrowForwardIos />}
label={buttonText} label={buttonText}
iconPlacement={'right'} iconPlacement={'right'}
@ -120,11 +112,11 @@ function WelcomeModal({ modalClose, modalSkip }) {
const tabComponents = { const tabComponents = {
0: <Intro />, 0: <Intro />,
1: <ChooseLanguage />, 1: <ChooseLanguage />,
2: <ImportSettings switchTab={switchTab} />, 2: <ImportSettings switchTab={switchToTab} />,
3: <ThemeSelection />, 3: <ThemeSelection />,
4: <StyleSelection />, 4: <StyleSelection />,
5: <PrivacyOptions />, 5: <PrivacyOptions />,
6: <Final currentTab={currentTab} switchTab={switchTab} />, 6: <Final currentTab={currentTab} switchTab={switchToTab} />,
}; };
let CurrentTab = tabComponents[currentTab] || <Intro />; let CurrentTab = tabComponents[currentTab] || <Intro />;
@ -133,13 +125,13 @@ function WelcomeModal({ modalClose, modalSkip }) {
<Wrapper> <Wrapper>
<Panel type="aside"> <Panel type="aside">
<AsideImage currentTab={currentTab} /> <AsideImage currentTab={currentTab} />
<ProgressBar numberOfTabs={finalTab + 1} currentTab={currentTab} switchTab={switchTab} /> <ProgressBar numberOfTabs={finalTab + 1} currentTab={currentTab} switchTab={switchToTab} />
</Panel> </Panel>
<Panel type="content"> <Panel type="content">
{CurrentTab} {CurrentTab}
<Navigation <Navigation
currentTab={currentTab} currentTab={currentTab}
changeTab={changeTab} changeTab={switchToTab}
buttonText={buttonText} buttonText={buttonText}
modalSkip={modalSkip} modalSkip={modalSkip}
/> />

View File

@ -1,34 +0,0 @@
import { MdArrowBackIosNew, MdArrowForwardIos, MdOutlinePreview } from 'react-icons/md';
import { Button } from 'components/Elements';
import variables from 'config/variables';
function Navigation({ currentTab, changeTab, buttonText, modalSkip }) {
return (
<div className="welcomeButtons">
{currentTab !== 0 ? (
<Button
type="settings"
onClick={() => changeTab(true)}
icon={<MdArrowBackIosNew />}
label={variables.getMessage('modals.welcome.buttons.previous')}
/>
) : (
<Button
type="settings"
onClick={() => modalSkip()}
icon={<MdOutlinePreview />}
label={variables.getMessage('modals.welcome.buttons.preview')}
/>
)}
<Button
type="settings"
onClick={() => changeTab()}
icon={<MdArrowForwardIos />}
label={buttonText}
iconPlacement={'right'}
/>
</div>
);
}
export { Navigation as default, Navigation };

View File

@ -1 +0,0 @@
export * from './Navigation';

View File

@ -1,3 +1,2 @@
export * from './ProgressBar'; export * from './ProgressBar';
export * from './AsideImage'; export * from './AsideImage';
export * from './Navigation';

View File