mirror of https://github.com/mue/mue.git
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:
parent
e0ced3de08
commit
4975bd3077
|
@ -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');
|
||||
}
|
||||
});
|
||||
});
|
|
@ -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 };
|
|
@ -0,0 +1 @@
|
|||
export * from './Collection';
|
|
@ -86,4 +86,6 @@ function EmblaCarousel({ data }) {
|
|||
);
|
||||
}
|
||||
|
||||
export default memo(EmblaCarousel);
|
||||
const Carousel = memo(EmblaCarousel);
|
||||
|
||||
export { Carousel as default, Carousel };
|
|
@ -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;
|
|
@ -0,0 +1 @@
|
|||
export * from './Carousel';
|
|
@ -14,4 +14,6 @@ function Lightbox({ modalClose, img }) {
|
|||
);
|
||||
}
|
||||
|
||||
export default memo(Lightbox);
|
||||
const MemoizedLightbox = memo(Lightbox);
|
||||
export default MemoizedLightbox;
|
||||
export { MemoizedLightbox as Lightbox };
|
|
@ -0,0 +1 @@
|
|||
export * from './Lightbox';
|
|
@ -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 };
|
|
@ -0,0 +1 @@
|
|||
export * from './SideloadFailedModal';
|
|
@ -0,0 +1,3 @@
|
|||
export * from './Carousel';
|
||||
export * from './SideloadFailedModal';
|
||||
export * from './Lightbox';
|
|
@ -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 };
|
|
@ -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 };
|
|
@ -0,0 +1,2 @@
|
|||
export * from './Elements';
|
||||
export * from './Items';
|
|
@ -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';
|
||||
|
|
@ -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';
|
|
@ -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() {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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;
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
};
|
|
@ -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
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue