Refactor state updates for consistency and readability across components

- Simplified state updates in Background, Favourite, PhotoInformation, GreetingOptions, Added, Browse, About, Overview, Navbar, Apps, Notes, QuickLinksOptions, Quote, and QuoteOptions components by consolidating multiple lines into single line updates.
- Improved readability by reducing unnecessary line breaks and maintaining consistent formatting in JSX elements.
- Enhanced maintainability by ensuring uniformity in how state is set and how JSX is structured.
This commit is contained in:
alexsparkes
2025-10-27 23:27:37 +00:00
parent 6f05e3bf03
commit 467adcdd85
18 changed files with 296 additions and 480 deletions

View File

@@ -24,11 +24,7 @@ export default [
languageOptions: {
ecmaVersion: 2024,
sourceType: 'module',
parserOptions: {
ecmaFeatures: {
jsx: true,
},
},
parserOptions: { ecmaFeatures: { jsx: true } },
globals: {
// Browser globals
window: 'readonly',
@@ -60,16 +56,8 @@ export default [
require: 'readonly',
},
},
plugins: {
react,
'react-hooks': reactHooks,
'jsx-a11y': jsxA11y,
},
settings: {
react: {
version: 'detect',
},
},
plugins: { react, 'react-hooks': reactHooks, 'jsx-a11y': jsxA11y },
settings: { react: { version: 'detect' } },
rules: {
...js.configs.recommended.rules,
...react.configs.recommended.rules,
@@ -84,7 +72,7 @@ export default [
// General rules
'no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
'no-console': ['warn', { allow: ['warn', 'error'] }],
// Modern JS
'prefer-const': 'warn',
'no-var': 'error',

View File

@@ -1,4 +1,3 @@
// todo: rewrite this mess
import variables from 'config/variables';
import { PureComponent } from 'react';
@@ -24,12 +23,7 @@ export default class Background extends PureComponent {
url: '',
currentAPI: '',
firstTime: false,
photoInfo: {
hidden: false,
offline: false,
photographerURL: '',
photoURL: '',
},
photoInfo: { hidden: false, offline: false, photographerURL: '', photoURL: '' },
};
}
@@ -164,22 +158,9 @@ export default class Background extends PureComponent {
const setFavourited = ({ type, url, credit, location, camera, pun, offline }) => {
if (type === 'random_colour' || type === 'random_gradient') {
return this.setState({
type: 'colour',
style: `background:${url}`,
});
return this.setState({ type: 'colour', style: `background:${url}` });
}
this.setState({
url,
photoInfo: {
credit,
location,
camera,
pun,
offline,
url,
},
});
this.setState({ url, photoInfo: { credit, location, camera, pun, offline, url } });
};
const favourited = JSON.parse(localStorage.getItem('favourite'));
@@ -195,7 +176,8 @@ export default class Background extends PureComponent {
}
// API background
const data = JSON.parse(localStorage.getItem('nextImage')) || (await this.getAPIImageData());
const data =
JSON.parse(localStorage.getItem('nextImage')) || (await this.getAPIImageData());
localStorage.setItem('nextImage', null);
if (data) {
this.setState(data);
@@ -263,9 +245,7 @@ export default class Background extends PureComponent {
url: customBackground,
type: 'custom',
video: videoCheck(customBackground),
photoInfo: {
hidden: true,
},
photoInfo: { hidden: true },
};
this.setState(object);
@@ -363,15 +343,7 @@ export default class Background extends PureComponent {
// this resets it so the fade in and getting background all works properly
const refresh = () => {
element.classList.remove('fade-in');
this.setState({
url: '',
style: '',
type: '',
video: false,
photoInfo: {
hidden: true,
},
});
this.setState({ url: '', style: '', type: '', video: false, photoInfo: { hidden: true } });
this.getBackground();
};

View File

@@ -20,9 +20,7 @@ class Favourite extends PureComponent {
async favourite() {
if (localStorage.getItem('favourite')) {
localStorage.removeItem('favourite');
this.setState({
favourited: this.buttons.unfavourited,
});
this.setState({ favourited: this.buttons.unfavourited });
this.props.tooltipText(variables.getMessage('widgets.quote.favourite'));
variables.stats.postEvent('feature', 'Background favourite');
} else {
@@ -62,13 +60,7 @@ class Favourite extends PureComponent {
}
if (type === 'custom') {
localStorage.setItem(
'favourite',
JSON.stringify({
type,
url,
}),
);
localStorage.setItem('favourite', JSON.stringify({ type, url }));
} else {
// photo information now hides information if it isn't sent, unless if photoinformation hover is hidden
const location = document.getElementById('infoLocation');
@@ -92,9 +84,7 @@ class Favourite extends PureComponent {
}
}
this.setState({
favourited: this.buttons.favourited,
});
this.setState({ favourited: this.buttons.favourited });
this.props.tooltipText(variables.getMessage('widgets.quote.unfavourite'));
variables.stats.postEvent('feature', 'Background unfavourite');
}

View File

@@ -170,12 +170,7 @@ function PhotoInformation({ info, url, api }) {
<Source />
<span id="infoSource">
{info.photoURL ? (
<a
href={info.photoURL}
target="_blank"
rel="noopener noreferrer"
className="link"
>
<a href={info.photoURL} target="_blank" rel="noopener noreferrer" className="link">
{api.charAt(0).toUpperCase() + api.slice(1)}
</a>
) : (

View File

@@ -50,12 +50,7 @@ const GreetingOptions = () => {
const customEvents = JSON.parse(localStorage.getItem('customEvents')) || [];
// Create a new event
const newEvent = {
id: 'widgets.greeting.halloween',
name: '',
month: 1,
date: 1,
};
const newEvent = { id: 'widgets.greeting.halloween', name: '', month: 1, date: 1 };
// Add the new event to the array
const updatedEvents = [...customEvents, newEvent];

View File

@@ -62,18 +62,13 @@ export default class Added extends PureComponent {
}
if (failedReason !== '' && this.state.showFailed === false) {
return this.setState({
failedReason,
showFailed: true,
});
return this.setState({ failedReason, showFailed: true });
}
install(input.type, input, true, false);
toast(variables.getMessage('toasts.installed'));
variables.stats.postEvent('marketplace', 'Sideload');
this.setState({
installed: JSON.parse(localStorage.getItem('installed')),
});
this.setState({ installed: JSON.parse(localStorage.getItem('installed')) });
}
getSideloadButton() {
@@ -91,9 +86,7 @@ export default class Added extends PureComponent {
toggle(type, data) {
if (type === 'item') {
const installed = JSON.parse(localStorage.getItem('installed'));
const info = {
data: installed.find((i) => i.name === data.name),
};
const info = { data: installed.find((i) => i.name === data.name) };
this.setState({
item: {
@@ -110,9 +103,7 @@ export default class Added extends PureComponent {
});
variables.stats.postEvent('marketplace', 'ItemPage viewed');
} else {
this.setState({
item: {},
});
this.setState({ item: {} });
}
}
@@ -157,9 +148,7 @@ export default class Added extends PureComponent {
break;
}
this.setState({
installed,
});
this.setState({ installed });
if (sendEvent) {
variables.stats.postEvent('marketplace', 'Sort');
@@ -178,11 +167,7 @@ export default class Added extends PureComponent {
});
if (updates > 0) {
toast(
variables.getMessage('modals.main.addons.updates_available', {
amount: updates,
}),
);
toast(variables.getMessage('modals.main.addons.updates_available', { amount: updates }));
} else {
toast(variables.getMessage('modals.main.addons.no_updates'));
}
@@ -201,9 +186,7 @@ export default class Added extends PureComponent {
toast(variables.getMessage('toasts.uninstalled_all'));
this.setState({
installed: [],
});
this.setState({ installed: [] });
this.forceUpdate();
}
@@ -301,22 +284,10 @@ export default class Added extends PureComponent {
name="sortAddons"
onChange={(value) => this.sortAddons(value)}
items={[
{
value: 'newest',
text: variables.getMessage('modals.main.addons.sort.newest'),
},
{
value: 'oldest',
text: variables.getMessage('modals.main.addons.sort.oldest'),
},
{
value: 'a-z',
text: variables.getMessage('modals.main.addons.sort.a_z'),
},
{
value: 'z-a',
text: variables.getMessage('modals.main.addons.sort.z_a'),
},
{ value: 'newest', text: variables.getMessage('modals.main.addons.sort.newest') },
{ value: 'oldest', text: variables.getMessage('modals.main.addons.sort.oldest') },
{ value: 'a-z', text: variables.getMessage('modals.main.addons.sort.a_z') },
{ value: 'z-a', text: variables.getMessage('modals.main.addons.sort.z_a') },
]}
/>
<Items

View File

@@ -21,14 +21,7 @@ import { install, urlParser, uninstall } from 'utils/marketplace';
class Marketplace extends PureComponent {
constructor() {
super();
this.state = {
items: [],
button: '',
done: false,
item: {},
collection: false,
filter: '',
};
this.state = { items: [], button: '', done: false, item: {}, collection: false, filter: '' };
this.buttons = {
uninstall: (
<Button
@@ -112,10 +105,7 @@ class Marketplace extends PureComponent {
document.querySelector('#modal').scrollTop = 0;
variables.stats.postEvent('marketplace-item', `${this.state.item.display_name} viewed`);
} else if (pageType === 'collection') {
this.setState({
done: false,
item: {},
});
this.setState({ done: false, item: {} });
const collection = await (
await fetch(`${variables.constants.API_URL}/marketplace/collection/${data}`, {
signal: this.controller.signal,
@@ -130,25 +120,17 @@ class Marketplace extends PureComponent {
done: true,
});
} else {
this.setState({
item: {},
});
this.setState({ item: {} });
}
}
async getItems() {
this.setState({
done: false,
});
this.setState({ done: false });
const dataURL =
this.props.type === 'collections'
? variables.constants.API_URL + '/marketplace/collections'
: variables.constants.API_URL + '/marketplace/items/' + this.props.type;
const { data } = await (
await fetch(dataURL, {
signal: this.controller.signal,
})
).json();
const { data } = await (await fetch(dataURL, { signal: this.controller.signal })).json();
const collections = await (
await fetch(variables.constants.API_URL + '/marketplace/collections', {
signal: this.controller.signal,
@@ -180,9 +162,7 @@ class Marketplace extends PureComponent {
}
toast(variables.getMessage('toasts.' + type + 'ed'));
this.setState({
button: type === 'install' ? this.buttons.uninstall : this.buttons.install,
});
this.setState({ button: type === 'install' ? this.buttons.uninstall : this.buttons.install });
variables.stats.postEvent(
'marketplace-item',
@@ -250,10 +230,7 @@ class Marketplace extends PureComponent {
variables.stats.postEvent('marketplace', 'Sort');
}
return {
items: items,
sortType: value,
};
return { items: items, sortType: value };
}
changeSort(value) {
@@ -262,10 +239,7 @@ class Marketplace extends PureComponent {
}
returnToMain() {
this.setState({
items: this.state.oldItems,
collection: false,
});
this.setState({ items: this.state.oldItems, collection: false });
}
componentDidMount() {
@@ -411,14 +385,8 @@ class Marketplace extends PureComponent {
name="sortMarketplace"
onChange={(value) => this.changeSort(value)}
items={[
{
value: 'a-z',
text: variables.getMessage('modals.main.addons.sort.a_z'),
},
{
value: 'z-a',
text: variables.getMessage('modals.main.addons.sort.z_a'),
},
{ value: 'a-z', text: variables.getMessage('modals.main.addons.sort.a_z') },
{ value: 'z-a', text: variables.getMessage('modals.main.addons.sort.z_a') },
]}
/>
</div>

View File

@@ -345,11 +345,7 @@ class About extends PureComponent {
</div>
<div
className="settingsRow"
style={{
flexFlow: 'column',
alignItems: 'flex-start',
minHeight: '10px',
}}
style={{ flexFlow: 'column', alignItems: 'flex-start', minHeight: '10px' }}
>
<span className="title">
{variables.getMessage('modals.main.settings.sections.about.photographers')}

View File

@@ -40,10 +40,7 @@ const widget_name = {
const SortableItem = ({ id }) => {
const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id });
const style = {
transform: CSS.Transform.toString(transform),
transition,
};
const style = { transform: CSS.Transform.toString(transform), transition };
return (
<li ref={setNodeRef} style={style} {...attributes} {...listeners} className="sortableItem">
@@ -77,9 +74,7 @@ const Overview = () => {
const sensors = useSensors(
useSensor(PointerSensor),
useSensor(KeyboardSensor, {
coordinateGetter: sortableKeyboardCoordinates,
}),
useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }),
);
const handleDragEnd = (event) => {
@@ -135,11 +130,7 @@ const Overview = () => {
const data = await response.json();
data.date = new window.Date(data.date).toLocaleDateString(
variables.languagecode.replace('_', '-'),
{
year: 'numeric',
month: 'long',
day: 'numeric',
},
{ year: 'numeric', month: 'long', day: 'numeric' },
);
setNews(data);
setNewsDone(true);
@@ -187,7 +178,11 @@ const Overview = () => {
<span className="title">
{variables.getMessage('modals.main.settings.sections.order.title')}
</span>
<DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
<DndContext
sensors={sensors}
collisionDetection={closestCenter}
onDragEnd={handleDragEnd}
>
<SortableContext items={items} strategy={verticalListSortingStrategy}>
<ul className="sortableContainer">
{items.map((value) => {

View File

@@ -51,9 +51,7 @@ class Navbar extends PureComponent {
break;
}
this.setState({
refreshText,
});
this.setState({ refreshText });
}
componentDidMount() {

View File

@@ -45,15 +45,11 @@ class Apps extends PureComponent {
}
showApps() {
this.setState({
showApps: true,
});
this.setState({ showApps: true });
}
hideApps() {
this.setState({
showApps: localStorage.getItem('AppsPinned') === 'true',
});
this.setState({ showApps: localStorage.getItem('AppsPinned') === 'true' });
}
render() {
@@ -137,9 +133,7 @@ function AppsWrapper() {
const { x, y, refs, strategy } = useFloating({
placement: 'bottom',
middleware: [shift()],
elements: {
reference,
},
elements: { reference },
});
return (

View File

@@ -47,30 +47,22 @@ class Notes extends PureComponent {
setNotes = (e) => {
localStorage.setItem('notes', e.target.value);
this.setState({
notes: e.target.value,
});
this.setState({ notes: e.target.value });
};
showNotes() {
this.setState({
showNotes: true,
});
this.setState({ showNotes: true });
}
hideNotes() {
this.setState({
showNotes: localStorage.getItem('notesPinned') === 'true',
});
this.setState({ showNotes: localStorage.getItem('notesPinned') === 'true' });
}
pin() {
variables.stats.postEvent('feature', 'Notes pin');
const notesPinned = localStorage.getItem('notesPinned') === 'true';
localStorage.setItem('notesPinned', !notesPinned);
this.setState({
showNotes: !notesPinned,
});
this.setState({ showNotes: !notesPinned });
}
copy() {
@@ -156,9 +148,7 @@ function NotesWrapper() {
const { x, y, refs, strategy } = useFloating({
placement: 'bottom',
middleware: [shift()],
elements: {
reference,
},
elements: { reference },
});
return (

View File

@@ -59,7 +59,10 @@ const SortableItem = ({ value, enabled, startEditLink, deleteLink }) => {
};
const getIconUrl = (item) => {
return item.icon || 'https://icon.horse/icon/' + item.url.replace('https://', '').replace('http://', '');
return (
item.icon ||
'https://icon.horse/icon/' + item.url.replace('https://', '').replace('http://', '')
);
};
return (
@@ -115,14 +118,8 @@ const SortableItem = ({ value, enabled, startEditLink, deleteLink }) => {
const SortableList = ({ items, enabled, onDragEnd, startEditLink, deleteLink }) => {
const sensors = useSensors(
useSensor(PointerSensor, {
activationConstraint: {
distance: 6,
},
}),
useSensor(KeyboardSensor, {
coordinateGetter: sortableKeyboardCoordinates,
}),
useSensor(PointerSensor, { activationConstraint: { distance: 6 } }),
useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }),
);
return (
@@ -162,85 +159,88 @@ class QuickLinksOptions extends PureComponent {
}
setContainerDisplay(enabled) {
if (!this.quicklinksContainer || !this.quicklinksContainer.current) return;
const el = this.quicklinksContainer.current;
el.classList.toggle('disabled', !enabled);
if (!enabled) {
el.setAttribute('aria-hidden', 'true');
} else {
el.removeAttribute('aria-hidden');
if (!this.quicklinksContainer || !this.quicklinksContainer.current) return;
const el = this.quicklinksContainer.current;
el.classList.toggle('disabled', !enabled);
if (!enabled) {
el.setAttribute('aria-hidden', 'true');
} else {
el.removeAttribute('aria-hidden');
}
}
}
deleteLink(key, event) {
event.preventDefault();
const stored = readQuicklinks();
const data = stored.filter((i) => i.key !== key);
this.silenceEvent = true;
localStorage.setItem('quicklinks', JSON.stringify(data));
this.setState({ items: data }, () => {
variables.stats.postEvent('feature', 'Quicklink delete');
EventBus.emit('refresh', 'quicklinks');
setTimeout(() => { this.silenceEvent = false; }, 0);
});
}
event.preventDefault();
const stored = readQuicklinks();
const data = stored.filter((i) => i.key !== key);
this.silenceEvent = true;
localStorage.setItem('quicklinks', JSON.stringify(data));
this.setState({ items: data }, () => {
variables.stats.postEvent('feature', 'Quicklink delete');
EventBus.emit('refresh', 'quicklinks');
setTimeout(() => {
this.silenceEvent = false;
}, 0);
});
}
async addLink(name, url, icon) {
const data = readQuicklinks();
const data = readQuicklinks();
if (!url.startsWith('http://') && !url.startsWith('https://')) {
url = 'https://' + url;
if (!url.startsWith('http://') && !url.startsWith('https://')) {
url = 'https://' + url;
}
if (url.length <= 0 || isValidUrl(url) === false) {
return this.setState({ urlError: variables.getMessage('widgets.quicklinks.url_error') });
}
if (icon.length > 0 && isValidUrl(icon) === false) {
return this.setState({ iconError: variables.getMessage('widgets.quicklinks.url_error') });
}
const newItem = {
name: name || (await getTitleFromUrl(url)),
url,
icon: icon || '',
key: Date.now().toString() + Math.random().toString(36).substring(2),
};
data.push(newItem);
this.silenceEvent = true;
localStorage.setItem('quicklinks', JSON.stringify(data));
this.setState({ items: data, showAddModal: false, urlError: '', iconError: '' }, () => {
variables.stats.postEvent('feature', 'Quicklink add');
EventBus.emit('refresh', 'quicklinks');
setTimeout(() => {
this.silenceEvent = false;
}, 0);
});
}
if (url.length <= 0 || isValidUrl(url) === false) {
return this.setState({ urlError: variables.getMessage('widgets.quicklinks.url_error') });
}
if (icon.length > 0 && isValidUrl(icon) === false) {
return this.setState({ iconError: variables.getMessage('widgets.quicklinks.url_error') });
}
const newItem = {
name: name || (await getTitleFromUrl(url)),
url,
icon: icon || '',
key: Date.now().toString() + Math.random().toString(36).substring(2),
};
data.push(newItem);
this.silenceEvent = true;
localStorage.setItem('quicklinks', JSON.stringify(data));
this.setState({ items: data, showAddModal: false, urlError: '', iconError: '' }, () => {
variables.stats.postEvent('feature', 'Quicklink add');
EventBus.emit('refresh', 'quicklinks');
setTimeout(() => { this.silenceEvent = false; }, 0);
});
}
startEditLink(data) {
this.setState({ edit: true, editData: data, showAddModal: true });
}
async editLink(og, name, url, icon) {
const data = readQuicklinks();
const dataobj = data.find((i) => i.key === og.key);
if (!dataobj) return;
const data = readQuicklinks();
const dataobj = data.find((i) => i.key === og.key);
if (!dataobj) return;
dataobj.name = name || (await getTitleFromUrl(url));
dataobj.url = url;
dataobj.icon = icon || '';
this.silenceEvent = true;
localStorage.setItem('quicklinks', JSON.stringify(data));
this.setState({ items: data, showAddModal: false, edit: false }, () => {
EventBus.emit('refresh', 'quicklinks');
setTimeout(() => { this.silenceEvent = false; }, 0);
});
}
dataobj.name = name || (await getTitleFromUrl(url));
dataobj.url = url;
dataobj.icon = icon || '';
this.silenceEvent = true;
localStorage.setItem('quicklinks', JSON.stringify(data));
this.setState({ items: data, showAddModal: false, edit: false }, () => {
EventBus.emit('refresh', 'quicklinks');
setTimeout(() => {
this.silenceEvent = false;
}, 0);
});
}
arrayMove = (array, oldIndex, newIndex) => {
const result = Array.from(array);
@@ -251,7 +251,7 @@ class QuickLinksOptions extends PureComponent {
handleDragEnd = (event) => {
const { active, over } = event;
if (!over || !this.state.enabled) return;
if (active.id === over.id) return;
@@ -272,51 +272,48 @@ class QuickLinksOptions extends PureComponent {
});
};
componentDidMount() {
this.setContainerDisplay(this.state.enabled);
this.setContainerDisplay(this.state.enabled);
this.handleRefresh = (data) => {
if (data !== 'quicklinks') return;
if (this.silenceEvent) return;
this.handleRefresh = (data) => {
if (data !== 'quicklinks') return;
if (this.silenceEvent) return;
const enabled = localStorage.getItem('quicklinksenabled') !== 'false';
const newItems = readQuicklinks();
const oldItems = this.state.items || [];
const oldKeys = new Set(oldItems.map(i => i.key));
const newKeys = new Set(newItems.map(i => i.key));
const enabled = localStorage.getItem('quicklinksenabled') !== 'false';
const newItems = readQuicklinks();
const oldItems = this.state.items || [];
const oldKeys = new Set(oldItems.map((i) => i.key));
const newKeys = new Set(newItems.map((i) => i.key));
const keysEqual =
oldItems.length === newItems.length &&
oldItems.every(i => newKeys.has(i.key));
const keysEqual =
oldItems.length === newItems.length && oldItems.every((i) => newKeys.has(i.key));
if (enabled !== this.state.enabled || !keysEqual) {
this.setContainerDisplay(enabled);
this.setState({ items: newItems, enabled });
}
};
EventBus.on('refresh', this.handleRefresh);
}
if (enabled !== this.state.enabled || !keysEqual) {
this.setContainerDisplay(enabled);
this.setState({ items: newItems, enabled });
}
};
EventBus.on('refresh', this.handleRefresh);
}
componentDidUpdate(prevProps, prevState) {
if (prevState.enabled !== this.state.enabled) {
this.setContainerDisplay(this.state.enabled);
}
}
componentWillUnmount() {
if (this.handleRefresh) {
EventBus.off('refresh', this.handleRefresh);
} else {
try {
EventBus.off('refresh');
} catch {
// Ignore errors
if (prevState.enabled !== this.state.enabled) {
this.setContainerDisplay(this.state.enabled);
}
}
componentWillUnmount() {
if (this.handleRefresh) {
EventBus.off('refresh', this.handleRefresh);
} else {
try {
EventBus.off('refresh');
} catch {
// Ignore errors
}
}
}
}
render() {
const QUICKLINKS_SECTION = 'modals.main.settings.sections.quicklinks';
const { enabled } = this.state;
@@ -328,8 +325,16 @@ class QuickLinksOptions extends PureComponent {
subtitle={variables.getMessage(`${QUICKLINKS_SECTION}.additional`)}
/>
<Action>
<Checkbox name="quicklinksnewtab" text={variables.getMessage(`${QUICKLINKS_SECTION}.open_new`)} category="quicklinks" />
<Checkbox name="quicklinkstooltip" text={variables.getMessage(`${QUICKLINKS_SECTION}.tooltip`)} category="quicklinks" />
<Checkbox
name="quicklinksnewtab"
text={variables.getMessage(`${QUICKLINKS_SECTION}.open_new`)}
category="quicklinks"
/>
<Checkbox
name="quicklinkstooltip"
text={variables.getMessage(`${QUICKLINKS_SECTION}.tooltip`)}
category="quicklinks"
/>
</Action>
</Row>
);
@@ -338,7 +343,9 @@ class QuickLinksOptions extends PureComponent {
<Row>
<Content
title={variables.getMessage(`${QUICKLINKS_SECTION}.styling`)}
subtitle={variables.getMessage('modals.main.settings.sections.quicklinks.styling_description')}
subtitle={variables.getMessage(
'modals.main.settings.sections.quicklinks.styling_description',
)}
/>
<Action>
<Dropdown
@@ -347,7 +354,10 @@ class QuickLinksOptions extends PureComponent {
category="quicklinks"
items={[
{ value: 'icon', text: variables.getMessage(`${QUICKLINKS_SECTION}.options.icon`) },
{ value: 'text_only', text: variables.getMessage(`${QUICKLINKS_SECTION}.options.text_only`) },
{
value: 'text_only',
text: variables.getMessage(`${QUICKLINKS_SECTION}.options.text_only`),
},
{ value: 'metro', text: variables.getMessage(`${QUICKLINKS_SECTION}.options.metro`) },
]}
/>
@@ -395,9 +405,18 @@ class QuickLinksOptions extends PureComponent {
<div className="photosEmpty">
<div className="emptyNewMessage">
<MdLinkOff />
<span className="title">{variables.getMessage(`${QUICKLINKS_SECTION}.no_quicklinks`)}</span>
<span className="subtitle">{variables.getMessage('modals.main.settings.sections.message.add_some')}</span>
<Button type="settings" onClick={() => this.setState({ showAddModal: true })} icon={<MdAddLink />} label={variables.getMessage(`${QUICKLINKS_SECTION}.add_link`)} />
<span className="title">
{variables.getMessage(`${QUICKLINKS_SECTION}.no_quicklinks`)}
</span>
<span className="subtitle">
{variables.getMessage('modals.main.settings.sections.message.add_some')}
</span>
<Button
type="settings"
onClick={() => this.setState({ showAddModal: true })}
icon={<MdAddLink />}
label={variables.getMessage(`${QUICKLINKS_SECTION}.add_link`)}
/>
</div>
</div>
)}
@@ -432,7 +451,9 @@ class QuickLinksOptions extends PureComponent {
editLink={(og, name, url, icon) => this.editLink(og, name, url, icon)}
edit={this.state.edit}
editData={this.state.editData}
closeModal={() => this.setState({ showAddModal: false, urlError: '', iconError: '', edit: false })}
closeModal={() =>
this.setState({ showAddModal: false, urlError: '', iconError: '', edit: false })
}
/>
</Modal>
</>
@@ -440,4 +461,4 @@ class QuickLinksOptions extends PureComponent {
}
}
export { QuickLinksOptions as default, QuickLinksOptions };
export { QuickLinksOptions as default, QuickLinksOptions };

View File

@@ -122,10 +122,7 @@ class Quote extends PureComponent {
async getAuthorImg(author) {
if (localStorage.getItem('authorImg') === 'false') {
return {
authorimg: null,
authorimglicense: null,
};
return { authorimg: null, authorimglicense: null };
}
const authorimgdata = await (
@@ -185,10 +182,7 @@ class Quote extends PureComponent {
authorimglicense = null;
}
return {
authorimg,
authorimglicense,
};
return { authorimg, authorimglicense };
}
async getQuote() {
@@ -237,9 +231,7 @@ class Quote extends PureComponent {
noQuote: false,
});
} else {
this.setState({
noQuote: true,
});
this.setState({ noQuote: true });
}
break;
}
@@ -330,14 +322,10 @@ class Quote extends PureComponent {
favourite() {
if (localStorage.getItem('favouriteQuote')) {
localStorage.removeItem('favouriteQuote');
this.setState({
favourited: this.buttons.unfavourited,
});
this.setState({ favourited: this.buttons.unfavourited });
} else {
localStorage.setItem('favouriteQuote', this.state.quote + ' - ' + this.state.author);
this.setState({
favourited: this.buttons.favourited,
});
this.setState({ favourited: this.buttons.favourited });
}
variables.stats.postEvent('feature', 'Quote favourite');
@@ -438,85 +426,91 @@ class Quote extends PureComponent {
{localStorage.getItem('widgetStyle') === 'legacy' ? (
<>
{ this.authorDetails && (
{this.authorDetails && (
<>
<div>
<h1 className="quoteauthor" ref={this.quoteauthor}>
<a
href={this.state.authorlink}
className="quoteAuthorLink"
target="_blank"
rel="noopener noreferrer"
aria-label="Learn about the author of the quote."
>
{this.state.author}
</a>
</h1>
</div>
<div style={{ display: 'flex', justifyContent: 'center', gap: '20px' }}>
{this.state.copy} {this.state.share} {this.state.favourited}
</div>
</>
)}
<div>
<h1 className="quoteauthor" ref={this.quoteauthor}>
<a
href={this.state.authorlink}
className="quoteAuthorLink"
target="_blank"
rel="noopener noreferrer"
aria-label="Learn about the author of the quote."
>
{this.state.author}
</a>
</h1>
</div>
<div style={{ display: 'flex', justifyContent: 'center', gap: '20px' }}>
{this.state.copy} {this.state.share} {this.state.favourited}
</div>
</>
)}
</>
) : (
<>
{ this.authorDetails && (
<>
<div className="author-holder">
<div className="author">
{localStorage.getItem('authorImg') !== 'false' ? (
<div
className="author-img"
style={{ backgroundImage: `url(${this.state.authorimg})` }}
>
{this.state.authorimg === undefined || this.state.authorimg ? '' : <MdPerson />}
</div>
) : null}
{this.state.author !== null ? (
<div className="author-content" ref={this.quoteauthor}>
<span className="title">{this.state.author}</span>
{this.state.authorOccupation !== 'Unknown' && (
<span className="subtitle">{this.state.authorOccupation}</span>
)}
<span className="author-license" title={this.state.authorimglicense}>
{this.state.authorimglicense &&
this.state.authorimglicense.substring(0, 40) +
(this.state.authorimglicense.length > 40 ? '…' : '')}
</span>
</div>
) : (
<div className="author-content whileLoading" ref={this.quoteauthor}>
{/* these are placeholders for skeleton and as such don't need translating */}
<span className="title pulse">loading</span>
<span className="subtitle pulse">loading</span>
</div>
)}
{(this.state.authorOccupation !== 'Unknown' && this.state.authorlink !== null) ||
this.state.copy ||
this.state.share ||
this.state.favourited ? (
<div className="quote-buttons">
{this.state.authorOccupation !== 'Unknown' && this.state.authorlink !== null ? (
<Tooltip title={variables.getMessage('widgets.quote.link_tooltip')}>
<a
href={this.state.authorlink}
className="quoteAuthorLink"
target="_blank"
rel="noopener noreferrer"
aria-label="Learn about the author of the quote."
{this.authorDetails && (
<>
<div className="author-holder">
<div className="author">
{localStorage.getItem('authorImg') !== 'false' ? (
<div
className="author-img"
style={{ backgroundImage: `url(${this.state.authorimg})` }}
>
<MdOpenInNew />
</a>{' '}
</Tooltip>
) : null}
{this.state.copy} {this.state.share} {this.state.favourited}
{this.state.authorimg === undefined || this.state.authorimg ? (
''
) : (
<MdPerson />
)}
</div>
) : null}
{this.state.author !== null ? (
<div className="author-content" ref={this.quoteauthor}>
<span className="title">{this.state.author}</span>
{this.state.authorOccupation !== 'Unknown' && (
<span className="subtitle">{this.state.authorOccupation}</span>
)}
<span className="author-license" title={this.state.authorimglicense}>
{this.state.authorimglicense &&
this.state.authorimglicense.substring(0, 40) +
(this.state.authorimglicense.length > 40 ? '…' : '')}
</span>
</div>
) : (
<div className="author-content whileLoading" ref={this.quoteauthor}>
{/* these are placeholders for skeleton and as such don't need translating */}
<span className="title pulse">loading</span>
<span className="subtitle pulse">loading</span>
</div>
)}
{(this.state.authorOccupation !== 'Unknown' &&
this.state.authorlink !== null) ||
this.state.copy ||
this.state.share ||
this.state.favourited ? (
<div className="quote-buttons">
{this.state.authorOccupation !== 'Unknown' &&
this.state.authorlink !== null ? (
<Tooltip title={variables.getMessage('widgets.quote.link_tooltip')}>
<a
href={this.state.authorlink}
className="quoteAuthorLink"
target="_blank"
rel="noopener noreferrer"
aria-label="Learn about the author of the quote."
>
<MdOpenInNew />
</a>{' '}
</Tooltip>
) : null}
{this.state.copy} {this.state.share} {this.state.favourited}
</div>
) : null}
</div>
</div>
) : null}
</div>
</div>
</>
)}
</>
)}
</>
)}
</div>

View File

@@ -29,14 +29,7 @@ class QuoteOptions extends PureComponent {
resetCustom = () => {
localStorage.setItem('customQuote', '[{"quote": "", "author": ""}]');
this.setState({
customQuote: [
{
quote: '',
author: '',
},
],
});
this.setState({ customQuote: [{ quote: '', author: '' }] });
toast(variables.getMessage('toasts.reset'));
EventBus.emit('refresh', 'background');
};
@@ -46,9 +39,7 @@ class QuoteOptions extends PureComponent {
const customQuote = this.state.customQuote;
customQuote[index][type] = result;
this.setState({
customQuote,
});
this.setState({ customQuote });
this.forceUpdate();
localStorage.setItem('customQuote', JSON.stringify(customQuote));
@@ -59,17 +50,12 @@ class QuoteOptions extends PureComponent {
modifyCustomQuote(type, index) {
const customQuote = this.state.customQuote;
if (type === 'add') {
customQuote.push({
quote: '',
author: '',
});
customQuote.push({ quote: '', author: '' });
} else {
customQuote.splice(index, 1);
}
this.setState({
customQuote,
});
this.setState({ customQuote });
this.forceUpdate();
localStorage.setItem('customQuote', JSON.stringify(customQuote));
@@ -153,7 +139,7 @@ class QuoteOptions extends PureComponent {
name="authorLink"
text={variables.getMessage(`${QUOTE_SECTION}.author_link`)}
element=".other"
disabled={localStorage.getItem('authorDetails' )=== 'false'}
disabled={localStorage.getItem('authorDetails') === 'false'}
/>
<Checkbox
name="authorImg"

View File

@@ -46,9 +46,7 @@ export default class Clock extends PureComponent {
// load analog clock css
import('react-clock/dist/Clock.css');
this.setState({
time: now,
});
this.setState({ time: now });
break;
default: {
// Default clock
@@ -78,10 +76,7 @@ export default class Clock extends PureComponent {
});
}
this.setState({
time,
ampm: '',
});
this.setState({ time, ampm: '' });
} else {
// 12 hour
let hours = now.getHours();
@@ -106,10 +101,7 @@ export default class Clock extends PureComponent {
});
}
this.setState({
time,
ampm: now.getHours() > 11 ? 'PM' : 'AM',
});
this.setState({ time, ampm: now.getHours() > 11 ? 'PM' : 'AM' });
}
break;
}

View File

@@ -17,10 +17,7 @@ export function install(type, input, sideload, collection) {
const oldSettings = [];
Object.keys(localStorage).forEach((key) => {
oldSettings.push({
name: key,
value: localStorage.getItem(key),
});
oldSettings.push({ name: key, value: localStorage.getItem(key) });
});
localStorage.setItem('backup_settings', JSON.stringify(oldSettings));

View File

@@ -29,9 +29,7 @@ const prepareBuilds = () => ({
fs.cpSync(
path.resolve(__dirname, './manifest/_locales'),
path.resolve(__dirname, './build/chrome/_locales'),
{
recursive: true,
},
{ recursive: true },
);
fs.cpSync(path.resolve(__dirname, './dist'), path.resolve(__dirname, './build/chrome/'), {
recursive: true,
@@ -39,17 +37,13 @@ const prepareBuilds = () => ({
fs.cpSync(
path.resolve(__dirname, './src/assets/icons'),
path.resolve(__dirname, './build/chrome/icons'),
{
recursive: true,
},
{ recursive: true },
);
fs.mkdirSync(path.resolve(__dirname, './build/chrome/src/assets'), { recursive: true });
fs.cpSync(
path.resolve(__dirname, './src/assets'),
path.resolve(__dirname, './build/chrome/src/assets'),
{
recursive: true,
},
{ recursive: true },
);
// firefox
@@ -68,16 +62,12 @@ const prepareBuilds = () => ({
fs.cpSync(
path.resolve(__dirname, './src/assets/icons'),
path.resolve(__dirname, './build/firefox/icons'),
{
recursive: true,
},
{ recursive: true },
);
fs.cpSync(
path.resolve(__dirname, './src/assets'),
path.resolve(__dirname, './build/firefox/src/assets'),
{
recursive: true,
},
{ recursive: true },
);
// create zip
@@ -94,9 +84,7 @@ const prepareBuilds = () => ({
fs.cpSync(
path.resolve(__dirname, './src/assets'),
path.resolve(__dirname, './dist/src/assets'),
{
recursive: true,
},
{ recursive: true },
);
}
},
@@ -105,17 +93,9 @@ const prepareBuilds = () => ({
export default defineConfig(({ command, mode }) => {
const env = loadEnv(mode, process.cwd(), '');
return {
define: {
__APP_ENV__: JSON.stringify(env.APP_ENV),
},
define: { __APP_ENV__: JSON.stringify(env.APP_ENV) },
plugins: [react(), prepareBuilds(), progress()],
server: {
open: true,
hmr: {
protocol: 'ws',
host: 'localhost',
},
},
server: { open: true, hmr: { protocol: 'ws', host: 'localhost' } },
build: {
target: 'esnext', // Use modern JavaScript features
minify: isProd ? 'esbuild' : false,
@@ -151,12 +131,6 @@ export default defineConfig(({ command, mode }) => {
utils: path.resolve(__dirname, './src/utils'),
},
},
css: {
preprocessorOptions: {
scss: {
api: 'modern-compiler',
},
},
},
css: { preprocessorOptions: { scss: { api: 'modern-compiler' } } },
};
});