From 9f461edb5529b14eb3ab3f9292d58f6a996eeb54 Mon Sep 17 00:00:00 2001 From: alexsparkes Date: Sun, 1 Feb 2026 20:51:52 +0000 Subject: [PATCH] Add new localization strings for quote packs and update caching logic for authors - Added "Installed Quote Packs" and "Get More" strings to multiple language files. - Updated the author caching mechanism in wikidataAuthorFetcher.js to limit the number of cached entries to 50 and prune old entries when the limit is exceeded. - Enhanced the occupation extraction logic to return the highest-ranked occupation based on Wikidata rank. --- .../background/options/BackgroundOptions.jsx | 70 ++++++++++++ .../options/sections/SourceSection.jsx | 72 +++++++++--- src/features/quote/hooks/useQuoteLoader.js | 11 +- src/features/quote/options/QuoteOptions.jsx | 107 +++++++++++++++++- src/i18n/locales/ar.json | 6 +- src/i18n/locales/arz.json | 6 +- src/i18n/locales/az.json | 6 +- src/i18n/locales/azb.json | 6 +- src/i18n/locales/bn.json | 6 +- src/i18n/locales/de_DE.json | 6 +- src/i18n/locales/el.json | 6 +- src/i18n/locales/en_GB.json | 6 +- src/i18n/locales/en_US.json | 6 +- src/i18n/locales/es.json | 6 +- src/i18n/locales/es_419.json | 6 +- src/i18n/locales/et.json | 6 +- src/i18n/locales/fa.json | 6 +- src/i18n/locales/fr.json | 6 +- src/i18n/locales/hu.json | 6 +- src/i18n/locales/id_ID.json | 6 +- src/i18n/locales/ja.json | 6 +- src/i18n/locales/lt.json | 6 +- src/i18n/locales/lv.json | 6 +- src/i18n/locales/nl.json | 6 +- src/i18n/locales/no.json | 6 +- src/i18n/locales/peo.json | 6 +- src/i18n/locales/pt.json | 6 +- src/i18n/locales/pt_BR.json | 6 +- src/i18n/locales/ru.json | 6 +- src/i18n/locales/sl.json | 6 +- src/i18n/locales/sv.json | 6 +- src/i18n/locales/ta.json | 6 +- src/i18n/locales/tr_TR.json | 6 +- src/i18n/locales/uk.json | 6 +- src/i18n/locales/vi.json | 6 +- src/i18n/locales/zh_CN.json | 6 +- src/i18n/locales/zh_Hant.json | 6 +- src/utils/wikidata/wikidataAuthorFetcher.js | 63 +++++++++-- 38 files changed, 462 insertions(+), 59 deletions(-) diff --git a/src/features/background/options/BackgroundOptions.jsx b/src/features/background/options/BackgroundOptions.jsx index 9234fddb..ad899747 100644 --- a/src/features/background/options/BackgroundOptions.jsx +++ b/src/features/background/options/BackgroundOptions.jsx @@ -1,8 +1,11 @@ import variables from 'config/variables'; import { memo, useState, useEffect, useCallback, useRef } from 'react'; import { MdSource, MdOutlineAutoAwesome } from 'react-icons/md'; +import { toast } from 'react-toastify'; import EventBus from 'utils/eventbus'; import { clearQueuesOnSettingChange } from 'utils/queueOperations'; +import { uninstall } from 'utils/marketplace'; +import { updateHash } from 'utils/deepLinking'; import { Header } from 'components/Layout/Settings'; import { Dropdown } from 'components/Form/Settings'; @@ -33,6 +36,18 @@ const BackgroundOptions = memo(({ currentSubSection, onSubSectionChange, section ); const [marketplaceEnabled] = useState(localStorage.getItem('photo_packs')); + // Helper function to get installed photo packs + const getInstalledPhotoPacks = () => { + try { + const installed = JSON.parse(localStorage.getItem('installed')) || []; + return installed.filter((item) => item.type === 'photos'); + } catch { + return []; + } + }; + + const [installedPhotoPacks, setInstalledPhotoPacks] = useState(getInstalledPhotoPacks()); + // Auto-show source section for types without effects/display settings const shouldShowSourceByDefault = ['colour', 'random_colour', 'random_gradient'].includes( backgroundType, @@ -106,6 +121,56 @@ const BackgroundOptions = memo(({ currentSubSection, onSubSectionChange, section }; }, [getBackgroundCategories]); + // Listen for installed addons changes + useEffect(() => { + const handleInstalledAddonsChanged = () => { + setInstalledPhotoPacks(getInstalledPhotoPacks()); + // Update backgroundType if it changed (e.g., when all packs are uninstalled) + const currentType = localStorage.getItem('backgroundType') || 'api'; + if (currentType !== backgroundType) { + setBackgroundType(currentType); + } + }; + + window.addEventListener('installedAddonsChanged', handleInstalledAddonsChanged); + return () => window.removeEventListener('installedAddonsChanged', handleInstalledAddonsChanged); + }, [backgroundType]); + + // Handle photo pack uninstall + const handlePhotoPackUninstall = (type, name) => { + uninstall(type, name); + toast(variables.getMessage('toasts.uninstalled')); + variables.stats.postEvent('marketplace-item', `${name} uninstalled`); + setInstalledPhotoPacks(getInstalledPhotoPacks()); + window.dispatchEvent(new window.Event('installedAddonsChanged')); + }; + + // Navigate to photo packs marketplace + const goToPhotoPacks = () => { + variables.updateHash('#discover/photo_packs'); + const event = new window.Event('popstate'); + window.dispatchEvent(event); + }; + + const handleToggle = (pack) => { + // Navigate to discover tab with the item + const itemId = pack.name; + updateHash(`#discover/all?item=${itemId}`); + + // Trigger navigation + const event = new window.Event('popstate'); + window.dispatchEvent(event); + + variables.stats.postEvent('marketplace', 'ItemPage viewed'); + }; + + // Get total count of photos across all installed packs + const getTotalPhotoCount = () => { + return installedPhotoPacks.reduce((total, pack) => { + return total + (pack.photos?.length || 0); + }, 0); + }; + const getBackgroundSettings = () => { switch (backgroundType) { case 'custom': @@ -231,11 +296,16 @@ const BackgroundOptions = memo(({ currentSubSection, onSubSectionChange, section { // Clear prefetch queue when changing background type clearQueuesOnSettingChange('backgroundType'); setBackgroundType(value); }} + onPhotoPackUninstall={handlePhotoPackUninstall} + onGoToPhotoPacks={goToPhotoPacks} + onToggle={handleToggle} /> {getBackgroundSettings()} diff --git a/src/features/background/options/sections/SourceSection.jsx b/src/features/background/options/sections/SourceSection.jsx index 1d4ab14b..21c9abdf 100644 --- a/src/features/background/options/sections/SourceSection.jsx +++ b/src/features/background/options/sections/SourceSection.jsx @@ -1,25 +1,67 @@ import variables from 'config/variables'; +import { MdExplore } from 'react-icons/md'; import { Dropdown } from 'components/Form/Settings'; import { Row, Content, Action } from 'components/Layout/Settings/Item'; +import { Button } from 'components/Elements'; +import Items from 'features/marketplace/components/Items/Items'; import { getBackgroundOptionItems } from '../optionTypes'; -const SourceSection = ({ backgroundType, marketplaceEnabled, onTypeChange }) => { +const SourceSection = ({ + backgroundType, + marketplaceEnabled, + installedPhotoPacks = [], + totalPhotoCount = 0, + onTypeChange, + onPhotoPackUninstall, + onGoToPhotoPacks, + onToggle, +}) => { + const showInstalledPhotoPacks = + backgroundType === 'photo_pack' && + marketplaceEnabled && + installedPhotoPacks.length > 0; + return ( - - - - + + - - + + + + + + {showInstalledPhotoPacks && ( + <> + + + +