Update to UI and server
This commit is contained in:
parent
5884bff2c0
commit
87ccab7a4b
13 changed files with 440 additions and 22 deletions
218
client/package-lock.json
generated
218
client/package-lock.json
generated
|
@ -15,6 +15,8 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tauri-apps/cli": "^1.3.0",
|
"@tauri-apps/cli": "^1.3.0",
|
||||||
"@types/react-dom": "^18.2.4",
|
"@types/react-dom": "^18.2.4",
|
||||||
|
"sass": "^1.62.1",
|
||||||
|
"scss": "^0.2.4",
|
||||||
"vite": "^4.3.4"
|
"vite": "^4.3.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -701,6 +703,40 @@
|
||||||
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz",
|
||||||
"integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
|
"integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/anymatch": {
|
||||||
|
"version": "3.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
|
||||||
|
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"normalize-path": "^3.0.0",
|
||||||
|
"picomatch": "^2.0.4"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/binary-extensions": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/braces": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||||
|
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"fill-range": "^7.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/case-anything": {
|
"node_modules/case-anything": {
|
||||||
"version": "2.1.10",
|
"version": "2.1.10",
|
||||||
"resolved": "https://registry.npmjs.org/case-anything/-/case-anything-2.1.10.tgz",
|
"resolved": "https://registry.npmjs.org/case-anything/-/case-anything-2.1.10.tgz",
|
||||||
|
@ -712,6 +748,33 @@
|
||||||
"url": "https://github.com/sponsors/mesqueeb"
|
"url": "https://github.com/sponsors/mesqueeb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/chokidar": {
|
||||||
|
"version": "3.5.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
|
||||||
|
"integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://paulmillr.com/funding/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"anymatch": "~3.1.2",
|
||||||
|
"braces": "~3.0.2",
|
||||||
|
"glob-parent": "~5.1.2",
|
||||||
|
"is-binary-path": "~2.1.0",
|
||||||
|
"is-glob": "~4.0.1",
|
||||||
|
"normalize-path": "~3.0.0",
|
||||||
|
"readdirp": "~3.6.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8.10.0"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"fsevents": "~2.3.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/csstype": {
|
"node_modules/csstype": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
|
||||||
|
@ -778,6 +841,18 @@
|
||||||
"@esbuild/win32-x64": "0.17.18"
|
"@esbuild/win32-x64": "0.17.18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fill-range": {
|
||||||
|
"version": "7.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||||
|
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"to-regex-range": "^5.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fsevents": {
|
"node_modules/fsevents": {
|
||||||
"version": "2.3.2",
|
"version": "2.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||||
|
@ -792,6 +867,18 @@
|
||||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/glob-parent": {
|
||||||
|
"version": "5.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||||
|
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"is-glob": "^4.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/hoist-non-react-statics": {
|
"node_modules/hoist-non-react-statics": {
|
||||||
"version": "3.3.2",
|
"version": "3.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
|
||||||
|
@ -814,6 +901,54 @@
|
||||||
"url": "https://opencollective.com/immer"
|
"url": "https://opencollective.com/immer"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/immutable": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"node_modules/is-binary-path": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"binary-extensions": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-extglob": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-glob": {
|
||||||
|
"version": "4.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||||
|
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"is-extglob": "^2.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/is-number": {
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||||
|
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.12.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/js-tokens": {
|
"node_modules/js-tokens": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||||
|
@ -853,6 +988,15 @@
|
||||||
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/normalize-path": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/object-hash": {
|
"node_modules/object-hash": {
|
||||||
"version": "1.3.1",
|
"version": "1.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.1.tgz",
|
||||||
|
@ -861,12 +1005,33 @@
|
||||||
"node": ">= 0.10.0"
|
"node": ">= 0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/ometa": {
|
||||||
|
"version": "0.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ometa/-/ometa-0.2.2.tgz",
|
||||||
|
"integrity": "sha512-LZuoK/yjU3FvrxPjUXUlZ1bavCfBPqauA7fsNdwi+AVhRdyk2IzgP3JRnevvjzQ6fKHdUw8YISshf53FmpHrng==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/picocolors": {
|
"node_modules/picocolors": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
||||||
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
|
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/picomatch": {
|
||||||
|
"version": "2.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||||
|
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/postcss": {
|
"node_modules/postcss": {
|
||||||
"version": "8.4.23",
|
"version": "8.4.23",
|
||||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz",
|
||||||
|
@ -986,6 +1151,18 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/readdirp": {
|
||||||
|
"version": "3.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||||
|
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"picomatch": "^2.2.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/redux": {
|
"node_modules/redux": {
|
||||||
"version": "4.2.1",
|
"version": "4.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
|
||||||
|
@ -1028,6 +1205,23 @@
|
||||||
"fsevents": "~2.3.2"
|
"fsevents": "~2.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/sass": {
|
||||||
|
"version": "1.62.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/sass/-/sass-1.62.1.tgz",
|
||||||
|
"integrity": "sha512-NHpxIzN29MXvWiuswfc1W3I0N8SXBd8UR26WntmDlRYf0bSADnwnOjsyMZ3lMezSlArD33Vs3YFhp7dWvL770A==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"chokidar": ">=3.0.0 <4.0.0",
|
||||||
|
"immutable": "^4.0.0",
|
||||||
|
"source-map-js": ">=0.6.2 <2.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"sass": "sass.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/scheduler": {
|
"node_modules/scheduler": {
|
||||||
"version": "0.23.0",
|
"version": "0.23.0",
|
||||||
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
|
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
|
||||||
|
@ -1036,6 +1230,18 @@
|
||||||
"loose-envify": "^1.1.0"
|
"loose-envify": "^1.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/scss": {
|
||||||
|
"version": "0.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/scss/-/scss-0.2.4.tgz",
|
||||||
|
"integrity": "sha512-4u8V87F+Q/upVhUmhPnB4C1R11xojkRkWjExL2v0CX2EXTg18VrKd+9JWoeyCp2VEMdSpJsyAvVU+rVjogh51A==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"ometa": "0.2.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/source-map-js": {
|
"node_modules/source-map-js": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||||
|
@ -1045,6 +1251,18 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/to-regex-range": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"is-number": "^7.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ts-poet": {
|
"node_modules/ts-poet": {
|
||||||
"version": "6.4.1",
|
"version": "6.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/ts-poet/-/ts-poet-6.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/ts-poet/-/ts-poet-6.4.1.tgz",
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tauri-apps/cli": "^1.3.0",
|
"@tauri-apps/cli": "^1.3.0",
|
||||||
"@types/react-dom": "^18.2.4",
|
"@types/react-dom": "^18.2.4",
|
||||||
|
"sass": "^1.62.1",
|
||||||
|
"scss": "^0.2.4",
|
||||||
"vite": "^4.3.4"
|
"vite": "^4.3.4"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
@ -12,13 +12,15 @@ type MyGreeterClient = GreeterClient<Channel>;
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
async fn send_message(
|
async fn send_message(
|
||||||
state: tauri::State<'_, Mutex<MyGreeterClient>>,
|
state: tauri::State<'_, Mutex<MyGreeterClient>>,
|
||||||
|
message: String,
|
||||||
) -> Result<(), ()> {
|
) -> Result<(), ()> {
|
||||||
println!("SHIET {state:?}");
|
println!("SHIET {state:?}");
|
||||||
|
|
||||||
let mut client = state.lock().await;
|
let mut client = state.lock().await;
|
||||||
client
|
client
|
||||||
.say_hello(HelloRequest {
|
.say_hello(HelloRequest {
|
||||||
name: "Hellosu".into(),
|
message,
|
||||||
|
..Default::default()
|
||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
|
9
client/src/App.module.scss
Normal file
9
client/src/App.module.scss
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
body, html {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
|
@ -3,17 +3,22 @@ import { Provider } from "react-redux";
|
||||||
import { store } from "./store";
|
import { store } from "./store";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
|
|
||||||
|
import styles from "./App.module.scss";
|
||||||
|
import LeftSidebar from "./components/LeftSidebar";
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
const [currentMessage, setCurrentMessage] = useState("");
|
const [currentMessage, setCurrentMessage] = useState("");
|
||||||
|
|
||||||
const onSubmit = (e) => {
|
const onSubmit = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
invoke("send_message", { content: currentMessage });
|
invoke("send_message", { message: currentMessage });
|
||||||
setCurrentMessage("");
|
setCurrentMessage("");
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
|
<div className={styles.app}>
|
||||||
|
<LeftSidebar />
|
||||||
<h1>mraow chat</h1>
|
<h1>mraow chat</h1>
|
||||||
|
|
||||||
<form onSubmit={onSubmit}>
|
<form onSubmit={onSubmit}>
|
||||||
|
@ -25,6 +30,7 @@ export default function App() {
|
||||||
autoFocus
|
autoFocus
|
||||||
/>
|
/>
|
||||||
</form>
|
</form>
|
||||||
|
</div>
|
||||||
</Provider>
|
</Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
1
client/src/components/CenterPanel.tsx
Normal file
1
client/src/components/CenterPanel.tsx
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export default function CenterPanel() {}
|
3
client/src/components/LeftSidebar.module.scss
Normal file
3
client/src/components/LeftSidebar.module.scss
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
.leftSidebar {
|
||||||
|
background-color: var(--left-sidebar-background-color);
|
||||||
|
}
|
5
client/src/components/LeftSidebar.tsx
Normal file
5
client/src/components/LeftSidebar.tsx
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import styles from "./LeftSidebar.module.scss";
|
||||||
|
|
||||||
|
export default function LeftSidebar() {
|
||||||
|
return <div className={styles.leftSidebar}>Rooms</div>;
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
import { createRoot } from "react-dom/client";
|
import { createRoot } from "react-dom/client";
|
||||||
import App from "./App";
|
import App from "./App";
|
||||||
|
import "./variables.scss";
|
||||||
|
|
||||||
// Render your React component instead
|
// Render your React component instead
|
||||||
const el = document.getElementById("app");
|
const el = document.getElementById("app");
|
||||||
|
|
7
client/src/variables.scss
Normal file
7
client/src/variables.scss
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
:root {
|
||||||
|
--main-background-color: #eee;
|
||||||
|
--left-sidebar-background-color: #ddd;
|
||||||
|
|
||||||
|
@mixin dark-mode() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,7 +12,9 @@ message ChatMessage {
|
||||||
|
|
||||||
message Channel {}
|
message Channel {}
|
||||||
|
|
||||||
message UserList {}
|
message UserList { repeated User user = 1; }
|
||||||
|
|
||||||
|
message RoomList {}
|
||||||
|
|
||||||
message User { string username = 1; }
|
message User { string username = 1; }
|
||||||
|
|
||||||
|
@ -22,6 +24,8 @@ service Chat {
|
||||||
rpc join(User) returns (JoinResponse) {}
|
rpc join(User) returns (JoinResponse) {}
|
||||||
rpc sendMsg(ChatMessage) returns (google.protobuf.Empty) {}
|
rpc sendMsg(ChatMessage) returns (google.protobuf.Empty) {}
|
||||||
rpc receiveMsg(google.protobuf.Empty) returns (stream ChatMessage) {}
|
rpc receiveMsg(google.protobuf.Empty) returns (stream ChatMessage) {}
|
||||||
|
|
||||||
|
rpc listRooms(google.protobuf.Empty) returns (RoomList) {}
|
||||||
rpc getAllUsers(google.protobuf.Empty) returns (UserList) {}
|
rpc getAllUsers(google.protobuf.Empty) returns (UserList) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +38,10 @@ service Greeter {
|
||||||
}
|
}
|
||||||
|
|
||||||
// The request message containing the user's name.
|
// The request message containing the user's name.
|
||||||
message HelloRequest { string name = 1; }
|
message HelloRequest {
|
||||||
|
string name = 1;
|
||||||
|
string message = 2;
|
||||||
|
}
|
||||||
|
|
||||||
// The response message containing the greetings
|
// The response message containing the greetings
|
||||||
message HelloReply { string message = 1; }
|
message HelloReply { string message = 1; }
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
|
mod mux;
|
||||||
|
|
||||||
|
use futures::Stream;
|
||||||
use hyper::Body;
|
use hyper::Body;
|
||||||
use std::{
|
use std::{
|
||||||
|
pin::Pin,
|
||||||
task::{Context, Poll},
|
task::{Context, Poll},
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
@ -7,36 +11,91 @@ use tonic::{body::BoxBody, transport::Server, Request, Response, Status};
|
||||||
use tower::{Layer, Service};
|
use tower::{Layer, Service};
|
||||||
|
|
||||||
use mraow_common::chat_proto::{
|
use mraow_common::chat_proto::{
|
||||||
greeter_server::{Greeter, GreeterServer},
|
chat_server::{Chat, ChatServer},
|
||||||
HelloReply, HelloRequest,
|
ChatMessage, HelloReply, HelloRequest, JoinResponse, RoomList, User,
|
||||||
|
UserList,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type ResponseStream =
|
||||||
|
Pin<Box<dyn Stream<Item = Result<ChatMessage, Status>> + Send>>;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct MyGreeter {}
|
pub struct ChatImpl {}
|
||||||
|
|
||||||
#[tonic::async_trait]
|
#[tonic::async_trait]
|
||||||
impl Greeter for MyGreeter {
|
impl Chat for ChatImpl {
|
||||||
|
type receiveMsgStream = ResponseStream;
|
||||||
|
|
||||||
|
async fn join(
|
||||||
|
&self,
|
||||||
|
request: Request<User>,
|
||||||
|
) -> Result<Response<JoinResponse>, Status> {
|
||||||
|
println!("Join {request:?}");
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn send_msg(
|
||||||
|
&self,
|
||||||
|
request: Request<ChatMessage>,
|
||||||
|
) -> Result<Response<()>, Status> {
|
||||||
|
println!("Send message {request:?}");
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn receive_msg(
|
||||||
|
&self,
|
||||||
|
request: Request<()>,
|
||||||
|
) -> Result<Response<Self::receiveMsgStream>, Status> {
|
||||||
|
println!("Receive message {request:?}");
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn list_rooms(
|
||||||
|
&self,
|
||||||
|
request: Request<()>,
|
||||||
|
) -> Result<Response<RoomList>, Status> {
|
||||||
|
println!("Get all rooms {request:?}");
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_all_users(
|
||||||
|
&self,
|
||||||
|
request: Request<()>,
|
||||||
|
) -> Result<Response<UserList>, Status> {
|
||||||
|
println!("Get all users {request:?}");
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
async fn say_hello(
|
async fn say_hello(
|
||||||
&self,
|
&self,
|
||||||
request: Request<HelloRequest>,
|
request: Request<HelloRequest>,
|
||||||
) -> Result<Response<HelloReply>, Status> {
|
) -> Result<Response<HelloReply>, Status> {
|
||||||
println!("Got a request from {:?}", request.remote_addr());
|
let addr = request.remote_addr();
|
||||||
|
let request = request.into_inner();
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"Got a request from {:?}: {}",
|
||||||
|
addr,
|
||||||
|
request.message
|
||||||
|
);
|
||||||
|
|
||||||
let reply = HelloReply {
|
let reply = HelloReply {
|
||||||
message: format!("Hello {}!", request.into_inner().name),
|
message: format!("Hello {}!", request.name),
|
||||||
};
|
};
|
||||||
Ok(Response::new(reply))
|
Ok(Response::new(reply))
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let addr = "[::1]:50051".parse().unwrap();
|
let addr = "[::1]:50051".parse().unwrap();
|
||||||
let greeter = MyGreeter::default();
|
let greeter = ChatImpl::default();
|
||||||
|
|
||||||
println!("GreeterServer listening on {}", addr);
|
println!("GreeterServer listening on {}", addr);
|
||||||
|
|
||||||
let svc = GreeterServer::new(greeter);
|
let svc = ChatServer::new(greeter);
|
||||||
|
|
||||||
// The stack of middleware that our service will be wrapped in
|
// The stack of middleware that our service will be wrapped in
|
||||||
let layer = tower::ServiceBuilder::new()
|
let layer = tower::ServiceBuilder::new()
|
||||||
|
|
98
server/src/mux.rs
Normal file
98
server/src/mux.rs
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
pin::Pin,
|
||||||
|
task::{Context, Poll},
|
||||||
|
};
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
|
use futures::{future, Future, FutureExt, Sink, Stream};
|
||||||
|
use tokio::{
|
||||||
|
sync::{
|
||||||
|
broadcast::{Receiver, Sender},
|
||||||
|
mpsc::{self, UnboundedReceiver, UnboundedSender},
|
||||||
|
},
|
||||||
|
task::JoinHandle,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct Mux {}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum RoomMessage {}
|
||||||
|
|
||||||
|
pub struct Room {
|
||||||
|
name: String,
|
||||||
|
tx: Sender<RoomMessage>,
|
||||||
|
rx: Receiver<RoomMessage>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Room {
|
||||||
|
pub fn get_handle(&self) -> RoomHandle {
|
||||||
|
RoomHandle {
|
||||||
|
name: self.name.clone(),
|
||||||
|
tx: self.tx.clone(),
|
||||||
|
rx: self.tx.subscribe(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct RoomHandle {
|
||||||
|
name: String,
|
||||||
|
tx: Sender<RoomMessage>,
|
||||||
|
rx: Receiver<RoomMessage>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum CompositeListenerMessage {
|
||||||
|
Room { name: String, message: RoomMessage },
|
||||||
|
JoinRoom(String),
|
||||||
|
DropRoom(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct CompositeListener {
|
||||||
|
current_listening_rooms: HashMap<String, RoomHandle>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CompositeListener {}
|
||||||
|
|
||||||
|
fn create_listener() -> (
|
||||||
|
JoinHandle<()>,
|
||||||
|
UnboundedSender<CompositeListenerMessage>,
|
||||||
|
UnboundedReceiver<CompositeListenerMessage>,
|
||||||
|
) {
|
||||||
|
let (tx, rx) = mpsc::unbounded_channel();
|
||||||
|
|
||||||
|
/*
|
||||||
|
let join_handle = tokio::spawn(async {
|
||||||
|
let mut currently_listening_to: HashMap<String, RoomHandle> =
|
||||||
|
HashMap::new();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
// Build select targets
|
||||||
|
let ouais = rx.recv().boxed();
|
||||||
|
let mut select_targets: Vec<
|
||||||
|
Pin<Box<dyn Future<Output = Option<CompositeListenerMessage>>>>,
|
||||||
|
> = vec![ouais];
|
||||||
|
for (_, room_handle) in currently_listening_to.iter() {
|
||||||
|
select_targets.push(
|
||||||
|
room_handle
|
||||||
|
.rx
|
||||||
|
.recv()
|
||||||
|
.map(|f| {
|
||||||
|
f.ok().map(|m| CompositeListenerMessage::Room {
|
||||||
|
name: room_handle.name.clone(),
|
||||||
|
message: m,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.boxed(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select
|
||||||
|
let result = future::select_all(select_targets).await;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
(join_handle, tx, rx)
|
||||||
|
*/
|
||||||
|
|
||||||
|
todo!()
|
||||||
|
}
|
Loading…
Reference in a new issue