diff --git a/front/src/components/popup/TrackEditPopUp.tsx b/front/src/components/popup/MediaEditPopUp.tsx
similarity index 70%
rename from front/src/components/popup/TrackEditPopUp.tsx
rename to front/src/components/popup/MediaEditPopUp.tsx
index 14fbff9..1ec99ad 100644
--- a/front/src/components/popup/TrackEditPopUp.tsx
+++ b/front/src/components/popup/MediaEditPopUp.tsx
@@ -1,6 +1,6 @@
-import { useRef, useState } from 'react';
+import { useRef } from 'react';
-import { Button, Text, useDisclosure } from '@chakra-ui/react';
+import { Button, Tabs, Text, useDisclosure } from '@chakra-ui/react';
import { MdAdminPanelSettings, MdDeleteForever, MdEdit } from 'react-icons/md';
import { useNavigate, useParams } from 'react-router-dom';
@@ -9,15 +9,14 @@ import { FormGroupShow } from '@/components/form/FormGroup';
import { FormInput } from '@/components/form/FormInput';
import { FormNumber } from '@/components/form/FormNumber';
import { FormSelect } from '@/components/form/FormSelect';
-import { FormSelectMultiple } from '@/components/form/FormSelectMultiple';
import { FormTextarea } from '@/components/form/FormTextarea';
import { ConfirmPopUp } from '@/components/popup/ConfirmPopUp';
import {
- DialogBody,
- DialogContent,
- DialogFooter,
- DialogHeader,
- DialogRoot,
+ DialogBody,
+ DialogContent,
+ DialogFooter,
+ DialogHeader,
+ DialogRoot,
} from '@/components/ui/dialog';
import { useMediaService, useSpecificMedia } from '@/service/Media';
import { useOrderedSeasons } from '@/service/Season';
@@ -31,32 +30,31 @@ import { Formidable, useFormidable } from '../formidable';
export type MediaEditPopUpProps = {};
export const MediaEditPopUp = ({}: MediaEditPopUpProps) => {
- const { MediaId } = useParams();
- const MediaIdInt = isNullOrUndefined(MediaId)
+ const { mediaId } = useParams();
+ const mediaIdInt = isNullOrUndefined(mediaId)
? undefined
- : parseInt(MediaId, 10);
+ : parseInt(mediaId, 10);
const { session } = useServiceContext();
- const { dataTypes } = useOrderedTypes(undefined);
- const { dataSeries } = useOrderedSeries(undefined);
- const { dataSeasons } = useOrderedSeasons(undefined);
+ const { dataTypes } = useOrderedTypes();
+ const { dataSeries } = useOrderedSeries();
+ const { dataSeasons } = useOrderedSeasons();
const { store } = useMediaService();
- const { dataMedia } = useSpecificMedia(MediaIdInt);
- const [admin, setAdmin] = useState(false);
+ const { dataMedia } = useSpecificMedia(mediaIdInt);
const navigate = useNavigate();
const disclosure = useDisclosure();
const onClose = () => {
- navigate('../../', { relative: 'path' });
+ navigate('../../..', { relative: 'path' });
};
const onRemove = () => {
- if (isNullOrUndefined(MediaIdInt)) {
+ if (isNullOrUndefined(mediaIdInt)) {
return;
}
store.remove(
- MediaIdInt,
+ mediaIdInt,
MediaResource.remove({
restConfig: session.getRestConfig(),
params: {
- id: MediaIdInt,
+ id: mediaIdInt,
},
})
);
@@ -69,7 +67,7 @@ export const MediaEditPopUp = ({}: MediaEditPopUpProps) => {
deltaConfig: { omit: ['covers'] },
});
const onSave = async (dataDelta: MediaWrite) => {
- if (isNullOrUndefined(MediaIdInt)) {
+ if (isNullOrUndefined(mediaIdInt)) {
return;
}
console.log(`onSave = ${JSON.stringify(dataDelta, null, 2)}`);
@@ -78,7 +76,7 @@ export const MediaEditPopUp = ({}: MediaEditPopUpProps) => {
restConfig: session.getRestConfig(),
data: dataDelta,
params: {
- id: MediaIdInt,
+ id: mediaIdInt,
},
})
);
@@ -99,8 +97,48 @@ export const MediaEditPopUp = ({}: MediaEditPopUpProps) => {
{/* */}
- {admin && (
- <>
+
+
+
+
+ Edit
+
+
+
+ Admin
+
+
+ {/* ---------------------- Other Tabs --------------------------- */}
+
+
+
+
+
+
+
+
+ {/* ---------------------- Other Tabs --------------------------- */}
+
{dataMedia?.id}
@@ -123,62 +161,18 @@ export const MediaEditPopUp = ({}: MediaEditPopUpProps) => {
confirmTitle="Remove"
onConfirm={onRemove}
/>
- >
- )}
- {!admin && (
- <>
-
-
-
-
-
-
- >
- )}
+
+
-
diff --git a/front/src/components/select/SelectMultiple.tsx b/front/src/components/select/SelectMultiple.tsx
index b247a23..96e6926 100644
--- a/front/src/components/select/SelectMultiple.tsx
+++ b/front/src/components/select/SelectMultiple.tsx
@@ -57,7 +57,8 @@ export const SelectMultiple = ({
return [];
}
return transformedOption.filter((element) => {
- return values.includes(element[keyKey]);
+ console.log(`plop ${JSON.stringify(values, null, 2)}`);
+ return values?.includes(element[keyKey]);
});
}, [values, transformedOption]);
diff --git a/front/src/scene/home/AddPage.tsx b/front/src/scene/home/AddPage.tsx
index b640258..4e4c4ff 100644
--- a/front/src/scene/home/AddPage.tsx
+++ b/front/src/scene/home/AddPage.tsx
@@ -1,4 +1,4 @@
-import { useCallback, useState } from 'react';
+import { useCallback, useEffect, useState } from 'react';
import { Box, Button, Flex, Input, Table, Text } from '@chakra-ui/react';
import { LuTrash } from 'react-icons/lu';
@@ -12,9 +12,10 @@ import {
Series,
SeriesResource,
Type,
- TypeResource
+ TypeResource,
} from '@/back-api';
import { PageLayout } from '@/components/Layout/PageLayout';
+import { ParameterLayout } from '@/components/ParameterLayout';
import { TopBar } from '@/components/TopBar/TopBar';
import { FormSelect } from '@/components/form/FormSelect';
import { Formidable, useFormidable } from '@/components/formidable';
@@ -23,10 +24,20 @@ import {
NumberInputField,
NumberInputRoot,
} from '@/components/ui/number-input';
-import { useMediaService } from '@/service/Media';
-import { useOrderedSeries, useOrderedSeriesWithType, useSeriesService } from '@/service/Series';
+import {
+ MediaExpandSeason,
+ useFilteredMedia,
+ useMediaExpandSeason,
+ useMediaService,
+} from '@/service/Media';
+import {
+ useOrderedSeries,
+ useOrderedSeriesWithType,
+ useSeriesService,
+} from '@/service/Series';
import { useServiceContext } from '@/service/ServiceContext';
import { useOrderedTypes, useTypeService } from '@/service/Type';
+import { useDebounce, useDebouncedCallback } from '@/utils/debouncedCallback';
import { isNullOrUndefined } from '@/utils/validator';
export class ElementList {
@@ -40,7 +51,7 @@ export class ElementList {
export class FileParsedElement {
public isSended: boolean = false;
public nameDetected: boolean = false;
- public mediaIdDetected: boolean = false;
+ public episodeDetected: boolean = false;
public seasonId?: Season['id'] = undefined;
public seriesId?: Series['id'] = undefined;
constructor(
@@ -50,7 +61,7 @@ export class FileParsedElement {
public universe?: string,
public series?: string,
public season?: number,
- public mediaId?: number
+ public episode?: number
) {
console.log(`Unique element: ${uniqueId}`);
// nothing to do.
@@ -66,7 +77,11 @@ export class FileFailParsedElement {
// nothing to do.
}
}
-
+type InspectionType = {
+ episodeDetected: boolean;
+ nameDetected: boolean;
+ media: MediaExpandSeason;
+};
type FormInsertData = {
typeId?: number;
seriesId?: number;
@@ -81,26 +96,95 @@ export const AddPage = () => {
const [needSend, setNeedSend] = useState(false);
- // list of all files already registered in the bdd to compare with the current list of files.
- const [listFileInBdd, setListFileInBdd] = useState(
- undefined
- );
-
const { dataTypes } = useOrderedTypes();
const { dataSeries: dataSeriesFull } = useOrderedSeries();
const { store: storeType } = useTypeService();
const { store: storeSeries } = useSeriesService();
const { store: storeMedia } = useMediaService();
const { session } = useServiceContext();
-
const form = useFormidable({
configuration: {
enableModifyNotification: false,
enableReset: false,
},
});
+ // list of all files already registered in the bdd to compare with the current list of files.
+ const [listFileInBdd, setListFileInBdd] = useState<
+ InspectionType[] | undefined
+ >(undefined);
+ const formValuesSelectForCheck = useDebounce(form.values, 700);
+ const { medias } = useFilteredMedia(
+ formValuesSelectForCheck.typeId,
+ formValuesSelectForCheck.seriesId
+ );
+ const { mediasExpand } = useMediaExpandSeason(medias);
+ useEffect(() => {
+ handleCheck('');
+ }, [
+ formValuesSelectForCheck,
+ formValuesSelectForCheck.typeId,
+ mediasExpand,
+ parsedElement,
+ ]);
+
+ const handleCheck = useDebouncedCallback((_newValue) => {
+ console.log(`values has changes ... ${mediasExpand.length} medias`);
+ // find the good case: (ignore the universe that have no sense...)
+ if (formValuesSelectForCheck.typeId === undefined) {
+ setListFileInBdd(undefined);
+ return;
+ }
+ const out: InspectionType[] = [];
+ mediasExpand.forEach((media) => {
+ out.push({
+ episodeDetected: false,
+ nameDetected: false,
+ media,
+ });
+ });
+ // clear previous data:
+ out.forEach((elem) => {
+ elem.episodeDetected = false;
+ elem.nameDetected = false;
+ });
+ parsedElement.forEach((elem) => {
+ elem.episodeDetected = false;
+ elem.nameDetected = false;
+ });
+ // Detect the identical season + identical ID:
+ console.log(`check:'${JSON.stringify(parsedElement, null, 2)}'`);
+ out.forEach((checkElem) => {
+ parsedElement.forEach((parsedElem) => {
+ if (
+ `${parsedElem.season}` === `${checkElem.media?.season?.name}` &&
+ `${parsedElem.episode}` === `${checkElem.media?.episode}`
+ ) {
+ checkElem.episodeDetected = true;
+ parsedElem.episodeDetected = true;
+ }
+ if (
+ parsedElem.title?.length !== undefined &&
+ parsedElem.title?.length !== 0 &&
+ checkElem.media?.name?.length !== 0 &&
+ checkElem.media?.name?.length !== 0 &&
+ (parsedElem.title.startsWith(checkElem.media?.name) ||
+ checkElem.media?.name.startsWith(parsedElem.title))
+ ) {
+ checkElem.nameDetected = true;
+ parsedElem.nameDetected = true;
+ }
+ });
+ });
+ setListFileInBdd(
+ out.sort((a, b) => {
+ const aPriority = a.episodeDetected || a.nameDetected ? 1 : 0;
+ const bPriority = b.episodeDetected || b.nameDetected ? 1 : 0;
+ return bPriority - aPriority;
+ })
+ );
+ }, 1000);
// I think this does not work ...
- const { dataSeries } = useOrderedSeriesWithType(form.values["typeId"]);
+ const { dataSeries } = useOrderedSeriesWithType(form.values.typeId);
const updateNeedSend = () => {
if (parsedElement.length === 0) {
@@ -145,8 +229,8 @@ export const AddPage = () => {
updateNeedSend();
};
- const onMediaId = (data: FileParsedElement, value: any): void => {
- data.mediaId = value;
+ const onEpisode = (data: FileParsedElement, value: any): void => {
+ data.episode = value;
setParsedElement([...parsedElement]);
updateNeedSend();
};
@@ -163,15 +247,16 @@ export const AddPage = () => {
setSuggestedSeries(undefined);
//setSuggestedSeason(undefined);
};
-
- const regex = /^(?:(?[\w. -]+):)?((?[\w. -]+?)((-s| S)(?\d{1,5}))?(?:(-e|E)(?\d{1,5}))[- ])?\s*(?.+?)\.(webm|WEBM|Webm|mkv|MKV|Mkv)$/;
+
+ const regex =
+ /^(?:(?[\w. -]+):)?((?[\w. -]+?)((-s| S)(?\d{1,5}))?(?:(-e|E)(?\d{1,5}))[- ])?\s*(?.+?)\.(webm|WEBM|Webm|mkv|MKV|Mkv)$/;
const addFileWithMetaData = (file: File, id: number) => {
// parsedElement: FileParsedElement[] = [];
let universe: string | undefined = undefined;
let series: string | undefined = undefined;
let season: number | undefined = undefined;
- let mediaIdNumber: number | undefined = undefined;
+ let episodeNumber: number | undefined = undefined;
let title: string = '';
form.restoreValues();
@@ -180,21 +265,25 @@ export const AddPage = () => {
const match = file.name.match(regex);
if (match?.groups) {
- universe = match.groups.universe || undefined;
- series = match.groups.series ? match.groups.series.trim() : undefined;
- season = match.groups.season? parseInt(match.groups.season, 10) : undefined;
- mediaIdNumber = match.groups.episode ? parseInt(match.groups.episode, 10) : undefined;
- title = match.groups.title.trim();
+ universe = match.groups.universe || undefined;
+ series = match.groups.series ? match.groups.series.trim() : undefined;
+ season = match.groups.season
+ ? parseInt(match.groups.season, 10)
+ : undefined;
+ episodeNumber = match.groups.episode
+ ? parseInt(match.groups.episode, 10)
+ : undefined;
+ title = match.groups.title.trim();
} else {
- console.log("❌ not match :", file.name);
+ console.log('❌ not match :', file.name);
title = file.name.trim();
}
if (season && isNaN(season)) {
season = undefined;
}
- if (mediaIdNumber && isNaN(mediaIdNumber)) {
- mediaIdNumber = undefined;
+ if (episodeNumber && isNaN(episodeNumber)) {
+ episodeNumber = undefined;
}
// remove extension
title = title.replace(new RegExp('\\.(webm|WEBM|Webm|mkv|MKV|Mkv)'), '');
@@ -205,7 +294,7 @@ export const AddPage = () => {
universe,
series,
season,
- mediaIdNumber
+ episodeNumber
);
console.log(`==>${JSON.stringify(tmp, null, 2)}`);
@@ -316,10 +405,10 @@ export const AddPage = () => {
typeId: `${form.values['typeId']}`,
seriesId: `${form.values['seriesId']}`,
season: `${parsedElement[index].season}`,
- episode: `${parsedElement[index].mediaId}`,
+ episode: `${parsedElement[index].episode}`,
};
console.log(`data= ${JSON.stringify(data, null, 2)}`);
- console.error("Not_ implemented");
+ console.error('Not_ implemented');
storeMedia
.update(
MediaResource.uploadMedia({
@@ -384,7 +473,7 @@ export const AddPage = () => {
restConfig: session.getRestConfig(),
data: {
name: data,
- parentId: form.values["typeId"]
+ parentId: form.values['typeId'],
},
})
);
@@ -394,140 +483,160 @@ export const AddPage = () => {
<>
-
-
-
- format:
-
- The format of the media permit to automatic find meta-data:
- Universe:Series name-s05-e22-Title.webm/mkv
- Universe:Series name S05E22 Title.webm/mkv
- example: Stargate:SG1-s05-e22-Tolans.webm
-
+
+
+
+
+
+ format:
+
+ The format of the media permit to automatic find meta-data:
+
+ Universe:Series name-s05-e22-Title.webm/mkv
+ Universe:Series name S05E22 Title.webm/mkv
+ example: Stargate:SG1-s05-e22-Tolans.webm
+
+
+
+ Media:
+
+
-
- Media:
-
-
-
- {parsedElement && parsedElement.length !== 0 && (
-
- Meta-data:
-
-
+
+
+
-
-
-
-
- Season ID
-
-
- Media ID
-
- Title
- actions
-
-
-
- {parsedElement.map((data) => (
-
-
- {form.values["seriesId"] &&
- onSeasonId(data, e.value)}
- min={0}
- max={5000}
- backgroundColor={
- data.mediaIdDetected === true
- ? 'darkred'
- : undefined
- }
- >
-
-
- }
-
-
- {form.values["seriesId"] &&
- onMediaId(data, e.value)}
- min={0}
- max={5000}
- backgroundColor={
- data.mediaIdDetected === true
- ? 'darkred'
- : undefined
- }
- >
-
-
- }
-
-
- onTitle(data, e.target.value)}
- backgroundColor={
- data.title === '' ? 'darkred' : undefined
- }
- />
- {data.nameDetected === true && (
- <>
-
-
- ^^^This title already exist !!!
-
- >
- )}
-
-
- removeElementFromList(data, e.target)}
- >
- Remove
-
-
+ {parsedElement && parsedElement.length !== 0 && (
+
+
+
+
+
+
+
+
+
+
+
+ Season ID
+
+
+ Media ID
+
+
+ Title
+
+ actions
- ))}
-
-
-
+
+
+ {parsedElement.map((data) => (
+
+
+ {form.values['seriesId'] && (
+ onSeasonId(data, e.value)}
+ min={0}
+ max={5000}
+ backgroundColor={
+ data.episodeDetected === true
+ ? 'darkred'
+ : undefined
+ }
+ >
+
+
+ )}
+
+
+ {form.values['seriesId'] && (
+ onEpisode(data, e.value)}
+ min={0}
+ max={5000}
+ backgroundColor={
+ data.episodeDetected === true
+ ? 'darkred'
+ : undefined
+ }
+ >
+
+
+ )}
+
+
+ onTitle(data, e.target.value)}
+ backgroundColor={
+ data.title === ''
+ ? 'purple'
+ : data.nameDetected === true
+ ? 'darkred'
+ : undefined
+ }
+ />
+ {data.nameDetected === true && (
+ <>
+
+
+ ^^^This title already exist !!!
+
+ >
+ )}
+
+
+
+ removeElementFromList(data, e.target)
+ }
+ >
+ Remove
+
+
+
+ ))}
+
+
+
+
{
>
Upload
-
-
- )}
+
+
+
+ )}
- {listFileInBdd && (
-
-
-
- Media ID
- Title
- actions
-
-
-
- {listFileInBdd.map((data) => (
+ {listFileInBdd && (
+
+
+
+
+
-
-
- {data.MediaId}
-
-
-
-
- {data.title}
-
-
-
+ Media ID
+ Data ID
+ Season
+ Episode
+ Title
+ Date
+ Actions
- ))}
-
-
- )}
-
- {parsedFailedElement && (
- <>
+
+
+ {listFileInBdd.map((data) => (
+
+ ))}
+
+
+
+
+
+ )}
+ {parsedFailedElement && (
+
+
+
Rejected:
{
))}
- >
- )}
-
-
+
+
+
+ )}
+
+ {/* upload pop-in */}
{indexUpload !== undefined && (
{
>
);
};
+export const MediaDetectionDetail = ({ data }: { data: InspectionType }) => {
+ return (
+
+
+ {data.media.id}
+
+
+ {data.media.dataId.toUpperCase()}
+
+
+
+ {data.media.season?.name}
+
+
+
+
+ {data.media.episode}
+
+
+
+
+ {data.media.name}
+
+
+
+ {data.media.date}
+
+
+
+ );
+};
diff --git a/front/src/scene/onAir/OnAirPage.tsx b/front/src/scene/onAir/OnAirPage.tsx
index 0ad0e4c..066caf7 100644
--- a/front/src/scene/onAir/OnAirPage.tsx
+++ b/front/src/scene/onAir/OnAirPage.tsx
@@ -11,10 +11,10 @@ import { Route, Routes, useNavigate } from 'react-router-dom';
import { EmptyEnd } from '@/components/EmptyEnd';
import { PageLayout } from '@/components/Layout/PageLayout';
import { PageLayoutInfoCenter } from '@/components/Layout/PageLayoutInfoCenter';
+import { BUTTON_TOP_BAR_PROPERTY, TopBar } from '@/components/TopBar/TopBar';
import { DisplayMediaFullId } from '@/components/media/DisplayMediaFullId';
import { SeasonEditPopUp } from '@/components/popup/AlbumEditPopUp';
-import { MediaEditPopUp } from '@/components/popup/TrackEditPopUp';
-import { BUTTON_TOP_BAR_PROPERTY, TopBar } from '@/components/TopBar/TopBar';
+import { MediaEditPopUp } from '@/components/popup/MediaEditPopUp';
import { Button } from '@/components/ui/button';
import { useColorModeValue } from '@/components/ui/color-mode';
import { BASE_WRAP_SPACING } from '@/constants/genericSpacing';
diff --git a/front/src/scene/season/SeasonDetailPage.tsx b/front/src/scene/season/SeasonDetailPage.tsx
index 862a66d..930e369 100644
--- a/front/src/scene/season/SeasonDetailPage.tsx
+++ b/front/src/scene/season/SeasonDetailPage.tsx
@@ -7,12 +7,16 @@ import { Covers } from '@/components/Cover';
import { EmptyEnd } from '@/components/EmptyEnd';
import { PageLayout } from '@/components/Layout/PageLayout';
import { PageLayoutInfoCenter } from '@/components/Layout/PageLayoutInfoCenter';
-import { SeasonEditPopUp } from '@/components/popup/AlbumEditPopUp';
-import { MediaEditPopUp } from '@/components/popup/TrackEditPopUp';
import { BUTTON_TOP_BAR_PROPERTY, TopBar } from '@/components/TopBar/TopBar';
+import { SeasonEditPopUp } from '@/components/popup/AlbumEditPopUp';
+import { MediaEditPopUp } from '@/components/popup/MediaEditPopUp';
import { useColorModeValue } from '@/components/ui/color-mode';
import { BASE_WRAP_SPACING } from '@/constants/genericSpacing';
-import { useActivePlaylistService, useSeasonVideo, useSpecificSeason } from '@/service';
+import {
+ useActivePlaylistService,
+ useSeasonVideo,
+ useSpecificSeason,
+} from '@/service';
export const SeasonDetailPage = () => {
const { SeasonId } = useParams();
diff --git a/front/src/scene/sso/series/SeriesSeasonDetailPage.tsx b/front/src/scene/sso/series/SeriesSeasonDetailPage.tsx
index 9ee726e..9be8cf4 100644
--- a/front/src/scene/sso/series/SeriesSeasonDetailPage.tsx
+++ b/front/src/scene/sso/series/SeriesSeasonDetailPage.tsx
@@ -7,9 +7,9 @@ import { Covers } from '@/components/Cover';
import { EmptyEnd } from '@/components/EmptyEnd';
import { PageLayout } from '@/components/Layout/PageLayout';
import { PageLayoutInfoCenter } from '@/components/Layout/PageLayoutInfoCenter';
-import { SeasonEditPopUp } from '@/components/popup/AlbumEditPopUp';
-import { MediaEditPopUp } from '@/components/popup/TrackEditPopUp';
import { BUTTON_TOP_BAR_PROPERTY, TopBar } from '@/components/TopBar/TopBar';
+import { SeasonEditPopUp } from '@/components/popup/AlbumEditPopUp';
+import { MediaEditPopUp } from '@/components/popup/MediaEditPopUp';
import { useActivePlaylistService } from '@/service/ActivePlaylist';
import { useSeasonVideo, useSpecificSeason } from '@/service/Season';
import { useSpecificSeries } from '@/service/Series';
diff --git a/front/src/scene/type/TypesDetailPage.tsx b/front/src/scene/type/TypesDetailPage.tsx
index 7c02307..a9ccfef 100644
--- a/front/src/scene/type/TypesDetailPage.tsx
+++ b/front/src/scene/type/TypesDetailPage.tsx
@@ -11,7 +11,7 @@ import { BUTTON_TOP_BAR_PROPERTY, TopBar } from '@/components/TopBar/TopBar';
//import { useMediasOfAType } from '@/service/Media';
import { DisplayMediaFull } from '@/components/media/DisplayMediaFull';
import { TypeEditPopUp } from '@/components/popup/GenderEditPopUp';
-import { MediaEditPopUp } from '@/components/popup/TrackEditPopUp';
+import { MediaEditPopUp } from '@/components/popup/MediaEditPopUp';
import { DisplaySeries } from '@/components/series/DisplaySeries';
import { useColorModeValue } from '@/components/ui/color-mode';
import {
diff --git a/front/src/scene/type/TypesSeriesDetailPage.tsx b/front/src/scene/type/TypesSeriesDetailPage.tsx
index 4a41f6b..627ef75 100644
--- a/front/src/scene/type/TypesSeriesDetailPage.tsx
+++ b/front/src/scene/type/TypesSeriesDetailPage.tsx
@@ -11,7 +11,7 @@ import { BUTTON_TOP_BAR_PROPERTY, TopBar } from '@/components/TopBar/TopBar';
//import { useMediasOfAType } from '@/service/Media';
import { DisplayMediaFull } from '@/components/media/DisplayMediaFull';
import { TypeEditPopUp } from '@/components/popup/GenderEditPopUp';
-import { MediaEditPopUp } from '@/components/popup/TrackEditPopUp';
+import { MediaEditPopUp } from '@/components/popup/MediaEditPopUp';
import { DisplaySeason } from '@/components/season/DisplaySeason';
import { useColorModeValue } from '@/components/ui/color-mode';
import {
@@ -34,11 +34,11 @@ export const TypesSeriesDetailPage = () => {
const navigate = useNavigate();
const onSelectSeasonItem = (mediaId: number) => {
navigate(`/type/${typeId}/series/${seriesId}/season/${mediaId}`);
- }
+ };
const onSelectItem = (mediaId: number) => {
let currentPlay = 0;
const listMediaId: number[] = [];
- console.log(`select item:${mediaId}`);
+ console.log(`select item:${mediaId}`);
if (!videoWithType) {
console.log('Fail to get Type...');
return;
@@ -108,8 +108,8 @@ export const TypesSeriesDetailPage = () => {
>
{seasonOfSeriesId?.map((data) => (
{
/>
))}
-
-
+
+
{
>
{videoWithType?.map((data) => (
{
const { dataType } = useSpecificType(typeIdInt);
const { dataSeries } = useSpecificSeries(seriesIdInt);
const { dataSeason } = useSpecificSeason(seasonIdInt);
- const { videoWithType: videos } = useTypeSeriesSeasonGetVideo(typeIdInt, seriesIdInt, seasonIdInt);
+ const { videoWithType: videos } = useTypeSeriesSeasonGetVideo(
+ typeIdInt,
+ seriesIdInt,
+ seasonIdInt
+ );
const navigate = useNavigate();
const onSelectItem = (mediaId: number) => {
let currentPlay = 0;
@@ -107,7 +111,7 @@ export const TypesSeriesSeasonDetailPage = () => {
{videos?.map((data) => (
;
@@ -42,3 +45,46 @@ export const useSpecificMedia = (id: number | undefined) => {
return { isLoading: store.isLoading, dataMedia };
};
+export const useFilteredMedia = (typeId?: number, seriesId?: number) => {
+ const { store } = useMediaService();
+ const medias = useMemo(() => {
+ if (typeId === undefined) {
+ return [];
+ }
+ return DataTools.getsWhere(
+ store.data,
+ [
+ {
+ check: TypeCheck.EQUAL,
+ key: 'typeId',
+ value: typeId,
+ },
+ {
+ check: TypeCheck.EQUAL,
+ key: 'seriesId',
+ value: seriesId,
+ },
+ ],
+ ['name']
+ );
+ }, [store.data, typeId, seriesId]);
+ return { isLoading: store.isLoading, medias };
+};
+export type MediaExpandSeason = Media & {
+ season?: Season;
+};
+export const useMediaExpandSeason = (medias: Media[]) => {
+ const { store } = useSeasonService();
+ const mediasExpand = useMemo(() => {
+ const out: MediaExpandSeason[] = [];
+ medias.forEach((media) => {
+ if (media.seasonId === undefined) {
+ out.push(media);
+ }
+ const tmp = DataTools.get(store.data, media.seasonId, 'id');
+ out.push({ ...media, season: tmp });
+ });
+ return out;
+ }, [store.data, medias]);
+ return { isLoading: store.isLoading, mediasExpand };
+};
diff --git a/front/src/service/Series.ts b/front/src/service/Series.ts
index 5f39ee2..d3db21d 100644
--- a/front/src/service/Series.ts
+++ b/front/src/service/Series.ts
@@ -43,6 +43,9 @@ export const useOrderedSeries = (nameFilter?: string) => {
const { store } = useSeriesService();
const dataSeries = useMemo(() => {
let tmpData = store.data;
+ if (tmpData == undefined) {
+ return [];
+ }
if (!isNullOrUndefined(nameFilter)) {
tmpData = DataTools.getNameLike(tmpData, nameFilter);
}
@@ -60,7 +63,10 @@ export const useOrderedSeries = (nameFilter?: string) => {
}, [store.data, nameFilter]);
return { isLoading: store.isLoading, dataSeries };
};
-export const useOrderedSeriesWithType = (typeId?: Type["id"], nameFilter?: string) => {
+export const useOrderedSeriesWithType = (
+ typeId?: Type['id'],
+ nameFilter?: string
+) => {
const { store } = useSeriesService();
const dataSeries = useMemo(() => {
let tmpData = store.data;
@@ -70,6 +76,7 @@ export const useOrderedSeriesWithType = (typeId?: Type["id"], nameFilter?: strin
if (typeId === undefined) {
return [];
}
+ console.log('RRRRRRRRRRRRRRRRRRRRRRRegenarate ');
return DataTools.getsWhere(
tmpData,
[
diff --git a/front/src/service/Type.ts b/front/src/service/Type.ts
index 2534b0c..9c9e4a0 100644
--- a/front/src/service/Type.ts
+++ b/front/src/service/Type.ts
@@ -84,10 +84,10 @@ export const useTypeCountVideo = (id?: number) => {
return { isLoading: store.isLoading, countVideoWithType };
};
-export const useTypeGetVideo = (id?: number) => {
+export const useTypeGetVideo = (typeId?: number) => {
const { store } = useMediaService();
const videoWithType = useMemo(() => {
- if (id === undefined) {
+ if (typeId === undefined) {
return [];
}
return DataTools.getsWhere(
@@ -96,7 +96,7 @@ export const useTypeGetVideo = (id?: number) => {
{
check: TypeCheck.EQUAL,
key: 'typeId',
- value: id,
+ value: typeId,
},
{
check: TypeCheck.EQUAL,
@@ -111,7 +111,7 @@ export const useTypeGetVideo = (id?: number) => {
],
['name']
);
- }, [store.data, id]);
+ }, [store.data, typeId]);
return { isLoading: store.isLoading, videoWithType };
};
@@ -154,7 +154,11 @@ export const useTypeSeriesGetVideo = (idType?: number, idSeries?: number) => {
return { isLoading: store.isLoading, videoWithType };
};
-export const useTypeSeriesSeasonGetVideo = (idType?: number, idSeries?: number, idSeason?: number) => {
+export const useTypeSeriesSeasonGetVideo = (
+ idType?: number,
+ idSeries?: number,
+ idSeason?: number
+) => {
const { store } = useMediaService();
const videoWithType = useMemo(() => {
if (idType === undefined) {
diff --git a/front/src/utils/debouncedCallback.ts b/front/src/utils/debouncedCallback.ts
new file mode 100644
index 0000000..ea4a30b
--- /dev/null
+++ b/front/src/utils/debouncedCallback.ts
@@ -0,0 +1,39 @@
+import { useCallback, useEffect, useRef, useState } from 'react';
+
+export const useDebouncedCallback = (
+ callback: (...args: any[]) => void,
+ delay: number = 2000
+) => {
+ const timeoutRef = useRef(null);
+
+ const debouncedFunction = useCallback(
+ (...args: any[]) => {
+ // Cancel timeout if it previously exist
+ if (timeoutRef.current) {
+ clearTimeout(timeoutRef.current);
+ }
+
+ // start a new timer
+ timeoutRef.current = setTimeout(() => {
+ callback(...args);
+ }, delay);
+ },
+ [callback, delay]
+ );
+
+ return debouncedFunction;
+};
+
+export const useDebounce = (value: T, delay: number = 2000): T => {
+ const [debouncedValue, setDebouncedValue] = useState(value);
+
+ useEffect(() => {
+ const timer = setTimeout(() => {
+ setDebouncedValue(value);
+ }, delay);
+
+ return () => clearTimeout(timer);
+ }, [value, delay]);
+
+ return debouncedValue;
+};