refactor: cleanup and remove unused stuff

This commit is contained in:
David Ralph 2022-04-16 19:25:42 +01:00
parent 987a7eda6e
commit 4691ccf166
60 changed files with 414 additions and 491 deletions

View File

@ -1,6 +1,3 @@
{ {
"extends": [ "extends": ["stylelint-config-standard-scss", "stylelint-config-prettier-scss"]
"stylelint-config-standard-scss",
"stylelint-config-prettier-scss"
]
} }

View File

@ -4,7 +4,7 @@
"default_locale": "en", "default_locale": "en",
"name": "__MSG_name__", "name": "__MSG_name__",
"description": "__MSG_description__", "description": "__MSG_description__",
"version": "6.0.5", "version": "7.0.0",
"homepage_url": "https://muetab.com", "homepage_url": "https://muetab.com",
"browser_action": { "browser_action": {
"default_icon": "icons/128x128.png" "default_icon": "icons/128x128.png"

View File

@ -2,7 +2,7 @@
"manifest_version": 2, "manifest_version": 2,
"name": "Mue", "name": "Mue",
"description": "Fast, open and free-to-use new tab page for modern browsers.", "description": "Fast, open and free-to-use new tab page for modern browsers.",
"version": "6.0.5", "version": "7.0.0",
"homepage_url": "https://muetab.com", "homepage_url": "https://muetab.com",
"browser_action": { "browser_action": {
"default_icon": "icons/128x128.png" "default_icon": "icons/128x128.png"

View File

@ -9,7 +9,7 @@
"homepage": "https://muetab.com", "homepage": "https://muetab.com",
"bugs": "https://github.com/mue/mue/issues/new?assignees=&labels=bug&template=bug-report.md&title=%5BBUG%5D", "bugs": "https://github.com/mue/mue/issues/new?assignees=&labels=bug&template=bug-report.md&title=%5BBUG%5D",
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"version": "6.0.5", "version": "7.0.0",
"dependencies": { "dependencies": {
"@eartharoid/i18n": "1.0.2", "@eartharoid/i18n": "1.0.2",
"@emotion/react": "^11.9.0", "@emotion/react": "^11.9.0",

View File

@ -1,52 +1,52 @@
import variables from 'modules/variables'; import variables from 'modules/variables';
import { PureComponent } from 'react'; import { PureComponent } from 'react';
import { ToastContainer } from 'react-toastify'; import { ToastContainer } from 'react-toastify';
import Background from 'components/widgets/background/Background'; import Background from 'components/widgets/background/Background';
import Widgets from 'components/widgets/Widgets'; import Widgets from 'components/widgets/Widgets';
import Modals from 'components/modals/Modals'; import Modals from 'components/modals/Modals';
import { loadSettings, moveSettings } from 'modules/helpers/settings'; import { loadSettings, moveSettings } from 'modules/helpers/settings';
import EventBus from 'modules/helpers/eventbus'; import EventBus from 'modules/helpers/eventbus';
export default class App extends PureComponent { export default class App extends PureComponent {
componentDidMount() { componentDidMount() {
// 4.0 -> 5.0 (the key below is only on 5.0) // 4.0 -> 5.0 (the key below is only on 5.0)
// now featuring 5.0 -> 5.1 // now featuring 5.0 -> 5.1
// the firstRun check was moved here because the old function was useless // the firstRun check was moved here because the old function was useless
if (!localStorage.getItem('firstRun') || !localStorage.getItem('stats')) { if (!localStorage.getItem('firstRun') || !localStorage.getItem('stats')) {
moveSettings(); moveSettings();
window.location.reload(); window.location.reload();
} }
loadSettings(); loadSettings();
EventBus.on('refresh', (data) => { EventBus.on('refresh', (data) => {
if (data === 'other') { if (data === 'other') {
loadSettings(true); loadSettings(true);
} }
}); });
variables.stats.tabLoad(); variables.stats.tabLoad();
} }
render() { render() {
return ( return (
<> <>
{localStorage.getItem('background') === 'true' ? <Background /> : null} {localStorage.getItem('background') === 'true' ? <Background /> : null}
<ToastContainer <ToastContainer
position="bottom-right" position="bottom-right"
autoClose={localStorage.getItem('toastDisplayTime') || 2500} autoClose={localStorage.getItem('toastDisplayTime') || 2500}
newestOnTop={true} newestOnTop={true}
closeOnClick closeOnClick
pauseOnFocusLoss pauseOnFocusLoss
/> />
<div id="center"> <div id="center">
<Widgets /> <Widgets />
<Modals /> <Modals />
</div> </div>
</> </>
); );
} }
} }

View File

@ -1,7 +1,5 @@
import { PureComponent } from 'react'; import { PureComponent } from 'react';
import { InputBase } from '@mui/material';
import EventBus from 'modules/helpers/eventbus'; import EventBus from 'modules/helpers/eventbus';
import './autocomplete.scss'; import './autocomplete.scss';

View File

@ -40,5 +40,5 @@
} }
.micActive { .micActive {
box-shadow: 0px 0px 50px 9px #E74C3C !important; box-shadow: 0px 0px 50px 9px #e74c3c !important;
} }

View File

@ -1,5 +1,4 @@
import variables from 'modules/variables'; import variables from 'modules/variables';
import { MdArrowForwardIos } from 'react-icons/md';
import './preview.scss'; import './preview.scss';
export default function Preview(props) { export default function Preview(props) {

View File

@ -68,6 +68,9 @@ export default function ShareModal({ modalClose, data }) {
<MdEmail /> <MdEmail />
</button> </button>
</Tooltip> </Tooltip>
{/* i think that wechat has no actual share function outside of qrcodes, as the only example of a share to wechat button i've seen used this api
* this requires some investigating before we deploy to production
*/ }
<Tooltip title="WeChat"> <Tooltip title="WeChat">
<button <button
onClick={() => onClick={() =>

View File

@ -1,43 +0,0 @@
import variables from 'modules/variables';
export default function Collection({ items, toggleFunction }) {
return [
<div className="collection starWars">
<div className="content">
<div className="tags">
<div className="tag">
<span>Star Wars</span>
</div>
</div>
<span className="title">Star Wars Collection</span>
<span className="subtitle">
A Collection of stuff inspired by the film franchise star wars..
</span>
<button>Explore Collection</button>
</div>
</div>,
<div className="items">
{items.map((item) => (
<div className="item" onClick={() => toggleFunction(item)} key={item.name}>
<img
alt="icon"
draggable="false"
src={variables.constants.DDG_IMAGE_PROXY + item.icon_url}
/>
<div className="card-details">
<span className="card-title">{item.display_name || item.name}</span>
<span className="card-subtitle">{item.author}</span>
<div className="tags">
<div className="tag">
<span>{item.author}</span>
</div>
<div className="moreTag">
<span>1</span>
</div>
</div>
</div>
</div>
))}
</div>,
];
}

View File

@ -4,7 +4,6 @@ import Tooltip from '../../../helpers/tooltip/Tooltip';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import { import {
MdArrowBack, MdArrowBack,
MdFavoriteBorder,
MdIosShare, MdIosShare,
MdFlag, MdFlag,
MdWarning, MdWarning,
@ -20,7 +19,6 @@ import Modal from 'react-modal';
import { install, uninstall } from 'modules/helpers/marketplace'; import { install, uninstall } from 'modules/helpers/marketplace';
import Lightbox from './Lightbox';
import ShareModal from '../../../helpers/sharemodal/ShareModal'; import ShareModal from '../../../helpers/sharemodal/ShareModal';
export default class Item extends PureComponent { export default class Item extends PureComponent {
@ -111,7 +109,7 @@ export default class Item extends PureComponent {
</Modal> </Modal>
<div className="flexTopMarketplace"> <div className="flexTopMarketplace">
<div className="returnButton"> <div className="returnButton">
<Tooltip title="back" key="cheese"> <Tooltip title="back" key="backArrow">
<MdArrowBack className="backArrow" onClick={this.props.toggleFunction} /> <MdArrowBack className="backArrow" onClick={this.props.toggleFunction} />
</Tooltip> </Tooltip>
</div> </div>
@ -197,7 +195,7 @@ export default class Item extends PureComponent {
<MdTranslate /> <MdTranslate />
<div className="text"> <div className="text">
<span className="header">Language</span> <span className="header">Language</span>
<span>English</span> <span>{this.props.data.data.language}</span>
</div> </div>
</div> </div>
) : null} ) : null}
@ -218,10 +216,10 @@ export default class Item extends PureComponent {
/> />
{this.props.button} {this.props.button}
<div className="iconButtons"> <div className="iconButtons">
<Tooltip title="Share" key="cheese"> <Tooltip title="Share" key="share">
<MdIosShare onClick={() => this.setState({ shareModal: true })} /> <MdIosShare onClick={() => this.setState({ shareModal: true })} />
</Tooltip> </Tooltip>
<Tooltip title="Report" key="cheese"> <Tooltip title="Report" key="report">
<MdFlag <MdFlag
onClick={() => onClick={() =>
window.open( window.open(

View File

@ -89,7 +89,7 @@ export default class Added extends PureComponent {
} }
this.setState({ this.setState({
installed: installed, installed,
}); });
if (sendEvent) { if (sendEvent) {

View File

@ -1,3 +1,7 @@
// warning: this file is even worse than Background.jsx
// if anyone wants to rewrite it to be actually decent, feel free
// otherwise it will be cleaned up probably when alex asks me to add something here :(
// - david
import variables from 'modules/variables'; import variables from 'modules/variables';
import { PureComponent } from 'react'; import { PureComponent } from 'react';
import { import {
@ -303,7 +307,10 @@ export default class Create extends PureComponent {
onInput={(e) => setMetadata(e.target.value, 'screenshot_url')} onInput={(e) => setMetadata(e.target.value, 'screenshot_url')}
/> />
</SettingsItem> </SettingsItem>
<SettingsItem title={getMessage('modals.main.addons.create.metadata.description')} final={true}> <SettingsItem
title={getMessage('modals.main.addons.create.metadata.description')}
final={true}
>
<TextField <TextField
label={getMessage('modals.main.addons.create.metadata.description')} label={getMessage('modals.main.addons.create.metadata.description')}
varient="outlined" varient="outlined"

View File

@ -7,7 +7,6 @@
@import 'modules/scrollbars'; @import 'modules/scrollbars';
@import 'settings/main'; @import 'settings/main';
@import 'settings/buttons';
@import 'marketplace/main'; @import 'marketplace/main';

View File

@ -1,8 +1,9 @@
// this file is too long
@import 'modules/item'; @import 'modules/item';
@import 'modules/buttons'; @import 'modules/buttons';
@import 'modules/featured'; @import 'modules/featured';
@import 'modules/lightbox'; @import 'modules/lightbox';
@import '../../../../../scss/variables'; @import 'scss/variables';
.items { .items {
display: flex; display: flex;
@ -188,11 +189,13 @@
align-items: center; align-items: center;
gap: 15px; gap: 15px;
min-width: 100px; min-width: 100px;
@include themed() { @include themed() {
padding: 45px; padding: 45px;
border-radius: t($borderRadius); border-radius: t($borderRadius);
background: t($modal-sidebar); background: t($modal-sidebar);
box-shadow: 0 0 0 4px t($modal-sidebarActive); box-shadow: 0 0 0 4px t($modal-sidebarActive);
svg { svg {
font-size: 50px; font-size: 50px;
color: t($subColor); color: t($subColor);
@ -288,6 +291,7 @@ p.author {
} }
} }
// reminder to remove this url
.collection { .collection {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
@ -296,22 +300,27 @@ p.author {
background-image: linear-gradient(to left, transparent, #000), background-image: linear-gradient(to left, transparent, #000),
url('https://www.gonefullgeek.com/wp-content/uploads/2017/09/RDR2-Banner.jpg'); url('https://www.gonefullgeek.com/wp-content/uploads/2017/09/RDR2-Banner.jpg');
align-items: center; align-items: center;
@include themed() { @include themed() {
box-shadow: 0 0 0 4px t($modal-sidebarActive); box-shadow: 0 0 0 4px t($modal-sidebarActive);
border-radius: t($borderRadius); border-radius: t($borderRadius);
} }
.content { .content {
display: flex; display: flex;
flex-flow: column; flex-flow: column;
gap: 15px; gap: 15px;
max-width: 250px; max-width: 250px;
.title { .title {
color: #fff !important; color: #fff !important;
} }
.subtitle { .subtitle {
color: #ccc !important; color: #ccc !important;
} }
} }
.items { .items {
justify-content: center; justify-content: center;
} }
@ -321,16 +330,19 @@ p.author {
button { button {
padding: 0 15px 0 15px; padding: 0 15px 0 15px;
} }
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
padding: 15px; padding: 15px;
margin-top: 15px; margin-top: 15px;
align-items: center; align-items: center;
@include themed() { @include themed() {
box-shadow: 0 0 0 4px t($modal-sidebarActive); box-shadow: 0 0 0 4px t($modal-sidebarActive);
border-radius: t($borderRadius); border-radius: t($borderRadius);
background: t($modal-sidebar); background: t($modal-sidebar);
} }
.content { .content {
display: flex; display: flex;
flex-flow: column; flex-flow: column;
@ -346,16 +358,10 @@ p.author {
flex-flow: column; flex-flow: column;
gap: 15px; gap: 15px;
padding: 15px; padding: 15px;
@include themed() { @include themed() {
box-shadow: 0 0 0 4px t($modal-sidebarActive); box-shadow: 0 0 0 4px t($modal-sidebarActive);
border-radius: t($borderRadius); border-radius: t($borderRadius);
} }
} }
.starWars {
background-image: linear-gradient(to left, transparent, #000),
url(https://www.broadway.org.uk/sites/default/files/styles/banner_crop/public/2019-10/star-wars-the-rise-of-skywalker-banner-min.jpg?h=639d4ef1&itok=z4KZ-3Tt);
background-size: cover !important;
background-repeat: no-repeat !important;
background-position: center !important;
}

View File

@ -19,36 +19,44 @@ p.description {
flex-wrap: wrap; flex-wrap: wrap;
width: calc(100% - 30px); width: calc(100% - 30px);
gap: 15px; gap: 15px;
.items { .items {
margin-top: 0 !important; margin-top: 0 !important;
} }
.item { .item {
flex: 1 0 40% !important; flex: 1 0 40% !important;
} }
@include themed() { @include themed() {
background: t($modal-sidebar); background: t($modal-sidebar);
box-shadow: 0 0 0 4px t($modal-sidebarActive); box-shadow: 0 0 0 4px t($modal-sidebarActive);
border-radius: t($borderRadius); border-radius: t($borderRadius);
padding: 15px; padding: 15px;
.infoItem { .infoItem {
display: flex; display: flex;
flex-flow: row; flex-flow: row;
align-items: center; align-items: center;
gap: 15px; gap: 15px;
flex: 1 0 44%; flex: 1 0 44%;
svg { svg {
font-size: 25px; font-size: 25px;
color: t($subColor); color: t($subColor);
} }
.text { .text {
display: flex; display: flex;
flex-flow: column; flex-flow: column;
} }
} }
.header { .header {
text-transform: uppercase; text-transform: uppercase;
color: t($subColor); color: t($subColor);
} }
span { span {
color: t($color); color: t($color);
} }
@ -58,6 +66,7 @@ p.description {
.itemTitle { .itemTitle {
font-size: 38px; font-size: 38px;
font-weight: 600; font-weight: 600;
@include themed() { @include themed() {
color: t($color); color: t($color);
} }
@ -75,6 +84,7 @@ p.description {
gap: 5px; gap: 5px;
transition: 0.5s; transition: 0.5s;
cursor: pointer; cursor: pointer;
@include themed() { @include themed() {
&:hover { &:hover {
color: t($subColor); color: t($subColor);

View File

@ -1 +0,0 @@
@import 'scss/modules/buttons';

View File

@ -7,8 +7,6 @@ import { BiDonateHeart } from 'react-icons/bi';
import Tooltip from 'components/helpers/tooltip/Tooltip'; import Tooltip from 'components/helpers/tooltip/Tooltip';
import SettingsItem from '../SettingsItem';
import other_contributors from 'modules/other_contributors.json'; import other_contributors from 'modules/other_contributors.json';
export default class About extends PureComponent { export default class About extends PureComponent {

View File

@ -10,7 +10,6 @@ import {
import { exportSettings, importSettings } from 'modules/helpers/settings/modals'; import { exportSettings, importSettings } from 'modules/helpers/settings/modals';
import Checkbox from '../Checkbox';
import FileUpload from '../FileUpload'; import FileUpload from '../FileUpload';
import Text from '../Text'; import Text from '../Text';
import Switch from '../Switch'; import Switch from '../Switch';
@ -69,12 +68,11 @@ export default class AdvancedSettings extends PureComponent {
</div> </div>
</div> </div>
) : null} ) : null}
<SettingsItem title={getMessage('modals.main.settings.sections.advanced.timezone.title')} subtitle='Choose a timezone from a list of hundreds instead of the automatic default.'> <SettingsItem
<Dropdown title={getMessage('modals.main.settings.sections.advanced.timezone.title')}
name="timezone" subtitle="Choose a timezone from a list of hundreds instead of the automatic default."
category="timezone" >
manual={true} <Dropdown name="timezone" category="timezone" manual={true}>
>
<MenuItem value="auto"> <MenuItem value="auto">
{getMessage('modals.main.settings.sections.advanced.timezone.automatic')} {getMessage('modals.main.settings.sections.advanced.timezone.automatic')}
</MenuItem> </MenuItem>
@ -86,11 +84,7 @@ export default class AdvancedSettings extends PureComponent {
</Dropdown> </Dropdown>
</SettingsItem> </SettingsItem>
<SettingsItem title={getMessage('modals.main.settings.sections.advanced.tab_name')}> <SettingsItem title={getMessage('modals.main.settings.sections.advanced.tab_name')}>
<Text <Text name="tabName" default={getMessage('tabname')} category="other" />
name="tabName"
default={getMessage('tabname')}
category="other"
/>
</SettingsItem> </SettingsItem>
<FileUpload <FileUpload
id="file-input" id="file-input"

View File

@ -12,32 +12,6 @@ import { values } from 'modules/helpers/settings/modals';
export default function AppearanceSettings() { export default function AppearanceSettings() {
const getMessage = (text) => variables.language.getMessage(variables.languagecode, text); const getMessage = (text) => variables.language.getMessage(variables.languagecode, text);
const themeOptions = [
{
name: getMessage('modals.main.settings.sections.appearance.theme.auto'),
value: 'auto',
},
{
name: getMessage('modals.main.settings.sections.appearance.theme.light'),
value: 'light',
},
{
name: getMessage('modals.main.settings.sections.appearance.theme.dark'),
value: 'dark',
},
];
const styleOptions = [
{
name: 'Legacy',
value: 'legacy',
},
{
name: 'New',
value: 'new',
},
];
return ( return (
<> <>
<span className="mainTitle"> <span className="mainTitle">
@ -51,7 +25,24 @@ export default function AppearanceSettings() {
<span className="subtitle">subtitle</span> <span className="subtitle">subtitle</span>
</div> </div>
<div className="action"> <div className="action">
<Radio name="theme" options={themeOptions} category="other" /> <Radio
name="theme"
options={[
{
name: getMessage('modals.main.settings.sections.appearance.theme.auto'),
value: 'auto',
},
{
name: getMessage('modals.main.settings.sections.appearance.theme.light'),
value: 'light',
},
{
name: getMessage('modals.main.settings.sections.appearance.theme.dark'),
value: 'dark',
},
]}
category="other"
/>
</div> </div>
</div> </div>
<div className="settingsRow"> <div className="settingsRow">
@ -125,7 +116,20 @@ export default function AppearanceSettings() {
title="Widget Style" title="Widget Style"
subtitle="Choose between the two styles, legacy (enabled for pre 7.0 users) and our slick modern styling." subtitle="Choose between the two styles, legacy (enabled for pre 7.0 users) and our slick modern styling."
> >
<Radio name="widgetStyle" options={styleOptions} category="widgets" /> <Radio
name="widgetStyle"
options={[
{
name: 'Legacy',
value: 'legacy',
},
{
name: 'New',
value: 'new',
},
]}
category="widgets"
/>
</SettingsItem> </SettingsItem>
{/*<h3>{getMessage('modals.main.settings.sections.appearance.accessibility.title')}</h3> {/*<h3>{getMessage('modals.main.settings.sections.appearance.accessibility.title')}</h3>

View File

@ -2,7 +2,7 @@ import variables from 'modules/variables';
import { PureComponent } from 'react'; import { PureComponent } from 'react';
import { MdCancel, MdAdd } from 'react-icons/md'; import { MdCancel, MdAdd } from 'react-icons/md';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import { TextField, TextareaAutosize } from '@mui/material'; import { TextareaAutosize } from '@mui/material';
import SettingsItem from '../SettingsItem'; import SettingsItem from '../SettingsItem';
import Header from '../Header'; import Header from '../Header';

View File

@ -50,13 +50,10 @@ export default function Navbar() {
{showRefreshOptions ? ( {showRefreshOptions ? (
<SettingsItem <SettingsItem
title={getMessage('modals.main.settings.sections.appearance.navbar.refresh')} title={getMessage('modals.main.settings.sections.appearance.navbar.refresh')}
subtitle='Choose what is refreshed when you click the refresh button' subtitle="Choose what is refreshed when you click the refresh button"
final={true} final={true}
> >
<Dropdown <Dropdown name="refreshOption" category="navbar">
name="refreshOption"
category="navbar"
>
<option value="page"> <option value="page">
{getMessage('modals.main.settings.sections.appearance.navbar.refresh_options.page')} {getMessage('modals.main.settings.sections.appearance.navbar.refresh_options.page')}
</option> </option>

View File

@ -1,7 +1,6 @@
import variables from 'modules/variables'; import variables from 'modules/variables';
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import { MdCancel, MdAdd } from 'react-icons/md'; import { MdCancel, MdAdd } from 'react-icons/md';
import { TextField } from '@mui/material';
import TextareaAutosize from '@mui/material/TextareaAutosize'; import TextareaAutosize from '@mui/material/TextareaAutosize';
import Header from '../Header'; import Header from '../Header';

View File

@ -1,7 +1,6 @@
import variables from 'modules/variables'; import variables from 'modules/variables';
import { PureComponent } from 'react'; import { PureComponent } from 'react';
import Header from '../Header'; import Header from '../Header';
import Text from '../Text';
import { MdRemoveCircleOutline } from 'react-icons/md'; import { MdRemoveCircleOutline } from 'react-icons/md';
import SettingsItem from '../SettingsItem'; import SettingsItem from '../SettingsItem';
export default class ReminderSettings extends PureComponent { export default class ReminderSettings extends PureComponent {
@ -45,45 +44,35 @@ export default class ReminderSettings extends PureComponent {
zoomSetting="zoomReminder" zoomSetting="zoomReminder"
switch={true} switch={true}
/> />
{/*<input
type="color"
name="colour"
className="colour"
onChange={(event) => this.updateColour(event)}
value={this.state.colour}
></input>
<label htmlFor={'colour'} className="customBackgroundHex">
{this.state.colour}
</label>*/}
<SettingsItem final={true} title="Add reminder" subtitle="Add reminder"> <SettingsItem final={true} title="Add reminder" subtitle="Add reminder">
<button onClick={() => this.addReminder()}>Add reminder</button> <button onClick={() => this.addReminder()}>Add reminder</button>
</SettingsItem> </SettingsItem>
<div className="reminderSettingsHolder"> <div className="reminderSettingsHolder">
<div className="reminderSetting"> <div className="reminderSetting">
<div> <div>
<div className="colorPicker"> <div className="colorPicker">
<input <input
type="color" type="color"
name="colour" name="colour"
className="colour" className="colour"
onChange={(event) => this.updateColour(event)} onChange={(event) => this.updateColour(event)}
value={this.state.colour} value={this.state.colour}
></input> ></input>
<label htmlFor={'colour'} className="customBackgroundHex"> <label htmlFor={'colour'} className="customBackgroundHex">
{this.state.colour} {this.state.colour}
</label> </label>
</div>
<span className="link">
<MdRemoveCircleOutline /> Remove
</span>
</div>
<div>
<span className="title">
<input type="text" id="lname" placeholder="Name" />
</span>
<input type="date" required />
</div> </div>
<span className="link">
<MdRemoveCircleOutline /> Remove
</span>
</div> </div>
<div>
<span className="title">
<input type="text" id="lname" placeholder="Name" />
</span>
<input type="date" required />
</div>
</div>
</div> </div>
</> </>
); );

View File

@ -123,7 +123,7 @@ export default class SearchSettings extends PureComponent {
</SettingsItem> </SettingsItem>
<SettingsItem <SettingsItem
title={this.getMessage('modals.main.settings.sections.search.search_engine')} title={this.getMessage('modals.main.settings.sections.search.search_engine')}
subtitle="cheese is gucci tbf" subtitle="Choose search engine to use in the search bar"
> >
<Dropdown <Dropdown
label={this.getMessage('modals.main.settings.sections.search.search_engine')} label={this.getMessage('modals.main.settings.sections.search.search_engine')}

View File

@ -25,23 +25,26 @@ export default class TimeSettings extends PureComponent {
let timeSettings = null; let timeSettings = null;
const digitalOptions = [
{
name: getMessage('modals.main.settings.sections.time.digital.twentyfourhour'),
value: 'twentyfourhour',
},
{
name: getMessage('modals.main.settings.sections.time.digital.twelvehour'),
value: 'twelvehour',
},
];
const digitalSettings = ( const digitalSettings = (
<SettingsItem <SettingsItem
title={getMessage('modals.main.settings.sections.time.digital.title')} title={getMessage('modals.main.settings.sections.time.digital.title')}
subtitle={getMessage('modals.main.settings.sections.time.format')} subtitle={getMessage('modals.main.settings.sections.time.format')}
> >
<Radio name="timeformat" options={digitalOptions} smallTitle={true} category="clock" /> <Radio
name="timeformat"
options={[
{
name: getMessage('modals.main.settings.sections.time.digital.twentyfourhour'),
value: 'twentyfourhour',
},
{
name: getMessage('modals.main.settings.sections.time.digital.twelvehour'),
value: 'twelvehour',
},
]}
smallTitle={true}
category="clock"
/>
<Checkbox <Checkbox
name="seconds" name="seconds"
text={getMessage('modals.main.settings.sections.time.digital.seconds')} text={getMessage('modals.main.settings.sections.time.digital.seconds')}
@ -132,10 +135,10 @@ export default class TimeSettings extends PureComponent {
final={true} final={true}
> >
<Switch <Switch
name='Pomodoro' name="Pomodoro"
text={getMessage('modals.main.settings.enabled')} text={getMessage('modals.main.settings.enabled')}
category='Pomodoro' category="Pomodoro"
element='Pomodoro' element="Pomodoro"
/> />
<Slider <Slider
title="Work Length" title="Work Length"
@ -145,7 +148,7 @@ export default class TimeSettings extends PureComponent {
min="5" min="5"
max="60" max="60"
marks={values('pomodoroWork')} marks={values('pomodoroWork')}
display={' ' + 'ms'} display={' ms'}
/> />
<Slider <Slider
title="Break Length" title="Break Length"
@ -155,7 +158,7 @@ export default class TimeSettings extends PureComponent {
min="1" min="1"
max="45" max="45"
marks={values('pomodoroBreak')} marks={values('pomodoroBreak')}
display={' ' + 'ms'} display={' ms'}
/> />
</SettingsItem> </SettingsItem>
</> </>

View File

@ -61,21 +61,6 @@ export default class TimeSettings extends PureComponent {
render() { render() {
const getMessage = (text) => variables.language.getMessage(variables.languagecode, text); const getMessage = (text) => variables.language.getMessage(variables.languagecode, text);
const tempFormat = [
{
name: getMessage('modals.main.settings.sections.weather.temp_format.celsius') + ' (°C)',
value: 'celsius',
},
{
name: getMessage('modals.main.settings.sections.weather.temp_format.fahrenheit') + ' (°F)',
value: 'fahrenheit',
},
{
name: getMessage('modals.main.settings.sections.weather.temp_format.kelvin') + ' (K)',
value: 'kelvin',
},
];
return ( return (
<> <>
<Header <Header
@ -107,7 +92,28 @@ export default class TimeSettings extends PureComponent {
</span> </span>
</SettingsItem> </SettingsItem>
<SettingsItem title={getMessage('modals.main.settings.sections.weather.temp_format.title')}> <SettingsItem title={getMessage('modals.main.settings.sections.weather.temp_format.title')}>
<Radio name="tempformat" options={tempFormat} category="weather" /> <Radio
name="tempformat"
options={[
{
name:
getMessage('modals.main.settings.sections.weather.temp_format.celsius') + ' (°C)',
value: 'celsius',
},
{
name:
getMessage('modals.main.settings.sections.weather.temp_format.fahrenheit') +
' (°F)',
value: 'fahrenheit',
},
{
name:
getMessage('modals.main.settings.sections.weather.temp_format.kelvin') + ' (K)',
value: 'kelvin',
},
]}
category="weather"
/>
</SettingsItem> </SettingsItem>
{localStorage.getItem('weatherType') > 1 && ( {localStorage.getItem('weatherType') > 1 && (
<SettingsItem title="Active bit" subtitle="idk a better word for it sorry"> <SettingsItem title="Active bit" subtitle="idk a better word for it sorry">
@ -203,21 +209,13 @@ export default class TimeSettings extends PureComponent {
text={getMessage('modals.main.settings.sections.weather.extra_info.max_temp')} text={getMessage('modals.main.settings.sections.weather.extra_info.max_temp')}
category="weather" category="weather"
/> />
<Checkbox <Checkbox name="feelsliketemp" text={'Feels like temperature'} category="weather" />
name="feelsliketemp"
text={'Feels like temperature'}
category="weather"
/>
<Checkbox <Checkbox
name="atmosphericpressure" name="atmosphericpressure"
text={getMessage('modals.main.settings.sections.weather.extra_info.atmospheric_pressure')} text={getMessage('modals.main.settings.sections.weather.extra_info.atmospheric_pressure')}
category="weather" category="weather"
/> />
<Checkbox <Checkbox name="upcomingForecast" text="Upcoming Forecast" category="weather" />
name="upcomingForecast"
text="Upcoming Forecast"
category="weather"
/>
</> </>
); );
} }

View File

@ -6,7 +6,6 @@ import EventBus from 'modules/helpers/eventbus';
import Checkbox from '../../Checkbox'; import Checkbox from '../../Checkbox';
import FileUpload from '../../FileUpload'; import FileUpload from '../../FileUpload';
import SettingsItem from '../../SettingsItem';
import Modal from 'react-modal'; import Modal from 'react-modal';

View File

@ -277,12 +277,12 @@ a.privacy {
} }
@keyframes float-in { @keyframes float-in {
0% { 0% {
transform: translate(0, 30px); transform: translate(0, 30px);
opacity: 0; opacity: 0;
} }
100% { 100% {
transform: translate(0, 0px); transform: translate(0, 0px);
opacity: 1; opacity: 1;
} }
} }

View File

@ -11,6 +11,10 @@ import Reminder from './reminder/Reminder';
import EventBus from 'modules/helpers/eventbus'; import EventBus from 'modules/helpers/eventbus';
// weather is lazy loaded due to the size of the weather icons module
// since we're using react-icons this might not be accurate,
// however, when we used the original module https://bundlephobia.com/package/weather-icons-react@1.2.0
// as seen here it is ridiculously large
const Weather = lazy(() => import('./weather/Weather')); const Weather = lazy(() => import('./weather/Weather'));
const renderLoader = () => <></>; const renderLoader = () => <></>;
@ -68,27 +72,26 @@ export default class Widgets extends PureComponent {
render() { render() {
// don't show when welcome is there // don't show when welcome is there
if (this.state.welcome !== 'false') { if (this.state.welcome !== 'false') {
return <div id="widgets"></div>; return <div id="widgets" />;
} }
// allow for re-ordering widgets // allow for re-ordering widgets
let elements = []; // we have a default to prevent errors
let elements = [
<Greeting />,
<Clock />,
<QuickLinks />,
<Quote />,
<Date />,
<Message />,
<Reminder />,
];
if (this.state.order) { if (this.state.order) {
elements = [];
this.state.order.forEach((element) => { this.state.order.forEach((element) => {
elements.push(<Fragment key={element}>{this.widgets[element]}</Fragment>); elements.push(<Fragment key={element}>{this.widgets[element]}</Fragment>);
}); });
} else {
// prevent error
elements = [
<Greeting />,
<Clock />,
<QuickLinks />,
<Quote />,
<Date />,
<Message />,
<Reminder />,
];
} }
return ( return (

View File

@ -27,6 +27,7 @@ export default class Favourite extends PureComponent {
variables.stats.postEvent('feature', 'Background favourite'); variables.stats.postEvent('feature', 'Background favourite');
} else { } else {
const type = localStorage.getItem('backgroundType'); const type = localStorage.getItem('backgroundType');
switch (type) { switch (type) {
case 'colour': case 'colour':
return; return;
@ -86,8 +87,7 @@ export default class Favourite extends PureComponent {
} }
render() { render() {
const backgroundType = localStorage.getItem('backgroundType'); if (localStorage.getItem('backgroundType') === 'colour') {
if (backgroundType === 'colour') {
return null; return null;
} }

View File

@ -35,8 +35,6 @@ const downloadImage = async (info) => {
variables.stats.postEvent('feature', 'Background download'); variables.stats.postEvent('feature', 'Background download');
}; };
// todo: copy link to unsplash/pexels page not image url // todo: copy link to unsplash/pexels page not image url
const copyImage = (info) => { const copyImage = (info) => {
variables.stats.postEvent('feature', 'Background copied'); variables.stats.postEvent('feature', 'Background copied');
@ -136,7 +134,6 @@ export default function PhotoInformation({ info, url, api }) {
); );
} }
const downloadEnabled = const downloadEnabled =
localStorage.getItem('downloadbtn') === 'true' && !info.offline && !info.photographerURL && api; localStorage.getItem('downloadbtn') === 'true' && !info.offline && !info.photographerURL && api;
const downloadBackground = () => { const downloadBackground = () => {
@ -282,7 +279,9 @@ export default function PhotoInformation({ info, url, api }) {
<Download onClick={() => downloadImage(info)} /> <Download onClick={() => downloadImage(info)} />
</Tooltip> </Tooltip>
</div> </div>
<span className='subtitle' style={{marginBottom: '20px'}}>Description</span> <span className="subtitle" style={{ marginBottom: '20px' }}>
Description
</span>
<div className="extra-content"> <div className="extra-content">
<span className="subtitle"> <span className="subtitle">
{variables.language.getMessage( {variables.language.getMessage(

View File

@ -197,7 +197,7 @@
color: t($link); color: t($link);
} }
&:hover { &:hover {
opacity: 0.8; opacity: 0.8;
} }
} }
&:hover { &:hover {

View File

@ -1,17 +1,15 @@
import variables from 'modules/variables'; import variables from 'modules/variables';
import { PureComponent, createRef } from 'react'; import { PureComponent, createRef } from 'react';
import { MdRefresh, MdSettings, MdAssignment } from 'react-icons/md'; import { MdRefresh, MdSettings } from 'react-icons/md';
import Notes from './Notes'; import Notes from './Notes';
import Todo from './Todo'; import Todo from './Todo';
import Maximise from '../background/Maximise'; import Maximise from '../background/Maximise';
import Tooltip from 'components/helpers/tooltip/Tooltip'; import Tooltip from 'components/helpers/tooltip/Tooltip';
import InfoTooltip from 'components/helpers/tooltip/infoTooltip';
import EventBus from 'modules/helpers/eventbus'; import EventBus from 'modules/helpers/eventbus';
import './scss/index.scss'; import './scss/index.scss';
import { FaThemeisle } from 'react-icons/fa';
export default class Navbar extends PureComponent { export default class Navbar extends PureComponent {
constructor() { constructor() {

View File

@ -1,10 +1,11 @@
import variables from 'modules/variables'; import variables from 'modules/variables';
import { PureComponent, useRef } from 'react'; import { PureComponent } from 'react';
import { MdContentCopy, MdAssignment, MdPushPin, MdDownload } from 'react-icons/md'; import { MdContentCopy, MdAssignment, MdPushPin, MdDownload } from 'react-icons/md';
import { useFloating, shift } from '@floating-ui/react-dom'; import { useFloating, shift } from '@floating-ui/react-dom';
import TextareaAutosize from '@mui/material/TextareaAutosize'; import TextareaAutosize from '@mui/material/TextareaAutosize';
import { toast } from 'react-toastify'; import { toast } from 'react-toastify';
import Tooltip from '../../helpers/tooltip/Tooltip'; //import Hotkeys from 'react-hot-keys'; import Tooltip from '../../helpers/tooltip/Tooltip';
//import Hotkeys from 'react-hot-keys';
import { saveFile } from 'modules/helpers/settings/modals'; import { saveFile } from 'modules/helpers/settings/modals';
class Notes extends PureComponent { class Notes extends PureComponent {

View File

@ -41,7 +41,37 @@ class Todo extends PureComponent {
} }
} }
updateTodoState(todoContent) { updateTodo(action, index, data) {
let todoContent = this.state.todo;
switch (action) {
case 'add':
todoContent.push({
value: '',
done: false,
});
break;
case 'remove':
todoContent.splice(index, 1);
if (todoContent.length === 0) {
todoContent.push({
value: '',
done: false,
});
}
break;
case 'set':
todoContent[index] = {
value: data.target.value,
done: todoContent[index].done,
};
break;
case 'done':
todoContent[index].done = !todoContent[index].done;
break;
default:
break;
}
localStorage.setItem('todoContent', JSON.stringify(todoContent)); localStorage.setItem('todoContent', JSON.stringify(todoContent));
this.setState({ this.setState({
todo: todoContent, todo: todoContent,
@ -49,42 +79,6 @@ class Todo extends PureComponent {
this.forceUpdate(); this.forceUpdate();
} }
setTodo(index, data) {
let todoContent = this.state.todo;
todoContent[index] = {
value: data.target.value,
done: todoContent[index].done,
};
this.updateTodoState(todoContent);
}
addTodo() {
let todoContent = this.state.todo;
todoContent.push({
value: '',
done: false,
});
this.updateTodoState(todoContent);
}
removeTodo(index) {
let todoContent = this.state.todo;
todoContent.splice(index, 1);
if (todoContent.length === 0) {
todoContent.push({
value: '',
done: false,
});
}
this.updateTodoState(todoContent);
}
doneTodo(index) {
let todoContent = this.state.todo;
todoContent[index].done = !todoContent[index].done;
this.updateTodoState(todoContent);
}
pin() { pin() {
variables.stats.postEvent('feature', 'Todo pin'); variables.stats.postEvent('feature', 'Todo pin');
if (localStorage.getItem('todoPinned') === 'true') { if (localStorage.getItem('todoPinned') === 'true') {
@ -134,20 +128,20 @@ class Todo extends PureComponent {
</button> </button>
</Tooltip> </Tooltip>
<Tooltip title={'Add'}> <Tooltip title={'Add'}>
<button onClick={() => this.addTodo()}> <button onClick={() => this.updateTodo('add')}>
<MdPlaylistAdd /> <MdPlaylistAdd />
</button> </button>
</Tooltip> </Tooltip>
</div> </div>
<div className={'todoRows'}> <div className={'todoRows'}>
{this.state.todo.map((value, index) => ( {this.state.todo.map((_value, index) => (
<div <div
className={'todoRow' + (this.state.todo[index].done ? ' done' : '')} className={'todoRow' + (this.state.todo[index].done ? ' done' : '')}
key={index} key={index}
> >
<Checkbox <Checkbox
checked={this.state.todo[index].done} checked={this.state.todo[index].done}
onClick={() => this.doneTodo(index)} onClick={() => this.updateTodo('done', index)}
/> />
<TextareaAutosize <TextareaAutosize
placeholder={variables.language.getMessage( placeholder={variables.language.getMessage(
@ -155,10 +149,10 @@ class Todo extends PureComponent {
'widgets.navbar.notes.placeholder', 'widgets.navbar.notes.placeholder',
)} )}
value={this.state.todo[index].value} value={this.state.todo[index].value}
onChange={(data) => this.setTodo(index, data)} onChange={(data) => this.updateTodo('set', index, data)}
readOnly={this.state.todo[index].done} readOnly={this.state.todo[index].done}
/> />
<MdDelete onClick={() => this.removeTodo(index)} /> <MdDelete onClick={() => this.updateTodo('remove', index)} />
</div> </div>
))} ))}
</div> </div>
@ -169,6 +163,7 @@ class Todo extends PureComponent {
); );
} }
} }
export default function TodoWrapper() { export default function TodoWrapper() {
const { x, y, reference, floating, strategy } = useFloating({ const { x, y, reference, floating, strategy } = useFloating({
placement: 'bottom', placement: 'bottom',

View File

@ -68,7 +68,7 @@ export default class QuickLinks extends PureComponent {
data.push({ data.push({
name: this.state.name || url, name: this.state.name || url,
url: url, url,
icon: this.state.icon || '', icon: this.state.icon || '',
key: Math.random().toString(36).substring(7) + 1, key: Math.random().toString(36).substring(7) + 1,
}); });

View File

@ -398,7 +398,7 @@ export default class Quote extends PureComponent {
<span className="quote" ref={this.quote}> <span className="quote" ref={this.quote}>
{this.state.quote} {this.state.quote}
</span> </span>
{(localStorage.getItem('widgetStyle') === 'legacy') ? ( {localStorage.getItem('widgetStyle') === 'legacy' ? (
<> <>
<div> <div>
<h1 className="quoteauthor" ref={this.quoteauthor}> <h1 className="quoteauthor" ref={this.quoteauthor}>
@ -418,7 +418,7 @@ export default class Quote extends PureComponent {
</> </>
) : ( ) : (
<> <>
{this.state.author !== '' ? ( {this.state.author !== '' ? (
<div className="author-holder"> <div className="author-holder">
<div className="author"> <div className="author">
<div <div
@ -451,7 +451,9 @@ export default class Quote extends PureComponent {
</div> </div>
</div> </div>
</div> </div>
) : <div ref={this.quoteauthor}></div> } ) : (
<div ref={this.quoteauthor}></div>
)}
</> </>
)} )}
{/*variables.keybinds.favouriteQuote && variables.keybinds.favouriteQuote !== '' ? <Hotkeys keyName={variables.keybinds.favouriteQuote} onKeyDown={() => this.favourite()} /> : null*/} {/*variables.keybinds.favouriteQuote && variables.keybinds.favouriteQuote !== '' ? <Hotkeys keyName={variables.keybinds.favouriteQuote} onKeyDown={() => this.favourite()} /> : null*/}

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import './reminder.scss'; import './reminder.scss';
import Tooltip from '../../helpers/tooltip/Tooltip' import Tooltip from '../../helpers/tooltip/Tooltip';
import { MdClose, MdSnooze, MdWork } from 'react-icons/md'; import { MdClose, MdSnooze, MdWork } from 'react-icons/md';
export default class Reminder extends React.PureComponent { export default class Reminder extends React.PureComponent {
@ -21,8 +21,12 @@ export default class Reminder extends React.PureComponent {
<span className="subtitle">Time</span> <span className="subtitle">Time</span>
</div> </div>
<div className="icons"> <div className="icons">
<Tooltip title='Remove'><MdClose /></Tooltip> <Tooltip title="Remove">
<Tooltip title='Snooze'><MdSnooze /></Tooltip> <MdClose />
</Tooltip>
<Tooltip title="Snooze">
<MdSnooze />
</Tooltip>
</div> </div>
</div> </div>
); );

View File

@ -8,6 +8,7 @@
gap: 10px; gap: 10px;
height: 60px; height: 60px;
text-align: left; text-align: left;
.identifier { .identifier {
color: #fff; color: #fff;
height: 60px; height: 60px;
@ -17,15 +18,18 @@
justify-content: center; justify-content: center;
align-items: center; align-items: center;
} }
.content { .content {
display: flex; display: flex;
flex-flow: column; flex-flow: column;
padding: 10px; padding: 10px;
} }
.icons { .icons {
display: flex; display: flex;
gap: 10px; gap: 10px;
padding: 10px; padding: 10px;
svg { svg {
@include basicIconButton(10px, 0.9rem, ui); @include basicIconButton(10px, 0.9rem, ui);
} }

View File

@ -1,5 +1,5 @@
import variables from 'modules/variables'; import variables from 'modules/variables';
import { PureComponent, Fragment } from 'react'; import { PureComponent } from 'react';
import { MdSearch, MdMic, MdSettings } from 'react-icons/md'; import { MdSearch, MdMic, MdSettings } from 'react-icons/md';
import Tooltip from 'components/helpers/tooltip/Tooltip'; import Tooltip from 'components/helpers/tooltip/Tooltip';
//import Hotkeys from 'react-hot-keys'; //import Hotkeys from 'react-hot-keys';
@ -106,7 +106,7 @@ export default class Search extends PureComponent {
if (localStorage.getItem('voiceSearch') === 'true') { if (localStorage.getItem('voiceSearch') === 'true') {
microphone = ( microphone = (
<button onClick={this.startSpeechRecognition} id='micBtn'> <button onClick={this.startSpeechRecognition} id="micBtn">
<MdMic className="micIcon" /> <MdMic className="micIcon" />
</button> </button>
); );

View File

@ -5,12 +5,14 @@
border-radius: 12px; border-radius: 12px;
justify-content: flex-start; justify-content: flex-start;
flex-direction: row; flex-direction: row;
input[type='text'] { input[type='text'] {
@extend %basic; @extend %basic;
outline: none; outline: none;
border: none; border: none;
font-size: 20px; font-size: 20px;
padding: 10px 0 10px 20px; padding: 10px 0 10px 20px;
&::placeholder { &::placeholder {
@include themed() { @include themed() {
color: t($color); color: t($color);
@ -24,6 +26,7 @@
gap: 10px; gap: 10px;
margin-top: 1px; margin-top: 1px;
margin-right: 10px; margin-right: 10px;
.tooltip { .tooltip {
max-height: 44px; max-height: 44px;
} }
@ -35,6 +38,7 @@
left: 1rem; left: 1rem;
display: flex; display: flex;
flex-flow: column; flex-flow: column;
button { button {
@include basicIconButton(12px, 20px, ui); @include basicIconButton(12px, 20px, ui);
} }
@ -50,10 +54,12 @@
font-size: 0.6em; font-size: 0.6em;
width: 200px; width: 200px;
transition: 0.5s; transition: 0.5s;
span { span {
padding: 0.5rem; padding: 0.5rem;
cursor: pointer; cursor: pointer;
border-radius: 12px; border-radius: 12px;
&:hover { &:hover {
@include themed() { @include themed() {
background: t($btn-backgroundHover); background: t($btn-backgroundHover);

View File

@ -2,8 +2,6 @@ import { PureComponent, Suspense, lazy } from 'react';
import { convertTimezone } from 'modules/helpers/date'; import { convertTimezone } from 'modules/helpers/date';
import EventBus from 'modules/helpers/eventbus'; import EventBus from 'modules/helpers/eventbus';
import { MdSkipNext, MdOutlineRestartAlt, MdPlayArrow } from 'react-icons/md';
import Tooltip from '../../helpers/tooltip/Tooltip';
import './clock.scss'; import './clock.scss';
import Pomodoro from './Pomodoro'; import Pomodoro from './Pomodoro';
@ -142,7 +140,10 @@ export default class Clock extends PureComponent {
<span className="ampm">{this.state.ampm}</span> <span className="ampm">{this.state.ampm}</span>
</span> </span>
{localStorage.getItem('Pomodoro') === 'true' ? ( {localStorage.getItem('Pomodoro') === 'true' ? (
<Pomodoro hours={this.state.nowGlobal.getHours} minutes={this.state.nowGlobal.getMinutes} /> <Pomodoro
hours={this.state.nowGlobal.getHours}
minutes={this.state.nowGlobal.getMinutes}
/>
) : null} ) : null}
</> </>
); );

View File

@ -19,9 +19,11 @@
border-radius: 100%; border-radius: 100%;
/*box-shadow: inset 0 0 100px rgba(0, 0, 0, 0.3);*/ /*box-shadow: inset 0 0 100px rgba(0, 0, 0, 0.3);*/
border: none !important; border: none !important;
@include themed() { @include themed() {
border: 1px solid t($color) !important; border: 1px solid t($color) !important;
} }
cursor: initial; cursor: initial;
user-select: none; user-select: none;
} }
@ -39,23 +41,27 @@
padding: 1rem; padding: 1rem;
} }
// ok so if pomodoro is a separate component, why is this in clock?
// ^ above note is for alex
.pomodoro { .pomodoro {
margin-top: -20px; margin-top: -20px;
@extend %basic; @extend %basic;
padding: 5px 15px 5px 15px; padding: 5px 15px 5px 15px;
font-size: 12px; font-size: 12px;
display: flex; display: flex;
flex-flow: row; flex-flow: row;
gap: 10px; gap: 10px;
align-items: center; align-items: center;
.pomodoroTime { .pomodoroTime {
display: flex; display: flex;
flex-flow: row; flex-flow: row;
align-items: center; align-items: center;
gap: 5px; gap: 5px;
.timeRemaining { .timeRemaining {
} }
.type { .type {
color: #ccc; color: #ccc;
font-weight: bold; font-weight: bold;
@ -63,13 +69,15 @@
display: grid; display: grid;
} }
} }
.pomodoroControls { .pomodoroControls {
display: flex; display: flex;
flex-flow: row; flex-flow: row;
justify-content: space-evenly; justify-content: space-evenly;
gap: 5px; gap: 5px;
} }
button { button {
@include basicIconButton(5px, 11px, ui); @include basicIconButton(5px, 11px, ui);
} }
} }

View File

@ -203,27 +203,27 @@ export default class Weather extends PureComponent {
{enabled('showlocation') ? <span className="loc">{this.state.location}</span> : null} {enabled('showlocation') ? <span className="loc">{this.state.location}</span> : null}
</div> </div>
<div className="expanded-info"> <div className="expanded-info">
{enabled('upcomingForecast') ? ( {enabled('upcomingForecast') ? (
<> <>
<span className="subtitle">Upcoming Forecast</span> <span className="subtitle">Upcoming Forecast</span>
<div className="upcomingForecast"> <div className="upcomingForecast">
<div> <div>
<WeatherIcon name={this.state.icon} /> <WeatherIcon name={this.state.icon} />
<span className="period">15:00</span> <span className="period">15:00</span>
<span className="minmax">{minmax()}</span> <span className="minmax">{minmax()}</span>
</div> </div>
<div> <div>
<WeatherIcon name={this.state.icon} /> <WeatherIcon name={this.state.icon} />
<span className="period">16:00</span> <span className="period">16:00</span>
<span className="minmax">{minmax()}</span> <span className="minmax">{minmax()}</span>
</div> </div>
<div> <div>
<WeatherIcon name={this.state.icon} /> <WeatherIcon name={this.state.icon} />
<span className="period">17:00</span> <span className="period">17:00</span>
<span className="minmax">{minmax()}</span> <span className="minmax">{minmax()}</span>
</div> </div>
</div> </div>
</> </>
) : null} ) : null}
<span className="subtitle">Extra Information</span> <span className="subtitle">Extra Information</span>

View File

@ -12,6 +12,7 @@
width: auto; width: auto;
display: grid; display: grid;
place-items: center; place-items: center;
&:hover { &:hover {
height: auto; height: auto;
transition: 0.8s cubic-bezier(0.075, 0.82, 0.165, 1); transition: 0.8s cubic-bezier(0.075, 0.82, 0.165, 1);
@ -26,6 +27,7 @@
.extra-info { .extra-info {
font-size: 18px; font-size: 18px;
gap: 40px; gap: 40px;
@include themed() { @include themed() {
color: t($weather); color: t($weather);
} }
@ -39,6 +41,7 @@
display: flex; display: flex;
flex-flow: row; flex-flow: row;
justify-content: space-evenly; justify-content: space-evenly;
span { span {
display: flex; display: flex;
align-items: center; align-items: center;
@ -50,16 +53,20 @@
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
gap: 25px; gap: 25px;
div { div {
align-items: center; align-items: center;
display: flex; display: flex;
svg { svg {
font-size: 2em !important; font-size: 2em !important;
} }
span { span {
font-size: 34px; font-size: 34px;
} }
} }
.minmax { .minmax {
display: flex; display: flex;
flex-flow: column; flex-flow: column;
@ -79,10 +86,12 @@
align-items: center; align-items: center;
gap: 20px; gap: 20px;
} }
@include themed() { @include themed() {
svg { svg {
color: t($subColor); color: t($subColor);
} }
.weatherIcon { .weatherIcon {
font-size: 1.4em; font-size: 1.4em;
display: grid; display: grid;
@ -96,22 +105,27 @@
width: 100%; width: 100%;
justify-content: space-between; justify-content: space-between;
gap: 10px; gap: 10px;
div { div {
@include themed() { @include themed() {
border-radius: t($borderRadius); border-radius: t($borderRadius);
border: 1px solid t($btn-backgroundHover); border: 1px solid t($btn-backgroundHover);
padding: 5px; padding: 5px;
flex: 1; flex: 1;
svg { svg {
font-size: 36px; font-size: 36px;
} }
span { span {
justify-content: center; justify-content: center;
} }
.period { .period {
color: t($color); color: t($color);
font-size: 15px; font-size: 15px;
} }
.minmax { .minmax {
margin-top: 5px; margin-top: 5px;
flex-flow: column; flex-flow: column;

View File

@ -13,6 +13,7 @@ import Stats from 'modules/helpers/stats';
// language // language
import I18n from '@eartharoid/i18n'; import I18n from '@eartharoid/i18n';
// this is because of vite
import * as de_DE from './translations/de_DE.json'; import * as de_DE from './translations/de_DE.json';
import * as en_GB from './translations/en_GB.json'; import * as en_GB from './translations/en_GB.json';
import * as en_US from './translations/en_US.json'; import * as en_US from './translations/en_US.json';

View File

@ -11,7 +11,7 @@ export const OPENSTREETMAP_URL = 'https://www.openstreetmap.org';
// Mue URLs // Mue URLs
export const WEBSITE_URL = 'https://muetab.com'; export const WEBSITE_URL = 'https://muetab.com';
export const PRIVACY_URL = 'https://muetab.com/privacy'; export const PRIVACY_URL = 'https://muetab.com/privacy';
export const BLOG_POST = 'https://blog.muetab.com/posts/version-6-0'; export const BLOG_POST = 'https://blog.muetab.com/posts/version-7-0';
export const TRANSLATIONS_URL = 'https://docs.muetab.com/translations/'; export const TRANSLATIONS_URL = 'https://docs.muetab.com/translations/';
export const REPORT_ITEM = export const REPORT_ITEM =
'https://github.com/mue/marketplace/issues/new?assignees=&labels=item+report&template=item-report.md&title=%5BItem+Report%5D+'; 'https://github.com/mue/marketplace/issues/new?assignees=&labels=item+report&template=item-report.md&title=%5BItem+Report%5D+';
@ -28,8 +28,8 @@ export const DISCORD_SERVER = 'zv8C9F8';
export const COPYRIGHT_NAME = 'The Mue Authors'; export const COPYRIGHT_NAME = 'The Mue Authors';
export const COPYRIGHT_YEAR = '2018'; export const COPYRIGHT_YEAR = '2018';
export const COPYRIGHT_LICENSE = 'BSD-3-Clause License'; export const COPYRIGHT_LICENSE = 'BSD-3-Clause License';
export const SPONSORS_USERNAME = 'davidcralph';
export const LIBERAPAY_USERNAME = 'mue'; export const LIBERAPAY_USERNAME = 'mue';
export const SPONSORS_USERNAME = 'davidcralph';
export const KOFI_USERNAME = 'davidcralph'; export const KOFI_USERNAME = 'davidcralph';
export const PATREON_USERNAME = 'davidcralph'; export const PATREON_USERNAME = 'davidcralph';

View File

@ -1,3 +1,5 @@
// one day it might be a good idea to replace all this with redux, but it'd take
// a lot of rewriting
export default class EventBus { export default class EventBus {
static on(event, callback) { static on(event, callback) {
document.addEventListener(event, (e) => { document.addEventListener(event, (e) => {

View File

@ -1,4 +1,4 @@
// todo: add more // mainly this is just to make life easier when debugging stuff like hover
export default function ExperimentalInit() { export default function ExperimentalInit() {
if (localStorage.getItem('debug') === 'true') { if (localStorage.getItem('debug') === 'true') {
document.onkeydown = (e) => { document.onkeydown = (e) => {

View File

@ -1,4 +1,8 @@
// based on https://stackoverflow.com/a/47009962 // based on https://stackoverflow.com/a/47009962
// it has been brought to my attention (many) times that this is horribly broken if the time
// on the "Change every" setting is longer than 1 minute. I wasn't going to wait days to see
// if the function worked, so i just assumed it did. i apologise. this function will be
// replaced entirely in the future probably
export default function interval(callback, interval, name) { export default function interval(callback, interval, name) {
const key = name + 'interval'; const key = name + 'interval';
const ms = localStorage.getItem(key); const ms = localStorage.getItem(key);

View File

@ -29,7 +29,7 @@ export function setDefaultSettings(reset) {
localStorage.setItem('showWelcome', false); localStorage.setItem('showWelcome', false);
} }
// Finally we set this to true so it doesn't run the function on every load // finally we set this to true so it doesn't run the function on every load
localStorage.setItem('firstRun', true); localStorage.setItem('firstRun', true);
} }

View File

@ -17,6 +17,7 @@ export function saveFile(data, filename = 'file', type = 'text/json') {
a.download = filename; a.download = filename;
a.dataset.downloadurl = [type, a.download, a.href].join(':'); a.dataset.downloadurl = [type, a.download, a.href].join(':');
// i need to see what all this actually does, i think wessel wrote this function
event.initMouseEvent( event.initMouseEvent(
'click', 'click',
true, true,
@ -39,9 +40,13 @@ export function saveFile(data, filename = 'file', type = 'text/json') {
export function exportSettings() { export function exportSettings() {
const settings = {}; const settings = {};
Object.keys(localStorage).forEach((key) => { Object.keys(localStorage).forEach((key) => {
settings[key] = localStorage.getItem(key); settings[key] = localStorage.getItem(key);
}); });
// i think a good improvement would be to make the file names more descriptive, or allow for saving as custom
// otherwise you'll end up with mue-settings (6000).json and have absolutely no idea what any of them are for
saveFile(settings, 'mue-settings.json'); saveFile(settings, 'mue-settings.json');
variables.stats.postEvent('tab', 'Settings exported'); variables.stats.postEvent('tab', 'Settings exported');
} }

View File

@ -1,4 +1,4 @@
import * as Constants from 'modules/constants'; import * as constants from 'modules/constants';
const variables = { const variables = {
language: {}, language: {},
@ -8,7 +8,7 @@ const variables = {
postEvent: () => '', postEvent: () => '',
}, },
//keybinds: {}, //keybinds: {},
constants: Constants, constants,
}; };
export default variables; export default variables;

View File

View File

@ -1,4 +1,4 @@
@import '../variables'; @import 'variables';
.Toastify__toast-body { .Toastify__toast-body {
font-size: 16px !important; font-size: 16px !important;

View File

@ -1,3 +1,5 @@
// since alex will no doubtedly be looking at this file often
// here's a reminder: please add a new line when doing nested scss, otherwise it is messy!
@use 'sass:map'; @use 'sass:map';
@import 'mixins'; @import 'mixins';
@ -93,15 +95,20 @@ $themes: (
color: t($color); color: t($color);
box-shadow: t($boxShadow); box-shadow: t($boxShadow);
} }
backdrop-filter: blur(map.get($ui-elements, 'backgroundBlur')); backdrop-filter: blur(map.get($ui-elements, 'backgroundBlur'));
.title { .title {
font-size: 18px; font-size: 18px;
@include themed() { @include themed() {
color: t($color); color: t($color);
} }
} }
.subtitle { .subtitle {
font-size: 14px; font-size: 14px;
@include themed() { @include themed() {
color: t($subColor); color: t($subColor);
} }
@ -113,32 +120,40 @@ $themes: (
font-size: 38px; font-size: 38px;
font-weight: 600; font-weight: 600;
margin-bottom: 15px; margin-bottom: 15px;
@include themed() { @include themed() {
color: t($color); color: t($color);
} }
} }
.title { .title {
font-size: 24px; font-size: 24px;
font-weight: 600; font-weight: 600;
@include themed() { @include themed() {
color: t($color); color: t($color);
} }
} }
.subtitle { .subtitle {
font-size: 16px; font-size: 16px;
@include themed() { @include themed() {
color: t($subColor); color: t($subColor);
} }
} }
.link { .link {
font-size: 16px; font-size: 16px;
text-decoration: none; text-decoration: none;
cursor: pointer; cursor: pointer;
@include themed() { @include themed() {
color: t($link); color: t($link);
} }
&:hover { &:hover {
opacity: 0.8; opacity: 0.8;
} }
} }
} }
@ -149,10 +164,12 @@ $themes: (
background: t($modal-sidebar); background: t($modal-sidebar);
border: 3px solid t($modal-sidebarActive); border: 3px solid t($modal-sidebarActive);
color: t($color); color: t($color);
&:hover { &:hover {
background: t($modal-sidebarActive); background: t($modal-sidebarActive);
} }
} }
border-radius: 12px; border-radius: 12px;
height: 40px; height: 40px;
font-size: 1rem; font-size: 1rem;
@ -163,17 +180,21 @@ $themes: (
gap: 20px; gap: 20px;
transition: 0.5s; transition: 0.5s;
cursor: pointer; cursor: pointer;
&:hover { &:hover {
background: t($modal-sidebarActive); background: t($modal-sidebarActive);
} }
&:active { &:active {
background: t($modal-sidebarActive); background: t($modal-sidebarActive);
box-shadow: 0 0 0 1px t($color); box-shadow: 0 0 0 1px t($color);
} }
&:focus { &:focus {
background: t($modal-sidebarActive); background: t($modal-sidebarActive);
box-shadow: 0 0 0 1px t($color); box-shadow: 0 0 0 1px t($color);
} }
&:disabled { &:disabled {
background: t($modal-sidebarActive); background: t($modal-sidebarActive);
cursor: not-allowed; cursor: not-allowed;
@ -188,56 +209,69 @@ $themes: (
color: t($color); color: t($color);
box-shadow: t($boxShadow); box-shadow: t($boxShadow);
border-radius: t($borderRadius); border-radius: t($borderRadius);
&:hover { &:hover {
background: t($btn-backgroundHover); background: t($btn-backgroundHover);
} }
&:active { &:active {
background: t($btn-backgroundHover); background: t($btn-backgroundHover);
box-shadow: 0 0 0 1px t($color); box-shadow: 0 0 0 1px t($color);
} }
&:focus { &:focus {
background: t($btn-backgroundHover); background: t($btn-backgroundHover);
box-shadow: 0 0 0 1px t($color); box-shadow: 0 0 0 1px t($color);
} }
} }
@if $type == 'modal-text' { @if $type == 'modal-text' {
color: t($color); color: t($color);
background: none; background: none;
border-radius: t($borderRadius); border-radius: t($borderRadius);
&:hover { &:hover {
background: t($modal-sidebarActive); background: t($modal-sidebarActive);
box-shadow: 3px solid t($modal-sidebarActive); box-shadow: 3px solid t($modal-sidebarActive);
} }
} }
@if $type == 'modal' { @if $type == 'modal' {
background: t($modal-sidebar); background: t($modal-sidebar);
border: 3px solid t($modal-sidebarActive); border: 3px solid t($modal-sidebarActive);
color: t($color); color: t($color);
border-radius: t($borderRadius); border-radius: t($borderRadius);
&:hover { &:hover {
background: t($modal-sidebarActive); background: t($modal-sidebarActive);
} }
&:active { &:active {
background: t($modal-sidebarActive); background: t($modal-sidebarActive);
box-shadow: 0 0 0 1px t($color); box-shadow: 0 0 0 1px t($color);
} }
&:focus { &:focus {
background: t($modal-sidebarActive); background: t($modal-sidebarActive);
box-shadow: 0 0 0 1px t($color); box-shadow: 0 0 0 1px t($color);
} }
} }
@if $type == 'legacy' { @if $type == 'legacy' {
background: none; background: none;
color: #fff; color: #fff;
border-radius: t($borderRadius); border-radius: t($borderRadius);
box-shadow: 0 0 0 0 !important; box-shadow: 0 0 0 0 !important;
&:hover { &:hover {
background-color: rgb(66 66 66 / 23%); background-color: rgb(66 66 66 / 23%);
} }
&:active { &:active {
background-color: rgb(66 66 66 / 23%); background-color: rgb(66 66 66 / 23%);
box-shadow: 0 0 0 1px t($color); box-shadow: 0 0 0 1px t($color);
} }
&:focus { &:focus {
background-color: rgb(66 66 66 / 23%); background-color: rgb(66 66 66 / 23%);
box-shadow: 0 0 0 1px t($color); box-shadow: 0 0 0 1px t($color);
@ -245,6 +279,7 @@ $themes: (
} }
} }
// this needs to be moved up!
padding: $padding; padding: $padding;
font-size: $font-size; font-size: $font-size;
cursor: pointer; cursor: pointer;
@ -259,6 +294,7 @@ $themes: (
@include themed() { @include themed() {
color: t($color); color: t($color);
} }
&:hover { &:hover {
@include themed() { @include themed() {
background: t($btn-background); background: t($btn-background);

View File

@ -1,7 +1,5 @@
@import 'variables'; @import 'variables';
@import 'toast';
@import 'modules/toast';
@import 'modules/buttons';
body { body {
background: #000; background: #000;
@ -86,6 +84,8 @@ body {
} }
/* fonts (imported from fontsource) */ /* fonts (imported from fontsource) */
// i don't even know what the unicode-range is for, but we're keeping it so that nothing breaks
// same reason as why fontsource is never updated, it broke font loading last time so it flashed
@font-face { @font-face {
font-family: 'Lexend Deca'; font-family: 'Lexend Deca';
font-style: normal; font-style: normal;

View File

@ -1,113 +0,0 @@
/*%settingsButton {
transition: ease 0.33s;
color: map-get($theme-colours, 'main');
cursor: pointer;
padding: 10px 30px;
font-size: 20px;
border-radius: 24px;
box-shadow: 0 5px 15px rgba(128, 161, 144, 0.4);
&:hover,
&:active {
outline: none;
background: none;
}
&:disabled {
cursor: not-allowed;
color: grey !important;
background: none;
border: 2px solid grey !important;
}
}
.dark %settingsButton {
box-shadow: 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');
}
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;
}
}
.copyNote {
@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;
display: inline;
margin: 5px;
&:hover {
color: map-get($button-colours, 'other');
}
}
.upload {
width: 100%;
height: 100%;
border-radius: 20px;
border: none;
outline: none;
padding: 50px;
background: var(--sidebar);
color: var(--modal-text);
cursor: pointer;
&:hover {
background: var(--tab-active);
}
svg {
font-size: 4em;
}
span {
font-size: 2em;
}
}
.cleanButton {
background: none;
border: none;
vertical-align: middle;
svg {
fill: #ff4757;
border-radius: 100%;
background-color: var(--background);
height: 1.2em;
width: 1.2em;
cursor: pointer;
transition: ease 0.5s;
&:hover {
border-radius: 100%;
background: #ff4757;
fill: var(--background);
transition: ease 0.5s;
}
}
}
*/

View File

@ -4,14 +4,13 @@ import path from 'path';
const isProd = process.env.NODE_ENV === 'production'; const isProd = process.env.NODE_ENV === 'production';
export default defineConfig({ export default defineConfig({
plugins: [react()], plugins: [react()],
server: { server: {
hmr: { hmr: {
protocol: 'ws', protocol: 'ws',
host: 'localhost', host: 'localhost',
} },
}, },
build: { build: {
minify: isProd, minify: isProd,
@ -22,7 +21,7 @@ export default defineConfig({
components: path.resolve(__dirname, './src/components'), components: path.resolve(__dirname, './src/components'),
modules: path.resolve(__dirname, './src/modules'), modules: path.resolve(__dirname, './src/modules'),
translations: path.resolve(__dirname, './src/translations'), translations: path.resolve(__dirname, './src/translations'),
scss: path.resolve(__dirname, './src/scss') scss: path.resolve(__dirname, './src/scss'),
} },
} },
}); });