mirror of
https://github.com/mue/mue.git
synced 2026-07-09 05:34:20 +02:00
Add notes feature and improved navbar
Co-authored-by: Alex Sparkes <turbomarshmello@gmail.com>
This commit is contained in:
26
src/App.jsx
26
src/App.jsx
@@ -31,12 +31,22 @@ export default class App extends React.PureComponent {
|
||||
};
|
||||
}
|
||||
|
||||
// Render all the components
|
||||
render() {
|
||||
componentDidMount() {
|
||||
if (!localStorage.getItem('firstRun')) SettingsFunctions.setDefaultSettings();
|
||||
|
||||
const theme = localStorage.getItem('theme'); // Marketplace themes (WIP)
|
||||
if (theme) {
|
||||
const style = document.createElement('link');
|
||||
style.href = theme;
|
||||
style.rel = 'stylesheet';
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
}
|
||||
|
||||
// Render all the components
|
||||
render() {
|
||||
let modalClassList = 'Modal'; // Modal features
|
||||
// let tooltipClassList = 'tooltiptext';
|
||||
// let tooltipClassList = 'tooltiptext';
|
||||
if ((localStorage.getItem('brightnessTime') && new Date().getHours() > 18) || localStorage.getItem('darkTheme') === 'true') {
|
||||
modalClassList = 'Modal dark';
|
||||
// tooltipClassList = 'tooltiptext dark';
|
||||
@@ -46,21 +56,13 @@ export default class App extends React.PureComponent {
|
||||
const en = require('./translations/en.json'); // User language
|
||||
const language = merge(en, require(`./translations/${localStorage.getItem('language') || 'en'}.json`));
|
||||
|
||||
const theme = localStorage.getItem('theme'); // Marketplace themes (WIP)
|
||||
if (theme) {
|
||||
const style = document.createElement('link');
|
||||
style.href = theme;
|
||||
style.rel = 'stylesheet';
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Background/>
|
||||
<ToastContainer position='bottom-right' autoClose={2500} newestOnTop={true} closeOnClick rtl={false} pauseOnFocusLoss />
|
||||
<div id='center'>
|
||||
<Search language={language.search} />
|
||||
<Navbar settingsModalOpen={() => this.setState({ mainModal: true })} updateModalOpen={() => this.setState({ updateModal: true })} />
|
||||
<Navbar mainModalOpen={() => this.setState({ mainModal: true })} updateModalOpen={() => this.setState({ updateModal: true })} />
|
||||
<Greeting language={language.greeting} />
|
||||
<Clock/>
|
||||
<Quote language={language.toasts}/>
|
||||
|
||||
@@ -1,24 +1,39 @@
|
||||
import React from 'react';
|
||||
import RefreshIcon from '@material-ui/icons/Refresh';
|
||||
import Gear from '@material-ui/icons/Settings';
|
||||
import NewReleases from '@material-ui/icons/NewReleases';
|
||||
import RefreshIcon from '@material-ui/icons/RefreshRounded';
|
||||
import Gear from '@material-ui/icons/SettingsRounded';
|
||||
import NewReleases from '@material-ui/icons/NewReleasesRounded';
|
||||
import NotesIcon from '@material-ui/icons/AssignmentRounded';
|
||||
import Tooltip from '@material-ui/core/Tooltip';
|
||||
|
||||
const Notes = React.lazy(() => import('./widgets/Notes'));
|
||||
const renderLoader = () => <div></div>;
|
||||
|
||||
export default class Navbar extends React.PureComponent {
|
||||
render() {
|
||||
let refreshHTML = <div className='navbar2'><RefreshIcon className='refreshicon' onClick={() => window.location.reload()} /></div>;
|
||||
let refreshHTML = <RefreshIcon className='refreshicon topicons' onClick={() => window.location.reload()} />
|
||||
const refresh = localStorage.getItem('refresh');
|
||||
if (refresh === 'false') refreshHTML = '';
|
||||
|
||||
return (
|
||||
<div className='navbar-container'>
|
||||
<div className='navbar1'>
|
||||
<Gear className='settingsicon' onClick={this.props.settingsModalOpen} />
|
||||
<div className='notes'>
|
||||
<NotesIcon className='topicons' />
|
||||
<React.Suspense fallback={renderLoader()}>
|
||||
<Notes/>
|
||||
</React.Suspense>
|
||||
</div>
|
||||
{refreshHTML}
|
||||
<div className={refresh === 'false' ? 'navbar2' : 'navbar3'}>
|
||||
<NewReleases className='updateicon' onClick={this.props.updateModalOpen} />
|
||||
<Tooltip title='Update Patch Notes' placement='top'>
|
||||
<NewReleases className='refreshicon topicons' onClick={this.props.updateModalOpen} />
|
||||
</Tooltip>
|
||||
</div>
|
||||
<Tooltip title='Refresh Page'>
|
||||
{refreshHTML}
|
||||
</Tooltip>
|
||||
<Tooltip title='Settings' placement='top'>
|
||||
<Gear className='settings-icon topicons' onClick={this.props.mainModalOpen} />
|
||||
</Tooltip>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
46
src/components/widgets/Notes.jsx
Normal file
46
src/components/widgets/Notes.jsx
Normal file
@@ -0,0 +1,46 @@
|
||||
import React from 'react';
|
||||
import TextareaAutosize from '@material-ui/core/TextareaAutosize';
|
||||
import CopyIcon from '@material-ui/icons/FileCopyRounded';
|
||||
import Pin from './icons/Pin';
|
||||
import NotesIcon from '@material-ui/icons/AssignmentRounded';
|
||||
|
||||
export default class Notes extends React.PureComponent {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
this.state = {
|
||||
notes: localStorage.getItem('notes')
|
||||
};
|
||||
}
|
||||
|
||||
setNotes(e) {
|
||||
localStorage.setItem('notes', e.target.value);
|
||||
this.setState({ notes: e.target.value });
|
||||
};
|
||||
|
||||
pin() {
|
||||
const pinned = localStorage.getItem('notesPinned');
|
||||
document.getElementById('noteContainer').classList.toggle('visibilityshow');
|
||||
if (pinned === 'true') localStorage.setItem('notesPinned', false);
|
||||
else localStorage.setItem('notesPinned', true);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (localStorage.getItem('notesPinned') === 'true') document.getElementById('noteContainer').classList.toggle('visibilityshow');
|
||||
}
|
||||
|
||||
render() {
|
||||
const copyNotes = () => navigator.clipboard.writeText(this.state.notes);
|
||||
|
||||
return (
|
||||
<span id='noteContainer' className='notescontainer'>
|
||||
<div className='topbarnotes'>
|
||||
<NotesIcon/>
|
||||
<h3>Notes</h3>
|
||||
</div>
|
||||
<TextareaAutosize rowsMax={50} placeholder='Enter Notes' value={this.state.notes} onChange={this.setNotes}/>
|
||||
<button onClick={this.pin} className='pinNote'><Pin/></button>
|
||||
<button onClick={copyNotes} className='saveNote'><CopyIcon/></button>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}
|
||||
27
src/components/widgets/icons/Pin.jsx
Normal file
27
src/components/widgets/icons/Pin.jsx
Normal file
@@ -0,0 +1,27 @@
|
||||
// License for original pin SVG below
|
||||
/*
|
||||
Copyright 2020 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
export default class Pin extends React.PureComponent {
|
||||
render() {
|
||||
return <svg xmlns='http://www.w3.org/2000/svg' enableBackground='new 0 0 24 24' viewBox='0 0 24 24' fill='black' width='18px' height='18px'>
|
||||
<g><rect fill='none' height='24' width='24'/></g>
|
||||
<g><path d='M16,9V4l1,0c0.55,0,1-0.45,1-1v0c0-0.55-0.45-1-1-1H7C6.45,2,6,2.45,6,3v0 c0,0.55,0.45,1,1,1l1,0v5c0,1.66-1.34,3-3,3h0v2h5.97v7l1,1l1-1v-7H19v-2h0C17.34,12,16,10.66,16,9z' fillRule='evenodd'/></g>
|
||||
</svg>;
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
text-align: center;
|
||||
border: none;
|
||||
transition: ease 0.33s;
|
||||
color: map-get($theme-colours, "main");
|
||||
color: map-get($theme-colours, 'main');
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
@@ -23,25 +23,25 @@
|
||||
.apply {
|
||||
@extend %settingsButton;
|
||||
margin-right: 20px;
|
||||
background-color: map-get($button-colours, "confirm");
|
||||
border: 2px solid map-get($button-colours, "confirm");
|
||||
background-color: map-get($button-colours, 'confirm');
|
||||
border: 2px solid map-get($button-colours, 'confirm');
|
||||
|
||||
&:hover {
|
||||
border: 2px solid map-get($button-colours, "confirm");
|
||||
color: map-get($button-colours, "confirm");
|
||||
border: 2px solid map-get($button-colours, 'confirm');
|
||||
color: map-get($button-colours, 'confirm');
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
|
||||
.reset {
|
||||
@extend %settingsButton;
|
||||
background-color: map-get($button-colours, "reset");
|
||||
border: 2px solid map-get($button-colours, "reset");
|
||||
background-color: map-get($button-colours, 'reset');
|
||||
border: 2px solid map-get($button-colours, 'reset');
|
||||
margin-left: 5px;
|
||||
|
||||
&:hover {
|
||||
border: 2px solid map-get($button-colours, "reset");
|
||||
color: map-get($button-colours, "reset");
|
||||
border: 2px solid map-get($button-colours, 'reset');
|
||||
color: map-get($button-colours, 'reset');
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
@@ -49,24 +49,24 @@
|
||||
.close {
|
||||
@extend %settingsButton;
|
||||
padding: 10px 50px 10px 50px;
|
||||
background-color: map-get($button-colours, "other");
|
||||
border: 2px solid map-get($button-colours, "other");
|
||||
background-color: map-get($button-colours, 'other');
|
||||
border: 2px solid map-get($button-colours, 'other');
|
||||
|
||||
&:hover {
|
||||
color: map-get($button-colours, "other");
|
||||
border: 2px solid map-get($button-colours, "other");
|
||||
color: map-get($button-colours, 'other');
|
||||
border: 2px solid map-get($button-colours, 'other');
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
|
||||
.add {
|
||||
@extend %settingsButton;
|
||||
background-color: map-get($button-colours, "other");
|
||||
border: 2px solid map-get($button-colours, "other");
|
||||
background-color: map-get($button-colours, 'other');
|
||||
border: 2px solid map-get($button-colours, 'other');
|
||||
|
||||
&:hover {
|
||||
color: map-get($button-colours, "other");
|
||||
border: 2px solid map-get($button-colours, "other");
|
||||
color: map-get($button-colours, 'other');
|
||||
border: 2px solid map-get($button-colours, 'other');
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
@@ -76,7 +76,7 @@
|
||||
border-radius: 50%;
|
||||
background: none;
|
||||
border: 2px solid rgba(0,0,0,0);
|
||||
color: map-get($button-colours, "reset");
|
||||
color: map-get($button-colours, 'reset');
|
||||
text-align: center;
|
||||
vertical-align: sub;
|
||||
height: 60px;
|
||||
@@ -85,8 +85,8 @@
|
||||
font-size: 30px;
|
||||
|
||||
&:hover {
|
||||
color: map-get($button-colours, "background");
|
||||
border: 2px solid map-get($button-colours, "reset");
|
||||
color: map-get($button-colours, 'background');
|
||||
border: 2px solid map-get($button-colours, 'reset');
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
@@ -95,13 +95,13 @@
|
||||
.uploadbg,
|
||||
.import {
|
||||
@extend %settingsButton;
|
||||
background-color: map-get($button-colours, "other");
|
||||
border: 2px solid map-get($button-colours, "other");
|
||||
color: map-get($theme-colours, "main");
|
||||
background-color: map-get($button-colours, 'other');
|
||||
border: 2px solid map-get($button-colours, 'other');
|
||||
color: map-get($theme-colours, 'main');
|
||||
|
||||
&:hover {
|
||||
color: map-get($button-colours, "other");
|
||||
border: 2px solid map-get($button-colours, "other");
|
||||
color: map-get($button-colours, 'other');
|
||||
border: 2px solid map-get($button-colours, 'other');
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
@@ -128,19 +128,19 @@
|
||||
|
||||
&:hover {
|
||||
background: #2d3436;
|
||||
color: map-get($theme-colours, "main");;
|
||||
color: map-get($theme-colours, 'main');;
|
||||
border: 2px solid #2d3436;
|
||||
}
|
||||
}
|
||||
|
||||
.dark .storebutton {
|
||||
border: 2px solid map-get($theme-colours, "main");
|
||||
color: map-get($theme-colours, "main");
|
||||
border: 2px solid map-get($theme-colours, 'main');
|
||||
color: map-get($theme-colours, 'main');
|
||||
|
||||
&:hover {
|
||||
background: map-get($theme-colours, "main");
|
||||
background: map-get($theme-colours, 'main');
|
||||
color: #2d3436;
|
||||
border: 2px solid map-get($theme-colours, "main");
|
||||
border: 2px solid map-get($theme-colours, 'main');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@
|
||||
|
||||
&:hover {
|
||||
background: #ff4757;
|
||||
color: map-get($theme-colours, "main");;
|
||||
color: map-get($theme-colours, 'main');;
|
||||
border: 2px solid #ff4757;
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@
|
||||
.stop {
|
||||
outline: none;
|
||||
border-image-slice: 1;
|
||||
border-image-source: map-get($theme-colours, "gradient");
|
||||
border-image-source: map-get($theme-colours, 'gradient');
|
||||
font-size: 1.2em;
|
||||
padding-left: 7px;
|
||||
vertical-align: middle;
|
||||
@@ -200,4 +200,48 @@ input[type=number]::-webkit-inner-spin-button,
|
||||
input[type=number]::-webkit-outer-spin-button {
|
||||
opacity: 1;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.pinNote {
|
||||
@extend %settingsButton;
|
||||
background-color: map-get($button-colours, 'confirm');
|
||||
border: 2px solid map-get($button-colours, 'confirm');
|
||||
color: map-get($theme-colours, 'main');
|
||||
transition: 0s;
|
||||
|
||||
&:hover {
|
||||
color: map-get($button-colours, 'confirm');
|
||||
border: 2px solid map-get($button-colours, 'confirm');
|
||||
background: none;
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: currentColor;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
display: inline-block;
|
||||
font-size: 1.5rem;
|
||||
transition: fill 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
|
||||
flex-shrink: 0;
|
||||
user-select: none;
|
||||
}
|
||||
}
|
||||
|
||||
.saveNote {
|
||||
@extend %settingsButton;
|
||||
background-color: map-get($button-colours, 'other');
|
||||
border: 2px solid map-get($button-colours, 'other');
|
||||
color: map-get($theme-colours, 'main');
|
||||
transition: 0s;
|
||||
|
||||
&:hover {
|
||||
color: map-get($button-colours, 'other');
|
||||
border: 2px solid map-get($button-colours, 'other');
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
|
||||
.saveNote {
|
||||
display: inline;
|
||||
margin: 5px;
|
||||
}
|
||||
@@ -1,44 +1,150 @@
|
||||
%navbar {
|
||||
.navbar-container {
|
||||
position: absolute;
|
||||
text-align: right;
|
||||
min-width: 50px;
|
||||
-webkit-filter: drop-shadow(0 0 6px rgba(0, 0, 0, 0.3));
|
||||
filter: drop-shadow(0 0 6px rgba(0, 0, 0, 0.3));
|
||||
top: 20px;
|
||||
top: 1rem;
|
||||
right: 1rem;
|
||||
|
||||
div {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
img {
|
||||
height: 1em;
|
||||
width: auto;
|
||||
margin: 0.5rem;
|
||||
}
|
||||
|
||||
svg.topicons {
|
||||
color: map-get($theme-colours, 'main-text-color');
|
||||
-webkit-font-smoothing: subpixel-antialiased;
|
||||
font-size: 1em;
|
||||
display: inline;
|
||||
margin: 0.5rem;
|
||||
filter: drop-shadow(0 0 6px rgba(0, 0, 0, 0.3));
|
||||
cursor: pointer;
|
||||
transition: .2s ease;
|
||||
|
||||
&:hover {
|
||||
color: map-get($theme-colours, 'main-text-color');
|
||||
transform: translateZ(0);
|
||||
transform: scale(1.3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.navbar-container-bottom {
|
||||
position: absolute;
|
||||
bottom: 1rem;
|
||||
right: 1rem;
|
||||
|
||||
div {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
img {
|
||||
height: 1em;
|
||||
width: auto;
|
||||
margin: 0.5rem;
|
||||
}
|
||||
|
||||
svg.topicons {
|
||||
color: map-get($theme-colours, 'main-text-color');
|
||||
-webkit-font-smoothing: subpixel-antialiased;
|
||||
font-size: 1em;
|
||||
display: inline;
|
||||
margin: 0.5rem;
|
||||
filter: drop-shadow(0 0 6px rgba(0, 0, 0, 0.3));
|
||||
cursor: pointer;
|
||||
transition: .2s ease;
|
||||
|
||||
&:hover {
|
||||
color: map-get($theme-colours, 'main-text-color');
|
||||
transform: translateZ(0);
|
||||
transform: scale(1.3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.notes {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
|
||||
h3 {
|
||||
text-shadow: none;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.notes .notescontainer {
|
||||
text-align: center;
|
||||
padding: 15px;
|
||||
visibility: hidden;
|
||||
background-color: #fff;
|
||||
color: #000;
|
||||
text-align: center;
|
||||
border-radius: 12px;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 80%;
|
||||
left: 50%;
|
||||
margin-left: -125px;
|
||||
|
||||
input[type=text] {
|
||||
border: none;
|
||||
color: #2d3436;
|
||||
}
|
||||
|
||||
svg,
|
||||
input[type=text] {
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
svg {
|
||||
transition: ease 0.2s;
|
||||
font-size: calc(10px + 1.5vmin) !important;
|
||||
float: left;
|
||||
}
|
||||
|
||||
::placeholder {
|
||||
color: #636e72;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.navbar1 {
|
||||
@extend %navbar;
|
||||
right: 20px;
|
||||
|
||||
svg { // apparently fixes shaking issue that only happens to settings icon
|
||||
-webkit-backface-visibility: hidden;
|
||||
-webkit-transform: translateZ(0) scale(1, 1);
|
||||
backface-visibility: hidden;
|
||||
transform: translateZ(0) scale(1, 1);
|
||||
.notes:hover .notescontainer {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
textarea {
|
||||
overflow: none;
|
||||
border: none;
|
||||
outline: none;
|
||||
width: 200px;
|
||||
resize: none;
|
||||
height: 100px;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.noteIcon {
|
||||
display: inline;
|
||||
font-size: 1em;
|
||||
float: none;
|
||||
}
|
||||
|
||||
.topbarnotes {
|
||||
text-align: center;
|
||||
|
||||
svg {
|
||||
font-size: 48px;
|
||||
float: left !important;
|
||||
padding: 9px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 48px;
|
||||
float: right;
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.navbar2 {
|
||||
@extend %navbar;
|
||||
right: 60px;
|
||||
}
|
||||
|
||||
.navbar3 {
|
||||
@extend %navbar;
|
||||
right: 100px;
|
||||
}
|
||||
|
||||
.refreshicon, .settingsicon, .updateicon {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
transform: scale(1.1);
|
||||
color: map-get($theme-colours, "main");;
|
||||
}
|
||||
.visibilityshow {
|
||||
visibility: visible !important;
|
||||
}
|
||||
Reference in New Issue
Block a user