refactor: split quicklinks, move features to functional components

This commit is contained in:
David Ralph
2025-10-28 23:04:19 +00:00
parent 2eed0f7307
commit 293cc93500
39 changed files with 2847 additions and 3021 deletions

View File

@@ -1,43 +1,37 @@
import { PureComponent } from 'react';
import { useState, useEffect } from 'react';
import EventBus from 'utils/eventbus';
import './autocomplete.scss';
class Autocomplete extends PureComponent {
constructor(props) {
super(props);
this.state = {
filtered: [],
input: '',
autocompleteDisabled: localStorage.getItem('autocomplete') !== 'true',
};
}
const Autocomplete = ({ suggestions, onChange: onChangeCallback, onClick: onClickCallback, placeholder, id }) => {
const [filtered, setFiltered] = useState([]);
const [input, setInput] = useState('');
const [autocompleteDisabled, setAutocompleteDisabled] = useState(
localStorage.getItem('autocomplete') !== 'true',
);
onChange = (e) => {
if (this.state.autocompleteDisabled) {
return this.setState({
input: e.target.value,
});
const onChange = (e) => {
if (autocompleteDisabled) {
setInput(e.target.value);
return;
}
this.setState({
filtered: this.props.suggestions.filter(
setFiltered(
suggestions.filter(
(suggestion) => suggestion.toLowerCase().indexOf(e.target.value.toLowerCase()) > -1,
),
input: e.target.value,
});
);
setInput(e.target.value);
this.props.onChange(e.target.value);
onChangeCallback(e.target.value);
};
onClick = (e) => {
this.setState({
filtered: [],
input: e.target.innerText,
});
const onClick = (e) => {
setFiltered([]);
setInput(e.target.innerText);
this.props.onClick({
onClickCallback({
preventDefault: () => e.preventDefault(),
target: {
value: e.target.innerText,
@@ -45,51 +39,48 @@ class Autocomplete extends PureComponent {
});
};
componentDidMount() {
EventBus.on('refresh', (data) => {
useEffect(() => {
const handleRefresh = (data) => {
if (data === 'search') {
this.setState({
autocompleteDisabled: localStorage.getItem('autocomplete') !== 'true',
});
setAutocompleteDisabled(localStorage.getItem('autocomplete') !== 'true');
}
});
}
};
componentWillUnmount() {
EventBus.off('refresh');
}
EventBus.on('refresh', handleRefresh);
return () => {
EventBus.off('refresh');
};
}, []);
render() {
let autocomplete = null;
let autocomplete = null;
// length will only be > 0 if enabled
if (this.state.filtered.length > 0 && this.state.input.length > 0) {
autocomplete = (
<div className="suggestions">
{this.state.filtered.map((suggestion) => (
<div key={suggestion} onClick={this.onClick}>
{suggestion}
</div>
))}
</div>
);
}
return (
<div style={{ display: 'flex', flexFlow: 'column' }}>
<input
type="text"
onChange={this.onChange}
value={this.state.input}
placeholder={this.props.placeholder || ''}
autoComplete="off"
spellCheck={false}
id={this.props.id || ''}
/>
{autocomplete}
// length will only be > 0 if enabled
if (filtered.length > 0 && input.length > 0) {
autocomplete = (
<div className="suggestions">
{filtered.map((suggestion) => (
<div key={suggestion} onClick={onClick}>
{suggestion}
</div>
))}
</div>
);
}
}
return (
<div style={{ display: 'flex', flexFlow: 'column' }}>
<input
type="text"
onChange={onChange}
value={input}
placeholder={placeholder || ''}
autoComplete="off"
spellCheck={false}
id={id || ''}
/>
{autocomplete}
</div>
);
};
export { Autocomplete as default, Autocomplete };

View File

@@ -1,5 +1,4 @@
import variables from 'config/variables';
import { PureComponent } from 'react';
import { MdOutlineWarning } from 'react-icons/md';
import { Header, Row, Content, Action, PreferencesWrapper } from 'components/Layout/Settings';
@@ -7,65 +6,62 @@ import { Checkbox } from 'components/Form/Settings';
import EventBus from 'utils/eventbus';
class SearchOptions extends PureComponent {
render() {
const SEARCH_SECTION = 'modals.main.settings.sections.search';
const ChromePolicyWarning = () => {
return (
<div className="itemWarning" style={{ marginBottom: '20px' }}>
<MdOutlineWarning />
<div className="text">
<span className="header">Search Engine Selection Removed</span>
<span>{variables.getMessage(`${SEARCH_SECTION}.chrome_policy_warning`)}</span>
</div>
</div>
);
};
const AdditionalOptions = () => {
return (
<Row final={true}>
<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="searchFocus"
text={variables.getMessage(`${SEARCH_SECTION}.focus`)}
category="search"
element=".other"
/>
</Action>
</Row>
);
};
const SearchOptions = () => {
const SEARCH_SECTION = 'modals.main.settings.sections.search';
const ChromePolicyWarning = () => {
return (
<>
<Header
title={variables.getMessage(`${SEARCH_SECTION}.title`)}
setting="searchBar"
category="widgets"
visibilityToggle={true}
/>
<PreferencesWrapper setting="searchBar" category="widgets" visibilityToggle={true}>
<ChromePolicyWarning />
<AdditionalOptions />
</PreferencesWrapper>
</>
<div className="itemWarning" style={{ marginBottom: '20px' }}>
<MdOutlineWarning />
<div className="text">
<span className="header">Search Engine Selection Removed</span>
<span>{variables.getMessage(`${SEARCH_SECTION}.chrome_policy_warning`)}</span>
</div>
</div>
);
}
}
};
const AdditionalOptions = () => {
return (
<Row final={true}>
<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="searchFocus"
text={variables.getMessage(`${SEARCH_SECTION}.focus`)}
category="search"
element=".other"
/>
</Action>
</Row>
);
};
return (
<>
<Header
title={variables.getMessage(`${SEARCH_SECTION}.title`)}
setting="searchBar"
category="widgets"
visibilityToggle={true}
/>
<PreferencesWrapper setting="searchBar" category="widgets" visibilityToggle={true}>
<ChromePolicyWarning />
<AdditionalOptions />
</PreferencesWrapper>
</>
);
};
export { SearchOptions as default, SearchOptions };