mirror of
https://github.com/mue/mue.git
synced 2026-06-08 14:10:42 +02:00
refactor: update widgets and fix font change
This commit is contained in:
@@ -36,11 +36,11 @@ Mue is a fast, open and free-to-use browser extension that gives a new, fresh an
|
||||
* Fast and free
|
||||
* Supports multiple browsers
|
||||
* Actively developed and open source
|
||||
* Automatically updating API (no tracking) with new photos, quotes and offline mode
|
||||
* Automatically updating [API](https://github.com/mue/api) with new photos, quotes and offline mode
|
||||
* Widgets such as searchbar, weather, quick links, clock, date, quote, greeting
|
||||
* Settings - enable/disable various features and customise parts of Mue
|
||||
* Navbar with copy button, favourite background, notes feature etc
|
||||
* Marketplace - download custom photo packs made by the community
|
||||
* [Marketplace](https://github.com/mue/marketplace) - download custom photo packs, quote packs and preset settings made by the community
|
||||
|
||||
### Planned Features
|
||||
Please see our [roadmap](https://github.com/mue/mue/projects)
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.4.0",
|
||||
"@emotion/styled": "^11.3.0",
|
||||
"@fontsource/lexend-deca": "^4.5.0",
|
||||
"@fontsource/montserrat": "^4.5.0",
|
||||
"@fontsource/lexend-deca": "4.4.5",
|
||||
"@fontsource/montserrat": "4.4.5",
|
||||
"@material-ui/core": "5.0.0-beta.0",
|
||||
"@material-ui/icons": "5.0.0-beta.0",
|
||||
"react": "17.0.2",
|
||||
|
||||
@@ -6,10 +6,15 @@ import StarIcon from '@material-ui/icons/Star';
|
||||
import StarIcon2 from '@material-ui/icons/StarBorder';
|
||||
|
||||
export default class Favourite extends React.PureComponent {
|
||||
buttons = {
|
||||
favourited: <StarIcon onClick={this.favourite} className='topicons' />,
|
||||
unfavourited: <StarIcon2 onClick={this.favourite} className='topicons' />
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
favourited: (localStorage.getItem('favourite')) ? <StarIcon onClick={this.favourite} className='topicons' /> : <StarIcon2 onClick={this.favourite} className='topicons' />
|
||||
favourited: (localStorage.getItem('favourite')) ? this.buttons.favourited : this.buttons.unfavourited
|
||||
};
|
||||
}
|
||||
|
||||
@@ -17,7 +22,7 @@ export default class Favourite extends React.PureComponent {
|
||||
if (localStorage.getItem('favourite')) {
|
||||
localStorage.removeItem('favourite');
|
||||
this.setState({
|
||||
favourited: <StarIcon2 onClick={this.favourite} className='topicons' />
|
||||
favourited: this.buttons.unfavourited
|
||||
});
|
||||
window.stats.postEvent('feature', 'Background favourite');
|
||||
} else {
|
||||
@@ -36,7 +41,7 @@ export default class Favourite extends React.PureComponent {
|
||||
}));
|
||||
|
||||
this.setState({
|
||||
favourited: <StarIcon onClick={this.favourite} className='topicons' />
|
||||
favourited: this.buttons.favourited
|
||||
});
|
||||
window.stats.postEvent('feature', 'Background unfavourite');
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@ export default class Notes extends React.PureComponent {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
notes: localStorage.getItem('notes') || ''
|
||||
notes: localStorage.getItem('notes') || '',
|
||||
visibility: (localStorage.getItem('notesPinned') === 'true') ? 'visible' : 'hidden'
|
||||
};
|
||||
this.language = window.language.widgets.navbar.notes;
|
||||
}
|
||||
@@ -26,44 +27,42 @@ export default class Notes extends React.PureComponent {
|
||||
|
||||
pin() {
|
||||
window.stats.postEvent('feature', 'Notes pin');
|
||||
document.getElementById('noteContainer').classList.toggle('visibilityshow');
|
||||
|
||||
if (localStorage.getItem('notesPinned') === 'true') {
|
||||
localStorage.setItem('notesPinned', false);
|
||||
this.setState({
|
||||
visibility: 'hidden'
|
||||
});
|
||||
} else {
|
||||
localStorage.setItem('notesPinned', true);
|
||||
this.setState({
|
||||
visibility: 'visible'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
copy() {
|
||||
window.stats.postEvent('feature', 'Notes copied');
|
||||
// this.state.notes doesn't work for some reason
|
||||
navigator.clipboard.writeText(localStorage.getItem('notes'));
|
||||
navigator.clipboard.writeText(this.state.notes);
|
||||
toast(window.language.toasts.notes);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const noteContainer = document.getElementById('noteContainer');
|
||||
|
||||
if (localStorage.getItem('notesPinned') === 'true') {
|
||||
noteContainer.classList.toggle('visibilityshow');
|
||||
}
|
||||
|
||||
if (localStorage.getItem('refresh') === 'false') {
|
||||
noteContainer.style.marginLeft = '-200px';
|
||||
document.getElementById('noteContainer').style.marginLeft = '-200px';
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<span id='noteContainer' className='notescontainer'>
|
||||
<span id='noteContainer' className='notescontainer' style={{ visibility: this.state.visibility }}>
|
||||
<div className='topbarnotes'>
|
||||
<NotesIcon/>
|
||||
<h3>{this.language.title}</h3>
|
||||
</div>
|
||||
<TextareaAutosize rowsmax={50} placeholder={this.language.placeholder} value={this.state.notes} onChange={this.setNotes}/>
|
||||
<button onClick={this.pin} className='pinNote'><Pin/></button>
|
||||
<button onClick={this.copy} className='copyNote'><CopyIcon/></button>
|
||||
<button onClick={() => this.pin()} className='pinNote'><Pin/></button>
|
||||
<button onClick={() => this.copy()} className='copyNote'><CopyIcon/></button>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
}
|
||||
|
||||
&:hover .notescontainer {
|
||||
visibility: visible;
|
||||
visibility: visible !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,3 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.visibilityshow {
|
||||
visibility: visible !important;
|
||||
}
|
||||
|
||||
@@ -99,6 +99,15 @@ export default class QuickLinks extends React.PureComponent {
|
||||
}
|
||||
}
|
||||
|
||||
// widget zoom
|
||||
setZoom(element) {
|
||||
const images = element.getElementsByTagName('img');
|
||||
for (const img of images) {
|
||||
img.style.height = `${0.87 * Number((localStorage.getItem('zoomQuicklinks') || 100) / 100)}em`;
|
||||
};
|
||||
element.querySelector('button').style.fontSize = `${1.15 * Number((localStorage.getItem('zoomQuicklinks') || 100) / 100)}em`;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (localStorage.getItem('offlineMode') === 'true') {
|
||||
return;
|
||||
@@ -113,11 +122,7 @@ export default class QuickLinks extends React.PureComponent {
|
||||
}
|
||||
|
||||
element.style.display = 'block';
|
||||
const images = element.getElementsByTagName('img');
|
||||
for (const img of images) {
|
||||
img.style.height = `${0.87 * Number((localStorage.getItem('zoomQuicklinks') || 100) / 100)}em`;
|
||||
};
|
||||
element.querySelector('button').style.fontSize = `${1.15 * Number((localStorage.getItem('zoomQuicklinks') || 100) / 100)}em`;
|
||||
this.setZoom(element);
|
||||
|
||||
this.setState({
|
||||
items: JSON.parse(localStorage.getItem('quicklinks'))
|
||||
@@ -135,12 +140,7 @@ export default class QuickLinks extends React.PureComponent {
|
||||
}
|
||||
};
|
||||
|
||||
const element = document.querySelector('.quicklinks-container');
|
||||
const images = element.getElementsByTagName('img');
|
||||
for (const img of images) {
|
||||
img.style.height = `${0.87 * Number((localStorage.getItem('zoomQuicklinks') || 100) / 100)}em`;
|
||||
};
|
||||
element.querySelector('button').style.fontSize = `${1.15 * Number((localStorage.getItem('zoomQuicklinks') || 100) / 100)}em`;
|
||||
this.setZoom(document.querySelector('.quicklinks-container'));
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
|
||||
@@ -12,23 +12,35 @@ import { toast } from 'react-toastify';
|
||||
import './quote.scss';
|
||||
|
||||
export default class Quote extends React.PureComponent {
|
||||
buttons = {
|
||||
tweet: <TwitterIcon className='copyButton' onClick={() => this.tweetQuote()} />,
|
||||
copy: <FileCopy className='copyButton' onClick={() => this.copyQuote()} />,
|
||||
unfavourited: <StarIcon2 className='copyButton' onClick={() => this.favourite()} />,
|
||||
favourited: <StarIcon className='copyButton' onClick={() => this.favourite()} />
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
quote: '',
|
||||
author: '',
|
||||
favourited: <StarIcon2 className='copyButton' onClick={this.favourite} />,
|
||||
tweet: '',
|
||||
copy: '',
|
||||
quoteLanguage: ''
|
||||
};
|
||||
this.buttons = {
|
||||
tweet: <TwitterIcon className='copyButton' onClick={this.tweetQuote} />,
|
||||
copy: <FileCopy className='copyButton' onClick={this.copyQuote} />
|
||||
favourited: this.useFavourite(),
|
||||
tweet: (localStorage.getItem('tweetButton') === 'false') ? null : this.buttons.tweet,
|
||||
copy: (localStorage.getItem('copyButton') === 'false') ? null : this.buttons.copy,
|
||||
quoteLanguage: '',
|
||||
type: localStorage.getItem('quoteType') || 'api'
|
||||
};
|
||||
this.language = window.language.widgets.quote;
|
||||
}
|
||||
|
||||
useFavourite() {
|
||||
let favouriteQuote = null;
|
||||
if (localStorage.getItem('favouriteQuoteEnabled') === 'true') {
|
||||
favouriteQuote = localStorage.getItem('favouriteQuote') ? this.buttons.favourited : this.buttons.unfavourited;
|
||||
}
|
||||
return favouriteQuote;
|
||||
}
|
||||
|
||||
doOffline() {
|
||||
const quotes = require('./offline_quotes.json');
|
||||
|
||||
@@ -63,7 +75,7 @@ export default class Quote extends React.PureComponent {
|
||||
});
|
||||
}
|
||||
|
||||
switch (localStorage.getItem('quoteType') || 'api') {
|
||||
switch (this.state.type) {
|
||||
case 'custom':
|
||||
const customQuote = localStorage.getItem('customQuote');
|
||||
const customQuoteAuthor = localStorage.getItem('customQuoteAuthor');
|
||||
@@ -72,8 +84,7 @@ export default class Quote extends React.PureComponent {
|
||||
return this.setState({
|
||||
quote: '"' + customQuote + '"',
|
||||
author: customQuoteAuthor,
|
||||
authorlink: this.getAuthorLink(customQuote),
|
||||
type: 'custom'
|
||||
authorlink: this.getAuthorLink(customQuote)
|
||||
});
|
||||
}
|
||||
break;
|
||||
@@ -91,8 +102,7 @@ export default class Quote extends React.PureComponent {
|
||||
return this.setState({
|
||||
quote: '"' + data[quotePackAPI.quote] + '"',
|
||||
author: author,
|
||||
authorlink: this.getAuthorLink(author),
|
||||
type: 'quote_pack'
|
||||
authorlink: this.getAuthorLink(author)
|
||||
});
|
||||
} catch (e) {
|
||||
return this.doOffline();
|
||||
@@ -109,8 +119,7 @@ export default class Quote extends React.PureComponent {
|
||||
return this.setState({
|
||||
quote: '"' + data.quote + '"',
|
||||
author: data.author,
|
||||
authorlink: this.getAuthorLink(data.author),
|
||||
type: 'quote_pack'
|
||||
authorlink: this.getAuthorLink(data.author)
|
||||
});
|
||||
} else {
|
||||
return this.doOffline();
|
||||
@@ -136,8 +145,7 @@ export default class Quote extends React.PureComponent {
|
||||
quote: '"' + data.quote + '"',
|
||||
author: data.author,
|
||||
authorlink: this.getAuthorLink(data.author),
|
||||
quoteLanguage: quotelanguage,
|
||||
type: 'api'
|
||||
quoteLanguage: quotelanguage
|
||||
});
|
||||
} catch (e) {
|
||||
// ..and if that fails we load one locally
|
||||
@@ -149,27 +157,27 @@ export default class Quote extends React.PureComponent {
|
||||
}
|
||||
}
|
||||
|
||||
copyQuote = () => {
|
||||
copyQuote() {
|
||||
window.stats.postEvent('feature', 'Quote copied');
|
||||
navigator.clipboard.writeText(`${this.state.quote} - ${this.state.author}`);
|
||||
toast(window.language.toasts.quote);
|
||||
}
|
||||
|
||||
tweetQuote = () => {
|
||||
tweetQuote() {
|
||||
window.stats.postEvent('feature', 'Quote tweet');
|
||||
window.open(`https://twitter.com/intent/tweet?text=${this.state.quote} - ${this.state.author} on @getmue`, '_blank').focus();
|
||||
}
|
||||
|
||||
favourite = () => {
|
||||
favourite() {
|
||||
if (localStorage.getItem('favouriteQuote')) {
|
||||
localStorage.removeItem('favouriteQuote');
|
||||
this.setState({
|
||||
favourited: <StarIcon2 className='copyButton' onClick={this.favourite} />
|
||||
favourited: this.buttons.unfavourited
|
||||
});
|
||||
} else {
|
||||
localStorage.setItem('favouriteQuote', this.state.quote + ' - ' + this.state.author);
|
||||
this.setState({
|
||||
favourited: <StarIcon className='copyButton' onClick={this.favourite} />
|
||||
favourited: this.buttons.favourited
|
||||
});
|
||||
}
|
||||
|
||||
@@ -177,16 +185,7 @@ export default class Quote extends React.PureComponent {
|
||||
}
|
||||
|
||||
init() {
|
||||
let favouriteQuote = '';
|
||||
if (localStorage.getItem('favouriteQuoteEnabled') === 'true') {
|
||||
favouriteQuote = localStorage.getItem('favouriteQuote') ? <StarIcon className='copyButton' onClick={this.favourite} /> : <StarIcon2 className='copyButton' onClick={this.favourite} />;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
favourited: favouriteQuote,
|
||||
copy: (localStorage.getItem('copyButton') === 'false') ? null : this.buttons.copy,
|
||||
tweet: (localStorage.getItem('tweetButton') === 'false') ? null : this.buttons.tweet
|
||||
});
|
||||
this.setZoom();
|
||||
|
||||
const quoteType = localStorage.getItem('quoteType');
|
||||
|
||||
@@ -196,6 +195,11 @@ export default class Quote extends React.PureComponent {
|
||||
}
|
||||
}
|
||||
|
||||
setZoom() {
|
||||
document.querySelector('.quote').style.fontSize = `${0.8 * Number((localStorage.getItem('zoomQuote') || 100) / 100)}em`;
|
||||
document.querySelector('.quoteauthor').style.fontSize = `${0.9 * Number((localStorage.getItem('zoomQuote') || 100) / 100)}em`;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
EventBus.on('refresh', (data) => {
|
||||
if (data === 'quote') {
|
||||
@@ -206,8 +210,6 @@ export default class Quote extends React.PureComponent {
|
||||
}
|
||||
|
||||
element.style.display = 'block';
|
||||
document.querySelector('.quote').style.fontSize = `${0.8 * Number((localStorage.getItem('zoomQuote') || 100) / 100)}em`;
|
||||
document.querySelector('.quoteauthor').style.fontSize = `${0.9 * Number((localStorage.getItem('zoomQuote') || 100) / 100)}em`;
|
||||
this.init();
|
||||
}
|
||||
|
||||
@@ -217,10 +219,9 @@ export default class Quote extends React.PureComponent {
|
||||
}
|
||||
});
|
||||
|
||||
document.querySelector('.quote').style.fontSize = `${0.8 * Number((localStorage.getItem('zoomQuote') || 100) / 100)}em`;
|
||||
document.querySelector('.quoteauthor').style.fontSize = `${0.9 * Number((localStorage.getItem('zoomQuote') || 100) / 100)}em`;
|
||||
|
||||
this.init();
|
||||
// don't bother with the checks if we're loading for the first time
|
||||
this.setZoom();
|
||||
this.getQuote();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
@@ -230,7 +231,7 @@ export default class Quote extends React.PureComponent {
|
||||
render() {
|
||||
return (
|
||||
<div className='quotediv'>
|
||||
<h1 className='quote'>{`${this.state.quote}`}</h1>
|
||||
<h1 className='quote'>{this.state.quote}</h1>
|
||||
<h1 className='quoteauthor'>
|
||||
<a href={this.state.authorlink} className='quoteauthorlink' target='_blank' rel='noopener noreferrer'>{this.state.author}</a>
|
||||
<br/>
|
||||
|
||||
@@ -65,9 +65,9 @@ export default class Search extends React.PureComponent {
|
||||
async getSuggestions(input) {
|
||||
window.setResults = (results) => {
|
||||
window.searchResults = results;
|
||||
}
|
||||
};
|
||||
|
||||
const script = document.createElement('script')
|
||||
const script = document.createElement('script');
|
||||
script.src = `${this.state.autocompleteURL + this.state.autocompleteQuery + input}&${this.state.autocompleteCallback}=window.setResults`;
|
||||
document.head.appendChild(script);
|
||||
|
||||
@@ -82,9 +82,8 @@ export default class Search extends React.PureComponent {
|
||||
}
|
||||
|
||||
init() {
|
||||
let url;
|
||||
let url, microphone;
|
||||
let query = 'q';
|
||||
let microphone = null;
|
||||
|
||||
const setting = localStorage.getItem('searchEngine');
|
||||
const info = searchEngines.find((i) => i.settingsName === setting);
|
||||
@@ -104,9 +103,7 @@ export default class Search extends React.PureComponent {
|
||||
microphone = <MicIcon className='micIcon' onClick={this.startSpeechRecognition}/>;
|
||||
}
|
||||
|
||||
let autocompleteURL;
|
||||
let autocompleteQuery;
|
||||
let autocompleteCallback;
|
||||
let autocompleteURL, autocompleteQuery, autocompleteCallback;
|
||||
|
||||
if (localStorage.getItem('autocomplete') === 'true') {
|
||||
const info = autocompleteProviders.find((i) => i.value === localStorage.getItem('autocompleteProvider'));
|
||||
|
||||
@@ -11,7 +11,7 @@ export default class DateWidget extends React.PureComponent {
|
||||
super();
|
||||
this.state = {
|
||||
date: '',
|
||||
weekNumber: ''
|
||||
weekNumber: null
|
||||
};
|
||||
}
|
||||
|
||||
@@ -37,6 +37,10 @@ export default class DateWidget extends React.PureComponent {
|
||||
|
||||
if (localStorage.getItem('weeknumber') === 'true') {
|
||||
this.getWeekNumber(date);
|
||||
} else if (this.state.weekNumber !== null) {
|
||||
this.setState({
|
||||
weekNumber: null
|
||||
});
|
||||
}
|
||||
|
||||
if (localStorage.getItem('dateType') === 'short') {
|
||||
@@ -60,7 +64,8 @@ export default class DateWidget extends React.PureComponent {
|
||||
year = dateDay;
|
||||
break;
|
||||
// DMY
|
||||
default: break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
let format;
|
||||
@@ -77,7 +82,8 @@ export default class DateWidget extends React.PureComponent {
|
||||
case 'slashes':
|
||||
format = `${day}/${month}/${year}`;
|
||||
break;
|
||||
default: break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
|
||||
@@ -90,7 +90,8 @@ export default class Weather extends React.PureComponent {
|
||||
temp_text = '°F';
|
||||
break;
|
||||
// kelvin
|
||||
default: break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
|
||||
Reference in New Issue
Block a user