import { createFeatureSelector, createSelector } from '@ngrx/store'; import { MessagesState, messagesAdapter } from './messages.reducer'; /** Selects the top-level messages feature state. */ export const selectMessagesState = createFeatureSelector('messages'); const { selectIds, selectEntities, selectAll, selectTotal } = messagesAdapter.getSelectors(); /** Selects all message entities as a flat array. */ export const selectAllMessages = createSelector(selectMessagesState, selectAll); /** Selects the message entity dictionary keyed by ID. */ export const selectMessagesEntities = createSelector(selectMessagesState, selectEntities); /** Selects all message IDs. */ export const selectMessagesIds = createSelector(selectMessagesState, selectIds); /** Selects the total count of messages. */ export const selectMessagesTotal = createSelector(selectMessagesState, selectTotal); /** Whether messages are currently being loaded from the database. */ export const selectMessagesLoading = createSelector( selectMessagesState, (state) => state.loading ); /** Selects the most recent messages-related error message. */ export const selectMessagesError = createSelector( selectMessagesState, (state) => state.error ); /** Whether a peer-to-peer message sync cycle is in progress. */ export const selectMessagesSyncing = createSelector( selectMessagesState, (state) => state.syncing ); /** Selects the ID of the room whose messages are currently loaded. */ export const selectCurrentRoomId = createSelector( selectMessagesState, (state) => state.currentRoomId ); /** Selects all messages belonging to the currently active room. */ export const selectCurrentRoomMessages = createSelector( selectAllMessages, selectCurrentRoomId, (messages, roomId) => roomId ? messages.filter((message) => message.roomId === roomId) : [] ); /** Creates a selector that returns messages for a specific text channel within the current room. */ export const selectChannelMessages = (channelId: string) => createSelector( selectAllMessages, selectCurrentRoomId, (messages, roomId) => { if (!roomId) return []; return messages.filter( (message) => message.roomId === roomId && (message.channelId || 'general') === channelId ); } ); /** Creates a selector that returns a single message by its ID. */ export const selectMessageById = (id: string) => createSelector(selectMessagesEntities, (entities) => entities[id]); /** Creates a selector that returns all messages for a specific room. */ export const selectMessagesByRoomId = (roomId: string) => createSelector(selectAllMessages, (messages) => messages.filter((message) => message.roomId === roomId) ); /** Creates a selector that returns the N most recent messages. */ export const selectRecentMessages = (limit: number) => createSelector(selectAllMessages, (messages) => messages.slice(-limit) ); /** Selects only messages that have at least one reaction. */ export const selectMessagesWithReactions = createSelector( selectAllMessages, (messages) => messages.filter((message) => message.reactions.length > 0) );