├── .gitignore ├── .sh ├── Dockerfile ├── README.md ├── envoy.yaml ├── package.json ├── public ├── favicon.ico ├── index.html ├── logo192.png ├── logo512.png ├── manifest.json └── robots.txt ├── src ├── App.css ├── App.js ├── App.test.js ├── _App.js ├── chat.proto ├── chat_grpc_web_pb.js ├── chat_pb.js ├── components │ ├── Chat │ │ ├── Chat.css │ │ └── index.js │ ├── Header │ │ ├── Header.css │ │ └── index.js │ └── UsersList │ │ ├── UsersList.css │ │ └── index.js ├── index.css ├── index.js ├── logo.svg ├── pages │ ├── ChatPage │ │ ├── ChatPage.css │ │ └── index.js │ └── Join │ │ └── index.js ├── reportWebVitals.js └── setupTests.js ├── trash ├── __Dockerfile-- └── envoy.yaml └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | /trash 4 | /src/_App.js 5 | 6 | # dependencies 7 | /node_modules 8 | /.pnp 9 | .pnp.js 10 | 11 | # testing 12 | /coverage 13 | 14 | # production 15 | /build 16 | 17 | # misc 18 | .DS_Store 19 | .env.local 20 | .env.development.local 21 | .env.test.local 22 | .env.production.local 23 | 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | -------------------------------------------------------------------------------- /.sh: -------------------------------------------------------------------------------- 1 | protoc -I=. src/chat.proto --js_out=import_style=commonjs:. --grpc-web_out=import_style=commonjs,mode=grpcwebtext:. 2 | 3 | protoc-gen-grpc-web -I=. src/chat.proto --js_out=import_style=commonjs:. --grpc-web_out=import_style=commonjs,mode=grpcwebtext:. 4 | 5 | protoc-gen-grpc-web chat.proto \ 6 | --js_out=import_style=commonjs,binary:./../js-client/src/sensorpb \ 7 | --grpc-web_out=import_style=commonjs,mode=grpcwebtext:./../js-client/src/sensorpb 8 | 9 | 10 | 11 | protoc-gen-grpc-web src/chat.proto \ 12 | --js_out=import_style=commonjs:src \ 13 | --grpc-web_out=import_style=commonjs,mode=grpcwebtext:src 14 | 15 | docker run -d -v 0000/envoy.yaml:/etc/envoy/envoy.yaml:ro \ 16 | -p 8080:8080 -p 9901:9901 envoyproxy/envoy:v1.17.0 -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM envoyproxy/envoy-dev:latest 2 | COPY envoy.yaml /etc/envoy/envoy.yaml 3 | RUN chmod go+r /etc/envoy/envoy.yaml -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Create React App 2 | 3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 4 | 5 | ## Available Scripts 6 | 7 | In the project directory, you can run: 8 | 9 | ### `yarn start` 10 | 11 | Runs the app in the development mode.\ 12 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 13 | 14 | The page will reload if you make edits.\ 15 | You will also see any lint errors in the console. 16 | 17 | ### `yarn test` 18 | 19 | Launches the test runner in the interactive watch mode.\ 20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 21 | 22 | ### `yarn build` 23 | 24 | Builds the app for production to the `build` folder.\ 25 | It correctly bundles React in production mode and optimizes the build for the best performance. 26 | 27 | The build is minified and the filenames include the hashes.\ 28 | Your app is ready to be deployed! 29 | 30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 31 | 32 | ### `yarn eject` 33 | 34 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 35 | 36 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 37 | 38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 39 | 40 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 41 | 42 | ## Learn More 43 | 44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 45 | 46 | To learn React, check out the [React documentation](https://reactjs.org/). 47 | 48 | ### Code Splitting 49 | 50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting) 51 | 52 | ### Analyzing the Bundle Size 53 | 54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size) 55 | 56 | ### Making a Progressive Web App 57 | 58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app) 59 | 60 | ### Advanced Configuration 61 | 62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration) 63 | 64 | ### Deployment 65 | 66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment) 67 | 68 | ### `yarn build` fails to minify 69 | 70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify) 71 | # grpc-chat-react 72 | -------------------------------------------------------------------------------- /envoy.yaml: -------------------------------------------------------------------------------- 1 | admin: 2 | access_log_path: /tmp/admin_access.log 3 | address: 4 | socket_address: { address: 0.0.0.0, port_value: 9901 } 5 | 6 | static_resources: 7 | listeners: 8 | - name: listener_0 9 | address: 10 | socket_address: { address: 0.0.0.0, port_value: 8080 } 11 | filter_chains: 12 | - filters: 13 | - name: envoy.filters.network.http_connection_manager 14 | typed_config: 15 | "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager 16 | codec_type: auto 17 | stat_prefix: ingress_http 18 | stream_idle_timeout: 0s 19 | route_config: 20 | name: local_route 21 | virtual_hosts: 22 | - name: local_service 23 | domains: ["*"] 24 | routes: 25 | - match: { prefix: "/" } 26 | route: 27 | cluster: chat_service 28 | max_grpc_timeout: 0s 29 | max_stream_duration: 30 | grpc_timeout_header_max: 0s 31 | cors: 32 | allow_origin_string_match: 33 | - prefix: "*" 34 | allow_methods: GET, PUT, DELETE, POST, OPTIONS 35 | allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,custom-header-1,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout 36 | max_age: "1728000" 37 | expose_headers: custom-header-1,grpc-status,grpc-message 38 | http_filters: 39 | - name: envoy.filters.http.grpc_web 40 | - name: envoy.filters.http.cors 41 | - name: envoy.filters.http.router 42 | clusters: 43 | - name: chat_service 44 | connect_timeout: 0.25s 45 | type: logical_dns 46 | http2_protocol_options: {} 47 | # upstream_connection_options: 48 | # tcp_keepalive: 49 | # keepalive_time: 300 50 | lb_policy: round_robin 51 | # win/mac hosts: Use address: host.docker.internal instead of address: localhost in the line below 52 | load_assignment: 53 | cluster_name: cluster_0 54 | endpoints: 55 | - lb_endpoints: 56 | - endpoint: 57 | address: 58 | socket_address: 59 | address: host.docker.internal 60 | port_value: 9090 61 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "grpc-chat-react", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.11.4", 7 | "@testing-library/react": "^11.1.0", 8 | "@testing-library/user-event": "^12.1.10", 9 | "google-protobuf": "^3.15.8", 10 | "grpc-web": "^1.2.1", 11 | "react": "^17.0.2", 12 | "react-dom": "^17.0.2", 13 | "react-router-dom": "^5.2.0", 14 | "react-scripts": "4.0.3", 15 | "web-vitals": "^1.0.1" 16 | }, 17 | "scripts": { 18 | "start": "react-scripts start", 19 | "build": "react-scripts build", 20 | "test": "react-scripts test", 21 | "eject": "react-scripts eject" 22 | }, 23 | "eslintConfig": { 24 | "extends": [ 25 | "react-app", 26 | "react-app/jest" 27 | ] 28 | }, 29 | "browserslist": { 30 | "production": [ 31 | ">0.2%", 32 | "not dead", 33 | "not op_mini all" 34 | ], 35 | "development": [ 36 | "last 1 chrome version", 37 | "last 1 firefox version", 38 | "last 1 safari version" 39 | ] 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grpc-prj/grpc-chat-react/bf951cf37f86417e0cccb51c1c68e8452962c22a/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grpc-prj/grpc-chat-react/bf951cf37f86417e0cccb51c1c68e8452962c22a/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grpc-prj/grpc-chat-react/bf951cf37f86417e0cccb51c1c68e8452962c22a/public/logo512.png -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grpc-prj/grpc-chat-react/bf951cf37f86417e0cccb51c1c68e8452962c22a/src/App.css -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import "./App.css"; 2 | import Header from "./components/Header"; 3 | 4 | import { User } from "./chat_pb"; 5 | import { ChatServiceClient } from "./chat_grpc_web_pb"; 6 | import ChatPage from "./pages/ChatPage"; 7 | import { useState, useRef } from "react"; 8 | 9 | export const client = new ChatServiceClient( 10 | "http://localhost:8080", 11 | null, 12 | null 13 | ); 14 | 15 | export default function App() { 16 | const inputRef = useRef(null); 17 | const [submitted, setSubmitted] = useState(null); 18 | function joinHandler() { 19 | const _username = inputRef.current.value; 20 | 21 | const user = new User(); 22 | user.setId(Date.now()); 23 | user.setName(_username); 24 | 25 | client.join(user, null, (err, response) => { 26 | if (err) return console.log(err); 27 | const error = response.getError(); 28 | const msg = response.getMsg(); 29 | 30 | if (error === 1) { 31 | console.log(error, msg); 32 | setSubmitted(true); 33 | //window.alert("Username already exists."); 34 | return; 35 | } 36 | window.localStorage.setItem("username", _username.toString()); 37 | setSubmitted(true); 38 | // history.push("chatslist"); 39 | }); 40 | } 41 | 42 | function renderChatPage() { 43 | return ; 44 | } 45 | 46 | function renderJoinPage() { 47 | return ( 48 |
49 |
50 |

Join Chat As...

51 |
52 |
53 | 59 |
60 |
61 | 72 |
73 |
74 | ); 75 | } 76 | 77 | return ( 78 | <> 79 | 80 | ChatApp 81 | 82 | 83 |
84 |
85 |
86 | {submitted ? renderChatPage() : renderJoinPage()} 87 |
88 |
89 | 90 | ); 91 | } 92 | -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /src/_App.js: -------------------------------------------------------------------------------- 1 | import "./App.css"; 2 | import { BrowserRouter, Route, Switch, Redirect } from "react-router-dom"; 3 | import Header from "./components/Header"; 4 | import ChatPage from "./pages/ChatPage"; 5 | import Join from "./pages/Join"; 6 | 7 | function App() { 8 | return ( 9 | <> 10 |
11 |
12 | 13 | NewsNet 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | {" "} 32 | 33 | 34 |
35 |
36 | 37 | ); 38 | } 39 | 40 | export default App; 41 | -------------------------------------------------------------------------------- /src/chat.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | message ChatMessage { 4 | string from = 1; 5 | string msg = 2; 6 | string time = 3; 7 | } 8 | 9 | message User { 10 | string id = 1; 11 | string name = 2; 12 | } 13 | 14 | message Empty {} 15 | 16 | message UserList { 17 | repeated User users = 1; 18 | } 19 | 20 | message JoinResponse { 21 | int32 error = 1; 22 | string msg = 2; 23 | } 24 | 25 | message ReceiveMsgRequest { 26 | string user = 1; 27 | } 28 | 29 | service ChatService { 30 | rpc join(User) returns (JoinResponse) {} 31 | rpc sendMsg(ChatMessage) returns (Empty) {} 32 | rpc receiveMsg(ReceiveMsgRequest) returns (stream ChatMessage) {} 33 | rpc getAllUsers(Empty) returns (UserList) {} 34 | } 35 | -------------------------------------------------------------------------------- /src/chat_grpc_web_pb.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview gRPC-Web generated client stub for 3 | * @enhanceable 4 | * @public 5 | */ 6 | 7 | // GENERATED CODE -- DO NOT EDIT! 8 | 9 | 10 | /* eslint-disable */ 11 | // @ts-nocheck 12 | 13 | 14 | 15 | const grpc = {}; 16 | grpc.web = require('grpc-web'); 17 | 18 | const proto = require('./chat_pb.js'); 19 | 20 | /** 21 | * @param {string} hostname 22 | * @param {?Object} credentials 23 | * @param {?Object} options 24 | * @constructor 25 | * @struct 26 | * @final 27 | */ 28 | proto.ChatServiceClient = 29 | function(hostname, credentials, options) { 30 | if (!options) options = {}; 31 | options['format'] = 'text'; 32 | 33 | /** 34 | * @private @const {!grpc.web.GrpcWebClientBase} The client 35 | */ 36 | this.client_ = new grpc.web.GrpcWebClientBase(options); 37 | 38 | /** 39 | * @private @const {string} The hostname 40 | */ 41 | this.hostname_ = hostname; 42 | 43 | }; 44 | 45 | 46 | /** 47 | * @param {string} hostname 48 | * @param {?Object} credentials 49 | * @param {?Object} options 50 | * @constructor 51 | * @struct 52 | * @final 53 | */ 54 | proto.ChatServicePromiseClient = 55 | function(hostname, credentials, options) { 56 | if (!options) options = {}; 57 | options['format'] = 'text'; 58 | 59 | /** 60 | * @private @const {!grpc.web.GrpcWebClientBase} The client 61 | */ 62 | this.client_ = new grpc.web.GrpcWebClientBase(options); 63 | 64 | /** 65 | * @private @const {string} The hostname 66 | */ 67 | this.hostname_ = hostname; 68 | 69 | }; 70 | 71 | 72 | /** 73 | * @const 74 | * @type {!grpc.web.MethodDescriptor< 75 | * !proto.User, 76 | * !proto.JoinResponse>} 77 | */ 78 | const methodDescriptor_ChatService_join = new grpc.web.MethodDescriptor( 79 | '/ChatService/join', 80 | grpc.web.MethodType.UNARY, 81 | proto.User, 82 | proto.JoinResponse, 83 | /** 84 | * @param {!proto.User} request 85 | * @return {!Uint8Array} 86 | */ 87 | function(request) { 88 | return request.serializeBinary(); 89 | }, 90 | proto.JoinResponse.deserializeBinary 91 | ); 92 | 93 | 94 | /** 95 | * @const 96 | * @type {!grpc.web.AbstractClientBase.MethodInfo< 97 | * !proto.User, 98 | * !proto.JoinResponse>} 99 | */ 100 | const methodInfo_ChatService_join = new grpc.web.AbstractClientBase.MethodInfo( 101 | proto.JoinResponse, 102 | /** 103 | * @param {!proto.User} request 104 | * @return {!Uint8Array} 105 | */ 106 | function(request) { 107 | return request.serializeBinary(); 108 | }, 109 | proto.JoinResponse.deserializeBinary 110 | ); 111 | 112 | 113 | /** 114 | * @param {!proto.User} request The 115 | * request proto 116 | * @param {?Object} metadata User defined 117 | * call metadata 118 | * @param {function(?grpc.web.Error, ?proto.JoinResponse)} 119 | * callback The callback function(error, response) 120 | * @return {!grpc.web.ClientReadableStream|undefined} 121 | * The XHR Node Readable Stream 122 | */ 123 | proto.ChatServiceClient.prototype.join = 124 | function(request, metadata, callback) { 125 | return this.client_.rpcCall(this.hostname_ + 126 | '/ChatService/join', 127 | request, 128 | metadata || {}, 129 | methodDescriptor_ChatService_join, 130 | callback); 131 | }; 132 | 133 | 134 | /** 135 | * @param {!proto.User} request The 136 | * request proto 137 | * @param {?Object} metadata User defined 138 | * call metadata 139 | * @return {!Promise} 140 | * Promise that resolves to the response 141 | */ 142 | proto.ChatServicePromiseClient.prototype.join = 143 | function(request, metadata) { 144 | return this.client_.unaryCall(this.hostname_ + 145 | '/ChatService/join', 146 | request, 147 | metadata || {}, 148 | methodDescriptor_ChatService_join); 149 | }; 150 | 151 | 152 | /** 153 | * @const 154 | * @type {!grpc.web.MethodDescriptor< 155 | * !proto.ChatMessage, 156 | * !proto.Empty>} 157 | */ 158 | const methodDescriptor_ChatService_sendMsg = new grpc.web.MethodDescriptor( 159 | '/ChatService/sendMsg', 160 | grpc.web.MethodType.UNARY, 161 | proto.ChatMessage, 162 | proto.Empty, 163 | /** 164 | * @param {!proto.ChatMessage} request 165 | * @return {!Uint8Array} 166 | */ 167 | function(request) { 168 | return request.serializeBinary(); 169 | }, 170 | proto.Empty.deserializeBinary 171 | ); 172 | 173 | 174 | /** 175 | * @const 176 | * @type {!grpc.web.AbstractClientBase.MethodInfo< 177 | * !proto.ChatMessage, 178 | * !proto.Empty>} 179 | */ 180 | const methodInfo_ChatService_sendMsg = new grpc.web.AbstractClientBase.MethodInfo( 181 | proto.Empty, 182 | /** 183 | * @param {!proto.ChatMessage} request 184 | * @return {!Uint8Array} 185 | */ 186 | function(request) { 187 | return request.serializeBinary(); 188 | }, 189 | proto.Empty.deserializeBinary 190 | ); 191 | 192 | 193 | /** 194 | * @param {!proto.ChatMessage} request The 195 | * request proto 196 | * @param {?Object} metadata User defined 197 | * call metadata 198 | * @param {function(?grpc.web.Error, ?proto.Empty)} 199 | * callback The callback function(error, response) 200 | * @return {!grpc.web.ClientReadableStream|undefined} 201 | * The XHR Node Readable Stream 202 | */ 203 | proto.ChatServiceClient.prototype.sendMsg = 204 | function(request, metadata, callback) { 205 | return this.client_.rpcCall(this.hostname_ + 206 | '/ChatService/sendMsg', 207 | request, 208 | metadata || {}, 209 | methodDescriptor_ChatService_sendMsg, 210 | callback); 211 | }; 212 | 213 | 214 | /** 215 | * @param {!proto.ChatMessage} request The 216 | * request proto 217 | * @param {?Object} metadata User defined 218 | * call metadata 219 | * @return {!Promise} 220 | * Promise that resolves to the response 221 | */ 222 | proto.ChatServicePromiseClient.prototype.sendMsg = 223 | function(request, metadata) { 224 | return this.client_.unaryCall(this.hostname_ + 225 | '/ChatService/sendMsg', 226 | request, 227 | metadata || {}, 228 | methodDescriptor_ChatService_sendMsg); 229 | }; 230 | 231 | 232 | /** 233 | * @const 234 | * @type {!grpc.web.MethodDescriptor< 235 | * !proto.ReceiveMsgRequest, 236 | * !proto.ChatMessage>} 237 | */ 238 | const methodDescriptor_ChatService_receiveMsg = new grpc.web.MethodDescriptor( 239 | '/ChatService/receiveMsg', 240 | grpc.web.MethodType.SERVER_STREAMING, 241 | proto.ReceiveMsgRequest, 242 | proto.ChatMessage, 243 | /** 244 | * @param {!proto.ReceiveMsgRequest} request 245 | * @return {!Uint8Array} 246 | */ 247 | function(request) { 248 | return request.serializeBinary(); 249 | }, 250 | proto.ChatMessage.deserializeBinary 251 | ); 252 | 253 | 254 | /** 255 | * @const 256 | * @type {!grpc.web.AbstractClientBase.MethodInfo< 257 | * !proto.ReceiveMsgRequest, 258 | * !proto.ChatMessage>} 259 | */ 260 | const methodInfo_ChatService_receiveMsg = new grpc.web.AbstractClientBase.MethodInfo( 261 | proto.ChatMessage, 262 | /** 263 | * @param {!proto.ReceiveMsgRequest} request 264 | * @return {!Uint8Array} 265 | */ 266 | function(request) { 267 | return request.serializeBinary(); 268 | }, 269 | proto.ChatMessage.deserializeBinary 270 | ); 271 | 272 | 273 | /** 274 | * @param {!proto.ReceiveMsgRequest} request The request proto 275 | * @param {?Object} metadata User defined 276 | * call metadata 277 | * @return {!grpc.web.ClientReadableStream} 278 | * The XHR Node Readable Stream 279 | */ 280 | proto.ChatServiceClient.prototype.receiveMsg = 281 | function(request, metadata) { 282 | return this.client_.serverStreaming(this.hostname_ + 283 | '/ChatService/receiveMsg', 284 | request, 285 | metadata || {}, 286 | methodDescriptor_ChatService_receiveMsg); 287 | }; 288 | 289 | 290 | /** 291 | * @param {!proto.ReceiveMsgRequest} request The request proto 292 | * @param {?Object} metadata User defined 293 | * call metadata 294 | * @return {!grpc.web.ClientReadableStream} 295 | * The XHR Node Readable Stream 296 | */ 297 | proto.ChatServicePromiseClient.prototype.receiveMsg = 298 | function(request, metadata) { 299 | return this.client_.serverStreaming(this.hostname_ + 300 | '/ChatService/receiveMsg', 301 | request, 302 | metadata || {}, 303 | methodDescriptor_ChatService_receiveMsg); 304 | }; 305 | 306 | 307 | /** 308 | * @const 309 | * @type {!grpc.web.MethodDescriptor< 310 | * !proto.Empty, 311 | * !proto.UserList>} 312 | */ 313 | const methodDescriptor_ChatService_getAllUsers = new grpc.web.MethodDescriptor( 314 | '/ChatService/getAllUsers', 315 | grpc.web.MethodType.UNARY, 316 | proto.Empty, 317 | proto.UserList, 318 | /** 319 | * @param {!proto.Empty} request 320 | * @return {!Uint8Array} 321 | */ 322 | function(request) { 323 | return request.serializeBinary(); 324 | }, 325 | proto.UserList.deserializeBinary 326 | ); 327 | 328 | 329 | /** 330 | * @const 331 | * @type {!grpc.web.AbstractClientBase.MethodInfo< 332 | * !proto.Empty, 333 | * !proto.UserList>} 334 | */ 335 | const methodInfo_ChatService_getAllUsers = new grpc.web.AbstractClientBase.MethodInfo( 336 | proto.UserList, 337 | /** 338 | * @param {!proto.Empty} request 339 | * @return {!Uint8Array} 340 | */ 341 | function(request) { 342 | return request.serializeBinary(); 343 | }, 344 | proto.UserList.deserializeBinary 345 | ); 346 | 347 | 348 | /** 349 | * @param {!proto.Empty} request The 350 | * request proto 351 | * @param {?Object} metadata User defined 352 | * call metadata 353 | * @param {function(?grpc.web.Error, ?proto.UserList)} 354 | * callback The callback function(error, response) 355 | * @return {!grpc.web.ClientReadableStream|undefined} 356 | * The XHR Node Readable Stream 357 | */ 358 | proto.ChatServiceClient.prototype.getAllUsers = 359 | function(request, metadata, callback) { 360 | return this.client_.rpcCall(this.hostname_ + 361 | '/ChatService/getAllUsers', 362 | request, 363 | metadata || {}, 364 | methodDescriptor_ChatService_getAllUsers, 365 | callback); 366 | }; 367 | 368 | 369 | /** 370 | * @param {!proto.Empty} request The 371 | * request proto 372 | * @param {?Object} metadata User defined 373 | * call metadata 374 | * @return {!Promise} 375 | * Promise that resolves to the response 376 | */ 377 | proto.ChatServicePromiseClient.prototype.getAllUsers = 378 | function(request, metadata) { 379 | return this.client_.unaryCall(this.hostname_ + 380 | '/ChatService/getAllUsers', 381 | request, 382 | metadata || {}, 383 | methodDescriptor_ChatService_getAllUsers); 384 | }; 385 | 386 | 387 | module.exports = proto; 388 | 389 | -------------------------------------------------------------------------------- /src/chat_pb.js: -------------------------------------------------------------------------------- 1 | // source: src/chat.proto 2 | /** 3 | * @fileoverview 4 | * @enhanceable 5 | * @suppress {missingRequire} reports error on implicit type usages. 6 | * @suppress {messageConventions} JS Compiler reports an error if a variable or 7 | * field starts with 'MSG_' and isn't a translatable message. 8 | * @public 9 | */ 10 | // GENERATED CODE -- DO NOT EDIT! 11 | /* eslint-disable */ 12 | // @ts-nocheck 13 | 14 | var jspb = require('google-protobuf'); 15 | var goog = jspb; 16 | var global = Function('return this')(); 17 | 18 | goog.exportSymbol('proto.ChatMessage', null, global); 19 | goog.exportSymbol('proto.Chats', null, global); 20 | goog.exportSymbol('proto.Empty', null, global); 21 | goog.exportSymbol('proto.JoinResponse', null, global); 22 | goog.exportSymbol('proto.ReceiveMsgRequest', null, global); 23 | goog.exportSymbol('proto.User', null, global); 24 | goog.exportSymbol('proto.UserList', null, global); 25 | /** 26 | * Generated by JsPbCodeGenerator. 27 | * @param {Array=} opt_data Optional initial data array, typically from a 28 | * server response, or constructed directly in Javascript. The array is used 29 | * in place and becomes part of the constructed object. It is not cloned. 30 | * If no data is provided, the constructed object will be empty, but still 31 | * valid. 32 | * @extends {jspb.Message} 33 | * @constructor 34 | */ 35 | proto.ChatMessage = function(opt_data) { 36 | jspb.Message.initialize(this, opt_data, 0, -1, null, null); 37 | }; 38 | goog.inherits(proto.ChatMessage, jspb.Message); 39 | if (goog.DEBUG && !COMPILED) { 40 | /** 41 | * @public 42 | * @override 43 | */ 44 | proto.ChatMessage.displayName = 'proto.ChatMessage'; 45 | } 46 | /** 47 | * Generated by JsPbCodeGenerator. 48 | * @param {Array=} opt_data Optional initial data array, typically from a 49 | * server response, or constructed directly in Javascript. The array is used 50 | * in place and becomes part of the constructed object. It is not cloned. 51 | * If no data is provided, the constructed object will be empty, but still 52 | * valid. 53 | * @extends {jspb.Message} 54 | * @constructor 55 | */ 56 | proto.User = function(opt_data) { 57 | jspb.Message.initialize(this, opt_data, 0, -1, null, null); 58 | }; 59 | goog.inherits(proto.User, jspb.Message); 60 | if (goog.DEBUG && !COMPILED) { 61 | /** 62 | * @public 63 | * @override 64 | */ 65 | proto.User.displayName = 'proto.User'; 66 | } 67 | /** 68 | * Generated by JsPbCodeGenerator. 69 | * @param {Array=} opt_data Optional initial data array, typically from a 70 | * server response, or constructed directly in Javascript. The array is used 71 | * in place and becomes part of the constructed object. It is not cloned. 72 | * If no data is provided, the constructed object will be empty, but still 73 | * valid. 74 | * @extends {jspb.Message} 75 | * @constructor 76 | */ 77 | proto.Empty = function(opt_data) { 78 | jspb.Message.initialize(this, opt_data, 0, -1, null, null); 79 | }; 80 | goog.inherits(proto.Empty, jspb.Message); 81 | if (goog.DEBUG && !COMPILED) { 82 | /** 83 | * @public 84 | * @override 85 | */ 86 | proto.Empty.displayName = 'proto.Empty'; 87 | } 88 | /** 89 | * Generated by JsPbCodeGenerator. 90 | * @param {Array=} opt_data Optional initial data array, typically from a 91 | * server response, or constructed directly in Javascript. The array is used 92 | * in place and becomes part of the constructed object. It is not cloned. 93 | * If no data is provided, the constructed object will be empty, but still 94 | * valid. 95 | * @extends {jspb.Message} 96 | * @constructor 97 | */ 98 | proto.UserList = function(opt_data) { 99 | jspb.Message.initialize(this, opt_data, 0, -1, proto.UserList.repeatedFields_, null); 100 | }; 101 | goog.inherits(proto.UserList, jspb.Message); 102 | if (goog.DEBUG && !COMPILED) { 103 | /** 104 | * @public 105 | * @override 106 | */ 107 | proto.UserList.displayName = 'proto.UserList'; 108 | } 109 | /** 110 | * Generated by JsPbCodeGenerator. 111 | * @param {Array=} opt_data Optional initial data array, typically from a 112 | * server response, or constructed directly in Javascript. The array is used 113 | * in place and becomes part of the constructed object. It is not cloned. 114 | * If no data is provided, the constructed object will be empty, but still 115 | * valid. 116 | * @extends {jspb.Message} 117 | * @constructor 118 | */ 119 | proto.Chats = function(opt_data) { 120 | jspb.Message.initialize(this, opt_data, 0, -1, proto.Chats.repeatedFields_, null); 121 | }; 122 | goog.inherits(proto.Chats, jspb.Message); 123 | if (goog.DEBUG && !COMPILED) { 124 | /** 125 | * @public 126 | * @override 127 | */ 128 | proto.Chats.displayName = 'proto.Chats'; 129 | } 130 | /** 131 | * Generated by JsPbCodeGenerator. 132 | * @param {Array=} opt_data Optional initial data array, typically from a 133 | * server response, or constructed directly in Javascript. The array is used 134 | * in place and becomes part of the constructed object. It is not cloned. 135 | * If no data is provided, the constructed object will be empty, but still 136 | * valid. 137 | * @extends {jspb.Message} 138 | * @constructor 139 | */ 140 | proto.JoinResponse = function(opt_data) { 141 | jspb.Message.initialize(this, opt_data, 0, -1, null, null); 142 | }; 143 | goog.inherits(proto.JoinResponse, jspb.Message); 144 | if (goog.DEBUG && !COMPILED) { 145 | /** 146 | * @public 147 | * @override 148 | */ 149 | proto.JoinResponse.displayName = 'proto.JoinResponse'; 150 | } 151 | /** 152 | * Generated by JsPbCodeGenerator. 153 | * @param {Array=} opt_data Optional initial data array, typically from a 154 | * server response, or constructed directly in Javascript. The array is used 155 | * in place and becomes part of the constructed object. It is not cloned. 156 | * If no data is provided, the constructed object will be empty, but still 157 | * valid. 158 | * @extends {jspb.Message} 159 | * @constructor 160 | */ 161 | proto.ReceiveMsgRequest = function(opt_data) { 162 | jspb.Message.initialize(this, opt_data, 0, -1, null, null); 163 | }; 164 | goog.inherits(proto.ReceiveMsgRequest, jspb.Message); 165 | if (goog.DEBUG && !COMPILED) { 166 | /** 167 | * @public 168 | * @override 169 | */ 170 | proto.ReceiveMsgRequest.displayName = 'proto.ReceiveMsgRequest'; 171 | } 172 | 173 | 174 | 175 | if (jspb.Message.GENERATE_TO_OBJECT) { 176 | /** 177 | * Creates an object representation of this proto. 178 | * Field names that are reserved in JavaScript and will be renamed to pb_name. 179 | * Optional fields that are not set will be set to undefined. 180 | * To access a reserved field use, foo.pb_, eg, foo.pb_default. 181 | * For the list of reserved names please see: 182 | * net/proto2/compiler/js/internal/generator.cc#kKeyword. 183 | * @param {boolean=} opt_includeInstance Deprecated. whether to include the 184 | * JSPB instance for transitional soy proto support: 185 | * http://goto/soy-param-migration 186 | * @return {!Object} 187 | */ 188 | proto.ChatMessage.prototype.toObject = function(opt_includeInstance) { 189 | return proto.ChatMessage.toObject(opt_includeInstance, this); 190 | }; 191 | 192 | 193 | /** 194 | * Static version of the {@see toObject} method. 195 | * @param {boolean|undefined} includeInstance Deprecated. Whether to include 196 | * the JSPB instance for transitional soy proto support: 197 | * http://goto/soy-param-migration 198 | * @param {!proto.ChatMessage} msg The msg instance to transform. 199 | * @return {!Object} 200 | * @suppress {unusedLocalVariables} f is only used for nested messages 201 | */ 202 | proto.ChatMessage.toObject = function(includeInstance, msg) { 203 | var f, obj = { 204 | from: jspb.Message.getFieldWithDefault(msg, 1, ""), 205 | msg: jspb.Message.getFieldWithDefault(msg, 2, ""), 206 | time: jspb.Message.getFieldWithDefault(msg, 3, "") 207 | }; 208 | 209 | if (includeInstance) { 210 | obj.$jspbMessageInstance = msg; 211 | } 212 | return obj; 213 | }; 214 | } 215 | 216 | 217 | /** 218 | * Deserializes binary data (in protobuf wire format). 219 | * @param {jspb.ByteSource} bytes The bytes to deserialize. 220 | * @return {!proto.ChatMessage} 221 | */ 222 | proto.ChatMessage.deserializeBinary = function(bytes) { 223 | var reader = new jspb.BinaryReader(bytes); 224 | var msg = new proto.ChatMessage; 225 | return proto.ChatMessage.deserializeBinaryFromReader(msg, reader); 226 | }; 227 | 228 | 229 | /** 230 | * Deserializes binary data (in protobuf wire format) from the 231 | * given reader into the given message object. 232 | * @param {!proto.ChatMessage} msg The message object to deserialize into. 233 | * @param {!jspb.BinaryReader} reader The BinaryReader to use. 234 | * @return {!proto.ChatMessage} 235 | */ 236 | proto.ChatMessage.deserializeBinaryFromReader = function(msg, reader) { 237 | while (reader.nextField()) { 238 | if (reader.isEndGroup()) { 239 | break; 240 | } 241 | var field = reader.getFieldNumber(); 242 | switch (field) { 243 | case 1: 244 | var value = /** @type {string} */ (reader.readString()); 245 | msg.setFrom(value); 246 | break; 247 | case 2: 248 | var value = /** @type {string} */ (reader.readString()); 249 | msg.setMsg(value); 250 | break; 251 | case 3: 252 | var value = /** @type {string} */ (reader.readString()); 253 | msg.setTime(value); 254 | break; 255 | default: 256 | reader.skipField(); 257 | break; 258 | } 259 | } 260 | return msg; 261 | }; 262 | 263 | 264 | /** 265 | * Serializes the message to binary data (in protobuf wire format). 266 | * @return {!Uint8Array} 267 | */ 268 | proto.ChatMessage.prototype.serializeBinary = function() { 269 | var writer = new jspb.BinaryWriter(); 270 | proto.ChatMessage.serializeBinaryToWriter(this, writer); 271 | return writer.getResultBuffer(); 272 | }; 273 | 274 | 275 | /** 276 | * Serializes the given message to binary data (in protobuf wire 277 | * format), writing to the given BinaryWriter. 278 | * @param {!proto.ChatMessage} message 279 | * @param {!jspb.BinaryWriter} writer 280 | * @suppress {unusedLocalVariables} f is only used for nested messages 281 | */ 282 | proto.ChatMessage.serializeBinaryToWriter = function(message, writer) { 283 | var f = undefined; 284 | f = message.getFrom(); 285 | if (f.length > 0) { 286 | writer.writeString( 287 | 1, 288 | f 289 | ); 290 | } 291 | f = message.getMsg(); 292 | if (f.length > 0) { 293 | writer.writeString( 294 | 2, 295 | f 296 | ); 297 | } 298 | f = message.getTime(); 299 | if (f.length > 0) { 300 | writer.writeString( 301 | 3, 302 | f 303 | ); 304 | } 305 | }; 306 | 307 | 308 | /** 309 | * optional string from = 1; 310 | * @return {string} 311 | */ 312 | proto.ChatMessage.prototype.getFrom = function() { 313 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); 314 | }; 315 | 316 | 317 | /** 318 | * @param {string} value 319 | * @return {!proto.ChatMessage} returns this 320 | */ 321 | proto.ChatMessage.prototype.setFrom = function(value) { 322 | return jspb.Message.setProto3StringField(this, 1, value); 323 | }; 324 | 325 | 326 | /** 327 | * optional string msg = 2; 328 | * @return {string} 329 | */ 330 | proto.ChatMessage.prototype.getMsg = function() { 331 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); 332 | }; 333 | 334 | 335 | /** 336 | * @param {string} value 337 | * @return {!proto.ChatMessage} returns this 338 | */ 339 | proto.ChatMessage.prototype.setMsg = function(value) { 340 | return jspb.Message.setProto3StringField(this, 2, value); 341 | }; 342 | 343 | 344 | /** 345 | * optional string time = 3; 346 | * @return {string} 347 | */ 348 | proto.ChatMessage.prototype.getTime = function() { 349 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); 350 | }; 351 | 352 | 353 | /** 354 | * @param {string} value 355 | * @return {!proto.ChatMessage} returns this 356 | */ 357 | proto.ChatMessage.prototype.setTime = function(value) { 358 | return jspb.Message.setProto3StringField(this, 3, value); 359 | }; 360 | 361 | 362 | 363 | 364 | 365 | if (jspb.Message.GENERATE_TO_OBJECT) { 366 | /** 367 | * Creates an object representation of this proto. 368 | * Field names that are reserved in JavaScript and will be renamed to pb_name. 369 | * Optional fields that are not set will be set to undefined. 370 | * To access a reserved field use, foo.pb_, eg, foo.pb_default. 371 | * For the list of reserved names please see: 372 | * net/proto2/compiler/js/internal/generator.cc#kKeyword. 373 | * @param {boolean=} opt_includeInstance Deprecated. whether to include the 374 | * JSPB instance for transitional soy proto support: 375 | * http://goto/soy-param-migration 376 | * @return {!Object} 377 | */ 378 | proto.User.prototype.toObject = function(opt_includeInstance) { 379 | return proto.User.toObject(opt_includeInstance, this); 380 | }; 381 | 382 | 383 | /** 384 | * Static version of the {@see toObject} method. 385 | * @param {boolean|undefined} includeInstance Deprecated. Whether to include 386 | * the JSPB instance for transitional soy proto support: 387 | * http://goto/soy-param-migration 388 | * @param {!proto.User} msg The msg instance to transform. 389 | * @return {!Object} 390 | * @suppress {unusedLocalVariables} f is only used for nested messages 391 | */ 392 | proto.User.toObject = function(includeInstance, msg) { 393 | var f, obj = { 394 | id: jspb.Message.getFieldWithDefault(msg, 1, ""), 395 | name: jspb.Message.getFieldWithDefault(msg, 2, "") 396 | }; 397 | 398 | if (includeInstance) { 399 | obj.$jspbMessageInstance = msg; 400 | } 401 | return obj; 402 | }; 403 | } 404 | 405 | 406 | /** 407 | * Deserializes binary data (in protobuf wire format). 408 | * @param {jspb.ByteSource} bytes The bytes to deserialize. 409 | * @return {!proto.User} 410 | */ 411 | proto.User.deserializeBinary = function(bytes) { 412 | var reader = new jspb.BinaryReader(bytes); 413 | var msg = new proto.User; 414 | return proto.User.deserializeBinaryFromReader(msg, reader); 415 | }; 416 | 417 | 418 | /** 419 | * Deserializes binary data (in protobuf wire format) from the 420 | * given reader into the given message object. 421 | * @param {!proto.User} msg The message object to deserialize into. 422 | * @param {!jspb.BinaryReader} reader The BinaryReader to use. 423 | * @return {!proto.User} 424 | */ 425 | proto.User.deserializeBinaryFromReader = function(msg, reader) { 426 | while (reader.nextField()) { 427 | if (reader.isEndGroup()) { 428 | break; 429 | } 430 | var field = reader.getFieldNumber(); 431 | switch (field) { 432 | case 1: 433 | var value = /** @type {string} */ (reader.readString()); 434 | msg.setId(value); 435 | break; 436 | case 2: 437 | var value = /** @type {string} */ (reader.readString()); 438 | msg.setName(value); 439 | break; 440 | default: 441 | reader.skipField(); 442 | break; 443 | } 444 | } 445 | return msg; 446 | }; 447 | 448 | 449 | /** 450 | * Serializes the message to binary data (in protobuf wire format). 451 | * @return {!Uint8Array} 452 | */ 453 | proto.User.prototype.serializeBinary = function() { 454 | var writer = new jspb.BinaryWriter(); 455 | proto.User.serializeBinaryToWriter(this, writer); 456 | return writer.getResultBuffer(); 457 | }; 458 | 459 | 460 | /** 461 | * Serializes the given message to binary data (in protobuf wire 462 | * format), writing to the given BinaryWriter. 463 | * @param {!proto.User} message 464 | * @param {!jspb.BinaryWriter} writer 465 | * @suppress {unusedLocalVariables} f is only used for nested messages 466 | */ 467 | proto.User.serializeBinaryToWriter = function(message, writer) { 468 | var f = undefined; 469 | f = message.getId(); 470 | if (f.length > 0) { 471 | writer.writeString( 472 | 1, 473 | f 474 | ); 475 | } 476 | f = message.getName(); 477 | if (f.length > 0) { 478 | writer.writeString( 479 | 2, 480 | f 481 | ); 482 | } 483 | }; 484 | 485 | 486 | /** 487 | * optional string id = 1; 488 | * @return {string} 489 | */ 490 | proto.User.prototype.getId = function() { 491 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); 492 | }; 493 | 494 | 495 | /** 496 | * @param {string} value 497 | * @return {!proto.User} returns this 498 | */ 499 | proto.User.prototype.setId = function(value) { 500 | return jspb.Message.setProto3StringField(this, 1, value); 501 | }; 502 | 503 | 504 | /** 505 | * optional string name = 2; 506 | * @return {string} 507 | */ 508 | proto.User.prototype.getName = function() { 509 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); 510 | }; 511 | 512 | 513 | /** 514 | * @param {string} value 515 | * @return {!proto.User} returns this 516 | */ 517 | proto.User.prototype.setName = function(value) { 518 | return jspb.Message.setProto3StringField(this, 2, value); 519 | }; 520 | 521 | 522 | 523 | 524 | 525 | if (jspb.Message.GENERATE_TO_OBJECT) { 526 | /** 527 | * Creates an object representation of this proto. 528 | * Field names that are reserved in JavaScript and will be renamed to pb_name. 529 | * Optional fields that are not set will be set to undefined. 530 | * To access a reserved field use, foo.pb_, eg, foo.pb_default. 531 | * For the list of reserved names please see: 532 | * net/proto2/compiler/js/internal/generator.cc#kKeyword. 533 | * @param {boolean=} opt_includeInstance Deprecated. whether to include the 534 | * JSPB instance for transitional soy proto support: 535 | * http://goto/soy-param-migration 536 | * @return {!Object} 537 | */ 538 | proto.Empty.prototype.toObject = function(opt_includeInstance) { 539 | return proto.Empty.toObject(opt_includeInstance, this); 540 | }; 541 | 542 | 543 | /** 544 | * Static version of the {@see toObject} method. 545 | * @param {boolean|undefined} includeInstance Deprecated. Whether to include 546 | * the JSPB instance for transitional soy proto support: 547 | * http://goto/soy-param-migration 548 | * @param {!proto.Empty} msg The msg instance to transform. 549 | * @return {!Object} 550 | * @suppress {unusedLocalVariables} f is only used for nested messages 551 | */ 552 | proto.Empty.toObject = function(includeInstance, msg) { 553 | var f, obj = { 554 | 555 | }; 556 | 557 | if (includeInstance) { 558 | obj.$jspbMessageInstance = msg; 559 | } 560 | return obj; 561 | }; 562 | } 563 | 564 | 565 | /** 566 | * Deserializes binary data (in protobuf wire format). 567 | * @param {jspb.ByteSource} bytes The bytes to deserialize. 568 | * @return {!proto.Empty} 569 | */ 570 | proto.Empty.deserializeBinary = function(bytes) { 571 | var reader = new jspb.BinaryReader(bytes); 572 | var msg = new proto.Empty; 573 | return proto.Empty.deserializeBinaryFromReader(msg, reader); 574 | }; 575 | 576 | 577 | /** 578 | * Deserializes binary data (in protobuf wire format) from the 579 | * given reader into the given message object. 580 | * @param {!proto.Empty} msg The message object to deserialize into. 581 | * @param {!jspb.BinaryReader} reader The BinaryReader to use. 582 | * @return {!proto.Empty} 583 | */ 584 | proto.Empty.deserializeBinaryFromReader = function(msg, reader) { 585 | while (reader.nextField()) { 586 | if (reader.isEndGroup()) { 587 | break; 588 | } 589 | var field = reader.getFieldNumber(); 590 | switch (field) { 591 | default: 592 | reader.skipField(); 593 | break; 594 | } 595 | } 596 | return msg; 597 | }; 598 | 599 | 600 | /** 601 | * Serializes the message to binary data (in protobuf wire format). 602 | * @return {!Uint8Array} 603 | */ 604 | proto.Empty.prototype.serializeBinary = function() { 605 | var writer = new jspb.BinaryWriter(); 606 | proto.Empty.serializeBinaryToWriter(this, writer); 607 | return writer.getResultBuffer(); 608 | }; 609 | 610 | 611 | /** 612 | * Serializes the given message to binary data (in protobuf wire 613 | * format), writing to the given BinaryWriter. 614 | * @param {!proto.Empty} message 615 | * @param {!jspb.BinaryWriter} writer 616 | * @suppress {unusedLocalVariables} f is only used for nested messages 617 | */ 618 | proto.Empty.serializeBinaryToWriter = function(message, writer) { 619 | var f = undefined; 620 | }; 621 | 622 | 623 | 624 | /** 625 | * List of repeated fields within this message type. 626 | * @private {!Array} 627 | * @const 628 | */ 629 | proto.UserList.repeatedFields_ = [1]; 630 | 631 | 632 | 633 | if (jspb.Message.GENERATE_TO_OBJECT) { 634 | /** 635 | * Creates an object representation of this proto. 636 | * Field names that are reserved in JavaScript and will be renamed to pb_name. 637 | * Optional fields that are not set will be set to undefined. 638 | * To access a reserved field use, foo.pb_, eg, foo.pb_default. 639 | * For the list of reserved names please see: 640 | * net/proto2/compiler/js/internal/generator.cc#kKeyword. 641 | * @param {boolean=} opt_includeInstance Deprecated. whether to include the 642 | * JSPB instance for transitional soy proto support: 643 | * http://goto/soy-param-migration 644 | * @return {!Object} 645 | */ 646 | proto.UserList.prototype.toObject = function(opt_includeInstance) { 647 | return proto.UserList.toObject(opt_includeInstance, this); 648 | }; 649 | 650 | 651 | /** 652 | * Static version of the {@see toObject} method. 653 | * @param {boolean|undefined} includeInstance Deprecated. Whether to include 654 | * the JSPB instance for transitional soy proto support: 655 | * http://goto/soy-param-migration 656 | * @param {!proto.UserList} msg The msg instance to transform. 657 | * @return {!Object} 658 | * @suppress {unusedLocalVariables} f is only used for nested messages 659 | */ 660 | proto.UserList.toObject = function(includeInstance, msg) { 661 | var f, obj = { 662 | usersList: jspb.Message.toObjectList(msg.getUsersList(), 663 | proto.User.toObject, includeInstance) 664 | }; 665 | 666 | if (includeInstance) { 667 | obj.$jspbMessageInstance = msg; 668 | } 669 | return obj; 670 | }; 671 | } 672 | 673 | 674 | /** 675 | * Deserializes binary data (in protobuf wire format). 676 | * @param {jspb.ByteSource} bytes The bytes to deserialize. 677 | * @return {!proto.UserList} 678 | */ 679 | proto.UserList.deserializeBinary = function(bytes) { 680 | var reader = new jspb.BinaryReader(bytes); 681 | var msg = new proto.UserList; 682 | return proto.UserList.deserializeBinaryFromReader(msg, reader); 683 | }; 684 | 685 | 686 | /** 687 | * Deserializes binary data (in protobuf wire format) from the 688 | * given reader into the given message object. 689 | * @param {!proto.UserList} msg The message object to deserialize into. 690 | * @param {!jspb.BinaryReader} reader The BinaryReader to use. 691 | * @return {!proto.UserList} 692 | */ 693 | proto.UserList.deserializeBinaryFromReader = function(msg, reader) { 694 | while (reader.nextField()) { 695 | if (reader.isEndGroup()) { 696 | break; 697 | } 698 | var field = reader.getFieldNumber(); 699 | switch (field) { 700 | case 1: 701 | var value = new proto.User; 702 | reader.readMessage(value,proto.User.deserializeBinaryFromReader); 703 | msg.addUsers(value); 704 | break; 705 | default: 706 | reader.skipField(); 707 | break; 708 | } 709 | } 710 | return msg; 711 | }; 712 | 713 | 714 | /** 715 | * Serializes the message to binary data (in protobuf wire format). 716 | * @return {!Uint8Array} 717 | */ 718 | proto.UserList.prototype.serializeBinary = function() { 719 | var writer = new jspb.BinaryWriter(); 720 | proto.UserList.serializeBinaryToWriter(this, writer); 721 | return writer.getResultBuffer(); 722 | }; 723 | 724 | 725 | /** 726 | * Serializes the given message to binary data (in protobuf wire 727 | * format), writing to the given BinaryWriter. 728 | * @param {!proto.UserList} message 729 | * @param {!jspb.BinaryWriter} writer 730 | * @suppress {unusedLocalVariables} f is only used for nested messages 731 | */ 732 | proto.UserList.serializeBinaryToWriter = function(message, writer) { 733 | var f = undefined; 734 | f = message.getUsersList(); 735 | if (f.length > 0) { 736 | writer.writeRepeatedMessage( 737 | 1, 738 | f, 739 | proto.User.serializeBinaryToWriter 740 | ); 741 | } 742 | }; 743 | 744 | 745 | /** 746 | * repeated User users = 1; 747 | * @return {!Array} 748 | */ 749 | proto.UserList.prototype.getUsersList = function() { 750 | return /** @type{!Array} */ ( 751 | jspb.Message.getRepeatedWrapperField(this, proto.User, 1)); 752 | }; 753 | 754 | 755 | /** 756 | * @param {!Array} value 757 | * @return {!proto.UserList} returns this 758 | */ 759 | proto.UserList.prototype.setUsersList = function(value) { 760 | return jspb.Message.setRepeatedWrapperField(this, 1, value); 761 | }; 762 | 763 | 764 | /** 765 | * @param {!proto.User=} opt_value 766 | * @param {number=} opt_index 767 | * @return {!proto.User} 768 | */ 769 | proto.UserList.prototype.addUsers = function(opt_value, opt_index) { 770 | return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.User, opt_index); 771 | }; 772 | 773 | 774 | /** 775 | * Clears the list making it empty but non-null. 776 | * @return {!proto.UserList} returns this 777 | */ 778 | proto.UserList.prototype.clearUsersList = function() { 779 | return this.setUsersList([]); 780 | }; 781 | 782 | 783 | 784 | /** 785 | * List of repeated fields within this message type. 786 | * @private {!Array} 787 | * @const 788 | */ 789 | proto.Chats.repeatedFields_ = [1]; 790 | 791 | 792 | 793 | if (jspb.Message.GENERATE_TO_OBJECT) { 794 | /** 795 | * Creates an object representation of this proto. 796 | * Field names that are reserved in JavaScript and will be renamed to pb_name. 797 | * Optional fields that are not set will be set to undefined. 798 | * To access a reserved field use, foo.pb_, eg, foo.pb_default. 799 | * For the list of reserved names please see: 800 | * net/proto2/compiler/js/internal/generator.cc#kKeyword. 801 | * @param {boolean=} opt_includeInstance Deprecated. whether to include the 802 | * JSPB instance for transitional soy proto support: 803 | * http://goto/soy-param-migration 804 | * @return {!Object} 805 | */ 806 | proto.Chats.prototype.toObject = function(opt_includeInstance) { 807 | return proto.Chats.toObject(opt_includeInstance, this); 808 | }; 809 | 810 | 811 | /** 812 | * Static version of the {@see toObject} method. 813 | * @param {boolean|undefined} includeInstance Deprecated. Whether to include 814 | * the JSPB instance for transitional soy proto support: 815 | * http://goto/soy-param-migration 816 | * @param {!proto.Chats} msg The msg instance to transform. 817 | * @return {!Object} 818 | * @suppress {unusedLocalVariables} f is only used for nested messages 819 | */ 820 | proto.Chats.toObject = function(includeInstance, msg) { 821 | var f, obj = { 822 | chatsList: jspb.Message.toObjectList(msg.getChatsList(), 823 | proto.ChatMessage.toObject, includeInstance) 824 | }; 825 | 826 | if (includeInstance) { 827 | obj.$jspbMessageInstance = msg; 828 | } 829 | return obj; 830 | }; 831 | } 832 | 833 | 834 | /** 835 | * Deserializes binary data (in protobuf wire format). 836 | * @param {jspb.ByteSource} bytes The bytes to deserialize. 837 | * @return {!proto.Chats} 838 | */ 839 | proto.Chats.deserializeBinary = function(bytes) { 840 | var reader = new jspb.BinaryReader(bytes); 841 | var msg = new proto.Chats; 842 | return proto.Chats.deserializeBinaryFromReader(msg, reader); 843 | }; 844 | 845 | 846 | /** 847 | * Deserializes binary data (in protobuf wire format) from the 848 | * given reader into the given message object. 849 | * @param {!proto.Chats} msg The message object to deserialize into. 850 | * @param {!jspb.BinaryReader} reader The BinaryReader to use. 851 | * @return {!proto.Chats} 852 | */ 853 | proto.Chats.deserializeBinaryFromReader = function(msg, reader) { 854 | while (reader.nextField()) { 855 | if (reader.isEndGroup()) { 856 | break; 857 | } 858 | var field = reader.getFieldNumber(); 859 | switch (field) { 860 | case 1: 861 | var value = new proto.ChatMessage; 862 | reader.readMessage(value,proto.ChatMessage.deserializeBinaryFromReader); 863 | msg.addChats(value); 864 | break; 865 | default: 866 | reader.skipField(); 867 | break; 868 | } 869 | } 870 | return msg; 871 | }; 872 | 873 | 874 | /** 875 | * Serializes the message to binary data (in protobuf wire format). 876 | * @return {!Uint8Array} 877 | */ 878 | proto.Chats.prototype.serializeBinary = function() { 879 | var writer = new jspb.BinaryWriter(); 880 | proto.Chats.serializeBinaryToWriter(this, writer); 881 | return writer.getResultBuffer(); 882 | }; 883 | 884 | 885 | /** 886 | * Serializes the given message to binary data (in protobuf wire 887 | * format), writing to the given BinaryWriter. 888 | * @param {!proto.Chats} message 889 | * @param {!jspb.BinaryWriter} writer 890 | * @suppress {unusedLocalVariables} f is only used for nested messages 891 | */ 892 | proto.Chats.serializeBinaryToWriter = function(message, writer) { 893 | var f = undefined; 894 | f = message.getChatsList(); 895 | if (f.length > 0) { 896 | writer.writeRepeatedMessage( 897 | 1, 898 | f, 899 | proto.ChatMessage.serializeBinaryToWriter 900 | ); 901 | } 902 | }; 903 | 904 | 905 | /** 906 | * repeated ChatMessage chats = 1; 907 | * @return {!Array} 908 | */ 909 | proto.Chats.prototype.getChatsList = function() { 910 | return /** @type{!Array} */ ( 911 | jspb.Message.getRepeatedWrapperField(this, proto.ChatMessage, 1)); 912 | }; 913 | 914 | 915 | /** 916 | * @param {!Array} value 917 | * @return {!proto.Chats} returns this 918 | */ 919 | proto.Chats.prototype.setChatsList = function(value) { 920 | return jspb.Message.setRepeatedWrapperField(this, 1, value); 921 | }; 922 | 923 | 924 | /** 925 | * @param {!proto.ChatMessage=} opt_value 926 | * @param {number=} opt_index 927 | * @return {!proto.ChatMessage} 928 | */ 929 | proto.Chats.prototype.addChats = function(opt_value, opt_index) { 930 | return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.ChatMessage, opt_index); 931 | }; 932 | 933 | 934 | /** 935 | * Clears the list making it empty but non-null. 936 | * @return {!proto.Chats} returns this 937 | */ 938 | proto.Chats.prototype.clearChatsList = function() { 939 | return this.setChatsList([]); 940 | }; 941 | 942 | 943 | 944 | 945 | 946 | if (jspb.Message.GENERATE_TO_OBJECT) { 947 | /** 948 | * Creates an object representation of this proto. 949 | * Field names that are reserved in JavaScript and will be renamed to pb_name. 950 | * Optional fields that are not set will be set to undefined. 951 | * To access a reserved field use, foo.pb_, eg, foo.pb_default. 952 | * For the list of reserved names please see: 953 | * net/proto2/compiler/js/internal/generator.cc#kKeyword. 954 | * @param {boolean=} opt_includeInstance Deprecated. whether to include the 955 | * JSPB instance for transitional soy proto support: 956 | * http://goto/soy-param-migration 957 | * @return {!Object} 958 | */ 959 | proto.JoinResponse.prototype.toObject = function(opt_includeInstance) { 960 | return proto.JoinResponse.toObject(opt_includeInstance, this); 961 | }; 962 | 963 | 964 | /** 965 | * Static version of the {@see toObject} method. 966 | * @param {boolean|undefined} includeInstance Deprecated. Whether to include 967 | * the JSPB instance for transitional soy proto support: 968 | * http://goto/soy-param-migration 969 | * @param {!proto.JoinResponse} msg The msg instance to transform. 970 | * @return {!Object} 971 | * @suppress {unusedLocalVariables} f is only used for nested messages 972 | */ 973 | proto.JoinResponse.toObject = function(includeInstance, msg) { 974 | var f, obj = { 975 | error: jspb.Message.getFieldWithDefault(msg, 1, 0), 976 | msg: jspb.Message.getFieldWithDefault(msg, 2, "") 977 | }; 978 | 979 | if (includeInstance) { 980 | obj.$jspbMessageInstance = msg; 981 | } 982 | return obj; 983 | }; 984 | } 985 | 986 | 987 | /** 988 | * Deserializes binary data (in protobuf wire format). 989 | * @param {jspb.ByteSource} bytes The bytes to deserialize. 990 | * @return {!proto.JoinResponse} 991 | */ 992 | proto.JoinResponse.deserializeBinary = function(bytes) { 993 | var reader = new jspb.BinaryReader(bytes); 994 | var msg = new proto.JoinResponse; 995 | return proto.JoinResponse.deserializeBinaryFromReader(msg, reader); 996 | }; 997 | 998 | 999 | /** 1000 | * Deserializes binary data (in protobuf wire format) from the 1001 | * given reader into the given message object. 1002 | * @param {!proto.JoinResponse} msg The message object to deserialize into. 1003 | * @param {!jspb.BinaryReader} reader The BinaryReader to use. 1004 | * @return {!proto.JoinResponse} 1005 | */ 1006 | proto.JoinResponse.deserializeBinaryFromReader = function(msg, reader) { 1007 | while (reader.nextField()) { 1008 | if (reader.isEndGroup()) { 1009 | break; 1010 | } 1011 | var field = reader.getFieldNumber(); 1012 | switch (field) { 1013 | case 1: 1014 | var value = /** @type {number} */ (reader.readInt32()); 1015 | msg.setError(value); 1016 | break; 1017 | case 2: 1018 | var value = /** @type {string} */ (reader.readString()); 1019 | msg.setMsg(value); 1020 | break; 1021 | default: 1022 | reader.skipField(); 1023 | break; 1024 | } 1025 | } 1026 | return msg; 1027 | }; 1028 | 1029 | 1030 | /** 1031 | * Serializes the message to binary data (in protobuf wire format). 1032 | * @return {!Uint8Array} 1033 | */ 1034 | proto.JoinResponse.prototype.serializeBinary = function() { 1035 | var writer = new jspb.BinaryWriter(); 1036 | proto.JoinResponse.serializeBinaryToWriter(this, writer); 1037 | return writer.getResultBuffer(); 1038 | }; 1039 | 1040 | 1041 | /** 1042 | * Serializes the given message to binary data (in protobuf wire 1043 | * format), writing to the given BinaryWriter. 1044 | * @param {!proto.JoinResponse} message 1045 | * @param {!jspb.BinaryWriter} writer 1046 | * @suppress {unusedLocalVariables} f is only used for nested messages 1047 | */ 1048 | proto.JoinResponse.serializeBinaryToWriter = function(message, writer) { 1049 | var f = undefined; 1050 | f = message.getError(); 1051 | if (f !== 0) { 1052 | writer.writeInt32( 1053 | 1, 1054 | f 1055 | ); 1056 | } 1057 | f = message.getMsg(); 1058 | if (f.length > 0) { 1059 | writer.writeString( 1060 | 2, 1061 | f 1062 | ); 1063 | } 1064 | }; 1065 | 1066 | 1067 | /** 1068 | * optional int32 error = 1; 1069 | * @return {number} 1070 | */ 1071 | proto.JoinResponse.prototype.getError = function() { 1072 | return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0)); 1073 | }; 1074 | 1075 | 1076 | /** 1077 | * @param {number} value 1078 | * @return {!proto.JoinResponse} returns this 1079 | */ 1080 | proto.JoinResponse.prototype.setError = function(value) { 1081 | return jspb.Message.setProto3IntField(this, 1, value); 1082 | }; 1083 | 1084 | 1085 | /** 1086 | * optional string msg = 2; 1087 | * @return {string} 1088 | */ 1089 | proto.JoinResponse.prototype.getMsg = function() { 1090 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); 1091 | }; 1092 | 1093 | 1094 | /** 1095 | * @param {string} value 1096 | * @return {!proto.JoinResponse} returns this 1097 | */ 1098 | proto.JoinResponse.prototype.setMsg = function(value) { 1099 | return jspb.Message.setProto3StringField(this, 2, value); 1100 | }; 1101 | 1102 | 1103 | 1104 | 1105 | 1106 | if (jspb.Message.GENERATE_TO_OBJECT) { 1107 | /** 1108 | * Creates an object representation of this proto. 1109 | * Field names that are reserved in JavaScript and will be renamed to pb_name. 1110 | * Optional fields that are not set will be set to undefined. 1111 | * To access a reserved field use, foo.pb_, eg, foo.pb_default. 1112 | * For the list of reserved names please see: 1113 | * net/proto2/compiler/js/internal/generator.cc#kKeyword. 1114 | * @param {boolean=} opt_includeInstance Deprecated. whether to include the 1115 | * JSPB instance for transitional soy proto support: 1116 | * http://goto/soy-param-migration 1117 | * @return {!Object} 1118 | */ 1119 | proto.ReceiveMsgRequest.prototype.toObject = function(opt_includeInstance) { 1120 | return proto.ReceiveMsgRequest.toObject(opt_includeInstance, this); 1121 | }; 1122 | 1123 | 1124 | /** 1125 | * Static version of the {@see toObject} method. 1126 | * @param {boolean|undefined} includeInstance Deprecated. Whether to include 1127 | * the JSPB instance for transitional soy proto support: 1128 | * http://goto/soy-param-migration 1129 | * @param {!proto.ReceiveMsgRequest} msg The msg instance to transform. 1130 | * @return {!Object} 1131 | * @suppress {unusedLocalVariables} f is only used for nested messages 1132 | */ 1133 | proto.ReceiveMsgRequest.toObject = function(includeInstance, msg) { 1134 | var f, obj = { 1135 | user: jspb.Message.getFieldWithDefault(msg, 1, "") 1136 | }; 1137 | 1138 | if (includeInstance) { 1139 | obj.$jspbMessageInstance = msg; 1140 | } 1141 | return obj; 1142 | }; 1143 | } 1144 | 1145 | 1146 | /** 1147 | * Deserializes binary data (in protobuf wire format). 1148 | * @param {jspb.ByteSource} bytes The bytes to deserialize. 1149 | * @return {!proto.ReceiveMsgRequest} 1150 | */ 1151 | proto.ReceiveMsgRequest.deserializeBinary = function(bytes) { 1152 | var reader = new jspb.BinaryReader(bytes); 1153 | var msg = new proto.ReceiveMsgRequest; 1154 | return proto.ReceiveMsgRequest.deserializeBinaryFromReader(msg, reader); 1155 | }; 1156 | 1157 | 1158 | /** 1159 | * Deserializes binary data (in protobuf wire format) from the 1160 | * given reader into the given message object. 1161 | * @param {!proto.ReceiveMsgRequest} msg The message object to deserialize into. 1162 | * @param {!jspb.BinaryReader} reader The BinaryReader to use. 1163 | * @return {!proto.ReceiveMsgRequest} 1164 | */ 1165 | proto.ReceiveMsgRequest.deserializeBinaryFromReader = function(msg, reader) { 1166 | while (reader.nextField()) { 1167 | if (reader.isEndGroup()) { 1168 | break; 1169 | } 1170 | var field = reader.getFieldNumber(); 1171 | switch (field) { 1172 | case 1: 1173 | var value = /** @type {string} */ (reader.readString()); 1174 | msg.setUser(value); 1175 | break; 1176 | default: 1177 | reader.skipField(); 1178 | break; 1179 | } 1180 | } 1181 | return msg; 1182 | }; 1183 | 1184 | 1185 | /** 1186 | * Serializes the message to binary data (in protobuf wire format). 1187 | * @return {!Uint8Array} 1188 | */ 1189 | proto.ReceiveMsgRequest.prototype.serializeBinary = function() { 1190 | var writer = new jspb.BinaryWriter(); 1191 | proto.ReceiveMsgRequest.serializeBinaryToWriter(this, writer); 1192 | return writer.getResultBuffer(); 1193 | }; 1194 | 1195 | 1196 | /** 1197 | * Serializes the given message to binary data (in protobuf wire 1198 | * format), writing to the given BinaryWriter. 1199 | * @param {!proto.ReceiveMsgRequest} message 1200 | * @param {!jspb.BinaryWriter} writer 1201 | * @suppress {unusedLocalVariables} f is only used for nested messages 1202 | */ 1203 | proto.ReceiveMsgRequest.serializeBinaryToWriter = function(message, writer) { 1204 | var f = undefined; 1205 | f = message.getUser(); 1206 | if (f.length > 0) { 1207 | writer.writeString( 1208 | 1, 1209 | f 1210 | ); 1211 | } 1212 | }; 1213 | 1214 | 1215 | /** 1216 | * optional string user = 1; 1217 | * @return {string} 1218 | */ 1219 | proto.ReceiveMsgRequest.prototype.getUser = function() { 1220 | return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); 1221 | }; 1222 | 1223 | 1224 | /** 1225 | * @param {string} value 1226 | * @return {!proto.ReceiveMsgRequest} returns this 1227 | */ 1228 | proto.ReceiveMsgRequest.prototype.setUser = function(value) { 1229 | return jspb.Message.setProto3StringField(this, 1, value); 1230 | }; 1231 | 1232 | 1233 | goog.object.extend(exports, proto); 1234 | -------------------------------------------------------------------------------- /src/components/Chat/Chat.css: -------------------------------------------------------------------------------- 1 | .chat-input { 2 | display: flex; 3 | justify-content: space-between; 4 | } 5 | 6 | .chat-header { 7 | height: 30px; 8 | padding: 4px; 9 | background-color: rgb(53 151 234); 10 | color: white; 11 | } 12 | 13 | .chat-header h3 { 14 | margin: 4px; 15 | } 16 | 17 | .chat-list { 18 | padding: 4px; 19 | height: 400px; 20 | overflow: scroll; 21 | } 22 | 23 | .chat-input { 24 | margin: 4px 0; 25 | margin-left: 4px; 26 | } 27 | 28 | .chat-input textarea { 29 | border-radius: 20px; 30 | font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; 31 | outline: none; 32 | width: 100%; 33 | /*padding: 6px; */ 34 | box-sizing: content-box; 35 | } 36 | 37 | .chat-input button { 38 | border-radius: 50px; 39 | } 40 | 41 | .chatcard { 42 | background-color: dodgerblue; 43 | padding: 8px; 44 | border-radius: 14px; 45 | margin: 4px; 46 | color: white; 47 | } 48 | 49 | .chatcard-mine { 50 | border-bottom-right-radius: 0; 51 | } 52 | 53 | .chatcard-friend { 54 | border-top-left-radius: 0; 55 | background-color: forestgreen; 56 | } 57 | 58 | .chatcard-msg { 59 | padding: 4px; 60 | } 61 | 62 | .chatcard-time { 63 | text-align: right; 64 | font-size: 10px; 65 | } 66 | -------------------------------------------------------------------------------- /src/components/Chat/index.js: -------------------------------------------------------------------------------- 1 | import "./Chat.css"; 2 | 3 | export default function Chat({ msgList, sendMessage }) { 4 | function handler() { 5 | var msg = window.msgTextArea.value; 6 | sendMessage(msg); 7 | window.msgTextArea.value = ""; 8 | } 9 | 10 | return ( 11 |
12 |
13 |

Group Messages

14 |
15 |
16 | {msgList?.map((chat, i) => ( 17 | 18 | ))} 19 |
20 |
21 |
22 |