From 6f262c3c7793a52235b0a65210d1922d8a27ff37 Mon Sep 17 00:00:00 2001 From: Harshith Mohan <26010946+harshithmohan@users.noreply.github.com> Date: Wed, 18 Sep 2024 15:14:10 +0530 Subject: [PATCH] save view type in recently imported panel (#1076) --- src/core/react-query/settings/helpers.ts | 11 ++++- src/core/types/api/settings.ts | 1 + src/core/util.ts | 24 +--------- .../dashboard/panels/RecentlyImported.tsx | 44 ++++++++++++++----- 4 files changed, 44 insertions(+), 36 deletions(-) diff --git a/src/core/react-query/settings/helpers.ts b/src/core/react-query/settings/helpers.ts index b962677c3..f34c3e2c3 100644 --- a/src/core/react-query/settings/helpers.ts +++ b/src/core/react-query/settings/helpers.ts @@ -1,3 +1,4 @@ +import { merge } from 'lodash'; import semver from 'semver'; import { webuiSettingsPatches } from '@/core/patches'; @@ -308,6 +309,7 @@ export const initialSettings: SettingsType = { shokoNewsPostsCount: 5, recentlyImportedEpisodesCount: 30, recentlyImportedSeriesCount: 20, + recentlyImportedView: 'episodes', }, }, FirstRun: false, @@ -427,6 +429,13 @@ export const transformSettings = (response: SettingsServerType) => { let webuiSettings = JSON.parse( response.WebUI_Settings === '' ? '{}' : response.WebUI_Settings, ) as WebUISettingsType; + + // Settings aren't fetched yet, transform is running on initialData + // Return without any operatations + if (webuiSettings.settingsRevision === 0) { + return { ...response, WebUI_Settings: webuiSettings }; + } + const currentSettingsRevision = webuiSettings.settingsRevision ?? 0; const versionedInitialSettings: WebUISettingsType = { ...initialSettings.WebUI_Settings, @@ -444,7 +453,7 @@ export const transformSettings = (response: SettingsServerType) => { .forEach((key) => { webuiSettings = webuiSettingsPatches[key](webuiSettings); }); - webuiSettings = Object.assign({}, initialSettings.WebUI_Settings, webuiSettings); + webuiSettings = merge({}, initialSettings.WebUI_Settings, webuiSettings); } catch { webuiSettings = versionedInitialSettings; } diff --git a/src/core/types/api/settings.ts b/src/core/types/api/settings.ts index ab98fd50c..2f62f4849 100644 --- a/src/core/types/api/settings.ts +++ b/src/core/types/api/settings.ts @@ -431,6 +431,7 @@ export type WebUISettingsType = { shokoNewsPostsCount: number; recentlyImportedEpisodesCount: number; recentlyImportedSeriesCount: number; + recentlyImportedView: 'episodes' | 'series'; }; }; diff --git a/src/core/util.ts b/src/core/util.ts index c7f3452b3..9aedf7c18 100644 --- a/src/core/util.ts +++ b/src/core/util.ts @@ -5,7 +5,7 @@ import calendar from 'dayjs/plugin/calendar'; import durationPlugin from 'dayjs/plugin/duration'; import formatThousands from 'format-thousands'; import { enableMapSet } from 'immer'; -import { isObject, toNumber } from 'lodash'; +import { toNumber } from 'lodash'; import semver from 'semver'; import toast from '@/components/Toast'; @@ -42,28 +42,6 @@ export const parseServerVersion = (version: string) => { export const getParsedSupportedServerVersion = () => parseServerVersion(minimumSupportedServerVersion)!; -export function mergeDeep(...objects: object[]) { - return objects.reduce((prev, obj) => { - Object.keys(obj).forEach((key) => { - const pVal: unknown = prev[key]; - const oVal: unknown = obj[key]; - - if (Array.isArray(pVal) && Array.isArray(oVal)) { - // eslint-disable-next-line no-param-reassign - prev[key] = Array.from(new Set(pVal.concat(...oVal as []))); - } else if (isObject(pVal) && isObject(oVal)) { - // eslint-disable-next-line no-param-reassign - prev[key] = mergeDeep(pVal, oVal); - } else { - // eslint-disable-next-line no-param-reassign - prev[key] = oVal; - } - }); - - return prev; - }, {}); -} - export const formatThousand = (num: number) => formatThousands(num, ','); export const copyToClipboard = async (text: string, entityName?: string) => { diff --git a/src/pages/dashboard/panels/RecentlyImported.tsx b/src/pages/dashboard/panels/RecentlyImported.tsx index 07ac3e5ed..4242f5053 100644 --- a/src/pages/dashboard/panels/RecentlyImported.tsx +++ b/src/pages/dashboard/panels/RecentlyImported.tsx @@ -1,5 +1,6 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import { useSelector } from 'react-redux'; +import { produce } from 'immer'; import MultiStateButton from '@/components/Input/MultiStateButton'; import ShokoPanel from '@/components/Panels/ShokoPanel'; @@ -8,6 +9,7 @@ import { useDashboardRecentlyAddedEpisodesQuery, useDashboardRecentlyAddedSeriesQuery, } from '@/core/react-query/dashboard/queries'; +import { usePatchSettingsMutation } from '@/core/react-query/settings/mutations'; import { useSettingsQuery } from '@/core/react-query/settings/queries'; import useEventCallback from '@/hooks/useEventCallback'; import EpisodeDetails from '@/pages/dashboard/components/EpisodeDetails'; @@ -15,20 +17,22 @@ import SeriesDetails from '@/pages/dashboard/components/SeriesDetails'; import type { RootState } from '@/core/store'; -type TabType = 'Series' | 'Episodes'; -const tabStates: { label?: string, value: TabType }[] = [ - { value: 'Episodes' }, - { value: 'Series' }, +const tabStates: { label?: string, value: string }[] = [ + { label: 'Episodes', value: 'episodes' }, + { label: 'Series', value: 'series' }, ]; const RecentlyImported = () => { const layoutEditMode = useSelector((state: RootState) => state.mainpage.layoutEditMode); + const settings = useSettingsQuery().data; const { hideR18Content, recentlyImportedEpisodesCount, recentlyImportedSeriesCount, - } = useSettingsQuery().data.WebUI_Settings.dashboard; + recentlyImportedView, + } = settings.WebUI_Settings.dashboard; + const { mutate: patchSettings } = usePatchSettingsMutation(); const recentSeriesQuery = useDashboardRecentlyAddedSeriesQuery({ includeRestricted: !hideR18Content, @@ -39,27 +43,43 @@ const RecentlyImported = () => { pageSize: recentlyImportedEpisodesCount, }); - const [currentTab, setCurrentTab] = useState(tabStates[0].value); - const handleTabChange = useEventCallback((newTab: TabType) => setCurrentTab(newTab)); + const [viewMode, setViewMode] = useState<'episodes' | 'series'>('episodes'); + + useEffect(() => { + setViewMode(recentlyImportedView); + }, [recentlyImportedView]); + + const handleTabChange = useEventCallback((newTab: 'episodes' | 'series') => { + setViewMode(newTab); + const newSettings = produce(settings, (draftState) => { + draftState.WebUI_Settings.dashboard.recentlyImportedView = newTab; + }); + patchSettings({ newSettings }); + }); return ( + } >
- + {(recentEpisodesQuery.data?.length ?? 0) > 0 ? recentEpisodesQuery.data?.map(item => ( )) :
No Recently Imported Episodes!
}
- + {(recentSeriesQuery.data?.length ?? 0) > 0 ? recentSeriesQuery.data?.map(item => ) :
No Recently Imported Series!
}