UNPKG

@replyke/core

Version:

Replyke: Build interactive apps with social features like comments, votes, feeds, user lists, notifications, and more.

104 lines 4.42 kB
import { createSlice } from "@reduxjs/toolkit"; // Initial state const initialState = { notifications: [], unreadCount: 0, loading: false, hasMore: true, page: 1, limit: 10, notificationTemplates: undefined, currentProjectId: undefined, }; // Create the slice export const appNotificationsSlice = createSlice({ name: 'appNotifications', initialState, reducers: { // Set the current project context setProjectContext: (state, action) => { state.currentProjectId = action.payload; }, // Set pagination limit setLimit: (state, action) => { state.limit = action.payload; }, // Set notification templates setNotificationTemplates: (state, action) => { state.notificationTemplates = action.payload; }, // Reset notifications (clear all and restart pagination) resetNotifications: (state) => { state.notifications = []; state.page = 1; state.hasMore = true; state.loading = false; }, // Load more notifications (increment page) loadMore: (state) => { if (state.hasMore && !state.loading) { state.page += 1; } }, // Set loading state setLoading: (state, action) => { state.loading = action.payload; }, // Add new notifications (for pagination) addNotifications: (state, action) => { const { notifications, hasMore, isFirstPage = false } = action.payload; if (isFirstPage) { state.notifications = notifications; } else { // Prevent duplicates when adding new pages const existingIds = new Set(state.notifications.map(n => n.id)); const newNotifications = notifications.filter(n => !existingIds.has(n.id)); state.notifications.push(...newNotifications); } // Update hasMore from pagination metadata state.hasMore = hasMore; state.loading = false; }, // Mark notification as read locally (optimistic update) markAsReadLocally: (state, action) => { const notificationId = action.payload; const notification = state.notifications.find(n => n.id === notificationId); if (notification && !notification.isRead) { notification.isRead = true; // Decrease unread count state.unreadCount = Math.max(state.unreadCount - 1, 0); } }, // Mark all notifications as read locally (optimistic update) markAllAsReadLocally: (state) => { state.notifications.forEach(notification => { notification.isRead = true; }); // Set unread count to 0 state.unreadCount = 0; }, // Set unread count setUnreadCount: (state, action) => { state.unreadCount = action.payload; }, // Handle errors by stopping loading handleError: (state) => { state.loading = false; }, }, }); // Export actions export const { setProjectContext, setLimit, setNotificationTemplates, resetNotifications, loadMore, setLoading, addNotifications, markAsReadLocally, markAllAsReadLocally, setUnreadCount, handleError, } = appNotificationsSlice.actions; // Export reducer export default appNotificationsSlice.reducer; // Selectors - use namespaced state for dual-mode support export const selectAppNotifications = (state) => state.replyke.appNotifications.notifications; export const selectUnreadCount = (state) => state.replyke.appNotifications.unreadCount; export const selectAppNotificationsLoading = (state) => state.replyke.appNotifications.loading; export const selectAppNotificationsHasMore = (state) => state.replyke.appNotifications.hasMore; export const selectAppNotificationsPage = (state) => state.replyke.appNotifications.page; export const selectAppNotificationsLimit = (state) => state.replyke.appNotifications.limit; export const selectNotificationTemplates = (state) => state.replyke.appNotifications.notificationTemplates; export const selectCurrentProjectId = (state) => state.replyke.appNotifications.currentProjectId; //# sourceMappingURL=appNotificationsSlice.js.map