mirror of
https://github.com/mue/mue.git
synced 2026-07-17 14:04:09 +02:00
feat: custom background drag and drop, error reporting, better ui, new settings, fixes
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
"@fontsource/lexend-deca": "4.4.5",
|
||||
"@fontsource/montserrat": "4.4.5",
|
||||
"@mui/material": "5.6.0",
|
||||
"@sentry/react": "^6.19.6",
|
||||
"react": "^18.0.0",
|
||||
"react-clock": "3.1.0",
|
||||
"react-color-gradient-picker": "0.1.2",
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
import variables from 'modules/variables';
|
||||
import { PureComponent } from 'react';
|
||||
import { MdErrorOutline } from 'react-icons/md';
|
||||
import { captureException } from '@sentry/react';
|
||||
|
||||
export default class ErrorBoundary extends PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
error: false,
|
||||
errorData: '',
|
||||
showReport: true
|
||||
};
|
||||
}
|
||||
|
||||
@@ -15,9 +18,17 @@ export default class ErrorBoundary extends PureComponent {
|
||||
variables.stats.postEvent('modal', 'Error occurred');
|
||||
return {
|
||||
error: true,
|
||||
errorData: error
|
||||
};
|
||||
}
|
||||
|
||||
reportError() {
|
||||
captureException(this.state.errorData);
|
||||
this.setState({
|
||||
showReport: false
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.error) {
|
||||
return (
|
||||
@@ -36,6 +47,9 @@ export default class ErrorBoundary extends PureComponent {
|
||||
'modals.main.error_boundary.message',
|
||||
)}
|
||||
</p>
|
||||
{this.state.showReport ? <button onClick={() => this.reportError()}>
|
||||
Send Error Report
|
||||
</button> : <button>Sent!</button>}
|
||||
<button className="refresh" onClick={() => window.location.reload()}>
|
||||
{variables.language.getMessage(
|
||||
variables.languagecode,
|
||||
|
||||
@@ -35,13 +35,14 @@ export default class Header extends PureComponent {
|
||||
{this.props.switch ? (
|
||||
<SettingsItem
|
||||
title={getMessage('modals.main.settings.enabled')}
|
||||
subtitle={getMessage('modals.main.settings.enabled')}
|
||||
subtitle='Choose whether or not to show this widget'
|
||||
>
|
||||
<Switch
|
||||
name={this.props.setting}
|
||||
text={getMessage('modals.main.settings.enabled')}
|
||||
category={this.props.category}
|
||||
element={this.props.element || null}
|
||||
header={true}
|
||||
/>
|
||||
</SettingsItem>
|
||||
) : null}
|
||||
|
||||
@@ -47,7 +47,7 @@ export default class Switch extends PureComponent {
|
||||
onChange={this.handleChange}
|
||||
/>
|
||||
}
|
||||
label={this.props.text}
|
||||
label={this.props.header ? '' : this.props.text}
|
||||
labelPlacement="start"
|
||||
/>
|
||||
</>
|
||||
|
||||
@@ -209,6 +209,11 @@ export default class QuoteSettings extends PureComponent {
|
||||
text={this.getMessage('modals.main.settings.sections.quote.author_link')}
|
||||
element=".other"
|
||||
/>
|
||||
<Checkbox
|
||||
name="authorImg"
|
||||
text='Show author image'
|
||||
element=".other"
|
||||
/>
|
||||
</SettingsItem>
|
||||
<SettingsItem
|
||||
title={this.getMessage('modals.main.settings.sections.background.type.title')}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { PureComponent } from 'react';
|
||||
import Header from '../Header';
|
||||
import { MdRemoveCircleOutline } from 'react-icons/md';
|
||||
import SettingsItem from '../SettingsItem';
|
||||
|
||||
export default class ReminderSettings extends PureComponent {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
@@ -81,14 +81,14 @@ export default class ColourSettings extends PureComponent {
|
||||
const newValue = event.target.value;
|
||||
const name = event.target.name;
|
||||
this.setState((s) => {
|
||||
return (newState = {
|
||||
return {
|
||||
gradientSettings: {
|
||||
...s.gradientSettings,
|
||||
gradient: s.gradientSettings.gradient.map((g, i) =>
|
||||
i === index ? { ...g, [name]: newValue } : g,
|
||||
),
|
||||
},
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
this.showReminder();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import variables from 'modules/variables';
|
||||
import { PureComponent } from 'react';
|
||||
import { PureComponent, createRef } from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
import { MdCancel, MdAddLink, MdAddPhotoAlternate, MdPersonalVideo } from 'react-icons/md';
|
||||
import EventBus from 'modules/helpers/eventbus';
|
||||
@@ -20,6 +20,7 @@ export default class CustomSettings extends PureComponent {
|
||||
customBackground: this.getCustom(),
|
||||
customURLModal: false,
|
||||
};
|
||||
this.customDnd = createRef(null);
|
||||
}
|
||||
|
||||
resetCustom = () => {
|
||||
@@ -122,6 +123,27 @@ export default class CustomSettings extends PureComponent {
|
||||
this.customBackground({ target: { value: e } }, true, this.state.customBackground.length);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const dnd = this.customDnd.current;
|
||||
dnd.ondragover = dnd.ondragenter = (e) => {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
dnd.ondrop = (e) => {
|
||||
e.preventDefault();
|
||||
const file = e.dataTransfer.files[0];
|
||||
const reader = new FileReader();
|
||||
if (file.size > 2000000) {
|
||||
return toast(this.getMessage('modals.main.file_upload_error'));
|
||||
}
|
||||
reader.onload = (e) => {
|
||||
this.customBackground(e, false, this.state.customBackground.length);
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<>
|
||||
@@ -150,7 +172,7 @@ export default class CustomSettings extends PureComponent {
|
||||
</div>
|
||||
<div className="action">
|
||||
{/*<button onClick={() => this.uploadCustomBackground()}>{this.getMessage('modals.main.settings.sections.background.source.add_background')} <MdAddPhotoAlternate/></button>*/}
|
||||
<div className="dropzone">
|
||||
<div className="dropzone" ref={this.customDnd}>
|
||||
<MdAddPhotoAlternate />
|
||||
<span className="title">Drop to upload</span>
|
||||
<span className="subtitle">
|
||||
|
||||
@@ -103,6 +103,13 @@ export default class Quote extends PureComponent {
|
||||
}
|
||||
|
||||
async getAuthorImg(author) {
|
||||
if (localStorage.getItem('authorImg') === 'false') {
|
||||
return {
|
||||
authorimg: null,
|
||||
authorimglicense: null
|
||||
}
|
||||
}
|
||||
|
||||
const authorimgdata = await (
|
||||
await fetch(
|
||||
`https://en.wikipedia.org/w/api.php?action=query&titles=${author}&origin=*&prop=pageimages&format=json&pithumbsize=100`,
|
||||
@@ -438,7 +445,7 @@ export default class Quote extends PureComponent {
|
||||
<span className="author-license">{this.state.authorimglicense}</span>
|
||||
</div>
|
||||
<div className="quote-buttons">
|
||||
{this.state.authorOccupation !== 'Unknown' ? (
|
||||
{this.state.authorOccupation !== 'Unknown' && this.state.authorlink !== '' ? (
|
||||
<Tooltip title="Open On Wikipedia">
|
||||
<a
|
||||
href={this.state.authorlink}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { render } from 'react-dom';
|
||||
import * as Sentry from '@sentry/react';
|
||||
|
||||
import App from './App';
|
||||
import variables from 'modules/variables';
|
||||
@@ -60,4 +61,10 @@ if (localStorage.getItem('stats') === 'true') {
|
||||
variables.keybinds = JSON.parse(localStorage.getItem('keybinds') || '{}');
|
||||
}*/
|
||||
|
||||
Sentry.init({
|
||||
dsn: variables.constants.SENTRY_DSN,
|
||||
defaultIntegrations: false,
|
||||
autoSessionTracking: false
|
||||
});
|
||||
|
||||
render(<App />, document.getElementById('root'));
|
||||
|
||||
@@ -18,6 +18,7 @@ export const REPORT_ITEM =
|
||||
export const BUG_REPORT =
|
||||
'https://github.com/mue/mue/issues/new?assignees=&labels=issue+report&template=bug-report.md&title=%5BBug%5D+';
|
||||
export const DONATE_LINK = 'https://muetab.com/donate';
|
||||
export const SENTRY_DSN = 'https://430352fd4b174d688ebd82fc85c22c58@o1217438.ingest.sentry.io/6359480';
|
||||
|
||||
// Mue Info
|
||||
export const ORG_NAME = 'mue';
|
||||
|
||||
Reference in New Issue
Block a user