Compare commits
285 Commits
Author | SHA1 | Date |
---|---|---|
alexsparkes | b88451311a | |
David Ralph | f4c1506107 | |
Isaac | 1e8db6c73c | |
Isaac | 9baf650d3d | |
Isaac | 82c0e58027 | |
David Ralph | e1f624d0cf | |
David Ralph | c46c433111 | |
alexsparkes | b102269161 | |
dependabot[bot] | ea5cba2e17 | |
dependabot[bot] | 31250ffa70 | |
dependabot[bot] | aee1d33f2d | |
dependabot[bot] | 2b2c3d4585 | |
dependabot[bot] | a7c3300a06 | |
dependabot[bot] | 8cd6908fe8 | |
dependabot[bot] | d39da02e4d | |
dependabot[bot] | cf235a8821 | |
dependabot[bot] | 1ec487d4f5 | |
dependabot[bot] | a757681684 | |
dependabot[bot] | e0094449a9 | |
dependabot[bot] | 57e1ebc9cf | |
David Ralph | 8f0ac31994 | |
David Ralph | 90425c30a5 | |
dependabot[bot] | 99be70835e | |
dependabot[bot] | 4c3c806aa8 | |
dependabot[bot] | e251c53fe0 | |
dependabot[bot] | a194c57777 | |
dependabot[bot] | 83b47d5a35 | |
dependabot[bot] | d90471c430 | |
dependabot[bot] | 9cc506bb69 | |
dependabot[bot] | ff63ab836a | |
dependabot[bot] | cc510e399d | |
David Ralph | ef5778ea59 | |
David Ralph | 8f9735044a | |
David Ralph | a21528f998 | |
dependabot[bot] | dcb510b642 | |
dependabot[bot] | 54f7a4fcb3 | |
dependabot[bot] | 92593c3584 | |
dependabot[bot] | ebbdb5fcc2 | |
dependabot[bot] | 02217694d3 | |
dependabot[bot] | 0351a79062 | |
dependabot[bot] | 7edc2e3878 | |
dependabot[bot] | 64e480febc | |
dependabot[bot] | c5971e8374 | |
alexsparkes | 9fd263b256 | |
dependabot[bot] | 6b7f8f901b | |
dependabot[bot] | c67b781fd5 | |
David Ralph | 71c48b6896 | |
dependabot[bot] | c16205fd0f | |
dependabot[bot] | fac8d82434 | |
dependabot[bot] | 603a585210 | |
dependabot[bot] | 64299212b7 | |
alexsparkes | d76e93481f | |
alexsparkes | 35e90225b0 | |
alexsparkes | ff48319c42 | |
alexsparkes | ccd6dc2d28 | |
alexsparkes | d931aa13b7 | |
alexsparkes | e7630e9357 | |
alexsparkes | 953ce3fdea | |
alexsparkes | 40e04af5d4 | |
dependabot[bot] | 7876bd69fd | |
alexsparkes | c1cba4dd5e | |
alexsparkes | a9f3992d2c | |
dependabot[bot] | 36e4ea5e55 | |
dependabot[bot] | 7b3bc12a54 | |
alexsparkes | 4af8733795 | |
David Ralph | 2136f558b9 | |
David Ralph | 57df2ce523 | |
dependabot[bot] | 0a4c90be99 | |
alexsparkes | ae0530cfc6 | |
alexsparkes | c2019de7d2 | |
alexsparkes | 920ba68108 | |
dependabot[bot] | 89b8840bb7 | |
David Ralph | 9b326737e1 | |
David Ralph | e0e3a38661 | |
alexsparkes | 86f64dfc98 | |
alexsparkes | 59357357bb | |
dependabot[bot] | aab6f42d55 | |
dependabot[bot] | 3644deccfe | |
dependabot[bot] | a6a383e4fc | |
dependabot[bot] | 66a10b8e50 | |
dependabot[bot] | 02c972ef67 | |
dependabot[bot] | 3c19ce5e83 | |
dependabot[bot] | ff976c6262 | |
dependabot[bot] | 52fedb6df3 | |
David Ralph | e587b3d6ea | |
alexsparkes | 908ad1cc3b | |
alexsparkes | bc52049a9b | |
dependabot[bot] | e48597cb45 | |
David Ralph | 9e868428c0 | |
David Ralph | e100513b37 | |
dependabot[bot] | f0fbb71f25 | |
dependabot[bot] | eebe558b6e | |
dependabot[bot] | 5622d1c89e | |
dependabot[bot] | 22405c66f0 | |
dependabot[bot] | 658838fccd | |
dependabot[bot] | 30a4686886 | |
dependabot[bot] | 7771136881 | |
dependabot[bot] | 5ded3984f6 | |
dependabot[bot] | b116a78c9f | |
dependabot[bot] | c4479dd94f | |
David Ralph | 12248db893 | |
alexsparkes | a049cb297d | |
alexsparkes | 9812aae740 | |
alexsparkes | 603a6c5acc | |
alexsparkes | 038185b656 | |
alexsparkes | ebb5e922bc | |
David Ralph | 3e1ac0cfbb | |
alexsparkes | c6b4359612 | |
alexsparkes | 67a387c73d | |
alexsparkes | 87bb3fb066 | |
alexsparkes | 66904cca47 | |
alexsparkes | 76c4a9d8b7 | |
alexsparkes | 851e6ff7e8 | |
alexsparkes | dbd85cdc95 | |
alexsparkes | 6041372860 | |
alexsparkes | 8bf70eff81 | |
alexsparkes | ebe0784e8d | |
alexsparkes | 7e78465406 | |
alexsparkes | 9a9d7bb136 | |
alexsparkes | 397c67ff83 | |
alexsparkes | 90092a80ea | |
alexsparkes | 03a55a21bd | |
alexsparkes | a45238ea54 | |
alexsparkes | 90ed4d8d7c | |
alexsparkes | 56463d3609 | |
alexsparkes | 4975bd3077 | |
alexsparkes | e0ced3de08 | |
alexsparkes | ffb1c513c9 | |
alexsparkes | fc9d1c3f65 | |
alexsparkes | 5a0185c574 | |
dependabot[bot] | 27b55c6bbd | |
alexsparkes | 6e85da363c | |
dependabot[bot] | dacb11d935 | |
David Ralph | 294b3830bf | |
David Ralph | 618b5fe466 | |
David Ralph | 10f12b20c5 | |
alexsparkes | 8fc6b1bf1b | |
dependabot[bot] | 6b9ae07d8a | |
dependabot[bot] | eb2c0ad210 | |
dependabot[bot] | b87ca6aa30 | |
dependabot[bot] | 896a00c4b2 | |
dependabot[bot] | 92290923d4 | |
dependabot[bot] | d1e69cbe98 | |
dependabot[bot] | 12b6f5b69e | |
alexsparkes | f8df95e7e0 | |
David Ralph | da43dbeed0 | |
alexsparkes | b9bb735371 | |
alexsparkes | 2f851d8933 | |
dependabot[bot] | 6fdb90961f | |
alexsparkes | 5b995eaf9f | |
alexsparkes | 53d649e04a | |
David Ralph | c9fb5109c9 | |
David Ralph | 35d4a7780c | |
alexsparkes | b6adfab047 | |
alexsparkes | bad8daac6b | |
alexsparkes | dbd0359ccc | |
alexsparkes | 8c7cfd3cb1 | |
alexsparkes | ad2af657d7 | |
alexsparkes | 9716ddd9af | |
alexsparkes | 6f00709c3d | |
alexsparkes | 84c1bc8df1 | |
alexsparkes | 48b919ebea | |
alexsparkes | 16639c4b94 | |
Wessel Tip | 8e1b7ab2ac | |
Wessel Tip | 3503e65039 | |
Wessel Tip | f309967214 | |
Wessel Tip | 7179ee2a87 | |
alexsparkes | f71c19d081 | |
alexsparkes | bd9c868196 | |
alexsparkes | 85b0e9826c | |
David Ralph | 21184c6c03 | |
alexsparkes | fba4012875 | |
dependabot[bot] | 5ebfc6c379 | |
alexsparkes | ad4532c150 | |
alexsparkes | 2f9acde332 | |
alexsparkes | 4f0a8207b1 | |
dependabot[bot] | df0e7bfec5 | |
alexsparkes | 959a928366 | |
alexsparkes | c7f21c295c | |
David Ralph | 6cb00cca9d | |
alexsparkes | cdae5ed29e | |
dependabot[bot] | b3b17ad234 | |
dependabot[bot] | 0bd23354cc | |
Wessel T | 87e6dfe4bf | |
LibreTranslate | 4c1392c24d | |
Wessel T | 8c0f7a7617 | |
Shashank | 0d77508f4c | |
dependabot[bot] | 59e721d663 | |
dependabot[bot] | 470957dc69 | |
dependabot[bot] | b53f9310e8 | |
dependabot[bot] | 044715d9a2 | |
dependabot[bot] | b9825f89af | |
dependabot[bot] | 85bb1f98ad | |
Wessel T | f188f2cf02 | |
dependabot[bot] | 9bbc6dc8b8 | |
Wessel Tip | 6dc0f8652a | |
Wessel Tip | b2fedb17c9 | |
alexsparkes | 8eb9e25a9c | |
alexsparkes | afc1c603d2 | |
Oğuz Ersen | acd6230399 | |
gallegonovato | ade1ee507f | |
alexsparkes | c3ff63fa91 | |
Alex Sparkes | a95197a763 | |
dependabot[bot] | cf8b6ab2fe | |
dependabot[bot] | 8748a7ea57 | |
dependabot[bot] | ef2fbe202b | |
dependabot[bot] | e14d67ce37 | |
alexsparkes | e1ff22a210 | |
dependabot[bot] | e97609cd11 | |
dependabot[bot] | 359f6e5d2b | |
dependabot[bot] | 461d0686ff | |
Oğuz Ersen | 24f2f79e72 | |
gallegonovato | c96a96eb71 | |
dependabot[bot] | ad60fe4aa7 | |
dependabot[bot] | 3d0d602e11 | |
dependabot[bot] | 5b61f94360 | |
dependabot[bot] | 16bebe0a33 | |
dependabot[bot] | 4593cc0c7e | |
dependabot[bot] | cde114d52c | |
dependabot[bot] | e01ef63e10 | |
dependabot[bot] | bac92080cb | |
dependabot[bot] | ba77423944 | |
dependabot[bot] | acfb67cf65 | |
dependabot[bot] | 7605c58e53 | |
dependabot[bot] | 78c348c3b5 | |
dependabot[bot] | eb498f8330 | |
dependabot[bot] | 48854b5842 | |
dependabot[bot] | 84477e3680 | |
dependabot[bot] | 8271ed813f | |
dependabot[bot] | 88661e725d | |
dependabot[bot] | 183c8a7e5e | |
alexsparkes | e1e282f406 | |
dependabot[bot] | 10832691c4 | |
dependabot[bot] | 1b598f5ced | |
Hosted Weblate | be11066e34 | |
Isaac | fd9e17aa8d | |
David Ralph | d98fd05b06 | |
David Ralph | 96f16352a6 | |
David Ralph | 3a2cbb377f | |
David Ralph | ea7b8b5036 | |
dependabot[bot] | 36d4c6d7bd | |
dependabot[bot] | 1d3a4cbb2e | |
dependabot[bot] | d1a6dd7de4 | |
dependabot[bot] | ab4e0dba1c | |
dependabot[bot] | b9ef591bc8 | |
alexsparkes | 6915c0ef9e | |
dependabot[bot] | 80dd8bcd8e | |
dependabot[bot] | 265180aedc | |
dependabot[bot] | 576723dd3d | |
dependabot[bot] | 4256ef1eed | |
Isaac | a7069fbf1e | |
David Ralph | c29376f715 | |
David Ralph | 2ba9714cad | |
David Ralph | 12b46de706 | |
David Ralph | d482deccb4 | |
dependabot[bot] | 50dfc81857 | |
dependabot[bot] | 54a1b6c512 | |
dependabot[bot] | fc946e5283 | |
dependabot[bot] | 19cfdf719c | |
David Ralph | de24d11463 | |
David Ralph | 270b774d7b | |
FreeFun | f67e732da1 | |
Samiul Islam | 28a065c198 | |
alexsparkes | 90110ec6cd | |
Samiul Islam | 32b3b48261 | |
Evgeniy Khramov | 77295f0dc3 | |
alexsparkes | 2972d9f76e | |
alexsparkes | 79261a6ab4 | |
alexsparkes | 901833da91 | |
Torch | a91ef8e596 | |
Torch | 48ab9a4ddd | |
Samiul Islam | 9adda47fed | |
Hosted Weblate | 5aa0c432f2 | |
Samiul Islam | 9baf0feab9 | |
David Ralph | 7131fa555e | |
David Ralph | ef3733d534 | |
dependabot[bot] | b1c1b98bb8 | |
David Ralph | fc6d988a52 | |
David Ralph | a035b70841 | |
David | e385dc6503 | |
David Ralph | b58d4ddc59 | |
Kağan Can Şit | 0b85ecd9d2 | |
David Ralph | 00c89596cd | |
dependabot[bot] | b3ac93b483 | |
alexsparkes | ede25cc513 |
|
@ -0,0 +1,27 @@
|
|||
# API URLs
|
||||
API_URL=https://api.muetab.com/v2
|
||||
SPONSORS_URL=https://sponsors.muetab.com
|
||||
GITHUB_URL=https://api.github.com
|
||||
OPENSTREETMAP_URL=https://www.openstreetmap.org
|
||||
|
||||
# Mue URLs
|
||||
WEBSITE_URL=https://muetab.com
|
||||
PRIVACY_URL=https://muetab.com/privacy
|
||||
BLOG_POST=https://blog.muetab.com/posts/version-7-0
|
||||
TRANSLATIONS_URL=https://docs.muetab.com/translations/
|
||||
WEBLATE_URL=https://hosted.weblate.org/projects/mue/mue-tab/
|
||||
REPORT_ITEM =https://github.com/mue/marketplace/issues/new?assignees=&labels=item+report&template=item-report.md&title=%5BItem+Report%5D+
|
||||
BUG_REPORT =https://github.com/mue/mue/issues/new?assignees=&labels=issue+report&template=bug-report.md&title=%5BBug%5D+
|
||||
DONATE_LINK=https://muetab.com/donate
|
||||
SENTRY_DSN =https://430352fd4b174d688ebd82fc85c22c58@o1217438.ingest.sentry.io/6359480
|
||||
KNOWLEDGEBASE=https://support.muetab.com
|
||||
|
||||
# Mue Info
|
||||
ORG_NAME=mue
|
||||
REPO_NAME=mue
|
||||
EMAIL=hello@muetab.com
|
||||
TWITTER_HANDLE=getmue
|
||||
DISCORD_SERVER=zv8C9F8
|
||||
OPENCOLLECTIVE_USERNAME=mue
|
||||
|
||||
VERSION=7.0.1
|
|
@ -24,10 +24,10 @@ If applicable, add screenshots to help explain your problem.
|
|||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. Windows, Ubuntu]
|
||||
- OS Version: [e.g 10, 19.10]
|
||||
- OS Version: [e.g 11, 23.10]
|
||||
- Browser: [e.g. Chrome, Firefox]
|
||||
- Browser Version: [e.g. 70]
|
||||
- Mue Version: [e.g. 0.5]
|
||||
- Browser Version: [e.g. 115]
|
||||
- Mue Version: [e.g. 7.1.0]
|
||||
- Resolution: [e.g 1920x1080]
|
||||
|
||||
**Additional context**
|
||||
|
|
|
@ -8,7 +8,7 @@ jobs:
|
|||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: "14.x"
|
||||
node-version: "20.x"
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
- name: Build
|
||||
|
|
4
LICENSE
|
@ -1,7 +1,7 @@
|
|||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2023- Kaiso One Ltd
|
||||
Copyright (c) 2019-2023 The Mue Authors
|
||||
Copyright (c) 2023-2024 Kaiso One Ltd
|
||||
Copyright (c) 2019-2024 The Mue Authors
|
||||
Copyright (c) 2018-2019 David Ralph
|
||||
|
||||
All rights reserved.
|
||||
|
|
11
README.md
|
@ -12,6 +12,7 @@ Mue is a fast, open and free-to-use browser extension that gives a new, fresh an
|
|||
<br>
|
||||
|
||||
## Table of contents
|
||||
|
||||
- [Table of contents](#table-of-contents)
|
||||
- [Screenshots](#screenshots)
|
||||
- [Features](#features)
|
||||
|
@ -48,7 +49,7 @@ Mue is a fast, open and free-to-use browser extension that gives a new, fresh an
|
|||
|
||||
### Planned Features
|
||||
|
||||
Please see our [roadmap](https://trello.com/b/w7zhS7Hi/mue-50).
|
||||
Please see our [roadmap](https://trello.com/b/w7zhS7Hi/mue-50). We are currently working on a rewrite over on the "phoenix" branch.
|
||||
|
||||
## Installation
|
||||
|
||||
|
@ -107,6 +108,7 @@ Please see the [documentation](https://docs.muetab.com/development#mue-tab).
|
|||
[Aksal](https://github.com/aksalsf) - Indonesian <br/>
|
||||
[Kağan Can Şit](https://github.com/KaganCanSit) - Turkish <br/>
|
||||
efeaydal - Turkish <br/>
|
||||
|
||||
### Contributors
|
||||
|
||||
Many thanks to the photographers [here](https://api.muetab.com/images/photographers) for letting us use their wonderful photographs.
|
||||
|
@ -117,10 +119,3 @@ And finally, a big thank you to all the other [contributors](https://github.com/
|
|||
|
||||
[Pexels](https://pexels.com), [Unsplash](https://unsplash.com) - Stock photos used for offline mode <br/>
|
||||
[Undraw](https://undraw.co) - Welcome modal images
|
||||
|
||||
<p>This project is supported by:</p>
|
||||
<p>
|
||||
<a href="https://www.digitalocean.com/">
|
||||
<img src="https://opensource.nyc3.cdn.digitaloceanspaces.com/attribution/assets/SVG/DO_Logo_horizontal_blue.svg" width="201px">
|
||||
</a>
|
||||
</p>
|
||||
|
|
111
index.html
|
@ -1,38 +1,113 @@
|
|||
<!DOCTYPE html>
|
||||
<!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" />
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/src/assets/icons/32x32.png" />
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/src/assets/icons/16x16.png" />
|
||||
<title>New Tab</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript>
|
||||
<style>
|
||||
*,
|
||||
a {
|
||||
@import url('https://fonts.googleapis.com/css2?family=Lexend+Deca:wght@400&display=swap');
|
||||
|
||||
* {
|
||||
font-family: 'Lexend Deca', sans-serif;
|
||||
text-align: center;
|
||||
color: black;
|
||||
background: white !important;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.criticalError {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.criticalError .criticalError-actions {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.criticalError a {
|
||||
border: 0;
|
||||
border-radius: 12px;
|
||||
padding: 10px 30px 10px 30px;
|
||||
font-size: 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-flow: row;
|
||||
justify-content: center;
|
||||
gap: 20px;
|
||||
transition: 0.5s;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
*,
|
||||
a {
|
||||
color: white;
|
||||
background: #2f3640 !important;
|
||||
* {
|
||||
background-color: #000000;
|
||||
}
|
||||
|
||||
.criticalError .criticalError-message {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.criticalError p {
|
||||
color: rgba(255, 255, 255, 0.7529411765);
|
||||
}
|
||||
|
||||
.criticalError a {
|
||||
background: #0e1013;
|
||||
box-shadow: 0 0 0 1px #484848;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.criticalError a:hover {
|
||||
background: #1e1e1e;
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
* {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.criticalError .criticalError-message {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.criticalError p {
|
||||
color: rgba(0, 0, 0, 0.7529411765);
|
||||
}
|
||||
|
||||
.criticalError a {
|
||||
background: #fdfdfd;
|
||||
box-shadow: 0 0 0 1px #484848;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.criticalError a:hover {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
}
|
||||
</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>
|
||||
<div class="criticalError">
|
||||
<div class="criticalError-message">
|
||||
<h1>A critical error has occurred</h1>
|
||||
<p>The new tab could not be loaded. Please enable JavaScript and try again.</p>
|
||||
<div class="criticalError-actions">
|
||||
<a href="https://github.com/mue/mue/issues/new/choose" target="_blank" rel="noreferrer"
|
||||
>Report Issue</a
|
||||
>
|
||||
<a href="https://discord.gg/zv8C9F8" target="_blank" rel="noreferrer"
|
||||
>Support Discord</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</noscript>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/index.jsx"></script>
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es6"
|
||||
"target": "es6",
|
||||
"baseUrl": "src"
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
|
|
@ -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'),
|
||||
});
|
||||
}
|
||||
});
|
|
@ -1,4 +1,9 @@
|
|||
/* eslint-disable no-use-before-define */
|
||||
/* eslint-disable no-undef */
|
||||
if (typeof browser === 'undefined') {
|
||||
var browser = chrome;
|
||||
}
|
||||
|
||||
browser.runtime.setUninstallURL('https://muetab.com/uninstall');
|
||||
|
||||
browser.runtime.onInstalled.addListener((details) => {
|
61
package.json
|
@ -9,46 +9,45 @@
|
|||
"homepage": "https://muetab.com",
|
||||
"bugs": "https://github.com/mue/mue/issues/new?assignees=&labels=bug&template=bug-report.md&title=%5BBUG%5D",
|
||||
"license": "BSD-3-Clause",
|
||||
"version": "7.0.0",
|
||||
"version": "7.1.0",
|
||||
"dependencies": {
|
||||
"@eartharoid/i18n": "1.2.1",
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@floating-ui/react-dom": "1.3.0",
|
||||
"@fontsource/lexend-deca": "5.0.5",
|
||||
"@fontsource/montserrat": "5.0.5",
|
||||
"@muetab/react-color-gradient-picker": "0.1.2",
|
||||
"@emotion/react": "^11.11.4",
|
||||
"@emotion/styled": "^11.11.5",
|
||||
"@floating-ui/react-dom": "2.0.9",
|
||||
"@fontsource/lexend-deca": "5.0.12",
|
||||
"@fontsource/montserrat": "5.0.17",
|
||||
"@muetab/react-sortable-hoc": "^2.0.1",
|
||||
"@mui/material": "5.14.8",
|
||||
"@sentry/react": "^7.58.1",
|
||||
"embla-carousel-autoplay": "8.0.0-rc11",
|
||||
"embla-carousel-react": "8.0.0-rc11",
|
||||
"@mui/material": "5.15.18",
|
||||
"@sentry/react": "^8.2.1",
|
||||
"embla-carousel-autoplay": "8.0.4",
|
||||
"embla-carousel-react": "8.0.4",
|
||||
"fast-blurhash": "^1.1.2",
|
||||
"image-conversion": "^2.1.1",
|
||||
"prop-types": "^15.8.1",
|
||||
"react": "^18.2.0",
|
||||
"react-clock": "4.5.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-icons": "^4.10.1",
|
||||
"react": "^18.3.1",
|
||||
"react-best-gradient-color-picker": "^3.0.7",
|
||||
"react-clock": "5.0.0",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-icons": "^5.2.1",
|
||||
"react-modal": "3.16.1",
|
||||
"react-toastify": "9.1.3"
|
||||
"react-toastify": "10.0.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^17.7.1",
|
||||
"@commitlint/config-conventional": "^17.6.6",
|
||||
"@commitlint/cli": "^19.3.0",
|
||||
"@commitlint/config-conventional": "^19.2.2",
|
||||
"@eartharoid/deep-merge": "^0.0.2",
|
||||
"@vitejs/plugin-react-swc": "^3.3.2",
|
||||
"adm-zip": "^0.5.10",
|
||||
"eslint": "^8.48.0",
|
||||
"eslint-config-prettier": "^8.8.0",
|
||||
"@vitejs/plugin-react-swc": "^3.6.0",
|
||||
"adm-zip": "^0.5.12",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-config-react-app": "^7.0.1",
|
||||
"husky": "^8.0.3",
|
||||
"prettier": "^3.0.0",
|
||||
"sass": "^1.63.6",
|
||||
"stylelint": "^15.10.3",
|
||||
"stylelint-config-standard-scss": "^10.0.0",
|
||||
"stylelint-scss": "^5.0.1",
|
||||
"vite": "4.4.4",
|
||||
"husky": "^9.0.11",
|
||||
"prettier": "^3.2.5",
|
||||
"sass": "^1.77.2",
|
||||
"stylelint": "^16.5.0",
|
||||
"stylelint-config-standard-scss": "^13.1.0",
|
||||
"stylelint-scss": "^6.3.0",
|
||||
"vite": "5.2.11",
|
||||
"vite-plugin-progress": "^0.0.7"
|
||||
},
|
||||
"scripts": {
|
||||
|
@ -59,6 +58,6 @@
|
|||
"pretty": "prettier --write \"./**/*.{js,jsx,json,scss,css}\"",
|
||||
"lint": "eslint \"./src/**/*.{js,jsx}\" && stylelint \"./src/**/*.{scss,css}\"",
|
||||
"lint:fix": "eslint \"./src/**/*.{js,jsx}\" --fix && stylelint \"./src/**/*.{scss,css}\" --fix",
|
||||
"postinstall": "husky install"
|
||||
"postinstall": "husky"
|
||||
}
|
||||
}
|
||||
|
|
9696
pnpm-lock.yaml
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 645 B |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 2.4 KiB |
|
@ -1,13 +1,7 @@
|
|||
// tl;dr this function merges the translation file with the english file in order to add untranslated strings
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
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)) {
|
||||
|
@ -20,20 +14,72 @@ const compareAndRemoveKeys = (json1, json2) => {
|
|||
}
|
||||
};
|
||||
|
||||
fs.readdirSync('../src/translations').forEach((file) => {
|
||||
const localesDir = path.join(__dirname, '../src/i18n/locales');
|
||||
const achievementsDir = path.join(localesDir, 'achievements');
|
||||
|
||||
// Check if the locales directory exists, if not, create it
|
||||
if (!fs.existsSync(localesDir)) {
|
||||
fs.mkdirSync(localesDir, { recursive: true });
|
||||
}
|
||||
|
||||
// Check if the achievements directory exists, if not, create it
|
||||
if (!fs.existsSync(achievementsDir)) {
|
||||
fs.mkdirSync(achievementsDir, { recursive: true });
|
||||
}
|
||||
|
||||
fs.readdirSync(localesDir).forEach((file) => {
|
||||
if (file === 'en_GB.json') {
|
||||
return;
|
||||
}
|
||||
|
||||
const en = require('../src/translations/en_GB.json');
|
||||
const newdata = merge(en, require('../src/translations/' + file));
|
||||
if (fs.lstatSync(path.join(localesDir, file)).isDirectory()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const en = require(path.join(localesDir, 'en_GB.json'));
|
||||
const newdata = merge(en, require(path.join(localesDir, file)));
|
||||
|
||||
// remove strings not in english file
|
||||
compareAndRemoveKeys(newdata, en);
|
||||
|
||||
// write new file
|
||||
fs.writeFileSync('../src/translations/' + file, JSON.stringify(newdata, null, 2));
|
||||
fs.writeFileSync(path.join(localesDir, file), JSON.stringify(newdata, null, 2));
|
||||
|
||||
// add new line
|
||||
fs.appendFileSync('../src/translations/' + file, '\n');
|
||||
fs.appendFileSync(path.join(localesDir, file), '\n');
|
||||
});
|
||||
|
||||
fs.readdirSync(achievementsDir).forEach((file) => {
|
||||
if (file === 'en_GB.json') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (fs.lstatSync(path.join(achievementsDir, file)).isDirectory()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const enGBFilePath = path.join(achievementsDir, 'en_GB.json');
|
||||
if (!fs.existsSync(enGBFilePath)) {
|
||||
console.error(`File 'en_GB.json' does not exist in the directory '${achievementsDir}'`);
|
||||
return;
|
||||
}
|
||||
|
||||
const en = require(enGBFilePath);
|
||||
const newdata = merge(en, require(path.join(achievementsDir, file)));
|
||||
|
||||
compareAndRemoveKeys(newdata, en);
|
||||
|
||||
fs.writeFileSync(path.join(achievementsDir, file), JSON.stringify(newdata, null, 2));
|
||||
|
||||
fs.appendFileSync(path.join(achievementsDir, file), '\n');
|
||||
|
||||
const locales = fs.readdirSync(localesDir);
|
||||
locales.forEach((locale) => {
|
||||
if (!fs.existsSync(path.join(achievementsDir, locale))) {
|
||||
// ignore directories
|
||||
if (fs.lstatSync(path.join(localesDir, locale)).isDirectory()) {
|
||||
return;
|
||||
}
|
||||
|
||||
fs.writeFileSync(path.join(achievementsDir, locale), JSON.stringify(en, null, 2));
|
||||
fs.appendFileSync(path.join(achievementsDir, locale), '\n');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
14
src/App.jsx
|
@ -1,14 +1,14 @@
|
|||
import variables from 'modules/variables';
|
||||
import variables from 'config/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 Background from 'features/background/Background';
|
||||
import Widgets from 'features/misc/views/Widgets';
|
||||
import Modals from 'features/misc/modals/Modals';
|
||||
|
||||
import { loadSettings, moveSettings } from 'modules/helpers/settings';
|
||||
import { loadSettings, moveSettings } from 'utils/settings';
|
||||
|
||||
import EventBus from 'modules/helpers/eventbus';
|
||||
import EventBus from 'utils/eventbus';
|
||||
|
||||
export default class App extends PureComponent {
|
||||
componentDidMount() {
|
||||
|
@ -38,7 +38,7 @@ export default class App extends PureComponent {
|
|||
render() {
|
||||
return (
|
||||
<>
|
||||
{localStorage.getItem('background') === 'true' ? <Background /> : null}
|
||||
{localStorage.getItem('background') === 'true' && <Background />}
|
||||
<ToastContainer
|
||||
position="bottom-right"
|
||||
autoClose={localStorage.getItem('toastDisplayTime') || 2500}
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
import React, { PureComponent } from 'react';
|
||||
|
||||
import { captureException } from '@sentry/react';
|
||||
|
||||
class ErrorBoundary extends PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
error: false,
|
||||
errorData: '',
|
||||
showReport: true,
|
||||
};
|
||||
}
|
||||
|
||||
componentDidCatch(error, errorInfo) {
|
||||
this.setState({ error: true, errorData: errorInfo });
|
||||
console.error('Error boundary caught an error:', error, errorInfo);
|
||||
}
|
||||
|
||||
reportError() {
|
||||
captureException(this.state.errorData);
|
||||
this.setState({
|
||||
showReport: false,
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.error) {
|
||||
return (
|
||||
<div className="criticalError">
|
||||
<div className="criticalError-message">
|
||||
<h1>A critical error has occurred</h1>
|
||||
<p>
|
||||
The new tab page could not be loaded. Please uninstall the extension and try again.
|
||||
</p>
|
||||
<div className="criticalError-actions">
|
||||
{this.state.showReport ? (
|
||||
<button onClick={() => this.reportError()}>Report Issue</button>
|
||||
) : (
|
||||
<p>Sent Successfully</p>
|
||||
)}
|
||||
<a href="https://discord.gg/zv8C9F8" target="_blank" rel="noreferrer">
|
||||
Support Discord
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
|
||||
export default ErrorBoundary;
|
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 804 B |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 7.9 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
Before Width: | Height: | Size: 308 KiB After Width: | Height: | Size: 308 KiB |
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 104 KiB |
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 94 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
Before Width: | Height: | Size: 274 KiB After Width: | Height: | Size: 274 KiB |
Before Width: | Height: | Size: 171 KiB After Width: | Height: | Size: 171 KiB |
Before Width: | Height: | Size: 161 KiB After Width: | Height: | Size: 161 KiB |
Before Width: | Height: | Size: 157 KiB After Width: | Height: | Size: 157 KiB |
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 136 KiB |
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 126 KiB |
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 124 KiB |
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 118 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 7.0 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
|
@ -1,20 +1,23 @@
|
|||
import variables from 'modules/variables';
|
||||
import variables from 'config/variables';
|
||||
|
||||
import { useState, memo } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { TextareaAutosize } from '@mui/material';
|
||||
import { MdAddLink, MdClose } from 'react-icons/md';
|
||||
import Tooltip from 'components/helpers/tooltip/Tooltip';
|
||||
import { Tooltip } from 'components/Elements';
|
||||
|
||||
function AddModal({ urlError, iconError, addLink, closeModal, edit, editData, editLink }) {
|
||||
const [name, setName] = useState(edit ? editData.name : '');
|
||||
const [url, setUrl] = useState(edit ? editData.url : '');
|
||||
const [icon, setIcon] = useState(edit ? editData.url : '');
|
||||
const [icon, setIcon] = useState(edit ? editData.icon : '');
|
||||
|
||||
return (
|
||||
<div className="smallModal" style={{ width: '260px' }}>
|
||||
<div className="addLinkModal">
|
||||
<div className="shareHeader">
|
||||
<span className="title">{variables.getMessage('widgets.quicklinks.new')}</span>
|
||||
<span className="title">
|
||||
{edit
|
||||
? variables.getMessage('widgets.quicklinks.edit')
|
||||
: variables.getMessage('widgets.quicklinks.new')}
|
||||
</span>
|
||||
<Tooltip title={variables.getMessage('modals.welcome.buttons.close')}>
|
||||
<div className="close" onClick={() => closeModal()}>
|
||||
<MdClose />
|
||||
|
@ -27,15 +30,14 @@ function AddModal({ urlError, iconError, addLink, closeModal, edit, editData, ed
|
|||
placeholder={variables.getMessage('widgets.quicklinks.name')}
|
||||
value={name}
|
||||
onChange={(e) => setName(e.target.value.replace(/(\r\n|\n|\r)/gm, ''))}
|
||||
style={{ gridColumn: 'span 2' }}
|
||||
/>
|
||||
<span className="dropdown-error" />
|
||||
<TextareaAutosize
|
||||
maxRows={10}
|
||||
placeholder={variables.getMessage('widgets.quicklinks.url')}
|
||||
value={url}
|
||||
onChange={(e) => setUrl(e.target.value.replace(/(\r\n|\n|\r)/gm, ''))}
|
||||
/>
|
||||
<span className="dropdown-error">{urlError}</span>
|
||||
<TextareaAutosize
|
||||
maxRows={10}
|
||||
maxLines={1}
|
||||
|
@ -43,7 +45,11 @@ function AddModal({ urlError, iconError, addLink, closeModal, edit, editData, ed
|
|||
value={icon}
|
||||
onChange={(e) => setIcon(e.target.value.replace(/(\r\n|\n|\r)/gm, ''))}
|
||||
/>
|
||||
<span className="dropdown-error">{iconError}</span>
|
||||
</div>
|
||||
<div className="addFooter">
|
||||
<span className="dropdown-error">
|
||||
{iconError} {urlError}
|
||||
</span>
|
||||
{edit ? (
|
||||
<button
|
||||
style={{
|
||||
|
@ -60,6 +66,7 @@ function AddModal({ urlError, iconError, addLink, closeModal, edit, editData, ed
|
|||
height: '16px',
|
||||
fontSize: '15px',
|
||||
}}
|
||||
className="btn-settings"
|
||||
onClick={() => addLink(name, url, icon)}
|
||||
>
|
||||
<MdAddLink /> {variables.getMessage('widgets.quicklinks.add')}
|
||||
|
@ -70,14 +77,5 @@ function AddModal({ urlError, iconError, addLink, closeModal, edit, editData, ed
|
|||
);
|
||||
}
|
||||
|
||||
AddModal.propTypes = {
|
||||
urlError: PropTypes.string.isRequired,
|
||||
iconError: PropTypes.string.isRequired,
|
||||
addLink: PropTypes.func.isRequired,
|
||||
closeModal: PropTypes.func.isRequired,
|
||||
edit: PropTypes.bool.isRequired,
|
||||
editData: PropTypes.object.isRequired,
|
||||
editLink: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default memo(AddModal);
|
||||
const MemoizedAddModal = memo(AddModal);
|
||||
export { MemoizedAddModal as default, MemoizedAddModal as AddModal };
|
|
@ -0,0 +1 @@
|
|||
export * from './AddModal';
|
|
@ -0,0 +1,56 @@
|
|||
import React, { forwardRef } from 'react';
|
||||
import Tooltip from 'components/Elements/Tooltip/Tooltip';
|
||||
|
||||
const Button = forwardRef(
|
||||
(
|
||||
{ icon, label, type, iconPlacement, onClick, active, disabled, tooltipTitle, tooltipKey },
|
||||
ref,
|
||||
) => {
|
||||
let className;
|
||||
|
||||
switch (type) {
|
||||
case 'settings':
|
||||
className = 'btn-settings';
|
||||
break;
|
||||
case 'secondary':
|
||||
className = 'btn-secondary';
|
||||
break;
|
||||
case 'icon':
|
||||
className = 'btn-icon';
|
||||
break;
|
||||
case 'navigation':
|
||||
className = 'btn-navigation';
|
||||
break;
|
||||
case 'collection':
|
||||
className = 'btn-collection';
|
||||
break;
|
||||
default:
|
||||
className = 'btn-default';
|
||||
}
|
||||
|
||||
if (iconPlacement === 'right') {
|
||||
className += ' flowReverse';
|
||||
}
|
||||
|
||||
if (active) {
|
||||
className += ` ${className}-active`;
|
||||
}
|
||||
|
||||
const button = (
|
||||
<button className={className} onClick={onClick} ref={ref} disabled={disabled}>
|
||||
{icon}
|
||||
{label}
|
||||
</button>
|
||||
);
|
||||
|
||||
return type === 'icon' ? (
|
||||
<Tooltip title={tooltipTitle} key={tooltipKey}>
|
||||
{button}
|
||||
</Tooltip>
|
||||
) : (
|
||||
button
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
export { Button as default, Button };
|
|
@ -0,0 +1 @@
|
|||
export * from './Button';
|
|
@ -1,23 +1,19 @@
|
|||
import variables from 'modules/variables';
|
||||
import variables from 'config/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'));
|
||||
import { Tooltip } from 'components/Elements';
|
||||
const Settings = lazy(() => import('../../../features/misc/views/Settings'));
|
||||
const Addons = lazy(() => import('../../../features/misc/views/Addons'));
|
||||
const Marketplace = lazy(() => import('../../../features/misc/views/Marketplace'));
|
||||
|
||||
const renderLoader = () => (
|
||||
<div style={{ display: 'flex', width: '100%', minHeight: '100%' }}>
|
||||
<ul className="sidebar">
|
||||
<div className="modalSidebar">
|
||||
<span className="mainTitle">Mue</span>
|
||||
</ul>
|
||||
<div className="tab-content" style={{ width: '100%' }}>
|
||||
</div>
|
||||
<div className="modalTabContent">
|
||||
<div className="emptyItems">
|
||||
<div className="emptyMessage">
|
||||
<div className="loaderHolder">
|
||||
|
@ -31,27 +27,22 @@ const renderLoader = () => (
|
|||
);
|
||||
|
||||
function MainModal({ modalClose }) {
|
||||
const [currentTab, setCurrentTab] = useState(0);
|
||||
const [currentTab, setCurrentTab] = useState('settings');
|
||||
|
||||
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;
|
||||
}
|
||||
setCurrentTab(type);
|
||||
};
|
||||
|
||||
if (currentTab === 0) {
|
||||
setCurrentTab(<Settings changeTab={changeTab} />);
|
||||
}
|
||||
const renderTab = () => {
|
||||
switch (currentTab) {
|
||||
case 'addons':
|
||||
return <Addons changeTab={changeTab} />;
|
||||
case 'marketplace':
|
||||
return <Marketplace changeTab={changeTab} />;
|
||||
default:
|
||||
return <Settings changeTab={changeTab} />;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="frame">
|
||||
|
@ -64,13 +55,10 @@ function MainModal({ modalClose }) {
|
|||
<MdClose />
|
||||
</span>
|
||||
</Tooltip>
|
||||
<Suspense fallback={renderLoader()}>{currentTab}</Suspense>
|
||||
<Suspense fallback={renderLoader()}>{renderTab()}</Suspense>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
MainModal.propTypes = {
|
||||
modalClose: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default memo(MainModal);
|
||||
const MemoizedMainModal = memo(MainModal);
|
||||
export { MemoizedMainModal as default, MemoizedMainModal as MainModal };
|
|
@ -0,0 +1,104 @@
|
|||
import variables from 'config/variables';
|
||||
import { memo, useState, useEffect } from 'react';
|
||||
import {
|
||||
MdSettings as Settings,
|
||||
MdWidgets as Addons,
|
||||
MdShoppingBasket as Marketplace,
|
||||
MdMenu as Navbar,
|
||||
MdEmojiPeople as Greeting,
|
||||
MdAccessAlarm as Time,
|
||||
MdOutlineFormatQuote as Quote,
|
||||
MdLink as QuickLinks,
|
||||
MdDateRange as Date,
|
||||
MdOutlineTextsms as Message,
|
||||
MdOutlinePhoto as Background,
|
||||
MdSearch,
|
||||
MdCloudQueue as Weather,
|
||||
MdFormatPaint as Appearance,
|
||||
MdTranslate as Language,
|
||||
MdOutlineSettings as Advanced,
|
||||
MdBugReport as Experimental,
|
||||
MdOutlineAssessment as Stats,
|
||||
MdOutlineNewReleases as Changelog,
|
||||
MdInfoOutline as About,
|
||||
MdOutlineExtension as Added,
|
||||
MdAddCircleOutline as Create,
|
||||
MdViewAgenda as Overview,
|
||||
MdCollectionsBookmark as Collections,
|
||||
} from 'react-icons/md';
|
||||
|
||||
const iconMapping = {
|
||||
[variables.getMessage('modals.main.marketplace.product.overview')]: <Overview />,
|
||||
[variables.getMessage('modals.main.navbar.settings')]: <Settings />,
|
||||
[variables.getMessage('modals.main.navbar.addons')]: <Addons />,
|
||||
[variables.getMessage('modals.main.navbar.marketplace')]: <Marketplace />,
|
||||
[variables.getMessage('modals.main.settings.sections.appearance.navbar.title')]: <Navbar />,
|
||||
[variables.getMessage('modals.main.settings.sections.greeting.title')]: <Greeting />,
|
||||
[variables.getMessage('modals.main.settings.sections.time.title')]: <Time />,
|
||||
[variables.getMessage('modals.main.settings.sections.quicklinks.title')]: <QuickLinks />,
|
||||
[variables.getMessage('modals.main.settings.sections.quote.title')]: <Quote />,
|
||||
[variables.getMessage('modals.main.settings.sections.date.title')]: <Date />,
|
||||
[variables.getMessage('modals.main.settings.sections.message.title')]: <Message />,
|
||||
[variables.getMessage('modals.main.settings.sections.background.title')]: <Background />,
|
||||
[variables.getMessage('modals.main.settings.sections.search.title')]: <MdSearch />,
|
||||
[variables.getMessage('modals.main.settings.sections.weather.title')]: <Weather />,
|
||||
[variables.getMessage('modals.main.settings.sections.appearance.title')]: <Appearance />,
|
||||
[variables.getMessage('modals.main.settings.sections.language.title')]: <Language />,
|
||||
[variables.getMessage('modals.main.settings.sections.advanced.title')]: <Advanced />,
|
||||
[variables.getMessage('modals.main.settings.sections.stats.title')]: <Stats />,
|
||||
[variables.getMessage('modals.main.settings.sections.experimental.title')]: <Experimental />,
|
||||
[variables.getMessage('modals.main.settings.sections.changelog.title')]: <Changelog />,
|
||||
[variables.getMessage('modals.main.settings.sections.about.title')]: <About />,
|
||||
[variables.getMessage('modals.main.addons.added')]: <Added />,
|
||||
[variables.getMessage('modals.main.addons.create.title')]: <Create />,
|
||||
[variables.getMessage('modals.main.marketplace.all')]: <Addons />,
|
||||
[variables.getMessage('modals.main.marketplace.photo_packs')]: <Background />,
|
||||
[variables.getMessage('modals.main.marketplace.quote_packs')]: <Quote />,
|
||||
[variables.getMessage('modals.main.marketplace.preset_settings')]: <Advanced />,
|
||||
[variables.getMessage('modals.main.marketplace.collections')]: <Collections />,
|
||||
};
|
||||
|
||||
function Tab({ label, currentTab, onClick, navbarTab }) {
|
||||
const [isExperimental, setIsExperimental] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
setIsExperimental(localStorage.getItem('experimental') !== 'false');
|
||||
}, []);
|
||||
|
||||
let className = navbarTab ? 'navbar-item' : 'tab-list-item';
|
||||
if (currentTab === label) {
|
||||
className += navbarTab ? ' navbar-item-active' : ' tab-list-active';
|
||||
}
|
||||
|
||||
const icon = iconMapping[label];
|
||||
const divider = [
|
||||
variables.getMessage('modals.main.settings.sections.weather.title'),
|
||||
variables.getMessage('modals.main.settings.sections.language.title'),
|
||||
variables.getMessage('modals.main.marketplace.all'),
|
||||
variables.getMessage('modals.main.settings.sections.experimental.title'),
|
||||
].includes(label);
|
||||
const mue = [
|
||||
variables.getMessage('modals.main.marketplace.product.overview'),
|
||||
variables.getMessage('modals.main.addons.added'),
|
||||
variables.getMessage('modals.main.marketplace.all'),
|
||||
].includes(label);
|
||||
|
||||
if (
|
||||
label === variables.getMessage('modals.main.settings.sections.experimental.title') &&
|
||||
!isExperimental
|
||||
) {
|
||||
return <hr />;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{mue && <span className="mainTitle">Mue</span>}
|
||||
<button className={className} onClick={() => onClick(label)}>
|
||||
{icon} <span>{label}</span>
|
||||
</button>
|
||||
{divider && <hr />}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default memo(Tab);
|
|
@ -0,0 +1,121 @@
|
|||
import variables from 'config/variables';
|
||||
import { PureComponent } from 'react';
|
||||
import {
|
||||
MdSettings,
|
||||
MdOutlineShoppingBasket,
|
||||
MdOutlineExtension,
|
||||
MdRefresh,
|
||||
MdClose,
|
||||
} from 'react-icons/md';
|
||||
import Tab from './Tab';
|
||||
import { Button } from 'components/Elements';
|
||||
import ErrorBoundary from '../../../../features/misc/modals/ErrorBoundary';
|
||||
|
||||
class Tabs extends PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
currentTab: this.props.children[0].props.label,
|
||||
currentName: this.props.children[0].props.name,
|
||||
};
|
||||
}
|
||||
|
||||
onClick = (tab, name) => {
|
||||
if (name !== this.state.currentName) {
|
||||
variables.stats.postEvent('tab', `Opened ${name}`);
|
||||
}
|
||||
|
||||
this.setState({
|
||||
currentTab: tab,
|
||||
currentName: name,
|
||||
});
|
||||
};
|
||||
|
||||
hideReminder() {
|
||||
localStorage.setItem('showReminder', false);
|
||||
document.querySelector('.reminder-info').style.display = 'none';
|
||||
}
|
||||
|
||||
render() {
|
||||
const navbarButtons = [
|
||||
{
|
||||
tab: 'settings',
|
||||
icon: <MdSettings />,
|
||||
},
|
||||
{
|
||||
tab: 'addons',
|
||||
icon: <MdOutlineExtension />,
|
||||
},
|
||||
{
|
||||
tab: 'marketplace',
|
||||
icon: <MdOutlineShoppingBasket />,
|
||||
},
|
||||
];
|
||||
|
||||
const reminderInfo = (
|
||||
<div
|
||||
className="reminder-info"
|
||||
style={{ display: localStorage.getItem('showReminder') === 'true' ? 'flex' : 'none' }}
|
||||
>
|
||||
<div className="shareHeader">
|
||||
<span className="title">
|
||||
{variables.getMessage('modals.main.settings.reminder.title')}
|
||||
</span>
|
||||
<span className="closeModal" onClick={() => this.hideReminder()}>
|
||||
<MdClose />
|
||||
</span>
|
||||
</div>
|
||||
<span className="subtitle">
|
||||
{variables.getMessage('modals.main.settings.reminder.message')}
|
||||
</span>
|
||||
<button onClick={() => window.location.reload()}>
|
||||
<MdRefresh />
|
||||
{variables.getMessage('modals.main.error_boundary.refresh')}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<div style={{ display: 'flex', width: '100%', minHeight: '100%' }}>
|
||||
<div className="modalSidebar">
|
||||
{this.props.children.map((tab, index) => (
|
||||
<Tab
|
||||
currentTab={this.state.currentTab}
|
||||
key={index}
|
||||
label={tab.props.label}
|
||||
onClick={(nextTab) => this.onClick(nextTab, tab.props.name)}
|
||||
navbarTab={this.props.navbar || false}
|
||||
/>
|
||||
))}
|
||||
{reminderInfo}
|
||||
</div>
|
||||
<div className="modalTabContent">
|
||||
<div className="modalNavbar">
|
||||
{navbarButtons.map(({ tab, icon }, index) => (
|
||||
<Button
|
||||
type="navigation"
|
||||
onClick={() => this.props.changeTab(tab)}
|
||||
icon={icon}
|
||||
label={variables.getMessage(`modals.main.navbar.${tab}`)}
|
||||
active={this.props.current === tab}
|
||||
key={`${tab}-${index}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
{this.props.children.map((tab, index) => {
|
||||
if (tab.props.label !== this.state.currentTab) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return (
|
||||
<ErrorBoundary key={`error-boundary-${index}`}>{tab.props.children}</ErrorBoundary>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Tabs;
|
|
@ -0,0 +1 @@
|
|||
export * from './Main';
|
|
@ -1,7 +1,7 @@
|
|||
@import 'scss/variables';
|
||||
@import 'modules/sidebar';
|
||||
@import 'modules/navbar';
|
||||
@import 'modules/tab-content';
|
||||
@import 'modules/modalTabContent';
|
||||
@import 'modules/links';
|
||||
@import 'modules/scrollbars';
|
||||
@import 'settings/main';
|
||||
|
@ -10,10 +10,7 @@
|
|||
.Overlay {
|
||||
position: fixed;
|
||||
z-index: 100;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
inset: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
display: grid;
|
||||
|
@ -52,13 +49,16 @@
|
|||
padding: 0.5em;
|
||||
border-radius: 12px;
|
||||
cursor: pointer;
|
||||
transition: 0.5s;
|
||||
|
||||
svg {
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: rgb(121 121 121 / 22.6%);
|
||||
@include themed {
|
||||
background: t($modal-sidebarActive);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,6 +164,21 @@ h5 {
|
|||
}
|
||||
}
|
||||
|
||||
.headerActions {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
gap: 20px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.link {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
gap: 15px;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.marketplaceCondition {
|
||||
display: flex;
|
||||
flex-flow: row !important;
|
||||
|
@ -244,6 +259,16 @@ h5 {
|
|||
flex-flow: row;
|
||||
align-items: center;
|
||||
gap: 25px;
|
||||
|
||||
svg {
|
||||
@include themed {
|
||||
background-image: t($slightGradient);
|
||||
box-shadow: t($boxShadow);
|
||||
}
|
||||
|
||||
padding: 15px;
|
||||
border-radius: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
|
@ -1,7 +1,6 @@
|
|||
// this file is too long
|
||||
@import 'modules/item';
|
||||
@import 'modules/buttons';
|
||||
@import 'modules/featured';
|
||||
@import 'modules/lightbox';
|
||||
@import 'scss/variables';
|
||||
|
||||
|
@ -184,64 +183,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.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%;
|
||||
|
@ -255,6 +196,15 @@
|
|||
grid-gap: 5px;
|
||||
padding: 50px;
|
||||
|
||||
.title,
|
||||
svg {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
svg {
|
||||
font-size: 70px;
|
||||
}
|
||||
|
||||
@include themed {
|
||||
.sideloadIcon {
|
||||
font-size: 50px;
|
||||
|
@ -346,49 +296,12 @@ p.author {
|
|||
}
|
||||
}
|
||||
|
||||
.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;
|
||||
padding: 15px;
|
||||
gap: 15px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: 15px;
|
||||
|
||||
@include themed {
|
||||
background: t($modal-sidebar);
|
||||
border-radius: t($borderRadius);
|
||||
box-shadow: 0 0 0 4px t($modal-sidebarActive);
|
||||
}
|
||||
|
||||
.MuiFormControl-root {
|
||||
margin-bottom: 10px;
|
||||
|
@ -445,24 +358,6 @@ p.author {
|
|||
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 {
|
||||
|
@ -499,58 +394,6 @@ p.author {
|
|||
.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 {
|
||||
|
@ -590,15 +433,17 @@ a.collectionButton {
|
|||
}
|
||||
|
||||
.inCollection {
|
||||
background-image: linear-gradient(to left, transparent, #000),
|
||||
url('https://external-preview.redd.it/JyhsEoGMhKIMi3kvfBS24L0IllAO_KrIm4UI-dA1Ax4.jpg?auto=webp&s=b5adf9859b2c1855a5b3085f9453a6e878548505');
|
||||
// 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;
|
||||
margin-top: 15px;
|
||||
|
||||
@include themed {
|
||||
box-shadow: 0 0 0 4px t($modal-sidebarActive);
|
||||
background-color: t($modal-secondaryColour);
|
||||
box-shadow: 0 0 0 1px t($modal-sidebarActive);
|
||||
border-radius: t($borderRadius);
|
||||
}
|
||||
}
|
||||
|
@ -614,3 +459,24 @@ a.collectionButton {
|
|||
font-size: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.topAddons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.modalHeader {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 15px;
|
||||
|
||||
.tooltip {
|
||||
margin-right: 25px;
|
||||
}
|
||||
|
||||
.mainTitle {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
.updateCheck {
|
||||
flex-flow: row !important;
|
||||
}
|
||||
|
||||
.btn-settings {
|
||||
@include modal-button(standard);
|
||||
|
||||
display: inline;
|
||||
margin-top: 0;
|
||||
float: none !important;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
@include modal-button(secondary);
|
||||
|
||||
display: inline;
|
||||
margin-top: 0;
|
||||
float: none !important;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.btn-navigation {
|
||||
@include modal-button(standard);
|
||||
|
||||
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) {
|
||||
.btn-navigation {
|
||||
display: inline-block !important;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-navigation-active {
|
||||
@include themed {
|
||||
background: t($modal-sidebarActive) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-collection {
|
||||
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;
|
||||
border-radius: 12px;
|
||||
height: 40px;
|
||||
font-size: 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-flow: row;
|
||||
justify-content: center;
|
||||
gap: 20px;
|
||||
transition: 0.5s;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
backdrop-filter: blur(16px) saturate(180%);
|
||||
background-color: rgb(17 25 40 / 20%);
|
||||
border: 1px solid rgb(255 255 255 / 12.5%);
|
||||
}
|
||||
|
||||
&:active {
|
||||
@include themed {
|
||||
background: t($modal-sidebarActive);
|
||||
box-shadow: 0 0 0 1px t($color);
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
@include themed {
|
||||
background: t($modal-sidebarActive);
|
||||
box-shadow: 0 0 0 1px t($color);
|
||||
}
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
@include themed {
|
||||
background: t($modal-sidebarActive);
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a.btn-collection {
|
||||
height: 40px;
|
||||
text-decoration: none;
|
||||
|
||||
@include themed {
|
||||
border-radius: t($borderRadius);
|
||||
}
|
||||
}
|
||||
|
||||
.flowReverse {
|
||||
flex-flow: row-reverse !important;
|
||||
}
|
||||
|
||||
.btn-icon {
|
||||
@include modal-button(standard);
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
.side {
|
||||
float: right;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
p.description {
|
||||
margin-top: 0;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.infoItem {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
flex: 1 0 44%;
|
||||
|
||||
svg {
|
||||
@include themed {
|
||||
background-image: t($slightGradient);
|
||||
}
|
||||
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
font-size: 20px;
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
.text {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
}
|
||||
}
|
||||
|
||||
.header {
|
||||
text-transform: uppercase;
|
||||
|
||||
@include themed {
|
||||
color: t($subColor);
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
@include themed {
|
||||
color: t($color);
|
||||
}
|
||||
}
|
||||
|
||||
@include themed {
|
||||
background: t($modal-secondaryColour);
|
||||
box-shadow: 0 0 0 1px t($modal-sidebarActive);
|
||||
border-radius: t($borderRadius);
|
||||
padding: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.showMoreItems {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.marketplaceDescription {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
gap: 15px;
|
||||
}
|
|
@ -1,9 +1,11 @@
|
|||
@import 'scss/variables';
|
||||
|
||||
.tab-content {
|
||||
button {
|
||||
.modalTabContent {
|
||||
width: 100% !important;
|
||||
|
||||
/* button {
|
||||
@include modal-button(standard);
|
||||
}
|
||||
} */
|
||||
|
||||
@include themed {
|
||||
padding: 1rem 3rem 3rem;
|
||||
|
@ -25,9 +27,10 @@
|
|||
align-items: center;
|
||||
min-height: 100px;
|
||||
justify-content: space-between;
|
||||
transition: 0.4s ease-in-out;
|
||||
|
||||
/* border-top: 1px solid #ccc; */
|
||||
border-bottom: 1px solid #ccc;
|
||||
border-bottom: 1px solid #676767;
|
||||
padding-top: 1rem;
|
||||
padding-bottom: 1rem;
|
||||
|
||||
|
@ -49,30 +52,36 @@
|
|||
|
||||
button {
|
||||
margin-top: 10px;
|
||||
width: 283px;
|
||||
}
|
||||
|
||||
.link {
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
gap: 15px;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.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;
|
||||
.resetDataButtonsLayout {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-gap: 20px;
|
||||
|
||||
:nth-child(1) {
|
||||
grid-column: span 2;
|
||||
}
|
||||
|
||||
button {
|
||||
@include modal-button(standard);
|
||||
padding: 5px 10px 5px 10px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
table {
|
||||
border-collapse: separate;
|
||||
|
||||
|
@ -139,6 +148,12 @@ table {
|
|||
padding: 25px;
|
||||
justify-content: space-between;
|
||||
|
||||
@include themed {
|
||||
background: t($modal-sidebar);
|
||||
border-radius: t($borderRadius);
|
||||
box-shadow: 0 0 0 1px t($modal-sidebarActive);
|
||||
}
|
||||
|
||||
div:nth-child(1) {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
|
@ -147,15 +162,14 @@ table {
|
|||
}
|
||||
|
||||
.icon {
|
||||
border-radius: 100%;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
padding: 15px;
|
||||
font-size: 25px;
|
||||
|
||||
@include themed {
|
||||
background: t($modal-sidebarActive);
|
||||
background-image: t($slightGradient);
|
||||
box-shadow: t($boxShadow);
|
||||
}
|
||||
|
||||
padding: 15px;
|
||||
border-radius: 100%;
|
||||
font-size: 25px;
|
||||
}
|
||||
|
||||
.messageText {
|
||||
|
@ -180,11 +194,6 @@ table {
|
|||
.messageAction {
|
||||
float: right;
|
||||
}
|
||||
|
||||
@include themed {
|
||||
background: t($modal-sidebar);
|
||||
border-radius: t($borderRadius);
|
||||
}
|
||||
}
|
||||
|
||||
.messagesContainer {
|
||||
|
@ -192,3 +201,46 @@ table {
|
|||
flex-flow: column;
|
||||
gap: 25px;
|
||||
}
|
||||
|
||||
.eventDateSelection {
|
||||
display: flex !important;
|
||||
flex-flow: row !important;
|
||||
gap: 5px !important;
|
||||
text-align: center !important;
|
||||
@include themed() {
|
||||
background: t($modal-sidebar);
|
||||
box-shadow: t($boxShadow);
|
||||
color: t($color) !important;
|
||||
}
|
||||
hr {
|
||||
height: 100%;
|
||||
margin-right: 5px;
|
||||
@include themed {
|
||||
border-color: t($modal-secondaryColour);
|
||||
}
|
||||
}
|
||||
text-align: center;
|
||||
border-radius: 12px;
|
||||
height: 40px;
|
||||
font-size: 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-flow: row;
|
||||
justify-content: center;
|
||||
gap: 20px;
|
||||
transition: 0.5s;
|
||||
cursor: pointer;
|
||||
border: 0;
|
||||
padding-left: 10px;
|
||||
padding-right: 5px;
|
||||
input[type='tel'] {
|
||||
background: none;
|
||||
outline: none;
|
||||
border: none;
|
||||
max-width: 20px;
|
||||
text-align: center;
|
||||
@include themed {
|
||||
color: t($color) !important;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
#modal {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.modalNavbar {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
gap: 25px;
|
||||
margin-bottom: 1rem;
|
||||
}
|
|
@ -1,18 +1,17 @@
|
|||
@import 'scss/variables';
|
||||
|
||||
.sidebar {
|
||||
.modalSidebar {
|
||||
@include themed {
|
||||
top: 0;
|
||||
left: 0;
|
||||
position: sticky;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
padding: 0 5px;
|
||||
background: t($modal-sidebar);
|
||||
border-radius: 12px 0 0 12px;
|
||||
overflow-y: auto;
|
||||
overflow: hidden auto;
|
||||
height: 80vh;
|
||||
min-width: 250px;
|
||||
overflow-x: hidden;
|
||||
|
||||
.mainTitle {
|
||||
text-align: center;
|
||||
|
@ -73,3 +72,8 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.css-j204z7-MuiFormControlLabel-root {
|
||||
margin-left: 0 !important;
|
||||
margin-right: 0 !important;
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
@import 'modules/resetmodal';
|
||||
@import 'scss/variables';
|
||||
@import 'modules/material-ui';
|
||||
@import 'modules/tabs/about';
|
||||
@import 'modules/tabs/changelog';
|
||||
@import 'modules/tabs/order';
|
||||
@import 'modules/tabs/stats';
|
||||
|
||||
input {
|
||||
/* colour picker */
|
||||
|
@ -42,10 +42,6 @@ input {
|
|||
vertical-align: middle;
|
||||
background: none;
|
||||
|
||||
&::-moz-color-swatch-wrapper {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&::-moz-color-swatch {
|
||||
border: none;
|
||||
border-radius: 100%;
|
||||
|
@ -55,10 +51,11 @@ input {
|
|||
/* date picker */
|
||||
&[type='date'] {
|
||||
width: 260px;
|
||||
flex-flow: column;
|
||||
|
||||
@include themed {
|
||||
background: t($modal-sidebar);
|
||||
border: 3px solid t($modal-sidebarActive);
|
||||
border: 1px solid t($modal-sidebarActive);
|
||||
color: t($color);
|
||||
}
|
||||
|
||||
|
@ -132,139 +129,18 @@ h4 {
|
|||
}
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.preferences {
|
||||
transition: 0.4s ease-in-out;
|
||||
}
|
||||
|
||||
.preferencesInactive {
|
||||
opacity: 0.5;
|
||||
pointer-events: none;
|
||||
transition: 0.4s ease-in-out;
|
||||
}
|
|
@ -170,3 +170,12 @@ legend,
|
|||
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.MuiChip-root {
|
||||
text-transform: capitalize;
|
||||
|
||||
@include themed {
|
||||
background: t($modal-sidebarActive) !important;
|
||||
color: t($color) !important;
|
||||
}
|
||||
}
|
|
@ -47,3 +47,9 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.aboutText {
|
||||
text-align: center;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
.updateChangelog {
|
||||
max-width: 75%;
|
||||
margin-top: 15px;
|
||||
white-space: pre-wrap;
|
||||
|
||||
a {
|
||||
color: var(--modal-link);
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.changelogtab {
|
||||
.mainTitle {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 95%;
|
||||
}
|
||||
}
|
|
@ -1,14 +1,15 @@
|
|||
@import 'scss/variables';
|
||||
|
||||
.sortableItem {
|
||||
cursor: move;
|
||||
width: 200px;
|
||||
z-index: 999 !important;
|
||||
padding: 15px;
|
||||
margin-bottom: 10px;
|
||||
font-size: 1.325rem;
|
||||
|
||||
@include themed {
|
||||
padding: 15px;
|
||||
margin-bottom: 10px;
|
||||
font-size: 1.325rem;
|
||||
color: t($color) !important;
|
||||
cursor: move;
|
||||
width: 200px;
|
||||
z-index: 999 !important;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
|
@ -0,0 +1,135 @@
|
|||
.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.achievements {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
.achievementsGrid {
|
||||
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;
|
||||
}
|
||||
|
||||
.timestamp {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
font-size: 12px;
|
||||
@include themed {
|
||||
color: t($subColor);
|
||||
}
|
||||
}
|
||||
|
||||
.achievementTitle {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
svg.trophy {
|
||||
font-size: 20px !important;
|
||||
@include themed {
|
||||
background-image: t($slightGradient);
|
||||
box-shadow: t($boxShadow);
|
||||
}
|
||||
|
||||
padding: 15px;
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
svg.trophyLocked {
|
||||
font-size: 20px !important;
|
||||
@include themed {
|
||||
background-image: t($modal-sidebarActive);
|
||||
box-shadow: t($boxShadow);
|
||||
}
|
||||
|
||||
padding: 15px;
|
||||
border-radius: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.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;
|
||||
|
||||
.subtitle {
|
||||
font-size: 13px !important;
|
||||
}
|
||||
}
|
||||
|
||||
.statsTopBar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
button {
|
||||
margin-bottom: 15px;
|
||||
flex-flow: row !important;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
}
|
|
@ -1,9 +1,8 @@
|
|||
import { memo } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import variables from 'modules/variables';
|
||||
import variables from 'config/variables';
|
||||
import { MdClose, MdRestartAlt } from 'react-icons/md';
|
||||
import { setDefaultSettings } from 'modules/helpers/settings';
|
||||
import Tooltip from 'components/helpers/tooltip/Tooltip';
|
||||
import { setDefaultSettings } from 'utils/settings';
|
||||
import { Tooltip, Button } from 'components/Elements';
|
||||
|
||||
function ResetModal({ modalClose }) {
|
||||
const reset = () => {
|
||||
|
@ -33,21 +32,13 @@ function ResetModal({ modalClose }) {
|
|||
{variables.getMessage('modals.main.settings.sections.advanced.reset_modal.information')}
|
||||
</span>
|
||||
<div className="resetFooter">
|
||||
<button className="textButton" onClick={modalClose}>
|
||||
<MdClose />
|
||||
{variables.getMessage('modals.main.settings.sections.advanced.reset_modal.cancel')}
|
||||
</button>
|
||||
<button onClick={() => reset()}>
|
||||
<MdRestartAlt />
|
||||
{variables.getMessage('modals.main.settings.buttons.reset')}
|
||||
</button>
|
||||
<Button type="secondary" onClick={modalClose} icon={<MdClose />} label={variables.getMessage('modals.main.settings.sections.advanced.reset_modal.cancel')} />
|
||||
<Button type="settings" onClick={() => reset()} icon={<MdRestartAlt />} label={variables.getMessage('modals.main.settings.buttons.reset')} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
ResetModal.propTypes = {
|
||||
modalClose: PropTypes.func.isRequired,
|
||||
};
|
||||
const MemoizedResetModal = memo(ResetModal);
|
||||
|
||||
export default memo(ResetModal);
|
||||
export { MemoizedResetModal as default, MemoizedResetModal as ResetModal };
|
|
@ -0,0 +1 @@
|
|||
export * from './ResetModal';
|
|
@ -1,11 +1,10 @@
|
|||
import { memo } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import variables from 'modules/variables';
|
||||
import variables from 'config/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 Tooltip from '../Tooltip/Tooltip';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
import './sharemodal.scss';
|
||||
|
@ -104,7 +103,7 @@ function ShareModal({ modalClose, data }) {
|
|||
<button
|
||||
onClick={() =>
|
||||
window
|
||||
.open(`http://connect.qq.com/widget/shareqq/index.html?url=${data.url}`, '_blank')
|
||||
.open(`https://connect.qq.com/widget/shareqq/index.html?url=${data.url}`, '_blank')
|
||||
.focus()
|
||||
}
|
||||
>
|
||||
|
@ -124,9 +123,6 @@ function ShareModal({ modalClose, data }) {
|
|||
);
|
||||
}
|
||||
|
||||
ShareModal.propTypes = {
|
||||
modalClose: PropTypes.func.isRequired,
|
||||
data: PropTypes.string.isRequired,
|
||||
};
|
||||
const MemoizedSharemodal = memo(ShareModal);
|
||||
|
||||
export default memo(ShareModal);
|
||||
export { MemoizedSharemodal as default, MemoizedSharemodal as ShareModal };
|
|
@ -0,0 +1 @@
|
|||
export * from './ShareModal';
|
|
@ -18,12 +18,6 @@
|
|||
flex-flow: row;
|
||||
justify-content: flex-end;
|
||||
gap: 20px;
|
||||
|
||||
button {
|
||||
gap: 20px;
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
}
|
||||
}
|
||||
|
||||
.textButton {
|
||||
|
@ -46,13 +40,6 @@
|
|||
gap: 15px;
|
||||
}
|
||||
|
||||
button {
|
||||
place-items: center;
|
||||
display: grid;
|
||||
|
||||
@include basicIconButton(11px, 1.3rem, modal);
|
||||
}
|
||||
|
||||
.copy {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
|
@ -86,20 +73,6 @@
|
|||
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 {
|
||||
|
@ -107,4 +80,22 @@
|
|||
flex-flow: row;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.close {
|
||||
padding: 15px;
|
||||
place-items: center;
|
||||
display: grid;
|
||||
cursor: pointer;
|
||||
transition: 0.3s;
|
||||
|
||||
@include themed {
|
||||
border-radius: t($borderRadius);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@include themed {
|
||||
background: t($modal-sidebarActive);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,13 +1,17 @@
|
|||
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({
|
||||
const [reference, setReference] = useState(null);
|
||||
|
||||
const { x, y, refs, strategy } = useFloating({
|
||||
placement: placement || 'bottom',
|
||||
middleware: [flip(), offset(15), shift()],
|
||||
elements: {
|
||||
reference,
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
|
@ -19,13 +23,13 @@ function Tooltip({ children, title, style, placement, subtitle }) {
|
|||
onMouseLeave={() => setShowTooltip(false)}
|
||||
onFocus={() => setShowTooltip(true)}
|
||||
onBlur={() => setShowTooltip(false)}
|
||||
ref={reference}
|
||||
ref={setReference}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
{showTooltip && (
|
||||
<span
|
||||
ref={floating}
|
||||
ref={refs.setFloating}
|
||||
style={{
|
||||
position: strategy,
|
||||
top: y ?? '',
|
||||
|
@ -43,12 +47,6 @@ function Tooltip({ children, title, style, placement, subtitle }) {
|
|||
);
|
||||
}
|
||||
|
||||
Tooltip.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
style: PropTypes.object,
|
||||
placement: PropTypes.string,
|
||||
subtitle: PropTypes.string.isRequired,
|
||||
};
|
||||
const MemoizedTooltip = memo(Tooltip);
|
||||
|
||||
export default memo(Tooltip);
|
||||
export { MemoizedTooltip as default, MemoizedTooltip as Tooltip };
|
|
@ -0,0 +1 @@
|
|||
export * from './Tooltip';
|
|
@ -96,52 +96,3 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
export * from './Button';
|
||||
export * from './Tooltip';
|
||||
export * from './ShareModal';
|
||||
export * from './AddModal';
|
||||
export * from './ResetModal';
|
||||
export * from './MainModal';
|
|
@ -1,9 +1,8 @@
|
|||
import variables from 'modules/variables';
|
||||
import variables from 'config/variables';
|
||||
import { PureComponent } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Checkbox as CheckboxUI, FormControlLabel } from '@mui/material';
|
||||
|
||||
import EventBus from 'modules/helpers/eventbus';
|
||||
import EventBus from 'utils/eventbus';
|
||||
|
||||
class Checkbox extends PureComponent {
|
||||
constructor(props) {
|
||||
|
@ -59,13 +58,4 @@ class Checkbox extends PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
Checkbox.propTypes = {
|
||||
name: PropTypes.string.isRequired,
|
||||
text: PropTypes.string.isRequired,
|
||||
category: PropTypes.string,
|
||||
element: PropTypes.string,
|
||||
onChange: PropTypes.func,
|
||||
disabled: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default Checkbox;
|
||||
export { Checkbox as default, Checkbox };
|
|
@ -0,0 +1 @@
|
|||
export * from './Checkbox';
|
|
@ -1,5 +1,4 @@
|
|||
import { useState, memo } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import Box from '@mui/material/Box';
|
||||
import OutlinedInput from '@mui/material/OutlinedInput';
|
||||
|
@ -9,7 +8,7 @@ import FormControl from '@mui/material/FormControl';
|
|||
import Select from '@mui/material/Select';
|
||||
import Chip from '@mui/material/Chip';
|
||||
|
||||
function ChipSelect({ label, options, name }) {
|
||||
function ChipSelect({ label, options }) {
|
||||
let start = (localStorage.getItem('apiCategories') || '').split(',');
|
||||
if (start[0] === '') {
|
||||
start = [];
|
||||
|
@ -46,7 +45,8 @@ function ChipSelect({ label, options, name }) {
|
|||
>
|
||||
{options.map((option) => (
|
||||
<MenuItem key={option.name} value={option.name}>
|
||||
{option.name.charAt(0).toUpperCase() + option.name.slice(1)} ({option.count})
|
||||
{option.name.charAt(0).toUpperCase() + option.name.slice(1)}{' '}
|
||||
{option.count && `(${option.count})`}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
|
@ -55,10 +55,5 @@ function ChipSelect({ label, options, name }) {
|
|||
);
|
||||
}
|
||||
|
||||
ChipSelect.propTypes = {
|
||||
label: PropTypes.string,
|
||||
options: PropTypes.array,
|
||||
name: PropTypes.string,
|
||||
};
|
||||
|
||||
export default memo(ChipSelect);
|
||||
const MemoizedChipSelect = memo(ChipSelect);
|
||||
export { ChipSelect as default, MemoizedChipSelect as ChipSelect };
|
|
@ -0,0 +1 @@
|
|||
export * from './ChipSelect';
|
|
@ -1,15 +1,14 @@
|
|||
import variables from 'modules/variables';
|
||||
import variables from 'config/variables';
|
||||
import { PureComponent, createRef } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { InputLabel, MenuItem, FormControl, Select } from '@mui/material';
|
||||
|
||||
import EventBus from 'modules/helpers/eventbus';
|
||||
import EventBus from 'utils/eventbus';
|
||||
|
||||
class Dropdown extends PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
value: localStorage.getItem(this.props.name) || this.props.children[0].props.value,
|
||||
value: localStorage.getItem(this.props.name) || this.props.items[0].value,
|
||||
title: '',
|
||||
};
|
||||
this.dropdown = createRef();
|
||||
|
@ -63,31 +62,17 @@ class Dropdown extends PureComponent {
|
|||
ref={this.dropdown}
|
||||
key={id}
|
||||
>
|
||||
{this.props.manual
|
||||
? this.props.children
|
||||
: this.props.children.map((e, index) => {
|
||||
return e ? (
|
||||
<MenuItem key={index} value={e.props ? e.props.value : ''}>
|
||||
{e.props ? e.props.children : ''}
|
||||
</MenuItem>
|
||||
) : null;
|
||||
})}
|
||||
{this.props.items.map((item) =>
|
||||
item !== null ? (
|
||||
<MenuItem key={id + item.value} value={item.value}>
|
||||
{item.text}
|
||||
</MenuItem>
|
||||
) : null,
|
||||
)}
|
||||
</Select>
|
||||
</FormControl>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Dropdown.propTypes = {
|
||||
name: PropTypes.string.isRequired,
|
||||
label: PropTypes.string,
|
||||
category: PropTypes.string,
|
||||
element: PropTypes.string,
|
||||
onChange: PropTypes.func,
|
||||
noSetting: PropTypes.bool,
|
||||
manual: PropTypes.bool,
|
||||
value2: PropTypes.string,
|
||||
name2: PropTypes.string,
|
||||
};
|
||||
|
||||
export default Dropdown;
|
||||
export { Dropdown as default, Dropdown };
|
|
@ -0,0 +1 @@
|
|||
export * from './Dropdown';
|
|
@ -1,9 +1,8 @@
|
|||
import variables from 'modules/variables';
|
||||
import variables from 'config/variables';
|
||||
import { PureComponent } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { toast } from 'react-toastify';
|
||||
import { compressAccurately, filetoDataURL } from 'image-conversion';
|
||||
import { videoCheck } from 'modules/helpers/background/widget';
|
||||
import videoCheck from 'features/background/api/videoCheck';
|
||||
|
||||
class FileUpload extends PureComponent {
|
||||
componentDidMount() {
|
||||
|
@ -63,11 +62,4 @@ class FileUpload extends PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
FileUpload.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
type: PropTypes.string.isRequired,
|
||||
loadFunction: PropTypes.func.isRequired,
|
||||
accept: PropTypes.string,
|
||||
};
|
||||
|
||||
export default FileUpload;
|
||||
export { FileUpload as default, FileUpload };
|
|
@ -0,0 +1 @@
|
|||
export * from './FileUpload';
|
|
@ -1,6 +1,5 @@
|
|||
import variables from 'modules/variables';
|
||||
import variables from 'config/variables';
|
||||
import { PureComponent } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import {
|
||||
Radio as RadioUI,
|
||||
RadioGroup,
|
||||
|
@ -9,8 +8,8 @@ import {
|
|||
FormLabel,
|
||||
} from '@mui/material';
|
||||
|
||||
import EventBus from 'modules/helpers/eventbus';
|
||||
import { translations } from 'modules/translations';
|
||||
import EventBus from 'utils/eventbus';
|
||||
import { translations } from 'lib/translations';
|
||||
|
||||
class Radio extends PureComponent {
|
||||
constructor(props) {
|
||||
|
@ -85,19 +84,4 @@ class Radio extends PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
Radio.propTypes = {
|
||||
name: PropTypes.string.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
options: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
name: PropTypes.string.isRequired,
|
||||
value: PropTypes.string.isRequired,
|
||||
}),
|
||||
).isRequired,
|
||||
onChange: PropTypes.func,
|
||||
category: PropTypes.string,
|
||||
element: PropTypes.string,
|
||||
smallTitle: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default Radio;
|
||||
export { Radio as default, Radio };
|
|
@ -0,0 +1 @@
|
|||
export * from './Radio';
|
|
@ -1,11 +1,10 @@
|
|||
import variables from 'modules/variables';
|
||||
import variables from 'config/variables';
|
||||
import { PureComponent } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { toast } from 'react-toastify';
|
||||
import { Slider } from '@mui/material';
|
||||
import { MdRefresh } from 'react-icons/md';
|
||||
|
||||
import EventBus from 'modules/helpers/eventbus';
|
||||
import EventBus from 'utils/eventbus';
|
||||
|
||||
class SliderComponent extends PureComponent {
|
||||
constructor(props) {
|
||||
|
@ -86,16 +85,4 @@ class SliderComponent extends PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
SliderComponent.propTypes = {
|
||||
name: PropTypes.string.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
default: PropTypes.number.isRequired,
|
||||
min: PropTypes.number.isRequired,
|
||||
max: PropTypes.number.isRequired,
|
||||
step: PropTypes.number,
|
||||
marks: PropTypes.array,
|
||||
element: PropTypes.string,
|
||||
category: PropTypes.string,
|
||||
};
|
||||
|
||||
export default SliderComponent;
|
||||
export { SliderComponent as default, SliderComponent as Slider };
|
|
@ -0,0 +1 @@
|
|||
export * from './Slider';
|
|
@ -1,9 +1,8 @@
|
|||
import variables from 'modules/variables';
|
||||
import variables from 'config/variables';
|
||||
import { PureComponent } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Switch as SwitchUI, FormControlLabel } from '@mui/material';
|
||||
|
||||
import EventBus from 'modules/helpers/eventbus';
|
||||
import EventBus from 'utils/eventbus';
|
||||
|
||||
class Switch extends PureComponent {
|
||||
constructor(props) {
|
||||
|
@ -21,6 +20,10 @@ class Switch extends PureComponent {
|
|||
checked: value,
|
||||
});
|
||||
|
||||
if (this.props.onChange) {
|
||||
this.props.onChange(value);
|
||||
}
|
||||
|
||||
variables.stats.postEvent(
|
||||
'setting',
|
||||
`${this.props.name} ${this.state.checked === true ? 'enabled' : 'disabled'}`,
|
||||
|
@ -54,12 +57,4 @@ class Switch extends PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
Switch.propTypes = {
|
||||
name: PropTypes.string.isRequired,
|
||||
text: PropTypes.string.isRequired,
|
||||
category: PropTypes.string,
|
||||
element: PropTypes.string,
|
||||
header: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default Switch;
|
||||
export { Switch as default, Switch };
|
|
@ -0,0 +1 @@
|
|||
export * from './Switch';
|
|
@ -1,10 +1,10 @@
|
|||
import variables from 'modules/variables';
|
||||
import variables from 'config/variables';
|
||||
import { PureComponent } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { toast } from 'react-toastify';
|
||||
import { TextField } from '@mui/material';
|
||||
import { MdRefresh } from 'react-icons/md';
|
||||
|
||||
import EventBus from 'modules/helpers/eventbus';
|
||||
import EventBus from 'utils/eventbus';
|
||||
|
||||
class Text extends PureComponent {
|
||||
constructor(props) {
|
||||
|
@ -69,9 +69,11 @@ class Text extends PureComponent {
|
|||
onChange={this.handleChange}
|
||||
varient="outlined"
|
||||
InputLabelProps={{ shrink: true }}
|
||||
placeholder={this.props.placeholder || ''}
|
||||
/>
|
||||
)}
|
||||
<span className="link" onClick={this.resetItem}>
|
||||
<MdRefresh />
|
||||
{variables.getMessage('modals.main.settings.buttons.reset')}
|
||||
</span>
|
||||
</>
|
||||
|
@ -79,15 +81,4 @@ class Text extends PureComponent {
|
|||
}
|
||||
}
|
||||
|
||||
Text.propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
category: PropTypes.string.isRequired,
|
||||
default: PropTypes.string,
|
||||
element: PropTypes.string,
|
||||
customcss: PropTypes.bool,
|
||||
textarea: PropTypes.bool,
|
||||
upperCaseFirst: PropTypes.bool,
|
||||
};
|
||||
|
||||
export default Text;
|
||||
export { Text as default, Text };
|
|
@ -0,0 +1 @@
|
|||
export * from './Text';
|
|
@ -0,0 +1,8 @@
|
|||
export * from './Checkbox';
|
||||
export * from './ChipSelect';
|
||||
export * from './Dropdown';
|
||||
export * from './FileUpload';
|
||||
export * from './Radio';
|
||||
export * from './Slider';
|
||||
export * from './Switch';
|
||||
export * from './Text';
|