Improve metadata value conversion
The current approach has issues with numbers of type long
This commit is contained in:
@@ -12,91 +12,93 @@ import { DEFAULT_READER_SETTINGS } from '@/modules/reader/constants/ReaderSettin
|
|||||||
|
|
||||||
export const APP_METADATA_KEY_PREFIX = 'webUI';
|
export const APP_METADATA_KEY_PREFIX = 'webUI';
|
||||||
|
|
||||||
const APP_METADATA_OBJECT: Record<AppMetadataKeys, undefined> = {
|
// At the moment any non-primitive types need to be specified as "string" and handled in the according "MetadataService".
|
||||||
migration: undefined,
|
// "auto" can be used to try to automatically convert the value to a specific type (string, number, boolean, undefined, null)
|
||||||
deleteChaptersManuallyMarkedRead: undefined,
|
export const APP_METADATA_KEY_TO_TYPE = {
|
||||||
deleteChaptersWhileReading: undefined,
|
migration: 'number',
|
||||||
deleteChaptersWithBookmark: undefined,
|
deleteChaptersManuallyMarkedRead: 'boolean',
|
||||||
downloadAheadLimit: undefined,
|
deleteChaptersWhileReading: 'number',
|
||||||
showAddToLibraryCategorySelectDialog: undefined,
|
deleteChaptersWithBookmark: 'boolean',
|
||||||
ignoreFilters: undefined,
|
downloadAheadLimit: 'number',
|
||||||
removeMangaFromCategories: undefined,
|
showAddToLibraryCategorySelectDialog: 'boolean',
|
||||||
showTabSize: undefined,
|
ignoreFilters: 'boolean',
|
||||||
devices: undefined,
|
removeMangaFromCategories: 'boolean',
|
||||||
migrateChapters: undefined,
|
showTabSize: 'boolean',
|
||||||
migrateCategories: undefined,
|
devices: 'string', // string[]
|
||||||
migrateTracking: undefined,
|
migrateChapters: 'boolean',
|
||||||
deleteChapters: undefined,
|
migrateCategories: 'boolean',
|
||||||
migrateSortSettings: undefined,
|
migrateTracking: 'boolean',
|
||||||
hideLibraryEntries: undefined,
|
deleteChapters: 'boolean',
|
||||||
updateProgressAfterReading: undefined,
|
migrateSortSettings: 'string', // SortSettings (object)
|
||||||
updateProgressManualMarkRead: undefined,
|
hideLibraryEntries: 'boolean',
|
||||||
webUIInformAvailableUpdate: undefined,
|
updateProgressAfterReading: 'boolean',
|
||||||
serverInformAvailableUpdate: undefined,
|
updateProgressManualMarkRead: 'boolean',
|
||||||
readerWidth: undefined,
|
webUIInformAvailableUpdate: 'boolean',
|
||||||
savedSearches: undefined,
|
serverInformAvailableUpdate: 'boolean',
|
||||||
showContinueReadingButton: undefined,
|
readerWidth: 'string', // object
|
||||||
showDownloadBadge: undefined,
|
savedSearches: 'string', // object
|
||||||
showUnreadBadge: undefined,
|
showContinueReadingButton: 'boolean',
|
||||||
gridLayout: undefined,
|
showDownloadBadge: 'boolean',
|
||||||
sortBy: undefined,
|
showUnreadBadge: 'boolean',
|
||||||
sortDesc: undefined,
|
gridLayout: 'number', // GridLayout (enum)
|
||||||
hasDownloadedChapters: undefined,
|
sortBy: 'auto', // LibrarySortMode undefined null
|
||||||
hasBookmarkedChapters: undefined,
|
sortDesc: 'auto', // boolean undefined null
|
||||||
hasUnreadChapters: undefined,
|
hasDownloadedChapters: 'auto', // boolean undefined null
|
||||||
hasReadChapters: undefined,
|
hasBookmarkedChapters: 'auto', // boolean undefined null
|
||||||
hasDuplicateChapters: undefined,
|
hasUnreadChapters: 'auto', // boolean undefined null
|
||||||
hasTrackerBinding: undefined,
|
hasReadChapters: 'auto', // boolean undefined null
|
||||||
hasStatus: undefined,
|
hasDuplicateChapters: 'auto', // boolean undefined null
|
||||||
customThemes: undefined,
|
hasTrackerBinding: 'string', // object
|
||||||
mangaThumbnailBackdrop: undefined,
|
hasStatus: 'string', // object
|
||||||
mangaDynamicColorSchemes: undefined,
|
customThemes: 'string', // object
|
||||||
tapZoneLayout: undefined,
|
mangaThumbnailBackdrop: 'boolean',
|
||||||
tapZoneInvertMode: undefined,
|
mangaDynamicColorSchemes: 'boolean',
|
||||||
readingDirection: undefined,
|
tapZoneLayout: 'number', // TapZoneLayouts (enum)
|
||||||
progressBarType: undefined,
|
tapZoneInvertMode: 'string', // TapZoneInvertMode (object)
|
||||||
progressBarSize: undefined,
|
readingDirection: 'number', // ReadingDirection (enum)
|
||||||
progressBarPosition: undefined,
|
progressBarType: 'number', // ProgressBarType (enum)
|
||||||
progressBarPositionAutoVertical: undefined,
|
progressBarSize: 'number',
|
||||||
readingMode: undefined,
|
progressBarPosition: 'number', // ProgressBarPosition (enum)
|
||||||
pageScaleMode: undefined,
|
progressBarPositionAutoVertical: 'number', // TProgressBarPositionAutoVertical (enum)
|
||||||
shouldOffsetDoubleSpreads: undefined,
|
readingMode: 'number', // ReadingMode (enum)
|
||||||
exitMode: undefined,
|
pageScaleMode: 'number', // ReaderPageScaleMode (enum)
|
||||||
customFilter: undefined,
|
shouldOffsetDoubleSpreads: 'boolean',
|
||||||
shouldSkipDupChapters: undefined,
|
exitMode: 'number', // ReaderExitMode (enum)
|
||||||
isStaticNav: undefined,
|
customFilter: 'string', // ReaderCustomFilter (object)
|
||||||
overlayMode: undefined,
|
shouldSkipDupChapters: 'boolean',
|
||||||
shouldStretchPage: undefined,
|
isStaticNav: 'boolean',
|
||||||
shouldShowPageNumber: undefined,
|
overlayMode: 'number', // ReaderOverlayMode (enum)
|
||||||
backgroundColor: undefined,
|
shouldStretchPage: 'boolean',
|
||||||
pageGap: undefined,
|
shouldShowPageNumber: 'boolean',
|
||||||
hotkeys: undefined,
|
backgroundColor: 'number', // ReaderBackgroundColor (enum)
|
||||||
imagePreLoadAmount: undefined,
|
pageGap: 'number',
|
||||||
shouldUseAutoWebtoonMode: undefined,
|
hotkeys: 'string', // object
|
||||||
autoScroll: undefined,
|
imagePreLoadAmount: 'number',
|
||||||
shouldShowReadingModePreview: undefined,
|
shouldUseAutoWebtoonMode: 'boolean',
|
||||||
shouldShowTapZoneLayoutPreview: undefined,
|
autoScroll: 'string', // object
|
||||||
shouldInformAboutMissingChapter: undefined,
|
shouldShowReadingModePreview: 'boolean',
|
||||||
shouldInformAboutScanlatorChange: undefined,
|
shouldShowTapZoneLayoutPreview: 'boolean',
|
||||||
hideHistory: undefined,
|
shouldInformAboutMissingChapter: 'boolean',
|
||||||
scrollAmount: undefined,
|
shouldInformAboutScanlatorChange: 'boolean',
|
||||||
reverse: undefined,
|
hideHistory: 'boolean',
|
||||||
bookmarked: undefined,
|
scrollAmount: 'number', // ReaderScrollAmount (enum)
|
||||||
downloaded: undefined,
|
reverse: 'boolean',
|
||||||
unread: undefined,
|
bookmarked: 'auto', // boolean undefined null
|
||||||
showChapterNumber: undefined,
|
downloaded: 'auto', // boolean undefined null
|
||||||
extensionLanguages: undefined,
|
unread: 'auto', // boolean undefined null
|
||||||
showNsfw: undefined,
|
showChapterNumber: 'boolean',
|
||||||
shouldUseInfiniteScroll: undefined,
|
extensionLanguages: 'string', // string[]
|
||||||
shouldShowTransitionPage: undefined,
|
showNsfw: 'boolean',
|
||||||
appTheme: undefined,
|
shouldUseInfiniteScroll: 'boolean',
|
||||||
themeMode: undefined,
|
shouldShowTransitionPage: 'boolean',
|
||||||
shouldUsePureBlackMode: undefined,
|
appTheme: 'string',
|
||||||
mangaGridItemWidth: undefined,
|
themeMode: 'string', // ThemeMode (enum)
|
||||||
isPinned: undefined,
|
shouldUsePureBlackMode: 'boolean',
|
||||||
};
|
mangaGridItemWidth: 'number',
|
||||||
|
isPinned: 'boolean',
|
||||||
|
} as const satisfies Record<AppMetadataKeys, 'auto' | 'string' | 'number' | 'boolean'>;
|
||||||
|
|
||||||
export const VALID_APP_METADATA_KEYS = Object.keys(APP_METADATA_OBJECT);
|
export const VALID_APP_METADATA_KEYS = Object.keys(APP_METADATA_KEY_TO_TYPE);
|
||||||
|
|
||||||
export const GLOBAL_METADATA_KEYS: AppMetadataKeys[] = [
|
export const GLOBAL_METADATA_KEYS: AppMetadataKeys[] = [
|
||||||
// metadata applied migration id
|
// metadata applied migration id
|
||||||
|
|||||||
@@ -7,24 +7,29 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { MetaType } from '@/lib/graphql/generated/graphql.ts';
|
import { MetaType } from '@/lib/graphql/generated/graphql.ts';
|
||||||
import { AllowedMetadataValueTypes, Metadata } from '@/modules/metadata/Metadata.types.ts';
|
import { AllowedMetadataValueTypes, AppMetadataKeys, Metadata } from '@/modules/metadata/Metadata.types.ts';
|
||||||
|
import { APP_METADATA_KEY_TO_TYPE } from '@/modules/metadata/Metadata.constants.ts';
|
||||||
|
|
||||||
export const convertValueFromMetadata = <T extends AllowedMetadataValueTypes = AllowedMetadataValueTypes>(
|
export const convertValueFromMetadata = <T extends AllowedMetadataValueTypes = AllowedMetadataValueTypes>(
|
||||||
|
key: string,
|
||||||
value: string,
|
value: string,
|
||||||
): T => {
|
): T => {
|
||||||
if (!Number.isNaN(+value)) {
|
const typeOfKey = APP_METADATA_KEY_TO_TYPE[key as AppMetadataKeys];
|
||||||
|
const isAutoType = typeOfKey === 'auto';
|
||||||
|
|
||||||
|
if ((isAutoType && !Number.isNaN(+value)) || typeOfKey === 'number') {
|
||||||
return +value as T;
|
return +value as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value === 'true' || value === 'false') {
|
if ((isAutoType && (value === 'true' || value === 'false')) || typeOfKey === 'boolean') {
|
||||||
return (value === 'true') as T;
|
return (value === 'true') as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value === 'undefined') {
|
if (isAutoType && value === 'undefined') {
|
||||||
return undefined as T;
|
return undefined as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value === 'null') {
|
if (isAutoType && value === 'null') {
|
||||||
return null as T;
|
return null as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ const getMetadataValueFrom = <Key extends AppMetadataKeys, Value extends Allowed
|
|||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return convertValueFromMetadata(metadata[getMetadataKey(key, prefixes)]);
|
return convertValueFromMetadata(key, metadata[getMetadataKey(key, prefixes)]);
|
||||||
};
|
};
|
||||||
|
|
||||||
export function getMetadataFrom<METADATA extends Partial<Metadata<AppMetadataKeys, AllowedMetadataValueTypes>>>(
|
export function getMetadataFrom<METADATA extends Partial<Metadata<AppMetadataKeys, AllowedMetadataValueTypes>>>(
|
||||||
|
|||||||
Reference in New Issue
Block a user