mirror of
https://github.com/mue/mue.git
synced 2026-07-15 04:53:48 +02:00
feat: add update frequency settings for quotes and backgrounds
- Introduced frequency settings for quotes and background updates in multiple languages. - Added new localization keys for "Update Frequency" and its options. - Implemented a new hook `useFrequencyInterval` to manage update intervals based on user settings. - Created a `frequencyManager` utility to handle frequency intervals and update logic. - Updated default settings to include frequency preferences for both quotes and backgrounds.
This commit is contained in:
@@ -5,6 +5,7 @@ import { useBackgroundState } from './hooks/useBackgroundState';
|
||||
import { useBackgroundLoader } from './hooks/useBackgroundLoader';
|
||||
import { useBackgroundRenderer, useBackgroundFilters, useBackgroundOverlayFilters } from './hooks/useBackgroundRenderer';
|
||||
import { useBackgroundEvents } from './hooks/useBackgroundEvents';
|
||||
import { useFrequencyInterval } from '../../hooks/useFrequencyInterval';
|
||||
|
||||
import './scss/index.scss';
|
||||
|
||||
@@ -14,12 +15,13 @@ import './scss/index.scss';
|
||||
*/
|
||||
export default function Background() {
|
||||
const { backgroundData, updateBackground, resetBackground } = useBackgroundState();
|
||||
const { refreshBackground } = useBackgroundLoader(updateBackground, resetBackground);
|
||||
const { loadBackground, refreshBackground } = useBackgroundLoader(updateBackground, resetBackground);
|
||||
const filterStyle = useBackgroundFilters();
|
||||
const overlayFilterStyle = useBackgroundOverlayFilters();
|
||||
|
||||
useBackgroundRenderer(backgroundData);
|
||||
useBackgroundEvents(backgroundData, refreshBackground);
|
||||
useFrequencyInterval('background', loadBackground);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useCallback, useEffect, useRef } from 'react';
|
||||
import { getBackgroundData } from '../api/backgroundLoader';
|
||||
import { shouldUpdateByFrequency, resetStartTime } from 'utils/frequencyManager';
|
||||
|
||||
/**
|
||||
* Hook for loading and refreshing background data
|
||||
@@ -25,6 +26,7 @@ export function useBackgroundLoader(updateBackground, resetBackground) {
|
||||
const data = await getBackgroundData();
|
||||
if (data) {
|
||||
updateBackground(data);
|
||||
resetStartTime('background'); // Reset timestamp after successful load
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to load background:', error);
|
||||
@@ -34,21 +36,31 @@ export function useBackgroundLoader(updateBackground, resetBackground) {
|
||||
}, [updateBackground]);
|
||||
|
||||
const refreshBackground = useCallback(() => {
|
||||
resetStartTime('background'); // Reset timer on manual refresh
|
||||
resetBackground();
|
||||
loadBackground();
|
||||
}, [loadBackground, resetBackground]);
|
||||
|
||||
// Initial load - only run once on mount
|
||||
// Initial load - check frequency before loading
|
||||
useEffect(() => {
|
||||
const changeMode = localStorage.getItem('backgroundchange');
|
||||
const hasStartTime = localStorage.getItem('backgroundStartTime');
|
||||
|
||||
if (!hasStartTime || changeMode === 'refresh') {
|
||||
localStorage.setItem('backgroundStartTime', Date.now());
|
||||
// Check if we should update based on frequency
|
||||
if (shouldUpdateByFrequency('background')) {
|
||||
loadBackground();
|
||||
} else {
|
||||
// Load cached background without fetching new one
|
||||
const cached = localStorage.getItem('currentBackground');
|
||||
if (cached) {
|
||||
try {
|
||||
updateBackground(JSON.parse(cached));
|
||||
} catch {
|
||||
// If cache invalid, load new
|
||||
loadBackground();
|
||||
}
|
||||
} else {
|
||||
loadBackground();
|
||||
}
|
||||
}
|
||||
|
||||
loadBackground();
|
||||
}, [loadBackground]);
|
||||
}, [loadBackground, updateBackground]);
|
||||
|
||||
return { loadBackground, refreshBackground };
|
||||
}
|
||||
|
||||
@@ -1,36 +1,70 @@
|
||||
import variables from 'config/variables';
|
||||
import { Checkbox } from 'components/Form/Settings';
|
||||
import { Checkbox, Dropdown } from 'components/Form/Settings';
|
||||
import { Row, Content, Action } from 'components/Layout/Settings/Item';
|
||||
import { FREQUENCY_OPTIONS } from 'utils/frequencyManager';
|
||||
import { clearQueuesOnSettingChange } from 'utils/queueOperations';
|
||||
|
||||
const DisplaySettings = ({ usingImage }) => {
|
||||
return (
|
||||
<Row final={true}>
|
||||
<Content
|
||||
title={variables.getMessage('modals.main.settings.sections.background.display')}
|
||||
subtitle={variables.getMessage(
|
||||
'modals.main.settings.sections.background.display_subtitle',
|
||||
)}
|
||||
/>
|
||||
<Action>
|
||||
<Checkbox
|
||||
name="bgtransition"
|
||||
text={variables.getMessage('modals.main.settings.sections.background.transition')}
|
||||
element=".other"
|
||||
disabled={!usingImage}
|
||||
<>
|
||||
<Row>
|
||||
<Content
|
||||
title={variables.getMessage('modals.main.settings.sections.background.frequency.title')}
|
||||
subtitle={variables.getMessage(
|
||||
'modals.main.settings.sections.background.frequency.subtitle',
|
||||
)}
|
||||
/>
|
||||
<Checkbox
|
||||
name="photoInformation"
|
||||
text={variables.getMessage('modals.main.settings.sections.background.photo_information')}
|
||||
element=".other"
|
||||
<Action>
|
||||
<Dropdown
|
||||
name="backgroundFrequency"
|
||||
label={variables.getMessage('modals.main.settings.sections.background.frequency.title')}
|
||||
onChange={(value) => {
|
||||
localStorage.setItem('backgroundStartTime', Date.now());
|
||||
// Clear queue if switching from refresh to time-based frequency
|
||||
const oldValue = localStorage.getItem('backgroundFrequency');
|
||||
if (oldValue === 'refresh' && value !== 'refresh') {
|
||||
clearQueuesOnSettingChange('backgroundFrequency');
|
||||
}
|
||||
// Notify the frequency interval hook that the frequency changed
|
||||
window.dispatchEvent(new CustomEvent('frequencyChanged', {
|
||||
detail: { type: 'background' }
|
||||
}));
|
||||
}}
|
||||
items={FREQUENCY_OPTIONS.map((opt) => ({
|
||||
value: opt.value,
|
||||
text: variables.getMessage(opt.text),
|
||||
}))}
|
||||
/>
|
||||
</Action>
|
||||
</Row>
|
||||
<Row final={true}>
|
||||
<Content
|
||||
title={variables.getMessage('modals.main.settings.sections.background.display')}
|
||||
subtitle={variables.getMessage(
|
||||
'modals.main.settings.sections.background.display_subtitle',
|
||||
)}
|
||||
/>
|
||||
<Checkbox
|
||||
name="photoMap"
|
||||
text={variables.getMessage('modals.main.settings.sections.background.show_map')}
|
||||
element=".other"
|
||||
disabled={!usingImage}
|
||||
/>
|
||||
</Action>
|
||||
</Row>
|
||||
<Action>
|
||||
<Checkbox
|
||||
name="bgtransition"
|
||||
text={variables.getMessage('modals.main.settings.sections.background.transition')}
|
||||
element=".other"
|
||||
disabled={!usingImage}
|
||||
/>
|
||||
<Checkbox
|
||||
name="photoInformation"
|
||||
text={variables.getMessage('modals.main.settings.sections.background.photo_information')}
|
||||
element=".other"
|
||||
/>
|
||||
<Checkbox
|
||||
name="photoMap"
|
||||
text={variables.getMessage('modals.main.settings.sections.background.show_map')}
|
||||
element=".other"
|
||||
disabled={!usingImage}
|
||||
/>
|
||||
</Action>
|
||||
</Row>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import { ShareModal } from 'components/Elements';
|
||||
import { useQuoteState, useQuoteLoader, useQuoteActions } from './hooks';
|
||||
import { AuthorInfo, AuthorInfoLegacy } from './components';
|
||||
import EventBus from 'utils/eventbus';
|
||||
import { useFrequencyInterval } from '../../hooks/useFrequencyInterval';
|
||||
|
||||
import './scss/index.scss';
|
||||
|
||||
@@ -38,6 +39,9 @@ export default function Quote() {
|
||||
setLocalIsFavourited(!localIsFavourited);
|
||||
};
|
||||
|
||||
// Set up frequency-based interval for automatic quote updates
|
||||
useFrequencyInterval('quote', getQuote);
|
||||
|
||||
useEffect(() => {
|
||||
const handleRefresh = (data) => {
|
||||
if (data === 'quote') {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useCallback } from 'react';
|
||||
import variables from 'config/variables';
|
||||
import offline_quotes from '../offline_quotes.json';
|
||||
import { shouldUpdateByFrequency, resetStartTime } from 'utils/frequencyManager';
|
||||
|
||||
/**
|
||||
* Custom hook for loading quote data from various sources
|
||||
@@ -278,6 +279,21 @@ export function useQuoteLoader(updateQuote) {
|
||||
localStorage.setItem('quotePrefetchEnabled', 'true');
|
||||
}
|
||||
|
||||
// Check if we should update based on frequency
|
||||
if (!shouldUpdateByFrequency('quote')) {
|
||||
// Load cached quote without fetching new one
|
||||
const cached = localStorage.getItem('currentQuote');
|
||||
if (cached) {
|
||||
try {
|
||||
const cachedQuote = JSON.parse(cached);
|
||||
updateQuote(cachedQuote);
|
||||
return;
|
||||
} catch {
|
||||
// If cache invalid, continue to fetch new
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SPECIAL CASE: Favourite quote (highest priority, no queue)
|
||||
const favouriteQuote = localStorage.getItem('favouriteQuote');
|
||||
if (favouriteQuote) {
|
||||
@@ -353,9 +369,10 @@ export function useQuoteLoader(updateQuote) {
|
||||
updateQuote(quoteData);
|
||||
}
|
||||
|
||||
// Step 4: Store current quote
|
||||
// Step 4: Store current quote and reset timestamp
|
||||
try {
|
||||
localStorage.setItem('currentQuote', JSON.stringify(quoteData));
|
||||
resetStartTime('quote'); // Reset timestamp after successfully updating quote
|
||||
} catch (e) {
|
||||
console.warn('Could not save currentQuote to localStorage:', e);
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
} from 'components/Layout/Settings';
|
||||
import { Checkbox, Dropdown, Textarea } from 'components/Form/Settings';
|
||||
import { Button } from 'components/Elements';
|
||||
import { FREQUENCY_OPTIONS } from 'utils/frequencyManager';
|
||||
|
||||
const QuoteOptions = ({ currentSubSection, onSubSectionChange, sectionName }) => {
|
||||
const getCustom = () => {
|
||||
@@ -123,6 +124,39 @@ const QuoteOptions = ({ currentSubSection, onSubSectionChange, sectionName }) =>
|
||||
);
|
||||
};
|
||||
|
||||
const FrequencyOptions = () => {
|
||||
return (
|
||||
<Row>
|
||||
<Content
|
||||
title={variables.getMessage(`${QUOTE_SECTION}.frequency.title`)}
|
||||
subtitle={variables.getMessage(`${QUOTE_SECTION}.frequency.subtitle`)}
|
||||
/>
|
||||
<Action>
|
||||
<Dropdown
|
||||
name="quoteFrequency"
|
||||
label={variables.getMessage(`${QUOTE_SECTION}.frequency.title`)}
|
||||
onChange={(value) => {
|
||||
localStorage.setItem('quoteStartTime', Date.now());
|
||||
// Clear queue if switching from refresh to time-based frequency
|
||||
const oldValue = localStorage.getItem('quoteFrequency');
|
||||
if (oldValue === 'refresh' && value !== 'refresh') {
|
||||
localStorage.removeItem('quoteQueue');
|
||||
}
|
||||
// Notify the frequency interval hook that the frequency changed
|
||||
window.dispatchEvent(new CustomEvent('frequencyChanged', {
|
||||
detail: { type: 'quote' }
|
||||
}));
|
||||
}}
|
||||
items={FREQUENCY_OPTIONS.map((opt) => ({
|
||||
value: opt.value,
|
||||
text: variables.getMessage(opt.text),
|
||||
}))}
|
||||
/>
|
||||
</Action>
|
||||
</Row>
|
||||
);
|
||||
};
|
||||
|
||||
const AdditionalOptions = () => {
|
||||
return (
|
||||
<Row final={true}>
|
||||
@@ -282,6 +316,7 @@ const QuoteOptions = ({ currentSubSection, onSubSectionChange, sectionName }) =>
|
||||
<SourceDropdown />
|
||||
</Section>
|
||||
<ButtonOptions />
|
||||
<FrequencyOptions />
|
||||
<AdditionalOptions />
|
||||
</PreferencesWrapper>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user