diff --git a/src/components/Panels/ShokoPanel.tsx b/src/components/Panels/ShokoPanel.tsx
index 52fc54cae..95c7b2338 100644
--- a/src/components/Panels/ShokoPanel.tsx
+++ b/src/components/Panels/ShokoPanel.tsx
@@ -1,4 +1,6 @@
import React, { ReactNode } from 'react';
+import { Icon } from '@mdi/react';
+import { mdiLoading } from '@mdi/js';
type Props = {
title: string;
@@ -9,7 +11,7 @@ type Props = {
titleTabs?: ReactNode;
};
-const ShokoPanel = ({ className, title, options, children, titleTabs }: Props) => (
+const ShokoPanel = ({ className, title, options, children, titleTabs, isFetching }: Props) => (
{title}{titleTabs}
@@ -22,8 +24,8 @@ const ShokoPanel = ({ className, title, options, children, titleTabs }: Props) =
-
- {children}
+
+ {isFetching ?
: children}
);
diff --git a/src/core/sagas/dashboard.ts b/src/core/sagas/dashboard.ts
index 5d5f2fd46..e090875cd 100644
--- a/src/core/sagas/dashboard.ts
+++ b/src/core/sagas/dashboard.ts
@@ -5,6 +5,7 @@ import ApiDashboard from '../api/v3/dashboard';
import {
setFetched,
+ unsetFetched,
setSeriesSummary,
setStats,
setRecentEpisodes,
@@ -71,9 +72,11 @@ function* getDashboardContinueWatching() {
}
yield put(setContinueWatching(resultJson.data));
+ yield put(setFetched('continueWatching'));
}
function* getDashboardUpcomingAnime(action: PayloadAction) {
+ yield put(unsetFetched('upcomingAnime'));
const resultJson = yield call(ApiDashboard.getDashboardAniDBCalendar, action.payload);
if (resultJson.error) {
toast.error(resultJson.message);
@@ -81,6 +84,7 @@ function* getDashboardUpcomingAnime(action: PayloadAction) {
}
yield put(setUpcomingAnime(resultJson.data));
+ yield put(setFetched('upcomingAnime'));
}
export default {
diff --git a/src/core/sagas/mainpage.ts b/src/core/sagas/mainpage.ts
index 9a277b04d..2dc34f456 100644
--- a/src/core/sagas/mainpage.ts
+++ b/src/core/sagas/mainpage.ts
@@ -31,7 +31,6 @@ function* eventMainPageLoad() {
yield call(SagaImportFolder.getImportFolders),
yield call(SagaDashboard.getDashboardRecentlyAddedEpisodes),
yield call(SagaDashboard.getDashboardRecentlyAddedSeries),
- yield call(SagaFile.getRecentFiles),
yield call(SagaFile.getUnrecognizedFiles),
yield call(SagaDashboard.getDashboardContinueWatching),
yield call(SagaDashboard.getDashboardUpcomingAnime, { type: Events.DASHBOARD_UPCOMING_ANIME, payload: false }),
diff --git a/src/pages/dashboard/panels/ContinueWatching.tsx b/src/pages/dashboard/panels/ContinueWatching.tsx
index e5c7908d9..2324f3a3a 100644
--- a/src/pages/dashboard/panels/ContinueWatching.tsx
+++ b/src/pages/dashboard/panels/ContinueWatching.tsx
@@ -6,6 +6,7 @@ import { DashboardEpisodeDetailsType } from '../../../core/types/api/dashboard';
const ContinueWatching = () => {
const items = useSelector((state: RootState) => state.mainpage.continueWatching);
+ const hasFetched = useSelector((state: RootState) => state.mainpage.fetched.continueWatching);
const renderDetails = (item: DashboardEpisodeDetailsType ) => {
@@ -17,7 +18,7 @@ const ContinueWatching = () => {
};
return (
-
+
{items.map(item => renderDetails(item))}
);
diff --git a/src/pages/dashboard/panels/ImportBreakdown.tsx b/src/pages/dashboard/panels/ImportBreakdown.tsx
index 7a095c991..4846bdaf0 100644
--- a/src/pages/dashboard/panels/ImportBreakdown.tsx
+++ b/src/pages/dashboard/panels/ImportBreakdown.tsx
@@ -1,46 +1,18 @@
-import React, { useState } from 'react';
+import React from 'react';
import { useSelector } from 'react-redux';
-import cx from 'classnames';
import { RootState } from '../../../core/store';
import ShokoPanel from '../../../components/Panels/ShokoPanel';
-import Button from '../../../components/Input/Button';
-import ImportedTab from './ImportBreakdownTabs/ImportedTab';
import UnrecognizedTab from './ImportBreakdownTabs/UnrecognizedTab';
function ImportBreakdown() {
- const hasFetchedRecents = useSelector((state: RootState) => state.mainpage.fetched.recentFiles);
const hasFetchedUnrecognized = useSelector(
(state: RootState) => state.mainpage.fetched.unrecognizedFiles,
);
- const [activeTab, setActiveTab] = useState('unrecognized');
-
- const renderOptions = () => (
-
-
-
-
- );
-
- const renderContent = () => {
- switch (activeTab) {
- case 'imported':
- return ;
- case 'unrecognized':
- return ;
- default:
- return ;
- }
- };
-
return (
-
- {renderContent()}
+
+
);
}
diff --git a/src/pages/dashboard/panels/ImportBreakdownTabs/ImportedTab.tsx b/src/pages/dashboard/panels/ImportBreakdownTabs/ImportedTab.tsx
deleted file mode 100644
index bb511ceb2..000000000
--- a/src/pages/dashboard/panels/ImportBreakdownTabs/ImportedTab.tsx
+++ /dev/null
@@ -1,160 +0,0 @@
-import React, { useEffect, useState } from 'react';
-import { useDispatch, useSelector } from 'react-redux';
-import { forEach, orderBy } from 'lodash';
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { faCaretDown, faCaretUp, faCircleNotch } from '@fortawesome/free-solid-svg-icons';
-import prettyBytes from 'pretty-bytes';
-import moment from 'moment';
-import cx from 'classnames';
-
-import { RootState } from '../../../../core/store';
-import Events from '../../../../core/events';
-import Button from '../../../../components/Input/Button';
-
-import type { FileDetailedType } from '../../../../core/types/api/file';
-import TransitionDiv from '../../../../components/TransitionDiv';
-
-const epTypes = {
- Normal: 'E',
- Special: 'S',
- Parody: 'P',
- ThemeSong: 'C',
- Trailer: 'T',
- Other: 'O',
- Unknown: 'X',
-};
-
-function ImportedTab() {
- const dispatch = useDispatch();
-
- const items = useSelector((state: RootState) => state.mainpage.recentFiles);
- const recentFileDetails = useSelector((state: RootState) => state.mainpage.recentFileDetails);
-
- const [expandedItems, setExpandedItems] = useState({} as { [ID: number]: boolean });
-
- useEffect(() => {
- forEach(items, (item) => {
- expandedItems[item.ID] = false;
- });
-
- setExpandedItems(expandedItems);
- });
-
- const getDetails = (fileId: number, seriesId: number, episodeId: number) => dispatch(
- { type: Events.MAINPAGE_RECENT_FILE_DETAILS, payload: { fileId, seriesId, episodeId } },
- );
-
- const handleExpand = (item: FileDetailedType) => {
- expandedItems[item.ID] = !expandedItems[item.ID];
-
- const { SeriesIDs } = item;
- getDetails(item.ID, SeriesIDs[0].SeriesID.ID, SeriesIDs[0].EpisodeIDs[0].ID);
-
- setExpandedItems(expandedItems);
- };
-
- const getFileInfo = (
- resolution = 'Unknown',
- source = 'Unknown',
- audioLanguages: Array = [],
- subtitleLanguages: Array = [],
- videoCodec = 'Unknown',
- ) => {
- let info = `${resolution} | ${videoCodec} | ${source.toUpperCase()} | `;
- if (audioLanguages.length > 2) info += 'Multi Audio';
- else if (audioLanguages.length === 2) info += 'Dual Audio';
- else if (subtitleLanguages[0] !== 'none') info += 'Subbed';
- else info += 'Raw';
-
- return info;
- };
-
- const renderDate = (item: FileDetailedType) => (
-
- {moment(item.Created).format('yyyy-MM-DD')} / {moment(item.Created).format('hh:mm A')}
-
-
- );
-
- const renderName = (idx: number, serverPath: string) => (
- {serverPath}
- );
-
- const renderDetails = (item: FileDetailedType) => {
- const fileDetails = recentFileDetails[item.ID];
- const { fetched, details } = fileDetails ?? {};
-
- return (
-
- {
- expandedItems[item.ID] && (!fetched
- ? (
-
-
-
- )
- : (
-
-
- Series
- {details.SeriesName ?? 'Unknown'}
-
-
- Episode
- {`${(epTypes[details.EpisodeType ?? 'Unknown']) + details.EpisodeNumber}: ${details.EpisodeName ?? 'Unknown'}`}
-
-
- Group
- {details.ReleaseGroup ?? 'Unknown'}
-
-
- Size
- {prettyBytes(item.Size, { binary: true })}
-
-
- Video Info
- {getFileInfo(
- item.RoundedStandardResolution,
- details.Source,
- details.AudioLanguages,
- details.SubtitleLanguages,
- details.VideoCodec,
- )}
-
-
- )
- )
- }
-
- );
- };
-
- const sortedItems = orderBy(items, ['ID'], ['desc']);
- const files: Array = [];
-
- forEach(sortedItems, (item) => {
- if (item?.SeriesIDs && item?.Locations && item?.Locations?.length !== 0) {
- files.push(renderDate(item));
- files.push(renderName(item.ID, item.Locations[0].RelativePath));
- files.push(renderDetails(item));
- }
- });
-
- if (files.length === 0) {
- return (No imported files!
);
- }
-
- return ({files});
-}
-
-export default ImportedTab;
diff --git a/src/pages/dashboard/panels/ImportFolders.tsx b/src/pages/dashboard/panels/ImportFolders.tsx
index 6f8b25e9b..009598ed0 100644
--- a/src/pages/dashboard/panels/ImportFolders.tsx
+++ b/src/pages/dashboard/panels/ImportFolders.tsx
@@ -68,10 +68,8 @@ function ImportFolders() {
};
const renderOptions = () => (
-
-