diff --git a/src/core/router/index.tsx b/src/core/router/index.tsx
index 9ab6742a4..31cc70131 100644
--- a/src/core/router/index.tsx
+++ b/src/core/router/index.tsx
@@ -30,6 +30,7 @@ import MainPage from '@/pages/main/MainPage';
import SettingsPage from '@/pages/settings/SettingsPage';
import AniDBSettings from '@/pages/settings/tabs/AniDBSettings';
import ApiKey from '@/pages/settings/tabs/ApiKeys';
+import CollectionSettings from '@/pages/settings/tabs/CollectionSettings';
import GeneralSettings from '@/pages/settings/tabs/GeneralSettings';
import ImportSettings from '@/pages/settings/tabs/ImportSettings';
import MetadataSitesSettings from '@/pages/settings/tabs/MetadataSitesSettings';
@@ -110,6 +111,7 @@ const router = sentryCreateBrowserRouter(
} />
} />
} />
+ } />
} />
} />
diff --git a/src/css/common.css b/src/css/common.css
index 270aa51ff..90085ddac 100644
--- a/src/css/common.css
+++ b/src/css/common.css
@@ -150,6 +150,11 @@ body {
font-family: Sora, sans, serif, mono !important;
}
+/* stylelint-disable-next-line selector-class-pattern */
+.Toastify__progress-bar {
+ height: 10% !important;
+}
+
/* stylelint-disable-next-line selector-class-pattern */
.Toastify__progress-bar--success {
background: theme('colors.panel-text-important') !important;
diff --git a/src/pages/settings/SettingsPage.tsx b/src/pages/settings/SettingsPage.tsx
index 1ea5da408..14d5ed65f 100644
--- a/src/pages/settings/SettingsPage.tsx
+++ b/src/pages/settings/SettingsPage.tsx
@@ -18,6 +18,7 @@ const items = [
{ name: 'Import', path: 'import' },
{ name: 'AniDB', path: 'anidb' },
{ name: 'Metadata Sites', path: 'metadata-sites' },
+ { name: 'Collection', path: 'collection' },
// { name: 'Display', path: 'display' },
{ name: 'User Management', path: 'user-management' },
// { name: 'Themes', path: 'themes' },
diff --git a/src/pages/settings/tabs/AniDBSettings.tsx b/src/pages/settings/tabs/AniDBSettings.tsx
index 09f6ae472..48b4a592e 100644
--- a/src/pages/settings/tabs/AniDBSettings.tsx
+++ b/src/pages/settings/tabs/AniDBSettings.tsx
@@ -1,13 +1,7 @@
/* eslint-disable @typescript-eslint/naming-convention */
-import React, { useState } from 'react';
-import { mdiMinusCircleOutline, mdiPlusCircleOutline } from '@mdi/js';
-import { Icon } from '@mdi/react';
+import React from 'react';
import cx from 'classnames';
-import { remove } from 'lodash';
-import LanguagesModal from '@/components/Dialogs/LanguagesModal';
-import { languageDescription } from '@/components/Dialogs/constants';
-import DnDList from '@/components/DnDList/DnDList';
import Button from '@/components/Input/Button';
import Checkbox from '@/components/Input/Checkbox';
import InputSmall from '@/components/Input/InputSmall';
@@ -16,8 +10,6 @@ import toast from '@/components/Toast';
import { useAniDBTestLoginMutation } from '@/core/react-query/settings/mutations';
import useSettingsContext from '@/hooks/useSettingsContext';
-import type { DropResult } from '@hello-pangea/dnd';
-
const UpdateFrequencyValues = () => (
<>
@@ -30,12 +22,9 @@ const UpdateFrequencyValues = () => (
);
function AniDBSettings() {
- const { newSettings, setNewSettings, updateSetting } = useSettingsContext();
-
+ const { newSettings, updateSetting } = useSettingsContext();
const { isPending: isAnidbLoginPending, mutate: testAniDbLogin } = useAniDBTestLoginMutation();
- const [showLanguagesModal, setShowLanguagesModal] = useState<'Series' | 'Episode' | null>(null);
-
const {
AVDumpClientPort,
AVDumpKey,
@@ -61,34 +50,6 @@ function AniDBSettings() {
Username,
} = newSettings.AniDb;
- const onDragEnd = (result: DropResult, episodePreference = false) => {
- if (!result.destination || result.destination.index === result.source.index) {
- return;
- }
-
- const items = Array.from(
- episodePreference ? newSettings.EpisodeLanguagePreference : newSettings.LanguagePreference,
- );
- const [removed] = items.splice(result.source.index, 1);
- items.splice(result.destination.index, 0, removed);
-
- setNewSettings({
- ...newSettings,
- [episodePreference ? 'EpisodeLanguagePreference' : 'LanguagePreference']: items,
- });
- };
-
- const removeLanguage = (language: string, episodePreference = false) => {
- const items = Array.from(
- episodePreference ? newSettings.EpisodeLanguagePreference : newSettings.LanguagePreference,
- );
- remove(items, item => item === language);
- setNewSettings({
- ...newSettings,
- [episodePreference ? 'EpisodeLanguagePreference' : 'LanguagePreference']: items,
- });
- };
-
const testLogin = () => {
testAniDbLogin({ Username, Password }, {
onSuccess: () => toast.success('AniDB Login Successful!'),
@@ -345,67 +306,6 @@ function AniDBSettings() {
-
-
-
Language Options
-
-
setNewSettings({ ...newSettings, LanguageUseSynonyms: event.target.checked })}
- justify
- />
-
- Series Title (Drag to Reorder)
-
-
-
-
onDragEnd(result)}>
- {newSettings.LanguagePreference.map(language => (
- {
- key: language,
- item: (
-
- {languageDescription[language]}
-
-
- ),
- }
- ))}
-
-
-
- Episode Title (Drag to Reorder)
-
-
-
-
onDragEnd(result, true)}>
- {newSettings.EpisodeLanguagePreference.map(language => (
- {
- key: language,
- item: (
-
- {languageDescription[language]}
-
-
- ),
- }
- ))}
-
-
-
-
-
- setShowLanguagesModal(null)} />
>
);
}
diff --git a/src/pages/settings/tabs/CollectionSettings.tsx b/src/pages/settings/tabs/CollectionSettings.tsx
new file mode 100644
index 000000000..836f729fc
--- /dev/null
+++ b/src/pages/settings/tabs/CollectionSettings.tsx
@@ -0,0 +1,236 @@
+/* eslint-disable @typescript-eslint/naming-convention */
+import React, { type ChangeEvent, useState } from 'react';
+import { mdiMinusCircleOutline, mdiPlusCircleOutline } from '@mdi/js';
+import { Icon } from '@mdi/react';
+import { keys, remove } from 'lodash';
+
+import LanguagesModal from '@/components/Dialogs/LanguagesModal';
+import { languageDescription } from '@/components/Dialogs/constants';
+import DnDList from '@/components/DnDList/DnDList';
+import Button from '@/components/Input/Button';
+import Checkbox from '@/components/Input/Checkbox';
+import useSettingsContext from '@/hooks/useSettingsContext';
+
+import type { DropResult } from '@hello-pangea/dnd';
+
+const CollectionSettings = () => {
+ const { newSettings, setNewSettings } = useSettingsContext();
+ const [showLanguagesModal, setShowLanguagesModal] = useState<'Series' | 'Episode' | null>(null);
+
+ const {
+ AutoGroupSeries,
+ AutoGroupSeriesRelationExclusions,
+ AutoGroupSeriesUseScoreAlgorithm,
+ } = newSettings;
+
+ const onDragEnd = (result: DropResult, episodePreference = false) => {
+ if (!result.destination || result.destination.index === result.source.index) {
+ return;
+ }
+
+ const items = Array.from(
+ episodePreference ? newSettings.EpisodeLanguagePreference : newSettings.LanguagePreference,
+ );
+ const [removed] = items.splice(result.source.index, 1);
+ items.splice(result.destination.index, 0, removed);
+
+ setNewSettings({
+ ...newSettings,
+ [episodePreference ? 'EpisodeLanguagePreference' : 'LanguagePreference']: items,
+ });
+ };
+
+ const removeLanguage = (language: string, episodePreference = false) => {
+ const items = Array.from(
+ episodePreference ? newSettings.EpisodeLanguagePreference : newSettings.LanguagePreference,
+ );
+ remove(items, item => item === language);
+ setNewSettings({
+ ...newSettings,
+ [episodePreference ? 'EpisodeLanguagePreference' : 'LanguagePreference']: items,
+ });
+ };
+
+ const exclusionMapping = {
+ dissimilarTitles: {
+ id: 'AllowDissimilarTitleExclusion',
+ name: 'Dissimilar Titles',
+ },
+ prequel: {
+ id: 'prequel',
+ name: 'Prequel',
+ },
+ sequel: {
+ id: 'sequel',
+ name: 'Sequel',
+ },
+ ova: {
+ id: 'ova',
+ name: 'OVA',
+ },
+ movie: {
+ id: 'movie',
+ name: 'Movie',
+ },
+ sameSetting: {
+ id: 'same setting',
+ name: 'Same Setting',
+ },
+ altSetting: {
+ id: 'alternative setting',
+ name: 'Alternative Setting',
+ },
+ altVersion: {
+ id: 'alternative version',
+ name: 'Alternative Version',
+ },
+ parentStory: {
+ id: 'parent story',
+ name: 'Parent Story',
+ },
+ sideStory: {
+ id: 'side story',
+ name: 'Side Story',
+ },
+ fullStory: {
+ id: 'full story',
+ name: 'Full Story',
+ },
+ summary: {
+ id: 'summary',
+ name: 'Summary',
+ },
+ character: {
+ id: 'character',
+ name: 'Character',
+ },
+ other: {
+ id: 'other',
+ name: 'Other',
+ },
+ };
+
+ function isExclusionKey(id: string): id is keyof typeof exclusionMapping {
+ return id in exclusionMapping;
+ }
+
+ const handleExclusionChange = (event: ChangeEvent) => {
+ if (!(event.target.id in exclusionMapping)) return;
+ const { checked, id } = event.target;
+
+ if (isExclusionKey(id)) {
+ if (checked) {
+ const tempExclusions = [...AutoGroupSeriesRelationExclusions, exclusionMapping[id].id];
+ setNewSettings({ ...newSettings, AutoGroupSeriesRelationExclusions: tempExclusions });
+ } else {
+ const tempExclusions = AutoGroupSeriesRelationExclusions.filter(
+ exclusion => exclusion !== exclusionMapping[id].id,
+ );
+ setNewSettings({ ...newSettings, AutoGroupSeriesRelationExclusions: tempExclusions });
+ }
+ }
+ };
+
+ return (
+ <>
+ Collection
+ {/* Language Settings */}
+
+
Language Options
+
+
setNewSettings({ ...newSettings, LanguageUseSynonyms: event.target.checked })}
+ justify
+ />
+
+ Series Title (Drag to Reorder)
+
+
+
+
onDragEnd(result)}>
+ {newSettings.LanguagePreference.map(language => (
+ {
+ key: language,
+ item: (
+
+ {languageDescription[language]}
+
+
+ ),
+ }
+ ))}
+
+
+
+ Episode Title (Drag to Reorder)
+
+
+
+
onDragEnd(result, true)}>
+ {newSettings.EpisodeLanguagePreference.map(language => (
+ {
+ key: language,
+ item: (
+
+ {languageDescription[language]}
+
+
+ ),
+ }
+ ))}
+
+
+
+
+ setShowLanguagesModal(null)} />
+
+ {/* Relation Settings */}
+
+
Relation Options
+
+
setNewSettings({ ...newSettings, AutoGroupSeries: event.target.checked })}
+ />
+
+ setNewSettings({ ...newSettings, AutoGroupSeriesUseScoreAlgorithm: event.target.checked })}
+ />
+ Exclude following relations
+
+ {keys(exclusionMapping).map((item: keyof typeof exclusionMapping) => (
+
+ ))}
+
+
+
+ >
+ );
+};
+
+export default CollectionSettings;
diff --git a/src/pages/settings/tabs/GeneralSettings.tsx b/src/pages/settings/tabs/GeneralSettings.tsx
index a3ab6593f..8ff3a8b7d 100644
--- a/src/pages/settings/tabs/GeneralSettings.tsx
+++ b/src/pages/settings/tabs/GeneralSettings.tsx
@@ -1,10 +1,8 @@
/* eslint-disable @typescript-eslint/naming-convention */
import React, { useMemo } from 'react';
-import type { ChangeEvent } from 'react';
import { mdiOpenInNew, mdiRefresh } from '@mdi/js';
import { Icon } from '@mdi/react';
import cx from 'classnames';
-import { keys } from 'lodash';
import Button from '@/components/Input/Button';
import Checkbox from '@/components/Input/Checkbox';
@@ -16,76 +14,10 @@ import useSettingsContext from '@/hooks/useSettingsContext';
const UI_VERSION = uiVersion();
-const exclusionMapping = {
- dissimilarTitles: {
- id: 'AllowDissimilarTitleExclusion',
- name: 'Dissimilar Titles',
- },
- prequel: {
- id: 'prequel',
- name: 'Prequel',
- },
- sequel: {
- id: 'sequel',
- name: 'Sequel',
- },
- ova: {
- id: 'ova',
- name: 'OVA',
- },
- movie: {
- id: 'movie',
- name: 'Movie',
- },
- sameSetting: {
- id: 'same setting',
- name: 'Same Setting',
- },
- altSetting: {
- id: 'alternative setting',
- name: 'Alternative Setting',
- },
- altVersion: {
- id: 'alternative version',
- name: 'Alternative Version',
- },
- parentStory: {
- id: 'parent story',
- name: 'Parent Story',
- },
- sideStory: {
- id: 'side story',
- name: 'Side Story',
- },
- fullStory: {
- id: 'full story',
- name: 'Full Story',
- },
- summary: {
- id: 'summary',
- name: 'Summary',
- },
- character: {
- id: 'character',
- name: 'Character',
- },
- other: {
- id: 'other',
- name: 'Other',
- },
-};
-
-function isExclusionKey(id: string): id is keyof typeof exclusionMapping {
- return id in exclusionMapping;
-}
-
function GeneralSettings() {
const { newSettings, setNewSettings, updateSetting } = useSettingsContext();
const {
- AutoGroupSeries,
- AutoGroupSeriesRelationExclusions,
- AutoGroupSeriesUseScoreAlgorithm,
LogRotator,
TraceLog,
WebUI_Settings,
@@ -102,23 +34,6 @@ function GeneralSettings() {
themesQuery.data?.find(theme => `theme-${theme.ID}` === WebUI_Settings.theme)
), [themesQuery.data, WebUI_Settings.theme]);
- const handleExclusionChange = (event: ChangeEvent) => {
- if (!(event.target.id in exclusionMapping)) return;
- const { checked, id } = event.target;
-
- if (isExclusionKey(id)) {
- if (checked) {
- const tempExclusions = [...AutoGroupSeriesRelationExclusions, exclusionMapping[id].id];
- setNewSettings({ ...newSettings, AutoGroupSeriesRelationExclusions: tempExclusions });
- } else {
- const tempExclusions = AutoGroupSeriesRelationExclusions.filter(
- exclusion => exclusion !== exclusionMapping[id].id,
- );
- setNewSettings({ ...newSettings, AutoGroupSeriesRelationExclusions: tempExclusions });
- }
- }
- };
-
return (
<>
General
@@ -304,40 +219,6 @@ function GeneralSettings() {
/>
-
-
-
Relation Options
-
-
setNewSettings({ ...newSettings, AutoGroupSeries: event.target.checked })}
- />
-
- setNewSettings({ ...newSettings, AutoGroupSeriesUseScoreAlgorithm: event.target.checked })}
- />
- Exclude following relations
-
- {keys(exclusionMapping).map((item: keyof typeof exclusionMapping) => (
-
- ))}
-
-
-
>
);
}