import { AppDispatch } from "app/store";
|
|
import {
|
|
RoomMembership,
|
|
RoomMessagePayload,
|
|
RoomState,
|
|
roomGetAll,
|
|
roomReceiveMessage,
|
|
roomSendMessage,
|
|
roomSetMembership,
|
|
roomSetAll,
|
|
roomSetState,
|
|
} from "modules/room/slice";
|
|
import { SocketMessage, SocketMessageMiddleware } from "modules/socket/message";
|
|
|
|
function convertMembership(membership: string): RoomMembership {
|
|
switch (membership) {
|
|
case "NonMember":
|
|
return RoomMembership.Left;
|
|
case "Joining":
|
|
return RoomMembership.Joining;
|
|
case "Member":
|
|
return RoomMembership.Joined;
|
|
case "Leaving":
|
|
return RoomMembership.Leaving;
|
|
}
|
|
}
|
|
|
|
function convertMessages(messages: any[]): RoomMessage[] {
|
|
const result = [];
|
|
for (const message of messages) {
|
|
result.push({
|
|
userName: message.user_name,
|
|
message: message.message,
|
|
});
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function convertRoomListEntry(name: string, room: any): RoomState {
|
|
return {
|
|
name,
|
|
membership: convertMembership(room.membership),
|
|
visibility: room.visibility,
|
|
operated: room.operated,
|
|
userCount: room.user_count,
|
|
owner: room.owner,
|
|
operators: room.operators,
|
|
members: room.members,
|
|
messages: convertMessages(room.messages),
|
|
tickers: room.tickers,
|
|
};
|
|
}
|
|
|
|
function handleRoomListResponse(dispatch: AppDispatch, response): void {
|
|
const { rooms } = response;
|
|
if (rooms === undefined) {
|
|
console.log("RoomListResponse has wrong shape:", response);
|
|
return;
|
|
}
|
|
|
|
const payload = [];
|
|
for (const [name, room] of rooms) {
|
|
payload.push(convertRoomListEntry(name, room));
|
|
}
|
|
|
|
dispatch(roomSetAll(payload));
|
|
}
|
|
|
|
function handleRoomMessageResponse(dispatch: AppDispatch, response): void {
|
|
dispatch(
|
|
roomReceiveMessage({
|
|
roomName: response.room_name,
|
|
userName: response.user_name,
|
|
message: response.message,
|
|
})
|
|
);
|
|
}
|
|
|
|
function handleRoomJoinResponse(dispatch: AppDispatch, response): void {
|
|
const room = convertRoomListEntry(response.room_name, response.room);
|
|
dispatch(roomSetState(room));
|
|
}
|
|
|
|
function handleRoomLeaveResponse(dispatch: AppDispatch, response): void {
|
|
dispatch(roomSetMembership([response.room_name, RoomMembership.Left]));
|
|
}
|
|
|
|
function roomListRequest(): SocketMessage {
|
|
return "RoomListRequest";
|
|
}
|
|
|
|
function roomMessageRequest({ roomName, message }: RoomMessagePayload) {
|
|
return {
|
|
RoomMessageRequest: {
|
|
room_name: roomName,
|
|
message,
|
|
},
|
|
};
|
|
}
|
|
|
|
const roomJoinRequest = (name: string) => ({
|
|
RoomJoinRequest: name,
|
|
});
|
|
|
|
const roomLeaveRequest = (name: string) => ({
|
|
RoomLeaveRequest: name,
|
|
});
|
|
|
|
function handleSetMembershipAction(
|
|
send: SocketMessageSender,
|
|
[name, membership]: [string, RoomMembership]
|
|
) {
|
|
switch (membership) {
|
|
case RoomMembership.Joining:
|
|
send(roomJoinRequest(name));
|
|
break;
|
|
case RoomMembership.Leaving:
|
|
send(roomLeaveRequest(name));
|
|
break;
|
|
}
|
|
}
|
|
|
|
export const roomSocketMessageMiddleware: SocketMessageMiddleware = {
|
|
handleMessage: (dispatch, message) => {
|
|
if ("RoomListResponse" in message) {
|
|
handleRoomListResponse(dispatch, message["RoomListResponse"]);
|
|
} else if ("RoomMessageResponse" in message) {
|
|
handleRoomMessageResponse(dispatch, message["RoomMessageResponse"]);
|
|
} else if ("RoomJoinResponse" in message) {
|
|
handleRoomJoinResponse(dispatch, message["RoomJoinResponse"]);
|
|
} else if ("RoomLeaveResponse" in message) {
|
|
handleRoomLeaveResponse(dispatch, message["RoomLeaveResponse"]);
|
|
}
|
|
},
|
|
|
|
handleAction: (send, action) => {
|
|
if (roomGetAll.match(action)) {
|
|
send(roomListRequest());
|
|
} else if (roomSendMessage.match(action)) {
|
|
send(roomMessageRequest(action.payload));
|
|
} else if (roomSetMembership.match(action)) {
|
|
handleSetMembershipAction(send, action.payload);
|
|
}
|
|
},
|
|
};
|