diff --git a/src/typings.ts b/src/typings.ts index 20a3b03f..02eb2bec 100644 --- a/src/typings.ts +++ b/src/typings.ts @@ -74,13 +74,13 @@ export interface IMetadataMigration { keys?: { oldKey: string; newKey: string }[]; } -export interface IMetadata { - [key: string]: VALUES; -} +export type Metadata = { + [key in Keys]: Values; +}; -export interface IMetadataHolder { - meta?: IMetadata; -} +export type MetadataHolder = { + meta?: Metadata; +}; export type AllowedMetadataValueTypes = string | boolean | number | undefined; @@ -100,7 +100,7 @@ export interface IMangaCard { unreadCount?: number; downloadCount?: number; inLibrary?: boolean; - meta?: IMetadata; + meta?: Metadata; inLibraryAt: number; lastReadAt: number; } @@ -122,7 +122,7 @@ export interface IManga { inLibrary: boolean; source: ISource; - meta: IMetadata; + meta: Metadata; realUrl: string; freshData: boolean; @@ -158,7 +158,7 @@ export interface IChapter { chapterCount: number; pageCount: number; downloaded: boolean; - meta: IMetadata; + meta: Metadata; } export interface IMangaChapter { @@ -178,7 +178,7 @@ export interface ICategory { order: number; name: string; default: boolean; - meta: IMetadata; + meta: Metadata; } export interface INavbarOverride { diff --git a/src/util/metadata.ts b/src/util/metadata.ts index e1beff1b..50c3758a 100644 --- a/src/util/metadata.ts +++ b/src/util/metadata.ts @@ -15,8 +15,8 @@ import { IManga, IMangaCard, IMangaChapter, - IMetadata, - IMetadataHolder, + Metadata, + MetadataHolder, IMetadataMigration, MetadataKeyValuePair, } from 'typings'; @@ -96,7 +96,7 @@ const getAppKeyPrefixForMigration = (migrationId: number): string => { const getMetadataKey = (key: string, appPrefix: string = APP_METADATA_KEY_PREFIX) => `${appPrefix}${key}`; -const doesMetadataKeyExistIn = (meta: IMetadata | undefined, key: string, appPrefix?: string): boolean => +const doesMetadataKeyExistIn = (meta: Metadata | undefined, key: string, appPrefix?: string): boolean => Object.prototype.hasOwnProperty.call(meta ?? {}, getMetadataKey(key, appPrefix)); const convertValueFromMetadata = ( @@ -117,8 +117,8 @@ const convertValueFromMetadata = { - const appMetadata: IMetadata = {}; +const getAppMetadataFrom = (meta: Metadata, appPrefix: string = APP_METADATA_KEY_PREFIX): Metadata => { + const appMetadata: Metadata = {}; Object.entries(meta).forEach(([key, value]) => { if (key.startsWith(appPrefix)) { @@ -129,8 +129,8 @@ const getAppMetadataFrom = (meta: IMetadata, appPrefix: string = APP_METADATA_KE return appMetadata; }; -const applyAppKeyPrefixMigration = (meta: IMetadata, migration: IMetadataMigration): IMetadata => { - const migratedMetadata: IMetadata = { ...meta }; +const applyAppKeyPrefixMigration = (meta: Metadata, migration: IMetadataMigration): Metadata => { + const migratedMetadata: Metadata = { ...meta }; if (!migration.appKeyPrefix) { return migratedMetadata; @@ -154,12 +154,8 @@ const applyAppKeyPrefixMigration = (meta: IMetadata, migration: IMetadataMigrati return migratedMetadata; }; -const applyMetadataValueMigration = ( - meta: IMetadata, - migration: IMetadataMigration, - appKeyPrefix: string, -): IMetadata => { - const migratedMetadata: IMetadata = { ...meta }; +const applyMetadataValueMigration = (meta: Metadata, migration: IMetadataMigration, appKeyPrefix: string): Metadata => { + const migratedMetadata: Metadata = { ...meta }; if (!migration.values) { return migratedMetadata; @@ -193,8 +189,8 @@ const applyMetadataValueMigration = ( return migratedMetadata; }; -const applyMetadataKeyMigration = (meta: IMetadata, migration: IMetadataMigration): IMetadata => { - const migratedMetadata: IMetadata = { ...meta }; +const applyMetadataKeyMigration = (meta: Metadata, migration: IMetadataMigration): Metadata => { + const migratedMetadata: Metadata = { ...meta }; if (!migration.keys) { return migratedMetadata; @@ -217,12 +213,12 @@ const applyMetadataKeyMigration = (meta: IMetadata, migration: IMetadataMigratio return migratedMetadata; }; -const applyMetadataMigrations = (meta?: IMetadata): IMetadata | undefined => { +const applyMetadataMigrations = (meta?: Metadata): Metadata | undefined => { if (!meta) { return undefined; } - const migrationToMetadata: [number, IMetadata][] = [[0, meta]]; + const migrationToMetadata: [number, Metadata][] = [[0, meta]]; migrations.forEach((migration, index) => { const migrationId = index + 1; @@ -246,12 +242,12 @@ const applyMetadataMigrations = (meta?: IMetadata): IMetadata | undefined => { return migrationToMetadata.pop()![1]; }; -export const getMetadataValueFrom = ( - { meta }: IMetadataHolder, - key: AppMetadataKeys, - defaultValue?: T, +export const getMetadataValueFrom = ( + { meta }: MetadataHolder, + key: Key, + defaultValue?: Value, applyMigrations: boolean = true, -): T | undefined => { +): Value | undefined => { const metadata = applyMigrations ? applyMetadataMigrations(meta) : meta; if (metadata === undefined || !doesMetadataKeyExistIn(metadata, key)) { @@ -261,21 +257,26 @@ export const getMetadataValueFrom = >>( + { meta }: MetadataHolder, + metadataWithDefaultValues: METADATA, applyMigrations?: boolean, -): IMetadata => { - const appMetadata: IMetadata = {}; +): METADATA => { + const appMetadata = {} as METADATA; - keysToDefaultValues.forEach(([key, defaultValue]) => { - appMetadata[key] = getMetadataValueFrom({ meta }, key, defaultValue, applyMigrations); + Object.entries(metadataWithDefaultValues).forEach(([key, defaultValue]) => { + appMetadata[key as AppMetadataKeys] = getMetadataValueFrom( + { meta }, + key as AppMetadataKeys, + defaultValue, + applyMigrations, + ); }); return appMetadata; }; -const wrapMetadataWithMetaKey = (wrap: boolean, metadata: IMetadata): IMetadataHolder => { +const wrapMetadataWithMetaKey = (wrap: boolean, metadata: Metadata): MetadataHolder => { if (wrap) { return { meta: { @@ -291,7 +292,7 @@ const wrapMetadataWithMetaKey = (wrap: boolean, metadata: IMetadata): IMetadataH export const requestUpdateMetadataValue = async ( endpoint: string, - metadataHolder: IMetadataHolder, + metadataHolder: MetadataHolder, key: AppMetadataKeys, value: AllowedMetadataValueTypes, endpointToMutate: string = endpoint, @@ -323,7 +324,7 @@ export const requestUpdateMetadataValue = async ( export const requestUpdateMetadata = async ( endpoint: string, - metadataHolder: IMetadataHolder, + metadataHolder: MetadataHolder, keysToValues: [AppMetadataKeys, AllowedMetadataValueTypes][], endpointToMutate?: string, wrapWithMetaKey?: boolean, @@ -335,7 +336,7 @@ export const requestUpdateMetadata = async ( ); export const requestUpdateServerMetadata = async ( - serverMetadata: IMetadata, + serverMetadata: Metadata, keysToValues: MetadataKeyValuePair[], ): Promise => requestUpdateMetadata('', { meta: serverMetadata }, keysToValues, '/meta', false); diff --git a/src/util/readerSettings.ts b/src/util/readerSettings.ts index e6cae1d2..c20c72e3 100644 --- a/src/util/readerSettings.ts +++ b/src/util/readerSettings.ts @@ -8,51 +8,45 @@ import { getMetadataFrom, requestUpdateMangaMetadata, requestUpdateServerMetadata } from 'util/metadata'; import { useQuery } from 'util/client'; -import { IManga, IMetadata, IMetadataHolder, IReaderSettings, MetadataKeyValuePair } from 'typings'; +import { IManga, Metadata, MetadataHolder, IReaderSettings, MetadataKeyValuePair } from 'typings'; -export const getDefaultSettings = (forceUndefined: boolean = false) => - ({ - staticNav: forceUndefined ? undefined : false, - showPageNumber: forceUndefined ? undefined : true, - continuesPageGap: forceUndefined ? undefined : false, - loadNextOnEnding: forceUndefined ? undefined : false, - skipDupChapters: forceUndefined ? undefined : true, - readerType: forceUndefined ? undefined : 'ContinuesVertical', - } as IReaderSettings); +type UndefinedReaderSettings = { + [setting in keyof IReaderSettings]: IReaderSettings[setting] | undefined; +}; -const getReaderSettingsWithDefaultValueFallback = ( - meta?: IMetadata, - defaultSettings?: IReaderSettings, - applyMetadataMigration: boolean = true, -): IReaderSettings => ({ - ...(getMetadataFrom( - { meta }, - Object.entries(defaultSettings ?? getDefaultSettings()) as MetadataKeyValuePair[], - applyMetadataMigration, - ) as unknown as IReaderSettings), +export const getDefaultSettings = (): IReaderSettings => ({ + staticNav: false, + showPageNumber: true, + loadNextOnEnding: false, + skipDupChapters: true, + readerType: 'ContinuesVertical', }); +const getReaderSettingsWithDefaultValueFallback = ( + meta?: Metadata, + defaultSettings: DefaultSettings = getDefaultSettings() as DefaultSettings, + applyMetadataMigration: boolean = true, +): DefaultSettings => getMetadataFrom({ meta }, defaultSettings, applyMetadataMigration); + export const getReaderSettingsFromMetadata = ( - meta?: IMetadata, + meta?: Metadata, defaultSettings?: IReaderSettings, applyMetadataMigration?: boolean, -): IReaderSettings => ({ - ...getReaderSettingsWithDefaultValueFallback(meta, defaultSettings, applyMetadataMigration), -}); +): IReaderSettings => getReaderSettingsWithDefaultValueFallback(meta, defaultSettings, applyMetadataMigration); export const getReaderSettingsFor = ( - { meta }: IMetadataHolder, + { meta }: MetadataHolder, defaultSettings?: IReaderSettings, applyMetadataMigration?: boolean, ): IReaderSettings => getReaderSettingsFromMetadata(meta, defaultSettings, applyMetadataMigration); export const useDefaultReaderSettings = (): { - metadata?: IMetadata; + metadata?: Metadata; settings: IReaderSettings; loading: boolean; } => { - const { data: meta, loading } = useQuery('/api/v1/meta'); - const settings = getReaderSettingsWithDefaultValueFallback(meta); + const { data: meta, loading } = useQuery('/api/v1/meta'); + const settings = getReaderSettingsWithDefaultValueFallback(meta); return { metadata: meta, settings, loading }; }; @@ -65,12 +59,22 @@ export const useDefaultReaderSettings = (): { * @param defaultSettings */ export const checkAndHandleMissingStoredReaderSettings = async ( - metadataHolder: IManga | IMetadataHolder, + metadataHolder: IManga | MetadataHolder, metadataHolderType: 'manga' | 'server', defaultSettings: IReaderSettings, ): Promise => { - const meta = metadataHolder.meta ?? (metadataHolder as IMetadata); - const settingsToCheck = getReaderSettingsFor({ meta }, getDefaultSettings(true), false); + const meta = metadataHolder.meta ?? (metadataHolder as Metadata); + const settingsToCheck = getReaderSettingsWithDefaultValueFallback( + meta, + { + staticNav: undefined, + showPageNumber: undefined, + loadNextOnEnding: undefined, + skipDupChapters: undefined, + readerType: undefined, + }, + false, + ); const newSettings = getReaderSettingsFor({ meta }, defaultSettings); const undefinedSettings = Object.entries(settingsToCheck).filter((setting) => setting[1] === undefined); diff --git a/src/util/searchSettings.ts b/src/util/searchSettings.ts index 73fd789e..d8fd47d4 100644 --- a/src/util/searchSettings.ts +++ b/src/util/searchSettings.ts @@ -1,30 +1,22 @@ import { useQuery } from 'util/client'; import { getMetadataFrom } from 'util/metadata'; -import { IMetadata, ISearchSettings, MetadataKeyValuePair } from 'typings'; +import { Metadata, ISearchSettings } from 'typings'; -export const getDefaultSettings = () => - ({ - ignoreFilters: false, - } as ISearchSettings); - -const getSearchSettingsWithDefaultValueFallback = ( - meta?: IMetadata, - defaultSettings?: ISearchSettings, - applyMetadataMigration: boolean = true, -): ISearchSettings => ({ - ...(getMetadataFrom( - { meta }, - Object.entries(defaultSettings ?? getDefaultSettings()) as MetadataKeyValuePair[], - applyMetadataMigration, - ) as unknown as ISearchSettings), +export const getDefaultSettings = (): ISearchSettings => ({ + ignoreFilters: false, }); +const getSearchSettingsWithDefaultValueFallback = ( + meta?: Metadata, + defaultSettings: ISearchSettings = getDefaultSettings(), + applyMetadataMigration: boolean = true, +): ISearchSettings => getMetadataFrom({ meta }, defaultSettings, applyMetadataMigration); export const useSearchSettings = (): { - metadata?: IMetadata; + metadata?: Metadata; settings: ISearchSettings; loading: boolean; } => { - const { data: meta, loading } = useQuery('/api/v1/meta'); + const { data: meta, loading } = useQuery('/api/v1/meta'); const settings = getSearchSettingsWithDefaultValueFallback(meta); return { metadata: meta, settings, loading };