refactor(marketplace & achievements): Structural achanges and fixes

Co-authored-by: Isaac <contact@eartharoid.me>
Co-authored-by: David Ralph <me@davidcralph.co.uk>
This commit is contained in:
alexsparkes 2024-02-19 23:37:25 +00:00
parent e0ced3de08
commit 4975bd3077
26 changed files with 318 additions and 142 deletions

View File

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

View File

@ -0,0 +1,53 @@
import { MdOutlineArrowForward, MdOutlineOpenInNew } from 'react-icons/md';
import { Button } from 'components/Elements';
import variables from 'config/variables';
const Collection = ({ collection, toggle, collectionFunction }) => {
const { news, background_colour, img, display_name, description, name } = collection;
const getStyle = () => {
if (news) {
return { backgroundColor: background_colour };
}
return {
backgroundImage: `linear-gradient(to left, #000, transparent, #000), url('${variables.constants.DDG_IMAGE_PROXY + img}')`,
};
};
return (
<div className="collection" style={getStyle()}>
<div className="content">
<span className="title">{display_name} using component</span>
<span className="subtitle">{description}</span>
</div>
{collection.news === true ? (
<a
className="btn-collection"
href={collection.news_link}
target="_blank"
rel="noopener noreferrer"
>
{variables.getMessage('modals.main.marketplace.learn_more')} <MdOutlineOpenInNew />
</a>
) : (
<Button
type="collection"
onClick={() => collectionFunction(collection.name)}
icon={<MdOutlineArrowForward />}
label={variables.getMessage('modals.main.marketplace.explore_collection')}
iconPlacement={'right'}
/>
)}
{/*<Button
type="collection"
onClick={() => toggle('collection', name)}
icon={<MdOutlineArrowForward />}
label={variables.getMessage('modals.main.marketplace.explore_collection')}
iconPlacement="right"
/>*/}
</div>
);
};
export default Collection;
export { Collection };

View File

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

View File

@ -86,4 +86,6 @@ function EmblaCarousel({ data }) {
);
}
export default memo(EmblaCarousel);
const Carousel = memo(EmblaCarousel);
export { Carousel as default, Carousel };

View File

@ -22,6 +22,7 @@
.carousel_container {
display: flex;
-webkit-touch-callout: none;
-webkit-user-select: none;
user-select: none;
-webkit-tap-highlight-color: transparent;
margin-left: -10px;

View File

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

View File

@ -14,4 +14,6 @@ function Lightbox({ modalClose, img }) {
);
}
export default memo(Lightbox);
const MemoizedLightbox = memo(Lightbox);
export default MemoizedLightbox;
export { MemoizedLightbox as Lightbox };

View File

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

View File

@ -2,6 +2,7 @@ import { memo } from 'react';
import variables from 'config/variables';
import { MdClose } from 'react-icons/md';
import { Tooltip } from 'components/Elements';
function SideloadFailedModal({ modalClose, reason }) {
return (
<div className="smallModal">
@ -21,4 +22,7 @@ function SideloadFailedModal({ modalClose, reason }) {
);
}
export default memo(SideloadFailedModal);
const MemoizedSideloadFailedModal = memo(SideloadFailedModal);
export default MemoizedSideloadFailedModal;
export { MemoizedSideloadFailedModal as SideloadFailedModal };

View File

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

View File

@ -0,0 +1,3 @@
export * from './Carousel';
export * from './SideloadFailedModal';
export * from './Lightbox';

View File

@ -1,7 +1,5 @@
import variables from 'config/variables';
import { PureComponent, Fragment } from 'react';
import { Tooltip } from 'components/Elements';
import ImageCarousel from 'features/helpers/carousel/Carousel';
import { toast } from 'react-toastify';
import {
MdIosShare,
@ -21,7 +19,7 @@ import { Header } from 'components/Layout/Settings';
import { Button } from 'components/Elements';
import { install, uninstall } from 'utils/marketplace';
import { Carousel } from '../Elements/Carousel';
import { ShareModal } from 'components/Elements';
class Item extends PureComponent {
@ -124,7 +122,7 @@ class Item extends PureComponent {
{this.props.data.data.photos && (
<div className="carousel">
<div className="carousel_container">
<ImageCarousel data={this.props.data.data.photos} />
<Carousel data={this.props.data.data.photos} />
</div>
</div>
)}
@ -306,4 +304,4 @@ class Item extends PureComponent {
}
}
export default Item;
export { Item as default, Item };

View File

@ -3,6 +3,7 @@ import React, { memo } from 'react';
import { MdAutoFixHigh, MdOutlineArrowForward, MdOutlineOpenInNew } from 'react-icons/md';
import { Button } from 'components/Elements';
import MemoizedLightbox from '../Elements/Lightbox/Lightbox';
function Items({
type,
@ -114,4 +115,5 @@ function Items({
);
}
export default memo(Items);
const MemoizedItems = memo(Items);
export { MemoizedItems as default, MemoizedItems as Items };

View File

@ -0,0 +1,2 @@
export * from './Elements';
export * from './Items';

View File

@ -4,11 +4,10 @@ import { MdUpdate, MdOutlineExtensionOff, MdSendTimeExtension } from 'react-icon
import { toast } from 'react-toastify';
import Modal from 'react-modal';
import SideloadFailedModal from '../SideloadFailedModal';
import FileUpload from '../../../../../components/Form/Settings/FileUpload/FileUpload';
import Item from '../Item';
import Items from '../Items';
import Dropdown from '../../../../../components/Form/Settings/Dropdown/Dropdown';
import { SideloadFailedModal } from '../components/Elements/SideloadFailedModal/SideloadFailedModal';
import Item from '../components/Items/Item';
import Items from '../components/Items/Items';
import { Dropdown, FileUpload } from 'components/Form/Settings';
import { Header, CustomActions } from 'components/Layout/Settings';
import { Button } from 'components/Elements';

View File

@ -10,8 +10,8 @@ import {
MdLibraryAdd,
} from 'react-icons/md';
import Item from '../Item';
import Items from '../Items';
import Item from '../components/Items/Item';
import Items from '../components/Items/Items';
import Dropdown from '../../../../../components/Form/Settings/Dropdown/Dropdown';
import { Header } from 'components/Layout/Settings';
import { Button } from 'components/Elements';

View File

@ -3,7 +3,7 @@ import { PureComponent, createRef } from 'react';
import { MdOutlineWifiOff } from 'react-icons/md';
import Modal from 'react-modal';
import Lightbox from '../../marketplace/Lightbox';
import Lightbox from '../../marketplace/components/Elements/Lightbox/Lightbox';
export default class Changelog extends PureComponent {
constructor() {

View File

@ -10,31 +10,14 @@ import { Header, CustomActions } from 'components/Layout/Settings';
import { saveFile } from 'utils/saveFile';
import achievementsData from 'utils/data/achievements.json';
import translations from 'i18n/locales/achievements/index';
const achievementLanguage = {
de_DE: translations.de_DE,
en_GB: translations.en_GB,
en_US: translations.en_US,
es: translations.es,
fr: translations.fr,
nl: translations.nl,
no: translations.no,
ru: translations.ru,
zh_CN: translations.zh_CN,
id_ID: translations.id_ID,
tr_TR: translations.tr_TR,
bn: translations.bn,
pt_BR: translations.pt_BR,
};
import { translations, achievements } from 'utils/achievements';
export default class Stats extends PureComponent {
constructor() {
super();
this.state = {
stats: JSON.parse(localStorage.getItem('statsData')) || {},
achievements: achievementsData.achievements,
achievements,
};
}
@ -79,7 +62,7 @@ export default class Stats extends PureComponent {
this.setState({
stats: {},
});
toast('Stats reset');
toast(variables.getMessage('toasts.stats_reset'));
this.getAchievements();
this.forceUpdate();
}
@ -92,23 +75,35 @@ export default class Stats extends PureComponent {
saveFile(JSON.stringify(this.state.stats, null, 2), filename);
}
getLocalisedAchievementData(id) {
const localised = translations[variables.languagecode][id] ||
translations.en_GB[id] || { name: id, description: '' };
return {
name: localised.name,
description: localised.description,
};
}
componentDidMount() {
this.getAchievements();
this.forceUpdate();
}
render() {
const achievementElement = (key, name, achieved) => (
<div className="achievement">
<FaTrophy />
<div className={'achievementContent' + (achieved ? ' achieved' : '')}>
<span>{name}</span>
<span className="subtitle">
{achievementLanguage[localStorage.getItem('language')][key]}
</span>
const achievementElement = (key, id, achieved) => {
const { name, description } = this.getLocalisedAchievementData(id);
return (
<div className="achievement" key={key}>
<FaTrophy />
<div className={'achievementContent' + (achieved ? ' achieved' : '')}>
<span>{name}</span>
<span className="subtitle">{description}</span>
</div>
</div>
</div>
);
);
};
const STATS_SECTION = 'modals.main.settings.sections.stats';
@ -220,7 +215,7 @@ export default class Stats extends PureComponent {
<div className="achievements">
{this.state.achievements.map((achievement, index) => {
if (achievement.achieved) {
return achievementElement(index, achievement.name, achievement.achieved);
return achievementElement(index, achievement.id, achievement.achieved);
}
})}
</div>

View File

@ -2,8 +2,8 @@ import variables from 'config/variables';
import { memo } from 'react';
import Tabs from './backend/Tabs';
import Added from '../marketplace/sections/Added';
import Create from '../marketplace/sections/Create';
import Added from '../marketplace/views/Added';
import Create from '../marketplace/views/Create';
function Addons(props) {
return (

View File

@ -2,7 +2,7 @@ import variables from 'config/variables';
import { memo } from 'react';
import Tabs from './backend/Tabs';
import MarketplaceTab from '../marketplace/sections/Marketplace';
import MarketplaceTab from '../marketplace/views/Browse';
function Marketplace(props) {
return (

View File

@ -1,8 +1,50 @@
[
"Opened 10 tabs",
"Opened 39 tabs",
"Opened 100 tabs",
"Opened 305 tabs",
"Installed an add-on",
"Installed 5 add-ons"
]
{
"10tabs": {
"name": "10/10 IGN",
"description": "Opened 10 tabs"
},
"thankyou": {
"name": "Thank You",
"description": "Opened 39 tabs"
},
"seasoning": {
"name": "Seasoning",
"description": "Opened 100 tabs"
},
"mrworldwide": {
"name": "Mr. Worldwide",
"description": "Opened 305 tabs"
},
"tabaholic": {
"name": "Tabaholic",
"description": "Opened 500 tabs"
},
"727": {
"name": "When You See It",
"description": "Opened 727 tabs"
},
"808s": {
"name": "808s & Tab Breaks",
"description": "Opened 808 tabs"
},
"1337": {
"name": "MU3T4B",
"description": "Opened 1337 tabs"
},
"averagelinuxuser": {
"name": "Average Linux User",
"description": "Installed an add-on"
},
"fullyriced": {
"name": "Fully Riced",
"description": "Installed 5 add-ons"
},
"21addons": {
"name": "They installed 21 add-ons? Whaaat?",
"description": "Installed 21 add-ons"
},
"overload": {
"name": "System Overload",
"description": "Installed 50 add-ons"
}
}

View File

@ -1,31 +0,0 @@
import de_DE from './de_DE.json';
import en_GB from './en_GB.json';
import en_US from './en_US.json';
import es from './es.json';
import fr from './fr.json';
import nl from './nl.json';
import no from './no.json';
import ru from './ru.json';
import zh_CN from './zh_CN.json';
import id_ID from './id_ID.json';
import tr_TR from './tr_TR.json';
import bn from './bn.json';
import pt_BR from './pt_BR.json';
const translations = {
de_DE,
en_GB,
en_US,
es,
fr,
nl,
no,
ru,
zh_CN,
id_ID,
tr_TR,
bn,
pt_BR,
};
export default translations;

View File

@ -676,6 +676,7 @@
"error": "Something went wrong",
"imported": "Successfully imported",
"no_storage": "Not enough storage",
"link_copied": "Link copied"
"link_copied": "Link copied",
"stats_reset": "Stats reset"
}
}

View File

@ -0,0 +1,36 @@
import de_DE from 'i18n/locales/achievements/de_DE.json';
import en_GB from 'i18n/locales/achievements/en_GB.json';
import en_US from 'i18n/locales/achievements/en_US.json';
import es from 'i18n/locales/achievements/es.json';
import fr from 'i18n/locales/achievements/fr.json';
import nl from 'i18n/locales/achievements/nl.json';
import no from 'i18n/locales/achievements/no.json';
import ru from 'i18n/locales/achievements/ru.json';
import zh_CN from 'i18n/locales/achievements/zh_CN.json';
import id_ID from 'i18n/locales/achievements/id_ID.json';
import tr_TR from 'i18n/locales/achievements/tr_TR.json';
import bn from 'i18n/locales/achievements/bn.json';
import pt_BR from 'i18n/locales/achievements/pt_BR.json';
import achievements from 'utils/data/achievements.json';
const translations = {
de_DE,
en_GB,
en_US,
es,
fr,
nl,
no,
ru,
zh_CN,
id_ID,
tr_TR,
bn,
pt_BR,
};
export {
achievements,
translations
};

View File

@ -1,52 +1,86 @@
{
"achievements": [
{
"name": "10/10 IGN",
"description": "Opened 10 tabs",
"condition": {
"type": "tabsOpened",
"amount": 10
}
},
{
"name": "Thank you",
"description": "Opened 39 tabs",
"condition": {
"type": "tabsOpened",
"amount": 39
}
},
{
"name": "Seasoning",
"description": "Opened 100 tabs",
"condition": {
"type": "tabsOpened",
"amount": 100
}
},
{
"name": "Mr Worldwide",
"description": "Opened 305 tabs",
"condition": {
"type": "tabsOpened",
"amount": 305
}
},
{
"name": "Average Linux user",
"description": "Installed an add-on",
"condition": {
"type": "addonInstall",
"amount": 1
}
},
{
"name": "Fully riced",
"description": "Installed 5 add-ons",
"condition": {
"type": "addonInstall",
"amount": 5
}
[
{
"id": "10tabs",
"condition": {
"type": "tabsOpened",
"amount": 10
}
]
}
},
{
"id": "thankyou",
"condition": {
"type": "tabsOpened",
"amount": 39
}
},
{
"id": "seasoning",
"condition": {
"type": "tabsOpened",
"amount": 100
}
},
{
"id": "mrworldwide",
"condition": {
"type": "tabsOpened",
"amount": 305
}
},
{
"id": "tabaholic",
"condition": {
"type": "tabsOpened",
"amount": 500
}
},
{
"id": "727",
"condition": {
"type": "tabsOpened",
"amount": 727
}
},
{
"id": "808sandtabs",
"condition": {
"type": "tabsOpened",
"amount": 808
}
},
{
"id": "1337",
"condition": {
"type": "tabsOpened",
"amount": 1337
}
},
{
"id": "averagelinuxuser",
"condition": {
"type": "addonInstall",
"amount": 1
}
},
{
"id": "fullyriced",
"condition": {
"type": "addonInstall",
"amount": 5
}
},
{
"id": "21addons",
"condition": {
"type": "addonInstall",
"amount": 21
}
},
{
"id": "overload",
"condition": {
"type": "addonInstall",
"amount": 50
}
}
]