Merge "selected source/extension" languages
This commit is contained in:
@@ -18,6 +18,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|||||||
- (**Theme**) Increase max length of custom theme names to 32 (previously 16)
|
- (**Theme**) Increase max length of custom theme names to 32 (previously 16)
|
||||||
- (**Theme**) Change "pure black mode" paper background color to true black
|
- (**Theme**) Change "pure black mode" paper background color to true black
|
||||||
- (**Library**) Improve library manga sorting
|
- (**Library**) Improve library manga sorting
|
||||||
|
- (**Browse**) Merge languages filter of the sources and extensions into one
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- (**Library**) Fix total library size chip color in light mode
|
- (**Library**) Fix total library size chip color in light mode
|
||||||
|
|||||||
@@ -38,7 +38,9 @@ export function LanguageSelect({ selectedLanguages, setSelectedLanguages, langua
|
|||||||
const languagesSortedBySelectState = useMemo(
|
const languagesSortedBySelectState = useMemo(
|
||||||
() =>
|
() =>
|
||||||
toUniqueLanguageCodes([
|
toUniqueLanguageCodes([
|
||||||
...tmpSelectedLanguages.toSorted(languageSortComparator),
|
...tmpSelectedLanguages
|
||||||
|
.filter((language) => languages.includes(language))
|
||||||
|
.toSorted(languageSortComparator),
|
||||||
...languages.toSorted(languageSortComparator),
|
...languages.toSorted(languageSortComparator),
|
||||||
]),
|
]),
|
||||||
[languages, tmpSelectedLanguages],
|
[languages, tmpSelectedLanguages],
|
||||||
|
|||||||
@@ -10,8 +10,7 @@ import { SourceIdInfo } from '@/features/source/Source.types.ts';
|
|||||||
|
|
||||||
export type MetadataBrowseSettings = {
|
export type MetadataBrowseSettings = {
|
||||||
hideLibraryEntries: boolean;
|
hideLibraryEntries: boolean;
|
||||||
extensionLanguages: string[];
|
browseLanguages: string[];
|
||||||
sourceLanguages: string[];
|
|
||||||
showNsfw: boolean;
|
showNsfw: boolean;
|
||||||
lastUsedSourceId: SourceIdInfo['id'] | null;
|
lastUsedSourceId: SourceIdInfo['id'] | null;
|
||||||
shouldShowOnlySourcesWithResults: boolean;
|
shouldShowOnlySourcesWithResults: boolean;
|
||||||
|
|||||||
@@ -129,10 +129,10 @@ export function Extensions({ tabsMenuHeight }: { tabsMenuHeight: number }) {
|
|||||||
requestManager.useExtensionListFetch();
|
requestManager.useExtensionListFetch();
|
||||||
|
|
||||||
const {
|
const {
|
||||||
settings: { extensionLanguages: shownLangs, showNsfw },
|
settings: { browseLanguages: shownLangs, showNsfw },
|
||||||
} = useMetadataServerSettings();
|
} = useMetadataServerSettings();
|
||||||
const updateMetadataServerSettings = createUpdateMetadataServerSettings<
|
const updateMetadataServerSettings = createUpdateMetadataServerSettings<
|
||||||
keyof Pick<MetadataBrowseSettings, 'extensionLanguages'>
|
keyof Pick<MetadataBrowseSettings, 'browseLanguages'>
|
||||||
>((e) => makeToast(t`Failed to save changes`, 'error', getErrorMessage(e)));
|
>((e) => makeToast(t`Failed to save changes`, 'error', getErrorMessage(e)));
|
||||||
|
|
||||||
const [query] = useQueryParam(SearchParam.QUERY, StringParam);
|
const [query] = useQueryParam(SearchParam.QUERY, StringParam);
|
||||||
@@ -220,7 +220,7 @@ export function Extensions({ tabsMenuHeight }: { tabsMenuHeight: number }) {
|
|||||||
<LanguageSelect
|
<LanguageSelect
|
||||||
selectedLanguages={shownLangs}
|
selectedLanguages={shownLangs}
|
||||||
setSelectedLanguages={(languages: string[]) =>
|
setSelectedLanguages={(languages: string[]) =>
|
||||||
updateMetadataServerSettings('extensionLanguages', languages)
|
updateMetadataServerSettings('browseLanguages', languages)
|
||||||
}
|
}
|
||||||
languages={allLangs}
|
languages={allLangs}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import { MetadataThemeSettings } from '@/features/theme/AppTheme.types.ts';
|
|||||||
import { TapZoneInvertMode } from '@/features/reader/tap-zones/TapZoneLayout.types.ts';
|
import { TapZoneInvertMode } from '@/features/reader/tap-zones/TapZoneLayout.types.ts';
|
||||||
import { detectLocale, getISOLanguage } from '@/lib/ISOLanguageUtil.ts';
|
import { detectLocale, getISOLanguage } from '@/lib/ISOLanguageUtil.ts';
|
||||||
import { i18nResources } from '@/i18n';
|
import { i18nResources } from '@/i18n';
|
||||||
|
import { toUniqueLanguageCodes } from '@/base/utils/Languages.ts';
|
||||||
|
|
||||||
export const APP_METADATA_KEY_PREFIX = 'webUI';
|
export const APP_METADATA_KEY_PREFIX = 'webUI';
|
||||||
|
|
||||||
@@ -333,10 +334,7 @@ export const APP_METADATA: Record<
|
|||||||
showChapterNumber: {
|
showChapterNumber: {
|
||||||
convert: convertToBoolean,
|
convert: convertToBoolean,
|
||||||
},
|
},
|
||||||
extensionLanguages: {
|
browseLanguages: {
|
||||||
convert: convertToObject<string[]>,
|
|
||||||
},
|
|
||||||
sourceLanguages: {
|
|
||||||
convert: convertToObject<string[]>,
|
convert: convertToObject<string[]>,
|
||||||
},
|
},
|
||||||
showNsfw: {
|
showNsfw: {
|
||||||
@@ -437,8 +435,7 @@ export const GLOBAL_METADATA_KEYS: AppMetadataKeys[] = [
|
|||||||
|
|
||||||
// browse
|
// browse
|
||||||
'hideLibraryEntries',
|
'hideLibraryEntries',
|
||||||
'extensionLanguages',
|
'browseLanguages',
|
||||||
'sourceLanguages',
|
|
||||||
'showNsfw',
|
'showNsfw',
|
||||||
'lastUsedSourceId',
|
'lastUsedSourceId',
|
||||||
'shouldShowOnlySourcesWithResults',
|
'shouldShowOnlySourcesWithResults',
|
||||||
@@ -490,11 +487,14 @@ export const GLOBAL_METADATA_KEYS: AppMetadataKeys[] = [
|
|||||||
* getting migrated, the key in the value migration is the "old" key (before the migration to the
|
* getting migrated, the key in the value migration is the "old" key (before the migration to the
|
||||||
* new key).
|
* new key).
|
||||||
*
|
*
|
||||||
|
* For new metadata migrations, the value migrations have already been applied while the key migrations are still outstanding (same as for the value migrations)
|
||||||
|
*
|
||||||
* Migration order (function "applyMetadataMigrations"):
|
* Migration order (function "applyMetadataMigrations"):
|
||||||
* 1. app metadata key prefix
|
* 1. app metadata key prefix
|
||||||
* 2. app metadata values
|
* 2. app metadata values
|
||||||
* 3. app metadata keys
|
* 3. create new app metadata with values from existing metadata
|
||||||
* 4. app metadata keys deletion
|
* 4. app metadata keys
|
||||||
|
* 5. app metadata keys deletion
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* // changes:
|
* // changes:
|
||||||
@@ -666,4 +666,25 @@ export const METADATA_MIGRATIONS: IMetadataMigration[] = [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
key: 'sourceLanguages',
|
||||||
|
oldValue: /^\[.*]$/g,
|
||||||
|
newValue: (sourceLanguagesValue, key, oldMetadata) => {
|
||||||
|
const extensionLanguagesKey = key.replace('sourceLanguages', 'extensionLanguages');
|
||||||
|
const extensionLanguagesValue = oldMetadata[extensionLanguagesKey];
|
||||||
|
|
||||||
|
const convertedSourceLanguages = convertToObject<string[]>(sourceLanguagesValue, []);
|
||||||
|
const convertedExtensionLanguages = convertToObject<string[]>(extensionLanguagesValue, []);
|
||||||
|
|
||||||
|
return JSON.stringify(
|
||||||
|
toUniqueLanguageCodes([...convertedSourceLanguages, ...convertedExtensionLanguages]),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
keys: [{ oldKey: 'sourceLanguages', newKey: 'browseLanguages' }],
|
||||||
|
deleteKeys: ['sourceLanguages', 'extensionLanguages'],
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export interface IMetadataMigration {
|
|||||||
*/
|
*/
|
||||||
key?: string;
|
key?: string;
|
||||||
oldValue: string | RegExp | undefined;
|
oldValue: string | RegExp | undefined;
|
||||||
newValue: string | ((oldValue: string) => string);
|
newValue: string | ((oldValue: string, key: string, oldMetadata: Metadata) => string);
|
||||||
}[];
|
}[];
|
||||||
keys?: { oldKey: string; newKey: string }[];
|
keys?: { oldKey: string; newKey: string }[];
|
||||||
deleteKeys?: string[];
|
deleteKeys?: string[];
|
||||||
|
|||||||
@@ -87,7 +87,8 @@ const applyMetadataValueMigration = (meta: Metadata, migration: IMetadataMigrati
|
|||||||
(oldValue === undefined && meta[metaKey] === oldValue) ||
|
(oldValue === undefined && meta[metaKey] === oldValue) ||
|
||||||
(oldValue !== undefined && meta[metaKey].match(oldValue))
|
(oldValue !== undefined && meta[metaKey].match(oldValue))
|
||||||
) {
|
) {
|
||||||
migratedMetadata[metaKey] = typeof newValue === 'function' ? newValue(meta[metaKey]) : newValue;
|
migratedMetadata[metaKey] =
|
||||||
|
typeof newValue === 'function' ? newValue(meta[metaKey], metaKey, appMetadata) : newValue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -68,8 +68,7 @@ export const SERVER_SETTINGS_METADATA_DEFAULT: MetadataServerSettings = {
|
|||||||
|
|
||||||
// browse
|
// browse
|
||||||
hideLibraryEntries: false,
|
hideLibraryEntries: false,
|
||||||
extensionLanguages: getDefaultLanguages(),
|
browseLanguages: getDefaultLanguages(),
|
||||||
sourceLanguages: getDefaultLanguages(),
|
|
||||||
showNsfw: true,
|
showNsfw: true,
|
||||||
lastUsedSourceId: null,
|
lastUsedSourceId: null,
|
||||||
shouldShowOnlySourcesWithResults: true,
|
shouldShowOnlySourcesWithResults: true,
|
||||||
|
|||||||
@@ -23,8 +23,7 @@ export const convertSettingsToMetadata = (
|
|||||||
devices: JSON.stringify(settings.devices),
|
devices: JSON.stringify(settings.devices),
|
||||||
customThemes: JSON.stringify(settings.customThemes),
|
customThemes: JSON.stringify(settings.customThemes),
|
||||||
migrateSortSettings: JSON.stringify(settings.migrateSortSettings),
|
migrateSortSettings: JSON.stringify(settings.migrateSortSettings),
|
||||||
extensionLanguages: JSON.stringify(settings.extensionLanguages),
|
browseLanguages: JSON.stringify(settings.browseLanguages),
|
||||||
sourceLanguages: JSON.stringify(settings.sourceLanguages),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const getMetadataServerSettingsWithDefaultFallback = (
|
const getMetadataServerSettingsWithDefaultFallback = (
|
||||||
|
|||||||
@@ -157,16 +157,16 @@ export class Sources {
|
|||||||
} {
|
} {
|
||||||
const { t } = useLingui();
|
const { t } = useLingui();
|
||||||
const {
|
const {
|
||||||
settings: { sourceLanguages },
|
settings: { browseLanguages },
|
||||||
} = useMetadataServerSettings();
|
} = useMetadataServerSettings();
|
||||||
|
|
||||||
const updateSetting = createUpdateMetadataServerSettings<'sourceLanguages'>((e) =>
|
const updateSetting = createUpdateMetadataServerSettings<'browseLanguages'>((e) =>
|
||||||
makeToast(t`Failed to save changes`, 'error', getErrorMessage(e)),
|
makeToast(t`Failed to save changes`, 'error', getErrorMessage(e)),
|
||||||
);
|
);
|
||||||
const setLanguages = useCallback((languages: string[]) => updateSetting('sourceLanguages', languages), []);
|
const setLanguages = useCallback((languages: string[]) => updateSetting('browseLanguages', languages), []);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
languages: sourceLanguages,
|
languages: browseLanguages,
|
||||||
setLanguages,
|
setLanguages,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user