From 93edb489f775d5abf40b511a6748ad7494b5c015 Mon Sep 17 00:00:00 2001 From: David Ralph Date: Sat, 17 Oct 2020 18:46:27 +0100 Subject: [PATCH] Add notes feature and improved navbar Co-authored-by: Alex Sparkes --- src/App.jsx | 26 ++-- src/components/Navbar.jsx | 33 +++-- src/components/widgets/Notes.jsx | 46 +++++++ src/components/widgets/icons/Pin.jsx | 27 +++++ src/scss/modules/_buttons.scss | 108 ++++++++++++----- src/scss/modules/_navbar.scss | 172 ++++++++++++++++++++++----- 6 files changed, 326 insertions(+), 86 deletions(-) create mode 100644 src/components/widgets/Notes.jsx create mode 100644 src/components/widgets/icons/Pin.jsx diff --git a/src/App.jsx b/src/App.jsx index f1e92937..3da24d09 100644 --- a/src/App.jsx +++ b/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 (
- this.setState({ mainModal: true })} updateModalOpen={() => this.setState({ updateModal: true })} /> + this.setState({ mainModal: true })} updateModalOpen={() => this.setState({ updateModal: true })} /> diff --git a/src/components/Navbar.jsx b/src/components/Navbar.jsx index d3e666c3..ff8ef1d2 100644 --- a/src/components/Navbar.jsx +++ b/src/components/Navbar.jsx @@ -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 = () =>
; export default class Navbar extends React.PureComponent { render() { - let refreshHTML =
window.location.reload()} />
; + let refreshHTML = window.location.reload()} /> const refresh = localStorage.getItem('refresh'); if (refresh === 'false') refreshHTML = ''; return (
-
- +
+ + + +
- {refreshHTML}
- + + +
+ + {refreshHTML} + + + +
); } -} \ No newline at end of file +} diff --git a/src/components/widgets/Notes.jsx b/src/components/widgets/Notes.jsx new file mode 100644 index 00000000..41b91f28 --- /dev/null +++ b/src/components/widgets/Notes.jsx @@ -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 ( + +
+ +

Notes

+
+ + + +
+ ); + } +} diff --git a/src/components/widgets/icons/Pin.jsx b/src/components/widgets/icons/Pin.jsx new file mode 100644 index 00000000..70cd7d8d --- /dev/null +++ b/src/components/widgets/icons/Pin.jsx @@ -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 + + + ; + } +} diff --git a/src/scss/modules/_buttons.scss b/src/scss/modules/_buttons.scss index c0e3c5e7..e9b66edf 100644 --- a/src/scss/modules/_buttons.scss +++ b/src/scss/modules/_buttons.scss @@ -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; } \ No newline at end of file diff --git a/src/scss/modules/_navbar.scss b/src/scss/modules/_navbar.scss index 4e74f97f..f8884cea 100644 --- a/src/scss/modules/_navbar.scss +++ b/src/scss/modules/_navbar.scss @@ -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; } \ No newline at end of file