Skip to content

Commit

Permalink
Support multiple file uploads.
Browse files Browse the repository at this point in the history
  • Loading branch information
pkulak committed Apr 22, 2023
1 parent 6ea3b3b commit cd470b0
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 43 deletions.
17 changes: 10 additions & 7 deletions src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub enum MatuiEvent {
LoginComplete,
LoginRequired,
LoginStarted,
ProgressStarted(String),
ProgressStarted(String, u64),
ProgressComplete,
RoomMember(Joined, RoomMember),
RoomSelected(Joined),
Expand Down Expand Up @@ -53,7 +53,7 @@ pub fn handle_app_event(event: MatuiEvent, app: &mut App) {
app.set_popup(Popup::Signin(Signin::default()));
}
MatuiEvent::LoginStarted => {
app.set_popup(Popup::Progress(Progress::new("Logging in")));
app.set_popup(Popup::Progress(Progress::new("Logging in", 0)));
}
MatuiEvent::LoginComplete => {
app.popup = None;
Expand All @@ -65,15 +65,18 @@ pub fn handle_app_event(event: MatuiEvent, app: &mut App) {
c.room_member_event(room, member);
}
}
MatuiEvent::ProgressStarted(msg) => app.set_popup(Popup::Progress(Progress::new(&msg))),
MatuiEvent::ProgressStarted(msg, delay) => {
app.set_popup(Popup::Progress(Progress::new(&msg, delay)))
}
MatuiEvent::ProgressComplete => app.popup = None,
MatuiEvent::RoomSelected(room) => app.select_room(room),
MatuiEvent::SyncStarted(st) => {
match st {
SyncType::Initial => {
app.set_popup(Popup::Progress(Progress::new("Performing initial sync.")))
}
SyncType::Latest => app.set_popup(Popup::Progress(Progress::new("Syncing"))),
SyncType::Initial => app.set_popup(Popup::Progress(Progress::new(
"Performing initial sync.",
0,
))),
SyncType::Latest => app.set_popup(Popup::Progress(Progress::new("Syncing", 0))),
};
}
MatuiEvent::SyncComplete => {
Expand Down
61 changes: 34 additions & 27 deletions src/matrix/matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ impl Matrix {
let matrix = self.clone();

self.rt.spawn(async move {
Matrix::send(ProgressStarted("Downloading file.".to_string()));
Matrix::send(ProgressStarted("Downloading file.".to_string(), 250));

let (content_type, request) = match message {
Image(content) => (
Expand Down Expand Up @@ -345,7 +345,7 @@ impl Matrix {

pub fn send_text_message(&self, room: Joined, message: String) {
self.rt.spawn(async move {
Matrix::send(ProgressStarted("Sending message.".to_string()));
Matrix::send(ProgressStarted("Sending message.".to_string(), 500));

if let Err(err) = room
.send(RoomMessageEventContent::text_plain(message), None)
Expand All @@ -358,41 +358,48 @@ impl Matrix {
});
}

pub fn send_attachement(&self, room: Joined, path: PathBuf) {
let content_type = mime_from_path(&path);

let name = path
.file_name()
.unwrap_or_default()
.to_str()
.unwrap_or_default()
.to_string();
pub fn send_attachements(&self, room: Joined, paths: Vec<PathBuf>) {
let total = paths.len();

self.rt.spawn(async move {
Matrix::send(ProgressStarted("Uploading".to_string()));
for (i, path) in paths.into_iter().enumerate() {
Matrix::send(ProgressStarted(
format!("Uploading {} of {}.", i + 1, total),
0,
));

let content_type = mime_from_path(&path);

let name = path
.file_name()
.unwrap_or_default()
.to_str()
.unwrap_or_default()
.to_string();

let data = match fs::read(path.to_str().unwrap()) {
Ok(d) => d,
Err(err) => {
Matrix::send(Error(err.to_string()));
return;
}
};

let data = match fs::read(path.to_str().unwrap()) {
Ok(d) => d,
Err(err) => {
if let Err(err) = room
.send_attachment(&name, &content_type, data, AttachmentConfig::new())
.await
{
Matrix::send(Error(err.to_string()));
return;
}
};

if let Err(err) = room
.send_attachment(&name, &content_type, data, AttachmentConfig::new())
.await
{
Matrix::send(Error(err.to_string()));
Matrix::send(ProgressComplete);
}

Matrix::send(ProgressComplete);
});
}

pub fn send_reaction(&self, room: Joined, event_id: OwnedEventId, key: String) {
self.rt.spawn(async move {
Matrix::send(ProgressStarted("Sending reaction.".to_string()));
Matrix::send(ProgressStarted("Sending reaction.".to_string(), 500));

if let Err(err) = room
.send(
Expand All @@ -410,7 +417,7 @@ impl Matrix {

pub fn redact_event(&self, room: Joined, event_id: OwnedEventId) {
self.rt.spawn(async move {
Matrix::send(ProgressStarted("Removing.".to_string()));
Matrix::send(ProgressStarted("Removing.".to_string(), 500));

if let Err(err) = room.redact(&event_id, None, None).await {
Matrix::send(Error(err.to_string()));
Expand All @@ -422,7 +429,7 @@ impl Matrix {

pub fn replace_event(&self, room: Joined, id: OwnedEventId, message: String) {
self.rt.spawn(async move {
Matrix::send(ProgressStarted("Editing message.".to_string()));
Matrix::send(ProgressStarted("Editing message.".to_string(), 500));

if let Err(err) = room
.send(
Expand Down
4 changes: 2 additions & 2 deletions src/spawn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ use std::path::PathBuf;
use std::process::{Command, Stdio};
use tempfile::Builder;

pub fn get_file_path() -> anyhow::Result<Option<PathBuf>> {
pub fn get_file_paths() -> anyhow::Result<Vec<PathBuf>> {
let home = dirs::home_dir().context("no home directory")?;

let path = FileDialog::new()
.set_location(home.as_path())
.show_open_single_file()?;
.show_open_multiple_file()?;

Ok(path)
}
Expand Down
8 changes: 4 additions & 4 deletions src/widgets/chat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::handler::Batch;
use crate::matrix::matrix::Matrix;
use crate::matrix::roomcache::DecoratedRoom;
use crate::settings::is_muted;
use crate::spawn::{get_file_path, get_text};
use crate::spawn::{get_file_paths, get_text};
use crate::widgets::message::{Message, Reaction, ReactionEvent};
use crate::widgets::react::React;
use crate::widgets::react::ReactResult;
Expand Down Expand Up @@ -259,15 +259,15 @@ impl Chat {
Ok(consumed!())
}
KeyCode::Char('u') => {
let path = get_file_path()?;
let paths = get_file_paths()?;

App::get_sender().send(Event::Redraw)?;

if path.is_none() {
if paths.is_empty() {
return Ok(EventResult::Ignored);
}

self.matrix.send_attachement(self.room(), path.unwrap());
self.matrix.send_attachements(self.room(), paths);

Ok(consumed!())
}
Expand Down
8 changes: 5 additions & 3 deletions src/widgets/progress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@ pub struct Progress {
text: String,
tail: String,
created: Instant,
delay: u64,
}

impl Progress {
pub fn new(text: &str) -> Progress {
pub fn new(text: &str, delay: u64) -> Progress {
Progress {
text: text.to_string(),
tail: "".to_string(),
created: Instant::now(),
delay,
}
}

Expand All @@ -42,8 +44,8 @@ pub struct ProgressWidget<'a> {

impl Widget for ProgressWidget<'_> {
fn render(self, area: Rect, buf: &mut Buffer) {
// don't even render until it's been half a second
if self.progress.created.elapsed() < Duration::from_millis(500) {
// don't render until it's been past the delay
if self.progress.created.elapsed() < Duration::from_millis(self.progress.delay) {
return;
}

Expand Down

0 comments on commit cd470b0

Please sign in to comment.