diff --git a/scripts/updatetranslations.js b/scripts/updatetranslations.js
index d33a49cf..e0e54624 100644
--- a/scripts/updatetranslations.js
+++ b/scripts/updatetranslations.js
@@ -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');
+ }
+ });
+});
\ No newline at end of file
diff --git a/src/features/modals/main/marketplace/components/Collection/Collection.jsx b/src/features/modals/main/marketplace/components/Collection/Collection.jsx
new file mode 100644
index 00000000..ffc2fe03
--- /dev/null
+++ b/src/features/modals/main/marketplace/components/Collection/Collection.jsx
@@ -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 (
+
@@ -21,4 +22,7 @@ function SideloadFailedModal({ modalClose, reason }) {
);
}
-export default memo(SideloadFailedModal);
+const MemoizedSideloadFailedModal = memo(SideloadFailedModal);
+
+export default MemoizedSideloadFailedModal;
+export { MemoizedSideloadFailedModal as SideloadFailedModal };
\ No newline at end of file
diff --git a/src/features/modals/main/marketplace/components/Elements/SideloadFailedModal/index.jsx b/src/features/modals/main/marketplace/components/Elements/SideloadFailedModal/index.jsx
new file mode 100644
index 00000000..7b7ea247
--- /dev/null
+++ b/src/features/modals/main/marketplace/components/Elements/SideloadFailedModal/index.jsx
@@ -0,0 +1 @@
+export * from './SideloadFailedModal';
\ No newline at end of file
diff --git a/src/features/modals/main/marketplace/components/Elements/index.jsx b/src/features/modals/main/marketplace/components/Elements/index.jsx
new file mode 100644
index 00000000..63a1a581
--- /dev/null
+++ b/src/features/modals/main/marketplace/components/Elements/index.jsx
@@ -0,0 +1,3 @@
+export * from './Carousel';
+export * from './SideloadFailedModal';
+export * from './Lightbox';
\ No newline at end of file
diff --git a/src/features/modals/main/marketplace/Item.jsx b/src/features/modals/main/marketplace/components/Items/Item.jsx
similarity index 98%
rename from src/features/modals/main/marketplace/Item.jsx
rename to src/features/modals/main/marketplace/components/Items/Item.jsx
index ef1ea9d0..2eb95161 100644
--- a/src/features/modals/main/marketplace/Item.jsx
+++ b/src/features/modals/main/marketplace/components/Items/Item.jsx
@@ -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 && (
)}
@@ -306,4 +304,4 @@ class Item extends PureComponent {
}
}
-export default Item;
+export { Item as default, Item };
diff --git a/src/features/modals/main/marketplace/Items.jsx b/src/features/modals/main/marketplace/components/Items/Items.jsx
similarity index 96%
rename from src/features/modals/main/marketplace/Items.jsx
rename to src/features/modals/main/marketplace/components/Items/Items.jsx
index ec0502ea..bccc6758 100644
--- a/src/features/modals/main/marketplace/Items.jsx
+++ b/src/features/modals/main/marketplace/components/Items/Items.jsx
@@ -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 };
diff --git a/src/features/modals/main/marketplace/components/index.jsx b/src/features/modals/main/marketplace/components/index.jsx
new file mode 100644
index 00000000..1f5d55b4
--- /dev/null
+++ b/src/features/modals/main/marketplace/components/index.jsx
@@ -0,0 +1,2 @@
+export * from './Elements';
+export * from './Items';
\ No newline at end of file
diff --git a/src/features/modals/main/marketplace/sections/Added.jsx b/src/features/modals/main/marketplace/views/Added.jsx
similarity index 96%
rename from src/features/modals/main/marketplace/sections/Added.jsx
rename to src/features/modals/main/marketplace/views/Added.jsx
index c111de34..8449f736 100644
--- a/src/features/modals/main/marketplace/sections/Added.jsx
+++ b/src/features/modals/main/marketplace/views/Added.jsx
@@ -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';
diff --git a/src/features/modals/main/marketplace/sections/Marketplace.jsx b/src/features/modals/main/marketplace/views/Browse.jsx
similarity index 99%
rename from src/features/modals/main/marketplace/sections/Marketplace.jsx
rename to src/features/modals/main/marketplace/views/Browse.jsx
index 8ab60438..4e26e14e 100644
--- a/src/features/modals/main/marketplace/sections/Marketplace.jsx
+++ b/src/features/modals/main/marketplace/views/Browse.jsx
@@ -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';
diff --git a/src/features/modals/main/marketplace/sections/Create.jsx b/src/features/modals/main/marketplace/views/Create.jsx
similarity index 100%
rename from src/features/modals/main/marketplace/sections/Create.jsx
rename to src/features/modals/main/marketplace/views/Create.jsx
diff --git a/src/features/modals/main/settings/sections/Changelog.jsx b/src/features/modals/main/settings/sections/Changelog.jsx
index 658bde63..95d4df2b 100644
--- a/src/features/modals/main/settings/sections/Changelog.jsx
+++ b/src/features/modals/main/settings/sections/Changelog.jsx
@@ -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() {
diff --git a/src/features/modals/main/settings/sections/Stats.jsx b/src/features/modals/main/settings/sections/Stats.jsx
index fffaac60..b9c93b54 100644
--- a/src/features/modals/main/settings/sections/Stats.jsx
+++ b/src/features/modals/main/settings/sections/Stats.jsx
@@ -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) => (
-
-
-
-
{name}
-
- {achievementLanguage[localStorage.getItem('language')][key]}
-
+ const achievementElement = (key, id, achieved) => {
+ const { name, description } = this.getLocalisedAchievementData(id);
+
+ return (
+
+
+
+ {name}
+ {description}
+
-
- );
+ );
+ };
const STATS_SECTION = 'modals.main.settings.sections.stats';
@@ -220,7 +215,7 @@ export default class Stats extends PureComponent {
{this.state.achievements.map((achievement, index) => {
if (achievement.achieved) {
- return achievementElement(index, achievement.name, achievement.achieved);
+ return achievementElement(index, achievement.id, achievement.achieved);
}
})}
diff --git a/src/features/modals/main/tabs/Addons.jsx b/src/features/modals/main/tabs/Addons.jsx
index 2c42d393..3af185ec 100644
--- a/src/features/modals/main/tabs/Addons.jsx
+++ b/src/features/modals/main/tabs/Addons.jsx
@@ -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 (
diff --git a/src/features/modals/main/tabs/Marketplace.jsx b/src/features/modals/main/tabs/Marketplace.jsx
index a158c562..cd87863a 100644
--- a/src/features/modals/main/tabs/Marketplace.jsx
+++ b/src/features/modals/main/tabs/Marketplace.jsx
@@ -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 (
diff --git a/src/i18n/locales/achievements/en_GB.json b/src/i18n/locales/achievements/en_GB.json
index 8dcc1526..4d63ede3 100644
--- a/src/i18n/locales/achievements/en_GB.json
+++ b/src/i18n/locales/achievements/en_GB.json
@@ -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"
+ }
+}
\ No newline at end of file
diff --git a/src/i18n/locales/achievements/index.js b/src/i18n/locales/achievements/index.js
deleted file mode 100644
index 562c6219..00000000
--- a/src/i18n/locales/achievements/index.js
+++ /dev/null
@@ -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;
diff --git a/src/i18n/locales/en_GB.json b/src/i18n/locales/en_GB.json
index 735ab71a..24c7c909 100644
--- a/src/i18n/locales/en_GB.json
+++ b/src/i18n/locales/en_GB.json
@@ -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"
}
}
diff --git a/src/utils/achievements/index.js b/src/utils/achievements/index.js
new file mode 100644
index 00000000..9e49e634
--- /dev/null
+++ b/src/utils/achievements/index.js
@@ -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
+};
\ No newline at end of file
diff --git a/src/utils/data/achievements.json b/src/utils/data/achievements.json
index ddd6b44d..18a1cc75 100644
--- a/src/utils/data/achievements.json
+++ b/src/utils/data/achievements.json
@@ -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
+ }
+ }
+]