diff --git a/frontend/src/@redux/actions/movie.ts b/frontend/src/@redux/actions/movie.ts index b76752cdc..ce3797143 100644 --- a/frontend/src/@redux/actions/movie.ts +++ b/frontend/src/@redux/actions/movie.ts @@ -1,8 +1,10 @@ +import { createAction } from "redux-actions"; import { createDeleteAction } from "../../@socketio/reducer"; import { MoviesApi } from "../../apis"; import { MOVIES_DELETE_ITEMS, MOVIES_DELETE_WANTED_ITEMS, + MOVIES_MARK_WANTED_LIST_DIRTY, MOVIES_UPDATE_BLACKLIST, MOVIES_UPDATE_HISTORY_LIST, MOVIES_UPDATE_LIST, @@ -26,6 +28,10 @@ export const movieDeleteWantedItems = createDeleteAction( MOVIES_DELETE_WANTED_ITEMS ); +export const movieMarkWantedListDirty = createAction( + MOVIES_MARK_WANTED_LIST_DIRTY +); + export const movieUpdateWantedByRange = createAsyncAction( MOVIES_UPDATE_WANTED_LIST, (start: number, length: number) => MoviesApi.wanted(start, length) diff --git a/frontend/src/@redux/actions/series.ts b/frontend/src/@redux/actions/series.ts index c53277469..9b7caef74 100644 --- a/frontend/src/@redux/actions/series.ts +++ b/frontend/src/@redux/actions/series.ts @@ -1,9 +1,11 @@ +import { createAction } from "redux-actions"; import { createDeleteAction } from "../../@socketio/reducer"; import { EpisodesApi, SeriesApi } from "../../apis"; import { SERIES_DELETE_EPISODES, SERIES_DELETE_ITEMS, SERIES_DELETE_WANTED_ITEMS, + SERIES_MARK_WANTED_LIST_DIRTY, SERIES_UPDATE_BLACKLIST, SERIES_UPDATE_EPISODE_LIST, SERIES_UPDATE_HISTORY_LIST, @@ -21,6 +23,10 @@ export const seriesDeleteWantedItems = createDeleteAction( SERIES_DELETE_WANTED_ITEMS ); +export const seriesMarkWantedListDirty = createAction( + SERIES_MARK_WANTED_LIST_DIRTY +); + export const seriesUpdateWantedByRange = createAsyncAction( SERIES_UPDATE_WANTED_LIST, (start: number, length: number) => EpisodesApi.wanted(start, length) diff --git a/frontend/src/@redux/constants/index.ts b/frontend/src/@redux/constants/index.ts index a76476b1b..b675297a5 100644 --- a/frontend/src/@redux/constants/index.ts +++ b/frontend/src/@redux/constants/index.ts @@ -15,6 +15,7 @@ export const SYSTEM_UPDATE_PROVIDERS = "SYSTEM_UPDATE_PROVIDERS"; // Series action export const SERIES_UPDATE_WANTED_LIST = "UPDATE_SERIES_WANTED_LIST"; export const SERIES_DELETE_WANTED_ITEMS = "SERIES_DELETE_WANTED_ITEMS"; +export const SERIES_MARK_WANTED_LIST_DIRTY = "SERIES_MARK_WANTED_LIST_DIRTY"; export const SERIES_UPDATE_EPISODE_LIST = "UPDATE_SERIES_EPISODE_LIST"; export const SERIES_DELETE_EPISODES = "SERIES_DELETE_EPISODES"; export const SERIES_UPDATE_HISTORY_LIST = "UPDATE_SERIES_HISTORY_LIST"; @@ -25,6 +26,7 @@ export const SERIES_UPDATE_BLACKLIST = "UPDATE_SERIES_BLACKLIST"; // Movie action export const MOVIES_UPDATE_LIST = "UPDATE_MOVIE_LIST"; export const MOVIES_DELETE_ITEMS = "MOVIES_DELETE_ITEMS"; +export const MOVIES_MARK_WANTED_LIST_DIRTY = "MOVIES_MARK_WANTED_LIST_DIRTY"; export const MOVIES_UPDATE_WANTED_LIST = "UPDATE_MOVIE_WANTED_LIST"; export const MOVIES_DELETE_WANTED_ITEMS = "MOVIES_DELETE_WANTED_ITEMS"; export const MOVIES_UPDATE_HISTORY_LIST = "UPDATE_MOVIE_HISTORY_LIST"; diff --git a/frontend/src/@redux/hooks/index.ts b/frontend/src/@redux/hooks/index.ts index ac15d5b21..364871a4f 100644 --- a/frontend/src/@redux/hooks/index.ts +++ b/frontend/src/@redux/hooks/index.ts @@ -5,11 +5,13 @@ import { episodeDeleteItems, episodeUpdateBy, episodeUpdateById, + movieDeleteWantedItems, movieUpdateBlacklist, movieUpdateHistoryList, movieUpdateList, movieUpdateWantedList, providerUpdateList, + seriesDeleteWantedItems, seriesUpdateBlacklist, seriesUpdateHistoryList, seriesUpdateList, @@ -322,6 +324,18 @@ export function useWantedSeries() { const update = useReduxAction(seriesUpdateWantedList); const items = useReduxStore((d) => d.series.wantedEpisodesList); + const updateAction = useWrapToOptionalId(update); + const deleteAction = useReduxAction(seriesDeleteWantedItems); + const reducer = useMemo( + () => ({ + key: "episode-wanted", + update: updateAction, + delete: deleteAction, + }), + [updateAction, deleteAction] + ); + useSocketIOReducer(reducer); + return stateBuilder(items, update); } @@ -329,6 +343,18 @@ export function useWantedMovies() { const update = useReduxAction(movieUpdateWantedList); const items = useReduxStore((d) => d.movie.wantedMovieList); + const updateAction = useWrapToOptionalId(update); + const deleteAction = useReduxAction(movieDeleteWantedItems); + const reducer = useMemo( + () => ({ + key: "movie-wanted", + update: updateAction, + delete: deleteAction, + }), + [updateAction, deleteAction] + ); + useSocketIOReducer(reducer); + return stateBuilder(items, update); } diff --git a/frontend/src/@redux/reducers/movie.ts b/frontend/src/@redux/reducers/movie.ts index 2b7fe8df1..40c0a947f 100644 --- a/frontend/src/@redux/reducers/movie.ts +++ b/frontend/src/@redux/reducers/movie.ts @@ -2,6 +2,7 @@ import { Action, handleActions } from "redux-actions"; import { MOVIES_DELETE_ITEMS, MOVIES_DELETE_WANTED_ITEMS, + MOVIES_MARK_WANTED_LIST_DIRTY, MOVIES_UPDATE_BLACKLIST, MOVIES_UPDATE_HISTORY_LIST, MOVIES_UPDATE_LIST, @@ -11,6 +12,7 @@ import { AsyncAction } from "../types"; import { defaultAOS } from "../utils"; import { deleteOrderListItemBy, + markOrderListDirty, updateAsyncState, updateOrderIdState, } from "../utils/mapper"; @@ -36,6 +38,12 @@ const reducer = handleActions( wantedMovieList: deleteOrderListItemBy(action, state.wantedMovieList), }; }, + [MOVIES_MARK_WANTED_LIST_DIRTY]: (state, action) => { + return { + ...state, + wantedMovieList: markOrderListDirty(state.wantedMovieList), + }; + }, [MOVIES_UPDATE_HISTORY_LIST]: ( state, action: AsyncAction diff --git a/frontend/src/@redux/reducers/series.ts b/frontend/src/@redux/reducers/series.ts index 23ae4ecd6..8f72928ae 100644 --- a/frontend/src/@redux/reducers/series.ts +++ b/frontend/src/@redux/reducers/series.ts @@ -3,6 +3,7 @@ import { SERIES_DELETE_EPISODES, SERIES_DELETE_ITEMS, SERIES_DELETE_WANTED_ITEMS, + SERIES_MARK_WANTED_LIST_DIRTY, SERIES_UPDATE_BLACKLIST, SERIES_UPDATE_EPISODE_LIST, SERIES_UPDATE_HISTORY_LIST, @@ -14,6 +15,7 @@ import { defaultAOS } from "../utils"; import { deleteAsyncListItemBy, deleteOrderListItemBy, + markOrderListDirty, updateAsyncList, updateAsyncState, updateOrderIdState, @@ -43,6 +45,12 @@ const reducer = handleActions( ), }; }, + [SERIES_MARK_WANTED_LIST_DIRTY]: (state, action) => { + return { + ...state, + wantedEpisodesList: markOrderListDirty(state.wantedEpisodesList), + }; + }, [SERIES_UPDATE_EPISODE_LIST]: ( state, action: AsyncAction diff --git a/frontend/src/@redux/utils/index.ts b/frontend/src/@redux/utils/index.ts index e0e063f0d..c269932da 100644 --- a/frontend/src/@redux/utils/index.ts +++ b/frontend/src/@redux/utils/index.ts @@ -4,7 +4,7 @@ export function defaultAOS(): AsyncOrderState { data: { items: [], order: [], - dirty: false, + dirty: true, }, }; } diff --git a/frontend/src/@redux/utils/mapper.ts b/frontend/src/@redux/utils/mapper.ts index 772caa39a..1236b2af9 100644 --- a/frontend/src/@redux/utils/mapper.ts +++ b/frontend/src/@redux/utils/mapper.ts @@ -36,7 +36,7 @@ export function updateOrderIdState( return { data: { ...state.data, - dirty: true, + dirty: false, }, updating: true, }; @@ -44,7 +44,7 @@ export function updateOrderIdState( return { data: { ...state.data, - dirty: true, + dirty: false, }, updating: false, error: action.payload.item as Error, @@ -107,7 +107,7 @@ export function updateOrderIdState( return { updating: false, data: { - dirty: true, + dirty: false, items: newItems, order: newOrder, }, @@ -131,13 +131,25 @@ export function deleteOrderListItemBy( return { ...state, data: { - dirty: true, + dirty: false, items: newItems, order: newOrder, }, }; } +export function markOrderListDirty( + state: AsyncOrderState +): AsyncOrderState { + return { + ...state, + data: { + ...state.data, + dirty: true, + }, + }; +} + export function deleteAsyncListItemBy( action: Action, state: AsyncState, diff --git a/frontend/src/@socketio/reducer.ts b/frontend/src/@socketio/reducer.ts index 5ea5fba94..4585592c3 100644 --- a/frontend/src/@socketio/reducer.ts +++ b/frontend/src/@socketio/reducer.ts @@ -3,13 +3,11 @@ import { badgeUpdateAll, bootstrap, movieDeleteItems, - movieDeleteWantedItems, + movieMarkWantedListDirty, movieUpdateList, - movieUpdateWantedList, seriesDeleteItems, - seriesDeleteWantedItems, + seriesMarkWantedListDirty, seriesUpdateList, - seriesUpdateWantedList, siteAddNotifications, siteAddProgress, siteInitializationFailed, @@ -97,21 +95,11 @@ export function createDefaultReducer(): SocketIO.Reducer[] { }, { key: "episode-wanted", - update: (ids: number[] | undefined) => { - if (ids) { - reduxStore.dispatch(seriesUpdateWantedList(ids) as any); - } - }, - delete: bindToReduxStore(seriesDeleteWantedItems), + any: bindToReduxStore(seriesMarkWantedListDirty), }, { key: "movie-wanted", - update: (ids: number[] | undefined) => { - if (ids) { - reduxStore.dispatch(movieUpdateWantedList(ids) as any); - } - }, - delete: bindToReduxStore(movieDeleteWantedItems), + any: bindToReduxStore(movieMarkWantedListDirty), }, { key: "settings", diff --git a/frontend/src/components/tables/AsyncPageTable.tsx b/frontend/src/components/tables/AsyncPageTable.tsx index 54bb969c9..2af0809dc 100644 --- a/frontend/src/components/tables/AsyncPageTable.tsx +++ b/frontend/src/components/tables/AsyncPageTable.tsx @@ -85,7 +85,7 @@ export default function AsyncPageTable(props: Props) { }, [pageIndex]); useEffect(() => { - const needFetch = visibleItemIds.length === 0 && dirty === false; + const needFetch = visibleItemIds.length === 0 || dirty === true; const needRefresh = !visibleItemIds.every(isNonNullable); if (needFetch || needRefresh) { loader(pageStart, pageSize);