embed
This commit is contained in:
parent
f1f4df2902
commit
52a292a4d5
6 changed files with 149 additions and 21 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
||||||
/target
|
/target
|
||||||
/node_modules
|
/node_modules
|
||||||
|
/dist
|
83
Cargo.lock
generated
83
Cargo.lock
generated
|
@ -510,7 +510,9 @@ dependencies = [
|
||||||
"derivative",
|
"derivative",
|
||||||
"flume",
|
"flume",
|
||||||
"futures",
|
"futures",
|
||||||
|
"mime_guess",
|
||||||
"mzlib",
|
"mzlib",
|
||||||
|
"rust-embed",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_bytes",
|
"serde_bytes",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
@ -744,6 +746,16 @@ version = "0.3.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mime_guess"
|
||||||
|
version = "2.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"
|
||||||
|
dependencies = [
|
||||||
|
"mime",
|
||||||
|
"unicase",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "miniz_oxide"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
|
@ -940,6 +952,40 @@ dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rust-embed"
|
||||||
|
version = "6.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a36224c3276f8c4ebc8c20f158eca7ca4359c8db89991c4925132aaaf6702661"
|
||||||
|
dependencies = [
|
||||||
|
"rust-embed-impl",
|
||||||
|
"rust-embed-utils",
|
||||||
|
"walkdir",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rust-embed-impl"
|
||||||
|
version = "6.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49b94b81e5b2c284684141a2fb9e2a31be90638caf040bf9afbc5a0416afe1ac"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"rust-embed-utils",
|
||||||
|
"syn 2.0.28",
|
||||||
|
"walkdir",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rust-embed-utils"
|
||||||
|
version = "7.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9d38ff6bf570dc3bb7100fce9f7b60c33fa71d80e88da3f2580df4ff2bdded74"
|
||||||
|
dependencies = [
|
||||||
|
"sha2",
|
||||||
|
"walkdir",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
version = "0.1.23"
|
version = "0.1.23"
|
||||||
|
@ -958,6 +1004,15 @@ version = "1.0.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "same-file"
|
||||||
|
version = "1.0.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||||
|
dependencies = [
|
||||||
|
"winapi-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
|
@ -1332,6 +1387,15 @@ version = "1.16.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
|
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicase"
|
||||||
|
version = "2.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
|
||||||
|
dependencies = [
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-bidi"
|
name = "unicode-bidi"
|
||||||
version = "0.3.13"
|
version = "0.3.13"
|
||||||
|
@ -1386,6 +1450,16 @@ version = "0.9.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "walkdir"
|
||||||
|
version = "2.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698"
|
||||||
|
dependencies = [
|
||||||
|
"same-file",
|
||||||
|
"winapi-util",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "want"
|
name = "want"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
|
@ -1477,6 +1551,15 @@ version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winapi-util"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||||
|
dependencies = [
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-x86_64-pc-windows-gnu"
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
|
|
@ -13,6 +13,8 @@ dashmap = "5.5.0"
|
||||||
derivative = "2.2.0"
|
derivative = "2.2.0"
|
||||||
flume = "0.10.14"
|
flume = "0.10.14"
|
||||||
futures = "0.3.28"
|
futures = "0.3.28"
|
||||||
|
mime_guess = "2.0.4"
|
||||||
|
rust-embed = "6.8.1"
|
||||||
serde = { version = "1.0.183", features = ["derive"] }
|
serde = { version = "1.0.183", features = ["derive"] }
|
||||||
serde_bytes = "0.11.12"
|
serde_bytes = "0.11.12"
|
||||||
serde_json = "1.0.104"
|
serde_json = "1.0.104"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
{
|
{
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite"
|
"dev": "vite",
|
||||||
|
"build": "vite build"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/libsodium-wrappers": "^0.7.10",
|
"@types/libsodium-wrappers": "^0.7.10",
|
||||||
|
|
71
src/main.rs
71
src/main.rs
|
@ -7,7 +7,7 @@ use std::{io::Cursor, mem, sync::Arc};
|
||||||
|
|
||||||
use automerge::{
|
use automerge::{
|
||||||
sync::{State as SyncState, SyncDoc},
|
sync::{State as SyncState, SyncDoc},
|
||||||
Automerge, Value,
|
Automerge,
|
||||||
};
|
};
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::{
|
extract::{
|
||||||
|
@ -18,9 +18,10 @@ use axum::{
|
||||||
routing::get,
|
routing::get,
|
||||||
Router,
|
Router,
|
||||||
};
|
};
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::Utc;
|
||||||
use dashmap::{DashMap, DashSet};
|
use dashmap::{DashMap, DashSet};
|
||||||
use flume::r#async::SendSink;
|
use flume::r#async::SendSink;
|
||||||
|
use frontend::frontend;
|
||||||
use futures::{stream, FutureExt, SinkExt, StreamExt};
|
use futures::{stream, FutureExt, SinkExt, StreamExt};
|
||||||
use message::Message;
|
use message::Message;
|
||||||
use mzlib::axum_error::Result;
|
use mzlib::axum_error::Result;
|
||||||
|
@ -61,7 +62,10 @@ impl Room {
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
let state = AppState::default();
|
let state = AppState::default();
|
||||||
|
|
||||||
let app = Router::new().route("/ws", get(handler)).with_state(state);
|
let app = Router::new()
|
||||||
|
.route("/ws", get(handler))
|
||||||
|
.fallback(frontend)
|
||||||
|
.with_state(state);
|
||||||
|
|
||||||
axum::Server::bind(&"0.0.0.0:3100".parse().unwrap())
|
axum::Server::bind(&"0.0.0.0:3100".parse().unwrap())
|
||||||
.serve(app.into_make_service())
|
.serve(app.into_make_service())
|
||||||
|
@ -70,6 +74,45 @@ async fn main() -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(non_upper_case_globals)]
|
||||||
|
mod frontend {
|
||||||
|
use axum::{
|
||||||
|
body::{Body, HttpBody},
|
||||||
|
http::{header::CONTENT_TYPE, HeaderMap, HeaderValue, StatusCode, Uri},
|
||||||
|
response::IntoResponse,
|
||||||
|
};
|
||||||
|
use rust_embed::RustEmbed;
|
||||||
|
|
||||||
|
#[derive(RustEmbed)]
|
||||||
|
#[folder = "dist/"]
|
||||||
|
struct Frontend;
|
||||||
|
|
||||||
|
pub async fn frontend(uri: Uri) -> impl IntoResponse {
|
||||||
|
let path = uri.path().trim_start_matches("/").to_owned();
|
||||||
|
|
||||||
|
match Frontend::get(&path).or_else(|| Frontend::get("index.html")) {
|
||||||
|
Some(file) => {
|
||||||
|
let guess = mime_guess::from_path(path);
|
||||||
|
let mut headers = HeaderMap::default();
|
||||||
|
if let Some(guess) = guess.first() {
|
||||||
|
headers.append(
|
||||||
|
CONTENT_TYPE,
|
||||||
|
HeaderValue::from_str(&guess.to_string()).unwrap(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let data = file.data.as_ref();
|
||||||
|
let body = Body::from(data.to_owned());
|
||||||
|
let body = body.boxed();
|
||||||
|
(headers, body).into_response()
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
(StatusCode::NOT_FOUND, format!("No route for {}", uri)).into_response()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn handler(
|
async fn handler(
|
||||||
ws: WebSocketUpgrade,
|
ws: WebSocketUpgrade,
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
|
@ -78,7 +121,7 @@ async fn handler(
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_socket(state: AppState, socket: WebSocket) -> Result<()> {
|
async fn handle_socket(state: AppState, socket: WebSocket) -> Result<()> {
|
||||||
let (mut socket_tx, socket_rx) = socket.split();
|
let (socket_tx, socket_rx) = socket.split();
|
||||||
|
|
||||||
// Generate an ID for this connection
|
// Generate an ID for this connection
|
||||||
let client_id = Uuid::new_v4();
|
let client_id = Uuid::new_v4();
|
||||||
|
@ -148,7 +191,7 @@ async fn handle_socket(state: AppState, socket: WebSocket) -> Result<()> {
|
||||||
// println!("inner doc: {:?}", room.document);
|
// println!("inner doc: {:?}", room.document);
|
||||||
|
|
||||||
// Remove current client, so send to everyone else
|
// Remove current client, so send to everyone else
|
||||||
let mut connected_clients = room.connected_clients.clone();
|
let connected_clients = room.connected_clients.clone();
|
||||||
connected_clients.remove(client_id);
|
connected_clients.remove(client_id);
|
||||||
|
|
||||||
// Send to everyone else
|
// Send to everyone else
|
||||||
|
@ -183,11 +226,11 @@ async fn handle_socket(state: AppState, socket: WebSocket) -> Result<()> {
|
||||||
}
|
}
|
||||||
|
|
||||||
Message::ChatMessage {
|
Message::ChatMessage {
|
||||||
timestamp,
|
timestamp: _,
|
||||||
message_id,
|
message_id: _,
|
||||||
room_id,
|
room_id,
|
||||||
author,
|
author: _,
|
||||||
content,
|
content: _,
|
||||||
} => {
|
} => {
|
||||||
let room = state
|
let room = state
|
||||||
.rooms
|
.rooms
|
||||||
|
@ -217,17 +260,15 @@ async fn handle_socket(state: AppState, socket: WebSocket) -> Result<()> {
|
||||||
connected_clients.remove(&client_id);
|
connected_clients.remove(&client_id);
|
||||||
|
|
||||||
match &message {
|
match &message {
|
||||||
Message::FileUploadBegin { header, .. } => {
|
Message::FileUploadBegin { .. } => match room.current_uploader {
|
||||||
match room.current_uploader {
|
|
||||||
Some(v) if v == client_id => {}
|
Some(v) if v == client_id => {}
|
||||||
Some(v) => continue,
|
Some(_v) => continue,
|
||||||
None => room.current_uploader = Some(client_id.clone()),
|
None => room.current_uploader = Some(client_id.clone()),
|
||||||
}
|
},
|
||||||
}
|
|
||||||
Message::FileUploadComplete { .. } => {
|
Message::FileUploadComplete { .. } => {
|
||||||
room.current_uploader = None;
|
room.current_uploader = None;
|
||||||
}
|
}
|
||||||
Message::FileUploadChunk { data, .. } => {}
|
Message::FileUploadChunk { .. } => {}
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::fmt::{write, Formatter};
|
use std::fmt::{Formatter};
|
||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
|
|
||||||
use axum::extract::ws;
|
use axum::extract::ws;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use ciborium::Value;
|
|
||||||
use mzlib::axum_error::Result;
|
use mzlib::axum_error::Result;
|
||||||
use serde::de::Visitor;
|
use serde::de::Visitor;
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
|
Loading…
Reference in a new issue