Files
suwayomi-material-you-webui/src/util/metadata.ts

365 lines
11 KiB
TypeScript
Raw Normal View History

Save reader settings per manga in Meta (#216) * [#213] Add missing "meta" property - IManga - IMangaCard (optional) - IChapter - ICategory * [#213] Add util functions for handling metadata - global server - manga - chapter - category * [#213] Use "ReaderSettings" from the manga metadata - get ReaderSettings from manga metadata - remove unnecessary check "make sure settings has all the keys" in case the stored settings in the metadata are outdated they will be filled with default values * [#213] Reload manga only in case "mangaId" changed In case the chapter is still from the same manga, a reload is unnecessary * [#213] Only update the changed reader setting Otherwise the app has to send patch requests to the server for every setting even if it didn't change * [#213] Hide "openButton" on first render in case "navBar" is shown The "openButton" was always set to be visible event in case the navBar was shown on the first render * [#213] Open the "ReaderNavBar" if needed after receiving new settings Otherwise, the drawer won't open in case the "navBar" was hidden on the first render since the default state in that case was set to false * [#213] Update "ReaderSettings" after receiving the manga response Otherwise, the default settings aren't getting removed * [#213] Hide/Show "OpenButton" when opening/closing the drawer Otherwise, the button stays hidden until it gets updated due to scrolling * [#213] Keep "ReaderNavBar" state when opening prev/next chapter In case the navBar wasn't sticky but opened, it got closed when the prev/next chapter got opened * [#213] Prevent "ReaderNavBar" from closing when changing "staticNav" setting
2023-01-06 17:15:29 +01:00
/*
* Copyright (C) Contributors to the Suwayomi project
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
import { mutate } from 'swr';
import {
AllowedMetadataValueTypes,
AppMetadataKeys,
ICategory,
IManga,
IMangaCard,
IMangaChapter,
IMetadataMigration,
Metadata,
MetadataHolder,
MetadataKeyValuePair,
} from '@/typings';
2023-08-15 13:54:29 +02:00
import requestManager, { RequestManager } from '@/lib/requests/RequestManager.ts';
Save reader settings per manga in Meta (#216) * [#213] Add missing "meta" property - IManga - IMangaCard (optional) - IChapter - ICategory * [#213] Add util functions for handling metadata - global server - manga - chapter - category * [#213] Use "ReaderSettings" from the manga metadata - get ReaderSettings from manga metadata - remove unnecessary check "make sure settings has all the keys" in case the stored settings in the metadata are outdated they will be filled with default values * [#213] Reload manga only in case "mangaId" changed In case the chapter is still from the same manga, a reload is unnecessary * [#213] Only update the changed reader setting Otherwise the app has to send patch requests to the server for every setting even if it didn't change * [#213] Hide "openButton" on first render in case "navBar" is shown The "openButton" was always set to be visible event in case the navBar was shown on the first render * [#213] Open the "ReaderNavBar" if needed after receiving new settings Otherwise, the drawer won't open in case the "navBar" was hidden on the first render since the default state in that case was set to false * [#213] Update "ReaderSettings" after receiving the manga response Otherwise, the default settings aren't getting removed * [#213] Hide/Show "OpenButton" when opening/closing the drawer Otherwise, the button stays hidden until it gets updated due to scrolling * [#213] Keep "ReaderNavBar" state when opening prev/next chapter In case the navBar wasn't sticky but opened, it got closed when the prev/next chapter got opened * [#213] Prevent "ReaderNavBar" from closing when changing "staticNav" setting
2023-01-06 17:15:29 +01:00
const APP_METADATA_KEY_PREFIX = 'webUI_';
/**
* Once all changes have been done in the current branch, a new migration for all changes should be
* created.
*
* In case a value should be migrated for a specific key, and in the same migration the key is
* getting migrated, the key in the value migration is the "old" key (before the migration to the
* new key).
*
* Migration order (function "applyMetadataMigrations"):
* 1. app metadata key prefix
* 2. app metadata values
* 3. app metadata keys
*
* @example
* // changes:
* // commit: change key "X" to "Z"
* // commit: change key "Y" to "A"
* // commit: fix typo in reader setting "someTipo"
* // commit: add metadata migration
*
* // result:
* // old migrations:
* // const migrations = [
* // {
* // keys: [{ oldKey: 'loadNextonEnding', newKey: 'loadNextOnEnding' }],
* // }
* // ];
*
* // updated migrations
* const migrations = [
* {
* keys: [{ oldKey: 'loadNextonEnding', newKey: 'loadNextOnEnding' }],
* },
* {
* keys: [
* { oldKey: 'X', newKey: 'Z' },
* { oldKey: 'Y', newKey: 'A' },
* ],
* // all stored values in the metadata (of this app) will get migrated
* values: [
* {
* oldValue: 'someTipo',
* newValue: 'someTypo'
* },
* ],
* // to migrate only the value of a specific key (in this case of "someKey"):
* // values: [
* // {
* // key: 'someKey',
* // oldValue: 'someTipo',
* // newValue: 'someTypo',
* // },
* // ],
* },
* ];
*/
const migrations: IMetadataMigration[] = [
{
keys: [{ oldKey: 'loadNextonEnding', newKey: 'loadNextOnEnding' }],
},
];
const getAppKeyPrefixForMigration = (migrationId: number): string => {
const appKeyPrefix = migrations
.slice(0, migrationId)
.reverse()
.find((migration) => !!migration.appKeyPrefix);
return appKeyPrefix?.appKeyPrefix?.newPrefix ?? APP_METADATA_KEY_PREFIX;
};
const getMetadataKey = (key: string, appPrefix: string = APP_METADATA_KEY_PREFIX) => `${appPrefix}${key}`;
const doesMetadataKeyExistIn = (meta: Metadata | undefined, key: string, appPrefix?: string): boolean =>
Object.prototype.hasOwnProperty.call(meta ?? {}, getMetadataKey(key, appPrefix));
Save reader settings per manga in Meta (#216) * [#213] Add missing "meta" property - IManga - IMangaCard (optional) - IChapter - ICategory * [#213] Add util functions for handling metadata - global server - manga - chapter - category * [#213] Use "ReaderSettings" from the manga metadata - get ReaderSettings from manga metadata - remove unnecessary check "make sure settings has all the keys" in case the stored settings in the metadata are outdated they will be filled with default values * [#213] Reload manga only in case "mangaId" changed In case the chapter is still from the same manga, a reload is unnecessary * [#213] Only update the changed reader setting Otherwise the app has to send patch requests to the server for every setting even if it didn't change * [#213] Hide "openButton" on first render in case "navBar" is shown The "openButton" was always set to be visible event in case the navBar was shown on the first render * [#213] Open the "ReaderNavBar" if needed after receiving new settings Otherwise, the drawer won't open in case the "navBar" was hidden on the first render since the default state in that case was set to false * [#213] Update "ReaderSettings" after receiving the manga response Otherwise, the default settings aren't getting removed * [#213] Hide/Show "OpenButton" when opening/closing the drawer Otherwise, the button stays hidden until it gets updated due to scrolling * [#213] Keep "ReaderNavBar" state when opening prev/next chapter In case the navBar wasn't sticky but opened, it got closed when the prev/next chapter got opened * [#213] Prevent "ReaderNavBar" from closing when changing "staticNav" setting
2023-01-06 17:15:29 +01:00
const convertValueFromMetadata = <T extends AllowedMetadataValueTypes = AllowedMetadataValueTypes>(
Save reader settings per manga in Meta (#216) * [#213] Add missing "meta" property - IManga - IMangaCard (optional) - IChapter - ICategory * [#213] Add util functions for handling metadata - global server - manga - chapter - category * [#213] Use "ReaderSettings" from the manga metadata - get ReaderSettings from manga metadata - remove unnecessary check "make sure settings has all the keys" in case the stored settings in the metadata are outdated they will be filled with default values * [#213] Reload manga only in case "mangaId" changed In case the chapter is still from the same manga, a reload is unnecessary * [#213] Only update the changed reader setting Otherwise the app has to send patch requests to the server for every setting even if it didn't change * [#213] Hide "openButton" on first render in case "navBar" is shown The "openButton" was always set to be visible event in case the navBar was shown on the first render * [#213] Open the "ReaderNavBar" if needed after receiving new settings Otherwise, the drawer won't open in case the "navBar" was hidden on the first render since the default state in that case was set to false * [#213] Update "ReaderSettings" after receiving the manga response Otherwise, the default settings aren't getting removed * [#213] Hide/Show "OpenButton" when opening/closing the drawer Otherwise, the button stays hidden until it gets updated due to scrolling * [#213] Keep "ReaderNavBar" state when opening prev/next chapter In case the navBar wasn't sticky but opened, it got closed when the prev/next chapter got opened * [#213] Prevent "ReaderNavBar" from closing when changing "staticNav" setting
2023-01-06 17:15:29 +01:00
value: string,
): T => {
if (!Number.isNaN(+value)) {
return +value as T;
}
if (value === 'true' || value === 'false') {
return (value === 'true') as T;
}
if (value === 'undefined') {
return undefined as T;
}
return value as T;
};
const getAppMetadataFrom = (meta: Metadata, appPrefix: string = APP_METADATA_KEY_PREFIX): Metadata => {
const appMetadata: Metadata = {};
Object.entries(meta).forEach(([key, value]) => {
if (key.startsWith(appPrefix)) {
appMetadata[key] = value;
}
});
return appMetadata;
};
const applyAppKeyPrefixMigration = (meta: Metadata, migration: IMetadataMigration): Metadata => {
const migratedMetadata: Metadata = { ...meta };
if (!migration.appKeyPrefix) {
return migratedMetadata;
}
const { oldPrefix, newPrefix } = migration.appKeyPrefix;
const oldAppMetadata = getAppMetadataFrom(meta, oldPrefix);
const newAppMetadata = getAppMetadataFrom(meta, newPrefix);
const missingMetadataKeys = Object.keys(oldAppMetadata).filter((key) => !Object.keys(newAppMetadata).includes(key));
const isMissingOldMetadata = missingMetadataKeys.length;
if (isMissingOldMetadata) {
missingMetadataKeys.forEach((oldKey) => {
const keyWithNewPrefix = oldKey.replace(oldPrefix, newPrefix);
migratedMetadata[keyWithNewPrefix] = oldAppMetadata[oldKey];
});
}
return migratedMetadata;
};
const applyMetadataValueMigration = (meta: Metadata, migration: IMetadataMigration, appKeyPrefix: string): Metadata => {
const migratedMetadata: Metadata = { ...meta };
if (!migration.values) {
return migratedMetadata;
}
const appMetadata = getAppMetadataFrom(meta, appKeyPrefix);
const metadataValueChanges = migration.values;
metadataValueChanges.forEach(({ key, oldValue, newValue }) => {
const migrateValue = (metaKey: string) => {
if (meta[metaKey] === oldValue) {
migratedMetadata[metaKey] = newValue;
}
};
const migrateValueOfAllAppKeys = key === undefined;
if (migrateValueOfAllAppKeys) {
Object.keys(appMetadata).forEach((metaKey) => {
migrateValue(metaKey);
});
return;
}
if (!doesMetadataKeyExistIn(meta, key, appKeyPrefix)) {
return;
}
migrateValue(getMetadataKey(key, appKeyPrefix));
});
return migratedMetadata;
};
const applyMetadataKeyMigration = (meta: Metadata, migration: IMetadataMigration): Metadata => {
const migratedMetadata: Metadata = { ...meta };
if (!migration.keys) {
return migratedMetadata;
}
const metadataKeyChanges = migration.keys;
metadataKeyChanges.forEach(({ oldKey, newKey }) => {
if (!doesMetadataKeyExistIn(meta, oldKey)) {
return;
}
if (doesMetadataKeyExistIn(meta, newKey)) {
return;
}
migratedMetadata[getMetadataKey(newKey)] = meta[getMetadataKey(oldKey)];
});
return migratedMetadata;
};
const applyMetadataMigrations = (meta?: Metadata): Metadata | undefined => {
if (!meta) {
return undefined;
}
const migrationToMetadata: [number, Metadata][] = [[0, meta]];
migrations.forEach((migration, index) => {
const migrationId = index + 1;
const metadataToMigrate = migrationToMetadata[migrationId - 1][1];
const appKeyPrefixMigrated = applyAppKeyPrefixMigration(metadataToMigrate, migration);
const metadataValuesMigrated = applyMetadataValueMigration(
appKeyPrefixMigrated,
migration,
getAppKeyPrefixForMigration(migrationId),
);
const metadataKeysMigrated = applyMetadataKeyMigration(metadataValuesMigrated, migration);
migrationToMetadata.push([migrationId, metadataKeysMigrated]);
});
const appliedMigration = migrationToMetadata.length > 1;
if (!appliedMigration) {
return { ...meta };
}
return migrationToMetadata.pop()![1];
};
export const getMetadataValueFrom = <Key extends AppMetadataKeys, Value extends AllowedMetadataValueTypes>(
{ meta }: MetadataHolder,
key: Key,
defaultValue?: Value,
applyMigrations: boolean = true,
): Value | undefined => {
const metadata = applyMigrations ? applyMetadataMigrations(meta) : meta;
Save reader settings per manga in Meta (#216) * [#213] Add missing "meta" property - IManga - IMangaCard (optional) - IChapter - ICategory * [#213] Add util functions for handling metadata - global server - manga - chapter - category * [#213] Use "ReaderSettings" from the manga metadata - get ReaderSettings from manga metadata - remove unnecessary check "make sure settings has all the keys" in case the stored settings in the metadata are outdated they will be filled with default values * [#213] Reload manga only in case "mangaId" changed In case the chapter is still from the same manga, a reload is unnecessary * [#213] Only update the changed reader setting Otherwise the app has to send patch requests to the server for every setting even if it didn't change * [#213] Hide "openButton" on first render in case "navBar" is shown The "openButton" was always set to be visible event in case the navBar was shown on the first render * [#213] Open the "ReaderNavBar" if needed after receiving new settings Otherwise, the drawer won't open in case the "navBar" was hidden on the first render since the default state in that case was set to false * [#213] Update "ReaderSettings" after receiving the manga response Otherwise, the default settings aren't getting removed * [#213] Hide/Show "OpenButton" when opening/closing the drawer Otherwise, the button stays hidden until it gets updated due to scrolling * [#213] Keep "ReaderNavBar" state when opening prev/next chapter In case the navBar wasn't sticky but opened, it got closed when the prev/next chapter got opened * [#213] Prevent "ReaderNavBar" from closing when changing "staticNav" setting
2023-01-06 17:15:29 +01:00
if (metadata === undefined || !doesMetadataKeyExistIn(metadata, key)) {
Save reader settings per manga in Meta (#216) * [#213] Add missing "meta" property - IManga - IMangaCard (optional) - IChapter - ICategory * [#213] Add util functions for handling metadata - global server - manga - chapter - category * [#213] Use "ReaderSettings" from the manga metadata - get ReaderSettings from manga metadata - remove unnecessary check "make sure settings has all the keys" in case the stored settings in the metadata are outdated they will be filled with default values * [#213] Reload manga only in case "mangaId" changed In case the chapter is still from the same manga, a reload is unnecessary * [#213] Only update the changed reader setting Otherwise the app has to send patch requests to the server for every setting even if it didn't change * [#213] Hide "openButton" on first render in case "navBar" is shown The "openButton" was always set to be visible event in case the navBar was shown on the first render * [#213] Open the "ReaderNavBar" if needed after receiving new settings Otherwise, the drawer won't open in case the "navBar" was hidden on the first render since the default state in that case was set to false * [#213] Update "ReaderSettings" after receiving the manga response Otherwise, the default settings aren't getting removed * [#213] Hide/Show "OpenButton" when opening/closing the drawer Otherwise, the button stays hidden until it gets updated due to scrolling * [#213] Keep "ReaderNavBar" state when opening prev/next chapter In case the navBar wasn't sticky but opened, it got closed when the prev/next chapter got opened * [#213] Prevent "ReaderNavBar" from closing when changing "staticNav" setting
2023-01-06 17:15:29 +01:00
return defaultValue;
}
return convertValueFromMetadata(metadata[getMetadataKey(key)]);
Save reader settings per manga in Meta (#216) * [#213] Add missing "meta" property - IManga - IMangaCard (optional) - IChapter - ICategory * [#213] Add util functions for handling metadata - global server - manga - chapter - category * [#213] Use "ReaderSettings" from the manga metadata - get ReaderSettings from manga metadata - remove unnecessary check "make sure settings has all the keys" in case the stored settings in the metadata are outdated they will be filled with default values * [#213] Reload manga only in case "mangaId" changed In case the chapter is still from the same manga, a reload is unnecessary * [#213] Only update the changed reader setting Otherwise the app has to send patch requests to the server for every setting even if it didn't change * [#213] Hide "openButton" on first render in case "navBar" is shown The "openButton" was always set to be visible event in case the navBar was shown on the first render * [#213] Open the "ReaderNavBar" if needed after receiving new settings Otherwise, the drawer won't open in case the "navBar" was hidden on the first render since the default state in that case was set to false * [#213] Update "ReaderSettings" after receiving the manga response Otherwise, the default settings aren't getting removed * [#213] Hide/Show "OpenButton" when opening/closing the drawer Otherwise, the button stays hidden until it gets updated due to scrolling * [#213] Keep "ReaderNavBar" state when opening prev/next chapter In case the navBar wasn't sticky but opened, it got closed when the prev/next chapter got opened * [#213] Prevent "ReaderNavBar" from closing when changing "staticNav" setting
2023-01-06 17:15:29 +01:00
};
export const getMetadataFrom = <METADATA extends Partial<Metadata<AppMetadataKeys, AllowedMetadataValueTypes>>>(
{ meta }: MetadataHolder,
metadataWithDefaultValues: METADATA,
applyMigrations?: boolean,
): METADATA => {
const appMetadata = {} as METADATA;
Object.entries(metadataWithDefaultValues).forEach(([key, defaultValue]) => {
appMetadata[key as AppMetadataKeys] = getMetadataValueFrom(
{ meta },
key as AppMetadataKeys,
defaultValue,
applyMigrations,
);
Save reader settings per manga in Meta (#216) * [#213] Add missing "meta" property - IManga - IMangaCard (optional) - IChapter - ICategory * [#213] Add util functions for handling metadata - global server - manga - chapter - category * [#213] Use "ReaderSettings" from the manga metadata - get ReaderSettings from manga metadata - remove unnecessary check "make sure settings has all the keys" in case the stored settings in the metadata are outdated they will be filled with default values * [#213] Reload manga only in case "mangaId" changed In case the chapter is still from the same manga, a reload is unnecessary * [#213] Only update the changed reader setting Otherwise the app has to send patch requests to the server for every setting even if it didn't change * [#213] Hide "openButton" on first render in case "navBar" is shown The "openButton" was always set to be visible event in case the navBar was shown on the first render * [#213] Open the "ReaderNavBar" if needed after receiving new settings Otherwise, the drawer won't open in case the "navBar" was hidden on the first render since the default state in that case was set to false * [#213] Update "ReaderSettings" after receiving the manga response Otherwise, the default settings aren't getting removed * [#213] Hide/Show "OpenButton" when opening/closing the drawer Otherwise, the button stays hidden until it gets updated due to scrolling * [#213] Keep "ReaderNavBar" state when opening prev/next chapter In case the navBar wasn't sticky but opened, it got closed when the prev/next chapter got opened * [#213] Prevent "ReaderNavBar" from closing when changing "staticNav" setting
2023-01-06 17:15:29 +01:00
});
return appMetadata;
};
const wrapMetadataWithMetaKey = (wrap: boolean, metadata: Metadata): MetadataHolder => {
Save reader settings per manga in Meta (#216) * [#213] Add missing "meta" property - IManga - IMangaCard (optional) - IChapter - ICategory * [#213] Add util functions for handling metadata - global server - manga - chapter - category * [#213] Use "ReaderSettings" from the manga metadata - get ReaderSettings from manga metadata - remove unnecessary check "make sure settings has all the keys" in case the stored settings in the metadata are outdated they will be filled with default values * [#213] Reload manga only in case "mangaId" changed In case the chapter is still from the same manga, a reload is unnecessary * [#213] Only update the changed reader setting Otherwise the app has to send patch requests to the server for every setting even if it didn't change * [#213] Hide "openButton" on first render in case "navBar" is shown The "openButton" was always set to be visible event in case the navBar was shown on the first render * [#213] Open the "ReaderNavBar" if needed after receiving new settings Otherwise, the drawer won't open in case the "navBar" was hidden on the first render since the default state in that case was set to false * [#213] Update "ReaderSettings" after receiving the manga response Otherwise, the default settings aren't getting removed * [#213] Hide/Show "OpenButton" when opening/closing the drawer Otherwise, the button stays hidden until it gets updated due to scrolling * [#213] Keep "ReaderNavBar" state when opening prev/next chapter In case the navBar wasn't sticky but opened, it got closed when the prev/next chapter got opened * [#213] Prevent "ReaderNavBar" from closing when changing "staticNav" setting
2023-01-06 17:15:29 +01:00
if (wrap) {
return {
meta: {
...metadata,
},
};
}
return {
...metadata,
};
};
type MetadataHolderType = 'manga' | 'chapter' | 'category' | 'global';
Save reader settings per manga in Meta (#216) * [#213] Add missing "meta" property - IManga - IMangaCard (optional) - IChapter - ICategory * [#213] Add util functions for handling metadata - global server - manga - chapter - category * [#213] Use "ReaderSettings" from the manga metadata - get ReaderSettings from manga metadata - remove unnecessary check "make sure settings has all the keys" in case the stored settings in the metadata are outdated they will be filled with default values * [#213] Reload manga only in case "mangaId" changed In case the chapter is still from the same manga, a reload is unnecessary * [#213] Only update the changed reader setting Otherwise the app has to send patch requests to the server for every setting even if it didn't change * [#213] Hide "openButton" on first render in case "navBar" is shown The "openButton" was always set to be visible event in case the navBar was shown on the first render * [#213] Open the "ReaderNavBar" if needed after receiving new settings Otherwise, the drawer won't open in case the "navBar" was hidden on the first render since the default state in that case was set to false * [#213] Update "ReaderSettings" after receiving the manga response Otherwise, the default settings aren't getting removed * [#213] Hide/Show "OpenButton" when opening/closing the drawer Otherwise, the button stays hidden until it gets updated due to scrolling * [#213] Keep "ReaderNavBar" state when opening prev/next chapter In case the navBar wasn't sticky but opened, it got closed when the prev/next chapter got opened * [#213] Prevent "ReaderNavBar" from closing when changing "staticNav" setting
2023-01-06 17:15:29 +01:00
export const requestUpdateMetadataValue = async (
metadataHolder: MetadataHolder,
holderType: MetadataHolderType,
Save reader settings per manga in Meta (#216) * [#213] Add missing "meta" property - IManga - IMangaCard (optional) - IChapter - ICategory * [#213] Add util functions for handling metadata - global server - manga - chapter - category * [#213] Use "ReaderSettings" from the manga metadata - get ReaderSettings from manga metadata - remove unnecessary check "make sure settings has all the keys" in case the stored settings in the metadata are outdated they will be filled with default values * [#213] Reload manga only in case "mangaId" changed In case the chapter is still from the same manga, a reload is unnecessary * [#213] Only update the changed reader setting Otherwise the app has to send patch requests to the server for every setting even if it didn't change * [#213] Hide "openButton" on first render in case "navBar" is shown The "openButton" was always set to be visible event in case the navBar was shown on the first render * [#213] Open the "ReaderNavBar" if needed after receiving new settings Otherwise, the drawer won't open in case the "navBar" was hidden on the first render since the default state in that case was set to false * [#213] Update "ReaderSettings" after receiving the manga response Otherwise, the default settings aren't getting removed * [#213] Hide/Show "OpenButton" when opening/closing the drawer Otherwise, the button stays hidden until it gets updated due to scrolling * [#213] Keep "ReaderNavBar" state when opening prev/next chapter In case the navBar wasn't sticky but opened, it got closed when the prev/next chapter got opened * [#213] Prevent "ReaderNavBar" from closing when changing "staticNav" setting
2023-01-06 17:15:29 +01:00
key: AppMetadataKeys,
value: AllowedMetadataValueTypes,
): Promise<void> => {
const metadataKey = getMetadataKey(key);
const mutatedMetadata = {
...metadataHolder.meta,
[metadataKey]: `${value}`,
Save reader settings per manga in Meta (#216) * [#213] Add missing "meta" property - IManga - IMangaCard (optional) - IChapter - ICategory * [#213] Add util functions for handling metadata - global server - manga - chapter - category * [#213] Use "ReaderSettings" from the manga metadata - get ReaderSettings from manga metadata - remove unnecessary check "make sure settings has all the keys" in case the stored settings in the metadata are outdated they will be filled with default values * [#213] Reload manga only in case "mangaId" changed In case the chapter is still from the same manga, a reload is unnecessary * [#213] Only update the changed reader setting Otherwise the app has to send patch requests to the server for every setting even if it didn't change * [#213] Hide "openButton" on first render in case "navBar" is shown The "openButton" was always set to be visible event in case the navBar was shown on the first render * [#213] Open the "ReaderNavBar" if needed after receiving new settings Otherwise, the drawer won't open in case the "navBar" was hidden on the first render since the default state in that case was set to false * [#213] Update "ReaderSettings" after receiving the manga response Otherwise, the default settings aren't getting removed * [#213] Hide/Show "OpenButton" when opening/closing the drawer Otherwise, the button stays hidden until it gets updated due to scrolling * [#213] Keep "ReaderNavBar" state when opening prev/next chapter In case the navBar wasn't sticky but opened, it got closed when the prev/next chapter got opened * [#213] Prevent "ReaderNavBar" from closing when changing "staticNav" setting
2023-01-06 17:15:29 +01:00
};
let endpoint: string;
switch (holderType) {
case 'category':
endpoint = `category/${(metadataHolder as ICategory).id}/meta`;
await requestManager.setCategoryMeta((metadataHolder as ICategory).id, metadataKey, value).response;
break;
case 'chapter':
// eslint-disable-next-line no-case-declarations
const { manga, chapter } = metadataHolder as IMangaChapter;
endpoint = `manga/${manga.id}/chapter/${chapter.index}/meta`;
await requestManager.setChapterMeta(manga.id, chapter.index, metadataKey, value).response;
break;
case 'global':
endpoint = 'meta';
await requestManager.setGlobalMetadata(metadataKey, value).response;
break;
case 'manga':
endpoint = `manga/${(metadataHolder as IManga).id}/meta`;
await requestManager.setMangaMeta((metadataHolder as IManga).id, metadataKey, value).response;
break;
default:
throw new Error(`requestUpdateMetadataValue: unknown holderType "${holderType}"`);
}
const urlToMutate = `${RequestManager.API_VERSION}${endpoint}`;
mutate(
Save reader settings per manga in Meta (#216) * [#213] Add missing "meta" property - IManga - IMangaCard (optional) - IChapter - ICategory * [#213] Add util functions for handling metadata - global server - manga - chapter - category * [#213] Use "ReaderSettings" from the manga metadata - get ReaderSettings from manga metadata - remove unnecessary check "make sure settings has all the keys" in case the stored settings in the metadata are outdated they will be filled with default values * [#213] Reload manga only in case "mangaId" changed In case the chapter is still from the same manga, a reload is unnecessary * [#213] Only update the changed reader setting Otherwise the app has to send patch requests to the server for every setting even if it didn't change * [#213] Hide "openButton" on first render in case "navBar" is shown The "openButton" was always set to be visible event in case the navBar was shown on the first render * [#213] Open the "ReaderNavBar" if needed after receiving new settings Otherwise, the drawer won't open in case the "navBar" was hidden on the first render since the default state in that case was set to false * [#213] Update "ReaderSettings" after receiving the manga response Otherwise, the default settings aren't getting removed * [#213] Hide/Show "OpenButton" when opening/closing the drawer Otherwise, the button stays hidden until it gets updated due to scrolling * [#213] Keep "ReaderNavBar" state when opening prev/next chapter In case the navBar wasn't sticky but opened, it got closed when the prev/next chapter got opened * [#213] Prevent "ReaderNavBar" from closing when changing "staticNav" setting
2023-01-06 17:15:29 +01:00
urlToMutate,
{ ...metadataHolder, ...wrapMetadataWithMetaKey(holderType !== 'global', mutatedMetadata) },
Save reader settings per manga in Meta (#216) * [#213] Add missing "meta" property - IManga - IMangaCard (optional) - IChapter - ICategory * [#213] Add util functions for handling metadata - global server - manga - chapter - category * [#213] Use "ReaderSettings" from the manga metadata - get ReaderSettings from manga metadata - remove unnecessary check "make sure settings has all the keys" in case the stored settings in the metadata are outdated they will be filled with default values * [#213] Reload manga only in case "mangaId" changed In case the chapter is still from the same manga, a reload is unnecessary * [#213] Only update the changed reader setting Otherwise the app has to send patch requests to the server for every setting even if it didn't change * [#213] Hide "openButton" on first render in case "navBar" is shown The "openButton" was always set to be visible event in case the navBar was shown on the first render * [#213] Open the "ReaderNavBar" if needed after receiving new settings Otherwise, the drawer won't open in case the "navBar" was hidden on the first render since the default state in that case was set to false * [#213] Update "ReaderSettings" after receiving the manga response Otherwise, the default settings aren't getting removed * [#213] Hide/Show "OpenButton" when opening/closing the drawer Otherwise, the button stays hidden until it gets updated due to scrolling * [#213] Keep "ReaderNavBar" state when opening prev/next chapter In case the navBar wasn't sticky but opened, it got closed when the prev/next chapter got opened * [#213] Prevent "ReaderNavBar" from closing when changing "staticNav" setting
2023-01-06 17:15:29 +01:00
{ revalidate: false },
);
};
export const requestUpdateMetadata = async (
metadataHolder: MetadataHolder,
holderType: MetadataHolderType,
Save reader settings per manga in Meta (#216) * [#213] Add missing "meta" property - IManga - IMangaCard (optional) - IChapter - ICategory * [#213] Add util functions for handling metadata - global server - manga - chapter - category * [#213] Use "ReaderSettings" from the manga metadata - get ReaderSettings from manga metadata - remove unnecessary check "make sure settings has all the keys" in case the stored settings in the metadata are outdated they will be filled with default values * [#213] Reload manga only in case "mangaId" changed In case the chapter is still from the same manga, a reload is unnecessary * [#213] Only update the changed reader setting Otherwise the app has to send patch requests to the server for every setting even if it didn't change * [#213] Hide "openButton" on first render in case "navBar" is shown The "openButton" was always set to be visible event in case the navBar was shown on the first render * [#213] Open the "ReaderNavBar" if needed after receiving new settings Otherwise, the drawer won't open in case the "navBar" was hidden on the first render since the default state in that case was set to false * [#213] Update "ReaderSettings" after receiving the manga response Otherwise, the default settings aren't getting removed * [#213] Hide/Show "OpenButton" when opening/closing the drawer Otherwise, the button stays hidden until it gets updated due to scrolling * [#213] Keep "ReaderNavBar" state when opening prev/next chapter In case the navBar wasn't sticky but opened, it got closed when the prev/next chapter got opened * [#213] Prevent "ReaderNavBar" from closing when changing "staticNav" setting
2023-01-06 17:15:29 +01:00
keysToValues: [AppMetadataKeys, AllowedMetadataValueTypes][],
): Promise<void[]> =>
Promise.all(keysToValues.map(([key, value]) => requestUpdateMetadataValue(metadataHolder, holderType, key, value)));
Save reader settings per manga in Meta (#216) * [#213] Add missing "meta" property - IManga - IMangaCard (optional) - IChapter - ICategory * [#213] Add util functions for handling metadata - global server - manga - chapter - category * [#213] Use "ReaderSettings" from the manga metadata - get ReaderSettings from manga metadata - remove unnecessary check "make sure settings has all the keys" in case the stored settings in the metadata are outdated they will be filled with default values * [#213] Reload manga only in case "mangaId" changed In case the chapter is still from the same manga, a reload is unnecessary * [#213] Only update the changed reader setting Otherwise the app has to send patch requests to the server for every setting even if it didn't change * [#213] Hide "openButton" on first render in case "navBar" is shown The "openButton" was always set to be visible event in case the navBar was shown on the first render * [#213] Open the "ReaderNavBar" if needed after receiving new settings Otherwise, the drawer won't open in case the "navBar" was hidden on the first render since the default state in that case was set to false * [#213] Update "ReaderSettings" after receiving the manga response Otherwise, the default settings aren't getting removed * [#213] Hide/Show "OpenButton" when opening/closing the drawer Otherwise, the button stays hidden until it gets updated due to scrolling * [#213] Keep "ReaderNavBar" state when opening prev/next chapter In case the navBar wasn't sticky but opened, it got closed when the prev/next chapter got opened * [#213] Prevent "ReaderNavBar" from closing when changing "staticNav" setting
2023-01-06 17:15:29 +01:00
export const requestUpdateServerMetadata = async (
serverMetadata: Metadata,
Save reader settings per manga in Meta (#216) * [#213] Add missing "meta" property - IManga - IMangaCard (optional) - IChapter - ICategory * [#213] Add util functions for handling metadata - global server - manga - chapter - category * [#213] Use "ReaderSettings" from the manga metadata - get ReaderSettings from manga metadata - remove unnecessary check "make sure settings has all the keys" in case the stored settings in the metadata are outdated they will be filled with default values * [#213] Reload manga only in case "mangaId" changed In case the chapter is still from the same manga, a reload is unnecessary * [#213] Only update the changed reader setting Otherwise the app has to send patch requests to the server for every setting even if it didn't change * [#213] Hide "openButton" on first render in case "navBar" is shown The "openButton" was always set to be visible event in case the navBar was shown on the first render * [#213] Open the "ReaderNavBar" if needed after receiving new settings Otherwise, the drawer won't open in case the "navBar" was hidden on the first render since the default state in that case was set to false * [#213] Update "ReaderSettings" after receiving the manga response Otherwise, the default settings aren't getting removed * [#213] Hide/Show "OpenButton" when opening/closing the drawer Otherwise, the button stays hidden until it gets updated due to scrolling * [#213] Keep "ReaderNavBar" state when opening prev/next chapter In case the navBar wasn't sticky but opened, it got closed when the prev/next chapter got opened * [#213] Prevent "ReaderNavBar" from closing when changing "staticNav" setting
2023-01-06 17:15:29 +01:00
keysToValues: MetadataKeyValuePair[],
): Promise<void[]> => requestUpdateMetadata({ meta: serverMetadata }, 'global', keysToValues);
Save reader settings per manga in Meta (#216) * [#213] Add missing "meta" property - IManga - IMangaCard (optional) - IChapter - ICategory * [#213] Add util functions for handling metadata - global server - manga - chapter - category * [#213] Use "ReaderSettings" from the manga metadata - get ReaderSettings from manga metadata - remove unnecessary check "make sure settings has all the keys" in case the stored settings in the metadata are outdated they will be filled with default values * [#213] Reload manga only in case "mangaId" changed In case the chapter is still from the same manga, a reload is unnecessary * [#213] Only update the changed reader setting Otherwise the app has to send patch requests to the server for every setting even if it didn't change * [#213] Hide "openButton" on first render in case "navBar" is shown The "openButton" was always set to be visible event in case the navBar was shown on the first render * [#213] Open the "ReaderNavBar" if needed after receiving new settings Otherwise, the drawer won't open in case the "navBar" was hidden on the first render since the default state in that case was set to false * [#213] Update "ReaderSettings" after receiving the manga response Otherwise, the default settings aren't getting removed * [#213] Hide/Show "OpenButton" when opening/closing the drawer Otherwise, the button stays hidden until it gets updated due to scrolling * [#213] Keep "ReaderNavBar" state when opening prev/next chapter In case the navBar wasn't sticky but opened, it got closed when the prev/next chapter got opened * [#213] Prevent "ReaderNavBar" from closing when changing "staticNav" setting
2023-01-06 17:15:29 +01:00
export const requestUpdateMangaMetadata = async (
manga: IMangaCard | IManga,
keysToValues: MetadataKeyValuePair[],
): Promise<void[]> => requestUpdateMetadata(manga, 'manga', keysToValues);
Save reader settings per manga in Meta (#216) * [#213] Add missing "meta" property - IManga - IMangaCard (optional) - IChapter - ICategory * [#213] Add util functions for handling metadata - global server - manga - chapter - category * [#213] Use "ReaderSettings" from the manga metadata - get ReaderSettings from manga metadata - remove unnecessary check "make sure settings has all the keys" in case the stored settings in the metadata are outdated they will be filled with default values * [#213] Reload manga only in case "mangaId" changed In case the chapter is still from the same manga, a reload is unnecessary * [#213] Only update the changed reader setting Otherwise the app has to send patch requests to the server for every setting even if it didn't change * [#213] Hide "openButton" on first render in case "navBar" is shown The "openButton" was always set to be visible event in case the navBar was shown on the first render * [#213] Open the "ReaderNavBar" if needed after receiving new settings Otherwise, the drawer won't open in case the "navBar" was hidden on the first render since the default state in that case was set to false * [#213] Update "ReaderSettings" after receiving the manga response Otherwise, the default settings aren't getting removed * [#213] Hide/Show "OpenButton" when opening/closing the drawer Otherwise, the button stays hidden until it gets updated due to scrolling * [#213] Keep "ReaderNavBar" state when opening prev/next chapter In case the navBar wasn't sticky but opened, it got closed when the prev/next chapter got opened * [#213] Prevent "ReaderNavBar" from closing when changing "staticNav" setting
2023-01-06 17:15:29 +01:00
export const requestUpdateChapterMetadata = async (
mangaChapter: IMangaChapter,
keysToValues: MetadataKeyValuePair[],
): Promise<void[]> => requestUpdateMetadata(mangaChapter.chapter, 'chapter', keysToValues);
Save reader settings per manga in Meta (#216) * [#213] Add missing "meta" property - IManga - IMangaCard (optional) - IChapter - ICategory * [#213] Add util functions for handling metadata - global server - manga - chapter - category * [#213] Use "ReaderSettings" from the manga metadata - get ReaderSettings from manga metadata - remove unnecessary check "make sure settings has all the keys" in case the stored settings in the metadata are outdated they will be filled with default values * [#213] Reload manga only in case "mangaId" changed In case the chapter is still from the same manga, a reload is unnecessary * [#213] Only update the changed reader setting Otherwise the app has to send patch requests to the server for every setting even if it didn't change * [#213] Hide "openButton" on first render in case "navBar" is shown The "openButton" was always set to be visible event in case the navBar was shown on the first render * [#213] Open the "ReaderNavBar" if needed after receiving new settings Otherwise, the drawer won't open in case the "navBar" was hidden on the first render since the default state in that case was set to false * [#213] Update "ReaderSettings" after receiving the manga response Otherwise, the default settings aren't getting removed * [#213] Hide/Show "OpenButton" when opening/closing the drawer Otherwise, the button stays hidden until it gets updated due to scrolling * [#213] Keep "ReaderNavBar" state when opening prev/next chapter In case the navBar wasn't sticky but opened, it got closed when the prev/next chapter got opened * [#213] Prevent "ReaderNavBar" from closing when changing "staticNav" setting
2023-01-06 17:15:29 +01:00
export const requestUpdateCategoryMetadata = async (
category: ICategory,
keysToValues: MetadataKeyValuePair[],
): Promise<void[]> => requestUpdateMetadata(category, 'category', keysToValues);