118 lines
3.3 KiB
TypeScript
118 lines
3.3 KiB
TypeScript
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<string, UserStatus>;
|
|
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<string, UserStatus> = {};
|
|
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;
|