Compare commits

...

99 Commits
5.0.0 ... 5.1.0

Author SHA1 Message Date
David Ralph
4449957fe6 chore: release 5.1.0 2021-06-21 13:26:31 +01:00
David Ralph
5b00b3d859 fix: voice search no longer redirects on empty and now has reload warning 2021-06-21 13:13:16 +01:00
David Ralph
aad568bd28 fix: autocomplete now works on extension, hot reload warnings added for background quality and gradient 2021-06-21 12:26:22 +01:00
David Ralph
4e1347ad4e chore: update manifest 2021-06-20 21:46:48 +01:00
David Ralph
8073d8325a fix(translations): zh-CN merge errors fixed 2021-06-20 21:08:23 +01:00
Austin Huang
dc1f1fab45 Update zh-CN translations (#161)
* Update zh_CN.json

* Update zh_CN.json

Co-authored-by: David Ralph <ohlookitsderpy@protonmail.com>
2021-06-20 20:58:54 +01:00
David Ralph
dc442ef917 fix: upgrading from 5.0.1 to latest now works, code style changes etc 2021-06-20 13:09:41 +01:00
David Ralph
796896571d feat: add support for google favicon to quick links 2021-06-18 12:40:46 +01:00
David Ralph
cad3f53140 feat(translations): added translation support to weather visibility 2021-06-17 13:08:04 +01:00
David Ralph
b0da5cfa75 feat: language support for weather description 2021-06-16 23:30:50 +01:00
Vicente
c2ca979971 feat(translations): added the missing ones (#160)
* feat(translations): updated spanish translation

* feat(translations): added the missing ones
2021-06-16 12:46:33 +01:00
Vicente
1e5f288d42 feat(translations): updated spanish translation (#159) 2021-06-16 12:31:39 +01:00
David Ralph
b2c94924a2 Merge branch 'main' of https://github.com/mue/mue 2021-06-16 12:05:15 +01:00
David Ralph
de1797c662 fix: background hot reload, settings issue, remove navbar hover setting 2021-06-16 12:05:03 +01:00
dependabot[bot]
db3081efc5 chore(deps): bump react-modal from 3.14.2 to 3.14.3 (#158)
Bumps [react-modal](https://github.com/reactjs/react-modal) from 3.14.2 to 3.14.3.
- [Release notes](https://github.com/reactjs/react-modal/releases)
- [Changelog](https://github.com/reactjs/react-modal/blob/master/CHANGELOG.md)
- [Commits](https://github.com/reactjs/react-modal/compare/v3.14.2...v3.14.3)

---
updated-dependencies:
- dependency-name: react-modal
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-06-16 10:11:32 +01:00
David Ralph
dcddd78164 feat: api background quality setting 2021-06-13 16:36:43 +01:00
David Ralph
335a6864b1 fix: custom js, reminder on reset button etc 2021-06-13 13:47:18 +01:00
dependabot[bot]
1f6dc34ee6 chore(deps-dev): bump sass-loader from 11.1.1 to 12.0.0 (#156)
Bumps [sass-loader](https://github.com/webpack-contrib/sass-loader) from 11.1.1 to 12.0.0.
- [Release notes](https://github.com/webpack-contrib/sass-loader/releases)
- [Changelog](https://github.com/webpack-contrib/sass-loader/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack-contrib/sass-loader/compare/v11.1.1...v12.0.0)

---
updated-dependencies:
- dependency-name: sass-loader
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-06-02 10:15:14 +01:00
dependabot[bot]
fbc9189cba chore(deps): bump react-modal from 3.13.1 to 3.14.2 (#155)
Bumps [react-modal](https://github.com/reactjs/react-modal) from 3.13.1 to 3.14.2.
- [Release notes](https://github.com/reactjs/react-modal/releases)
- [Changelog](https://github.com/reactjs/react-modal/blob/master/CHANGELOG.md)
- [Commits](https://github.com/reactjs/react-modal/compare/v3.13.1...v3.14.2)

---
updated-dependencies:
- dependency-name: react-modal
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-06-02 10:15:03 +01:00
David Ralph
586b6f8700 style: cleanup some things 2021-05-26 22:28:26 +01:00
David Ralph
1d6013f738 fix: background location info works properly on unsplash and pexels now 2021-05-24 22:01:54 +01:00
David Ralph
c1ef3e3528 fix: small modal and marketplace css fixes 2021-05-24 11:43:38 +01:00
David Ralph
4b57229396 fix: custom quote hot reload 2021-05-24 10:44:20 +01:00
David Ralph
e721babcf7 fix: marketplace sort and widget zoom breaking analogue clock 2021-05-23 12:24:58 +01:00
David Ralph
8a816516c9 chore: cleanup readme slightly and update some content 2021-05-22 23:06:56 +01:00
David Ralph
bd09542b34 Merge branch 'main' of https://github.com/mue/mue 2021-05-22 22:56:33 +01:00
David Ralph
84dad33548 style: code cleanup and about tab changes 2021-05-22 22:56:24 +01:00
David Ralph
588021cf92 chore: update readme intro 2021-05-22 14:57:10 +01:00
David Ralph
6a9eccaed0 chore: mue edge is now updated 2021-05-21 10:33:34 +01:00
David Ralph
299547842a fix: safari css fixes 2021-05-20 15:58:06 +01:00
David Ralph
ba2dc61a5d fix: css fixes for firefox and safari, fix widget order css 2021-05-20 12:27:52 +01:00
David Ralph
2fd2e06bac fix: duckduckgo proxy no longer breaks offline mode 2021-05-16 21:05:56 +01:00
David Ralph
08bfa2772d feat: show navbar on hover setting, fix photo information toggle hot reload
Co-authored-by: Alex Sparkes <turbomarshmello@gmail.com>
2021-05-09 22:39:45 +01:00
David Ralph
9b9c2e74f6 feat: add photo information icon toggle option and optimise font 2021-05-09 16:37:28 +01:00
David Ralph
63e49b79cd feat: favourite background now shows all photo info 2021-05-08 17:12:02 +01:00
David Ralph
da6ebb8c60 fix: maximise with background filters, css fixes
Co-authored-by: Alex Sparkes <turbomarshmello@gmail.com>
2021-05-08 13:47:09 +01:00
David Ralph
b1fbaa7601 fix: search button and refactor wind direction icon slightly 2021-05-08 10:58:17 +01:00
David Ralph
7327382497 feat: widget zoom for weather and fixes 2021-05-07 13:27:28 +01:00
David Ralph
cb129238cb fix: improvements and fixes to about tab and photoinformation 2021-05-06 18:30:57 +01:00
David Ralph
2ac08a7cf6 chore: stop vercel from commenting on each commit 2021-05-06 18:13:00 +01:00
David Ralph
eeb0870feb fix: proper support for pexels 2021-05-06 17:30:13 +01:00
David Ralph
260d1928d8 style: code changes etc 2021-05-05 15:44:39 +01:00
David Ralph
fa19570c36 fix: various marketplace fixes 2021-05-03 15:39:34 +01:00
David Ralph
ed76fcccc8 fix: preset settings now work 2021-05-03 12:05:21 +01:00
David Ralph
6b4922b825 perf: marketplace cleanup 2021-05-03 11:27:52 +01:00
David Ralph
1dc5e7375b fix: search bar and add quote pack api support back 2021-05-03 11:10:04 +01:00
David Ralph
7628e769be fix: quote fixes and light theme search bar 2021-05-03 10:50:00 +01:00
David Ralph
7470ca9e3a feat: finish quote pack support, change quote settings ui and improve hot reload 2021-05-02 22:45:29 +01:00
David Ralph
f49cf1f65b fix: quote packs, add preset settings to sidebar (WIP) 2021-05-02 18:12:03 +01:00
David Ralph
f21ee5c5ba fix: various bug fixes for background and marketplace 2021-05-02 17:10:20 +01:00
David Ralph
5ea158c21d fix: revert css change 2021-05-02 17:01:20 +01:00
David Ralph
3aa17f0c30 fix: add missing translations 2021-05-02 14:45:34 +01:00
David Ralph
e8698f2141 feat: sort addons/marketplace items 2021-05-02 14:44:23 +01:00
David Ralph
9b5946038a feat: background filters 2021-05-02 13:40:11 +01:00
David Ralph
31a666fe22 feat: individual widget zoom, hot reload for font and custom js/css etc 2021-05-02 12:11:07 +01:00
David Ralph
b9663831fd fix: search autocomplete, add visibility to weather 2021-05-01 22:27:44 +01:00
David Ralph
48268111d0 Merge pull request #154 from Vicente015/fix-photo-info
feat: Improve photo packs text and information
2021-05-01 22:08:55 +01:00
Vicente
af335adc23 feat: Add photo location in photo packs 2021-05-01 21:35:41 +01:00
Vicente
e88cd0b765 fix: remove Unsplash text from photo packs 2021-05-01 21:33:07 +01:00
David Ralph
a1b6832747 feat: autocomplete for search
Co-authored-by: Alex Sparkes <turbomarshmello@gmail.com>
2021-05-01 18:29:07 +01:00
David Ralph
7942c367a7 feat: finish lightbox
Co-authored-by: Alex Sparkes <turbomarshmello@gmail.com>
2021-05-01 12:31:46 +01:00
David Ralph
f2f683201d fix: weather auto location not working on firefox 2021-05-01 11:45:12 +01:00
David Ralph
84dbe5cb69 feat: pexels background api 2021-04-30 22:49:04 +01:00
David Ralph
90927c9e8f fix: update check in about page 2021-04-30 18:58:58 +01:00
David Ralph
1af688c489 fix: add setting for cloudiness and fix strings 2021-04-30 18:44:03 +01:00
David Ralph
1715e7d089 feat: Auto location for weather, option to show text for weather, wind direction option etc 2021-04-30 18:19:36 +01:00
David Ralph
4b18ea74a7 5.0.1 2021-04-29 19:02:14 +01:00
David Ralph
6c7ab96350 fix: background hot reload when changing from custom to api 2021-04-29 09:02:19 +01:00
David Ralph
b26a261644 Merge pull request #153 from mue/dependabot/add-v2-config-file
Upgrade to GitHub-native Dependabot
2021-04-29 08:47:27 +01:00
dependabot-preview[bot]
7ce71497bb Upgrade to GitHub-native Dependabot 2021-04-28 22:08:45 +00:00
David Ralph
696b58f9bc fix: modal text styles 2021-04-28 21:14:50 +01:00
David Ralph
e45600b4db Merge pull request #152 from mue/dependabot/npm_and_yarn/material-ui/core-4.11.4
build(deps): bump @material-ui/core from 4.11.3 to 4.11.4
2021-04-28 16:27:53 +01:00
dependabot-preview[bot]
7126a2e295 build(deps): bump @material-ui/core from 4.11.3 to 4.11.4
Bumps [@material-ui/core](https://github.com/mui-org/material-ui/tree/HEAD/packages/material-ui) from 4.11.3 to 4.11.4.
- [Release notes](https://github.com/mui-org/material-ui/releases)
- [Changelog](https://github.com/mui-org/material-ui/blob/v4.11.4/CHANGELOG.md)
- [Commits](https://github.com/mui-org/material-ui/commits/v4.11.4/packages/material-ui)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>
2021-04-28 15:26:42 +00:00
David Ralph
e323d4c692 fix: photoinformation not appearing when turning background off and on again 2021-04-28 16:16:27 +01:00
David Ralph
b795ceb33d feat: hot reload for clock and greeting 2021-04-28 15:06:15 +01:00
David Ralph
b26265eceb fix: various fixes for offline mode and background components 2021-04-28 14:25:24 +01:00
David Ralph
2afc9159cf fix: various modal fixes 2021-04-27 22:17:36 +01:00
David Ralph
8f629b1ef9 fix: background hot reload now only reloads when needed 2021-04-27 21:51:22 +01:00
David Ralph
79a0ec8df9 fix: responsive css fixes 2021-04-27 19:46:56 +01:00
David Ralph
133db009aa fix: unsplash links etc 2021-04-27 14:52:04 +01:00
David Ralph
8f017cda32 fix: remove unneeded import 2021-04-26 19:10:29 +01:00
David Ralph
38546ef074 feat: wind direction display on weather 2021-04-26 19:10:00 +01:00
David Ralph
57cc5de60a fix: url regex and language for add quick link, slider fixes 2021-04-26 17:49:20 +01:00
David Ralph
84571682b0 fix: slider text 2021-04-26 17:21:30 +01:00
David Ralph
d97a3236cf feat: text input for sliders (WIP) 2021-04-26 14:41:23 +01:00
David Ralph
1bc1729bdd fix: changelog style 2021-04-26 13:11:40 +01:00
David Ralph
ff94d66163 fix: marketplace css, reset modal transitions, add WIP lightbox to item page 2021-04-26 09:52:22 +01:00
David Ralph
48979d4a75 fix: marketplace style fixes and update dependencies 2021-04-25 22:46:17 +01:00
David Ralph
1c4a0fa9c1 Merge pull request #151 from Vicente015/fix-default-language
Fix default language
2021-04-24 13:56:47 +01:00
Vicente
cf176bccda fix: ci issues 2021-04-24 13:53:49 +01:00
Vicente
f3cf6bd0b3 Merge main, update translations files 2021-04-24 13:45:03 +01:00
Vicente
7a03a00013 fix: Added parentheses around arrow function 2021-04-24 13:43:40 +01:00
Vicente
6382202dbf Fix default language 2021-04-24 13:43:40 +01:00
Vicente
942644dc40 fix: Added parentheses around arrow function 2021-04-24 13:40:09 +01:00
Vicente
eb5bc8a843 Fix default language 2021-04-24 13:33:09 +01:00
David Ralph
6a147ff890 Merge pull request #150 from Vicente015/translations/spanish
Update Spanish translation
2021-04-24 13:32:22 +01:00
Vicente
03670e8773 Added missing translation 2021-04-24 12:32:11 +01:00
Vicente
6a64f31940 Fix typos, added missing translations 2021-04-24 12:06:26 +01:00
Vicente
11129f2d70 Update Spanish translations 2021-04-23 23:50:49 +01:00
85 changed files with 2097 additions and 979 deletions

17
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,17 @@
version: 2
updates:
- package-ecosystem: npm
directory: "/"
schedule:
interval: daily
open-pull-requests-limit: 10
ignore:
- dependency-name: fontsource-lexend-deca
versions:
- ">= 4.a, < 5"
- dependency-name: fontsource-roboto
versions:
- ">= 4.a, < 5"
- dependency-name: react-modal
versions:
- 3.13.1

View File

@@ -1,13 +1,13 @@
<img src="https://raw.githubusercontent.com/mue/branding/master/logo/logo_round.png" align="left" width="180px" height="180px"/>
<img src="https://raw.githubusercontent.com/mue/branding/main/logo/logo_round.png" align="left" width="180px" height="180px"/>
<img align="left" width="0" height="192px" hspace="10"/>
> <a href="https://muetab.com/">Mue</a>
[![License](https://img.shields.io/badge/license-BSD%203-blue?style=flat-square)](/LICENSE) [![Discord](https://img.shields.io/discord/659129207208804381?label=discord&color=7289DA&style=flat-square)](https://discord.gg/zv8C9F8) [![Code Size]( https://img.shields.io/github/languages/code-size/mue/mue?color=green&label=size&style=flat-square)]()
[![License](https://img.shields.io/badge/license-BSD%203-blue?style=flat-square)](/LICENSE) [![Discord](https://img.shields.io/discord/659129207208804381?label=discord&color=7289DA&style=flat-square)](https://discord.gg/zv8C9F8) [![Code Size](https://img.shields.io/github/languages/code-size/mue/mue?color=green&label=size&style=flat-square)]()
<br>
[![Microsoft Edge](https://img.shields.io/badge/dynamic/json?style=flat-square&label=microsoft%20edge&query=%24.version&url=https%3A%2F%2Fmicrosoftedge.microsoft.com%2Faddons%2Fgetproductdetailsbycrxid%2Faepnglgjfokepefimhbnibfjekidhmja)](https://microsoftedge.microsoft.com/addons/detail/aepnglgjfokepefimhbnibfjekidhmja) [![Firefox](https://img.shields.io/amo/v/mue?label=firefox&style=flat-square)](https://addons.mozilla.org/firefox/addon/mue) [![Chrome](https://img.shields.io/chrome-web-store/v/bngmbednanpcfochchhgbkookpiaiaid?label=chrome&style=flat-square)](https://chrome.google.com/webstore/detail/mue/bngmbednanpcfochchhgbkookpiaiaid)
Mue is a fast, open and free-to-use browser extension that gives a new, fresh and customizable tab page to most modern browsers
Mue is a fast, open and free-to-use browser extension that gives a new, fresh and customisable tab page to modern browsers
<br>
@@ -22,9 +22,7 @@ Mue is a fast, open and free-to-use browser extension that gives a new, fresh an
* [Naver](#naver)
* [Other](#other)
* [Contributing](#development)
* [Requirements](#requirements)
* [Starting](#starting)
* [Building](#building)
* [Translations](#translations)
* [Credits](#credits)
* [Developers](#developers)
* [Translators](#translators)
@@ -60,7 +58,7 @@ Please see our [roadmap](https://github.com/mue/mue/projects)
[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
[Microsoft Edge Addons](https://microsoftedge.microsoft.com/addons/detail/aepnglgjfokepefimhbnibfjekidhmja)
### Naver
[Whale Store](https://store.whale.naver.com/detail/ecllekeilcmicbfkkiknfdddbogibbnc)
@@ -71,47 +69,10 @@ 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/Edge (Chromium)</b> (Click to expand)</summary>
<ol>
<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 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>
<ol>
<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>
<li> Enjoy your new tab!
</ol>
</details>
<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> <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>
This section has moved to the [documentation](https://docs.muetab.com/development#mue-tab).
### Translations
Please see the [documentation](https://docs.muetab.com/translations).
## Credits
### Developers
@@ -128,7 +89,7 @@ Please note that we have dropped support for Opera as of Mue 5.0
[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.
Many thanks to the photographers [here](https://api.muetab.com/images/photographers) for letting us use their wonderful photographs.
And finally, a big thank you to all the other [contributors](https://github.com/mue/mue/graphs/contributors)!
### Resources

View File

@@ -3,7 +3,8 @@
"offline_enabled": true,
"name": "Mue",
"description": "Fast, open and free-to-use new tab page for modern browsers.",
"version": "5.0.0",
"version": "5.1.0",
"homepage_url": "https://muetab.com",
"browser_action": {
"default_icon": "icons/128x128.png"
},
@@ -14,5 +15,6 @@
"16": "icons/16x16.png",
"48": "icons/48x48.png",
"128": "icons/128x128.png"
}
},
"content_security_policy": "script-src 'self' https://api.bing.com https://www.google.com; object-src 'self'"
}

View File

@@ -2,14 +2,21 @@
"manifest_version": 2,
"name": "Mue",
"description": "Fast, open and free-to-use new tab page for modern browsers.",
"version": "5.0.0",
"version": "5.1.0",
"homepage_url": "https://muetab.com",
"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"
},
"chrome_settings_overrides": {
"homepage": "index.html"
}
},
"content_security_policy": "script-src 'self' https://api.bing.com https://www.google.com; object-src 'self'"
}

View File

@@ -9,45 +9,45 @@
"homepage": "https://muetab.com",
"bugs": "https://github.com/mue/mue/issues/new?assignees=&labels=bug&template=bug-report.md&title=%5BBUG%5D",
"license": "BSD-3-Clause",
"version": "5.0.0",
"version": "5.1.0",
"dependencies": {
"@fontsource/lexend-deca": "^4.2.3",
"@fontsource/montserrat": "^4.2.2",
"@material-ui/core": "4.11.3",
"@fontsource/lexend-deca": "^4.4.5",
"@fontsource/montserrat": "^4.4.5",
"@material-ui/core": "4.11.4",
"@material-ui/icons": "4.11.2",
"fetch-jsonp": "^1.1.3",
"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-modal": "3.14.3",
"react-sortable-hoc": "2.0.0",
"react-toastify": "7.0.3",
"weather-icons-react": "^1.2.0"
"react-toastify": "7.0.4",
"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/core": "^7.14.6",
"@babel/eslint-parser": "^7.14.5",
"@babel/plugin-proposal-class-properties": "^7.14.5",
"@babel/plugin-transform-react-constant-elements": "^7.13.15",
"@babel/plugin-transform-runtime": "^7.14.5",
"@babel/preset-env": "^7.14.5",
"@babel/preset-react": "^7.14.5",
"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",
"copy-webpack-plugin": "^9.0.0",
"css-loader": "^5.2.6",
"eslint": "^7.28.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",
"mini-css-extract-plugin": "^1.6.0",
"sass": "^1.35.1",
"sass-loader": "^7.3.1",
"source-map-loader": "^3.0.0",
"webpack": "^5.39.1",
"webpack-cli": "^4.7.2",
"webpack-dev-server": "^3.11.2"
},
"scripts": {

View File

@@ -17,7 +17,8 @@ export default class App extends React.PureComponent {
}
// 4.0 -> 5.0 (the key below is only on 5.0)
if (!localStorage.getItem('order')) {
// now featuring 5.0 -> 5.1
if (!localStorage.getItem('order') || !localStorage.getItem('autocompleteProvider')) {
SettingsFunctions.moveSettings();
window.location.reload();
}

View File

@@ -0,0 +1,75 @@
import React from 'react';
import './autocomplete.scss';
export default class Autocomplete extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
filtered: [],
showList: false,
input: ''
};
this.enabled = (localStorage.getItem('autocomplete') === 'true');
}
onChange = (e) => {
if (this.enabled === false) {
return this.setState({
input: e.target.value
});
}
this.setState({
filtered: this.props.suggestions.filter((suggestion) => suggestion.toLowerCase().indexOf(e.target.value.toLowerCase()) > -1),
showList: true,
input: e.target.value
});
this.props.onChange(e.target.value);
};
onClick = (e) => {
this.setState({
filtered: [],
showList: false,
input: e.target.innerText
});
this.props.onClick(e);
};
render() {
let autocomplete = null;
if (this.state.showList && this.state.input) {
if (this.state.filtered.length && localStorage.getItem('autocomplete') === 'true') {
autocomplete = (
<ul className='suggestions'>
{this.state.filtered.map((suggestion) => {
return (
<li key={suggestion} onClick={this.onClick}>
{suggestion}
</li>
);
})}
</ul>
);
}
}
return (
<>
<input
type='text'
onChange={this.onChange}
value={this.state.input}
name={this.props.name || 'name'}
placeholder={this.props.placeholder || ''}
autoComplete='off'
id={this.props.id || ''} />
{autocomplete}
</>
);
}
}

View File

@@ -0,0 +1,50 @@
.suggestions {
text-align: left;
font-size: calc(5px + 1.2vmin);
background-color: rgba(255, 255, 255, 0.8);
color: black;
border-top-width: 0;
list-style: none;
margin-top: 40px;
max-height: 143px;
overflow: hidden;
position: relative;
display: inline-block;
margin-left: 40px;
border-radius: 24px;
width: 430px;
opacity: 0;
li {
padding: 0.5rem;
padding-left: 20px;
&:hover {
background-color: rgba(255, 255, 255, 0.8);
cursor: pointer;
}
}
}
.searchBar {
input[type=text]:focus+.suggestions {
opacity: 1;
}
}
@media screen and (min-width: 1400px) {
.suggestions {
margin-top: 50px;
}
}
.dark .suggestions {
background-color: rgba(0, 0, 0, 0.5);
color: white;
li {
&:hover {
background-color: rgba(0, 0, 0, 0.5);
}
}
}

View File

@@ -1,5 +1,3 @@
import React from 'react';
import './tooltip.scss';
export default function Tooltip(props) {

View File

@@ -44,14 +44,14 @@ export default class Modals extends React.PureComponent {
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}>
<Modal closeTimeoutMS={300} id='modal' onRequestClose={() => this.setState({ mainModal: false })} isOpen={this.state.mainModal} className='Modal mainModal' 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}>
<Modal closeTimeoutMS={300} onRequestClose={() => this.closeWelcome()} isOpen={this.state.welcomeModal} className='Modal welcomemodal mainModal' 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}>
<Modal closeTimeoutMS={300} onRequestClose={() => this.setState({ feedbackModal: false })} isOpen={this.state.feedbackModal} className='Modal mainModal' overlayClassName='Overlay' ariaHideApp={false}>
<Feedback modalClose={() => this.setState({ feedbackModal: false })}/>
</Modal>
</React.Suspense>

View File

@@ -1,14 +1,28 @@
import React from 'react';
import Modal from 'react-modal';
import Lightbox from './Lightbox';
import ArrowBackIcon from '@material-ui/icons/ArrowBack';
export default function Item(props) {
const language = window.language.modals.main.marketplace.product;
export default class Item extends React.PureComponent {
constructor() {
super();
this.state = {
showLightbox: false
};
}
let warningHTML;
// For some reason it breaks sometimes so we use try/catch
try {
if (props.content.content.data.quote_api) {
render() {
const language = window.language.modals.main.marketplace.product;
if (!this.props.data.display_name) {
return null;
}
let warningHTML;
if (this.props.data.quote_api) {
warningHTML = (
<div className='productInformation'>
<ul>
@@ -18,42 +32,45 @@ export default function Item(props) {
</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}
// prevent console error
let iconsrc = window.constants.DDG_PROXY + this.props.data.icon;
if (!this.props.data.icon) {
iconsrc = null;
}
return (
<div id='item'>
<br/>
<ArrowBackIcon className='backArrow' onClick={this.props.toggleFunction}/>
<br/>
<h1>{this.props.data.display_name}</h1>
<br/>
{this.props.button}
<br/>
{iconsrc ? <img alt='product' draggable='false' src={iconsrc} onClick={() => this.setState({ showLightbox: true })}/> : null}
<div className='informationContainer'>
<h1 className='overview'>{language.overview}</h1>
<p className='description' dangerouslySetInnerHTML={{ __html: this.props.data.description }}></p>
<div className='productInformation'>
<ul>
{/* <li className='header'>{language.last_updated}</li>
<li>{this.props.data.updated}</li>
<br/>*/}
<li className='header'>{language.version}</li>
<li>{this.props.data.version}</li>
<br/>
<li className='header'>{language.author}</li>
<li>{this.props.data.author}</li>
</ul>
</div>
<br/>
{warningHTML}
</div>
<Modal closeTimeoutMS={100} onRequestClose={() => this.setState({ showLightbox: false })} isOpen={this.state.showLightbox} className='Modal lightboxmodal' overlayClassName='Overlay resetoverlay' ariaHideApp={false}>
<Lightbox modalClose={() => this.setState({ showLightbox: false })} img={iconsrc}/>
</Modal>
</div>
</div>
);
);
}
}

View File

@@ -1,5 +1,3 @@
import React from 'react';
export default function Items(props) {
return (
<div className='items'>
@@ -7,7 +5,7 @@ export default function Items(props) {
<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>
<h4>{item.display_name || item.name}</h4>
<p>{item.author}</p>
</div>
</div>

View File

@@ -0,0 +1,8 @@
export default function Lightbox(props) {
return (
<>
<span className='closeModal' onClick={props.modalClose}>&times;</span>
<img src={props.img} className='lightboximg' draggable={false} alt='Item screenshot'/>
</>
);
}

View File

@@ -3,6 +3,7 @@ import React from 'react';
import LocalMallIcon from '@material-ui/icons/LocalMall';
import Item from '../Item';
import Items from '../Items';
import Dropdown from '../../settings/Dropdown';
import MarketplaceFunctions from '../../../../../modules/helpers/marketplace';
@@ -13,19 +14,8 @@ export default class Added extends React.PureComponent {
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'
}
item: {},
button: ''
};
this.buttons = {
uninstall: <button className='removeFromMue' onClick={() => this.uninstall()}>{window.language.modals.main.marketplace.product.buttons.remove}</button>,
@@ -47,20 +37,14 @@ export default class Added extends React.PureComponent {
description: MarketplaceFunctions.urlParser(info.description.replace(/\n/g, '<br>')),
//updated: info.updated,
version: info.version,
icon: info.screenshot_url
icon: info.screenshot_url,
quote_api: info.quote_api || null
},
button: this.buttons.uninstall,
display: {
marketplace: 'none',
item: 'block'
}
button: this.buttons.uninstall
});
} else {
this.setState({
display: {
marketplace: 'block',
item: 'none'
}
item: {}
});
}
}
@@ -76,6 +60,34 @@ export default class Added extends React.PureComponent {
});
}
sortAddons(value) {
let installed = JSON.parse(localStorage.getItem('installed'));
switch (value) {
case 'newest':
installed.reverse();
break;
case 'oldest':
break;
case 'a-z':
installed.sort();
break;
case 'z-a':
installed.sort();
installed.reverse();
break;
default:
break;
}
this.setState({
installed: installed
});
}
componentDidMount() {
this.sortAddons(localStorage.getItem('sortAddons'));
}
render() {
if (this.state.installed.length === 0) {
return (
@@ -89,12 +101,20 @@ export default class Added extends React.PureComponent {
);
}
if (this.state.item.display_name) {
return <Item data={this.state.item} button={this.state.button} toggleFunction={() => this.toggle()} />;
}
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} />
<Dropdown label={this.language.sort.title} name='sortAddons' onChange={(value) => this.sortAddons(value)}>
<option value='newest'>{this.language.sort.newest}</option>
<option value='oldest'>{this.language.sort.oldest}</option>
<option value='a-z'>{this.language.sort.a_z}</option>
<option value='z-a'>{this.language.sort.z_a}</option>
</Dropdown>
<br/>
<Items items={this.state.installed} toggleFunction={(input) => this.toggle('item', input)} />
</>
);
}

View File

@@ -5,6 +5,7 @@ import LocalMallIcon from '@material-ui/icons/LocalMall';
import Item from '../Item';
import Items from '../Items';
import Dropdown from '../../settings/Dropdown';
import MarketplaceFunctions from '../../../../../modules/helpers/marketplace';
@@ -18,18 +19,7 @@ export default class Marketplace extends React.PureComponent {
button: '',
featured: {},
done: false,
item: {
name: 'Name',
author: 'Author',
description: 'Description',
//updated: '???',
version: '1.0.0',
icon: ''
},
display: {
marketplace: 'block',
item: 'none'
}
item: {}
};
this.buttons = {
uninstall: <button className='removeFromMue' onClick={() => this.manage('uninstall')}>{window.language.modals.main.marketplace.product.buttons.remove}</button>,
@@ -66,7 +56,7 @@ export default class Marketplace extends React.PureComponent {
this.setState({
item: {
type: this.props.type,
type: info.data.type,
display_name: info.data.name,
author: info.data.author,
description: MarketplaceFunctions.urlParser(info.data.description.replace(/\n/g, '<br>')),
@@ -75,18 +65,11 @@ export default class Marketplace extends React.PureComponent {
icon: info.data.screenshot_url,
data: info.data
},
button: button,
display: {
item: 'block',
marketplace: 'none'
}
button: button
});
} else {
this.setState({
display: {
marketplace: 'block',
item: 'none'
}
item: {}
});
}
}
@@ -101,9 +84,12 @@ export default class Marketplace extends React.PureComponent {
this.setState({
items: data[this.props.type],
oldItems: data[this.props.type],
featured: featured.data,
done: true
});
this.sortMarketplace(localStorage.getItem('sortMarketplace'));
}
manage(type) {
@@ -119,6 +105,30 @@ export default class Marketplace extends React.PureComponent {
});
}
sortMarketplace(value) {
let items = this.state.oldItems;
switch (value) {
case 'a-z':
items.sort();
// fix sort not working sometimes
if (this.state.sortType === 'z-a') {
items.reverse();
}
break;
case 'z-a':
items.sort();
items.reverse();
break;
default:
break;
}
this.setState({
items: items,
sortType: value
});
}
componentDidMount() {
if (navigator.onLine === false || localStorage.getItem('offlineMode') === 'true') {
return;
@@ -143,6 +153,16 @@ export default class Marketplace extends React.PureComponent {
);
};
const featured = () => {
return (
<div className='featured' style={{ 'backgroundColor': this.state.featured.colour }}>
<p>{this.state.featured.title}</p>
<h1>{this.state.featured.name}</h1>
<button className='addToMue' onClick={() => window.open(this.state.featured.buttonLink)}>{this.state.featured.buttonText}</button>
</div>
);
}
if (navigator.onLine === false || localStorage.getItem('offlineMode') === 'true') {
return errorMessage(<>
<WifiOffIcon/>
@@ -156,24 +176,32 @@ export default class Marketplace extends React.PureComponent {
}
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 (
<>
{featured()}
{errorMessage(<>
<LocalMallIcon/>
<h1>{window.language.modals.main.addons.empty.title}</h1>
<p className='description'>{this.language.no_items}</p>
</>)}
</>
)
}
if (this.state.item.display_name) {
return <Item data={this.state.item} button={this.state.button} toggleFunction={() => this.toggle()}/>;
}
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} />
{featured()}
<br/>
<Dropdown label={window.language.modals.main.addons.sort.title} name='sortMarketplace' onChange={(value) => this.sortMarketplace(value)}>
<option value='a-z'>{window.language.modals.main.addons.sort.a_z}</option>
<option value='z-a'>{window.language.modals.main.addons.sort.z_a}</option>
</Dropdown>
<br/>
<Items items={this.state.items} toggleFunction={(input) => this.toggle('item', input)} />
</>
);
}

View File

@@ -1,5 +1,3 @@
import React from 'react';
import LocalMallIcon from '@material-ui/icons/LocalMall';
import FileUpload from '../../settings/FileUpload';

View File

@@ -15,7 +15,6 @@
border: none;
opacity: 1;
z-index: -2;
padding: 25px;
transition-timing-function: ease-in;
border-radius: map-get($modal, 'border-radius');
user-select: none;
@@ -28,10 +27,30 @@
}
}
.mainModal {
padding: 25px;
}
.resetLink {
color: var(--modal-link);
cursor: pointer;
&:hover {
opacity: 0.8;
}
span {
font-size: 1.2rem;
color: var(--modal-link);
vertical-align: text-bottom;
margin-left: 5px;
}
}
.modalLink {
color: var(--modal-link);
cursor: pointer;
padding-left: 10px;
margin-left: 5px;
&:hover {
opacity: 0.8;
@@ -70,8 +89,8 @@
}
.ReactModal__Content {
min-height: calc(100vh - 30vh);
max-height: calc(100vh - 10vh);
//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;
@@ -99,12 +118,6 @@
}
}
@media only screen and (min-height: 700px) {
.ReactModal__Content {
min-height: 600px;
}
}
ul.sidebar {
position: absolute;
top: 0;
@@ -253,6 +266,12 @@ li {
}
}
@supports (-webkit-hyphens: none) {
.navbar-item {
display: inline-block !important;
}
}
.modalNavbar {
position: absolute;
left: 20rem;
@@ -262,7 +281,7 @@ li {
svg {
margin-right: 0.5rem;
padding: 3px;
font-size: 1.4em !important;
vertical-align: middle;
}
}
@@ -272,7 +291,7 @@ li {
}
}
@media only screen and (max-width: 1300px) {
@media only screen and (max-width: 1650px) {
li.navbar-item {
span {
display: none;
@@ -291,7 +310,7 @@ li {
background: map-get($theme-colours, 'gradient');
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
svg {
color: orange;
@@ -301,12 +320,13 @@ li {
background: map-get($theme-colours, 'gradient');
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
}
}
::-webkit-scrollbar {
width: 6px;
height: 6px;
border-top-right-radius: map-get($modal, 'border-radius');
border-bottom-right-radius: map-get($modal, 'border-radius');
}
@@ -363,11 +383,19 @@ li {
}
}
.aboutLogo {
height: 100px;
width: auto;
margin-left: -15px;
}
.MuiFormControl-root {
margin-top: 10px !important;
}
label, p {
label,
p,
span.modalLink {
font-size: 1rem;
}

View File

@@ -39,7 +39,7 @@
.addToMue {
@extend %storebutton;
margin-top: 5px;
margin-top: 12px;
}
.sideload {

View File

@@ -1,5 +1,5 @@
#item a {
color: map-get($button-colours, 'other');
color: var(--modal-link);
cursor: pointer;
&:hover {
@@ -16,7 +16,7 @@
.items {
display: inline-grid;
grid-template-columns: repeat(2, 1fr);
grid-template-columns: repeat(6, 1fr);
margin-top: 15px;
.item {
@@ -24,7 +24,7 @@
border-radius: 12px;
height: 80px;
width: 260px;
background: map-get($marketplace, 'item-background');
background: var(--sidebar);
transition: 0.5s;
cursor: pointer;
margin-right: 20px;
@@ -32,8 +32,8 @@
box-shadow: 0 0 6px rgb(0 0 0 / 30%);
img {
height: 100%;
width: auto;
height: 80px;
width: 80px;
border-radius: 12px 0 0 12px;
background: white;
}
@@ -71,8 +71,22 @@
}
}
.dark .items .item {
background: #2d3436;
@media only screen and (max-width: 2100px) {
.items {
grid-template-columns: repeat(3, 1fr);
}
}
@media only screen and (max-width: 1870px) {
.items {
grid-template-columns: repeat(2, 1fr);
}
}
@media only screen and (min-width: 1079px), (max-width: 1869px) {
.items {
grid-template-columns: repeat(3, 1fr);
}
}
p.author {
@@ -80,8 +94,6 @@ p.author {
}
#item {
display: none;
h1 {
font-size: 40px;
line-height: 20px;
@@ -129,7 +141,7 @@ p.description {
.productInformation {
padding: 10px;
background: map-get($marketplace, 'product-information-backgroud');
background: var(--sidebar);
width: 350px;
border-radius: 12px;
@@ -151,14 +163,11 @@ p.description {
}
}
.dark .productInformation {
background: #2d3436;
}
#item>img, .updateimage, .updatechangelog>p>img {
border-radius: 24px;
border-radius: 12px;
height: 200px;
width: auto;
cursor: pointer;
}
.featured {
@@ -167,7 +176,7 @@ p.description {
padding: 50px;
color: #fff;
box-shadow: 0 0 10px rgb(0 0 0 / 30%);
width: 100%;
width: 85%;
button {
float: left;
@@ -185,3 +194,24 @@ p.description {
margin-top: -20px;
}
}
.lightboxmodal {
margin: auto;
max-width: 60%;
background: none !important;
box-shadow: none !important;
img {
height: auto;
width: 100%;
}
.closeModal {
color: #fff;
text-shadow: 0 0 20px rgb(0 0 0 / 30%);
}
}
.overview {
font-size: 30px !important;
}

View File

@@ -81,6 +81,10 @@
border-radius: 15px;
margin-bottom: 10px;
font-size: 1.325rem;
color: var(--modal-text) !important;
cursor: move;
width: 150px;
z-index: 999 !important;
svg {
font-size: 1.3rem;
@@ -90,8 +94,6 @@
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 {

View File

@@ -12,11 +12,27 @@ select {
@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;
background: url("data:image/svg+xml;utf8,<svg fill='black' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path d='M7 10l5 5 5-5z'/><path d='M0 0h24v24H0z' fill='none'/></svg>") right center no-repeat, var(--sidebar) !important;
}
.dark select {
background: url("data:image/svg+xml;utf8,<svg fill='white' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path d='M7 10l5 5 5-5z'/><path d='M0 0h24v24H0z' fill='none'/></svg>") right center no-repeat, var(--sidebar) !important;
}
option {
font: -moz-pull-down-menu !important;
}
}
// safari dropdown
@supports (-webkit-hyphens: none) {
select {
-webkit-appearance: none !important;
background: url("data:image/svg+xml;utf8,<svg fill='black' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path d='M7 10l5 5 5-5z'/><path d='M0 0h24v24H0z' fill='none'/></svg>") right center no-repeat, var(--sidebar) !important;
}
.dark select {
background: url("data:image/svg+xml;utf8,<svg fill='white' height='24' viewBox='0 0 24 24' width='24' xmlns='http://www.w3.org/2000/svg'><path d='M7 10l5 5 5-5z'/><path d='M0 0h24v24H0z' fill='none'/></svg>") right center no-repeat, var(--sidebar) !important;
}
}

View File

@@ -105,6 +105,7 @@ ul {
margin-left: 0;
width: 400px;
height: 200px;
max-width: 60%;
}
.MuiCheckbox-colorPrimary.Mui-checked,
@@ -115,7 +116,6 @@ ul {
.PrivateSwitchBase-input-4,
.MuiRadio-root,
.aboutLink,
.MuiIconButton-root,
legend {
color: var(--modal-text) !important;
}
@@ -161,6 +161,8 @@ legend {
}
.updatechangelog {
max-width: 75%;
li {
cursor: initial;
font-size: 1rem;
@@ -168,4 +170,53 @@ legend {
padding: 0;
margin-left: 20px;
}
a {
color: var(--modal-link);
&:hover {
opacity: 0.8;
}
}
}
.changelogtab {
h1 {
max-width: 85%;
}
img {
max-width: 95%;
}
}
.sliderText {
color: var(--modal-text);
background: none;
border: none;
border-radius: 0;
font-size: 1rem;
}
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
input[type=number] {
-moz-appearance: textfield;
}
.resetArea {
h2 {
font-size: 2rem !important;
}
h2, span, svg {
display: inline;
}
svg {
vertical-align: sub;
font-size: 1.4rem;
}
}

View File

@@ -1,5 +1,3 @@
import React from 'react';
import SettingsFunctions from '../../../../modules/helpers/settings';
export default function ResetModal(props) {
@@ -12,7 +10,7 @@ export default function ResetModal(props) {
return (
<>
<h3 style={{'textAlign': 'center'}}>{language.title}</h3>
<h3 style={{ 'textAlign': 'center' }}>{language.title}</h3>
<h4>{language.question}</h4>
<p>{language.information}</p>
<div className='resetfooter'>

View File

@@ -1,3 +1,4 @@
// todo: find a better method to do width of number input
import React from 'react';
import EventBus from '../../../../modules/helpers/eventbus';
@@ -8,36 +9,63 @@ export default class Slider extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
value: localStorage.getItem(this.props.name) || ''
value: localStorage.getItem(this.props.name) || this.props.default,
numberWidth: localStorage.getItem(this.props.name) ? ((localStorage.getItem(this.props.name).length + 1) * ((this.props.toast === true) ? 7.75 : 7)) : 32
};
this.language = window.language.modals.main.settings;
this.widthCalculation = (this.props.toast === true) ? 7.75 : 7;
}
handleChange = (e) => {
const { value } = e.target;
handleChange = (e, text) => {
let { value } = e.target;
if (text) {
if (value === '') {
return this.setState({
value: 0
});
}
if (Number(value) > this.props.max) {
value = this.props.max;
}
if (Number(value) < this.props.min) {
value = this.props.min;
}
}
localStorage.setItem(this.props.name, value);
this.setState({
value: value
value: value,
numberWidth: ((value.length + 1) * this.widthCalculation)
});
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);
}
resetItem = () => {
localStorage.setItem(this.props.name, this.props.default);
this.setState({
value: this.props.default
this.handleChange({
target: {
value: this.props.default || ''
}
});
toast(window.language.toasts.reset);
EventBus.dispatch('refresh', this.props.category);
}
render() {
const text = <input className='sliderText' type='number' min={this.props.min} max={this.props.max} onChange={(e) => this.handleChange(e, 'text')} value={this.state.value} style={{ width: this.state.numberWidth }}/>;
return (
<>
<p>{this.props.title} ({this.state.value}{this.props.display}) <span className='modalLink' onClick={this.resetItem}>{this.language.buttons.reset}</span></p>
<p>{this.props.title} ({text}{this.props.display}) <span className='modalLink' onClick={this.resetItem}>{this.language.buttons.reset}</span></p>
<input className='range' type='range' min={this.props.min} max={this.props.max} step={this.props.step || 1} value={this.state.value} onChange={this.handleChange} />
</>
);

View File

@@ -37,13 +37,12 @@ export default class Text extends React.PureComponent {
}
resetItem = () => {
localStorage.setItem(this.props.name, this.props.default || '');
this.setState({
value: this.props.default || ''
this.handleChange({
target: {
value: this.props.default || ''
}
});
toast(window.language.toasts.reset);
EventBus.dispatch('refresh', this.props.category);
}
render() {

View File

@@ -4,6 +4,8 @@ import Tooltip from '../../../../helpers/tooltip/Tooltip';
import EmailIcon from '@material-ui/icons/Email';
import TwitterIcon from '@material-ui/icons/Twitter';
import ForumIcon from '@material-ui/icons/Forum';
import InstagramIcon from '@material-ui/icons/Instagram';
import FacebookIcon from '@material-ui/icons/Facebook';
const other_contributors = require('../../../../../modules/other_contributors.json');
@@ -14,7 +16,7 @@ export default class About extends React.PureComponent {
contributors: [],
sponsors: [],
other_contributors: [],
photographers: [],
photographers: window.language.modals.main.loading,
update: window.language.modals.main.settings.sections.about.version.checking_update,
loading: window.language.modals.main.loading
};
@@ -24,20 +26,22 @@ export default class About extends React.PureComponent {
async getGitHubData() {
let contributors, sponsors, photographers, versionData;
try {
versionData = await (await fetch(window.constants.GITHUB_URL + '/repos/mue/mue/releases', { signal: this.controller.signal })).json();
contributors = await (await fetch(window.constants.GITHUB_URL + '/repos/mue/mue/contributors', { signal: this.controller.signal })).json();
sponsors = (await (await fetch(window.constants.SPONSORS_URL + '/list', { signal: this.controller.signal })).json()).sponsors;
photographers = await (await fetch(window.constants.API_URL + '/images/photographers', { signal: this.controller.signal })).json();
versionData = await (await fetch(window.constants.GITHUB_URL + '/repos/mue/mue/releases', { signal: this.controller.signal })).json();
} catch (e) {
if (this.controller.signal.aborted === true) {
return;
}
return this.setState({
update: 'Failed to get update information',
loading: 'An error occurred'
update: this.language.version.error.title,
loading: this.language.version.error.description
});
}
@@ -48,11 +52,10 @@ export default class About extends React.PureComponent {
const newVersion = versionData[0].tag_name;
let updateMsg = this.language.version.no_update;
if (Number(window.constants.VERSION) < newVersion) {
if (Number(window.constants.VERSION.replaceAll('.', '')) < Number(newVersion.replaceAll('.', ''))) {
updateMsg = `${this.language.version.update_available}: ${newVersion}`;
}
this.setState({
contributors: contributors.filter((contributor) => !contributor.login.includes('bot')),
sponsors: sponsors,
@@ -66,7 +69,8 @@ export default class About extends React.PureComponent {
componentDidMount() {
if (navigator.onLine === false || localStorage.getItem('offlineMode') === 'true') {
this.setState({
update: this.language.version.offline_mode
update: this.language.version.offline_mode,
loading: window.language.modals.main.marketplace.offline.description
});
return;
}
@@ -83,23 +87,31 @@ export default class About extends React.PureComponent {
return (
<>
<h2>{this.language.title}</h2>
<img draggable='false' style={{'height': '100px', 'width': 'auto'}} src='./././icons/logo_horizontal.png' alt='Mue logo'></img>
<p>{this.language.copyright} 2018-{new Date().getFullYear()} Mue Tab (BSD-3 License)</p>
<img draggable='false' className='aboutLogo' src='./././icons/logo_horizontal.png' alt='Mue logo'></img>
<p>{this.language.copyright} 2018-{new Date().getFullYear()} <a href='https://github.com/mue/mue/graphs/contributors' className='aboutLink' target='_blank' rel='noopener noreferrer'>The Mue Authors</a> (BSD-3 License)</p>
<p>{this.language.version.title} {window.constants.VERSION} ({this.state.update})</p>
<h3>{this.language.contact_us}</h3>
<a href='mailto:hello@muetab.com' className='aboutIcon' target='_blank' rel='noopener noreferrer'><EmailIcon/></a>
<a href='https://twitter.com/getmue' className='aboutIcon' target='_blank' rel='noopener noreferrer'><TwitterIcon/></a>
<a href='https://instagram.com/mue.tab' className='aboutIcon' target='_blank' rel='noopener noreferrer'><InstagramIcon/></a>
<a href='https://facebook.com/muetab' className='aboutIcon' target='_blank' rel='noopener noreferrer'><FacebookIcon/></a>
<a href='https://discord.gg/zv8C9F8' className='aboutIcon' target='_blank' rel='noopener noreferrer'><ForumIcon/></a>
<h3>{this.language.support_mue}</h3>
<p><a href='https://github.com/sponsors/davidjcralph' className='aboutLink' target='_blank' rel='noopener noreferrer'>GitHub Sponsors</a> <a href='https://ko-fi.com/davidjcralph' className='aboutLink' target='_blank' rel='noopener noreferrer'>Ko-Fi</a> <a href='https://patreon.com/davidjcralph' className='aboutLink' target='_blank' rel='noopener noreferrer'>Patreon</a></p>
<p>
<a href='https://github.com/sponsors/davidjcralph' className='aboutLink' target='_blank' rel='noopener noreferrer'>GitHub Sponsors</a>
&nbsp; &nbsp;<a href='https://ko-fi.com/davidjcralph' className='aboutLink' target='_blank' rel='noopener noreferrer'>Ko-Fi</a>
&nbsp; &nbsp;<a href='https://patreon.com/davidjcralph' className='aboutLink' target='_blank' rel='noopener noreferrer'>Patreon</a>
</p>
<h3>{this.language.resources_used.title}</h3>
<p>Pexels ({this.language.resources_used.bg_images})</p>
<p>Unsplash ({this.language.resources_used.bg_images})</p>
<p>Google ({this.language.resources_used.pin_icon})</p>
<p>Undraw ({this.language.resources_used.welcome_img})</p>
<p>
<a href='https://www.pexels.com' className='aboutLink' target='_blank' rel='noopener noreferrer'>Pexels</a>
, <a href='https://unsplash.com' className='aboutLink' target='_blank' rel='noopener noreferrer'>Unsplash</a> ({this.language.resources_used.bg_images})
</p>
<p><a href='https://fonts.google.com/icons?selected=Material+Icons' className='aboutLink' target='_blank' rel='noopener noreferrer'>Google Fonts</a> ({this.language.resources_used.pin_icon})</p>
<p><a href='https://undraw.co' className='aboutLink' target='_blank' rel='noopener noreferrer'>Undraw</a> ({this.language.resources_used.welcome_img})</p>
<h3>{this.language.contributors}</h3>
<p>{this.state.loading}</p>
@@ -124,7 +136,6 @@ export default class About extends React.PureComponent {
))}
<h3>{this.language.photographers}</h3>
<p>{this.state.loading}</p>
<p>{this.state.photographers}</p>
</>
);

View File

@@ -36,7 +36,7 @@ export default class AdvancedSettings extends React.PureComponent {
return (
<>
<h2>{advanced.title}</h2>
<Checkbox name='offlineMode' text={advanced.offline_mode} />
<Checkbox name='offlineMode' text={advanced.offline_mode} element='.other' />
<h3>{advanced.data}</h3>
<button className='reset' onClick={() => this.setState({ resetModal: true })}>{this.language.buttons.reset}</button>
@@ -46,14 +46,14 @@ export default class AdvancedSettings extends React.PureComponent {
<h3>{advanced.customisation}</h3>
<Text title={advanced.tab_name} name='tabName' default={window.language.tabname} category='other'/>
<Text title={advanced.custom_js} name='customjs' textarea={true} element='.other'/>
<Text title={advanced.custom_css} name='customcss' textarea={true} element='.other'/>
<Text title={advanced.custom_js} name='customjs' textarea={true} category='other' element='other'/>
<Text title={advanced.custom_css} name='customcss' textarea={true} category='other'/>
<h3>{this.language.sections.experimental.title}</h3>
<p style={{ 'maxWidth': '75%'}}>{advanced.experimental_warning}</p>
<Switch name='experimental' text={this.language.enabled} element='.other'/>
<Modal onRequestClose={() => this.setState({ resetModal: false })} isOpen={this.state.resetModal} className='Modal resetmodal' overlayClassName='Overlay resetoverlay' ariaHideApp={false}>
<Modal closeTimeoutMS={100} onRequestClose={() => this.setState({ resetModal: false })} isOpen={this.state.resetModal} className='Modal resetmodal mainModal' overlayClassName='Overlay resetoverlay' ariaHideApp={false}>
<ResetModal modalClose={() => this.setState({ resetModal: false })} />
</Modal>
</>

View File

@@ -1,5 +1,3 @@
import React from 'react';
import { engineName } from 'react-device-detect';
import Checkbox from '../Checkbox';
@@ -13,16 +11,16 @@ export default function AppearanceSettings() {
const themeOptions = [
{
'name': appearance.theme.auto,
'value': 'auto'
name: appearance.theme.auto,
value: 'auto'
},
{
'name': appearance.theme.light,
'value': 'light'
name: appearance.theme.light,
value: 'light'
},
{
'name': appearance.theme.dark,
'value': 'dark'
name: appearance.theme.dark,
value: 'dark'
}
];
@@ -36,10 +34,10 @@ export default function AppearanceSettings() {
<Checkbox name='refresh' text={appearance.navbar.refresh} element='.other' />
<h3>{appearance.font.title}</h3>
<Text title={appearance.font.custom} name='font' upperCaseFirst={true} element='.other' />
<Text title={appearance.font.custom} name='font' upperCaseFirst={true} category='other' />
<br/>
<Checkbox name='fontGoogle' text={appearance.font.google} element='.other' />
<Dropdown label={appearance.font.weight.title} name='fontweight' element='.other'>
<Checkbox name='fontGoogle' text={appearance.font.google} category='other' />
<Dropdown label={appearance.font.weight.title} name='fontweight' category='other'>
{/* names are taken from https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight */}
<option value='100'>{appearance.font.weight.thin}</option>
<option value='200'>{appearance.font.weight.extra_light}</option>
@@ -51,7 +49,7 @@ export default function AppearanceSettings() {
<option value='800'>{appearance.font.weight.extra_bold}</option>
</Dropdown>
<br/><br/>
<Dropdown label={appearance.font.style.title} name='fontstyle' element='.other'>
<Dropdown label={appearance.font.style.title} name='fontstyle' category='other'>
<option value='normal'>{appearance.font.style.normal}</option>
<option value='italic'>{appearance.font.style.italic}</option>
<option value='oblique'>{appearance.font.style.oblique}</option>
@@ -61,7 +59,7 @@ export default function AppearanceSettings() {
{(engineName === 'Blink') ?
<Slider title={appearance.accessibility.widget_zoom} name='widgetzoom' default='100' step='10' min='50' max='200' display='%' category='other'/>
: null}
<Slider title={appearance.accessibility.toast_duration} name='toastDisplayTime' default='2500' step='100' min='500' max='5000' display={' ' + appearance.accessibility.milliseconds} />
<Slider title={appearance.accessibility.toast_duration} name='toastDisplayTime' default='2500' step='100' min='500' max='5000' toast={true} display={' ' + appearance.accessibility.milliseconds} />
</>
);
}

View File

@@ -1,12 +1,18 @@
import React from 'react';
import Modal from 'react-modal';
import Lightbox from '../../marketplace/Lightbox';
import WifiOffIcon from '@material-ui/icons/WifiOff';
export default class Changelog extends React.PureComponent {
constructor() {
super();
this.state = {
title: null
title: null,
showLightbox: false,
lightboxImg: null
};
this.language = window.language.modals.update;
this.controller = new AbortController();
@@ -19,13 +25,40 @@ export default class Changelog extends React.PureComponent {
return;
}
let date = new Date(data.date);
date = date.toLocaleDateString(window.languagecode.replace('_', '-'), {
year: 'numeric',
month: 'long',
day: 'numeric'
});
this.setState({
title: data.title,
date: data.date.split(' ')[0],
date: date,
image: data.featured_image || null,
author: 'By ' + data.authors.join(', '),
html: data.html
});
// lightbox etc
const content = document.querySelector('.tab-content');
const images = content.getElementsByTagName('img');
const links = content.getElementsByTagName('a');
for (const img of images) {
img.draggable = false;
img.onclick = () => {
this.setState({
showLightbox: true,
lightboxImg: img.src
});
};
}
for (let link = 0; link < links.length; link++) {
links[link].target = '_blank';
links[link].rel = 'noopener noreferrer';
}
}
componentDidMount() {
@@ -67,12 +100,15 @@ export default class Changelog extends React.PureComponent {
}
return (
<>
<div className='changelogtab'>
<h1 style={{ 'marginBottom': '-10px' }}>{this.state.title}</h1>
<h5 style={{ 'lineHeight': '0px' }}>{this.state.author} {this.state.date}</h5>
{this.state.image ? <img draggable='false' src={this.state.image} alt={window.language.modals.update.title} className='updateimage'/> : null}
<div className='updatechangelog' dangerouslySetInnerHTML={{ __html: this.state.html }}/>
</>
<Modal closeTimeoutMS={100} onRequestClose={() => this.setState({ showLightbox: false })} isOpen={this.state.showLightbox} className='Modal lightboxmodal' overlayClassName='Overlay resetoverlay' ariaHideApp={false}>
<Lightbox modalClose={() => this.setState({ showLightbox: false })} img={this.state.lightboxImg}/>
</Modal>
</div>
);
}
}

View File

@@ -1,8 +1,5 @@
import React from 'react';
import Checkbox from '../Checkbox';
import Slider from '../Slider';
//import Text from '../Text';
export default function ExperimentalSettings() {
const { experimental } = window.language.modals.main.settings.sections;
@@ -15,15 +12,6 @@ export default function ExperimentalSettings() {
<h3>{experimental.developer}</h3>
<Checkbox name='debug' text='Debug hotkey (Ctrl + #)' element='.other'/>
<Slider title='Debug timeout' name='debugtimeout' min='0' max='5000' default='0' step='100' display=' miliseconds' element='.other' />
{/* <Checkbox name='beta' text='Beta Mode Override'/>
<Text name='api_override' title='Version Override (format example: 5.0)'/>
<Text name='api_override' title='API URL Override'/>
<Text name='marketplace_override' title='Marketplace URL Override'/>
<Text name='unsplash_override' title='Unsplash URL Override'/>
<Text name='sponsors_override' title='Sponsors URL Override'/>
<Text name='github_override' title='GitHub URL Override'/>
<br/><br/>
*/}
<br/><br/>
<button className='reset' style={{'marginLeft': '0px'}} onClick={() => localStorage.clear()}>Clear LocalStorage</button>
</>

View File

@@ -3,6 +3,7 @@ import React from 'react';
import Checkbox from '../Checkbox';
import Switch from '../Switch';
import Text from '../Text';
import Slider from '../Slider';
import DayPickerInput from 'react-day-picker/DayPickerInput';
import 'react-day-picker/lib/style.css';
@@ -22,9 +23,6 @@ export default class GreetingSettings extends React.PureComponent {
this.setState({
birthday: data
});
document.querySelector('.reminder-info').style.display = 'block';
localStorage.setItem('showReminder', true);
}
render() {
@@ -34,13 +32,14 @@ export default class GreetingSettings extends React.PureComponent {
<>
<h2>{greeting.title}</h2>
<Switch name='greeting' text={this.language.enabled} category='greeting' element='.greeting'/>
<Checkbox name='events' text={greeting.events} category='greeting' element='.other'/>
<Checkbox name='defaultGreetingMessage' text={greeting.default} category='greeting' element='.other'/>
<Text title={greeting.name} name='greetingName' category='greeting' element='.other'/>
<Checkbox name='events' text={greeting.events} category='greeting' element='.greeting'/>
<Checkbox name='defaultGreetingMessage' text={greeting.default} category='greeting' element='.greeting'/>
<Text title={greeting.name} name='greetingName' category='greeting' element='.greeting'/>
<Slider title={window.language.modals.main.settings.sections.appearance.accessibility.widget_zoom} name='zoomGreeting' min='10' max='400' default='100' display='%' category='greeting' element='.greeting' />
<h3>{greeting.birthday}</h3>
<Switch name='birthdayenabled' text={this.language.enabled} category='greeting' element='.other'/>
<Checkbox name='birthdayage' text={greeting.birthday_age} category='greeting' element='.other'/>
<Switch name='birthdayenabled' text={this.language.enabled} category='greeting' element='.greeting'/>
<Checkbox name='birthdayage' text={greeting.birthday_age} category='greeting' element='.greeting'/>
<p>{greeting.birthday_date}</p>
<DayPickerInput onDayChange={this.changeDate} value={this.state.birthday}/>
</>

View File

@@ -24,7 +24,7 @@ export default class BackgroundSettings extends React.PureComponent {
}
let array = [];
data.forEach(item => {
data.forEach((item) => {
array.push({
name: item,
value: item
@@ -37,6 +37,15 @@ export default class BackgroundSettings extends React.PureComponent {
}
componentDidMount() {
if (navigator.onLine === false || localStorage.getItem('offlineMode') === 'true') {
return this.setState({
quoteLanguages: [{
name: window.language.modals.main.marketplace.offline.description,
value: 'loading'
}]
});
}
this.getQuoteLanguages();
}

View File

@@ -25,14 +25,14 @@ const widget_name = {
date: settings.time.date.title
};
const SortableItem = sortableElement(({value}) => (
const SortableItem = sortableElement(({ value }) => (
<li className='sortableitem' style={{ display: enabled(value) ? 'block' : 'none' }}>
<DragHandleIcon style={{'verticalAlign': 'middle'}} />
{widget_name[value]}
</li>
));
const SortableContainer = sortableContainer(({children}) => {
const SortableContainer = sortableContainer(({ children }) => {
return <ul className='sortablecontainer'>{children}</ul>;
});
@@ -65,10 +65,10 @@ export default class OrderSettings extends React.PureComponent {
return newArray;
}
onSortEnd = ({oldIndex, newIndex}) => {
this.setState(({items}) => ({
items: this.arrayMove(items, oldIndex, newIndex)
}));
onSortEnd = ({ oldIndex, newIndex }) => {
this.setState({
items: this.arrayMove(this.state.items, oldIndex, newIndex)
});
}
reset = () => {

View File

@@ -1,5 +1,3 @@
import React from 'react';
import Switch from '../Switch';
import Checkbox from '../Checkbox';
@@ -10,6 +8,7 @@ export default function QuickLinks() {
<>
<h2>{language.title}</h2>
<Switch name='quicklinksenabled' text={window.language.modals.main.settings.enabled} category='quicklinks' element='.quicklinks-container' />
<Checkbox name='quicklinksddgProxy' text={window.language.modals.main.settings.sections.background.ddg_proxy} element='.other' />
<Checkbox name='quicklinksnewtab' text={language.open_new} category='quicklinks' />
<Checkbox name='quicklinkstooltip' text={language.tooltip} category='quicklinks' />
</>

View File

@@ -3,22 +3,58 @@ import React from 'react';
import Checkbox from '../Checkbox';
import Text from '../Text';
import Switch from '../Switch';
import Slider from '../Slider';
import Dropdown from '../Dropdown';
export default function QuoteSettings() {
const { quote } = window.language.modals.main.settings.sections;
export default class QuoteSettings extends React.PureComponent {
constructor() {
super();
this.state = {
quoteType: localStorage.getItem('quoteType') || 'api',
};
}
return (
<>
<h2>{quote.title}</h2>
<Switch name='quote' text={window.language.modals.main.settings.enabled} category='quote' element='.quotediv' />
<Checkbox name='authorLink' text={quote.author_link} element='.other' />
<Text title={quote.custom} name='customQuote' element='.other' />
<Text title={quote.custom_author} name='customQuoteAuthor' element='.other'/>
marketplaceType = () => {
if (localStorage.getItem('quote_packs')) {
return <option value='quote_pack'>{window.language.modals.main.navbar.marketplace}</option>;
}
}
<h3>{quote.buttons.title}</h3>
<Checkbox name='copyButton' text={quote.buttons.copy} category='quote'/>
<Checkbox name='tweetButton' text={quote.buttons.tweet} category='quote'/>
<Checkbox name='favouriteQuoteEnabled' text={quote.buttons.favourite} category='quote'/>
</>
);
render() {
const { quote } = window.language.modals.main.settings.sections;
let quoteSettings;
const customSettings = (
<>
<Text title={quote.custom} name='customQuote' category='quote' element='.quotediv' />
<Text title={quote.custom_author} name='customQuoteAuthor' category='quote' element='.quotediv'/>
</>
);
switch (this.state.quoteType) {
case 'custom': quoteSettings = customSettings; break;
default: break;
}
return (
<>
<h2>{quote.title}</h2>
<Switch name='quote' text={window.language.modals.main.settings.enabled} category='quote' element='.quotediv' />
<Checkbox name='authorLink' text={quote.author_link} element='.other' />
<Dropdown label={window.language.modals.main.settings.sections.background.type.title} name='quoteType' onChange={(value) => this.setState({ quoteType: value })} category='quote'>
{this.marketplaceType()}
<option value='api'>{window.language.modals.main.settings.sections.background.type.api}</option>
<option value='custom'>{quote.custom}</option>
</Dropdown>
{quoteSettings}
<Slider title={window.language.modals.main.settings.sections.appearance.accessibility.widget_zoom} name='zoomQuote' min='10' max='400' default='100' display='%' category='quote' element='.quotediv' />
<h3>{quote.buttons.title}</h3>
<Checkbox name='copyButton' text={quote.buttons.copy} category='quote'/>
<Checkbox name='tweetButton' text={quote.buttons.tweet} category='quote'/>
<Checkbox name='favouriteQuoteEnabled' text={quote.buttons.favourite} category='quote'/>
</>
);
}
}

View File

@@ -3,6 +3,7 @@ import React from 'react';
import Dropdown from '../Dropdown';
import Checkbox from '../Checkbox';
import Switch from '../Switch';
import Radio from '../Radio';
import EventBus from '../../../../../modules/helpers/eventbus';
@@ -10,6 +11,7 @@ import { isChrome } from 'react-device-detect';
import { toast } from 'react-toastify';
const searchEngines = require('../../../../widgets/search/search_engines.json');
const autocompleteProviders = require('../../../../widgets/search/autocomplete_providers.json')
export default class SearchSettings extends React.PureComponent {
constructor() {
@@ -75,8 +77,7 @@ export default class SearchSettings extends React.PureComponent {
<>
<h2>{search.title}</h2>
<Switch name='searchBar' text={language.enabled} category='widgets' />
{isChrome ? <Checkbox name='voiceSearch' text={search.voice_search} /> : null}
{isChrome ? <Checkbox name='voiceSearch' text={search.voice_search} category='search' element='.other' /> : null}
<Dropdown label={search.search_engine} name='searchEngine' onChange={(value) => this.setSearchEngine(value)}>
{searchEngines.map((engine) => (
<option key={engine.name} value={engine.settingsName}>{engine.name}</option>
@@ -84,11 +85,14 @@ export default class SearchSettings extends React.PureComponent {
<option value='custom'>{search.custom.split(' ')[0]}</option>
</Dropdown>
<br/><br/>
<ul style={{ display: this.state.customDisplay }}>
<br/>
<p style={{ 'marginTop': '0px' }}>{search.custom} <span className='modalLink' onClick={() => this.resetSearch()}>{language.buttons.reset}</span></p>
<input type='text' value={this.state.customValue} onInput={(e) => this.setState({ customValue: e.target.value })}></input>
</ul>
<br/>
<Checkbox name='autocomplete' text={search.autocomplete} category='search' element='.other'/>
<Radio title={search.autocomplete_provider} options={autocompleteProviders} name='autocompleteProvider' category='search'/>
</>
);
}

View File

@@ -4,6 +4,7 @@ import Checkbox from '../Checkbox';
import Dropdown from '../Dropdown';
import Switch from '../Switch';
import Radio from '../Radio';
import Slider from '../Slider';
export default class TimeSettings extends React.PureComponent {
constructor() {
@@ -22,33 +23,33 @@ export default class TimeSettings extends React.PureComponent {
const digitalOptions = [
{
'name': time.digital.twentyfourhour,
'value': 'twentyfourhour'
name: time.digital.twentyfourhour,
value: 'twentyfourhour'
},
{
'name': time.digital.twelvehour,
'value': 'twelvehour'
name: time.digital.twelvehour,
value: 'twelvehour'
}
];
const digitalSettings = (
<>
<h3>{time.digital.title}</h3>
<Radio title={time.format} name='timeformat' options={digitalOptions} smallTitle={true} category='clock' element='.other' />
<Radio title={time.format} name='timeformat' options={digitalOptions} smallTitle={true} category='clock' element='.clock-container' />
<br/>
<Checkbox name='seconds' text={time.digital.seconds} category='clock' element='.other' />
<Checkbox name='zero' text={time.digital.zero} category='clock' element='.other' />
<Checkbox name='seconds' text={time.digital.seconds} category='clock' element='.clock-container' />
<Checkbox name='zero' text={time.digital.zero} category='clock' element='.clock-container' />
</>
);
const analogSettings = (
<>
<h3>{time.analogue.title}</h3>
<Checkbox name='secondHand' text={time.analogue.second_hand} category='clock' />
<Checkbox name='minuteHand' text={time.analogue.minute_hand} category='clock' />
<Checkbox name='hourHand' text={time.analogue.hour_hand} category='clock' />
<Checkbox name='hourMarks' text={time.analogue.hour_marks} category='clock' />
<Checkbox name='minuteMarks' text={time.analogue.minute_marks} category='clock' />
<Checkbox name='secondHand' text={time.analogue.second_hand} category='clock' element='.clock-container' />
<Checkbox name='minuteHand' text={time.analogue.minute_hand} category='clock' element='.clock-container' />
<Checkbox name='hourHand' text={time.analogue.hour_hand} category='clock' element='.clock-container' />
<Checkbox name='hourMarks' text={time.analogue.hour_marks} category='clock' element='.clock-container' />
<Checkbox name='minuteMarks' text={time.analogue.minute_marks} category='clock' element='.clock-container' />
</>
);
@@ -94,13 +95,16 @@ export default class TimeSettings extends React.PureComponent {
return (
<>
<h2>{time.title}</h2>
<Switch name='time' text={this.language.enabled} category='clock' element='.clock' />
<Dropdown label={time.type} name='timeType' onChange={(value) => this.setState({ timeType: value })} category='clock' element='.other'>
<Switch name='time' text={this.language.enabled} category='clock' element='.clock-container' />
<Dropdown label={time.type} name='timeType' onChange={(value) => this.setState({ timeType: value })} category='clock' element='.clock-container'>
<option value='digital'>{time.digital.title}</option>
<option value='analogue'>{time.analogue.title}</option>
<option value='percentageComplete'>{time.percentage_complete}</option>
</Dropdown>
{timeSettings}
{this.state.timeType !== 'analogue' ?
<Slider title={window.language.modals.main.settings.sections.appearance.accessibility.widget_zoom} name='zoomClock' min='10' max='400' default='100' display='%' category='clock' element='.clock-container' />
: null}
<h3>{time.date.title}</h3>
<Switch name='date' text={this.language.enabled} category='date' element='.date'/>
@@ -112,6 +116,7 @@ export default class TimeSettings extends React.PureComponent {
<Checkbox name='datezero' text={time.digital.zero} category='date' element='.date' />
<Checkbox name='weeknumber' text={time.date.week_number} category='date' element='.date'/>
{dateSettings}
<Slider title={window.language.modals.main.settings.sections.appearance.accessibility.widget_zoom} name='zoomDate' min='10' max='400' default='100' display='%' category='date' element='.date' />
</>
);
}

View File

@@ -3,6 +3,7 @@ import React from 'react';
import Switch from '../Switch';
import Radio from '../Radio';
import Checkbox from '../Checkbox';
import Slider from '../Slider';
export default class TimeSettings extends React.PureComponent {
constructor() {
@@ -26,21 +27,38 @@ export default class TimeSettings extends React.PureComponent {
localStorage.setItem('showReminder', true);
}
getAuto() {
navigator.geolocation.getCurrentPosition(async (position) => {
const data = await (await fetch(`${window.constants.WEATHER_URL}/location?getAuto=true&lat=${position.coords.latitude}&lon=${position.coords.longitude}`)).json();
this.setState({
location: data[0].name
});
document.querySelector('.reminder-info').style.display = 'block';
localStorage.setItem('showReminder', true);
}, (error) => {
// firefox requires this 2nd function
console.log(error);
}, {
enableHighAccuracy: true
});
}
render() {
const language = window.language.modals.main.settings.sections.weather;
const tempFormat = [
{
'name': language.temp_format.celsius + ' (°C)',
'value': 'celsius'
name: language.temp_format.celsius + ' (°C)',
value: 'celsius'
},
{
'name': language.temp_format.fahrenheit + ' (°F)',
'value': 'fahrenheit'
name: language.temp_format.fahrenheit + ' (°F)',
value: 'fahrenheit'
},
{
'name': language.temp_format.kelvin + ' (K)',
'value': 'kelvin'
name: language.temp_format.kelvin + ' (K)',
value: 'kelvin'
}
];
@@ -49,15 +67,21 @@ export default class TimeSettings extends React.PureComponent {
<h2>{language.title}</h2>
<Switch name='weatherEnabled' text={this.language.enabled} category='widgets'/>
<ul>
<p>{language.location}</p>
<p>{language.location} <span className='modalLink' onClick={() => this.getAuto()}>{language.auto}</span></p>
<input type='text' value={this.state.location} onChange={(e) => this.changeLocation(e)}></input>
</ul>
<br/>
<Radio name='tempformat' title={language.temp_format.title} options={tempFormat} category='weather'/>
<Slider title={window.language.modals.main.settings.sections.appearance.accessibility.widget_zoom} name='zoomWeather' min='10' max='400' default='100' display='%' category='weather'/>
<h3>{language.extra_info.title}</h3>
<Checkbox name='showlocation' text={language.extra_info.show_location} category='weather'/>
<Checkbox name='weatherdescription' text={language.extra_info.show_description} category='weather'/>
<Checkbox name='cloudiness' text={language.extra_info.cloudiness} category='weather'/>
<Checkbox name='humidity' text={language.extra_info.humidity} category='weather'/>
<Checkbox name='visibility' text={language.extra_info.visibility} category='weather'/>
<Checkbox name='windspeed' text={language.extra_info.wind_speed} category='weather'/>
<Checkbox name='windDirection' text={language.extra_info.wind_direction} category='weather'/>
<Checkbox name='mintemp' text={language.extra_info.min_temp} category='weather'/>
<Checkbox name='maxtemp' text={language.extra_info.max_temp} category='weather'/>
<Checkbox name='atmosphericpressure' text={language.extra_info.atmospheric_pressure} category='weather'/>

View File

@@ -78,7 +78,9 @@ export default class BackgroundSettings extends React.PureComponent {
componentDidMount() {
if (navigator.onLine === false || localStorage.getItem('offlineMode') === 'true') {
return;
return this.setState({
backgroundCategories: [window.language.modals.update.offline.title]
});
}
this.getBackgroundCategories();
@@ -96,12 +98,16 @@ export default class BackgroundSettings extends React.PureComponent {
const apiOptions = [
{
'name': 'Mue',
'value': 'mue'
name: 'Mue',
value: 'mue'
},
{
'name': 'Unsplash',
'value': 'unsplash'
name: 'Unsplash',
value: 'unsplash'
},
{
name: 'Pexels',
value: 'pexels'
}
];
@@ -115,6 +121,13 @@ export default class BackgroundSettings extends React.PureComponent {
<option value={category} key={category}>{category.charAt(0).toUpperCase() + category.slice(1)}</option>
))}
</Dropdown>
<br/><br/>
<Dropdown label={background.source.quality.title} name='apiQuality' category='background' element='.other'>
<option value='original'>{background.source.quality.original}</option>
<option value='high'>{background.source.quality.high}</option>
<option value='normal'>{background.source.quality.normal}</option>
<option value='datasaver'>{background.source.quality.datasaver}</option>
</Dropdown>
</>
);
@@ -133,7 +146,6 @@ export default class BackgroundSettings extends React.PureComponent {
switch (this.state.backgroundType) {
case 'custom': backgroundSettings = customSettings; break;
case 'colour': backgroundSettings = <ColourSettings/>; break;
// API
default: backgroundSettings = APISettings; break;
}
@@ -143,6 +155,7 @@ export default class BackgroundSettings extends React.PureComponent {
<Switch name='background' text={this.language.enabled} category='background' />
<Checkbox name='ddgProxy' text={background.ddg_proxy} />
<Checkbox name='bgtransition' text={background.transition} />
<Checkbox name='photoInformation' text={background.photo_information} category='background' element='.other' />
<h3>{background.source.title}</h3>
<Dropdown label={background.type.title} name='backgroundType' onChange={(value) => this.setState({ backgroundType: value })} category='background'>
@@ -156,14 +169,22 @@ export default class BackgroundSettings extends React.PureComponent {
{backgroundSettings}
<h3>{background.buttons.title}</h3>
<Checkbox name='view' text={background.buttons.view} />
<Checkbox name='favouriteEnabled' text={background.buttons.favourite} />
<Checkbox name='downloadbtn' text={background.buttons.download}/>
<Checkbox name='view' text={background.buttons.view} element='.other' />
<Checkbox name='favouriteEnabled' text={background.buttons.favourite} element='.other' />
<Checkbox name='downloadbtn' text={background.buttons.download} element='.other' />
<h3>{background.effects.title}</h3>
<Slider title={background.effects.blur} name='blur' min='0' max='100' default='0' display='%' category='background' />
<Slider title={background.effects.brightness} name='brightness' min='0' max='100' default='100' display='%' category='background' />
<Slider title={background.effects.brightness} name='brightness' min='0' max='100' default='90' display='%' category='background' />
<br/><br/>
<Dropdown label={background.effects.filters.title} name='backgroundFilter' category='background'>
<option value='grayscale'>{background.effects.filters.grayscale}</option>
<option value='sepia'>{background.effects.filters.sepia}</option>
<option value='invert'>{background.effects.filters.invert}</option>
<option value='saturate'>{background.effects.filters.saturate}</option>
<option value='contrast'>{background.effects.filters.contrast}</option>
</Dropdown>
<Slider title={background.effects.filters.amount} name='backgroundFilterAmount' min='0' max='100' default='0' display='%' category='background' />
</>
);
}

View File

@@ -11,7 +11,7 @@ import 'react-color-gradient-picker/dist/index.css';
import '../../../scss/settings/react-color-picker-gradient-picker-custom-styles.scss';
export default class ColourSettings extends React.PureComponent {
DefaultGradientSettings = { 'angle': '180', 'gradient': [{ 'colour': '#ffb032', 'stop': 0 }], 'type': 'linear' };
DefaultGradientSettings = { angle: '180', gradient: [{ colour: '#ffb032', stop: 0 }], type: 'linear' };
GradientPickerInitalState = undefined;
constructor() {
@@ -30,7 +30,7 @@ export default class ColourSettings extends React.PureComponent {
toast(window.language.toasts.reset);
}
initialiseColorPickerState(gradientSettings) {
initialiseColourPickerState(gradientSettings) {
this.GradientPickerInitalState = {
points: gradientSettings.gradient.map((g) => {
const rgb = hexToRgb(g.colour);
@@ -84,6 +84,12 @@ export default class ColourSettings extends React.PureComponent {
};
return newState;
});
const reminderInfo = document.querySelector('.reminder-info');
if (reminderInfo.style.display !== 'block') {
reminderInfo.style.display = 'block';
localStorage.setItem('showReminder', true);
}
}
addColour = () => {
@@ -92,7 +98,7 @@ export default class ColourSettings extends React.PureComponent {
const newState = {
gradientSettings: {
...s.gradientSettings,
gradient: [...initGradients, lastGradient, { 'colour': localStorage.getItem('theme') === 'dark' ? '#000000' : '#ffffff', stop: 100 }].sort((a, b) => (a.stop > b.stop) ? 1 : -1)
gradient: [...initGradients, lastGradient, { colour: localStorage.getItem('theme') === 'dark' ? '#000000' : '#ffffff', stop: 100 }].sort((a, b) => (a.stop > b.stop) ? 1 : -1)
}
};
return newState;
@@ -110,22 +116,28 @@ export default class ColourSettings extends React.PureComponent {
return this.language.sections.background.source.disabled;
}
onColorPickerChange = (attrs, name) => {
onColourPickerChange = (attrs, name) => {
if (process.env.NODE_ENV === 'development') {
console.log(attrs, name);
}
this.setState({
gradientSettings: {
'angle': attrs.degree,
'gradient': attrs.points.map((p) => {
angle: attrs.degree,
gradient: attrs.points.map((p) => {
return {
'colour': '#' + rgbToHex(p.red, p.green, p.blue),
'stop': p.left
colour: '#' + rgbToHex(p.red, p.green, p.blue),
stop: p.left
}}),
'type': attrs.type
type: attrs.type
}
});
const reminderInfo = document.querySelector('.reminder-info');
if (reminderInfo.style.display !== 'block') {
reminderInfo.style.display = 'block';
localStorage.setItem('showReminder', true);
}
};
render() {
@@ -138,14 +150,14 @@ export default class ColourSettings extends React.PureComponent {
let gradientInputs;
if (gradientHasMoreThanOneColour) {
if (this.GradientPickerInitalState === undefined) {
this.initialiseColorPickerState(this.state.gradientSettings);
this.initialiseColourPickerState(this.state.gradientSettings);
}
gradientInputs = (
<ColorPicker
onStartChange={(color) => this.onColorPickerChange(color, 'start')}
onChange={(color) => this.onColorPickerChange(color, 'change')}
onEndChange={(color) => this.onColorPickerChange(color, 'end')}
onStartChange={(colour) => this.onColourPickerChange(colour, 'start')}
onChange={(colour) => this.onColourPickerChange(colour, 'change')}
onEndChange={(colour) => this.onColourPickerChange(colour, 'end')}
gradient={this.GradientPickerInitalState}
isGradient/>
);
@@ -176,4 +188,4 @@ export default class ColourSettings extends React.PureComponent {
</>
);
}
}
}

View File

@@ -1,5 +1,3 @@
import React from 'react';
import Added from '../marketplace/sections/Added';
import Sideload from '../marketplace/sections/Sideload';

View File

@@ -1,5 +1,3 @@
import React from 'react';
import MarketplaceTab from '../marketplace/sections/Marketplace';
import Tabs from './backend/Tabs';
@@ -11,6 +9,7 @@ export default function Marketplace() {
<Tabs>
<div label={marketplace.photo_packs}><MarketplaceTab type='photo_packs'/></div>
<div label={marketplace.quote_packs}><MarketplaceTab type='quote_packs'/></div>
<div label={marketplace.preset_settings}><MarketplaceTab type='preset_settings'/></div>
</Tabs>
);
}

View File

@@ -1,5 +1,3 @@
import React from 'react';
import About from '../settings/sections/About';
import Language from '../settings/sections/Language';
import Search from '../settings/sections/Search';

View File

@@ -39,7 +39,7 @@ function Tab(props) {
}
const settings = window.language.modals.main.settings.sections;
const { navbar, marketplace, addons }= window.language.modals.main;
const { navbar, marketplace, addons } = window.language.modals.main;
let icon, divider;
switch (props.label) {
@@ -67,6 +67,7 @@ function Tab(props) {
// Store
case marketplace.photo_packs: icon = <Background/>; break;
case marketplace.quote_packs: icon = <Quote/>; break;
case marketplace.preset_settings: icon = <Advanced/>; break;
case addons.added: icon = <Added/>; break;
case addons.sideload: icon = <Sideload/>; break;

View File

@@ -1,5 +1,3 @@
import React from 'react';
import EmailIcon from '@material-ui/icons/Email';
import TwitterIcon from '@material-ui/icons/Twitter';
import ForumIcon from '@material-ui/icons/Forum';

View File

@@ -51,6 +51,7 @@ export default class Widgets extends React.PureComponent {
elements.push(<React.Fragment key={element}>{this.widgets[element]}</React.Fragment>);
});
} else {
// prevent error
elements = ['greeting', 'time', 'quicklinks', 'quote', 'date'];
}

View File

@@ -15,7 +15,10 @@ export default class Background extends React.PureComponent {
url: '',
currentAPI: '',
photoInfo: {
hidden: false
hidden: false,
offline: false,
photographerURL: '',
photoURL: ''
}
};
this.language = window.language.widgets.background;
@@ -55,6 +58,7 @@ export default class Background extends React.PureComponent {
this.setState({
url: `./offline-images/${randomImage}.webp`,
photoInfo: {
offline: true,
credit: photographer
}
});
@@ -64,9 +68,10 @@ export default class Background extends React.PureComponent {
const backgroundImage = document.getElementById('backgroundImage');
if (this.state.url !== '') {
const url = (localStorage.getItem('ddgProxy') === 'true') ? window.constants.DDG_PROXY + this.state.url : this.state.url;
const url = (localStorage.getItem('ddgProxy') === 'true' && this.state.photoInfo.offline !== true) ? window.constants.DDG_PROXY + this.state.url : this.state.url;
const photoInformation = document.querySelector('.photoInformation');
// just set the background
if (localStorage.getItem('bgtransition') === 'false') {
if (photoInformation) {
photoInformation.style.display = 'block';
@@ -75,15 +80,17 @@ export default class Background extends React.PureComponent {
return backgroundImage.style.background = `url(${url})`;
}
// firstly we set the background as hidden and make sure there is no background set currently
backgroundImage.classList.add('backgroundPreload');
backgroundImage.style.background = null;
// same with photo information if not using custom background
if (photoInformation) {
photoInformation.classList.add('backgroundPreload');
}
// preloader for background transition
let preloader = document.createElement('img');
// preloader for background transition, required so it loads in nice
const preloader = document.createElement('img');
preloader.src = url;
// once image has loaded, add the fade-in transition
@@ -91,7 +98,9 @@ export default class Background extends React.PureComponent {
backgroundImage.classList.remove('backgroundPreload');
backgroundImage.classList.add('fade-in');
backgroundImage.style.background = `url(${url})`;
// this doesn't make it fetch again which is nice
backgroundImage.style.background = `url(${url})`;
// remove the preloader element we created earlier
preloader.remove();
if (photoInformation) {
@@ -100,6 +109,7 @@ export default class Background extends React.PureComponent {
}
});
} else {
// custom colour
backgroundImage.setAttribute('style', this.state.style);
}
}
@@ -120,7 +130,10 @@ export default class Background extends React.PureComponent {
return this.setState({
url: favourited.url,
photoInfo: {
credit: favourited.credit
credit: favourited.credit,
location: favourited.location,
camera: favourited.camera,
resolution: favourited.resolution
}
});
}
@@ -128,16 +141,20 @@ export default class Background extends React.PureComponent {
// API background
const backgroundAPI = localStorage.getItem('backgroundAPI');
const apiCategory = localStorage.getItem('apiCategory');
const apiQuality = localStorage.getItem('apiQuality');
let requestURL, data;
switch (backgroundAPI) {
case 'unsplash':
//requestURL = `${window.constants.UNSPLASH_URL}/getImage?category=${apiCategory}`;
requestURL = `${window.constants.UNSPLASH_URL}/getImage`;
requestURL = `${window.constants.UNSPLASH_URL}/images/random?quality=${apiQuality}`;
break;
case 'pexels':
requestURL = `${window.constants.PEXELS_URL}/images/random?quality=${apiQuality}`;
break;
// Defaults to Mue
default:
requestURL = `${window.constants.API_URL}/images/random?category=${apiCategory}`;
requestURL = `${window.constants.API_URL}/images/random?category=${apiCategory}&quality=${apiQuality}`;
break;
}
@@ -148,17 +165,33 @@ export default class Background extends React.PureComponent {
return this.offlineBackground();
}
let credit = data.photographer;
let photoURL = '';
let photographerURL = '';
if (backgroundAPI === 'unsplash') {
credit = data.photographer + ` ${this.language.unsplash}`;
photoURL = data.photo_page;
photographerURL = data.photographer_page;
} else if (backgroundAPI === 'pexels') {
credit = data.photographer + ` ${this.language.pexels}`;
photoURL = data.photo_page;
photographerURL = data.photographer_page;
}
this.setState({
url: data.file,
type: 'api',
currentAPI: backgroundAPI,
photoInfo: {
hidden: false,
credit: (backgroundAPI !== 'unsplash') ? data.photographer : data.photographer + ` ${this.language.unsplash}`,
location: (data.location.replace(/[null]+/g, '') !== ' ') ? data.location : 'N/A',
credit: credit,
location: data.location,
camera: data.camera,
resolution: data.resolution,
url: data.file
url: data.file,
photographerURL: photographerURL,
photoURL: photoURL
}
});
break;
@@ -213,9 +246,11 @@ export default class Background extends React.PureComponent {
const randomPhoto = photoPack[Math.floor(Math.random() * photoPack.length)];
return this.setState({
url: randomPhoto.url.default,
type: 'photo_pack',
photoInfo: {
hidden: false,
credit: randomPhoto.photographer
credit: randomPhoto.photographer,
location: randomPhoto.location || 'N/A'
}
});
}
@@ -228,11 +263,13 @@ export default class Background extends React.PureComponent {
componentDidMount() {
const element = document.getElementById('backgroundImage');
// this resets it so the fade in and getting background all works properly
const refresh = () => {
element.classList.remove('fade-in');
this.setState({
url: '',
style: '',
type: '',
video: false,
photoInfo: {
hidden: true
@@ -244,40 +281,53 @@ export default class Background extends React.PureComponent {
EventBus.on('refresh', (data) => {
if (data === 'background') {
if (localStorage.getItem('background') === 'false') {
// user is using custom colour or image
if (this.state.photoInfo.hidden === false) {
document.querySelector('.photoInformation').style.display = 'none';
}
// video backgrounds
if (this.state.video === true) {
return document.getElementById('backgroundVideo').style.display = 'none';
} else {
return element.style.display = 'none';
}
}
// video backgrounds
if (this.state.video === true) {
document.getElementById('backgroundVideo').style.display = 'block';
} else {
if (this.state.photoInfo.hidden === false) {
// fix bug
try {
document.querySelector('.photoInformation').style.display = 'block';
} catch (e) {}
}
element.style.display = 'block';
}
const backgroundType = localStorage.getItem('backgroundType');
// todo: make this good
if (backgroundType !== this.state.type
|| (localStorage.getItem('backgroundAPI') !== this.state.currentAPI && backgroundType === 'api')
|| (backgroundType === 'custom' && localStorage.getItem('customBackground') !== this.state.url)
) {
return refresh();
if (this.state.photoInfo.offline !== true) {
// basically check to make sure something has changed before we try getting another background
if (backgroundType !== this.state.type || (this.state.type === 'api' && localStorage.getItem('backgroundAPI') !== this.state.currentAPI) || (this.state.type === 'custom' && localStorage.getItem('customBackground') !== this.state.url)) {
return refresh();
}
}
// background effects so we don't get another image again
const backgroundFilter = localStorage.getItem('backgroundFilter');
if (this.state.video === true) {
document.getElementById('backgroundVideo').style.webkitFilter = `blur(${localStorage.getItem('blur')}px) brightness(${localStorage.getItem('brightness')}%)`;
document.getElementById('backgroundVideo').style.webkitFilter = `blur(${localStorage.getItem('blur')}px) brightness(${localStorage.getItem('brightness')}%) ${backgroundFilter ? backgroundFilter + '(' + localStorage.getItem('backgroundFilterAmount') + '%)' : ''}`;
} else {
element.style.webkitFilter = `blur(${localStorage.getItem('blur')}px) brightness(${localStorage.getItem('brightness')}%)`;
element.style.webkitFilter = `blur(${localStorage.getItem('blur')}px) brightness(${localStorage.getItem('brightness')}%) ${backgroundFilter ? backgroundFilter + '(' + localStorage.getItem('backgroundFilterAmount') + '%)' : ''}`;
}
}
// uninstall photo pack reverts your background to what you had previously
if (data === 'marketplacebackgrounduninstall') {
refresh();
}
@@ -308,11 +358,13 @@ export default class Background extends React.PureComponent {
);
}
const backgroundFilter = localStorage.getItem('backgroundFilter');
return (
<>
<div style={{ 'WebkitFilter': `blur(${localStorage.getItem('blur')}px) brightness(${localStorage.getItem('brightness')}%)` }} id='backgroundImage'/>
<div style={{ 'WebkitFilter': `blur(${localStorage.getItem('blur')}px) brightness(${localStorage.getItem('brightness')}%) ${backgroundFilter ? backgroundFilter + '(' + localStorage.getItem('backgroundFilterAmount') + '%)' : ''}` }} id='backgroundImage'/>
{(this.state.photoInfo.credit !== '') ?
<PhotoInformation className={this.props.photoInformationClass} info={this.state.photoInfo}/>
<PhotoInformation className={this.props.photoInformationClass} info={this.state.photoInfo} api={this.state.currentAPI}/>
: null}
</>
);

View File

@@ -21,9 +21,18 @@ export default class Favourite extends React.PureComponent {
});
} else {
const url = document.getElementById('backgroundImage').style.backgroundImage.replace('url("', '').replace('")', '');
const credit = document.getElementById('credit').textContent;
localStorage.setItem('favourite', JSON.stringify({ url: url, credit: credit }));
if (!url) {
return;
}
localStorage.setItem('favourite', JSON.stringify({
url: url,
credit: document.getElementById('credit').textContent,
location: document.getElementById('infoLocation').textContent,
camera: document.getElementById('infoCamera').textContent,
resolution: document.getElementById('infoResolution').textContent
}));
this.setState({
favourited: <StarIcon onClick={this.favourite} className='topicons' />

View File

@@ -12,11 +12,17 @@ export default class Maximise extends React.PureComponent {
};
}
setAttribute(blur, brightness) {
setAttribute(blur, brightness, filter) {
const element = document.getElementById('backgroundImage');
let backgroundFilter;
if (filter === true) {
backgroundFilter = localStorage.getItem('backgroundFilter');
}
element.setAttribute(
'style',
`background-image: url(${element.style.backgroundImage.replace('url("', '').replace('")', '')}); -webkit-filter: blur(${blur}px) brightness(${brightness}%);`
`background-image: url(${element.style.backgroundImage.replace('url("', '').replace('")', '')}); -webkit-filter: blur(${blur}px) brightness(${brightness}%) ${backgroundFilter ? backgroundFilter + '(' + localStorage.getItem('backgroundFilterAmount') + '%)' : ''};`
);
}
@@ -43,7 +49,7 @@ export default class Maximise extends React.PureComponent {
hidden: false
});
this.setAttribute(localStorage.getItem('blur'), localStorage.getItem('brightness'));
this.setAttribute(localStorage.getItem('blur'), localStorage.getItem('brightness'), true);
}
}

View File

@@ -1,5 +1,3 @@
import React from 'react';
import Info from '@material-ui/icons/Info';
import Location from '@material-ui/icons/LocationOn';
import Camera from '@material-ui/icons/PhotoCamera';
@@ -29,28 +27,46 @@ export default function PhotoInformation(props) {
return null;
}
// remove unsplash and pexels text
const photographer = props.info.credit.split(` ${language.unsplash}`)[0].split(` ${language.pexels}`);
let credit = props.info.credit;
let photo = language.credit;
// unsplash and pexels credit
if (props.info.photographerURL && props.info.photographerURL !== '' && !props.info.offline && props.api) {
if (props.api === 'unsplash') {
photo = <a href={props.info.photoURL + '?utm_source=mue'} target='_blank' rel='noopener noreferrer'>{language.credit}</a>;
credit = <><a href={props.info.photographerURL} target='_blank' rel='noopener noreferrer'>{photographer}</a> <a href='https://unsplash.com?utm_source=mue' target='_blank' rel='noopener noreferrer'>{language.unsplash}</a></>;
} else {
photo = <a href={props.info.photoURL} target='_blank' rel='noopener noreferrer'>{language.credit}</a>;
credit = <><a href={props.info.photographerURL} target='_blank' rel='noopener noreferrer'>{photographer}</a> <a href='https://pexels.com' target='_blank' rel='noopener noreferrer'>{language.pexels}</a></>;
}
}
return (
<div className='photoInformation'>
<h1>{language.credit} <span id='credit'>{props.info.credit}</span></h1>
<Info className='photoInformationHover'/>
<div className={props.className || 'infoCard'}>
<Info className='infoIcon'/>
<h1>{language.information}</h1>
<hr/>
<Location/>
<span>{props.info.location || 'N/A'}</span>
<Camera/>
<span>{props.info.camera || 'N/A'}</span>
<Resolution/>
<span>{props.info.resolution || 'N/A'}</span>
<Photographer/>
<span>{props.info.credit.split(` ${language.unsplash}`)[0]}</span>
{(localStorage.getItem('downloadbtn') === 'true') ?
<>
<Download/>
<span className='download' onClick={() => downloadImage(props.info)}>{language.download}</span>
</> : null}
</div>
<h1>{photo} <span id='credit'>{credit}</span></h1>
{localStorage.getItem('photoInformation') !== 'false' ? <><Info className='photoInformationHover'/>
<div className={props.className || 'infoCard'}>
<Info className='infoIcon'/>
<h1>{language.information}</h1>
<hr/>
<Location/>
<span id='infoLocation'>{props.info.location || 'N/A'}</span>
<Camera/>
<span id='infoCamera'>{props.info.camera || 'N/A'}</span>
<Resolution/>
<span id='infoResolution'>{props.info.resolution || 'N/A'}</span>
<Photographer/>
<span>{photographer}</span>
{(localStorage.getItem('downloadbtn') === 'true') && !props.info.offline && !props.info.photographerURL ?
<>
<Download/>
<span className='download' onClick={() => downloadImage(props.info)}>{language.download}</span>
</> : null}
</div>
</>: null}
</div>
);
}

View File

@@ -23,6 +23,15 @@
svg:hover+.infoCard {
display: block;
}
a {
color: white;
text-decoration: none;
&:hover {
text-decoration: underline;
}
}
}
.infoCard {

View File

@@ -110,10 +110,18 @@ export default class Greeting extends React.PureComponent {
return element.style.display = 'none';
}
this.timer = null;
this.getGreeting(0);
element.style.display = 'block';
element.style.fontSize = `${1.6 * Number(localStorage.getItem('zoomGreeting') / 100)}em`;
}
});
// this comment can apply to all widget zoom features apart from the general one in the Accessibility section
// in a nutshell: 1.6 is the current font size and we do "localstorage || 100" so we don't have to try that 4.0 -> 5.0 thing again
document.querySelector('.greeting').style.fontSize = `${1.6 * Number((localStorage.getItem('zoomGreeting') || 100) / 100)}em`;
this.getGreeting(0);
}

View File

@@ -13,35 +13,33 @@ import Tooltip from '../../helpers/tooltip/Tooltip';
import './scss/index.scss';
export default function Navbar(props) {
const language = window.language;
const backgroundEnabled = (localStorage.getItem('background') === 'true');
return (
<div className='navbar-container'>
{(localStorage.getItem('view') === 'true' && backgroundEnabled) ? <Maximise/> :null}
{(localStorage.getItem('favouriteEnabled') === 'true' && backgroundEnabled) ? <Favourite/> :null}
{(localStorage.getItem('view') === 'true' && backgroundEnabled) ? <Maximise/> : null}
{(localStorage.getItem('favouriteEnabled') === 'true' && backgroundEnabled) ? <Favourite/> : null}
{(localStorage.getItem('notesEnabled') === 'true') ?
<div className='notes'>
<NotesIcon className='topicons'/>
<Notes/>
</div>
:null}
: null}
{(window.constants.BETA_VERSION === true) ?
<Tooltip title={language.widgets.navbar.tooltips.feedback}>
<Tooltip title={window.language.widgets.navbar.tooltips.feedback}>
<Report className='topicons' onClick={() => props.openModal('feedbackModal')}/>
</Tooltip>
:null}
: null}
{(localStorage.getItem('refresh') === 'true') ?
<Tooltip title={language.widgets.navbar.tooltips.refresh}>
<Tooltip title={window.language.widgets.navbar.tooltips.refresh}>
<RefreshIcon className='refreshicon topicons' onClick={() => window.location.reload()}/>
</Tooltip>
:null}
: null}
<Tooltip title={language.modals.main.navbar.settings}>
<Tooltip title={window.language.modals.main.navbar.settings}>
<Gear className='settings-icon topicons' onClick={() => props.openModal('mainModal')}/>
</Tooltip>
</div>

View File

@@ -1,6 +1,7 @@
import React from 'react';
import TextareaAutosize from '@material-ui/core/TextareaAutosize';
import CopyIcon from '@material-ui/icons/FileCopyRounded';
import NotesIcon from '@material-ui/icons/AssignmentRounded';
import Pin from './Pin';

View File

@@ -14,8 +14,6 @@
See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
export default function Pin() {
return (
<svg xmlns='http://www.w3.org/2000/svg' enableBackground='new 0 0 24 24' viewBox='0 0 24 24' fill='black' width='18px' height='18px'>

View File

@@ -7,6 +7,10 @@
cursor: initial;
user-select: none;
}
&:hover .notescontainer {
visibility: visible;
}
}
.notescontainer {
@@ -30,10 +34,6 @@
}
}
.notes:hover .notescontainer {
visibility: visible;
}
textarea {
border: none;
resize: none;

View File

@@ -39,11 +39,13 @@ export default class QuickLinks extends React.PureComponent {
let nameError, urlError;
if (this.state.name.length <= 0) {
nameError = 'Must provide name';
nameError = this.language.name_error;
}
if (url.length <= 0) {
urlError = 'Must provide URL';
// regex: https://ihateregex.io/expr/url/
// eslint-disable-next-line no-useless-escape
if (url.length <= 0 || /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()!@:%_\+.~#?&\/\/=]*)/.test(url) === false) {
urlError = this.language.url_error;
}
if (nameError || urlError) {
@@ -102,9 +104,10 @@ export default class QuickLinks extends React.PureComponent {
}
});
// allows you to add a link by pressing enter
document.querySelector('.topbarquicklinks').onkeydown = (e) => {
e = e || window.event;
let code = e.which || e.keyCode;
const code = e.which || e.keyCode;
if (code === 13 && this.state.showAddLink === 'visible') {
this.addLink();
e.preventDefault();
@@ -122,9 +125,12 @@ export default class QuickLinks extends React.PureComponent {
const tooltipEnabled = localStorage.getItem('quicklinkstooltip');
const quickLink = (item) => {
const useProxy = (localStorage.getItem('quicklinksddgProxy') !== 'false');
const url = useProxy ? 'https://icons.duckduckgo.com/ip2/' : 'https://www.google.com/s2/favicons?sz=32&domain=';
const link = (
<a key={item.key} onContextMenu={(e) => this.deleteLink(item.key, e)} href={item.url} target={target} rel={rel} draggable={false}>
<img src={'https://icons.duckduckgo.com/ip2/' + item.url.replace('https://', '').replace('http://', '') + '.ico'} alt={item.name} draggable={false}/>
<img src={url + item.url.replace('https://', '').replace('http://', '') + (useProxy ? '.ico' : '')} alt={item.name} draggable={false}/>
</a>
);

View File

@@ -11,7 +11,6 @@ import { toast } from 'react-toastify';
import './quote.scss';
export default class Quote extends React.PureComponent {
constructor() {
super();
@@ -32,93 +31,121 @@ export default class Quote extends React.PureComponent {
doOffline() {
const quotes = require('./offline_quotes.json');
// Get a random quote from our local package
const quote = quotes[Math.floor(Math.random() * quotes.length)];
// Set the quote
this.setState({
quote: '"' + quote.quote + '"',
author: quote.author
author: quote.author,
authorlink: this.getAuthorLink(quote.author)
});
}
getQuotePack() {
let quotePack = localStorage.getItem('quote_packs');
if (quotePack === 'undefined') {
return this.doOffline();
getAuthorLink(author) {
let authorlink = `https://${window.languagecode.split('_')[0]}.wikipedia.org/wiki/${author.split(' ').join('_')}`;
if (localStorage.getItem('authorLink') === 'false' || author === 'Unknown') {
authorlink = null;
}
quotePack = JSON.parse(quotePack);
if (quotePack) {
const data = quotePack[Math.floor(Math.random() * quotePack.length)];
return this.setState({
quote: '"' + data.quote + '"',
author: data.author
});
} else {
this.doOffline();
}
return authorlink;
}
async getQuote() {
const offline = (localStorage.getItem('offlineMode') === 'true');
const favouriteQuote = localStorage.getItem('favouriteQuote');
if (favouriteQuote) {
return this.setState({
quote: favouriteQuote.split(' - ')[0],
author: favouriteQuote.split(' - ')[1]
author: favouriteQuote.split(' - ')[1],
authorlink: this.getAuthorLink(favouriteQuote.split(' - ')[1])
});
}
const customQuote = localStorage.getItem('customQuote');
if (customQuote) {
return this.setState({
quote: '"' + customQuote + '"',
author: localStorage.getItem('customQuoteAuthor')
});
}
switch (localStorage.getItem('quoteType') || 'api') {
case 'custom':
const customQuote = localStorage.getItem('customQuote');
const customQuoteAuthor = localStorage.getItem('customQuoteAuthor');
if (localStorage.getItem('offlineMode') === 'true') {
return this.doOffline();
}
if (customQuote) {
return this.setState({
quote: '"' + customQuote + '"',
author: customQuoteAuthor,
authorlink: this.getAuthorLink(customQuote),
type: 'custom'
});
}
break;
case 'quote_pack':
if (offline) {
return this.doOffline();
}
const quotePackAPI = JSON.parse(localStorage.getItem('quoteAPI'));
if (quotePackAPI) {
try {
const data = await (await fetch(quotePackAPI.url)).json();
return this.setState({
quote: '"' + data.quote + '"',
author: quotePackAPI.author || data.author
});
} catch (e) {
return this.getQuotePack();
}
}
const quotePackAPI = JSON.parse(localStorage.getItem('quoteAPI'));
if (quotePackAPI) {
try {
const data = await (await fetch(quotePackAPI.url)).json();
const author = data[quotePackAPI.author] || quotePackAPI.author;
// First we try and get a quote from the API...
try {
const quotelanguage = localStorage.getItem('quotelanguage');
const data = await (await fetch(window.constants.API_URL + '/quotes/random?language=' + quotelanguage)).json();
return this.setState({
quote: '"' + data[quotePackAPI.quote] + '"',
author: author,
authorlink: this.getAuthorLink(author),
type: 'quote_pack'
});
} catch (e) {
return this.doOffline();
}
}
let quotePack = localStorage.getItem('quote_packs');
if (quotePack !== null) {
quotePack = JSON.parse(quotePack);
if (quotePack) {
const data = quotePack[Math.floor(Math.random() * quotePack.length)];
return this.setState({
quote: '"' + data.quote + '"',
author: data.author,
authorlink: this.getAuthorLink(data.author),
type: 'quote_pack'
});
} else {
return this.doOffline();
}
}
break;
case 'api':
if (offline) {
return this.doOffline();
}
// If we hit the ratelimit, we fallback to local quotes
if (data.statusCode === 429) {
return this.doOffline();
}
// First we try and get a quote from the API...
try {
const quotelanguage = localStorage.getItem('quotelanguage');
const data = await (await fetch(window.constants.API_URL + '/quotes/random?language=' + quotelanguage)).json();
let authorlink = `https://${window.languagecode.split('_')[0]}.wikipedia.org/wiki/${data.author.split(' ').join('_')}`;
if (localStorage.getItem('authorLink') === 'false' || data.author === 'Unknown') {
authorlink = null;
}
// If we hit the ratelimit, we fallback to local quotes
if (data.statusCode === 429) {
return this.doOffline();
}
this.setState({
quote: '"' + data.quote + '"',
author: data.author,
authorlink: authorlink,
quoteLanguage: quotelanguage
});
} catch (e) {
// ..and if that fails we load one locally
this.doOffline();
this.setState({
quote: '"' + data.quote + '"',
author: data.author,
authorlink: this.getAuthorLink(data.author),
quoteLanguage: quotelanguage,
type: 'api'
});
} catch (e) {
// ..and if that fails we load one locally
this.doOffline();
}
break;
default:
break;
}
}
@@ -157,7 +184,10 @@ export default class Quote extends React.PureComponent {
tweet: (localStorage.getItem('tweetButton') === 'false') ? null : this.buttons.tweet
});
if (!this.state.quote || localStorage.getItem('quotelanguage') !== this.state.quoteLanguage) {
const quoteType = localStorage.getItem('quoteType');
if (this.state.type !== quoteType || localStorage.getItem('quotelanguage') !== this.state.quoteLanguage || (quoteType === 'custom' && this.state.quote !== localStorage.getItem('customQuote'))
|| (quoteType === 'custom' && this.state.author !== localStorage.getItem('customQuoteAuthor'))) {
this.getQuote();
}
}
@@ -172,10 +202,20 @@ export default class Quote extends React.PureComponent {
}
element.style.display = 'block';
document.querySelector('.quote').style.fontSize = `${0.8 * Number((localStorage.getItem('zoomQuote') || 100) / 100)}em`;
document.querySelector('.quoteauthor').style.fontSize = `${0.9 * Number((localStorage.getItem('zoomQuote') || 100) / 100)}em`;
this.init();
}
// uninstall quote pack reverts the quote to what you had previously
if (data === 'marketplacequoteuninstall') {
this.init();
}
});
document.querySelector('.quote').style.fontSize = `${0.8 * Number((localStorage.getItem('zoomQuote') || 100) / 100)}em`;
document.querySelector('.quoteauthor').style.fontSize = `${0.9 * Number((localStorage.getItem('zoomQuote') || 100) / 100)}em`;
this.init();
}

View File

@@ -1,6 +1,9 @@
import React from 'react';
import EventBus from '../../../modules/helpers/eventbus';
import fetchJSONP from 'fetch-jsonp';
import AutocompleteInput from '../../helpers/autocomplete/Autocomplete';
import SearchIcon from '@material-ui/icons/Search';
import MicIcon from '@material-ui/icons/Mic';
@@ -8,6 +11,7 @@ import MicIcon from '@material-ui/icons/Mic';
import './search.scss';
const searchEngines = require('./search_engines.json');
const autocompleteProviders = require('./autocomplete_providers.json');
export default class Search extends React.PureComponent {
constructor() {
@@ -15,7 +19,11 @@ export default class Search extends React.PureComponent {
this.state = {
url: '',
query: '',
microphone: null
autocompleteURL: '',
autocompleteQuery: '',
autocompleteCallback: '',
microphone: null,
suggestions: []
};
this.language = window.language.widgets.search;
}
@@ -31,17 +39,38 @@ export default class Search extends React.PureComponent {
};
voiceSearch.onend = () => {
if (searchText.value === '') {
return;
}
setTimeout(() => {
window.location.href = this.state.url + `?${this.state.query}=` + searchText.value;
}, 1000);
};
}
searchButton = () => {
const value = document.getElementById('searchtext').value || 'mue fast';
searchButton = (e) => {
let value;
if (e.target.innerText !== undefined) {
value = e.target.innerText;
} else {
value = document.getElementById('searchtext').value || 'mue fast';
}
window.location.href = this.state.url + `?${this.state.query}=` + value;
}
async getSuggestions(input) {
const data = await (await fetchJSONP(this.state.autocompleteURL + this.state.autocompleteQuery + input, {
jsonpCallback: this.state.autocompleteCallback
})).json();
this.setState({
suggestions: data[1].splice(0, 3)
});
}
init() {
let url;
let query = 'q';
@@ -65,9 +94,23 @@ export default class Search extends React.PureComponent {
microphone = <MicIcon className='micIcon' onClick={this.startSpeechRecognition}/>;
}
let autocompleteURL;
let autocompleteQuery;
let autocompleteCallback;
if (localStorage.getItem('autocomplete') === 'true') {
const info = autocompleteProviders.find((i) => i.value === localStorage.getItem('autocompleteProvider'));
autocompleteURL = info.url;
autocompleteQuery = info.query;
autocompleteCallback = info.callback;
}
this.setState({
url: url,
query: query,
autocompleteURL: autocompleteURL,
autocompleteQuery: autocompleteQuery,
autocompleteCallback: autocompleteCallback,
microphone: microphone
});
}
@@ -91,7 +134,7 @@ export default class Search extends React.PureComponent {
<form action={this.state.url} className='searchBar'>
{this.state.microphone}
<SearchIcon onClick={this.searchButton}/>
<input type='text' placeholder={this.language} name={this.state.query} id='searchtext'/>
<AutocompleteInput placeholder={this.language} name={this.state.query} id='searchtext' suggestions={this.state.suggestions} onChange={(e) => this.getSuggestions(e)} onClick={this.searchButton}/>
</form>
);
}

View File

@@ -0,0 +1,17 @@
[
{
"name": "Google",
"value": "google",
"url": "https://www.google.com/complete/search?client=chrome",
"callback": "callback",
"query": "&q="
},
{
"name": "Bing",
"value": "bing",
"url": "https://api.bing.com/osjson.aspx?JsonType=callback",
"callback": "JsonCallback",
"query": "&query="
}
]

View File

@@ -8,27 +8,36 @@
input[type=text] {
width: 140px;
margin-left: 12px;
margin-left: 40px;
border-radius: 24px;
font-size: calc(5px + 1.2vmin);
border: none;
position: absolute;
background-color: rgba(0, 0, 0, 0.3);
background-color: rgba(255, 255, 255, 0.7);
-webkit-transition: width 0.5s ease-in-out;
transition: width 0.5s ease-in-out;
color: white;
color: black;
padding: 0.5rem 1rem;
user-select: none;
&:focus {
width: 400px;
background-color: rgba(0, 0, 0, 0.5);
background-color: rgba(255, 255, 255, 0.8);
user-select: text;
}
&::-webkit-input-placeholder {
color: black;
}
&::-moz-placeholder {
color: black;
}
}
.MuiSvgIcon-root {
margin-top: 4px;
position: absolute;
margin-top: 6px;
font-size: 30px;
filter: drop-shadow(0 0 6px rgba(0, 0, 0, 0.3));
cursor: pointer;
@@ -42,4 +51,24 @@
.micIcon {
margin-right: 10px;
position: relative !important;
}
.dark .searchBar {
input[type=text] {
background-color: rgba(0, 0, 0, 0.3);
color: white;
&:focus {
background-color: rgba(0, 0, 0, 0.5);
}
&::-webkit-input-placeholder {
color: white;
}
&::-moz-placeholder {
color: white;
}
}
}

View File

@@ -39,6 +39,12 @@
"settingsName": "startpage",
"url": "https://www.startpage.com/sp/search"
},
{
"name": "Yahoo! JAPAN",
"settingsName": "yahoojp",
"url": "https://search.yahoo.co.jp/search",
"query": "p"
},
{
"name": "Яндекс",
"settingsName": "yandex",

View File

@@ -96,10 +96,18 @@ export default class Clock extends React.PureComponent {
return element.style.display = 'none';
}
this.timer = null;
this.startTime(0);
element.style.display = 'block';
element.style.fontSize = `${4 * Number((localStorage.getItem('zoomClock') || 100) / 100)}em`;
}
});
if (localStorage.getItem('timeType') !== 'analogue') {
document.querySelector('.clock-container').style.fontSize = `${4 * Number((localStorage.getItem('zoomClock') || 100) / 100)}em`;
}
this.startTime(0);
}

View File

@@ -108,10 +108,13 @@ export default class DateWidget extends React.PureComponent {
}
element.style.display = 'block';
element.style.fontSize = `${Number((localStorage.getItem('zoomDate') || 100) / 100)}em`;
this.getDate();
}
});
document.querySelector('.date').style.fontSize = `${Number((localStorage.getItem('zoomDate') || 100) / 100)}em`;
this.getDate();
}

View File

@@ -3,7 +3,8 @@ import React from 'react';
import EventBus from '../../../modules/helpers/eventbus';
import WeatherIcon from './WeatherIcon';
import { WiHumidity, WiWindy } from 'weather-icons-react';
import WindDirectionIcon from './WindDirectionIcon';
import { WiHumidity, WiWindy, WiBarometer, WiCloud } from 'weather-icons-react';
import './weather.scss';
@@ -16,10 +17,14 @@ export default class Weather extends React.PureComponent {
temp_text: '',
weather: {
temp: '',
description: '',
temp_min: '',
temp_max: '',
humidity: '',
windspeed: '',
wind_speed: '',
wind_degrees: '',
cloudiness: '',
visibility: '',
pressure: ''
}
};
@@ -33,23 +38,29 @@ export default class Weather extends React.PureComponent {
let data = {
weather: [
{
description: this.state.weather.description,
icon: this.state.icon
}
],
wind: {
speed: this.state.weather.windspeed
},
main: {
temp: this.state.weather.original_temp,
temp_min: this.state.weather.original_temp_min,
temp_max: this.state.weather.original_temp_max,
humidity: this.state.weather.humidity,
pressure: this.state.weather.pressure
},
visibility: this.state.weather.visibility,
wind: {
speed: this.state.weather.wind_speed,
deg: this.state.weather.wind_degrees
},
clouds: {
all: this.state.weather.cloudiness
}
};
if (!this.state.weather.temp) {
data = await (await fetch (window.constants.WEATHER_URL + `/current?city=${this.state.location}`)).json();
data = await (await fetch (window.constants.WEATHER_URL + `/current?city=${this.state.location}&lang=${localStorage.getItem('language')}`)).json();
}
if (data.cod === '404') {
@@ -85,25 +96,34 @@ export default class Weather extends React.PureComponent {
temp_text: temp_text,
weather: {
temp: Math.round(temp),
description: data.weather[0].description,
temp_min: Math.round(temp_min),
temp_max: Math.round(temp_max),
humidity: data.main.humidity,
windspeed: data.wind.speed,
wind_speed: data.wind.speed,
wind_degrees: data.wind.deg,
cloudiness: data.clouds.all,
visibility: data.visibility,
pressure: data.main.pressure,
original_temp: data.main.temp,
original_temp_min: data.main.temp_min,
original_temp_max: data.main.temp_max
}
});
document.querySelector('.weather svg').style.fontSize = `${0.95 * Number((localStorage.getItem('zoomWeather') || 100) / 100)}em`;
}
componentDidMount() {
EventBus.on('refresh', (data) => {
if (data === 'weather') {
this.getWeather();
document.querySelector('.weather').style.fontSize = `${Number((localStorage.getItem('zoomWeather') || 100) / 100)}em`;
document.querySelector('.weather svg').style.fontSize = `${0.95 * Number((localStorage.getItem('zoomWeather') || 100) / 100)}em`;
}
});
document.querySelector('.weather').style.fontSize = `${Number((localStorage.getItem('zoomWeather') || 100) / 100)}em`;
this.getWeather();
}
@@ -140,15 +160,18 @@ export default class Weather extends React.PureComponent {
return <><br/>{this.state.weather.temp_min + this.state.temp_text} {this.state.weather.temp_max + this.state.temp_text}</>;
}
};
return (
<div className='weather'>
<WeatherIcon name={this.state.icon}/>
<span>{this.state.weather.temp + this.state.temp_text}</span>
{enabled('weatherdescription') ? <span className='loc' style={{ 'textTransform': 'capitalize' }}><br/>{this.state.weather.description}</span> : null}
<span className='minmax'>{minmax()}</span>
{enabled('humidity') ? <span className='loc'><br/><WiHumidity/>{this.state.weather.humidity}%</span> : null}
{enabled('windspeed') ? <span className='loc'><br/><WiWindy/>{this.state.weather.windspeed}<span className='minmax'> m/s</span></span> : null}
{enabled('atmosphericpressure') ? <span className='loc'><br/>{this.state.weather.pressure}<span className='minmax'> hPa</span></span> : null}
{enabled('windspeed') ? <span className='loc'><br/><WiWindy/>{this.state.weather.wind_speed}<span className='minmax'> m/s</span> {enabled('windDirection') ? <WindDirectionIcon degrees={this.state.weather.wind_degrees}/> : null}</span> : null}
{enabled('cloudiness') ? <span className='loc'><br/><WiCloud/>{this.state.weather.cloudiness}%</span> : null}
{enabled('visibility') ? <span className='loc'><br/>{this.state.weather.visibility} {window.language.widgets.weather.meters}</span> : null}
{enabled('atmosphericpressure') ? <span className='loc'><br/><WiBarometer/>{this.state.weather.pressure}<span className='minmax'> hPa</span></span> : null}
<br/>
{enabled('showlocation') ? <span className='loc'>{this.state.location}</span> : null}
</div>

View File

@@ -1,8 +1,5 @@
import React from 'react';
import { WiDaySunny, WiNightClear, WiDayCloudy, WiNightCloudy, WiCloud, WiCloudy, WiDayShowers, WiNightShowers, WiRain, WiThunderstorm, WiSnow, WiFog } from 'weather-icons-react';
import './weather.scss';
export default function WeatherIcon(props) {
let icon;

View File

@@ -0,0 +1,23 @@
import { WiDirectionDownLeft, WiDirectionDownRight, WiDirectionDown, WiDirectionLeft, WiDirectionRight, WiDirectionUpLeft, WiDirectionUpRight, WiDirectionUp } from 'weather-icons-react';
export default function WindDirectionIcon(props) {
let icon;
// convert the number openweathermap gives us to closest direction or something
const directions = ['North', 'North-West', 'West', 'South-West', 'South', 'South-East', 'East', 'North-East'];
const direction = directions[Math.round(((props.degrees %= 360) < 0 ? props.degrees + 360 : props.degrees) / 45) % 8];
switch (direction) {
case 'North': icon = <WiDirectionUp/>; break;
case 'North-West': icon = <WiDirectionUpLeft/>; break;
case 'West': icon = <WiDirectionLeft/>; break;
case 'South-West': icon = <WiDirectionDownLeft/>; break;
case 'South': icon = <WiDirectionDown/>; break;
case 'South-East': icon = <WiDirectionDownRight/>; break;
case 'East': icon = <WiDirectionRight/>; break;
case 'North-East': icon = <WiDirectionUpRight/>; break;
default: icon = null; break;
}
return icon;
}

View File

@@ -8,21 +8,25 @@ import './scss/index.scss';
// the toast css is based on default so we need to import it
import 'react-toastify/dist/ReactToastify.min.css';
import '@fontsource/lexend-deca/latin-400.css';
import '@fontsource/montserrat/cyrillic-500.css';
import '@fontsource/lexend-deca/400.css';
// language
import merge from '@material-ui/utils/esm/deepmerge';
const languagecode = localStorage.getItem('language') || 'en_GB';
// we set things to window. so they're global and we avoid passing the translation strings as props to each component
// we set things to window. so we avoid passing the translation strings as props to each component
window.languagecode = languagecode.replace('-', '_');
if (languagecode === 'en') {
window.languagecode = 'en_GB';
}
// only load font if needed
if (languagecode === 'ru') {
require('@fontsource/montserrat/cyrillic-500.css');
}
// these are merged so if a string is untranslated it doesn't break mue
window.language = merge(require('./translations/en_GB.json'), require(`./translations/${window.languagecode}.json`));
@@ -31,7 +35,6 @@ if (window.languagecode !== 'en_GB' || window.languagecode !== 'en_US') {
document.documentElement.lang = window.languagecode.split('_')[0];
}
// window.constants
window.constants = Constants;
ReactDOM.render(

View File

@@ -1,13 +1,14 @@
export const API_URL = 'https://api.muetab.com';
export const UNSPLASH_URL = 'https://unsplash.muetab.com';
export const PEXELS_URL = 'https://pexels.muetab.com';
export const MARKETPLACE_URL = 'https://marketplace.muetab.com';
export const WEATHER_URL = 'https://weather.muetab.com';
export const WEBSITE_URL = 'https://muetab.com';
export const SPONSORS_URL = 'https://sponsors.muetab.com';
export const GITHUB_URL = 'https://api.github.com';
export const BLOG_POST = 'https://blog.muetab.com/posts/version-5-0-the-big-one';
export const BLOG_POST = 'https://blog.muetab.com/posts/version-5-1';
export const FEEDBACK_FORM = 'https://api.formcake.com/api/form/349b56cb-7e2b-4004-b32b-e8964d217dd1/submission';
export const DDG_PROXY = 'https://external-content.duckduckgo.com/iu/?u=';
export const OFFLINE_IMAGES = 20;
export const BETA_VERSION = false;
export const VERSION = '5.0';
export const VERSION = '5.1.0';

View File

@@ -202,5 +202,33 @@
{
"name": "datezero",
"value": true
},
{
"name": "autocompleteProvider",
"value": "google"
},
{
"name": "quoteType",
"value": "api"
},
{
"name": "backgroundFilter",
"value": "grayscale"
},
{
"name": "navbarHover",
"value": false
},
{
"name": "apiQuality",
"value": "high"
},
{
"name": "photoInformation",
"value": true
},
{
"name": "quicklinksddgProxy",
"value": true
}
]

View File

@@ -3,10 +3,12 @@ export default function ExperimentalInit() {
if (localStorage.getItem('debug') === 'true') {
document.onkeydown = (e) => {
e = e || window.event;
if (!e.ctrlKey) {
return;
}
let code = e.which || e.keyCode;
const code = e.which || e.keyCode;
switch (code) {
case 222:

View File

@@ -1,5 +1,3 @@
import { toast } from 'react-toastify';
import EventBus from './eventbus';
export default class MarketplaceFunctions {
@@ -18,24 +16,21 @@ export default class MarketplaceFunctions {
localStorage.setItem(item.name, item.value);
});
break;
case 'quote_packs':
case 'quotes':
localStorage.removeItem('quote_packs');
localStorage.removeItem('quoteAPI');
localStorage.setItem('quoteType', localStorage.getItem('oldQuoteType'));
localStorage.removeItem('oldQuoteType');
EventBus.dispatch('refresh', 'marketplacequoteuninstall');
break;
case 'photos':
case 'photo_packs':
localStorage.removeItem('photo_packs');
localStorage.setItem('backgroundType', localStorage.getItem('oldBackgroundType'));
localStorage.removeItem('oldBackgroundType');
EventBus.dispatch('refresh', 'marketplacebackgrounduninstall');
break;
default:
try {
localStorage.removeItem(type);
} catch (e) {
toast('Failed to uninstall addon, check the console');
console.error(e);
}
break;
}
let installed = JSON.parse(localStorage.getItem('installed'));
@@ -62,31 +57,33 @@ export default class MarketplaceFunctions {
});
localStorage.setItem('backup_settings', JSON.stringify(oldSettings));
input.settings.forEach((element) => {
localStorage.setItem(element.name, element.value);
Object.keys(input.settings).forEach((key) => {
localStorage.setItem(key, input.settings[key]);
});
break;
case 'photos':
case 'photo_packs':
localStorage.setItem('photo_packs', JSON.stringify(input.photos));
localStorage.setItem('oldBackgroundType', localStorage.getItem('backgroundType'));
localStorage.setItem('backgroundType', 'photo_pack');
EventBus.dispatch('refresh', 'background');
break;
case 'quote_packs':
case 'quotes':
if (input.quote_api) {
localStorage.setItem('quoteAPI', JSON.stringify(input.quote_api));
}
localStorage.setItem('quote_packs', JSON.stringify(input.quotes));
localStorage.setItem('oldQuoteType', localStorage.getItem('quoteType'));
localStorage.setItem('quoteType', 'quote_pack');
EventBus.dispatch('refresh', 'quote');
break;
default:
break;
}
let installed = JSON.parse(localStorage.getItem('installed'));
const installed = JSON.parse(localStorage.getItem('installed'));
if (sideload) {
installed.push({

View File

@@ -51,10 +51,10 @@ export default class SettingsFunctions {
defaultSettings.forEach((element) => localStorage.setItem(element.name, element.value));
// Languages
const languageCodes = languages.map(({ code }) => code);
const browserLanguage = (navigator.languages && navigator.languages[0]) || navigator.language;
const languageCodes = languages.map(({ value }) => value);
const browserLanguage = (navigator.languages && navigator.languages.find((lang) => lang.replace('-', '_') && languageCodes.includes(lang))) || navigator.language.replace('-', '_');
if (languageCodes.includes(browserLanguage.replace('-', '_'))) {
if (languageCodes.includes(browserLanguage)) {
localStorage.setItem('language', browserLanguage);
} else {
localStorage.setItem('language', 'en_GB');
@@ -91,24 +91,27 @@ export default class SettingsFunctions {
document.title = tabName;
if (hotreload === true) {
return;
const custom = ['customcss', 'customjs', 'customfont'];
custom.forEach((element) => {
try {
document.head.removeChild(document.getElementById(element));
} catch (e) {}
});
}
const css = localStorage.getItem('customcss');
if (css) {
document.head.insertAdjacentHTML('beforeend', '<style>' + css + '</style>');
}
const js = localStorage.getItem('customjs');
if (js) {
document.body.insertAdjacentHTML('beforeend', '<script>' + js + '</script>');
document.head.insertAdjacentHTML('beforeend', '<style id="customcss">' + css + '</style>');
}
const font = localStorage.getItem('font');
if (font) {
const google = localStorage.getItem('fontGoogle');
let url, fontweight, fontstyle = '';
let url = '';
let fontweight = '';
let fontstyle = '';
if (google === 'true') {
url = `@import url('https://fonts.googleapis.com/css2?family=${font}&display=swap');`;
}
@@ -124,7 +127,7 @@ export default class SettingsFunctions {
}
document.head.insertAdjacentHTML('beforeend', `
<style>
<style id='customfont'>
${url}
* {
font-family: '${font}', 'Lexend Deca', 'Montserrat' !important;
@@ -135,6 +138,16 @@ export default class SettingsFunctions {
`);
}
if (hotreload === true) {
return;
}
const js = localStorage.getItem('customjs');
if (js) {
// eslint-disable-next-line no-eval
eval(js);
}
if (localStorage.getItem('experimental') === 'true') {
experimentalInit();
}
@@ -174,7 +187,7 @@ export default class SettingsFunctions {
localStorage.clear();
this.setDefaultSettings();
Object.keys(settings).forEach(key => {
Object.keys(settings).forEach((key) => {
localStorage.setItem(key, settings[key]);
});
}

View File

@@ -24,11 +24,6 @@ $modal: (
'modal-link-dark': #3498db
);
$marketplace: (
'item-background': rgba(242, 243, 244, 1),
'product-information-backgroud': rgba(242, 243, 244, 1)
);
$button-colours: (
'confirm': rgba(46, 213, 115, 1),
'reset': rgba(255, 71, 87, 1),

View File

@@ -13,6 +13,7 @@
"background": {
"credit": "Foto von",
"unsplash": "unsplash.com",
"pexels": "pexels.com",
"information": "Informationen",
"download": "Download"
},
@@ -29,7 +30,8 @@
"week": "Kalenderwoche"
},
"weather": {
"not_found": "Nicht gefunden"
"not_found": "Nicht gefunden",
"meters": "Meter"
},
"navbar": {
"tooltips": {
@@ -130,6 +132,7 @@
"title": "Hintergrund",
"ddg_proxy": "DuckDuckGo Bilder Proxy verwenden",
"transition": "Weicher übergang",
"photo_information": "Show photo information",
"category": "Kategorie",
"buttons": {
"title": "Schaltflächen",
@@ -140,7 +143,16 @@
"effects": {
"title": "Effekte",
"blur": "Unschärfe anpassen",
"brightness": "Helligkeit anpassen"
"brightness": "Helligkeit anpassen",
"filters": {
"title": "Background filter",
"amount": "Filter amount",
"grayscale": "Grayscale",
"sepia": "Sepia",
"invert": "Invert",
"saturate": "Saturate",
"contrast": "Contrast"
}
},
"type": {
"title": "Type",
@@ -157,13 +169,22 @@
"add_colour": "Farbe hinzufügen",
"disabled": "Deaktiviert",
"loop_video": "Video schleife",
"mute_video": "Video stumm"
"mute_video": "Video stumm",
"quality": {
"title": "Quality",
"original": "Original",
"high": "High Quality",
"normal": "Normal Quality",
"datasaver": "Data Saver"
}
}
},
"search": {
"title": "Suche",
"search_engine": "Suchmaschine",
"custom": "Abfrage-URL",
"autocomplete": "Autocomplete",
"autocomplete_provider": "Autocomplete Provider",
"voice_search": "Sprachsuche"
},
"weather": {
@@ -177,10 +198,14 @@
"kelvin": "Kelvin"
},
"extra_info": {
"title": "Zusätzliche Informationen",
"title": "Zusätzliche informationen",
"show_location": "Standort anzeigen",
"show_description": "Show description",
"cloudiness": "Cloudiness",
"humidity": "Luftfeuchtigkeit",
"visibility": "Visibility",
"wind_speed": "Windgeschwindigkeit",
"wind_direction": "Wind direction",
"min_temp": "Mindesttemperatur",
"max_temp": "Höchsttemperatur",
"atmospheric_pressure": "Atmosphärischer Druck"
@@ -271,7 +296,11 @@
"checking_update": "Auf Update prüfen",
"update_available": "Update verfügbar",
"no_update": "Kein Update verfügbar",
"offline_mode": "Im Offline Modus kann nicht nach Updates gesucht werden"
"offline_mode": "Im Offline Modus kann nicht nach Updates gesucht werden",
"error": {
"title": "Failed to get update information",
"description": "An error occured"
}
},
"contact_us": "Kontaktieren Sie uns",
"support_mue": "Mue unterstützen",
@@ -296,7 +325,6 @@
"photo_packs": "Fotopakete",
"quote_packs": "Zitat-Pakete",
"preset_settings": "Voreingestellte Einstellungen",
"themes": "Themen",
"no_items": "Keine Einträge in dieser Kategorie",
"product": {
"overview": "Übersicht",
@@ -315,16 +343,23 @@
},
"offline": {
"title": "Sieht aus, als ob Sie offline sind",
"description": "Bitte stellen Sie eine Verbindung zum Internet her."
"description": "Bitte stellen Sie eine Verbindung zum Internet her"
}
},
"addons": {
"added": "Hinzugefügt",
"empty": {
"title": "Hier ist es leer",
"description": "Gehen Sie zum Marktplatz, um einige hinzuzufügen."
"description": "Gehen Sie zum Marktplatz, um einige hinzuzufügen"
},
"sideload": "Hochladen"
"sideload": "Hochladen",
"sort": {
"title": "Sort",
"newest": "Installed (Newest)",
"oldest": "Installed (Oldest)",
"a_z": "Alphabetical (A-Z)",
"z_a": "Alphabetical (Z-A)"
}
}
},
"update": {

View File

@@ -13,6 +13,7 @@
"background": {
"credit": "Photo by",
"unsplash": "on Unsplash",
"pexels": "on Pexels",
"information": "Information",
"download": "Download"
},
@@ -29,7 +30,8 @@
"week": "Week"
},
"weather": {
"not_found": "Not Found"
"not_found": "Not Found",
"meters": "metres"
},
"navbar": {
"tooltips": {
@@ -107,9 +109,9 @@
},
"quote": {
"title": "Quote",
"author_link": "Authour link",
"author_link": "Author link",
"custom": "Custom quote",
"custom_author": "Custom authour",
"custom_author": "Custom author",
"buttons": {
"title": "Buttons",
"copy": "Copy",
@@ -130,6 +132,7 @@
"title": "Background",
"ddg_proxy": "Use DuckDuckGo image proxy",
"transition": "Fade-in transition",
"photo_information": "Show photo information",
"category": "Category",
"buttons": {
"title": "Buttons",
@@ -140,7 +143,16 @@
"effects": {
"title": "Effects",
"blur": "Adjust blur",
"brightness": "Adjust brightness"
"brightness": "Adjust brightness",
"filters": {
"title": "Background filter",
"amount": "Filter amount",
"grayscale": "Grayscale",
"sepia": "Sepia",
"invert": "Invert",
"saturate": "Saturate",
"contrast": "Contrast"
}
},
"type": {
"title": "Type",
@@ -157,13 +169,22 @@
"add_colour": "Add colour",
"disabled": "Disabled",
"loop_video": "Loop video",
"mute_video": "Mute video"
"mute_video": "Mute video",
"quality": {
"title": "Quality",
"original": "Original",
"high": "High Quality",
"normal": "Normal Quality",
"datasaver": "Data Saver"
}
}
},
"search": {
"title": "Search",
"search_engine": "Search engine",
"custom": "Custom search URL",
"autocomplete": "Autocomplete",
"autocomplete_provider": "Autocomplete Provider",
"voice_search": "Voice search"
},
"weather": {
@@ -178,9 +199,13 @@
},
"extra_info": {
"title": "Extra information",
"show_location": "Show Location",
"show_location": "Show location",
"show_description": "Show description",
"cloudiness": "Cloudiness",
"humidity": "Humidity",
"visibility": "Visibility",
"wind_speed": "Wind speed",
"wind_direction": "Wind direction",
"min_temp": "Minimum temperature",
"max_temp": "Maximum temperature",
"atmospheric_pressure": "Atmospheric pressure"
@@ -271,7 +296,11 @@
"checking_update": "Checking for update",
"update_available": "Update available",
"no_update": "No update available",
"offline_mode": "Cannot check for update in offline mode"
"offline_mode": "Cannot check for update in offline mode",
"error": {
"title": "Failed to get update information",
"description": "An error occured"
}
},
"contact_us": "Contact Us",
"support_mue": "Support Mue",
@@ -296,14 +325,13 @@
"photo_packs": "Photo Packs",
"quote_packs": "Quote Packs",
"preset_settings": "Preset Settings",
"themes": "Themes",
"no_items": "No items in this category",
"product": {
"overview": "Overview",
"information": "Information",
"last_updated": "Last Updated",
"version": "Version",
"author": "Authour",
"author": "Author",
"buttons": {
"addtomue": "Add To Mue",
"remove": "Remove"
@@ -315,7 +343,7 @@
},
"offline": {
"title": "Looks like you're offline",
"description": "Please connect to the internet."
"description": "Please connect to the internet"
}
},
"addons": {
@@ -324,7 +352,14 @@
"title": "Empty",
"description": "No addons are installed"
},
"sideload": "Sideload"
"sideload": "Sideload",
"sort": {
"title": "Sort",
"newest": "Installed (Newest)",
"oldest": "Installed (Oldest)",
"a_z": "Alphabetical (A-Z)",
"z_a": "Alphabetical (Z-A)"
}
}
},
"update": {

View File

@@ -13,6 +13,7 @@
"background": {
"credit": "Photo by",
"unsplash": "on Unsplash",
"pexels": "on Pexels",
"information": "Information",
"download": "Download"
},
@@ -29,7 +30,8 @@
"week": "Week"
},
"weather": {
"not_found": "Not Found"
"not_found": "Not Found",
"meters": "meters"
},
"navbar": {
"tooltips": {
@@ -130,6 +132,7 @@
"title": "Background",
"ddg_proxy": "Use DuckDuckGo image proxy",
"transition": "Fade-in transition",
"photo_information": "Show photo information",
"category": "Category",
"buttons": {
"title": "Buttons",
@@ -140,7 +143,16 @@
"effects": {
"title": "Effects",
"blur": "Adjust blur",
"brightness": "Adjust brightness"
"brightness": "Adjust brightness",
"filters": {
"title": "Background filter",
"amount": "Filter amount",
"grayscale": "Grayscale",
"sepia": "Sepia",
"invert": "Invert",
"saturate": "Saturate",
"contrast": "Contrast"
}
},
"type": {
"title": "Type",
@@ -157,13 +169,22 @@
"add_colour": "Add color",
"disabled": "Disabled",
"loop_video": "Loop video",
"mute_video": "Mute video"
"mute_video": "Mute video",
"quality": {
"title": "Quality",
"original": "Original",
"high": "High Quality",
"normal": "Normal Quality",
"datasaver": "Data Saver"
}
}
},
"search": {
"title": "Search",
"search_engine": "Search engine",
"custom": "Custom search URL",
"autocomplete": "Autocomplete",
"autocomplete_provider": "Autocomplete Provider",
"voice_search": "Voice search"
},
"weather": {
@@ -178,9 +199,13 @@
},
"extra_info": {
"title": "Extra information",
"show_location": "Show Location",
"show_location": "Show location",
"show_description": "Show description",
"cloudiness": "Cloudiness",
"humidity": "Humidity",
"visibility": "Visibility",
"wind_speed": "Wind speed",
"wind_direction": "Wind direction",
"min_temp": "Minimum temperature",
"max_temp": "Maximum temperature",
"atmospheric_pressure": "Atmospheric pressure"
@@ -271,7 +296,11 @@
"checking_update": "Checking for update",
"update_available": "Update available",
"no_update": "No update available",
"offline_mode": "Cannot check for update in offline mode"
"offline_mode": "Cannot check for update in offline mode",
"error": {
"title": "Failed to get update information",
"description": "An error occured"
}
},
"contact_us": "Contact Us",
"support_mue": "Support Mue",
@@ -296,7 +325,6 @@
"photo_packs": "Photo Packs",
"quote_packs": "Quote Packs",
"preset_settings": "Preset Settings",
"themes": "Themes",
"no_items": "No items in this category",
"product": {
"overview": "Overview",
@@ -315,7 +343,7 @@
},
"offline": {
"title": "Looks like you're offline",
"description": "Please connect to the internet."
"description": "Please connect to the internet"
}
},
"addons": {
@@ -324,7 +352,14 @@
"title": "Empty",
"description": "No addons are installed"
},
"sideload": "Sideload"
"sideload": "Sideload",
"sort": {
"title": "Sort",
"newest": "Installed (Newest)",
"oldest": "Installed (Oldest)",
"a_z": "Alphabetical (A-Z)",
"z_a": "Alphabetical (Z-A)"
}
}
},
"update": {

View File

@@ -1,5 +1,5 @@
{
"tabname": "New Tab",
"tabname": "Nueva pestaña",
"widgets": {
"greeting": {
"morning": "Buenos días",
@@ -8,38 +8,40 @@
"christmas": "Feliz Navidad",
"newyear": "Feliz año nuevo",
"halloween": "Feliz Halloween",
"birthday": "Happy Birthday"
"birthday": "Feliz cumpleaños"
},
"background": {
"credit": "Foto por",
"unsplash": "on Unsplash",
"information": "Information",
"download": "Download"
"unsplash": "en Unsplash",
"pexels": "en Pexels",
"information": "Información",
"download": "Descargar"
},
"search": "Buscar",
"quicklinks": {
"new": "New Link",
"name": "Name",
"new": "Nuevo enlace",
"name": "Nombre",
"url": "URL",
"add": "Add",
"name_error": "Must provide name",
"url_error": "Must provide URL"
"add": "Añadir",
"name_error": "Debe indicar el nombre",
"url_error": "Debe indicar la URL"
},
"date": {
"week": "Week"
"week": "Semana"
},
"weather": {
"not_found": "Not Found"
"not_found": "No encontrado",
"meters": "metros"
},
"navbar": {
"tooltips": {
"update": "Update Patch Notes",
"refresh": "Refresh Page",
"feedback": "Feedback"
"update": "Notas de actualización del parche",
"refresh": "Recargar página",
"feedback": "Comentarios"
},
"notes": {
"title": "Notes",
"placeholder": "Type here"
"title": "Notas",
"placeholder": "Escribe aquí"
}
}
},
@@ -47,7 +49,7 @@
"main": {
"title": "Opciones",
"loading": "Cargando...",
"file_upload_error": "File is over 2MB",
"file_upload_error": "El archivo pesa más de 2MB",
"navbar": {
"settings": "Ajustes",
"addons": "Mis complementos",
@@ -55,20 +57,20 @@
},
"error_boundary": {
"title": "Error",
"message": "Failed to load this component of Mue",
"refresh": "Refrescar"
"message": "No se ha podido cargar este componente de Mue",
"refresh": "Recargar"
},
"settings": {
"enabled": "Enabled",
"enabled": "Activado",
"reminder": {
"title": "NOTICE",
"message": "In order for all of the changes to take place, the page must be refreshed."
"title": "AVISO",
"message": "Para que se produzcan todos los cambios hay que recargar la página."
},
"sections": {
"time": {
"title": "Tiempo",
"format": "Format",
"type": "Type",
"format": "Formato",
"type": "Tipo",
"digital": {
"title": "Digital",
"seconds": "Segundos",
@@ -77,213 +79,240 @@
"zero": "Sin ceros"
},
"analogue": {
"analog": "Analógico",
"second_hand": "Seconds hand",
"minute_hand": "Minutes hand",
"hour_hand": "Hours hand",
"hour_marks": "Hour marks",
"minute_marks": "Minute marks"
"title": "Analógico",
"second_hand": "Manecilla de los segundos",
"minute_hand": "Manecilla de los minutos",
"hour_hand": "Manecilla de las horas",
"hour_marks": "Marcas de las horas",
"minute_marks": "Marcas de los minutos"
},
"percentage_complete": "Percentage complete",
"percentage_complete": "Porcentaje completado",
"date": {
"title": "Date",
"week_number": "Week number",
"day_of_week": "Day of week",
"datenth": "Date nth",
"title": "Fecha",
"week_number": "Número de la semana",
"day_of_week": "Día de la semana",
"datenth": "Fecha nth",
"type": {
"short": "Short",
"long": "Long"
"short": "Corto",
"long": "Largo"
},
"short_date": "Short date",
"short_format": "Short format",
"short_date": "Fecha corta",
"short_format": "Formato corto",
"short_separator": {
"title": "Short separator",
"dots": "Dots",
"dash": "Dash",
"gaps": "Gaps",
"slashes": "Slashes"
"title": "Separador corto",
"dots": "Puntos",
"dash": "Guiones",
"gaps": "Guiones con espacios",
"slashes": "Barras"
}
}
},
"quote": {
"title": "Cita",
"author_link": "Authour link",
"custom": "Custom quote",
"custom_author": "Custom authour",
"author_link": "Enlace del autor",
"custom": "Cita personalizada",
"custom_author": "Autor personalizado",
"buttons": {
"title": "Buttons",
"title": "Botones",
"copy": "Botón de copiar",
"tweet": "Botón de Tweet",
"favourite": "Botón de favoritos"
}
},
"greeting": {
"title": "Saludos",
"title": "Saludo",
"events": "Eventos",
"default": "Mensaje del saludo por defecto",
"name": "Nombre para el saludo",
"birthday": "Birthday",
"birthday_age": "Birthday age",
"birthday_date": "Birthday date"
"birthday": "Cumpleaños",
"birthday_age": "Edad de cumpleaños",
"birthday_date": "Fecha de cumpleaños"
},
"background": {
"title": "Fondo",
"ddg_proxy": "Use DuckDuckGo image proxy",
"transition": "Fade-in transition",
"category": "Category",
"ddg_proxy": "Utilizar el proxy de imágenes de DuckDuckGo",
"transition": "Transición fade-in",
"photo_information": "Ver información de la foto",
"category": "Categoría",
"buttons": {
"title": "Buttons",
"title": "Botones",
"view": "Ver",
"favourite": "Favorito",
"download": "Download"
"download": "Descargar"
},
"effects": {
"title": "Effects",
"title": "Efectos",
"blur": "Ajustar difuminado",
"brightness": "Ajustar brillo"
"brightness": "Ajustar brillo",
"filters": {
"title": "Filtros del fondo",
"amount": "Cantidad del filtro",
"grayscale": "Escala de grises",
"sepia": "Sepia",
"invert": "Invertir",
"saturate": "Saturar",
"contrast": "Contraste"
}
},
"type": {
"title": "Type",
"title": "Tipo",
"api": "API",
"custom_image": "Custom image",
"custom_colour": "Custom colour/gradient"
"custom_image": "Imagen personalizada",
"custom_colour": "Color/degradado personalizado"
},
"source": {
"title": "Source",
"api": "Fondos API",
"title": "Fuente",
"api": "API de fondos",
"custom_background": "Fondo personalizado",
"custom_colour": "Color del fondo personalizado",
"upload": "Upload",
"upload": "Subir",
"add_colour": "Añadir color",
"disabled": "Desactivado",
"loop_video": "Loop video",
"mute_video": "Mute video"
"loop_video": "Vídeo en bucle",
"mute_video": "Silenciar video",
"quality": {
"title": "Calidad",
"original": "Original",
"high": "Calidad alta",
"normal": "Calidad normal",
"datasaver": "Ahorro de datos"
}
}
},
"search": {
"title": "Barra de búsqueda",
"title": "Búsqueda",
"search_engine": "Motor de búsqueda",
"custom": "URL de búsqueda personalizada",
"autocomplete": "Autocompletado",
"autocomplete_provider": "Proveedor del autocompletado",
"voice_search": "Búsqueda por voz"
},
"weather": {
"title": "Weather",
"location": "Location",
"title": "Clima",
"location": "Ubicación",
"auto": "Auto",
"temp_format": {
"title": "Temperature format",
"title": "Formato de la temperatura",
"celsius": "Celsius",
"fahrenheit": "Fahrenheit",
"kelvin": "Kelvin"
},
"extra_info": {
"title": "Extra information",
"show_location": "Show Location",
"humidity": "Humidity",
"wind_speed": "Wind speed",
"min_temp": "Minimum temperature",
"max_temp": "Maximum temperature",
"atmospheric_pressure": "Atmospheric pressure"
"title": "Información extra",
"show_location": "Mostrar ubicación",
"show_description": "Mostrar descripción",
"cloudiness": "Nubosidad",
"humidity": "Humedad",
"visibility": "Visibilidad",
"wind_speed": "Velocidad del viento",
"wind_direction": "Dirección del viento",
"min_temp": "Temperatura mínima",
"max_temp": "Temperatura máxima",
"atmospheric_pressure": "Presión atmosférica"
}
},
"quicklinks": {
"title": "Quick Links",
"open_new": "Open in new tab",
"tooltip": "Tooltip"
"title": "Enlaces rápidos",
"open_new": "Abrir en una nueva pestaña",
"tooltip": "Descripción emergente"
},
"appearance": {
"title": "Appearance",
"title": "Apariencia",
"theme": {
"title": "Theme",
"title": "Tema",
"auto": "Auto",
"light": "Light",
"dark": "Dark"
"light": "Claro",
"dark": "Oscuro"
},
"animations": "Animaciones",
"navbar": {
"title": "Navbar",
"notes": "Notes",
"refresh": "Refresh button"
"title": "Barra de búsqueda",
"notes": "Notas",
"refresh": "Botón de recargar"
},
"font": {
"title": "Font",
"custom": "Custom font",
"google": "Import from Google Fonts",
"title": "Fuente",
"custom": "Fuente personalizada",
"google": "Importar desde Google Fonts",
"weight": {
"title": "Font weight",
"thin": "Thin",
"extra_light": "Extra Light",
"light": "Light",
"title": "Tipo de la fuente",
"thin": "Delgado",
"extra_light": "Extra fino",
"light": "Fino",
"normal": "Normal",
"medium": "Medium",
"semi_bold": "Semi-Bold",
"bold": "Bold",
"extra_bold": "Extra-Bold"
"medium": "Mediano",
"semi_bold": "Semi negrita",
"bold": "Negrita",
"extra_bold": "Extra negrita"
},
"style": {
"title": "Font style",
"title": "Estilo de la fuente",
"normal": "Normal",
"italic": "Italic",
"oblique": "Oblique"
"italic": "Cursiva",
"oblique": "Oblicua"
}
},
"accessibility": {
"title": "Accessibility",
"widget_zoom": "Widget zoom",
"toast_duration": "Toast duration",
"milliseconds": "milliseconds"
"title": "Accesibilidad",
"widget_zoom": "Zoom del widget",
"toast_duration": "Duración de la notificación",
"milliseconds": "milisegundos"
}
},
"order": {
"title": "Widget Order"
"title": "Orden de widgets"
},
"advanced": {
"title": "Advanced",
"offline_mode": "Modo Offline",
"data": "Data",
"title": "Avanzado",
"offline_mode": "Modo sin conexión",
"data": "Datos",
"reset_modal": {
"title": "WARNING",
"question": "Do you want to reset Mue?",
"information": "This will delete all data. If you wish to keep your data and preferences, please export them first.",
"cancel": "Cancel"
"title": "ADVERTENCIA",
"question": "¿Quieres reiniciar Mue?",
"information": "Esto borrará todos los datos. Si desea mantener sus datos y preferencias, por favor, expórtelos primero.",
"cancel": "Cancelar"
},
"customisation": "Customisation",
"custom_css": "Custom CSS",
"custom_js": "Custom JS",
"tab_name": "Tab name",
"experimental_warning": "Please note that the Mue team cannot provide support if you have experimental mode on. Please disable it first and see if the issue continues to occur before contacting support."
"customisation": "Personalización",
"custom_css": "CSS personalizado",
"custom_js": "JS personalizado",
"tab_name": "Nombre de la pestaña",
"experimental_warning": "Por favor, ten en cuenta que el equipo de Mue no puede dar soporte si tienes el modo experimental activado. Por favor, desactívalo primero y comprueba si el problema sigue ocurriendo antes de contactar con el equipo de soporte."
},
"experimental": {
"title": "Experimental",
"warning": "These settings have not been fully tested/implemented and may not work correctly!",
"developer": "Developer"
"warning": "Estos ajustes no han sido totalmente probados/implementados y pueden no funcionar correctamente.",
"developer": "Desarrollador"
},
"language": {
"language": "Lenguaje",
"quote": "Quote language"
"title": "Idioma",
"quote": "Idioma de las citas"
},
"changelog": "Change Log",
"changelog": "Registro de cambios",
"about": {
"title": "About",
"title": "Acerca de",
"copyright": "Copyright",
"version": {
"title": "Version",
"checking_update": "Checking for update",
"update_available": "Update available",
"no_update": "No update available",
"offline_mode": "Cannot check for update in offline mode"
"title": "Versión",
"checking_update": "Comprobando actualizaciones",
"update_available": "Actualización disponible",
"no_update": "Actualizaciones no disponibles",
"offline_mode": "No se puede comprobar la actualización en modo sin conexión",
"error": {
"title": "Fallo al obtener la información de la actualización",
"description": "Ha ocurrido un error"
}
},
"contact_us": "Contact Us",
"support_mue": "Support Mue",
"contact_us": "Contacto",
"support_mue": "Apoya Mue",
"resources_used": {
"title": "Resources used",
"bg_images": "Offline background images",
"welcome_img": "Welcome image",
"pin_icon": "Pin icon"
"title": "Recursos usados",
"bg_images": "Imágenes de fondo sin conexión",
"welcome_img": "Imagen de bienvenida",
"pin_icon": "Icono de chincheta"
},
"contributors": "Contributors",
"supporters": "Supporters",
"photographers": "Photographers"
"contributors": "Contribuyentes",
"supporters": "Partidarios",
"photographers": "Fotógrafos"
}
},
"buttons": {
@@ -296,41 +325,47 @@
"photo_packs": "Paquetes de fotos",
"quote_packs": "Paquetes de citas",
"preset_settings": "Ajustes preestablecidos",
"themes": "Tema",
"no_items": "No items in this category",
"no_items": "No hay artículos en esta categoría",
"product": {
"overview": "Visión general",
"overview": "Vista general",
"information": "Información",
"last_updated": "Última actualización",
"version": "Versión",
"author": "Autor",
"buttons": {
"addtomue": "Añadir a Mue",
"remove": "Remover"
"remove": "Desinstalar"
},
"quote_warning": {
"title": "Advertencia",
"description": "¡Este paquete de citas solicita a servidores externos que pueden rastrearlo!"
"description": "¡Este paquete de citas solicita a servidores externos que pueden rastrearte!"
}
},
"offline": {
"title": "Parece que estás desconectado",
"description": "Por favor conéctate a Internet."
"description": "Por favor conéctate a Internet"
}
},
"addons": {
"added": "Añadido",
"added": "Añadidos",
"empty": {
"title": "Está vacío aquí",
"title": "Vacío",
"description": "Dirígete a la tienda para agregar algunos."
},
"sideload": "Cargar complemento localmente"
"sideload": "Cargar localmente",
"sort": {
"title": "Ordenar",
"newest": "Instalado (Nuevos)",
"oldest": "Instalado (Antiguos)",
"a_z": "Alfabético (A-Z)",
"z_a": "Alfabético (Z-A)"
}
}
},
"update": {
"title": "Actualizar",
"offline": {
"title": "Offline",
"title": "Sin conexión",
"description": "No se pueden obtener actualizaciones en modo sin conexión"
},
"error": {
@@ -341,30 +376,30 @@
"contact_support": "Contáctanos aquí"
},
"welcome": {
"title": "Welcome to",
"information": "Information",
"thankyoumessage1": "Thank you for installing Mue Tab,",
"thankyoumessage2": "we hope you enjoy your time with our extension.",
"support": "Support",
"close": "Close"
"title": "Bienvenido a",
"information": "Información",
"thankyoumessage1": "Gracias por instalar Mue Tab,",
"thankyoumessage2": "esperamos que disfrute de su tiempo con nuestra extensión.",
"support": "Soporte",
"close": "Cerrar"
},
"feedback": {
"title": "Give us feedback",
"question_one": "How would you rate your experience of this Mue build?",
"question_two": "What bugs did you encounter in your use of Mue?",
"question_three": "How likely would you be to recommend this version of Mue to a friend or colleague?",
"question_four": "What do you want adding to the next Mue build?",
"not_filled": "Question box must be filled",
"success": "Sent successfully!",
"submit": "Submit"
"title": "Danos tu opinión",
"question_one": "¿Cómo calificaría su experiencia en esta versión de Mue?",
"question_two": "¿Qué errores has encontrado usando Mue?",
"question_three": "¿Qué probabilidad tendría de recomendar esta versión de Mue a un amigo?",
"question_four": "¿Qué te gustaría ver en la próxima versión de Mue?",
"not_filled": "La casilla de preguntas debe ser rellenada",
"success": "¡Enviado con éxito!",
"submit": "Enviar"
}
},
"toasts": {
"quote": "Cita copiada",
"notes": "Notes copied",
"notes": "Notas copiadas",
"reset": "Restablecido correctamente",
"installed": "Instalado correctamente",
"uninstalled": "Retirado correctamente",
"uninstalled": "Desinstalado correctamente",
"error": "Algo salió mal",
"imported": "Importado correctamente"
}

View File

@@ -13,6 +13,7 @@
"background": {
"credit": "Photo par",
"unsplash": "sur Unsplash",
"pexels": "sur Pexels",
"information": "Information",
"download": "Téléchargement"
},
@@ -29,7 +30,8 @@
"week": "Semaine"
},
"weather": {
"not_found": "Pas trouvé"
"not_found": "Pas trouvé",
"meters": "mètres"
},
"navbar": {
"tooltips": {
@@ -130,6 +132,7 @@
"title": "Fond",
"ddg_proxy": "Utiliser le proxy d'image DuckDuckGo",
"transition": "Transition en fondu",
"photo_information": "Show photo information",
"category": "Catégorie",
"buttons": {
"title": "Boutons",
@@ -140,7 +143,16 @@
"effects": {
"title": "Effets",
"blur": "Ajuster le flou",
"brightness": "Ajuster la luminosité"
"brightness": "Ajuster la luminosité",
"filters": {
"title": "Background filter",
"amount": "Filter amount",
"grayscale": "Grayscale",
"sepia": "Sepia",
"invert": "Invert",
"saturate": "Saturate",
"contrast": "Contrast"
}
},
"type": {
"title": "Type",
@@ -157,13 +169,22 @@
"add_colour": "Ajouter une couleur",
"disabled": "Disabled",
"loop_video": "Boucle vidéo",
"mute_video": "Mettre la vidéo en sourdine"
"mute_video": "Mettre la vidéo en sourdine",
"quality": {
"title": "Quality",
"original": "Original",
"high": "High Quality",
"normal": "Normal Quality",
"datasaver": "Data Saver"
}
}
},
"search": {
"title": "Barre de Recherche",
"search_engine": "Moteur de recherche",
"custom": "URL de recherche personnalisée",
"autocomplete": "Autocomplete",
"autocomplete_provider": "Autocomplete Provider",
"voice_search": "Recherche vocale"
},
"weather": {
@@ -179,8 +200,12 @@
"extra_info": {
"title": "Informations supplémentaires",
"show_location": "Afficher l'emplacement",
"show_description": "Show description",
"cloudiness": "Cloudiness",
"humidity": "Humidité",
"visibility": "Visibility",
"wind_speed": "Vitesse du vent",
"wind_direction": "Wind direction",
"min_temp": "Température minimale",
"max_temp": "Température maximale",
"atmospheric_pressure": "Pression atmosphérique"
@@ -271,7 +296,11 @@
"checking_update": "Vérification de la mise à jour",
"update_available": "Mise à jour disponible",
"no_update": "Pas de mise a jour disponible",
"offline_mode": "Impossible de vérifier la mise à jour en mode hors ligne"
"offline_mode": "Impossible de vérifier la mise à jour en mode hors ligne",
"error": {
"title": "Failed to get update information",
"description": "An error occured"
}
},
"contact_us": "Nous contacter",
"support_mue": "Soutenir Mue",
@@ -296,7 +325,6 @@
"photo_packs": "Packs Photos",
"quote_packs": "Packs Citations",
"preset_settings": "Paramètres prédéfinis",
"themes": "Thèmes",
"no_items": "Aucun article dans cette catégorie",
"product": {
"overview": "Aperçu",
@@ -322,9 +350,16 @@
"added": "Ajoutées",
"empty": {
"title": "C'est vide par ici",
"description": "Dirigez vous vers le marché pour ajouter des options."
"description": "Dirigez vous vers le marché pour ajouter des options"
},
"sideload": "Charger"
"sideload": "Charger",
"sort": {
"title": "Sort",
"newest": "Installed (Newest)",
"oldest": "Installed (Oldest)",
"a_z": "Alphabetical (A-Z)",
"z_a": "Alphabetical (Z-A)"
}
}
},
"update": {

View File

@@ -13,6 +13,7 @@
"background": {
"credit": "Foto van",
"unsplash": "on Unsplash",
"pexels": "on Pexels",
"information": "Information",
"download": "Download"
},
@@ -29,7 +30,8 @@
"week": "Week"
},
"weather": {
"not_found": "Not Found"
"not_found": "Not Found",
"meters": "meter"
},
"navbar": {
"tooltips": {
@@ -107,9 +109,9 @@
},
"quote": {
"title": "Citaat",
"author_link": "Authour link",
"author_link": "Author link",
"custom": "Custom quote",
"custom_author": "Custom authour",
"custom_author": "Custom author",
"buttons": {
"title": "Buttons",
"copy": "Kopieerknop",
@@ -130,6 +132,7 @@
"title": "Achtergrond",
"ddg_proxy": "Use DuckDuckGo image proxy",
"transition": "Fade-in transition",
"photo_information": "Show photo information",
"category": "Category",
"buttons": {
"title": "Buttons",
@@ -140,7 +143,16 @@
"effects": {
"title": "Effects",
"blur": "Vervaging instellen",
"brightness": "Adjust brightness"
"brightness": "Adjust brightness",
"filters": {
"title": "Background filter",
"amount": "Filter amount",
"grayscale": "Grayscale",
"sepia": "Sepia",
"invert": "Invert",
"saturate": "Saturate",
"contrast": "Contrast"
}
},
"type": {
"title": "Type",
@@ -157,13 +169,22 @@
"add_colour": "Kleur toevoegen",
"disabled": "Uitgeschakeld",
"loop_video": "Loop video",
"mute_video": "Mute video"
"mute_video": "Mute video",
"quality": {
"title": "Quality",
"original": "Original",
"high": "High Quality",
"normal": "Normal Quality",
"datasaver": "Data Saver"
}
}
},
"search": {
"title": "Zoekbalk",
"search_engine": "Zoekmachine",
"custom": "Aangepaste zoekmachine-url",
"autocomplete": "Autocomplete",
"autocomplete_provider": "Autocomplete Provider",
"voice_search": "Spraakgestuurd zoeken gebruiken"
},
"weather": {
@@ -178,9 +199,13 @@
},
"extra_info": {
"title": "Extra information",
"show_location": "Show Location",
"show_location": "Show location",
"show_description": "Show description",
"cloudiness": "Cloudiness",
"humidity": "Humidity",
"visibility": "Visibility",
"wind_speed": "Wind speed",
"wind_direction": "Wind direction",
"min_temp": "Minimum temperature",
"max_temp": "Maximum temperature",
"atmospheric_pressure": "Atmospheric pressure"
@@ -271,7 +296,11 @@
"checking_update": "Checking for update",
"update_available": "Update available",
"no_update": "No update available",
"offline_mode": "Cannot check for update in offline mode"
"offline_mode": "Cannot check for update in offline mode",
"error": {
"title": "Failed to get update information",
"description": "An error occured"
}
},
"contact_us": "Contact Us",
"support_mue": "Support Mue",
@@ -296,7 +325,6 @@
"photo_packs": "Fotoverzamelingen",
"quote_packs": "Citaatverzamelingen",
"preset_settings": "Voorinstellingen",
"themes": "Thema's",
"no_items": "No items in this category",
"product": {
"overview": "Overzicht",
@@ -315,16 +343,23 @@
},
"offline": {
"title": "Het lijkt er op dat je niet verbonden bent het internet",
"description": "Maak verbinding met het internet."
"description": "Maak verbinding met het internet"
}
},
"addons": {
"added": "Toegevoegd",
"empty": {
"title": "Het is hier erg leeg",
"description": "Ga naar de marktplaats om een paar extensies toe te voegen."
"description": "Ga naar de marktplaats om een paar extensies toe te voegen"
},
"sideload": "Sideloaden"
"sideload": "Sideloaden",
"sort": {
"title": "Sort",
"newest": "Installed (Newest)",
"oldest": "Installed (Oldest)",
"a_z": "Alphabetical (A-Z)",
"z_a": "Alphabetical (Z-A)"
}
}
},
"update": {

View File

@@ -13,6 +13,7 @@
"background": {
"credit": "Bilde av",
"unsplash": "on Unsplash",
"pexels": "on Pexels",
"information": "Information",
"download": "Download"
},
@@ -29,7 +30,8 @@
"week": "Week"
},
"weather": {
"not_found": "Not Found"
"not_found": "Not Found",
"meters": "meter"
},
"navbar": {
"tooltips": {
@@ -107,9 +109,9 @@
},
"quote": {
"title": "Sitat",
"author_link": "Authour link",
"author_link": "Author link",
"custom": "Custom quote",
"custom_author": "Custom authour",
"custom_author": "Custom author",
"buttons": {
"title": "Buttons",
"copy": "Kopier knapp",
@@ -130,6 +132,7 @@
"title": "Bakgrunn",
"ddg_proxy": "Use DuckDuckGo image proxy",
"transition": "Fade-in transition",
"photo_information": "Show photo information",
"category": "Category",
"buttons": {
"title": "Buttons",
@@ -140,7 +143,16 @@
"effects": {
"title": "Effects",
"blur": "Juster Blur",
"brightness": "Adjust brightness"
"brightness": "Adjust brightness",
"filters": {
"title": "Background filter",
"amount": "Filter amount",
"grayscale": "Grayscale",
"sepia": "Sepia",
"invert": "Invert",
"saturate": "Saturate",
"contrast": "Contrast"
}
},
"type": {
"title": "Type",
@@ -157,13 +169,22 @@
"add_colour": "Legg til farge",
"disabled": "Disabled",
"loop_video": "Loop video",
"mute_video": "Mute video"
"mute_video": "Mute video",
"quality": {
"title": "Quality",
"original": "Original",
"high": "High Quality",
"normal": "Normal Quality",
"datasaver": "Data Saver"
}
}
},
"search": {
"title": "Søkebar",
"search_engine": "Søkemotor",
"custom": "Custom search URL",
"autocomplete": "Autocomplete",
"autocomplete_provider": "Autocomplete Provider",
"voice_search": "Voice search"
},
"weather": {
@@ -178,9 +199,13 @@
},
"extra_info": {
"title": "Extra information",
"show_location": "Show Location",
"show_location": "Show location",
"show_description": "Show description",
"cloudiness": "Cloudiness",
"humidity": "Humidity",
"visibility": "Visibility",
"wind_speed": "Wind speed",
"wind_direction": "Wind direction",
"min_temp": "Minimum temperature",
"max_temp": "Maximum temperature",
"atmospheric_pressure": "Atmospheric pressure"
@@ -271,7 +296,11 @@
"checking_update": "Checking for update",
"update_available": "Update available",
"no_update": "No update available",
"offline_mode": "Cannot check for update in offline mode"
"offline_mode": "Cannot check for update in offline mode",
"error": {
"title": "Failed to get update information",
"description": "An error occured"
}
},
"contact_us": "Contact Us",
"support_mue": "Support Mue",
@@ -296,7 +325,6 @@
"photo_packs": "Bilde pakker",
"quote_packs": "Sitat pakker",
"preset_settings": "Preset instillinger",
"themes": "Themes",
"no_items": "No items in this category",
"product": {
"overview": "Oversikt",
@@ -314,24 +342,31 @@
}
},
"offline": {
"title": "Ser ut som at du er offiline.",
"description": "Vær så snill, koble til internettet."
"title": "Ser ut som at du er offiline",
"description": "Vær så snill, koble til internettet"
}
},
"addons": {
"added": "Lagt til",
"empty": {
"title": "Det er tomt her.",
"description": "Gå til markedsplassen å legg til noe."
"description": "Gå til markedsplassen å legg til noe"
},
"sideload": "Sideload"
"sideload": "Sideload",
"sort": {
"title": "Sort",
"newest": "Installed (Newest)",
"oldest": "Installed (Oldest)",
"a_z": "Alphabetical (A-Z)",
"z_a": "Alphabetical (Z-A)"
}
}
},
"update": {
"title": "Oppdater",
"offline": {
"title": "Offline",
"description": "Kan ikke få oppdatering loggene når i offline modus."
"description": "Kan ikke få oppdatering loggene når i offline modus"
},
"error": {
"title": "Error",

View File

@@ -13,6 +13,7 @@
"background": {
"credit": "Фото",
"unsplash": "on Unsplash",
"pexels": "on Pexels",
"information": "Information",
"download": "Download"
},
@@ -29,7 +30,8 @@
"week": "Week"
},
"weather": {
"not_found": "Not Found"
"not_found": "Not Found",
"meters": "метры"
},
"navbar": {
"tooltips": {
@@ -107,9 +109,9 @@
},
"quote": {
"title": "Цитата",
"author_link": "Authour link",
"author_link": "Author link",
"custom": "Custom quote",
"custom_author": "Custom authour",
"custom_author": "Custom author",
"buttons": {
"title": "Buttons",
"copy": "Кнопка копирования",
@@ -130,6 +132,7 @@
"title": "Фон",
"ddg_proxy": "Use DuckDuckGo image proxy",
"transition": "Fade-in transition",
"photo_information": "Show photo information",
"category": "Category",
"buttons": {
"title": "Buttons",
@@ -140,7 +143,16 @@
"effects": {
"title": "Effects",
"blur": "Размытие",
"brightness": "Яркость"
"brightness": "Яркость",
"filters": {
"title": "Background filter",
"amount": "Filter amount",
"grayscale": "Grayscale",
"sepia": "Sepia",
"invert": "Invert",
"saturate": "Saturate",
"contrast": "Contrast"
}
},
"type": {
"title": "Type",
@@ -157,13 +169,22 @@
"add_colour": "Добавить цвет",
"disabled": "Выключен",
"loop_video": "Loop video",
"mute_video": "Mute video"
"mute_video": "Mute video",
"quality": {
"title": "Quality",
"original": "Original",
"high": "High Quality",
"normal": "Normal Quality",
"datasaver": "Data Saver"
}
}
},
"search": {
"title": "Панель поиска",
"search_engine": "Поисковый движок",
"custom": "Пользовательский поисковый движок",
"autocomplete": "Autocomplete",
"autocomplete_provider": "Autocomplete Provider",
"voice_search": "Поиск голосом"
},
"weather": {
@@ -178,9 +199,13 @@
},
"extra_info": {
"title": "Extra information",
"show_location": "Show Location",
"show_location": "Show location",
"show_description": "Show description",
"cloudiness": "Cloudiness",
"humidity": "Humidity",
"visibility": "Visibility",
"wind_speed": "Wind speed",
"wind_direction": "Wind direction",
"min_temp": "Minimum temperature",
"max_temp": "Maximum temperature",
"atmospheric_pressure": "Atmospheric pressure"
@@ -271,7 +296,11 @@
"checking_update": "Checking for update",
"update_available": "Update available",
"no_update": "No update available",
"offline_mode": "Cannot check for update in offline mode"
"offline_mode": "Cannot check for update in offline mode",
"error": {
"title": "Failed to get update information",
"description": "An error occured"
}
},
"contact_us": "Contact Us",
"support_mue": "Support Mue",
@@ -296,7 +325,6 @@
"photo_packs": "Наборы фото",
"quote_packs": "Наборы цитат",
"preset_settings": "Пресеты настроек",
"themes": "Темы",
"no_items": "No items in this category",
"product": {
"overview": "Обзор",
@@ -315,16 +343,23 @@
},
"offline": {
"title": "Похоже, что вы офлайн",
"description": "Пожалуйста, подключитесь к интернету."
"description": "Пожалуйста, подключитесь к интернету"
}
},
"addons": {
"added": "Добавлен",
"empty": {
"title": "Здесь пусто",
"description": "Зайдите в магазин, чтобы найти что-то интересное."
"description": "Зайдите в магазин, чтобы найти что-то интересное"
},
"sideload": "Загрузить"
"sideload": "Загрузить",
"sort": {
"title": "Sort",
"newest": "Installed (Newest)",
"oldest": "Installed (Oldest)",
"a_z": "Alphabetical (A-Z)",
"z_a": "Alphabetical (Z-A)"
}
}
},
"update": {

View File

@@ -1,5 +1,5 @@
{
"tabname": "New Tab",
"tabname": "新标签页",
"widgets": {
"greeting": {
"morning": "早上好",
@@ -8,38 +8,40 @@
"christmas": "圣诞节快乐",
"newyear": "新年快乐",
"halloween": "万圣节快乐",
"birthday": "Happy Birthday"
"birthday": "生日快乐"
},
"background": {
"credit": "图像作者:",
"unsplash": "on Unsplash",
"information": "Information",
"download": "Download"
"unsplash": "@ Unsplash",
"pexels": "@ Pexels",
"information": "信息",
"download": "下载"
},
"search": "搜索",
"quicklinks": {
"new": "New Link",
"name": "Name",
"url": "URL",
"add": "Add",
"name_error": "Must provide name",
"url_error": "Must provide URL"
"new": "新快捷方式",
"name": "名称",
"url": "链接",
"add": "添加",
"name_error": "请输入名称",
"url_error": "请输入链接"
},
"date": {
"week": "Week"
"week": ""
},
"weather": {
"not_found": "Not Found"
"not_found": "未找到",
"meters": "meters"
},
"navbar": {
"tooltips": {
"update": "Update Patch Notes",
"refresh": "Refresh Page",
"feedback": "Feedback"
"update": "更新日志",
"refresh": "刷新页面",
"feedback": "用户反馈"
},
"notes": {
"title": "Notes",
"placeholder": "Type here"
"title": "备注",
"placeholder": "请键入内容"
}
}
},
@@ -47,7 +49,7 @@
"main": {
"title": "选项",
"loading": "载入中...",
"file_upload_error": "File is over 2MB",
"file_upload_error": "大小超过了 2MB",
"navbar": {
"settings": "设置",
"addons": "我的插件",
@@ -55,63 +57,63 @@
},
"error_boundary": {
"title": "错误",
"message": "Failed to load this component of Mue",
"message": "无法载入本板块",
"refresh": "刷新"
},
"settings": {
"enabled": "已启用",
"reminder": {
"title": "NOTICE",
"message": "In order for all of the changes to take place, the page must be refreshed."
"title": "注意",
"message": "刷新页面后设置才会生效"
},
"sections": {
"time": {
"title": "时间",
"format": "Format",
"type": "Type",
"format": "格式",
"type": "类型",
"digital": {
"title": "Digital",
"title": "数字时钟",
"seconds": "显示秒",
"twentyfourhour": "使用 24 小时制",
"twelvehour": "12 小时制下显示",
"zero": "加零补足二位数字"
},
"analogue": {
"analog": "Analogue",
"second_hand": "Seconds hand",
"minute_hand": "Minutes hand",
"hour_hand": "Hours hand",
"hour_marks": "Hour marks",
"minute_marks": "Minute marks"
"title": "模拟时钟",
"second_hand": "秒针",
"minute_hand": "分针",
"hour_hand": "时针",
"hour_marks": "时钟刻度",
"minute_marks": "分钟刻度"
},
"percentage_complete": "Percentage complete",
"percentage_complete": "经过时间百分比",
"date": {
"title": "Date",
"week_number": "Week number",
"day_of_week": "Day of week",
"datenth": "Date nth",
"title": "日期",
"week_number": "第几周",
"day_of_week": "星期几",
"datenth": "几日",
"type": {
"short": "Short",
"long": "Long"
"short": "简写",
"long": "全称"
},
"short_date": "Short date",
"short_format": "Short format",
"short_date": "简写日期",
"short_format": "简写格式",
"short_separator": {
"title": "Short separator",
"dots": "Dots",
"dash": "Dash",
"gaps": "Gaps",
"slashes": "Slashes"
"title": "简写分隔",
"dots": "",
"dash": "横杠",
"gaps": "空格",
"slashes": "斜杠"
}
}
},
"quote": {
"title": "名言",
"author_link": "Authour link",
"custom": "Custom quote",
"custom_author": "Custom authour",
"author_link": "出处链接",
"custom": "自定义名言",
"custom_author": "自定义出处",
"buttons": {
"title": "Buttons",
"title": "按钮",
"copy": "复制按钮",
"tweet": "发推按钮",
"favourite": "收藏按钮"
@@ -122,168 +124,195 @@
"events": "节日问候",
"default": "常规问候",
"name": "您在问候中的名字",
"birthday": "Birthday",
"birthday_age": "Birthday age",
"birthday_date": "Birthday date"
"birthday": "生日",
"birthday_age": "生日年龄",
"birthday_date": "生日日期"
},
"background": {
"title": "背景",
"ddg_proxy": "Use DuckDuckGo image proxy",
"transition": "Fade-in transition",
"category": "Category",
"ddg_proxy": "使用 DuckDuckGo 图像代理",
"transition": "渐变",
"photo_information": "Show photo information",
"category": "分类",
"buttons": {
"title": "Buttons",
"title": "按钮",
"view": "查看",
"favourite": "收藏",
"download": "下载"
},
"effects": {
"title": "Effects",
"title": "效果",
"blur": "调整模糊",
"brightness": "调整亮度"
"brightness": "调整亮度",
"filters": {
"title": "Background filter",
"amount": "Filter amount",
"grayscale": "Grayscale",
"sepia": "Sepia",
"invert": "Invert",
"saturate": "Saturate",
"contrast": "Contrast"
}
},
"type": {
"title": "Type",
"title": "来源",
"api": "API",
"custom_image": "Custom image",
"custom_colour": "Custom colour/gradient"
"custom_image": "自定义图像",
"custom_colour": "自定义背景颜色"
},
"source": {
"title": "Source",
"title": "来源",
"api": "背景来源",
"custom_background": "自定义背景",
"custom_colour": "自定义背景颜色",
"upload": "上传",
"add_colour": "添加颜色",
"disabled": "已禁用",
"loop_video": "Loop video",
"mute_video": "Mute video"
"loop_video": "循环播放",
"mute_video": "静音",
"quality": {
"title": "Quality",
"original": "Original",
"high": "High Quality",
"normal": "Normal Quality",
"datasaver": "Data Saver"
}
}
},
"search": {
"title": "搜索栏",
"search_engine": "搜索引擎",
"custom": "自定义搜索链接",
"autocomplete": "Autocomplete",
"autocomplete_provider": "Autocomplete Provider",
"voice_search": "语音搜索"
},
"weather": {
"title": "Weather",
"location": "Location",
"auto": "Auto",
"title": "天气",
"location": "位置",
"auto": "自动",
"temp_format": {
"title": "Temperature format",
"celsius": "Celsius",
"fahrenheit": "Fahrenheit",
"kelvin": "Kelvin"
"title": "温度单位",
"celsius": "摄氏度",
"fahrenheit": "华氏度",
"kelvin": "开尔文"
},
"extra_info": {
"title": "Extra information",
"show_location": "Show Location",
"title": "更多信息",
"show_location": "显示位置",
"show_description": "Show description",
"cloudiness": "Cloudiness",
"humidity": "Humidity",
"wind_speed": "Wind speed",
"min_temp": "Minimum temperature",
"max_temp": "Maximum temperature",
"atmospheric_pressure": "Atmospheric pressure"
"visibility": "Visibility",
"wind_speed": "风速",
"wind_direction": "Wind direction",
"min_temp": "最低温度",
"max_temp": "最高温度",
"atmospheric_pressure": "大气压"
}
},
"quicklinks": {
"title": "Quick Links",
"open_new": "Open in new tab",
"tooltip": "Tooltip"
"title": "快捷方式",
"open_new": "在新标签页打开",
"tooltip": "光标停留时下方显示标题"
},
"appearance": {
"title": "Appearance",
"title": "显示",
"theme": {
"title": "Theme",
"auto": "Auto",
"light": "Light",
"dark": "Dark"
"title": "主题",
"auto": "自动选择",
"light": "日间主题",
"dark": "夜间主题"
},
"animations": "动画",
"navbar": {
"title": "Navbar",
"notes": "Notes",
"refresh": "Refresh button"
"title": "右上方功能键",
"notes": "备忘录",
"refresh": "刷新键"
},
"font": {
"title": "Font",
"custom": "Custom font",
"google": "Import from Google Fonts",
"title": "字体",
"custom": "自定义字体",
"google": " Google Fonts 导入",
"weight": {
"title": "Font weight",
"thin": "Thin",
"extra_light": "Extra Light",
"light": "Light",
"normal": "Normal",
"medium": "Medium",
"semi_bold": "Semi-Bold",
"bold": "Bold",
"extra_bold": "Extra-Bold"
"title": "字体厚度",
"thin": "极细",
"extra_light": "细字",
"light": "较细",
"normal": "一般",
"medium": "中等",
"semi_bold": "较粗",
"bold": "粗体",
"extra_bold": "加粗"
},
"style": {
"title": "Font style",
"normal": "Normal",
"italic": "Italic",
"oblique": "Oblique"
"title": "字体样式",
"normal": "常规",
"italic": "意大利斜体",
"oblique": "伪斜体"
}
},
"accessibility": {
"title": "Accessibility",
"widget_zoom": "Widget zoom",
"toast_duration": "Toast duration",
"milliseconds": "milliseconds"
"title": "无障碍设定",
"widget_zoom": "小部件缩放",
"toast_duration": "窗口弹出时间长度",
"milliseconds": "毫秒"
}
},
"order": {
"title": "Widget Order"
"title": "小部件顺序"
},
"advanced": {
"title": "Advanced",
"title": "高级",
"offline_mode": "离线模式",
"data": "Data",
"data": "数据",
"reset_modal": {
"title": "WARNING",
"question": "Do you want to reset Mue?",
"information": "This will delete all data. If you wish to keep your data and preferences, please export them first.",
"cancel": "Cancel"
"title": "警告",
"question": "您是否想恢复 Mue 默认设定?",
"information": "本操作将删除所有数据。若您想保留数据及设置,请先将其导出。",
"cancel": "取消"
},
"customisation": "Customisation",
"custom_css": "Custom CSS",
"custom_js": "Custom JS",
"tab_name": "Tab name",
"experimental_warning": "Please note that the Mue team cannot provide support if you have experimental mode on. Please disable it first and see if the issue continues to occur before contacting support."
"customisation": "定制",
"custom_css": "自定义 CSS",
"custom_js": "自定义 JS",
"tab_name": "标签页名称",
"experimental_warning": "请注意 Mue 团队无法提供实验性功能的支持。若您遇到问题,请先关闭实验性功能,再寻求帮助。"
},
"experimental": {
"title": "实验性功能",
"warning": "These settings have not been fully tested/implemented and may not work correctly!",
"developer": "Developer"
"warning": "以下设置仍未完成编写或测试,可能无法正常运作!",
"developer": "开发者"
},
"language": {
"title": "语言",
"quote": "Quote language"
"quote": "名言语言"
},
"changelog": "Change Log",
"changelog": "更新日志",
"about": {
"title": "About",
"copyright": "Copyright",
"title": "关于",
"copyright": "版权",
"version": {
"title": "Version",
"checking_update": "Checking for update",
"update_available": "Update available",
"no_update": "No update available",
"offline_mode": "Cannot check for update in offline mode"
"title": "版本",
"checking_update": "正在检查更新……",
"update_available": "可下载更新",
"no_update": "无可下载更新",
"offline_mode": "离线模式下不能检查更新",
"error": {
"title": "Failed to get update information",
"description": "An error occured"
}
},
"contact_us": "Contact Us",
"support_mue": "Support Mue",
"contact_us": "联系我们",
"support_mue": "给我们打赏",
"resources_used": {
"title": "Resources used",
"bg_images": "Offline background images",
"welcome_img": "Welcome image",
"pin_icon": "Pin icon"
"title": "使用资源",
"bg_images": "离线背景",
"welcome_img": "欢迎图像",
"pin_icon": "大头针图标"
},
"contributors": "Contributors",
"supporters": "Supporters",
"photographers": "Photographers"
"contributors": "贡献者",
"supporters": "打赏者",
"photographers": "摄影者"
}
},
"buttons": {
@@ -296,8 +325,7 @@
"photo_packs": "图片包",
"quote_packs": "名言包",
"preset_settings": "预设设定",
"themes": "主题",
"no_items": "No items in this category",
"no_items": "本类别为空",
"product": {
"overview": "总览",
"information": "信息",
@@ -324,7 +352,14 @@
"title": "这里空空如也",
"description": "请访问插件市场来添加插件。"
},
"sideload": "上传插件"
"sideload": "上传插件",
"sort": {
"title": "Sort",
"newest": "Installed (Newest)",
"oldest": "Installed (Oldest)",
"a_z": "Alphabetical (A-Z)",
"z_a": "Alphabetical (Z-A)"
}
}
},
"update": {
@@ -341,22 +376,22 @@
"contact_support": "点此联系我们"
},
"welcome": {
"title": "Welcome to",
"information": "Information",
"thankyoumessage1": "Thank you for installing Mue Tab,",
"thankyoumessage2": "we hope you enjoy your time with our extension.",
"support": "Support",
"close": "Close"
"title": "欢迎使用",
"information": "信息",
"thankyoumessage1": "感谢您安装 Mue Tab",
"thankyoumessage2": "祝您使用愉快。",
"support": "支持",
"close": "关闭"
},
"feedback": {
"title": "Give us feedback",
"question_one": "How would you rate your experience of this Mue build?",
"question_two": "What bugs did you encounter in your use of Mue?",
"question_three": "How likely would you be to recommend this version of Mue to a friend or colleague?",
"question_four": "What do you want adding to the next Mue build?",
"not_filled": "Question box must be filled",
"success": "Sent successfully!",
"submit": "Submit"
"title": "给我们反馈",
"question_one": "您使用本 Mue 版本感受如何?",
"question_two": "您首次使用 Mue 时遇到过问题吗?",
"question_three": "您会向朋友和同事推荐 Mue 吗?",
"question_four": "您觉得下一个 Mue 版本需要什么改进?",
"not_filled": "必须回答本问题",
"success": "提交成功!",
"submit": "提交"
}
},
"toasts": {

5
vercel.json Normal file
View File

@@ -0,0 +1,5 @@
{
"github": {
"silent": true
}
}

View File

@@ -2,7 +2,6 @@ const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
//const ESLintPlugin = require('eslint-webpack-plugin');
module.exports = {
entry: path.resolve(__dirname, './src/index.js'),
@@ -72,6 +71,5 @@ module.exports = {
filename: '[name].[chunkhash].css',
chunkFilename: '[id].[chunkhash].chunk.css'
}),
//new ESLintPlugin()
]
};