mirror of
https://github.com/mue/mue.git
synced 2026-07-13 20:13:47 +02:00
4.0
Co-authored-by: Alex Sparkes <turbomarshmello@gmail.com> Co-authored-by: Wessel Tip <discord@go2it.eu> Co-authored-by: Isaac Saunders <contact@eartharoid.me>
This commit is contained in:
@@ -1,18 +0,0 @@
|
||||
/* eslint-disable jsx-a11y/heading-has-content */
|
||||
import RoomIcon from '@material-ui/icons/Room';
|
||||
import React from 'react';
|
||||
|
||||
export default class Credit extends React.PureComponent {
|
||||
render() {
|
||||
return (
|
||||
<div className='credits'>
|
||||
{/*<h1 id='location'></h1>*/}
|
||||
<h1 id='photographer'>{this.props.language}</h1>
|
||||
<div id='backgroundCredits' className='tooltip'>
|
||||
<RoomIcon className='locationicon'/>
|
||||
<span className='tooltiptext' id='location'/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,18 @@
|
||||
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 React from 'react';
|
||||
|
||||
export default class Navbar extends React.PureComponent {
|
||||
render() {
|
||||
let refreshHTML = <div className='navbar2'><RefreshIcon className='refreshicon' onClick={() => window.location.reload()} /></div>
|
||||
let refreshHTML = <div className='navbar2' ><RefreshIcon className='refreshicon' onClick={() => window.location.reload()} /></div>
|
||||
const refresh = localStorage.getItem('refresh');
|
||||
if (refresh === 'false') refreshHTML = '';
|
||||
|
||||
const viewedUpdate = localStorage.getItem('viewedUpdate');
|
||||
let update = <NewReleases className='refreshicon' onClick={this.props.updateModalOpen} />;
|
||||
if (viewedUpdate === 'false') update = <NewReleases className='refreshicon' onClick={this.props.updateModalOpen} />
|
||||
|
||||
return (
|
||||
<div className='navbar-container'>
|
||||
<div className='navbar1'>
|
||||
@@ -16,7 +20,7 @@ export default class Navbar extends React.PureComponent {
|
||||
</div>
|
||||
{refreshHTML}
|
||||
<div className={refresh === 'false' ? 'navbar2' : 'navbar3'}>
|
||||
<NewReleases className='refreshicon' onClick={this.props.updateModalOpen} />
|
||||
{update}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
export default class Search extends React.PureComponent {
|
||||
render() {
|
||||
if (localStorage.getItem('searchBar') === 'false') return <div></div>;
|
||||
|
||||
let url;
|
||||
|
||||
switch (localStorage.getItem('searchEngine')) {
|
||||
case 'duckduckgo': url = 'https://duckduckgo.com'; break;
|
||||
case 'google': url = 'https://google.com/search'; break;
|
||||
case 'bing': url = 'https://bing.com/search'; break;
|
||||
default: url = 'https://duckduckgo.com'; break;
|
||||
}
|
||||
|
||||
return <div id='searchBar' className='searchbar'>
|
||||
<form id='searchBar' className='searchbarform' action={url}>
|
||||
<input type='text' placeholder={this.props.language} name='q' id='searchtext' className='searchtext'/>
|
||||
<div className='blursearcbBG'/>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
143
src/components/modals/Addons.jsx
Normal file
143
src/components/modals/Addons.jsx
Normal file
@@ -0,0 +1,143 @@
|
||||
import React from 'react';
|
||||
import LocalMallIcon from '@material-ui/icons/LocalMall';
|
||||
import { toast } from 'react-toastify';
|
||||
import dtf from '@eartharoid/dtf';
|
||||
import Item from './marketplace/Item';
|
||||
import MarketplaceFunctions from '../../modules/marketplaceFunctions';
|
||||
|
||||
export default class Addons extends React.PureComponent {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
this.state = {
|
||||
installed: [],
|
||||
item_data: {
|
||||
name: 'Name',
|
||||
author: 'Author',
|
||||
description: 'Description',
|
||||
updated: '???',
|
||||
version: '1.0.0',
|
||||
icon: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async toggle(type, type2, data) {
|
||||
if (type === 'item') {
|
||||
let installed = JSON.parse(localStorage.getItem('installed'));
|
||||
let info = installed.find(i => i.name === data).content;
|
||||
this.setState({
|
||||
current_data: { type: type2, name: data, content: info },
|
||||
item_data: {
|
||||
name: info.data.name,
|
||||
author: info.data.author,
|
||||
description: MarketplaceFunctions.urlParser(info.data.description.replace(/\n/g, '<br>')),
|
||||
updated: dtf('n_D MMM YYYY', info.updated, 'en-GB'),
|
||||
version: info.data.version,
|
||||
icon: info.data.screenshot_url
|
||||
}
|
||||
});
|
||||
document.getElementById('marketplace').style.display = 'none';
|
||||
document.getElementById('item').style.display = 'block';
|
||||
} else {
|
||||
document.getElementById('marketplace').style.display = 'block';
|
||||
document.getElementById('item').style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
uninstall() {
|
||||
let installed = JSON.parse(localStorage.getItem('installed'));
|
||||
|
||||
const uninstallStuff = () => {
|
||||
for (let i = 0; i < installed.length; i++) {
|
||||
if (installed[i].name === this.state.current_data.name) {
|
||||
installed.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
localStorage.setItem('installed', JSON.stringify(installed));
|
||||
toast(this.props.toastLanguage.removed);
|
||||
this.toggle();
|
||||
this.componentDidMount();
|
||||
}
|
||||
|
||||
switch (this.state.current_data.type) {
|
||||
case 'settings':
|
||||
let oldSettings = JSON.parse(localStorage.getItem('backup_settings'));
|
||||
localStorage.clear();
|
||||
oldSettings.forEach(item => localStorage.setItem(item.name, item.value));
|
||||
uninstallStuff();
|
||||
break;
|
||||
default:
|
||||
try {
|
||||
localStorage.removeItem(this.state.current_data.type);
|
||||
uninstallStuff();
|
||||
} catch (e) {
|
||||
console.log('invalid');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
document.getElementById('backgroundImage').classList.toggle('backgroundEffects');
|
||||
document.getElementById('center').classList.toggle('backgroundEffects');
|
||||
this.setState({ installed: JSON.parse(localStorage.getItem('installed')) });
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
document.getElementById('backgroundImage').classList.toggle('backgroundEffects');
|
||||
document.getElementById('center').classList.toggle('backgroundEffects');
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.installed.length === 0) {
|
||||
return <div className='content'>
|
||||
<span className='closeModal' onClick={this.props.modalClose}>×</span>
|
||||
<h1>{this.props.modalLanguage.title}</h1>
|
||||
<div className="tab">
|
||||
<button className="tablinks" onClick={this.props.openMarketplace}>{this.props.modalLanguage.marketplace}</button>
|
||||
<button className="tablinks" id="active">{this.props.modalLanguage.addons}</button>
|
||||
<button className="tablinks" onClick={this.props.openSettings}>{this.props.modalLanguage.settings}</button>
|
||||
</div>
|
||||
<div id='marketplace'>
|
||||
{ /*<input id='file-input' type='file' name='name' className='hidden' />
|
||||
<button className='addToMue sideload' onClick={() => document.getElementById('file-input').click()}>Sideload</button> */}
|
||||
<h1>{this.props.language.added}</h1>
|
||||
<div className="items">
|
||||
<div className="emptyMessage">
|
||||
<LocalMallIcon />
|
||||
<h1>{this.props.language.empty.title}</h1>
|
||||
<p className="description">{this.props.language.empty.description}</p>
|
||||
<button className="goToMarket" onClick={this.props.openMarketplace}>{this.props.language.empty.button}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
return <div className='content'>
|
||||
<span className='closeModal' onClick={this.props.modalClose}>×</span>
|
||||
<h1>{this.props.modalLanguage.title}</h1>
|
||||
<div className="tab">
|
||||
<button className="tablinks" onClick={this.props.openMarketplace}>{this.props.modalLanguage.marketplace}</button>
|
||||
<button className="tablinks" id="active">{this.props.modalLanguage.addons}</button>
|
||||
<button className="tablinks" onClick={this.props.openSettings}>{this.props.modalLanguage.settings}</button>
|
||||
</div>
|
||||
<div id='marketplace'>
|
||||
{ /*<input id='file-input' type='file' name='name' className='hidden' />
|
||||
<button className='addToMue sideload' onClick={() => document.getElementById('file-input').click()}>Sideload</button> */}
|
||||
<h1>{this.props.language.added}</h1>
|
||||
<div className="items">
|
||||
{this.state.installed.map((item) =>
|
||||
<div className="item" onClick={()=> this.toggle('item', item.type, item.name)}>
|
||||
<img alt="icon" src={item.content.data.icon_url} />
|
||||
<div className="details">
|
||||
<h4>{item.content.data.name}</h4>
|
||||
<p>{item.content.data.author}</p>
|
||||
</div>
|
||||
</div>)}
|
||||
</div>
|
||||
</div>
|
||||
<Item button={<button className="removeFromMue" onClick={() => this.uninstall()}>{this.props.language.product.buttons.remove}</button>} data={this.state.item_data} function={()=> this.toggle()} language={this.props.language.product} />
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
265
src/components/modals/Marketplace.jsx
Normal file
265
src/components/modals/Marketplace.jsx
Normal file
@@ -0,0 +1,265 @@
|
||||
import React from 'react';
|
||||
import WifiOffIcon from '@material-ui/icons/WifiOff';
|
||||
import ArrowBackIcon from '@material-ui/icons/ArrowBack';
|
||||
import { toast } from 'react-toastify';
|
||||
import dtf from '@eartharoid/dtf';
|
||||
import Item from './marketplace/Item';
|
||||
import MarketplaceFunctions from '../../modules/marketplaceFunctions';
|
||||
import * as Constants from '../../modules/constants';
|
||||
import Items from './marketplace/Items';
|
||||
|
||||
export default class Marketplace extends React.PureComponent {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
this.state = {
|
||||
themes: [],
|
||||
settings: [],
|
||||
photo_packs: [],
|
||||
quote_packs: [],
|
||||
see_more: [],
|
||||
see_more_type: '',
|
||||
current_data: {
|
||||
type: '',
|
||||
name: '',
|
||||
content: {}
|
||||
},
|
||||
button: '',
|
||||
featured: {},
|
||||
done: false,
|
||||
item_data: {
|
||||
name: 'Name',
|
||||
author: 'Author',
|
||||
description: 'Description',
|
||||
updated: '???',
|
||||
version: '1.0.0',
|
||||
icon: ''
|
||||
}
|
||||
}
|
||||
|
||||
this.offlineHTML = <div className='content'>
|
||||
<span className='closeModal' onClick={this.props.modalClose}>×</span>
|
||||
<h1>{this.props.modalLanguage.title}</h1>
|
||||
<div className="tab">
|
||||
<button className="tablinks" id="active">{this.props.modalLanguage.marketplace}</button>
|
||||
<button className="tablinks" onClick={this.props.openAddons}>{this.props.modalLanguage.addons}</button>
|
||||
<button className="tablinks"
|
||||
onClick={this.props.openSettings}>{this.props.modalLanguage.settings}</button>
|
||||
</div>
|
||||
<div id='marketplace'>
|
||||
<div className="emptyMessage" style={{"marginTop": "20px", "transform": "translateY(80%)"}}>
|
||||
<WifiOffIcon />
|
||||
<h1>{this.props.language.offline.title}</h1>
|
||||
<p className="description">{this.props.language.offline.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
|
||||
async toggle(type, type2, data) {
|
||||
if (type === 'seemore') {
|
||||
document.getElementById('marketplace').style.display = 'none';
|
||||
document.getElementById('seemore').style.display = 'block';
|
||||
return this.setState({
|
||||
see_more: this.state[type2],
|
||||
see_more_type: type2
|
||||
});
|
||||
}
|
||||
|
||||
if (type === 'item') {
|
||||
let info;
|
||||
try {
|
||||
info = await fetch(`${Constants.MARKETPLACE_URL}/item/${type2}/${data}`);
|
||||
info = await info.json();
|
||||
} catch (e) {
|
||||
return toast(this.props.toastLanguage.error);
|
||||
}
|
||||
|
||||
this.setState({
|
||||
current_data: { type: type2, name: data, content: info },
|
||||
item_data: {
|
||||
name: info.data.name,
|
||||
author: info.data.author,
|
||||
description: MarketplaceFunctions.urlParser(info.data.description.replace(/\n/g, '<br>')),
|
||||
updated: dtf('n_D MMM YYYY', info.updated, 'en-GB'),
|
||||
version: info.data.version,
|
||||
icon: info.data.screenshot_url
|
||||
}
|
||||
});
|
||||
document.getElementById('marketplace').style.display = 'none';
|
||||
document.getElementById('seemore').style.display = 'none';
|
||||
document.getElementById('item').style.display = 'block';
|
||||
|
||||
let button = <button className="addToMue" onClick={() => this.install()}>{this.props.language.product.buttons.addtomue}</button>;
|
||||
let installed = JSON.parse(localStorage.getItem('installed'));
|
||||
if (installed.some(item => item.name === data)) button = <button className="removeFromMue" onClick={() => this.uninstall()}>{this.props.language.product.buttons.remove}</button>;
|
||||
this.setState({ button: button });
|
||||
} else {
|
||||
document.getElementById('marketplace').style.display = 'block';
|
||||
document.getElementById('item').style.display = 'none';
|
||||
document.getElementById('seemore').style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
async getItems() {
|
||||
let data = await fetch(Constants.MARKETPLACE_URL + '/all');
|
||||
data = await data.json();
|
||||
let data2 = await fetch(Constants.MARKETPLACE_URL + '/featured');
|
||||
data2 = await data2.json();
|
||||
this.setState({
|
||||
themes: data.data.themes,
|
||||
settings: data.data.settings,
|
||||
photo_packs: data.data.photo_packs,
|
||||
quote_packs: data.data.quote_packs,
|
||||
see_more: data.data.photo_packs,
|
||||
featured: data2.data,
|
||||
done: true
|
||||
});
|
||||
}
|
||||
|
||||
async install() {
|
||||
let installed = JSON.parse(localStorage.getItem('installed'));
|
||||
let button;
|
||||
|
||||
const installStuff = () => {
|
||||
installed.push(this.state.current_data);
|
||||
localStorage.setItem('installed', JSON.stringify(installed));
|
||||
toast(this.props.toastLanguage.installed);
|
||||
button = <button className="removeFromMue" onClick={() => this.uninstall()}>{this.props.language.product.buttons.remove}</button>;
|
||||
this.setState({ button: button });
|
||||
}
|
||||
|
||||
switch (this.state.current_data.type) {
|
||||
case 'settings':
|
||||
localStorage.removeItem('backup_settings');
|
||||
let oldSettings = [];
|
||||
for (const key of Object.keys(localStorage)) oldSettings.push({name: key, value: localStorage.getItem(key)});
|
||||
localStorage.setItem('backup_settings', JSON.stringify(oldSettings));
|
||||
this.state.current_data.content.data.settings.forEach(element => localStorage.setItem(element.name, element.value));
|
||||
installStuff();
|
||||
break;
|
||||
case 'photo_packs':
|
||||
localStorage.setItem('photo_packs', JSON.stringify(this.state.current_data.content.data.photos));
|
||||
installStuff();
|
||||
break;
|
||||
case 'theme':
|
||||
localStorage.setItem('theme', this.state.current_data.content.data.theme);
|
||||
installStuff();
|
||||
break;
|
||||
case 'quote_packs':
|
||||
localStorage.setItem('quote_packs', JSON.stringify(this.state.current_data.content.data.quotes));
|
||||
installStuff();
|
||||
break;
|
||||
default:
|
||||
console.log('invalid');
|
||||
}
|
||||
}
|
||||
|
||||
uninstall() {
|
||||
let installed = JSON.parse(localStorage.getItem('installed'));
|
||||
let button;
|
||||
|
||||
const uninstallStuff = () => {
|
||||
for (let i = 0; i < installed.length; i++) {
|
||||
if (installed[i].name === this.state.current_data.name) {
|
||||
installed.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
localStorage.setItem('installed', JSON.stringify(installed));
|
||||
toast(this.props.toastLanguage.removed);
|
||||
button = <button className="addToMue" onClick={() => this.install()}>{this.props.language.product.buttons.addtomue}</button>;
|
||||
this.setState({ button: button });
|
||||
}
|
||||
|
||||
switch (this.state.current_data.type) {
|
||||
case 'settings':
|
||||
let oldSettings = JSON.parse(localStorage.getItem('backup_settings'));
|
||||
localStorage.clear();
|
||||
oldSettings.forEach(item => localStorage.setItem(item.name, item.value));
|
||||
uninstallStuff();
|
||||
break;
|
||||
default:
|
||||
try {
|
||||
localStorage.removeItem(this.state.current_data.type);
|
||||
uninstallStuff();
|
||||
} catch (e) {
|
||||
console.log('invalid');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
document.getElementById('backgroundImage').classList.toggle('backgroundEffects');
|
||||
document.getElementById('center').classList.toggle('backgroundEffects');
|
||||
if (navigator.onLine === false) return;
|
||||
this.getItems();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
document.getElementById('backgroundImage').classList.toggle('backgroundEffects');
|
||||
document.getElementById('center').classList.toggle('backgroundEffects');
|
||||
}
|
||||
|
||||
render() {
|
||||
if (navigator.onLine === false || this.state.done === false) {
|
||||
return this.offlineHTML;
|
||||
}
|
||||
|
||||
return <div className='content'>
|
||||
<span className='closeModal' onClick={this.props.modalClose}>×</span>
|
||||
<h1>{this.props.modalLanguage.title}</h1>
|
||||
<div className="tab">
|
||||
<button className="tablinks" id="active">{this.props.modalLanguage.marketplace}</button>
|
||||
<button className="tablinks" onClick={this.props.openAddons}>{this.props.modalLanguage.addons}</button>
|
||||
<button className="tablinks"
|
||||
onClick={this.props.openSettings}>{this.props.modalLanguage.settings}</button>
|
||||
</div>
|
||||
<div id='marketplace'>
|
||||
<div className="featured" style={{backgroundColor: this.state.featured.colour}}>
|
||||
<p>{this.state.featured.title}</p>
|
||||
<h1>{this.state.featured.name}</h1>
|
||||
<button className="addToMue" onClick={() => window.location.href =
|
||||
this.state.featured.buttonLink}>{this.state.featured.buttonText}</button>
|
||||
</div>
|
||||
<Items
|
||||
title={this.props.language.photo_packs}
|
||||
seeMoreTitle={this.props.language.see_more}
|
||||
items={this.state.photo_packs.slice(0, 3)}
|
||||
toggleFunction={(input) => this.toggle('item', 'photo_packs', input)}
|
||||
seeMore={true}
|
||||
seeMoreFunction={() => this.toggle('seemore', 'photo_packs')} />
|
||||
<Items
|
||||
title={this.props.language.preset_settings}
|
||||
seeMoreTitle={this.props.language.see_more}
|
||||
items={this.state.settings.slice(0, 3)}
|
||||
toggleFunction={(input) => this.toggle('item', 'settings', input)}
|
||||
seeMore={true}
|
||||
seeMoreFunction={() => this.toggle('seemore', 'settings')} />
|
||||
<Items
|
||||
title={this.props.language.quote_packs}
|
||||
seeMoreTitle={this.props.language.see_more}
|
||||
items={this.state.quote_packs.slice(0, 3)}
|
||||
toggleFunction={(input) => this.toggle('item', 'quote_packs', input)}
|
||||
seeMore={true}
|
||||
seeMoreFunction={() => this.toggle('seemore', 'quote_packs')} />
|
||||
<Items
|
||||
title={this.props.language.themes}
|
||||
seeMoreTitle={this.props.language.see_more}
|
||||
items={this.state.themes.slice(0, 3)}
|
||||
toggleFunction={(input) => this.toggle('item', 'theme', input)}
|
||||
seeMore={true}
|
||||
seeMoreFunction={() => this.toggle('seemore', 'themes')} />
|
||||
</div>
|
||||
<Item button={this.state.button} data={this.state.item_data} function={()=> this.toggle()} language={this.props.language.product} />
|
||||
<div id='seemore'>
|
||||
<ArrowBackIcon className='backArrow' onClick={() => this.toggle()} />
|
||||
<Items
|
||||
title={this.props.language.see_more}
|
||||
seeMoreTitle={this.props.language.see_more}
|
||||
toggleFunction={(input) => this.toggle('item', this.state.see_more_type, input)}
|
||||
items={this.state.see_more}
|
||||
/>
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import ExpandMore from '@material-ui/icons/ExpandMore';
|
||||
import * as SettingsFunctions from '../modules/settingsFunctions';
|
||||
import SettingsFunctions from '../../modules/settingsFunctions';
|
||||
import Checkbox from './settings/Checkbox';
|
||||
import Slider from './settings/Slider';
|
||||
import { toast } from 'react-toastify';
|
||||
@@ -22,7 +22,7 @@ export default class Settings extends React.PureComponent {
|
||||
case 'customSearchEngine': document.getElementById('searchEngine').value = 'DuckDuckGo'; break;
|
||||
default: console.log('[ERROR] resetItem requires a key!');
|
||||
}
|
||||
toast('Reset successfully!');
|
||||
toast(this.props.toastLanguage.reset);
|
||||
}
|
||||
|
||||
updateCurrent() {
|
||||
@@ -108,16 +108,9 @@ export default class Settings extends React.PureComponent {
|
||||
document.getElementById('customBackgroundHex').innerText = hex;
|
||||
}*/
|
||||
|
||||
|
||||
document.getElementById('backgroundImage').classList.toggle('backgroundEffects');
|
||||
document.getElementById('center').classList.toggle('backgroundEffects');
|
||||
|
||||
/* document.addEventListener('keyup', (event) => {
|
||||
if (event.keyCode === 13) this.saveStuff();
|
||||
if (event.keyCode === 27) {
|
||||
document.getElementById('root').classList.toggle('backgroundEffects');
|
||||
this.props.modalClose();
|
||||
}
|
||||
});*/
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
@@ -130,12 +123,17 @@ export default class Settings extends React.PureComponent {
|
||||
//if (localStorage.getItem('animations') === 'true') expandClassList = 'all 0.5 ease 0s';
|
||||
|
||||
return <div className='content'>
|
||||
<span className='closeModal' onClick={this.props.modalClose}>×</span>
|
||||
<h1>{this.props.language.title}</h1>
|
||||
<p>{this.props.language.description}</p>
|
||||
<span className='closeModal' onClick={this.props.modalClose}>×</span>
|
||||
<h1>{this.props.modalLanguage.title}</h1>
|
||||
<div className="tab">
|
||||
<button className="tablinks" onClick={this.props.openMarketplace}>{this.props.modalLanguage.marketplace}</button>
|
||||
<button className="tablinks" onClick={this.props.openAddons}>{this.props.modalLanguage.addons}</button>
|
||||
<button className="tablinks" id="active">{this.props.modalLanguage.settings}</button>
|
||||
</div>
|
||||
<br />
|
||||
<div className='columns'>
|
||||
<div className='section'>
|
||||
<h4>{this.props.language.time.title}</h4>
|
||||
<h4 onClick={() => SettingsFunctions.toggleExtra(document.getElementsByClassName('extraSettings')[0], document.getElementsByClassName('expandIcons')[0])}>{this.props.language.time.title}</h4>
|
||||
<ExpandMore style={{ 'transition': 'all 0.5s ease 0s' }} className='expandIcons' onClick={() => SettingsFunctions.toggleExtra(document.getElementsByClassName('extraSettings')[0], document.getElementsByClassName('expandIcons')[0])} />
|
||||
<Slider name='time' />
|
||||
<li className='extraSettings'>
|
||||
@@ -147,7 +145,7 @@ export default class Settings extends React.PureComponent {
|
||||
</li>
|
||||
</div>
|
||||
<div className='section'>
|
||||
<h4>{this.props.language.greeting.title}</h4>
|
||||
<h4 onClick={() => SettingsFunctions.toggleExtra(document.getElementsByClassName('extraSettings')[1], document.getElementsByClassName('expandIcons')[1])}>{this.props.language.greeting.title}</h4>
|
||||
<ExpandMore style={{ 'transition': 'all 0.5s ease 0s' }} className='expandIcons' onClick={() => SettingsFunctions.toggleExtra(document.getElementsByClassName('extraSettings')[1], document.getElementsByClassName('expandIcons')[1])} />
|
||||
<Slider name='greeting' />
|
||||
<li className='extraSettings'>
|
||||
@@ -160,7 +158,7 @@ export default class Settings extends React.PureComponent {
|
||||
</li>
|
||||
</div>
|
||||
<div className='section'>
|
||||
<h4>{this.props.language.quote.title}</h4>
|
||||
<h4 onClick={() => SettingsFunctions.toggleExtra(document.getElementsByClassName('extraSettings')[2], document.getElementsByClassName('expandIcons')[2])}>{this.props.language.quote.title}</h4>
|
||||
<ExpandMore style={{ 'transition': 'all 0.5s ease 0s' }} className='expandIcons' onClick={() => SettingsFunctions.toggleExtra(document.getElementsByClassName('extraSettings')[2], document.getElementsByClassName('expandIcons')[2])} />
|
||||
<Slider name='quote' />
|
||||
<li className='extraSettings'>
|
||||
@@ -168,7 +166,7 @@ export default class Settings extends React.PureComponent {
|
||||
</li>
|
||||
</div>
|
||||
<div className='section'>
|
||||
<h4>{this.props.language.background.title}</h4>
|
||||
<h4 onClick={() => SettingsFunctions.toggleExtra(document.getElementsByClassName('extraSettings')[3], document.getElementsByClassName('expandIcons')[3])}>{this.props.language.background.title}</h4>
|
||||
<ExpandMore style={{ 'transition': 'all 0.5s ease 0s' }} className='expandIcons' onClick={() => SettingsFunctions.toggleExtra(document.getElementsByClassName('extraSettings')[3], document.getElementsByClassName('expandIcons')[3])} />
|
||||
<Slider name='background' override='customBackground' />
|
||||
<li className='extraSettings'>
|
||||
@@ -203,7 +201,7 @@ export default class Settings extends React.PureComponent {
|
||||
</li>
|
||||
</div>
|
||||
<div className='section'>
|
||||
<h4>{this.props.language.searchbar.title}</h4>
|
||||
<h4 onClick={() => SettingsFunctions.toggleExtra(document.getElementsByClassName('extraSettings')[4], document.getElementsByClassName('expandIcons')[4])}>{this.props.language.searchbar.title}</h4>
|
||||
<ExpandMore style={{ 'transition': 'all 0.5s ease 0s' }} className='expandIcons' onClick={() => SettingsFunctions.toggleExtra(document.getElementsByClassName('extraSettings')[4], document.getElementsByClassName('expandIcons')[4])} />
|
||||
<Slider name='searchBar' />
|
||||
<li className='extraSettings'>
|
||||
@@ -213,11 +211,17 @@ export default class Settings extends React.PureComponent {
|
||||
<option value='duckduckgo'>DuckDuckGo</option>
|
||||
<option value='google'>Google</option>
|
||||
<option value='bing'>Bing</option>
|
||||
{ /* <option value='custom'>Custom</option> */ }
|
||||
<option value='yahoo'>Yahoo</option>
|
||||
<option value='ecosia'>Ecosia</option>
|
||||
<option value='yandex'>Yandex</option>
|
||||
<option value='qwant'>Qwant</option>
|
||||
<option value='ask'>Ask</option>
|
||||
<option value='startpage'>Startpage</option>
|
||||
{/* <option value='custom'>Custom</option> */}
|
||||
</select>
|
||||
</ul>
|
||||
<ul id='searchEngineInput' style={{ display: 'none' }}>
|
||||
<p>Custom Search URL <span className='modalLink' onClick={() => this.resetItem('customSearchEngine')}>Reset</span></p>
|
||||
<p style={{"marginTop": "0px"}}>Custom Search URL <span className='modalLink' onClick={() => this.resetItem('customSearchEngine')}>Reset</span></p>
|
||||
<input type='text' id='customSearchEngine'></input>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -243,8 +247,10 @@ export default class Settings extends React.PureComponent {
|
||||
<h4 htmlFor='9'>{this.props.language.language} </h4>
|
||||
<select className='select-css' name='9' id='language' onChange={() => localStorage.setItem('language', document.getElementById('language').value)}>
|
||||
<option className='choices' value='en'>English</option>
|
||||
<option className='choices' value='nl'>Dutch</option>
|
||||
<option className='choices' value='fr'>French</option>
|
||||
<option className='choices' value='nl'>Nederlands</option>
|
||||
<option className='choices' value='fr'>Français</option>
|
||||
<option className='choices' value='no'>Norsk</option>
|
||||
<option className='choices' value='ru'>Russian</option>
|
||||
</select>
|
||||
</div>
|
||||
<button className='apply' onClick={() => SettingsFunctions.saveStuff()}>{this.props.language.apply}</button>
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import * as Constants from '../modules/constants';
|
||||
import * as Constants from '../../modules/constants';
|
||||
|
||||
export default class Update extends React.PureComponent {
|
||||
constructor(...args) {
|
||||
@@ -33,15 +33,18 @@ export default class Update extends React.PureComponent {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
localStorage.setItem('viewedUpdate', true);
|
||||
this.getUpdate();
|
||||
}
|
||||
|
||||
render() {
|
||||
return <div className='content'>
|
||||
return <div className='updateContent'>
|
||||
<span className='closeModal' onClick={this.props.modalClose}>×</span>
|
||||
<h1 style={{ 'marginBottom':'-10px' }} dangerouslySetInnerHTML={{__html: this.state.title}}></h1>
|
||||
<h5 style={{ 'lineHeight':'0px' }}> By Mue • <span dangerouslySetInnerHTML={{__html: this.state.date}}></span></h5>
|
||||
<p style={{ 'padding': '0px 20px 0px 20px' }} dangerouslySetInnerHTML={{__html: this.state.content}}></p>
|
||||
<img alt='update picture' src='https://i.redd.it/dtm7e7ggxxh51.png' />
|
||||
<figcaption>Image of JIF.</figcaption>
|
||||
<p dangerouslySetInnerHTML={{__html: this.state.content}}></p>
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
31
src/components/modals/Welcome.jsx
Normal file
31
src/components/modals/Welcome.jsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import React from 'react';
|
||||
import EmailIcon from '@material-ui/icons/Email';
|
||||
|
||||
export default class Welcome extends React.PureComponent {
|
||||
render() {
|
||||
return <div className='welcomeContent'>
|
||||
<span className='closeModal' onClick={this.props.modalClose}>×</span>
|
||||
<div className="welcomeModalText">
|
||||
<h2 className="subtitle">Welcome to</h2>
|
||||
<h1 className="welcometitle">Mue Tab</h1>
|
||||
<img alt="celebration" style={{"height": "200px", "width": "auto"}} src="./././icons/undraw_celebration.svg" />
|
||||
<h2 className="subtitle">Information</h2>
|
||||
<p>Thank you for downloading Mue Tab,<br/> we hope you enjoy your time with our extension.</p>
|
||||
<h2 className="subtitle">Tutorials</h2>
|
||||
<a href=''>General Start</a>
|
||||
<br/>
|
||||
<a href='https://blog.muetab.xyz/welcome-to-marketplace/'>Marketplace</a>
|
||||
<br/>
|
||||
<a href=''>Submitting Photos</a>
|
||||
<br/>
|
||||
<a href=''>Settings</a>
|
||||
<h2 className="subtitle">Support</h2>
|
||||
<img alt="twitter" href="https://twitter.com/getmue" className="icon" src="./././icons/iconmonstr-twitter.svg"/>
|
||||
<img alt="discord" href="https://discord.gg/kJsufA9" className="icon" src="https://cdn.discordapp.com/attachments/252071498397777921/747860127171739758/Discord-Logo-Black.svg"/>
|
||||
<EmailIcon />
|
||||
<br/>
|
||||
<button className="close" onClick={this.props.modalClose}>Close</button>
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
43
src/components/modals/marketplace/Item.jsx
Normal file
43
src/components/modals/marketplace/Item.jsx
Normal file
@@ -0,0 +1,43 @@
|
||||
import React from 'react';
|
||||
import ArrowBackIcon from '@material-ui/icons/ArrowBack';
|
||||
|
||||
export default class Item extends React.PureComponent {
|
||||
render() {
|
||||
return (
|
||||
<div id='item'>
|
||||
<br/>
|
||||
<ArrowBackIcon className='backArrow' onClick={this.props.function} />
|
||||
<br/>
|
||||
<h1>{this.props.data.name}</h1>
|
||||
{this.props.button}
|
||||
<br/><br/>
|
||||
<img alt="product" src={'https://external-content.duckduckgo.com/iu/?u=' + this.props.data.icon} />
|
||||
<div className="informationContainer">
|
||||
<div className="productInformation">
|
||||
<h4>{this.props.language.information}</h4>
|
||||
<ul>
|
||||
<br/>
|
||||
<li className="header">{this.props.language.last_updated}</li>
|
||||
<li>{this.props.data.updated}</li>
|
||||
<br/>
|
||||
<li className="header">{this.props.language.version}</li>
|
||||
<li>{this.props.data.version}</li>
|
||||
<br/>
|
||||
<li className="header">{this.props.language.author}</li>
|
||||
<li>{this.props.data.author}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="productInformation">
|
||||
<ul>
|
||||
<li className="header">{this.props.language.notice.title}</li>
|
||||
<li id='updated'>{this.props.language.notice.description}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<br/>
|
||||
<h1>{this.props.language.overview}</h1>
|
||||
<p className="description" dangerouslySetInnerHTML={{__html: this.props.data.description}}></p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
25
src/components/modals/marketplace/Items.jsx
Normal file
25
src/components/modals/marketplace/Items.jsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import React from 'react';
|
||||
|
||||
export default class Items extends React.PureComponent {
|
||||
render() {
|
||||
let seeMoreHTML;
|
||||
if (this.props.seeMore === true) seeMoreHTML = <button className='addToMue seemore' onClick={this.props.seeMoreFunction}>{this.props.seeMoreTitle}</button>;
|
||||
|
||||
return (
|
||||
<div>
|
||||
{seeMoreHTML}
|
||||
<h1>{this.props.title}</h1>
|
||||
<div className="items">
|
||||
{this.props.items.map((item) =>
|
||||
<div className="item" onClick={() => this.props.toggleFunction(item.name)}>
|
||||
<img alt="icon" src={'https://external-content.duckduckgo.com/iu/?u=' + item.icon_url} />
|
||||
<div className="details">
|
||||
<h4>{item.display_name}</h4>
|
||||
<p>{item.author}</p>
|
||||
</div>
|
||||
</div>)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
43
src/components/modals/settings/Checkbox.jsx
Normal file
43
src/components/modals/settings/Checkbox.jsx
Normal file
@@ -0,0 +1,43 @@
|
||||
import React from 'react';
|
||||
import SettingsFunctions from '../../../modules/settingsFunctions';
|
||||
import CheckboxUI from '@material-ui/core/Checkbox';
|
||||
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
||||
|
||||
export default class Checkbox extends React.PureComponent {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
this.state = {
|
||||
checked: true
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const handleChange = () => {
|
||||
SettingsFunctions.setItem(this.props.name);
|
||||
let checked;
|
||||
if (this.state.checked === true) checked = false;
|
||||
else checked = true;
|
||||
this.setState({ checked: checked });
|
||||
}
|
||||
|
||||
let value = localStorage.getItem(this.props.name);
|
||||
|
||||
switch (value) {
|
||||
case 'true': value = true; break;
|
||||
case 'false': value = false; break;
|
||||
default: value = false;
|
||||
}
|
||||
|
||||
this.setState({ checked: value });
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<FormControlLabel
|
||||
control={<CheckboxUI name="checkedB" color="primary" checked={this.state.checked} onChange={handleChange} />}
|
||||
label={this.props.text}
|
||||
/>
|
||||
<br/>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import * as SettingsFunctions from '../../modules/settingsFunctions';
|
||||
import SettingsFunctions from '../../../modules/settingsFunctions';
|
||||
|
||||
export default class Slider extends React.PureComponent {
|
||||
render() {
|
||||
@@ -1,13 +0,0 @@
|
||||
import React from 'react';
|
||||
import * as SettingsFunctions from '../../modules/settingsFunctions';
|
||||
|
||||
export default class Checkbox extends React.PureComponent {
|
||||
render() {
|
||||
return (
|
||||
<ul>
|
||||
<input name={this.props.name} type="checkbox" onClick={() => SettingsFunctions.setItem(this.props.name)} id={this.props.name + 'Status'} />
|
||||
<label htmlFor={this.props.name}>{this.props.text}</label>
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import supportsWebP from 'supports-webp';
|
||||
import * as Constants from '../modules/constants';
|
||||
import * as Constants from '../../modules/constants';
|
||||
|
||||
export default class Background extends React.PureComponent {
|
||||
doOffline() {
|
||||
@@ -24,7 +24,15 @@ export default class Background extends React.PureComponent {
|
||||
}
|
||||
|
||||
async setBackground() {
|
||||
if (localStorage.getItem('offlineMode')=== 'true') return this.doOffline();
|
||||
if (localStorage.getItem('offlineMode') === 'true') return this.doOffline();
|
||||
|
||||
const photoPack = JSON.parse(localStorage.getItem('photo_packs'));
|
||||
if (photoPack) {
|
||||
let background = photoPack[Math.floor(Math.random() * photoPack.length)];
|
||||
document.getElementById('backgroundCredits').style.display = 'none'; // Hide the location icon
|
||||
document.getElementById('photographer').style.display = 'none';
|
||||
return document.getElementById('backgroundImage').setAttribute('style', `-webkit-filter:blur(${localStorage.getItem('blur')}px); background-image: url(${background.url.default})`); // Set background and blur etc
|
||||
}
|
||||
|
||||
const colour = localStorage.getItem('customBackgroundColour');
|
||||
if (colour) {
|
||||
@@ -54,7 +62,7 @@ export default class Background extends React.PureComponent {
|
||||
requestURL = 'https://unsplash.muetab.xyz/getImage';
|
||||
break;
|
||||
default:
|
||||
if (await supportsWebP && enabled === 'true') requestURL = Constants.API_URL +'/getImage?webp=true';
|
||||
if (await supportsWebP && enabled === 'true') requestURL = Constants.API_URL +'/getImage?webp=true';
|
||||
else requestURL = Constants.API_URL + '/getImage?category=Outdoors';
|
||||
break;
|
||||
}
|
||||
@@ -79,6 +87,6 @@ export default class Background extends React.PureComponent {
|
||||
}
|
||||
|
||||
render() {
|
||||
return null; // React gets annoyed if I don't put anything here or use "return;"
|
||||
return <div id='backgroundImage'></div>;
|
||||
}
|
||||
}
|
||||
@@ -69,7 +69,7 @@ export default class Clock extends React.PureComponent {
|
||||
|
||||
render() {
|
||||
let clockHTML = <h1 className='clock'>{this.state.time}<span className='ampm'>{this.state.ampm}</span> </h1>;
|
||||
if (localStorage.getItem('analog') === 'true') clockHTML = <Analog className='analogclock' value={this.state.time}/>;
|
||||
if (localStorage.getItem('analog') === 'true') clockHTML = <Analog className='analogclock' value={this.state.time} renderHourMarks={false} renderMinuteMarks={false} />;
|
||||
return clockHTML;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,8 @@
|
||||
import React from 'react';
|
||||
import Quotes from '@muetab/quotes';
|
||||
import copy from 'copy-text-to-clipboard';
|
||||
import FileCopy from '@material-ui/icons/FilterNone';
|
||||
import { toast } from 'react-toastify';
|
||||
import * as Constants from '../modules/constants';
|
||||
import * as Constants from '../../modules/constants';
|
||||
|
||||
export default class Quote extends React.PureComponent {
|
||||
constructor(...args) {
|
||||
@@ -23,10 +22,19 @@ export default class Quote extends React.PureComponent {
|
||||
}
|
||||
|
||||
async getQuote() {
|
||||
const quotePack = JSON.parse(localStorage.getItem('quote_packs'));
|
||||
if (quotePack) {
|
||||
const data = quotePack[Math.floor(Math.random() * quotePack.length)]
|
||||
return this.setState({
|
||||
quote: '"' + data.quote + '"',
|
||||
author: data.author
|
||||
});
|
||||
}
|
||||
|
||||
if (localStorage.getItem('offlineMode') === 'true') return this.doOffline();
|
||||
|
||||
try { // First we try and get a quote from the API...
|
||||
let data = await fetch(Constants.API_URL +'/getQuote');
|
||||
let data = await fetch(Constants.API_URL + '/getQuote');
|
||||
data = await data.json();
|
||||
if (data.statusCode === 429) this.doOffline(); // If we hit the ratelimit, we fallback to local quotes
|
||||
this.setState({
|
||||
@@ -39,8 +47,8 @@ export default class Quote extends React.PureComponent {
|
||||
}
|
||||
|
||||
copyQuote() {
|
||||
copy(`${this.state.quote} - ${this.state.author}`);
|
||||
toast('Quote copied!');
|
||||
navigator.clipboard.writeText(`${this.state.quote} - ${this.state.author}`);
|
||||
toast(this.props.language.quote);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
38
src/components/widgets/Search.jsx
Normal file
38
src/components/widgets/Search.jsx
Normal file
@@ -0,0 +1,38 @@
|
||||
import React from 'react';
|
||||
import SearchIcon from '@material-ui/icons/Search';
|
||||
|
||||
export default class Search extends React.PureComponent {
|
||||
render() {
|
||||
if (localStorage.getItem('searchBar') === 'false') return <div></div>;
|
||||
|
||||
let url;
|
||||
let query = 'q';
|
||||
|
||||
switch (localStorage.getItem('searchEngine')) {
|
||||
case 'duckduckgo': url = 'https://duckduckgo.com'; break;
|
||||
case 'google': url = 'https://google.com/search'; break;
|
||||
case 'bing': url = 'https://bing.com/search'; break;
|
||||
case 'yahoo': url ='https://search.yahoo.com/search'; break;
|
||||
case 'ecosia': url = 'https://ecosia.org/search'; break;
|
||||
case 'yandex': url = 'https://yandex.ru/search'; query = 'text'; break;
|
||||
case 'qwant': url = 'https://www.qwant.com/'; break;
|
||||
case 'ask': url = 'https://ask.com/web'; break;
|
||||
case 'startpage': url = 'https://www.startpage.com/sp/search'; break;
|
||||
default: url = 'https://duckduckgo.com'; break;
|
||||
}
|
||||
|
||||
const searchButton = () => {
|
||||
let value = document.getElementById('searchtext').value;
|
||||
if (!value) value = 'mue fast';
|
||||
window.location.href = url + '?q=' + value;
|
||||
}
|
||||
|
||||
return <div id='searchBar' className='searchbar'>
|
||||
<form id='searchBar' className='searchbarform' action={url}>
|
||||
<SearchIcon onClick={() => searchButton()} />
|
||||
<input type='text' placeholder={this.props.language} name={query} id='searchtext' className='searchtext'/>
|
||||
<div className='blursearcbBG'/>
|
||||
</form>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user