mirror of
https://github.com/mue/mue.git
synced 2026-06-18 06:27:36 +02:00
Compare commits
99 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4449957fe6 | ||
|
|
5b00b3d859 | ||
|
|
aad568bd28 | ||
|
|
4e1347ad4e | ||
|
|
8073d8325a | ||
|
|
dc1f1fab45 | ||
|
|
dc442ef917 | ||
|
|
796896571d | ||
|
|
cad3f53140 | ||
|
|
b0da5cfa75 | ||
|
|
c2ca979971 | ||
|
|
1e5f288d42 | ||
|
|
b2c94924a2 | ||
|
|
de1797c662 | ||
|
|
db3081efc5 | ||
|
|
dcddd78164 | ||
|
|
335a6864b1 | ||
|
|
1f6dc34ee6 | ||
|
|
fbc9189cba | ||
|
|
586b6f8700 | ||
|
|
1d6013f738 | ||
|
|
c1ef3e3528 | ||
|
|
4b57229396 | ||
|
|
e721babcf7 | ||
|
|
8a816516c9 | ||
|
|
bd09542b34 | ||
|
|
84dad33548 | ||
|
|
588021cf92 | ||
|
|
6a9eccaed0 | ||
|
|
299547842a | ||
|
|
ba2dc61a5d | ||
|
|
2fd2e06bac | ||
|
|
08bfa2772d | ||
|
|
9b9c2e74f6 | ||
|
|
63e49b79cd | ||
|
|
da6ebb8c60 | ||
|
|
b1fbaa7601 | ||
|
|
7327382497 | ||
|
|
cb129238cb | ||
|
|
2ac08a7cf6 | ||
|
|
eeb0870feb | ||
|
|
260d1928d8 | ||
|
|
fa19570c36 | ||
|
|
ed76fcccc8 | ||
|
|
6b4922b825 | ||
|
|
1dc5e7375b | ||
|
|
7628e769be | ||
|
|
7470ca9e3a | ||
|
|
f49cf1f65b | ||
|
|
f21ee5c5ba | ||
|
|
5ea158c21d | ||
|
|
3aa17f0c30 | ||
|
|
e8698f2141 | ||
|
|
9b5946038a | ||
|
|
31a666fe22 | ||
|
|
b9663831fd | ||
|
|
48268111d0 | ||
|
|
af335adc23 | ||
|
|
e88cd0b765 | ||
|
|
a1b6832747 | ||
|
|
7942c367a7 | ||
|
|
f2f683201d | ||
|
|
84dbe5cb69 | ||
|
|
90927c9e8f | ||
|
|
1af688c489 | ||
|
|
1715e7d089 | ||
|
|
4b18ea74a7 | ||
|
|
6c7ab96350 | ||
|
|
b26a261644 | ||
|
|
7ce71497bb | ||
|
|
696b58f9bc | ||
|
|
e45600b4db | ||
|
|
7126a2e295 | ||
|
|
e323d4c692 | ||
|
|
b795ceb33d | ||
|
|
b26265eceb | ||
|
|
2afc9159cf | ||
|
|
8f629b1ef9 | ||
|
|
79a0ec8df9 | ||
|
|
133db009aa | ||
|
|
8f017cda32 | ||
|
|
38546ef074 | ||
|
|
57cc5de60a | ||
|
|
84571682b0 | ||
|
|
d97a3236cf | ||
|
|
1bc1729bdd | ||
|
|
ff94d66163 | ||
|
|
48979d4a75 | ||
|
|
1c4a0fa9c1 | ||
|
|
cf176bccda | ||
|
|
f3cf6bd0b3 | ||
|
|
7a03a00013 | ||
|
|
6382202dbf | ||
|
|
942644dc40 | ||
|
|
eb5bc8a843 | ||
|
|
6a147ff890 | ||
|
|
03670e8773 | ||
|
|
6a64f31940 | ||
|
|
11129f2d70 |
17
.github/dependabot.yml
vendored
Normal file
17
.github/dependabot.yml
vendored
Normal 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
|
||||
59
README.md
59
README.md
@@ -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://discord.gg/zv8C9F8) []()
|
||||
[](/LICENSE) [](https://discord.gg/zv8C9F8) []()
|
||||
<br>
|
||||
[](https://microsoftedge.microsoft.com/addons/detail/aepnglgjfokepefimhbnibfjekidhmja) [](https://addons.mozilla.org/firefox/addon/mue) [](https://chrome.google.com/webstore/detail/mue/bngmbednanpcfochchhgbkookpiaiaid)
|
||||
|
||||
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
|
||||
|
||||
@@ -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'"
|
||||
}
|
||||
|
||||
@@ -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'"
|
||||
}
|
||||
|
||||
48
package.json
48
package.json
@@ -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": {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
75
src/components/helpers/autocomplete/Autocomplete.jsx
Normal file
75
src/components/helpers/autocomplete/Autocomplete.jsx
Normal 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}
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
50
src/components/helpers/autocomplete/autocomplete.scss
Normal file
50
src/components/helpers/autocomplete/autocomplete.scss
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
import './tooltip.scss';
|
||||
|
||||
export default function Tooltip(props) {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
8
src/components/modals/main/marketplace/Lightbox.jsx
Normal file
8
src/components/modals/main/marketplace/Lightbox.jsx
Normal file
@@ -0,0 +1,8 @@
|
||||
export default function Lightbox(props) {
|
||||
return (
|
||||
<>
|
||||
<span className='closeModal' onClick={props.modalClose}>×</span>
|
||||
<img src={props.img} className='lightboximg' draggable={false} alt='Item screenshot'/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -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)} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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)} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
import LocalMallIcon from '@material-ui/icons/LocalMall';
|
||||
|
||||
import FileUpload from '../../settings/FileUpload';
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
|
||||
.addToMue {
|
||||
@extend %storebutton;
|
||||
margin-top: 5px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.sideload {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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'>
|
||||
|
||||
@@ -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} />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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>
|
||||
• <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>
|
||||
|
||||
<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>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -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>
|
||||
</>
|
||||
|
||||
@@ -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} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
</>
|
||||
|
||||
@@ -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}/>
|
||||
</>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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 = () => {
|
||||
|
||||
@@ -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' />
|
||||
</>
|
||||
|
||||
@@ -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'/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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'/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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' />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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'/>
|
||||
|
||||
@@ -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' />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import React from 'react';
|
||||
|
||||
import Added from '../marketplace/sections/Added';
|
||||
import Sideload from '../marketplace/sections/Sideload';
|
||||
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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'];
|
||||
}
|
||||
|
||||
|
||||
@@ -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}
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -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' />
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,15 @@
|
||||
svg:hover+.infoCard {
|
||||
display: block;
|
||||
}
|
||||
|
||||
a {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.infoCard {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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'>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
|
||||
17
src/components/widgets/search/autocomplete_providers.json
Normal file
17
src/components/widgets/search/autocomplete_providers.json
Normal 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="
|
||||
}
|
||||
]
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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",
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
23
src/components/widgets/weather/WindDirectionIcon.jsx
Normal file
23
src/components/widgets/weather/WindDirectionIcon.jsx
Normal 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;
|
||||
}
|
||||
11
src/index.js
11
src/index.js
@@ -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(
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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
|
||||
}
|
||||
]
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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]);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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
5
vercel.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"github": {
|
||||
"silent": true
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
]
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user