From 5884bff2c02890ceb3ad401bd58a6f2c55088c84 Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Tue, 9 May 2023 02:15:01 -0500 Subject: [PATCH] Some more web app stuff --- Cargo.lock | 1 + client/index.html | 4 +- client/package-lock.json | 248 +++++++++++++++++++++++++++++++++++ client/package.json | 6 + client/src-tauri/Cargo.toml | 1 + client/src-tauri/src/main.rs | 32 ++++- client/src/App.tsx | 30 +++++ client/src/main.ts | 1 - client/src/main.tsx | 8 ++ client/src/store.ts | 8 ++ client/tsconfig.json | 5 + proto/chat.proto | 34 +++-- 12 files changed, 349 insertions(+), 29 deletions(-) create mode 100644 client/src/App.tsx delete mode 100644 client/src/main.ts create mode 100644 client/src/main.tsx create mode 100644 client/src/store.ts create mode 100644 client/tsconfig.json diff --git a/Cargo.lock b/Cargo.lock index 455c435..7ca9de0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1776,6 +1776,7 @@ dependencies = [ "tauri", "tauri-build", "tokio", + "tonic", ] [[package]] diff --git a/client/index.html b/client/index.html index ce4539a..2543e0f 100644 --- a/client/index.html +++ b/client/index.html @@ -1,3 +1,3 @@ -hellosu +
- + diff --git a/client/package-lock.json b/client/package-lock.json index b798338..e1c1016 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -5,13 +5,30 @@ "packages": { "": { "dependencies": { + "@reduxjs/toolkit": "^1.9.5", + "@tauri-apps/api": "^1.3.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-redux": "^8.0.5", "ts-proto": "^1.147.1" }, "devDependencies": { "@tauri-apps/cli": "^1.3.0", + "@types/react-dom": "^18.2.4", "vite": "^4.3.4" } }, + "node_modules/@babel/runtime": { + "version": "7.21.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz", + "integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==", + "dependencies": { + "regenerator-runtime": "^0.13.11" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@esbuild/android-arm": { "version": "0.17.18", "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.18.tgz", @@ -418,6 +435,43 @@ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, + "node_modules/@reduxjs/toolkit": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.5.tgz", + "integrity": "sha512-Rt97jHmfTeaxL4swLRNPD/zV4OxTes4la07Xc4hetpUW/vc75t5m1ANyxG6ymnEQ2FsLQsoMlYB2vV1sO3m8tQ==", + "dependencies": { + "immer": "^9.0.21", + "redux": "^4.2.1", + "redux-thunk": "^2.4.2", + "reselect": "^4.1.8" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18", + "react-redux": "^7.2.1 || ^8.0.2" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, + "node_modules/@tauri-apps/api": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-1.3.0.tgz", + "integrity": "sha512-AH+3FonkKZNtfRtGrObY38PrzEj4d+1emCbwNGu0V2ENbXjlLHMZQlUh+Bhu/CRmjaIwZMGJ3yFvWaZZgTHoog==", + "engines": { + "node": ">= 14.6.0", + "npm": ">= 6.6.0", + "yarn": ">= 1.19.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + } + }, "node_modules/@tauri-apps/cli": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-1.3.0.tgz", @@ -589,6 +643,15 @@ "node": ">= 10" } }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", + "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "node_modules/@types/long": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz", @@ -604,6 +667,40 @@ "resolved": "https://registry.npmjs.org/@types/object-hash/-/object-hash-1.3.4.tgz", "integrity": "sha512-xFdpkAkikBgqBdG9vIlsqffDV8GpvnPEzs0IUtr1v3BEB97ijsFQ4RXVbUZwjFThhB4MDSTUfvmxUD5PGx0wXA==" }, + "node_modules/@types/prop-types": { + "version": "15.7.5", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + }, + "node_modules/@types/react": { + "version": "18.2.6", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.6.tgz", + "integrity": "sha512-wRZClXn//zxCFW+ye/D2qY65UsYP1Fpex2YXorHc8awoNamkMZSvBxwxdYVInsHOZZd2Ppq8isnSzJL5Mpf8OA==", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.2.4", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.4.tgz", + "integrity": "sha512-G2mHoTMTL4yoydITgOGwWdWMVd8sNgyEP85xVmMKAPUBwQWm9wBPQUmvbeF4V3WBY1P7mmL4BkjQ0SqUpf1snw==", + "devOptional": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.3", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz", + "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==" + }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" + }, "node_modules/case-anything": { "version": "2.1.10", "resolved": "https://registry.npmjs.org/case-anything/-/case-anything-2.1.10.tgz", @@ -615,6 +712,11 @@ "url": "https://github.com/sponsors/mesqueeb" } }, + "node_modules/csstype": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + }, "node_modules/dataloader": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-1.4.0.tgz", @@ -690,11 +792,49 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "node_modules/immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, "node_modules/long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/nanoid": { "version": "3.3.6", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", @@ -780,6 +920,98 @@ "pbts": "bin/pbts" } }, + "node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/react-redux": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.0.5.tgz", + "integrity": "sha512-Q2f6fCKxPFpkXt1qNRZdEDLlScsDWyrgSj0mliK59qU6W5gvBiKkdMEG2lJzhd1rCctf0hb6EtePPLZ2e0m1uw==", + "dependencies": { + "@babel/runtime": "^7.12.1", + "@types/hoist-non-react-statics": "^3.3.1", + "@types/use-sync-external-store": "^0.0.3", + "hoist-non-react-statics": "^3.3.2", + "react-is": "^18.0.0", + "use-sync-external-store": "^1.0.0" + }, + "peerDependencies": { + "@types/react": "^16.8 || ^17.0 || ^18.0", + "@types/react-dom": "^16.8 || ^17.0 || ^18.0", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0", + "react-native": ">=0.59", + "redux": "^4" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "node_modules/redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, + "node_modules/redux-thunk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.2.tgz", + "integrity": "sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==", + "peerDependencies": { + "redux": "^4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.13.11", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" + }, + "node_modules/reselect": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz", + "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==" + }, "node_modules/rollup": { "version": "3.21.4", "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.21.4.tgz", @@ -796,6 +1028,14 @@ "fsevents": "~2.3.2" } }, + "node_modules/scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, "node_modules/source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", @@ -839,6 +1079,14 @@ "protobufjs": "^6.8.8" } }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/vite": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/vite/-/vite-4.3.4.tgz", diff --git a/client/package.json b/client/package.json index f9317e5..ed712f8 100644 --- a/client/package.json +++ b/client/package.json @@ -4,9 +4,15 @@ }, "devDependencies": { "@tauri-apps/cli": "^1.3.0", + "@types/react-dom": "^18.2.4", "vite": "^4.3.4" }, "dependencies": { + "@reduxjs/toolkit": "^1.9.5", + "@tauri-apps/api": "^1.3.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-redux": "^8.0.5", "ts-proto": "^1.147.1" } } diff --git a/client/src-tauri/Cargo.toml b/client/src-tauri/Cargo.toml index 6f43337..7455212 100644 --- a/client/src-tauri/Cargo.toml +++ b/client/src-tauri/Cargo.toml @@ -20,6 +20,7 @@ tauri = { version = "1.3.0", features = [] } mraow-common = { path = "../../common" } tokio = { version = "1.28.0", features = ["full"] } anyhow = "1.0.71" +tonic = "0.9.2" [features] default = ["mraow-common/client"] diff --git a/client/src-tauri/src/main.rs b/client/src-tauri/src/main.rs index ae4353f..012a16a 100644 --- a/client/src-tauri/src/main.rs +++ b/client/src-tauri/src/main.rs @@ -2,22 +2,40 @@ #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] use anyhow::Result; +use tauri::async_runtime::{Mutex, TokioHandle}; +use tonic::transport::channel::Channel; use mraow_common::chat_proto::{greeter_client::GreeterClient, HelloRequest}; +type MyGreeterClient = GreeterClient; + +#[tauri::command] +async fn send_message( + state: tauri::State<'_, Mutex>, +) -> Result<(), ()> { + println!("SHIET {state:?}"); + + let mut client = state.lock().await; + client + .say_hello(HelloRequest { + name: "Hellosu".into(), + }) + .await; + + Ok(()) +} + #[tokio::main] async fn main() -> Result<()> { - tauri::async_runtime::set(tokio::runtime::Handle::current()); + tauri::async_runtime::set(TokioHandle::current()); - let mut greeter_client = GreeterClient::connect("http://[::1]:50051").await?; + let greeter_client = GreeterClient::connect("http://[::1]:50051").await?; + let greeter_client = Mutex::new(greeter_client); println!("Connected :)"); - let response = greeter_client.say_hello(HelloRequest { - name: "helosu".into(), - }).await?; - println!("Response: {response:?}"); - tauri::Builder::default() + .manage(greeter_client) + .invoke_handler(tauri::generate_handler![send_message]) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/client/src/App.tsx b/client/src/App.tsx new file mode 100644 index 0000000..882accb --- /dev/null +++ b/client/src/App.tsx @@ -0,0 +1,30 @@ +import { invoke } from "@tauri-apps/api/tauri"; +import { Provider } from "react-redux"; +import { store } from "./store"; +import { useState } from "react"; + +export default function App() { + const [currentMessage, setCurrentMessage] = useState(""); + + const onSubmit = (e) => { + e.preventDefault(); + invoke("send_message", { content: currentMessage }); + setCurrentMessage(""); + }; + + return ( + +

mraow chat

+ +
+ setCurrentMessage(e.currentTarget.value)} + autoFocus + /> +
+
+ ); +} diff --git a/client/src/main.ts b/client/src/main.ts deleted file mode 100644 index 83a5272..0000000 --- a/client/src/main.ts +++ /dev/null @@ -1 +0,0 @@ -console.log("SHIET"); diff --git a/client/src/main.tsx b/client/src/main.tsx new file mode 100644 index 0000000..8038389 --- /dev/null +++ b/client/src/main.tsx @@ -0,0 +1,8 @@ +import { createRoot } from "react-dom/client"; +import App from "./App"; + +// Render your React component instead +const el = document.getElementById("app"); +if (!el) throw new Error("welp"); +const root = createRoot(el); +root.render(); diff --git a/client/src/store.ts b/client/src/store.ts new file mode 100644 index 0000000..c5db1dc --- /dev/null +++ b/client/src/store.ts @@ -0,0 +1,8 @@ +import { configureStore } from "@reduxjs/toolkit"; + +export const store = configureStore({ + reducer: {}, +}); + +export type RootState = ReturnType; +export type AppDispatch = typeof store.dispatch; diff --git a/client/tsconfig.json b/client/tsconfig.json new file mode 100644 index 0000000..cb622d2 --- /dev/null +++ b/client/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "jsx": "react-jsx" + } +} diff --git a/proto/chat.proto b/proto/chat.proto index 9770dbb..9dc2ed1 100644 --- a/proto/chat.proto +++ b/proto/chat.proto @@ -5,24 +5,24 @@ package chat; import "google/protobuf/empty.proto"; message ChatMessage { - string from = 1; - string msg = 2; - string time = 3; + string from = 1; + string msg = 2; + string time = 3; } +message Channel {} + message UserList {} -message User { -} +message User { string username = 1; } -message JoinResponse { -} +message JoinResponse {} -service ChatService { - rpc join(User) returns (JoinResponse) {} - rpc sendMsg(ChatMessage) returns (google.protobuf.Empty) {} - rpc receiveMsg(google.protobuf.Empty) returns (stream ChatMessage) {} - rpc getAllUsers(google.protobuf.Empty) returns (UserList) {} +service Chat { + rpc join(User) returns (JoinResponse) {} + rpc sendMsg(ChatMessage) returns (google.protobuf.Empty) {} + rpc receiveMsg(google.protobuf.Empty) returns (stream ChatMessage) {} + rpc getAllUsers(google.protobuf.Empty) returns (UserList) {} } // Hello world shit @@ -30,15 +30,11 @@ service ChatService { // The greeting service definition. service Greeter { // Sends a greeting - rpc SayHello (HelloRequest) returns (HelloReply) {} + rpc SayHello(HelloRequest) returns (HelloReply) {} } // The request message containing the user's name. -message HelloRequest { - string name = 1; -} +message HelloRequest { string name = 1; } // The response message containing the greetings -message HelloReply { - string message = 1; -} +message HelloReply { string message = 1; }