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


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

@ -1,53 +1,107 @@
import { AppDispatch } from "app/store"; 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"; import { SocketMessage, SocketMessageMiddleware } from "modules/socket/message";
function roomListRequest(): SocketMessage { function roomListRequest(): SocketMessage {
return "RoomListRequest"; 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; 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 = { export const roomSocketMessageMiddleware: SocketMessageMiddleware = {
// TODO: Adapt to new response format. // 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) => { handleAction: (send, action) => {
if (roomGetAll.match(action)) { if (roomGetAll.match(action)) {
send(roomListRequest()); 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[]; operators: string[];
members: string[]; members: string[];
messages: RoomMessage[]; messages: RoomMessage[];
tickers: string[];
tickers: [string, string][];
// showUsers: boolean; // showUsers: boolean;
} }
@ -99,7 +99,7 @@ export const roomSlice = createSlice({
room.membership = membership; room.membership = membership;
}, },
roomMessage: (
roomReceiveMessage: (
state: RoomSliceState, state: RoomSliceState,
action: PayloadAction<RoomMessagePayload> action: PayloadAction<RoomMessagePayload>
) => { ) => {
@ -115,6 +115,21 @@ export const roomSlice = createSlice({
room.messages.push({ userName, message }); 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[]>) => { roomSetAll: (state: RoomSliceState, action: PayloadAction<Room[]>) => {
state.rooms = {}; state.rooms = {};
for (const room of action.payload) { 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 { export function selectAllRooms(state: RootState): RoomMap {
return state.rooms.rooms; 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"; import { AppDispatch } from "app/store";
// The type of a message exchanged over a websocket. // 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. // Serializes the given message for sending over the wire.
export function serializeMessage(message: SocketMessage): string { 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. // Attempts to parse a message out of the given data.
// Throws an error if unsuccessful. // Throws an error if unsuccessful.
export function parseMessage(serialized: string): SocketMessage { 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. // An interface passed to socket message middleware, used to send messages.


Loading…
Cancel
Save