Settings! (Almost finished)

Co-authored-by: Alex Sparkes <turbomarshmello@gmail.com>
Co-authored-by: Wessel Tip <discord@go2it.eu>
This commit is contained in:
David Ralph
2020-07-15 21:06:21 +01:00
parent da5a4da97b
commit 0c6022aa2d
13 changed files with 341 additions and 29 deletions

View File

@@ -20,12 +20,13 @@
"@muetab/quotes": "^1.0.0", "@muetab/quotes": "^1.0.0",
"react": "^16.13.1", "react": "^16.13.1",
"react-dom": "^16.13.1", "react-dom": "^16.13.1",
"react-modal": "^3.11.2",
"react-scripts": "3.4.1", "react-scripts": "3.4.1",
"supports-webp": "^2.0.1" "supports-webp": "^2.0.1"
}, },
"devDependencies": { "devDependencies": {
"eslint": "^7.1.0", "eslint": "^7.3.0",
"node-sass": "^4.13.0" "node-sass": "^4.14.1"
}, },
"scripts": { "scripts": {
"start": "react-scripts start", "start": "react-scripts start",

View File

@@ -6,23 +6,52 @@ import Greeting from './components/Greeting';
import Quote from './components/Quote'; import Quote from './components/Quote';
import Search from './components/Search'; import Search from './components/Search';
import Credit from './components/Credit'; import Credit from './components/Credit';
//import Navbar from './components/Navbar'; import Navbar from './components/Navbar';
import Settings from './components/Settings';
import Modal from 'react-modal';
import './scss/index.scss'; import './scss/index.scss';
//* App //* App
export default class App extends React.Component { export default class App extends React.Component {
// Modal stuff
constructor(props) {
super(props);
this.state = { modal: false };
this.openModal = this.onOpenModal.bind(this);
}
onOpenModal() {
this.setState({ modal: true });
}
onCloseModal() {
this.setState({ modal: false });
}
// Render all the components // Render all the components
render() { render() {
if (!localStorage.getItem('firstRun')) {
localStorage.setItem('time', true);
localStorage.setItem('greeting', true);
localStorage.setItem('background', true);
localStorage.setItem('quote', true);
localStorage.setItem('firstRun', true);
}
return ( return (
<React.Fragment> <React.Fragment>
<Background/> <Background/>
<Search/> <Search/>
<div id='center'> <div id='center'>
<Greeting/> <Navbar modalOpen={() => this.onOpenModal()}/>
<Clock/> <Greeting/>
<Quote/> <Clock/>
<Credit/> <Quote/>
</div> <Credit/>
<Modal isOpen={this.state.modal} className='Modal' overlayClassName="Overlay" ariaHideApp={false}>
<Settings modalClose={() => this.onCloseModal()} />
</Modal>
</div>
</React.Fragment> </React.Fragment>
); );
} }

View File

@@ -53,6 +53,8 @@ export default class Background extends React.Component {
} }
componentDidMount() { componentDidMount() {
const enabled = localStorage.getItem('background');
if (enabled === 'false') return;
this.setBackground(); this.setBackground();
} }

View File

@@ -26,6 +26,8 @@ export default class Clock extends React.Component {
} }
componentDidMount() { componentDidMount() {
const enabled = localStorage.getItem('time');
if (enabled === 'false') return;
this.startTime(); this.startTime();
} }

View File

@@ -33,6 +33,8 @@ export default class Greeting extends React.Component {
} }
componentDidMount() { componentDidMount() {
const enabled = localStorage.getItem('greeting');
if (enabled === 'false') return;
this.getGreeting(); this.getGreeting();
} }

View File

@@ -1,6 +1,6 @@
//* Imports //* Imports
import RefreshIcon from '@material-ui/icons/Refresh'; import RefreshIcon from '@material-ui/icons/Refresh';
import LocalPizzaIcon from '@material-ui/icons/LocalPizza'; import Gear from '@material-ui/icons/Settings';
import React from 'react'; import React from 'react';
export default class Navbar extends React.Component { export default class Navbar extends React.Component {
@@ -8,10 +8,10 @@ export default class Navbar extends React.Component {
return ( return (
<div className='navbar-container'> <div className='navbar-container'>
<div className='navbar1'> <div className='navbar1'>
<RefreshIcon className='locationicon'/> <Gear className='settings-icon' onClick={this.props.modalOpen} />
</div> </div>
<div className='navbar2'> <div className='navbar2'>
<LocalPizzaIcon className='pizzaicon'/> <RefreshIcon className='refreshicon' onClick={() => window.location.reload()} />
</div> </div>
</div> </div>
); );

View File

@@ -18,30 +18,32 @@ export default class Quote extends React.Component {
if (data.statusCode === 429) { // If we hit the ratelimit, we fallback to local quotes if (data.statusCode === 429) { // If we hit the ratelimit, we fallback to local quotes
const quote = Quotes.random(); // Get a random quote from our local package const quote = Quotes.random(); // Get a random quote from our local package
return this.setState({ return this.setState({
quote: quote.quote, quote: '"' + quote.quote + '"',
author: quote.author author: quote.author
}); // Set the quote }); // Set the quote
} }
this.setState({ this.setState({
quote: data.quote, quote: '"' + data.quote + '"',
author: data.author author: data.author
}); });
} catch (e) { // ..and if that fails we load one locally } catch (e) { // ..and if that fails we load one locally
const quote = Quotes.random(); // Get a random quote from our local package const quote = Quotes.random(); // Get a random quote from our local package
this.setState({ this.setState({
quote: quote.quote, quote: '"' + quote.quote + '"',
author: quote.author author: quote.author
}); // Set the quote }); // Set the quote
} }
} }
componentDidMount() { componentDidMount() {
const enabled = localStorage.getItem('quote');
if (enabled === 'false') return;
this.getQuote(); this.getQuote();
} }
render() { render() {
return [ return [
<h1 className='quote'>{`"${this.state.quote}"`}</h1>, <h1 className='quote'>{`${this.state.quote}`}</h1>,
// <i class="material-icons">perm_identity</i>, // <i class="material-icons">perm_identity</i>,
<h1 className='quoteauthor'>{`${this.state.author}`}</h1>, <h1 className='quoteauthor'>{`${this.state.author}`}</h1>,
]; ];

View File

@@ -0,0 +1,81 @@
import React from 'react';
export default class Settings extends React.Component {
setItem(key, value) {
let old = localStorage.getItem(key);
let val = true;
if (old !== null && !value) {
if (old === 'true') val = false;
if (old === 'false') val = true;
}
localStorage.setItem(key, val);
document.getElementById(`${key}Status`).innerHTML = val === true ? 'ON' : 'OFF';
console.log(`[DEBUG] setItem(${key}, ${old} -> ${val})`);
}
render() {
return <div className="content">
<a class="closeModal" onClick={this.props.modalClose}>&times;</a>
<h1>Settings</h1>
<p>Edit different components to make Mue your new tab.</p>
<div className='columns'>
<div className='section'>
<h4>Time</h4>
<label class="switch">
<input type="checkbox" />
<span class="slider round"></span>
</label>
</div>
<div className='section'>
<h4>Quote</h4>
<label class="switch">
<input type="checkbox" />
<span class="slider"></span>
</label>
</div>
<div className='section'>
<h4>Background</h4>
<label class="switch">
<input type="checkbox" />
<span class="slider"></span>
</label>
</div>
<button class="apply">Apply</button>
<p>You need to refresh the page to see your changes!</p>
{/*
<h4 style={{ flex: 2 }}>Time <span id="timeStatus">{localStorage.getItem('time') === 'true' ? 'ON' : 'OFF'}</span>
</h4>
<button onClick={()=>this.setItem('time')}>Toggle Time</button>
<h4 style={{ flex: 2 }}>Search Bar</h4>
<button onClick={()=>this.setItem('searchbar')}>Toggle Searchbar</button>
<h4 style={{ flex: 2 }}>Greeting <span id="greetingStatus">{localStorage.getItem('greeting') === 'true' ? 'ON' :
'OFF'}</span></h4>
<button onClick={()=>this.setItem('greeting')}>Greeting Toggle</button>
<h4 style={{ flex: 2 }}>Quote <span id="quoteStatus">{localStorage.getItem('quote') === 'true' ? 'ON' :
'OFF'}</span> <button onClick={()=>this.setItem('quote')}>Quote Toggle</button>
</h4>
<h4 style={{ flex: 2 }}>Background <span id="backgroundStatus">{localStorage.getItem('background') === 'true' ? 'ON'
: 'OFF'}</span></h4>
<button onClick={()=> this.setItem('background')}>Background Toggle</button>
<label class="switch">
<input type="checkbox" />
<span class="slider round"></span>
</label>
<label class="switch">
<input type="checkbox" checked />
<span class="slider round"></span>
</label>
{/* <label className="switch">
<input type="checkbox" checked></input>
<span className="slider round"></span>
</label> */}
</div>
</div>;
}
}

View File

@@ -4,5 +4,7 @@
@import 'modules/quote'; @import 'modules/quote';
@import 'modules/search'; @import 'modules/search';
@import 'modules/credit'; @import 'modules/credit';
/*@import 'modules/navbar';*/ @import 'modules/navbar';
@import 'modules/miscellaneous'; @import 'modules/modal';
@import 'modules/settings';
@import 'modules/miscellaneous';

View File

@@ -0,0 +1,74 @@
.Modal {
background-color: #fff;
width: 600px;
margin: 0 auto;
margin-top: 40px;
border: none;
opacity: 1;
z-index: -2;
height: auto;
padding: 20px;
cursor: hand;
}
.Overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: #2196F3;
}
input:focus + .slider {
box-shadow: 0 0 1px #2196F3;
}
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}

View File

@@ -2,24 +2,17 @@
position: absolute; position: absolute;
text-align: right; text-align: right;
min-width: 50px; min-width: 50px;
cursor: pointer;
} }
.navbar1 { .navbar1 {
@extend navbar; @extend %navbar;
top: 50px; top: 50px;
right: 0px; right: 0px;
} }
.navbar2 { .navbar2 {
@extend navbar; @extend %navbar;
top: 50px; top: 50px;
right: 50px; right: 50px;
}
.PizzaIcon {
margin-right: 20px;
}
.pizza {
right: 2000px;
} }

View File

@@ -16,7 +16,6 @@
color: #ffff; color: #ffff;
position: absolute; position: absolute;
box-shadow: 0 0 25px rgba(0, 0, 0, 0.3); box-shadow: 0 0 25px rgba(0, 0, 0, 0.3);
z-index: 1;
} }
} }

View File

@@ -0,0 +1,125 @@
.Modal {
width: auto;
color: #000;
background-color: #fff;
max-width: 500px;
box-shadow: 0 0 200px rgba(0, 0, 0, 0.3);
}
.Modal:focus {
outline: 0;
}
.closeModal {
float: right;
font-size: 2em;
cursor: pointer;
}
.closeModal:hover {
color: grey;
}
.switch {
position: relative;
/* display: inline-block; */
width: 60px;
height: 34px;
float: right;
}
.switch input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
-webkit-transition: .4s;
transition: .4s;
border-radius: 34px;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
border-radius: 50%;
}
input:checked + .slider {
background: linear-gradient(90deg, #ffb032 0%, #dd3b67 100%);
}
input:focus + .slider {
box-shadow: 0 0 1px #e67e22;
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
h4, .switch {
display: inline;
font-size: 1.4em;
}
.section {
margin-bottom: 20px;
}
.apply {
height: 45px;
width: 130px;
text-align: center;
border: none;
transition: 0.25s;
background-color: #dd3b67;
color: #fff;
cursor: pointer;
display: inline-block;
box-shadow: 20px #000;
font-size: 1.3em;
position: relative;
&:hover {
transform: translateY(-0.10em);
}
&:before {
content: '';
background: linear-gradient(90deg, #ffb032 0%, #dd3b67 100%);
position: absolute;
width: 0%;
top: 0;
left: 0;
height: 100%;
transition: 0.3s linear;
z-index: -1;
color: #fff;
}
&:hover:before {
width: 100%;
}
&:active {
outline: none;
}
}