feat(Quote): refactor quote component to enhance state management and event handling

This commit is contained in:
alexsparkes
2026-01-24 18:31:50 +00:00
parent 6ca19fc48d
commit d84b09801c
2 changed files with 48 additions and 30 deletions

View File

@@ -2,8 +2,9 @@ import { useEffect, useRef, useState, useMemo } from 'react';
import Modal from 'react-modal'; import Modal from 'react-modal';
import { ShareModal } from 'components/Elements'; import { ShareModal } from 'components/Elements';
import { useQuoteState, useQuoteLoader, useQuoteActions, useQuoteEvents } from './hooks'; import { useQuoteState, useQuoteLoader, useQuoteActions } from './hooks';
import { AuthorInfo, AuthorInfoLegacy } from './components'; import { AuthorInfo, AuthorInfoLegacy } from './components';
import EventBus from 'utils/eventbus';
import './scss/index.scss'; import './scss/index.scss';
@@ -17,49 +18,63 @@ export default function Quote() {
const { copyQuote, toggleFavourite } = useQuoteActions(quoteData); const { copyQuote, toggleFavourite } = useQuoteActions(quoteData);
const quoteRef = useRef(null); const quoteRef = useRef(null);
const [isFavourited, setIsFavourited] = useState(false); const [localIsFavourited, setLocalIsFavourited] = useState(false);
const [display, setDisplay] = useState('block');
const [fontSize, setFontSize] = useState(() => {
const zoomQuote = localStorage.getItem('zoomQuote');
return `${0.8 * Number((zoomQuote || 100) / 100)}em`;
});
const [authorDetails, setAuthorDetails] = useState(localStorage.getItem('authorDetails') === 'true');
const [isLegacyStyle, setIsLegacyStyle] = useState(localStorage.getItem('widgetStyle') === 'legacy');
const settings = useMemo(() => ({ // Compute if current quote is favorited
authorDetails: localStorage.getItem('authorDetails') === 'true', const isFavourited = useMemo(() => {
isLegacyStyle: localStorage.getItem('widgetStyle') === 'legacy', const favQuote = localStorage.getItem('favouriteQuote');
isEnabled: localStorage.getItem('quote') !== 'false', return !!favQuote && favQuote === `${quoteData.quote} - ${quoteData.author}`;
zoom: Number((localStorage.getItem('zoomQuote') || 100) / 100), }, [quoteData.quote, quoteData.author]);
}), []);
const setZoom = () => {
if (quoteRef.current) {
quoteRef.current.style.fontSize = `${0.8 * settings.zoom}em`;
}
};
const handleFavourite = () => { const handleFavourite = () => {
toggleFavourite(); toggleFavourite();
setIsFavourited(!isFavourited); setLocalIsFavourited(!localIsFavourited);
}; };
useQuoteEvents(getQuote, setZoom);
useEffect(() => { useEffect(() => {
const shouldRefresh = localStorage.getItem('quotechange') === 'refresh' || const handleRefresh = (data) => {
if (data === 'quote') {
const quoteSetting = localStorage.getItem('quote');
const zoomQuote = localStorage.getItem('zoomQuote');
const authorDetailsSetting = localStorage.getItem('authorDetails');
const widgetStyle = localStorage.getItem('widgetStyle');
setDisplay(quoteSetting === 'false' ? 'none' : 'block');
setFontSize(`${0.8 * Number((zoomQuote || 100) / 100)}em`);
setAuthorDetails(authorDetailsSetting === 'true');
setIsLegacyStyle(widgetStyle === 'legacy');
} else if (data === 'marketplacequoteuninstall' || data === 'quoterefresh') {
getQuote();
}
};
const shouldRefresh = localStorage.getItem('quotechange') === 'refresh' ||
localStorage.getItem('quotechange') === null; localStorage.getItem('quotechange') === null;
if (shouldRefresh) { if (shouldRefresh) {
setZoom();
getQuote(); getQuote();
localStorage.setItem('quoteStartTime', Date.now()); localStorage.setItem('quoteStartTime', Date.now());
} }
EventBus.on('refresh', handleRefresh);
return () => {
EventBus.off('refresh', handleRefresh);
};
}, [getQuote]); }, [getQuote]);
useEffect(() => { if (quoteData.noQuote) {
setIsFavourited(!!localStorage.getItem('favouriteQuote'));
}, [quoteData.quote]);
if (quoteData.noQuote || !settings.isEnabled) {
return null; return null;
} }
return ( return (
<div className="quotediv"> <div className="quotediv" style={{ display, fontSize }}>
<Modal <Modal
closeTimeoutMS={300} closeTimeoutMS={300}
isOpen={uiState.shareModal} isOpen={uiState.shareModal}
@@ -78,8 +93,8 @@ export default function Quote() {
{quoteData.quote} {quoteData.quote}
</span> </span>
{settings.authorDetails && ( {authorDetails && (
settings.isLegacyStyle ? ( isLegacyStyle ? (
<AuthorInfoLegacy <AuthorInfoLegacy
author={quoteData.author} author={quoteData.author}
authorlink={quoteData.authorlink} authorlink={quoteData.authorlink}

View File

@@ -4,12 +4,15 @@ import EventBus from 'utils/eventbus';
/** /**
* Custom hook for handling quote-related events * Custom hook for handling quote-related events
*/ */
export function useQuoteEvents(getQuote, setZoom) { export function useQuoteEvents(getQuote, setZoom, onSettingsChange) {
useEffect(() => { useEffect(() => {
const handleRefresh = (data) => { const handleRefresh = (data) => {
switch (data) { switch (data) {
case 'quote': case 'quote':
setZoom(); setZoom();
if (onSettingsChange) {
onSettingsChange();
}
break; break;
case 'marketplacequoteuninstall': case 'marketplacequoteuninstall':
case 'quoterefresh': case 'quoterefresh':
@@ -20,5 +23,5 @@ export function useQuoteEvents(getQuote, setZoom) {
EventBus.on('refresh', handleRefresh); EventBus.on('refresh', handleRefresh);
return () => EventBus.off('refresh', handleRefresh); return () => EventBus.off('refresh', handleRefresh);
}, [getQuote, setZoom]); }, [getQuote, setZoom, onSettingsChange]);
} }