Darkness falls, code rises

This commit is contained in:
David Ralph 2023-12-28 22:23:23 +00:00
parent f67e732da1
commit bc637374bd
245 changed files with 0 additions and 36624 deletions

View File

@ -1,3 +0,0 @@
{
"extends": ["@commitlint/config-conventional"]
}

View File

@ -1,8 +0,0 @@
root = true
[*]
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

View File

@ -1,4 +0,0 @@
module.exports = {
extends: ['react-app', 'prettier'],
ignorePatterns: ['node_modules/', 'build/', 'coverage/', '*.scss', '*.css', '*.json'],
};

View File

@ -1,7 +0,0 @@
{
"printWidth": 100,
"trailingComma": "all",
"tabWidth": 2,
"semi": true,
"singleQuote": true
}

View File

@ -1,9 +0,0 @@
{
"extends": ["stylelint-config-standard-scss"],
"plugins": ["stylelint-scss"],
"rules": {
"selector-class-pattern": null,
"no-descending-specificity": null,
"scss/no-global-function-names": null
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

View File

@ -1,40 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/png" sizes="32x32" href="./icons/32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="./icons/16x16.png" />
<title>New Tab</title>
</head>
<body>
<noscript>
<style>
*,
a {
font-family: 'Lexend Deca', sans-serif;
text-align: center;
color: black;
background: white !important;
}
@media (prefers-color-scheme: dark) {
*,
a {
color: white;
background: #2f3640 !important;
}
}
</style>
<h1>Error</h1>
<h2>You need to enable JavaScript to use Mue</h2>
<p>
Having trouble? Contact us:
<a href="https://muetab.com/contact">https://muetab.com/contact</a>
</p>
</noscript>
<div id="root"></div>
<script type="module" src="/src/index.jsx"></script>
</body>
</html>

View File

@ -1,7 +0,0 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es6"
},
"exclude": ["node_modules"]
}

View File

@ -1,8 +0,0 @@
{
"name": {
"message": "Mue"
},
"description": {
"message": "Fast, open and free-to-use new tab page for modern browsers."
}
}

View File

@ -1,8 +0,0 @@
{
"name": {
"message": "Mue"
},
"description": {
"message": "Fast, open and free-to-use new tab page for modern browsers."
}
}

View File

@ -1,8 +0,0 @@
{
"name": {
"message": "Mue"
},
"description": {
"message": "Fast, open and free-to-use new tab page for modern browsers."
}
}

View File

@ -1,8 +0,0 @@
{
"name": {
"message": "Mue"
},
"description": {
"message": "Fast, open and free-to-use new tab page for modern browsers."
}
}

View File

@ -1,8 +0,0 @@
{
"name": {
"message": "Mue"
},
"description": {
"message": "Fast, open and free-to-use new tab page for modern browsers."
}
}

View File

@ -1,8 +0,0 @@
{
"name": {
"message": "Mue"
},
"description": {
"message": "Fast, open and free-to-use new tab page for modern browsers."
}
}

View File

@ -1,8 +0,0 @@
{
"name": {
"message": "Mue"
},
"description": {
"message": "Fast, open and free-to-use new tab page for modern browsers."
}
}

View File

@ -1,8 +0,0 @@
{
"name": {
"message": "Mue"
},
"description": {
"message": "Fast, open and free-to-use new tab page for modern browsers."
}
}

View File

@ -1,8 +0,0 @@
{
"name": {
"message": "Mue"
},
"description": {
"message": "Fast, open and free-to-use new tab page for modern browsers."
}
}

View File

@ -1,8 +0,0 @@
{
"name": {
"message": "Mue"
},
"description": {
"message": "Modern tarayıcılar için hızlı, açık ve kullanımı ücretsiz yeni sekme sayfası."
}
}

View File

@ -1,8 +0,0 @@
{
"name": {
"message": "Mue"
},
"description": {
"message": "Fast, open and free-to-use new tab page for modern browsers."
}
}

View File

@ -1,10 +0,0 @@
/* eslint-disable no-undef */
chrome.runtime.setUninstallURL('https://muetab.com/uninstall');
chrome.runtime.onInstalled.addListener((details) => {
if (details.reason === 'install') {
chrome.tabs.create({
url: chrome.runtime.getURL('index.html'),
});
}
});

View File

@ -1,10 +0,0 @@
/* eslint-disable no-undef */
browser.runtime.setUninstallURL('https://muetab.com/uninstall');
browser.runtime.onInstalled.addListener((details) => {
if (details.reason === 'install') {
browser.tabs.create({
url: browser.runtime.getURL('index.html'),
});
}
});

View File

@ -1,23 +0,0 @@
{
"manifest_version": 3,
"offline_enabled": true,
"default_locale": "en",
"name": "__MSG_name__",
"description": "__MSG_description__",
"version": "7.0.0",
"homepage_url": "https://muetab.com",
"action": {
"default_icon": "icons/128x128.png"
},
"chrome_url_overrides": {
"newtab": "index.html"
},
"icons": {
"16": "icons/16x16.png",
"48": "icons/48x48.png",
"128": "icons/128x128.png"
},
"background": {
"service_worker": "background.js"
}
}

View File

@ -1,21 +0,0 @@
{
"manifest_version": 3,
"name": "Mue",
"description": "Fast, open and free-to-use new tab page for modern browsers.",
"version": "7.0.0",
"homepage_url": "https://muetab.com",
"action": {
"default_icon": "icons/128x128.png"
},
"chrome_url_overrides": {
"newtab": "index.html"
},
"icons": {
"16": "icons/16x16.png",
"48": "icons/48x48.png",
"128": "icons/128x128.png"
},
"chrome_settings_overrides": {
"homepage": "index.html"
}
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 645 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

View File

@ -1 +0,0 @@
<svg width="783" height="702" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#a)"><path d="m400.51 1.53-25.446 6.562L61.56 88.94 36.113 95.5a48.18 48.18 0 0 0-34.582 58.618l110.341 427.877a48.183 48.183 0 0 0 22.157 29.413 48.183 48.183 0 0 0 36.46 5.17l.066-.017 364.265-93.936.066-.017a48.18 48.18 0 0 0 34.583-58.618L459.128 36.113A48.18 48.18 0 0 0 400.51 1.53z" fill="#F2F2F2"/><path d="m403.969 14.945-30.139 7.773-304.119 78.426-30.139 7.772a34.312 34.312 0 0 0-24.627 41.743l110.341 427.878a34.307 34.307 0 0 0 41.743 24.627l.065-.017L531.36 509.21l.066-.017a34.308 34.308 0 0 0 24.627-41.743L445.712 39.573a34.31 34.31 0 0 0-41.743-24.628z" fill="#fff"/><path d="m381.212 153.503-184.273 47.521a8.016 8.016 0 0 1-9.761-5.759 8.014 8.014 0 0 1 5.759-9.762l184.273-47.52a8.012 8.012 0 0 1 9.754 5.761 8.01 8.01 0 0 1-5.752 9.759zM419.977 171.439l-216.284 55.775a8.01 8.01 0 0 1-9.761-5.759 8.011 8.011 0 0 1 5.759-9.761l216.284-55.775a8.011 8.011 0 0 1 9.761 5.759 8.012 8.012 0 0 1-5.759 9.761zM411.48 270.877l-184.273 47.52a8.014 8.014 0 0 1-4.003-15.52l184.273-47.521a8.014 8.014 0 0 1 4.003 15.521zM450.245 288.813l-216.284 55.775a8.014 8.014 0 0 1-4.003-15.521l216.284-55.775a8.015 8.015 0 0 1 4.003 15.521zM441.748 388.25l-184.273 47.521a8.017 8.017 0 0 1-9.756-5.761 8.011 8.011 0 0 1 5.753-9.76l184.273-47.52a8.014 8.014 0 0 1 4.003 15.52zM480.513 406.186l-216.284 55.775a8 8 0 0 1-6.077-.854 8.019 8.019 0 0 1-3.866-8.027 8.01 8.01 0 0 1 3.121-5.284 8.006 8.006 0 0 1 2.82-1.355l216.284-55.775a8.011 8.011 0 0 1 9.761 5.759 8.012 8.012 0 0 1-5.759 9.761z" fill="#F2F2F2"/><path d="m165.481 249.749-65.212 16.817a3.847 3.847 0 0 1-4.68-2.762l-14.97-58.048a3.845 3.845 0 0 1 2.761-4.681l65.213-16.817a3.85 3.85 0 0 1 4.68 2.762l14.97 58.048a3.846 3.846 0 0 1-2.762 4.681zM195.749 367.122l-65.212 16.817a3.845 3.845 0 0 1-4.681-2.761l-14.97-58.048a3.854 3.854 0 0 1 .413-2.912 3.853 3.853 0 0 1 2.349-1.769l65.212-16.817a3.849 3.849 0 0 1 4.681 2.761l14.969 58.049a3.847 3.847 0 0 1-2.761 4.68zM226.019 484.496l-65.213 16.817a3.846 3.846 0 0 1-4.681-2.762l-14.969-58.048a3.846 3.846 0 0 1 2.761-4.681l65.213-16.817a3.85 3.85 0 0 1 4.681 2.762l14.969 58.048a3.846 3.846 0 0 1-2.761 4.681zM654.658 109.992H278.34a48.179 48.179 0 0 0-48.125 48.125v441.876a48.176 48.176 0 0 0 48.125 48.125h376.318a48.184 48.184 0 0 0 48.125-48.125V158.117a48.179 48.179 0 0 0-48.125-48.125z" fill="#E6E6E6"/><path d="M654.658 123.846H278.339a34.309 34.309 0 0 0-34.271 34.271v441.876a34.312 34.312 0 0 0 34.271 34.27h376.319a34.309 34.309 0 0 0 34.271-34.27V158.117a34.309 34.309 0 0 0-34.271-34.271z" fill="#fff"/><path d="M694.194 701.88c48.519 0 87.85-39.332 87.85-87.85 0-48.519-39.331-87.851-87.85-87.851-48.518 0-87.85 39.332-87.85 87.851 0 48.518 39.332 87.85 87.85 87.85z" fill="#5352ED"/><path d="M598.022 366.656H407.72a8.018 8.018 0 0 1-8.023-8.015 8.021 8.021 0 0 1 2.351-5.67 8.005 8.005 0 0 1 5.672-2.344h190.302a8.016 8.016 0 0 1 0 16.029zM631.08 393.703H407.72a8.017 8.017 0 0 1-7.412-4.945 8.021 8.021 0 0 1 0-6.138 8.008 8.008 0 0 1 4.343-4.338 8.017 8.017 0 0 1 3.069-.607h223.36a8.013 8.013 0 1 1 0 16.028zM598.022 487.869H407.72a8.017 8.017 0 0 1-7.412-4.945 8.021 8.021 0 0 1 0-6.138 8.008 8.008 0 0 1 4.343-4.338 8.017 8.017 0 0 1 3.069-.607h190.302a8.013 8.013 0 1 1 0 16.028zM631.08 514.917H407.72a8.018 8.018 0 0 1-8.023-8.014 8.014 8.014 0 0 1 8.023-8.015h223.36a8.027 8.027 0 0 1 5.673 2.344 8.02 8.02 0 0 1 0 11.341 8.016 8.016 0 0 1-5.673 2.344zM365.093 405.982h-67.346a3.847 3.847 0 0 1-3.843-3.843v-59.947a3.847 3.847 0 0 1 3.843-3.843h67.346a3.847 3.847 0 0 1 3.843 3.843v59.947a3.85 3.85 0 0 1-3.843 3.843zM365.093 527.195h-67.346a3.847 3.847 0 0 1-3.843-3.843v-59.947a3.847 3.847 0 0 1 3.843-3.843h67.346a3.847 3.847 0 0 1 3.843 3.843v59.947a3.847 3.847 0 0 1-3.843 3.843z" fill="#E6E6E6"/><path d="M598.234 231.721H457.932a8.015 8.015 0 1 1 0-16.028h140.302a8.015 8.015 0 1 1 0 16.028zM631.292 258.769h-173.36a8.009 8.009 0 0 1-7.404-4.948 8.005 8.005 0 0 1 0-6.133 8.011 8.011 0 0 1 7.404-4.948h173.36a8.016 8.016 0 0 1 5.667 13.681 8.016 8.016 0 0 1-5.667 2.348z" fill="#CCC"/><path d="M426.882 291.547H297.536a3.845 3.845 0 0 1-3.843-3.843V186.757a3.847 3.847 0 0 1 3.843-3.843h129.346a3.847 3.847 0 0 1 3.843 3.843v100.947a3.843 3.843 0 0 1-1.127 2.716 3.843 3.843 0 0 1-2.716 1.127z" fill="#5352ED"/><path d="M700.5 648v-57a6.5 6.5 0 1 0-13 0v57a6.5 6.5 0 1 0 13 0z" fill="#fff" stroke="#fff" stroke-width="5"/><path d="m728.202 621.069.609-.571a6.5 6.5 0 0 0 .33-9.154l-30.362-32.861a6.5 6.5 0 0 0-9.548-.001l-30.371 32.862a6.5 6.5 0 0 0 .329 9.154l.61.571a6.498 6.498 0 0 0 9.219-.332l23.885-25.853a1.5 1.5 0 0 1 2.204 0l23.875 25.852a6.5 6.5 0 0 0 9.22.333z" fill="#fff" stroke="#fff" stroke-width="5"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h782.044v701.88H0z"/></clipPath></defs></svg>

Before

Width:  |  Height:  |  Size: 4.7 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.7 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.2 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 36 KiB

View File

@ -1 +0,0 @@
<svg data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" width="769.001" height="771.636"><path d="M769.001 0H310.286a400.77 400.77 0 0 0-5.285 65c0 219.81 178.191 398 398 398a400.7 400.7 0 0 0 66-5.45z" fill="#2f2e41"/><path d="M574.85 248.809a57.4 57.4 0 0 1-20.163-3.64 3 3 0 1 1 2.106-5.617 52.393 52.393 0 0 0 51.263-8.531c-22.038.234-43.595-10.18-54.32-26.893-6.894-10.743-9.148-23.384-6.52-36.558a65.225 65.225 0 0 1 12.09-26.277 52.051 52.051 0 0 0-36.024 54.65 3 3 0 1 1-5.971.592 58.044 58.044 0 0 1 49.792-63.138 3 3 0 0 1 2.55 5.076C554.31 154.06 545 179.402 558.787 200.888c10.878 16.95 34.283 26.644 56.928 23.58a3 3 0 0 1 2.642 4.968 58.387 58.387 0 0 1-43.507 19.373z" fill="#6c63ff"/><path d="M527.001 250a22 22 0 1 1 22-22 22.025 22.025 0 0 1-22 22zm0-38a16 16 0 1 0 16 16 16.018 16.018 0 0 0-16-16z" fill="#6c63ff"/><path d="M8.69 567.078A10.276 10.276 0 0 1 .42 554.027l7.788-26.48 11.835 2.218.509 26.967a10.276 10.276 0 0 1-11.86 10.346z" fill="#9f616a"/><path fill="#2f2e41" d="m76.996 736.132-14.793-2.219 3.698-144.235-20.71 62.132-11.095 87.281-14.054-3.698-2.959-90.979 16.273-107.252 81.363 18.492-37.723 180.478z"/><path d="M70.205 771.636a10.873 10.873 0 0 1-10.873-10.873q0-.533.052-1.064l2.297-23.354a3.428 3.428 0 0 1 1.784-2.678c4.36-2.352 8.845-1.782 13.434 1.288a3.407 3.407 0 0 1 1.48 2.429l2.623 22.098a10.873 10.873 0 0 1-10.797 12.154zM9.82 769.898a9.794 9.794 0 0 1-4.754-14.662l15.78-23.457c5.689-4.082 9.12-2.094 10.454 5.534l3.19-7.993 2.404 2.622a7.647 7.647 0 0 1 .404 9.854l-16.368 24.91a9.794 9.794 0 0 1-11.11 3.192z" fill="#2f2e41"/><circle cx="109.542" cy="375.915" r="22.19" fill="#9f616a"/><path d="M123.595 416.596 85.872 409.2c4.86-10.364 8.75-13.87 4.438-25.15h30.327c-2.675 11.683-.09 22.648 2.958 32.546z" fill="#9f616a"/><path d="m119.157 566.009-88.76-25.149c17.78-39.13 21.503-82.09 16.232-127.504a8.217 8.217 0 0 1 7.207-9.116q.15-.017.3-.03c11.578-.953 23.648-2.177 36.174-3.886l14.054 9.615 16.273-3.698c5.221 2.53 10.48 4.636 15.227 6.734a19.038 19.038 0 0 1 10.35 23.414c-14.462 43.677-24.143 86.94-27.057 129.62z" fill="#e6e6e6"/><path d="m22.261 532.724-17.012-2.22L45.55 414.38c2.05-5.907 7.134-9.104 13.323-9.988l5.918.74-4.438 68.788zM155.525 510.524a13.484 13.484 0 0 1-13.487-8.271l-16.224-39.058 13.314-48.078 3.52 2.24q.509.323 1.004.663a31.653 31.653 0 0 1 13.002 31.471l-3.472 20.361 14.323 30.753a13.484 13.484 0 0 1-11.98 9.92z" fill="#e6e6e6"/><path d="M111.248 343.027a23.564 23.564 0 0 1 10.766 3.17c.755.439.406 2.022 1.103 2.539.878.65 2.785.255 3.563 1.017a23.615 23.615 0 0 1 7.022 19.026l-1.238 12.311-2.921-3.194a30.448 30.448 0 0 0-20.305-9.97q-.497-.033-.996-.052l2.247-3.933-3.905 3.906a38.03 38.03 0 0 0-5.321.433l2.988-5.23-5.734 5.734a15.331 15.331 0 0 0-10.713 8.738l-.637 1.411-.713-11.745a23.674 23.674 0 0 1 23.154-24.182q.82-.018 1.64.02z" fill="#2f2e41"/><ellipse cx="131.877" cy="380.205" rx="1.782" ry="4.233" fill="#9f616a"/><ellipse cx="87.319" cy="378.868" rx="1.782" ry="4.233" fill="#9f616a"/><path d="M174.034 435.42a10.276 10.276 0 0 1 7.134 13.706L171.16 474.85l-11.604-3.216 1.782-26.913a10.276 10.276 0 0 1 12.696-9.302z" fill="#9f616a"/><path fill="#e6e6e6" d="m160.579 509.055-18.492-11.835 15.533-31.806 19.231 7.397-9.615 28.107-6.657 8.137z"/><path d="M173.001 409.101V284h-2v125.101a5 5 0 1 0 2 0zm-1 7.899a3 3 0 1 1 3-3 3.003 3.003 0 0 1-3 3z" fill="#3f3d56"/><path d="M170.435 164.57a4.314 4.314 0 0 1-4.314-4.315v-12.941a4.314 4.314 0 0 1 8.627 0v12.941a4.314 4.314 0 0 1-4.313 4.314zM170.435 263.787a4.314 4.314 0 0 1-4.314-4.313v-12.942a4.314 4.314 0 1 1 8.627 0v12.942a4.314 4.314 0 0 1-4.313 4.313zM200.939 177.203a4.314 4.314 0 0 1-3.05-7.364l9.15-9.15a4.314 4.314 0 0 1 6.1 6.1l-9.15 9.15a4.3 4.3 0 0 1-3.05 1.264zM130.78 247.362a4.314 4.314 0 0 1-3.05-7.364l9.15-9.15a4.314 4.314 0 0 1 6.1 6.1l-9.15 9.151a4.3 4.3 0 0 1-3.05 1.263zM226.514 207.708h-12.941a4.314 4.314 0 0 1 0-8.628h12.941a4.314 4.314 0 1 1 0 8.628zM127.296 207.708h-12.941a4.314 4.314 0 1 1 0-8.628h12.941a4.314 4.314 0 0 1 0 8.628zM210.09 247.362a4.3 4.3 0 0 1-3.05-1.263l-9.152-9.15a4.314 4.314 0 1 1 6.101-6.101l9.15 9.15a4.314 4.314 0 0 1-3.05 7.365zM139.93 177.203a4.3 4.3 0 0 1-3.05-1.263l-9.15-9.15a4.314 4.314 0 0 1 6.1-6.102l9.15 9.151a4.314 4.314 0 0 1-3.05 7.364zM170.435 229.277a25.883 25.883 0 1 1 25.883-25.883 25.912 25.912 0 0 1-25.883 25.883zm0-43.139a17.255 17.255 0 1 0 17.255 17.256 17.275 17.275 0 0 0-17.255-17.256z" fill="#6c63ff"/></svg>

Before

Width:  |  Height:  |  Size: 4.4 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 22 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 7.9 KiB

View File

@ -1 +0,0 @@
<svg width="400" height="100" viewBox="0 0 629 160" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M502.973 139.536h68.977L606.438 79.8 571.95 20.064h-68.977L468.484 79.8l34.489 59.736zM56.973 138.577h68.977l34.488-59.736-34.488-59.735H56.973L22.484 78.84l34.489 59.736zM279.973 139.616h68.977l34.488-59.736-34.488-59.735h-68.977L245.484 79.88l34.489 59.736z" fill="#F2F2F2"/><path d="M357.693 159.759h-86.464a5.019 5.019 0 0 1-4.33-2.5l-43.231-74.88a5.009 5.009 0 0 1 0-5L266.899 2.5a5.02 5.02 0 0 1 4.33-2.5h86.464a5.015 5.015 0 0 1 4.33 2.5l43.231 74.879a5.009 5.009 0 0 1 0 5l-43.231 74.88a5.018 5.018 0 0 1-4.33 2.5zM271.229 2a3.008 3.008 0 0 0-2.598 1.5L225.4 78.38a3.003 3.003 0 0 0 0 3l43.231 74.88a3.011 3.011 0 0 0 2.598 1.5h86.464a3.012 3.012 0 0 0 2.597-1.5l43.232-74.88a3.003 3.003 0 0 0 0-3L360.29 3.5a2.999 2.999 0 0 0-2.597-1.5h-86.464zM134.693 159.759H48.229a5.018 5.018 0 0 1-4.33-2.5L.668 82.379a5.015 5.015 0 0 1 0-5L43.899 2.5A5.014 5.014 0 0 1 48.23 0h86.464a5.015 5.015 0 0 1 4.33 2.5l43.231 74.879a5.009 5.009 0 0 1 0 5l-43.231 74.88a5.018 5.018 0 0 1-4.33 2.5zM48.229 2a3.008 3.008 0 0 0-2.598 1.5L2.4 78.379a3.009 3.009 0 0 0 0 3l43.231 74.88a3.011 3.011 0 0 0 2.598 1.5h86.464a3.012 3.012 0 0 0 2.597-1.5l43.232-74.88a3.003 3.003 0 0 0 0-3L137.29 3.5a2.999 2.999 0 0 0-2.597-1.5H48.229zM580.693 159.759H494.23a5.013 5.013 0 0 1-4.331-2.5l-43.231-74.88a5.009 5.009 0 0 1 0-5L489.899 2.5A5.016 5.016 0 0 1 494.23 0h86.463a5.015 5.015 0 0 1 4.33 2.5l43.231 74.879a5.009 5.009 0 0 1 0 5l-43.231 74.88a5.016 5.016 0 0 1-4.33 2.5zM494.23 2a3.01 3.01 0 0 0-2.599 1.5L448.4 78.379a3.003 3.003 0 0 0 0 3l43.231 74.88a3.011 3.011 0 0 0 2.599 1.5h86.463a3.012 3.012 0 0 0 2.598-1.5l43.231-74.88a3.003 3.003 0 0 0 0-3L583.291 3.5a3.009 3.009 0 0 0-2.598-1.5H494.23z" fill="#CCC"/><path d="M91.461 45.863a32.977 32.977 0 1 0 0 65.954 32.977 32.977 0 0 0 0-65.954zm0 9.893a9.893 9.893 0 1 1 0 19.786 9.893 9.893 0 0 1 0-19.786zm0 47.626a24.026 24.026 0 0 1-19.786-10.559c.159-6.595 13.19-10.226 19.786-10.226 6.595 0 19.628 3.631 19.786 10.226a24.062 24.062 0 0 1-19.786 10.559zM314.397 56.907a17.995 17.995 0 0 0-12.604-5.58 18.005 18.005 0 0 0-12.851 31.035l26.067 26.068 25.456-25.456a18.44 18.44 0 0 0-.306-25.761 18.44 18.44 0 0 0-25.762-.306zM558.697 59.821c0 11.728-21.235 37.474-21.235 37.474s-21.235-25.746-21.235-37.474a21.223 21.223 0 0 1 6.207-15.02 21.236 21.236 0 0 1 36.263 14.985v.035z" fill="#5352ED"/><path d="M537.462 68.163a8.342 8.342 0 1 0 0-16.684 8.342 8.342 0 0 0 0 16.684z" fill="#fff"/><path d="M536.702 121.029a8.342 8.342 0 1 0 0-16.685 8.342 8.342 0 0 0 0 16.685z" fill="#5352ED"/></svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -1 +0,0 @@
<svg width="1066" height="774" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#a)"><path opacity=".1" d="M995.19 369.87c.59-6.77.9-13.65.9-20.6 0-108.83-73.84-197.06-164.92-197.06-29 0-56.34 9-80 24.75-64.47-50-148.64-80.21-240.72-80.21-149.83 0-278.71 80.07-335.89 194.9a138.6 138.6 0 0 0-9.6-.34C73.83 291.31 0 379.53 0 488.36c0 40 10 77.23 27.14 108.31 0 97.91 78.45 177.31 175.22 177.31h122l.54-.93c7.17-11.64 24.34-14.55 36.3-7.94 3.16 1.74 6.1 4 9.63 4.8 14.13 3 23.62-19.73 37.92-17.52 7.18 1.11 12.78 8.53 20 7.77 4.79-.51 8.42-4.52 12.92-6.22 7.21-2.74 14.52 1.06 19.57 7.23 2.93-8.43 2.91-18.42 7.65-26.15 7.17-11.64 24.34-14.55 36.3-7.94 3.16 1.74 6.1 4 9.63 4.8 14.13 3 23.62-19.73 37.92-17.52 7.18 1.11 12.78 8.53 20 7.77 4.79-.51 8.42-4.52 12.92-6.22 11.22-4.27 22.71 7.32 25.47 19a81.066 81.066 0 0 1 1.69 15.64c9.68-4.69 17.86-17.88 28.91-16.17 7.18 1.11 12.78 8.53 20 7.77 4.79-.51 8.42-4.52 12.92-6.22 11.22-4.27 22.71 7.32 25.47 19 1.47 6.2 1.57 12.64 1.82 19h202.15c76 0 137.58-62.32 137.58-139.2 15.42-30 24.33-65.28 24.33-103.06 0-67-28-126.2-70.81-161.8z" fill="#6C63FF"/><path d="M114 582.98v-24.3l11.2 11.2 2.8-2.9-16-16-16 16 2.8 2.8 11.2-11.1v24.3h4zM789 299a6 6 0 1 0 0-12 6 6 0 0 0 0 12zM224 283a6 6 0 1 0 0-12 6 6 0 0 0 0 12zM401 435a6 6 0 1 0 0-12 6 6 0 0 0 0 12zM925 534a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM700 617a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM315 687a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM96 444a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM125 380a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM957 492a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM770 716a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM215 612a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM284 337a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM386.5 227.5H371V212h-2v15.5h-15.5v2H369V245h2v-15.5h15.5v-2zM764 513.89h-9.39v-9.39h-1.22v9.39H744v1.22h9.39v9.39h1.22v-9.39H764v-1.22zM707 688.89h-9.39v-9.39h-1.22v9.39H687v1.22h9.39v9.39h1.22v-9.39H707v-1.22zM240 666.89h-9.39v-9.39h-1.22v9.39H220v1.22h9.39v9.39h1.22v-9.39H240v-1.22zM174 490.89h-9.39v-9.39h-1.22v9.39H154v1.22h9.39v9.39h1.22v-9.39H174v-1.22zM940 667v-24.3l11.2 11.2 2.8-2.9-16-16-16 16 2.8 2.8 11.2-11.1V667h4zM747 385a6 6 0 1 0 0-12 6 6 0 0 0 0 12zM816 618a6 6 0 1 0 0-12 6 6 0 0 0 0 12zM807 439a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM909.5 329.5H894V314h-2v15.5h-15.5v2H892V347h2v-15.5h15.5v-2zM697 592.89h-9.39v-9.39h-1.22v9.39H677v1.22h9.39v9.39h1.22v-9.39H697v-1.22z" fill="#fff"/><path d="m258.343 592.735 3.913-4.048-2.432-2.348-3.913 4.048-15.794 8.254 10.535 10.166 7.691-16.072z" fill="#5352ED"/><path d="m268.811 603.045 4.009-4.15-2.49-2.417-4.016 4.158-16.198 8.463 10.812 10.428 7.883-16.482z" fill="#5352ED"/><path d="m279.414 613.083 3.913-4.048-2.432-2.348-3.913 4.048-15.794 8.254 10.543 10.173 7.683-16.079zM354.436 685.727l4.016-4.158-2.497-2.409-4.016 4.157-16.191 8.456 10.805 10.435 7.883-16.481zM365.242 696.161l4.016-4.157-2.498-2.41-4.016 4.158-16.191 8.456 10.805 10.434 7.884-16.481zM376.047 706.596l4.016-4.158-2.498-2.409-4.016 4.157-16.191 8.456 10.805 10.435 7.884-16.481zM305.384 638.366l4.016-4.158-2.497-2.409-4.016 4.157-16.191 8.456 10.805 10.435 7.883-16.481z" fill="#5352ED"/><path d="m316.19 648.8 4.016-4.157-2.49-2.403-4.016 4.158-16.199 8.449 10.805 10.435 7.884-16.482zM326.995 659.235l4.016-4.158-2.49-2.402-4.016 4.157-16.199 8.45 10.812 10.441 7.877-16.488zM575.105 337.375c13.499-14.624 20.646-56.373 11.545-65.16-9.102-8.787-49.749.608-63.888 14.613l-.437-.411-277.74 287.63 52.795 50.972 277.733-287.623-.008-.021zM671.535 430.49c13.499-14.623 20.646-56.373 11.545-65.16-9.102-8.787-49.749.609-63.881 14.621l-.436-.412L341.022 667.17l52.795 50.971L671.55 430.518l-.015-.028z" fill="#5352ED"/><path d="M752.018 249.005c19.93-21.3 38.411-74.794 29.317-83.574-9.094-8.78-61.104 12.332-81.634 32.984l-.429-.405-407.254 421.748 52.781 50.972 407.26-421.755-.041.03z" fill="#363192"/><g opacity=".1" fill="#000"><path opacity=".1" d="M574.87 274.92c7.59-17.71 22.41-36.18 31.63-36.07 12 .14 33.62 31.79 36.07 52l.26-21.71c-.21-19.9-23.65-55.18-36.3-55.33-9.1-.11-23.64 17.88-31.32 35.38l-.34 25.73zM435.41 291.7h.6c.67-19.89 23.81-54.61 36.45-54.46 8.26.1 21.11 15.17 29.1 31.16l1.94-162.36h.59c.78-29.16 24.13-80.2 36.77-80 11.94.14 33.36 46.21 35.78 75.9l.23-20c-.11-29.17-23.36-80.77-36-80.92-12.64-.15-36 50.89-36.77 80.05h-.59l-1.94 162.36c-8-16-20.84-31.06-29.1-31.16-12.64-.15-35.78 34.57-36.45 54.46h-.6l-4.77 399.81h.3l4.46-374.84z"/></g><path d="M540.858 25.386h-.01a6.93 6.93 0 0 0-7.012 6.847l-.192 16.189a6.93 6.93 0 0 0 6.847 7.011h.01a6.93 6.93 0 0 0 7.012-6.847l.192-16.189a6.93 6.93 0 0 0-6.847-7.011z" fill="#ECECF3"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h1066v773.96H0z"/></clipPath></defs></svg>

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 308 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 274 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 171 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

View File

@ -1,39 +0,0 @@
// tl;dr this function merges the translation file with the english file in order to add untranslated strings
const fs = require('fs');
const merge = require('@eartharoid/deep-merge');
/**
* It recursively compares the keys of two JSON objects and removes the keys from the first object that
* are not present in the second object
* @param json1 - The JSON object that you want to remove keys from.
* @param json2 - The JSON object that you want to compare against.
*/
const compareAndRemoveKeys = (json1, json2) => {
for (let key in json1) {
if (json2.hasOwnProperty(key)) {
if (typeof json1[key] === 'object' && typeof json2[key] === 'object') {
compareAndRemoveKeys(json1[key], json2[key]);
}
} else {
delete json1[key];
}
}
};
fs.readdirSync('../src/translations').forEach((file) => {
if (file === 'en_GB.json') {
return;
}
const en = require('../src/translations/en_GB.json');
const newdata = merge(en, require('../src/translations/' + file));
// remove strings not in english file
compareAndRemoveKeys(newdata, en);
// write new file
fs.writeFileSync('../src/translations/' + file, JSON.stringify(newdata, null, 2));
// add new line
fs.appendFileSync('../src/translations/' + file, '\n');
});

View File

@ -1,56 +0,0 @@
import variables from 'modules/variables';
import { PureComponent } from 'react';
import { ToastContainer } from 'react-toastify';
import Background from 'components/widgets/background/Background';
import Widgets from 'components/widgets/Widgets';
import Modals from 'components/modals/Modals';
import { loadSettings, moveSettings } from 'modules/helpers/settings';
import EventBus from 'modules/helpers/eventbus';
export default class App extends PureComponent {
componentDidMount() {
// 4.0 -> 5.0 (the key below is only on 5.0)
// now featuring 5.0 -> 5.1
// the firstRun check was moved here because the old function was useless
if (!localStorage.getItem('firstRun') || !localStorage.getItem('stats')) {
moveSettings();
window.location.reload();
}
loadSettings();
EventBus.on('refresh', (data) => {
if (data === 'other') {
loadSettings(true);
}
});
variables.stats.tabLoad();
}
componentWillUnmount() {
EventBus.off('refresh');
}
render() {
return (
<>
{localStorage.getItem('background') === 'true' ? <Background /> : null}
<ToastContainer
position="bottom-right"
autoClose={localStorage.getItem('toastDisplayTime') || 2500}
newestOnTop={true}
closeOnClick
pauseOnFocusLoss
/>
<div id="center">
<Widgets />
<Modals />
</div>
</>
);
}
}

View File

@ -1,103 +0,0 @@
import { PureComponent } from 'react';
import PropTypes from 'prop-types';
import EventBus from 'modules/helpers/eventbus';
import './autocomplete.scss';
class Autocomplete extends PureComponent {
constructor(props) {
super(props);
this.state = {
filtered: [],
input: '',
autocompleteDisabled: localStorage.getItem('autocomplete') !== 'true',
};
}
onChange = (e) => {
if (this.state.autocompleteDisabled) {
return this.setState({
input: e.target.value,
});
}
this.setState({
filtered: this.props.suggestions.filter(
(suggestion) => suggestion.toLowerCase().indexOf(e.target.value.toLowerCase()) > -1,
),
input: e.target.value,
});
this.props.onChange(e.target.value);
};
onClick = (e) => {
this.setState({
filtered: [],
input: e.target.innerText,
});
this.props.onClick({
preventDefault: () => e.preventDefault(),
target: {
value: e.target.innerText,
},
});
};
componentDidMount() {
EventBus.on('refresh', (data) => {
if (data === 'search') {
this.setState({
autocompleteDisabled: localStorage.getItem('autocomplete') !== 'true',
});
}
});
}
componentWillUnmount() {
EventBus.off('refresh');
}
render() {
let autocomplete = null;
// length will only be > 0 if enabled
if (this.state.filtered.length > 0 && this.state.input.length > 0) {
autocomplete = (
<div className="suggestions">
{this.state.filtered.map((suggestion) => (
<div key={suggestion} onClick={this.onClick}>
{suggestion}
</div>
))}
</div>
);
}
return (
<div style={{ display: 'flex', flexFlow: 'column' }}>
<input
type="text"
onChange={this.onChange}
value={this.state.input}
placeholder={this.props.placeholder || ''}
autoComplete="off"
spellCheck={false}
id={this.props.id || ''}
/>
{autocomplete}
</div>
);
}
}
Autocomplete.propTypes = {
suggestions: PropTypes.arrayOf(PropTypes.string).isRequired,
onChange: PropTypes.func.isRequired,
onClick: PropTypes.func.isRequired,
placeholder: PropTypes.string,
};
export default Autocomplete;

View File

@ -1,45 +0,0 @@
@use 'scss/variables';
.suggestions {
@extend %basic;
text-align: left;
border-top-width: 0;
list-style: none;
overflow: hidden;
position: relative;
display: inline-block;
opacity: 1;
margin-top: 5px;
div {
padding: 0.5rem 0.5rem 0.5rem 20px;
font-size: 0.6em;
&:hover {
background-color: rgb(255 255 255 / 80%);
cursor: pointer;
}
}
}
.searchBar {
input[type='text']:focus + .suggestions {
opacity: 1;
}
}
.dark .suggestions {
background: rgb(0 0 0 / 70%);
color: white;
li {
&:hover {
background: rgb(0 0 0 / 70%);
}
}
}
.micActive {
box-shadow: 0 0 50px 1px #e74c3c !important;
}

View File

@ -1,85 +0,0 @@
import React, { useState, useEffect, useCallback, useRef, memo } from 'react';
import PropTypes from 'prop-types';
import { MdOutlineArrowForwardIos, MdOutlineArrowBackIos } from 'react-icons/md';
import useEmblaCarousel from 'embla-carousel-react';
import Autoplay from 'embla-carousel-autoplay';
import './carousel.scss';
function EmblaCarousel({ data }) {
const autoplay = useRef(
Autoplay({ delay: 3000, stopOnInteraction: false }, (emblaRoot) => emblaRoot.parentElement),
);
const [emblaRef, emblaApi] = useEmblaCarousel({ loop: false }, [autoplay.current]);
const [prevBtnEnabled, setPrevBtnEnabled] = useState(false);
const [nextBtnEnabled, setNextBtnEnabled] = useState(false);
const scroll = useCallback(
(direction) => {
if (!emblaApi) {
return;
}
if (direction === 'next') {
emblaApi.scrollNext();
} else {
emblaApi.scrollPrev();
}
autoplay.current.reset();
},
[emblaApi],
);
const onSelect = useCallback(() => {
if (!emblaApi) {
return;
}
setPrevBtnEnabled(emblaApi.canScrollPrev());
setNextBtnEnabled(emblaApi.canScrollNext());
}, [emblaApi]);
useEffect(() => {
if (!emblaApi) {
return;
}
onSelect();
emblaApi.on('select', onSelect);
}, [emblaApi, onSelect]);
return (
<div className="carousel">
<div className="carousel_viewport" ref={emblaRef}>
<div className="carousel_container">
{data.map((photo, index) => (
<div className="carousel_slide" key={index}>
<div className="carousel_slide_inner">
<img src={photo.url.default} alt="Marketplace example screenshot" />
</div>
</div>
))}
</div>
</div>
<button
className="carousel_button prev"
onClick={() => scroll('prev')}
disabled={!prevBtnEnabled}
>
<MdOutlineArrowBackIos />
</button>
<button
className="carousel_button next"
onClick={() => scroll('next')}
disabled={!nextBtnEnabled}
>
<MdOutlineArrowForwardIos />
</button>
</div>
);
}
EmblaCarousel.propTypes = {
data: PropTypes.arrayOf(PropTypes.object).isRequired,
};
export default memo(EmblaCarousel);

View File

@ -1,84 +0,0 @@
.carousel {
position: relative;
width: 100%;
margin-left: 5px;
}
.carousel_viewport {
overflow: hidden;
width: 100%;
&.is-draggable {
cursor: move;
cursor: grab;
}
&.is-dragging {
cursor: grabbing;
}
border-radius: 15px !important;
}
.carousel_container {
display: flex;
-webkit-touch-callout: none;
user-select: none;
-webkit-tap-highlight-color: transparent;
margin-left: -10px;
}
.carousel_slide {
position: relative;
min-width: 100%;
padding-left: 10px;
img {
position: absolute;
display: block;
top: 50%;
left: 50%;
width: auto;
min-height: 100%;
min-width: 100%;
max-width: none;
transform: translate(-50%, -50%);
}
}
.carousel_slide_inner {
position: relative;
overflow: hidden;
height: 250px;
}
.carousel_button {
outline: 0;
cursor: pointer;
touch-action: manipulation;
position: absolute;
z-index: 1;
top: 50%;
transform: translateY(-50%);
border: 0;
width: 30px !important;
height: 30px !important;
display: grid;
place-items: center;
justify-content: center;
align-items: center;
padding: 0;
&:disabled {
cursor: default;
opacity: 0.3;
}
&.prev {
left: 27px;
}
&.next {
right: 27px;
}
}

View File

@ -1,22 +0,0 @@
import { memo } from 'react';
import PropTypes from 'prop-types';
import variables from 'modules/variables';
import './preview.scss';
function Preview(props) {
return (
<div className="preview-mode">
<span className="title">{variables.getMessage('modals.main.settings.reminder.title')}</span>
<span className="subtitle">{variables.getMessage('modals.welcome.preview.description')}</span>
<button onClick={() => props.setup()}>
{variables.getMessage('modals.welcome.preview.continue')}
</button>
</div>
);
}
Preview.propTypes = {
setup: PropTypes.func.isRequired,
};
export default memo(Preview);

View File

@ -1,24 +0,0 @@
@import 'scss/variables';
.preview-mode {
@extend %basic;
position: absolute;
bottom: 1rem;
right: 1rem;
padding: 15px;
max-width: 250px;
border-radius: 12px;
z-index: 999;
text-align: left;
cursor: default;
display: flex;
flex-flow: column;
gap: 15px;
button {
@include basicIconButton(10px, 14px, ui);
gap: 20px;
}
}

View File

@ -1,132 +0,0 @@
import { memo } from 'react';
import PropTypes from 'prop-types';
import variables from 'modules/variables';
import { MdClose, MdEmail, MdContentCopy } from 'react-icons/md';
import { FaTwitter, FaFacebookF } from 'react-icons/fa';
import { AiFillWechat } from 'react-icons/ai';
import { SiTencentqq } from 'react-icons/si';
import Tooltip from '../tooltip/Tooltip';
import { toast } from 'react-toastify';
import './sharemodal.scss';
function ShareModal({ modalClose, data }) {
if (data.startsWith('https://cdn.')) {
data = {
url: data,
name: 'this image',
};
} else if (data.startsWith('"')) {
data = {
url: data,
name: 'this quote',
};
} else {
data = {
url: data,
name: 'this marketplace item',
};
}
const copyLink = () => {
navigator.clipboard.writeText(data.url);
toast(variables.getMessage('modals.share.copy_link'));
};
return (
<div className="smallModal">
<div className="shareHeader">
<span className="title">{variables.getMessage('widgets.quote.share')}</span>
<Tooltip title={variables.getMessage('modals.welcome.buttons.close')}>
<div className="close" onClick={modalClose}>
<MdClose />
</div>
</Tooltip>
</div>
<div className="shareButtons">
<Tooltip title="Twitter">
<button
onClick={() =>
window
.open(
`https://twitter.com/intent/tweet?text=Check out ${data.name} on @getmue: ${data.url}`,
'_blank',
)
.focus()
}
>
<FaTwitter />
</button>
</Tooltip>
<Tooltip title="Facebook">
<button
onClick={() =>
window
.open(`https://www.facebook.com/sharer/sharer.php?u=${data.url}`, '_blank')
.focus()
}
>
<FaFacebookF />
</button>
</Tooltip>
<Tooltip title="Email">
<button
onClick={() =>
window
.open(
'mailto:email@example.com?subject=Check%20out%20this%20%on%20%Mue!&body=' +
data.data.name +
'on Mue: ' +
data,
'_blank',
)
.focus()
}
>
<MdEmail />
</button>
</Tooltip>
<Tooltip title="WeChat">
<button
onClick={() =>
window
.open(
`https://api.qrserver.com/v1/create-qr-code/?size=154x154&data=${data.url}`,
'_blank',
)
.focus()
}
>
<AiFillWechat />
</button>
</Tooltip>
<Tooltip title="Tencent QQ">
<button
onClick={() =>
window
.open(`http://connect.qq.com/widget/shareqq/index.html?url=${data.url}`, '_blank')
.focus()
}
>
<SiTencentqq />
</button>
</Tooltip>
</div>
<div className="copy">
<input type="text" value={data.url} className="left field" readOnly />
<Tooltip title={variables.getMessage('modals.share.copy_link')} placement="top">
<button onClick={() => copyLink()}>
<MdContentCopy />
</button>
</Tooltip>
</div>
</div>
);
}
ShareModal.propTypes = {
modalClose: PropTypes.func.isRequired,
data: PropTypes.string.isRequired,
};
export default memo(ShareModal);

View File

@ -1,110 +0,0 @@
@import 'scss/variables';
.smallModal {
@extend %tabText;
display: flex;
flex-flow: column;
gap: 15px;
padding: 15px;
width: 320px;
@include themed {
background: t($modal-secondaryColour);
}
.resetFooter {
display: flex;
flex-flow: row;
justify-content: flex-end;
gap: 20px;
button {
gap: 20px;
display: flex;
flex-flow: row;
}
}
.textButton {
@include basicIconButton(11px, 1.3rem, modal-text);
border: none !important;
}
.tooltipTitle {
@include themed {
background: t($modal-sidebar);
box-shadow: 0 0 0 1px t($modal-sidebarActive);
color: t($color);
}
}
.shareButtons {
justify-content: space-between;
display: flex;
gap: 15px;
}
button {
place-items: center;
display: grid;
@include basicIconButton(11px, 1.3rem, modal);
}
.copy {
display: flex;
flex-flow: row;
gap: 15px;
input[type='text'] {
@include themed {
background: t($modal-sidebar);
border-radius: t($borderRadius);
box-shadow: 0 0 0 1px t($modal-sidebarActive);
padding: 11px;
flex: 1;
color: t($color);
}
border: none;
outline: none;
}
}
input[type='text'] {
@include themed {
background: t($modal-sidebar);
border-radius: t($borderRadius);
box-shadow: 0 0 0 1px t($modal-sidebarActive);
padding: 11px;
flex: 1;
color: t($color);
}
border: none;
outline: none;
}
.close {
padding: 15px;
place-items: center;
display: grid;
cursor: pointer;
&:hover {
@include themed {
background: t($modal-sidebar);
border-radius: t($borderRadius);
}
}
}
}
.shareHeader {
display: flex;
flex-flow: row;
justify-content: space-between;
align-items: center;
}

View File

@ -1,54 +0,0 @@
import { useState, memo } from 'react';
import PropTypes from 'prop-types';
import { useFloating, flip, offset, shift } from '@floating-ui/react-dom';
import './tooltip.scss';
function Tooltip({ children, title, style, placement, subtitle }) {
const [showTooltip, setShowTooltip] = useState(false);
const { x, y, reference, floating, strategy } = useFloating({
placement: placement || 'bottom',
middleware: [flip(), offset(15), shift()],
});
return (
<>
<div
className="tooltip"
style={style}
onMouseEnter={() => setShowTooltip(true)}
onMouseLeave={() => setShowTooltip(false)}
onFocus={() => setShowTooltip(true)}
onBlur={() => setShowTooltip(false)}
ref={reference}
>
{children}
</div>
{showTooltip && (
<span
ref={floating}
style={{
position: strategy,
top: y ?? '',
left: x ?? '',
display: 'flex',
flexFlow: 'column',
}}
className="tooltipTitle"
>
{title}
<span style={{ fontSize: '8px' }}>{subtitle}</span>
</span>
)}
</>
);
}
Tooltip.propTypes = {
children: PropTypes.node.isRequired,
title: PropTypes.string.isRequired,
style: PropTypes.object,
placement: PropTypes.string,
subtitle: PropTypes.string.isRequired,
};
export default memo(Tooltip);

View File

@ -1,55 +0,0 @@
import variables from 'modules/variables';
import { useState, memo } from 'react';
import PropTypes from 'prop-types';
import { useFloating, flip, offset, shift } from '@floating-ui/react-dom';
import { MdClose, MdInfo, MdOpenInNew } from 'react-icons/md';
import Tooltip from './Tooltip';
import './tooltip.scss';
function InfoTooltip({ title, style, placement, subtitle }) {
const [showTooltip, setShowTooltip] = useState(false);
const { x, y, reference, floating, strategy } = useFloating({
placement: placement || 'top-start',
middleware: [flip(), offset(10), shift()],
});
return (
<div className="infoTooltip" style={style} ref={reference}>
<MdInfo onClick={() => setShowTooltip(true)} />
{showTooltip && (
<div
ref={floating}
style={{
position: strategy,
top: y ?? '',
left: x ?? '',
}}
className="infoTooltipTitle"
>
<div className="tooltipHeader">
<span className="title">{title}</span>
<Tooltip title={variables.getMessage('modals.welcome.buttons.close')}>
<div className="close" onClick={() => setShowTooltip(false)}>
<MdClose />
</div>
</Tooltip>
</div>
<span className="subtitle">{subtitle}</span>
<span className="link">
{variables.getMessage('modals.main.settings.open_knowledgebase')} <MdOpenInNew />
</span>
</div>
)}
</div>
);
}
InfoTooltip.propTypes = {
title: PropTypes.string.isRequired,
style: PropTypes.object,
placement: PropTypes.string,
subtitle: PropTypes.string.isRequired,
};
export default memo(InfoTooltip);

View File

@ -1,147 +0,0 @@
@import 'scss/variables';
.tooltip {
position: relative;
display: grid;
}
@keyframes floating {
0% {
transform: translate(0, -5px);
opacity: 0;
}
100% {
transform: translate(0, -0);
opacity: 1;
}
}
.tooltipTitle {
@extend %basic;
text-align: center;
font-size: 0.6rem;
padding: 5px 10px;
position: absolute;
z-index: 1;
/* top: 100%;
left: 50%;
margin-top: 15px;
margin-left: -30px; */
cursor: initial;
user-select: none;
opacity: 1;
animation-name: floating;
animation-duration: 0.3s;
animation-timing-function: ease-in;
}
#modal {
.tooltipTitle {
@include themed {
background: t($modal-sidebar);
box-shadow: 0 0 0 1px t($modal-sidebarActive);
color: t($color);
}
}
}
#root {
.tooltipTitle {
@extend %basic;
}
}
.tooltipTitle::before {
transform: scale3d(0.2, 0.2, 1);
transition: all 0.2s ease-in-out;
}
.tooltipTitle::after {
transform: translate3d(0, 6px, 0);
transition: all 0.1s ease-in-out;
}
.tooltipTitle:hover::before,
.tooltipTitle:hover::after {
opacity: 1;
transform: scale3d(1, 1, 1);
}
.tooltipTitle:hover::after {
transition: all 0.2s 0.1s ease-in-out;
}
#arrow {
position: absolute;
background: #333;
width: 8px;
height: 8px;
transform: rotate(45deg);
}
.infoTooltip {
position: relative;
display: grid;
svg {
cursor: pointer;
&:hover {
@include themed {
color: t($color);
}
}
}
}
.infoTooltipTitle {
min-width: 200px;
position: absolute;
z-index: 1;
cursor: initial;
user-select: none;
opacity: 1;
text-align: left;
padding: 25px;
display: flex;
justify-content: center;
flex-flow: column;
gap: 10px;
@include themed {
background-color: t($modal-background);
border-radius: t($borderRadius);
box-shadow: 0 0 0 1px t($modal-sidebarActive);
}
.tooltipHeader {
display: flex;
flex-flow: row;
align-items: center;
gap: 25px;
}
.link {
display: flex;
gap: 10px;
align-items: center;
}
.close {
font-size: 20px;
padding: 15px;
place-items: center;
display: grid;
cursor: pointer;
&:hover {
@include themed {
background: t($modal-sidebar);
border-radius: t($borderRadius);
}
}
}
}

View File

@ -1,78 +0,0 @@
import variables from 'modules/variables';
import { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { MdErrorOutline } from 'react-icons/md';
import { captureException } from '@sentry/react';
class ErrorBoundary extends PureComponent {
constructor(props) {
super(props);
this.state = {
error: false,
errorData: '',
showReport: true,
};
}
/**
* If an error occurs, log the error, and set the state to error: true, and errorData: error.
* @param {Error} error The error that occurred.
* @returns An object with two properties: error and errorData.
*/
static getDerivedStateFromError(error) {
console.log(error);
variables.stats.postEvent('modal', 'Error occurred');
return {
error: true,
errorData: error,
};
}
reportError() {
captureException(this.state.errorData);
this.setState({
showReport: false,
});
}
render() {
if (this.state.error) {
return (
<div className="emptyItems">
<div className="emptyNewMessage">
<MdErrorOutline />
<span className="title">
{variables.getMessage('modals.main.error_boundary.title')}
</span>
<span className="subtitle">
{variables.getMessage('modals.main.error_boundary.message')}
</span>
<div className="buttonsRow">
{this.state.showReport ? (
<button onClick={() => this.reportError()}>
{variables.getMessage('modals.main.error_boundary.report_error')}
</button>
) : (
<span className="subtitle">
{variables.getMessage('modals.main.error_boundary.sent')}
</span>
)}
<button className="refresh" onClick={() => window.location.reload()}>
{variables.getMessage('modals.main.error_boundary.refresh')}
</button>
</div>
</div>
</div>
);
}
return this.props.children;
}
}
ErrorBoundary.propTypes = {
children: PropTypes.node.isRequired,
};
export default ErrorBoundary;

View File

@ -1,109 +0,0 @@
import variables from 'modules/variables';
import { PureComponent } from 'react';
import Modal from 'react-modal';
import Main from './main/Main';
import Navbar from '../widgets/navbar/Navbar';
import Preview from '../helpers/preview/Preview';
import EventBus from 'modules/helpers/eventbus';
import Welcome from './welcome/Welcome';
export default class Modals extends PureComponent {
constructor() {
super();
this.state = {
mainModal: false,
updateModal: false,
welcomeModal: false,
preview: false,
};
}
componentDidMount() {
if (
localStorage.getItem('showWelcome') === 'true' &&
window.location.search !== '?nointro=true'
) {
this.setState({
welcomeModal: true,
});
variables.stats.postEvent('modal', 'Opened welcome');
}
if (window.location.search === '?nointro=true') {
if (localStorage.getItem('showWelcome') === 'true') {
localStorage.setItem('showWelcome', false);
EventBus.emit('refresh', 'widgets');
EventBus.emit('refresh', 'backgroundwelcome');
}
}
// hide refresh reminder once the user has refreshed the page
localStorage.setItem('showReminder', false);
}
closeWelcome() {
localStorage.setItem('showWelcome', false);
this.setState({
welcomeModal: false,
});
EventBus.emit('refresh', 'widgetsWelcomeDone');
EventBus.emit('refresh', 'widgets');
EventBus.emit('refresh', 'backgroundwelcome');
}
previewWelcome() {
localStorage.setItem('showWelcome', false);
localStorage.setItem('welcomePreview', true);
this.setState({
welcomeModal: false,
preview: true,
});
EventBus.emit('refresh', 'widgetsWelcome');
}
toggleModal(type, action) {
this.setState({
[type]: action,
});
if (action !== false) {
variables.stats.postEvent('modal', `Opened ${type.replace('Modal', '')}`);
}
}
render() {
return (
<>
{this.state.welcomeModal === false ? (
<Navbar openModal={(modal) => this.toggleModal(modal, true)} />
) : null}
<Modal
closeTimeoutMS={300}
id="modal"
onRequestClose={() => this.toggleModal('mainModal', false)}
isOpen={this.state.mainModal}
className="Modal mainModal"
overlayClassName="Overlay"
ariaHideApp={false}
>
<Main modalClose={() => this.toggleModal('mainModal', false)} />
</Modal>
<Modal
closeTimeoutMS={300}
onRequestClose={() => this.closeWelcome()}
isOpen={this.state.welcomeModal}
className="Modal welcomemodal mainModal"
overlayClassName="Overlay mainModal"
shouldCloseOnOverlayClick={false}
ariaHideApp={false}
>
<Welcome modalClose={() => this.closeWelcome()} modalSkip={() => this.previewWelcome()} />
</Modal>
{this.state.preview ? <Preview setup={() => window.location.reload()} /> : null}
</>
);
}
}

View File

@ -1,76 +0,0 @@
import variables from 'modules/variables';
import { Suspense, lazy, useState, memo } from 'react';
import PropTypes from 'prop-types';
import { MdClose } from 'react-icons/md';
import './scss/index.scss';
import Tooltip from 'components/helpers/tooltip/Tooltip';
// Lazy load all the tabs instead of the modal itself
const Settings = lazy(() => import('./tabs/Settings'));
const Addons = lazy(() => import('./tabs/Addons'));
const Marketplace = lazy(() => import('./tabs/Marketplace'));
const renderLoader = () => (
<div style={{ display: 'flex', width: '100%', minHeight: '100%' }}>
<ul className="sidebar">
<span className="mainTitle">Mue</span>
</ul>
<div className="tab-content" style={{ width: '100%' }}>
<div className="emptyItems">
<div className="emptyMessage">
<div className="loaderHolder">
<div id="loader"></div>
<span className="subtitle">{variables.getMessage('modals.main.loading')}</span>
</div>
</div>
</div>
</div>
</div>
);
function MainModal({ modalClose }) {
const [currentTab, setCurrentTab] = useState(0);
const changeTab = (type) => {
switch (type) {
case 'settings':
setCurrentTab(<Settings changeTab={changeTab} />);
break;
case 'addons':
setCurrentTab(<Addons changeTab={changeTab} />);
break;
case 'marketplace':
setCurrentTab(<Marketplace changeTab={changeTab} />);
break;
default:
break;
}
};
if (currentTab === 0) {
setCurrentTab(<Settings changeTab={changeTab} />);
}
return (
<div className="frame">
<Tooltip
style={{ position: 'absolute', top: '1rem', right: '1rem' }}
title={variables.getMessage('modals.welcome.buttons.close')}
key="closeTooltip"
>
<span className="closeModal" onClick={modalClose}>
<MdClose />
</span>
</Tooltip>
<Suspense fallback={renderLoader()}>{currentTab}</Suspense>
</div>
);
}
MainModal.propTypes = {
modalClose: PropTypes.func.isRequired,
};
export default memo(MainModal);

View File

@ -1,339 +0,0 @@
import variables from 'modules/variables';
import { PureComponent, Fragment } from 'react';
import PropTypes from 'prop-types';
import Tooltip from 'components/helpers/tooltip/Tooltip';
import ImageCarousel from 'components/helpers/carousel/Carousel';
import { toast } from 'react-toastify';
import {
MdIosShare,
MdFlag,
MdAccountCircle,
MdBugReport,
MdFormatQuote,
MdImage,
MdTranslate,
MdOutlineKeyboardArrowRight,
MdExpandMore,
MdExpandLess,
MdStyle,
} from 'react-icons/md';
import Modal from 'react-modal';
import { install, uninstall } from 'modules/helpers/marketplace';
import ShareModal from 'components/helpers/sharemodal/ShareModal';
class Item extends PureComponent {
constructor(props) {
super(props);
this.state = {
showLightbox: false,
showUpdateButton:
this.props.addonInstalled === true &&
this.props.addonInstalledVersion !== this.props.data.version,
showMore: false,
shareModal: false,
count: 5,
};
}
updateAddon() {
uninstall(this.props.data.type, this.props.data.display_name);
install(this.props.data.type, this.props.data);
toast(variables.getMessage('toasts.updated'));
this.setState({
showUpdateButton: false,
});
}
toggleShowMore() {
if (this.state.showMore === true) {
this.setState({ showMore: false });
} else {
this.setState({ showMore: true });
}
}
incrementCount(type) {
if (this.state.count !== this.props.data.data[type].length) {
this.setState({ count: this.props.data.data[type].length });
} else {
this.setState({ count: 5 });
}
}
render() {
if (!this.props.data.display_name) {
return null;
}
// prevent console error
let iconsrc = variables.constants.DDG_IMAGE_PROXY + this.props.data.icon;
if (!this.props.data.icon) {
iconsrc = null;
}
let updateButton;
if (this.state.showUpdateButton) {
updateButton = (
<Fragment key="update">
<button className="removeFromMue" onClick={() => this.updateAddon()}>
{variables.getMessage('modals.main.addons.product.buttons.update_addon')}
</button>
</Fragment>
);
}
return (
<div id="item">
<Modal
closeTimeoutMS={300}
isOpen={this.state.shareModal}
className="Modal mainModal"
overlayClassName="Overlay"
ariaHideApp={false}
onRequestClose={() => this.setState({ shareModal: false })}
>
<ShareModal
data={variables.constants.MARKETPLACE_URL + '/share/' + btoa(this.props.data.api_name)}
modalClose={() => this.setState({ shareModal: false })}
/>
</Modal>
<div className="flexTopMarketplace">
<span className="mainTitle" onClick={this.props.toggleFunction}>
<span className="backTitle">
{variables.getMessage('modals.main.navbar.marketplace')}
</span>
<MdOutlineKeyboardArrowRight /> {this.props.data.display_name}
</span>
</div>
<div className="itemPage">
<div className="itemShowcase">
{this.props.data.data.photos ? (
<div className="carousel">
<div className="carousel_container">
<ImageCarousel data={this.props.data.data.photos} />
</div>
</div>
) : null}
{this.props.data.data.settings ? (
<img
alt="product"
draggable={false}
src={iconsrc}
onClick={() => this.setState({ showLightbox: true })}
/>
) : null}
{this.props.data.data.quotes ? (
<>
<table>
<tbody>
<tr>
<th>{variables.getMessage('modals.main.settings.sections.quote.title')}</th>
<th>{variables.getMessage('modals.main.settings.sections.quote.author')}</th>
</tr>
{this.props.data.data.quotes.slice(0, this.state.count).map((quote, index) => (
<tr key={index}>
<td>{quote.quote}</td>
<td>{quote.author}</td>
</tr>
))}
</tbody>
</table>
<div className="showMoreItems">
<span className="link" onClick={() => this.incrementCount('quotes')}>
{this.state.count !== this.props.data.data.quotes.length ? (
<>
<MdExpandMore />{' '}
{variables.getMessage('modals.main.marketplace.product.show_all')}
</>
) : (
<>
<MdExpandLess />{' '}
{variables.getMessage('modals.main.marketplace.product.show_less')}
</>
)}
</span>
</div>
</>
) : null}
{this.props.data.data.settings ? (
<>
<table>
<tbody>
<tr>
<th>{variables.getMessage('modals.main.marketplace.product.setting')}</th>
<th>{variables.getMessage('modals.main.marketplace.product.value')}</th>
</tr>
{Object.entries(this.props.data.data.settings)
.slice(0, this.state.count)
.map(([key, value]) => (
<tr key={key}>
<td>{key}</td>
<td>{value}</td>
</tr>
))}
</tbody>
</table>
<div className="showMoreItems">
<span className="link" onClick={() => this.incrementCount('settings')}>
{this.state.count !== this.props.data.data.settings.length ? (
<>
<MdExpandMore />{' '}
{variables.getMessage('modals.main.marketplace.product.show_all')}
</>
) : (
<>
<MdExpandLess />{' '}
{variables.getMessage('modals.main.marketplace.product.show_less')}
</>
)}
</span>
</div>
</>
) : null}
<div>
<p className="title">
{variables.getMessage('modals.main.marketplace.product.description')}
</p>
<p dangerouslySetInnerHTML={{ __html: this.props.data.description }} />
</div>
<div className="moreInfo">
<div className="infoItem">
<MdBugReport />
<div className="text">
<span className="header">
{variables.getMessage('modals.main.marketplace.product.version')}
</span>
{updateButton ? (
<span>
{this.props.data.version} (Installed: {this.props.data.addonInstalledVersion})
</span>
) : (
<span>{this.props.data.version}</span>
)}
</div>
</div>
<div className="infoItem">
<MdAccountCircle />
<div className="text">
<span className="header">
{variables.getMessage('modals.main.marketplace.product.author')}
</span>
<span>{this.props.data.author}</span>
</div>
</div>
{this.props.data.data.quotes ? (
<div className="infoItem">
<MdFormatQuote />
<div className="text">
<span className="header">
{variables.getMessage('modals.main.marketplace.product.no_quotes')}
</span>
<span>{this.props.data.data.quotes.length}</span>
</div>
</div>
) : null}
{this.props.data.data.photos ? (
<div className="infoItem">
<MdImage />
<div className="text">
<span className="header">
{variables.getMessage('modals.main.marketplace.product.no_images')}
</span>
<span>{this.props.data.data.photos.length}</span>
</div>
</div>
) : null}
{this.props.data.data.quotes && this.props.data.data.language !== '' ? (
<div className="infoItem">
<MdTranslate />
<div className="text">
<span className="header">
{variables.getMessage('modals.main.settings.sections.language.title')}
</span>
<span>{this.props.data.data.language}</span>
</div>
</div>
) : null}
<div className="infoItem">
<MdStyle />
<div className="text">
<span className="header">
{' '}
{variables.getMessage('modals.main.settings.sections.background.type.title')}
</span>
<span>
{' '}
{variables.getMessage(
'modals.main.addons.create.types.' + this.props.data.data.type,
) || 'marketplace'}
</span>
</div>
</div>
</div>
</div>
<div
className="itemInfo"
style={{
backgroundImage: `url("${
variables.constants.DDG_IMAGE_PROXY + this.props.data.data.icon_url
}")`,
}}
>
<div className="front">
<img
className="icon"
alt="icon"
draggable={false}
src={variables.constants.DDG_IMAGE_PROXY + this.props.data.data.icon_url}
/>
{this.props.button}
<div className="iconButtons">
<Tooltip title={variables.getMessage('widgets.quote.share')} key="share">
<button onClick={() => this.setState({ shareModal: true })}>
<MdIosShare />
</button>
</Tooltip>
<Tooltip
title={variables.getMessage('modals.main.marketplace.product.buttons.report')}
key="report"
>
<button
onClick={() =>
window.open(
variables.constants.REPORT_ITEM +
this.props.data.display_name.split(' ').join('+'),
'_blank',
)
}
>
<MdFlag />
</button>
</Tooltip>
</div>
{this.props.data.data.collection ? (
<div className="inCollection">
<span className="subtitle">
{variables.getMessage('modals.main.marketplace.product.part_of')}
</span>
<span className="title">{this.props.data.data.collection}</span>
<button>{variables.getMessage('modals.main.marketplace.product.explore')}</button>
</div>
) : null}
</div>
</div>
</div>
</div>
);
}
}
Item.propTypes = {
data: PropTypes.object,
addonInstalled: PropTypes.bool,
addonInstalledVersion: PropTypes.string,
toggleFunction: PropTypes.func,
};
export default Item;

View File

@ -1,132 +0,0 @@
import variables from 'modules/variables';
import React, { memo } from 'react';
import PropTypes from 'prop-types';
import { MdAutoFixHigh, MdOutlineArrowForward, MdOutlineOpenInNew } from 'react-icons/md';
function Items({
type,
items,
collection,
toggleFunction,
collectionFunction,
onCollection,
filter,
}) {
return (
<>
{(type === 'all' && !onCollection && (filter === null || filter === '')) ||
(type === 'collections' && !onCollection && (filter === null || filter === '')) ? (
<>
<div
className="collection"
style={
collection.news
? { backgroundColor: collection.background_colour }
: {
backgroundImage: `linear-gradient(to right, rgba(0, 0, 0, 0.9), rgba(0, 0, 0, 0.7), transparent, rgba(0, 0, 0, 0.7), rgba(0 ,0, 0, 0.9)), url('${collection.img}')`,
}
}
>
<div className="content">
<span className="title">{collection.display_name}</span>
<span className="subtitle">{collection.description}</span>
</div>
{collection.news === true ? (
<a
className="collectionButton"
href={collection.news_link}
target="_blank"
rel="noopener noreferrer"
>
{variables.getMessage('modals.main.marketplace.learn_more')} <MdOutlineOpenInNew />
</a>
) : (
<button
className="collectionButton"
onClick={() => collectionFunction(collection.name)}
>
<MdOutlineArrowForward />
{variables.getMessage('modals.main.marketplace.explore_collection')}
</button>
)}
</div>
</>
) : null}
<div className="items">
{items
?.filter(
(item) =>
item.name.toLowerCase().includes(filter.toLowerCase()) ||
filter === '' ||
item.author.toLowerCase().includes(filter.toLowerCase()) ||
item.type.toLowerCase().includes(filter.toLowerCase()),
)
.map((item) => (
<div className="item" onClick={() => toggleFunction(item)} key={item.name}>
<img
className="item-back"
alt=""
draggable={false}
src={variables.constants.DDG_IMAGE_PROXY + item.icon_url}
aria-hidden="true"
/>
<img
className="item-icon"
alt="icon"
draggable={false}
src={variables.constants.DDG_IMAGE_PROXY + item.icon_url}
/>
<div className="card-details">
<span className="card-title">{item.display_name || item.name}</span>
<span className="card-subtitle">
{variables.getMessage('modals.main.marketplace.by', { author: item.author })}
</span>
{type === 'all' && !onCollection ? (
<span className="card-type">
{variables.getMessage(
`modals.main.addons.create.types.${
item.type.split('_')[0] === 'preset'
? 'settings'
: item.type.split('_')[0] + 's'
}`,
)}
</span>
) : null}
</div>
</div>
))}
</div>
<div className="loader"></div>
{type === 'all' && !onCollection ? (
<div className="createYourOwn">
<MdAutoFixHigh />
<span className="title">{variables.getMessage('modals.main.marketplace.cant_find')}</span>
<span className="subtitle">
{variables.getMessage('modals.main.marketplace.knowledgebase_one') + ' '}
<a
className="link"
target="_blank"
href={variables.constants.KNOWLEDGEBASE}
rel="noreferrer"
>
{variables.getMessage('modals.main.marketplace.knowledgebase_two')}
</a>
{' ' + variables.getMessage('modals.main.marketplace.knowledgebase_three')}
</span>
</div>
) : null}
</>
);
}
Items.propTypes = {
type: PropTypes.string.isRequired,
items: PropTypes.arrayOf(PropTypes.object).isRequired,
collection: PropTypes.object,
toggleFunction: PropTypes.func.isRequired,
collectionFunction: PropTypes.func.isRequired,
onCollection: PropTypes.bool.isRequired,
filter: PropTypes.string,
};
export default memo(Items);

View File

@ -1,23 +0,0 @@
import { memo } from 'react';
import PropTypes from 'prop-types';
import variables from 'modules/variables';
function Lightbox({ modalClose, img }) {
variables.stats.postEvent('modal', 'Opened lightbox');
return (
<>
<span className="closeModal" onClick={modalClose}>
&times;
</span>
<img src={img} className="lightboximg" draggable={false} alt="Item screenshot" />
</>
);
}
Lightbox.propTypes = {
modalClose: PropTypes.func.isRequired,
img: PropTypes.string.isRequired,
};
export default memo(Lightbox);

View File

@ -1,31 +0,0 @@
import { memo } from 'react';
import PropTypes from 'prop-types';
import variables from 'modules/variables';
import { MdClose } from 'react-icons/md';
import Tooltip from 'components/helpers/tooltip/Tooltip';
function SideloadFailedModal({ modalClose, reason }) {
return (
<div className="smallModal">
<div className="shareHeader">
<span className="title">{variables.getMessage('modals.main.error_boundary.title')}</span>
<Tooltip
title={variables.getMessage('modals.main.settings.sections.advanced.reset_modal.cancel')}
>
<div className="close" onClick={modalClose}>
<MdClose />
</div>
</Tooltip>
</div>
<span>{variables.getMessage('modals.main.addons.sideload.failed')}</span>
<span className="subtitle">{reason}</span>
</div>
);
}
SideloadFailedModal.propTypes = {
modalClose: PropTypes.func.isRequired,
reason: PropTypes.string.isRequired,
};
export default memo(SideloadFailedModal);

View File

@ -1,25 +0,0 @@
{
"name": "Example Photos",
"description": "This is an example.",
"type": "photos",
"version": "1.0.0",
"author": "Mue",
"icon_url": "https://raw.githubusercontent.com/mue/branding/main/logo/logo_square.png",
"screenshot_url": "https://github.com/mue/mue/raw/main/assets/screenshot.webp",
"photos": [
{
"photographer": "Example photographer",
"location": "Example location",
"url": {
"default": "https://github.com/mue/mue/raw/main/assets/screenshot.webp"
}
},
{
"photographer": "Example photographer 2",
"location": "Example location 2",
"url": {
"default": "https://github.com/mue/mue/raw/main/assets/screenshot2.webp"
}
}
]
}

View File

@ -1,20 +0,0 @@
{
"name": "Example Quotes",
"description": "This is an example.",
"type": "quotes",
"version": "1.0.0",
"author": "Mue",
"icon_url": "https://raw.githubusercontent.com/mue/branding/main/logo/logo_square.png",
"screenshot_url": "https://github.com/mue/mue/raw/main/assets/screenshot.webp",
"language": "en",
"quotes": [
{
"quote": "This is an example quote.",
"author": "Example 1"
},
{
"quote": "This is another example quote.",
"author": "Example 2"
}
]
}

View File

@ -1,13 +0,0 @@
{
"name": "Example Settings",
"description": "This is an example.",
"type": "settings",
"version": "1.0.0",
"author": "Mue",
"icon_url": "https://raw.githubusercontent.com/mue/branding/main/logo/logo_square.png",
"screenshot_url": "https://github.com/mue/mue/raw/main/assets/screenshot.webp",
"settings": {
"searchBar": false,
"weather": true
}
}

View File

@ -1,272 +0,0 @@
import variables from 'modules/variables';
import { PureComponent } from 'react';
import { MdUpdate, MdOutlineExtensionOff, MdCode } from 'react-icons/md';
import { toast } from 'react-toastify';
import Modal from 'react-modal';
import SideloadFailedModal from '../SideloadFailedModal';
import FileUpload from '../../settings/FileUpload';
import Item from '../Item';
import Items from '../Items';
import Dropdown from '../../settings/Dropdown';
import { install, uninstall, urlParser } from 'modules/helpers/marketplace';
export default class Added extends PureComponent {
constructor() {
super();
this.state = {
installed: JSON.parse(localStorage.getItem('installed')),
item: {},
button: '',
showFailed: false,
failedReason: '',
};
this.buttons = {
uninstall: (
<button className="removeFromMue" onClick={() => this.uninstall()}>
{variables.getMessage('modals.main.marketplace.product.buttons.remove')}
</button>
),
};
}
installAddon(input) {
let failedReason = '';
if (!input.name) {
failedReason = variables.getMessage('modals.main.addons.sideload.errors.no_name');
} else if (!input.author) {
failedReason = variables.getMessage('modals.main.addons.sideload.errors.no_author');
} else if (!input.type) {
failedReason = variables.getMessage('modals.main.addons.sideload.errors.no_type');
} else if (!input.version) {
failedReason = variables.getMessage('modals.main.addons.sideload.errors.no_version');
} else if (
input.type === 'photos' &&
(!input.photos ||
!input.photos.length ||
!input.photos[0].url ||
!input.photos[0].url.default ||
!input.photos[0].photographer ||
!input.photos[0].location)
) {
failedReason = variables.getMessage('modals.main.addons.sideload.errors.invalid_photos');
} else if (
input.type === 'quotes' &&
(!input.quotes || !input.quotes.length || !input.quotes[0].quote || !input.quotes[0].author)
) {
failedReason = variables.getMessage('modals.main.addons.sideload.errors.invalid_quotes');
}
if (failedReason !== '') {
return this.setState({
failedReason,
showFailed: true,
});
}
install(input.type, input);
toast(variables.getMessage('toasts.installed'));
variables.stats.postEvent('marketplace', 'Sideload');
}
toggle(type, data) {
if (type === 'item') {
const installed = JSON.parse(localStorage.getItem('installed'));
const info = {
data: installed.find((i) => i.name === data.name),
};
this.setState({
item: {
type: info.data.type,
display_name: info.data.name,
author: info.data.author,
description: urlParser(info.data.description.replace(/\n/g, '<br>')),
//updated: info.updated,
version: info.data.version,
icon: info.data.screenshot_url,
data: info.data,
},
button: this.buttons.uninstall,
});
variables.stats.postEvent('marketplace', 'Item viewed');
} else {
this.setState({
item: {},
});
}
}
uninstall() {
uninstall(this.state.item.type, this.state.item.display_name);
toast(variables.getMessage('toasts.uninstalled'));
this.setState({
button: '',
installed: JSON.parse(localStorage.getItem('installed')),
});
variables.stats.postEvent('marketplace', 'Uninstall');
}
sortAddons(value, sendEvent) {
let installed = JSON.parse(localStorage.getItem('installed'));
switch (value) {
case 'newest':
installed.reverse();
break;
case 'oldest':
break;
case 'a-z':
installed.sort();
break;
case 'z-a':
installed.sort();
installed.reverse();
break;
default:
break;
}
this.setState({
installed,
});
if (sendEvent) {
variables.stats.postEvent('marketplace', 'Sort');
}
}
updateCheck() {
let updates = 0;
this.state.installed.forEach(async (item) => {
const data = await (
await fetch(variables.constants.MARKETPLACE_URL + '/item/' + item.name)
).json();
if (data.version !== item.version) {
updates++;
}
});
if (updates > 0) {
toast(
variables.getMessage('modals.main.addons.updates_available', {
amount: updates,
}),
);
} else {
toast(variables.getMessage('modals.main.addons.no_updates'));
}
}
componentDidMount() {
this.sortAddons(localStorage.getItem('sortAddons'), false);
}
render() {
const sideLoadBackendElements = () => (
<>
<Modal
closeTimeoutMS={100}
onRequestClose={() => this.setState({ showFailed: false })}
isOpen={this.state.showFailed}
className="Modal resetmodal mainModal resetmodal"
overlayClassName="Overlay resetoverlay"
ariaHideApp={false}
>
<SideloadFailedModal
modalClose={() => this.setState({ showFailed: false })}
reason={this.state.failedReason}
/>
</Modal>
<FileUpload
id="file-input"
type="settings"
accept="application/json"
loadFunction={(e) => this.installAddon(JSON.parse(e))}
/>
</>
);
if (this.state.installed.length === 0) {
return (
<>
<div className="flexTopMarketplace topAddons">
<span className="mainTitle">{variables.getMessage('modals.main.navbar.addons')}</span>
{sideLoadBackendElements()}
<button
className="sideload"
onClick={() => document.getElementById('file-input').click()}
ref={this.customDnd}
>
{variables.getMessage('modals.main.addons.sideload.title')}
<MdCode />
</button>
</div>
<div className="emptyItems">
<div className="emptyNewMessage">
<MdOutlineExtensionOff />
<span className="title">
{variables.getMessage('modals.main.addons.empty.title')}
</span>
<span className="subtitle">
{variables.getMessage('modals.main.addons.empty.description')}
</span>
</div>
</div>
</>
);
}
if (this.state.item.display_name) {
return (
<Item
data={this.state.item}
button={this.state.button}
toggleFunction={() => this.toggle()}
/>
);
}
return (
<>
<div className="flexTopMarketplace topAddons">
<span className="mainTitle">{variables.getMessage('modals.main.addons.added')}</span>
<div className="filter">
{sideLoadBackendElements()}
<div className="buttonSection">
<button className="addToMue sideload updateCheck" onClick={() => this.updateCheck()}>
<MdUpdate />
{variables.getMessage('modals.main.addons.check_updates')}
</button>
<button
className="sideload"
onClick={() => document.getElementById('file-input').click()}
>
{variables.getMessage('modals.main.addons.sideload.title')}
<MdCode />
</button>
</div>
</div>
</div>
<Dropdown
label={variables.getMessage('modals.main.addons.sort.title')}
name="sortAddons"
onChange={(value) => this.sortAddons(value)}
>
<option value="newest">{variables.getMessage('modals.main.addons.sort.newest')}</option>
<option value="oldest">{variables.getMessage('modals.main.addons.sort.oldest')}</option>
<option value="a-z">{variables.getMessage('modals.main.addons.sort.a_z')}</option>
<option value="z-a">{variables.getMessage('modals.main.addons.sort.z_a')}</option>
</Dropdown>
<Items
items={this.state.installed}
filter=""
toggleFunction={(input) => this.toggle('item', input)}
/>
</>
);
}
}

View File

@ -1,37 +0,0 @@
/* eslint-disable no-unused-vars */
import variables from 'modules/variables';
import { PureComponent } from 'react';
import { MdOutlineExtensionOff } from 'react-icons/md';
export default class Create extends PureComponent {
constructor() {
super();
this.state = {};
}
render() {
return (
<>
<div className="flexTopMarketplace">
<span className="mainTitle">
{variables.getMessage('modals.main.addons.create.title')}
</span>
</div>
<div className="emptyItems">
<div className="emptyNewMessage">
<MdOutlineExtensionOff />
<span className="title">
{variables.getMessage('modals.main.addons.create.moved_title')}
</span>
<span className="subtitle">
{variables.getMessage('modals.main.addons.create.moved_description')}
</span>
<div className="createButtons">
<button> {variables.getMessage('modals.main.addons.create.moved_button')}</button>
</div>
</div>
</div>
</>
);
}
}

View File

@ -1,479 +0,0 @@
import variables from 'modules/variables';
import { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { toast } from 'react-toastify';
import {
MdWifiOff,
MdLocalMall,
MdOutlineKeyboardArrowRight,
MdSearch,
MdOutlineArrowForward,
MdLibraryAdd,
} from 'react-icons/md';
import Item from '../Item';
import Items from '../Items';
import Dropdown from '../../settings/Dropdown';
import { install, urlParser, uninstall } from 'modules/helpers/marketplace';
class Marketplace extends PureComponent {
constructor() {
super();
this.state = {
items: [],
button: '',
featured: {},
done: false,
item: {},
collection: false,
filter: '',
};
this.buttons = {
uninstall: (
<button onClick={() => this.manage('uninstall')}>
{variables.getMessage('modals.main.marketplace.product.buttons.remove')}
</button>
),
install: (
<button onClick={() => this.manage('install')}>
{variables.getMessage('modals.main.marketplace.product.buttons.addtomue')}
<MdLibraryAdd />
</button>
),
};
this.controller = new AbortController();
}
async toggle(type, data) {
if (type === 'item') {
let info;
// get item info
try {
let type = this.props.type;
if (type === 'all' || type === 'collections') {
type = data.type;
}
info = await (
await fetch(`${variables.constants.MARKETPLACE_URL}/item/${type}/${data.name}`, {
signal: this.controller.signal,
})
).json();
} catch (e) {
if (this.controller.signal.aborted === false) {
return toast(variables.getMessage('toasts.error'));
}
}
if (this.controller.signal.aborted === true) {
return;
}
// check if already installed
let button = this.buttons.install;
let addonInstalled = false;
let addonInstalledVersion;
const installed = JSON.parse(localStorage.getItem('installed'));
if (installed.some((item) => item.name === info.data.name)) {
button = this.buttons.uninstall;
addonInstalled = true;
for (let i = 0; i < installed.length; i++) {
if (installed[i].name === info.data.name) {
addonInstalledVersion = installed[i].version;
break;
}
}
}
this.setState({
item: {
type: info.data.type,
display_name: info.data.name,
author: info.data.author,
description: urlParser(info.data.description.replace(/\n/g, '<br>')),
//updated: info.updated,
version: info.data.version,
icon: info.data.screenshot_url,
data: info.data,
addonInstalled,
addonInstalledVersion,
api_name: data.name,
},
button: button,
});
variables.stats.postEvent('marketplace-item', `${this.state.item.display_name} viewed`);
} else if (type === 'collection') {
this.setState({
done: false,
});
const collection = await (
await fetch(`${variables.constants.MARKETPLACE_URL}/collection/${data}`, {
signal: this.controller.signal,
})
).json();
this.setState({
items: collection.data.items,
collectionTitle: collection.data.name,
collectionDescription: collection.data.description,
collectionImg: collection.data.img,
collection: true,
done: true,
});
} else {
this.setState({
item: {},
});
}
}
async getItems() {
const dataURL =
this.props.type === 'collections'
? variables.constants.MARKETPLACE_URL + '/collections'
: variables.constants.MARKETPLACE_URL + '/items/' + this.props.type;
const { data } = await (
await fetch(dataURL, {
signal: this.controller.signal,
})
).json();
const featured = await (
await fetch(variables.constants.MARKETPLACE_URL + '/featured', {
signal: this.controller.signal,
})
).json();
const collections = await (
await fetch(variables.constants.MARKETPLACE_URL + '/collections', {
signal: this.controller.signal,
})
).json();
if (this.controller.signal.aborted === true) {
return;
}
this.setState({
items: data,
oldItems: data,
featured: featured.data,
collections: collections.data,
done: true,
});
this.sortMarketplace(localStorage.getItem('sortMarketplace'), false);
}
manage(type) {
if (type === 'install') {
install(this.state.item.type, this.state.item.data);
} else {
uninstall(this.state.item.type, this.state.item.display_name);
}
toast(variables.getMessage('toasts.' + type + 'ed'));
this.setState({
button: type === 'install' ? this.buttons.uninstall : this.buttons.install,
});
variables.stats.postEvent(
'marketplace-item',
`${this.state.item.display_name} ${type === 'install' ? 'installed' : 'uninstalled'}`,
);
variables.stats.postEvent('marketplace', type === 'install' ? 'Install' : 'Uninstall');
}
async installCollection() {
this.setState({ busy: true });
try {
const installed = JSON.parse(localStorage.getItem('installed'));
for (const item of this.state.items) {
if (installed.some((i) => i.name === item.display_name)) continue; // don't install if already installed
let { data } = await (
await fetch(`${variables.constants.MARKETPLACE_URL}/item/${item.type}/${item.name}`, {
signal: this.controller.signal,
})
).json();
install(data.type, data);
variables.stats.postEvent('marketplace-item', `${item.display_name} installed}`);
variables.stats.postEvent('marketplace', 'Install');
}
toast(variables.getMessage('toasts.installed'));
} catch (error) {
console.error(error);
toast(variables.getMessage('toasts.error'));
} finally {
this.setState({ busy: false });
}
}
sortMarketplace(value, sendEvent) {
let items = this.state.oldItems;
switch (value) {
case 'a-z':
items.sort();
// fix sort not working sometimes
if (this.state.sortType === 'z-a') {
items.reverse();
}
break;
case 'z-a':
items.sort();
items.reverse();
break;
default:
break;
}
this.setState({
items: items,
sortType: value,
});
if (sendEvent) {
variables.stats.postEvent('marketplace', 'Sort');
}
}
returnToMain() {
this.setState({
items: this.state.oldItems,
collection: false,
});
}
reloadItems() {
this.setState({
done: false,
});
this.getItems();
}
componentDidMount() {
if (navigator.onLine === false || localStorage.getItem('offlineMode') === 'true') {
return;
}
this.getItems();
}
componentWillUnmount() {
// stop making requests
this.controller.abort();
}
render() {
const errorMessage = (msg) => {
return (
<>
<div className="flexTopMarketplace">
<span className="mainTitle">
{variables.getMessage('modals.main.navbar.marketplace')}
</span>
</div>
<div className="emptyItems">
<div className="emptyMessage">{msg}</div>
</div>
</>
);
};
if (navigator.onLine === false || localStorage.getItem('offlineMode') === 'true') {
return errorMessage(
<>
<MdWifiOff />
<h1>{variables.getMessage('modals.main.marketplace.offline.title')}</h1>
<p className="description">
{variables.getMessage('modals.main.marketplace.offline.description')}
</p>
</>,
);
}
if (this.state.done === false) {
return errorMessage(
<>
<div className="loaderHolder">
<div id="loader"></div>
<span className="subtitle">{variables.getMessage('modals.main.loading')}</span>
</div>
</>,
);
}
const featured = () => {
const openFeatured = () => {
variables.stats.postEvent('marketplace', 'Featured clicked');
window.open(this.state.featured.buttonLink);
};
return (
<div className="featured" style={{ backgroundColor: this.state.featured.colour }}>
<p>{this.state.featured.title}</p>
<h1>{this.state.featured.name}</h1>
<button className="addToMue" onClick={() => openFeatured()}>
{this.state.featured.buttonText}
</button>
</div>
);
};
if (this.state.items?.length === 0) {
return (
<>
{featured()}
{errorMessage(
<>
<MdLocalMall />
<h1>{variables.getMessage('modals.main.addons.empty.title')}</h1>
<p className="description">
{variables.getMessage('modals.main.marketplace.no_items')}
</p>
</>,
)}
</>
);
}
if (this.state.item.display_name) {
return (
<Item
data={this.state.item}
button={this.state.button}
toggleFunction={() => this.toggle()}
addonInstalled={this.state.item.addonInstalled}
addonInstalledVersion={this.state.item.addonInstalledVersion}
icon={this.state.item.screenshot_url}
/>
);
}
return (
<>
{this.state.collection === true ? (
<>
<div className="flexTopMarketplace">
<span className="mainTitle" onClick={() => this.returnToMain()}>
<span className="backTitle">
{variables.getMessage('modals.main.navbar.marketplace')}
</span>
<MdOutlineKeyboardArrowRight />{' '}
{variables.getMessage('modals.main.marketplace.collection')}
</span>
</div>
<div
className="collectionPage"
style={{
backgroundImage: `linear-gradient(to bottom, transparent, black), url('${this.state.collectionImg}')`,
}}
>
<div className="nice-tag">
{variables.getMessage('modals.main.marketplace.collection')}
</div>
<div className="content">
<span className="mainTitle">{this.state.collectionTitle}</span>
<span className="subtitle">{this.state.collectionDescription}</span>
</div>
<button
className="addAllButton"
onClick={() => this.installCollection()}
disabled={this.state.busy}
>
{variables.getMessage('modals.main.marketplace.add_all')}
<MdLibraryAdd />
</button>
</div>
</>
) : (
<>
<div className="flexTopMarketplace">
<span className="mainTitle">
{variables.getMessage('modals.main.navbar.marketplace')}
</span>
</div>
<div className="headerExtras marketplaceCondition">
{this.props.type !== 'collections' ? (
<div>
<form className="marketplaceSearch">
<input
label={variables.getMessage('widgets.search')}
placeholder={variables.getMessage('widgets.search')}
name="filter"
id="filter"
value={this.state.filter}
onChange={(event) => this.setState({ filter: event.target.value })}
/>
<MdSearch />
</form>
{/*<span className="link marketplaceRefresh" onClick={() => this.reloadItems()}>
<MdRefresh /> {variables.getMessage('widgets.navbar.tooltips.refresh')}
</span>*/}
</div>
) : null}
<Dropdown
label={variables.getMessage('modals.main.addons.sort.title')}
name="sortMarketplace"
onChange={(value) => this.sortMarketplace(value)}
>
<option value="a-z">{variables.getMessage('modals.main.addons.sort.a_z')}</option>
<option value="z-a">{variables.getMessage('modals.main.addons.sort.z_a')}</option>
</Dropdown>
</div>
</>
)}
{this.props.type === 'collections' && !this.state.collection ? (
this.state.items.map((item) => (
<>
{!item.news ? (
<div
className="collection"
style={
item.news
? { backgroundColor: item.background_colour }
: {
backgroundImage: `linear-gradient(to left, #000, transparent, #000), url('${item.img}')`,
}
}
>
<div className="content">
<span className="title">{item.display_name}</span>
<span className="subtitle">{item.description}</span>
</div>
<button
className="collectionButton"
onClick={() => this.toggle('collection', item.name)}
>
<MdOutlineArrowForward />{' '}
{variables.getMessage('modals.main.marketplace.explore_collection')}
</button>
</div>
) : null}
</>
))
) : (
<Items
type={this.props.type}
items={this.state.items}
collection={
this.state.collections[Math.floor(Math.random() * this.state.collections.length)] ||
[]
}
onCollection={this.state.collection}
toggleFunction={(input) => this.toggle('item', input)}
collectionFunction={(input) => this.toggle('collection', input)}
filter={this.state.filter}
/>
)}
</>
);
}
}
Marketplace.propTypes = {
type: PropTypes.string,
};
export default Marketplace;

View File

@ -1,370 +0,0 @@
@import 'scss/variables';
@import 'modules/sidebar';
@import 'modules/navbar';
@import 'modules/tab-content';
@import 'modules/links';
@import 'modules/scrollbars';
@import 'settings/main';
@import 'marketplace/main';
.Overlay {
position: fixed;
z-index: 100;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100vw;
height: 100vh;
display: grid;
place-items: center;
}
.Modal {
@include themed {
color: t($color);
}
box-shadow: 0 0 20px rgb(0 0 0 / 30%);
opacity: 1;
z-index: -2;
transition-timing-function: ease-in;
border-radius: map-get($modal, 'border-radius');
user-select: none;
overflow-y: auto;
transform: scale(0);
transition: all 0.3s cubic-bezier(0.47, 1.64, 0.41, 0.8);
&:focus {
outline: 0;
}
}
.closePositioning {
position: absolute;
top: 3rem;
right: 3rem;
}
.closeModal {
display: grid;
place-items: center;
padding: 0.5em;
border-radius: 12px;
cursor: pointer;
svg {
font-size: 2em;
}
&:hover {
background: rgb(121 121 121 / 22.6%);
}
}
.ReactModal__Html--open,
.ReactModal__Body--open {
overflow: hidden;
}
/* modal transition */
.ReactModal__Content--after-open {
opacity: 1;
transform: scale(1);
}
.ReactModal__Content--before-close {
opacity: 0;
transform: scale(0);
}
#modal {
height: 80vh;
width: clamp(60vw, 1200px, 90vw);
@include themed {
background-color: t($modal-background);
}
}
/* fixes for font size on extension */
label,
p,
span.modalLink {
font-size: 1rem;
}
h2 {
font-size: 2rem;
margin-bottom: 0;
}
h3 {
font-size: 1.17rem;
}
h5 {
font-size: 0.8rem;
}
.loaderHolder {
display: flex;
gap: 15px;
flex-flow: column;
align-items: center;
}
#loader {
display: inline-block;
width: 50px;
height: 50px;
@include themed {
border: 3px solid t($modal-sidebar);
border-radius: 50%;
border-top-color: t($modal-sidebarActive);
}
animation: spin 1s ease-in-out infinite;
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
.headerExtras {
display: flex;
flex-flow: column;
gap: -1px;
padding: 10px 0;
div:nth-child(1) {
display: flex;
flex-flow: column;
gap: 10px;
}
form {
margin-top: 10px;
}
.link {
display: flex;
flex-flow: row;
gap: 15px;
align-items: center;
}
}
.marketplaceCondition {
display: flex;
flex-flow: row !important;
gap: -1px;
justify-content: space-between;
align-items: center;
}
.languageSettings {
margin-bottom: 15px;
.MuiFormGroup-root {
gap: 5px;
}
.MuiFormControl-root {
width: 100% !important;
gap: 15px;
.MuiFormControlLabel-root {
display: flex;
flex-direction: row-reverse;
justify-content: space-between;
padding: 5px 5px 5px 20px;
transition: 0.3s;
@include themed {
background: t($modal-sidebar);
border-radius: t($borderRadius);
&:hover {
background: t($modal-sidebarActive);
}
}
}
}
}
.sliderTitle {
width: 100%;
display: flex;
justify-content: space-between;
padding: 15px 0;
.link {
display: flex;
flex-flow: row;
gap: 15px;
align-items: center;
}
}
.moreSettings {
cursor: pointer;
display: flex;
flex-flow: row;
justify-content: space-between;
padding: 25px;
margin-top: 20px;
transition: 0.5s;
@include themed {
background: t($modal-sidebar);
border-radius: t($borderRadius);
box-shadow: 0 0 0 1px t($modal-sidebarActive);
&:hover {
background: t($modal-sidebarActive);
}
}
svg {
font-size: 20px;
}
.left {
display: flex;
flex-flow: row;
align-items: center;
gap: 25px;
}
.content {
display: flex;
flex-flow: column;
}
.action {
display: flex;
flex-flow: row;
gap: 20px;
align-items: center;
}
}
.reminder-info {
display: flex;
flex-flow: column;
position: absolute;
bottom: 0;
padding: 15px;
gap: 15px;
@include themed {
background-color: t($modal-secondaryColour);
border-radius: t($borderRadius);
border: 1px solid t($modal-sidebarActive);
}
button {
@include basicIconButton(5px, 5px, modal);
display: flex;
justify-content: center;
gap: 15px;
svg {
margin: 0 !important;
}
}
svg {
margin: 0 !important;
}
@extend %tabText;
}
.quoteSkeleton {
margin-top: 5px;
display: flex;
flex-flow: column;
gap: 5px;
align-items: center;
div {
display: flex;
flex-flow: row;
}
.text {
display: flex;
flex-flow: column;
padding: 5px;
}
.skeletonAuthor {
font-size: smaller;
display: flex;
flex-flow: row;
align-items: center;
gap: 25px;
padding: 0 20px 0 5px;
svg {
@include themed {
background-color: t($modal-sidebar);
padding: 10px;
border-radius: t($borderRadius);
place-items: center;
}
}
@include themed {
background-color: t($modal-sidebarActive);
border-radius: t($borderRadius);
}
.title {
font-size: medium !important;
}
.subtitle {
font-size: smaller !important;
}
}
}
.quickLinksSkeleton {
.circles {
display: flex;
flex-flow: row;
gap: 5px;
div {
margin-top: 10px;
padding: 3px;
height: 20px;
width: 20px;
border-radius: 100%;
display: grid;
place-items: center;
@include themed {
background-color: t($modal-sidebarActive);
}
}
}
}
.clockSkeleton {
font-size: 30px !important;
font-weight: bold;
}

View File

@ -1,614 +0,0 @@
// this file is too long
@import 'modules/item';
@import 'modules/buttons';
@import 'modules/featured';
@import 'modules/lightbox';
@import 'scss/variables';
.items {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
grid-gap: 1.5rem;
margin-top: 15px;
margin-bottom: 30px;
.item {
position: relative;
border-radius: 12px;
width: auto;
cursor: pointer;
transition: 0.5s;
display: flex;
flex-flow: column;
align-items: center;
text-align: center;
gap: 15px;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
@include themed {
background-color: t($modal-secondaryColour);
box-shadow: 0 0 0 1px t($modal-sidebarActive);
&:hover {
background-color: t($modal-sidebarActive);
img {
background-color: t($modal-sidebarActive);
}
}
}
.tags {
margin-top: 7px;
}
.item-back {
filter: blur(60px) saturate(180%) brightness(90%);
position: absolute;
object-fit: cover !important;
height: 90px !important;
width: 100px !important;
border-radius: 100px;
transition: 0.5s;
margin-top: 30px;
}
.item-icon {
object-fit: cover !important;
height: 60px !important;
width: 60px !important;
border-radius: 12px;
transition: 0.5s;
margin-top: 25px;
}
.card-details {
padding: 10px;
margin-bottom: 24px;
display: flex;
flex-flow: column;
gap: 5px;
.card-title {
font-size: 18px;
}
.card-subtitle {
font-size: 14px;
@include themed {
color: t($subColor);
}
}
.card-type {
margin-top: 8px;
font-size: 12px;
font-weight: bolder;
@include themed {
color: t($subColor);
}
border-radius: 150px;
padding: 2px 8px;
background-color: rgb(255 255 255 / 10%);
border: 1px solid rgb(209 213 219 / 30%);
}
}
}
}
.itemPage {
display: flex;
flex-flow: row;
justify-content: space-between;
.itemShowcase {
display: flex;
flex-flow: column;
gap: 25px;
width: 60%;
max-width: 650px;
.description {
max-lines: 3;
font-size: 16px;
}
img {
width: 100%;
height: auto;
}
table {
table-layout: fixed;
width: 100%;
max-width: 650px !important;
word-wrap: break-word !important;
}
}
.itemInfo {
background-position: center;
background-repeat: no-repeat;
background-size: cover;
border-radius: 15px;
width: 25%;
max-height: 450px;
.front {
padding: 20px;
height: 100%;
display: flex;
flex-flow: column;
gap: 15px;
width: 100%;
box-sizing: border-box !important;
border-radius: 12px 12px 0 0;
backdrop-filter: blur(40px) saturate(150%) brightness(75%);
@include themed {
background-image: linear-gradient(to bottom, transparent, t($modal-background));
}
}
.icon {
width: 100%;
height: auto;
border-radius: 12px;
box-shadow: 0 5px 25px black;
}
.divider {
text-transform: uppercase;
@include themed {
color: t($subColor);
}
}
.iconButtons {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr;
grid-gap: 20px;
button {
width: 100%;
padding: 0;
}
}
}
}
.tags {
display: flex;
flex-flow: row;
flex-wrap: wrap;
gap: 15px;
align-items: center;
}
.tag {
padding: 2px 10px;
border-radius: 12px;
font-size: 12px;
display: grid;
place-items: center;
@include themed {
background: t($modal-sidebar);
box-shadow: 0 0 0 3px t($modal-sidebarActive);
span {
&::before {
content: '#';
color: t($subColor);
margin-right: 5px;
}
}
&:hover {
background: t($modal-sidebarActive);
}
}
}
.moreTag {
padding: 2px 10px;
border-radius: 12px;
font-size: 12px;
display: grid;
place-items: center;
@include themed {
background: t($modal-sidebar);
box-shadow: 0 0 0 3px t($modal-sidebarActive);
span {
&::before {
content: '+';
color: t($subColor);
margin-right: 5px;
}
}
&:hover {
background: t($modal-sidebarActive);
}
}
}
.emptyItems {
width: 100%;
height: 100%;
display: grid;
place-items: center;
}
.emptyMessage {
display: grid;
place-items: center;
grid-gap: 5px;
padding: 50px;
@include themed {
.sideloadIcon {
font-size: 50px;
color: t($subColor);
}
}
button {
display: flex;
flex-flow: row;
}
}
.emptyNewMessage {
display: flex;
gap: 20px;
flex-flow: column;
text-align: center;
align-items: center;
user-select: none;
img {
width: 200px;
height: auto;
}
svg {
font-size: 70px;
/* background: -webkit-linear-gradient(90deg,rgba(255,92,39,.7) 37%,rgba(255,70,110,.67) 60%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent; */
}
button {
svg {
font-size: 1rem;
}
}
.buttonsRow {
display: flex;
flex-flow: row;
gap: 30px;
align-items: center;
}
}
p.author {
margin-top: -5px;
}
#item > img,
.updateImage,
.updateChangelog > p > img {
border-radius: 12px;
height: 200px;
width: auto;
cursor: pointer;
}
.returnButton {
display: grid;
place-items: center;
width: 48px;
height: 48px;
border-radius: 12px;
cursor: pointer;
svg {
font-size: 2em;
}
&:hover {
background: rgb(121 121 121 / 22.6%);
}
}
.flexTopMarketplace {
display: flex;
margin-bottom: 15px;
.tooltip {
margin-right: 25px;
}
.mainTitle {
margin-bottom: 0 !important;
}
}
.itemWarning {
display: flex;
flex-direction: column;
align-items: center;
@include themed {
background: t($modal-sidebar);
box-shadow: 0 0 0 4px t($modal-sidebarActive);
border-radius: t($borderRadius);
padding: 15px;
}
.topRow {
display: flex;
flex-flow: column;
align-items: center;
}
.subtitle {
text-align: justify;
}
}
.truncate {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
.filter {
display: flex;
flex-flow: row;
gap: 15px;
justify-content: space-between;
align-items: center;
.MuiFormControl-root {
margin-bottom: 10px;
}
.buttonSection {
display: flex;
flex-flow: row;
gap: 20px;
}
.tags {
max-width: 50%;
}
}
.collectionPage {
// height: 200px;
padding: 1.5rem;
display: flex;
flex-flow: column;
align-items: center;
justify-content: center;
gap: 15px;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
@include themed {
border-radius: t($borderRadius);
}
.nice-tag {
border-radius: 150px;
padding: 1px 12px;
backdrop-filter: blur(16px) saturate(180%);
background-color: rgb(255 255 255 / 10%);
border: 1px solid rgb(209 213 219 / 30%);
color: #fff;
}
.content {
display: flex;
flex-flow: column;
text-align: center;
text-shadow: #000 0 0 15px;
.mainTitle {
justify-content: center;
color: #fff !important;
}
.subtitle {
color: #ccc !important;
}
}
.addAllButton {
margin: 0.5rem;
display: flex;
align-items: center;
gap: 15px;
padding: 1px 12px;
backdrop-filter: blur(16px) saturate(180%) !important;
background-color: rgb(255 255 255 / 10%) !important;
border: 1px solid rgb(209 213 219 / 30%) !important;
color: #fff !important;
&:hover {
backdrop-filter: blur(16px) saturate(180%) !important;
background-color: rgb(17 25 40 / 20%) !important;
border: 1px solid rgb(255 255 255 / 12.5%) !important;
}
}
}
.collection {
display: flex;
justify-content: space-between;
padding: 36px 48px;
margin: 15px 0;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
align-items: center;
@include themed {
box-shadow: 0 0 0 1px t($modal-sidebarActive);
border-radius: t($borderRadius);
}
.content {
display: flex;
flex-flow: column;
gap: 15px;
max-width: 250px;
text-shadow: #000 0 0 15px;
.title {
color: #fff !important;
}
.subtitle {
color: #ccc !important;
}
}
.items {
justify-content: center;
}
button.collectionButton,
a.collectionButton {
display: flex;
align-items: center;
gap: 15px;
padding: 1px 12px;
backdrop-filter: blur(16px) saturate(180%);
background-color: rgb(255 255 255 / 10%);
border: 1px solid rgb(209 213 219 / 30%);
color: #fff;
&:hover {
backdrop-filter: blur(16px) saturate(180%);
background-color: rgb(17 25 40 / 20%);
border: 1px solid rgb(255 255 255 / 12.5%);
}
}
}
a.collectionButton {
height: 40px;
text-decoration: none;
@include themed {
border-radius: t($borderRadius);
}
}
.smallBanner {
button {
padding: 0 15px;
}
display: flex;
justify-content: space-between;
padding: 15px;
margin-top: 15px;
align-items: center;
@include themed {
box-shadow: 0 0 0 4px t($modal-sidebarActive);
border-radius: t($borderRadius);
background: t($modal-sidebar);
}
.content {
display: flex;
flex-flow: column;
gap: 15px;
max-width: 250px;
}
}
.marketplaceRefresh {
display: flex;
flex-flow: row;
gap: 5px;
align-items: center;
}
.marketplaceSearch {
display: flex;
align-items: center;
padding: 10px 30px;
border-radius: 10px;
font-size: 18px;
@include themed {
box-shadow: 0 0 0 3px t($modal-sidebarActive);
background: t($modal-sidebar);
}
input {
all: unset;
}
@include themed {
&:focus-within {
background: t($modal-sidebarActive);
box-shadow: 0 0 0 1px t($color);
}
&:disabled {
background: t($modal-sidebarActive);
cursor: not-allowed;
}
}
}
.inCollection {
background-image: linear-gradient(to left, transparent, #000),
url('https://external-preview.redd.it/JyhsEoGMhKIMi3kvfBS24L0IllAO_KrIm4UI-dA1Ax4.jpg?auto=webp&s=b5adf9859b2c1855a5b3085f9453a6e878548505');
display: flex;
flex-flow: column;
gap: 15px;
padding: 15px;
@include themed {
box-shadow: 0 0 0 4px t($modal-sidebarActive);
border-radius: t($borderRadius);
}
}
.createYourOwn {
display: flex;
flex-flow: column;
gap: 20px;
align-items: center;
margin-top: 30px;
svg {
font-size: 30px;
}
}
.topAddons {
display: flex;
align-items: center;
justify-content: space-between;
}

View File

@ -1,36 +0,0 @@
%storeButton {
cursor: pointer;
font-size: 18px;
display: block;
padding: 5px 30px;
background: none;
border-radius: 24px;
transition: ease 0.33s;
border: 2px solid black;
&:hover {
background: #2d3436;
color: map-get($theme-colours, 'main');
}
}
.dark %storeButton {
border: 2px solid map-get($theme-colours, 'main');
color: map-get($theme-colours, 'main');
&:hover {
background: map-get($theme-colours, 'main');
color: #2d3436;
}
}
.sideload {
display: inline;
margin-top: 0;
float: none !important;
width: 200px;
}
.updateCheck {
flex-flow: row !important;
}

View File

@ -1,24 +0,0 @@
.featured {
border-radius: 15px;
padding: 50px;
color: #fff;
width: calc(100% - 6rem);
margin-top: 13px;
button {
float: left;
margin-top: -7px;
border: 2px solid map-get($theme-colours, 'main');
color: map-get($theme-colours, 'main');
&:hover {
background: map-get($theme-colours, 'main');
color: #2d3436;
}
}
h1 {
margin-top: -20px;
font-size: 2rem;
}
}

View File

@ -1,101 +0,0 @@
.side {
float: right;
margin-left: 20px;
}
p.description {
margin-top: 0;
max-width: 800px;
}
.informationContainer {
margin-top: 150px;
position: absolute;
}
.moreInfo {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
width: calc(100% - 30px);
gap: 25px;
.items {
margin-top: 0 !important;
}
.item {
flex: 1 0 40% !important;
}
@include themed {
background: t($modal-sidebar);
box-shadow: t(boxshadow);
border-radius: t($borderRadius);
padding: 15px;
.infoItem {
display: flex;
flex-flow: row;
align-items: center;
gap: 15px;
flex: 1 0 44%;
svg {
font-size: 25px;
color: t($subColor);
}
.text {
display: flex;
flex-flow: column;
}
}
.header {
text-transform: uppercase;
color: t($subColor);
}
span {
color: t($color);
}
}
}
.itemTitle {
font-size: 38px;
font-weight: 600;
@include themed {
color: t($color);
}
}
.titleTop {
display: flex;
flex-flow: column;
gap: 3px;
}
.showMore {
display: flex;
align-items: center;
gap: 5px;
transition: 0.5s;
cursor: pointer;
@include themed {
&:hover {
color: t($subColor);
}
}
}
.showMoreItems {
display: flex;
flex-flow: column;
justify-content: center;
align-items: center;
gap: 10px;
}

View File

@ -1,16 +0,0 @@
.lightBoxModal {
margin: auto;
max-width: 60%;
background: none !important;
box-shadow: none !important;
img {
height: auto;
width: 100%;
}
.closeModal {
color: #fff;
text-shadow: 0 0 20px rgb(0 0 0 / 30%);
}
}

View File

@ -1,25 +0,0 @@
.resetLink {
color: var(--modal-link);
cursor: pointer;
&:hover {
opacity: 0.8;
}
span {
font-size: 1.2rem;
color: var(--modal-link);
vertical-align: text-bottom;
margin-left: 5px;
}
}
.modalLink {
color: var(--modal-link);
cursor: pointer;
margin-left: 5px;
&:hover {
opacity: 0.8;
}
}

View File

@ -1,59 +0,0 @@
.navbar-item {
flex-flow: row !important;
padding: 0 15px;
@include themed {
background: t($modal-secondaryColour) !important;
border-radius: t($borderRadius) !important;
box-shadow: t($boxShadow) !important;
border: 0 !important;
&:hover {
background: t($modal-sidebarActive) !important;
}
}
&:hover {
svg {
background: var(--tab-active);
}
color: var(--modal-text);
}
span,
svg {
font-size: 1.1em !important;
}
svg {
font-size: 1.2em !important;
color: var(--photo-info);
}
}
/* safari fix */
@supports (-webkit-hyphens: none) {
.navbar-item {
display: inline-block !important;
}
}
#modal {
display: flex;
align-items: flex-start;
justify-content: flex-start;
}
.modalNavbar {
display: flex;
flex-flow: row;
gap: 25px;
margin-bottom: 1rem;
}
.navbar-item-active {
@include themed {
background: t($modal-sidebarActive) !important;
}
}

View File

@ -1,19 +0,0 @@
@import 'scss/variables';
::-webkit-scrollbar {
width: 6px;
height: 6px;
border-radius: 12px;
@include themed {
background: t($modal-sidebar);
}
}
::-webkit-scrollbar-thumb {
@include themed {
background: t($modal-sidebarActive);
}
border-radius: 12px;
}

View File

@ -1,75 +0,0 @@
@import 'scss/variables';
.sidebar {
@include themed {
top: 0;
left: 0;
position: sticky;
margin: 0;
padding: 0;
background: t($modal-sidebar);
border-radius: 12px 0 0 12px;
overflow-y: auto;
height: 80vh;
min-width: 250px;
overflow-x: hidden;
.mainTitle {
text-align: center;
font-size: 35px;
display: flex;
justify-content: center;
padding: 25px;
}
svg {
margin-left: 20px;
margin-right: 20px;
color: t($subColor);
font-size: 17px;
}
hr {
height: 1px;
background: #ccc;
margin: 0 1.75rem;
border: none;
}
button {
color: t($color);
font-size: 18px;
list-style: none;
cursor: pointer;
border-radius: 12px;
display: flex;
align-items: center;
margin: 0.2rem;
padding: 0.5rem;
transition: 0.5s;
outline: none;
border: none;
background: none;
min-width: calc(100% - 1.2em);
text-align: left;
&:hover {
background: t($modal-sidebarActive);
}
&:active {
background: t($modal-sidebarActive);
box-shadow: 0 0 0 0.5px t($color);
}
&:focus {
background: t($modal-sidebarActive);
box-shadow: 0 0 0 0.5px t($color);
}
}
.tab-list-active {
background: t($modal-sidebarActive);
}
}
}

View File

@ -1,194 +0,0 @@
@import 'scss/variables';
.tab-content {
button {
@include modal-button(standard);
}
@include themed {
padding: 1rem 3rem 3rem;
display: flex;
flex-direction: column;
width: 100%;
background: t($modal-background);
@extend %tabText;
hr {
width: 100%;
background: rgb(196 196 196 / 74%);
outline: none;
}
.settingsRow {
display: flex;
align-items: center;
min-height: 100px;
justify-content: space-between;
/* border-top: 1px solid #ccc; */
border-bottom: 1px solid #ccc;
padding-top: 1rem;
padding-bottom: 1rem;
&.settingsNoBorder {
border-bottom: none;
}
.content {
display: flex;
flex-flow: column;
max-width: 50%;
}
.action {
display: flex;
flex-flow: column;
align-items: flex-end;
width: 300px;
button {
margin-top: 10px;
width: 283px;
}
}
}
}
}
.activityButtons {
justify-content: space-between !important;
align-items: flex-end !important;
align-content: space-between !important;
flex-flow: row wrap !important;
button:not(:first-child) {
width: 40% !important;
height: 99px !important;
flex-flow: column-reverse !important;
}
button {
@include modal-button(standard);
}
}
table {
border-collapse: separate;
@include themed {
border-radius: t($borderRadius);
margin-top: 20px;
tr:first-child {
background: t($modal-sidebarActive);
th {
padding: 1rem;
}
}
td {
padding: 15px;
}
tr {
th:last-child {
display: grid;
place-items: center;
}
}
::placeholder {
color: t($subColor);
}
tr:not(:first-child) {
background: t($modal-sidebar);
textarea {
width: 90%;
margin: 10px;
color: t($color);
}
}
}
}
.donateButton {
@include modal-button(standard);
flex-flow: row !important;
text-decoration: none;
height: auto !important;
svg {
font-size: 1.5rem !important;
}
}
.flexGrow {
flex-grow: 1;
}
.messageMap {
display: flex;
flex-flow: row;
align-items: center;
gap: 25px;
padding: 25px;
justify-content: space-between;
div:nth-child(1) {
display: flex;
flex-flow: row;
gap: 25px;
align-items: center;
}
.icon {
border-radius: 100%;
display: grid;
place-items: center;
padding: 15px;
font-size: 25px;
@include themed {
background: t($modal-sidebarActive);
}
}
.messageText {
display: flex;
flex-flow: column;
flex-grow: 3;
textarea {
@include themed {
color: t($color);
}
}
.subtitle {
@include themed {
color: t($subColor);
font-size: 13px;
}
}
}
.messageAction {
float: right;
}
@include themed {
background: t($modal-sidebar);
border-radius: t($borderRadius);
}
}
.messagesContainer {
display: flex;
flex-flow: column;
gap: 25px;
}

View File

@ -1,270 +0,0 @@
@import 'modules/resetmodal';
@import 'scss/variables';
@import 'modules/material-ui';
@import 'modules/tabs/about';
@import 'modules/tabs/changelog';
@import 'modules/tabs/order';
input {
/* colour picker */
&[type='color'] {
border-radius: 100%;
height: 30px;
width: 30px;
border: none;
outline: none;
appearance: none;
vertical-align: middle;
background: none;
@include themed {
border: t($modal-sidebarActive) 1px solid;
}
&::-webkit-color-swatch-wrapper {
padding: 0;
}
&::-webkit-color-swatch {
border: none;
border-radius: 100%;
}
}
/* firefox fixes for colour picker (using "," didn't work) */
&[type='color']::-moz-color-swatch {
border-radius: 100%;
height: 30px;
width: 30px;
border: none;
outline: none;
appearance: none;
vertical-align: middle;
background: none;
&::-moz-color-swatch-wrapper {
padding: 0;
}
&::-moz-color-swatch {
border: none;
border-radius: 100%;
}
}
/* date picker */
&[type='date'] {
width: 260px;
@include themed {
background: t($modal-sidebar);
border: 3px solid t($modal-sidebarActive);
color: t($color);
}
padding: 15px 20px;
border-radius: 4px;
display: flex !important;
cursor: pointer;
&::-webkit-calendar-picker-indicator {
cursor: pointer;
}
}
}
/* dark theme date picker fix */
.dark {
::-webkit-calendar-picker-indicator {
filter: invert(1);
}
}
h4 {
cursor: pointer;
}
.photosEmpty {
height: 400px;
display: grid;
place-items: center;
button {
padding: 0 20px;
}
}
.imagesTopBar {
padding-top: 25px;
display: flex;
flex-flow: row;
justify-content: space-between;
align-items: center;
div:nth-child(1) {
display: flex;
flex-flow: row;
align-items: center;
gap: 20px;
svg {
font-size: 30px;
@include themed {
color: t($subColor);
}
}
div {
display: flex;
flex-flow: column;
}
}
.topbarbuttons {
display: flex;
flex-flow: row;
gap: 25px;
}
button {
padding: 0 20px;
}
}
.stats {
display: flex;
flex-flow: column;
gap: 30px;
width: 100%;
.rightPanel {
.statIcon {
display: flex;
justify-content: center;
margin-bottom: 30px;
}
.statGrid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-gap: 10px;
div {
display: flex;
flex-flow: column;
}
}
.subtitle {
text-transform: capitalize;
}
span {
font-size: 20px;
}
}
}
.breadcrumb {
display: flex;
flex-flow: row;
padding-top: 20px;
gap: 10px;
align-items: center;
.settingsReturn {
border-radius: 12px;
cursor: pointer;
padding: 4px;
svg {
font-size: 2em;
}
&:hover {
background: rgb(121 121 121 / 22.6%);
}
}
.returnButton {
display: grid;
place-items: center;
width: 48px;
height: 48px;
border-radius: 12px;
cursor: pointer;
margin-right: 25px;
svg {
font-size: 2em;
}
&:hover {
background: rgb(121 121 121 / 22.6%);
}
}
}
.achievements {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
grid-gap: 10px;
}
.achievement {
padding: 20px 10px;
display: flex;
flex-flow: row !important;
align-items: center;
@include themed {
background: t($modal-secondaryColour);
border: 1px solid t($modal-sidebarActive);
border-radius: t($borderRadius);
gap: 10px;
}
svg {
font-size: 20px !important;
padding: 15px;
border-radius: 100%;
@include themed {
background: t($modal-sidebarActive);
}
}
}
.statSection.rightPanel {
padding: 25px;
@include themed {
border-radius: t($borderRadius);
background: t($modal-secondaryColour);
box-shadow: 0 0 0 1px t($modal-sidebarActive);
svg {
font-size: 50px;
color: t($subColor);
}
}
}
.achievementContent {
display: flex;
flex-flow: column;
gap: 2px;
span:first-child {
font-weight: bold;
font-size: 15px;
}
.subtitle {
font-size: 13px !important;
}
}
.customcss textarea {
font-family: Consolas, 'Andale Mono WT', 'Andale Mono', 'Lucida Console', 'Lucida Sans Typewriter',
'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Liberation Mono', 'Nimbus Mono L', Monaco,
'Courier New', Courier, monospace !important;
}

View File

@ -1,172 +0,0 @@
/* these are overrides for the material ui default styles */
@import 'scss/variables';
.MuiCheckbox-colorPrimary.Mui-checked,
.MuiSwitch-colorPrimary.Mui-checked,
.MuIconButton-colorPrimary.Mui-checked,
.MuiSwitch-thumb,
.MuiRadio-colorSecondary.Mui-checked,
.PrivateSwitchBase-input-4,
.MuiRadio-root,
.aboutLink,
.MuiSlider-colorPrimary,
legend {
@include themed {
color: t($color) !important;
}
}
.MuiFormControlLabel-labelPlacementStart {
margin-left: 0 !important;
}
.MuiSwitch-colorPrimary.Mui-checked + .MuiSwitch-track {
@include themed {
background-color: t($subColor) !important;
}
}
.MuiSwitch-track {
@include themed {
background-color: t($subColor) !important;
}
}
.MuiIconButton-label > svg.MuiSvgIcon-root {
@include themed {
color: t($color) !important;
}
}
.MuiTouchRipple-root {
background: transparent;
}
.MuiFormControl-root {
margin-top: 10px !important;
}
.checkbox svg {
@include themed {
fill: t($color) !important;
}
}
.radio-title {
font-weight: bold;
font-size: 1.17rem;
}
.radio-title-small {
font-weight: bold;
font-size: 1rem;
}
.MuiSlider-root {
margin-bottom: 30px !important;
}
.MuiOutlinedInput-notchedOutline {
@include themed {
border-color: t($color) !important;
}
}
.MuiFormLabel-root-MuiInputLabel-root {
@include themed {
color: t($color) !important;
}
}
.MuiInputLabel-root,
.MuiSlider-markLabel,
.MuiInputLabel-root,
.MuiSelect-icon,
.MuiSelect-select,
.Mui-focused,
legend,
.MuiOutlinedInput-input {
@include themed {
color: t($color) !important;
}
}
.MuiMenu-list {
@include themed {
background-color: t($modal-background);
color: t($color);
}
li {
&:hover {
@include themed {
background-color: t($modal-sidebarActive);
transition: 0.5s;
}
}
}
}
.Mui-selected {
@include themed {
background-color: t($modal-sidebarActive) !important;
}
}
.MuiTextField-root,
.MuiFormControl-root,
.MuiSlider-root {
width: 300px !important;
}
.Mui-disabled {
color: #818181 !important;
cursor: not-allowed;
.checkbox svg {
fill: #818181 !important;
}
}
.MuiPaper-root {
@include themed {
background-color: t($modal-background) !important;
}
}
.MuiSlider-valueLabel {
@include themed {
background-color: t($modal-sidebarActive) !important;
}
}
.MuiFormControlLabel-labelPlacementStart {
justify-content: flex-end;
}
.settingsRow {
.MuiFormControlLabel-root {
flex-direction: row-reverse;
margin-right: 0;
display: flex;
justify-content: space-between;
width: 100%;
margin-left: 0;
}
.MuiFormControlLabel-root {
width: 100%;
}
}
.css-w66kx-MuiChip-root {
@include themed {
color: t($color) !important;
border: 1px solid t($modal-sidebarActive);
background: t($modal-sidebar) !important;
border-radius: t($borderRadius);
}
text-transform: capitalize;
}

View File

@ -1,49 +0,0 @@
.aboutLink {
&:hover {
opacity: 0.8;
}
}
.aboutLogo {
height: 100px;
width: auto;
margin: calc(1rem - 15px) 0 1rem 0;
align-self: center;
}
.aboutContact {
flex-flow: row;
display: flex;
gap: 15px;
a {
@include basicIconButton(11px, 1.2rem, modal);
}
}
.contributorImages {
display: flex;
flex-wrap: wrap;
gap: 15px;
img {
width: 75px;
height: auto;
@include themed {
border-radius: t($borderRadius);
}
}
}
.subtitle-photographers {
font-size: 16px;
@include themed {
color: t($color);
span {
color: t($subColor);
}
}
}

Some files were not shown because too many files have changed in this diff Show More