import { createAsyncThunk, createSlice } from "@reduxjs/toolkit"; import DetailedMeeting from "../../api-bodies/DetailedMeeting"; import { RootState } from "../store"; import UserStatus from "../../api-bodies/UserStatus"; import axios from "../../api/axios"; interface MeetingsAndUserStatusState { meetings: DetailedMeeting[]; userStatuses: Record; isConnecting: boolean; isConnected: boolean; } const initialState: MeetingsAndUserStatusState = { meetings: [], userStatuses: {}, isConnecting: false, isConnected: false, }; export const meetingsAndUserStatusSlice = createSlice({ name: "meetingsAndUserStatus", initialState, reducers: { startConnecting: (state) => { state.isConnecting = true; }, connectionEstablished: (state) => { state.isConnecting = true; state.isConnected = true; }, meetingCreated: (state, action) => { state.meetings.push(action.payload.meeting); }, userStatusChanged: (state, action) => { state.userStatuses[action.payload.uuid] = action.payload; }, }, extraReducers(builder) { builder.addCase(fetchMeetings.fulfilled, (state, action) => { state.meetings = action.payload.meetings; state.userStatuses = action.payload.userStatuses; }); }, }); export const fetchMeetings = createAsyncThunk( "meetingsAndUserStatus/fetchMeetings", async (uuid: string) => { const response = await axios.get( `/users/${uuid}/meetings?start=1900-01-01&end=2100-01-01` ); const meetings: DetailedMeeting[] = response.data.meetings; const userStatuses: Record = {}; meetings.forEach((meeting) => { meeting.liveParticipantIds.forEach((uuid) => { userStatuses[uuid] = { userId: uuid, inMeeting: true, meetingId: meeting.meetingId, }; }); }); return { userStatuses: userStatuses, meetings: meetings }; } ); export const selectMeetings = (state: RootState) => state.meetingsAndUserStatuses.meetings; export const selectMeeting = (state: RootState, meetingID: string | null) => { return meetingID !== null ? state.meetingsAndUserStatuses.meetings.find( (meeting) => meeting.meetingId === meetingID ) : null; }; export const selectUserUpcomingMeetings = (state: RootState, uuid: string) => { return state.meetingsAndUserStatuses.meetings.filter((meeting) => meeting.registrantIds.includes(uuid) ); }; export const selectUserStatus = ( state: RootState, uuid: string ): UserStatus => { const userStatus = state.meetingsAndUserStatuses.userStatuses[uuid]; if (userStatus) { return userStatus; } else { return { userId: uuid, inMeeting: false, meetingId: null, }; } }; export const selectUserStatuses = ( state: RootState, uuids: string[] ): UserStatus[] => { const userStatuses: UserStatus[] = []; uuids.forEach((uuid) => { const userStatus = state.meetingsAndUserStatuses.userStatuses[uuid]; if (userStatus) { userStatuses.push(userStatus); } else { userStatuses.push({ userId: uuid, inMeeting: false, meetingId: null, }); } }); return userStatuses; }; export default meetingsAndUserStatusSlice.reducer; export const socketActions = meetingsAndUserStatusSlice.actions;