Browse Source

Handle new message format for room module.

main
Titouan Rigoudy 4 years ago
parent
commit
f9c4c1cb4b
4 changed files with 106 additions and 40 deletions
  1. +2
    -2
      src/modules/room/RoomChatForm.tsx
  2. +78
    -24
      src/modules/room/message.ts
  3. +24
    -4
      src/modules/room/slice.ts
  4. +2
    -10
      src/modules/socket/message.ts

+ 2
- 2
src/modules/room/RoomChatForm.tsx View File

@ -2,7 +2,7 @@ import { FC } from "react";
import { Form, Field } from "react-final-form";
import { useDispatch } from "react-redux";
import { roomMessage } from "modules/room/slice";
import { roomSendMessage } from "modules/room/slice";
interface Props {
roomName: string;
@ -18,7 +18,7 @@ const RoomChatForm: FC<Props> = ({ roomName, loginUserName }) => {
const onSubmit = ({ message }: Fields, form: any) => {
dispatch(
roomMessage({
roomSendMessage({
roomName,
userName: loginUserName,
message,


+ 78
- 24
src/modules/room/message.ts View File

@ -1,53 +1,107 @@
import { AppDispatch } from "app/store";
import { roomMessage, roomGetAll, roomSetAll } from "modules/room/slice";
import {
RoomMembership,
RoomMessagePayload,
RoomState,
roomReceiveMessage,
roomSendMessage,
roomGetAll,
roomSetAll,
} from "modules/room/slice";
import { SocketMessage, SocketMessageMiddleware } from "modules/socket/message";
function roomListRequest(): SocketMessage {
return "RoomListRequest";
}
// TODO: Adapt to new response format.
function handleRoomListResponse(dispatch: AppDispatch, outerFields: any[]) {
if (outerFields.length !== 1) {
console.log("RoomListResponse has wrong number of fields:", outerFields);
return;
function roomMessageRequest({ roomName, message }: RoomMessagePayload) {
return {
RoomMessageRequest: {
room_name: roomName,
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;
}
}
const { rooms } = outerFields[0];
if (rooms === undefined) {
console.log("RoomListResponse field has wrong shape:", outerFields[0]);
return;
function convertMessages(messages: any[]): RoomMessage[] {
const result = [];
for (const message of messages) {
result.push({
userName: message.user_name,
message: message.message,
});
}
return result;
}
dispatch(roomSetAll(rooms));
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,
};
}
// TODO: Adapt to new response format.
function handleRoomMessageResponse(dispatch: AppDispatch, outerFields: any[]) {
if (outerFields.length !== 1) {
console.log("RoomMessageResponse has wrong number of fields:", outerFields);
function handleRoomListResponse(dispatch: AppDispatch, response) {
const { rooms } = response;
if (rooms === undefined) {
console.log("RoomListResponse has wrong shape:", response);
return;
}
dispatch(roomMessage(outerFields[0]));
const map = {};
for (const [name, room] of rooms) {
map[name] = convertRoomListEntry(name, room);
}
dispatch(roomSetAll(map));
}
function handleRoomMessageResponse(dispatch: AppDispatch, response) {
dispatch(
roomReceiveMessage({
roomName: response.room_name,
userName: response.user_name,
message: response.message,
})
);
}
export const roomSocketMessageMiddleware: SocketMessageMiddleware = {
// TODO: Adapt to new response format.
handleMessage: (dispatch, { variant, fields }) => {
switch (variant) {
case "RoomListResponse":
handleRoomListResponse(dispatch, fields);
break;
case "RoomMessageResponse":
handleRoomMessageResponse(dispatch, fields);
break;
handleMessage: (dispatch, message) => {
if ("RoomListResponse" in message) {
handleRoomListResponse(dispatch, message["RoomListResponse"]);
} else if ("RoomMessageResponse" in message) {
handleRoomMessageResponse(dispatch, message["RoomMessageResponse"]);
}
},
handleAction: (send, action) => {
if (roomGetAll.match(action)) {
send(roomListRequest());
} else if (roomSendMessage.match(action)) {
send(roomMessageRequest(action.payload));
}
},
};

+ 24
- 4
src/modules/room/slice.ts View File

@ -24,7 +24,7 @@ export interface RoomState {
operators: string[];
members: string[];
messages: RoomMessage[];
tickers: string[];
tickers: [string, string][];
// showUsers: boolean;
}
@ -99,7 +99,7 @@ export const roomSlice = createSlice({
room.membership = membership;
},
roomMessage: (
roomReceiveMessage: (
state: RoomSliceState,
action: PayloadAction<RoomMessagePayload>
) => {
@ -115,6 +115,21 @@ export const roomSlice = createSlice({
room.messages.push({ userName, message });
},
roomSendMessage: (
state: RoomSliceState,
action: PayloadAction<RoomMessagePayload>
) => {
const { roomName, userName, message } = action.payload;
const room = state.rooms[roomName];
if (room === undefined) {
console.log(
`Cannot send message to unknown room ${roomName}: ${message}`
);
return;
}
room.messages.push({ userName, message });
},
roomSetAll: (state: RoomSliceState, action: PayloadAction<Room[]>) => {
state.rooms = {};
for (const room of action.payload) {
@ -125,8 +140,13 @@ export const roomSlice = createSlice({
},
});
export const { roomSetMembership, roomMessage, roomGetAll, roomSetAll } =
roomSlice.actions;
export const {
roomSetMembership,
roomReceiveMessage,
roomSendMessage,
roomGetAll,
roomSetAll,
} = roomSlice.actions;
export function selectAllRooms(state: RootState): RoomMap {
return state.rooms.rooms;


+ 2
- 10
src/modules/socket/message.ts View File

@ -5,10 +5,7 @@ import { PayloadAction } from "@reduxjs/toolkit";
import { AppDispatch } from "app/store";
// The type of a message exchanged over a websocket.
export interface SocketMessage {
variant: string;
fields: any[];
}
export type SocketMessage = any;
// Serializes the given message for sending over the wire.
export function serializeMessage(message: SocketMessage): string {
@ -18,12 +15,7 @@ export function serializeMessage(message: SocketMessage): string {
// Attempts to parse a message out of the given data.
// Throws an error if unsuccessful.
export function parseMessage(serialized: string): SocketMessage {
const { variant, fields } = JSON.parse(serialized);
if (typeof variant === "undefined") {
throw new Error('Missing "variant" field in socket message');
}
return { variant, fields };
return JSON.parse(serialized);
}
// An interface passed to socket message middleware, used to send messages.


Loading…
Cancel
Save