Skip to content

Commit

Permalink
save view type in recently imported panel (#1076)
Browse files Browse the repository at this point in the history
  • Loading branch information
harshithmohan authored Sep 18, 2024
1 parent d3f88e5 commit 6f262c3
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 36 deletions.
11 changes: 10 additions & 1 deletion src/core/react-query/settings/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { merge } from 'lodash';
import semver from 'semver';

import { webuiSettingsPatches } from '@/core/patches';
Expand Down Expand Up @@ -308,6 +309,7 @@ export const initialSettings: SettingsType = {
shokoNewsPostsCount: 5,
recentlyImportedEpisodesCount: 30,
recentlyImportedSeriesCount: 20,
recentlyImportedView: 'episodes',
},
},
FirstRun: false,
Expand Down Expand Up @@ -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,
Expand All @@ -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;
}
Expand Down
1 change: 1 addition & 0 deletions src/core/types/api/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ export type WebUISettingsType = {
shokoNewsPostsCount: number;
recentlyImportedEpisodesCount: number;
recentlyImportedSeriesCount: number;
recentlyImportedView: 'episodes' | 'series';
};
};

Expand Down
24 changes: 1 addition & 23 deletions src/core/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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) => {
Expand Down
44 changes: 32 additions & 12 deletions src/pages/dashboard/panels/RecentlyImported.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -8,27 +9,30 @@ 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';
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,
Expand All @@ -39,27 +43,43 @@ const RecentlyImported = () => {
pageSize: recentlyImportedEpisodesCount,
});

const [currentTab, setCurrentTab] = useState<TabType>(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 (
<ShokoPanel
title="Recently Imported"
editMode={layoutEditMode}
isFetching={currentTab === 'Series' ? recentSeriesQuery.isPending : recentEpisodesQuery.isPending}
isFetching={viewMode === 'series' ? recentSeriesQuery.isPending : recentEpisodesQuery.isPending}
options={
<MultiStateButton activeState={currentTab} states={tabStates} onStateChange={handleTabChange} alternateColor />
<MultiStateButton
activeState={viewMode}
states={tabStates}
onStateChange={handleTabChange}
alternateColor
/>
}
>
<div className="shoko-scrollbar relative flex">
<TransitionDiv show={currentTab !== 'Series'} className="absolute flex w-full">
<TransitionDiv show={viewMode !== 'series'} className="absolute flex w-full">
{(recentEpisodesQuery.data?.length ?? 0) > 0
? recentEpisodesQuery.data?.map(item => (
<EpisodeDetails episode={item} key={`${item.IDs.ShokoEpisode}-${item.IDs.ShokoFile}`} />
))
: <div className="flex w-full justify-center font-semibold">No Recently Imported Episodes!</div>}
</TransitionDiv>
<TransitionDiv show={currentTab === 'Series'} className="absolute flex w-full">
<TransitionDiv show={viewMode === 'series'} className="absolute flex w-full">
{(recentSeriesQuery.data?.length ?? 0) > 0
? recentSeriesQuery.data?.map(item => <SeriesDetails series={item} key={item.IDs.ID} />)
: <div className="flex w-full justify-center font-semibold">No Recently Imported Series!</div>}
Expand Down

0 comments on commit 6f262c3

Please sign in to comment.