mirror of
https://github.com/mue/mue.git
synced 2026-07-28 19:21:03 +02:00
Settings! (Almost finished)
Co-authored-by: Alex Sparkes <turbomarshmello@gmail.com> Co-authored-by: Wessel Tip <discord@go2it.eu>
This commit is contained in:
@@ -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",
|
||||||
|
|||||||
43
src/App.jsx
43
src/App.jsx
@@ -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>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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>,
|
||||||
];
|
];
|
||||||
|
|||||||
81
src/components/Settings.jsx
Normal file
81
src/components/Settings.jsx
Normal 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}>×</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>;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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/modal';
|
||||||
|
@import 'modules/settings';
|
||||||
@import 'modules/miscellaneous';
|
@import 'modules/miscellaneous';
|
||||||
74
src/scss/modules/_modal.scss
Normal file
74
src/scss/modules/_modal.scss
Normal 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%;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
125
src/scss/modules/_settings.scss
Normal file
125
src/scss/modules/_settings.scss
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user