diff --git a/src/redux/endSlice.ts b/src/redux/endSlice.ts index 72eb9c300..21ff4c9cf 100644 --- a/src/redux/endSlice.ts +++ b/src/redux/endSlice.ts @@ -22,12 +22,14 @@ export const endSlice = createSlice({ state.value = action.payload.value; }, }, + selectors: { + selectIsEnd: state => state.end, + selectEndState: state => state.value, + }, }); export const { setEnd } = endSlice.actions; -// Export Selectors -export const selectIsEnd = (state: { endState: { end: end["end"]; }; }) => state.endState.end; -export const selectEndState = (state: { endState: { value: end["value"]; }; }) => state.endState.value; +export const { selectIsEnd, selectEndState } = endSlice.selectors; export default endSlice.reducer; diff --git a/src/redux/errorSlice.ts b/src/redux/errorSlice.ts index fbd1cedf6..21132872e 100644 --- a/src/redux/errorSlice.ts +++ b/src/redux/errorSlice.ts @@ -38,20 +38,23 @@ export const errorSlice = createSlice({ state.errorIcon = action.payload.errorIcon; }, }, + selectors: { + selectIsError: state => state.error, + selectErrorTitle: state => state.errorTitle, + selectErrorMessage: state => state.errorMessage, + selectErrorDetails: state => state.errorDetails, + selectErrorIcon: state => state.errorIcon, + }, }); export const { setError } = errorSlice.actions; -// Export Selectors -export const selectIsError = (state: { errorState: { error: error["error"]; }; }) => - state.errorState.error; -export const selectErrorTitle = (state: { errorState: { errorTitle: error["errorTitle"]; }; }) => - state.errorState.errorTitle; -export const selectErrorMessage = (state: { errorState: { errorMessage: error["errorMessage"]; }; }) => - state.errorState.errorMessage; -export const selectErrorDetails = (state: { errorState: { errorDetails: error["errorDetails"]; }; }) => - state.errorState.errorDetails; -export const selectErrorIcon = (state: { errorState: { errorIcon: error["errorIcon"]; }; }) => - state.errorState.errorIcon; +export const { + selectIsError, + selectErrorTitle, + selectErrorMessage, + selectErrorDetails, + selectErrorIcon, +} = errorSlice.selectors; export default errorSlice.reducer; diff --git a/src/redux/finishSlice.ts b/src/redux/finishSlice.ts index e5f2cfdff..fe41b0f00 100644 --- a/src/redux/finishSlice.ts +++ b/src/redux/finishSlice.ts @@ -24,15 +24,15 @@ export const finishSlice = createSlice({ state.pageNumber = action.payload; }, }, + selectors: { + selectFinishState: state => state.value, + selectPageNumber: state => state.pageNumber, + }, }); // Export Actions export const { setState, setPageNumber } = finishSlice.actions; -// Export Selectors -export const selectFinishState = (state: { finishState: { value: finish["value"]; }; }) => - state.finishState.value; -export const selectPageNumber = (state: { finishState: { pageNumber: finish["pageNumber"]; }; }) => - state.finishState.pageNumber; +export const { selectFinishState, selectPageNumber } = finishSlice.selectors; export default finishSlice.reducer; diff --git a/src/redux/mainMenuSlice.ts b/src/redux/mainMenuSlice.ts index ce8028c11..cd57edb79 100644 --- a/src/redux/mainMenuSlice.ts +++ b/src/redux/mainMenuSlice.ts @@ -21,14 +21,13 @@ export const mainMenuSlice = createSlice({ state.value = action.payload; }, }, + selectors: { + selectMainMenuState: state => state.value, + }, }); export const { setState } = mainMenuSlice.actions; -// The function below is called a selector and allows us to select a value from -// the state. Selectors can also be defined inline where they"re used instead of -// in the slice file. For example: `useSelector((state) => state.counter.value)` -export const selectMainMenuState = (state: { mainMenuState: { value: mainMenu["value"]; }; }) => - state.mainMenuState.value; +export const { selectMainMenuState } = mainMenuSlice.selectors; export default mainMenuSlice.reducer; diff --git a/src/redux/metadataSlice.ts b/src/redux/metadataSlice.ts index d1567e219..170434b48 100644 --- a/src/redux/metadataSlice.ts +++ b/src/redux/metadataSlice.ts @@ -143,35 +143,39 @@ const metadataSlice = createSlice({ state.postError = action.error.message; }); }, + selectors: { + selectCatalogs: state => state.catalogs, + selectHasChanges: state => state.hasChanges, + selectGetStatus: state => state.status, + selectGetError: state => state.error, + selectPostStatus: state => state.postStatus, + selectPostError: state => state.postError, + selectTitleFromEpisodeDc: state => { + for (const catalog of state.catalogs) { + if (catalog.flavor === "dublincore/episode") { + for (const field of catalog.fields) { + if (field.id === "title") { + return field.value; + } + } + } + } + + return undefined; + }, + }, }); export const { setFieldValue, setHasChanges, setFieldReadonly, resetPostRequestState } = metadataSlice.actions; -export const selectCatalogs = (state: { metadataState: { catalogs: metadata["catalogs"]; }; }) => - state.metadataState.catalogs; -export const selectHasChanges = (state: { metadataState: { hasChanges: metadata["hasChanges"]; }; }) => - state.metadataState.hasChanges; -export const selectGetStatus = (state: { metadataState: { status: httpRequestState["status"]; }; }) => - state.metadataState.status; -export const selectGetError = (state: { metadataState: { error: httpRequestState["error"]; }; }) => - state.metadataState.error; -export const selectPostStatus = (state: { metadataState: { postStatus: postRequestState["postStatus"]; }; }) => - state.metadataState.postStatus; -export const selectPostError = (state: { metadataState: { postError: postRequestState["postError"]; }; }) => - state.metadataState.postError; - -export const selectTitleFromEpisodeDc = (state: { metadataState: { catalogs: metadata["catalogs"]; }; }) => { - for (const catalog of state.metadataState.catalogs) { - if (catalog.flavor === "dublincore/episode") { - for (const field of catalog.fields) { - if (field.id === "title") { - return field.value; - } - } - } - } - - return undefined; -}; +export const { + selectCatalogs, + selectHasChanges, + selectGetStatus, + selectGetError, + selectPostStatus, + selectPostError, + selectTitleFromEpisodeDc, +} = metadataSlice.selectors; export default metadataSlice.reducer; diff --git a/src/redux/subtitleSlice.ts b/src/redux/subtitleSlice.ts index f718090f3..6281d2ce5 100644 --- a/src/redux/subtitleSlice.ts +++ b/src/redux/subtitleSlice.ts @@ -192,6 +192,25 @@ export const subtitleSlice = createSlice({ state.hasChanges = action.payload; }, }, + selectors: { + selectIsDisplayEditView: state => state.isDisplayEditView, + selectIsPlaying: state => state.isPlaying, + selectIsPlayPreview: state => state.isPlayPreview, + selectPreviewTriggered: state => state.previewTriggered, + selectCurrentlyAt: state => state.currentlyAt, + selectCurrentlyAtInSeconds: state => state.currentlyAt / 1000, + selectClickTriggered: state => state.clickTriggered, + selectFocusSegmentTriggered: state => state.focusSegmentTriggered, + selectFocusSegmentId: state => state.focusSegmentId, + selectFocusSegmentTriggered2: state => state.focusSegmentTriggered2, + // Hardcoding this value to achieve a desired size for the video player + // TODO: Don"t hardcode this value, instead make the video player component more flexible + selectAspectRatio: () => 50, + selectSubtitles: state => state.subtitles, + selectSelectedSubtitleId: state => state.selectedSubtitleId, + selectSelectedSubtitleById: state => state.subtitles[state.selectedSubtitleId], + selectHasChanges: state => state.hasChanges, + }, }); // Sort a subtitle array by startTime @@ -205,47 +224,23 @@ export const { setIsDisplayEditView, setIsPlaying, setIsPlayPreview, setPreviewT setSelectedSubtitleId, setFocusSegmentTriggered, setFocusSegmentId, setFocusSegmentTriggered2, setFocusToSegmentAboveId, setFocusToSegmentBelowId, setAspectRatio, setHasChanges } = subtitleSlice.actions; -// Export Selectors -export const selectIsDisplayEditView = (state: RootState) => - state.subtitleState.isDisplayEditView; -export const selectIsPlaying = (state: RootState) => - state.subtitleState.isPlaying; -export const selectIsPlayPreview = (state: { subtitleState: { isPlayPreview: subtitle["isPlayPreview"]; }; }) => - state.subtitleState.isPlayPreview; -export const selectPreviewTriggered = - (state: { subtitleState: { previewTriggered: subtitle["previewTriggered"]; }; }) => - state.subtitleState.previewTriggered; -export const selectCurrentlyAt = (state: RootState) => - state.subtitleState.currentlyAt; -export const selectCurrentlyAtInSeconds = (state: { subtitleState: { currentlyAt: subtitle["currentlyAt"]; }; }) => - state.subtitleState.currentlyAt / 1000; -export const selectClickTriggered = (state: { subtitleState: { clickTriggered: subtitle["clickTriggered"]; }; }) => - state.subtitleState.clickTriggered; -export const selectFocusSegmentTriggered = - (state: { subtitleState: { focusSegmentTriggered: subtitle["focusSegmentTriggered"]; }; }) => - state.subtitleState.focusSegmentTriggered; -export const selectFocusSegmentId = (state: { subtitleState: { focusSegmentId: subtitle["focusSegmentId"]; }; }) => - state.subtitleState.focusSegmentId; -export const selectFocusSegmentTriggered2 = - (state: { subtitleState: { focusSegmentTriggered2: subtitle["focusSegmentTriggered2"]; }; }) => - state.subtitleState.focusSegmentTriggered2; -// Hardcoding this value to achieve a desired size for the video player -// TODO: Don"t hardcode this value, instead make the video player component more flexible -export const selectAspectRatio = (_state: { subtitleState: { aspectRatios: subtitle["aspectRatios"]; }; }) => - 50; - -export const selectSubtitles = (state: { subtitleState: { subtitles: subtitle["subtitles"]; }; }) => - state.subtitleState.subtitles; -export const selectSelectedSubtitleId = - (state: { subtitleState: { selectedSubtitleId: subtitle["selectedSubtitleId"]; }; }) => - state.subtitleState.selectedSubtitleId; -export const selectSelectedSubtitleById = (state: { - subtitleState: - { subtitles: subtitle["subtitles"]; selectedSubtitleId: subtitle["selectedSubtitleId"]; }; -}) => - state.subtitleState.subtitles[state.subtitleState.selectedSubtitleId]; -export const selectHasChanges = (state: { subtitleState: { hasChanges: subtitle["hasChanges"]; }; }) => - state.subtitleState.hasChanges; +export const { + selectIsDisplayEditView, + selectIsPlaying, + selectIsPlayPreview, + selectPreviewTriggered, + selectCurrentlyAt, + selectCurrentlyAtInSeconds, + selectClickTriggered, + selectFocusSegmentTriggered, + selectFocusSegmentId, + selectFocusSegmentTriggered2, + selectAspectRatio, + selectSubtitles, + selectSelectedSubtitleId, + selectSelectedSubtitleById, + selectHasChanges, +} = subtitleSlice.selectors; /** * Alternative middleware to setCurrentlyAt. diff --git a/src/redux/videoSlice.ts b/src/redux/videoSlice.ts index 12f0bbfdd..bde240db1 100644 --- a/src/redux/videoSlice.ts +++ b/src/redux/videoSlice.ts @@ -268,6 +268,43 @@ const videoSlice = createSlice({ state.error = action.error.message; }); }, + selectors: { + // Selectors mainly pertaining to the video state + selectIsPlaying: state => state.isPlaying, + selectIsPlayPreview: state => state.isPlayPreview, + selectIsMuted: state => state.isMuted, + selectVolume: state => state.volume, + selectPreviewTriggered: state => state.previewTriggered, + selectClickTriggered: state => state.clickTriggered, + selectCurrentlyAt: state => state.currentlyAt, + selectCurrentlyAtInSeconds: state => state.currentlyAt / 1000, + selectSegments: state => state.segments, + selectActiveSegmentIndex: state => state.activeSegmentIndex, + selectIsCurrentSegmentAlive: state => !state.segments[state.activeSegmentIndex].deleted, + selectSelectedWorkflowId: state => state.selectedWorkflowId, + selectHasChanges: state => state.hasChanges, + selectWaveformImages: state => state.waveformImages, + selectOriginalThumbnails: state => state.originalThumbnails, + // Selectors mainly pertaining to the information fetched from Opencast + selectVideos: state => state.tracks.filter((track: Track) => track.video_stream.available === true), + selectVideoURL: state => state.videoURLs, + selectVideoCount: state => state.videoCount, + selectDuration: state => state.duration, + selectDurationInSeconds: state => state.duration / 1000, + selectTitle: state => state.title, + selectTracks: state => state.tracks, + selectWorkflows: state => state.workflows, + selectAspectRatio: state => calculateTotalAspectRatio(state.aspectRatios), + selectSubtitlesFromOpencast: state => state.subtitlesFromOpencast, + selectSubtitlesFromOpencastById: (state, id: string) => { + for (const cap of state.subtitlesFromOpencast) { + if (cap.id === id) { + return cap; + } + } + return undefined; + }, + }, }); /** @@ -391,76 +428,33 @@ export const { setTrackEnabled, setIsPlaying, setIsPlayPreview, setIsMuted, setV setPreviewTriggered, setClickTriggered } = videoSlice.actions; // Export selectors -// Selectors mainly pertaining to the video state -export const selectIsPlaying = (state: { videoState: { isPlaying: video["isPlaying"]; }; }) => - state.videoState.isPlaying; -export const selectIsPlayPreview = (state: { videoState: { isPlayPreview: video["isPlayPreview"]; }; }) => - state.videoState.isPlayPreview; -export const selectIsMuted = (state: { videoState: { isMuted: video["isMuted"]; }; }) => - state.videoState.isMuted; -export const selectVolume = (state: { videoState: { volume: video["volume"]; }; }) => - state.videoState.volume; -export const selectPreviewTriggered = (state: { videoState: { previewTriggered: video["previewTriggered"]; }; }) => - state.videoState.previewTriggered; -export const selectClickTriggered = (state: { videoState: { clickTriggered: video["clickTriggered"]; }; }) => - state.videoState.clickTriggered; -export const selectCurrentlyAt = (state: { videoState: { currentlyAt: video["currentlyAt"]; }; }) => - state.videoState.currentlyAt; -export const selectCurrentlyAtInSeconds = (state: { videoState: { currentlyAt: video["currentlyAt"]; }; }) => - state.videoState.currentlyAt / 1000; -export const selectSegments = (state: { videoState: { segments: video["segments"]; }; }) => - state.videoState.segments; -export const selectActiveSegmentIndex = - (state: { videoState: { activeSegmentIndex: video["activeSegmentIndex"]; }; }) => - state.videoState.activeSegmentIndex; -export const selectIsCurrentSegmentAlive = (state: { - videoState: - { segments: { [x: number]: { deleted: boolean; }; }; activeSegmentIndex: video["activeSegmentIndex"]; }; -}) => - !state.videoState.segments[state.videoState.activeSegmentIndex].deleted; -export const selectSelectedWorkflowId = (state: { - videoState: - { selectedWorkflowId: video["selectedWorkflowId"]; }; -}) => - state.videoState.selectedWorkflowId; -export const selectHasChanges = (state: { videoState: { hasChanges: video["hasChanges"]; }; }) => - state.videoState.hasChanges; -export const selectWaveformImages = (state: { videoState: { waveformImages: video["waveformImages"]; }; }) => - state.videoState.waveformImages; -export const selectOriginalThumbnails = - (state: { videoState: { originalThumbnails: video["originalThumbnails"]; }; }) => - state.videoState.originalThumbnails; - -// Selectors mainly pertaining to the information fetched from Opencast -export const selectVideos = (state: { videoState: { tracks: video["tracks"]; }; }) => - state.videoState.tracks.filter((track: Track) => track.video_stream.available === true); -export const selectVideoURL = (state: { videoState: { videoURLs: video["videoURLs"]; }; }) => - state.videoState.videoURLs; -export const selectVideoCount = (state: { videoState: { videoCount: video["videoCount"]; }; }) => - state.videoState.videoCount; -export const selectDuration = (state: { videoState: { duration: video["duration"]; }; }) => - state.videoState.duration; -export const selectDurationInSeconds = (state: { videoState: { duration: video["duration"]; }; }) => - state.videoState.duration / 1000; -export const selectTitle = (state: { videoState: { title: video["title"]; }; }) => - state.videoState.title; -export const selectTracks = (state: { videoState: { tracks: video["tracks"]; }; }) => - state.videoState.tracks; -export const selectWorkflows = (state: { videoState: { workflows: video["workflows"]; }; }) => - state.videoState.workflows; -export const selectAspectRatio = (state: { videoState: { aspectRatios: video["aspectRatios"]; }; }) => - calculateTotalAspectRatio(state.videoState.aspectRatios); -export const selectSubtitlesFromOpencast = - (state: { videoState: { subtitlesFromOpencast: video["subtitlesFromOpencast"]; }; }) => - state.videoState.subtitlesFromOpencast; -export const selectSubtitlesFromOpencastById = (id: string) => - (state: { videoState: { subtitlesFromOpencast: video["subtitlesFromOpencast"]; }; }) => { - for (const cap of state.videoState.subtitlesFromOpencast) { - if (cap.id === id) { - return cap; - } - } - return undefined; - }; +export const { + selectIsPlaying, + selectIsPlayPreview, + selectIsMuted, + selectVolume, + selectPreviewTriggered, + selectClickTriggered, + selectCurrentlyAt, + selectCurrentlyAtInSeconds, + selectSegments, + selectActiveSegmentIndex, + selectIsCurrentSegmentAlive, + selectSelectedWorkflowId, + selectHasChanges, + selectWaveformImages, + selectOriginalThumbnails, + selectVideos, + selectVideoURL, + selectVideoCount, + selectDuration, + selectDurationInSeconds, + selectTitle, + selectTracks, + selectWorkflows, + selectAspectRatio, + selectSubtitlesFromOpencast, + selectSubtitlesFromOpencastById, +} = videoSlice.selectors; export default videoSlice.reducer; diff --git a/src/redux/workflowPostAndProcessSlice.ts b/src/redux/workflowPostAndProcessSlice.ts index 5984eb8e0..92f352c60 100644 --- a/src/redux/workflowPostAndProcessSlice.ts +++ b/src/redux/workflowPostAndProcessSlice.ts @@ -52,12 +52,13 @@ const workflowPostAndProcessSlice = createSlice({ state.error = action.error.message; }); }, + selectors: { + selectStatus: state => state.status, + selectError: state => state.error, + }, }); -export const selectStatus = (state: { workflowPostAndProcessState: { status: httpRequestState["status"]; }; }) => - state.workflowPostAndProcessState.status; -export const selectError = (state: { workflowPostAndProcessState: { error: httpRequestState["error"]; }; }) => - state.workflowPostAndProcessState.error; +export const { selectStatus, selectError } = workflowPostAndProcessSlice.selectors; export default workflowPostAndProcessSlice.reducer; diff --git a/src/redux/workflowPostSlice.ts b/src/redux/workflowPostSlice.ts index 0e8dcee0e..a25f0ddcb 100644 --- a/src/redux/workflowPostSlice.ts +++ b/src/redux/workflowPostSlice.ts @@ -52,6 +52,10 @@ const workflowPostSlice = createSlice({ state.error = action.error.message; }); }, + selectors: { + selectStatus: state => state.status, + selectError: state => state.error, + }, }); interface segmentAPI { @@ -80,9 +84,6 @@ export const convertSegments = (segments: Segment[]) => { export const { resetPostRequestState } = workflowPostSlice.actions; -export const selectStatus = (state: { workflowPostState: { status: httpRequestState["status"]; }; }) => - state.workflowPostState.status; -export const selectError = (state: { workflowPostAndProcessState: { error: httpRequestState["error"]; }; }) => - state.workflowPostAndProcessState.error; +export const { selectStatus, selectError } = workflowPostSlice.selectors; export default workflowPostSlice.reducer;