mirror of
https://github.com/mue/mue.git
synced 2026-07-05 15:41:18 +02:00
feat: improved weather widget, fix marketplace and date widget etc
Co-authored-by: Alex Sparkes <turbomarshmello@gmail.com>
This commit is contained in:
@@ -31,17 +31,19 @@ export default function Item(props) {
|
||||
return (
|
||||
<div id='item'>
|
||||
<br/>
|
||||
<ArrowBackIcon className='backArrow' onClick={props.toggleFunction}/>
|
||||
<span>
|
||||
<ArrowBackIcon className='backArrow' onClick={props.toggleFunction}/>
|
||||
</span>
|
||||
<br/>
|
||||
<h1>{props.data.name}</h1>
|
||||
{props.button}
|
||||
<br/><br/>
|
||||
<br/>
|
||||
<img alt='product' draggable='false' src={iconsrc}/>
|
||||
<div className='informationContainer'>
|
||||
<h1>{language.overview}</h1>
|
||||
<p className='description' dangerouslySetInnerHTML={{__html: props.data.description}}></p>
|
||||
<div className='productInformation'>
|
||||
<h4>{language.information}</h4>
|
||||
<ul>
|
||||
<br/>
|
||||
<li className='header'>{language.last_updated}</li>
|
||||
<li>{props.data.updated}</li>
|
||||
<br/>
|
||||
@@ -52,17 +54,16 @@ export default function Item(props) {
|
||||
<li>{props.data.author}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className='productInformation'>
|
||||
|
||||
{/*} <div className='productInformation'>
|
||||
<ul>
|
||||
<li className='header'>{language.notice.title}</li>
|
||||
<li id='updated'>{language.notice.description}</li>
|
||||
</ul>
|
||||
</div>
|
||||
{warningHTML}
|
||||
</div> */}
|
||||
{warningHTML}
|
||||
</div>
|
||||
<br/>
|
||||
<h1>{language.overview}</h1>
|
||||
<p className='description' dangerouslySetInnerHTML={{__html: props.data.description}}></p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ export default class Added extends React.PureComponent {
|
||||
break;
|
||||
}
|
||||
|
||||
toast(window.language.modals.main.toasts[type + 'ed']);
|
||||
toast(window.language.toasts[type + 'ed']);
|
||||
|
||||
let button = '';
|
||||
if (type === 'install') {
|
||||
@@ -93,7 +93,13 @@ export default class Added extends React.PureComponent {
|
||||
}
|
||||
|
||||
render() {
|
||||
let content = <Items items={this.state.installed} toggleFunction={(input) => this.toggle('item', 'addon', input)} />;
|
||||
let content = (
|
||||
<Items
|
||||
items={this.state.installed}
|
||||
toggleFunction={(input) => this.toggle('item', 'addon', input)}
|
||||
reloadItemsList={() => this.setState({ installed: JSON.parse(localStorage.getItem('installed')) })}
|
||||
/>
|
||||
);
|
||||
|
||||
if (this.state.installed.length === 0) {
|
||||
content = (
|
||||
@@ -112,7 +118,7 @@ export default class Added extends React.PureComponent {
|
||||
<>
|
||||
<div id='marketplace'>
|
||||
<FileUpload id='file-input' type='settings' accept='application/json' loadFunction={(e) => this.manage('install', JSON.parse(e.target.result))} />
|
||||
<button className='addToMue sideload' onClick={() => document.getElementById('file-input').click()}>Sideload</button>
|
||||
{/*<button className='addToMue sideload' onClick={() => document.getElementById('file-input').click()}>Sideload</button>*/}
|
||||
{content}
|
||||
</div>
|
||||
<Item data={this.state.item_data} button={this.state.button} toggleFunction={() => this.toggle()} />
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import React from 'react';
|
||||
|
||||
import WifiOffIcon from '@material-ui/icons/WifiOff';
|
||||
import LocalMallIcon from '@material-ui/icons/LocalMall';
|
||||
|
||||
import Item from '../Item';
|
||||
import Items from '../Items';
|
||||
|
||||
@@ -31,9 +33,10 @@ export default class Marketplace extends React.PureComponent {
|
||||
}
|
||||
};
|
||||
this.buttons = {
|
||||
uninstall: <button className='removeFromMue' onClick={() => this.manage('uninstall')}>Remove</button>,
|
||||
install: <button className='addToMue' onClick={() => this.manage('install')}>Add to Mue</button>
|
||||
uninstall: <button className='removeFromMue' onClick={() => this.manage('uninstall')}>{window.language.modals.main.marketplace.product.buttons.remove}</button>,
|
||||
install: <button className='addToMue' onClick={() => this.manage('install')}>{window.language.modals.main.marketplace.product.buttons.addtomue}</button>
|
||||
}
|
||||
this.language = window.language.modals.main.marketplace;
|
||||
}
|
||||
|
||||
async toggle(type, data) {
|
||||
@@ -103,17 +106,13 @@ export default class Marketplace extends React.PureComponent {
|
||||
break;
|
||||
}
|
||||
|
||||
toast(this.props.toastLanguage[type + 'ed']);
|
||||
toast(window.language.toasts[type + 'ed']);
|
||||
this.setState({
|
||||
button: (type === 'install') ? this.buttons.uninstall : this.buttons.install
|
||||
});
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
if (localStorage.getItem('animations') === 'true') {
|
||||
document.getElementById('marketplace').classList.add('marketplaceanimation');
|
||||
}
|
||||
|
||||
if (navigator.onLine === false || localStorage.getItem('offlineMode') === 'true') {
|
||||
return;
|
||||
}
|
||||
@@ -156,6 +155,14 @@ export default class Marketplace extends React.PureComponent {
|
||||
return errorMessage(<h1>Loading</h1>);
|
||||
}
|
||||
|
||||
if (this.state.items.length === 0) {
|
||||
return errorMessage(<>
|
||||
<LocalMallIcon/>
|
||||
<h1>Empty</h1>
|
||||
<p className='description'>No items in this category</p>
|
||||
</>)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div id='marketplace'>
|
||||
@@ -165,7 +172,7 @@ export default class Marketplace extends React.PureComponent {
|
||||
<button className='addToMue' onClick={() => window.location.href = this.state.featured.buttonLink}>{this.state.featured.buttonText}</button>
|
||||
</div>
|
||||
<Items
|
||||
items={this.state.items.slice(0, 3)}
|
||||
items={this.state.items}
|
||||
toggleFunction={(input) => this.toggle('item', input)} />
|
||||
</div>
|
||||
<Item data={this.state.item_data} button={this.state.button} toggleFunction={() => this.toggle()} />
|
||||
|
||||
@@ -200,6 +200,14 @@ li {
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 2300px) {
|
||||
.tab-content {
|
||||
position: absolute !important;
|
||||
left: 25% !important;
|
||||
top: 7%;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 1920px) {
|
||||
.tab-content {
|
||||
position: absolute;
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
%storebutton {
|
||||
cursor: pointer;
|
||||
font-size: 18px;
|
||||
float: right;
|
||||
display: block;
|
||||
padding: 5px 30px;
|
||||
background: none;
|
||||
border-radius: 24px;
|
||||
|
||||
@@ -46,7 +46,7 @@ export default class AdvancedSettings extends React.PureComponent {
|
||||
<h3>{advanced.customisation}</h3>
|
||||
<Text title={advanced.custom_js} name='customjs' textarea={true}/>
|
||||
<Text title={advanced.custom_css} name='customcss' textarea={true}/>
|
||||
<Text title={advanced.tab_name} name='tabName'/>
|
||||
<Text title={advanced.tab_name} name='tabName' default={window.language.tabname}/>
|
||||
|
||||
<h3>{this.language.sections.experimental.title}</h3>
|
||||
<p>{advanced.experimental_warning}</p>
|
||||
|
||||
@@ -2,6 +2,7 @@ import React from 'react';
|
||||
|
||||
import Switch from '../Switch';
|
||||
import Radio from '../Radio';
|
||||
import Checkbox from '../Checkbox';
|
||||
|
||||
export default class TimeSettings extends React.PureComponent {
|
||||
constructor() {
|
||||
@@ -44,11 +45,18 @@ export default class TimeSettings extends React.PureComponent {
|
||||
<>
|
||||
<h2>{language.title}</h2>
|
||||
<Switch name='weatherEnabled' text={this.language.enabled} />
|
||||
<br/>
|
||||
<Radio name='tempformat' title='Temperature Format' options={tempFormat} />
|
||||
<ul>
|
||||
<p>Location <span className='modalLink' onClick={() => this.getLocation()}>Auto</span></p>
|
||||
<input type='text' value={this.state.location} onChange={(e) => this.setState({ location: e.target.value })}></input>
|
||||
</ul>
|
||||
<h3>Extra Information</h3>
|
||||
<Checkbox name='mintemp' text='Min temp'/>
|
||||
<Checkbox name='maxtemp' text='Max temp'/>
|
||||
<Checkbox name='humidity' text='Humidity'/>
|
||||
<Checkbox name='windspeed' text='Wind speed'/>
|
||||
<Checkbox name='windspeed' text='Atmospheric pressure'/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -51,6 +51,12 @@ export default class BackgroundSettings extends React.PureComponent {
|
||||
}
|
||||
}
|
||||
|
||||
marketplaceType = () => {
|
||||
if (localStorage.getItem('photo_packs')) {
|
||||
return <option value='photo_pack'>Marketplace</option>
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
localStorage.setItem('customBackground', this.state.customBackground);
|
||||
}
|
||||
@@ -107,7 +113,7 @@ export default class BackgroundSettings extends React.PureComponent {
|
||||
// API
|
||||
default: backgroundSettings = APISettings; break;
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<h2>{background.title}</h2>
|
||||
@@ -125,6 +131,7 @@ export default class BackgroundSettings extends React.PureComponent {
|
||||
<br/><br/>
|
||||
|
||||
<Dropdown label='Type' name='backgroundType' onChange={(value) => this.setState({ backgroundType: value })}>
|
||||
{this.marketplaceType()}
|
||||
<option value='api'>{background.type.api}</option>
|
||||
<option value='custom'>{background.type.custom_image}</option>
|
||||
<option value='colour'>{background.type.custom_colour}</option>
|
||||
|
||||
@@ -20,9 +20,10 @@ import Order from '@material-ui/icons/List';
|
||||
import Weather from '@material-ui/icons/CloudOutlined';
|
||||
import Advanced from '@material-ui/icons/SettingsOutlined';
|
||||
import QuickLinks from '@material-ui/icons/Link';
|
||||
import Sideload from '@material-ui/icons/Code';
|
||||
|
||||
// Store
|
||||
import Added from '@material-ui/icons/AddCircle';
|
||||
import Added from '@material-ui/icons/AddCircleOutline';
|
||||
|
||||
export default function Tab(props) {
|
||||
let className = 'tab-list-item';
|
||||
@@ -67,6 +68,7 @@ export default function Tab(props) {
|
||||
case 'Photo Packs': icon = <Background/>; break;
|
||||
case 'Quote Packs': icon = <Quote/>; break;
|
||||
case 'Added': icon = <Added/>; break;
|
||||
case 'Sideload': icon = <Sideload/>; break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ export default class DateWidget extends React.PureComponent {
|
||||
|
||||
getDate() {
|
||||
const date = new Date();
|
||||
const type = localStorage.getItem('type');
|
||||
const type = localStorage.getItem('dateType');
|
||||
|
||||
if (type === 'short') {
|
||||
const dateDay = date.getDate();
|
||||
@@ -33,8 +33,7 @@ export default class DateWidget extends React.PureComponent {
|
||||
year = dateDay;
|
||||
break;
|
||||
// DMY
|
||||
default:
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
let format;
|
||||
@@ -50,6 +49,8 @@ export default class DateWidget extends React.PureComponent {
|
||||
break;
|
||||
case 'slashes':
|
||||
format = `${day}/${month}/${year}`;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
|
||||
@@ -1,33 +1,64 @@
|
||||
import React from 'react';
|
||||
import WeatherIcon from './WeatherIcon';
|
||||
|
||||
import { WiHumidity, WiWindy } from 'weather-icons-react';
|
||||
|
||||
import './weather.scss';
|
||||
|
||||
export default class Weather extends React.PureComponent {
|
||||
constructor() {
|
||||
super();
|
||||
this.state = {
|
||||
location: localStorage.getItem('location') || 'London',
|
||||
icon: '',
|
||||
temp_text: '',
|
||||
weather: {
|
||||
title: '',
|
||||
temp: '',
|
||||
temp_min: '',
|
||||
temp_max: '',
|
||||
humidity: ''
|
||||
humidity: '',
|
||||
windspeed: '',
|
||||
pressure: ''
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async getWeather() {
|
||||
const data = await (await fetch (window.constants.WEATHER_URL + '?city=London')).json();
|
||||
const data = await (await fetch (window.constants.WEATHER_URL + `?city=${this.state.location}`)).json();
|
||||
|
||||
let temp = data.main.temp;
|
||||
let temp_min = data.main.temp_max
|
||||
let temp_max = data.main.temp_max;
|
||||
let temp_text = 'K';
|
||||
|
||||
switch (localStorage.getItem('tempformat')) {
|
||||
case 'celsius':
|
||||
temp = temp - 273.15;
|
||||
temp_min = temp_min - 273.15;
|
||||
temp_max = temp_max - 273.15;
|
||||
temp_text = '°C';
|
||||
break;
|
||||
case 'fahrenheit':
|
||||
temp = ((temp - 273.15) * 1.8) + 32;
|
||||
temp_min = ((temp_min - 273.15) * 1.8) + 32;
|
||||
temp_max = ((temp_max - 273.15) * 1.8) + 32;
|
||||
temp_text = '°F';
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
icon: data.weather[0].icon,
|
||||
temp_text: temp_text,
|
||||
weather: {
|
||||
title: data.weather[0].main,
|
||||
temp: Math.round(data.main.temp - 273.15),
|
||||
temp_min: Math.round(data.main.temp_min - 273.15),
|
||||
temp_max: Math.round(data.main.temp_max - 273.15),
|
||||
humidity: data.main.humidity
|
||||
temp: Math.round(temp),
|
||||
temp_min: Math.round(temp_min),
|
||||
temp_max: Math.round(temp_max),
|
||||
humidity: data.main.humidity,
|
||||
windspeed: data.wind.speed,
|
||||
pressure: data.main.pressure
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -40,11 +71,17 @@ export default class Weather extends React.PureComponent {
|
||||
return (
|
||||
<div className='weather'>
|
||||
<WeatherIcon name={this.state.icon}/>
|
||||
<span>{this.state.weather.temp}°C</span>
|
||||
<br />
|
||||
<span className='minmax'>{this.state.weather.temp_min}°C, {this.state.weather.temp_max}°C</span>
|
||||
<br />
|
||||
<span className='loc'>London</span>
|
||||
<span>{this.state.weather.temp + this.state.temp_text}</span>
|
||||
<br/>
|
||||
<span className='minmax'>{this.state.weather.temp_min + this.state.temp_text} {this.state.weather.temp_max + this.state.temp_text}</span>
|
||||
<br/>
|
||||
<span className='loc'><WiHumidity/>{this.state.weather.humidity}%</span>
|
||||
<br/>
|
||||
<span className='loc'><WiWindy/>{this.state.weather.windspeed}<span className='minmax'> m/s</span></span>
|
||||
<br/>
|
||||
<span className='loc'>{this.state.weather.pressure}<span className='minmax'> hPa</span></span>
|
||||
<br/>
|
||||
<span className='loc'>{this.state.location}</span>
|
||||
{/*<span>{this.state.weather.title}</span>*/}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -9,9 +9,7 @@
|
||||
|
||||
svg {
|
||||
filter: drop-shadow(0 0 6px rgba(0, 0, 0, 0.3));
|
||||
|
||||
font-size: 0.8em;
|
||||
|
||||
}
|
||||
|
||||
.loc {
|
||||
|
||||
@@ -158,5 +158,9 @@
|
||||
{
|
||||
"name": "weatherEnabled",
|
||||
"value": false
|
||||
},
|
||||
{
|
||||
"name": "temperatureformat",
|
||||
"value": "celsius"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -18,6 +18,11 @@ export default class MarketplaceFunctions {
|
||||
localStorage.removeItem('quote_packs');
|
||||
localStorage.removeItem('quoteAPI');
|
||||
break;
|
||||
case 'photo_packs':
|
||||
localStorage.removeItem('photo_packs');
|
||||
localStorage.setItem('backgroundType', localStorage.getItem('oldBackgroundType'));
|
||||
localStorage.removeItem('oldBackgroundType');
|
||||
break;
|
||||
default:
|
||||
try {
|
||||
localStorage.removeItem(type);
|
||||
@@ -56,6 +61,8 @@ export default class MarketplaceFunctions {
|
||||
|
||||
case 'photo_packs':
|
||||
localStorage.setItem('photo_packs', JSON.stringify(input.photos));
|
||||
localStorage.setItem('oldBackgroundType', localStorage.getItem('backgroundType'));
|
||||
localStorage.setItem('backgroundType', 'photo_pack');
|
||||
break;
|
||||
|
||||
case 'quote_packs':
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
[
|
||||
{
|
||||
"name": "Chinese (Simplified)",
|
||||
"value": "zh_CN"
|
||||
},
|
||||
{
|
||||
"name": "Deutsch",
|
||||
"value": "de_DE"
|
||||
@@ -30,9 +34,5 @@
|
||||
{
|
||||
"name": "Pусский",
|
||||
"value": "ru"
|
||||
},
|
||||
{
|
||||
"name": "Chinese (Simplified)",
|
||||
"value": "zh_CN"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -8,18 +8,21 @@
|
||||
}
|
||||
|
||||
.items {
|
||||
display: flex;
|
||||
display: inline-grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
margin-top: 15px;
|
||||
|
||||
.item {
|
||||
position: relative;
|
||||
border-radius: 12px;
|
||||
height: 80px;
|
||||
width: 270px;
|
||||
width: 260px;
|
||||
background: map-get($marketplace, 'item-background');
|
||||
transition: 0.5s;
|
||||
cursor: pointer;
|
||||
margin-right: 20px;
|
||||
margin-top: 20px;
|
||||
box-shadow: 0 0 6px rgb(0 0 0 / 30%);
|
||||
|
||||
img {
|
||||
height: 100%;
|
||||
@@ -74,17 +77,18 @@ p.author {
|
||||
|
||||
h1 {
|
||||
font-size: 40px;
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
#item>h1,
|
||||
#item>.MuiSvgIcon-root {
|
||||
display: inline;
|
||||
font-size: 35px !important;
|
||||
}
|
||||
|
||||
p.description {
|
||||
margin-top: 0px;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.emptyMessage {
|
||||
@@ -107,15 +111,13 @@ p.description {
|
||||
}
|
||||
|
||||
.informationContainer {
|
||||
float: right;
|
||||
margin-right: 15px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.productInformation {
|
||||
margin-bottom: 20px;
|
||||
padding: 20px;
|
||||
padding: 10px;
|
||||
background: map-get($marketplace, 'product-information-backgroud');
|
||||
width: 200px;
|
||||
width: 350px;
|
||||
border-radius: 12px;
|
||||
|
||||
h4 {
|
||||
@@ -163,14 +165,16 @@ p.description {
|
||||
}
|
||||
|
||||
.featured {
|
||||
margin-top: 20px;
|
||||
border-radius: 24px;
|
||||
margin-top: 40px;
|
||||
border-radius: 15px;
|
||||
padding: 50px;
|
||||
color: map-get($theme-colours, 'main');
|
||||
color: #fff;
|
||||
box-shadow: 0 0 10px rgb(0 0 0 / 30%);
|
||||
width: 85%;
|
||||
|
||||
button {
|
||||
float: left;
|
||||
margin-top: -20px;
|
||||
margin-top: -7px;
|
||||
border: 2px solid map-get($theme-colours, 'main');
|
||||
color: map-get($theme-colours, 'main');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user