refactor: move more purecomponents to functions

This commit is contained in:
David Ralph
2024-06-14 19:13:09 +01:00
parent 4747dea06b
commit a7ba47d15b
3 changed files with 188 additions and 231 deletions

View File

@@ -41,14 +41,16 @@ export default class CustomSettings extends PureComponent {
EventBus.emit('refresh', 'background');
};
customBackground(e, text, index) {
const result = text === true ? e.target.value : e.target.result;
customBackground(e, index) {
const result = e.target.result;
const customBackground = this.state.customBackground;
customBackground[index] = result;
customBackground[index || customBackground.length] = result;
this.setState({
customBackground,
});
this.forceUpdate();
localStorage.setItem('customBackground', JSON.stringify(customBackground));
@@ -159,7 +161,7 @@ export default class CustomSettings extends PureComponent {
return toast(variables.getMessage('toasts.no_storage'));
}
return this.customBackground(file, false, this.state.currentBackgroundIndex);
return this.customBackground(file, this.state.currentBackgroundIndex);
}
compressAccurately(file, {
@@ -170,7 +172,11 @@ export default class CustomSettings extends PureComponent {
return toast(variables.getMessage('toasts.no_storage'));
}
this.customBackground(await filetoDataURL(res), false, this.state.currentBackgroundIndex);
this.customBackground({
target: {
result: await filetoDataURL(res),
}
}, this.state.currentBackgroundIndex);
});
e.preventDefault();
};
@@ -274,7 +280,7 @@ export default class CustomSettings extends PureComponent {
<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)}
loadFunction={(e) => this.customBackground(e, this.state.currentBackgroundIndex)}
/>
{this.videoCustomSettings()}
<Modal

View File

@@ -1,110 +1,74 @@
import variables from 'config/variables';
import { PureComponent } from 'react';
import { useState, useEffect } from 'react';
import { MdOutlineOpenInNew } from 'react-icons/md';
import { Radio } from 'components/Form/Settings';
import languages from '@/i18n/languages.json';
class LanguageOptions extends PureComponent {
constructor() {
super();
this.state = {
quoteLanguages: [
{
name: variables.getMessage('modals.main.loading'),
value: 'loading',
},
],
};
this.controller = new AbortController();
}
function LanguageOptions() {
const [quoteLanguages, setQuoteLanguages] = useState([
{
name: variables.getMessage('modals.main.loading'),
value: 'loading',
},
]);
async getquoteLanguages() {
const data = await (
await fetch(variables.constants.API_URL + '/quotes/languages', {
signal: this.controller.signal,
})
).json();
useEffect(() => {
async function getQuoteLanguages() {
const data = await (await fetch(variables.constants.API_URL + '/quotes/languages')).json();
if (this.controller.signal.aborted === true) {
return;
}
const quoteLanguages = data.map((language) => {
return {
name: languages.find((l) => l.value === language.name)
? languages.find((l) => l.value === language.name).name
: 'English',
value: language,
};
});
this.setState({
quoteLanguages,
});
}
componentDidMount() {
if (navigator.onLine === false || localStorage.getItem('offlineMode') === 'true') {
return this.setState({
quoteLanguages: [
{
name: variables.getMessage('modals.main.marketplace.offline.description'),
value: 'loading',
},
],
const quoteLanguages = data.map((language) => {
return {
name: languages.find((l) => l.value === language.name)
? languages.find((l) => l.value === language.name).name
: 'English',
value: language,
};
});
setQuoteLanguages(quoteLanguages);
}
this.getquoteLanguages();
}
getQuoteLanguages();
}, []);
componentWillUnmount() {
// stop making requests
this.controller.abort();
}
render() {
return (
<>
<div className="modalHeader">
<span className="mainTitle">
{variables.getMessage('modals.main.settings.sections.language.title')}
</span>
<div className="headerActions">
<a
className="link"
href="https://hosted.weblate.org/new-lang/mue/mue-tab/"
target="_blank"
rel="noopener noreferrer"
>
Add translation
<MdOutlineOpenInNew />
</a>
</div>
</div>
<div className="languageSettings">
<Radio name="language" options={languages} element=".other" />
</div>
return (
<>
<div className="modalHeader">
<span className="mainTitle">
{variables.getMessage('modals.main.settings.sections.language.quote')}
{variables.getMessage('modals.main.settings.sections.language.title')}
</span>
<div className="languageSettings">
<Radio
name="quoteLanguage"
options={this.state.quoteLanguages.map((language) => {
return { name: language.name, value: language.value.name };
})}
defaultValue={this.state.quoteLanguages[0].name}
category="quote"
/>
</div>
</>
);
}
<div className="headerActions">
<a
className="link"
href="https://hosted.weblate.org/new-lang/mue/mue-tab/"
target="_blank"
rel="noopener noreferrer"
>
Add translation
<MdOutlineOpenInNew />
</a>
</div>
</div>
<div className="languageSettings">
<Radio name="language" options={languages} element=".other" />
</div>
<span className="mainTitle">
{variables.getMessage('modals.main.settings.sections.language.quote')}
</span>
<div className="languageSettings">
<Radio
name="quoteLanguage"
options={quoteLanguages.map((language) => {
return { name: language.name, value: language.value.name };
})}
defaultValue={quoteLanguages[0].name}
category="quote"
/>
</div>
</>
);
}
export { LanguageOptions as default, LanguageOptions };

View File

@@ -1,5 +1,5 @@
import variables from 'config/variables';
import { PureComponent } from 'react';
import { useState, useEffect } from 'react';
import { toast } from 'react-toastify';
import { TextField } from '@mui/material';
@@ -11,165 +11,152 @@ import EventBus from 'utils/eventbus';
import searchEngines from '../search_engines.json';
import defaults from './default';
class SearchOptions extends PureComponent {
constructor() {
super();
this.state = {
customEnabled: false,
customValue: localStorage.getItem('customSearchEngine') || defaults.customSearchEngine,
};
}
function SearchOptions() {
const [customEnabled, setCustomEnabled] = useState(false);
const [customValue, setCustomValue] = useState(
localStorage.getItem('customSearchEngine') || defaults.customSearchEngine,
);
resetSearch() {
function resetSearch() {
localStorage.removeItem('customSearchEngine');
this.setState({
customValue: '',
});
setCustomValue('');
toast(variables.getMessage('toasts.reset'));
}
componentDidMount() {
useEffect(() => {
if (localStorage.getItem('searchEngine') === 'custom') {
this.setState({
customEnabled: true,
});
setCustomEnabled(true);
} else {
localStorage.removeItem('customSearchEngine');
}
}
}, []);
componentDidUpdate() {
if (this.state.customEnabled === true && this.state.customValue !== '') {
localStorage.setItem('customSearchEngine', this.state.customValue);
useEffect(() => {
if (customEnabled === true && customValue !== '') {
localStorage.setItem('customSearchEngine', customValue);
}
EventBus.emit('refresh', 'search');
}
}, [customEnabled, customValue]);
setSearchEngine(input) {
function setSearchEngine(input) {
if (input === 'custom') {
this.setState({
customEnabled: true,
});
setCustomEnabled(true);
} else {
this.setState({
customEnabled: false,
});
setCustomEnabled(false);
localStorage.setItem('searchEngine', input);
}
EventBus.emit('refresh', 'search');
}
render() {
const SEARCH_SECTION = 'modals.main.settings.sections.search';
const AdditionalOptions = () => {
return (
<Row>
<Content
title={variables.getMessage('modals.main.settings.additional_settings')}
subtitle={variables.getMessage(`${SEARCH_SECTION}.additional`)}
/>
<Action>
{/* not supported on firefox */}
{navigator.userAgent.includes('Chrome') && typeof InstallTrigger === 'undefined' ? (
<Checkbox
name="voiceSearch"
text={variables.getMessage(`${SEARCH_SECTION}.voice_search`)}
category="search"
/>
) : null}
<Checkbox
name="searchDropdown"
text={variables.getMessage(`${SEARCH_SECTION}.dropdown`)}
category="search"
element=".other"
/>
<Checkbox
name="searchFocus"
text={variables.getMessage(`${SEARCH_SECTION}.focus`)}
category="search"
element=".other"
/>
<Checkbox
name="autocomplete"
text={variables.getMessage(`${SEARCH_SECTION}.autocomplete`)}
category="search"
/>
</Action>
</Row>
);
};
const SearchEngineSelection = () => {
return (
<Row final={!this.state.customEnabled}>
<Content
title={variables.getMessage(`${SEARCH_SECTION}.search_engine`)}
subtitle={variables.getMessage(
'modals.main.settings.sections.search.search_engine_subtitle',
)}
/>
<Action>
<Dropdown
name="searchEngine"
onChange={(value) => this.setSearchEngine(value)}
items={[
...searchEngines.map((engine) => ({
value: engine.settingsName,
text: engine.name,
})),
{
value: 'custom',
text: variables.getMessage(`${SEARCH_SECTION}.custom`),
},
]}
/>
</Action>
</Row>
);
};
const CustomOptions = () => {
return (
<Row final={true}>
<Content title={variables.getMessage(`${SEARCH_SECTION}.custom`)} />
<Action>
<TextField
label={variables.getMessage(`${SEARCH_SECTION}.custom`)}
value={this.state.customValue}
onInput={(e) => this.setState({ customValue: e.target.value })}
varient="outlined"
InputLabelProps={{ shrink: true }}
/>
<p style={{ marginTop: '0px' }}>
<span className="link" onClick={() => this.resetSearch()}>
{variables.getMessage('modals.main.settings.buttons.reset')}
</span>
</p>
</Action>
</Row>
);
};
const SEARCH_SECTION = 'modals.main.settings.sections.search';
const AdditionalOptions = () => {
return (
<>
<Header
title={variables.getMessage(`${SEARCH_SECTION}.title`)}
setting="searchBar"
category="widgets"
visibilityToggle={true}
<Row>
<Content
title={variables.getMessage('modals.main.settings.additional_settings')}
subtitle={variables.getMessage(`${SEARCH_SECTION}.additional`)}
/>
<PreferencesWrapper setting="searchBar" category="widgets" visibilityToggle={true}>
<AdditionalOptions />
<SearchEngineSelection />
{this.state.customEnabled && CustomOptions()}
</PreferencesWrapper>
</>
<Action>
{/* not supported on firefox */}
{navigator.userAgent.includes('Chrome') && typeof InstallTrigger === 'undefined' ? (
<Checkbox
name="voiceSearch"
text={variables.getMessage(`${SEARCH_SECTION}.voice_search`)}
category="search"
/>
) : null}
<Checkbox
name="searchDropdown"
text={variables.getMessage(`${SEARCH_SECTION}.dropdown`)}
category="search"
element=".other"
/>
<Checkbox
name="searchFocus"
text={variables.getMessage(`${SEARCH_SECTION}.focus`)}
category="search"
element=".other"
/>
<Checkbox
name="autocomplete"
text={variables.getMessage(`${SEARCH_SECTION}.autocomplete`)}
category="search"
/>
</Action>
</Row>
);
}
};
const SearchEngineSelection = () => {
return (
<Row final={!customEnabled}>
<Content
title={variables.getMessage(`${SEARCH_SECTION}.search_engine`)}
subtitle={variables.getMessage(
'modals.main.settings.sections.search.search_engine_subtitle',
)}
/>
<Action>
<Dropdown
name="searchEngine"
onChange={(value) => setSearchEngine(value)}
items={[
...searchEngines.map((engine) => ({
value: engine.settingsName,
text: engine.name,
})),
{
value: 'custom',
text: variables.getMessage(`${SEARCH_SECTION}.custom`),
},
]}
/>
</Action>
</Row>
);
};
const CustomOptions = () => {
return (
<Row final={true}>
<Content title={variables.getMessage(`${SEARCH_SECTION}.custom`)} />
<Action>
<TextField
label={variables.getMessage(`${SEARCH_SECTION}.custom`)}
value={customValue}
onInput={(e) => setCustomValue(e.target.value)}
varient="outlined"
InputLabelProps={{ shrink: true }}
/>
<p style={{ marginTop: '0px' }}>
<span className="link" onClick={() => resetSearch()}>
{variables.getMessage('modals.main.settings.buttons.reset')}
</span>
</p>
</Action>
</Row>
);
};
return (
<>
<Header
title={variables.getMessage(`${SEARCH_SECTION}.title`)}
setting="searchBar"
category="widgets"
visibilityToggle={true}
/>
<PreferencesWrapper setting="searchBar" category="widgets" visibilityToggle={true}>
<AdditionalOptions />
<SearchEngineSelection />
{customEnabled && CustomOptions()}
</PreferencesWrapper>
</>
);
}
export { SearchOptions as default, SearchOptions };