From 88c0d8153dae31885670d2836065b070e628f68d Mon Sep 17 00:00:00 2001 From: Harshith Mohan Date: Sun, 19 Nov 2023 14:17:27 +0530 Subject: [PATCH] Add dashboard settings (#681) * Update actions modal * Update queue processor panel to 7.5 * Update DashboardTitleToggle to 7.5 * Fix ShokoPanel loader * Add dashboard settings (WIP) * Add remaining dashboard settings * Fix linter warning * Fix fallback text in recently imported, remove `useMemo` for `isLoading` * Add Missing Widget Options. * Change Dependency Array value. --------- Co-authored-by: ElementalCrisis <9443295+ElementalCrisis@users.noreply.github.com> --- .../Dashboard/DashboardSettingsModal.tsx | 277 ++++++++++++++++++ src/components/Input/Checkbox.tsx | 10 +- src/components/Layout/TopNav.tsx | 20 +- src/components/Panels/ShokoPanel.tsx | 4 +- src/core/rtkQuery/splitV3Api/dashboardApi.ts | 15 +- src/core/types/api.ts | 5 + src/core/types/api/settings.ts | 18 ++ .../collection/series/SeriesOverview.tsx | 2 +- src/pages/dashboard/DashboardPage.tsx | 113 ++++--- .../components/DashboardTitleToggle.tsx | 37 +-- .../dashboard/panels/ContinueWatching.tsx | 12 +- src/pages/dashboard/panels/NextUp.tsx | 22 +- src/pages/dashboard/panels/QueueProcessor.tsx | 40 +-- .../dashboard/panels/RecentlyImported.tsx | 38 ++- src/pages/dashboard/panels/ShokoNews.tsx | 12 +- src/pages/dashboard/panels/UpcomingAnime.tsx | 21 +- src/pages/settings/SettingsPage.tsx | 24 +- 17 files changed, 545 insertions(+), 125 deletions(-) create mode 100644 src/components/Dashboard/DashboardSettingsModal.tsx diff --git a/src/components/Dashboard/DashboardSettingsModal.tsx b/src/components/Dashboard/DashboardSettingsModal.tsx new file mode 100644 index 000000000..fd1958320 --- /dev/null +++ b/src/components/Dashboard/DashboardSettingsModal.tsx @@ -0,0 +1,277 @@ +import React, { useEffect, useMemo, useState } from 'react'; +import { useDispatch } from 'react-redux'; +import cx from 'classnames'; +import { cloneDeep, toNumber } from 'lodash'; + +import Button from '@/components/Input/Button'; +import Checkbox from '@/components/Input/Checkbox'; +import InputSmall from '@/components/Input/InputSmall'; +import ModalPanel from '@/components/Panels/ModalPanel'; +import { useGetSettingsQuery, usePatchSettingsMutation } from '@/core/rtkQuery/splitV3Api/settingsApi'; +import { setLayoutEditMode } from '@/core/slices/mainpage'; +import { initialSettings } from '@/pages/settings/SettingsPage'; + +type Props = { + onClose: () => void; + show: boolean; +}; + +const Title = ({ onClose }: { onClose: () => void }) => { + const dispatch = useDispatch(); + + return ( +
+ Display Settings + +
+ ); +}; + +const DashboardSettingsModal = ({ onClose, show }: Props) => { + const dispatch = useDispatch(); + + const [newSettings, setNewSettings] = useState(initialSettings); + const [activeTab, setActiveTab] = useState('widgets'); + + const settingsQuery = useGetSettingsQuery(); + const settings = useMemo(() => settingsQuery?.data ?? initialSettings, [settingsQuery]); + const [patchSettings] = usePatchSettingsMutation(); + + useEffect(() => { + setNewSettings(settings); + }, [dispatch, settings]); + + const { + combineContinueWatching, + hideCollectionStats, + hideContinueWatching, + hideImportFolders, + hideMediaType, + hideNextUp, + hideQueueProcessor, + hideR18Content, + hideRecentlyImported, + hideRecommendedAnime, + hideShokoNews, + hideUnrecognizedFiles, + hideUpcomingAnime, + recentlyImportedEpisodesCount, + recentlyImportedSeriesCount, + shokoNewsPostsCount, + } = newSettings.WebUI_Settings.dashboard; + + const updateSetting = (key: keyof typeof settings.WebUI_Settings.dashboard, value: boolean | number) => { + const tempSettings = cloneDeep(newSettings); + if ( + key === 'recentlyImportedEpisodesCount' || key === 'recentlyImportedSeriesCount' || key === 'shokoNewsPostsCount' + ) { + tempSettings.WebUI_Settings.dashboard[key] = value as number; + } else { + tempSettings.WebUI_Settings.dashboard[key] = value as boolean; + } + setNewSettings(tempSettings); + }; + + const handleSave = async () => { + try { + await patchSettings({ oldSettings: settings, newSettings }).unwrap(); + onClose(); + } catch (error) { /* empty */ } + }; + + const handleCancel = () => { + setNewSettings(initialSettings); + onClose(); + }; + + return ( + } + size="sm" + className="w-[45rem]" + titleLeft + noPadding + > +
+
+
+
setActiveTab('widgets')} + > + Available Widgets +
+
setActiveTab('options')} + > + Display Options +
+
+
+ +
+ {activeTab === 'widgets' && ( +
+
+ updateSetting('hideQueueProcessor', event.target.checked)} + /> + updateSetting('hideUnrecognizedFiles', event.target.checked)} + /> + updateSetting('hideRecentlyImported', event.target.checked)} + /> + updateSetting('hideCollectionStats', event.target.checked)} + /> + updateSetting('hideMediaType', event.target.checked)} + /> + updateSetting('hideImportFolders', event.target.checked)} + /> + updateSetting('hideShokoNews', event.target.checked)} + /> + updateSetting('hideContinueWatching', event.target.checked)} + /> + updateSetting('hideNextUp', event.target.checked)} + /> + updateSetting('hideUpcomingAnime', event.target.checked)} + /> + updateSetting('hideRecommendedAnime', event.target.checked)} + /> +
+
+ )} + + {activeTab === 'options' && ( +
+ updateSetting('combineContinueWatching', event.target.checked)} + /> + updateSetting('hideR18Content', event.target.checked)} + /> +
+ Shoko News Posts + updateSetting('shokoNewsPostsCount', toNumber(event.target.value))} + className="w-12 px-2 py-0.5 text-center" + /> +
+
+ Recently Imported Episodes + updateSetting('recentlyImportedEpisodesCount', toNumber(event.target.value))} + className="w-12 px-2 py-0.5 text-center" + /> +
+
+ Recently Imported Series + updateSetting('recentlyImportedSeriesCount', toNumber(event.target.value))} + className="w-12 px-2 py-0.5 text-center" + /> +
+
+ )} +
+ + +
+
+
+
+ ); +}; + +export default DashboardSettingsModal; diff --git a/src/components/Input/Checkbox.tsx b/src/components/Input/Checkbox.tsx index 2088cd87c..698e7cdae 100644 --- a/src/components/Input/Checkbox.tsx +++ b/src/components/Input/Checkbox.tsx @@ -9,6 +9,7 @@ type Props = { id: string; label?: string; isChecked: boolean; + disabled?: boolean; intermediate?: boolean; className?: string; labelRight?: boolean; @@ -16,7 +17,9 @@ type Props = { onChange: React.ChangeEventHandler; }; -function Checkbox({ className, id, intermediate, isChecked, justify, label, labelRight, onChange }: Props) { +function Checkbox( + { className, disabled = false, id, intermediate, isChecked, justify, label, labelRight, onChange }: Props, +) { const [focused, setFocused] = useState(false); return ( @@ -27,13 +30,14 @@ function Checkbox({ className, id, intermediate, isChecked, justify, label, labe `${className}`, 'cursor-pointer flex items-center transition ease-in-out', focused && 'ring-2 ring-panel-icon-action ring-inset', + disabled && 'opacity-50 cursor-auto', ])} > !(networkStatus === NetworkAvailability.Internet || networkStatus === NetworkAvailability.PartialInternet), @@ -107,6 +109,7 @@ function TopNav() { const closeModalsAndSubmenus = () => { setShowActionsModal(false); + setShowDashboardSettingsModal(false); setShowUtilitiesMenu(false); }; @@ -219,14 +222,20 @@ function TopNav() { id="utilities" text="Utilities" icon={mdiTools} - onClick={() => setShowUtilitiesMenu(prev => !prev)} + onClick={() => { + closeModalsAndSubmenus(); + setShowUtilitiesMenu(prev => !prev); + }} isHighlighted={showUtilitiesMenu} /> setShowActionsModal(true)} + onClick={() => { + closeModalsAndSubmenus(); + setShowActionsModal(true); + }} isHighlighted={showActionsModal} /> {renderLinkMenuItem('log', 'Log', mdiTextBoxOutline)} @@ -239,10 +248,10 @@ function TopNav() { text="Dashboard Settings" icon={mdiTabletDashboard} onClick={() => { - dispatch(setLayoutEditMode(true)); closeModalsAndSubmenus(); + setShowDashboardSettingsModal(true); }} - isHighlighted={layoutEditMode} + isHighlighted={layoutEditMode || showDashboardSettingsModal} /> )} {((checkWebuiUpdate.isSuccess && semver.gt(checkWebuiUpdate.data.Version, VITE_APPVERSION)) @@ -312,6 +321,7 @@ function TopNav() { setShowActionsModal(false)} /> + setShowDashboardSettingsModal(false)} /> ); diff --git a/src/components/Panels/ShokoPanel.tsx b/src/components/Panels/ShokoPanel.tsx index 80b121055..79560c6f4 100644 --- a/src/components/Panels/ShokoPanel.tsx +++ b/src/components/Panels/ShokoPanel.tsx @@ -58,8 +58,8 @@ const ShokoPanel = ( > {isFetching ? ( -
- +
+
) : children} diff --git a/src/core/rtkQuery/splitV3Api/dashboardApi.ts b/src/core/rtkQuery/splitV3Api/dashboardApi.ts index c84e5dddf..8a360d8dc 100644 --- a/src/core/rtkQuery/splitV3Api/dashboardApi.ts +++ b/src/core/rtkQuery/splitV3Api/dashboardApi.ts @@ -1,6 +1,6 @@ import { splitV3Api } from '@/core/rtkQuery/splitV3Api'; -import type { PaginationType } from '@/core/types/api'; +import type { DashboardPaginationType } from '@/core/types/api'; import type { DashboardEpisodeDetailsType, DashboardSeriesSummaryType, @@ -31,31 +31,34 @@ const dashboardApi = splitV3Api.injectEndpoints({ }), // Get a list of recently added episodes (with additional details). - getDashboardRecentlyAddedEpisodes: build.query({ + getDashboardRecentlyAddedEpisodes: build.query({ query: params => ({ url: 'Dashboard/RecentlyAddedEpisodes', params }), providesTags: ['EpisodeUpdated', 'FileDeleted', 'FileMatched'], }), // Get a list of recently added series. - getDashboardRecentlyAddedSeries: build.query({ + getDashboardRecentlyAddedSeries: build.query({ query: params => ({ url: 'Dashboard/RecentlyAddedSeries', params }), providesTags: ['FileDeleted', 'FileMatched', 'SeriesUpdated'], }), // Get a list of the episodes to continue watching in recently watched order - getDashboardContinueWatchingEpisodes: build.query({ + getDashboardContinueWatchingEpisodes: build.query({ query: params => ({ url: 'Dashboard/ContinueWatchingEpisodes', params }), providesTags: ['EpisodeUpdated', 'FileDeleted', 'SeriesUpdated'], }), // Get the next episodes for series that currently don't have an active watch session for the user. - getDashboardNextUpEpisodes: build.query({ + getDashboardNextUpEpisodes: build.query({ query: params => ({ url: 'Dashboard/NextUpEpisodes', params }), providesTags: ['EpisodeUpdated', 'FileDeleted', 'FileMatched', 'SeriesUpdated'], }), // Get a list of the episodes to continue watching (soon-to-be) in recently watched order - getDashboardAniDBCalendar: build.query({ + getDashboardAniDBCalendar: build.query< + DashboardEpisodeDetailsType[], + { includeRestricted: boolean, showAll: boolean } + >({ query: params => ({ url: 'Dashboard/AniDBCalendar', params }), providesTags: ['SeriesUpdated'], }), diff --git a/src/core/types/api.ts b/src/core/types/api.ts index b8f6d619e..87f1b6c3f 100644 --- a/src/core/types/api.ts +++ b/src/core/types/api.ts @@ -21,6 +21,11 @@ export type PaginationType = { page?: number; }; +export type DashboardPaginationType = PaginationType & { + includeRestricted: boolean; + onlyUnwatched?: boolean; +}; + export type ListResultType = { Total: number; List: T; diff --git a/src/core/types/api/settings.ts b/src/core/types/api/settings.ts index fc10483cf..290a5bc72 100644 --- a/src/core/types/api/settings.ts +++ b/src/core/types/api/settings.ts @@ -199,6 +199,24 @@ export type WebUISettingsType = { showRandomPoster: boolean; }; }; + dashboard: { + hideQueueProcessor: boolean; + hideUnrecognizedFiles: boolean; + hideRecentlyImported: boolean; + hideCollectionStats: boolean; + hideMediaType: boolean; + hideImportFolders: boolean; + hideShokoNews: boolean; + hideContinueWatching: boolean; + hideNextUp: boolean; + hideUpcomingAnime: boolean; + hideRecommendedAnime: boolean; + combineContinueWatching: boolean; + hideR18Content: boolean; + shokoNewsPostsCount: number; + recentlyImportedEpisodesCount: number; + recentlyImportedSeriesCount: number; + }; }; export type SettingsType = Omit & { diff --git a/src/pages/collection/series/SeriesOverview.tsx b/src/pages/collection/series/SeriesOverview.tsx index bdc8231cd..c55e6c90d 100644 --- a/src/pages/collection/series/SeriesOverview.tsx +++ b/src/pages/collection/series/SeriesOverview.tsx @@ -52,7 +52,7 @@ const SeriesOverview = () => { return ( <>
-
+
settingsQuery.data ?? initialSettings, [settingsQuery]); const [patchSettings] = usePatchSettingsMutation(); + const { + combineContinueWatching, + hideCollectionStats, + hideContinueWatching, + hideImportFolders, + hideMediaType, + hideNextUp, + hideQueueProcessor, + hideRecentlyImported, + hideRecommendedAnime, + hideShokoNews, + hideUnrecognizedFiles, + hideUpcomingAnime, + } = settings.WebUI_Settings.dashboard; + const [currentLayout, setCurrentLayout] = useState( settings.WebUI_Settings.layout.dashboard ?? initialSettings.WebUI_Settings.layout.dashboard, ); @@ -101,6 +116,14 @@ function DashboardPage() { window.dispatchEvent(new Event('resize')); }, [currentLayout]); + if (!settingsQuery.isSuccess) { + return ( +
+ +
+ ); + } + return ( -
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
-
- -
+ {!hideQueueProcessor && ( +
+ +
+ )} + {!hideUnrecognizedFiles && ( +
+ +
+ )} + {!hideRecentlyImported && ( +
+ +
+ )} + {!hideCollectionStats && ( +
+ +
+ )} + {!hideMediaType && ( +
+ +
+ )} + {!hideImportFolders && ( +
+ +
+ )} + {!hideShokoNews && ( +
+ +
+ )} + {(!hideContinueWatching && !combineContinueWatching) && ( +
+ +
+ )} + {!hideNextUp && ( +
+ +
+ )} + {!hideUpcomingAnime && ( +
+ +
+ )} + {!hideRecommendedAnime && ( +
+ +
+ )}
); } diff --git a/src/pages/dashboard/components/DashboardTitleToggle.tsx b/src/pages/dashboard/components/DashboardTitleToggle.tsx index 8b9749b86..e58ad7c1a 100644 --- a/src/pages/dashboard/components/DashboardTitleToggle.tsx +++ b/src/pages/dashboard/components/DashboardTitleToggle.tsx @@ -1,8 +1,9 @@ import React from 'react'; import cx from 'classnames'; +import Button from '@/components/Input/Button'; + type Props = { - title: string; mainTitle: string; secondaryTitle: string; secondaryActive: boolean; @@ -14,33 +15,27 @@ const DashboardTitleToggle = ({ secondaryActive, secondaryTitle, setSecondaryActive, - title, }: Props) => ( -
- {title} - > - +
+ + ); export default DashboardTitleToggle; diff --git a/src/pages/dashboard/panels/ContinueWatching.tsx b/src/pages/dashboard/panels/ContinueWatching.tsx index cdbdd96ab..5946c15ba 100644 --- a/src/pages/dashboard/panels/ContinueWatching.tsx +++ b/src/pages/dashboard/panels/ContinueWatching.tsx @@ -1,16 +1,24 @@ -import React from 'react'; +import React, { useMemo } from 'react'; import { useSelector } from 'react-redux'; import ShokoPanel from '@/components/Panels/ShokoPanel'; import { useGetDashboardContinueWatchingEpisodesQuery } from '@/core/rtkQuery/splitV3Api/dashboardApi'; +import { useGetSettingsQuery } from '@/core/rtkQuery/splitV3Api/settingsApi'; import EpisodeDetails from '@/pages/dashboard/components/EpisodeDetails'; +import { initialSettings } from '@/pages/settings/SettingsPage'; import type { RootState } from '@/core/store'; const ContinueWatching = () => { const layoutEditMode = useSelector((state: RootState) => state.mainpage.layoutEditMode); - const items = useGetDashboardContinueWatchingEpisodesQuery({ pageSize: 20 }); + const settingsQuery = useGetSettingsQuery(); + const { hideR18Content } = useMemo( + () => settingsQuery.data?.WebUI_Settings.dashboard ?? initialSettings.WebUI_Settings.dashboard, + [settingsQuery], + ); + + const items = useGetDashboardContinueWatchingEpisodesQuery({ includeRestricted: !hideR18Content, pageSize: 20 }); return ( diff --git a/src/pages/dashboard/panels/NextUp.tsx b/src/pages/dashboard/panels/NextUp.tsx index 53ba145fa..fde55e12f 100644 --- a/src/pages/dashboard/panels/NextUp.tsx +++ b/src/pages/dashboard/panels/NextUp.tsx @@ -1,19 +1,35 @@ -import React from 'react'; +import React, { useMemo } from 'react'; import { useSelector } from 'react-redux'; import ShokoPanel from '@/components/Panels/ShokoPanel'; import { useGetDashboardNextUpEpisodesQuery } from '@/core/rtkQuery/splitV3Api/dashboardApi'; +import { useGetSettingsQuery } from '@/core/rtkQuery/splitV3Api/settingsApi'; import EpisodeDetails from '@/pages/dashboard/components/EpisodeDetails'; +import { initialSettings } from '@/pages/settings/SettingsPage'; import type { RootState } from '@/core/store'; const NextUp = () => { const layoutEditMode = useSelector((state: RootState) => state.mainpage.layoutEditMode); - const items = useGetDashboardNextUpEpisodesQuery({ pageSize: 20 }); + const settingsQuery = useGetSettingsQuery(); + const { combineContinueWatching, hideR18Content } = useMemo( + () => settingsQuery.data?.WebUI_Settings.dashboard ?? initialSettings.WebUI_Settings.dashboard, + [settingsQuery], + ); + + const items = useGetDashboardNextUpEpisodesQuery({ + includeRestricted: !hideR18Content, + onlyUnwatched: !combineContinueWatching, + pageSize: 20, + }); return ( - +
{(items.data?.length ?? 0) > 0 ? items.data?.map(item => ) diff --git a/src/pages/dashboard/panels/QueueProcessor.tsx b/src/pages/dashboard/panels/QueueProcessor.tsx index 97dda4f07..0af84b462 100644 --- a/src/pages/dashboard/panels/QueueProcessor.tsx +++ b/src/pages/dashboard/panels/QueueProcessor.tsx @@ -51,19 +51,19 @@ function QueueProcessor() {
{item.queueCount ?? 0}
-
+
{item?.status === 'Pausing' || item?.status === 'Paused' ? ( - ) : ( - )} -
@@ -82,33 +82,25 @@ function QueueProcessor() { }); return ( - <> +
+ {paused ? ( -
handleOperation('StartAll')} - title="Resume All" - > - -
+ ) : ( -
handleOperation('StopAll')} - title="Pause All" - > - -
+ )} - - - +
); }; diff --git a/src/pages/dashboard/panels/RecentlyImported.tsx b/src/pages/dashboard/panels/RecentlyImported.tsx index aee3a5a74..03a1913c8 100644 --- a/src/pages/dashboard/panels/RecentlyImported.tsx +++ b/src/pages/dashboard/panels/RecentlyImported.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useMemo, useState } from 'react'; import { useSelector } from 'react-redux'; import ShokoPanel from '@/components/Panels/ShokoPanel'; @@ -7,45 +7,59 @@ import { useGetDashboardRecentlyAddedEpisodesQuery, useGetDashboardRecentlyAddedSeriesQuery, } from '@/core/rtkQuery/splitV3Api/dashboardApi'; +import { useGetSettingsQuery } from '@/core/rtkQuery/splitV3Api/settingsApi'; import DashboardTitleToggle from '@/pages/dashboard/components/DashboardTitleToggle'; import EpisodeDetails from '@/pages/dashboard/components/EpisodeDetails'; import SeriesDetails from '@/pages/dashboard/components/SeriesDetails'; +import { initialSettings } from '@/pages/settings/SettingsPage'; import type { RootState } from '@/core/store'; const RecentlyImported = () => { const layoutEditMode = useSelector((state: RootState) => state.mainpage.layoutEditMode); + const settingsQuery = useGetSettingsQuery(); + const { hideR18Content, recentlyImportedEpisodesCount, recentlyImportedSeriesCount } = useMemo( + () => settingsQuery.data?.WebUI_Settings.dashboard ?? initialSettings.WebUI_Settings.dashboard, + [settingsQuery], + ); + const [showSeries, setShowSeries] = useState(false); - const series = useGetDashboardRecentlyAddedSeriesQuery({ pageSize: 20 }); - const episodes = useGetDashboardRecentlyAddedEpisodesQuery({ pageSize: 30 }); + const series = useGetDashboardRecentlyAddedSeriesQuery({ + includeRestricted: !hideR18Content, + pageSize: recentlyImportedSeriesCount, + }); + const episodes = useGetDashboardRecentlyAddedEpisodesQuery({ + includeRestricted: !hideR18Content, + pageSize: recentlyImportedEpisodesCount, + }); return ( } - editMode={layoutEditMode} - isFetching={showSeries ? series.isLoading : episodes.isLoading} > -
- +
+ {(episodes.data?.length ?? 0) > 0 ? episodes.data?.map(item => ( )) - :
No Recently Imported Episodes!
} + :
No Recently Imported Episodes!
}
- + {(series.data?.length ?? 0) > 0 ? series.data?.map(item => ) - :
No Recently Imported Series!
} + :
No Recently Imported Series!
}
diff --git a/src/pages/dashboard/panels/ShokoNews.tsx b/src/pages/dashboard/panels/ShokoNews.tsx index 3752dee3b..192f9b44e 100644 --- a/src/pages/dashboard/panels/ShokoNews.tsx +++ b/src/pages/dashboard/panels/ShokoNews.tsx @@ -1,11 +1,13 @@ -import React from 'react'; +import React, { useMemo } from 'react'; import { useSelector } from 'react-redux'; import { mdiOpenInNew } from '@mdi/js'; import { Icon } from '@mdi/react'; import ShokoPanel from '@/components/Panels/ShokoPanel'; import { useGetShokoNewsFeedQuery } from '@/core/rtkQuery/externalApi'; +import { useGetSettingsQuery } from '@/core/rtkQuery/splitV3Api/settingsApi'; import { dayjs } from '@/core/util'; +import { initialSettings } from '@/pages/settings/SettingsPage'; import type { RootState } from '@/core/store'; import type { DashboardNewsType } from '@/core/types/api/dashboard'; @@ -38,10 +40,16 @@ function ShokoNews() { const items = useGetShokoNewsFeedQuery(); + const settingsQuery = useGetSettingsQuery(); + const { shokoNewsPostsCount } = useMemo( + () => settingsQuery.data?.WebUI_Settings.dashboard ?? initialSettings.WebUI_Settings.dashboard, + [settingsQuery], + ); + return (
- {items.data?.slice(0, 5).map(item => )} + {items.data?.slice(0, shokoNewsPostsCount).map(item => )}
); diff --git a/src/pages/dashboard/panels/UpcomingAnime.tsx b/src/pages/dashboard/panels/UpcomingAnime.tsx index be7d49737..3efa4c777 100644 --- a/src/pages/dashboard/panels/UpcomingAnime.tsx +++ b/src/pages/dashboard/panels/UpcomingAnime.tsx @@ -1,11 +1,13 @@ -import React, { useState } from 'react'; +import React, { useMemo, useState } from 'react'; import { useSelector } from 'react-redux'; import ShokoPanel from '@/components/Panels/ShokoPanel'; import TransitionDiv from '@/components/TransitionDiv'; import { useGetDashboardAniDBCalendarQuery } from '@/core/rtkQuery/splitV3Api/dashboardApi'; +import { useGetSettingsQuery } from '@/core/rtkQuery/splitV3Api/settingsApi'; import DashboardTitleToggle from '@/pages/dashboard/components/DashboardTitleToggle'; import EpisodeDetails from '@/pages/dashboard/components/EpisodeDetails'; +import { initialSettings } from '@/pages/settings/SettingsPage'; import type { RootState } from '@/core/store'; @@ -13,22 +15,27 @@ const UpcomingAnime = () => { const layoutEditMode = useSelector((state: RootState) => state.mainpage.layoutEditMode); const [showAll, setShowAll] = useState(false); - const localItems = useGetDashboardAniDBCalendarQuery({ showAll: false }); - const items = useGetDashboardAniDBCalendarQuery({ showAll: true }); + + const settingsQuery = useGetSettingsQuery(); + const settings = useMemo(() => settingsQuery.data ?? initialSettings, [settingsQuery]); + const { hideR18Content } = settings.WebUI_Settings.dashboard; + + const localItems = useGetDashboardAniDBCalendarQuery({ showAll: false, includeRestricted: !hideR18Content }); + const items = useGetDashboardAniDBCalendarQuery({ showAll: true, includeRestricted: !hideR18Content }); return ( } - editMode={layoutEditMode} - isFetching={showAll ? items.isLoading : localItems.isLoading} >
diff --git a/src/pages/settings/SettingsPage.tsx b/src/pages/settings/SettingsPage.tsx index fc3811286..21636eb14 100644 --- a/src/pages/settings/SettingsPage.tsx +++ b/src/pages/settings/SettingsPage.tsx @@ -43,7 +43,7 @@ const initialLayout = { static: false, }, { - i: 'importBreakdown', + i: 'unrecognizedFiles', x: 6, y: 0, w: 6, @@ -221,7 +221,7 @@ const initialLayout = { static: false, }, { - i: 'importBreakdown', + i: 'unrecognizedFiles', x: 0, y: 65, w: 10, @@ -344,7 +344,7 @@ const initialLayout = { static: false, }, { - i: 'importBreakdown', + i: 'unrecognizedFiles', x: 0, y: 95, w: 6, @@ -426,6 +426,24 @@ export const initialSettings = { showRandomPoster: false, }, }, + dashboard: { + hideQueueProcessor: false, + hideUnrecognizedFiles: false, + hideRecentlyImported: false, + hideCollectionStats: false, + hideMediaType: false, + hideImportFolders: false, + hideShokoNews: false, + hideContinueWatching: false, + hideNextUp: false, + hideUpcomingAnime: false, + hideRecommendedAnime: false, + combineContinueWatching: false, + hideR18Content: true, + shokoNewsPostsCount: 5, + recentlyImportedEpisodesCount: 30, + recentlyImportedSeriesCount: 20, + }, }, FirstRun: false, Database: {