Chat ...kinda works?

This commit is contained in:
Michael Zhang 2023-05-09 15:19:19 -05:00
parent 080b4e0e09
commit e78d6ddf99
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
7 changed files with 94 additions and 27 deletions

View file

@ -1,15 +1,16 @@
// Prevents additional console window on Windows in release, DO NOT REMOVE!! // Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
use std::sync::Arc; use std::{sync::Arc, thread};
use anyhow::Result; use anyhow::Result;
use mraow_common::chat_proto::{ use mraow_common::chat_proto::{
chat_client::ChatClient, ChatMessage, ReceiveMsgsRequest, chat_client::ChatClient, ChatMessage, ReceiveMsgsRequest, RoomAction,
}; };
use serde_json::json;
use tauri::{ use tauri::{
async_runtime::{Mutex, TokioHandle}, async_runtime::{Mutex, TokioHandle},
State, Manager, State,
}; };
use tonic::{transport::channel::Channel, IntoRequest}; use tonic::{transport::channel::Channel, IntoRequest};
use uuid::Uuid; use uuid::Uuid;
@ -29,11 +30,18 @@ async fn send_message(
let mut client = state.lock().await; let mut client = state.lock().await;
let user_id = user_id.inner(); let user_id = user_id.inner();
client.send_msg(ChatMessage { let resp = client
from_user_id: user_id.0.to_string(), .send_msg(ChatMessage {
content: message, from_user_id: user_id.0.to_string(),
..Default::default() to_room_id: "general".to_string(),
}).await.unwrap(); content: message,
..Default::default()
})
.await
.unwrap();
println!("Sent message to server. {resp:?}");
/* client /* client
.say_hello(HelloRequest { .say_hello(HelloRequest {
message, message,
@ -57,20 +65,35 @@ async fn main() -> Result<()> {
tauri::Builder::default() tauri::Builder::default()
.setup(move |app| { .setup(move |app| {
let main_window = app.get_window("main").unwrap();
tokio::spawn(async move { tokio::spawn(async move {
let stream = { let mut client = chat_client2.lock().await;
let mut client = chat_client2.lock().await; client
client .room_action(RoomAction {
.receive_msgs(ReceiveMsgsRequest { room_id: "general".to_string(),
user_id: uuid.to_string(), user_id: uuid.to_string(),
}) action: "join".to_string(),
.await })
.unwrap() .await
}; .unwrap();
let stream = client
.receive_msgs(ReceiveMsgsRequest {
user_id: uuid.to_string(),
})
.await
.unwrap();
std::mem::drop(client);
let mut stream = stream.into_inner(); let mut stream = stream.into_inner();
while let Ok(Some(message)) = stream.message().await { while let Ok(Some(message)) = stream.message().await {
println!("SHIET message {message:?}"); println!("SHIET message {message:?}");
main_window
.emit_all("new-message", json!({ "content" : message.content }))
.unwrap();
} }
}); });

View file

@ -1,6 +1,5 @@
import { Provider } from "react-redux"; import { Provider } from "react-redux";
import { store } from "./store"; import { store, useAppDispatch } from "./store";
import { useState } from "react";
import styles from "./App.module.scss"; import styles from "./App.module.scss";
import LeftSidebar from "./components/LeftSidebar"; import LeftSidebar from "./components/LeftSidebar";

View file

@ -1,9 +1,11 @@
import { invoke } from "@tauri-apps/api/tauri"; import { invoke } from "@tauri-apps/api/tauri";
import styles from "./CenterPanel.module.scss"; import styles from "./CenterPanel.module.scss";
import { useState } from "react"; import { useEffect, useState } from "react";
import { useAppDispatch, useAppSelector } from "../store"; import { useAppDispatch, useAppSelector } from "../store";
import { messageSelectors, messageSlice } from "../store/messages"; import { messageSelectors, messageSlice } from "../store/messages";
import { v4 as uuidv4 } from "uuid"; import { v4 as uuidv4 } from "uuid";
import { emit, listen } from "@tauri-apps/api/event";
import { appWindow, WebviewWindow } from "@tauri-apps/api/window";
export default function CenterPanel() { export default function CenterPanel() {
const [currentMessage, setCurrentMessage] = useState(""); const [currentMessage, setCurrentMessage] = useState("");
@ -12,12 +14,32 @@ export default function CenterPanel() {
messageSelectors.selectAll(state) messageSelectors.selectAll(state)
); );
useEffect(() => {
let unlisten;
(async () => {
unlisten = await appWindow.listen("new-message", (event) => {
console.log("NEW EVENT", event);
const id = "lol";
const time = Date.now();
const content = event.payload.content;
dispatch(messageSlice.actions.addMessage({ id, time, content }));
});
console.log("Listen handler active.");
})();
return () => {
if (unlisten) unlisten();
};
});
const onSubmit = (e) => { const onSubmit = (e) => {
e.preventDefault(); e.preventDefault();
invoke("send_message", { message: currentMessage }); invoke("send_message", { message: currentMessage });
const id = uuidv4(); const id = uuidv4();
const time = new Date(); const time = Date.now();
dispatch( dispatch(
messageSlice.actions.addMessage({ id, time, content: currentMessage }) messageSlice.actions.addMessage({ id, time, content: currentMessage })
); );
@ -31,7 +53,8 @@ export default function CenterPanel() {
<div className={styles.middlePart}> <div className={styles.middlePart}>
{allMessages.map((msg) => ( {allMessages.map((msg) => (
<div key={msg.id}> <div key={msg.id}>
<small>{msg.time.toISOString()}</small> <small>{new Date(msg.time).toISOString()}</small>
&nbsp;
{msg.content} {msg.content}
</div> </div>
))} ))}

View file

@ -3,7 +3,7 @@ import { RootState } from ".";
export type Message = { export type Message = {
id: string; id: string;
time: Date; time: number;
content: string; content: string;
}; };

View file

@ -37,7 +37,7 @@ message RoomAction {
service Chat { service Chat {
// Rooms // Rooms
rpc roomAction(RoomAction) returns (RoomActionResponse) {} rpc roomAction(RoomAction) returns (google.protobuf.Empty) {}
// Messages // Messages
rpc sendMsg(ChatMessage) returns (google.protobuf.Empty) {} rpc sendMsg(ChatMessage) returns (google.protobuf.Empty) {}

View file

@ -34,9 +34,16 @@ impl Chat for ChatImpl {
async fn room_action( async fn room_action(
&self, &self,
request: Request<RoomAction>, request: Request<RoomAction>,
) -> Result<Response<RoomActionResponse>, Status> { ) -> Result<Response<()>, Status> {
let request = request.into_inner();
println!("Join {request:?}"); println!("Join {request:?}");
todo!()
let user_id = Uuid::parse_str(&request.user_id).unwrap();
let user_id = UserId(user_id);
let room_id = RoomId(request.room_id);
self.mux.user_join_room(user_id, room_id);
Ok(Response::new(()))
} }
async fn send_msg( async fn send_msg(

View file

@ -21,10 +21,12 @@ use uuid::Uuid;
use crate::ResponseStream; use crate::ResponseStream;
#[derive(Debug)]
pub struct TextMessage { pub struct TextMessage {
pub content: String, pub content: String,
} }
#[derive(Debug)]
pub enum RoomMessage { pub enum RoomMessage {
Text(TextMessage), Text(TextMessage),
} }
@ -66,6 +68,8 @@ impl Mux {
members.insert(user_id); members.insert(user_id);
Room { members } Room { members }
}); });
println!("Joined room. Rooms: {:?}", self.rooms);
} }
pub fn send_message_to_room(&self, room_id: RoomId, message: RoomMessage) { pub fn send_message_to_room(&self, room_id: RoomId, message: RoomMessage) {
@ -77,9 +81,11 @@ impl Mux {
None => return, None => return,
}; };
println!("Sending message {message:?} to recipients:");
for user_id in recipients { for user_id in recipients {
// TODO: This should technically never be None? // TODO: This should technically never be None?
let user = self.users.get(&user_id).unwrap(); let user = self.users.get(&user_id).unwrap();
println!(" - user: {user:?}");
user.tx.send(message.clone()); user.tx.send(message.clone());
} }
@ -101,8 +107,15 @@ impl Mux {
let stream = UnboundedReceiverStream::new(rx); let stream = UnboundedReceiverStream::new(rx);
stream stream
.map(|message| { .map(move |message| {
println!("Sending message to {user_id:?}: {message:?}");
let message = match message.as_ref() {
RoomMessage::Text(v) => v,
};
let chat_message = ChatMessage { let chat_message = ChatMessage {
content: message.content.clone(),
..Default::default() ..Default::default()
}; };
@ -112,10 +125,12 @@ impl Mux {
} }
} }
#[derive(Debug)]
pub struct Room { pub struct Room {
members: DashSet<UserId>, members: DashSet<UserId>,
} }
#[derive(Debug)]
pub struct ConnectedUser { pub struct ConnectedUser {
tx: UnboundedSender<Arc<RoomMessage>>, tx: UnboundedSender<Arc<RoomMessage>>,
rx: Option<UnboundedReceiver<Arc<RoomMessage>>>, rx: Option<UnboundedReceiver<Arc<RoomMessage>>>,