mirror of
https://github.com/youwen5/iamb.git
synced 2025-06-20 05:39:52 -07:00
Support uploading image attachments from clipboard (#36)
This commit is contained in:
parent
ad8b4a60d2
commit
2899d4f45a
4 changed files with 197 additions and 1 deletions
149
Cargo.lock
generated
149
Cargo.lock
generated
|
@ -239,6 +239,12 @@ version = "0.6.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
|
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bit_field"
|
||||||
|
version = "0.10.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
|
@ -587,6 +593,17 @@ dependencies = [
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crossbeam-deque"
|
||||||
|
version = "0.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"crossbeam-epoch",
|
||||||
|
"crossbeam-utils",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-epoch"
|
name = "crossbeam-epoch"
|
||||||
version = "0.9.14"
|
version = "0.9.14"
|
||||||
|
@ -650,6 +667,12 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crunchy"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crypto-common"
|
name = "crypto-common"
|
||||||
version = "0.1.6"
|
version = "0.1.6"
|
||||||
|
@ -1009,6 +1032,22 @@ version = "2.5.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
|
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "exr"
|
||||||
|
version = "1.6.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bdd2162b720141a91a054640662d3edce3d50a944a50ffca5313cd951abb35b4"
|
||||||
|
dependencies = [
|
||||||
|
"bit_field",
|
||||||
|
"flume",
|
||||||
|
"half",
|
||||||
|
"lebe",
|
||||||
|
"miniz_oxide",
|
||||||
|
"rayon-core",
|
||||||
|
"smallvec",
|
||||||
|
"zune-inflate",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fancy-regex"
|
name = "fancy-regex"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
|
@ -1029,6 +1068,19 @@ dependencies = [
|
||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flume"
|
||||||
|
version = "0.10.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
|
"nanorand",
|
||||||
|
"pin-project",
|
||||||
|
"spin 0.9.8",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fnv"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
|
@ -1271,6 +1323,16 @@ dependencies = [
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gif"
|
||||||
|
version = "0.11.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3edd93c6756b4dfaf2709eafcc345ba2636565295c198a9cfbf75fa5e3e00b06"
|
||||||
|
dependencies = [
|
||||||
|
"color_quant",
|
||||||
|
"weezl",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "h2"
|
name = "h2"
|
||||||
version = "0.3.16"
|
version = "0.3.16"
|
||||||
|
@ -1290,6 +1352,15 @@ dependencies = [
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "half"
|
||||||
|
version = "2.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "02b4af3693f1b705df946e9fe5631932443781d0aabb423b62fcd4d73f6d2fd0"
|
||||||
|
dependencies = [
|
||||||
|
"crunchy",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.12.3"
|
version = "0.12.3"
|
||||||
|
@ -1427,6 +1498,7 @@ dependencies = [
|
||||||
name = "iamb"
|
name = "iamb"
|
||||||
version = "0.0.7"
|
version = "0.0.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"arboard",
|
||||||
"bitflags 1.3.2",
|
"bitflags 1.3.2",
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
|
@ -1436,6 +1508,7 @@ dependencies = [
|
||||||
"emojis",
|
"emojis",
|
||||||
"gethostname 0.4.1",
|
"gethostname 0.4.1",
|
||||||
"html5ever",
|
"html5ever",
|
||||||
|
"image",
|
||||||
"lazy_static 1.4.0",
|
"lazy_static 1.4.0",
|
||||||
"markup5ever_rcdom",
|
"markup5ever_rcdom",
|
||||||
"matrix-sdk",
|
"matrix-sdk",
|
||||||
|
@ -1506,9 +1579,13 @@ dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"color_quant",
|
"color_quant",
|
||||||
|
"exr",
|
||||||
|
"gif",
|
||||||
|
"jpeg-decoder",
|
||||||
"num-rational",
|
"num-rational",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"png",
|
"png",
|
||||||
|
"scoped_threadpool",
|
||||||
"tiff",
|
"tiff",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1617,6 +1694,9 @@ name = "jpeg-decoder"
|
||||||
version = "0.3.0"
|
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 = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e"
|
checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e"
|
||||||
|
dependencies = [
|
||||||
|
"rayon",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
|
@ -1657,6 +1737,12 @@ version = "1.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lebe"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.140"
|
version = "0.2.140"
|
||||||
|
@ -2044,6 +2130,15 @@ dependencies = [
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nanorand"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.2.8",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "new_debug_unreachable"
|
name = "new_debug_unreachable"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
|
@ -2730,6 +2825,28 @@ dependencies = [
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon"
|
||||||
|
version = "1.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
"rayon-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rayon-core"
|
||||||
|
version = "1.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d"
|
||||||
|
dependencies = [
|
||||||
|
"crossbeam-channel",
|
||||||
|
"crossbeam-deque",
|
||||||
|
"crossbeam-utils",
|
||||||
|
"num_cpus",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rdrand"
|
name = "rdrand"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
@ -2824,7 +2941,7 @@ dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"libc",
|
"libc",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"spin",
|
"spin 0.5.2",
|
||||||
"untrusted",
|
"untrusted",
|
||||||
"web-sys",
|
"web-sys",
|
||||||
"winapi",
|
"winapi",
|
||||||
|
@ -3039,6 +3156,12 @@ dependencies = [
|
||||||
"winapi-util",
|
"winapi-util",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scoped_threadpool"
|
||||||
|
version = "0.1.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
@ -3194,6 +3317,12 @@ version = "1.6.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c"
|
checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "simd-adler32"
|
||||||
|
version = "0.3.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "238abfbb77c1915110ad968465608b68e869e0772622c9656714e73e5a1a522f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "siphasher"
|
name = "siphasher"
|
||||||
version = "0.3.10"
|
version = "0.3.10"
|
||||||
|
@ -3262,6 +3391,15 @@ version = "0.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spin"
|
||||||
|
version = "0.9.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||||
|
dependencies = [
|
||||||
|
"lock_api",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spki"
|
name = "spki"
|
||||||
version = "0.5.4"
|
version = "0.5.4"
|
||||||
|
@ -4341,3 +4479,12 @@ dependencies = [
|
||||||
"syn 1.0.109",
|
"syn 1.0.109",
|
||||||
"synstructure",
|
"synstructure",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zune-inflate"
|
||||||
|
version = "0.2.54"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02"
|
||||||
|
dependencies = [
|
||||||
|
"simd-adler32",
|
||||||
|
]
|
||||||
|
|
|
@ -14,6 +14,7 @@ categories = ["command-line-utilities"]
|
||||||
rust-version = "1.66"
|
rust-version = "1.66"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
arboard = "3.2.0"
|
||||||
bitflags = "1.3.2"
|
bitflags = "1.3.2"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
clap = {version = "4.0", features = ["derive"]}
|
clap = {version = "4.0", features = ["derive"]}
|
||||||
|
@ -23,6 +24,7 @@ dirs = "4.0.0"
|
||||||
emojis = "~0.5.2"
|
emojis = "~0.5.2"
|
||||||
gethostname = "0.4.1"
|
gethostname = "0.4.1"
|
||||||
html5ever = "0.26.0"
|
html5ever = "0.26.0"
|
||||||
|
image = "0.24.5"
|
||||||
markup5ever_rcdom = "0.2.0"
|
markup5ever_rcdom = "0.2.0"
|
||||||
mime = "^0.3.16"
|
mime = "^0.3.16"
|
||||||
mime_guess = "^2.0.4"
|
mime_guess = "^2.0.4"
|
||||||
|
|
|
@ -192,6 +192,7 @@ pub enum RoomAction {
|
||||||
pub enum SendAction {
|
pub enum SendAction {
|
||||||
Submit,
|
Submit,
|
||||||
Upload(String),
|
Upload(String),
|
||||||
|
UploadImage(usize, usize, Cow<'static, [u8]>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
|
@ -360,6 +361,12 @@ pub enum IambError {
|
||||||
|
|
||||||
#[error("Verification request error: {0}")]
|
#[error("Verification request error: {0}")]
|
||||||
VerificationRequestError(#[from] matrix_sdk::encryption::identities::RequestVerificationError),
|
VerificationRequestError(#[from] matrix_sdk::encryption::identities::RequestVerificationError),
|
||||||
|
|
||||||
|
#[error("Image error: {0}")]
|
||||||
|
Image(#[from] image::ImageError),
|
||||||
|
|
||||||
|
#[error("Could not use system clipboard data")]
|
||||||
|
Clipboard,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<IambError> for UIError<IambInfo> {
|
impl From<IambError> for UIError<IambInfo> {
|
||||||
|
|
|
@ -4,6 +4,7 @@ use std::fs;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
use modalkit::editing::store::RegisterError;
|
||||||
use tokio;
|
use tokio;
|
||||||
|
|
||||||
use matrix_sdk::{
|
use matrix_sdk::{
|
||||||
|
@ -471,6 +472,36 @@ impl ChatState {
|
||||||
let msg = MessageType::Text(msg);
|
let msg = MessageType::Text(msg);
|
||||||
let msg = RoomMessageEventContent::new(msg);
|
let msg = RoomMessageEventContent::new(msg);
|
||||||
|
|
||||||
|
(resp.event_id, msg)
|
||||||
|
},
|
||||||
|
SendAction::UploadImage(width, height, bytes) => {
|
||||||
|
// Convert to png because arboard does not give us the mime type.
|
||||||
|
let bytes =
|
||||||
|
image::ImageBuffer::from_raw(width as _, height as _, bytes.into_owned())
|
||||||
|
.ok_or(IambError::Clipboard)
|
||||||
|
.and_then(|imagebuf| {
|
||||||
|
let dynimage = image::DynamicImage::ImageRgba8(imagebuf);
|
||||||
|
let bytes = Vec::<u8>::new();
|
||||||
|
let mut buff = std::io::Cursor::new(bytes);
|
||||||
|
dynimage.write_to(&mut buff, image::ImageOutputFormat::Png)?;
|
||||||
|
Ok(buff.into_inner())
|
||||||
|
})
|
||||||
|
.map_err(IambError::from)?;
|
||||||
|
let mime = mime::IMAGE_PNG;
|
||||||
|
|
||||||
|
let name = Cow::from(format!("Clipboard.png"));
|
||||||
|
let config = AttachmentConfig::new();
|
||||||
|
|
||||||
|
let resp = room
|
||||||
|
.send_attachment(name.as_ref(), &mime, bytes.as_ref(), config)
|
||||||
|
.await
|
||||||
|
.map_err(IambError::from)?;
|
||||||
|
|
||||||
|
// Mock up the local echo message for the scrollback.
|
||||||
|
let msg = TextMessageEventContent::plain(format!("[Attached File: {name}]"));
|
||||||
|
let msg = MessageType::Text(msg);
|
||||||
|
let msg = RoomMessageEventContent::new(msg);
|
||||||
|
|
||||||
(resp.event_id, msg)
|
(resp.event_id, msg)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -617,6 +648,15 @@ impl Editable<ProgramContext, ProgramStore, IambInfo> for ChatState {
|
||||||
// Run command again.
|
// Run command again.
|
||||||
delegate!(self, w => w.editor_command(act, ctx, store))
|
delegate!(self, w => w.editor_command(act, ctx, store))
|
||||||
},
|
},
|
||||||
|
Err(EditError::Register(RegisterError::ClipboardImage(data))) => {
|
||||||
|
let msg = "Do you really want to upload the image from your system clipboard?";
|
||||||
|
let send =
|
||||||
|
IambAction::Send(SendAction::UploadImage(data.width, data.height, data.bytes));
|
||||||
|
let prompt = PromptYesNo::new(msg, vec![Action::from(send)]);
|
||||||
|
let prompt = Box::new(prompt);
|
||||||
|
|
||||||
|
Err(EditError::NeedConfirm(prompt))
|
||||||
|
},
|
||||||
res @ Err(_) => res,
|
res @ Err(_) => res,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue