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
|
// add new line
|
||||||
fs.appendFileSync('../src/i18n/locales/' + file, '\n');
|
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 {
|
.carousel_container {
|
||||||
display: flex;
|
display: flex;
|
||||||
-webkit-touch-callout: none;
|
-webkit-touch-callout: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
-webkit-tap-highlight-color: transparent;
|
-webkit-tap-highlight-color: transparent;
|
||||||
margin-left: -10px;
|
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 variables from 'config/variables';
|
||||||
import { MdClose } from 'react-icons/md';
|
import { MdClose } from 'react-icons/md';
|
||||||
import { Tooltip } from 'components/Elements';
|
import { Tooltip } from 'components/Elements';
|
||||||
|
|
||||||
function SideloadFailedModal({ modalClose, reason }) {
|
function SideloadFailedModal({ modalClose, reason }) {
|
||||||
return (
|
return (
|
||||||
<div className="smallModal">
|
<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 variables from 'config/variables';
|
||||||
import { PureComponent, Fragment } from 'react';
|
import { PureComponent, Fragment } from 'react';
|
||||||
import { Tooltip } from 'components/Elements';
|
|
||||||
import ImageCarousel from 'features/helpers/carousel/Carousel';
|
|
||||||
import { toast } from 'react-toastify';
|
import { toast } from 'react-toastify';
|
||||||
import {
|
import {
|
||||||
MdIosShare,
|
MdIosShare,
|
||||||
|
@ -21,7 +19,7 @@ import { Header } from 'components/Layout/Settings';
|
||||||
import { Button } from 'components/Elements';
|
import { Button } from 'components/Elements';
|
||||||
|
|
||||||
import { install, uninstall } from 'utils/marketplace';
|
import { install, uninstall } from 'utils/marketplace';
|
||||||
|
import { Carousel } from '../Elements/Carousel';
|
||||||
import { ShareModal } from 'components/Elements';
|
import { ShareModal } from 'components/Elements';
|
||||||
|
|
||||||
class Item extends PureComponent {
|
class Item extends PureComponent {
|
||||||
|
@ -124,7 +122,7 @@ class Item extends PureComponent {
|
||||||
{this.props.data.data.photos && (
|
{this.props.data.data.photos && (
|
||||||
<div className="carousel">
|
<div className="carousel">
|
||||||
<div className="carousel_container">
|
<div className="carousel_container">
|
||||||
<ImageCarousel data={this.props.data.data.photos} />
|
<Carousel data={this.props.data.data.photos} />
|
||||||
</div>
|
</div>
|
||||||
</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 { MdAutoFixHigh, MdOutlineArrowForward, MdOutlineOpenInNew } from 'react-icons/md';
|
||||||
|
|
||||||
import { Button } from 'components/Elements';
|
import { Button } from 'components/Elements';
|
||||||
|
import MemoizedLightbox from '../Elements/Lightbox/Lightbox';
|
||||||
|
|
||||||
function Items({
|
function Items({
|
||||||
type,
|
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 { toast } from 'react-toastify';
|
||||||
import Modal from 'react-modal';
|
import Modal from 'react-modal';
|
||||||
|
|
||||||
import SideloadFailedModal from '../SideloadFailedModal';
|
import { SideloadFailedModal } from '../components/Elements/SideloadFailedModal/SideloadFailedModal';
|
||||||
import FileUpload from '../../../../../components/Form/Settings/FileUpload/FileUpload';
|
import Item from '../components/Items/Item';
|
||||||
import Item from '../Item';
|
import Items from '../components/Items/Items';
|
||||||
import Items from '../Items';
|
import { Dropdown, FileUpload } from 'components/Form/Settings';
|
||||||
import Dropdown from '../../../../../components/Form/Settings/Dropdown/Dropdown';
|
|
||||||
import { Header, CustomActions } from 'components/Layout/Settings';
|
import { Header, CustomActions } from 'components/Layout/Settings';
|
||||||
import { Button } from 'components/Elements';
|
import { Button } from 'components/Elements';
|
||||||
|
|
|
@ -10,8 +10,8 @@ import {
|
||||||
MdLibraryAdd,
|
MdLibraryAdd,
|
||||||
} from 'react-icons/md';
|
} from 'react-icons/md';
|
||||||
|
|
||||||
import Item from '../Item';
|
import Item from '../components/Items/Item';
|
||||||
import Items from '../Items';
|
import Items from '../components/Items/Items';
|
||||||
import Dropdown from '../../../../../components/Form/Settings/Dropdown/Dropdown';
|
import Dropdown from '../../../../../components/Form/Settings/Dropdown/Dropdown';
|
||||||
import { Header } from 'components/Layout/Settings';
|
import { Header } from 'components/Layout/Settings';
|
||||||
import { Button } from 'components/Elements';
|
import { Button } from 'components/Elements';
|
|
@ -3,7 +3,7 @@ import { PureComponent, createRef } from 'react';
|
||||||
import { MdOutlineWifiOff } from 'react-icons/md';
|
import { MdOutlineWifiOff } from 'react-icons/md';
|
||||||
import Modal from 'react-modal';
|
import Modal from 'react-modal';
|
||||||
|
|
||||||
import Lightbox from '../../marketplace/Lightbox';
|
import Lightbox from '../../marketplace/components/Elements/Lightbox/Lightbox';
|
||||||
|
|
||||||
export default class Changelog extends PureComponent {
|
export default class Changelog extends PureComponent {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|
|
@ -10,31 +10,14 @@ import { Header, CustomActions } from 'components/Layout/Settings';
|
||||||
|
|
||||||
import { saveFile } from 'utils/saveFile';
|
import { saveFile } from 'utils/saveFile';
|
||||||
|
|
||||||
import achievementsData from 'utils/data/achievements.json';
|
import { translations, achievements } from 'utils/achievements';
|
||||||
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,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default class Stats extends PureComponent {
|
export default class Stats extends PureComponent {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.state = {
|
this.state = {
|
||||||
stats: JSON.parse(localStorage.getItem('statsData')) || {},
|
stats: JSON.parse(localStorage.getItem('statsData')) || {},
|
||||||
achievements: achievementsData.achievements,
|
achievements,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +62,7 @@ export default class Stats extends PureComponent {
|
||||||
this.setState({
|
this.setState({
|
||||||
stats: {},
|
stats: {},
|
||||||
});
|
});
|
||||||
toast('Stats reset');
|
toast(variables.getMessage('toasts.stats_reset'));
|
||||||
this.getAchievements();
|
this.getAchievements();
|
||||||
this.forceUpdate();
|
this.forceUpdate();
|
||||||
}
|
}
|
||||||
|
@ -92,23 +75,35 @@ export default class Stats extends PureComponent {
|
||||||
saveFile(JSON.stringify(this.state.stats, null, 2), filename);
|
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() {
|
componentDidMount() {
|
||||||
this.getAchievements();
|
this.getAchievements();
|
||||||
this.forceUpdate();
|
this.forceUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const achievementElement = (key, name, achieved) => (
|
const achievementElement = (key, id, achieved) => {
|
||||||
<div className="achievement">
|
const { name, description } = this.getLocalisedAchievementData(id);
|
||||||
<FaTrophy />
|
|
||||||
<div className={'achievementContent' + (achieved ? ' achieved' : '')}>
|
return (
|
||||||
<span>{name}</span>
|
<div className="achievement" key={key}>
|
||||||
<span className="subtitle">
|
<FaTrophy />
|
||||||
{achievementLanguage[localStorage.getItem('language')][key]}
|
<div className={'achievementContent' + (achieved ? ' achieved' : '')}>
|
||||||
</span>
|
<span>{name}</span>
|
||||||
|
<span className="subtitle">{description}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
);
|
||||||
);
|
};
|
||||||
|
|
||||||
const STATS_SECTION = 'modals.main.settings.sections.stats';
|
const STATS_SECTION = 'modals.main.settings.sections.stats';
|
||||||
|
|
||||||
|
@ -220,7 +215,7 @@ export default class Stats extends PureComponent {
|
||||||
<div className="achievements">
|
<div className="achievements">
|
||||||
{this.state.achievements.map((achievement, index) => {
|
{this.state.achievements.map((achievement, index) => {
|
||||||
if (achievement.achieved) {
|
if (achievement.achieved) {
|
||||||
return achievementElement(index, achievement.name, achievement.achieved);
|
return achievementElement(index, achievement.id, achievement.achieved);
|
||||||
}
|
}
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,8 +2,8 @@ import variables from 'config/variables';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import Tabs from './backend/Tabs';
|
import Tabs from './backend/Tabs';
|
||||||
|
|
||||||
import Added from '../marketplace/sections/Added';
|
import Added from '../marketplace/views/Added';
|
||||||
import Create from '../marketplace/sections/Create';
|
import Create from '../marketplace/views/Create';
|
||||||
|
|
||||||
function Addons(props) {
|
function Addons(props) {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -2,7 +2,7 @@ import variables from 'config/variables';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
|
|
||||||
import Tabs from './backend/Tabs';
|
import Tabs from './backend/Tabs';
|
||||||
import MarketplaceTab from '../marketplace/sections/Marketplace';
|
import MarketplaceTab from '../marketplace/views/Browse';
|
||||||
|
|
||||||
function Marketplace(props) {
|
function Marketplace(props) {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,8 +1,50 @@
|
||||||
[
|
{
|
||||||
"Opened 10 tabs",
|
"10tabs": {
|
||||||
"Opened 39 tabs",
|
"name": "10/10 IGN",
|
||||||
"Opened 100 tabs",
|
"description": "Opened 10 tabs"
|
||||||
"Opened 305 tabs",
|
},
|
||||||
"Installed an add-on",
|
"thankyou": {
|
||||||
"Installed 5 add-ons"
|
"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",
|
"error": "Something went wrong",
|
||||||
"imported": "Successfully imported",
|
"imported": "Successfully imported",
|
||||||
"no_storage": "Not enough storage",
|
"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": [
|
{
|
||||||
{
|
"id": "10tabs",
|
||||||
"name": "10/10 IGN",
|
"condition": {
|
||||||
"description": "Opened 10 tabs",
|
"type": "tabsOpened",
|
||||||
"condition": {
|
"amount": 10
|
||||||
"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": "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