Compare commits
561 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4eb76b6ed5 | ||
|
|
de5449d8b7 | ||
|
|
51e6582d23 | ||
|
|
9726ea1c89 | ||
|
|
28dec3c1f9 | ||
|
|
b28614340c | ||
|
|
4128fbae46 | ||
|
|
51d0715f0f | ||
|
|
9b43063935 | ||
|
|
98d6ef115c | ||
|
|
9113193d0f | ||
|
|
34aa72191b | ||
|
|
cb6e9ddf9c | ||
|
|
6c4cc5c373 | ||
|
|
44125d7471 | ||
|
|
b429ae2158 | ||
|
|
4a71cef3fc | ||
|
|
214d3dfe80 | ||
|
|
b1b8a5f6dc | ||
|
|
6573ba9553 | ||
|
|
de417f5fd1 | ||
|
|
bc065be590 | ||
|
|
05163532fe | ||
|
|
37e2985c46 | ||
|
|
8f21c0c7bf | ||
|
|
6e5b5dd77b | ||
|
|
81ae913be1 | ||
|
|
6c3b15a8f9 | ||
|
|
cae2c5ef71 | ||
|
|
1ac6f418bf | ||
|
|
fe4d17eff3 | ||
|
|
ea1a1fba2c | ||
|
|
b2bd871a7c | ||
|
|
6662514e5f | ||
|
|
f874f2a54c | ||
|
|
502f1683e2 | ||
|
|
4feb4f79a9 | ||
|
|
ca2ce43f2f | ||
|
|
6137139586 | ||
|
|
6ca99789c7 | ||
|
|
d596670fdb | ||
|
|
7fbadad649 | ||
|
|
0edaeb1732 | ||
|
|
3cc32e2738 | ||
|
|
baefd24c38 | ||
|
|
aff4158901 | ||
|
|
18c6514666 | ||
|
|
81787211b8 | ||
|
|
1fb0af10a8 | ||
|
|
a5b5ee1912 | ||
|
|
5c638ec355 | ||
|
|
f5b8346a26 | ||
|
|
90a4696114 | ||
|
|
b370de9ea3 | ||
|
|
fbe6e040ea | ||
|
|
cc341300b4 | ||
|
|
9d09ece8b7 | ||
|
|
061c9ef6db | ||
|
|
fbc656f978 | ||
|
|
465596d22d | ||
|
|
149bcdbe05 | ||
|
|
f4de44bbbb | ||
|
|
dad43e969f | ||
|
|
e3a482614c | ||
|
|
7c8c61472e | ||
|
|
d94813ef78 | ||
|
|
dece385ce2 | ||
|
|
9d3a72bc26 | ||
|
|
2f21b5b5c2 | ||
|
|
75fea391f0 | ||
|
|
eaa992ce16 | ||
|
|
2670c917b7 | ||
|
|
5cf9bd74f4 | ||
|
|
3d945656d6 | ||
|
|
ee9e5d2a90 | ||
|
|
670f897a80 | ||
|
|
d02da12d3f | ||
|
|
e2a18316f6 | ||
|
|
ea0c36474e | ||
|
|
8ce7be5173 | ||
|
|
426278d483 | ||
|
|
ad176a690f | ||
|
|
281713c679 | ||
|
|
5c8c6b8d07 | ||
|
|
d0934d8e6d | ||
|
|
5947aa25fd | ||
|
|
436dd884f0 | ||
|
|
6c7ca7a0a9 | ||
|
|
ceb68012d5 | ||
|
|
0575d5d565 | ||
|
|
0994bd08d8 | ||
|
|
7cf65d07c8 | ||
|
|
a5b2dd39cb | ||
|
|
4ad3c3142a | ||
|
|
880778dd7a | ||
|
|
5f9bc4a94b | ||
|
|
353fa85cba | ||
|
|
9eef6c9497 | ||
|
|
d1850f5e96 | ||
|
|
66d5f7e5b8 | ||
|
|
ea24e2653a | ||
|
|
456350c669 | ||
|
|
46142091d1 | ||
|
|
43741f4d58 | ||
|
|
98082158b7 | ||
|
|
ff69a0f487 | ||
|
|
507e7e507f | ||
|
|
3388701603 | ||
|
|
17bb8407b8 | ||
|
|
2956dabc8b | ||
|
|
214d06927e | ||
|
|
a3cf09287f | ||
|
|
af5354afb0 | ||
|
|
cf8546ebc5 | ||
|
|
f6cb133c4d | ||
|
|
b773f256a4 | ||
|
|
b4e1d00633 | ||
|
|
f3eb2c4cdb | ||
|
|
33a002003e | ||
|
|
a33151da91 | ||
|
|
5dd11aca94 | ||
|
|
29171bce5d | ||
|
|
177e4fdcdc | ||
|
|
1b40f112af | ||
|
|
2bf8e0cfbc | ||
|
|
f89a2f880d | ||
|
|
c6dd27180a | ||
|
|
d99cc7869a | ||
|
|
f6564fa758 | ||
|
|
e4395497ed | ||
|
|
b7656fa951 | ||
|
|
e092c805e8 | ||
|
|
ab7681f3d0 | ||
|
|
0c71f0ebef | ||
|
|
70756befa2 | ||
|
|
025303a01a | ||
|
|
8f74095a85 | ||
|
|
9ea6c18cd2 | ||
|
|
77a0bbe7ee | ||
|
|
66b11134c0 | ||
|
|
47817e06ac | ||
|
|
418d658658 | ||
|
|
b24739cabb | ||
|
|
4adf45094a | ||
|
|
51eaf3a90e | ||
|
|
b76cbc3bc6 | ||
|
|
f54fd5adb7 | ||
|
|
07c9e62205 | ||
|
|
b4a1a4bb19 | ||
|
|
04fb389d59 | ||
|
|
2454f1bbab | ||
|
|
8f1ebb309c | ||
|
|
67562c7297 | ||
|
|
895973e95b | ||
|
|
a6f10032c5 | ||
|
|
83b9b779b4 | ||
|
|
0f3b0ec144 | ||
|
|
9981a28638 | ||
|
|
ee0100895b | ||
|
|
aec47d9d0b | ||
|
|
4a427e23d8 | ||
|
|
7105360b31 | ||
|
|
30a3d87431 | ||
|
|
9d45d3e2b9 | ||
|
|
7ff14f5d96 | ||
|
|
5836849ab9 | ||
|
|
d42f69ae95 | ||
|
|
78350663e1 | ||
|
|
afcb7908d5 | ||
|
|
caf4a07473 | ||
|
|
195b7839d0 | ||
|
|
d79baacc1a | ||
|
|
412aa339d9 | ||
|
|
2664fcab19 | ||
|
|
e3fb5140be | ||
|
|
700fe25046 | ||
|
|
c1f34ae946 | ||
|
|
182da7cd5d | ||
|
|
ed5e8cfe76 | ||
|
|
3aafc445c2 | ||
|
|
3a39de75db | ||
|
|
e0e02544d7 | ||
|
|
8f0223dd07 | ||
|
|
c27c7074f6 | ||
|
|
049cfc35f8 | ||
|
|
801eb5f1aa | ||
|
|
98a065b934 | ||
|
|
06cc5705b5 | ||
|
|
7785706737 | ||
|
|
c83b65f27b | ||
|
|
f7946c4e19 | ||
|
|
c68228381b | ||
|
|
a9c06fd935 | ||
|
|
3ec5a2c199 | ||
|
|
0a735384df | ||
|
|
5c579ee0a2 | ||
|
|
c42e41ca15 | ||
|
|
d3f000fd69 | ||
|
|
61bc581557 | ||
|
|
bea887fff9 | ||
|
|
eef61ef9e2 | ||
|
|
17e1c43ad5 | ||
|
|
3fec08a492 | ||
|
|
e25f48cb14 | ||
|
|
e2d7a9aebd | ||
|
|
11b82fe944 | ||
|
|
88e54ad26a | ||
|
|
408f8c4502 | ||
|
|
0ba55b64bc | ||
|
|
3a5af3fe0d | ||
|
|
822f3bf260 | ||
|
|
7147dbef30 | ||
|
|
ba843b44c4 | ||
|
|
73d006d8da | ||
|
|
57cf5cb89e | ||
|
|
fc570089c2 | ||
|
|
89b4d154ad | ||
|
|
f60aae6b24 | ||
|
|
12e7ec8995 | ||
|
|
d80e9d09c8 | ||
|
|
7862c43752 | ||
|
|
7bfa7ed0a8 | ||
|
|
86b6ad6542 | ||
|
|
727e21480d | ||
|
|
82e1d7684a | ||
|
|
87dd07c45c | ||
|
|
4486050d06 | ||
|
|
a3ba90d1da | ||
|
|
0e10a4cf45 | ||
|
|
bb0db0f2de | ||
|
|
2215dd7dcd | ||
|
|
888dd7fb5f | ||
|
|
636c1892ec | ||
|
|
d954ae78f6 | ||
|
|
13757243a4 | ||
|
|
40d3281fa1 | ||
|
|
bbb49f536d | ||
|
|
6b9a0028c6 | ||
|
|
d7e4bfafda | ||
|
|
e1510e8277 | ||
|
|
f6d8ccf6e7 | ||
|
|
3b52010213 | ||
|
|
c0cced4f5d | ||
|
|
8642757bd8 | ||
|
|
be1bccd2ac | ||
|
|
5d2dc65e08 | ||
|
|
aa010be11d | ||
|
|
492b3b6715 | ||
|
|
1245d58b7e | ||
|
|
b3195d0819 | ||
|
|
aacc779162 | ||
|
|
96377c72ed | ||
|
|
3c27a5baf4 | ||
|
|
2d12875476 | ||
|
|
acc583f995 | ||
|
|
ac60d54950 | ||
|
|
7490b5926f | ||
|
|
8b8353297d | ||
|
|
d455e4b63b | ||
|
|
cc5fa542e1 | ||
|
|
4cb5d1eaae | ||
|
|
0f279b8087 | ||
|
|
1647d3c520 | ||
|
|
3da376e68a | ||
|
|
1f0bc275a0 | ||
|
|
60bf6315a4 | ||
|
|
4b25a1c955 | ||
|
|
16419ca775 | ||
|
|
f390c6ca92 | ||
|
|
d85fc79734 | ||
|
|
b45129f3d0 | ||
|
|
392f14c89d | ||
|
|
1c49306a46 | ||
|
|
30c50968a2 | ||
|
|
3b5ac499cc | ||
|
|
754fdbe284 | ||
|
|
1ce238722a | ||
|
|
0b4383d263 | ||
|
|
3b957142bf | ||
|
|
74b02f6bcf | ||
|
|
2f8d5eca21 | ||
|
|
78d3384d7e | ||
|
|
be74c98963 | ||
|
|
c84e727b22 | ||
|
|
38c84d1e82 | ||
|
|
a0d3b084a3 | ||
|
|
086d463277 | ||
|
|
610bbda43d | ||
|
|
5dc8bbf963 | ||
|
|
93edb489f7 | ||
|
|
c12091c5f0 | ||
|
|
eeaf678485 | ||
|
|
5e71a477de | ||
|
|
fef78cfeed | ||
|
|
df2a873ac6 | ||
|
|
4dd3e550a8 | ||
|
|
a865cb87ef | ||
|
|
52cc9cb579 | ||
|
|
aa16b7cffa | ||
|
|
917f99ff13 | ||
|
|
b70bd85370 | ||
|
|
edd8872403 | ||
|
|
d0a2d6c24c | ||
|
|
0a7ee1c52e | ||
|
|
205a56f086 | ||
|
|
26f5e0b0e5 | ||
|
|
ba66ed6279 | ||
|
|
d9021b0f57 | ||
|
|
44281c2449 | ||
|
|
38590f8278 | ||
|
|
201e3382f4 | ||
|
|
840917d123 | ||
|
|
7d59b18058 | ||
|
|
443c53e294 | ||
|
|
32fe3a664c | ||
|
|
3c5c7e71f1 | ||
|
|
8aaf3bb6e2 | ||
|
|
bf1ded0bd5 | ||
|
|
ca84948751 | ||
|
|
70a03b49da | ||
|
|
c9a89e5dc3 | ||
|
|
693aa1aa93 | ||
|
|
2bcc0beec7 | ||
|
|
caaed9603d | ||
|
|
d2ce84cac4 | ||
|
|
1cdb469d08 | ||
|
|
cdddffbe79 | ||
|
|
4ba7022b54 | ||
|
|
4b27532ac6 | ||
|
|
8e921e3c12 | ||
|
|
7e2772812c | ||
|
|
9bd4f99006 | ||
|
|
0dbc586952 | ||
|
|
e09fc3f99f | ||
|
|
7dbd4976b7 | ||
|
|
66414461c4 | ||
|
|
2dd0e9150b | ||
|
|
d1b998da12 | ||
|
|
e76594f426 | ||
|
|
6553c49fbe | ||
|
|
7b256fc956 | ||
|
|
7cc88449d7 | ||
|
|
8aeb645046 | ||
|
|
f50c32778c | ||
|
|
ed38bc2cbb | ||
|
|
e8c5f546cd | ||
|
|
d3ce835956 | ||
|
|
c858734d7f | ||
|
|
97a76bd0d7 | ||
|
|
ee4e49a058 | ||
|
|
150eb06cd0 | ||
|
|
7b71d0759e | ||
|
|
f38749961b | ||
|
|
b5e5b8618e | ||
|
|
cec368ab5f | ||
|
|
9db5150b07 | ||
|
|
4dfe05ac8a | ||
|
|
97f680d738 | ||
|
|
8b79f82e29 | ||
|
|
89a8621de1 | ||
|
|
a27cf2eede | ||
|
|
3399705935 | ||
|
|
a1963fb31b | ||
|
|
1a12f487e7 | ||
|
|
f014a79065 | ||
|
|
4fbcc19ff8 | ||
|
|
7dca1c9de9 | ||
|
|
1249ce45d3 | ||
|
|
9387357854 | ||
|
|
05c4a2c30c | ||
|
|
70cf17140b | ||
|
|
9969a4db10 | ||
|
|
ec9429adcb | ||
|
|
7dafd2c08d | ||
|
|
ad4fffb519 | ||
|
|
4715bb6144 | ||
|
|
2dc682cd14 | ||
|
|
3cfac7418b | ||
|
|
3f540b7772 | ||
|
|
003f1e62b2 | ||
|
|
320ae1c922 | ||
|
|
b6f74d4305 | ||
|
|
0a670de8f1 | ||
|
|
88efb6356a | ||
|
|
254dec9e8f | ||
|
|
c35aedbd2d | ||
|
|
97ed47b8cd | ||
|
|
6f046d144f | ||
|
|
088008165d | ||
|
|
d7e0091136 | ||
|
|
7a443c16bf | ||
|
|
b5e55fd331 | ||
|
|
5016cf3e69 | ||
|
|
a672c60afd | ||
|
|
aa5513a5dd | ||
|
|
291e7bcb82 | ||
|
|
4c9c31c90b | ||
|
|
5a15ce3cd8 | ||
|
|
8f3fa2f898 | ||
|
|
afb0f5c061 | ||
|
|
3a0468dcb9 | ||
|
|
f56854127c | ||
|
|
66980a4c62 | ||
|
|
259a36fd5d | ||
|
|
8869e53daa | ||
|
|
92495ce6ce | ||
|
|
736a589b59 | ||
|
|
2814174a38 | ||
|
|
dec9475a75 | ||
|
|
7253a174a6 | ||
|
|
348d3e8578 | ||
|
|
f9f77f24c0 | ||
|
|
f82f24f6a9 | ||
|
|
91fefbf73c | ||
|
|
21ae1ff461 | ||
|
|
80b1ef6ab4 | ||
|
|
5d08d24fdf | ||
|
|
824dd22d62 | ||
|
|
b15b42ab61 | ||
|
|
6b447e1c68 | ||
|
|
0e482a4947 | ||
|
|
005c51dcf8 | ||
|
|
281443d2d2 | ||
|
|
a17ce90e07 | ||
|
|
3f6aea4ae4 | ||
|
|
563804c415 | ||
|
|
7c055d6aff | ||
|
|
3e80586620 | ||
|
|
0464afea27 | ||
|
|
298a7da3b7 | ||
|
|
9c7bfafa23 | ||
|
|
752ce62f24 | ||
|
|
f458a69781 | ||
|
|
e967cebdc8 | ||
|
|
d9a4c76a8e | ||
|
|
771b374a0b | ||
|
|
10d11a39c6 | ||
|
|
2e36a58b78 | ||
|
|
2283492c2c | ||
|
|
0d017fa362 | ||
|
|
0c6022aa2d | ||
|
|
da5a4da97b | ||
|
|
69189fce79 | ||
|
|
93b90eda5d | ||
|
|
10738a5f8b | ||
|
|
d8620b64de | ||
|
|
d0874f7f6a | ||
|
|
99c3a0525c | ||
|
|
88cc56d9d4 | ||
|
|
aa600ba8c9 | ||
|
|
69b3a983db | ||
|
|
148c38085a | ||
|
|
dc5757f7db | ||
|
|
6a7ecd005e | ||
|
|
839d7bab79 | ||
|
|
da4e1cbc81 | ||
|
|
127045bbf6 | ||
|
|
267d38f06e | ||
|
|
7db55dddbd | ||
|
|
6970984941 | ||
|
|
2ad283abb8 | ||
|
|
8091fc7dbd | ||
|
|
4054b10714 | ||
|
|
b5ef757a00 | ||
|
|
389a8bfdb8 | ||
|
|
f54ce58b21 | ||
|
|
20b33346d0 | ||
|
|
8843fac900 | ||
|
|
bb4760d2c9 | ||
|
|
48e4e50fc7 | ||
|
|
e396ba2465 | ||
|
|
2ee44a6e18 | ||
|
|
ad094ccfdc | ||
|
|
5c5ec92eb6 | ||
|
|
2857c13434 | ||
|
|
9cb00fffba | ||
|
|
b6907a5aa0 | ||
|
|
45af502520 | ||
|
|
e05d65401e | ||
|
|
2ab09ff582 | ||
|
|
c871512e87 | ||
|
|
f821cf2314 | ||
|
|
76d24340c1 | ||
|
|
e2b7789eba | ||
|
|
e6ead89cdc | ||
|
|
a97b969e6f | ||
|
|
f9c129786c | ||
|
|
e149b57fb6 | ||
|
|
82417dc230 | ||
|
|
c5ae4fc9b4 | ||
|
|
e8ba860592 | ||
|
|
62bfd162e3 | ||
|
|
80c5c9cfb0 | ||
|
|
19e3fce5b6 | ||
|
|
5aafb4228b | ||
|
|
43101b7ded | ||
|
|
88c8428ae2 | ||
|
|
1055427e33 | ||
|
|
85a3ce0769 | ||
|
|
5c682eac26 | ||
|
|
4db5104181 | ||
|
|
d18020e4bd | ||
|
|
2772cfdefc | ||
|
|
92efb3ed23 | ||
|
|
f7acd0188d | ||
|
|
7fa5cf7f7d | ||
|
|
722f2711ae | ||
|
|
30dcc789ed | ||
|
|
dc013deaad | ||
|
|
7f49a412aa | ||
|
|
4e774d9ea3 | ||
|
|
30c05f03bf | ||
|
|
2edd9b4b07 | ||
|
|
24e261165b | ||
|
|
39188d5988 | ||
|
|
e175a1edfa | ||
|
|
6f7b6d2337 | ||
|
|
97c6fa58d9 | ||
|
|
ec66e8c9f9 | ||
|
|
35a60f07b6 | ||
|
|
50da14cce6 | ||
|
|
d45fec5028 | ||
|
|
77f2522a80 | ||
|
|
92d0d7efae | ||
|
|
a6c1a21088 | ||
|
|
983a6727e2 | ||
|
|
5da8731017 | ||
|
|
b78f4ccf26 | ||
|
|
2fa7567cf3 | ||
|
|
cde3743ff8 | ||
|
|
1a165f4f1d | ||
|
|
56944b3a07 | ||
|
|
6c39a751a1 | ||
|
|
2f7fd62d5c | ||
|
|
af8223d818 | ||
|
|
298f43bda2 | ||
|
|
7c8c0cfb85 | ||
|
|
1e99676ff8 | ||
|
|
3638e67f28 | ||
|
|
2d42753e77 | ||
|
|
39969cde6d | ||
|
|
40452b71bf | ||
|
|
ab1a7cdf5f | ||
|
|
bdfae155ab | ||
|
|
4ff9ef3545 | ||
|
|
9f21ffe5f0 | ||
|
|
5be47d798b | ||
|
|
c7e19aad03 | ||
|
|
df630e953a | ||
|
|
b5a0cbe0b2 | ||
|
|
aa6400b41f | ||
|
|
735ee6def9 | ||
|
|
9414a35fe8 | ||
|
|
13e5beadf6 | ||
|
|
3c398df411 | ||
|
|
27fb91e9a9 | ||
|
|
5e5214ad0c | ||
|
|
90eb9a424a | ||
|
|
9f961ffdde | ||
|
|
576d829c40 | ||
|
|
c6e9e2226a |
8
.editorconfig
Normal file
@@ -0,0 +1,8 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
4
.eslintrc.js
Normal file
@@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
extends: 'react-app',
|
||||
parser: '@babel/eslint-parser'
|
||||
};
|
||||
2
.github/FUNDING.yml
vendored
@@ -1,2 +0,0 @@
|
||||
patreon: ohlookitsderpy
|
||||
ko_fi: ohlookitsderpy
|
||||
17
.github/ISSUE_TEMPLATE/bug-report.md
vendored
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Report a bug to help improve this project
|
||||
title: "[BUG]"
|
||||
about: Report a bug to help improve Mue
|
||||
title: "[Bug]"
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
@@ -14,8 +14,7 @@ A clear and concise description of what the bug is.
|
||||
Steps to reproduce the behaviour:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
3. See error in console (Ctrl + Shift + I)
|
||||
|
||||
**Expected behaviour**
|
||||
A clear and concise description of what you expected to happen.
|
||||
@@ -24,10 +23,12 @@ A clear and concise description of what you expected to happen.
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. Windows]
|
||||
- Browser [e.g. Chrome, Firefox]
|
||||
- Version [e.g. 70]
|
||||
- Resolution [e.g 1920x1080]
|
||||
- OS: [e.g. Windows, Ubuntu]
|
||||
- OS Version: [e.g 10, 19.10]
|
||||
- Browser: [e.g. Chrome, Firefox]
|
||||
- Browser Version: [e.g. 70]
|
||||
- Mue Version: [e.g. 0.5]
|
||||
- Resolution: [e.g 1920x1080]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
|
||||
14
.github/ISSUE_TEMPLATE/feature-request.md
vendored
@@ -1,14 +0,0 @@
|
||||
---
|
||||
name: Feature Request
|
||||
about: Suggest an idea for this project
|
||||
title: "[Feature Request]"
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Description**
|
||||
A clear and concise description of what you want in this new feature.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
11
.gitignore
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
# Directories
|
||||
node_modules/
|
||||
.vscode/
|
||||
build/
|
||||
|
||||
# Files
|
||||
package-lock.json
|
||||
yarn-error.log
|
||||
.eslintcache
|
||||
stats.json
|
||||
yarn.lock
|
||||
42
LICENSE
@@ -1,21 +1,29 @@
|
||||
MIT License
|
||||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2018-2019 David Ralph (ohlookitsderpy)
|
||||
Copyright (c) 2018-2021 The Mue Authors
|
||||
All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
192
README.md
@@ -1,83 +1,102 @@
|
||||
<img src='assets/logo/logo_horizontal.png'>
|
||||
<img src="https://raw.githubusercontent.com/mue/branding/master/logo/logo_round.png" align="left" width="180px" height="180px"/>
|
||||
<img align="left" width="0" height="192px" hspace="10"/>
|
||||
|
||||
# Mue
|
||||
[](https://www.codacy.com/app/ohlookitsderpy/Mue?utm_source=github.com&utm_medium=referral&utm_content=ohlookitsderpy/Mue&utm_campaign=Badge_Grade)
|
||||
[](https://discord.gg/HJmmmTB)
|
||||
> <a href="https://muetab.com/">Mue</a>
|
||||
|
||||
<a href='https://ko-fi.com/ohlookitsderpy' target='_blank'><img height='36' src='assets/kofi.png' alt='Buy me a coffee at ko-fi.com' /></a>
|
||||
<a href='https://patreon.com/ohlookitsderpy' target='_blank'><img height='36' src='assets/patreon.png' alt='Become a patron on patreon.com' /></a>
|
||||
[](/LICENSE) [](https://discord.gg/zv8C9F8) []()
|
||||
<br>
|
||||
[](https://microsoftedge.microsoft.com/addons/detail/aepnglgjfokepefimhbnibfjekidhmja) [](https://addons.mozilla.org/firefox/addon/mue) [](https://chrome.google.com/webstore/detail/mue/bngmbednanpcfochchhgbkookpiaiaid)
|
||||
|
||||
Fast, open and free-to-use new tab page for most modern browsers.
|
||||
Mue is a fast, open and free-to-use browser extension that gives a new, fresh and customizable tab page to most modern browsers
|
||||
|
||||
*This is the code for the extension. If you are looking for the website code, please go [here](https://github.com/TurboMarshmello/muetab.xyz).*
|
||||
<br>
|
||||
|
||||
## Table of contents
|
||||
* [Screenshot](#screenshot)
|
||||
* [Features](#features)
|
||||
* [Planned Features](#planned-features)
|
||||
* [Installation](#installation)
|
||||
* [Chrome](#chrome)
|
||||
* [Firefox](#firefox)
|
||||
* [Edge Chromium](#edge-chromium)
|
||||
* [Naver](#naver)
|
||||
* [Other](#other)
|
||||
* [Contributing](#development)
|
||||
* [Requirements](#requirements)
|
||||
* [Starting](#starting)
|
||||
* [Building](#building)
|
||||
* [Credits](#credits)
|
||||
* [Developers](#developers)
|
||||
* [Translators](#translators)
|
||||
* [Contributors](#contributors)
|
||||
* [Resources](#resources)
|
||||
## Screenshots
|
||||

|
||||

|
||||
|
||||
## Features
|
||||
* Fast and free
|
||||
* Supports multiple browsers
|
||||
* Actively developed and opensource
|
||||
* Automatically updating API (with no tracking!) with new photos and offline mode
|
||||
* ~~Multiple language support~~
|
||||
* ~~Settings feature - enable/disable features!~~
|
||||
* Search bar, ~~update modal, copy button and more!~~
|
||||
* Actively developed and open source
|
||||
* Automatically updating API (no tracking) with new photos, quotes and offline mode
|
||||
* Widgets such as searchbar, weather, quick links, clock, date, quote, greeting
|
||||
* Settings - enable/disable various features and customise parts of Mue
|
||||
* Navbar with copy button, favourite background, notes feature etc
|
||||
* Marketplace - download custom photo packs made by the community
|
||||
|
||||
* Mue has been recently rewritten with React and is missing the features that are crossed out *
|
||||
### Planned Features
|
||||
Please see our [roadmap](https://github.com/mue/mue/projects)
|
||||
|
||||
## Installation
|
||||
*A demo of the tab can be found [here](https://demo.muetab.com)*
|
||||
### Chrome
|
||||
<a href='https://chrome.google.com/webstore/detail/mue/bngmbednanpcfochchhgbkookpiaiaid'><img src='assets/chrome.png' target='_blank'></a>
|
||||
[](https://chrome.google.com/webstore/detail/mue/bngmbednanpcfochchhgbkookpiaiaid)
|
||||
<br>
|
||||
[Chrome Web Store](https://chrome.google.com/webstore/detail/mue/bngmbednanpcfochchhgbkookpiaiaid)
|
||||
|
||||
Link: [Chrome Web Store](https://chrome.google.com/webstore/detail/mue/bngmbednanpcfochchhgbkookpiaiaid)
|
||||
|
||||
Development: Read the [Development](#development) section.
|
||||
### Firefox
|
||||
<a href='https://addons.mozilla.org/firefox/addon/mue'><img src='assets/firefox.png' target='_blank'></a>
|
||||
[](https://addons.mozilla.org/firefox/addon/mue)
|
||||
<br>
|
||||
[Firefox Add-ons](https://addons.mozilla.org/firefox/addon/mue)
|
||||
|
||||
Link: [Firefox Add-ons](https://addons.mozilla.org/firefox/addon/mue)
|
||||
### Edge (Chromium)
|
||||
~~[Microsoft Edge Addons](https://microsoftedge.microsoft.com/addons/detail/aepnglgjfokepefimhbnibfjekidhmja)~~ Currently outdated, please use the Chrome Web Store version
|
||||
|
||||
Development: Read the [Development](#development) section.
|
||||
### Opera/Other
|
||||
Link: [GitHub Releases](https://github.com/ohlookitsderpy/Mue/releases)
|
||||
### Naver
|
||||
[Whale Store](https://store.whale.naver.com/detail/ecllekeilcmicbfkkiknfdddbogibbnc)
|
||||
|
||||
Development/Other: Read the [Development](#development) section.
|
||||
### Development
|
||||
<h5>Requirements</h5>
|
||||
<ol>
|
||||
<li><a href='https://git-scm.com'>Git</a> (optional)</li>
|
||||
<li><a href='https://nodejs.org'>Node.js</a></li>
|
||||
<li>A suitable browser</li>
|
||||
</ol>
|
||||
<h5>Starting</h5>
|
||||
<ol>
|
||||
<li> <code>git clone https://github.com/ohlookitsderpy/Mue</code> (If you don't have Git just go to <b>Clone or
|
||||
download</b> and click <b>Download ZIP</b>)
|
||||
<li> Open a terminal and run these commands: (in the Mue directory)
|
||||
<li> <code>yarn</code> (or <code>npm install</code>)
|
||||
<li> <code>yarn start</code> (or <code>npm start</code>)
|
||||
<li> Start developing! (See the sections below for how to set up a developer copy of the extension.)
|
||||
</ol>
|
||||
### Other
|
||||
Please note that we have dropped support for Opera as of Mue 5.0
|
||||
|
||||
[GitHub Releases](https://github.com/mue/mue/releases)
|
||||
|
||||
## Development
|
||||
### Requirements
|
||||
* [Git](https://git-scm.com/)
|
||||
* [Node.JS](https://nodejs.org/)
|
||||
* A suitable browser
|
||||
### Starting
|
||||
1. Clone the repository using `git clone https://github.com/mue/mue.git`
|
||||
2. Run `yarn` or `npm i` to install all needed dependencies
|
||||
3. Run `yarn start` or `npm start` to start testing
|
||||
4. Code your heart out! (See the sections below for how to build the extension)
|
||||
### Building
|
||||
<details>
|
||||
<summary><b>Chrome</b> (Click to expand)</summary>
|
||||
<summary><b>Chrome/Edge (Chromium)</b> (Click to expand)</summary>
|
||||
<ol>
|
||||
<li> Rename <code>manifest-chrome.json</code> to <code>manifest.json</code>
|
||||
<li> <code>yarn run build</code> or <code>npm run build</code>
|
||||
<li> <code>yarn run chrome</code> or <code>npm run chrome</code>
|
||||
<li> Visit <code>chrome://extensions</code> in Chrome
|
||||
<li> Click <b>Load unpacked</b> (Make sure <b>Developer Mode</b> is on)
|
||||
<li> Go to the directory containing Mue and click <b>ok</b>
|
||||
<li> Enjoy your new tab!
|
||||
</details>
|
||||
<details>
|
||||
<summary><b>Opera</b> (Click to expand)</summary>
|
||||
<ol>
|
||||
<li> Rename <code>manifest-opera.json</code> to <code>manifest.json</code>
|
||||
<li> Visit <code>about://extensions</code> in Opera
|
||||
<li> Click <b>Load unpacked extension...</b> (Make sure <b>Developer Mode</b> is on)
|
||||
<li> Go to the directory containing Mue and click <b>ok</b>
|
||||
<li> Go to the directory containing the built copy of Mue and click <b>ok</b>
|
||||
<li> Enjoy your new tab!
|
||||
</ol>
|
||||
</details>
|
||||
<details>
|
||||
<summary><b>Firefox</b> (Click to expand)</summary>
|
||||
<i>Note: I'm currently trying to find a better method to do this, but this works for now.</i>
|
||||
<ol>
|
||||
<li> Rename <code>manifest-firefox.json</code> to <code>manifest.json</code>
|
||||
<li> <code>yarn run build</code> or <code>npm run build</code>
|
||||
<li> <code>yarn run firefox</code> or <code>npm run firefox</code>
|
||||
<li> Visit <code>about:debugging#addons</code> in Firefox
|
||||
<li> Click <b>Load Temporary Add-on</b>
|
||||
<li> Go to the directory containing Mue and click on the <b>manifest.json</b>
|
||||
@@ -87,49 +106,30 @@ Development/Other: Read the [Development](#development) section.
|
||||
<details>
|
||||
<summary><b>Other</b> (Click to expand)</summary>
|
||||
<i>Note: To get the full new tab experience, set your browser to open the <code>index.html</code> on startup and tab open!</i>
|
||||
<ol>
|
||||
<li> Open the <code>index.html</code> in your browser
|
||||
<li> Enjoy your new tab!
|
||||
</ol>
|
||||
<ol>
|
||||
<li> <code>yarn run build</code> or <code>npm run build</code>
|
||||
<li> Open the <code>index.html</code> in your browser
|
||||
<li> Enjoy your new tab!
|
||||
</ol>
|
||||
</details>
|
||||
|
||||
## Screenshot
|
||||
*Will be updated if needed*
|
||||
|
||||
<img src='assets/screenshot.jpg'>
|
||||
|
||||
## Credits
|
||||
### Maintainers
|
||||
[ohlookitsderpy](https://github.com/ohlookitsderpy)
|
||||
### Developers
|
||||
[David Ralph](https://github.com/davidjcralph) - Lead development, photographer <br/>
|
||||
[Alex Sparkes](https://github.com/alexsparkes) - Name, lead design, photographer <br/>
|
||||
[Isaac Saunders](https://github.com/eartharoid) - QA, development, photographer <br/>
|
||||
[Wessel Tip](https://github.com/Wessel) - Development <br/>
|
||||
### Translators
|
||||
[Wessel Tip](https://github.com/Wessel), [Heimen Stoffels](https://github.com/Vistaus) - Dutch<br/>
|
||||
[Alex Sparkes](https://github.com/alexsparkes), [Maxime](https://github.com/exiam) - French<br/>
|
||||
[Anders](https://github.com/FuryingFox) - Norwegian<br/>
|
||||
[Pronin Egor](https://github.com/MrZillaGold) - Russian<br/>
|
||||
[Vicente](https://github.com/Vicente015) - Spanish<br/>
|
||||
[Austin Huang](https://github.com/austinhuang0131) - Chinese (Simplified)<br/>
|
||||
[FreeFun](https://github.com/xXFreeFunXx) - German<br/>
|
||||
### Contributors
|
||||
Many thanks to [Highholding](https://discord.bio/p/highholding), [Noa Shapira](#), [Roee Lupo](https://github.com/RoeeLupo), [Jeroen](#), [Gio](#), [Anders](https://github.com/FuryingFox), [Oded Shapira](https://twitter.com/dondishdev), Jacob Tyrrell and [Nikka Lai](#) for letting us use their wonderful photographs.
|
||||
|
||||
[TurboMarshmello](https://github.com/TurboMarshmello)
|
||||
|
||||
### Other
|
||||
[TurboMarshmello](https://github.com/TurboMarshmello) - Portions of original code, name idea
|
||||
|
||||
[Pexels](https://pexels.com) - Stock photos used for offline mode
|
||||
|
||||
[Opera Forum](https://forums.opera.com/topic/25046/how-to-disable-completely-the-speed-dial/14) - Portions of code to add Opera support
|
||||
|
||||
### Translations
|
||||
[ohlookitsderpy](https://github.com/ohlookitsderpy) - English (Quotes and Messages)
|
||||
|
||||
[Yanderella](https://github.com/tomiedev) - Italian (Quotes and Messages)
|
||||
|
||||
Pepehound - Spanish (Quotes and Messages)
|
||||
|
||||
Candystick - Portuguese (Some Quotes)
|
||||
|
||||
[PassTheWessel](https://github.com/PassTheWessel) - Dutch (Messages)
|
||||
|
||||
[Yanderella](https://github.com/tomiedev) and [ohlookitsderpy](https://github.com/ohlookitsderpy) - French (Messages)
|
||||
|
||||
[untocodes](https://github.com/untocodes) - Finnish and German (Messages)
|
||||
|
||||
[dondish](https://github.com/dondish) - Hebrew and Russian (Messages)
|
||||
|
||||
[MrSheldon](https://github.com/MrSheldon) - Arabic and Swedish (Messages)
|
||||
|
||||
*Feel free to pull request with other translations!*
|
||||
|
||||
and all the contributors <3
|
||||
And finally, a big thank you to all the other [contributors](https://github.com/mue/mue/graphs/contributors)!
|
||||
### Resources
|
||||
[Pexels](https://pexels.com), [Unsplash](https://unsplash.com) - Stock photos used for offline mode
|
||||
|
||||
BIN
assets/kofi.png
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 925 B |
|
Before Width: | Height: | Size: 241 KiB |
BIN
assets/screenshot.webp
Normal file
|
After Width: | Height: | Size: 308 KiB |
BIN
assets/screenshot2.webp
Normal file
|
After Width: | Height: | Size: 68 KiB |
6
babel.config.js
Normal file
@@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
presets: ['@babel/preset-env', ['@babel/preset-react', {
|
||||
'runtime': 'automatic'
|
||||
}]],
|
||||
plugins: ['@babel/plugin-proposal-class-properties', '@babel/transform-runtime', 'babel-plugin-transform-react-class-to-function', '@babel/plugin-transform-react-constant-elements']
|
||||
};
|
||||
18
manifest/chrome.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"manifest_version": 2,
|
||||
"offline_enabled": true,
|
||||
"name": "Mue",
|
||||
"description": "Fast, open and free-to-use new tab page for modern browsers.",
|
||||
"version": "5.0.0",
|
||||
"browser_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"
|
||||
}
|
||||
}
|
||||
15
manifest/firefox.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"manifest_version": 2,
|
||||
"name": "Mue",
|
||||
"description": "Fast, open and free-to-use new tab page for modern browsers.",
|
||||
"version": "5.0.0",
|
||||
"browser_action": {
|
||||
"default_icon": "icons/128x128.png"
|
||||
},
|
||||
"chrome_url_overrides": {
|
||||
"newtab": "index.html"
|
||||
},
|
||||
"chrome_settings_overrides": {
|
||||
"homepage": "index.html"
|
||||
}
|
||||
}
|
||||
113
package.json
@@ -1,43 +1,70 @@
|
||||
{
|
||||
"name": "mue",
|
||||
"author": "ohlookitsderpy",
|
||||
"description": "Fast, open and free-to-use new tab page for most modern browsers.",
|
||||
"license": "MIT",
|
||||
"version": "2.0.0",
|
||||
"dependencies": {
|
||||
"@material-ui/core": "^4.4.3",
|
||||
"@material-ui/icons": "^4.4.3",
|
||||
"react": "^16.10.1",
|
||||
"react-dom": "^16.10.1",
|
||||
"react-scripts": "3.1.2",
|
||||
"unfetch": "^4.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^6.5.0",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"sass": "^1.22.12"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject",
|
||||
"sass": "sass --watch src/scss:src/css --style compressed",
|
||||
"start-all": "npm-run-all -p start sass"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "react-app"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
}
|
||||
{
|
||||
"name": "mue",
|
||||
"private": true,
|
||||
"author": "The Mue Authors (https://github.com/mue/mue/graphs/contributors)",
|
||||
"description": "Fast, open and free-to-use new tab page for modern browsers.",
|
||||
"repository": {
|
||||
"url": "github:mue/mue"
|
||||
},
|
||||
"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": "5.0.0",
|
||||
"dependencies": {
|
||||
"@fontsource/lexend-deca": "^4.2.3",
|
||||
"@fontsource/montserrat": "^4.2.2",
|
||||
"@material-ui/core": "4.11.3",
|
||||
"@material-ui/icons": "4.11.2",
|
||||
"react": "17.0.2",
|
||||
"react-clock": "3.0.0",
|
||||
"react-color-gradient-picker": "0.1.2",
|
||||
"react-day-picker": "7.4.10",
|
||||
"react-device-detect": "1.17.0",
|
||||
"react-dom": "17.0.2",
|
||||
"react-modal": "3.13.1",
|
||||
"react-sortable-hoc": "2.0.0",
|
||||
"react-toastify": "7.0.3",
|
||||
"weather-icons-react": "^1.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.13.15",
|
||||
"@babel/eslint-parser": "^7.13.14",
|
||||
"@babel/plugin-proposal-class-properties": "^7.13.0",
|
||||
"@babel/plugin-transform-react-constant-elements": "^7.13.13",
|
||||
"@babel/plugin-transform-runtime": "^7.13.15",
|
||||
"@babel/preset-env": "^7.13.15",
|
||||
"@babel/preset-react": "^7.13.13",
|
||||
"babel-loader": "^8.2.2",
|
||||
"babel-plugin-transform-react-class-to-function": "^1.2.2",
|
||||
"copy-webpack-plugin": "^8.1.1",
|
||||
"css-loader": "^5.2.1",
|
||||
"eslint": "^7.24.0",
|
||||
"eslint-config-react-app": "^6.0.0",
|
||||
"eslint-webpack-plugin": "^2.5.3",
|
||||
"html-webpack-plugin": "^5.3.1",
|
||||
"mini-css-extract-plugin": "^1.4.1",
|
||||
"sass": "^1.32.8",
|
||||
"sass-loader": "^11.0.1",
|
||||
"source-map-loader": "^2.0.1",
|
||||
"webpack": "^5.33.2",
|
||||
"webpack-cli": "^4.6.0",
|
||||
"webpack-dev-server": "^3.11.2"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "webpack serve",
|
||||
"build": "webpack --mode=production",
|
||||
"chrome": "cp manifest/chrome.json build/manifest.json",
|
||||
"firefox": "cp manifest/firefox.json build/manifest.json"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 9.5 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 15 KiB |
BIN
public/icons/128x128.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
public/icons/16x16.png
Normal file
|
After Width: | Height: | Size: 645 B |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
BIN
public/icons/48x48.png
Normal file
|
After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 9.9 KiB |
1
public/icons/undraw_celebration.svg
Normal file
|
After Width: | Height: | Size: 36 KiB |
@@ -1,15 +1,38 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<html lang='en'>
|
||||
<head>
|
||||
<meta charset='utf-8' />
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1' />
|
||||
<link rel='apple-touch-icon' sizes='180x180' href='apple-touch-icon.png'>
|
||||
<link rel='icon' type='image/png' sizes='32x32' href='favicon-32x32.png'>
|
||||
<link rel='icon' type='image/png' sizes='16x16' href='favicon-16x16.png'>
|
||||
<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>You need to enable JavaScript to use Mue.</noscript>
|
||||
<noscript>
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: 'Lexend Deca';
|
||||
src: url('./static/media/lexend-deca-latin-400-normal.35a9aeba.woff2');
|
||||
}
|
||||
|
||||
*, a {
|
||||
font-family: 'Lexend Deca', sans-serif;
|
||||
text-align: center;
|
||||
color: black;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
*, a {
|
||||
color: white;
|
||||
background: #2f3640;
|
||||
}
|
||||
}
|
||||
</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>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
{
|
||||
"short_name": "Mue New Tab",
|
||||
"name": "Fast, open and free-to-use new tab page for most modern browsers.",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon-32x32.png",
|
||||
"sizes": "96x96 64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
|
Before Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 128 KiB |
BIN
public/offline-images/1.webp
Normal file
|
After Width: | Height: | Size: 308 KiB |
|
Before Width: | Height: | Size: 280 KiB |
BIN
public/offline-images/10.webp
Normal file
|
After Width: | Height: | Size: 104 KiB |
|
Before Width: | Height: | Size: 200 KiB |
BIN
public/offline-images/11.webp
Normal file
|
After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 146 KiB |
BIN
public/offline-images/12.webp
Normal file
|
After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 230 KiB |
|
Before Width: | Height: | Size: 161 KiB |
|
Before Width: | Height: | Size: 135 KiB |
|
Before Width: | Height: | Size: 174 KiB |
|
Before Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 401 KiB |
|
Before Width: | Height: | Size: 737 KiB |
|
Before Width: | Height: | Size: 94 KiB |
BIN
public/offline-images/2.webp
Normal file
|
After Width: | Height: | Size: 274 KiB |
|
Before Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 390 KiB |
|
Before Width: | Height: | Size: 225 KiB |
|
Before Width: | Height: | Size: 251 KiB |
|
Before Width: | Height: | Size: 300 KiB |
|
Before Width: | Height: | Size: 148 KiB |
BIN
public/offline-images/3.webp
Normal file
|
After Width: | Height: | Size: 171 KiB |
|
Before Width: | Height: | Size: 290 KiB |
BIN
public/offline-images/4.webp
Normal file
|
After Width: | Height: | Size: 161 KiB |
|
Before Width: | Height: | Size: 324 KiB |
BIN
public/offline-images/5.webp
Normal file
|
After Width: | Height: | Size: 157 KiB |
|
Before Width: | Height: | Size: 264 KiB |
BIN
public/offline-images/6.webp
Normal file
|
After Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 495 KiB |
BIN
public/offline-images/7.webp
Normal file
|
After Width: | Height: | Size: 126 KiB |
|
Before Width: | Height: | Size: 322 KiB |
BIN
public/offline-images/8.webp
Normal file
|
After Width: | Height: | Size: 124 KiB |
|
Before Width: | Height: | Size: 472 KiB |
BIN
public/offline-images/9.webp
Normal file
|
After Width: | Height: | Size: 118 KiB |
94
src/App.jsx
@@ -1,66 +1,46 @@
|
||||
//* Imports
|
||||
import React from 'react';
|
||||
import Fetch from 'unfetch';
|
||||
import Clock from './modules/Clock';
|
||||
import Greeting from './modules/Greeting';
|
||||
import Quote from './modules/Quote';
|
||||
import Search from './modules/Search';
|
||||
import Credit from './modules/Credit';
|
||||
import './css/index.css';
|
||||
|
||||
//* Functions
|
||||
const getCookie = (cookiename) => {
|
||||
const cookiestring = RegExp('' + cookiename + '[^;]+').exec(document.cookie);
|
||||
return unescape(!!cookiestring ? cookiestring.toString().replace(/^[^=]+./,'') : '');
|
||||
};
|
||||
import Background from './components/widgets/background/Background';
|
||||
import Widgets from './components/widgets/Widgets';
|
||||
import Modals from './components/modals/Modals';
|
||||
|
||||
const randomInt = (min, max) => { return Math.floor(Math.random() * (max - min + 1)) + min; };
|
||||
import EventBus from './modules/helpers/eventbus';
|
||||
import SettingsFunctions from './modules/helpers/settings';
|
||||
|
||||
import { ToastContainer } from 'react-toastify';
|
||||
|
||||
export default class App extends React.PureComponent {
|
||||
componentDidMount() {
|
||||
if (!localStorage.getItem('firstRun')) {
|
||||
SettingsFunctions.setDefaultSettings();
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
// 4.0 -> 5.0 (the key below is only on 5.0)
|
||||
if (!localStorage.getItem('order')) {
|
||||
SettingsFunctions.moveSettings();
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
SettingsFunctions.loadSettings();
|
||||
|
||||
EventBus.on('refresh', (data) => {
|
||||
if (data === 'other') {
|
||||
SettingsFunctions.loadSettings(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//* App
|
||||
export default class App extends React.Component {
|
||||
// Render all the modules
|
||||
render() {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Search/>
|
||||
<div id='center'>
|
||||
<Greeting/>
|
||||
<Clock/>
|
||||
<Quote/>
|
||||
<Credit/>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
<>
|
||||
{(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>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
// Set background: Attempt to get one from the API first, and if that fails then use the offline ones.
|
||||
async getAndSetBackground() {
|
||||
const root = document.getElementById('root');
|
||||
|
||||
try {
|
||||
let data = await Fetch('https://api.muetab.xyz/getImage?category=Outdoors');
|
||||
data = await data.json();
|
||||
|
||||
const checkRepeat = getCookie('backgroundimageurl');
|
||||
document.getElementById('photographer').innerText = `Photo by ${data.photographer}`;
|
||||
document.getElementById('location').innerText = `${data.location}`;
|
||||
|
||||
if (checkRepeat !== root.style.backgroundImage) root.style.backgroundImage = `url(${data.file})`;
|
||||
else {
|
||||
/*let data = await Fetch('https://api.muetab.xyz/getImage?category=Outdoors');
|
||||
data = await data.json();*/
|
||||
document.cookie = 'backgroundimageurl; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
|
||||
root.style.backgroundImage = `url(${data.file})`;
|
||||
document.cookie = `backgroundimageurl=${data.file}`;
|
||||
}
|
||||
} catch (e) {
|
||||
document.getElementById('backgroundCredits').style.display = 'none';
|
||||
document.getElementById('photographer').innerText = 'Photo from Pexels';
|
||||
root.style.backgroundImage = `url(../offline-images/${randomInt(1, 25)}.jpeg)`;
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getAndSetBackground();
|
||||
}
|
||||
}
|
||||
|
||||
12
src/components/helpers/tooltip/Tooltip.jsx
Normal file
@@ -0,0 +1,12 @@
|
||||
import React from 'react';
|
||||
|
||||
import './tooltip.scss';
|
||||
|
||||
export default function Tooltip(props) {
|
||||
return (
|
||||
<div className='tooltip'>
|
||||
{props.children}
|
||||
<span className='tooltipTitle'>{props.title}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
37
src/components/helpers/tooltip/tooltip.scss
Normal file
@@ -0,0 +1,37 @@
|
||||
// todo: possibly add tooltip placement option
|
||||
.tooltip {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
||||
.tooltipTitle {
|
||||
width: 60px;
|
||||
background-color: rgba(255, 255, 255, 0.89);
|
||||
color: #000000;
|
||||
text-align: center;
|
||||
font-size: 0.6rem;
|
||||
border-radius: 6px;
|
||||
padding: 5px 0;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 100%;
|
||||
left: 50%;
|
||||
margin-left: -30px;
|
||||
visibility: hidden;
|
||||
cursor: initial;
|
||||
user-select: none;
|
||||
opacity: 0;
|
||||
transition: opacity 0.8s;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.tooltipTitle {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dark .tooltipTitle {
|
||||
background-color: rgba(0, 0, 0, 0.79);
|
||||
color: #ffffff;
|
||||
}
|
||||
37
src/components/modals/ErrorBoundary.jsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import React from 'react';
|
||||
|
||||
import ErrorOutlineIcon from '@material-ui/icons/ErrorOutline';
|
||||
|
||||
export default class ErrorBoundary extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
error: false
|
||||
};
|
||||
this.language = window.language.modals.main.error_boundary;
|
||||
}
|
||||
|
||||
static getDerivedStateFromError(error) {
|
||||
console.log(error);
|
||||
return {
|
||||
error: true
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.error) {
|
||||
return (
|
||||
<div className='emptyitems'>
|
||||
<div className='emptyMessage'>
|
||||
<ErrorOutlineIcon/>
|
||||
<h1>{this.language.title}</h1>
|
||||
<p>{this.language.message}</p>
|
||||
<button className='refresh' onClick={() => window.location.reload()}>{this.language.refresh}</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return this.props.children;
|
||||
}
|
||||
}
|
||||
61
src/components/modals/Modals.jsx
Normal file
@@ -0,0 +1,61 @@
|
||||
import React from 'react';
|
||||
|
||||
import Main from './main/Main';
|
||||
import Navbar from '../widgets/navbar/Navbar';
|
||||
|
||||
import Modal from 'react-modal';
|
||||
|
||||
// These modals are lazy loaded as the user won't use them every time they open a tab
|
||||
// We used to lazy load the main modal, but doing so broke the main modal open animation on first click
|
||||
const Welcome = React.lazy(() => import('./welcome/Welcome'));
|
||||
const Feedback = React.lazy(() => import('./feedback/Feedback'));
|
||||
const renderLoader = () => <></>;
|
||||
|
||||
export default class Modals extends React.PureComponent {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
mainModal: false,
|
||||
updateModal: false,
|
||||
welcomeModal: false,
|
||||
feedbackModal: false
|
||||
};
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (localStorage.getItem('showWelcome') === 'true' && window.location.search !== '?nointro=true') {
|
||||
this.setState({
|
||||
welcomeModal: true
|
||||
});
|
||||
}
|
||||
|
||||
// hide refresh reminder once the user has refreshed the page
|
||||
localStorage.setItem('showReminder', false);
|
||||
}
|
||||
|
||||
closeWelcome() {
|
||||
localStorage.setItem('showWelcome', false);
|
||||
this.setState({
|
||||
welcomeModal: false
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<>
|
||||
<Navbar openModal={(modal) => this.setState({ [modal]: true })}/>
|
||||
<Modal closeTimeoutMS={300} id='modal' onRequestClose={() => this.setState({ mainModal: false })} isOpen={this.state.mainModal} className='Modal' overlayClassName='Overlay' ariaHideApp={false}>
|
||||
<Main modalClose={() => this.setState({ mainModal: false })}/>
|
||||
</Modal>
|
||||
<React.Suspense fallback={renderLoader()}>
|
||||
<Modal closeTimeoutMS={300} onRequestClose={() => this.closeWelcome()} isOpen={this.state.welcomeModal} className='Modal welcomemodal' overlayClassName='Overlay' ariaHideApp={false}>
|
||||
<Welcome modalClose={() => this.closeWelcome()}/>
|
||||
</Modal>
|
||||
<Modal onRequestClose={() => this.setState({ feedbackModal: false })} isOpen={this.state.feedbackModal} className='Modal' overlayClassName='Overlay' ariaHideApp={false}>
|
||||
<Feedback modalClose={() => this.setState({ feedbackModal: false })}/>
|
||||
</Modal>
|
||||
</React.Suspense>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
93
src/components/modals/feedback/Feedback.jsx
Normal file
@@ -0,0 +1,93 @@
|
||||
import React from 'react';
|
||||
|
||||
import './feedback.scss';
|
||||
|
||||
export default class FeedbackModal extends React.PureComponent {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
questionone: 5,
|
||||
questionthree: 5,
|
||||
questiontwoerror: '',
|
||||
questionfourerror: '',
|
||||
formsubmit: ''
|
||||
};
|
||||
this.language = window.language.modals.feedback;
|
||||
}
|
||||
|
||||
async submitForm () {
|
||||
let questiontwoerror, questionfourerror;
|
||||
|
||||
if (document.getElementById('questiontwo').value.length <= 0) {
|
||||
questiontwoerror = this.language.not_filled;
|
||||
}
|
||||
|
||||
if (document.getElementById('questionfour').value.length <= 0) {
|
||||
questionfourerror = this.language.not_filled;
|
||||
}
|
||||
|
||||
if (questiontwoerror || questionfourerror) {
|
||||
this.setState({
|
||||
questiontwoerror: questiontwoerror,
|
||||
questionfourerror: questionfourerror
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
questiontwoerror: '',
|
||||
questionfourerror: ''
|
||||
});
|
||||
|
||||
await fetch(window.constants.FEEDBACK_FORM, {
|
||||
'method': 'POST'
|
||||
});
|
||||
|
||||
this.setState({
|
||||
formsubmit: this.language.success
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
this.props.modalClose();
|
||||
}, 3000);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className='feedback'>
|
||||
<h1>{this.language.title}</h1>
|
||||
<span className='closeModal' onClick={this.props.modalClose}>×</span>
|
||||
<>
|
||||
<input type='hidden' name='version' value={window.constants.VERSION} />
|
||||
<>
|
||||
<label>{this.language.question_one}</label>
|
||||
<br/><br/>
|
||||
<label className='values'>0</label>
|
||||
<input className='range' type='range' min='0' max='10' name='question1' value={this.state.questionone} onChange={(e) => this.setState({ questionone: e.target.value })}/>
|
||||
<label className='values'>10 ({this.state.questionone})</label>
|
||||
</>
|
||||
<br/><br/>
|
||||
<>
|
||||
<label>{this.language.question_two}</label>
|
||||
<textarea name='question2' id='questiontwo'/>
|
||||
<p className='feedbackerror'>{this.state.questiontwoerror}</p>
|
||||
</>
|
||||
<>
|
||||
<label>{this.language.question_three}</label>
|
||||
<br/><br/>
|
||||
<label className='values'>0</label>
|
||||
<input className='range' type='range' min='0' max='10' name='question3' value={this.state.questionthree} onChange={(e) => this.setState({ questionthree: e.target.value })}/>
|
||||
<label className='values'>10 ({this.state.questionthree})</label>
|
||||
</>
|
||||
<br/><br/>
|
||||
<>
|
||||
<label>{this.language.question_four}</label>
|
||||
<textarea name='question4' id='questionfour'/>
|
||||
<p className='feedbackerror'>{this.state.questionfourerror}</p>
|
||||
</>
|
||||
{this.state.formsubmit}
|
||||
<button onClick={() => this.submitForm()}>{this.language.submit}</button>
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
63
src/components/modals/feedback/feedback.scss
Normal file
@@ -0,0 +1,63 @@
|
||||
@import '../main/scss/index.scss';
|
||||
|
||||
#feedbackmodal {
|
||||
position: absolute;
|
||||
margin: auto;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 400px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.feedback {
|
||||
width: 400px;
|
||||
padding: 5px;
|
||||
|
||||
h1,
|
||||
.closeModal {
|
||||
font-size: 2.5em;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 6em;
|
||||
}
|
||||
|
||||
button {
|
||||
width: 50%;
|
||||
border-radius: 48px;
|
||||
outline: none;
|
||||
border: none;
|
||||
padding: 15px 20px;
|
||||
font-size: 1.5em;
|
||||
background: linear-gradient(90deg, #ffb032 0%, #dd3b67 100%);
|
||||
color: #fff;
|
||||
text-transform: uppercase;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
input[type=text] {
|
||||
width: 100%;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
input[type=range] {
|
||||
margin-left: 20px;
|
||||
margin-right: 20px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
label.values {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: 80%;
|
||||
background-color: var(--sidebar);
|
||||
}
|
||||
|
||||
.feedbackerror {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
50
src/components/modals/main/Main.jsx
Normal file
@@ -0,0 +1,50 @@
|
||||
import React from 'react';
|
||||
|
||||
import Tabs from './tabs/backend/Tabs';
|
||||
|
||||
import './scss/index.scss';
|
||||
|
||||
// Lazy load all the tabs instead of the modal itself
|
||||
const Settings = React.lazy(() => import('./tabs/Settings'));
|
||||
const Addons = React.lazy(() => import('./tabs/Addons'));
|
||||
const Marketplace = React.lazy(() => import('./tabs/Marketplace'));
|
||||
|
||||
const renderLoader = () => (
|
||||
<Tabs>
|
||||
<div label={window.language.modals.main.loading}>
|
||||
<div className='emptyitems'>
|
||||
<div className='emptyMessage'>
|
||||
<h1>{window.language.modals.main.loading}</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div label='' style={{ 'display': 'none' }}></div>
|
||||
</Tabs>
|
||||
);
|
||||
|
||||
export default function MainModal(props) {
|
||||
const language = window.language.modals.main.navbar;
|
||||
|
||||
return (
|
||||
<>
|
||||
<span className='closeModal' onClick={props.modalClose}>×</span>
|
||||
<Tabs navbar={true}>
|
||||
<div label={language.settings}>
|
||||
<React.Suspense fallback={renderLoader()}>
|
||||
<Settings/>
|
||||
</React.Suspense>
|
||||
</div>
|
||||
<div label={language.addons}>
|
||||
<React.Suspense fallback={renderLoader()}>
|
||||
<Addons/>
|
||||
</React.Suspense>
|
||||
</div>
|
||||
<div label={language.marketplace}>
|
||||
<React.Suspense fallback={renderLoader()}>
|
||||
<Marketplace/>
|
||||
</React.Suspense>
|
||||
</div>
|
||||
</Tabs>
|
||||
</>
|
||||
);
|
||||
}
|
||||
59
src/components/modals/main/marketplace/Item.jsx
Normal file
@@ -0,0 +1,59 @@
|
||||
import React from 'react';
|
||||
|
||||
import ArrowBackIcon from '@material-ui/icons/ArrowBack';
|
||||
|
||||
export default function Item(props) {
|
||||
const language = window.language.modals.main.marketplace.product;
|
||||
|
||||
let warningHTML;
|
||||
// For some reason it breaks sometimes so we use try/catch
|
||||
try {
|
||||
if (props.content.content.data.quote_api) {
|
||||
warningHTML = (
|
||||
<div className='productInformation'>
|
||||
<ul>
|
||||
<li className='header'>{language.quote_warning.title}</li>
|
||||
<li id='updated'>{language.quote_warning.description}</li>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
// prevent console error
|
||||
let iconsrc = window.constants.DDG_PROXY + props.data.icon;
|
||||
if (!props.data.icon) {
|
||||
iconsrc = null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div id='item' style={{ 'display': props.display }}>
|
||||
<br/>
|
||||
<span><ArrowBackIcon className='backArrow' onClick={props.toggleFunction}/></span>
|
||||
<br/>
|
||||
<h1>{props.data.display_name}</h1>
|
||||
{props.button}
|
||||
<br/>
|
||||
<img alt='product' draggable='false' src={iconsrc}/>
|
||||
<div className='informationContainer'>
|
||||
<h1>{language.overview}</h1>
|
||||
<p className='description' dangerouslySetInnerHTML={{ __html: props.data.description }}></p>
|
||||
<div className='productInformation'>
|
||||
<ul>
|
||||
{/* <li className='header'>{language.last_updated}</li>
|
||||
<li>{props.data.updated}</li>
|
||||
<br/>*/}
|
||||
<li className='header'>{language.version}</li>
|
||||
<li>{props.data.version}</li>
|
||||
<br/>
|
||||
<li className='header'>{language.author}</li>
|
||||
<li>{props.data.author}</li>
|
||||
</ul>
|
||||
</div>
|
||||
{warningHTML}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
17
src/components/modals/main/marketplace/Items.jsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function Items(props) {
|
||||
return (
|
||||
<div className='items'>
|
||||
{props.items.map((item) => (
|
||||
<div className='item' onClick={() => props.toggleFunction(item.name)} key={item.name}>
|
||||
<img alt='icon' draggable='false' src={window.constants.DDG_PROXY + item.icon_url} />
|
||||
<div className='details'>
|
||||
<h4>{item.display_name ? item.display_name : item.name}</h4>
|
||||
<p>{item.author}</p>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
101
src/components/modals/main/marketplace/sections/Added.jsx
Normal file
@@ -0,0 +1,101 @@
|
||||
import React from 'react';
|
||||
|
||||
import LocalMallIcon from '@material-ui/icons/LocalMall';
|
||||
import Item from '../Item';
|
||||
import Items from '../Items';
|
||||
|
||||
import MarketplaceFunctions from '../../../../../modules/helpers/marketplace';
|
||||
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
export default class Added extends React.PureComponent {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
installed: JSON.parse(localStorage.getItem('installed')),
|
||||
item: {
|
||||
name: 'Name',
|
||||
author: 'Author',
|
||||
description: 'Description',
|
||||
//updated: '???',
|
||||
version: '1.0.0',
|
||||
icon: ''
|
||||
},
|
||||
button: '',
|
||||
display: {
|
||||
marketplace: 'block',
|
||||
item: 'none'
|
||||
}
|
||||
};
|
||||
this.buttons = {
|
||||
uninstall: <button className='removeFromMue' onClick={() => this.uninstall()}>{window.language.modals.main.marketplace.product.buttons.remove}</button>,
|
||||
};
|
||||
this.language = window.language.modals.main.addons;
|
||||
}
|
||||
|
||||
toggle(type, data) {
|
||||
if (type === 'item') {
|
||||
const installed = JSON.parse(localStorage.getItem('installed'));
|
||||
const info = installed.find((i) => i.name === data);
|
||||
|
||||
this.setState({
|
||||
item: {
|
||||
type: info.type,
|
||||
name: data,
|
||||
display_name: info.name,
|
||||
author: info.author,
|
||||
description: MarketplaceFunctions.urlParser(info.description.replace(/\n/g, '<br>')),
|
||||
//updated: info.updated,
|
||||
version: info.version,
|
||||
icon: info.screenshot_url
|
||||
},
|
||||
button: this.buttons.uninstall,
|
||||
display: {
|
||||
marketplace: 'none',
|
||||
item: 'block'
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
display: {
|
||||
marketplace: 'block',
|
||||
item: 'none'
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
uninstall() {
|
||||
MarketplaceFunctions.uninstall(this.state.item.type, this.state.item.display_name);
|
||||
|
||||
toast(window.language.toasts.uninstalled);
|
||||
|
||||
this.setState({
|
||||
button: '',
|
||||
installed: JSON.parse(localStorage.getItem('installed'))
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.installed.length === 0) {
|
||||
return (
|
||||
<div className='emptyitems'>
|
||||
<div className='emptyMessage'>
|
||||
<LocalMallIcon/>
|
||||
<h1>{this.language.empty.title}</h1>
|
||||
<p className='description'>{this.language.empty.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div style={{ 'display': this.state.display.marketplace }}>
|
||||
<Items items={this.state.installed} toggleFunction={(input) => this.toggle('item', input)} />
|
||||
</div>
|
||||
<Item data={this.state.item} button={this.state.button} toggleFunction={() => this.toggle()} display={this.state.display.item} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
180
src/components/modals/main/marketplace/sections/Marketplace.jsx
Normal file
@@ -0,0 +1,180 @@
|
||||
import React from 'react';
|
||||
|
||||
import WifiOffIcon from '@material-ui/icons/WifiOff';
|
||||
import LocalMallIcon from '@material-ui/icons/LocalMall';
|
||||
|
||||
import Item from '../Item';
|
||||
import Items from '../Items';
|
||||
|
||||
import MarketplaceFunctions from '../../../../../modules/helpers/marketplace';
|
||||
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
export default class Marketplace extends React.PureComponent {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
items: [],
|
||||
button: '',
|
||||
featured: {},
|
||||
done: false,
|
||||
item: {
|
||||
name: 'Name',
|
||||
author: 'Author',
|
||||
description: 'Description',
|
||||
//updated: '???',
|
||||
version: '1.0.0',
|
||||
icon: ''
|
||||
},
|
||||
display: {
|
||||
marketplace: 'block',
|
||||
item: 'none'
|
||||
}
|
||||
};
|
||||
this.buttons = {
|
||||
uninstall: <button className='removeFromMue' onClick={() => this.manage('uninstall')}>{window.language.modals.main.marketplace.product.buttons.remove}</button>,
|
||||
install: <button className='addToMue' onClick={() => this.manage('install')}>{window.language.modals.main.marketplace.product.buttons.addtomue}</button>
|
||||
};
|
||||
this.language = window.language.modals.main.marketplace;
|
||||
this.controller = new AbortController();
|
||||
}
|
||||
|
||||
async toggle(type, data) {
|
||||
if (type === 'item') {
|
||||
let info;
|
||||
// get item info
|
||||
try {
|
||||
info = await (await fetch(`${window.constants.MARKETPLACE_URL}/item/${this.props.type}/${data}`, { signal: this.controller.signal })).json();
|
||||
} catch (e) {
|
||||
if (this.controller.signal.aborted === false) {
|
||||
return toast(window.language.toasts.error);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.controller.signal.aborted === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
// check if already installed
|
||||
let button = this.buttons.install;
|
||||
|
||||
const installed = JSON.parse(localStorage.getItem('installed'));
|
||||
|
||||
if (installed.some((item) => item.name === info.data.name)) {
|
||||
button = this.buttons.uninstall;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
item: {
|
||||
type: this.props.type,
|
||||
display_name: info.data.name,
|
||||
author: info.data.author,
|
||||
description: MarketplaceFunctions.urlParser(info.data.description.replace(/\n/g, '<br>')),
|
||||
//updated: info.updated,
|
||||
version: info.data.version,
|
||||
icon: info.data.screenshot_url,
|
||||
data: info.data
|
||||
},
|
||||
button: button,
|
||||
display: {
|
||||
item: 'block',
|
||||
marketplace: 'none'
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
display: {
|
||||
marketplace: 'block',
|
||||
item: 'none'
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async getItems() {
|
||||
const { data } = await (await fetch(window.constants.MARKETPLACE_URL + '/all', { signal: this.controller.signal })).json();
|
||||
const featured = await (await fetch(window.constants.MARKETPLACE_URL + '/featured', { signal: this.controller.signal })).json();
|
||||
|
||||
if (this.controller.signal.aborted === true) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
items: data[this.props.type],
|
||||
featured: featured.data,
|
||||
done: true
|
||||
});
|
||||
}
|
||||
|
||||
manage(type) {
|
||||
if (type === 'install') {
|
||||
MarketplaceFunctions.install(this.state.item.type, this.state.item.data);
|
||||
} else {
|
||||
MarketplaceFunctions.uninstall(this.state.item.type, this.state.item.display_name);
|
||||
}
|
||||
|
||||
toast(window.language.toasts[type + 'ed']);
|
||||
this.setState({
|
||||
button: (type === 'install') ? this.buttons.uninstall : this.buttons.install
|
||||
});
|
||||
}
|
||||
|
||||
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='emptyitems'>
|
||||
<div className='emptyMessage'>
|
||||
{msg}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
if (navigator.onLine === false || localStorage.getItem('offlineMode') === 'true') {
|
||||
return errorMessage(<>
|
||||
<WifiOffIcon/>
|
||||
<h1>{this.language.offline.title}</h1>
|
||||
<p className='description'>{this.language.offline.description}</p>
|
||||
</>);
|
||||
}
|
||||
|
||||
if (this.state.done === false) {
|
||||
return errorMessage(<h1>{window.language.modals.main.loading}</h1>);
|
||||
}
|
||||
|
||||
if (this.state.items.length === 0) {
|
||||
return errorMessage(<>
|
||||
<LocalMallIcon/>
|
||||
<h1>{window.language.modals.main.addons.empty.title}</h1>
|
||||
<p className='description'>{this.language.no_items}</p>
|
||||
</>);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div style={{ 'display': this.state.display.marketplace }}>
|
||||
<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={() => window.open(this.state.featured.buttonLink)}>{this.state.featured.buttonText}</button>
|
||||
</div>
|
||||
<Items items={this.state.items} toggleFunction={(input) => this.toggle('item', input)} />
|
||||
</div>
|
||||
<Item data={this.state.item} button={this.state.button} toggleFunction={() => this.toggle()} display={this.state.display.item} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
27
src/components/modals/main/marketplace/sections/Sideload.jsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
|
||||
import LocalMallIcon from '@material-ui/icons/LocalMall';
|
||||
|
||||
import FileUpload from '../../settings/FileUpload';
|
||||
|
||||
import MarketplaceFunctions from '../../../../../modules/helpers/marketplace';
|
||||
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
export default function Sideload() {
|
||||
const install = (input) => {
|
||||
MarketplaceFunctions.install(input.type, input);
|
||||
toast(window.language.toasts.installed);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='emptyitems'>
|
||||
<div className='emptyMessage'>
|
||||
<FileUpload id='file-input' type='settings' accept='application/json' loadFunction={(e) => install(JSON.parse(e.target.result))} />
|
||||
<LocalMallIcon/>
|
||||
<h1>{window.language.modals.main.addons.sideload}</h1>
|
||||
<button className='addToMue sideload' onClick={() => document.getElementById('file-input').click()}>{window.language.modals.main.settings.sections.background.source.upload}</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
384
src/components/modals/main/scss/index.scss
Normal file
@@ -0,0 +1,384 @@
|
||||
@import '../../../../scss/variables';
|
||||
|
||||
@import 'settings/main';
|
||||
@import 'settings/buttons';
|
||||
@import 'settings/dropdown';
|
||||
@import 'settings/daypicker';
|
||||
|
||||
@import 'marketplace/main';
|
||||
@import 'marketplace/buttons';
|
||||
|
||||
.Modal {
|
||||
color: var(--modal-text);
|
||||
background-color: var(--background);
|
||||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.3);
|
||||
border: none;
|
||||
opacity: 1;
|
||||
z-index: -2;
|
||||
padding: 25px;
|
||||
transition-timing-function: ease-in;
|
||||
border-radius: map-get($modal, 'border-radius');
|
||||
user-select: none;
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: #34495e #bdc3c7;
|
||||
position: relative;
|
||||
|
||||
&:focus {
|
||||
outline: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.modalLink {
|
||||
color: var(--modal-link);
|
||||
cursor: pointer;
|
||||
padding-left: 10px;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
.closeModal {
|
||||
position: absolute;
|
||||
top: 1rem;
|
||||
right: 2rem;
|
||||
font-size: 4em;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: grey;
|
||||
}
|
||||
}
|
||||
|
||||
.ReactModal__Html--open,
|
||||
.ReactModal__Body--open {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.Overlay {
|
||||
position: fixed;
|
||||
z-index: 100;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.ReactModal__Content {
|
||||
min-height: calc(100vh - 30vh);
|
||||
max-height: calc(100vh - 10vh);
|
||||
box-shadow: 0 0 30px 0 rgba(0, 0, 0, 0.25);
|
||||
overflow-y: auto;
|
||||
position: relative;
|
||||
|
||||
// animation
|
||||
opacity: 0;
|
||||
transform: scale(0);
|
||||
transition: all 300ms cubic-bezier(0.47, 1.64, 0.41, 0.8);
|
||||
}
|
||||
|
||||
.ReactModal__Content--after-open {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
.ReactModal__Content--before-close {
|
||||
opacity: 0;
|
||||
transform: scale(0);
|
||||
}
|
||||
|
||||
@media only screen and (max-height: 700px) {
|
||||
.ReactModal__Content {
|
||||
min-height: 500px;
|
||||
max-height: calc(100vh - 30vh);
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-height: 700px) {
|
||||
.ReactModal__Content {
|
||||
min-height: 600px;
|
||||
}
|
||||
}
|
||||
|
||||
ul.sidebar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
margin: 0;
|
||||
padding-left: 0;
|
||||
background: var(--sidebar);
|
||||
border-radius: 12px 0 0 12px;
|
||||
text-align: left;
|
||||
font-size: 24px;
|
||||
min-height: 100vh;
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
font-size: 1.8em;
|
||||
}
|
||||
|
||||
svg {
|
||||
vertical-align: middle;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
hr {
|
||||
height: 3px;
|
||||
background: rgba(196, 196, 196, 0.74);
|
||||
width: 75%;
|
||||
outline: none;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
font-size: 24px;
|
||||
padding: 5px 30px 5px 30px;
|
||||
cursor: pointer;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
#modal {
|
||||
position: absolute;
|
||||
margin: auto;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: 80%;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1300px) {
|
||||
#modal {
|
||||
width: 90% !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 1310px) {
|
||||
#modal {
|
||||
width: 60%;
|
||||
}
|
||||
}
|
||||
|
||||
.tab-list-active {
|
||||
background: var(--tab-active);
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1200px) {
|
||||
li.tab-list-item {
|
||||
span {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
ul.sidebar {
|
||||
h1 {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tab-list-item {
|
||||
&:hover {
|
||||
background: var(--tab-active);
|
||||
}
|
||||
}
|
||||
|
||||
.tab-content {
|
||||
position: absolute;
|
||||
|
||||
h3 {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 2300px) {
|
||||
.tab-content {
|
||||
left: 350px;
|
||||
top: 7%;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1920px) {
|
||||
.tab-content {
|
||||
left: 120px;
|
||||
top: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 1920px) {
|
||||
.tab-content {
|
||||
left: 350px;
|
||||
top: 7%;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1400px), (min-width: 1400px) {
|
||||
.tab-content {
|
||||
left: 350px;
|
||||
top: 75px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1200px) {
|
||||
.tab-content {
|
||||
left: 125px;
|
||||
top: 75px;
|
||||
}
|
||||
}
|
||||
|
||||
.navbar-item {
|
||||
font-size: 22px;
|
||||
font-weight: 500;
|
||||
display: inline-flex;
|
||||
|
||||
&:hover {
|
||||
color: rgb(165, 165, 165);
|
||||
background: none;
|
||||
}
|
||||
|
||||
span,
|
||||
svg {
|
||||
font-size: 1.1em !important;
|
||||
}
|
||||
|
||||
svg {
|
||||
font-size: 1.2em !important;
|
||||
}
|
||||
}
|
||||
|
||||
.modalNavbar {
|
||||
position: absolute;
|
||||
left: 20rem;
|
||||
top: 1rem;
|
||||
justify-content: center;
|
||||
|
||||
svg {
|
||||
margin-right: 0.5rem;
|
||||
padding: 3px;
|
||||
font-size: 1.4em !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1200px) {
|
||||
.modalNavbar {
|
||||
left: 6rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1300px) {
|
||||
li.navbar-item {
|
||||
span {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 1200px) {
|
||||
ul.sidebar {
|
||||
width: 310px;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
.navbar-item-active {
|
||||
background: map-get($theme-colours, 'gradient');
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
|
||||
svg {
|
||||
color: orange;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: map-get($theme-colours, 'gradient');
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
border-top-right-radius: map-get($modal, 'border-radius');
|
||||
border-bottom-right-radius: map-get($modal, 'border-radius');
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #636e72;
|
||||
border-top-right-radius: map-get($modal, 'border-radius');
|
||||
border-bottom-right-radius: map-get($modal, 'border-radius');
|
||||
}
|
||||
|
||||
.abouticon {
|
||||
width: 96px;
|
||||
height: auto;
|
||||
border-radius: 50%;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.resetmodal {
|
||||
min-height: 300px !important;
|
||||
max-width: 300px !important;
|
||||
margin: auto;
|
||||
|
||||
h4 {
|
||||
cursor: initial;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.resetfooter {
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
|
||||
button.reset {
|
||||
margin-right: 43px;
|
||||
}
|
||||
}
|
||||
|
||||
.resetoverlay {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.aboutIcon {
|
||||
color: var(--modal-text) !important;
|
||||
padding-right: 10px;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
.aboutLink {
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
.MuiFormControl-root {
|
||||
margin-top: 10px !important;
|
||||
}
|
||||
|
||||
label, p {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.17rem;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
48
src/components/modals/main/scss/marketplace/_buttons.scss
Normal file
@@ -0,0 +1,48 @@
|
||||
%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;
|
||||
}
|
||||
}
|
||||
|
||||
.removeFromMue {
|
||||
@extend %storebutton;
|
||||
|
||||
border: 2px solid #ff4757;
|
||||
color: #ff4757;
|
||||
margin-top: 5px;
|
||||
|
||||
&:hover {
|
||||
background: #ff4757;
|
||||
color: map-get($theme-colours, 'main');
|
||||
}
|
||||
}
|
||||
|
||||
.addToMue {
|
||||
@extend %storebutton;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.sideload {
|
||||
display: inline;
|
||||
margin-top: 0px;
|
||||
}
|
||||
187
src/components/modals/main/scss/marketplace/_main.scss
Normal file
@@ -0,0 +1,187 @@
|
||||
#item a {
|
||||
color: map-get($button-colours, 'other');
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
.emptyitems {
|
||||
width: 25vw;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 90px;
|
||||
}
|
||||
|
||||
.items {
|
||||
display: inline-grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
margin-top: 15px;
|
||||
|
||||
.item {
|
||||
position: relative;
|
||||
border-radius: 12px;
|
||||
height: 80px;
|
||||
width: 260px;
|
||||
background: map-get($marketplace, 'item-background');
|
||||
transition: 0.5s;
|
||||
cursor: pointer;
|
||||
margin-right: 20px;
|
||||
margin-top: 20px;
|
||||
box-shadow: 0 0 6px rgb(0 0 0 / 30%);
|
||||
|
||||
img {
|
||||
height: 100%;
|
||||
width: auto;
|
||||
border-radius: 12px 0 0 12px;
|
||||
background: white;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 20px;
|
||||
line-height: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
img,
|
||||
.details {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.details {
|
||||
position: absolute;
|
||||
left: 85px;
|
||||
top: -15px;
|
||||
|
||||
img {
|
||||
margin-left: 10px;
|
||||
height: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 5px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dark .items .item {
|
||||
background: #2d3436;
|
||||
}
|
||||
|
||||
p.author {
|
||||
margin-top: -5px;
|
||||
}
|
||||
|
||||
#item {
|
||||
display: none;
|
||||
|
||||
h1 {
|
||||
font-size: 40px;
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
#item>h1,
|
||||
#item>.MuiSvgIcon-root {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
p.description {
|
||||
margin-top: 0px;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.emptyMessage {
|
||||
text-align: center;
|
||||
background: var(--sidebar);
|
||||
padding: 25px;
|
||||
border-radius: 30px;
|
||||
box-shadow: 0 0 10px rgb(0 0 0 / 30%);
|
||||
position: absolute;
|
||||
width: 300px;
|
||||
|
||||
svg {
|
||||
font-size: 50px;
|
||||
margin-bottom: -20px;
|
||||
}
|
||||
}
|
||||
|
||||
.backArrow {
|
||||
cursor: pointer;
|
||||
width: 2rem !important;
|
||||
height: 2rem !important;
|
||||
|
||||
&:hover {
|
||||
color: grey;
|
||||
}
|
||||
}
|
||||
|
||||
.informationContainer {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.productInformation {
|
||||
padding: 10px;
|
||||
background: map-get($marketplace, 'product-information-backgroud');
|
||||
width: 350px;
|
||||
border-radius: 12px;
|
||||
|
||||
h4 {
|
||||
cursor: initial !important;
|
||||
}
|
||||
|
||||
li {
|
||||
margin-left: -4px;
|
||||
list-style: none;
|
||||
font-size: 16px;
|
||||
cursor: initial !important;
|
||||
|
||||
&.header {
|
||||
text-transform: uppercase;
|
||||
color: #787878;
|
||||
margin-left: -5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dark .productInformation {
|
||||
background: #2d3436;
|
||||
}
|
||||
|
||||
#item>img, .updateimage, .updatechangelog>p>img {
|
||||
border-radius: 24px;
|
||||
height: 200px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.featured {
|
||||
margin-top: 40px;
|
||||
border-radius: 15px;
|
||||
padding: 50px;
|
||||
color: #fff;
|
||||
box-shadow: 0 0 10px rgb(0 0 0 / 30%);
|
||||
width: 100%;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
99
src/components/modals/main/scss/settings/_buttons.scss
Normal file
@@ -0,0 +1,99 @@
|
||||
@import '../../../../../scss/modules/buttons';
|
||||
|
||||
.refresh {
|
||||
@extend %settingsButton;
|
||||
|
||||
background-color: map-get($button-colours, 'confirm');
|
||||
border: 2px solid map-get($button-colours, 'confirm');
|
||||
|
||||
&:hover {
|
||||
border: 2px solid map-get($button-colours, 'confirm');
|
||||
color: map-get($button-colours, 'confirm');
|
||||
}
|
||||
}
|
||||
|
||||
.reset {
|
||||
@extend %settingsButton;
|
||||
|
||||
margin-left: 5px;
|
||||
background-color: map-get($button-colours, 'reset');
|
||||
border: 2px solid map-get($button-colours, 'reset');
|
||||
|
||||
&:hover {
|
||||
border: 2px solid map-get($button-colours, 'reset');
|
||||
color: map-get($button-colours, 'reset');
|
||||
}
|
||||
}
|
||||
|
||||
.add {
|
||||
@extend %settingsButton;
|
||||
|
||||
background-color: map-get($button-colours, 'other');
|
||||
border: 2px solid map-get($button-colours, 'other');
|
||||
|
||||
&:hover {
|
||||
color: map-get($button-colours, 'other');
|
||||
border: 2px solid map-get($button-colours, 'other');
|
||||
}
|
||||
}
|
||||
|
||||
.close {
|
||||
@extend %settingsButton;
|
||||
|
||||
padding: 10px 50px 10px 50px;
|
||||
background-color: map-get($button-colours, 'other');
|
||||
border: 2px solid map-get($button-colours, 'other');
|
||||
|
||||
&:hover {
|
||||
color: map-get($button-colours, 'other');
|
||||
border: 2px solid map-get($button-colours, 'other');
|
||||
}
|
||||
}
|
||||
|
||||
.export,
|
||||
.uploadbg,
|
||||
.import {
|
||||
@extend %settingsButton;
|
||||
|
||||
background-color: map-get($button-colours, 'other');
|
||||
color: map-get($theme-colours, 'primary');
|
||||
border: 2px solid map-get($button-colours, 'other');
|
||||
|
||||
&:hover {
|
||||
color: map-get($button-colours, 'other');
|
||||
border: 2px solid map-get($button-colours, 'other');
|
||||
}
|
||||
}
|
||||
|
||||
.export,
|
||||
.import {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.MuiIconButton-label > svg.MuiSvgIcon-root {
|
||||
color: var(--modal-text) !important;
|
||||
}
|
||||
|
||||
.sortableitem {
|
||||
background: var(--sidebar) !important;
|
||||
padding: 10px 80px;
|
||||
padding-left: 10px;
|
||||
border-radius: 15px;
|
||||
margin-bottom: 10px;
|
||||
font-size: 1.325rem;
|
||||
|
||||
svg {
|
||||
font-size: 1.3rem;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25), 0 10px 10px rgba(0, 0, 0, 0.15);
|
||||
transition: 0.3s;
|
||||
}
|
||||
|
||||
z-index: 999 !important;
|
||||
}
|
||||
|
||||
.MuiTouchRipple-root {
|
||||
background: transparent;
|
||||
}
|
||||
26
src/components/modals/main/scss/settings/_daypicker.scss
Normal file
@@ -0,0 +1,26 @@
|
||||
.DayPickerInput,
|
||||
.input-container {
|
||||
input {
|
||||
width: 200px;
|
||||
color: var(--modal-text) !important;
|
||||
background: var(--sidebar);
|
||||
border: none;
|
||||
padding: 10px 10px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.DayPicker-Day--selected {
|
||||
background-color: #ff4757 !important;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.DayPicker-Months,
|
||||
.DayPickerInput-Overlay {
|
||||
background-color: var(--background) !important;
|
||||
color: var(--modal-text) !important;
|
||||
}
|
||||
|
||||
.DayPicker:not(.DayPicker--interactionDisabled) .DayPicker-Day:not(.DayPicker-Day--disabled):not(.DayPicker-Day--selected):not(.DayPicker-Day--outside):hover {
|
||||
color: black !important;
|
||||
}
|
||||
22
src/components/modals/main/scss/settings/_dropdown.scss
Normal file
@@ -0,0 +1,22 @@
|
||||
select {
|
||||
margin-left: 10px;
|
||||
width: 120px;
|
||||
color: var(--modal-text);
|
||||
background: var(--sidebar);
|
||||
border: none;
|
||||
padding: 10px 10px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
// firefox dropdown
|
||||
@supports (-moz-appearance: none) {
|
||||
select {
|
||||
-moz-appearance: none !important;
|
||||
background: url('data:image/gif;base64,R0lGODlhBgAGAKEDAFVVVX9/f9TU1CgmNyH5BAEKAAMALAAAAAAGAAYAAAIODA4hCDKWxlhNvmCnGwUAOw==') right center no-repeat, var(--sidebar) !important;
|
||||
background-position: calc(100% - 15px) center !important;
|
||||
}
|
||||
|
||||
option {
|
||||
font: -moz-pull-down-menu !important;
|
||||
}
|
||||
}
|
||||
171
src/components/modals/main/scss/settings/_main.scss
Normal file
@@ -0,0 +1,171 @@
|
||||
input {
|
||||
&[type=text] {
|
||||
width: 200px;
|
||||
color: var(--modal-text);
|
||||
background: var(--sidebar);
|
||||
border: none;
|
||||
padding: 10px 10px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
&[type=color] {
|
||||
border-radius: 100%;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
border: none;
|
||||
outline: none;
|
||||
-webkit-appearance: none;
|
||||
vertical-align: middle;
|
||||
background: none;
|
||||
|
||||
&::-webkit-color-swatch-wrapper {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&::-webkit-color-swatch {
|
||||
border: none;
|
||||
border-radius: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&[type=color]::-moz-color-swatch {
|
||||
border-radius: 100%;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
border: none;
|
||||
outline: none;
|
||||
-moz-appearance: none;
|
||||
vertical-align: middle;
|
||||
background: none;
|
||||
|
||||
&::-moz-color-swatch-wrapper {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&::-moz-color-swatch {
|
||||
border: none;
|
||||
border-radius: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
h4 {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 0px;
|
||||
margin: 0;
|
||||
|
||||
>label {
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.range {
|
||||
-webkit-appearance: none;
|
||||
width: 200px;
|
||||
height: 12px;
|
||||
border-radius: 12px;
|
||||
outline: none;
|
||||
background: var(--sidebar);
|
||||
box-shadow: 0 0 100px rgba(0, 0, 0, 0.3);
|
||||
|
||||
&::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 12px;
|
||||
background: var(--modal-text);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&::-moz-range-thumb {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 12px;
|
||||
border: 0;
|
||||
background: var(--modal-text);
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.newFeature {
|
||||
color: #ff4757;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.settingsTextarea {
|
||||
font-family: Consolas !important;
|
||||
padding: 15px;
|
||||
border-radius: 15px;
|
||||
background-color: var(--sidebar) !important;
|
||||
border: none;
|
||||
margin-left: 0;
|
||||
width: 400px;
|
||||
height: 200px;
|
||||
}
|
||||
|
||||
.MuiCheckbox-colorPrimary.Mui-checked,
|
||||
.MuiSwitch-colorPrimary.Mui-checked,
|
||||
.MuIconButton-colorPrimary.Mui-checked,
|
||||
.MuiSwitch-thumb,
|
||||
.MuiRadio-colorSecondary.Mui-checked,
|
||||
.PrivateSwitchBase-input-4,
|
||||
.MuiRadio-root,
|
||||
.aboutLink,
|
||||
.MuiIconButton-root,
|
||||
legend {
|
||||
color: var(--modal-text) !important;
|
||||
}
|
||||
|
||||
.MuiFormControlLabel-labelPlacementStart {
|
||||
margin-left: 0px !important;
|
||||
}
|
||||
|
||||
.MuiSwitch-colorPrimary.Mui-checked+.MuiSwitch-track {
|
||||
background: darkgray !important;
|
||||
}
|
||||
|
||||
.reminder-info {
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
padding: 15px;
|
||||
color: var(--modal-text);
|
||||
background: var(--sidebar);
|
||||
max-width: 300px;
|
||||
border-radius: 0.7em;
|
||||
|
||||
h1 {
|
||||
font-size: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.radio-title {
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
font-size: 1.17rem;
|
||||
}
|
||||
|
||||
.radio-title-small {
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.sortableitem {
|
||||
color: var(--modal-text) !important;
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
.updatechangelog {
|
||||
li {
|
||||
cursor: initial;
|
||||
font-size: 1rem;
|
||||
list-style-type:disc;
|
||||
padding: 0;
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// The following CSS is to work around some assumptions made by the react-color-gradient-picker
|
||||
* {
|
||||
// workaround for https://github.com/arthay/react-color-gradient-picker/issues/11
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
div.picker-area > div.preview > div.color-hue-alpha > div.alpha,
|
||||
div.color-preview-area > div > div:nth-child(5) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ui-color-picker {
|
||||
margin: 8px -12px;
|
||||
background-color: var(--background) !important;
|
||||
}
|
||||
|
||||
.input-field .label {
|
||||
color: inherit;
|
||||
color: var(--modal-text) !important;
|
||||
}
|
||||
|
||||
// other styling for themes support etc
|
||||
.gradient-degrees {
|
||||
border: 3px solid var(--modal-text) !important;
|
||||
}
|
||||
|
||||
.gradient-degree-pointer {
|
||||
background-color: var(--modal-text) !important;
|
||||
}
|
||||
|
||||
.gradient-type-item.active::after {
|
||||
border: 2px solid var(--modal-text) !important;
|
||||
}
|
||||
53
src/components/modals/main/settings/Checkbox.jsx
Normal file
@@ -0,0 +1,53 @@
|
||||
import React from 'react';
|
||||
|
||||
import EventBus from '../../../../modules/helpers/eventbus';
|
||||
import SettingsFunctions from '../../../../modules/helpers/settings';
|
||||
|
||||
import CheckboxUI from '@material-ui/core/Checkbox';
|
||||
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
||||
|
||||
export default class Checkbox extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
checked: (localStorage.getItem(this.props.name) === 'true')
|
||||
};
|
||||
}
|
||||
|
||||
handleChange = () => {
|
||||
SettingsFunctions.setItem(this.props.name);
|
||||
|
||||
this.setState({
|
||||
checked: (this.state.checked === true) ? false : true
|
||||
});
|
||||
|
||||
if (this.props.element) {
|
||||
if (!document.querySelector(this.props.element)) {
|
||||
document.querySelector('.reminder-info').style.display = 'block';
|
||||
return localStorage.setItem('showReminder', true);
|
||||
}
|
||||
}
|
||||
|
||||
EventBus.dispatch('refresh', this.props.category);
|
||||
}
|
||||
|
||||
render() {
|
||||
let text = this.props.text;
|
||||
|
||||
if (this.props.newFeature) {
|
||||
text = <>{this.props.text} <span className='newFeature'> NEW</span></>;
|
||||
} else if (this.props.betaFeature) {
|
||||
text = <>{this.props.text} <span className='newFeature'> BETA</span></>;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<FormControlLabel
|
||||
control={<CheckboxUI name={this.props.name} color='primary' checked={this.state.checked} onChange={this.handleChange} />}
|
||||
label={text}
|
||||
/>
|
||||
<br/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
64
src/components/modals/main/settings/Dropdown.jsx
Normal file
@@ -0,0 +1,64 @@
|
||||
import React from 'react';
|
||||
|
||||
import EventBus from '../../../../modules/helpers/eventbus';
|
||||
|
||||
export default class Dropdown extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
value: localStorage.getItem(this.props.name) || '',
|
||||
title: ''
|
||||
};
|
||||
}
|
||||
|
||||
getLabel() {
|
||||
return this.props.label ? <label>{this.props.label}</label> : null;
|
||||
}
|
||||
|
||||
onChange = (e) => {
|
||||
const { value } = e.target;
|
||||
|
||||
if (value === window.language.modals.main.loading) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
value: value,
|
||||
title: e.target[e.target.selectedIndex].text
|
||||
});
|
||||
|
||||
localStorage.setItem(this.props.name, value);
|
||||
|
||||
if (this.props.onChange) {
|
||||
this.props.onChange(value);
|
||||
}
|
||||
|
||||
if (this.props.element) {
|
||||
if (!document.querySelector(this.props.element)) {
|
||||
document.querySelector('.reminder-info').style.display = 'block';
|
||||
return localStorage.setItem('showReminder', true);
|
||||
}
|
||||
}
|
||||
|
||||
EventBus.dispatch('refresh', this.props.category);
|
||||
}
|
||||
|
||||
// todo: find a better way to do this
|
||||
componentDidMount() {
|
||||
const element = document.getElementById(this.props.name);
|
||||
this.setState({
|
||||
title: element[element.selectedIndex].text
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<>
|
||||
{this.getLabel()}
|
||||
<select id={this.props.name} value={this.state.value} onChange={this.onChange} style={{width: `${(8*this.state.title.length) + 50}px`}}>
|
||||
{this.props.children}
|
||||
</select>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
31
src/components/modals/main/settings/FileUpload.jsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import React from 'react';
|
||||
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
export default class FileUpload extends React.PureComponent {
|
||||
componentDidMount() {
|
||||
document.getElementById(this.props.id).onchange = (e) => {
|
||||
const reader = new FileReader();
|
||||
const file = e.target.files[0];
|
||||
|
||||
if (this.props.type === 'settings') {
|
||||
reader.readAsText(file, 'UTF-8');
|
||||
} else {
|
||||
// background upload
|
||||
if (file.size > 2000000) {
|
||||
return toast(window.language.modals.main.file_upload_error);
|
||||
}
|
||||
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
|
||||
reader.addEventListener('load', (e) => {
|
||||
this.props.loadFunction(e);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
return <input id={this.props.id} type='file' style={{ display: 'none' }} accept={this.props.accept} />;
|
||||
}
|
||||
}
|
||||
54
src/components/modals/main/settings/Radio.jsx
Normal file
@@ -0,0 +1,54 @@
|
||||
import React from 'react';
|
||||
|
||||
import EventBus from '../../../../modules/helpers/eventbus';
|
||||
|
||||
import RadioUI from '@material-ui/core/Radio';
|
||||
import RadioGroup from '@material-ui/core/RadioGroup';
|
||||
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
||||
import FormControl from '@material-ui/core/FormControl';
|
||||
import FormLabel from '@material-ui/core/FormLabel';
|
||||
|
||||
export default class Radio extends React.PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
value: localStorage.getItem(this.props.name)
|
||||
};
|
||||
}
|
||||
|
||||
handleChange = (e) => {
|
||||
const { value } = e.target;
|
||||
|
||||
if (value === 'loading') {
|
||||
return;
|
||||
}
|
||||
|
||||
localStorage.setItem(this.props.name, value);
|
||||
|
||||
this.setState({
|
||||
value: value
|
||||
});
|
||||
|
||||
if (this.props.element) {
|
||||
if (!document.querySelector(this.props.element)) {
|
||||
document.querySelector('.reminder-info').style.display = 'block';
|
||||
return localStorage.setItem('showReminder', true);
|
||||
}
|
||||
}
|
||||
|
||||
EventBus.dispatch('refresh', this.props.category);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<FormControl component='fieldset'>
|
||||
<FormLabel className={this.props.smallTitle ? 'radio-title-small' : 'radio-title'} component='legend'>{this.props.title}</FormLabel>
|
||||
<RadioGroup aria-label={this.props.name} name={this.props.name} onChange={this.handleChange} value={this.state.value}>
|
||||
{this.props.options.map((option) => (
|
||||
<FormControlLabel value={option.value} control={<RadioUI/>} label={option.name} key={option.name} />
|
||||
))}
|
||||
</RadioGroup>
|
||||
</FormControl>
|
||||
);
|
||||
}
|
||||
}
|
||||
24
src/components/modals/main/settings/ResetModal.jsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import React from 'react';
|
||||
|
||||
import SettingsFunctions from '../../../../modules/helpers/settings';
|
||||
|
||||
export default function ResetModal(props) {
|
||||
const language = window.language.modals.main.settings.sections.advanced.reset_modal;
|
||||
|
||||
const reset = () => {
|
||||
SettingsFunctions.setDefaultSettings('reset');
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<h3 style={{'textAlign': 'center'}}>{language.title}</h3>
|
||||
<h4>{language.question}</h4>
|
||||
<p>{language.information}</p>
|
||||
<div className='resetfooter'>
|
||||
<button className='reset' style={{ 'marginLeft': '0' }} onClick={() => reset()}>{window.language.modals.main.settings.buttons.reset}</button>
|
||||
<button className='import' style={{ 'marginLeft': '5px' }} onClick={props.modalClose}>{language.cancel}</button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||