mirror of
https://github.com/mue/mue.git
synced 2026-07-20 15:34:10 +02:00
fix: various modal things, improve ui, add missing translations etc
This commit is contained in:
@@ -5,7 +5,7 @@ export default function SideloadFailedModal({ modalClose, reason }) {
|
||||
|
||||
return (
|
||||
<>
|
||||
<h1 style={{ textAlign: 'center' }}>{getMessage('modals.main.error_boundary.error')}</h1>
|
||||
<h1>{getMessage('modals.main.error_boundary.title')}</h1>
|
||||
<span>{getMessage('modals.main.addons.sideload.failed')}</span>
|
||||
<br/><br/>
|
||||
<span>{reason}</span>
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
PhotoOutlined as Photos,
|
||||
FormatQuoteOutlined as Quotes
|
||||
} from '@mui/icons-material';
|
||||
import { TextField } from '@mui/material';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
import { saveFile } from 'modules/helpers/settings/modals';
|
||||
@@ -207,18 +208,12 @@ export default class Create extends PureComponent {
|
||||
const writeDescription = (
|
||||
<>
|
||||
<h3>{getMessage('modals.main.marketplace.product.information')}</h3>
|
||||
<p>{getMessage('modals.main.addons.create.metadata.name')}</p>
|
||||
<input type='text' value={this.state.addonMetadata.name} onInput={(e) => setMetadata(e.target.value, 'name')}/>
|
||||
<p>{getMessage('modals.main.marketplace.product.version')}</p>
|
||||
<input type='text' value={this.state.addonMetadata.version} onInput={(e) => setMetadata(e.target.value, 'version')}/>
|
||||
<p>{getMessage('modals.main.marketplace.product.author')}</p>
|
||||
<input type='text' value={this.state.addonMetadata.author} onInput={(e) => setMetadata(e.target.value, 'author')}/>
|
||||
<p>{getMessage('modals.main.addons.create.metadata.icon_url')}</p>
|
||||
<input type='text' value={this.state.addonMetadata.icon_url} onInput={(e) => setMetadata(e.target.value, 'icon_url')}/>
|
||||
<p>{getMessage('modals.main.addons.create.metadata.screenshot_url')}</p>
|
||||
<input type='text' value={this.state.addonMetadata.screenshot_url} onInput={(e) => setMetadata(e.target.value, 'screenshot_url')}/>
|
||||
<p>{getMessage('modals.main.addons.create.metadata.description')}</p>
|
||||
<textarea className='settingsTextarea' value={this.state.addonMetadata.description} onInput={(e) => setMetadata(e.target.value, 'description')}/>
|
||||
<TextField label={getMessage('modals.main.addons.create.metadata.name')} varient='outlined' value={this.state.addonMetadata.name} onInput={(e) => setMetadata(e.target.value, 'name')}/>
|
||||
<TextField label={getMessage('modals.main.marketplace.product.version')} varient='outlined' value={this.state.addonMetadata.version} onInput={(e) => setMetadata(e.target.value, 'version')}/>
|
||||
<TextField label={getMessage('modals.main.marketplace.product.author')} varient='outlined' value={this.state.addonMetadata.author} onInput={(e) => setMetadata(e.target.value, 'author')}/>
|
||||
<TextField label={getMessage('modals.main.addons.create.metadata.icon_url')} varient='outlined' value={this.state.addonMetadata.icon_url} onInput={(e) => setMetadata(e.target.value, 'icon_url')}/>
|
||||
<TextField label={getMessage('modals.main.addons.create.metadata.screenshot_url')} varient='outlined' value={this.state.addonMetadata.screenshot_url} onInput={(e) => setMetadata(e.target.value, 'screenshot_url')}/>
|
||||
<TextField label={getMessage('modals.main.addons.create.metadata.description')} varient='outlined' multiline spellCheck={false} rows={4} InputLabelProps={{ shrink: true }} value={this.state.addonMetadata.description} onInput={(e) => setMetadata(e.target.value, 'description')}/>
|
||||
<br/>
|
||||
<button onClick={() => this.changeTab(1)} className='uploadbg' style={{ marginRight: '10px' }}>{getMessage('modals.welcome.buttons.previous')}</button>
|
||||
<button onClick={() => this.changeTab(this.state.addonMetadata.type)} className='uploadbg' disabled={nextDescriptionDisabled}>{getMessage('modals.welcome.buttons.next')}</button>
|
||||
|
||||
@@ -24,17 +24,17 @@ export default class Sideload extends PureComponent {
|
||||
installAddon(input) {
|
||||
let failedReason = '';
|
||||
if (!input.name) {
|
||||
failedReason = getMessage('modals.main.addons.sideload.errors.no_name');
|
||||
failedReason = this.getMessage('modals.main.addons.sideload.errors.no_name');
|
||||
} else if (!input.author) {
|
||||
failedReason = getMessage('modals.main.addons.sideload.errors.no_author');
|
||||
failedReason = this.getMessage('modals.main.addons.sideload.errors.no_author');
|
||||
} else if (!input.type) {
|
||||
failedReason = getMessage('modals.main.addons.sideload.errors.no_type');
|
||||
failedReason = this.getMessage('modals.main.addons.sideload.errors.no_type');
|
||||
} else if (!input.version) {
|
||||
failedReason = getMessage('modals.main.addons.sideload.errors.no_version');
|
||||
failedReason = this.getMessage('modals.main.addons.sideload.errors.no_version');
|
||||
} else if (input.type === 'photos' && (!input.photos || !input.photos.length || !input.photos[0].url.default || !input.photos[0].photographer || !input.photos[0].location)) {
|
||||
failedReason = getMessage('modals.main.addons.sideload.errors.invalid_photos');
|
||||
failedReason = this.getMessage('modals.main.addons.sideload.errors.invalid_photos');
|
||||
} else if (input.type === 'quotes' && (!input.quotes || !input.quotes.length || !input.quotes[0].quote || !input.quotes[0].author)) {
|
||||
failedReason = getMessage('modals.main.addons.sideload.errors.invalid_quotes');
|
||||
failedReason = this.getMessage('modals.main.addons.sideload.errors.invalid_quotes');
|
||||
}
|
||||
|
||||
if (failedReason !== '') {
|
||||
|
||||
@@ -84,3 +84,12 @@ legend,
|
||||
width: 300px !important;
|
||||
display: flex !important;
|
||||
}
|
||||
|
||||
.Mui-disabled {
|
||||
color: #818181 !important;
|
||||
cursor: not-allowed;
|
||||
|
||||
.checkbox svg {
|
||||
fill: #818181 !important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,10 @@ export default class Checkbox extends PureComponent {
|
||||
checked: value
|
||||
});
|
||||
|
||||
if (this.props.onChange) {
|
||||
this.props.onChange(value);
|
||||
}
|
||||
|
||||
variables.stats.postEvent('setting', `${this.props.name} ${(this.state.checked === true) ? 'enabled' : 'disabled'}`);
|
||||
|
||||
if (this.props.element) {
|
||||
@@ -36,7 +40,7 @@ export default class Checkbox extends PureComponent {
|
||||
return (
|
||||
<>
|
||||
<FormControlLabel
|
||||
control={<CheckboxUI name={this.props.name} color='primary' className='checkbox' checked={this.state.checked} onChange={this.handleChange} />}
|
||||
control={<CheckboxUI name={this.props.name} color='primary' className='checkbox' checked={this.state.checked} onChange={this.handleChange} disabled={this.props.disabled || false} />}
|
||||
label={this.props.text}
|
||||
/>
|
||||
<br/>
|
||||
|
||||
@@ -32,6 +32,10 @@ export default class Radio extends PureComponent {
|
||||
value
|
||||
});
|
||||
|
||||
if (this.props.onChange) {
|
||||
this.props.onChange(value);
|
||||
}
|
||||
|
||||
variables.stats.postEvent('setting', `${this.props.name} from ${this.state.value} to ${value}`);
|
||||
|
||||
if (this.props.element) {
|
||||
|
||||
@@ -68,7 +68,7 @@ export default class SliderComponent extends PureComponent {
|
||||
default={Number(this.props.default)}
|
||||
min={Number(this.props.min)}
|
||||
max={Number(this.props.max)}
|
||||
step={this.props.step || 1}
|
||||
step={Number(this.props.step) || 1}
|
||||
getAriaValueText={(value) => `${value}`}
|
||||
marks={this.props.marks || []}
|
||||
/>
|
||||
|
||||
@@ -49,7 +49,7 @@ export default class Text extends PureComponent {
|
||||
return (
|
||||
<>
|
||||
{(this.props.textarea === true) ?
|
||||
<TextField label={this.props.title} value={this.state.value} onChange={this.handleChange} varient='outlined' multiline spellCheck={false} minRows={4} maxRows={10} InputLabelProps={{ shrink: true }} />
|
||||
<TextField label={this.props.title} value={this.state.value} onChange={this.handleChange} varient='outlined' multiline spellCheck={false} minRows={4} maxRows={10} InputLabelProps={{ shrink: true }} />
|
||||
: <TextField label={this.props.title} value={this.state.value} onChange={this.handleChange} varient='outlined' />
|
||||
}
|
||||
<span className='modalLink' onClick={this.resetItem}>{variables.language.getMessage(variables.languagecode, 'modals.main.settings.buttons.reset')}</span>
|
||||
|
||||
@@ -41,6 +41,10 @@ export default class About extends PureComponent {
|
||||
});
|
||||
}
|
||||
|
||||
if (sponsors.length === 0) {
|
||||
sponsors = [{ handle: 'empty' }];
|
||||
}
|
||||
|
||||
if (this.controller.signal.aborted === true) {
|
||||
return;
|
||||
}
|
||||
@@ -126,11 +130,17 @@ export default class About extends PureComponent {
|
||||
|
||||
<h3>{this.getMessage('modals.main.settings.sections.about.supporters')}</h3>
|
||||
<p>{this.state.loading}</p>
|
||||
{this.state.sponsors.map(({ handle, avatar }) => (
|
||||
<Tooltip title={handle} key={handle}>
|
||||
<a href={'https://github.com/' + handle} target='_blank' rel='noopener noreferrer'><img draggable='false' className='abouticon' src={avatar.split('?')[0] + '?s=128'} alt={handle}></img></a>
|
||||
</Tooltip>
|
||||
))}
|
||||
{this.state.sponsors.map(({ handle, avatar }) => {
|
||||
if (handle === 'empty') {
|
||||
return <p>{this.getMessage('modals.main.settings.sections.about.no_supporters')}</p>;
|
||||
}
|
||||
|
||||
return (
|
||||
<Tooltip title={handle} key={handle}>
|
||||
<a href={'https://github.com/' + handle} target='_blank' rel='noopener noreferrer'><img draggable='false' className='abouticon' src={avatar.split('?')[0] + '?s=128'} alt={handle}></img></a>
|
||||
</Tooltip>
|
||||
)
|
||||
})}
|
||||
|
||||
<h3>{this.getMessage('modals.main.settings.sections.about.photographers')}</h3>
|
||||
<p>{this.state.photographers}</p>
|
||||
|
||||
@@ -52,13 +52,13 @@ export default class DateSettings extends PureComponent {
|
||||
return (
|
||||
<>
|
||||
<Header title={getMessage('modals.main.settings.sections.date.title')} setting='date' category='date' element='.date' zoomSetting='zoomDate'/>
|
||||
<Checkbox name='weeknumber' text={getMessage('modals.main.settings.sections.date.week_number')} category='date'/>
|
||||
<Dropdown label={getMessage('modals.main.settings.sections.time.type')} name='dateType' onChange={(value) => this.setState({ dateType: value })} category='date'>
|
||||
<option value='long'>{getMessage('modals.main.settings.sections.date.type.long')}</option>
|
||||
<option value='short'>{getMessage('modals.main.settings.sections.date.type.short')}</option>
|
||||
</Dropdown>
|
||||
|
||||
<Checkbox name='datezero' text={getMessage('modals.main.settings.sections.time.digital.zero')} category='date'/>
|
||||
<Checkbox name='weeknumber' text={getMessage('modals.main.settings.sections.date.week_number')} category='date'/>
|
||||
{dateSettings}
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -16,7 +16,7 @@ export default class Navbar extends PureComponent {
|
||||
<>
|
||||
<h2>{getMessage('modals.main.settings.sections.appearance.navbar.title')}</h2>
|
||||
<Slider title={getMessage('modals.main.settings.sections.appearance.accessibility.widget_zoom')} name='zoomNavbar' min='10' max='400' default='100' display='%' marks={values('zoom')} category='navbar' />
|
||||
<Checkbox name='navbarHover' text={'Only display on hover'} category='navbar'/>
|
||||
<Checkbox name='navbarHover' text={getMessage('modals.main.settings.sections.appearance.navbar.hover')} category='navbar'/>
|
||||
<Checkbox name='notesEnabled' text={getMessage('modals.main.settings.sections.appearance.navbar.notes')} category='navbar' />
|
||||
<Checkbox name='view' text={getMessage('modals.main.settings.sections.background.buttons.view')} category='navbar' />
|
||||
<Checkbox name='favouriteEnabled' text={getMessage('modals.main.settings.sections.background.buttons.favourite')} category='navbar' />
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
import variables from 'modules/variables';
|
||||
import { useState } from 'react';
|
||||
|
||||
import Header from '../Header';
|
||||
import Checkbox from '../Checkbox';
|
||||
|
||||
export default function QuickLinks() {
|
||||
const getMessage = (text) => variables.language.getMessage(variables.languagecode, text);
|
||||
const [textOnly, setTextOnly] = useState(localStorage.getItem('quicklinksText') === 'true');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header title={getMessage('modals.main.settings.sections.quicklinks.title')} setting='quicklinksenabled' category='quicklinks' element='.quicklinks-container' zoomSetting='zoomQuicklinks'/>
|
||||
<Checkbox name='quicklinksText' text={getMessage('modals.main.settings.sections.quicklinks.text_only')} category='quicklinks'/>
|
||||
<Checkbox name='quicklinksddgProxy' text={getMessage('modals.main.settings.sections.background.ddg_image_proxy')} category='quicklinks'/>
|
||||
<Checkbox name='quicklinksText' text={getMessage('modals.main.settings.sections.quicklinks.text_only')} category='quicklinks' onChange={(value) => setTextOnly(value)}/>
|
||||
<Checkbox name='quicklinksddgProxy' text={getMessage('modals.main.settings.sections.background.ddg_image_proxy')} category='quicklinks' disabled={textOnly}/>
|
||||
<Checkbox name='quicklinksnewtab' text={getMessage('modals.main.settings.sections.quicklinks.open_new')} category='quicklinks'/>
|
||||
<Checkbox name='quicklinkstooltip' text={getMessage('modals.main.settings.sections.quicklinks.tooltip')} category='quicklinks'/>
|
||||
<Checkbox name='quicklinkstooltip' text={getMessage('modals.main.settings.sections.quicklinks.tooltip')} category='quicklinks' disabled={textOnly}/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,8 @@ export default class BackgroundSettings extends PureComponent {
|
||||
this.state = {
|
||||
backgroundType: localStorage.getItem('backgroundType') || 'api',
|
||||
backgroundFilter: localStorage.getItem('backgroundFilter') || 'none',
|
||||
backgroundCategories: [this.getMessage('modals.main.loading')]
|
||||
backgroundCategories: [this.getMessage('modals.main.loading')],
|
||||
backgroundAPI: localStorage.getItem('backgroundAPI') || 'mue'
|
||||
};
|
||||
this.controller = new AbortController();
|
||||
}
|
||||
@@ -93,8 +94,8 @@ export default class BackgroundSettings extends PureComponent {
|
||||
|
||||
const APISettings = (
|
||||
<>
|
||||
<Radio title={getMessage('modals.main.settings.sections.background.source.api')} options={apiOptions} name='backgroundAPI' category='background' element='#backgroundImage'/>
|
||||
<Dropdown label={getMessage('modals.main.settings.sections.background.category')} name='apiCategory' manual={true}>
|
||||
<Radio title={getMessage('modals.main.settings.sections.background.source.api')} options={apiOptions} name='backgroundAPI' category='background' element='#backgroundImage' onChange={(e) => this.setState({ backgroundAPI: e })}/>
|
||||
<Dropdown label={getMessage('modals.main.settings.sections.background.category')} name='apiCategory'>
|
||||
{this.state.backgroundCategories.map((category) => (
|
||||
<MenuItem value={category} key={category}>{category.charAt(0).toUpperCase() + category.slice(1)}</MenuItem>
|
||||
))}
|
||||
@@ -120,14 +121,16 @@ export default class BackgroundSettings extends PureComponent {
|
||||
if (localStorage.getItem('photo_packs') && this.state.backgroundType !== 'custom' && this.state.backgroundType !== 'colour' && this.state.backgroundType !== 'api') {
|
||||
backgroundSettings = null;
|
||||
}
|
||||
|
||||
const usingImage = this.state.backgroundType !== 'colour' && this.state.backgroundType !== 'random_colour' && this.state.backgroundType !== 'random_gradient';
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header title={getMessage('modals.main.settings.sections.background.title')} setting='background' category='background' element='#backgroundImage'/>
|
||||
<Checkbox name='ddgProxy' text={getMessage('modals.main.settings.sections.background.ddg_image_proxy')} element='.other' />
|
||||
<Checkbox name='bgtransition' text={getMessage('modals.main.settings.sections.background.transition')} element='.other' />
|
||||
<Checkbox name='photoInformation' text={getMessage('modals.main.settings.sections.background.photo_information')} element='.other' />
|
||||
<Checkbox name='photoMap' text={getMessage('modals.main.settings.sections.background.show_map')} element='.other'/>
|
||||
<Checkbox name='ddgProxy' text={getMessage('modals.main.settings.sections.background.ddg_image_proxy')} element='.other' disabled={!usingImage} />
|
||||
<Checkbox name='bgtransition' text={getMessage('modals.main.settings.sections.background.transition')} element='.other' disabled={!usingImage} />
|
||||
<Checkbox name='photoInformation' text={getMessage('modals.main.settings.sections.background.photo_information')} element='.other' disabled={this.state.backgroundType !== 'api' && this.state.backgroundType !== 'marketplace'} />
|
||||
<Checkbox name='photoMap' text={getMessage('modals.main.settings.sections.background.show_map')} element='.other' disabled={this.state.backgroundAPI !== 'unsplash'}/>
|
||||
|
||||
<h3>{getMessage('modals.main.settings.sections.background.source.title')}</h3>
|
||||
<Dropdown label={getMessage('modals.main.settings.sections.background.type.title')} name='backgroundType' onChange={(value) => this.setState({ backgroundType: value })} category='background'>
|
||||
@@ -141,7 +144,7 @@ export default class BackgroundSettings extends PureComponent {
|
||||
|
||||
{backgroundSettings}
|
||||
|
||||
{this.state.backgroundType === 'api' && APISettings ?
|
||||
{this.state.backgroundType === 'api' && APISettings && this.state.backgroundAPI === 'mue' ?
|
||||
<>
|
||||
<h3>{getMessage('modals.main.settings.sections.background.buttons.title')}</h3>
|
||||
<Checkbox name='downloadbtn' text={getMessage('modals.main.settings.sections.background.buttons.download')} element='.other' />
|
||||
@@ -155,7 +158,7 @@ export default class BackgroundSettings extends PureComponent {
|
||||
<Slider title={getMessage('modals.main.settings.sections.background.effects.brightness')} name='brightness' min='0' max='100' default='90' display='%' marks={values('background')} category='background' element='#backgroundImage' />
|
||||
<br/>
|
||||
<Dropdown label={getMessage('modals.main.settings.sections.background.effects.filters.title')} name='backgroundFilter' onChange={(value) => this.setState({ backgroundFilter: value })} category='background' element='#backgroundImage'>
|
||||
<option value='none'>None</option>
|
||||
<option value='none'>{getMessage('modals.main.settings.sections.appearance.navbar.refresh_options.none')}</option>
|
||||
<option value='grayscale'>{getMessage('modals.main.settings.sections.background.effects.filters.grayscale')}</option>
|
||||
<option value='sepia'>{getMessage('modals.main.settings.sections.background.effects.filters.sepia')}</option>
|
||||
<option value='invert'>{getMessage('modals.main.settings.sections.background.effects.filters.invert')}</option>
|
||||
|
||||
@@ -108,8 +108,8 @@ export default class CustomSettings extends PureComponent {
|
||||
<ul>
|
||||
<p>{this.getMessage('modals.main.settings.sections.background.source.custom_background')} <span className='modalLink' onClick={this.resetCustom}>{this.getMessage('modals.main.settings.buttons.reset')}</span></p>
|
||||
<div className='data-buttons-row'>
|
||||
<button onClick={() => this.uploadCustomBackground()}>Add background <AddPhotoAlternate/> </button>
|
||||
<button onClick={() => this.setState({ customURLModal: true })}>Add URL <AddLink/></button>
|
||||
<button onClick={() => this.uploadCustomBackground()}>{this.getMessage('modals.main.settings.sections.background.source.add_background')} <AddPhotoAlternate/></button>
|
||||
<button onClick={() => this.setState({ customURLModal: true })}>{this.getMessage('modals.main.settings.sections.background.source.add_url')} <AddLink/></button>
|
||||
</div>
|
||||
<div className='images-row'>
|
||||
{this.state.customBackground.map((_url, index) => (
|
||||
@@ -125,8 +125,8 @@ export default class CustomSettings extends PureComponent {
|
||||
</div>
|
||||
<FileUpload id='bg-input' accept='image/jpeg, image/png, image/webp, image/webm, image/gif, video/mp4, video/webm, video/ogg' loadFunction={(e) => this.customBackground(e, false, this.state.currentBackgroundIndex)} />
|
||||
{this.props.interval}
|
||||
<Modal closeTimeoutMS={100} isOpen={this.state.customURLModal} className='Modal resetmodal mainModal' overlayClassName='Overlay resetoverlay' ariaHideApp={false}>
|
||||
<CustomURLModal modalClose={(e) => this.addCustomURL(e)} />
|
||||
<Modal closeTimeoutMS={100} onRequestClose={() => this.setState({ customURLModal: false })} isOpen={this.state.customURLModal} className='Modal resetmodal mainModal' overlayClassName='Overlay resetoverlay' ariaHideApp={false}>
|
||||
<CustomURLModal modalClose={(e) => this.addCustomURL(e)} modalCloseOnly={() => this.setState({ customURLModal: false })} />
|
||||
</Modal>
|
||||
</ul>
|
||||
);
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import variables from 'modules/variables';
|
||||
import { useState } from 'react';
|
||||
import { Add } from '@mui/icons-material';
|
||||
import { TextField } from '@mui/material';
|
||||
|
||||
export default function CustomURLModal({ modalClose }) {
|
||||
export default function CustomURLModal({ modalClose, modalCloseOnly }) {
|
||||
const [url, setURL] = useState('URL');
|
||||
|
||||
return (
|
||||
<>
|
||||
<h1>Add URL</h1>
|
||||
<span className='closeModal' onClick={modalCloseOnly}>×</span>
|
||||
<h1>{variables.language.getMessage(variables.languagecode, 'modals.main.settings.sections.background.source.add_url')}</h1>
|
||||
<TextField value={url} onChange={(e) => setURL(e.target.value)} varient='outlined' />
|
||||
<div className='resetfooter'>
|
||||
<button className='round import' style={{ marginLeft: '5px' }} onClick={() => modalClose(url)}>
|
||||
|
||||
Reference in New Issue
Block a user