This commit is contained in:
David Ralph
2021-01-16 22:43:46 +00:00
parent 0a735384df
commit 3ec5a2c199
32 changed files with 530 additions and 182 deletions

View File

@@ -29,18 +29,31 @@ export default class App extends React.PureComponent {
} }
componentDidMount() { componentDidMount() {
if (!localStorage.getItem('firstRun')) SettingsFunctions.setDefaultSettings(); if (!localStorage.getItem('firstRun')) {
if (localStorage.getItem('showWelcome') === 'true') this.setState({ welcomeModal: true }); SettingsFunctions.setDefaultSettings();
}
if (localStorage.getItem('showWelcome') === 'true') {
this.setState({
welcomeModal: true
});
}
const css = localStorage.getItem('customcss'); const css = localStorage.getItem('customcss');
if (css) document.head.insertAdjacentHTML('beforeend', '<style>' + css + '</style>'); if (css) {
document.head.insertAdjacentHTML('beforeend', '<style>' + css + '</style>');
}
if (localStorage.getItem('darkTheme') === 'true') document.getElementsByClassName('Toastify')[0].classList.add('dark'); if (localStorage.getItem('darkTheme') === 'true'){
document.getElementsByClassName('Toastify')[0].classList.add('dark');
}
} }
closeWelcome() { closeWelcome() {
localStorage.setItem('showWelcome', false); localStorage.setItem('showWelcome', false);
this.setState({ welcomeModal: false }); this.setState({
welcomeModal: false
});
} }
// Render all the components // Render all the components
@@ -48,10 +61,12 @@ export default class App extends React.PureComponent {
// dark theme support for modals and info card // dark theme support for modals and info card
let modalClassList = 'Modal'; let modalClassList = 'Modal';
let tooltipClassList = 'infoCard'; let tooltipClassList = 'infoCard';
if ((localStorage.getItem('brightnessTime') && new Date().getHours() > 18) || localStorage.getItem('darkTheme') === 'true') { if ((localStorage.getItem('brightnessTime') && new Date().getHours() > 18) || localStorage.getItem('darkTheme') === 'true') {
modalClassList += ' dark'; modalClassList += ' dark';
tooltipClassList += ' dark'; tooltipClassList += ' dark';
} }
const overlayClassList = (localStorage.getItem('animations') === 'true') ? 'Overlay modal-animation' : 'Overlay'; const overlayClassList = (localStorage.getItem('animations') === 'true') ? 'Overlay modal-animation' : 'Overlay';
/// language /// language

View File

@@ -9,23 +9,26 @@ import AddonsIcon from '@material-ui/icons/Widgets';
import MarketplaceIcon from '@material-ui/icons/ShoppingBasket'; import MarketplaceIcon from '@material-ui/icons/ShoppingBasket';
export default class MainModal extends React.PureComponent { export default class MainModal extends React.PureComponent {
constructor(...args) { constructor(...args) {
super(...args); super(...args);
this.state = { this.state = {
tab: '', tab: '',
currentTab: '' currentTab: ''
};
this.tabs = {
settings: <Settings language={this.props.language.settings} toastLanguage={this.props.language.toasts} />,
addons: <Addons language={this.props.language.addons} marketplaceLanguage={this.props.language.marketplace} toastLanguage={this.props.language.toasts} openMarketplace={() => this.changeEnabled('marketplace')}/>,
marketplace: <Marketplace language={this.props.language.marketplace} toastLanguage={this.props.language.toasts} updateLanguage={this.props.language.update}/>
}
} }
this.tabs = {
settings: <Settings language={this.props.language.settings} toastLanguage={this.props.language.toasts} />,
addons: <Addons language={this.props.language.addons} marketplaceLanguage={this.props.language.marketplace} toastLanguage={this.props.language.toasts} openMarketplace={() => this.changeEnabled('marketplace')}/>,
marketplace: <Marketplace language={this.props.language.marketplace} toastLanguage={this.props.language.toasts} updateLanguage={this.props.language.update}/>
}
}
componentDidMount() { componentDidMount() {
document.getElementById('backgroundImage').classList.toggle('backgroundEffects'); document.getElementById('backgroundImage').classList.toggle('backgroundEffects');
document.getElementById('center').classList.toggle('backgroundEffects'); document.getElementById('center').classList.toggle('backgroundEffects');
this.setState({ tab: this.tabs.settings, currentTab: 'settings' });
this.setState({
tab: this.tabs.settings, currentTab: 'settings'
});
} }
componentWillUnmount() { componentWillUnmount() {
@@ -36,7 +39,10 @@ export default class MainModal extends React.PureComponent {
changeEnabled(input) { changeEnabled(input) {
document.getElementById(this.state.currentTab + 'TabLink').classList.toggle('active'); document.getElementById(this.state.currentTab + 'TabLink').classList.toggle('active');
document.getElementById(input + 'TabLink').classList.toggle('active'); document.getElementById(input + 'TabLink').classList.toggle('active');
this.setState({ tab: this.tabs[input], currentTab: input });
this.setState({
tab: this.tabs[input], currentTab: input
});
} }
render() { render() {

View File

@@ -22,6 +22,7 @@ export default class Update extends React.PureComponent {
} }
const data = await (await fetch(Constants.API_URL + '/getUpdate')).json(); const data = await (await fetch(Constants.API_URL + '/getUpdate')).json();
if (data.statusCode === 500 || data.title === null) { if (data.statusCode === 500 || data.title === null) {
const supportText = `<br/><p>${this.props.language.contact_support}: <a target='_blank' class='modalLink' href='https://muetab.com/contact'>https://muetab.com/contact</a></p>`; const supportText = `<br/><p>${this.props.language.contact_support}: <a target='_blank' class='modalLink' href='https://muetab.com/contact'>https://muetab.com/contact</a></p>`;
return this.setState({ return this.setState({

View File

@@ -15,7 +15,9 @@ export default class Item extends React.PureComponent {
</div> </div>
); );
} }
} catch (e) {} } catch (e) {
// ignore
}
return ( return (
<div id='item'> <div id='item'>

View File

@@ -2,10 +2,14 @@ import React from 'react';
export default class Items extends React.PureComponent { export default class Items extends React.PureComponent {
render() { render() {
if (this.props.items.length === 0) return null; // if there are no items in category don't render it if (this.props.items.length === 0) {
return null; // if there are no items in category don't render it
}
let seeMoreHTML; let seeMoreHTML;
if (this.props.seeMoreFunction && this.props.items.length === 3) seeMoreHTML = <button className='addToMue seemore' onClick={this.props.seeMoreFunction}>{this.props.seeMoreTitle}</button>; // only render see more button if there are enough addons if (this.props.seeMoreFunction && this.props.items.length === 3) {
seeMoreHTML = <button className='addToMue seemore' onClick={this.props.seeMoreFunction}>{this.props.seeMoreTitle}</button>; // only render see more button if there are enough addons
}
return ( return (
<div> <div>

View File

@@ -13,13 +13,19 @@ export default class Checkbox extends React.PureComponent {
handleChange(name) { handleChange(name) {
SettingsFunctions.setItem(name); SettingsFunctions.setItem(name);
this.setState({ checked: (this.state.checked === true) ? false : true }); this.setState({
checked: (this.state.checked === true) ? false : true
});
} }
render() { render() {
let text = this.props.text; let text = this.props.text;
if (this.props.newFeature) text = <span>{this.props.text} <span className='newFeature'> NEW</span></span>;
else if (this.props.betaFeature) text = <span>{this.props.text} <span className='newFeature'> BETA</span></span>; if (this.props.newFeature) {
text = <span>{this.props.text} <span className='newFeature'> NEW</span></span>;
} else if (this.props.betaFeature) {
text = <span>{this.props.text} <span className='newFeature'> BETA</span></span>;
}
return ( return (
<React.Fragment> <React.Fragment>

View File

@@ -7,9 +7,12 @@ export default class FileUpload extends React.PureComponent {
const reader = new FileReader(); const reader = new FileReader();
const file = e.target.files[0]; const file = e.target.files[0];
if (this.props.type === 'settings') reader.readAsText(file, 'UTF-8'); if (this.props.type === 'settings') {
else { // background upload reader.readAsText(file, 'UTF-8');
if (file.size > 2000000) return toast('File is over 2MB'); } else { // background upload
if (file.size > 2000000) {
return toast('File is over 2MB');
}
reader.readAsDataURL(file); reader.readAsDataURL(file);
} }
reader.addEventListener('load', (e) => this.props.loadFunction(e)); reader.addEventListener('load', (e) => this.props.loadFunction(e));

View File

@@ -19,7 +19,9 @@ export default class Section extends React.PureComponent {
transform: (this.state.transform === 'rotate(0)') ? 'rotate(-180deg)' : 'rotate(0)' transform: (this.state.transform === 'rotate(0)') ? 'rotate(-180deg)' : 'rotate(0)'
}); });
if (this.props.onToggle) this.props.onToggle(display); if (this.props.onToggle) {
this.props.onToggle(display);
}
} }
render() { render() {
@@ -31,6 +33,7 @@ export default class Section extends React.PureComponent {
<li className='extraSettings'>{this.props.children}</li> <li className='extraSettings'>{this.props.children}</li>
</div> </div>
); );
expandMore = ( expandMore = (
<ExpandMore <ExpandMore
style={{ 'transition': 'all 0.5s ease 0s', 'transform': this.state.transform }} style={{ 'transition': 'all 0.5s ease 0s', 'transform': this.state.transform }}
@@ -38,8 +41,14 @@ export default class Section extends React.PureComponent {
onClick={() => this.toggleSection()} /> onClick={() => this.toggleSection()} />
); );
} }
if (this.props.slider !== false) slider = <Slider name={this.props.name} />;
if (this.props.dropdown === false) noDropdown = 'nodropdown'; if (this.props.slider !== false) {
slider = <Slider name={this.props.name} />;
}
if (this.props.dropdown === false){
noDropdown = 'nodropdown';
}
return ( return (
<div className='section'> <div className='section'>

View File

@@ -11,11 +11,14 @@ export default class Slider extends React.PureComponent {
handleChange(name) { handleChange(name) {
SettingsFunctions.setItem(name); SettingsFunctions.setItem(name);
this.setState({ checked: (this.state.checked === true) ? false : true }); this.setState({
checked: (this.state.checked === true) ? false : true
});
} }
render() { render() {
let setText = (this.props.override) ? this.props.override : this.props.name; let setText = (this.props.override) ? this.props.override : this.props.name;
return ( return (
<label className='switch'> <label className='switch'>
<input type='checkbox' checked={this.state.checked} onChange={() => this.handleChange(setText)} /> <input type='checkbox' checked={this.state.checked} onChange={() => this.handleChange(setText)} />

View File

@@ -34,19 +34,33 @@ export default class BackgroundSettings extends React.PureComponent {
switch (key) { switch (key) {
case 'customBackgroundColour': case 'customBackgroundColour':
localStorage.setItem('customBackgroundColour', ''); localStorage.setItem('customBackgroundColour', '');
this.setState({ gradientSettings: this.DefaultGradientSettings }); this.setState({
gradientSettings: this.DefaultGradientSettings
});
break; break;
case 'customBackground': document.getElementById('customBackground').value = ''; break;
case 'customBackground':
document.getElementById('customBackground').value = '';
break;
case 'blur': case 'blur':
localStorage.setItem('blur', 0); localStorage.setItem('blur', 0);
this.setState({ blur: 0 }); this.setState({
blur: 0
});
break; break;
case 'brightness': case 'brightness':
localStorage.setItem('brightness', 100); localStorage.setItem('brightness', 100);
this.setState({ brightness: 100 }); this.setState({
brightness: 100
});
break; break;
default: toast('resetItem requires a key!');
default:
toast('resetItem requires a key!');
} }
toast(this.props.toastLanguage.reset); toast(this.props.toastLanguage.reset);
} }
@@ -79,7 +93,9 @@ export default class BackgroundSettings extends React.PureComponent {
} }
} }
if (gradientSettings === undefined) gradientSettings = this.DefaultGradientSettings; if (gradientSettings === undefined) {
gradientSettings = this.DefaultGradientSettings;
}
this.setState({ this.setState({
blur: localStorage.getItem('blur'), blur: localStorage.getItem('blur'),
@@ -129,9 +145,20 @@ export default class BackgroundSettings extends React.PureComponent {
} }
onColorPickerChange = (attrs, name) => { onColorPickerChange = (attrs, name) => {
if (process.env.NODE_ENV === 'development') console.log(attrs, name); if (process.env.NODE_ENV === 'development') {
console.log(attrs, name);
}
this.setState({ this.setState({
gradientSettings: { 'angle': attrs.degree, 'gradient': attrs.points.map((p) => { return { 'colour': '#' + rgbToHex(p.red, p.green, p.blue), 'stop': p.left } }), 'type': attrs.type } gradientSettings: {
'angle': attrs.degree,
'gradient': attrs.points.map((p) => {
return {
'colour': '#' + rgbToHex(p.red, p.green, p.blue),
'stop': p.left
} }),
'type': attrs.type
}
}); });
}; };
@@ -145,7 +172,9 @@ export default class BackgroundSettings extends React.PureComponent {
fileUpload(e) { fileUpload(e) {
localStorage.setItem('customBackground', e.target.result); localStorage.setItem('customBackground', e.target.result);
this.setState({ customBackground: e.target.result }); this.setState({
customBackground: e.target.result
});
} }
beforeUnload() { beforeUnload() {

View File

@@ -20,9 +20,14 @@ export default class GreetingSettings extends React.PureComponent {
} }
changeDate(data) { changeDate(data) {
if (data === 'reset') return; //soon if (data === 'reset') {
return; //soon
}
localStorage.setItem('birthday', data); localStorage.setItem('birthday', data);
this.setState({ birthday: data }); this.setState({
birthday: data
});
} }
beforeUnload() { beforeUnload() {

View File

@@ -16,12 +16,17 @@ export default class SearchSettings extends React.PureComponent {
componentDidMount() { componentDidMount() {
const searchEngine = localStorage.getItem('searchEngine'); const searchEngine = localStorage.getItem('searchEngine');
if (searchEngine === 'custom') { if (searchEngine === 'custom') {
const input = document.getElementById('searchEngineInput'); const input = document.getElementById('searchEngineInput');
input.style.display = 'block'; input.style.display = 'block';
input.enabled = 'true'; input.enabled = 'true';
document.getElementById('customSearchEngine').value = localStorage.getItem('customSearchEngine'); document.getElementById('customSearchEngine').value = localStorage.getItem('customSearchEngine');
} else localStorage.removeItem('customSearchEngine'); } else {
localStorage.removeItem('customSearchEngine');
}
document.getElementById('searchEngine').value = searchEngine; document.getElementById('searchEngine').value = searchEngine;
} }

View File

@@ -35,8 +35,13 @@ export default class Addons extends React.PureComponent {
if (type === 'item') { if (type === 'item') {
const installed = JSON.parse(localStorage.getItem('installed')); const installed = JSON.parse(localStorage.getItem('installed'));
const info = installed.find(i => i.name === data); const info = installed.find(i => i.name === data);
this.setState({ this.setState({
current_data: { type: type2, name: data, content: info }, current_data: {
type: type2,
name: data,
content: info
},
item_data: { item_data: {
name: info.name, name: info.name,
author: info.author, author: info.author,
@@ -53,23 +58,40 @@ export default class Addons extends React.PureComponent {
document.getElementById('marketplace').style.display = 'block'; document.getElementById('marketplace').style.display = 'block';
document.getElementById('item').style.display = 'none'; document.getElementById('item').style.display = 'none';
} }
this.setState({ button: this.buttons.uninstall }); this.setState({
button: this.buttons.uninstall
});
} }
manage(type, input) { manage(type, input) {
switch (type) { switch (type) {
case 'install': MarketplaceFunctions.install(input.type, input, true); break; case 'install':
case 'uninstall': MarketplaceFunctions.uninstall(this.state.current_data.name, this.state.current_data.content.type); break; MarketplaceFunctions.install(input.type, input, true);
default: break; break;
case 'uninstall':
MarketplaceFunctions.uninstall(this.state.current_data.name, this.state.current_data.content.type);
break;
default:
break;
} }
toast(this.props.toastLanguage[type + 'ed']); toast(this.props.toastLanguage[type + 'ed']);
let button = ''; let button = '';
if (type === 'install') button = this.buttons.uninstall; if (type === 'install'){
this.setState({ button: button, installed: JSON.parse(localStorage.getItem('installed')) }); button = this.buttons.uninstall;
}
this.setState({
button: button,
installed: JSON.parse(localStorage.getItem('installed'))
});
} }
componentDidMount() { componentDidMount() {
if (localStorage.getItem('animations') === 'true') document.getElementById('marketplace').classList.add('marketplaceanimation'); if (localStorage.getItem('animations') === 'true') {
document.getElementById('marketplace').classList.add('marketplaceanimation');
}
} }
render() { render() {

View File

@@ -44,12 +44,20 @@ export default class Marketplace extends React.PureComponent {
case 'seemore': case 'seemore':
document.getElementById('marketplace').style.display = 'none'; document.getElementById('marketplace').style.display = 'none';
document.getElementById('seemore').style.display = 'block'; document.getElementById('seemore').style.display = 'block';
this.setState({ see_more: this.state[type2], see_more_type: type2 });
this.setState({
see_more: this.state[type2],
see_more_type: type2
});
break; break;
case 'item': case 'item':
let info; let info;
try { info = await (await fetch(`${Constants.MARKETPLACE_URL}/item/${type2}/${data}`)).json(); } try {
catch (e) { return toast(this.props.toastLanguage.error); } info = await (await fetch(`${Constants.MARKETPLACE_URL}/item/${type2}/${data}`)).json();
} catch (e) {
return toast(this.props.toastLanguage.error);
}
this.setState({ this.setState({
current_data: { type: type2, name: data, content: info }, current_data: { type: type2, name: data, content: info },
@@ -64,14 +72,22 @@ export default class Marketplace extends React.PureComponent {
}); });
let button = this.buttons.install; let button = this.buttons.install;
const installed = JSON.parse(localStorage.getItem('installed')); const installed = JSON.parse(localStorage.getItem('installed'));
if (installed.some(item => item.name === data)) button = this.buttons.uninstall;
this.setState({ button: button }); if (installed.some(item => item.name === data)) {
button = this.buttons.uninstall;
}
this.setState({
button: button
});
document.getElementById('marketplace').style.display = 'none'; document.getElementById('marketplace').style.display = 'none';
document.getElementById('seemore').style.display = 'none'; document.getElementById('seemore').style.display = 'none';
document.getElementById('item').style.display = 'block'; document.getElementById('item').style.display = 'block';
break; break;
default: default:
document.getElementById('marketplace').style.display = 'block'; document.getElementById('marketplace').style.display = 'block';
document.getElementById('item').style.display = 'none'; document.getElementById('item').style.display = 'none';
@@ -83,6 +99,7 @@ export default class Marketplace extends React.PureComponent {
async getItems() { async getItems() {
const data = await (await fetch(Constants.MARKETPLACE_URL + '/all')).json(); const data = await (await fetch(Constants.MARKETPLACE_URL + '/all')).json();
const featured = await (await fetch(Constants.MARKETPLACE_URL + '/featured')).json(); const featured = await (await fetch(Constants.MARKETPLACE_URL + '/featured')).json();
this.setState({ this.setState({
settings: data.data.settings, settings: data.data.settings,
photo_packs: data.data.photo_packs, photo_packs: data.data.photo_packs,
@@ -95,10 +112,16 @@ export default class Marketplace extends React.PureComponent {
manage(type) { manage(type) {
switch (type) { switch (type) {
case 'install': MarketplaceFunctions.install(this.state.current_data.type, this.state.current_data.content.data); break; case 'install':
case 'uninstall': MarketplaceFunctions.uninstall(this.state.current_data.content.data.name, this.state.current_data.type); break; MarketplaceFunctions.install(this.state.current_data.type, this.state.current_data.content.data);
default: break; break;
case 'uninstall':
MarketplaceFunctions.uninstall(this.state.current_data.content.data.name, this.state.current_data.type);
break;
default:
break;
} }
toast(this.props.toastLanguage[type + 'ed']); toast(this.props.toastLanguage[type + 'ed']);
this.setState({ this.setState({
button: (type === 'install') ? this.buttons.uninstall : this.buttons.install button: (type === 'install') ? this.buttons.uninstall : this.buttons.install
@@ -106,8 +129,14 @@ export default class Marketplace extends React.PureComponent {
} }
componentDidMount() { componentDidMount() {
if (localStorage.getItem('animations') === 'true') document.getElementById('marketplace').classList.add('marketplaceanimation'); if (localStorage.getItem('animations') === 'true') {
if (navigator.onLine === false) return; document.getElementById('marketplace').classList.add('marketplaceanimation');
}
if (navigator.onLine === false) {
return;
}
this.getItems(); this.getItems();
} }

View File

@@ -24,13 +24,19 @@ export default class Settings extends React.PureComponent {
if (document.getElementById('modal').classList.contains('dark')) { // Dark theme support for dropdowns if (document.getElementById('modal').classList.contains('dark')) { // Dark theme support for dropdowns
const choices = document.getElementsByClassName('choices'); const choices = document.getElementsByClassName('choices');
for (let i = 0; i < choices.length; i++) choices[i].style.backgroundColor = '#2f3542'; for (let i = 0; i < choices.length; i++) {
choices[i].style.backgroundColor = '#2f3542';
}
} }
} }
settingsImport(e) { settingsImport(e) {
const content = JSON.parse(e.target.result); const content = JSON.parse(e.target.result);
for (const key of Object.keys(content)) localStorage.setItem(key, content[key]);
for (const key of Object.keys(content)) {
localStorage.setItem(key, content[key]);
}
toast(this.props.toastLanguage.imported); toast(this.props.toastLanguage.imported);
} }

View File

@@ -10,15 +10,20 @@ import Date from './time/Date';
export default class Widgets extends React.PureComponent { export default class Widgets extends React.PureComponent {
enabled(key) { enabled(key) {
const old = localStorage.getItem(key); const stringValue = localStorage.getItem(key);
let val = true; let enabled = true;
if (old !== null) { if (stringValue !== null) {
if (old === 'true') val = true; if (stringValue === 'true') {
if (old === 'false') val = false; enabled = true;
}
if (stringValue === 'false') {
enabled = false;
}
} }
return val; return enabled;
} }
// Render all the components // Render all the components
@@ -30,7 +35,7 @@ export default class Widgets extends React.PureComponent {
<React.Fragment> <React.Fragment>
{enabled('searchBar') ? <Search language={language.search} /> : null} {enabled('searchBar') ? <Search language={language.search} /> : null}
{enabled('greeting') ? <Greeting language={language.greeting} /> : null} {enabled('greeting') ? <Greeting language={language.greeting} /> : null}
{enabled('clock') ? <Clock/> : null} {enabled('time') ? <Clock/> : null}
{enabled('date') ? <Date/> : null} {enabled('date') ? <Date/> : null}
{enabled('quote') ? <Quote language={language.toasts} languagecode={languagecode} /> : null} {enabled('quote') ? <Quote language={language.toasts} languagecode={languagecode} /> : null}
{enabled('view') ? <Maximise/> : null} {enabled('view') ? <Maximise/> : null}

View File

@@ -27,33 +27,46 @@ export default class Background extends React.PureComponent {
localStorage.setItem('customBackgroundColour', JSON.stringify(gradientSettings)); localStorage.setItem('customBackgroundColour', JSON.stringify(gradientSettings));
} }
} }
const background = typeof gradientSettings === 'object' && gradientSettings !== null ? this.gradientStyleBuilder(gradientSettings) : `background-image: url(${url})`; const background = typeof gradientSettings === 'object' && gradientSettings !== null ? this.gradientStyleBuilder(gradientSettings) : `background-image: url(${url})`;
// Brightness
let brightness = localStorage.getItem('brightness'); let brightness = localStorage.getItem('brightness');
if (localStorage.getItem('brightnessTime') && new Date().getHours() > 18) brightness = 75; if (localStorage.getItem('brightnessTime') && new Date().getHours() > 18) {
brightness = 75;
}
document.querySelector('#backgroundImage').setAttribute( document.querySelector('#backgroundImage').setAttribute(
'style', 'style',
`${background}; -webkit-filter: blur(${localStorage.getItem('blur')}px) brightness(${brightness}%);` `${background}; -webkit-filter: blur(${localStorage.getItem('blur')}px) brightness(${brightness}%);`
); );
if (credit === 'false' && document.querySelector('#credits')) document.querySelector('#credits').style.display = 'none'; // Hide the credit if (credit === 'false' && document.querySelector('#credits')) {
document.querySelector('#credits').style.display = 'none'; // Hide the credit
}
} }
setCredit(photographer, unsplash, url) { setCredit(photographer, unsplash, url) {
let credit = photographer; let credit = photographer;
if (unsplash) credit = `<a href='${url}' class='creditlink'>${photographer}</a> on <a href='https://unsplash.com/?utm_source=mue&utm_medium=referral' class='creditlink'>Unsplash</a>`; if (unsplash){
document.querySelector('#photographer').insertAdjacentHTML("beforeend", ` ${credit}`); // Append credit credit = `<a href='${url}' class='creditlink'>${photographer}</a> on <a href='https://unsplash.com/?utm_source=mue&utm_medium=referral' class='creditlink'>Unsplash</a>`;
}
document.querySelector('#photographer').insertAdjacentHTML('beforeend', ` ${credit}`); // Append credit
document.getElementById('credit').textContent = credit; document.getElementById('credit').textContent = credit;
document.getElementById('photographerCard').textContent = credit; document.getElementById('photographerCard').textContent = credit;
} }
doOffline() { // Handles setting the background if the user is offline doOffline() { // Handles setting the background if the user is offline
const offlineImages = require('./offline_images.json'); const offlineImages = require('./offline_images.json');
const photographers = Object.keys(offlineImages); // Get all photographers from the keys in offlineImages.json const photographers = Object.keys(offlineImages); // Get all photographers from the keys in offlineImages.json
const photographer = photographers[Math.floor(Math.random() * photographers.length)]; // Select a random photographer from the keys const photographer = photographers[Math.floor(Math.random() * photographers.length)]; // Select a random photographer from the keys
const randomImage = offlineImages[photographer].photo[ const randomImage = offlineImages[photographer].photo[
Math.floor(Math.random() * offlineImages[photographer].photo.length) Math.floor(Math.random() * offlineImages[photographer].photo.length)
]; // Select a random image ]; // Select a random image
const url = `../offline-images/${randomImage}.jpg`; const url = `../offline-images/${randomImage}.jpg`;
this.setBackground(url); this.setBackground(url);
@@ -66,38 +79,54 @@ export default class Background extends React.PureComponent {
const offlineMode = localStorage.getItem('offlineMode'); const offlineMode = localStorage.getItem('offlineMode');
const photoPack = JSON.parse(localStorage.getItem('photo_packs')); const photoPack = JSON.parse(localStorage.getItem('photo_packs'));
const customBackgroundColour = localStorage.getItem('customBackgroundColour'); const customBackgroundColour = localStorage.getItem('customBackgroundColour');
const customBackground = localStorage.getItem('customBackground'); const customBackground = localStorage.getItem('customBackground');
const favourited = JSON.parse(localStorage.getItem('favourite')); const favourited = JSON.parse(localStorage.getItem('favourite'));
if (favourited) { if (favourited) {
if (offlineMode === 'true') return this.doOffline(); if (offlineMode === 'true') {
return this.doOffline();
}
this.setBackground(favourited.url, null, 'true'); this.setBackground(favourited.url, null, 'true');
this.setCredit(favourited.credit); this.setCredit(favourited.credit);
document.getElementById('location').textContent = favourited.location; document.getElementById('location').textContent = favourited.location;
} else if (photoPack) { } else if (photoPack) {
if (offlineMode === 'true') return this.doOffline(); if (offlineMode === 'true') {
return this.doOffline();
}
const randomPhoto = photoPack[Math.floor(Math.random() * photoPack.length)]; const randomPhoto = photoPack[Math.floor(Math.random() * photoPack.length)];
this.setBackground(randomPhoto.url.default, null, randomPhoto.photographer); this.setBackground(randomPhoto.url.default, null, randomPhoto.photographer);
this.setCredit(randomPhoto.photographer); this.setCredit(randomPhoto.photographer);
document.getElementById('location').textContent = randomPhoto.location; document.getElementById('location').textContent = randomPhoto.location;
} } else if (customBackgroundColour) {
else if (customBackgroundColour) this.setBackground(null, customBackgroundColour, 'false'); this.setBackground(null, customBackgroundColour, 'false');
else if (customBackground !== '') { } else if (customBackground !== '') {
if (customBackground.includes('.mp4') || customBackground.includes('.webm') || customBackground.includes('.ogg')) { if (customBackground.includes('.mp4') || customBackground.includes('.webm') || customBackground.includes('.ogg')) {
document.getElementById('backgroundImage').innerHTML = ` document.getElementById('backgroundImage').innerHTML = `
<video autoplay muted loop id='backgroundVideo'> <video autoplay muted loop id='backgroundVideo'>
<source src='${customBackground}'/> <source src='${customBackground}'/>
</video>`; </video>`;
} else this.setBackground(customBackground, null, 'false'); // Local } else {
this.setBackground(customBackground, null, 'false'); // Local
}
} else { // Online } else { // Online
if (offlineMode === 'true') return this.doOffline(); if (offlineMode === 'true') {
return this.doOffline();
}
try { // First we try and get an image from the API... try { // First we try and get an image from the API...
const enabled = localStorage.getItem('webp'); const enabled = localStorage.getItem('webp');
let requestURL; let requestURL;
switch (localStorage.getItem('backgroundAPI')) { switch (localStorage.getItem('backgroundAPI')) {
case 'unsplash': requestURL = `${Constants.UNSPLASH_URL}/getImage`; break; case 'unsplash':
requestURL = `${Constants.UNSPLASH_URL}/getImage`;
break;
default: // Defaults to Mue default: // Defaults to Mue
if (localStorage.getItem('supportswebp') === 'true' && enabled === 'true') requestURL = `${Constants.API_URL}/getImage?webp=true`; if (localStorage.getItem('supportswebp') === 'true' && enabled === 'true') requestURL = `${Constants.API_URL}/getImage?webp=true`;
else requestURL = `${Constants.API_URL}/getImage?category=Outdoors`; else requestURL = `${Constants.API_URL}/getImage?category=Outdoors`;
@@ -106,16 +135,24 @@ export default class Background extends React.PureComponent {
const data = await (await fetch(requestURL)).json(); // Fetch JSON data from requestURL const data = await (await fetch(requestURL)).json(); // Fetch JSON data from requestURL
if (data.statusCode === 429) this.doOffline(); // If we hit the rate limit, fallback to local images if (data.statusCode === 429) {
else { // Otherwise, set the background and credit from remote data this.doOffline(); // If we hit the rate limit, fallback to local images
} else { // Otherwise, set the background and credit from remote data
this.setBackground(data.file); this.setBackground(data.file);
if (localStorage.getItem('backgroundAPI') === 'unsplash') return this.setCredit(data.photographer, 'unsplash', data.photographer_page);
if (localStorage.getItem('backgroundAPI') === 'unsplash') {
return this.setCredit(data.photographer, 'unsplash', data.photographer_page);
}
this.setCredit(data.photographer); this.setCredit(data.photographer);
document.getElementById('camera').textContent = data.camera || 'N/A'; document.getElementById('camera').textContent = data.camera || 'N/A';
document.getElementById('resolution').textContent = data.resolution || 'N/A'; document.getElementById('resolution').textContent = data.resolution || 'N/A';
} }
if (data.location.replace(/[null]+/g, '') === ' ') return document.querySelector('#backgroundCredits').style.display = 'none'; if (data.location.replace(/[null]+/g, '') === ' ') {
return document.querySelector('#backgroundCredits').style.display = 'none';
}
document.getElementById('location').innerText = `${data.location.replace('null', '')}`; // Set the location tooltip document.getElementById('location').innerText = `${data.location.replace('null', '')}`; // Set the location tooltip
} catch (e) { // ..and if that fails we load one locally } catch (e) { // ..and if that fails we load one locally
this.doOffline(); this.doOffline();
@@ -124,8 +161,14 @@ export default class Background extends React.PureComponent {
} }
componentDidMount() { componentDidMount() {
if (localStorage.getItem('background') === 'false') return document.querySelector('#credits').style.display = 'none'; // Hide the credit if (localStorage.getItem('background') === 'false') {
if (localStorage.getItem('animations') === 'true') document.querySelector('#backgroundImage').classList.add('fade-in'); return document.querySelector('#credits').style.display = 'none'; // Hide the credit
}
if (localStorage.getItem('animations') === 'true') {
document.querySelector('#backgroundImage').classList.add('fade-in');
}
this.determineMode(); this.determineMode();
} }

View File

@@ -20,18 +20,26 @@ export default class Favourite extends React.PureComponent {
const location = document.getElementById('location').textContent; const location = document.getElementById('location').textContent;
localStorage.setItem('favourite', JSON.stringify({ url: url, credit: credit, location: location })); localStorage.setItem('favourite', JSON.stringify({ url: url, credit: credit, location: location }));
this.setState({ favourited: <StarIcon onClick={() => this.favourite()} /> });
this.setState({
favourited: <StarIcon onClick={() => this.favourite()} />
});
} }
} }
componentDidMount() { componentDidMount() {
if (localStorage.getItem('favourite')) { if (localStorage.getItem('favourite')) {
this.setState({ favourited: <StarIcon onClick={() => this.favourite()} /> }); this.setState({
favourited: <StarIcon onClick={() => this.favourite()} />
});
} }
} }
render() { render() {
if (localStorage.getItem('favouriteEnabled') === 'false' || localStorage.getItem('background') === 'false' || localStorage.getItem('customBackgroundColour') || localStorage.getItem('customBackground')) return null; if (localStorage.getItem('favouriteEnabled') === 'false' || localStorage.getItem('background') === 'false' || localStorage.getItem('customBackgroundColour') || localStorage.getItem('customBackground')) {
return null;
}
return <div className='favourite'> return <div className='favourite'>
{this.state.favourited} {this.state.favourited}
</div> </div>

View File

@@ -27,16 +27,23 @@ export default class View extends React.PureComponent {
}); });
if (this.state.hidden === false) { if (this.state.hidden === false) {
this.setState({ hidden: true }); this.setState({
hidden: true
});
this.setAttribute(0, 100); this.setAttribute(0, 100);
} else { } else {
this.setState({ hidden: false }); this.setState({
hidden: false
});
this.setAttribute(localStorage.getItem('blur'), localStorage.getItem('brightness')); this.setAttribute(localStorage.getItem('blur'), localStorage.getItem('brightness'));
} }
} }
render() { render() {
if (localStorage.getItem('background') === 'false') return null; if (localStorage.getItem('background') === 'false') {
return null;
}
return <div className='view'> return <div className='view'>
<FullscreenIcon onClick={() => this.viewStuff()} /> <FullscreenIcon onClick={() => this.viewStuff()} />
</div> </div>

View File

@@ -11,15 +11,21 @@ export default class Greeting extends React.PureComponent {
} }
doEvents(time, message) { doEvents(time, message) {
if (localStorage.getItem('events') === 'false') return message; if (localStorage.getItem('events') === 'false') {
return message;
}
// Get current month & day // Get current month & day
const m = time.getMonth(); const m = time.getMonth();
const d = time.getDate(); const d = time.getDate();
if (m === 11 && d === 25) message = this.props.language.christmas; // If it's December 25th, set the greeting string to "Merry Christmas" if (m === 11 && d === 25) {
else if (m === 0 && d === 1) message = this.props.language.newyear; // If the date is January 1st, set the greeting string to "Happy new year" message = this.props.language.christmas; // If it's December 25th, set the greeting string to "Merry Christmas"
else if (m === 9 && d === 31) message = this.props.language.halloween; // If it's October 31st, set the greeting string to "Happy Halloween" } else if (m === 0 && d === 1) {
message = this.props.language.newyear; // If the date is January 1st, set the greeting string to "Happy new year"
} else if (m === 9 && d === 31) {
message = this.props.language.halloween; // If it's October 31st, set the greeting string to "Happy Halloween"
}
return message; return message;
} }
@@ -29,13 +35,19 @@ export default class Greeting extends React.PureComponent {
const hour = now.getHours(); const hour = now.getHours();
let message = this.props.language.evening; // Set the default greeting string to "Good evening" let message = this.props.language.evening; // Set the default greeting string to "Good evening"
if (hour < 12) message = this.props.language.morning; // If it's before 12am, set the greeting string to "Good morning" if (hour < 12) {
else if (hour < 18) message = this.props.language.afternoon; // If it's before 6pm, set the greeting string to "Good afternoon" message = this.props.language.morning; // If it's before 12am, set the greeting string to "Good morning"
} else if (hour < 18) {
message = this.props.language.afternoon; // If it's before 6pm, set the greeting string to "Good afternoon"
}
// Events // Events
message = this.doEvents(now, message); message = this.doEvents(now, message);
const custom = localStorage.getItem('defaultGreetingMessage'); const custom = localStorage.getItem('defaultGreetingMessage');
if (custom === 'false') message = ''; if (custom === 'false') {
message = '';
}
// Name // Name
let name = ''; let name = '';
@@ -45,14 +57,20 @@ export default class Greeting extends React.PureComponent {
if (data.replace(/\s/g, '').length > 0) name = `, ${data.trim()}`; if (data.replace(/\s/g, '').length > 0) name = `, ${data.trim()}`;
} }
if (custom === 'false') name = name.replace(',', ''); if (custom === 'false') {
name = name.replace(',', '');
}
// Birthday // Birthday
const birth = new Date(localStorage.getItem('birthday')); const birth = new Date(localStorage.getItem('birthday'));
if (localStorage.getItem('birthdayenabled') === 'true' && birth.getDate() === now.getDate() && birth.getMonth() === now.getMonth()) message = 'Happy Birthday'; if (localStorage.getItem('birthdayenabled') === 'true' && birth.getDate() === now.getDate() && birth.getMonth() === now.getMonth()) {
message = 'Happy Birthday';
}
// Set the state to the greeting string // Set the state to the greeting string
this.setState({ greeting: `${message}${name}` }); this.setState({
greeting: `${message}${name}`
});
} }
componentDidMount() { componentDidMount() {

View File

@@ -23,7 +23,9 @@ export default class Navbar extends React.PureComponent {
</Tooltip> </Tooltip>
); );
if (localStorage.getItem('refresh') === 'false') refreshHTML = null; if (localStorage.getItem('refresh') === 'false') {
refreshHTML = null;
}
// toggle feedback button // toggle feedback button
let feedbackHTML = ( let feedbackHTML = (
@@ -32,7 +34,9 @@ export default class Navbar extends React.PureComponent {
</Tooltip> </Tooltip>
); );
if (Constants.BETA_VERSION === false) feedbackHTML = null; if (Constants.BETA_VERSION === false){
feedbackHTML = null;
}
return ( return (
<div className='navbar-container'> <div className='navbar-container'>

View File

@@ -30,7 +30,9 @@ export default class Notes extends React.PureComponent {
render() { render() {
let classList = 'notescontainer'; let classList = 'notescontainer';
if (localStorage.getItem('darkTheme') === 'true') classList += ' dark'; if (localStorage.getItem('darkTheme') === 'true') {
classList += ' dark';
}
return ( return (
<span id='noteContainer' className={classList}> <span id='noteContainer' className={classList}>

View File

@@ -16,7 +16,9 @@ export default class Quote extends React.PureComponent {
this.state = { this.state = {
quote: '', quote: '',
author: '', author: '',
favourited: <StarIcon2 className='copyButton' onClick={() => this.favourite()} /> favourited: <StarIcon2 className='copyButton' onClick={() => this.favourite()} />,
tweet: <TwitterIcon className='copyButton' onClick={() => this.tweetQuote()} />,
copy: <FileCopy className='copyButton' onClick={() => this.copyQuote()} />
}; };
} }
@@ -30,7 +32,11 @@ export default class Quote extends React.PureComponent {
getQuotePack() { getQuotePack() {
let quotePack = localStorage.getItem('quote_packs'); let quotePack = localStorage.getItem('quote_packs');
if (quotePack === 'undefined') return this.doOffline();
if (quotePack === 'undefined') {
return this.doOffline();
}
quotePack = JSON.parse(quotePack); quotePack = JSON.parse(quotePack);
if (quotePack) { if (quotePack) {
@@ -39,7 +45,9 @@ export default class Quote extends React.PureComponent {
quote: '"' + data.quote + '"', quote: '"' + data.quote + '"',
author: data.author author: data.author
}); });
} else this.doOffline(); } else {
this.doOffline();
}
} }
async getQuote() { async getQuote() {
@@ -57,16 +65,24 @@ export default class Quote extends React.PureComponent {
} }
const favouriteQuote = localStorage.getItem('favouriteQuote'); const favouriteQuote = localStorage.getItem('favouriteQuote');
if (favouriteQuote) return this.setState({ if (favouriteQuote) {
quote: favouriteQuote.split(' - ')[0], return this.setState({
author: favouriteQuote.split(' - ')[1] quote: favouriteQuote.split(' - ')[0],
}); author: favouriteQuote.split(' - ')[1]
});
}
if (localStorage.getItem('offlineMode') === 'true') return this.doOffline(); if (localStorage.getItem('offlineMode') === 'true') {
return this.doOffline();
}
try { // First we try and get a quote from the API... try { // First we try and get a quote from the API...
const data = await (await fetch(Constants.API_URL + '/getQuote?language=' + localStorage.getItem('quotelanguage'))).json(); const data = await (await fetch(Constants.API_URL + '/getQuote?language=' + localStorage.getItem('quotelanguage'))).json();
if (data.statusCode === 429) return this.doOffline(); // If we hit the ratelimit, we fallback to local quotes
if (data.statusCode === 429) {
return this.doOffline(); // If we hit the ratelimit, we fallback to local quotes
}
this.setState({ this.setState({
quote: '"' + data.quote + '"', quote: '"' + data.quote + '"',
author: data.author, author: data.author,
@@ -82,34 +98,50 @@ export default class Quote extends React.PureComponent {
toast(this.props.language.quote); toast(this.props.language.quote);
} }
tweetQuote() {
window.open(`https://twitter.com/intent/tweet?text=${this.state.quote} - ${this.state.author} on @getmue`, '_blank').focus();
}
favourite() { favourite() {
if (localStorage.getItem('favouriteQuote')) { if (localStorage.getItem('favouriteQuote')) {
localStorage.removeItem('favouriteQuote'); localStorage.removeItem('favouriteQuote');
this.setState({ favourited: <StarIcon2 className='copyButton' onClick={() => this.favourite()} /> }); this.setState({
favourited: <StarIcon2 className='copyButton' onClick={() => this.favourite()} />
});
} else { } else {
localStorage.setItem('favouriteQuote', this.state.quote + ' - ' + this.state.author); localStorage.setItem('favouriteQuote', this.state.quote + ' - ' + this.state.author);
this.setState({ favourited: <StarIcon className='copyButton' onClick={() => this.favourite()} /> }); this.setState({
favourited: <StarIcon className='copyButton' onClick={() => this.favourite()} />
});
} }
} }
componentDidMount() { componentDidMount() {
if (localStorage.getItem('favouriteQuote')) this.setState({ favourited: <StarIcon className='copyButton' onClick={() => this.favourite()} /> }); if (localStorage.getItem('favouriteQuote')) {
if (localStorage.getItem('favouriteQuoteEnabled') === 'false') this.setState({ favourited: null }); this.setState({ favourited: <StarIcon className='copyButton' onClick={() => this.favourite()} /> });
}
if (localStorage.getItem('favouriteQuoteEnabled') === 'false') {
this.setState({ favourited: null });
}
if (localStorage.getItem('copyButton') === 'false') {
this.setState({ copy: null });
}
if (localStorage.getItem('tweetEnabled') === 'false') {
this.setState({ tweet: null });
}
this.getQuote(); this.getQuote();
} }
render() { render() {
let copy = <FileCopy className='copyButton' onClick={() => this.copyQuote()}></FileCopy>;
if (localStorage.getItem('copyButton') === 'false') copy = null;
let tweet = <TwitterIcon className='copyButton' onClick={() => window.open(`https://twitter.com/intent/tweet?text=${this.state.quote} - ${this.state.author} on @getmue`, '_blank').focus()}/>
if (localStorage.getItem('tweetButton') === 'false') tweet = null;
return ( return (
<div className='quotediv'> <div className='quotediv'>
<h1 className='quote'>{`${this.state.quote}`}</h1> <h1 className='quote'>{`${this.state.quote}`}</h1>
<h1 className='quoteauthor'> <h1 className='quoteauthor'>
<a href={this.state.authorlink} className='quoteauthorlink' target='_blank' rel='noopener noreferrer'>{this.state.author}</a> {copy} {tweet} {this.state.favourited} <a href={this.state.authorlink} className='quoteauthorlink' target='_blank' rel='noopener noreferrer'>{this.state.author}</a> {this.state.copy} {this.state.tweet} {this.state.favourited}
</h1> </h1>
</div> </div>
); );

View File

@@ -20,7 +20,11 @@ export default class Search extends React.PureComponent {
voiceSearch.start(); voiceSearch.start();
const searchText = document.getElementById('searchtext'); const searchText = document.getElementById('searchtext');
voiceSearch.onresult = (event) => searchText.value = event.results[0][0].transcript; voiceSearch.onresult = (event) => searchText.value = event.results[0][0].transcript;
voiceSearch.onend = () => setTimeout(() => window.location.href = this.state.url + `?${this.state.query}=` + searchText.value, 1000); voiceSearch.onend = () =>{
setTimeout(() => {
window.location.href = this.state.url + `?${this.state.query}=` + searchText.value;
}, 1000);
}
} }
render() { render() {

View File

@@ -19,39 +19,56 @@ export default class Clock extends React.PureComponent {
const now = new Date(); const now = new Date();
// Percentage // Percentage
if (localStorage.getItem('percentageComplete') === 'true') return this.setState({ time: (now.getHours() / 24).toFixed(2).replace('0.', '') + '%'}); if (localStorage.getItem('percentageComplete') === 'true') {
return this.setState({ time: (now.getHours() / 24).toFixed(2).replace('0.', '') + '%'});
}
// Analog clock // Analog clock
if (localStorage.getItem('analog') === 'true') { if (localStorage.getItem('analog') === 'true') {
require('react-clock/dist/Clock.css'); require('react-clock/dist/Clock.css'); // load analog clock css
this.setState({ time: now }); this.setState({
time: now
});
} else { } else {
// Default clock
let time, sec = ''; let time, sec = '';
// Extra 0
const zero = localStorage.getItem('zero'); const zero = localStorage.getItem('zero');
if (localStorage.getItem('seconds') === 'true') { if (localStorage.getItem('seconds') === 'true') {
if (zero === 'false') sec = `:${now.getSeconds()}`; if (zero === 'false') {
else sec = `:${('00' + now.getSeconds()).slice(-2)}`; sec = ':' + now.getSeconds();
} else {
sec = `:${('00' + now.getSeconds()).slice(-2)}`;
}
} }
if (localStorage.getItem('24hour') === 'true') { if (localStorage.getItem('24hour') === 'true') {
if (zero === 'false') time = `${now.getHours()}:${now.getMinutes()}${sec}`; if (zero === 'false') {
else time = `${('00' + now.getHours()).slice(-2)}:${('00' + now.getMinutes()).slice(-2)}${sec}`; time = `${now.getHours()}:${now.getMinutes()}${sec}`;
} else {
time = `${('00' + now.getHours()).slice(-2)}:${('00' + now.getMinutes()).slice(-2)}${sec}`;
}
this.setState({ time: time }); this.setState({ time: time });
} else { } else {
// 12 hour support // 12 hour support
let hours = now.getHours(); let hours = now.getHours();
if (hours > 12) hours -= 12;
if (hours > 12) {
hours -= 12;
}
// Toggle AM/PM // Toggle AM/PM
let ampm = now.getHours() > 11 ? 'PM' : 'AM'; let ampm = now.getHours() > 11 ? 'PM' : 'AM';
if (localStorage.getItem('ampm') === 'false') ampm = ''; if (localStorage.getItem('ampm') === 'false') {
ampm = '';
}
if (zero === 'false') time = `${hours}:${now.getMinutes()}${sec}`; if (zero === 'false') {
else time = `${('00' + hours).slice(-2)}:${('00' + now.getMinutes()).slice(-2)}${sec}`; time = `${hours}:${now.getMinutes()}${sec}`;
} else {
time = `${('00' + hours).slice(-2)}:${('00' + now.getMinutes()).slice(-2)}${sec}`;
}
this.setState({ this.setState({
time: time, time: time,
@@ -65,15 +82,15 @@ export default class Clock extends React.PureComponent {
} }
componentDidMount() { componentDidMount() {
if (localStorage.getItem('time') === 'false') return;
this.startTime(0); this.startTime(0);
} }
render() { render() {
if (localStorage.getItem('time') === 'false') return null; let clockHTML = <h1 className='clock'>{this.state.time}<span className='ampm'>{this.state.ampm}</span></h1>;
let clockHTML = <h1 className='clock'>{this.state.time}<span className='ampm'>{this.state.ampm}</span> </h1>; if (localStorage.getItem('analog') === 'true') {
if (localStorage.getItem('analog') === 'true') clockHTML = <Analog className='analogclock' value={this.state.time} renderHourMarks={false} renderMinuteMarks={false} />; clockHTML = <Analog className='analogclock' value={this.state.time} renderHourMarks={false} renderMinuteMarks={false} />;
}
return clockHTML; return clockHTML;
} }

View File

@@ -5,24 +5,24 @@ export default class DateWidget extends React.PureComponent {
constructor(...args) { constructor(...args) {
super(...args); super(...args);
this.state = { this.state = {
date: '' date: ''
}; };
} }
getDate() { getDate() {
const date = new Date(); const date = new Date();
const short = localStorage.getItem('short'); const short = localStorage.getItem('short');
const dateFormat = localStorage.getItem('dateFormat');
if (short === 'true') { if (short === 'true') {
const dateDay = date.getDate(); const dateDay = date.getDate();
const dateMonth = date.getMonth() + 1; const dateMonth = date.getMonth() + 1;
const dateYear = date.getFullYear(); const dateYear = date.getFullYear();
let day = dateDay, month = dateMonth, year = dateYear; let day = dateDay;
let month = dateMonth;
let year = dateYear;
switch (dateFormat) { switch (localStorage.getItem('dateFormat')) {
case 'MDY': case 'MDY':
day = dateMonth; day = dateMonth;
month = dateDay; month = dateDay;
@@ -36,13 +36,21 @@ export default class DateWidget extends React.PureComponent {
let format; let format;
switch (localStorage.getItem('shortFormat')) { switch (localStorage.getItem('shortFormat')) {
case 'dash': format = `${day}-${month}-${year}`; break; case 'dash':
case 'gaps': format = `${day} - ${month} - ${year}`; break; format = `${day}-${month}-${year}`;
default: format = `${day}/${month}/${year}`; break;
case 'gaps':
format = `${day} - ${month} - ${year}`;
break;
default:
format = `${day}/${month}/${year}`;
} }
this.setState({ date: format }); this.setState({
} else { // full date date: format
});
} else {
// Full date
const lang = localStorage.getItem('language'); const lang = localStorage.getItem('language');
const day = date.toLocaleDateString(lang, { weekday: 'long' }); const day = date.toLocaleDateString(lang, { weekday: 'long' });
@@ -50,7 +58,9 @@ export default class DateWidget extends React.PureComponent {
const month = date.toLocaleDateString(lang, { month: 'long' }); const month = date.toLocaleDateString(lang, { month: 'long' });
const year = date.getFullYear(); const year = date.getFullYear();
this.setState({ date: `${day} ${nth} ${month} ${year}` }); this.setState({
date: `${day} ${nth} ${month} ${year}`
});
} }
} }

View File

@@ -9,8 +9,13 @@ export default function hexToRgb(value) {
const valid = hexRegexp.test(value); const valid = hexRegexp.test(value);
if (valid) { if (valid) {
if (value[0] === '#') value = value.slice(1, value.length); if (value[0] === '#') {
if (value.length === 3) value = value.replace(regexp, '$1$1$2$2$3$3'); value = value.slice(1, value.length);
}
if (value.length === 3){
value = value.replace(regexp, '$1$1$2$2$3$3');
}
const red = parseInt(value.substr(0, 2), 16); const red = parseInt(value.substr(0, 2), 16);
const green = parseInt(value.substr(2, 2), 16); const green = parseInt(value.substr(2, 2), 16);

View File

@@ -3,9 +3,17 @@ export default function rgbToHex(red, green, blue) {
let g16 = green.toString(16); let g16 = green.toString(16);
let b16 = blue.toString(16); let b16 = blue.toString(16);
if (red < 16) r16 = `0${r16}`; if (red < 16) {
if (green < 16) g16 = `0${g16}`; r16 = `0${r16}`;
if (blue < 16) b16 = `0${b16}`; }
if (green < 16) {
g16 = `0${g16}`;
}
if (blue < 16) {
b16 = `0${b16}`;
}
return r16 + g16 + b16; return r16 + g16 + b16;
} }

View File

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

View File

@@ -10,8 +10,10 @@ export default function setRGBA(red, green, blue, alpha) {
blue: blue | 0, blue: blue | 0,
}; };
if (isValidRGBValue(alpha) === true) color.alpha = alpha | 0; if (isValidRGBValue(alpha) === true) {
// RGBToHSL(color.r, color.g, color.b); color.alpha = alpha | 0;
}
return color; return color;
} }
} }

View File

@@ -18,8 +18,9 @@ export default class MarketplaceFunctions {
localStorage.removeItem('quoteAPI'); localStorage.removeItem('quoteAPI');
break; break;
default: default:
try { localStorage.removeItem(type); } try {
catch (e) { localStorage.removeItem(type);
} catch (e) {
toast('Failed to uninstall addon, check the console'); toast('Failed to uninstall addon, check the console');
console.error(e); console.error(e);
} }
@@ -39,17 +40,32 @@ export default class MarketplaceFunctions {
switch (type) { switch (type) {
case 'settings': case 'settings':
localStorage.removeItem('backup_settings'); localStorage.removeItem('backup_settings');
let oldSettings = []; let oldSettings = [];
for (const key of Object.keys(localStorage)) oldSettings.push({ name: key, value: localStorage.getItem(key) }); for (const key of Object.keys(localStorage)) {
oldSettings.push({
name: key,
value: localStorage.getItem(key)
});
}
localStorage.setItem('backup_settings', JSON.stringify(oldSettings)); localStorage.setItem('backup_settings', JSON.stringify(oldSettings));
input.settings.forEach(element => localStorage.setItem(element.name, element.value)); input.settings.forEach(element => localStorage.setItem(element.name, element.value));
break; break;
case 'photo_packs': localStorage.setItem('photo_packs', JSON.stringify(input.photos)); break;
case 'photo_packs':
localStorage.setItem('photo_packs', JSON.stringify(input.photos));
break;
case 'quote_packs': case 'quote_packs':
if (input.quote_api) localStorage.setItem('quoteAPI', JSON.stringify(input.quote_api)); if (input.quote_api) {
localStorage.setItem('quoteAPI', JSON.stringify(input.quote_api));
}
localStorage.setItem('quote_packs', JSON.stringify(input.quotes)); localStorage.setItem('quote_packs', JSON.stringify(input.quotes));
break; break;
default: break; default:
break;
} }
let installed = JSON.parse(localStorage.getItem('installed')); let installed = JSON.parse(localStorage.getItem('installed'));

View File

@@ -18,7 +18,9 @@ const saveFile = (data, filename = 'file') => {
export default class SettingsFunctions { export default class SettingsFunctions {
static exportSettings() { static exportSettings() {
let settings = {}; let settings = {};
for (const key of Object.keys(localStorage)) settings[key] = localStorage.getItem(key); for (const key of Object.keys(localStorage)) {
settings[key] = localStorage.getItem(key);
}
saveFile(settings, 'mue-settings.json'); saveFile(settings, 'mue-settings.json');
} }
@@ -27,8 +29,13 @@ export default class SettingsFunctions {
let val = true; let val = true;
if (old !== null && !value) { if (old !== null && !value) {
if (old === 'true') val = false; if (old === 'true') {
if (old === 'false') val = true; val = false;
}
if (old === 'false') {
val = true;
}
} }
localStorage.setItem(key, val); localStorage.setItem(key, val);
@@ -69,8 +76,11 @@ export default class SettingsFunctions {
defaultSettings.forEach((element) => localStorage.setItem(element.name, element.value)); defaultSettings.forEach((element) => localStorage.setItem(element.name, element.value));
// Set theme depending on user preferred // Set theme depending on user preferred
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) localStorage.setItem('darkTheme', true); if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
else localStorage.setItem('darkTheme', false); localStorage.setItem('darkTheme', true);
} else {
localStorage.setItem('darkTheme', false);
}
// Languages // Languages
const languages = ['nl', 'no', 'fr', 'ru', 'es']; const languages = ['nl', 'no', 'fr', 'ru', 'es'];
@@ -79,9 +89,13 @@ export default class SettingsFunctions {
if (languages.includes(browserLanguage)) { if (languages.includes(browserLanguage)) {
localStorage.setItem('language', browserLanguage); localStorage.setItem('language', browserLanguage);
document.documentElement.lang = browserLanguage; document.documentElement.lang = browserLanguage;
} else localStorage.setItem('language', 'en'); } else {
localStorage.setItem('language', 'en');
}
if (reset) localStorage.setItem('showWelcome', false); if (reset) {
localStorage.setItem('showWelcome', false);
}
// Finally we set this to true so it doesn't run the function on every load // Finally we set this to true so it doesn't run the function on every load
localStorage.setItem('firstRun', true); localStorage.setItem('firstRun', true);