wip image/file sending
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use base64::{display::Base64Display, prelude::BASE64_URL_SAFE};
|
||||
use dioxus::prelude::*;
|
||||
use mime_guess::Mime;
|
||||
use ordermap::OrderSet;
|
||||
use sir::{css, global_css};
|
||||
use std::collections::HashMap;
|
||||
@@ -27,6 +29,12 @@ pub enum Command {
|
||||
markdown: String,
|
||||
channels: Vec<ChannelId>,
|
||||
},
|
||||
SendFile {
|
||||
bytes: Vec<u8>,
|
||||
name: String,
|
||||
mime: Option<Mime>,
|
||||
channels: Vec<ChannelId>,
|
||||
},
|
||||
SetMute {
|
||||
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]
|
||||
pub fn ChatView() -> Element {
|
||||
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 {
|
||||
onclick: move |_| do_send(),
|
||||
"Send"
|
||||
|
||||
@@ -217,6 +217,47 @@ fn accept_command(
|
||||
u.set_channel_id(channels);
|
||||
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 } => {
|
||||
let mut u = msgs::UserState::new();
|
||||
u.set_session(session);
|
||||
|
||||
Reference in New Issue
Block a user