wip image/file sending

This commit is contained in:
2025-02-12 00:57:28 -07:00
parent de0e41ec85
commit dd65b238d1
4 changed files with 401 additions and 17 deletions
Generated
+323 -17
View File
@@ -127,7 +127,29 @@ dependencies = [
"serde_repr", "serde_repr",
"tokio", "tokio",
"url", "url",
"zbus", "zbus 4.0.1",
]
[[package]]
name = "ashpd"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9c39d707614dbcc6bed00015539f488d8e3fe3e66ed60961efc0c90f4b380b3"
dependencies = [
"async-fs",
"async-net",
"enumflags2",
"futures-channel",
"futures-util",
"rand 0.8.5",
"raw-window-handle 0.6.2",
"serde",
"serde_repr",
"url",
"wayland-backend",
"wayland-client",
"wayland-protocols",
"zbus 5.4.0",
] ]
[[package]] [[package]]
@@ -154,6 +176,30 @@ dependencies = [
"pin-project-lite", "pin-project-lite",
] ]
[[package]]
name = "async-executor"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec"
dependencies = [
"async-task",
"concurrent-queue",
"fastrand",
"futures-lite",
"slab",
]
[[package]]
name = "async-fs"
version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebcd09b382f40fcd159c2d695175b2ae620ffa5f3bd6f664131efff4e8b9e04a"
dependencies = [
"async-lock",
"blocking",
"futures-lite",
]
[[package]] [[package]]
name = "async-io" name = "async-io"
version = "2.4.0" version = "2.4.0"
@@ -184,6 +230,17 @@ dependencies = [
"pin-project-lite", "pin-project-lite",
] ]
[[package]]
name = "async-net"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b948000fad4873c1c9339d60f2623323a0cfd3816e5181033c6a5cb68b2accf7"
dependencies = [
"async-io",
"blocking",
"futures-lite",
]
[[package]] [[package]]
name = "async-process" name = "async-process"
version = "2.3.0" version = "2.3.0"
@@ -1262,7 +1319,7 @@ dependencies = [
"objc", "objc",
"objc_id", "objc_id",
"once_cell", "once_cell",
"rfd", "rfd 0.14.1",
"rustc-hash 1.1.0", "rustc-hash 1.1.0",
"serde", "serde",
"serde_json", "serde_json",
@@ -1574,6 +1631,15 @@ dependencies = [
"syn 2.0.87", "syn 2.0.87",
] ]
[[package]]
name = "dlib"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
dependencies = [
"libloading 0.8.5",
]
[[package]] [[package]]
name = "dlopen2" name = "dlopen2"
version = "0.7.0" version = "0.7.0"
@@ -1597,6 +1663,12 @@ dependencies = [
"syn 2.0.87", "syn 2.0.87",
] ]
[[package]]
name = "downcast-rs"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2"
[[package]] [[package]]
name = "dpi" name = "dpi"
version = "0.1.1" version = "0.1.1"
@@ -1695,12 +1767,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]] [[package]]
name = "errno" name = "errno"
version = "0.3.9" version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
dependencies = [ dependencies = [
"libc", "libc",
"windows-sys 0.52.0", "windows-sys 0.59.0",
] ]
[[package]] [[package]]
@@ -3418,6 +3490,7 @@ name = "mumble-web2-gui"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"asynchronous-codec", "asynchronous-codec",
"base64 0.22.1",
"byteorder", "byteorder",
"color-eyre", "color-eyre",
"cpal", "cpal",
@@ -3434,12 +3507,14 @@ dependencies = [
"lol_html 2.2.0", "lol_html 2.2.0",
"markdown", "markdown",
"merge-io", "merge-io",
"mime_guess",
"mumble-protocol-2x", "mumble-protocol-2x",
"mumble-web2-common", "mumble-web2-common",
"ogg", "ogg",
"once_cell", "once_cell",
"opus", "opus",
"ordermap", "ordermap",
"rfd 0.15.2",
"serde", "serde",
"serde-wasm-bindgen 0.6.5", "serde-wasm-bindgen 0.6.5",
"serde_json", "serde_json",
@@ -3575,6 +3650,7 @@ dependencies = [
"cfg-if", "cfg-if",
"cfg_aliases", "cfg_aliases",
"libc", "libc",
"memoffset",
] ]
[[package]] [[package]]
@@ -3771,6 +3847,7 @@ checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
dependencies = [ dependencies = [
"bitflags 2.6.0", "bitflags 2.6.0",
"block2", "block2",
"dispatch",
"libc", "libc",
"objc2", "objc2",
] ]
@@ -4241,6 +4318,12 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2" checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2"
[[package]]
name = "pollster"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3"
[[package]] [[package]]
name = "polyval" name = "polyval"
version = "0.6.2" version = "0.6.2"
@@ -4303,6 +4386,15 @@ dependencies = [
"toml_edit 0.20.2", "toml_edit 0.20.2",
] ]
[[package]]
name = "proc-macro-crate"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b"
dependencies = [
"toml_edit 0.22.22",
]
[[package]] [[package]]
name = "proc-macro-error" name = "proc-macro-error"
version = "1.0.4" version = "1.0.4"
@@ -4379,6 +4471,15 @@ dependencies = [
"protobuf-codegen", "protobuf-codegen",
] ]
[[package]]
name = "quick-xml"
version = "0.37.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "165859e9e55f79d67b96c5d96f4e88b6f2695a1972849c15a6a3f5c59fc2c003"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "quinn" name = "quinn"
version = "0.11.5" version = "0.11.5"
@@ -4660,7 +4761,7 @@ version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25a73a7337fc24366edfca76ec521f51877b114e42dab584008209cca6719251" checksum = "25a73a7337fc24366edfca76ec521f51877b114e42dab584008209cca6719251"
dependencies = [ dependencies = [
"ashpd", "ashpd 0.8.1",
"block", "block",
"dispatch", "dispatch",
"js-sys", "js-sys",
@@ -4668,7 +4769,7 @@ dependencies = [
"objc", "objc",
"objc-foundation", "objc-foundation",
"objc_id", "objc_id",
"pollster", "pollster 0.3.0",
"raw-window-handle 0.6.2", "raw-window-handle 0.6.2",
"urlencoding", "urlencoding",
"wasm-bindgen", "wasm-bindgen",
@@ -4677,6 +4778,30 @@ dependencies = [
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
[[package]]
name = "rfd"
version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a24763657bff09769a8ccf12c8b8a50416fb035fe199263b4c5071e4e3f006f"
dependencies = [
"ashpd 0.10.2",
"block2",
"core-foundation 0.10.0",
"core-foundation-sys",
"js-sys",
"log",
"objc2",
"objc2-app-kit",
"objc2-foundation",
"pollster 0.4.0",
"raw-window-handle 0.6.2",
"urlencoding",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"windows-sys 0.59.0",
]
[[package]] [[package]]
name = "ring" name = "ring"
version = "0.17.8" version = "0.17.8"
@@ -4772,15 +4897,15 @@ dependencies = [
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "0.38.40" version = "0.38.44"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
dependencies = [ dependencies = [
"bitflags 2.6.0", "bitflags 2.6.0",
"errno", "errno",
"libc", "libc",
"linux-raw-sys", "linux-raw-sys",
"windows-sys 0.52.0", "windows-sys 0.59.0",
] ]
[[package]] [[package]]
@@ -5053,6 +5178,12 @@ dependencies = [
"windows-sys 0.59.0", "windows-sys 0.59.0",
] ]
[[package]]
name = "scoped-tls"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
[[package]] [[package]]
name = "scopeguard" name = "scopeguard"
version = "1.2.0" version = "1.2.0"
@@ -6425,6 +6556,66 @@ dependencies = [
"web-sys", "web-sys",
] ]
[[package]]
name = "wayland-backend"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7208998eaa3870dad37ec8836979581506e0c5c64c20c9e79e9d2a10d6f47bf"
dependencies = [
"cc",
"downcast-rs",
"rustix",
"scoped-tls",
"smallvec",
"wayland-sys",
]
[[package]]
name = "wayland-client"
version = "0.31.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2120de3d33638aaef5b9f4472bff75f07c56379cf76ea320bd3a3d65ecaf73f"
dependencies = [
"bitflags 2.6.0",
"rustix",
"wayland-backend",
"wayland-scanner",
]
[[package]]
name = "wayland-protocols"
version = "0.32.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0781cf46869b37e36928f7b432273c0995aa8aed9552c556fb18754420541efc"
dependencies = [
"bitflags 2.6.0",
"wayland-backend",
"wayland-client",
"wayland-scanner",
]
[[package]]
name = "wayland-scanner"
version = "0.31.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "896fdafd5d28145fce7958917d69f2fd44469b1d4e861cb5961bcbeebc6d1484"
dependencies = [
"proc-macro2",
"quick-xml",
"quote",
]
[[package]]
name = "wayland-sys"
version = "0.31.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbcebb399c77d5aa9fa5db874806ee7b4eba4e73650948e8f93963f128896615"
dependencies = [
"dlib",
"log",
"pkg-config",
]
[[package]] [[package]]
name = "web-sys" name = "web-sys"
version = "0.3.72" version = "0.3.72"
@@ -6930,6 +7121,15 @@ dependencies = [
"memchr", "memchr",
] ]
[[package]]
name = "winnow"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59690dea168f2198d1a3b0cac23b8063efcd11012f10ae4698f284808c8ef603"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "write16" name = "write16"
version = "1.0.0" version = "1.0.0"
@@ -7087,9 +7287,45 @@ dependencies = [
"uds_windows", "uds_windows",
"windows-sys 0.52.0", "windows-sys 0.52.0",
"xdg-home", "xdg-home",
"zbus_macros", "zbus_macros 4.0.1",
"zbus_names", "zbus_names 3.0.0",
"zvariant", "zvariant 4.0.0",
]
[[package]]
name = "zbus"
version = "5.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbddd8b6cb25d5d8ec1b23277b45299a98bfb220f1761ca11e186d5c702507f8"
dependencies = [
"async-broadcast",
"async-executor",
"async-fs",
"async-io",
"async-lock",
"async-process",
"async-recursion",
"async-task",
"async-trait",
"blocking",
"enumflags2",
"event-listener",
"futures-core",
"futures-util",
"hex",
"nix 0.29.0",
"ordered-stream",
"serde",
"serde_repr",
"static_assertions",
"tracing",
"uds_windows",
"windows-sys 0.59.0",
"winnow 0.7.2",
"xdg-home",
"zbus_macros 5.4.0",
"zbus_names 4.2.0",
"zvariant 5.4.0",
] ]
[[package]] [[package]]
@@ -7103,7 +7339,22 @@ dependencies = [
"quote", "quote",
"regex", "regex",
"syn 1.0.109", "syn 1.0.109",
"zvariant_utils", "zvariant_utils 1.1.0",
]
[[package]]
name = "zbus_macros"
version = "5.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dac404d48b4e9cf193c8b49589f3280ceca5ff63519e7e64f55b4cf9c47ce146"
dependencies = [
"proc-macro-crate 3.2.0",
"proc-macro2",
"quote",
"syn 2.0.87",
"zbus_names 4.2.0",
"zvariant 5.4.0",
"zvariant_utils 3.2.0",
] ]
[[package]] [[package]]
@@ -7114,7 +7365,19 @@ checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c"
dependencies = [ dependencies = [
"serde", "serde",
"static_assertions", "static_assertions",
"zvariant", "zvariant 4.0.0",
]
[[package]]
name = "zbus_names"
version = "4.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7be68e64bf6ce8db94f63e72f0c7eb9a60d733f7e0499e628dfab0f84d6bcb97"
dependencies = [
"serde",
"static_assertions",
"winnow 0.7.2",
"zvariant 5.4.0",
] ]
[[package]] [[package]]
@@ -7198,7 +7461,23 @@ dependencies = [
"serde", "serde",
"static_assertions", "static_assertions",
"url", "url",
"zvariant_derive", "zvariant_derive 4.0.0",
]
[[package]]
name = "zvariant"
version = "5.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2df9ee044893fcffbdc25de30546edef3e32341466811ca18421e3cd6c5a3ac"
dependencies = [
"endi",
"enumflags2",
"serde",
"static_assertions",
"url",
"winnow 0.7.2",
"zvariant_derive 5.4.0",
"zvariant_utils 3.2.0",
] ]
[[package]] [[package]]
@@ -7211,7 +7490,20 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 1.0.109", "syn 1.0.109",
"zvariant_utils", "zvariant_utils 1.1.0",
]
[[package]]
name = "zvariant_derive"
version = "5.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74170caa85b8b84cc4935f2d56a57c7a15ea6185ccdd7eadb57e6edd90f94b2f"
dependencies = [
"proc-macro-crate 3.2.0",
"proc-macro2",
"quote",
"syn 2.0.87",
"zvariant_utils 3.2.0",
] ]
[[package]] [[package]]
@@ -7224,3 +7516,17 @@ dependencies = [
"quote", "quote",
"syn 1.0.109", "syn 1.0.109",
] ]
[[package]]
name = "zvariant_utils"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e16edfee43e5d7b553b77872d99bc36afdda75c223ca7ad5e3fbecd82ca5fc34"
dependencies = [
"proc-macro2",
"quote",
"serde",
"static_assertions",
"syn 2.0.87",
"winnow 0.7.2",
]
+3
View File
@@ -90,6 +90,9 @@ tracing = "0.1.40"
color-eyre = "0.6.3" color-eyre = "0.6.3"
crossbeam-queue = "0.3.11" crossbeam-queue = "0.3.11"
lol_html = "2.2.0" lol_html = "2.2.0"
rfd = "0.15.2"
base64 = "0.22"
mime_guess = "2.0.5"
[features] [features]
web = [ web = [
+34
View File
@@ -1,6 +1,8 @@
#![allow(non_snake_case)] #![allow(non_snake_case)]
use base64::{display::Base64Display, prelude::BASE64_URL_SAFE};
use dioxus::prelude::*; use dioxus::prelude::*;
use mime_guess::Mime;
use ordermap::OrderSet; use ordermap::OrderSet;
use sir::{css, global_css}; use sir::{css, global_css};
use std::collections::HashMap; use std::collections::HashMap;
@@ -27,6 +29,12 @@ pub enum Command {
markdown: String, markdown: String,
channels: Vec<ChannelId>, channels: Vec<ChannelId>,
}, },
SendFile {
bytes: Vec<u8>,
name: String,
mime: Option<Mime>,
channels: Vec<ChannelId>,
},
SetMute { SetMute {
mute: bool, mute: bool,
}, },
@@ -243,6 +251,28 @@ pub fn Channel(id: ChannelId) -> Element {
) )
} }
pub fn pick_and_send_file(net: &Coroutine<Command>) {
let channels = if let Some(user) = STATE.server.read().this_user() {
vec![user.channel]
} else {
return;
};
let dialog = rfd::AsyncFileDialog::new().pick_file();
let sender = net.tx();
spawn(async move {
let Some(handle) = dialog.await else { return };
let name = handle.file_name();
let bytes = handle.read().await;
let mime = mime_guess::from_path(&name).first();
let _ = sender.unbounded_send(SendFile {
bytes,
name,
mime,
channels,
});
});
}
#[component] #[component]
pub fn ChatView() -> Element { pub fn ChatView() -> Element {
let net: Coroutine<Command> = use_coroutine_handle(); let net: Coroutine<Command> = use_coroutine_handle();
@@ -321,6 +351,10 @@ pub fn ChatView() -> Element {
} }
} }
} }
button {
onclick: move |_| pick_and_send_file(&net),
"File"
}
button { button {
onclick: move |_| do_send(), onclick: move |_| do_send(),
"Send" "Send"
+41
View File
@@ -217,6 +217,47 @@ fn accept_command(
u.set_channel_id(channels); u.set_channel_id(channels);
let _ = send_chan.unbounded_send(u.into()); let _ = send_chan.unbounded_send(u.into());
} }
SendFile {
ref bytes,
name,
mime,
channels,
} => {
use base64::{display::Base64Display, prelude::BASE64_STANDARD};
let html = match mime {
Some(mime) if mime.type_() == "image" => format!(
"<img src=\"data:{};base64,{}\" />",
mime,
Base64Display::new(bytes, &BASE64_STANDARD)
),
Some(mime) => format!(
"<a href=\"data:{};base64,{}\" download>{name}</a>",
mime,
Base64Display::new(bytes, &BASE64_STANDARD)
),
None => format!(
"<a href=\"data:application/octet-stream;base64,{}\" download>{name}</a>",
Base64Display::new(bytes, &BASE64_STANDARD)
),
};
{
let mut server = STATE.server.write();
let Some(me) = server.session else {
bail!("not signed in with a session id")
};
server.chat.push(Chat {
raw: "".to_string(),
dangerous_html: html.clone(),
sender: Some(me),
})
}
let mut u = msgs::TextMessage::new();
u.set_message(html);
u.set_channel_id(channels);
let _ = send_chan.unbounded_send(u.into());
}
SetMute { mute } => { SetMute { mute } => {
let mut u = msgs::UserState::new(); let mut u = msgs::UserState::new();
u.set_session(session); u.set_session(session);