From 7b9d51142b331cc18d89f31fd0c0f19fde0df28f Mon Sep 17 00:00:00 2001 From: schroda <50052685+schroda@users.noreply.github.com> Date: Mon, 23 Jun 2025 02:30:29 +0200 Subject: [PATCH] Save selected source languages on the server --- src/modules/browse/Browse.types.ts | 1 + .../global-search/screens/SearchAll.tsx | 4 +-- src/modules/metadata/Metadata.constants.ts | 2 ++ src/modules/settings/Settings.constants.ts | 1 + .../services/ServerSettingsMetadata.ts | 4 +++ src/modules/source/screens/Sources.tsx | 5 ++-- src/modules/source/services/Sources.ts | 28 +++++++++++++++++++ 7 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/modules/browse/Browse.types.ts b/src/modules/browse/Browse.types.ts index b3c591fe..2d0346e2 100644 --- a/src/modules/browse/Browse.types.ts +++ b/src/modules/browse/Browse.types.ts @@ -11,6 +11,7 @@ import { SourceIdInfo } from '@/modules/source/Source.types.ts'; export type MetadataBrowseSettings = { hideLibraryEntries: boolean; extensionLanguages: string[]; + sourceLanguages: string[]; showNsfw: boolean; lastUsedSourceId: SourceIdInfo['id'] | null; shouldShowOnlySourcesWithResults: boolean; diff --git a/src/modules/global-search/screens/SearchAll.tsx b/src/modules/global-search/screens/SearchAll.tsx index 1f190e0d..93f3ae49 100644 --- a/src/modules/global-search/screens/SearchAll.tsx +++ b/src/modules/global-search/screens/SearchAll.tsx @@ -23,8 +23,6 @@ import { useElementSize } from '@mantine/hooks'; import IconButton from '@mui/material/IconButton'; // ms import ArrowForwardIcon from '@mui/icons-material/ArrowForward'; import { requestManager } from '@/lib/requests/RequestManager.ts'; -import { useLocalStorage } from '@/modules/core/hooks/useStorage.tsx'; -import { getDefaultLanguages } from '@/modules/core/utils/Languages.ts'; import { AppbarSearch } from '@/modules/core/components/AppbarSearch.tsx'; import { LanguageSelect } from '@/modules/core/components/inputs/LanguageSelect.tsx'; import { useDebounce } from '@/modules/core/hooks/useDebounce.ts'; @@ -243,7 +241,7 @@ export const SearchAll: React.FC = () => { const [query] = useQueryParam('query', StringParam); const searchString = useDebounce(query, TRIGGER_SEARCH_THRESHOLD); - const [shownLangs, setShownLangs] = useLocalStorage('shownSourceLangs', getDefaultLanguages()); + const { languages: shownLangs, setLanguages: setShownLangs } = Sources.useLanguages(); const { settings: { showNsfw, shouldShowOnlySourcesWithResults }, } = useMetadataServerSettings(); diff --git a/src/modules/metadata/Metadata.constants.ts b/src/modules/metadata/Metadata.constants.ts index d2c10980..99ff5247 100644 --- a/src/modules/metadata/Metadata.constants.ts +++ b/src/modules/metadata/Metadata.constants.ts @@ -88,6 +88,7 @@ export const APP_METADATA_KEY_TO_TYPE = { unread: 'auto', // boolean undefined null showChapterNumber: 'boolean', extensionLanguages: 'string', // string[] + sourceLanguages: 'string', // string[] showNsfw: 'boolean', shouldUseInfiniteScroll: 'boolean', shouldShowTransitionPage: 'boolean', @@ -150,6 +151,7 @@ export const GLOBAL_METADATA_KEYS: AppMetadataKeys[] = [ // browse 'hideLibraryEntries', 'extensionLanguages', + 'sourceLanguages', 'showNsfw', 'lastUsedSourceId', 'shouldShowOnlySourcesWithResults', diff --git a/src/modules/settings/Settings.constants.ts b/src/modules/settings/Settings.constants.ts index ed61dbc0..de3dc9ab 100644 --- a/src/modules/settings/Settings.constants.ts +++ b/src/modules/settings/Settings.constants.ts @@ -43,6 +43,7 @@ export const SERVER_SETTINGS_METADATA_DEFAULT: MetadataServerSettings = { // browse hideLibraryEntries: false, extensionLanguages: getDefaultLanguages(), + sourceLanguages: getDefaultLanguages(), showNsfw: true, lastUsedSourceId: null, shouldShowOnlySourcesWithResults: true, diff --git a/src/modules/settings/services/ServerSettingsMetadata.ts b/src/modules/settings/services/ServerSettingsMetadata.ts index 0bab4508..c066e0d2 100644 --- a/src/modules/settings/services/ServerSettingsMetadata.ts +++ b/src/modules/settings/services/ServerSettingsMetadata.ts @@ -27,6 +27,7 @@ export const convertSettingsToMetadata = ( customThemes: JSON.stringify(settings.customThemes), migrateSortSettings: JSON.stringify(settings.migrateSortSettings), extensionLanguages: JSON.stringify(settings.extensionLanguages), + sourceLanguages: JSON.stringify(settings.sourceLanguages), }); export const convertMetadataToSettings = ( @@ -47,6 +48,9 @@ export const convertMetadataToSettings = ( extensionLanguages: jsonSaveParse((metadata.extensionLanguages as string) ?? '') ?? SERVER_SETTINGS_METADATA_DEFAULT.extensionLanguages, + sourceLanguages: + jsonSaveParse((metadata.sourceLanguages as string) ?? '') ?? + SERVER_SETTINGS_METADATA_DEFAULT.sourceLanguages, }) satisfies MetadataServerSettings; const getMetadataServerSettingsWithDefaultFallback = ( diff --git a/src/modules/source/screens/Sources.tsx b/src/modules/source/screens/Sources.tsx index 0310346e..a8d2f245 100644 --- a/src/modules/source/screens/Sources.tsx +++ b/src/modules/source/screens/Sources.tsx @@ -14,8 +14,7 @@ import { useTranslation } from 'react-i18next'; import Typography from '@mui/material/Typography'; import { CustomTooltip } from '@/modules/core/components/CustomTooltip.tsx'; import { requestManager } from '@/lib/requests/RequestManager.ts'; -import { useLocalStorage } from '@/modules/core/hooks/useStorage.tsx'; -import { DefaultLanguage, getDefaultLanguages } from '@/modules/core/utils/Languages.ts'; +import { DefaultLanguage } from '@/modules/core/utils/Languages.ts'; import { LoadingPlaceholder } from '@/modules/core/components/feedback/LoadingPlaceholder.tsx'; import { SourceCard } from '@/modules/source/components/SourceCard.tsx'; import { LanguageSelect } from '@/modules/core/components/inputs/LanguageSelect.tsx'; @@ -35,7 +34,7 @@ import { StyledGroupItemWrapper } from '@/modules/core/components/virtuoso/Style export function Sources({ tabsMenuHeight }: { tabsMenuHeight: number }) { const { t } = useTranslation(); - const [shownLangs, setShownLangs] = useLocalStorage('shownSourceLangs', getDefaultLanguages()); + const { languages: shownLangs, setLanguages: setShownLangs } = SourceService.useLanguages(); const { settings: { showNsfw, lastUsedSourceId }, } = useMetadataServerSettings(); diff --git a/src/modules/source/services/Sources.ts b/src/modules/source/services/Sources.ts index ebc55f69..f388920e 100644 --- a/src/modules/source/services/Sources.ts +++ b/src/modules/source/services/Sources.ts @@ -6,6 +6,8 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +import { useTranslation } from 'react-i18next'; +import { useCallback } from 'react'; import { SourceDisplayNameInfo, SourceIdInfo, @@ -22,6 +24,12 @@ import { toUniqueLanguageCodes, } from '@/modules/core/utils/Languages.ts'; import { getSourceMetadata } from '@/modules/source/services/SourceMetadata.ts'; +import { + createUpdateMetadataServerSettings, + useMetadataServerSettings, +} from '@/modules/settings/services/ServerSettingsMetadata.ts'; +import { makeToast } from '@/modules/core/utils/Toast.ts'; +import { getErrorMessage } from '@/lib/HelperFunctions.ts'; export class Sources { static readonly LOCAL_SOURCE_ID = '0'; @@ -138,4 +146,24 @@ export class Sources { ): Source | undefined { return sources.find((source) => source.id === lastUsedSourceId); } + + static useLanguages(): { + languages: string[]; + setLanguages: (languages: string[]) => void; + } { + const { t } = useTranslation(); + const { + settings: { sourceLanguages }, + } = useMetadataServerSettings(); + + const updateSetting = createUpdateMetadataServerSettings<'sourceLanguages'>((e) => + makeToast(t('global.error.label.failed_to_save_changes', getErrorMessage(e)), 'error'), + ); + const setLanguages = useCallback((languages: string[]) => updateSetting('sourceLanguages', languages), []); + + return { + languages: sourceLanguages, + setLanguages, + }; + } }