Skip to content

Commit

Permalink
Support configuring automatic downloads by category
Browse files Browse the repository at this point in the history
Signed-off-by: Chance Zibolski <chance.zibolski@gmail.com>
  • Loading branch information
chancez committed Jan 17, 2024
1 parent e10cbf9 commit 87f5c7d
Show file tree
Hide file tree
Showing 9 changed files with 84 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,35 +19,35 @@ import Button from '@mui/material/Button';
import { t as translate } from 'i18next';
import { ThreeStateCheckboxInput } from '@/components/atoms/ThreeStateCheckboxInput.tsx';
import { makeToast } from '@/components/util/Toast.tsx';
import { IncludeInUpdate } from '@/lib/graphql/generated/graphql.ts';
import { IncludeOrExclude } from '@/lib/graphql/generated/graphql.ts';
import { TCategory } from '@/typings.ts';
import { requestManager } from '@/lib/requests/RequestManager.ts';
import { CheckboxContainer } from '@/components/settings/globalUpdate/CheckboxContainer.ts';

const booleanToIncludeInStatus = (status: boolean | null | undefined): IncludeInUpdate => {
const booleanToIncludeInStatus = (status: boolean | null | undefined): IncludeOrExclude => {
switch (status) {
case false:
return IncludeInUpdate.Exclude;
return IncludeOrExclude.Exclude;
case true:
return IncludeInUpdate.Include;
return IncludeOrExclude.Include;
case null:
case undefined:
return IncludeInUpdate.Unset;
return IncludeOrExclude.Unset;
default:
throw new Error(`booleanToIncludeInStatus: unexpected IncludeInUpdate status "${status}"`);
throw new Error(`booleanToIncludeInStatus: unexpected IncludeOrExclude status "${status}"`);
}
};

const includeInUpdateStatusToBoolean = (status: IncludeInUpdate): boolean | null => {
const includeInUpdateStatusToBoolean = (status: IncludeOrExclude): boolean | null => {
switch (status) {
case IncludeInUpdate.Exclude:
case IncludeOrExclude.Exclude:
return false;
case IncludeInUpdate.Include:
case IncludeOrExclude.Include:
return true;
case IncludeInUpdate.Unset:
case IncludeOrExclude.Unset:
return null;
default:
throw new Error(`includeInUpdateStatusToBoolean: unexpected IncludeInUpdate status "${status}"`);
throw new Error(`includeInUpdateStatusToBoolean: unexpected IncludeOrExclude status "${status}"`);
}
};

Expand Down Expand Up @@ -78,9 +78,12 @@ const getCategoryUpdateInfo = (
return categories.map((category) => category.name).join(', ');
};

export const GlobalUpdateSettingsCategories = () => {
type CategoryIncludeField = keyof Pick<TCategory, 'includeInUpdate' | 'includeInDownload'>

export const CategoriesSetting = (props: {includeField: CategoryIncludeField}) => {
const { t } = useTranslation();

const { includeField } = props;
const { data, error: requestError } = requestManager.useGetCategories();
const categories = data?.categories.nodes;
const [dialogCategories, setDialogCategories] = useState<TCategory[]>(categories ?? []);
Expand All @@ -95,11 +98,11 @@ export const GlobalUpdateSettingsCategories = () => {
}, [categories]);

const unsetCategories: TCategory[] =
categories?.filter((category) => category.includeInUpdate === IncludeInUpdate.Unset) ?? [];
categories?.filter((category) => category[includeField] === IncludeOrExclude.Unset) ?? [];
const excludedCategories: TCategory[] =
categories?.filter((category) => category.includeInUpdate === IncludeInUpdate.Exclude) ?? [];
categories?.filter((category) => category[includeField] === IncludeOrExclude.Exclude) ?? [];
const includedCategories: TCategory[] =
categories?.filter((category) => category.includeInUpdate === IncludeInUpdate.Include) ?? [];
categories?.filter((category) => category[includeField] === IncludeOrExclude.Include) ?? [];
const excludedCategoriesText = getCategoryUpdateInfo(
excludedCategories,
false,
Expand All @@ -116,7 +119,7 @@ export const GlobalUpdateSettingsCategories = () => {
);

const updateCategory = (category: TCategory) =>
requestManager.updateCategory(category.id, { includeInUpdate: category.includeInUpdate }).response;
requestManager.updateCategory(category.id, { [includeField]: category[includeField] }).response;

const updateCategories = async () => {
const categoriesToUpdate = dialogCategories.filter((category) => {
Expand All @@ -126,7 +129,7 @@ export const GlobalUpdateSettingsCategories = () => {
return false;
}

return currentCategory.includeInUpdate !== category.includeInUpdate;
return currentCategory[includeField] !== category[includeField];
});

setIsDialogOpen(false);
Expand Down Expand Up @@ -180,7 +183,7 @@ export const GlobalUpdateSettingsCategories = () => {
<ThreeStateCheckboxInput
key={category.id}
label={category.name}
checked={includeInUpdateStatusToBoolean(category.includeInUpdate)}
checked={includeInUpdateStatusToBoolean(category[includeField])}
onChange={(checked) => {
const newIncludeState = booleanToIncludeInStatus(checked);

Expand All @@ -191,7 +194,7 @@ export const GlobalUpdateSettingsCategories = () => {
...dialogCategories.slice(0, categoryIndex),
{
...category,
includeInUpdate: newIncludeState,
[includeField]: newIncludeState,
},
...dialogCategories.slice(categoryIndex + 1, dialogCategories.length),
];
Expand Down
7 changes: 5 additions & 2 deletions src/components/settings/globalUpdate/GlobalUpdateSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ import List from '@mui/material/List';
import ListSubheader from '@mui/material/ListSubheader';
import { useTranslation } from 'react-i18next';
import { ListItem, ListItemText, Switch } from '@mui/material';
import { GlobalUpdateSettingsCategories } from '@/components/settings/globalUpdate/GlobalUpdateSettingsCategories.tsx';
import { CategoriesSetting } from '@/components/settings/CategoriesSetting.tsx';
import { GlobalUpdateSettingsEntries } from '@/components/settings/globalUpdate/GlobalUpdateSettingsEntries.tsx';
import { GlobalUpdateSettingsInterval } from '@/components/settings/globalUpdate/GlobalUpdateSettingsInterval.tsx';
import { requestManager } from '@/lib/requests/RequestManager.ts';
import { makeToast } from '@/components/util/Toast.tsx';
import { ServerSettings } from '@/typings.ts';
import { TCategory } from '@/typings.ts';

type LibrarySettingsType = Pick<ServerSettings, 'updateMangas'>;

Expand Down Expand Up @@ -47,7 +48,9 @@ export const GlobalUpdateSettings = () => {
>
<GlobalUpdateSettingsInterval />
<GlobalUpdateSettingsEntries />
<GlobalUpdateSettingsCategories />
<CategoriesSetting
includeField='includeInUpdate'
/>
<ListItem>
<ListItemText
primary={t('library.settings.global_update.metadata.label.title')}
Expand Down
2 changes: 2 additions & 0 deletions src/lib/graphql/Fragments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const FULL_CATEGORY_FIELDS = gql`
default
id
includeInUpdate
includeInDownload
name
order
meta {
Expand All @@ -46,6 +47,7 @@ export const UPDATER_CATEGORY_FIELDS = gql`
id
name
includeInUpdate
includeInDownload
}
`;

Expand Down
31 changes: 13 additions & 18 deletions src/lib/graphql/generated/apollo-helpers.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
import {FieldPolicy, FieldReadFunction, Reference, TypePolicies, TypePolicy} from '@apollo/client/cache';
import {
GetCategoryQueryVariables, GetChapterQueryVariables,
GetChaptersQuery, GetDownloadStatusQueryVariables, GetExtensionQueryVariables, GetGlobalMetadataQueryVariables,
GetMangaQueryVariables, GetSourceQueryVariables, GetUpdateStatusQueryVariables, GetWebuiUpdateStatusQueryVariables,
} from "@/lib/graphql/generated/graphql.ts";
import {FieldFunctionOptions} from "@apollo/client/cache/inmemory/policies";
import { FieldPolicy, FieldReadFunction, TypePolicies, TypePolicy } from '@apollo/client/cache';
export type AboutServerPayloadKeySpecifier = ('buildTime' | 'buildType' | 'discord' | 'github' | 'name' | 'revision' | 'version' | AboutServerPayloadKeySpecifier)[];
export type AboutServerPayloadFieldPolicy = {
buildTime?: FieldPolicy<any> | FieldReadFunction<any>,
Expand Down Expand Up @@ -50,10 +44,11 @@ export type CategoryNodeListFieldPolicy = {
pageInfo?: FieldPolicy<any> | FieldReadFunction<any>,
totalCount?: FieldPolicy<any> | FieldReadFunction<any>
};
export type CategoryTypeKeySpecifier = ('default' | 'id' | 'includeInUpdate' | 'mangas' | 'meta' | 'name' | 'order' | CategoryTypeKeySpecifier)[];
export type CategoryTypeKeySpecifier = ('default' | 'id' | 'includeInDownload' | 'includeInUpdate' | 'mangas' | 'meta' | 'name' | 'order' | CategoryTypeKeySpecifier)[];
export type CategoryTypeFieldPolicy = {
default?: FieldPolicy<any> | FieldReadFunction<any>,
id?: FieldPolicy<any> | FieldReadFunction<any>,
includeInDownload?: FieldPolicy<any> | FieldReadFunction<any>,
includeInUpdate?: FieldPolicy<any> | FieldReadFunction<any>,
mangas?: FieldPolicy<any> | FieldReadFunction<any>,
meta?: FieldPolicy<any> | FieldReadFunction<any>,
Expand Down Expand Up @@ -549,30 +544,30 @@ export type QueryFieldPolicy = {
aboutServer?: FieldPolicy<any> | FieldReadFunction<any>,
aboutWebUI?: FieldPolicy<any> | FieldReadFunction<any>,
categories?: FieldPolicy<any> | FieldReadFunction<any>,
category?: FieldPolicy<Reference, Reference, Reference, FieldFunctionOptions<GetCategoryQueryVariables>> | FieldReadFunction<Reference, Reference, FieldFunctionOptions<GetCategoryQueryVariables>>,
chapter?: FieldPolicy<Reference, Reference, Reference, FieldFunctionOptions<GetChapterQueryVariables>> | FieldReadFunction<Reference, Reference, FieldFunctionOptions<GetChapterQueryVariables>>,
chapters?: FieldPolicy<GetChaptersQuery['chapters']> | FieldReadFunction<GetChaptersQuery['chapters']>,
category?: FieldPolicy<any> | FieldReadFunction<any>,
chapter?: FieldPolicy<any> | FieldReadFunction<any>,
chapters?: FieldPolicy<any> | FieldReadFunction<any>,
checkForServerUpdates?: FieldPolicy<any> | FieldReadFunction<any>,
checkForWebUIUpdate?: FieldPolicy<any> | FieldReadFunction<any>,
downloadStatus?: FieldPolicy<Reference, Reference, Reference, FieldFunctionOptions<GetDownloadStatusQueryVariables>> | FieldReadFunction<Reference, Reference, FieldFunctionOptions<GetDownloadStatusQueryVariables>>,
extension?: FieldPolicy<Reference, Reference, Reference, FieldFunctionOptions<GetExtensionQueryVariables>> | FieldReadFunction<Reference, Reference, FieldFunctionOptions<GetExtensionQueryVariables>>,
downloadStatus?: FieldPolicy<any> | FieldReadFunction<any>,
extension?: FieldPolicy<any> | FieldReadFunction<any>,
extensions?: FieldPolicy<any> | FieldReadFunction<any>,
getWebUIUpdateStatus?: FieldPolicy<Reference, Reference, Reference, FieldFunctionOptions<GetWebuiUpdateStatusQueryVariables>> | FieldReadFunction<Reference, Reference, FieldFunctionOptions<GetWebuiUpdateStatusQueryVariables>>,
getWebUIUpdateStatus?: FieldPolicy<any> | FieldReadFunction<any>,
lastUpdateTimestamp?: FieldPolicy<any> | FieldReadFunction<any>,
manga?: FieldPolicy<Reference, Reference, Reference, FieldFunctionOptions<GetMangaQueryVariables>> | FieldReadFunction<Reference, Reference, FieldFunctionOptions<GetMangaQueryVariables>>,
manga?: FieldPolicy<any> | FieldReadFunction<any>,
mangas?: FieldPolicy<any> | FieldReadFunction<any>,
meta?: FieldPolicy<Reference, Reference, Reference, FieldFunctionOptions<GetGlobalMetadataQueryVariables>> | FieldReadFunction<Reference, Reference, FieldFunctionOptions<GetGlobalMetadataQueryVariables>>,
meta?: FieldPolicy<any> | FieldReadFunction<any>,
metas?: FieldPolicy<any> | FieldReadFunction<any>,
restoreStatus?: FieldPolicy<any> | FieldReadFunction<any>,
searchTracker?: FieldPolicy<any> | FieldReadFunction<any>,
settings?: FieldPolicy<any> | FieldReadFunction<any>,
source?: FieldPolicy<Reference, Reference, Reference, FieldFunctionOptions<GetSourceQueryVariables>> | FieldReadFunction<Reference, Reference, FieldFunctionOptions<GetSourceQueryVariables>>,
source?: FieldPolicy<any> | FieldReadFunction<any>,
sources?: FieldPolicy<any> | FieldReadFunction<any>,
trackRecord?: FieldPolicy<any> | FieldReadFunction<any>,
trackRecords?: FieldPolicy<any> | FieldReadFunction<any>,
tracker?: FieldPolicy<any> | FieldReadFunction<any>,
trackers?: FieldPolicy<any> | FieldReadFunction<any>,
updateStatus?: FieldPolicy<Reference, Reference, Reference, FieldFunctionOptions<GetUpdateStatusQueryVariables>> | FieldReadFunction<Reference, Reference, FieldFunctionOptions<GetUpdateStatusQueryVariables>>,
updateStatus?: FieldPolicy<any> | FieldReadFunction<any>,
validateBackup?: FieldPolicy<any> | FieldReadFunction<any>
};
export type ReorderChapterDownloadPayloadKeySpecifier = ('clientMutationId' | 'downloadStatus' | ReorderChapterDownloadPayloadKeySpecifier)[];
Expand Down
Loading

0 comments on commit 87f5c7d

Please sign in to comment.