refactor and fix some things

This commit is contained in:
David Ralph
2021-01-16 18:39:03 +00:00
parent 5c579ee0a2
commit 0a735384df
23 changed files with 122 additions and 117 deletions

View File

@@ -32,6 +32,5 @@ Inspired features are fine.
### Bug Fixes ### Bug Fixes
See the note in general. See the note in general.
## Final Note ## Final Note
Contact us before doing anything if you don't want to have to change 1000 things and/or have your pull request closed. Contact us before doing anything if you don't want to have to change 1000 things and/or have your pull request closed.

View File

@@ -21,11 +21,10 @@
"react-beforeunload": "^2.4.0", "react-beforeunload": "^2.4.0",
"react-clock": "^3.0.0", "react-clock": "^3.0.0",
"react-color-gradient-picker": "^0.1.2", "react-color-gradient-picker": "^0.1.2",
"react-date-picker": "^8.0.5", "react-date-picker": "^8.0.6",
"react-dom": "17.0.1", "react-dom": "17.0.1",
"react-modal": "3.12.1", "react-modal": "3.12.1",
"react-toastify": "6.2.0", "react-toastify": "6.2.0"
"supports-webp": "2.0.1"
}, },
"devDependencies": { "devDependencies": {
"node-sass": "^4.14.1", "node-sass": "^4.14.1",

View File

@@ -1,10 +0,0 @@
<svg width="20" height="20" viewBox="0 0 400 400" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="200" cy="200" r="200" fill="url(#paint0_linear)"/>
<path d="M167 265.062L294.125 137.938L311 154.812L167 298.812L100.062 231.875L116.938 215L167 265.062Z" fill="white"/>
<defs>
<linearGradient id="paint0_linear" x1="200" y1="0" x2="200" y2="400" gradientUnits="userSpaceOnUse">
<stop stop-color="#FF5C25"/>
<stop offset="1" stop-color="#FF456E"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 490 B

View File

@@ -1,15 +1,8 @@
import React from 'react'; import React from 'react';
import Background from './components/widgets/background/Background'; import Background from './components/widgets/background/Background';
import Clock from './components/widgets/time/Clock'; import Widgets from './components/widgets/Widgets';
import Greeting from './components/widgets/greeting/Greeting';
import Quote from './components/widgets/quote/Quote';
import Search from './components/widgets/search/Search';
import Maximise from './components/widgets/background/Maximise';
import Favourite from './components/widgets/background/Favourite';
import PhotoInformation from './components/widgets/background/PhotoInformation'; import PhotoInformation from './components/widgets/background/PhotoInformation';
import Date from './components/widgets/time/Date';
import Navbar from './components/widgets/navbar/Navbar'; import Navbar from './components/widgets/navbar/Navbar';
import SettingsFunctions from './modules/helpers/settings'; import SettingsFunctions from './modules/helpers/settings';
@@ -38,8 +31,10 @@ export default class App extends React.PureComponent {
componentDidMount() { componentDidMount() {
if (!localStorage.getItem('firstRun')) SettingsFunctions.setDefaultSettings(); if (!localStorage.getItem('firstRun')) SettingsFunctions.setDefaultSettings();
if (localStorage.getItem('showWelcome') === 'true') this.setState({ welcomeModal: true }); 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');
} }
@@ -68,15 +63,9 @@ export default class App extends React.PureComponent {
<Background/> <Background/>
<ToastContainer position='bottom-right' autoClose={2500} newestOnTop={true} closeOnClick rtl={false} pauseOnFocusLoss /> <ToastContainer position='bottom-right' autoClose={2500} newestOnTop={true} closeOnClick rtl={false} pauseOnFocusLoss />
<div id='center'> <div id='center'>
<Search language={language.search} />
<Navbar mainModalOpen={() => this.setState({ mainModal: true })} updateModalOpen={() => this.setState({ updateModal: true })} feedbackModalOpen={() => this.setState({ feedbackModal: true })} language={language} /> <Navbar mainModalOpen={() => this.setState({ mainModal: true })} updateModalOpen={() => this.setState({ updateModal: true })} feedbackModalOpen={() => this.setState({ feedbackModal: true })} language={language} />
<Greeting language={language.greeting} /> <Widgets language={language} languagecode={languagecode} />
<Clock/>
<Date/>
<Quote language={language.toasts} languagecode={languagecode} />
<PhotoInformation language={language} className={tooltipClassList} /> <PhotoInformation language={language} className={tooltipClassList} />
<Maximise/>
<Favourite/>
<React.Suspense fallback={renderLoader()}> <React.Suspense fallback={renderLoader()}>
<Modal id={'modal'} onRequestClose={() => this.setState({ mainModal: false })} isOpen={this.state.mainModal} className={modalClassList} overlayClassName={overlayClassList} ariaHideApp={false}> <Modal id={'modal'} onRequestClose={() => this.setState({ mainModal: false })} isOpen={this.state.mainModal} className={modalClassList} overlayClassName={overlayClassList} ariaHideApp={false}>
<Main language={language} modalClose={() => this.setState({ mainModal: false })} /> <Main language={language} modalClose={() => this.setState({ mainModal: false })} />

View File

@@ -6,34 +6,24 @@ export default class Update extends React.PureComponent {
super(...args); super(...args);
this.state = { this.state = {
title: this.props.language.title, title: this.props.language.title,
date: '???', date: null,
content: this.props.language.title, content: this.props.language.title,
author: 'Mue', html: this.props.language.loading,
html: this.props.language.loading image: null
}; };
} }
async getUpdate() { async getUpdate() {
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 removeStuff = () => { // quick code to make update modal a bit better, will replace later
document.getElementById('author').innerText = '';
const img = document.getElementsByTagName('img')[0];
img.parentNode.removeChild(img);
}
if (localStorage.getItem('offlineMode') === 'true') { if (localStorage.getItem('offlineMode') === 'true') {
removeStuff();
return this.setState({ return this.setState({
title: this.props.language.offline.title, title: this.props.language.offline.title,
html: this.props.language.offline.description html: this.props.language.offline.description
}); });
} }
try { // Get update log from the API
const data = await (await fetch(Constants.API_URL + '/getUpdate')).json(); const data = await (await fetch(Constants.API_URL + '/getUpdate')).json();
if (data.statusCode === 500) { if (data.statusCode === 500 || data.title === null) {
removeStuff(); 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({
title: this.props.language.error.title, title: this.props.language.error.title,
html: this.props.language.error.description + supportText html: this.props.language.error.description + supportText
@@ -43,17 +33,10 @@ export default class Update extends React.PureComponent {
this.setState({ this.setState({
title: data.title, title: data.title,
date: data.published, date: data.published,
image: data.image, image: data.image || null,
author: data.author, author: data.author,
html: data.content + `<br/><p>${this.props.language.read_blog}: <a target='_blank' class='modalLink' href='${data.url}'>${data.url}</a></p>` html: data.content
}); });
} catch (e) { // If it fails, we send an error
removeStuff();
this.setState({
title: this.props.language.error.title,
html: this.props.language.error.description + supportText
});
}
} }
componentDidMount() { componentDidMount() {
@@ -64,8 +47,8 @@ export default class Update extends React.PureComponent {
return <div className='updateContent'> return <div className='updateContent'>
<span className='closeModal' onClick={this.props.modalClose}>&times;</span> <span className='closeModal' onClick={this.props.modalClose}>&times;</span>
<h1 style={{ 'marginBottom': '-10px' }}>{this.state.title}</h1> <h1 style={{ 'marginBottom': '-10px' }}>{this.state.title}</h1>
<h5 style={{ 'lineHeight':'0px' }} id='author'> By {this.state.author} {this.state.date}</h5> <h5 style={{ 'lineHeight': '0px' }}>{this.state.date}</h5>
<img draggable='false' src={this.state.image} alt='Update'></img> {this.state.image ? <img draggable='false' src={this.state.image} alt='Update'></img> : null}
<p dangerouslySetInnerHTML={{ __html: this.state.html }}></p> <p dangerouslySetInnerHTML={{ __html: this.state.html }}></p>
</div>; </div>;
} }

View File

@@ -1,12 +1,15 @@
import React from 'react'; import React from 'react';
import { toast } from 'react-toastify';
import Checkbox from '../Checkbox'; import Checkbox from '../Checkbox';
import Dropdown from '../Dropdown'; import Dropdown from '../Dropdown';
import Section from '../Section'; import Section from '../Section';
import FileUpload from '../FileUpload'; import FileUpload from '../FileUpload';
import { ColorPicker } from 'react-color-gradient-picker'; import { ColorPicker } from 'react-color-gradient-picker';
import hexToRgb from '../../../../modules/helpers/background/hexToRgb'; import hexToRgb from '../../../../modules/helpers/background/hexToRgb';
import rgbToHex from '../../../../modules/helpers/background/rgbToHex'; import rgbToHex from '../../../../modules/helpers/background/rgbToHex';
import { toast } from 'react-toastify';
import { Beforeunload } from 'react-beforeunload'; import { Beforeunload } from 'react-beforeunload';
import 'react-color-gradient-picker/dist/index.css'; import 'react-color-gradient-picker/dist/index.css';

View File

@@ -0,0 +1,41 @@
import React from 'react';
import Clock from './time/Clock';
import Greeting from './greeting/Greeting';
import Quote from './quote/Quote';
import Search from './search/Search';
import Maximise from './background/Maximise';
import Favourite from './background/Favourite';
import Date from './time/Date';
export default class Widgets extends React.PureComponent {
enabled(key) {
const old = localStorage.getItem(key);
let val = true;
if (old !== null) {
if (old === 'true') val = true;
if (old === 'false') val = false;
}
return val;
}
// Render all the components
render() {
const { language, languagecode } = this.props;
const enabled = this.enabled;
return (
<React.Fragment>
{enabled('searchBar') ? <Search language={language.search} /> : null}
{enabled('greeting') ? <Greeting language={language.greeting} /> : null}
{enabled('clock') ? <Clock/> : null}
{enabled('date') ? <Date/> : null}
{enabled('quote') ? <Quote language={language.toasts} languagecode={languagecode} /> : null}
{enabled('view') ? <Maximise/> : null}
{enabled('favouriteEnabled') ? <Favourite/> : null}
</React.Fragment>
);
}
}

View File

@@ -18,13 +18,16 @@ export default class Favourite extends React.PureComponent {
const url = document.getElementById('backgroundImage').style.backgroundImage.replace('url("', '').replace('")', ''); const url = document.getElementById('backgroundImage').style.backgroundImage.replace('url("', '').replace('")', '');
const credit = document.getElementById('credit').textContent; const credit = document.getElementById('credit').textContent;
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')) this.setState({ favourited: <StarIcon onClick={() => this.favourite()} /> }); if (localStorage.getItem('favourite')) {
this.setState({ favourited: <StarIcon onClick={() => this.favourite()} /> });
}
} }
render() { render() {

View File

@@ -36,7 +36,7 @@ export default class View extends React.PureComponent {
} }
render() { render() {
if (localStorage.getItem('view') === 'false' || 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

@@ -7,14 +7,11 @@ import Photographer from '@material-ui/icons/Person';
export default class PhotoInformation extends React.PureComponent { export default class PhotoInformation extends React.PureComponent {
render() { render() {
let classList = 'infoCard';
if (this.props.className) classList = this.props.className;
return ( return (
<div className='photoInformation'> <div className='photoInformation'>
<h1 id='photographer'>{this.props.language.credit}</h1> <h1 id='photographer'>{this.props.language.credit}</h1>
<Info className='photoInformationHover'/> <Info className='photoInformationHover'/>
<div className={classList}> <div className={this.props.className || 'infoCard'}>
<Info className='infoIcon'/> <Info className='infoIcon'/>
<h1>{this.props.language.information}</h1> <h1>{this.props.language.information}</h1>
<hr/> <hr/>

View File

@@ -9,6 +9,7 @@
float: left; float: left;
margin-right: 1rem; margin-right: 1rem;
font-size: calc(10px + 2vmin); font-size: calc(10px + 2vmin);
cursor: pointer;
} }
svg, svg,
@@ -72,10 +73,6 @@
} }
} }
.photoInformationHover {
cursor: pointer;
}
.dark hr { .dark hr {
background-color: white !important; background-color: white !important;
} }

View File

@@ -56,7 +56,6 @@ export default class Greeting extends React.PureComponent {
} }
componentDidMount() { componentDidMount() {
if (localStorage.getItem('greeting') === 'false') return;
this.getGreeting(); this.getGreeting();
} }

View File

@@ -1,10 +1,12 @@
import React from 'react'; import React from 'react';
import RefreshIcon from '@material-ui/icons/RefreshRounded'; import RefreshIcon from '@material-ui/icons/RefreshRounded';
import Gear from '@material-ui/icons/SettingsRounded'; import Gear from '@material-ui/icons/SettingsRounded';
import NewReleases from '@material-ui/icons/NewReleasesRounded'; import NewReleases from '@material-ui/icons/NewReleasesRounded';
import NotesIcon from '@material-ui/icons/AssignmentRounded'; import NotesIcon from '@material-ui/icons/AssignmentRounded';
import Tooltip from '@material-ui/core/Tooltip'; import Tooltip from '@material-ui/core/Tooltip';
import Report from '@material-ui/icons/SmsFailed'; import Report from '@material-ui/icons/SmsFailed';
import * as Constants from '../../../modules/constants'; import * as Constants from '../../../modules/constants';
import './scss/index.scss'; import './scss/index.scss';
@@ -20,6 +22,7 @@ export default class Navbar extends React.PureComponent {
<RefreshIcon className='refreshicon topicons' onClick={() => window.location.reload()} /> <RefreshIcon className='refreshicon topicons' onClick={() => window.location.reload()} />
</Tooltip> </Tooltip>
); );
if (localStorage.getItem('refresh') === 'false') refreshHTML = null; if (localStorage.getItem('refresh') === 'false') refreshHTML = null;
// toggle feedback button // toggle feedback button
@@ -28,6 +31,7 @@ export default class Navbar extends React.PureComponent {
<Report className='topicons' onClick={this.props.feedbackModalOpen} /> <Report className='topicons' onClick={this.props.feedbackModalOpen} />
</Tooltip> </Tooltip>
); );
if (Constants.BETA_VERSION === false) feedbackHTML = null; if (Constants.BETA_VERSION === false) feedbackHTML = null;
return ( return (

View File

@@ -23,12 +23,15 @@ export default class Notes extends React.PureComponent {
} }
componentDidMount() { componentDidMount() {
if (localStorage.getItem('notesPinned') === 'true') document.getElementById('noteContainer').classList.toggle('visibilityshow'); if (localStorage.getItem('notesPinned') === 'true') {
document.getElementById('noteContainer').classList.toggle('visibilityshow');
}
} }
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}>
<div className='topbarnotes'> <div className='topbarnotes'>

View File

@@ -93,15 +93,12 @@ export default class Quote extends React.PureComponent {
} }
componentDidMount() { componentDidMount() {
if (localStorage.getItem('quote') === 'false') return;
if (localStorage.getItem('favouriteQuote')) this.setState({ favourited: <StarIcon className='copyButton' onClick={() => this.favourite()} /> }); if (localStorage.getItem('favouriteQuote')) this.setState({ favourited: <StarIcon className='copyButton' onClick={() => this.favourite()} /> });
if (localStorage.getItem('favouriteQuoteEnabled') === 'false') this.setState({ favourited: null }); if (localStorage.getItem('favouriteQuoteEnabled') === 'false') this.setState({ favourited: null });
this.getQuote(); this.getQuote();
} }
render() { render() {
if (localStorage.getItem('quote') === 'false') return null;
let copy = <FileCopy className='copyButton' onClick={() => this.copyQuote()}></FileCopy>; let copy = <FileCopy className='copyButton' onClick={() => this.copyQuote()}></FileCopy>;
if (localStorage.getItem('copyButton') === 'false') copy = null; if (localStorage.getItem('copyButton') === 'false') copy = null;

View File

@@ -18,13 +18,12 @@ export default class Search extends React.PureComponent {
startSpeechRecognition() { startSpeechRecognition() {
const voiceSearch = new window.webkitSpeechRecognition(); const voiceSearch = new window.webkitSpeechRecognition();
voiceSearch.start(); voiceSearch.start();
voiceSearch.onresult = (event) => document.getElementById('searchtext').value = event.results[0][0].transcript; const searchText = document.getElementById('searchtext');
voiceSearch.onend = () => setTimeout(() => window.location.href = this.state.url + `?${this.state.query}=` + document.getElementById('searchtext').value, 1000); 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);
} }
render() { render() {
if (localStorage.getItem('searchBar') === 'false') return null;
let url; let url;
let query = 'q'; let query = 'q';
@@ -52,8 +51,8 @@ export default class Search extends React.PureComponent {
} }
return ( return (
<div id='searchBar' className='searchbar'> <div id='searchBar'>
<form id='searchBar' className='searchbarform' action={url}> <form action={url}>
{microphone} {microphone}
<SearchIcon onClick={() => searchButton()} id='searchButton' /> <SearchIcon onClick={() => searchButton()} id='searchButton' />
<input type='text' placeholder={this.props.language} name={query} id='searchtext' className='searchtext'/> <input type='text' placeholder={this.props.language} name={query} id='searchtext' className='searchtext'/>

View File

@@ -1,6 +1,6 @@
@import '../../../scss/variables'; @import '../../../scss/variables';
.searchbar { #searchBar {
position: absolute; position: absolute;
left: 20px; left: 20px;
top: 20px; top: 20px;

View File

@@ -22,8 +22,10 @@ export default class Clock extends React.PureComponent {
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') this.setState({ time: now }); if (localStorage.getItem('analog') === 'true') {
else { require('react-clock/dist/Clock.css');
this.setState({ time: now });
} else {
let time, sec = ''; let time, sec = '';
// Extra 0 // Extra 0

View File

@@ -11,6 +11,7 @@ export default class DateWidget extends React.PureComponent {
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'); const dateFormat = localStorage.getItem('dateFormat');
@@ -54,7 +55,6 @@ export default class DateWidget extends React.PureComponent {
} }
componentDidMount() { componentDidMount() {
if (localStorage.getItem('date') === 'false') return;
this.getDate(); this.getDate();
} }

View File

@@ -4,7 +4,6 @@ import ReactDOM from 'react-dom';
import App from './App'; import App from './App';
import './scss/index.scss'; import './scss/index.scss';
import 'react-clock/dist/Clock.css';
import 'react-toastify/dist/ReactToastify.css'; // the toast css is based on default so we need to import it import 'react-toastify/dist/ReactToastify.css'; // the toast css is based on default so we need to import it
import 'fontsource-lexend-deca/latin-400-normal.css'; import 'fontsource-lexend-deca/latin-400-normal.css';

View File

@@ -48,9 +48,11 @@ export default class SettingsFunctions {
static saveStuff(hexDisabled) { static saveStuff(hexDisabled) {
localStorage.setItem('customcss', document.getElementById('customcss').value); localStorage.setItem('customcss', document.getElementById('customcss').value);
if (document.getElementById('customBackgroundHex').value !== hexDisabled) { if (document.getElementById('customBackgroundHex').value !== hexDisabled) {
localStorage.setItem('customBackgroundColour', document.getElementById('customBackgroundHex').value); localStorage.setItem('customBackgroundColour', document.getElementById('customBackgroundHex').value);
} }
if (document.getElementById('searchEngineInput').enabled === 'true') { if (document.getElementById('searchEngineInput').enabled === 'true') {
const input = document.getElementById('customSearchEngine').value; const input = document.getElementById('customSearchEngine').value;
if (input) { if (input) {
@@ -58,6 +60,7 @@ export default class SettingsFunctions {
localStorage.setItem('customSearchEngine', input); localStorage.setItem('customSearchEngine', input);
} }
} }
window.location.reload(); window.location.reload();
} }
@@ -69,13 +72,10 @@ export default class SettingsFunctions {
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) localStorage.setItem('darkTheme', true); if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) localStorage.setItem('darkTheme', true);
else localStorage.setItem('darkTheme', false); else localStorage.setItem('darkTheme', false);
// Webp support
const supportsWebP = require('supports-webp'); // We import it here so it doesn't run the function on each page load
if (supportsWebP) localStorage.setItem('supportswebp', 'true');
// Languages // Languages
const languages = ['nl', 'no', 'fr', 'ru', 'es']; const languages = ['nl', 'no', 'fr', 'ru', 'es'];
const browserLanguage = (navigator.languages && navigator.languages[0]) || navigator.language; const browserLanguage = (navigator.languages && navigator.languages[0]) || navigator.language;
if (languages.includes(browserLanguage)) { if (languages.includes(browserLanguage)) {
localStorage.setItem('language', browserLanguage); localStorage.setItem('language', browserLanguage);
document.documentElement.lang = browserLanguage; document.documentElement.lang = browserLanguage;

View File

@@ -91,6 +91,7 @@
background: none; background: none;
border-radius: 24px; border-radius: 24px;
transition: ease 0.33s; transition: ease 0.33s;
border: 2px solid black;
&:hover { &:hover {
background: #2d3436; background: #2d3436;