bazarr/frontend/src/@redux/reducers/site.ts

131 lines
3.4 KiB
TypeScript

import { createReducer } from "@reduxjs/toolkit";
import { intersectionWith, pullAllWith, remove, sortBy, uniqBy } from "lodash";
import apis from "../../apis";
import { isProdEnv } from "../../utilities";
import {
siteAddNotifications,
siteAddProgress,
siteBootstrap,
siteChangeSidebarVisibility,
siteRedirectToAuth,
siteRemoveNotifications,
siteRemoveProgress,
siteUpdateBadges,
siteUpdateInitialization,
siteUpdateNotifier,
siteUpdateOffline,
siteUpdateProgressCount,
} from "../actions/site";
interface Site {
// Initialization state or error message
initialized: boolean | string;
offline: boolean;
auth: boolean;
progress: Site.Progress[];
notifier: {
content: string | null;
timestamp: string;
};
notifications: Server.Notification[];
showSidebar: boolean;
badges: Badge;
}
const defaultSite: Site = {
initialized: false,
auth: true,
progress: [],
notifier: {
content: null,
timestamp: String(Date.now()),
},
notifications: [],
showSidebar: false,
badges: {
movies: 0,
episodes: 0,
providers: 0,
status: 0,
},
offline: false,
};
const reducer = createReducer(defaultSite, (builder) => {
builder
.addCase(siteBootstrap.fulfilled, (state) => {
state.initialized = true;
})
.addCase(siteBootstrap.rejected, (state) => {
state.initialized = "An Error Occurred When Initializing Bazarr UI";
})
.addCase(siteRedirectToAuth, (state) => {
if (!isProdEnv) {
apis._resetApi("NEED_AUTH");
}
state.auth = false;
})
.addCase(siteUpdateInitialization, (state, action) => {
state.initialized = action.payload;
});
builder
.addCase(siteAddNotifications, (state, action) => {
state.notifications = uniqBy(
[...action.payload, ...state.notifications],
(v) => v.id
);
state.notifications = sortBy(state.notifications, (v) => v.id);
})
.addCase(siteRemoveNotifications, (state, action) => {
remove(state.notifications, (n) => n.id === action.payload);
});
builder
.addCase(siteAddProgress, (state, action) => {
state.progress = uniqBy(
[...action.payload, ...state.progress],
(n) => n.id
);
state.progress = sortBy(state.progress, (v) => v.id);
})
.addCase(siteRemoveProgress.pending, (state, action) => {
// Mark completed
intersectionWith(
state.progress,
action.meta.arg,
(l, r) => l.id === r
).forEach((v) => {
v.value = v.count + 1;
});
})
.addCase(siteRemoveProgress.fulfilled, (state, action) => {
pullAllWith(state.progress, action.payload, (l, r) => l.id === r);
})
.addCase(siteUpdateProgressCount, (state, action) => {
const { id, count } = action.payload;
const progress = state.progress.find((v) => v.id === id);
if (progress) {
progress.count = count;
}
});
builder.addCase(siteUpdateNotifier, (state, action) => {
state.notifier.content = action.payload;
state.notifier.timestamp = String(Date.now());
});
builder
.addCase(siteChangeSidebarVisibility, (state, action) => {
state.showSidebar = action.payload;
})
.addCase(siteUpdateOffline, (state, action) => {
state.offline = action.payload;
})
.addCase(siteUpdateBadges.fulfilled, (state, action) => {
state.badges = action.payload;
});
});
export default reducer;