fix: author loading before quote

- Make author div not load if quote is empty
- photoinformation taking too much of the screen
- more transitions and consistent transitions
- running prettier across all files

Co-authored-by: David Ralph <me@davidcralph.co.uk>
This commit is contained in:
alexsparkes 2022-04-11 22:57:07 +01:00
parent 4498f5b934
commit 7bb48ebc8e
84 changed files with 2630 additions and 2323 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@ -1,4 +1,4 @@
module.exports = {
extends: 'react-app',
parser: '@babel/eslint-parser'
parser: '@babel/eslint-parser',
};

View File

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

View File

@ -12,76 +12,95 @@ Mue is a fast, open and free-to-use browser extension that gives a new, fresh an
<br>
## NOTICE
This is the branch for the next version of Mue, 7.0. All development is occuring in this branch which will be merged into main when it is finished. If you want the current code, see the main branch.
## Table of contents
* [Screenshots](#screenshot)
* [Features](#features)
* [Planned Features](#planned-features)
* [Installation](#installation)
* [Chrome](#chrome)
* [Firefox](#firefox)
* [Edge Chromium](#edge-chromium)
* [Whale](#whale)
* [Other](#other)
* [Contributing](#development)
* [Translations](#translations)
* [Credits](#credits)
* [Developers](#developers)
* [Translators](#translators)
* [Contributors](#contributors)
* [Resources](#resources)
- [Screenshots](#screenshot)
- [Features](#features)
- [Planned Features](#planned-features)
- [Installation](#installation)
- [Chrome](#chrome)
- [Firefox](#firefox)
- [Edge Chromium](#edge-chromium)
- [Whale](#whale)
- [Other](#other)
- [Contributing](#development)
- [Translations](#translations)
- [Credits](#credits)
- [Developers](#developers)
- [Translators](#translators)
- [Contributors](#contributors)
- [Resources](#resources)
## Screenshots
![Screenshot](assets/screenshot.webp)
![Settings Modal](assets/screenshot2.webp)
## Features
* Fast and free
* Supports multiple browsers
* Actively developed and open source
* Automatically updating [API](https://github.com/mue/api) with new photos, quotes and offline mode
* Widgets such as search bar, weather, quick links, clock, date, quote, greeting
* Settings - enable/disable various features and customise parts of Mue
* Navbar with copy button, favourite background, notes feature etc
* [Marketplace](https://github.com/mue/marketplace) - download custom photo packs, quote packs and preset settings made by the community
- Fast and free
- Supports multiple browsers
- Actively developed and open source
- Automatically updating [API](https://github.com/mue/api) with new photos, quotes and offline mode
- Widgets such as search bar, weather, quick links, clock, date, quote, greeting
- Settings - enable/disable various features and customise parts of Mue
- Navbar with copy button, favourite background, notes feature etc
- [Marketplace](https://github.com/mue/marketplace) - download custom photo packs, quote packs and preset settings made by the community
### Planned Features
Please see our [roadmap](https://trello.com/b/w7zhS7Hi/mue-50).
## Installation
*A demo of the tab can be found [here](https://demo.muetab.com), and the latest GitHub commit build [here](https://mue.vercel.app)*
_A demo of the tab can be found [here](https://demo.muetab.com), and the latest GitHub commit build [here](https://mue.vercel.app)_
### Chrome
[![Chrome Web Store Logo](assets/chrome.png)](https://chrome.google.com/webstore/detail/mue/bngmbednanpcfochchhgbkookpiaiaid)
<br>
[Chrome Web Store](https://chrome.google.com/webstore/detail/mue/bngmbednanpcfochchhgbkookpiaiaid)
### Firefox
[![Firefox Add-ons Logo](assets/firefox.png)](https://addons.mozilla.org/firefox/addon/mue)
<br>
[Firefox Add-ons](https://addons.mozilla.org/firefox/addon/mue)
### Edge (Chromium)
[Microsoft Edge Addons](https://microsoftedge.microsoft.com/addons/detail/aepnglgjfokepefimhbnibfjekidhmja)
### Whale
[Whale Store](https://store.whale.naver.com/detail/ecllekeilcmicbfkkiknfdddbogibbnc)
### Other
[GitHub Releases](https://github.com/mue/mue/releases)
## Development
Please see the [documentation](https://docs.muetab.com/development#mue-tab).
### Translations
Please see the [documentation](https://docs.muetab.com/translations).
## Credits
### Developers
[David Ralph](https://github.com/davidcralph) - Lead development, photographer <br/>
[Alex Sparkes](https://github.com/alexsparkes) - Name, lead design, photographer <br/>
[Isaac Saunders](https://github.com/eartharoid) - QA, development, photographer <br/>
[Wessel Tip](https://github.com/Wessel) - Development <br/>
### Translators
[Wessel Tip](https://github.com/Wessel), [Heimen Stoffels](https://github.com/Vistaus) - Dutch <br/>
[Alex Sparkes](https://github.com/alexsparkes), [Maxime](https://github.com/exiam) - French <br/>
[Anders](https://github.com/FuryingFox) - Norwegian <br/>
@ -90,10 +109,14 @@ Please see the [documentation](https://docs.muetab.com/translations).
[Austin Huang](https://github.com/austinhuang0131) - Chinese (Simplified) <br/>
[FreeFun](https://github.com/xXFreeFunXx) - German <br/>
[Aksal](https://github.com/aksalsf) - Indonesian <br/>
### Contributors
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
[Pexels](https://pexels.com), [Unsplash](https://unsplash.com) - Stock photos used for offline mode <br/>
[Undraw](https://undraw.co) - Welcome modal images

View File

@ -1,6 +1,16 @@
module.exports = {
presets: ['@babel/preset-env', ['@babel/preset-react', {
runtime: 'automatic'
}]],
plugins: ['@babel/transform-runtime', '@babel/plugin-transform-react-inline-elements', '@babel/plugin-transform-react-constant-elements']
presets: [
'@babel/preset-env',
[
'@babel/preset-react',
{
runtime: 'automatic',
},
],
],
plugins: [
'@babel/transform-runtime',
'@babel/plugin-transform-react-inline-elements',
'@babel/plugin-transform-react-constant-elements',
],
};

View File

@ -4,7 +4,7 @@ chrome.runtime.setUninstallURL('https://muetab.com/uninstall');
chrome.runtime.onInstalled.addListener((details) => {
if (details.reason === 'install') {
chrome.tabs.create({
url: chrome.runtime.getURL('index.html')
url: chrome.runtime.getURL('index.html'),
});
}
});

View File

@ -4,7 +4,7 @@ browser.runtime.setUninstallURL('https://muetab.com/uninstall');
browser.runtime.onInstalled.addListener((details) => {
if (details.reason === 'install') {
browser.tabs.create({
url: browser.runtime.getURL('index.html')
url: browser.runtime.getURL('index.html'),
});
}
});

View File

@ -20,6 +20,6 @@
"content_security_policy": "script-src 'self' https://api.bing.com https://www.google.com; object-src 'self'",
"background": {
"persistent": false,
"scripts": [ "background-chrome.js" ]
"scripts": ["background-chrome.js"]
}
}

View File

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

View File

@ -7,7 +7,10 @@ fs.readdirSync('../src/translations').forEach((file) => {
return;
}
const newdata = merge(require('../src/translations/en_GB.json'), require('../src/translations/' + file));
const newdata = merge(
require('../src/translations/en_GB.json'),
require('../src/translations/' + file),
);
fs.writeFileSync('../src/translations/' + file, JSON.stringify(newdata, null, 2));
// add new line
fs.appendFileSync('../src/translations/' + file, '\n');

View File

@ -18,7 +18,7 @@ export default class App extends PureComponent {
if (!localStorage.getItem('firstRun') || !localStorage.getItem('stats')) {
moveSettings();
window.location.reload();
}
}
loadSettings();
@ -34,11 +34,17 @@ export default class App extends PureComponent {
render() {
return (
<>
{(localStorage.getItem('background') === 'true') ? <Background/> : null}
<ToastContainer position='bottom-right' autoClose={localStorage.getItem('toastDisplayTime') || 2500} newestOnTop={true} closeOnClick pauseOnFocusLoss/>
<div id='center'>
<Widgets/>
<Modals/>
{localStorage.getItem('background') === 'true' ? <Background /> : null}
<ToastContainer
position="bottom-right"
autoClose={localStorage.getItem('toastDisplayTime') || 2500}
newestOnTop={true}
closeOnClick
pauseOnFocusLoss
/>
<div id="center">
<Widgets />
<Modals />
</div>
</>
);

View File

@ -12,20 +12,22 @@ export default class Autocomplete extends PureComponent {
this.state = {
filtered: [],
input: '',
autocompleteDisabled: (localStorage.getItem('autocomplete') !== 'true')
autocompleteDisabled: localStorage.getItem('autocomplete') !== 'true',
};
}
onChange = (e) => {
if (this.state.autocompleteDisabled) {
return this.setState({
input: e.target.value
input: e.target.value,
});
}
this.setState({
filtered: this.props.suggestions.filter((suggestion) => suggestion.toLowerCase().indexOf(e.target.value.toLowerCase()) > -1),
input: e.target.value
filtered: this.props.suggestions.filter(
(suggestion) => suggestion.toLowerCase().indexOf(e.target.value.toLowerCase()) > -1,
),
input: e.target.value,
});
this.props.onChange(e.target.value);
@ -34,14 +36,14 @@ export default class Autocomplete extends PureComponent {
onClick = (e) => {
this.setState({
filtered: [],
input: e.target.innerText
input: e.target.innerText,
});
this.props.onClick({
preventDefault: () => e.preventDefault(),
target: {
value: e.target.innerText
}
value: e.target.innerText,
},
});
};
@ -49,7 +51,7 @@ export default class Autocomplete extends PureComponent {
EventBus.on('refresh', (data) => {
if (data === 'search') {
this.setState({
autocompleteDisabled: (localStorage.getItem('autocomplete') !== 'true')
autocompleteDisabled: localStorage.getItem('autocomplete') !== 'true',
});
}
});
@ -65,7 +67,7 @@ export default class Autocomplete extends PureComponent {
// length will only be > 0 if enabled
if (this.state.filtered.length > 0 && this.state.input.length > 0) {
autocomplete = (
<div className='suggestions'>
<div className="suggestions">
{this.state.filtered.map((suggestion) => (
<div key={suggestion} onClick={this.onClick}>
{suggestion}
@ -76,8 +78,16 @@ export default class Autocomplete extends PureComponent {
}
return (
<div style={{display: 'flex', flexFlow: 'column'}}>
<input type='text' onChange={this.onChange} value={this.state.input} placeholder={this.props.placeholder || ''} autoComplete='off' spellCheck={false} id={this.props.id || ''} />
<div style={{ display: 'flex', flexFlow: 'column' }}>
<input
type="text"
onChange={this.onChange}
value={this.state.input}
placeholder={this.props.placeholder || ''}
autoComplete="off"
spellCheck={false}
id={this.props.id || ''}
/>
{autocomplete}
</div>
);

View File

@ -6,9 +6,9 @@ export default function Preview(props) {
const getMessage = (text) => variables.language.getMessage(variables.languagecode, text);
return (
<div className='preview-mode'>
<span className='title'>{getMessage('modals.main.settings.reminder.title')}</span>
<span className='subtitle'>{getMessage('modals.welcome.preview.description')}</span>
<div className="preview-mode">
<span className="title">{getMessage('modals.main.settings.reminder.title')}</span>
<span className="subtitle">{getMessage('modals.welcome.preview.description')}</span>
<button onClick={() => props.setup()}>{getMessage('modals.welcome.preview.continue')}</button>
</div>
);

View File

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

View File

@ -1,11 +1,11 @@
import { useState } from "react";
import { useFloating, flip, offset, shift } from "@floating-ui/react-dom";
import "./tooltip.scss";
import { useState } from 'react';
import { useFloating, flip, offset, shift } from '@floating-ui/react-dom';
import './tooltip.scss';
export default function Tooltip({ children, title, style, placement }) {
const [showTooltip, setShowTooltip] = useState(false);
const { x, y, reference, floating, strategy } = useFloating({
placement: placement || "bottom",
placement: placement || 'bottom',
middleware: [flip(), offset(15), shift()],
});
@ -25,8 +25,8 @@ export default function Tooltip({ children, title, style, placement }) {
ref={floating}
style={{
position: strategy,
top: y ?? "",
left: x ?? "",
top: y ?? '',
left: x ?? '',
}}
className="tooltipTitle"
>

View File

@ -93,19 +93,16 @@ export default class Modals extends PureComponent {
<Main modalClose={() => this.toggleModal('mainModal', false)} />
</Modal>
<Modal
closeTimeoutMS={300}
onRequestClose={() => this.closeWelcome()}
isOpen={this.state.welcomeModal}
className="Modal welcomemodal mainModal"
overlayClassName="Overlay welcomeoverlay"
shouldCloseOnOverlayClick={false}
ariaHideApp={false}
>
<Welcome
modalClose={() => this.closeWelcome()}
modalSkip={() => this.previewWelcome()}
/>
</Modal>
closeTimeoutMS={300}
onRequestClose={() => this.closeWelcome()}
isOpen={this.state.welcomeModal}
className="Modal welcomemodal mainModal"
overlayClassName="Overlay welcomeoverlay"
shouldCloseOnOverlayClick={false}
ariaHideApp={false}
>
<Welcome modalClose={() => this.closeWelcome()} modalSkip={() => this.previewWelcome()} />
</Modal>
{this.state.preview ? <Preview setup={() => window.location.reload()} /> : null}
{/*variables.keybinds.toggleModal && variables.keybinds.toggleModal !== '' ? <Hotkeys keyName={variables.keybinds.toggleModal} onKeyDown={() => this.toggleModal('mainModal', (this.state.mainModal === true ? false : true))}/> : null*/}
</>

View File

@ -1,26 +1,24 @@
import variables from "modules/variables";
import variables from 'modules/variables';
export default function Collection({ items, toggleFunction }) {
return [
<div className='collection starWars'>
<div className='content'>
<div className="tags">
<div className="collection starWars">
<div className="content">
<div className="tags">
<div className="tag">
<span>Star Wars</span>
</div>
</div>
<span className='title'>Star Wars Collection</span>
<span className='subtitle'>A Collection of stuff inspired by the film franchise star wars..</span>
<button>Explore Collection</button>
</div>
</div>,
<div className="items">
<span className="title">Star Wars Collection</span>
<span className="subtitle">
A Collection of stuff inspired by the film franchise star wars..
</span>
<button>Explore Collection</button>
</div>
</div>,
<div className="items">
{items.map((item) => (
<div
className="item"
onClick={() => toggleFunction(item)}
key={item.name}
>
<div className="item" onClick={() => toggleFunction(item)} key={item.name}>
<img
alt="icon"
draggable="false"
@ -33,7 +31,7 @@ export default function Collection({ items, toggleFunction }) {
<div className="tag">
<span>{item.author}</span>
</div>
<div className='moreTag'>
<div className="moreTag">
<span>1</span>
</div>
</div>

View File

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

View File

@ -1,5 +1,5 @@
import variables from "modules/variables";
import { PureComponent } from "react";
import variables from 'modules/variables';
import { PureComponent } from 'react';
import {
MdSettings as Settings,
MdOutlineInsertPhoto as Photos,
@ -9,18 +9,18 @@ import {
MdArrowBack,
MdDownload,
MdOpenInNew,
} from "react-icons/md";
import { TextField } from "@mui/material";
import { toast } from "react-toastify";
import SettingsItem from "../../../main/settings/SettingsItem";
} from 'react-icons/md';
import { TextField } from '@mui/material';
import { toast } from 'react-toastify';
import SettingsItem from '../../../main/settings/SettingsItem';
import { saveFile } from "modules/helpers/settings/modals";
import Tooltip from "../../../../helpers/tooltip/Tooltip";
import { saveFile } from 'modules/helpers/settings/modals';
import Tooltip from '../../../../helpers/tooltip/Tooltip';
import FileUpload from "../../settings/FileUpload";
import Dropdown from "../../settings/Dropdown";
import FileUpload from '../../settings/FileUpload';
import Dropdown from '../../settings/Dropdown';
import "../../../welcome/welcome.scss";
import '../../../welcome/welcome.scss';
export default class Create extends PureComponent {
constructor() {
@ -28,18 +28,18 @@ export default class Create extends PureComponent {
this.state = {
currentTab: 1,
addonMetadata: {
name: "",
description: "",
type: "",
version: "",
author: "",
icon_url: "",
screenshot_url: "",
name: '',
description: '',
type: '',
version: '',
author: '',
icon_url: '',
screenshot_url: '',
},
addonData: "",
addonData: '',
settingsClasses: {
current: "toggle lightTheme",
json: "toggle lightTheme",
current: 'toggle lightTheme',
json: 'toggle lightTheme',
},
};
}
@ -64,17 +64,17 @@ export default class Create extends PureComponent {
let settings = {};
Object.keys(data).forEach((key) => {
if (
key === "statsData" ||
key === "firstRun" ||
key === "showWelcome" ||
key === "language" ||
key === "installed" ||
key === "stats" ||
key === "backup_settings" ||
key === "showReminder" ||
key === "experimental" ||
key === "debugtimeout" ||
key === "quotelanguage"
key === 'statsData' ||
key === 'firstRun' ||
key === 'showWelcome' ||
key === 'language' ||
key === 'installed' ||
key === 'stats' ||
key === 'backup_settings' ||
key === 'showReminder' ||
key === 'experimental' ||
key === 'debugtimeout' ||
key === 'quotelanguage'
) {
return;
}
@ -84,14 +84,12 @@ export default class Create extends PureComponent {
this.setState({
addonData: settings,
settingsClasses: {
current: input ? "toggle lightTheme active" : "toggle lightTheme",
json: input ? "toggle lightTheme active" : "toggle lightTheme",
current: input ? 'toggle lightTheme active' : 'toggle lightTheme',
json: input ? 'toggle lightTheme active' : 'toggle lightTheme',
},
});
toast(
variables.language.getMessage(variables.languagecode, "toasts.imported")
);
toast(variables.language.getMessage(variables.languagecode, 'toasts.imported'));
}
updateQuotePackType(type) {
@ -104,7 +102,7 @@ export default class Create extends PureComponent {
icon_url: this.state.addonMetadata.icon_url,
screenshot_url: this.state.addonMetadata.screenshot_url,
};
if (type === "quotePack") {
if (type === 'quotePack') {
this.setState({
addonMetadata: {
addonMetadata,
@ -117,9 +115,9 @@ export default class Create extends PureComponent {
addonMetadata,
},
addonData: {
url: "",
name: "",
author: "",
url: '',
name: '',
author: '',
},
});
}
@ -128,45 +126,38 @@ export default class Create extends PureComponent {
updateQuotePackAPI(type, data) {
this.setState({
addonData: {
url: type === "url" ? data : this.state.addonData.url || "",
name: type === "name" ? data : this.state.addonData.name || "",
author: type === "author" ? data : this.state.addonData.author || "",
url: type === 'url' ? data : this.state.addonData.url || '',
name: type === 'name' ? data : this.state.addonData.name || '',
author: type === 'author' ? data : this.state.addonData.author || '',
},
});
}
importQuotes() {
this.setState({
addonData: JSON.parse(localStorage.getItem("customQuote")) || [],
addonData: JSON.parse(localStorage.getItem('customQuote')) || [],
});
toast(
variables.language.getMessage(variables.languagecode, "toasts.imported")
);
toast(variables.language.getMessage(variables.languagecode, 'toasts.imported'));
}
importPhotos() {
let data = [];
try {
const current =
JSON.parse(localStorage.getItem("customBackground")) || [];
const current = JSON.parse(localStorage.getItem('customBackground')) || [];
data = current.map((item) => {
return {
photographer: "???",
location: "???",
photographer: '???',
location: '???',
url: {
default: item,
},
};
});
toast(
variables.language.getMessage(variables.languagecode, "toasts.imported")
);
toast(variables.language.getMessage(variables.languagecode, 'toasts.imported'));
} catch (e) {
console.log(e);
toast(
variables.language.getMessage(variables.languagecode, "toasts.error")
);
toast(variables.language.getMessage(variables.languagecode, 'toasts.error'));
}
this.setState({
@ -180,23 +171,20 @@ export default class Create extends PureComponent {
name: this.state.addonMetadata.name,
description: this.state.addonMetadata.description,
type:
this.state.addonMetadata.type === "quote_api"
? "quotes"
: this.state.addonMetadata.type,
this.state.addonMetadata.type === 'quote_api' ? 'quotes' : this.state.addonMetadata.type,
version: this.state.addonMetadata.version,
author: this.state.addonMetadata.author,
icon_url: this.state.addonMetadata.icon_url,
screenshot_url: this.state.addonMetadata.screenshot_url,
[this.state.addonMetadata.type]: this.state.addonData,
},
this.state.addonMetadata.name + ".json"
this.state.addonMetadata.name + '.json',
);
}
render() {
let tabContent;
const getMessage = (text) =>
variables.language.getMessage(variables.languagecode, text);
const getMessage = (text) => variables.language.getMessage(variables.languagecode, text);
const chooseType = (
<>
@ -204,8 +192,7 @@ export default class Create extends PureComponent {
<div className="content">
<span className="title">Help Centre</span>
<span className="subtitle">
Home of all docs and guides on creating addons for Mue's
marketplace
Home of all docs and guides on creating addons for Mue's marketplace
</span>
</div>
<button>
@ -215,28 +202,17 @@ export default class Create extends PureComponent {
</div>
<div className="themesToggleArea">
<div className="options">
<div
className="toggle lightTheme"
onClick={() => this.changeTab(2, "photos")}
>
<div className="toggle lightTheme" onClick={() => this.changeTab(2, 'photos')}>
<Photos />
<span>{getMessage("modals.main.marketplace.photo_packs")}</span>
<span>{getMessage('modals.main.marketplace.photo_packs')}</span>
</div>
<div
className="toggle lightTheme"
onClick={() => this.changeTab(2, "quotes")}
>
<div className="toggle lightTheme" onClick={() => this.changeTab(2, 'quotes')}>
<Quotes />
<span>{getMessage("modals.main.marketplace.quote_packs")}</span>
<span>{getMessage('modals.main.marketplace.quote_packs')}</span>
</div>
<div
className="toggle lightTheme"
onClick={() => this.changeTab(2, "settings")}
>
<div className="toggle lightTheme" onClick={() => this.changeTab(2, 'settings')}>
<Settings />
<span>
{getMessage("modals.main.marketplace.preset_settings")}
</span>
<span>{getMessage('modals.main.marketplace.preset_settings')}</span>
</div>
</div>
</div>
@ -256,19 +232,13 @@ export default class Create extends PureComponent {
const setMetadata = (data, type) => {
this.setState({
addonMetadata: {
name: type === "name" ? data : this.state.addonMetadata.name,
description:
type === "description"
? data
: this.state.addonMetadata.description,
version: type === "version" ? data : this.state.addonMetadata.version,
author: type === "author" ? data : this.state.addonMetadata.author,
icon_url:
type === "icon_url" ? data : this.state.addonMetadata.icon_url,
name: type === 'name' ? data : this.state.addonMetadata.name,
description: type === 'description' ? data : this.state.addonMetadata.description,
version: type === 'version' ? data : this.state.addonMetadata.version,
author: type === 'author' ? data : this.state.addonMetadata.author,
icon_url: type === 'icon_url' ? data : this.state.addonMetadata.icon_url,
screenshot_url:
type === "screenshot_url"
? data
: this.state.addonMetadata.screenshot_url,
type === 'screenshot_url' ? data : this.state.addonMetadata.screenshot_url,
type: this.state.addonMetadata.type,
},
});
@ -278,7 +248,7 @@ export default class Create extends PureComponent {
<>
<div className="smallBanner">
<div className="content">
<span className="title" style={{ textTransform: "capitalize" }}>
<span className="title" style={{ textTransform: 'capitalize' }}>
Create {this.state.addonMetadata.type} Pack
</span>
<span className="subtitle">Description of what is being made</span>
@ -288,120 +258,97 @@ export default class Create extends PureComponent {
<MdDownload />
</button>
</div>
<SettingsItem
title={getMessage("modals.main.addons.create.metadata.name")}
>
<SettingsItem title={getMessage('modals.main.addons.create.metadata.name')}>
<TextField
label={getMessage("modals.main.addons.create.metadata.name")}
label={getMessage('modals.main.addons.create.metadata.name')}
varient="outlined"
InputLabelProps={{ shrink: true }}
value={this.state.addonMetadata.name}
onInput={(e) => setMetadata(e.target.value, "name")}
onInput={(e) => setMetadata(e.target.value, 'name')}
/>
</SettingsItem>
<SettingsItem
title={getMessage("modals.main.marketplace.product.version")}
>
<SettingsItem title={getMessage('modals.main.marketplace.product.version')}>
<TextField
label={getMessage("modals.main.marketplace.product.version")}
label={getMessage('modals.main.marketplace.product.version')}
varient="outlined"
InputLabelProps={{ shrink: true }}
value={this.state.addonMetadata.version}
onInput={(e) => setMetadata(e.target.value, "version")}
onInput={(e) => setMetadata(e.target.value, 'version')}
/>
</SettingsItem>
<SettingsItem
title={getMessage("modals.main.marketplace.product.author")}
>
<SettingsItem title={getMessage('modals.main.marketplace.product.author')}>
<TextField
label={getMessage("modals.main.marketplace.product.author")}
label={getMessage('modals.main.marketplace.product.author')}
varient="outlined"
InputLabelProps={{ shrink: true }}
value={this.state.addonMetadata.author}
onInput={(e) => setMetadata(e.target.value, "author")}
onInput={(e) => setMetadata(e.target.value, 'author')}
/>
</SettingsItem>
<SettingsItem
title={getMessage("modals.main.addons.create.metadata.icon_url")}
>
<SettingsItem title={getMessage('modals.main.addons.create.metadata.icon_url')}>
<TextField
label={getMessage("modals.main.addons.create.metadata.icon_url")}
label={getMessage('modals.main.addons.create.metadata.icon_url')}
varient="outlined"
InputLabelProps={{ shrink: true }}
value={this.state.addonMetadata.icon_url}
onInput={(e) => setMetadata(e.target.value, "icon_url")}
onInput={(e) => setMetadata(e.target.value, 'icon_url')}
/>
</SettingsItem>
<SettingsItem
title={getMessage(
"modals.main.addons.create.metadata.screenshot_url"
)}
>
<SettingsItem title={getMessage('modals.main.addons.create.metadata.screenshot_url')}>
<TextField
label={getMessage(
"modals.main.addons.create.metadata.screenshot_url"
)}
label={getMessage('modals.main.addons.create.metadata.screenshot_url')}
varient="outlined"
InputLabelProps={{ shrink: true }}
value={this.state.addonMetadata.screenshot_url}
onInput={(e) => setMetadata(e.target.value, "screenshot_url")}
onInput={(e) => setMetadata(e.target.value, 'screenshot_url')}
/>
</SettingsItem>
<SettingsItem
title={getMessage("modals.main.addons.create.metadata.description")}
>
<SettingsItem title={getMessage('modals.main.addons.create.metadata.description')}>
<TextField
label={getMessage("modals.main.addons.create.metadata.description")}
label={getMessage('modals.main.addons.create.metadata.description')}
varient="outlined"
InputLabelProps={{ shrink: true }}
multiline
spellCheck={false}
rows={4}
value={this.state.addonMetadata.description}
onInput={(e) => setMetadata(e.target.value, "description")}
onInput={(e) => setMetadata(e.target.value, 'description')}
/>
</SettingsItem>
<div className="createButtons">
<button onClick={() => this.changeTab(1)}>
{getMessage("modals.welcome.buttons.previous")}
{getMessage('modals.welcome.buttons.previous')}
</button>
<button
onClick={() => this.changeTab(this.state.addonMetadata.type)}
disabled={nextDescriptionDisabled}
>
{getMessage("modals.welcome.buttons.next")}
{getMessage('modals.welcome.buttons.next')}
</button>
</div>
</>
);
// settings
const nextSettingsDisabled = this.state.addonData === "";
const nextSettingsDisabled = this.state.addonData === '';
const importSettings = (
<>
<SettingsItem
final={true}
title={getMessage("modals.welcome.sections.settings.title")}
>
<SettingsItem final={true} title={getMessage('modals.welcome.sections.settings.title')}>
<div className="themesToggleArea">
<div className="options" style={{ maxWidth: "512px" }}>
<div className="options" style={{ maxWidth: '512px' }}>
<div
className={this.state.settingsClasses.current}
onClick={() => this.importSettings()}
>
<ExportIcon />
<span>
{getMessage("modals.main.addons.create.settings.current")}
</span>
<span>{getMessage('modals.main.addons.create.settings.current')}</span>
</div>
<div
className={this.state.settingsClasses.json}
onClick={() => document.getElementById("file-input").click()}
onClick={() => document.getElementById('file-input').click()}
>
<ImportIcon />
<span>
{getMessage("modals.main.addons.create.settings.json")}
</span>
<span>{getMessage('modals.main.addons.create.settings.json')}</span>
</div>
</div>
</div>
@ -411,20 +358,15 @@ export default class Create extends PureComponent {
id="file-input"
type="settings"
accept="application/json"
loadFunction={(e) =>
this.importSettings(JSON.parse(e.target.result))
}
loadFunction={(e) => this.importSettings(JSON.parse(e.target.result))}
/>
</SettingsItem>
<div className="createButtons">
<button onClick={() => this.changeTab(2)}>
{getMessage("modals.welcome.buttons.previous")}
{getMessage('modals.welcome.buttons.previous')}
</button>
<button
onClick={() => this.changeTab(3)}
disabled={nextSettingsDisabled}
>
{getMessage("modals.welcome.buttons.next")}
<button onClick={() => this.changeTab(3)} disabled={nextSettingsDisabled}>
{getMessage('modals.welcome.buttons.next')}
</button>
</div>
</>
@ -432,68 +374,68 @@ export default class Create extends PureComponent {
// quotes
const nextQuotesDisabled = !(
(this.state.addonMetadata.type === "quote_api" &&
this.state.addonData.url !== "" &&
this.state.addonData.name !== "" &&
this.state.addonData.author !== "") ||
(this.state.addonMetadata.type === "quotes" &&
this.state.addonData.quotes !== "")
(this.state.addonMetadata.type === 'quote_api' &&
this.state.addonData.url !== '' &&
this.state.addonData.name !== '' &&
this.state.addonData.author !== '') ||
(this.state.addonMetadata.type === 'quotes' && this.state.addonData.quotes !== '')
);
const addQuotes = (
<>
<SettingsItem final={true} title={getMessage("modals.main.addons.create.quotes.title")}>
<SettingsItem final={true} title={getMessage('modals.main.addons.create.quotes.title')}>
<Dropdown
label={getMessage("modals.main.settings.sections.time.type")}
label={getMessage('modals.main.settings.sections.time.type')}
noSetting
onChange={(e) => this.updateQuotePackType(e)}
>
<option value="quotes">
{getMessage("modals.main.addons.create.quotes.local.title")}
{getMessage('modals.main.addons.create.quotes.local.title')}
</option>
<option value="quote_api">
{getMessage("modals.main.addons.create.quotes.api.title")}
{getMessage('modals.main.addons.create.quotes.api.title')}
</option>
</Dropdown>
</SettingsItem>
{this.state.addonMetadata.type === "quote_api" ? (
{this.state.addonMetadata.type === 'quote_api' ? (
<>
<TextField
label={getMessage("modals.main.addons.create.quotes.api.url")}
label={getMessage('modals.main.addons.create.quotes.api.url')}
varient="outlined"
InputLabelProps={{ shrink: true }}
value={this.state.addonData.url}
onInput={(e) => this.updateQuotePack(e.target.value, "url")}
onInput={(e) => this.updateQuotePack(e.target.value, 'url')}
/>
<TextField
label={getMessage("modals.main.addons.create.quotes.api.name")}
label={getMessage('modals.main.addons.create.quotes.api.name')}
varient="outlined"
InputLabelProps={{ shrink: true }}
value={this.state.addonData.name}
onInput={(e) => this.updateQuotePack(e.target.value, "name")}
onInput={(e) => this.updateQuotePack(e.target.value, 'name')}
/>
<TextField
label={getMessage("modals.main.addons.create.quotes.api.author")}
label={getMessage('modals.main.addons.create.quotes.api.author')}
varient="outlined"
InputLabelProps={{ shrink: true }}
value={this.state.addonData.author}
onInput={(e) => this.updateQuotePack(e.target.value, "author")}
onInput={(e) => this.updateQuotePack(e.target.value, 'author')}
/>
<br />
<br />
</>
) : (
<SettingsItem final={true} title={getMessage("modals.main.addons.create.settings.current")} >
<SettingsItem
final={true}
title={getMessage('modals.main.addons.create.settings.current')}
>
<div className="themesToggleArea">
<div className="options">
<div
onClick={() => this.importQuotes()}
className="toggle lightTheme"
style={{ width: "60%", margin: "10px 0 10px 0" }}
style={{ width: '60%', margin: '10px 0 10px 0' }}
>
<ExportIcon />
<span>
{getMessage("modals.main.addons.create.settings.current")}
</span>
<span>{getMessage('modals.main.addons.create.settings.current')}</span>
</div>
</div>
</div>
@ -501,13 +443,10 @@ export default class Create extends PureComponent {
)}
<div className="createButtons">
<button onClick={() => this.changeTab(2)}>
{getMessage("modals.welcome.buttons.previous")}
{getMessage('modals.welcome.buttons.previous')}
</button>
<button
onClick={() => this.changeTab(3)}
disabled={nextQuotesDisabled}
>
{getMessage("modals.welcome.buttons.next")}
<button onClick={() => this.changeTab(3)} disabled={nextQuotesDisabled}>
{getMessage('modals.welcome.buttons.next')}
</button>
</div>
</>
@ -515,26 +454,24 @@ export default class Create extends PureComponent {
// photos
const nextPhotosDisabled = !(
this.state.addonData.photos !== "" && this.state.addonData.photos !== []
this.state.addonData.photos !== '' && this.state.addonData.photos !== []
);
const addPhotos = (
<>
<SettingsItem
final={true}
title={getMessage("modals.main.addons.create.photos.title")}
subtitle={"Import from custom settings."}
title={getMessage('modals.main.addons.create.photos.title')}
subtitle={'Import from custom settings.'}
>
<div className="themesToggleArea">
<div className="options">
<div
onClick={() => this.importPhotos()}
className="toggle lightTheme"
style={{ width: "60%", margin: "10px 0 10px 0" }}
style={{ width: '60%', margin: '10px 0 10px 0' }}
>
<ExportIcon />
<span>
{getMessage("modals.main.addons.create.settings.current")}
</span>
<span>{getMessage('modals.main.addons.create.settings.current')}</span>
</div>
</div>
</div>
@ -542,13 +479,10 @@ export default class Create extends PureComponent {
<br />
<div className="createButtons">
<button onClick={() => this.changeTab(2)}>
{getMessage("modals.welcome.buttons.previous")}
{getMessage('modals.welcome.buttons.previous')}
</button>
<button
onClick={() => this.changeTab(3)}
disabled={nextPhotosDisabled}
>
{getMessage("modals.welcome.buttons.next")}
<button onClick={() => this.changeTab(3)} disabled={nextPhotosDisabled}>
{getMessage('modals.welcome.buttons.next')}
</button>
</div>
</>
@ -558,12 +492,11 @@ export default class Create extends PureComponent {
<>
<div className="smallBanner">
<div className="content">
<span className="title" style={{ textTransform: "capitalize" }}>
<span className="title" style={{ textTransform: 'capitalize' }}>
Next step, Publishing...
</span>
<span className="subtitle">
Visit the Mue Knowledgebase on information on how to publish your
newly created addon.
Visit the Mue Knowledgebase on information on how to publish your newly created addon.
</span>
</div>
<button>
@ -577,12 +510,10 @@ export default class Create extends PureComponent {
<div
onClick={() => this.downloadAddon()}
className="toggle lightTheme"
style={{ width: "60%", margin: "10px 0 10px 0" }}
style={{ width: '60%', margin: '10px 0 10px 0' }}
>
<ExportIcon />
<span>
{getMessage("modals.main.addons.create.finish.download")}
</span>
<span>{getMessage('modals.main.addons.create.finish.download')}</span>
</div>
</div>
</div>
@ -591,14 +522,14 @@ export default class Create extends PureComponent {
<button
onClick={() =>
this.changeTab(
this.state.addonMetadata.type === "quote_api"
? "quotes"
: this.state.addonMetadata.type
this.state.addonMetadata.type === 'quote_api'
? 'quotes'
: this.state.addonMetadata.type,
)
}
disabled={nextDescriptionDisabled}
>
{getMessage("modals.welcome.buttons.previous")}
{getMessage('modals.welcome.buttons.previous')}
</button>
</div>
{/*<button
@ -619,13 +550,13 @@ export default class Create extends PureComponent {
case 2:
tabContent = writeDescription;
break;
case "settings":
case 'settings':
tabContent = importSettings;
break;
case "quotes":
case 'quotes':
tabContent = addQuotes;
break;
case "photos":
case 'photos':
tabContent = addPhotos;
break;
case 3:
@ -648,9 +579,7 @@ export default class Create extends PureComponent {
</Tooltip>
</div>
)}
<span className="mainTitle">
{getMessage("modals.main.addons.create.other_title")}
</span>
<span className="mainTitle">{getMessage('modals.main.addons.create.other_title')}</span>
</div>
{tabContent}
</>

View File

@ -146,7 +146,7 @@ h5 {
gap: 15px;
align-items: center;
&:hover {
opacity: .8;
opacity: 0.8;
cursor: pointer;
}
}
@ -187,7 +187,7 @@ h5 {
gap: 15px;
align-items: center;
&:hover {
opacity: .8;
opacity: 0.8;
cursor: pointer;
}
}

View File

@ -3,7 +3,6 @@
margin-left: 20px;
}
p.description {
margin-top: 0;
max-width: 800px;

View File

@ -102,4 +102,4 @@ table {
svg {
font-size: 1.5rem !important;
}
}
}

View File

@ -26,4 +26,4 @@
display: flex;
flex-flow: row;
justify-content: space-around;
}
}

View File

@ -8,23 +8,26 @@ export default class Checkbox extends PureComponent {
constructor(props) {
super(props);
this.state = {
checked: (localStorage.getItem(this.props.name) === 'true')
checked: localStorage.getItem(this.props.name) === 'true',
};
}
handleChange = () => {
const value = (this.state.checked !== true);
const value = this.state.checked !== true;
localStorage.setItem(this.props.name, value);
this.setState({
checked: value
checked: value,
});
if (this.props.onChange) {
this.props.onChange(value);
}
variables.stats.postEvent('setting', `${this.props.name} ${(this.state.checked === true) ? 'enabled' : 'disabled'}`);
variables.stats.postEvent(
'setting',
`${this.props.name} ${this.state.checked === true ? 'enabled' : 'disabled'}`,
);
if (this.props.element) {
if (!document.querySelector(this.props.element)) {
@ -34,13 +37,22 @@ export default class Checkbox extends PureComponent {
}
EventBus.dispatch('refresh', this.props.category);
}
};
render() {
return (
<>
<FormControlLabel
control={<CheckboxUI name={this.props.name} color='primary' className='checkbox' checked={this.state.checked} onChange={this.handleChange} disabled={this.props.disabled || false} />}
control={
<CheckboxUI
name={this.props.name}
color="primary"
className="checkbox"
checked={this.state.checked}
onChange={this.handleChange}
disabled={this.props.disabled || false}
/>
}
label={this.props.text}
/>
</>

View File

@ -9,7 +9,7 @@ export default class Dropdown extends PureComponent {
super(props);
this.state = {
value: localStorage.getItem(this.props.name) || this.props.children[0].props.value,
title: ''
title: '',
};
this.dropdown = createRef();
}
@ -24,13 +24,13 @@ export default class Dropdown extends PureComponent {
variables.stats.postEvent('setting', `${this.props.name} from ${this.state.value} to ${value}`);
this.setState({
value
value,
});
if (!this.props.noSetting) {
localStorage.setItem(this.props.name, value);
}
if (this.props.onChange) {
this.props.onChange(value);
}
@ -43,7 +43,7 @@ export default class Dropdown extends PureComponent {
}
EventBus.dispatch('refresh', this.props.category);
}
};
render() {
const id = 'dropdown' + this.props.name;
@ -52,10 +52,24 @@ export default class Dropdown extends PureComponent {
return (
<FormControl fullWidth className={id}>
<InputLabel id={id}>{label}</InputLabel>
<Select labelId={id} id={this.props.name} value={this.state.value} label={label} onChange={this.onChange} ref={this.dropdown} key={id}>
{this.props.manual ? this.props.children : this.props.children.map((e, index) => {
return e ? <MenuItem key={index} value={e.props ? e.props.value : ''}>{e.props ? e.props.children : ''}</MenuItem> : null
})}
<Select
labelId={id}
id={this.props.name}
value={this.state.value}
label={label}
onChange={this.onChange}
ref={this.dropdown}
key={id}
>
{this.props.manual
? this.props.children
: this.props.children.map((e, index) => {
return e ? (
<MenuItem key={index} value={e.props ? e.props.value : ''}>
{e.props ? e.props.children : ''}
</MenuItem>
) : null;
})}
</Select>
</FormControl>
);

View File

@ -28,6 +28,13 @@ export default class FileUpload extends PureComponent {
}
render() {
return <input id={this.props.id} type='file' style={{ display: 'none' }} accept={this.props.accept} />;
return (
<input
id={this.props.id}
type="file"
style={{ display: 'none' }}
accept={this.props.accept}
/>
);
}
}

View File

@ -7,17 +7,53 @@ export default function KeybindInput(props) {
const getButton = () => {
if (!value) {
return <button className='cleanButton' style={{ visibility: 'hidden' }} onClick={() => props.action('reset', props.setting)}><MdCancel/></button>;;
} else if (value === variables.language.getMessage(variables.languagecode, 'modals.main.settings.sections.keybinds.recording')) {
return <button className='cleanButton' onClick={() => props.action('cancel', props.setting)}><MdCancel/></button>;
return (
<button
className="cleanButton"
style={{ visibility: 'hidden' }}
onClick={() => props.action('reset', props.setting)}
>
<MdCancel />
</button>
);
} else if (
value ===
variables.language.getMessage(
variables.languagecode,
'modals.main.settings.sections.keybinds.recording',
)
) {
return (
<button className="cleanButton" onClick={() => props.action('cancel', props.setting)}>
<MdCancel />
</button>
);
} else {
return <button className='cleanButton' onClick={() => props.action('reset', props.setting)}><MdCancel/></button>;
return (
<button className="cleanButton" onClick={() => props.action('reset', props.setting)}>
<MdCancel />
</button>
);
}
}
};
return (
<>
<TextField label={props.name} onClick={() => props.action('listen', props.setting)} value={value || variables.language.getMessage(variables.languagecode, 'modals.main.settings.sections.keybinds.click_to_record')} readOnly spellCheck={false} varient='outlined' InputLabelProps={{ shrink: true }} />
<TextField
label={props.name}
onClick={() => props.action('listen', props.setting)}
value={
value ||
variables.language.getMessage(
variables.languagecode,
'modals.main.settings.sections.keybinds.click_to_record',
)
}
readOnly
spellCheck={false}
varient="outlined"
InputLabelProps={{ shrink: true }}
/>
{getButton()}
</>
);

View File

@ -1,6 +1,12 @@
import variables from 'modules/variables';
import { PureComponent } from 'react';
import { Radio as RadioUI, RadioGroup, FormControlLabel, FormControl, FormLabel } from '@mui/material';
import {
Radio as RadioUI,
RadioGroup,
FormControlLabel,
FormControl,
FormLabel,
} from '@mui/material';
import EventBus from 'modules/helpers/eventbus';
@ -8,10 +14,10 @@ export default class Radio extends PureComponent {
constructor(props) {
super(props);
this.state = {
value: localStorage.getItem(this.props.name)
value: localStorage.getItem(this.props.name),
};
}
handleChange = (e) => {
const { value } = e.target;
@ -21,15 +27,21 @@ export default class Radio extends PureComponent {
if (this.props.name === 'language') {
// old tab name
if (localStorage.getItem('tabName') === variables.language.getMessage(variables.languagecode, 'tabname')) {
localStorage.setItem('tabName', require(`translations/${value.replace('-', '_')}.json`).tabname);
if (
localStorage.getItem('tabName') ===
variables.language.getMessage(variables.languagecode, 'tabname')
) {
localStorage.setItem(
'tabName',
require(`translations/${value.replace('-', '_')}.json`).tabname,
);
}
}
localStorage.setItem(this.props.name, value);
this.setState({
value
value,
});
if (this.props.onChange) {
@ -37,7 +49,7 @@ export default class Radio extends PureComponent {
}
variables.stats.postEvent('setting', `${this.props.name} from ${this.state.value} to ${value}`);
if (this.props.element) {
if (!document.querySelector(this.props.element)) {
document.querySelector('.reminder-info').style.display = 'flex';
@ -46,15 +58,30 @@ export default class Radio extends PureComponent {
}
EventBus.dispatch('refresh', this.props.category);
}
};
render() {
return (
<FormControl component='fieldset'>
<FormLabel className={this.props.smallTitle ? 'radio-title-small' : 'radio-title'} component='legend'>{this.props.title}</FormLabel>
<RadioGroup aria-label={this.props.name} name={this.props.name} onChange={this.handleChange} value={this.state.value}>
<FormControl component="fieldset">
<FormLabel
className={this.props.smallTitle ? 'radio-title-small' : 'radio-title'}
component="legend"
>
{this.props.title}
</FormLabel>
<RadioGroup
aria-label={this.props.name}
name={this.props.name}
onChange={this.handleChange}
value={this.state.value}
>
{this.props.options.map((option) => (
<FormControlLabel value={option.value} control={<RadioUI/>} label={option.name} key={option.name} />
<FormControlLabel
value={option.value}
control={<RadioUI />}
label={option.name}
key={option.name}
/>
))}
</RadioGroup>
</FormControl>

View File

@ -8,19 +8,22 @@ export default class Switch extends PureComponent {
constructor(props) {
super(props);
this.state = {
checked: (localStorage.getItem(this.props.name) === 'true')
checked: localStorage.getItem(this.props.name) === 'true',
};
}
handleChange = () => {
const value = (this.state.checked !== true);
const value = this.state.checked !== true;
localStorage.setItem(this.props.name, value);
this.setState({
checked: value
checked: value,
});
variables.stats.postEvent('setting', `${this.props.name} ${(this.state.checked === true) ? 'enabled' : 'disabled'}`);
variables.stats.postEvent(
'setting',
`${this.props.name} ${this.state.checked === true ? 'enabled' : 'disabled'}`,
);
if (this.props.element) {
if (!document.querySelector(this.props.element)) {
@ -30,15 +33,22 @@ export default class Switch extends PureComponent {
}
EventBus.dispatch('refresh', this.props.category);
}
};
render() {
return (
<>
<FormControlLabel
control={<SwitchUI name={this.props.name} color='primary' checked={this.state.checked} onChange={this.handleChange} />}
control={
<SwitchUI
name={this.props.name}
color="primary"
checked={this.state.checked}
onChange={this.handleChange}
/>
}
label={this.props.text}
labelPlacement='start'
labelPlacement="start"
/>
</>
);

View File

@ -9,13 +9,13 @@ export default class Text extends PureComponent {
constructor(props) {
super(props);
this.state = {
value: localStorage.getItem(this.props.name) || ''
value: localStorage.getItem(this.props.name) || '',
};
}
handleChange = (e) => {
let { value } = e.target;
// Alex wanted font to work with montserrat and Montserrat, so I made it work
if (this.props.upperCaseFirst === true) {
value = value.charAt(0).toUpperCase() + value.slice(1);
@ -23,7 +23,7 @@ export default class Text extends PureComponent {
localStorage.setItem(this.props.name, value);
this.setState({
value
value,
});
if (this.props.element) {
@ -34,25 +34,47 @@ export default class Text extends PureComponent {
}
EventBus.dispatch('refresh', this.props.category);
}
};
resetItem = () => {
this.handleChange({
target: {
value: this.props.default || ''
}
value: this.props.default || '',
},
});
toast(variables.language.getMessage(variables.languagecode, 'toasts.reset'));
}
};
render() {
return (
<>
{(this.props.textarea === true) ?
<TextField label={this.props.title} value={this.state.value} onChange={this.handleChange} varient='outlined' multiline spellCheck={false} minRows={4} maxRows={10} InputLabelProps={{ shrink: true }} />
: <TextField label={this.props.title} value={this.state.value} onChange={this.handleChange} varient='outlined' InputLabelProps={{ shrink: true }} />
}
<span className='link' onClick={this.resetItem}>{variables.language.getMessage(variables.languagecode, 'modals.main.settings.buttons.reset')}</span>
{this.props.textarea === true ? (
<TextField
label={this.props.title}
value={this.state.value}
onChange={this.handleChange}
varient="outlined"
multiline
spellCheck={false}
minRows={4}
maxRows={10}
InputLabelProps={{ shrink: true }}
/>
) : (
<TextField
label={this.props.title}
value={this.state.value}
onChange={this.handleChange}
varient="outlined"
InputLabelProps={{ shrink: true }}
/>
)}
<span className="link" onClick={this.resetItem}>
{variables.language.getMessage(
variables.languagecode,
'modals.main.settings.buttons.reset',
)}
</span>
</>
);
}

View File

@ -134,7 +134,7 @@ export default class About extends PureComponent {
<span className="mainTitle">
{this.getMessage('modals.main.settings.sections.about.title')}
</span>
<div className='settingsRow' style={{ justifyContent: 'center' }}>
<div className="settingsRow" style={{ justifyContent: 'center' }}>
<div style={{ display: 'flex', flexFlow: 'column', gap: '5px' }}>
<img draggable="false" className="aboutLogo" src={this.state.image} alt="Logo" />
<span className="title">
@ -179,10 +179,10 @@ export default class About extends PureComponent {
{this.getMessage('modals.main.settings.sections.about.contact_us')}
</span>
<div className="aboutContact">
<a class='donateButton' href='https://muetab.com/contact'>
<MdContactPage />
Form
</a>
<a class="donateButton" href="https://muetab.com/contact">
<MdContactPage />
Form
</a>
<Tooltip title={'Email'}>
<a
href={'mailto:' + variables.constants.EMAIL}
@ -217,13 +217,16 @@ export default class About extends PureComponent {
<span className="title">
{this.getMessage('modals.main.settings.sections.about.support_mue')}
</span>
<p>As Mue is entirely free, we rely on donations to cover pay the server bills and fund development</p>
<p>
As Mue is entirely free, we rely on donations to cover pay the server bills and fund
development
</p>
<div className="aboutContact">
<a class='donateButton' href={variables.constants.DONATE_LINK}>
<a class="donateButton" href={variables.constants.DONATE_LINK}>
<BiDonateHeart />
Donate
</a>
<Tooltip title={'Github Sponsors'}>
</a>
<Tooltip title={'Github Sponsors'}>
<a
href={'https://discord.gg/' + variables.constants.DISCORD_SERVER}
target="_blank"

View File

@ -1,27 +1,24 @@
import variables from "modules/variables";
import { PureComponent } from "react";
import Modal from "react-modal";
import { MenuItem } from "@mui/material";
import variables from 'modules/variables';
import { PureComponent } from 'react';
import Modal from 'react-modal';
import { MenuItem } from '@mui/material';
import {
MdUpload as ImportIcon,
MdDownload as ExportIcon,
MdRestartAlt as ResetIcon,
} from "react-icons/md";
} from 'react-icons/md';
import {
exportSettings,
importSettings,
} from "modules/helpers/settings/modals";
import { exportSettings, importSettings } from 'modules/helpers/settings/modals';
import Checkbox from "../Checkbox";
import FileUpload from "../FileUpload";
import Text from "../Text";
import Switch from "../Switch";
import ResetModal from "../ResetModal";
import Dropdown from "../Dropdown";
import SettingsItem from "../SettingsItem";
import Checkbox from '../Checkbox';
import FileUpload from '../FileUpload';
import Text from '../Text';
import Switch from '../Switch';
import ResetModal from '../ResetModal';
import Dropdown from '../Dropdown';
import SettingsItem from '../SettingsItem';
const time_zones = require("components/widgets/time/timezones.json");
const time_zones = require('components/widgets/time/timezones.json');
export default class AdvancedSettings extends PureComponent {
constructor() {
@ -32,52 +29,41 @@ export default class AdvancedSettings extends PureComponent {
}
render() {
const getMessage = (text) =>
variables.language.getMessage(variables.languagecode, text);
const getMessage = (text) => variables.language.getMessage(variables.languagecode, text);
return (
<>
<span className="mainTitle">
{getMessage("modals.main.settings.sections.advanced.title")}
{getMessage('modals.main.settings.sections.advanced.title')}
</span>
<SettingsItem
title={getMessage(
"modals.main.settings.sections.advanced.offline_mode"
)}
>
<SettingsItem title={getMessage('modals.main.settings.sections.advanced.offline_mode')}>
<Switch
name="offlineMode"
text={getMessage(
"modals.main.settings.sections.advanced.offline_mode"
)}
text={getMessage('modals.main.settings.sections.advanced.offline_mode')}
element=".other"
/>
</SettingsItem>
{localStorage.getItem("welcomePreview") !== "true" ? (
{localStorage.getItem('welcomePreview') !== 'true' ? (
<div className="settingsRow">
<div className="content">
<span className="title">
{getMessage("modals.main.settings.sections.advanced.data")}
{getMessage('modals.main.settings.sections.advanced.data')}
</span>
<span className="subtitle">
{getMessage(
"modals.main.settings.sections.advanced.experimental_warning"
)}
{getMessage('modals.main.settings.sections.advanced.experimental_warning')}
</span>
</div>
<div className="action activityButtons">
<button onClick={() => this.setState({ resetModal: true })}>
{getMessage("modals.main.settings.buttons.reset")}
{getMessage('modals.main.settings.buttons.reset')}
<ResetIcon />
</button>
<button onClick={() => exportSettings()}>
{getMessage("modals.main.settings.buttons.export")}
{getMessage('modals.main.settings.buttons.export')}
<ExportIcon />
</button>
<button
onClick={() => document.getElementById("file-input").click()}
>
{getMessage("modals.main.settings.buttons.import")}
<button onClick={() => document.getElementById('file-input').click()}>
{getMessage('modals.main.settings.buttons.import')}
<ImportIcon />
</button>
</div>
@ -86,16 +72,12 @@ export default class AdvancedSettings extends PureComponent {
<SettingsItem title="This should really be in time">
<Dropdown
name="timezone"
label={getMessage(
"modals.main.settings.sections.advanced.timezone.title"
)}
label={getMessage('modals.main.settings.sections.advanced.timezone.title')}
category="timezone"
manual={true}
>
<MenuItem value="auto">
{getMessage(
"modals.main.settings.sections.advanced.timezone.automatic"
)}
{getMessage('modals.main.settings.sections.advanced.timezone.automatic')}
</MenuItem>
{time_zones.map((timezone) => (
<MenuItem value={timezone} key={timezone}>
@ -104,15 +86,11 @@ export default class AdvancedSettings extends PureComponent {
))}
</Dropdown>
</SettingsItem>
<SettingsItem
title={getMessage("modals.main.settings.sections.advanced.tab_name")}
>
<SettingsItem title={getMessage('modals.main.settings.sections.advanced.tab_name')}>
<Text
title={getMessage(
"modals.main.settings.sections.advanced.tab_name"
)}
title={getMessage('modals.main.settings.sections.advanced.tab_name')}
name="tabName"
default={getMessage("tabname")}
default={getMessage('tabname')}
category="other"
/>
</SettingsItem>
@ -122,15 +100,9 @@ export default class AdvancedSettings extends PureComponent {
type="settings"
loadFunction={(e) => importSettings(e)}
/>
<SettingsItem
title={getMessage(
"modals.main.settings.sections.advanced.custom_css"
)}
>
<SettingsItem title={getMessage('modals.main.settings.sections.advanced.custom_css')}>
<Text
title={getMessage(
"modals.main.settings.sections.advanced.custom_css"
)}
title={getMessage('modals.main.settings.sections.advanced.custom_css')}
name="customcss"
textarea={true}
category="other"
@ -139,18 +111,16 @@ export default class AdvancedSettings extends PureComponent {
<div className="settingsRow">
<div className="content">
<span className="title">
{getMessage("modals.main.settings.sections.experimental.title")}
{getMessage('modals.main.settings.sections.experimental.title')}
</span>
<span className="subtitle">
{getMessage(
"modals.main.settings.sections.advanced.experimental_warning"
)}
{getMessage('modals.main.settings.sections.advanced.experimental_warning')}
</span>
</div>
<div className="action">
<Switch
name="experimental"
text={getMessage("modals.main.settings.enabled")}
text={getMessage('modals.main.settings.enabled')}
element=".other"
/>
</div>

View File

@ -1,53 +1,52 @@
import variables from "modules/variables";
import variables from 'modules/variables';
import Checkbox from "../Checkbox";
import Dropdown from "../Dropdown";
import Radio from "../Radio";
import Slider from "../Slider";
import Text from "../Text";
import SettingsItem from "../SettingsItem";
import Checkbox from '../Checkbox';
import Dropdown from '../Dropdown';
import Radio from '../Radio';
import Slider from '../Slider';
import Text from '../Text';
import SettingsItem from '../SettingsItem';
import { values } from "modules/helpers/settings/modals";
import { values } from 'modules/helpers/settings/modals';
export default function AppearanceSettings() {
const getMessage = (text) =>
variables.language.getMessage(variables.languagecode, text);
const getMessage = (text) => variables.language.getMessage(variables.languagecode, text);
const themeOptions = [
{
name: getMessage("modals.main.settings.sections.appearance.theme.auto"),
value: "auto",
name: getMessage('modals.main.settings.sections.appearance.theme.auto'),
value: 'auto',
},
{
name: getMessage("modals.main.settings.sections.appearance.theme.light"),
value: "light",
name: getMessage('modals.main.settings.sections.appearance.theme.light'),
value: 'light',
},
{
name: getMessage("modals.main.settings.sections.appearance.theme.dark"),
value: "dark",
name: getMessage('modals.main.settings.sections.appearance.theme.dark'),
value: 'dark',
},
];
const styleOptions = [
{
name: "Legacy",
value: "legacy",
name: 'Legacy',
value: 'legacy',
},
{
name: "New",
value: "new",
name: 'New',
value: 'new',
},
];
return (
<>
<span className="mainTitle">
{getMessage("modals.main.settings.sections.appearance.title")}
{getMessage('modals.main.settings.sections.appearance.title')}
</span>
<div className="settingsRow">
<div className="content">
<span className="title">
{getMessage("modals.main.settings.sections.appearance.theme.title")}
{getMessage('modals.main.settings.sections.appearance.theme.title')}
</span>
<span className="subtitle">subtitle</span>
</div>
@ -58,96 +57,66 @@ export default function AppearanceSettings() {
<div className="settingsRow">
<div className="content">
<span className="title">
{getMessage("modals.main.settings.sections.appearance.font.title")}
{getMessage('modals.main.settings.sections.appearance.font.title')}
</span>
<span className="subtitle">subtitle</span>
</div>
<div className="action">
<Checkbox
name="fontGoogle"
text={getMessage(
"modals.main.settings.sections.appearance.font.google"
)}
text={getMessage('modals.main.settings.sections.appearance.font.google')}
category="other"
/>
<Text
title={getMessage(
"modals.main.settings.sections.appearance.font.custom"
)}
title={getMessage('modals.main.settings.sections.appearance.font.custom')}
name="font"
upperCaseFirst={true}
category="other"
/>
<Dropdown
label={getMessage(
"modals.main.settings.sections.appearance.font.weight.title"
)}
label={getMessage('modals.main.settings.sections.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">
{getMessage(
"modals.main.settings.sections.appearance.font.weight.thin"
)}
{getMessage('modals.main.settings.sections.appearance.font.weight.thin')}
</option>
<option value="200">
{getMessage(
"modals.main.settings.sections.appearance.font.weight.extra_light"
)}
{getMessage('modals.main.settings.sections.appearance.font.weight.extra_light')}
</option>
<option value="300">
{getMessage(
"modals.main.settings.sections.appearance.font.weight.light"
)}
{getMessage('modals.main.settings.sections.appearance.font.weight.light')}
</option>
<option value="400">
{getMessage(
"modals.main.settings.sections.appearance.font.weight.normal"
)}
{getMessage('modals.main.settings.sections.appearance.font.weight.normal')}
</option>
<option value="500">
{getMessage(
"modals.main.settings.sections.appearance.font.weight.medium"
)}
{getMessage('modals.main.settings.sections.appearance.font.weight.medium')}
</option>
<option value="600">
{getMessage(
"modals.main.settings.sections.appearance.font.weight.semi_bold"
)}
{getMessage('modals.main.settings.sections.appearance.font.weight.semi_bold')}
</option>
<option value="700">
{getMessage(
"modals.main.settings.sections.appearance.font.weight.bold"
)}
{getMessage('modals.main.settings.sections.appearance.font.weight.bold')}
</option>
<option value="800">
{getMessage(
"modals.main.settings.sections.appearance.font.weight.extra_bold"
)}
{getMessage('modals.main.settings.sections.appearance.font.weight.extra_bold')}
</option>
</Dropdown>
<Dropdown
label={getMessage(
"modals.main.settings.sections.appearance.font.style.title"
)}
label={getMessage('modals.main.settings.sections.appearance.font.style.title')}
name="fontstyle"
category="other"
>
<option value="normal">
{getMessage(
"modals.main.settings.sections.appearance.font.style.normal"
)}
{getMessage('modals.main.settings.sections.appearance.font.style.normal')}
</option>
<option value="italic">
{getMessage(
"modals.main.settings.sections.appearance.font.style.italic"
)}
{getMessage('modals.main.settings.sections.appearance.font.style.italic')}
</option>
<option value="oblique">
{getMessage(
"modals.main.settings.sections.appearance.font.style.oblique"
)}
{getMessage('modals.main.settings.sections.appearance.font.style.oblique')}
</option>
</Dropdown>
</div>
@ -167,17 +136,13 @@ export default function AppearanceSettings() {
<div className="settingsRow">
<div className="content">
<span className="title">
{getMessage(
"modals.main.settings.sections.appearance.accessibility.title"
)}
{getMessage('modals.main.settings.sections.appearance.accessibility.title')}
</span>
<span className="subtitle">subtitle</span>
</div>
<div className="action">
<Dropdown
label={getMessage(
"modals.main.settings.sections.appearance.accessibility.text_shadow"
)}
label={getMessage('modals.main.settings.sections.appearance.accessibility.text_shadow')}
name="textBorder"
category="other"
>
@ -186,27 +151,23 @@ export default function AppearanceSettings() {
<option value="none">None</option>
</Dropdown>
<Checkbox
text={getMessage(
"modals.main.settings.sections.appearance.accessibility.animations"
)}
text={getMessage('modals.main.settings.sections.appearance.accessibility.animations')}
name="animations"
category="other"
/>
<Slider
title={getMessage(
"modals.main.settings.sections.appearance.accessibility.toast_duration"
'modals.main.settings.sections.appearance.accessibility.toast_duration',
)}
name="toastDisplayTime"
default="2500"
step="100"
min="500"
max="5000"
marks={values("toast")}
marks={values('toast')}
display={
" " +
getMessage(
"modals.main.settings.sections.appearance.accessibility.milliseconds"
)
' ' +
getMessage('modals.main.settings.sections.appearance.accessibility.milliseconds')
}
/>
</div>

View File

@ -1,9 +1,9 @@
import variables from "modules/variables";
import { PureComponent, createRef } from "react";
import { MdOutlineWifiOff } from "react-icons/md";
import Modal from "react-modal";
import variables from 'modules/variables';
import { PureComponent, createRef } from 'react';
import { MdOutlineWifiOff } from 'react-icons/md';
import Modal from 'react-modal';
import Lightbox from "../../marketplace/Lightbox";
import Lightbox from '../../marketplace/Lightbox';
export default class Changelog extends PureComponent {
constructor() {
@ -13,14 +13,14 @@ export default class Changelog extends PureComponent {
showLightbox: false,
lightboxImg: null,
};
this.offlineMode = localStorage.getItem("offlineMode") === "true";
this.offlineMode = localStorage.getItem('offlineMode') === 'true';
this.controller = new AbortController();
this.changelog = createRef();
}
async getUpdate() {
const data = await (
await fetch(variables.constants.BLOG_POST + "/index.json", {
await fetch(variables.constants.BLOG_POST + '/index.json', {
signal: this.controller.signal,
})
).json();
@ -29,11 +29,11 @@ export default class Changelog extends PureComponent {
return;
}
let date = new Date(data.date.split(" ")[0]);
date = date.toLocaleDateString(variables.languagecode.replace("_", "-"), {
year: "numeric",
month: "long",
day: "numeric",
let date = new Date(data.date.split(' ')[0]);
date = date.toLocaleDateString(variables.languagecode.replace('_', '-'), {
year: 'numeric',
month: 'long',
day: 'numeric',
});
this.setState({
@ -42,17 +42,17 @@ export default class Changelog extends PureComponent {
image: data.featured_image || null,
author: variables.language.getMessage(
variables.languagecode,
"modals.main.settings.sections.changelog.by",
'modals.main.settings.sections.changelog.by',
{
author: data.authors.join(", "),
}
author: data.authors.join(', '),
},
),
html: data.html,
});
// lightbox etc
const images = this.changelog.current.getElementsByTagName("img");
const links = this.changelog.current.getElementsByTagName("a");
const images = this.changelog.current.getElementsByTagName('img');
const links = this.changelog.current.getElementsByTagName('a');
for (const img of images) {
img.draggable = false;
@ -66,8 +66,8 @@ export default class Changelog extends PureComponent {
// open in new tab
for (let link = 0; link < links.length; link++) {
links[link].target = "_blank";
links[link].rel = "noopener noreferrer";
links[link].target = '_blank';
links[link].rel = 'noopener noreferrer';
}
}
@ -85,8 +85,7 @@ export default class Changelog extends PureComponent {
}
render() {
const getMessage = (text) =>
variables.language.getMessage(variables.languagecode, text);
const getMessage = (text) => variables.language.getMessage(variables.languagecode, text);
const errorMessage = (msg) => {
return (
@ -100,11 +99,9 @@ export default class Changelog extends PureComponent {
return errorMessage(
<>
<MdOutlineWifiOff />
<h1>{getMessage("modals.main.marketplace.offline.title")}</h1>
<p className="description">
{getMessage("modals.main.marketplace.offline.description")}
</p>
</>
<h1>{getMessage('modals.main.marketplace.offline.title')}</h1>
<p className="description">{getMessage('modals.main.marketplace.offline.description')}</p>
</>,
);
}
@ -113,7 +110,7 @@ export default class Changelog extends PureComponent {
<div className="loaderHolder">
<div id="loader"></div>
<span className="subtitle">Just be a sec.</span>
</div>
</div>,
);
}
@ -131,10 +128,7 @@ export default class Changelog extends PureComponent {
className="updateImage"
/>
) : null}
<div
className="updateChangelog"
dangerouslySetInnerHTML={{ __html: this.state.html }}
/>
<div className="updateChangelog" dangerouslySetInnerHTML={{ __html: this.state.html }} />
<Modal
closeTimeoutMS={100}
onRequestClose={() => this.setState({ showLightbox: false })}

View File

@ -1,44 +1,39 @@
import variables from "modules/variables";
import { PureComponent } from "react";
import variables from 'modules/variables';
import { PureComponent } from 'react';
import Header from "../Header";
import Checkbox from "../Checkbox";
import Dropdown from "../Dropdown";
import SettingsItem from "../SettingsItem";
import Header from '../Header';
import Checkbox from '../Checkbox';
import Dropdown from '../Dropdown';
import SettingsItem from '../SettingsItem';
export default class DateSettings extends PureComponent {
constructor() {
super();
this.state = {
dateType: localStorage.getItem("dateType") || "long",
dateType: localStorage.getItem('dateType') || 'long',
};
}
render() {
const getMessage = (text) =>
variables.language.getMessage(variables.languagecode, text);
const getMessage = (text) => variables.language.getMessage(variables.languagecode, text);
let dateSettings;
const longSettings = (
<>
<Dropdown
label="Long Format"
name="longFormat"
category="date"
>
<Dropdown label="Long Format" name="longFormat" category="date">
<option value="DMY">DMY</option>
<option value="MDY">MDY</option>
<option value="YMD">YMD</option>
</Dropdown>
<Checkbox
name="dayofweek"
text={getMessage("modals.main.settings.sections.date.day_of_week")}
text={getMessage('modals.main.settings.sections.date.day_of_week')}
category="date"
/>
<Checkbox
name="datenth"
text={getMessage("modals.main.settings.sections.date.datenth")}
text={getMessage('modals.main.settings.sections.date.datenth')}
category="date"
/>
</>
@ -47,7 +42,7 @@ export default class DateSettings extends PureComponent {
const shortSettings = (
<>
<Dropdown
label={getMessage("modals.main.settings.sections.date.short_format")}
label={getMessage('modals.main.settings.sections.date.short_format')}
name="dateFormat"
category="date"
>
@ -57,37 +52,27 @@ export default class DateSettings extends PureComponent {
</Dropdown>
<Dropdown
label={getMessage(
"modals.main.settings.sections.date.short_separator.title"
)}
label={getMessage('modals.main.settings.sections.date.short_separator.title')}
name="shortFormat"
category="date"
>
<option value="dash">
{getMessage(
"modals.main.settings.sections.date.short_separator.dash"
)}
{getMessage('modals.main.settings.sections.date.short_separator.dash')}
</option>
<option value="dots">
{getMessage(
"modals.main.settings.sections.date.short_separator.dots"
)}
{getMessage('modals.main.settings.sections.date.short_separator.dots')}
</option>
<option value="gaps">
{getMessage(
"modals.main.settings.sections.date.short_separator.gaps"
)}
{getMessage('modals.main.settings.sections.date.short_separator.gaps')}
</option>
<option value="slashes">
{getMessage(
"modals.main.settings.sections.date.short_separator.slashes"
)}
{getMessage('modals.main.settings.sections.date.short_separator.slashes')}
</option>
</Dropdown>
</>
);
if (this.state.dateType === "long") {
if (this.state.dateType === 'long') {
dateSettings = longSettings;
} else {
dateSettings = shortSettings;
@ -96,7 +81,7 @@ export default class DateSettings extends PureComponent {
return (
<>
<Header
title={getMessage("modals.main.settings.sections.date.title")}
title={getMessage('modals.main.settings.sections.date.title')}
setting="date"
category="date"
element=".date"
@ -105,28 +90,28 @@ export default class DateSettings extends PureComponent {
/>
<SettingsItem title="Date Type">
<Dropdown
label={getMessage("modals.main.settings.sections.time.type")}
label={getMessage('modals.main.settings.sections.time.type')}
name="dateType"
onChange={(value) => this.setState({ dateType: value })}
category="date"
>
<option value="long">
{getMessage("modals.main.settings.sections.date.type.long")}
{getMessage('modals.main.settings.sections.date.type.long')}
</option>
<option value="short">
{getMessage("modals.main.settings.sections.date.type.short")}
{getMessage('modals.main.settings.sections.date.type.short')}
</option>
</Dropdown>
</SettingsItem>
<SettingsItem title="Extra Options">
<Checkbox
name="weeknumber"
text={getMessage("modals.main.settings.sections.date.week_number")}
text={getMessage('modals.main.settings.sections.date.week_number')}
category="date"
/>
<Checkbox
name="datezero"
text={getMessage("modals.main.settings.sections.time.digital.zero")}
text={getMessage('modals.main.settings.sections.time.digital.zero')}
category="date"
/>
{dateSettings}

View File

@ -1,25 +1,22 @@
import variables from "modules/variables";
import { useState } from "react";
import Checkbox from "../Checkbox";
import Slider from "../Slider";
import { TextField } from "@mui/material";
import variables from 'modules/variables';
import { useState } from 'react';
import Checkbox from '../Checkbox';
import Slider from '../Slider';
import { TextField } from '@mui/material';
import EventBus from "modules/helpers/eventbus";
import { values } from "modules/helpers/settings/modals";
import EventBus from 'modules/helpers/eventbus';
import { values } from 'modules/helpers/settings/modals';
export default function ExperimentalSettings() {
const getMessage = (text) =>
variables.language.getMessage(variables.languagecode, text);
const getMessage = (text) => variables.language.getMessage(variables.languagecode, text);
const [eventType, setEventType] = useState();
const [eventName, setEventName] = useState();
return (
<>
<h2>{getMessage("modals.main.settings.sections.experimental.title")}</h2>
<p>{getMessage("modals.main.settings.sections.experimental.warning")}</p>
<h3>
{getMessage("modals.main.settings.sections.experimental.developer")}
</h3>
<h2>{getMessage('modals.main.settings.sections.experimental.title')}</h2>
<p>{getMessage('modals.main.settings.sections.experimental.warning')}</p>
<h3>{getMessage('modals.main.settings.sections.experimental.developer')}</h3>
<Checkbox name="debug" text="Debug hotkey (Ctrl + #)" element=".other" />
<Slider
title="Debug timeout"
@ -28,12 +25,12 @@ export default function ExperimentalSettings() {
max="5000"
default="0"
step="100"
marks={values("experimental")}
marks={values('experimental')}
element=".other"
/>
<p>Send Event</p>
<TextField
label={"Type"}
label={'Type'}
value={eventType}
onChange={(e) => setEventType(e.target.value)}
spellCheck={false}
@ -41,7 +38,7 @@ export default function ExperimentalSettings() {
InputLabelProps={{ shrink: true }}
/>
<TextField
label={"Name"}
label={'Name'}
value={eventName}
onChange={(e) => setEventName(e.target.value)}
spellCheck={false}
@ -49,19 +46,12 @@ export default function ExperimentalSettings() {
InputLabelProps={{ shrink: true }}
/>
<br />
<button
className="uploadbg"
onClick={() => EventBus.dispatch(eventType, eventName)}
>
<button className="uploadbg" onClick={() => EventBus.dispatch(eventType, eventName)}>
Send
</button>
<br />
<br />
<button
className="reset"
style={{ marginLeft: "0px" }}
onClick={() => localStorage.clear()}
>
<button className="reset" style={{ marginLeft: '0px' }} onClick={() => localStorage.clear()}>
Clear LocalStorage
</button>
</>

View File

@ -11,7 +11,7 @@ export default class GreetingSettings extends PureComponent {
constructor() {
super();
this.state = {
birthday: new Date(localStorage.getItem('birthday')) || new Date()
birthday: new Date(localStorage.getItem('birthday')) || new Date(),
};
}
@ -19,26 +19,64 @@ export default class GreetingSettings extends PureComponent {
localStorage.setItem('birthday', e.target.value || new Date());
this.setState({
birthday: e.target.value ? new Date(e.target.value) : new Date()
birthday: e.target.value ? new Date(e.target.value) : new Date(),
});
}
};
render() {
const getMessage = (text) => variables.language.getMessage(variables.languagecode, text);
return (
<>
<Header title={getMessage('modals.main.settings.sections.greeting.title')} setting='greeting' category='greeting' element='.greeting' zoomSetting='zoomGreeting' switch={true}/>
<SettingsItem title="Additional Settings" subtitle={getMessage('modals.main.settings.enabled')}>
<Checkbox name='events' text={getMessage('modals.main.settings.sections.greeting.events')} category='greeting'/>
<Checkbox name='defaultGreetingMessage' text={getMessage('modals.main.settings.sections.greeting.default')} category='greeting'/>
<Text title={getMessage('modals.main.settings.sections.greeting.name')} name='greetingName' category='greeting'/>
<Header
title={getMessage('modals.main.settings.sections.greeting.title')}
setting="greeting"
category="greeting"
element=".greeting"
zoomSetting="zoomGreeting"
switch={true}
/>
<SettingsItem
title="Additional Settings"
subtitle={getMessage('modals.main.settings.enabled')}
>
<Checkbox
name="events"
text={getMessage('modals.main.settings.sections.greeting.events')}
category="greeting"
/>
<Checkbox
name="defaultGreetingMessage"
text={getMessage('modals.main.settings.sections.greeting.default')}
category="greeting"
/>
<Text
title={getMessage('modals.main.settings.sections.greeting.name')}
name="greetingName"
category="greeting"
/>
</SettingsItem>
<SettingsItem title={getMessage('modals.main.settings.sections.greeting.birthday')} subtitle={getMessage('modals.main.settings.enabled')}>
<Switch name='birthdayenabled' text={getMessage('modals.main.settings.enabled')} category='greeting'/>
<Checkbox name='birthdayage' text={getMessage('modals.main.settings.sections.greeting.birthday_age')} category='greeting'/>
<p>{getMessage('modals.main.settings.sections.greeting.birthday_date')}</p>
<input type='date' onChange={this.changeDate} value={this.state.birthday.toISOString().substr(0, 10)} required/>
<SettingsItem
title={getMessage('modals.main.settings.sections.greeting.birthday')}
subtitle={getMessage('modals.main.settings.enabled')}
>
<Switch
name="birthdayenabled"
text={getMessage('modals.main.settings.enabled')}
category="greeting"
/>
<Checkbox
name="birthdayage"
text={getMessage('modals.main.settings.sections.greeting.birthday_age')}
category="greeting"
/>
<p>{getMessage('modals.main.settings.sections.greeting.birthday_date')}</p>
<input
type="date"
onChange={this.changeDate}
value={this.state.birthday.toISOString().substr(0, 10)}
required
/>
</SettingsItem>
{/*<h3>{getMessage('modals.main.settings.sections.greeting.birthday')}</h3>
<Switch name='birthdayenabled' text={getMessage('modals.main.settings.enabled')} category='greeting'/>

View File

@ -11,7 +11,7 @@ export default class KeybindSettings extends PureComponent {
super();
this.state = {
keybinds: JSON.parse(localStorage.getItem('keybinds')) || {},
cancelled: false
cancelled: false,
};
}
@ -25,7 +25,7 @@ export default class KeybindSettings extends PureComponent {
currentKeybinds[type] = this.getMessage('modals.main.settings.sections.keybinds.recording');
this.setState({
keybinds: currentKeybinds,
cancelled: false
cancelled: false,
});
this.forceUpdate();
@ -42,7 +42,7 @@ export default class KeybindSettings extends PureComponent {
keys = `${keys}+${event.key}`;
}
previouskey = event.key
previouskey = event.key;
});
this.keyup = document.addEventListener('keyup', () => {
@ -55,7 +55,7 @@ export default class KeybindSettings extends PureComponent {
keybinds[type] = keys.split('+').slice(0, 4).join('+');
localStorage.setItem('keybinds', JSON.stringify(keybinds));
this.setState({
keybinds: JSON.parse(localStorage.getItem('keybinds')) || {}
keybinds: JSON.parse(localStorage.getItem('keybinds')) || {},
});
});
@ -73,7 +73,7 @@ export default class KeybindSettings extends PureComponent {
this.setState({
keybinds: currentKeybinds,
cancelled: true
cancelled: true,
});
this.forceUpdate();
}
@ -85,7 +85,7 @@ export default class KeybindSettings extends PureComponent {
this.setState({
keybinds: JSON.parse(localStorage.getItem('keybinds')) || {},
cancelled: true
cancelled: true,
});
this.showReminder();
@ -110,35 +110,140 @@ export default class KeybindSettings extends PureComponent {
render() {
return (
<>
<Header title={this.getMessage('modals.main.settings.sections.keybinds.title')} setting='keybindsEnabled' element='.other' />
<table className='keybind-table'>
<Header
title={this.getMessage('modals.main.settings.sections.keybinds.title')}
setting="keybindsEnabled"
element=".other"
/>
<table className="keybind-table">
<tbody>
<tr>
<th><KeybindInput name={this.getMessage('modals.main.settings.sections.keybinds.background.favourite')} state={this.state.keybinds} setting='favouriteBackground' action={(type, e) => this.action(type, e)}/></th>
<th><KeybindInput name={this.getMessage('modals.main.settings.sections.keybinds.background.maximise')} state={this.state.keybinds} setting='maximiseBackground' action={(type, e) => this.action(type, e)}/></th>
<th>
<KeybindInput
name={this.getMessage(
'modals.main.settings.sections.keybinds.background.favourite',
)}
state={this.state.keybinds}
setting="favouriteBackground"
action={(type, e) => this.action(type, e)}
/>
</th>
<th>
<KeybindInput
name={this.getMessage(
'modals.main.settings.sections.keybinds.background.maximise',
)}
state={this.state.keybinds}
setting="maximiseBackground"
action={(type, e) => this.action(type, e)}
/>
</th>
</tr>
<tr>
<th><KeybindInput name={this.getMessage('modals.main.settings.sections.keybinds.background.download')} state={this.state.keybinds} setting='downloadBackground' action={(type, e) => this.action(type, e)}/></th>
<th><KeybindInput name={this.getMessage('modals.main.settings.sections.keybinds.background.show_info')} state={this.state.keybinds} setting='showBackgroundInformation' action={(type, e) => this.action(type, e)}/></th>
<th>
<KeybindInput
name={this.getMessage(
'modals.main.settings.sections.keybinds.background.download',
)}
state={this.state.keybinds}
setting="downloadBackground"
action={(type, e) => this.action(type, e)}
/>
</th>
<th>
<KeybindInput
name={this.getMessage(
'modals.main.settings.sections.keybinds.background.show_info',
)}
state={this.state.keybinds}
setting="showBackgroundInformation"
action={(type, e) => this.action(type, e)}
/>
</th>
</tr>
<tr>
<th><KeybindInput name={this.getMessage('modals.main.settings.sections.keybinds.background.show_info')} state={this.state.keybinds} setting='showBackgroundInformation' action={(type, e) => this.action(type, e)}/></th>
<th><KeybindInput name={this.getMessage('modals.main.settings.sections.keybinds.quote.favourite')} state={this.state.keybinds} setting='favouriteQuote' action={(type, e) => this.action(type, e)}/></th>
<th>
<KeybindInput
name={this.getMessage(
'modals.main.settings.sections.keybinds.background.show_info',
)}
state={this.state.keybinds}
setting="showBackgroundInformation"
action={(type, e) => this.action(type, e)}
/>
</th>
<th>
<KeybindInput
name={this.getMessage('modals.main.settings.sections.keybinds.quote.favourite')}
state={this.state.keybinds}
setting="favouriteQuote"
action={(type, e) => this.action(type, e)}
/>
</th>
</tr>
<tr>
<th><KeybindInput name={this.getMessage('modals.main.settings.sections.keybinds.quote.copy')} state={this.state.keybinds} setting='copyQuote' action={(type, e) => this.action(type, e)}/></th>
<th><KeybindInput name={this.getMessage('modals.main.settings.sections.keybinds.quote.tweet')} state={this.state.keybinds} setting='tweetQuote' action={(type, e) => this.action(type, e)}/></th>
<th>
<KeybindInput
name={this.getMessage('modals.main.settings.sections.keybinds.quote.copy')}
state={this.state.keybinds}
setting="copyQuote"
action={(type, e) => this.action(type, e)}
/>
</th>
<th>
<KeybindInput
name={this.getMessage('modals.main.settings.sections.keybinds.quote.tweet')}
state={this.state.keybinds}
setting="tweetQuote"
action={(type, e) => this.action(type, e)}
/>
</th>
</tr>
<tr>
<th><KeybindInput name={this.getMessage('modals.main.settings.sections.keybinds.notes.pin')} state={this.state.keybinds} setting='pinNotes' action={(type, e) => this.action(type, e)}/></th>
<th><KeybindInput name={this.getMessage('modals.main.settings.sections.keybinds.notes.copy')} state={this.state.keybinds} setting='copyNotes' action={(type, e) => this.action(type, e)}/></th>
<th>
<KeybindInput
name={this.getMessage('modals.main.settings.sections.keybinds.notes.pin')}
state={this.state.keybinds}
setting="pinNotes"
action={(type, e) => this.action(type, e)}
/>
</th>
<th>
<KeybindInput
name={this.getMessage('modals.main.settings.sections.keybinds.notes.copy')}
state={this.state.keybinds}
setting="copyNotes"
action={(type, e) => this.action(type, e)}
/>
</th>
</tr>
<tr>
<th><KeybindInput name={this.getMessage('modals.main.settings.sections.keybinds.search')} state={this.state.keybinds} setting='focusSearch' action={(type, e) => this.action(type, e)}/></th>
<th><KeybindInput name={this.getMessage('modals.main.settings.sections.keybinds.quicklinks')} state={this.state.keybinds} setting='toggleQuicklinks' action={(type, e) => this.action(type, e)}/></th>
<th>
<KeybindInput
name={this.getMessage('modals.main.settings.sections.keybinds.search')}
state={this.state.keybinds}
setting="focusSearch"
action={(type, e) => this.action(type, e)}
/>
</th>
<th>
<KeybindInput
name={this.getMessage('modals.main.settings.sections.keybinds.quicklinks')}
state={this.state.keybinds}
setting="toggleQuicklinks"
action={(type, e) => this.action(type, e)}
/>
</th>
</tr>
<tr>
<th><KeybindInput name={this.getMessage('modals.main.settings.sections.keybinds.modal')} state={this.state.keybinds} setting='toggleModal' action={(type, e) => this.action(type, e)}/></th>
<th>
<KeybindInput
name={this.getMessage('modals.main.settings.sections.keybinds.modal')}
state={this.state.keybinds}
setting="toggleModal"
action={(type, e) => this.action(type, e)}
/>
</th>
</tr>
</tbody>
</table>

View File

@ -96,8 +96,9 @@ export default class Message extends PureComponent {
<th>
{this.state.messages.length > 1 ? (
<button
className='deleteButton'
onClick={() => this.modifyMessage('remove', index)}>
className="deleteButton"
onClick={() => this.modifyMessage('remove', index)}
>
<MdCancel />
</button>
) : null}

View File

@ -12,12 +12,38 @@ export default function QuickLinks() {
return (
<>
<Header title={getMessage('modals.main.settings.sections.quicklinks.title')} setting='quicklinksenabled' category='quicklinks' element='.quicklinks-container' zoomSetting='zoomQuicklinks' switch={true}/>
<Header
title={getMessage('modals.main.settings.sections.quicklinks.title')}
setting="quicklinksenabled"
category="quicklinks"
element=".quicklinks-container"
zoomSetting="zoomQuicklinks"
switch={true}
/>
<SettingsItem title="Extra Options" subtitle="subtitle">
<Checkbox name='quicklinksText' text={getMessage('modals.main.settings.sections.quicklinks.text_only')} category='quicklinks' onChange={(value) => setTextOnly(value)}/>
<Checkbox name='quicklinksddgProxy' text={getMessage('modals.main.settings.sections.background.ddg_image_proxy')} category='quicklinks' disabled={textOnly}/>
<Checkbox name='quicklinksnewtab' text={getMessage('modals.main.settings.sections.quicklinks.open_new')} category='quicklinks'/>
<Checkbox name='quicklinkstooltip' text={getMessage('modals.main.settings.sections.quicklinks.tooltip')} category='quicklinks' disabled={textOnly}/>
<Checkbox
name="quicklinksText"
text={getMessage('modals.main.settings.sections.quicklinks.text_only')}
category="quicklinks"
onChange={(value) => setTextOnly(value)}
/>
<Checkbox
name="quicklinksddgProxy"
text={getMessage('modals.main.settings.sections.background.ddg_image_proxy')}
category="quicklinks"
disabled={textOnly}
/>
<Checkbox
name="quicklinksnewtab"
text={getMessage('modals.main.settings.sections.quicklinks.open_new')}
category="quicklinks"
/>
<Checkbox
name="quicklinkstooltip"
text={getMessage('modals.main.settings.sections.quicklinks.tooltip')}
category="quicklinks"
disabled={textOnly}
/>
</SettingsItem>
</>
);

View File

@ -6,7 +6,7 @@ export default class ReminderSettings extends PureComponent {
constructor() {
super();
this.state = {
colour: localStorage.getItem('reminderColour') || '#ffa500'
colour: localStorage.getItem('reminderColour') || '#ffa500',
};
}
@ -20,9 +20,24 @@ export default class ReminderSettings extends PureComponent {
const getMessage = (text) => variables.language.getMessage(variables.languagecode, text);
return (
<>
<Header title='Reminder' setting='reminder' category='reminder' element='.reminder' zoomSetting='zoomReminder' switch={true}/>
<input type='color' name='colour' className='colour' onChange={(event) => this.updateColour(event)} value={this.state.colour}></input>
<label htmlFor={'colour'} className='customBackgroundHex'>{this.state.colour}</label>
<Header
title="Reminder"
setting="reminder"
category="reminder"
element=".reminder"
zoomSetting="zoomReminder"
switch={true}
/>
<input
type="color"
name="colour"
className="colour"
onChange={(event) => this.updateColour(event)}
value={this.state.colour}
></input>
<label htmlFor={'colour'} className="customBackgroundHex">
{this.state.colour}
</label>
</>
);
}

View File

@ -22,14 +22,14 @@ export default class SearchSettings extends PureComponent {
this.state = {
customEnabled: false,
customDisplay: 'none',
customValue: localStorage.getItem('customSearchEngine') || ''
customValue: localStorage.getItem('customSearchEngine') || '',
};
}
resetSearch() {
localStorage.removeItem('customSearchEngine');
this.setState({
customValue: ''
customValue: '',
});
toast(this.getMessage('toasts.reset'));
@ -39,7 +39,7 @@ export default class SearchSettings extends PureComponent {
if (localStorage.getItem('searchEngine') === 'custom') {
this.setState({
customDisplay: 'block',
customEnabled: true
customEnabled: true,
});
} else {
localStorage.removeItem('customSearchEngine');
@ -58,12 +58,12 @@ export default class SearchSettings extends PureComponent {
if (input === 'custom') {
this.setState({
customDisplay: 'block',
customEnabled: true
customEnabled: true,
});
} else {
this.setState({
customDisplay: 'none',
customEnabled: false
customEnabled: false,
});
localStorage.setItem('searchEngine', input);
}
@ -74,30 +74,78 @@ export default class SearchSettings extends PureComponent {
render() {
return (
<>
<Header title={this.getMessage('modals.main.settings.sections.search.title')} setting='searchBar' category='widgets' switch={true}/>
<Header
title={this.getMessage('modals.main.settings.sections.search.title')}
setting="searchBar"
category="widgets"
switch={true}
/>
<SettingsItem title="Extra Options" subtitle="eeeee">
{/* not supported on firefox */}
{(navigator.userAgent.includes('Chrome') && typeof InstallTrigger === 'undefined') ?
<Checkbox name='voiceSearch' text={this.getMessage('modals.main.settings.sections.search.voice_search')} category='search'/>
: null}
<Checkbox name='searchDropdown' text={this.getMessage('modals.main.settings.sections.search.dropdown')} category='search' element='.other'/>
<Checkbox name='searchFocus' text={this.getMessage('modals.main.settings.sections.search.focus')} category='search' element='.other'/>
<ul style={{ display: this.state.customDisplay }}>
<p style={{ marginTop: '0px' }}><span className='link' onClick={() => this.resetSearch()}>{this.getMessage('modals.main.settings.buttons.reset')}</span></p>
<TextField label={this.getMessage('modals.main.settings.sections.search.custom')} value={this.state.customValue} onInput={(e) => this.setState({ customValue: e.target.value })} varient='outlined' InputLabelProps={{ shrink: true }} />
</ul>
<Checkbox name='autocomplete' text={this.getMessage('modals.main.settings.sections.search.autocomplete')} category='search' />
{/* not supported on firefox */}
{navigator.userAgent.includes('Chrome') && typeof InstallTrigger === 'undefined' ? (
<Checkbox
name="voiceSearch"
text={this.getMessage('modals.main.settings.sections.search.voice_search')}
category="search"
/>
) : null}
<Checkbox
name="searchDropdown"
text={this.getMessage('modals.main.settings.sections.search.dropdown')}
category="search"
element=".other"
/>
<Checkbox
name="searchFocus"
text={this.getMessage('modals.main.settings.sections.search.focus')}
category="search"
element=".other"
/>
<ul style={{ display: this.state.customDisplay }}>
<p style={{ marginTop: '0px' }}>
<span className="link" onClick={() => this.resetSearch()}>
{this.getMessage('modals.main.settings.buttons.reset')}
</span>
</p>
<TextField
label={this.getMessage('modals.main.settings.sections.search.custom')}
value={this.state.customValue}
onInput={(e) => this.setState({ customValue: e.target.value })}
varient="outlined"
InputLabelProps={{ shrink: true }}
/>
</ul>
<Checkbox
name="autocomplete"
text={this.getMessage('modals.main.settings.sections.search.autocomplete')}
category="search"
/>
</SettingsItem>
<SettingsItem title={this.getMessage('modals.main.settings.sections.search.search_engine')} subtitle="cheese is gucci tbf">
<Dropdown label={this.getMessage('modals.main.settings.sections.search.search_engine')} name='searchEngine' onChange={(value) => this.setSearchEngine(value)} manual={true}>
{searchEngines.map((engine) => (
<MenuItem key={engine.name} value={engine.settingsName}>{engine.name}</MenuItem>
))}
<MenuItem value='custom'>{this.getMessage('modals.main.settings.sections.search.custom').split(' ')[0]}</MenuItem>
</Dropdown>
<SettingsItem
title={this.getMessage('modals.main.settings.sections.search.search_engine')}
subtitle="cheese is gucci tbf"
>
<Dropdown
label={this.getMessage('modals.main.settings.sections.search.search_engine')}
name="searchEngine"
onChange={(value) => this.setSearchEngine(value)}
manual={true}
>
{searchEngines.map((engine) => (
<MenuItem key={engine.name} value={engine.settingsName}>
{engine.name}
</MenuItem>
))}
<MenuItem value="custom">
{this.getMessage('modals.main.settings.sections.search.custom').split(' ')[0]}
</MenuItem>
</Dropdown>
</SettingsItem>
<SettingsItem title={this.getMessage('modals.main.settings.sections.search.autocomplete_provider')} subtitle="cheese">
<Radio options={autocompleteProviders} name='autocompleteProvider' category='search'/>
<SettingsItem
title={this.getMessage('modals.main.settings.sections.search.autocomplete_provider')}
subtitle="cheese"
>
<Radio options={autocompleteProviders} name="autocompleteProvider" category="search" />
</SettingsItem>
</>
);

View File

@ -8,13 +8,12 @@ import Checkbox from '../Checkbox';
import { TextField } from '@mui/material';
import SettingsItem from '../SettingsItem';
export default class TimeSettings extends PureComponent {
constructor() {
super();
this.state = {
location: localStorage.getItem('location') || '',
windSpeed: (localStorage.getItem('windspeed') !== 'true')
windSpeed: localStorage.getItem('windspeed') !== 'true',
};
}
@ -29,26 +28,34 @@ export default class TimeSettings extends PureComponent {
changeLocation(e) {
this.setState({
location: e.target.value
location: e.target.value,
});
this.showReminder();
}
getAuto() {
navigator.geolocation.getCurrentPosition(async (position) => {
const data = await (await fetch(`${variables.constants.PROXY_URL}/weather/autolocation?lat=${position.coords.latitude}&lon=${position.coords.longitude}`)).json();
this.setState({
location: data[0].name
});
navigator.geolocation.getCurrentPosition(
async (position) => {
const data = await (
await fetch(
`${variables.constants.PROXY_URL}/weather/autolocation?lat=${position.coords.latitude}&lon=${position.coords.longitude}`,
)
).json();
this.setState({
location: data[0].name,
});
this.showReminder();
}, (error) => {
// firefox requires this 2nd function
console.log(error);
}, {
enableHighAccuracy: true
});
this.showReminder();
},
(error) => {
// firefox requires this 2nd function
console.log(error);
},
{
enableHighAccuracy: true,
},
);
}
render() {
@ -57,62 +64,151 @@ export default class TimeSettings extends PureComponent {
const tempFormat = [
{
name: getMessage('modals.main.settings.sections.weather.temp_format.celsius') + ' (°C)',
value: 'celsius'
value: 'celsius',
},
{
name: getMessage('modals.main.settings.sections.weather.temp_format.fahrenheit') + ' (°F)',
value: 'fahrenheit'
value: 'fahrenheit',
},
{
name: getMessage('modals.main.settings.sections.weather.temp_format.kelvin') + ' (K)',
value: 'kelvin'
}
value: 'kelvin',
},
];
return (
<>
<Header title={getMessage('modals.main.settings.sections.weather.title')} setting='weatherEnabled' category='widgets' zoomSetting='zoomWeather' zoomCategory='weather' switch={true}/>
<Header
title={getMessage('modals.main.settings.sections.weather.title')}
setting="weatherEnabled"
category="widgets"
zoomSetting="zoomWeather"
zoomCategory="weather"
switch={true}
/>
<SettingsItem title="Widget Type">
<Dropdown label="Type" name="weatherType">
<option value='1'>Basic</option>
<option value='2'>Standard</option>
<option value='3'>Expanded</option>
</Dropdown>
<Dropdown label="Type" name="weatherType">
<option value="1">Basic</option>
<option value="2">Standard</option>
<option value="3">Expanded</option>
</Dropdown>
</SettingsItem>
<SettingsItem title={getMessage('modals.main.settings.sections.weather.location')}>
<TextField label={getMessage('modals.main.settings.sections.weather.location')} value={this.state.location} onChange={(e) => this.changeLocation(e)} placeholder='London' varient='outlined' InputLabelProps={{ shrink: true }} />
<span className='link' onClick={() => this.getAuto()}>{getMessage('modals.main.settings.sections.weather.auto')}</span>
<TextField
label={getMessage('modals.main.settings.sections.weather.location')}
value={this.state.location}
onChange={(e) => this.changeLocation(e)}
placeholder="London"
varient="outlined"
InputLabelProps={{ shrink: true }}
/>
<span className="link" onClick={() => this.getAuto()}>
{getMessage('modals.main.settings.sections.weather.auto')}
</span>
</SettingsItem>
<SettingsItem title={getMessage('modals.main.settings.sections.weather.temp_format.title')}>
<Radio name='tempformat' options={tempFormat} category='weather'/>
<Radio name="tempformat" options={tempFormat} category="weather" />
</SettingsItem>
{ localStorage.getItem('weatherType') > 1 &&
{localStorage.getItem('weatherType') > 1 && (
<SettingsItem title="Active bit" subtitle="idk a better word for it sorry">
<Dropdown label="Type" name="weatherActiveBit" category='weather'>
<option value='weatherdescription'>{getMessage('modals.main.settings.sections.weather.extra_info.show_description')} </option>
<option value='cloudiness'>{getMessage('modals.main.settings.sections.weather.extra_info.cloudiness')}</option>
<option value='humidity'>{getMessage('modals.main.settings.sections.weather.extra_info.humidity')}</option>
<option value='visibility'>{getMessage('modals.main.settings.sections.weather.extra_info.visibility')}</option>
<option value='windspeed' onChange={() => this.setState({ windSpeed: (localStorage.getItem('windspeed') !== 'true') })}>{getMessage('modals.main.settings.sections.weather.extra_info.wind_speed')}</option>
<option value='windDirection' disabled={this.state.windSpeed}>{getMessage('modals.main.settings.sections.weather.extra_info.wind_direction')}</option>
<option value='mintemp'>{getMessage('modals.main.settings.sections.weather.extra_info.min_temp')}</option>
<option value='maxtemp'>{getMessage('modals.main.settings.sections.weather.extra_info.max_temp')}</option>
<option value='feelsliketemp'>Feels like temperature</option>
<option value='atmosphericpressure'>{getMessage('modals.main.settings.sections.weather.extra_info.atmospheric_pressure')}</option>
</Dropdown>
<Dropdown label="Type" name="weatherActiveBit" category="weather">
<option value="weatherdescription">
{getMessage('modals.main.settings.sections.weather.extra_info.show_description')}{' '}
</option>
<option value="cloudiness">
{getMessage('modals.main.settings.sections.weather.extra_info.cloudiness')}
</option>
<option value="humidity">
{getMessage('modals.main.settings.sections.weather.extra_info.humidity')}
</option>
<option value="visibility">
{getMessage('modals.main.settings.sections.weather.extra_info.visibility')}
</option>
<option
value="windspeed"
onChange={() =>
this.setState({
windSpeed: localStorage.getItem('windspeed') !== 'true',
})
}
>
{getMessage('modals.main.settings.sections.weather.extra_info.wind_speed')}
</option>
<option value="windDirection" disabled={this.state.windSpeed}>
{getMessage('modals.main.settings.sections.weather.extra_info.wind_direction')}
</option>
<option value="mintemp">
{getMessage('modals.main.settings.sections.weather.extra_info.min_temp')}
</option>
<option value="maxtemp">
{getMessage('modals.main.settings.sections.weather.extra_info.max_temp')}
</option>
<option value="feelsliketemp">Feels like temperature</option>
<option value="atmosphericpressure">
{getMessage(
'modals.main.settings.sections.weather.extra_info.atmospheric_pressure',
)}
</option>
</Dropdown>
</SettingsItem>
}
<Checkbox name='showlocation' text={getMessage('modals.main.settings.sections.weather.extra_info.show_location')} category='weather'/>
<Checkbox name='weatherdescription' text={getMessage('modals.main.settings.sections.weather.extra_info.show_description')} category='weather'/>
<Checkbox name='cloudiness' text={getMessage('modals.main.settings.sections.weather.extra_info.cloudiness')} category='weather'/>
<Checkbox name='humidity' text={getMessage('modals.main.settings.sections.weather.extra_info.humidity')} category='weather'/>
<Checkbox name='visibility' text={getMessage('modals.main.settings.sections.weather.extra_info.visibility')} category='weather'/>
<Checkbox name='windspeed' text={getMessage('modals.main.settings.sections.weather.extra_info.wind_speed')} category='weather' onChange={() => this.setState({ windSpeed: (localStorage.getItem('windspeed') !== 'true') })}/>
<Checkbox name='windDirection' text={getMessage('modals.main.settings.sections.weather.extra_info.wind_direction')} category='weather' disabled={this.state.windSpeed}/>
<Checkbox name='mintemp' text={getMessage('modals.main.settings.sections.weather.extra_info.min_temp')} category='weather'/>
<Checkbox name='maxtemp' text={getMessage('modals.main.settings.sections.weather.extra_info.max_temp')} category='weather'/>
<Checkbox name='feelsliketemp' text={'Feels like temperature'} category='weather'/>
<Checkbox name='atmosphericpressure' text={getMessage('modals.main.settings.sections.weather.extra_info.atmospheric_pressure')} category='weather'/>
)}
<Checkbox
name="showlocation"
text={getMessage('modals.main.settings.sections.weather.extra_info.show_location')}
category="weather"
/>
<Checkbox
name="weatherdescription"
text={getMessage('modals.main.settings.sections.weather.extra_info.show_description')}
category="weather"
/>
<Checkbox
name="cloudiness"
text={getMessage('modals.main.settings.sections.weather.extra_info.cloudiness')}
category="weather"
/>
<Checkbox
name="humidity"
text={getMessage('modals.main.settings.sections.weather.extra_info.humidity')}
category="weather"
/>
<Checkbox
name="visibility"
text={getMessage('modals.main.settings.sections.weather.extra_info.visibility')}
category="weather"
/>
<Checkbox
name="windspeed"
text={getMessage('modals.main.settings.sections.weather.extra_info.wind_speed')}
category="weather"
onChange={() =>
this.setState({
windSpeed: localStorage.getItem('windspeed') !== 'true',
})
}
/>
<Checkbox
name="windDirection"
text={getMessage('modals.main.settings.sections.weather.extra_info.wind_direction')}
category="weather"
disabled={this.state.windSpeed}
/>
<Checkbox
name="mintemp"
text={getMessage('modals.main.settings.sections.weather.extra_info.min_temp')}
category="weather"
/>
<Checkbox
name="maxtemp"
text={getMessage('modals.main.settings.sections.weather.extra_info.max_temp')}
category="weather"
/>
<Checkbox name="feelsliketemp" text={'Feels like temperature'} category="weather" />
<Checkbox
name="atmosphericpressure"
text={getMessage('modals.main.settings.sections.weather.extra_info.atmospheric_pressure')}
category="weather"
/>
</>
);
}

View File

@ -1,38 +1,37 @@
import variables from "modules/variables";
import { PureComponent } from "react";
import { MenuItem } from "@mui/material";
import variables from 'modules/variables';
import { PureComponent } from 'react';
import { MenuItem } from '@mui/material';
import Header from "../../Header";
import Checkbox from "../../Checkbox";
import Dropdown from "../../Dropdown";
import Slider from "../../Slider";
import Radio from "../../Radio";
import SettingsItem from "../../SettingsItem";
import Header from '../../Header';
import Checkbox from '../../Checkbox';
import Dropdown from '../../Dropdown';
import Slider from '../../Slider';
import Radio from '../../Radio';
import SettingsItem from '../../SettingsItem';
import ColourSettings from "./Colour";
import CustomSettings from "./Custom";
import ColourSettings from './Colour';
import CustomSettings from './Custom';
import { values } from "modules/helpers/settings/modals";
import { values } from 'modules/helpers/settings/modals';
export default class BackgroundSettings extends PureComponent {
getMessage = (text) =>
variables.language.getMessage(variables.languagecode, text);
getMessage = (text) => variables.language.getMessage(variables.languagecode, text);
constructor() {
super();
this.state = {
backgroundType: localStorage.getItem("backgroundType") || "api",
backgroundFilter: localStorage.getItem("backgroundFilter") || "none",
backgroundCategories: [this.getMessage("modals.main.loading")],
backgroundAPI: localStorage.getItem("backgroundAPI") || "mue",
marketplaceEnabled: localStorage.getItem("photo_packs"),
backgroundType: localStorage.getItem('backgroundType') || 'api',
backgroundFilter: localStorage.getItem('backgroundFilter') || 'none',
backgroundCategories: [this.getMessage('modals.main.loading')],
backgroundAPI: localStorage.getItem('backgroundAPI') || 'mue',
marketplaceEnabled: localStorage.getItem('photo_packs'),
};
this.controller = new AbortController();
}
async getBackgroundCategories() {
const data = await (
await fetch(variables.constants.API_URL + "/images/categories", {
await fetch(variables.constants.API_URL + '/images/categories', {
signal: this.controller.signal,
})
).json();
@ -47,12 +46,9 @@ export default class BackgroundSettings extends PureComponent {
}
componentDidMount() {
if (
navigator.onLine === false ||
localStorage.getItem("offlineMode") === "true"
) {
if (navigator.onLine === false || localStorage.getItem('offlineMode') === 'true') {
return this.setState({
backgroundCategories: [this.getMessage("modals.update.offline.title")],
backgroundCategories: [this.getMessage('modals.update.offline.title')],
});
}
@ -71,53 +67,41 @@ export default class BackgroundSettings extends PureComponent {
const apiOptions = [
{
name: "Mue",
value: "mue",
name: 'Mue',
value: 'mue',
},
{
name: "Unsplash",
value: "unsplash",
name: 'Unsplash',
value: 'unsplash',
},
{
name: "Pexels",
value: "pexels",
name: 'Pexels',
value: 'pexels',
},
];
const interval = (
<SettingsItem>
<Dropdown
label={getMessage(
"modals.main.settings.sections.background.interval.title"
)}
label={getMessage('modals.main.settings.sections.background.interval.title')}
name="backgroundchange"
>
<option value="refresh">{getMessage("tabname")}</option>
<option value="refresh">{getMessage('tabname')}</option>
<option value="60000">
{getMessage(
"modals.main.settings.sections.background.interval.minute"
)}
{getMessage('modals.main.settings.sections.background.interval.minute')}
</option>
<option value="1800000">
{getMessage(
"modals.main.settings.sections.background.interval.half_hour"
)}
{getMessage('modals.main.settings.sections.background.interval.half_hour')}
</option>
<option value="3600000">
{getMessage(
"modals.main.settings.sections.background.interval.hour"
)}
{getMessage('modals.main.settings.sections.background.interval.hour')}
</option>
<option value="86400000">
{getMessage(
"modals.main.settings.sections.background.interval.day"
)}
{getMessage('modals.main.settings.sections.background.interval.day')}
</option>
<option value="604800000">{getMessage("widgets.date.week")}</option>
<option value="604800000">{getMessage('widgets.date.week')}</option>
<option value="2628000000">
{getMessage(
"modals.main.settings.sections.background.interval.month"
)}
{getMessage('modals.main.settings.sections.background.interval.month')}
</option>
</Dropdown>
</SettingsItem>
@ -127,37 +111,30 @@ export default class BackgroundSettings extends PureComponent {
<>
<SettingsItem>
<Radio
title={getMessage(
"modals.main.settings.sections.background.source.api"
)}
title={getMessage('modals.main.settings.sections.background.source.api')}
options={apiOptions}
name="backgroundAPI"
category="background"
element="#backgroundImage"
onChange={(e) => this.setState({ backgroundAPI: e })}
/>
{this.state.backgroundCategories[0] ===
getMessage("modals.main.loading") ? (
{this.state.backgroundCategories[0] === getMessage('modals.main.loading') ? (
<>
<Dropdown
label={getMessage(
"modals.main.settings.sections.background.category"
)}
label={getMessage('modals.main.settings.sections.background.category')}
name="apiCategory"
>
<MenuItem value="loading" key="loading">
{getMessage("modals.main.loading")}
{getMessage('modals.main.loading')}
</MenuItem>
<MenuItem value="loading" key="loading">
{getMessage("modals.main.loading")}
{getMessage('modals.main.loading')}
</MenuItem>
</Dropdown>
</>
) : (
<Dropdown
label={getMessage(
"modals.main.settings.sections.background.category"
)}
label={getMessage('modals.main.settings.sections.background.category')}
name="apiCategory"
>
{this.state.backgroundCategories.map((category) => (
@ -168,31 +145,21 @@ export default class BackgroundSettings extends PureComponent {
</Dropdown>
)}
<Dropdown
label={getMessage(
"modals.main.settings.sections.background.source.quality.title"
)}
label={getMessage('modals.main.settings.sections.background.source.quality.title')}
name="apiQuality"
element=".other"
>
<option value="original">
{getMessage(
"modals.main.settings.sections.background.source.quality.original"
)}
{getMessage('modals.main.settings.sections.background.source.quality.original')}
</option>
<option value="high">
{getMessage(
"modals.main.settings.sections.background.source.quality.high"
)}
{getMessage('modals.main.settings.sections.background.source.quality.high')}
</option>
<option value="normal">
{getMessage(
"modals.main.settings.sections.background.source.quality.normal"
)}
{getMessage('modals.main.settings.sections.background.source.quality.normal')}
</option>
<option value="datasaver">
{getMessage(
"modals.main.settings.sections.background.source.quality.datasaver"
)}
{getMessage('modals.main.settings.sections.background.source.quality.datasaver')}
</option>
</Dropdown>
</SettingsItem>
@ -201,16 +168,16 @@ export default class BackgroundSettings extends PureComponent {
);
switch (this.state.backgroundType) {
case "custom":
case 'custom':
backgroundSettings = <CustomSettings interval={interval} />;
break;
case "colour":
case 'colour':
backgroundSettings = <ColourSettings />;
break;
case "random_colour":
case 'random_colour':
backgroundSettings = <></>;
break;
case "random_gradient":
case 'random_gradient':
backgroundSettings = <></>;
break;
default:
@ -219,23 +186,23 @@ export default class BackgroundSettings extends PureComponent {
}
if (
localStorage.getItem("photo_packs") &&
this.state.backgroundType !== "custom" &&
this.state.backgroundType !== "colour" &&
this.state.backgroundType !== "api"
localStorage.getItem('photo_packs') &&
this.state.backgroundType !== 'custom' &&
this.state.backgroundType !== 'colour' &&
this.state.backgroundType !== 'api'
) {
backgroundSettings = null;
}
const usingImage =
this.state.backgroundType !== "colour" &&
this.state.backgroundType !== "random_colour" &&
this.state.backgroundType !== "random_gradient";
this.state.backgroundType !== 'colour' &&
this.state.backgroundType !== 'random_colour' &&
this.state.backgroundType !== 'random_gradient';
return (
<>
<Header
title={getMessage("modals.main.settings.sections.background.title")}
title={getMessage('modals.main.settings.sections.background.title')}
setting="background"
category="background"
element="#backgroundImage"
@ -243,171 +210,130 @@ export default class BackgroundSettings extends PureComponent {
<SettingsItem title="cheese" subtitle="cheese">
<Checkbox
name="ddgProxy"
text={getMessage(
"modals.main.settings.sections.background.ddg_image_proxy"
)}
text={getMessage('modals.main.settings.sections.background.ddg_image_proxy')}
element=".other"
disabled={!usingImage}
/>
<Checkbox
name="bgtransition"
text={getMessage(
"modals.main.settings.sections.background.transition"
)}
text={getMessage('modals.main.settings.sections.background.transition')}
element=".other"
disabled={!usingImage}
/>
<Checkbox
name="photoInformation"
text={getMessage(
"modals.main.settings.sections.background.photo_information"
)}
text={getMessage('modals.main.settings.sections.background.photo_information')}
element=".other"
disabled={
this.state.backgroundType !== "api" &&
this.state.backgroundType !== "marketplace"
this.state.backgroundType !== 'api' && this.state.backgroundType !== 'marketplace'
}
/>
<Checkbox
name="photoMap"
text={getMessage(
"modals.main.settings.sections.background.show_map"
)}
text={getMessage('modals.main.settings.sections.background.show_map')}
element=".other"
disabled={this.state.backgroundAPI !== "unsplash"}
disabled={this.state.backgroundAPI !== 'unsplash'}
/>
</SettingsItem>
<SettingsItem
title={getMessage(
"modals.main.settings.sections.background.source.title"
)}
title={getMessage('modals.main.settings.sections.background.source.title')}
subtitle="mucho gracias"
>
<Dropdown
label={getMessage(
"modals.main.settings.sections.background.type.title"
)}
label={getMessage('modals.main.settings.sections.background.type.title')}
name="backgroundType"
onChange={(value) => this.setState({ backgroundType: value })}
category="background"
>
{this.state.marketplaceEnabled ? (
<option value="photo_pack">
{this.getMessage("modals.main.navbar.marketplace")}
{this.getMessage('modals.main.navbar.marketplace')}
</option>
) : null}
<option value="api">
{getMessage("modals.main.settings.sections.background.type.api")}
{getMessage('modals.main.settings.sections.background.type.api')}
</option>
<option value="custom">
{getMessage(
"modals.main.settings.sections.background.type.custom_image"
)}
{getMessage('modals.main.settings.sections.background.type.custom_image')}
</option>
<option value="colour">
{getMessage(
"modals.main.settings.sections.background.type.custom_colour"
)}
{getMessage('modals.main.settings.sections.background.type.custom_colour')}
</option>
<option value="random_colour">
{getMessage(
"modals.main.settings.sections.background.type.random_colour"
)}
{getMessage('modals.main.settings.sections.background.type.random_colour')}
</option>
<option value="random_gradient">
{getMessage(
"modals.main.settings.sections.background.type.random_gradient"
)}
{getMessage('modals.main.settings.sections.background.type.random_gradient')}
</option>
</Dropdown>
</SettingsItem>
{backgroundSettings}
{this.state.backgroundType === "api" ||
this.state.backgroundType === "custom" ||
{this.state.backgroundType === 'api' ||
this.state.backgroundType === 'custom' ||
this.state.marketplaceEnabled ? (
<SettingsItem
title={getMessage(
"modals.main.settings.sections.background.effects.title"
)}
title={getMessage('modals.main.settings.sections.background.effects.title')}
subtitle="cheese"
>
<Slider
title={getMessage(
"modals.main.settings.sections.background.effects.blur"
)}
title={getMessage('modals.main.settings.sections.background.effects.blur')}
name="blur"
min="0"
max="100"
default="0"
display="%"
marks={values("background")}
marks={values('background')}
category="background"
element="#backgroundImage"
/>
<Slider
title={getMessage(
"modals.main.settings.sections.background.effects.brightness"
)}
title={getMessage('modals.main.settings.sections.background.effects.brightness')}
name="brightness"
min="0"
max="100"
default="90"
display="%"
marks={values("background")}
marks={values('background')}
category="background"
element="#backgroundImage"
/>
<Dropdown
label={getMessage(
"modals.main.settings.sections.background.effects.filters.title"
)}
label={getMessage('modals.main.settings.sections.background.effects.filters.title')}
name="backgroundFilter"
onChange={(value) => this.setState({ backgroundFilter: value })}
category="background"
element="#backgroundImage"
>
<option value="none">
{getMessage(
"modals.main.settings.sections.appearance.navbar.refresh_options.none"
)}
{getMessage('modals.main.settings.sections.appearance.navbar.refresh_options.none')}
</option>
<option value="grayscale">
{getMessage(
"modals.main.settings.sections.background.effects.filters.grayscale"
)}
{getMessage('modals.main.settings.sections.background.effects.filters.grayscale')}
</option>
<option value="sepia">
{getMessage(
"modals.main.settings.sections.background.effects.filters.sepia"
)}
{getMessage('modals.main.settings.sections.background.effects.filters.sepia')}
</option>
<option value="invert">
{getMessage(
"modals.main.settings.sections.background.effects.filters.invert"
)}
{getMessage('modals.main.settings.sections.background.effects.filters.invert')}
</option>
<option value="saturate">
{getMessage(
"modals.main.settings.sections.background.effects.filters.saturate"
)}
{getMessage('modals.main.settings.sections.background.effects.filters.saturate')}
</option>
<option value="contrast">
{getMessage(
"modals.main.settings.sections.background.effects.filters.contrast"
)}
{getMessage('modals.main.settings.sections.background.effects.filters.contrast')}
</option>
</Dropdown>
{this.state.backgroundFilter !== "none" ? (
{this.state.backgroundFilter !== 'none' ? (
<Slider
title={getMessage(
"modals.main.settings.sections.background.effects.filters.amount"
'modals.main.settings.sections.background.effects.filters.amount',
)}
name="backgroundFilterAmount"
min="0"
max="100"
default="0"
display="%"
marks={values("background")}
marks={values('background')}
category="background"
element="#backgroundImage"
/>

View File

@ -1,25 +1,24 @@
import variables from "modules/variables";
import { PureComponent, Fragment } from "react";
import { ColorPicker } from "react-color-gradient-picker";
import { toast } from "react-toastify";
import SettingsItem from "../../SettingsItem";
import variables from 'modules/variables';
import { PureComponent, Fragment } from 'react';
import { ColorPicker } from 'react-color-gradient-picker';
import { toast } from 'react-toastify';
import SettingsItem from '../../SettingsItem';
import hexToRgb from "modules/helpers/background/hexToRgb";
import rgbToHex from "modules/helpers/background/rgbToHex";
import hexToRgb from 'modules/helpers/background/hexToRgb';
import rgbToHex from 'modules/helpers/background/rgbToHex';
import "react-color-gradient-picker/dist/index.css";
import "../../../scss/settings/react-color-picker-gradient-picker-custom-styles.scss";
import 'react-color-gradient-picker/dist/index.css';
import '../../../scss/settings/react-color-picker-gradient-picker-custom-styles.scss';
export default class ColourSettings extends PureComponent {
DefaultGradientSettings = {
angle: "180",
gradient: [{ colour: "#ffb032", stop: 0 }],
type: "linear",
angle: '180',
gradient: [{ colour: '#ffb032', stop: 0 }],
type: 'linear',
};
GradientPickerInitialState = undefined;
getMessage = (text) =>
variables.language.getMessage(variables.languagecode, text);
getMessage = (text) => variables.language.getMessage(variables.languagecode, text);
constructor() {
super();
@ -29,11 +28,11 @@ export default class ColourSettings extends PureComponent {
}
resetColour() {
localStorage.setItem("customBackgroundColour", "");
localStorage.setItem('customBackgroundColour', '');
this.setState({
gradientSettings: this.DefaultGradientSettings,
});
toast(this.getMessage("toasts.reset"));
toast(this.getMessage('toasts.reset'));
}
initialiseColourPickerState(gradientSettings) {
@ -54,10 +53,10 @@ export default class ColourSettings extends PureComponent {
}
componentDidMount() {
const hex = localStorage.getItem("customBackgroundColour");
const hex = localStorage.getItem('customBackgroundColour');
let gradientSettings = undefined;
if (hex !== "") {
if (hex !== '') {
try {
gradientSettings = JSON.parse(hex);
} catch (e) {
@ -75,10 +74,7 @@ export default class ColourSettings extends PureComponent {
}
componentDidUpdate() {
localStorage.setItem(
"customBackgroundColour",
this.currentGradientSettings()
);
localStorage.setItem('customBackgroundColour', this.currentGradientSettings());
}
onGradientChange = (event, index) => {
@ -89,7 +85,7 @@ export default class ColourSettings extends PureComponent {
gradientSettings: {
...s.gradientSettings,
gradient: s.gradientSettings.gradient.map((g, i) =>
i === index ? { ...g, [name]: newValue } : g
i === index ? { ...g, [name]: newValue } : g,
),
},
});
@ -100,8 +96,7 @@ export default class ColourSettings extends PureComponent {
addColour = () => {
this.setState((s) => {
const [lastGradient, ...initGradients] =
s.gradientSettings.gradient.reverse();
const [lastGradient, ...initGradients] = s.gradientSettings.gradient.reverse();
return {
gradientSettings: {
...s.gradientSettings,
@ -109,10 +104,7 @@ export default class ColourSettings extends PureComponent {
...initGradients,
lastGradient,
{
colour:
localStorage.getItem("theme") === "dark"
? "#000000"
: "#ffffff",
colour: localStorage.getItem('theme') === 'dark' ? '#000000' : '#ffffff',
stop: 100,
},
].sort((a, b) => (a.stop > b.stop ? 1 : -1)),
@ -120,25 +112,18 @@ export default class ColourSettings extends PureComponent {
};
});
variables.stats.postEvent(
"setting",
"Changed backgroundType from colour to gradient"
);
variables.stats.postEvent('setting', 'Changed backgroundType from colour to gradient');
};
currentGradientSettings = () => {
if (
typeof this.state.gradientSettings === "object" &&
typeof this.state.gradientSettings === 'object' &&
this.state.gradientSettings.gradient.every(
(g) =>
g.colour !==
this.getMessage(
"modals.main.settings.sections.background.source.disabled"
)
g.colour !== this.getMessage('modals.main.settings.sections.background.source.disabled'),
)
) {
const clampNumber = (num, a, b) =>
Math.max(Math.min(num, Math.max(a, b)), Math.min(a, b));
const clampNumber = (num, a, b) => Math.max(Math.min(num, Math.max(a, b)), Math.min(a, b));
return JSON.stringify({
...this.state.gradientSettings,
gradient: [
@ -148,13 +133,11 @@ export default class ColourSettings extends PureComponent {
].sort((a, b) => (a.stop > b.stop ? 1 : -1)),
});
}
return this.getMessage(
"modals.main.settings.sections.background.source.disabled"
);
return this.getMessage('modals.main.settings.sections.background.source.disabled');
};
onColourPickerChange = (attrs, name) => {
if (process.env.NODE_ENV === "development") {
if (process.env.NODE_ENV === 'development') {
console.log(attrs, name);
}
@ -163,7 +146,7 @@ export default class ColourSettings extends PureComponent {
angle: attrs.degree,
gradient: attrs.points.map((p) => {
return {
colour: "#" + rgbToHex(p.red, p.green, p.blue),
colour: '#' + rgbToHex(p.red, p.green, p.blue),
stop: p.left,
};
}),
@ -175,18 +158,17 @@ export default class ColourSettings extends PureComponent {
};
showReminder() {
const reminderInfo = document.querySelector(".reminder-info");
if (reminderInfo.style.display !== "block") {
reminderInfo.style.display = "block";
localStorage.setItem("showReminder", true);
const reminderInfo = document.querySelector('.reminder-info');
if (reminderInfo.style.display !== 'block') {
reminderInfo.style.display = 'block';
localStorage.setItem('showReminder', true);
}
}
render() {
let colourSettings = null;
if (typeof this.state.gradientSettings === "object") {
const gradientHasMoreThanOneColour =
this.state.gradientSettings.gradient.length > 1;
if (typeof this.state.gradientSettings === 'object') {
const gradientHasMoreThanOneColour = this.state.gradientSettings.gradient.length > 1;
let gradientInputs;
if (gradientHasMoreThanOneColour) {
@ -196,11 +178,9 @@ export default class ColourSettings extends PureComponent {
gradientInputs = (
<ColorPicker
onStartChange={(colour) =>
this.onColourPickerChange(colour, "start")
}
onChange={(colour) => this.onColourPickerChange(colour, "change")}
onEndChange={(colour) => this.onColourPickerChange(colour, "end")}
onStartChange={(colour) => this.onColourPickerChange(colour, 'start')}
onChange={(colour) => this.onColourPickerChange(colour, 'change')}
onEndChange={(colour) => this.onColourPickerChange(colour, 'end')}
gradient={this.GradientPickerInitialState}
isGradient
/>
@ -210,14 +190,14 @@ export default class ColourSettings extends PureComponent {
return (
<Fragment key={i}>
<input
id={"colour_" + i}
id={'colour_' + i}
type="color"
name="colour"
className="colour"
onChange={(event) => this.onGradientChange(event, i)}
value={g.colour}
></input>
<label htmlFor={"colour_" + i} className="customBackgroundHex">
<label htmlFor={'colour_' + i} className="customBackgroundHex">
{g.colour}
</label>
</Fragment>
@ -231,9 +211,7 @@ export default class ColourSettings extends PureComponent {
{!gradientHasMoreThanOneColour ? (
<>
<button type="button" className="add" onClick={this.addColour}>
{this.getMessage(
"modals.main.settings.sections.background.source.add_colour"
)}
{this.getMessage('modals.main.settings.sections.background.source.add_colour')}
</button>
</>
) : null}
@ -244,12 +222,10 @@ export default class ColourSettings extends PureComponent {
return (
<>
<SettingsItem
title={this.getMessage(
"modals.main.settings.sections.background.source.custom_colour"
)}
title={this.getMessage('modals.main.settings.sections.background.source.custom_colour')}
>
<span className="link" onClick={() => this.resetColour()}>
{this.getMessage("modals.main.settings.buttons.reset")}
{this.getMessage('modals.main.settings.buttons.reset')}
</span>
{colourSettings}
</SettingsItem>

View File

@ -1,25 +1,19 @@
import variables from "modules/variables";
import { PureComponent } from "react";
import { toast } from "react-toastify";
import {
MdCancel,
MdAddLink,
MdAddPhotoAlternate,
MdPersonalVideo,
} from "react-icons/md";
import EventBus from "modules/helpers/eventbus";
import variables from 'modules/variables';
import { PureComponent } from 'react';
import { toast } from 'react-toastify';
import { MdCancel, MdAddLink, MdAddPhotoAlternate, MdPersonalVideo } from 'react-icons/md';
import EventBus from 'modules/helpers/eventbus';
import Checkbox from "../../Checkbox";
import FileUpload from "../../FileUpload";
import SettingsItem from "../../SettingsItem";
import Checkbox from '../../Checkbox';
import FileUpload from '../../FileUpload';
import SettingsItem from '../../SettingsItem';
import Modal from "react-modal";
import Modal from 'react-modal';
import CustomURLModal from "./CustomURLModal";
import CustomURLModal from './CustomURLModal';
export default class CustomSettings extends PureComponent {
getMessage = (text) =>
variables.language.getMessage(variables.languagecode, text);
getMessage = (text) => variables.language.getMessage(variables.languagecode, text);
constructor() {
super();
@ -30,12 +24,12 @@ export default class CustomSettings extends PureComponent {
}
resetCustom = () => {
localStorage.setItem("customBackground", "[]");
localStorage.setItem('customBackground', '[]');
this.setState({
customBackground: [],
});
toast(this.getMessage("toasts.reset"));
EventBus.dispatch("refresh", "background");
toast(this.getMessage('toasts.reset'));
EventBus.dispatch('refresh', 'background');
};
customBackground(e, text, index) {
@ -48,15 +42,15 @@ export default class CustomSettings extends PureComponent {
});
this.forceUpdate();
localStorage.setItem("customBackground", JSON.stringify(customBackground));
document.querySelector(".reminder-info").style.display = "flex";
localStorage.setItem("showReminder", true);
localStorage.setItem('customBackground', JSON.stringify(customBackground));
document.querySelector('.reminder-info').style.display = 'flex';
localStorage.setItem('showReminder', true);
}
modifyCustomBackground(type, index) {
const customBackground = this.state.customBackground;
if (type === "add") {
customBackground.push("");
if (type === 'add') {
customBackground.push('');
} else {
customBackground.splice(index, 1);
}
@ -66,39 +60,33 @@ export default class CustomSettings extends PureComponent {
});
this.forceUpdate();
localStorage.setItem("customBackground", JSON.stringify(customBackground));
document.querySelector(".reminder-info").style.display = "flex";
localStorage.setItem("showReminder", true);
localStorage.setItem('customBackground', JSON.stringify(customBackground));
document.querySelector('.reminder-info').style.display = 'flex';
localStorage.setItem('showReminder', true);
}
videoCheck(url) {
return (
url.startsWith("data:video/") ||
url.endsWith(".mp4") ||
url.endsWith(".webm") ||
url.endsWith(".ogg")
url.startsWith('data:video/') ||
url.endsWith('.mp4') ||
url.endsWith('.webm') ||
url.endsWith('.ogg')
);
}
videoCustomSettings = () => {
const hasVideo = this.state.customBackground.filter((bg) =>
this.videoCheck(bg)
);
const hasVideo = this.state.customBackground.filter((bg) => this.videoCheck(bg));
if (hasVideo.length > 0) {
return (
<>
<Checkbox
name="backgroundVideoLoop"
text={this.getMessage(
"modals.main.settings.sections.background.source.loop_video"
)}
text={this.getMessage('modals.main.settings.sections.background.source.loop_video')}
/>
<Checkbox
name="backgroundVideoMute"
text={this.getMessage(
"modals.main.settings.sections.background.source.mute_video"
)}
text={this.getMessage('modals.main.settings.sections.background.source.mute_video')}
/>
</>
);
@ -110,19 +98,17 @@ export default class CustomSettings extends PureComponent {
getCustom() {
let data;
try {
data = JSON.parse(localStorage.getItem("customBackground"));
data = JSON.parse(localStorage.getItem('customBackground'));
} catch (e) {
data = [localStorage.getItem("customBackground")];
data = [localStorage.getItem('customBackground')];
}
return data;
}
uploadCustomBackground() {
document
.getElementById("bg-input")
.setAttribute("index", this.state.customBackground.length);
document.getElementById("bg-input").click();
document.getElementById('bg-input').setAttribute('index', this.state.customBackground.length);
document.getElementById('bg-input').click();
// to fix loadFunction
this.setState({
currentBackgroundIndex: this.state.customBackground.length,
@ -134,39 +120,27 @@ export default class CustomSettings extends PureComponent {
customURLModal: false,
currentBackgroundIndex: this.state.customBackground.length,
});
this.customBackground(
{ target: { value: e } },
true,
this.state.customBackground.length
);
this.customBackground({ target: { value: e } }, true, this.state.customBackground.length);
}
render() {
return (
<>
{this.props.interval}
<div className="settingsRow" style={{ alignItems: "flex-start" }}>
<div className="settingsRow" style={{ alignItems: 'flex-start' }}>
<div className="content">
<div className="images-row">
{this.state.customBackground.map((url, index) => (
<div key={index}>
<img
alt={"Custom background " + (index || 0)}
src={`${
!this.videoCheck(url)
? this.state.customBackground[index]
: ""
}`}
alt={'Custom background ' + (index || 0)}
src={`${!this.videoCheck(url) ? this.state.customBackground[index] : ''}`}
/>
{this.videoCheck(url) ? (
<MdPersonalVideo className="customvideoicon" />
) : null}
{this.videoCheck(url) ? <MdPersonalVideo className="customvideoicon" /> : null}
{this.state.customBackground.length > 0 ? (
<button
className="iconButton"
onClick={() =>
this.modifyCustomBackground("remove", index)
}
onClick={() => this.modifyCustomBackground('remove', index)}
>
<MdCancel />
</button>
@ -183,14 +157,10 @@ export default class CustomSettings extends PureComponent {
<span className="subtitle">
Available formats, jpeg, png, webp, webm, gif, mp4, webm, ogg
</span>
<button onClick={() => this.uploadCustomBackground()}>
Or Select
</button>
<button onClick={() => this.uploadCustomBackground()}>Or Select</button>
</div>
<button onClick={() => this.setState({ customURLModal: true })}>
{this.getMessage(
"modals.main.settings.sections.background.source.add_url"
)}{" "}
{this.getMessage('modals.main.settings.sections.background.source.add_url')}{' '}
<MdAddLink />
</button>
{/*<span className='subtitle'>
@ -204,9 +174,7 @@ export default class CustomSettings extends PureComponent {
<FileUpload
id="bg-input"
accept="image/jpeg, image/png, image/webp, image/webm, image/gif, video/mp4, video/webm, video/ogg"
loadFunction={(e) =>
this.customBackground(e, false, this.state.currentBackgroundIndex)
}
loadFunction={(e) => this.customBackground(e, false, this.state.currentBackgroundIndex)}
/>
{this.videoCustomSettings()}
<Modal

View File

@ -1,7 +1,7 @@
import variables from "modules/variables";
import { useState } from "react";
import { MdAdd } from "react-icons/md";
import { TextField } from "@mui/material";
import variables from 'modules/variables';
import { useState } from 'react';
import { MdAdd } from 'react-icons/md';
import { TextField } from '@mui/material';
export default function CustomURLModal({ modalClose, modalCloseOnly }) {
const [url, setURL] = useState();
@ -14,18 +14,14 @@ export default function CustomURLModal({ modalClose, modalCloseOnly }) {
<h1>
{variables.language.getMessage(
variables.languagecode,
"modals.main.settings.sections.background.source.add_url"
'modals.main.settings.sections.background.source.add_url',
)}
</h1>
<TextField
value={url}
onChange={(e) => setURL(e.target.value)}
varient="outlined"
/>
<TextField value={url} onChange={(e) => setURL(e.target.value)} varient="outlined" />
<div className="resetFooter">
<button
className="round import"
style={{ marginLeft: "5px" }}
style={{ marginLeft: '5px' }}
onClick={() => modalClose(url)}
>
<MdAdd />

View File

@ -9,10 +9,16 @@ export default function Addons(props) {
const getMessage = (text) => variables.language.getMessage(variables.languagecode, text);
return (
<Tabs changeTab={(type) => props.changeTab(type)} current='addons'>
<div label={getMessage('modals.main.addons.added')} name='added'><Added/></div>
<div label={getMessage('modals.main.addons.sideload.title')} name='sideload'><Sideload/></div>
<div label={getMessage('modals.main.addons.create.title')} name='create'><Create/></div>
<Tabs changeTab={(type) => props.changeTab(type)} current="addons">
<div label={getMessage('modals.main.addons.added')} name="added">
<Added />
</div>
<div label={getMessage('modals.main.addons.sideload.title')} name="sideload">
<Sideload />
</div>
<div label={getMessage('modals.main.addons.create.title')} name="create">
<Create />
</div>
</Tabs>
);
}

View File

@ -7,11 +7,19 @@ export default function Marketplace(props) {
const getMessage = (text) => variables.language.getMessage(variables.languagecode, text);
return (
<Tabs changeTab={(type) => props.changeTab(type)} current='marketplace'>
<div label='All' name='all'><MarketplaceTab type='all'/></div>
<div label={getMessage('modals.main.marketplace.photo_packs')} name='photo_packs'><MarketplaceTab type='photo_packs'/></div>
<div label={getMessage('modals.main.marketplace.quote_packs')} name='quote_packs'><MarketplaceTab type='quote_packs'/></div>
<div label={getMessage('modals.main.marketplace.preset_settings')} name='preset_settings'><MarketplaceTab type='preset_settings'/></div>
<Tabs changeTab={(type) => props.changeTab(type)} current="marketplace">
<div label="All" name="all">
<MarketplaceTab type="all" />
</div>
<div label={getMessage('modals.main.marketplace.photo_packs')} name="photo_packs">
<MarketplaceTab type="photo_packs" />
</div>
<div label={getMessage('modals.main.marketplace.quote_packs')} name="quote_packs">
<MarketplaceTab type="quote_packs" />
</div>
<div label={getMessage('modals.main.marketplace.preset_settings')} name="preset_settings">
<MarketplaceTab type="preset_settings" />
</div>
</Tabs>
);
}

View File

@ -26,28 +26,72 @@ export default function Settings(props) {
const getMessage = (text) => variables.language.getMessage(variables.languagecode, text);
return (
<Tabs changeTab={(type) => props.changeTab(type)} current='settings'>
<div label={getMessage('modals.main.settings.sections.appearance.navbar.title')} name='navbar'><Navbar/></div>
<div label={getMessage('modals.main.settings.sections.greeting.title')} name='greeting'><Greeting/></div>
<div label={getMessage('modals.main.settings.sections.time.title')} name='time'><Time/></div>
<div label={getMessage('modals.main.settings.sections.quicklinks.title')} name='quicklinks'><QuickLinks/></div>
<div label={getMessage('modals.main.settings.sections.quote.title')} name='quote'><Quote/></div>
<div label={getMessage('modals.main.settings.sections.date.title')} name='date'><Date/></div>
<div label='Reminder' name='reminder'><Reminder/></div>
<div label={getMessage('modals.main.settings.sections.message.title')} name='message'><Message/></div>
<div label={getMessage('modals.main.settings.sections.background.title')} name='background'><Background/></div>
<div label={getMessage('modals.main.settings.sections.search.title')} name='search'><Search/></div>
<div label={getMessage('modals.main.settings.sections.weather.title')} name='weather'><Weather/></div>
<div label={getMessage('modals.main.settings.sections.order.title')} name='order'><Order/></div>
<div label={getMessage('modals.main.settings.sections.appearance.title')} name='appearance'><Appearance/></div>
<div label={getMessage('modals.main.settings.sections.language.title')} name='language'><Language/></div>
<div label={getMessage('modals.main.settings.sections.advanced.title')} name='advanced'><Advanced/></div>
{/*<div label={getMessage('modals.main.settings.sections.keybinds.title')} name='keybinds'><Keybinds/></div>*/}
<div label={getMessage('modals.main.settings.sections.stats.title')} name='stats'><Stats/></div>
<div label={getMessage('modals.main.settings.sections.experimental.title')} name='experimental'><Experimental/></div>
<div label={getMessage('modals.main.settings.sections.changelog.title')} name='changelog'><Changelog/></div>
<div label={getMessage('modals.main.settings.sections.about.title')} name='about'><About/></div>
</Tabs>
<Tabs changeTab={(type) => props.changeTab(type)} current="settings">
<div
label={getMessage('modals.main.settings.sections.appearance.navbar.title')}
name="navbar"
>
<Navbar />
</div>
<div label={getMessage('modals.main.settings.sections.greeting.title')} name="greeting">
<Greeting />
</div>
<div label={getMessage('modals.main.settings.sections.time.title')} name="time">
<Time />
</div>
<div label={getMessage('modals.main.settings.sections.quicklinks.title')} name="quicklinks">
<QuickLinks />
</div>
<div label={getMessage('modals.main.settings.sections.quote.title')} name="quote">
<Quote />
</div>
<div label={getMessage('modals.main.settings.sections.date.title')} name="date">
<Date />
</div>
<div label="Reminder" name="reminder">
<Reminder />
</div>
<div label={getMessage('modals.main.settings.sections.message.title')} name="message">
<Message />
</div>
<div label={getMessage('modals.main.settings.sections.background.title')} name="background">
<Background />
</div>
<div label={getMessage('modals.main.settings.sections.search.title')} name="search">
<Search />
</div>
<div label={getMessage('modals.main.settings.sections.weather.title')} name="weather">
<Weather />
</div>
<div label={getMessage('modals.main.settings.sections.order.title')} name="order">
<Order />
</div>
<div label={getMessage('modals.main.settings.sections.appearance.title')} name="appearance">
<Appearance />
</div>
<div label={getMessage('modals.main.settings.sections.language.title')} name="language">
<Language />
</div>
<div label={getMessage('modals.main.settings.sections.advanced.title')} name="advanced">
<Advanced />
</div>
{/*<div label={getMessage('modals.main.settings.sections.keybinds.title')} name='keybinds'><Keybinds/></div>*/}
<div label={getMessage('modals.main.settings.sections.stats.title')} name="stats">
<Stats />
</div>
<div
label={getMessage('modals.main.settings.sections.experimental.title')}
name="experimental"
>
<Experimental />
</div>
<div label={getMessage('modals.main.settings.sections.changelog.title')} name="changelog">
<Changelog />
</div>
<div label={getMessage('modals.main.settings.sections.about.title')} name="about">
<About />
</div>
</Tabs>
);
}

View File

@ -26,7 +26,7 @@ import {
MdEvent as Reminder,
MdCode as Sideload,
MdAddCircleOutline as Added,
MdAddCircleOutline as Create
MdAddCircleOutline as Create,
} from 'react-icons/md';
function Tab({ label, currentTab, onClick, navbarTab }) {
@ -46,56 +46,119 @@ function Tab({ label, currentTab, onClick, navbarTab }) {
let icon, divider;
switch (label) {
case getMessage('modals.main.navbar.settings'): icon = <Settings/>; break;
case getMessage('modals.main.navbar.addons'): icon = <Addons/>; break;
case getMessage('modals.main.navbar.marketplace'): icon = <Marketplace/>; break;
case getMessage('modals.main.navbar.settings'):
icon = <Settings />;
break;
case getMessage('modals.main.navbar.addons'):
icon = <Addons />;
break;
case getMessage('modals.main.navbar.marketplace'):
icon = <Marketplace />;
break;
case getMessage('modals.main.settings.sections.appearance.navbar.title'): icon = <Navbar/>; break;
case getMessage('modals.main.settings.sections.greeting.title'): icon = <Greeting/>; break;
case getMessage('modals.main.settings.sections.time.title'): icon = <Time/>; break;
case getMessage('modals.main.settings.sections.quicklinks.title'): icon = <QuickLinks/>; break;
case getMessage('modals.main.settings.sections.quote.title'): icon = <Quote/>; break;
case getMessage('modals.main.settings.sections.date.title'): icon = <Date/>; break;
case getMessage('modals.main.settings.sections.message.title'): icon = <Message/>; break;
case getMessage('modals.main.settings.sections.background.title'): icon = <Background/>; break;
case getMessage('modals.main.settings.sections.search.title'): icon = <MdSearch/>; break;
case getMessage('modals.main.settings.sections.weather.title'): icon = <Weather/>; divider = true; break;
case getMessage('modals.main.settings.sections.order.title'): icon = <Order/>; break;
case 'Reminder': icon = <Reminder/>; break;
case getMessage('modals.main.settings.sections.appearance.navbar.title'):
icon = <Navbar />;
break;
case getMessage('modals.main.settings.sections.greeting.title'):
icon = <Greeting />;
break;
case getMessage('modals.main.settings.sections.time.title'):
icon = <Time />;
break;
case getMessage('modals.main.settings.sections.quicklinks.title'):
icon = <QuickLinks />;
break;
case getMessage('modals.main.settings.sections.quote.title'):
icon = <Quote />;
break;
case getMessage('modals.main.settings.sections.date.title'):
icon = <Date />;
break;
case getMessage('modals.main.settings.sections.message.title'):
icon = <Message />;
break;
case getMessage('modals.main.settings.sections.background.title'):
icon = <Background />;
break;
case getMessage('modals.main.settings.sections.search.title'):
icon = <MdSearch />;
break;
case getMessage('modals.main.settings.sections.weather.title'):
icon = <Weather />;
divider = true;
break;
case getMessage('modals.main.settings.sections.order.title'):
icon = <Order />;
break;
case 'Reminder':
icon = <Reminder />;
break;
case getMessage('modals.main.settings.sections.appearance.title'): icon = <Appearance/>; break;
case getMessage('modals.main.settings.sections.language.title'): icon = <Language/>; divider = true; break;
case getMessage('modals.main.settings.sections.advanced.title'): icon = <Advanced/>; break;
case getMessage('modals.main.settings.sections.appearance.title'):
icon = <Appearance />;
break;
case getMessage('modals.main.settings.sections.language.title'):
icon = <Language />;
divider = true;
break;
case getMessage('modals.main.settings.sections.advanced.title'):
icon = <Advanced />;
break;
//case getMessage('modals.main.settings.sections.keybinds.title'): icon = <Keybinds/>; break;
case getMessage('modals.main.settings.sections.stats.title'): icon = <Stats/>; break;
case getMessage('modals.main.settings.sections.experimental.title'): icon = <Experimental/>; divider = true; break;
case getMessage('modals.main.settings.sections.changelog.title'): icon = <Changelog/>; break;
case getMessage('modals.main.settings.sections.about.title'): icon = <About/>; break;
case getMessage('modals.main.settings.sections.stats.title'):
icon = <Stats />;
break;
case getMessage('modals.main.settings.sections.experimental.title'):
icon = <Experimental />;
divider = true;
break;
case getMessage('modals.main.settings.sections.changelog.title'):
icon = <Changelog />;
break;
case getMessage('modals.main.settings.sections.about.title'):
icon = <About />;
break;
case getMessage('modals.main.addons.added'): icon = <Added/>; break;
case getMessage('modals.main.addons.sideload.title'): icon = <Sideload/>; break;
case getMessage('modals.main.addons.create.title'): icon = <Create/>; break;
case getMessage('modals.main.addons.added'):
icon = <Added />;
break;
case getMessage('modals.main.addons.sideload.title'):
icon = <Sideload />;
break;
case getMessage('modals.main.addons.create.title'):
icon = <Create />;
break;
case 'All': icon = <Addons/>; divider = true; break;
case getMessage('modals.main.marketplace.photo_packs'): icon = <Background/>; break;
case getMessage('modals.main.marketplace.quote_packs'): icon = <Quote/>; break;
case getMessage('modals.main.marketplace.preset_settings'): icon = <Advanced/>; break;
case 'All':
icon = <Addons />;
divider = true;
break;
case getMessage('modals.main.marketplace.photo_packs'):
icon = <Background />;
break;
case getMessage('modals.main.marketplace.quote_packs'):
icon = <Quote />;
break;
case getMessage('modals.main.marketplace.preset_settings'):
icon = <Advanced />;
break;
default: break;
default:
break;
}
if (label === getMessage('modals.main.settings.sections.experimental.title')) {
if (localStorage.getItem('experimental') === 'false') {
return <hr/>;
return <hr />;
}
}
return (
<>
<button className={className} onClick={() => onClick(label)}>
{icon} <span>{label}</span>
{icon} <span>{label}</span>
</button>
{(divider === true) ? <hr/> : null}
{divider === true ? <hr /> : null}
</>
);
}

View File

@ -1,12 +1,8 @@
import variables from "modules/variables";
import { PureComponent } from "react";
import {
MdSettings,
MdOutlineShoppingBasket,
MdOutlineExtension,
} from "react-icons/md";
import Tab from "./Tab";
import ErrorBoundary from "../../../ErrorBoundary";
import variables from 'modules/variables';
import { PureComponent } from 'react';
import { MdSettings, MdOutlineShoppingBasket, MdOutlineExtension } from 'react-icons/md';
import Tab from './Tab';
import ErrorBoundary from '../../../ErrorBoundary';
export default class Tabs extends PureComponent {
constructor(props) {
@ -20,7 +16,7 @@ export default class Tabs extends PureComponent {
onClick = (tab, name) => {
if (name !== this.state.currentName) {
variables.stats.postEvent("tab", `Opened ${name}`);
variables.stats.postEvent('tab', `Opened ${name}`);
}
this.setState({
@ -31,48 +27,48 @@ export default class Tabs extends PureComponent {
render() {
const reminderInfo = (
<div className="reminder-info" style={{ display: "none" }}>
<div className="reminder-info" style={{ display: 'none' }}>
<span className="title">
{variables.language.getMessage(
variables.languagecode,
"modals.main.settings.reminder.title"
'modals.main.settings.reminder.title',
)}
</span>
<span className="subtitle">
{variables.language.getMessage(
variables.languagecode,
"modals.main.settings.reminder.message"
'modals.main.settings.reminder.message',
)}
</span>
<button onClick={() => window.location.reload()}>
{variables.language.getMessage(
variables.languagecode,
"modals.main.error_boundary.refresh"
'modals.main.error_boundary.refresh',
)}
</button>
</div>
);
let settingsActive = "";
let addonsActive = "";
let marketplaceActive = "";
let settingsActive = '';
let addonsActive = '';
let marketplaceActive = '';
switch (this.props.current) {
case "settings":
settingsActive = " navbar-item-active";
case 'settings':
settingsActive = ' navbar-item-active';
break;
case "addons":
addonsActive = " navbar-item-active";
case 'addons':
addonsActive = ' navbar-item-active';
break;
case "marketplace":
marketplaceActive = " navbar-item-active";
case 'marketplace':
marketplaceActive = ' navbar-item-active';
break;
default:
break;
}
return (
<div style={{ display: "flex", width: "100%" }}>
<div style={{ display: 'flex', width: '100%' }}>
<ul className="sidebar">
{reminderInfo}
{this.props.children.map((tab, index) => (
@ -85,26 +81,26 @@ export default class Tabs extends PureComponent {
/>
))}
</ul>
<div className="tab-content" style={{ width: "100%" }}>
<div className="tab-content" style={{ width: '100%' }}>
<ErrorBoundary>
<div className="modalNavbar">
<button
className={"navbar-item" + settingsActive}
onClick={() => this.props.changeTab("settings")}
className={'navbar-item' + settingsActive}
onClick={() => this.props.changeTab('settings')}
>
<MdSettings />
<span>Settings</span>
</button>
<button
className={"navbar-item" + addonsActive}
onClick={() => this.props.changeTab("addons")}
className={'navbar-item' + addonsActive}
onClick={() => this.props.changeTab('addons')}
>
<MdOutlineExtension />
<span>Add-ons</span>
</button>
<button
className={"navbar-item" + marketplaceActive}
onClick={() => this.props.changeTab("marketplace")}
className={'navbar-item' + marketplaceActive}
onClick={() => this.props.changeTab('marketplace')}
>
<MdOutlineShoppingBasket />
<span>Marketplace</span>

View File

@ -1,33 +1,27 @@
import variables from "modules/variables";
import { PureComponent } from "react";
import {
MdCloudUpload,
MdAutoAwesome,
MdLightMode,
MdDarkMode,
} from "react-icons/md";
import variables from 'modules/variables';
import { PureComponent } from 'react';
import { MdCloudUpload, MdAutoAwesome, MdLightMode, MdDarkMode } from 'react-icons/md';
import Radio from "../main/settings/Radio";
import Checkbox from "../main/settings/Checkbox";
import FileUpload from "../main/settings/FileUpload";
import Radio from '../main/settings/Radio';
import Checkbox from '../main/settings/Checkbox';
import FileUpload from '../main/settings/FileUpload';
import { loadSettings } from "modules/helpers/settings";
import { importSettings } from "modules/helpers/settings/modals";
import { loadSettings } from 'modules/helpers/settings';
import { importSettings } from 'modules/helpers/settings/modals';
const languages = require("modules/languages.json");
const default_settings = require("modules/default_settings.json");
const languages = require('modules/languages.json');
const default_settings = require('modules/default_settings.json');
export default class WelcomeSections extends PureComponent {
getMessage = (text) =>
variables.language.getMessage(variables.languagecode, text);
getMessage = (text) => variables.language.getMessage(variables.languagecode, text);
constructor() {
super();
this.state = {
// themes
autoClass: "toggle auto active",
lightClass: "toggle lightTheme",
darkClass: "toggle darkTheme",
autoClass: 'toggle auto active',
lightClass: 'toggle lightTheme',
darkClass: 'toggle darkTheme',
// welcome
welcomeImage: 0,
// final
@ -39,22 +33,17 @@ export default class WelcomeSections extends PureComponent {
changeTheme(type) {
this.setState({
autoClass: type === "auto" ? "toggle auto active" : "toggle auto",
lightClass:
type === "light" ? "toggle lightTheme active" : "toggle lightTheme",
darkClass:
type === "dark" ? "toggle darkTheme active" : "toggle darkTheme",
autoClass: type === 'auto' ? 'toggle auto active' : 'toggle auto',
lightClass: type === 'light' ? 'toggle lightTheme active' : 'toggle lightTheme',
darkClass: type === 'dark' ? 'toggle darkTheme active' : 'toggle darkTheme',
});
localStorage.setItem("theme", type);
localStorage.setItem('theme', type);
loadSettings(true);
}
getSetting(name) {
const value = localStorage
.getItem(name)
.replace("false", "Off")
.replace("true", "On");
const value = localStorage.getItem(name).replace('false', 'Off').replace('true', 'On');
return value.charAt(0).toUpperCase() + value.slice(1);
}
@ -66,11 +55,11 @@ export default class WelcomeSections extends PureComponent {
Object.keys(data).forEach((setting) => {
// language and theme already shown, the others are only used internally
if (
setting === "language" ||
setting === "theme" ||
setting === "firstRun" ||
setting === "showWelcome" ||
setting === "showReminder"
setting === 'language' ||
setting === 'theme' ||
setting === 'firstRun' ||
setting === 'showWelcome' ||
setting === 'showReminder'
) {
return;
}
@ -131,10 +120,8 @@ export default class WelcomeSections extends PureComponent {
render() {
const intro = (
<>
<span className="mainTitle">
{this.getMessage("modals.welcome.sections.intro.title")}
</span>
<p>{this.getMessage("modals.welcome.sections.intro.description")}</p>
<span className="mainTitle">{this.getMessage('modals.welcome.sections.intro.title')}</span>
<p>{this.getMessage('modals.welcome.sections.intro.description')}</p>
<h3 className="quicktip">#shareyourmue</h3>
<div className="examples">
<img
@ -149,10 +136,10 @@ export default class WelcomeSections extends PureComponent {
const chooseLanguage = (
<>
<span className="mainTitle">
{this.getMessage("modals.welcome.sections.language.title")}
{this.getMessage('modals.welcome.sections.language.title')}
</span>
<p>
{this.getMessage("modals.welcome.sections.language.description")}{" "}
{this.getMessage('modals.welcome.sections.language.description')}{' '}
<a
href={variables.constants.TRANSLATIONS_URL}
className="resetLink"
@ -169,48 +156,25 @@ export default class WelcomeSections extends PureComponent {
const theme = (
<>
<span className="mainTitle">
{this.getMessage("modals.welcome.sections.theme.title")}
</span>
<p>{this.getMessage("modals.welcome.sections.theme.description")}</p>
<span className="mainTitle">{this.getMessage('modals.welcome.sections.theme.title')}</span>
<p>{this.getMessage('modals.welcome.sections.theme.description')}</p>
<div className="themesToggleArea">
<div
className={this.state.autoClass}
onClick={() => this.changeTheme("auto")}
>
<div className={this.state.autoClass} onClick={() => this.changeTheme('auto')}>
<MdAutoAwesome />
<span>
{this.getMessage(
"modals.main.settings.sections.appearance.theme.auto"
)}
</span>
<span>{this.getMessage('modals.main.settings.sections.appearance.theme.auto')}</span>
</div>
<div className="options">
<div
className={this.state.lightClass}
onClick={() => this.changeTheme("light")}
>
<div className={this.state.lightClass} onClick={() => this.changeTheme('light')}>
<MdLightMode />
<span>
{this.getMessage(
"modals.main.settings.sections.appearance.theme.light"
)}
</span>
<span>{this.getMessage('modals.main.settings.sections.appearance.theme.light')}</span>
</div>
<div
className={this.state.darkClass}
onClick={() => this.changeTheme("dark")}
>
<div className={this.state.darkClass} onClick={() => this.changeTheme('dark')}>
<MdDarkMode />
<span>
{this.getMessage(
"modals.main.settings.sections.appearance.theme.dark"
)}
</span>
<span>{this.getMessage('modals.main.settings.sections.appearance.theme.dark')}</span>
</div>
</div>
<h3 className="quicktip">{this.getMessage("modals.welcome.tip")}</h3>
<p>{this.getMessage("modals.welcome.sections.theme.tip")}</p>
<h3 className="quicktip">{this.getMessage('modals.welcome.tip')}</h3>
<p>{this.getMessage('modals.welcome.sections.theme.tip')}</p>
</div>
</>
);
@ -218,16 +182,13 @@ export default class WelcomeSections extends PureComponent {
const settings = (
<>
<span className="mainTitle">
{this.getMessage("modals.welcome.sections.settings.title")}
{this.getMessage('modals.welcome.sections.settings.title')}
</span>
<p>{this.getMessage("modals.welcome.sections.settings.description")}</p>
<button
className="upload"
onClick={() => document.getElementById("file-input").click()}
>
<p>{this.getMessage('modals.welcome.sections.settings.description')}</p>
<button className="upload" onClick={() => document.getElementById('file-input').click()}>
<MdCloudUpload />
<br />
<span>{this.getMessage("modals.main.settings.buttons.import")}</span>
<span>{this.getMessage('modals.main.settings.buttons.import')}</span>
</button>
<FileUpload
id="file-input"
@ -235,58 +196,44 @@ export default class WelcomeSections extends PureComponent {
type="settings"
loadFunction={(e) => this.importSettings(e)}
/>
<h3 className="quicktip">{this.getMessage("modals.welcome.tip")}</h3>
<p>{this.getMessage("modals.welcome.sections.settings.tip")}</p>
<h3 className="quicktip">{this.getMessage('modals.welcome.tip')}</h3>
<p>{this.getMessage('modals.welcome.sections.settings.tip')}</p>
</>
);
const privacy = (
<>
<span className="mainTitle">
{this.getMessage("modals.welcome.sections.privacy.title")}
{this.getMessage('modals.welcome.sections.privacy.title')}
</span>
<p>{this.getMessage("modals.welcome.sections.privacy.description")}</p>
<p>{this.getMessage('modals.welcome.sections.privacy.description')}</p>
<Checkbox
name="offlineMode"
text={this.getMessage(
"modals.main.settings.sections.advanced.offline_mode"
)}
text={this.getMessage('modals.main.settings.sections.advanced.offline_mode')}
element=".other"
/>
<p>
{this.getMessage(
"modals.welcome.sections.privacy.offline_mode_description"
)}
</p>
<p>{this.getMessage('modals.welcome.sections.privacy.offline_mode_description')}</p>
<Checkbox
name="quicklinksddgProxy"
text={
this.getMessage(
"modals.main.settings.sections.background.ddg_image_proxy"
) +
" (" +
this.getMessage("modals.main.settings.sections.quicklinks.title") +
")"
this.getMessage('modals.main.settings.sections.background.ddg_image_proxy') +
' (' +
this.getMessage('modals.main.settings.sections.quicklinks.title') +
')'
}
/>
<Checkbox
name="ddgProxy"
text={
this.getMessage(
"modals.main.settings.sections.background.ddg_image_proxy"
) +
" (" +
this.getMessage("modals.main.settings.sections.background.title") +
")"
this.getMessage('modals.main.settings.sections.background.ddg_image_proxy') +
' (' +
this.getMessage('modals.main.settings.sections.background.title') +
')'
}
/>
<p>
{this.getMessage(
"modals.welcome.sections.privacy.ddg_proxy_description"
)}
</p>
<p>{this.getMessage('modals.welcome.sections.privacy.ddg_proxy_description')}</p>
<h3 className="quicktip">
{this.getMessage("modals.welcome.sections.privacy.links.title")}
{this.getMessage('modals.welcome.sections.privacy.links.title')}
</h3>
<a
className="privacy"
@ -294,59 +241,45 @@ export default class WelcomeSections extends PureComponent {
target="_blank"
rel="noopener noreferrer"
>
{this.getMessage(
"modals.welcome.sections.privacy.links.privacy_policy"
)}
{this.getMessage('modals.welcome.sections.privacy.links.privacy_policy')}
</a>
<br />
<br />
<a
className="privacy"
href={"https://github.com/" + variables.constants.ORG_NAME}
href={'https://github.com/' + variables.constants.ORG_NAME}
target="_blank"
rel="noopener noreferrer"
>
{this.getMessage("modals.welcome.sections.privacy.links.source_code")}
{this.getMessage('modals.welcome.sections.privacy.links.source_code')}
</a>
</>
);
const final = (
<>
<span className="mainTitle">
{this.getMessage("modals.welcome.sections.final.title")}
</span>
<p>{this.getMessage("modals.welcome.sections.final.description")}</p>
<h3 className="quicktip">
{this.getMessage("modals.welcome.sections.final.changes")}
</h3>
<p>
{this.getMessage("modals.welcome.sections.final.changes_description")}
</p>
<span className="mainTitle">{this.getMessage('modals.welcome.sections.final.title')}</span>
<p>{this.getMessage('modals.welcome.sections.final.description')}</p>
<h3 className="quicktip">{this.getMessage('modals.welcome.sections.final.changes')}</h3>
<p>{this.getMessage('modals.welcome.sections.final.changes_description')}</p>
<div className="themesToggleArea">
<div className="toggle" onClick={() => this.props.switchTab(1)}>
<span>
{this.getMessage("modals.main.settings.sections.language.title")}:{" "}
{
languages.find(
(i) => i.value === localStorage.getItem("language")
).name
}
{this.getMessage('modals.main.settings.sections.language.title')}:{' '}
{languages.find((i) => i.value === localStorage.getItem('language')).name}
</span>
</div>
<div className="toggle" onClick={() => this.props.switchTab(3)}>
<span>
{this.getMessage(
"modals.main.settings.sections.appearance.theme.title"
)}
: {this.getSetting("theme")}
{this.getMessage('modals.main.settings.sections.appearance.theme.title')}:{' '}
{this.getSetting('theme')}
</span>
</div>
{this.state.importedSettings.length !== 0 ? (
<div className="toggle" onClick={() => this.props.switchTab(2)}>
{this.getMessage("modals.main.settings.sections.final.imported", {
{this.getMessage('modals.main.settings.sections.final.imported', {
amount: this.state.importedSettings.length,
})}{" "}
})}{' '}
{this.state.importedSettings.length}
</div>
) : null}

View File

@ -1,67 +1,64 @@
import { PureComponent, Fragment, Suspense, lazy } from "react";
import { PureComponent, Fragment, Suspense, lazy } from 'react';
import Clock from "./time/Clock";
import Greeting from "./greeting/Greeting";
import Quote from "./quote/Quote";
import Search from "./search/Search";
import QuickLinks from "./quicklinks/QuickLinks";
import Date from "./time/Date";
import Message from "./message/Message";
import Reminder from "./reminder/Reminder";
import Clock from './time/Clock';
import Greeting from './greeting/Greeting';
import Quote from './quote/Quote';
import Search from './search/Search';
import QuickLinks from './quicklinks/QuickLinks';
import Date from './time/Date';
import Message from './message/Message';
import Reminder from './reminder/Reminder';
import EventBus from "modules/helpers/eventbus";
import EventBus from 'modules/helpers/eventbus';
const Weather = lazy(() => import("./weather/Weather"));
const Weather = lazy(() => import('./weather/Weather'));
const renderLoader = () => <></>;
export default class Widgets extends PureComponent {
online = localStorage.getItem("offlineMode") === "false";
online = localStorage.getItem('offlineMode') === 'false';
constructor() {
super();
this.state = {
order: JSON.parse(localStorage.getItem("order")),
welcome: localStorage.getItem("showWelcome"),
order: JSON.parse(localStorage.getItem('order')),
welcome: localStorage.getItem('showWelcome'),
};
// widgets we can re-order
this.widgets = {
time: this.enabled("time") ? <Clock /> : null,
greeting: this.enabled("greeting") ? <Greeting /> : null,
quote: this.enabled("quote") ? <Quote /> : null,
date: this.enabled("date") ? <Date /> : null,
quicklinks:
this.enabled("quicklinksenabled") && this.online ? (
<QuickLinks />
) : null,
message: this.enabled("message") ? <Message /> : null,
reminder: this.enabled("reminder") ? <Reminder /> : null,
time: this.enabled('time') ? <Clock /> : null,
greeting: this.enabled('greeting') ? <Greeting /> : null,
quote: this.enabled('quote') ? <Quote /> : null,
date: this.enabled('date') ? <Date /> : null,
quicklinks: this.enabled('quicklinksenabled') && this.online ? <QuickLinks /> : null,
message: this.enabled('message') ? <Message /> : null,
reminder: this.enabled('reminder') ? <Reminder /> : null,
};
}
enabled(key) {
return localStorage.getItem(key) === "true";
return localStorage.getItem(key) === 'true';
}
componentDidMount() {
EventBus.on("refresh", (data) => {
if (data === "widgets") {
EventBus.on('refresh', (data) => {
if (data === 'widgets') {
this.setState({
order: JSON.parse(localStorage.getItem("order")),
order: JSON.parse(localStorage.getItem('order')),
});
}
if (data === "widgetsWelcome") {
if (data === 'widgetsWelcome') {
this.setState({
welcome: localStorage.getItem("showWelcome"),
welcome: localStorage.getItem('showWelcome'),
});
localStorage.setItem("showWelcome", true);
localStorage.setItem('showWelcome', true);
window.onbeforeunload = () => {
localStorage.clear();
};
}
if (data === "widgetsWelcomeDone") {
if (data === 'widgetsWelcomeDone') {
this.setState({
welcome: localStorage.getItem("showWelcome"),
welcome: localStorage.getItem('showWelcome'),
});
window.onbeforeunload = null;
}
@ -70,7 +67,7 @@ export default class Widgets extends PureComponent {
render() {
// don't show when welcome is there
if (this.state.welcome !== "false") {
if (this.state.welcome !== 'false') {
return <div id="widgets"></div>;
}
@ -79,9 +76,7 @@ export default class Widgets extends PureComponent {
if (this.state.order) {
this.state.order.forEach((element) => {
elements.push(
<Fragment key={element}>{this.widgets[element]}</Fragment>
);
elements.push(<Fragment key={element}>{this.widgets[element]}</Fragment>);
});
} else {
// prevent error
@ -99,9 +94,9 @@ export default class Widgets extends PureComponent {
return (
<div id="widgets">
<Suspense fallback={renderLoader()}>
{this.enabled("searchBar") ? <Search /> : null}
{this.enabled('searchBar') ? <Search /> : null}
{elements}
{this.enabled("weatherEnabled") && this.online ? <Weather /> : null}
{this.enabled('weatherEnabled') && this.online ? <Weather /> : null}
</Suspense>
</div>
);

View File

@ -50,6 +50,7 @@
}
}
.photoInformation-content {
padding: 20px;
padding-left: 0;
}
.map-concept {
@ -183,13 +184,14 @@
font-size: 0.8em;
font-weight: 300;
z-index: 99;
padding: 20px;
display: flex;
flex-flow: row;
align-items: center;
transition: 0.8s cubic-bezier(0.075, 0.82, 0.165, 1);
width: 380px;
width: 300px;
padding: 10px;
&:hover {
padding: 20px;
height: auto;
align-items: flex-start;
flex-flow: column;
@ -240,15 +242,15 @@
}
.map-concept {
@extend %basic;
height: 80px;
width: 80px;
height: 50px;
width: 50px;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
border: none !important;
svg {
font-size: 25px;
font-size: 24px;
}
img {
width: 100%;
@ -281,7 +283,7 @@
.photoInformation-content {
display: flex;
flex-flow: column;
padding: 20px;
padding-left: 20px;
a {
color: #5352ed;
text-decoration: none;

View File

@ -89,14 +89,16 @@ export default class Navbar extends PureComponent {
linkText={'Learn more'}
>
</InfoTooltip>*/}
<Tooltip
title={variables.language.getMessage(
variables.languagecode,
'modals.main.navbar.settings',
)}
><button onClick={() => this.props.openModal('mainModal')}>
<MdSettings className="settings-icon topicons" />
</button></Tooltip>
<Tooltip
title={variables.language.getMessage(
variables.languagecode,
'modals.main.navbar.settings',
)}
>
<button onClick={() => this.props.openModal('mainModal')}>
<MdSettings className="settings-icon topicons" />
</button>
</Tooltip>
</div>
{/*<div className="notification">
<span className="title">New Update</span>

View File

@ -57,7 +57,6 @@
}
}
.flexNotes {
display: flex;
flex-flow: column;

View File

@ -61,4 +61,3 @@
cursor: not-allowed;
}
}

View File

@ -30,7 +30,6 @@
border-radius: 12px;
}
::placeholder {
color: #636e72;
opacity: 1;

View File

@ -63,7 +63,7 @@ export default class Quote extends PureComponent {
copy: localStorage.getItem('copyButton') === 'false' ? null : this.buttons.copy,
quoteLanguage: '',
type: localStorage.getItem('quoteType') || 'api',
shareModal: false
shareModal: false,
};
this.quote = createRef();
this.quotediv = createRef();
@ -398,7 +398,7 @@ export default class Quote extends PureComponent {
<span className="quote" ref={this.quote}>
{this.state.quote}
</span>
{localStorage.getItem('widgetStyle') === 'legacy' ? (
{(localStorage.getItem('widgetStyle') === 'legacy') ? (
<>
<div>
<h1 className="quoteauthor" ref={this.quoteauthor}>
@ -417,38 +417,42 @@ export default class Quote extends PureComponent {
</div>
</>
) : (
<div className="author-holder">
<div className="author">
<div
className="author-img"
style={{ backgroundImage: `url(${this.state.authorimg})` }}
>
{this.state.authorimg === undefined || this.state.authorimg ? '' : <MdPerson />}
<>
{this.state.author !== '' ? (
<div className="author-holder">
<div className="author">
<div
className="author-img"
style={{ backgroundImage: `url(${this.state.authorimg})` }}
>
{this.state.authorimg === undefined || this.state.authorimg ? '' : <MdPerson />}
</div>
<div className="author-content" ref={this.quoteauthor}>
<span className="title">{this.state.author}</span>
{this.state.authorOccupation !== 'Unknown' ? (
<span className="subtitle">{this.state.authorOccupation}</span>
) : null}
<span className="author-license">{this.state.authorimglicense}</span>
</div>
<div className="quote-buttons">
{this.state.authorOccupation !== 'Unknown' ? (
<Tooltip title="Open">
<a
href={this.state.authorlink}
className="quoteAuthorLink"
target="_blank"
rel="noopener noreferrer"
>
<MdOpenInNew />
</a>{' '}
</Tooltip>
) : null}
{this.state.copy} {this.state.share} {this.state.favourited}
</div>
</div>
</div>
<div className="author-content" ref={this.quoteauthor}>
<span className="title">{this.state.author}</span>
{this.state.authorOccupation !== 'Unknown' ? (
<span className="subtitle">{this.state.authorOccupation}</span>
) : null}
<span className="author-license">{this.state.authorimglicense}</span>
</div>
<div className="quote-buttons">
{this.state.authorOccupation !== 'Unknown' ? (
<Tooltip title="Open">
<a
href={this.state.authorlink}
className="quoteAuthorLink"
target="_blank"
rel="noopener noreferrer"
>
<MdOpenInNew />
</a>{' '}
</Tooltip>
) : null}
{this.state.copy} {this.state.share} {this.state.favourited}
</div>
</div>
</div>
) : <div ref={this.quoteauthor}></div> }
</>
)}
{/*variables.keybinds.favouriteQuote && variables.keybinds.favouriteQuote !== '' ? <Hotkeys keyName={variables.keybinds.favouriteQuote} onKeyDown={() => this.favourite()} /> : null*/}
{/*variables.keybinds.tweetQuote && variables.keybinds.tweetQuote !== '' ? <Hotkeys keyName={variables.keybinds.tweetQuote} onKeyDown={() => this.tweetQuote()} /> : null*/}

View File

@ -93,6 +93,16 @@ h1.quoteauthor {
align-items: center;
justify-content: center;
flex-flow: column;
animation: fadeIn 1s;
}
@keyframes fadeIn {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.quote-buttons {
@ -110,6 +120,7 @@ h1.quoteauthor {
}
.quotediv {
animation: fadeIn 1s;
width: 40vw;
display: flex;
flex-direction: column;

View File

@ -5,21 +5,26 @@ import './reminder.scss';
import { MdClose, MdSnooze, MdWork } from 'react-icons/md';
export default class Reminder extends React.PureComponent {
render() {
return (
<div className='reminder'>
<div className='identifier' style={{ backgroundColor: localStorage.getItem('reminderColour') || 'orange' }}>
<MdWork />
</div>
<div className='content'>
<span className='title'>Reminder</span>
<span className='subtitle'>Time</span>
</div>
<div className='icons'>
<MdClose />
<MdSnooze />
</div>
</div>
)
}
}
render() {
return (
<div className="reminder">
<div
className="identifier"
style={{
backgroundColor: localStorage.getItem('reminderColour') || 'orange',
}}
>
<MdWork />
</div>
<div className="content">
<span className="title">Reminder</span>
<span className="subtitle">Time</span>
</div>
<div className="icons">
<MdClose />
<MdSnooze />
</div>
</div>
);
}
}

View File

@ -14,4 +14,3 @@
"query": "&query="
}
]

View File

@ -1,11 +1,11 @@
import { PureComponent, Suspense, lazy } from "react";
import { PureComponent, Suspense, lazy } from 'react';
import { convertTimezone } from "modules/helpers/date";
import EventBus from "modules/helpers/eventbus";
import { convertTimezone } from 'modules/helpers/date';
import EventBus from 'modules/helpers/eventbus';
import "./clock.scss";
import './clock.scss';
const Analog = lazy(() => import("react-clock"));
const Analog = lazy(() => import('react-clock'));
const renderLoader = () => <></>;
export default class Clock extends PureComponent {
@ -14,34 +14,34 @@ export default class Clock extends PureComponent {
this.timer = undefined;
this.state = {
time: "",
ampm: "",
time: '',
ampm: '',
};
}
startTime(
time = localStorage.getItem("seconds") === "true" ||
localStorage.getItem("timeType") === "analogue"
time = localStorage.getItem('seconds') === 'true' ||
localStorage.getItem('timeType') === 'analogue'
? 1000 - (Date.now() % 1000)
: 60000 - (Date.now() % 60000)
: 60000 - (Date.now() % 60000),
) {
this.timer = setTimeout(() => {
let now = new Date();
const timezone = localStorage.getItem("timezone");
if (timezone && timezone !== "auto") {
const timezone = localStorage.getItem('timezone');
if (timezone && timezone !== 'auto') {
now = convertTimezone(now, timezone);
}
switch (localStorage.getItem("timeType")) {
case "percentageComplete":
switch (localStorage.getItem('timeType')) {
case 'percentageComplete':
this.setState({
time: (now.getHours() / 24).toFixed(2).replace("0.", "") + "%",
ampm: "",
time: (now.getHours() / 24).toFixed(2).replace('0.', '') + '%',
ampm: '',
});
break;
case "analogue":
case 'analogue':
// load analog clock css
require("react-clock/dist/Clock.css");
require('react-clock/dist/Clock.css');
this.setState({
time: now,
@ -50,27 +50,25 @@ export default class Clock extends PureComponent {
default:
// Default clock
let time,
sec = "";
const zero = localStorage.getItem("zero");
sec = '';
const zero = localStorage.getItem('zero');
if (localStorage.getItem("seconds") === "true") {
sec = `:${("00" + now.getSeconds()).slice(-2)}`;
if (localStorage.getItem('seconds') === 'true') {
sec = `:${('00' + now.getSeconds()).slice(-2)}`;
}
if (localStorage.getItem("timeformat") === "twentyfourhour") {
if (zero === "false") {
time = `${now.getHours()}:${("00" + now.getMinutes()).slice(
-2
)}${sec}`;
if (localStorage.getItem('timeformat') === 'twentyfourhour') {
if (zero === 'false') {
time = `${now.getHours()}:${('00' + now.getMinutes()).slice(-2)}${sec}`;
} else {
time = `${("00" + now.getHours()).slice(-2)}:${(
"00" + now.getMinutes()
).slice(-2)}${sec}`;
time = `${('00' + now.getHours()).slice(-2)}:${('00' + now.getMinutes()).slice(
-2,
)}${sec}`;
}
this.setState({
time,
ampm: "",
ampm: '',
});
} else {
// 12 hour
@ -82,17 +80,15 @@ export default class Clock extends PureComponent {
hours = 12;
}
if (zero === "false") {
time = `${hours}:${("00" + now.getMinutes()).slice(-2)}${sec}`;
if (zero === 'false') {
time = `${hours}:${('00' + now.getMinutes()).slice(-2)}${sec}`;
} else {
time = `${("00" + hours).slice(-2)}:${(
"00" + now.getMinutes()
).slice(-2)}${sec}`;
time = `${('00' + hours).slice(-2)}:${('00' + now.getMinutes()).slice(-2)}${sec}`;
}
this.setState({
time,
ampm: now.getHours() > 11 ? "PM" : "AM",
ampm: now.getHours() > 11 ? 'PM' : 'AM',
});
}
break;
@ -103,27 +99,27 @@ export default class Clock extends PureComponent {
}
componentDidMount() {
EventBus.on("refresh", (data) => {
if (data === "clock" || data === "timezone") {
const element = document.querySelector(".clock-container");
EventBus.on('refresh', (data) => {
if (data === 'clock' || data === 'timezone') {
const element = document.querySelector('.clock-container');
if (localStorage.getItem("time") === "false") {
return (element.style.display = "none");
if (localStorage.getItem('time') === 'false') {
return (element.style.display = 'none');
}
this.timer = null;
this.startTime(0);
element.style.display = "block";
element.style.display = 'block';
element.style.fontSize = `${
4 * Number((localStorage.getItem("zoomClock") || 100) / 100)
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)
if (localStorage.getItem('timeType') !== 'analogue') {
document.querySelector('.clock-container').style.fontSize = `${
4 * Number((localStorage.getItem('zoomClock') || 100) / 100)
}em`;
}
@ -131,7 +127,7 @@ export default class Clock extends PureComponent {
}
componentWillUnmount() {
EventBus.off("refresh");
EventBus.off('refresh');
}
render() {
@ -143,21 +139,21 @@ export default class Clock extends PureComponent {
);
const enabled = (setting) => {
return localStorage.getItem(setting) === "true";
return localStorage.getItem(setting) === 'true';
};
if (localStorage.getItem("timeType") === "analogue") {
if (localStorage.getItem('timeType') === 'analogue') {
clockHTML = (
<Suspense fallback={renderLoader()}>
<div className="clockBackground">
<Analog
className="analogclock clock-container"
value={this.state.time}
renderMinuteMarks={enabled("minuteMarks")}
renderHourMarks={enabled("hourMarks")}
renderSecondHand={enabled("secondHand")}
renderMinuteHand={enabled("minuteHand")}
renderHourHand={enabled("hourHand")}
renderMinuteMarks={enabled('minuteMarks')}
renderHourMarks={enabled('hourMarks')}
renderSecondHand={enabled('secondHand')}
renderMinuteHand={enabled('minuteHand')}
renderHourHand={enabled('hourHand')}
/>
</div>
</Suspense>

View File

@ -1,16 +1,16 @@
import variables from "modules/variables";
import { PureComponent, createRef } from "react";
import variables from 'modules/variables';
import { PureComponent, createRef } from 'react';
import { nth, convertTimezone } from "modules/helpers/date";
import EventBus from "modules/helpers/eventbus";
import { nth, convertTimezone } from 'modules/helpers/date';
import EventBus from 'modules/helpers/eventbus';
import "./date.scss";
import './date.scss';
export default class DateWidget extends PureComponent {
constructor() {
super();
this.state = {
date: "",
date: '',
weekNumber: null,
};
this.date = createRef();
@ -29,21 +29,20 @@ export default class DateWidget extends PureComponent {
}
this.setState({
weekNumber: `${variables.language.getMessage(
variables.languagecode,
"widgets.date.week"
)} ${1 + Math.ceil((firstThursday - dateToday) / 604800000)}`,
weekNumber: `${variables.language.getMessage(variables.languagecode, 'widgets.date.week')} ${
1 + Math.ceil((firstThursday - dateToday) / 604800000)
}`,
});
}
getDate() {
let date = new Date();
const timezone = localStorage.getItem("timezone");
if (timezone && timezone !== "auto") {
const timezone = localStorage.getItem('timezone');
if (timezone && timezone !== 'auto') {
date = convertTimezone(date, timezone);
}
if (localStorage.getItem("weeknumber") === "true") {
if (localStorage.getItem('weeknumber') === 'true') {
this.getWeekNumber(date);
} else if (this.state.weekNumber !== null) {
this.setState({
@ -51,23 +50,23 @@ export default class DateWidget extends PureComponent {
});
}
if (localStorage.getItem("dateType") === "short") {
if (localStorage.getItem('dateType') === 'short') {
const dateDay = date.getDate();
const dateMonth = date.getMonth() + 1;
const dateYear = date.getFullYear();
const zero = localStorage.getItem("datezero") === "true";
const zero = localStorage.getItem('datezero') === 'true';
let day = zero ? ("00" + dateDay).slice(-2) : dateDay;
let month = zero ? ("00" + dateMonth).slice(-2) : dateMonth;
let day = zero ? ('00' + dateDay).slice(-2) : dateDay;
let month = zero ? ('00' + dateMonth).slice(-2) : dateMonth;
let year = dateYear;
switch (localStorage.getItem("dateFormat")) {
case "MDY":
switch (localStorage.getItem('dateFormat')) {
case 'MDY':
day = dateMonth;
month = dateDay;
break;
case "YMD":
case 'YMD':
day = dateYear;
year = dateDay;
break;
@ -77,17 +76,17 @@ export default class DateWidget extends PureComponent {
}
let format;
switch (localStorage.getItem("shortFormat")) {
case "dots":
switch (localStorage.getItem('shortFormat')) {
case 'dots':
format = `${day}.${month}.${year}`;
break;
case "dash":
case 'dash':
format = `${day}-${month}-${year}`;
break;
case "gaps":
case 'gaps':
format = `${day} - ${month} - ${year}`;
break;
case "slashes":
case 'slashes':
format = `${day}/${month}/${year}`;
break;
default:
@ -99,31 +98,29 @@ export default class DateWidget extends PureComponent {
});
} else {
// Long date
const lang = variables.languagecode.split("_")[0];
const lang = variables.languagecode.split('_')[0];
const datenth =
localStorage.getItem("datenth") === "true"
? nth(date.getDate())
: date.getDate();
localStorage.getItem('datenth') === 'true' ? nth(date.getDate()) : date.getDate();
const dateDay =
localStorage.getItem("dayofweek") === "true"
? date.toLocaleDateString(lang, { weekday: "long" })
: "";
const dateMonth = date.toLocaleDateString(lang, { month: "long" });
localStorage.getItem('dayofweek') === 'true'
? date.toLocaleDateString(lang, { weekday: 'long' })
: '';
const dateMonth = date.toLocaleDateString(lang, { month: 'long' });
const dateYear = date.getFullYear();
let day = dateDay + " " + datenth;
let day = dateDay + ' ' + datenth;
let month = dateMonth;
let year = dateYear;
switch (localStorage.getItem("longFormat")) {
case "MDY":
switch (localStorage.getItem('longFormat')) {
case 'MDY':
day = dateMonth;
month = dateDay + " " + datenth;;
month = dateDay + ' ' + datenth;
break;
case "YMD":
case 'YMD':
day = dateYear;
year = dateDay + " " + datenth;;
year = dateDay + ' ' + datenth;
break;
// DMY
default:
@ -137,28 +134,28 @@ export default class DateWidget extends PureComponent {
}
componentDidMount() {
EventBus.on("refresh", (data) => {
if (data === "date" || data === "timezone") {
if (localStorage.getItem("date") === "false") {
return (this.date.current.style.display = "none");
EventBus.on('refresh', (data) => {
if (data === 'date' || data === 'timezone') {
if (localStorage.getItem('date') === 'false') {
return (this.date.current.style.display = 'none');
}
this.date.current.style.display = "block";
this.date.current.style.display = 'block';
this.date.current.style.fontSize = `${Number(
(localStorage.getItem("zoomDate") || 100) / 100
(localStorage.getItem('zoomDate') || 100) / 100,
)}em`;
this.getDate();
}
});
this.date.current.style.fontSize = `${Number(
(localStorage.getItem("zoomDate") || 100) / 100
(localStorage.getItem('zoomDate') || 100) / 100,
)}em`;
this.getDate();
}
componentWillUnmount() {
EventBus.off("refresh");
EventBus.off('refresh');
}
render() {

View File

@ -1,43 +1,41 @@
import variables from "modules/variables";
import { PureComponent } from "react";
import { WiHumidity, WiWindy, WiBarometer, WiCloud } from "react-icons/wi";
import { MdDisabledVisible } from "react-icons/md";
import variables from 'modules/variables';
import { PureComponent } from 'react';
import { WiHumidity, WiWindy, WiBarometer, WiCloud } from 'react-icons/wi';
import { MdDisabledVisible } from 'react-icons/md';
import WeatherIcon from "./WeatherIcon";
import WindDirectionIcon from "./WindDirectionIcon";
import WeatherIcon from './WeatherIcon';
import WindDirectionIcon from './WindDirectionIcon';
import EventBus from "modules/helpers/eventbus";
import EventBus from 'modules/helpers/eventbus';
import "./weather.scss";
import './weather.scss';
export default class Weather extends PureComponent {
constructor() {
super();
this.state = {
location: localStorage.getItem("location") || "London",
icon: "",
temp_text: "",
location: localStorage.getItem('location') || 'London',
icon: '',
temp_text: '',
weather: {
temp: "",
description: "",
temp_min: "",
temp_max: "",
temp_feels_like: "",
humidity: "",
wind_speed: "",
wind_degrees: "",
cloudiness: "",
visibility: "",
pressure: "",
temp: '',
description: '',
temp_min: '',
temp_max: '',
temp_feels_like: '',
humidity: '',
wind_speed: '',
wind_degrees: '',
cloudiness: '',
visibility: '',
pressure: '',
},
};
}
async getWeather() {
const zoomWeather = `${Number(
(localStorage.getItem("zoomWeather") || 100) / 100
)}em`;
document.querySelector(".weather").style.fontSize = zoomWeather;
const zoomWeather = `${Number((localStorage.getItem('zoomWeather') || 100) / 100)}em`;
document.querySelector('.weather').style.fontSize = zoomWeather;
let data = {
weather: [
@ -68,16 +66,16 @@ export default class Weather extends PureComponent {
data = await (
await fetch(
variables.constants.PROXY_URL +
`/weather/current?city=${this.state.location}&lang=${variables.languagecode}`
`/weather/current?city=${this.state.location}&lang=${variables.languagecode}`,
)
).json();
}
if (data.cod === "404") {
if (data.cod === '404') {
return this.setState({
location: variables.language.getMessage(
variables.languagecode,
"widgets.weather.not_found"
'widgets.weather.not_found',
),
});
}
@ -86,22 +84,22 @@ export default class Weather extends PureComponent {
let temp_min = data.main.temp_min;
let temp_max = data.main.temp_max;
let temp_feels_like = data.main.temp_feels_like;
let temp_text = "K";
let temp_text = 'K';
switch (localStorage.getItem("tempformat")) {
case "celsius":
switch (localStorage.getItem('tempformat')) {
case 'celsius':
temp -= 273.15;
temp_min -= 273.15;
temp_max -= 273.15;
temp_feels_like -= 273.15;
temp_text = "°C";
temp_text = '°C';
break;
case "fahrenheit":
case 'fahrenheit':
temp = (temp - 273.15) * 1.8 + 32;
temp_min = (temp_min - 273.15) * 1.8 + 32;
temp_max = (temp_max - 273.15) * 1.8 + 32;
temp_feels_like = (temp_feels_like - 273.15) * 1.8 + 32;
temp_text = "°F";
temp_text = '°F';
break;
// kelvin
default:
@ -130,12 +128,12 @@ export default class Weather extends PureComponent {
},
});
document.querySelector(".weather svg").style.fontSize = zoomWeather;
document.querySelector('.weather svg').style.fontSize = zoomWeather;
}
componentDidMount() {
EventBus.on("refresh", (data) => {
if (data === "weather") {
EventBus.on('refresh', (data) => {
if (data === 'weather') {
this.getWeather();
}
});
@ -144,17 +142,17 @@ export default class Weather extends PureComponent {
}
componentWillUnmount() {
EventBus.off("refresh");
EventBus.off('refresh');
}
render() {
const enabled = (setting) => {
return localStorage.getItem(setting) === "true";
return localStorage.getItem(setting) === 'true';
};
if (
this.state.location ===
variables.language.getMessage(variables.languagecode, "weather.not_found")
variables.language.getMessage(variables.languagecode, 'weather.not_found')
) {
return (
<div className="weather">
@ -164,33 +162,24 @@ export default class Weather extends PureComponent {
}
const minmax = () => {
const mintemp = enabled("mintemp");
const maxtemp = enabled("maxtemp");
const mintemp = enabled('mintemp');
const maxtemp = enabled('maxtemp');
if (!mintemp && !maxtemp) {
return null;
} else if (mintemp && !maxtemp) {
return (
<span className="subtitle">
{this.state.weather.temp_min + this.state.temp_text}
</span>
<span className="subtitle">{this.state.weather.temp_min + this.state.temp_text}</span>
);
} else if (maxtemp && !mintemp) {
return (
<span className="subtitle">
{this.state.weather.temp_max + this.state.temp_text}
</span>
<span className="subtitle">{this.state.weather.temp_max + this.state.temp_text}</span>
);
} else {
return (
<>
<span className="subtitle">
{this.state.weather.temp_min + this.state.temp_text}
</span>{" "}
<span className="subtitle">
{" "}
{this.state.weather.temp_max + this.state.temp_text}
</span>
<span className="subtitle">{this.state.weather.temp_min + this.state.temp_text}</span>{' '}
<span className="subtitle"> {this.state.weather.temp_max + this.state.temp_text}</span>
</>
);
}
@ -208,15 +197,10 @@ export default class Weather extends PureComponent {
</div>
<div className="extra-info">
{/*{enabled('humidity') ? <span><WiHumidity/>{this.state.weather.humidity}%</span> : null}*/}
{enabled("feelsliketemp") ? (
<span>
Feels like{" "}
{this.state.weather.temp_feels_like + this.state.temp_text}
</span>
) : null}
{enabled("showlocation") ? (
<span className="loc">{this.state.location}</span>
{enabled('feelsliketemp') ? (
<span>Feels like {this.state.weather.temp_feels_like + this.state.temp_text}</span>
) : null}
{enabled('showlocation') ? <span className="loc">{this.state.location}</span> : null}
</div>
<div className="expanded-info">
<span className="subtitle">Upcoming Forecast</span>
@ -238,18 +222,18 @@ export default class Weather extends PureComponent {
</div>
</div>
<span className="subtitle">Extra Information</span>
{enabled("cloudiness") ? (
{enabled('cloudiness') ? (
<span>
<WiCloud className="weatherIcon" />
{this.state.weather.cloudiness}%
</span>
) : null}
{enabled("windspeed") ? (
{enabled('windspeed') ? (
<span>
<WiWindy className="weatherIcon" />
{this.state.weather.wind_speed}
<span className="minmax"> m/s</span>{" "}
{enabled("windDirection") ? (
<span className="minmax"> m/s</span>{' '}
{enabled('windDirection') ? (
<div className="weatherIcon">
<WindDirectionIcon
className="weatherIcon"
@ -259,14 +243,14 @@ export default class Weather extends PureComponent {
) : null}
</span>
) : null}
{enabled("atmosphericpressure") ? (
{enabled('atmosphericpressure') ? (
<span>
<WiBarometer className="weatherIcon" />
{this.state.weather.pressure}
<span className="minmax"> hPa</span>
</span>
) : null}
{enabled("weatherdescription") ? (
{enabled('weatherdescription') ? (
<span>
<div className="weatherIcon">
<WeatherIcon name={this.state.icon} />
@ -274,16 +258,12 @@ export default class Weather extends PureComponent {
{this.state.weather.description}
</span>
) : null}
{enabled("visibility") ? (
{enabled('visibility') ? (
<span>
<MdDisabledVisible style={{ padding: "3px" }} />
{variables.language.getMessage(
variables.languagecode,
"widgets.weather.meters",
{
amount: this.state.weather.visibility,
}
)}
<MdDisabledVisible style={{ padding: '3px' }} />
{variables.language.getMessage(variables.languagecode, 'widgets.weather.meters', {
amount: this.state.weather.visibility,
})}
</span>
) : null}
</div>

View File

@ -11,53 +11,53 @@ import {
WiThunderstorm,
WiSnow,
WiFog,
} from "react-icons/wi";
} from 'react-icons/wi';
export default function WeatherIcon({ name }) {
let icon;
// name is the openweathermap icon name, see https://openweathermap.org/weather-conditions
switch (name) {
case "01d":
case '01d':
icon = <WiDaySunny />;
break;
case "01n":
case '01n':
icon = <WiNightClear />;
break;
case "02d":
case '02d':
icon = <WiDayCloudy />;
break;
case "02n":
case '02n':
icon = <WiNightCloudy />;
break;
case "03d":
case "03n":
case '03d':
case '03n':
icon = <WiCloud />;
break;
case "04d":
case "04n":
case '04d':
case '04n':
icon = <WiCloudy />;
break;
case "09d":
case '09d':
icon = <WiDayShowers />;
break;
case "09n":
case '09n':
icon = <WiNightShowers />;
break;
case "10d":
case "10n":
case '10d':
case '10n':
icon = <WiRain />;
break;
case "11d":
case "11n":
case '11d':
case '11n':
icon = <WiThunderstorm />;
break;
case "13d":
case "13n":
case '13d':
case '13n':
icon = <WiSnow />;
break;
case "50d":
case "50n":
case '50d':
case '50n':
icon = <WiFog />;
break;
default:

View File

@ -7,7 +7,7 @@ import {
WiDirectionUpLeft,
WiDirectionUpRight,
WiDirectionUp,
} from "react-icons/wi";
} from 'react-icons/wi';
// degrees are imported because of a potential bug, IDK what causes it, but now it is fixed
export default function WindDirectionIcon({ degrees }) {
@ -15,43 +15,41 @@ export default function WindDirectionIcon({ degrees }) {
// convert the number OpenWeatherMap gives us to the closest direction or something
const directions = [
"North",
"North-West",
"West",
"South-West",
"South",
"South-East",
"East",
"North-East",
'North',
'North-West',
'West',
'South-West',
'South',
'South-East',
'East',
'North-East',
];
const direction =
directions[
Math.round(((degrees %= 360) < 0 ? degrees + 360 : degrees) / 45) % 8
];
directions[Math.round(((degrees %= 360) < 0 ? degrees + 360 : degrees) / 45) % 8];
switch (direction) {
case "North":
case 'North':
icon = <WiDirectionUp />;
break;
case "North-West":
case 'North-West':
icon = <WiDirectionUpLeft />;
break;
case "West":
case 'West':
icon = <WiDirectionLeft />;
break;
case "South-West":
case 'South-West':
icon = <WiDirectionDownLeft />;
break;
case "South":
case 'South':
icon = <WiDirectionDown />;
break;
case "South-East":
case 'South-East':
icon = <WiDirectionDownRight />;
break;
case "East":
case 'East':
icon = <WiDirectionRight />;
break;
case "North-East":
case 'North-East':
icon = <WiDirectionUpRight />;
break;
default:

View File

@ -31,7 +31,7 @@ variables.language = new I18n(variables.languagecode, {
no: require('./translations/no.json'),
ru: require('./translations/ru.json'),
zh_CN: require('./translations/zh_CN.json'),
id_ID: require('./translations/id_ID.json')
id_ID: require('./translations/id_ID.json'),
});
// set html language tag
@ -50,4 +50,4 @@ if (localStorage.getItem('stats') === 'true') {
const container = document.getElementById('root');
const root = createRoot(container);
root.render(<App/>);
root.render(<App />);

View File

@ -13,8 +13,10 @@ export const WEBSITE_URL = 'https://muetab.com';
export const PRIVACY_URL = 'https://muetab.com/privacy';
export const BLOG_POST = 'https://blog.muetab.com/posts/version-6-0';
export const TRANSLATIONS_URL = 'https://docs.muetab.com/translations/';
export const REPORT_ITEM = 'https://github.com/mue/marketplace/issues/new?assignees=&labels=item+report&template=item-report.md&title=%5BItem+Report%5D+';
export const BUG_REPORT = 'https://github.com/mue/mue/issues/new?assignees=&labels=issue+report&template=bug-report.md&title=%5BBug%5D+';
export const REPORT_ITEM =
'https://github.com/mue/marketplace/issues/new?assignees=&labels=item+report&template=item-report.md&title=%5BItem+Report%5D+';
export const BUG_REPORT =
'https://github.com/mue/mue/issues/new?assignees=&labels=issue+report&template=bug-report.md&title=%5BBug%5D+';
export const DONATE_LINK = 'https://muetab.com/donate';
// Mue Info

View File

@ -21,9 +21,9 @@ export default function rgbToHSv({ red, green, blue }) {
if (rabs === v) {
h = bb - gg;
} else if (gabs === v) {
h = (1 / 3) + rr - bb;
h = 1 / 3 + rr - bb;
} else if (babs === v) {
h = (2 / 3) + gg - rr;
h = 2 / 3 + gg - rr;
}
if (h < 0) {

View File

@ -1,5 +1,5 @@
const isValidRGBValue = (value) => {
return (typeof (value) === 'number' && Number.isNaN(value) === false && value >= 0 && value <= 255);
return typeof value === 'number' && Number.isNaN(value) === false && value >= 0 && value <= 255;
};
export default function setRGBA(red, green, blue, alpha) {

View File

@ -1,6 +1,11 @@
// since there is so much code in the component, we have moved it to a separate file
export function videoCheck(url) {
return url.startsWith('data:video/') || url.endsWith('.mp4') || url.endsWith('.webm') || url.endsWith('.ogg');
return (
url.startsWith('data:video/') ||
url.endsWith('.mp4') ||
url.endsWith('.webm') ||
url.endsWith('.ogg')
);
}
export function offlineBackground() {
@ -10,16 +15,17 @@ export function offlineBackground() {
const photographers = Object.keys(offlineImages);
const photographer = photographers[Math.floor(Math.random() * photographers.length)];
const randomImage = offlineImages[photographer].photo[
Math.floor(Math.random() * offlineImages[photographer].photo.length)
];
const randomImage =
offlineImages[photographer].photo[
Math.floor(Math.random() * offlineImages[photographer].photo.length)
];
const object = {
url: `./offline-images/${randomImage}.webp`,
photoInfo: {
offline: true,
credit: photographer
}
credit: photographer,
},
};
localStorage.setItem('currentBackground', JSON.stringify(object));
@ -33,12 +39,16 @@ function gradientStyleBuilder({ type, angle, gradient }) {
return {
type: 'colour',
style: `background:${gradient[0]?.colour};${grad}`
style: `background:${gradient[0]?.colour};${grad}`,
};
}
export function getGradient() {
const customBackgroundColour = localStorage.getItem('customBackgroundColour') || {'angle':'180','gradient':[{'colour':'#ffb032','stop':0}],'type':'linear'};
const customBackgroundColour = localStorage.getItem('customBackgroundColour') || {
angle: '180',
gradient: [{ colour: '#ffb032', stop: 0 }],
type: 'linear',
};
let gradientSettings = '';
try {
@ -47,7 +57,11 @@ export function getGradient() {
const hexColorRegex = /#[0-9a-fA-F]{6}/s;
if (hexColorRegex.exec(customBackgroundColour)) {
// Colour used to be simply a hex colour or a NULL value before it was a JSON object. This automatically upgrades the hex colour value to the new standard. (NULL would not trigger an exception)
gradientSettings = { 'type': 'linear', 'angle': '180', 'gradient': [{ 'colour': customBackgroundColour, 'stop': 0 }] };
gradientSettings = {
type: 'linear',
angle: '180',
gradient: [{ colour: customBackgroundColour, stop: 0 }],
};
localStorage.setItem('customBackgroundColour', JSON.stringify(gradientSettings));
}
}
@ -59,16 +73,30 @@ export function getGradient() {
export function randomColourStyleBuilder(type) {
// randomColour based on https://stackoverflow.com/a/5092872
const randomColour = () => '#000000'.replace(/0/g, () => { return (~~(Math.random()*16)).toString(16) });
const randomColour = () =>
'#000000'.replace(/0/g, () => {
return (~~(Math.random() * 16)).toString(16);
});
let style = `background:${randomColour()};`;
if (type === 'random_gradient') {
const directions = ['to right', 'to left', 'to bottom', 'to top', 'to bottom right', 'to bottom left', 'to top right', 'to top left'];
style = `background:linear-gradient(${directions[Math.floor(Math.random() * directions.length)]}, ${randomColour()}, ${randomColour()});`;
const directions = [
'to right',
'to left',
'to bottom',
'to top',
'to bottom right',
'to bottom left',
'to top right',
'to top left',
];
style = `background:linear-gradient(${
directions[Math.floor(Math.random() * directions.length)]
}, ${randomColour()}, ${randomColour()});`;
}
return {
type: 'colour',
style
}
style,
};
}

View File

@ -16,5 +16,9 @@ export function nth(d) {
}
export function convertTimezone(date, tz) {
return new Date((typeof date === 'string' ? new Date(date) : date).toLocaleString('en-US', { timeZone: tz }));
return new Date(
(typeof date === 'string' ? new Date(date) : date).toLocaleString('en-US', {
timeZone: tz,
}),
);
}

View File

@ -6,9 +6,11 @@ export default class EventBus {
}
static dispatch(event, data) {
document.dispatchEvent(new CustomEvent(event, {
detail: data
}));
document.dispatchEvent(
new CustomEvent(event, {
detail: data,
}),
);
}
static off(event, callback) {

View File

@ -22,7 +22,8 @@ export default function ExperimentalInit() {
debugger;
}
break;
default: break;
default:
break;
}
};
}

View File

@ -7,7 +7,8 @@ function showReminder() {
// based on https://stackoverflow.com/questions/37684/how-to-replace-plain-urls-with-links
export function urlParser(input) {
const urlPattern = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()!@:%_+.~#?&//=]*)/;
const urlPattern =
/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()!@:%_+.~#?&//=]*)/;
return input.replace(urlPattern, '<br/><a href="$&" target="_blank">$&</a>');
}
@ -20,7 +21,7 @@ export function install(type, input, sideload) {
Object.keys(localStorage).forEach((key) => {
oldSettings.push({
name: key,
value: localStorage.getItem(key)
value: localStorage.getItem(key),
});
});
@ -33,7 +34,7 @@ export function install(type, input, sideload) {
case 'photos':
const currentPhotos = JSON.parse(localStorage.getItem('photo_packs')) || [];
input.photos.forEach(photo => {
input.photos.forEach((photo) => {
currentPhotos.push(photo);
});
localStorage.setItem('photo_packs', JSON.stringify(currentPhotos));
@ -63,8 +64,8 @@ export function install(type, input, sideload) {
installed.push({
content: {
updated: 'Unpublished',
data: input
}
data: input,
},
});
} else {
installed.push(input);
@ -94,9 +95,11 @@ export function uninstall(type, name) {
case 'photos':
const installedContents = JSON.parse(localStorage.getItem('photo_packs'));
const packContents = JSON.parse(localStorage.getItem('installed')).find(content => content.name === name);
const packContents = JSON.parse(localStorage.getItem('installed')).find(
(content) => content.name === name,
);
// todo: make it find in photo_packs all the ones in installed for that pack and remove
console.log(packContents)
console.log(packContents);
installedContents.forEach((item, index) => {
if (packContents.photos.includes(item)) {
installedContents.splice(index, 1);
@ -121,4 +124,4 @@ export function uninstall(type, name) {
}
localStorage.setItem('installed', JSON.stringify(installed));
};
}

View File

@ -12,7 +12,10 @@ export function setDefaultSettings(reset) {
// Languages
const languageCodes = languages.map(({ value }) => value);
const browserLanguage = (navigator.languages && navigator.languages.find((lang) => lang.replace('-', '_') && languageCodes.includes(lang))) || navigator.language.replace('-', '_');
const browserLanguage =
(navigator.languages &&
navigator.languages.find((lang) => lang.replace('-', '_') && languageCodes.includes(lang))) ||
navigator.language.replace('-', '_');
if (languageCodes.includes(browserLanguage)) {
localStorage.setItem('language', browserLanguage);
@ -63,7 +66,7 @@ export function loadSettings(hotreload) {
});
}
if (localStorage.getItem('animations') === 'false') {
if (localStorage.getItem('animations') === 'false') {
document.body.classList.add('no-animations');
} else {
document.body.classList.remove('no-animations');
@ -79,7 +82,7 @@ export function loadSettings(hotreload) {
try {
document.querySelector('.' + element).classList.add('textBorder');
} catch (e) {
// Disregard exception
// Disregard exception
}
});
} else {
@ -88,7 +91,7 @@ export function loadSettings(hotreload) {
try {
document.querySelector('.' + element).classList.remove('textBorder');
} catch (e) {
// Disregard exception
// Disregard exception
}
});
}
@ -112,7 +115,9 @@ export function loadSettings(hotreload) {
url = `@import url('https://fonts.googleapis.com/css2?family=${font}&display=swap');`;
}
document.head.insertAdjacentHTML('beforeend', `
document.head.insertAdjacentHTML(
'beforeend',
`
<style id='customfont'>
${url}
* {
@ -121,7 +126,8 @@ export function loadSettings(hotreload) {
font-style: ${localStorage.getItem('fontstyle')};
}
</style>
`);
`,
);
}
// everything below this shouldn't run on a hot reload event
@ -153,7 +159,7 @@ export function loadSettings(hotreload) {
`);
}
// in a nutshell, this function saves all of the current settings, resets them, sets the defaults and then overrides
// in a nutshell, this function saves all of the current settings, resets them, sets the defaults and then overrides
// the new settings with the old saved messages where they exist
export function moveSettings() {
const currentSettings = Object.keys(localStorage);

View File

@ -7,17 +7,33 @@ export function saveFile(data, filename = 'file', type = 'text/json') {
if (typeof data === 'object') {
data = JSON.stringify(data, undefined, 4);
}
const blob = new Blob([data], { type });
const event = document.createEvent('MouseEvents');
const a = document.createElement('a');
a.href = window.URL.createObjectURL(blob);
a.download = filename;
a.dataset.downloadurl = [type, a.download, a.href].join(':');
event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
event.initMouseEvent(
'click',
true,
false,
window,
0,
0,
0,
0,
0,
false,
false,
false,
false,
0,
null,
);
a.dispatchEvent(event);
}
@ -44,39 +60,39 @@ export function importSettings(e) {
export function values(type) {
const marks = {
zoom: [
{ value: 10, label: '0.1x' },
{ value: 100, label: '1x' },
{ value: 200, label: '2x' },
{ value: 400, label: '4x' }
{ value: 10, label: '0.1x' },
{ value: 100, label: '1x' },
{ value: 200, label: '2x' },
{ value: 400, label: '4x' },
],
toast: [
{ value: 500, label: '0.5s' },
{ value: 1000, label: '1s' },
{ value: 1500, label: '1.5s' },
{ value: 2000, label: '2s' },
{ value: 2500, label: '2.5s' },
{ value: 3000, label: '3s' },
{ value: 4000, label: '4s' },
{ value: 5000, label: '5s'}
{ value: 500, label: '0.5s' },
{ value: 1000, label: '1s' },
{ value: 1500, label: '1.5s' },
{ value: 2000, label: '2s' },
{ value: 2500, label: '2.5s' },
{ value: 3000, label: '3s' },
{ value: 4000, label: '4s' },
{ value: 5000, label: '5s' },
],
background: [
{ value: 0, label: '0%'},
{ value: 25, label: '25%' },
{ value: 50, label: '50%' },
{ value: 75, label: '75%' },
{ value: 100, label: '100%' }
{ value: 0, label: '0%' },
{ value: 25, label: '25%' },
{ value: 50, label: '50%' },
{ value: 75, label: '75%' },
{ value: 100, label: '100%' },
],
experimental: [
{ value: 0, label: '0s' },
{ value: 500, label: '0.5s' },
{ value: 1000, label: '1s' },
{ value: 1500, label: '1.5s' },
{ value: 2000, label: '2s' },
{ value: 2500, label: '2.5s' },
{ value: 3000, label: '3s' },
{ value: 4000, label: '4s' },
{ value: 5000, label: '5s'}
]
{ value: 500, label: '0.5s' },
{ value: 1000, label: '1s' },
{ value: 1500, label: '1.5s' },
{ value: 2000, label: '2s' },
{ value: 2500, label: '2.5s' },
{ value: 3000, label: '3s' },
{ value: 4000, label: '4s' },
{ value: 5000, label: '5s' },
],
};
return marks[type];

View File

@ -21,7 +21,7 @@ export default class Stats {
static async tabLoad() {
const data = JSON.parse(localStorage.getItem('statsData'));
data['tabs-opened'] = data['tabs-opened'] + 1 || 1;
data['tabs-opened'] = data['tabs-opened'] + 1 || 1;
localStorage.setItem('statsData', JSON.stringify(data));
}
}

View File

@ -5,10 +5,10 @@ const variables = {
languagecode: '',
stats: {
tabLoad: () => '',
postEvent: () => ''
postEvent: () => '',
},
//keybinds: {},
constants: Constants
constants: Constants,
};
export default variables;

View File

@ -61,7 +61,7 @@ $themes: (
'color': rgb(0, 0, 0),
'subColor': #333333,
'borderRadius': 12px,
'boxShadow': 0 0 0 1px #E7E3E9,
'boxShadow': 0 0 0 1px #e7e3e9,
'btn-background': #fff,
'btn-backgroundHover': rgba(247, 250, 252, 0.9),
'modal-background': #fff,

File diff suppressed because it is too large Load Diff

View File

@ -7,36 +7,38 @@ module.exports = {
entry: path.resolve(__dirname, './src/index.js'),
mode: 'development',
performance: {
hints: false
hints: false,
},
module: {
rules: [{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ['babel-loader']
},
{
test: /\.(|sc|c)ss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: ''
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ['babel-loader'],
},
{
test: /\.(|sc|c)ss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '',
},
},
},
'css-loader',
'sass-loader'
],
},
{
test: /\.(woff|woff2|svg)$/,
type: 'asset/resource'
},
{
test: /\.js$/,
enforce: 'pre',
use: ['source-map-loader']
}]
'css-loader',
'sass-loader',
],
},
{
test: /\.(woff|woff2|svg)$/,
type: 'asset/resource',
},
{
test: /\.js$/,
enforce: 'pre',
use: ['source-map-loader'],
},
],
},
resolve: {
extensions: ['.js', '.jsx'],
@ -44,42 +46,43 @@ module.exports = {
components: path.resolve(__dirname, './src/components'),
modules: path.resolve(__dirname, './src/modules'),
translations: path.resolve(__dirname, './src/translations'),
scss: path.resolve(__dirname, './src/scss')
}
scss: path.resolve(__dirname, './src/scss'),
},
},
output: {
path: path.resolve(__dirname, './build'),
filename: '[name].[chunkhash].js',
chunkFilename: '[id].[chunkhash].chunk.js',
clean: true
clean: true,
},
devServer: {
static: path.resolve(__dirname, './build'),
open: true,
port: 3000
port: 3000,
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, './public/index.html')
template: path.resolve(__dirname, './public/index.html'),
}),
new CopyPlugin({
patterns: [{
patterns: [
{
from: 'public/icons',
to: 'icons'
to: 'icons',
},
{
from: 'public/offline-images',
to: 'offline-images'
to: 'offline-images',
},
{
from: 'public/welcome-images',
to: 'welcome-images'
}
]
to: 'welcome-images',
},
],
}),
new MiniCssExtractPlugin({
filename: '[name].[chunkhash].css',
chunkFilename: '[id].[chunkhash].chunk.css'
chunkFilename: '[id].[chunkhash].chunk.css',
}),
]
],
};