Skip to content

Commit

Permalink
Added notifications using libnotify
Browse files Browse the repository at this point in the history
  • Loading branch information
danigm committed Aug 30, 2017
1 parent d6fed8c commit 591d65a
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 34 deletions.
10 changes: 7 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ version = "0.1.0"
chrono = "0.4.0"
gdk-pixbuf = "0.2.0"
gio = "0.2.0"
glib = "0.3.1"
regex = "0.2.2"
reqwest = "0.7.3"
secret-service = "0.4.0"
Expand All @@ -16,10 +17,13 @@ time = "0.1.38"
url = "1.5.1"
xdg = "2.1.0"

[dependencies.cairo-rs]
features = ["png"]
version = "0.2.0"

[dependencies.gtk]
features = ["v3_22"]
version = "0.2.0"

[dependencies.cairo-rs]
version = "0.2.0"
features = ["png"]
[dependencies.libnotify]
git = "https://github.com/danigm/rust-libnotify"
6 changes: 6 additions & 0 deletions TODO
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Fixs:
* Fix room list after join
* Ignore launched threads when changing room...
* Sort rooms by last message or fav?

Expand All @@ -16,6 +17,11 @@ Functionality:
* Send media messages (images / videos)
* Store last read message to show differently

Events to manage:
* New room events
* Invite event
* Join events

Other stuff:
* Set the app name correctly to show in the shell topbar

Expand Down
94 changes: 71 additions & 23 deletions src/app.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
extern crate glib;
extern crate gtk;
extern crate gio;
extern crate gdk_pixbuf;

extern crate secret_service;
extern crate libnotify;

use self::secret_service::SecretService;
use self::secret_service::EncryptionType;

Expand Down Expand Up @@ -45,6 +47,7 @@ pub struct AppOp {
pub backend: Sender<backend::BKCommand>,
pub active_room: String,
pub members: HashMap<String, Member>,
pub rooms: HashMap<String, Room>,
pub load_more_btn: gtk::Button,
}

Expand Down Expand Up @@ -124,7 +127,6 @@ impl AppOp {
let ser = server_url.clone();
self.backend.send(BKCommand::Register(uname, pass, ser)).unwrap();
self.hide_popup();
self.clear_room_list();
}

pub fn connect(&self, username: String, password: String, server: Option<String>) {
Expand All @@ -145,7 +147,6 @@ impl AppOp {
let ser = server_url.clone();
self.backend.send(BKCommand::Login(uname, pass, ser)).unwrap();
self.hide_popup();
self.clear_room_list();
}

pub fn connect_guest(&self, server: Option<String>) {
Expand All @@ -157,7 +158,6 @@ impl AppOp {
self.show_user_loading();
self.backend.send(BKCommand::Guest(server_url)).unwrap();
self.hide_popup();
self.clear_room_list();
}

pub fn get_username(&self) {
Expand Down Expand Up @@ -295,7 +295,11 @@ impl AppOp {
}

pub fn sync(&self) {
self.backend.send(BKCommand::Sync).unwrap();
let tx = self.backend.clone();
gtk::timeout_add(1000, move || {
tx.send(BKCommand::Sync).unwrap();
gtk::Continue(false)
});
}

pub fn set_rooms(&mut self, rooms: Vec<Room>, def: Option<Room>) {
Expand All @@ -304,7 +308,11 @@ impl AppOp {

let mut array: Vec<Room> = vec![];

self.rooms.clear();
store.clear();

for r in rooms {
self.rooms.insert(r.id.clone(), r.clone());
array.push(r);
}

Expand Down Expand Up @@ -340,17 +348,10 @@ impl AppOp {
.expect("Can't find main_content_stack in ui file.")
.set_visible_child_name("Chat");

self.clear_room_list();
self.room_panel(RoomPanel::Loading);
self.backend.send(BKCommand::SyncForced).unwrap();
}

pub fn clear_room_list(&self) {
let store: gtk::TreeStore = self.gtk_builder.get_object("rooms_tree_store")
.expect("Couldn't find rooms_tree_store in ui file.");
store.clear();
}

pub fn set_active_room(&mut self, room: String, name: String) {
self.active_room = room;

Expand Down Expand Up @@ -604,6 +605,50 @@ impl AppOp {
btn.set_label("Search");
btn.set_sensitive(true);
}

pub fn notify(&self, msg: &Message) {
let roomname = match self.rooms.get(&msg.room) {
Some(r) => r.name.clone(),
None => msg.room.clone(),
};

let mut body = msg.body.clone();
body.truncate(80);

let (tx, rx): (Sender<(String, String)>, Receiver<(String, String)>) = channel();
self.backend.send(BKCommand::GetUserInfoAsync(msg.sender.clone(), tx)).unwrap();
gtk::timeout_add(50, move || {
match rx.try_recv() {
Err(_) => gtk::Continue(true),
Ok((name, avatar)) => {
let summary = format!("@{} / {}", name, roomname);
let n = libnotify::Notification::new(&summary,
Some(&body[..]),
Some(&avatar[..]));
n.show().unwrap();
gtk::Continue(false)
}
}
});
}

pub fn show_room_messages(&self, msgs: Vec<Message>, init: bool) {
for msg in msgs.iter() {
self.add_room_message(msg, MsgPos::Bottom);
if !init {
self.notify(msg);
}
}

if !msgs.is_empty() {
self.scroll_down();
self.mark_as_read(msgs);
}

if init {
self.room_panel(RoomPanel::Room);
}
}
}

/// State for the main thread.
Expand Down Expand Up @@ -639,11 +684,12 @@ impl App {
backend: apptx,
active_room: String::from(""),
members: HashMap::new(),
rooms: HashMap::new(),
}
));

let theop = op.clone();
gtk::timeout_add(50, move || {
gtk::timeout_add(500, move || {
let recv = rx.try_recv();
match recv {
Ok(BKResponse::Token(uid, _)) => {
Expand Down Expand Up @@ -673,16 +719,10 @@ impl App {
theop.lock().unwrap().set_room_avatar(avatar);
},
Ok(BKResponse::RoomMessages(msgs)) => {
for msg in msgs.iter() {
theop.lock().unwrap().add_room_message(msg, MsgPos::Bottom);
}

if !msgs.is_empty() {
theop.lock().unwrap().scroll_down();
theop.lock().unwrap().mark_as_read(msgs);
}

theop.lock().unwrap().room_panel(RoomPanel::Room);
theop.lock().unwrap().show_room_messages(msgs, false);
},
Ok(BKResponse::RoomMessagesInit(msgs)) => {
theop.lock().unwrap().show_room_messages(msgs, true);
},
Ok(BKResponse::RoomMessagesTo(msgs)) => {
for msg in msgs.iter().rev() {
Expand Down Expand Up @@ -941,6 +981,14 @@ impl App {
pub fn run(self) {
self.op.lock().unwrap().init();

if let Err(err) = libnotify::init("guillotine") {
println!("Error: can't init notifications: {}", err);
};

glib::set_application_name("guillotine");
glib::set_prgname(Some("guillotine"));
gtk::main();

libnotify::uninit();
}
}
26 changes: 23 additions & 3 deletions src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ pub enum BKCommand {
GetRoomMessagesTo(String),
GetAvatarAsync(String, Sender<String>),
GetThumbAsync(String, Sender<String>),
GetUserInfoAsync(String, Sender<(String, String)>),
SendMsg(String, String),
SetRoom(String),
ShutDown,
Expand All @@ -74,6 +75,7 @@ pub enum BKResponse {
RoomDetail(String, String),
RoomAvatar(String),
RoomMessages(Vec<Message>),
RoomMessagesInit(Vec<Message>),
RoomMessagesTo(Vec<Message>),
RoomMembers(Vec<Member>),
SendMsg,
Expand Down Expand Up @@ -162,6 +164,10 @@ impl Backend {
let r = self.get_avatar_async(&sender, ctx);
bkerror!(r, tx, BKResponse::CommandError);
},
Ok(BKCommand::GetUserInfoAsync(sender, ctx)) => {
let r = self.get_user_info_async(&sender, ctx);
bkerror!(r, tx, BKResponse::CommandError);
},
Ok(BKCommand::GetThumbAsync(media, ctx)) => {
let r = self.get_thumb_async(media, ctx);
bkerror!(r, tx, BKResponse::CommandError);
Expand Down Expand Up @@ -347,7 +353,7 @@ impl Backend {
let tx = self.tx.clone();
thread::spawn(move || {
match get_user_avatar(&baseu, &userid) {
Ok(fname) => {
Ok((_, fname)) => {
tx.send(BKResponse::Avatar(fname)).unwrap();
},
Err(err) => {
Expand Down Expand Up @@ -511,7 +517,7 @@ impl Backend {
ms.push(m);
}
match to {
false => tx.send(BKResponse::RoomMessages(ms)).unwrap(),
false => tx.send(BKResponse::RoomMessagesInit(ms)).unwrap(),
true => tx.send(BKResponse::RoomMessagesTo(ms)).unwrap(),
};
},
Expand Down Expand Up @@ -569,14 +575,28 @@ impl Backend {
let u = String::from(uid);
thread::spawn(move || {
match get_user_avatar(&baseu, &u) {
Ok(fname) => { tx.send(fname).unwrap(); },
Ok((_, fname)) => { tx.send(fname).unwrap(); },
Err(_) => { tx.send(String::from("")).unwrap(); }
};
});

Ok(())
}

pub fn get_user_info_async(&self, uid: &str, tx: Sender<(String, String)>) -> Result<(), Error> {
let baseu = self.get_base_url()?;

let u = String::from(uid);
thread::spawn(move || {
match get_user_avatar(&baseu, &u) {
Ok(info) => { tx.send(info).unwrap(); },
Err(_) => { tx.send((String::new(), String::new())).unwrap(); }
};
});

Ok(())
}

pub fn get_thumb_async(&self, media: String, tx: Sender<String>) -> Result<(), Error> {
let baseu = self.get_base_url()?;

Expand Down
10 changes: 5 additions & 5 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,22 +276,22 @@ pub fn json_q(method: &str, url: &Url, attrs: &JsonValue) -> Result<JsonValue, E
}
}

pub fn get_user_avatar(baseu: &Url, userid: &str) -> Result<String, Error> {
pub fn get_user_avatar(baseu: &Url, userid: &str) -> Result<(String, String), Error> {
let url = baseu.join("/_matrix/client/r0/profile/")?.join(userid)?;
let attrs = json!(null);

match json_q("get", &url, &attrs) {
Ok(js) => {
let name = String::from(js["displayname"].as_str().unwrap_or("@"));
match js["avatar_url"].as_str() {
Some(url) => Ok(thumb!(baseu, &url)?),
Some(url) => Ok((name.clone(), thumb!(baseu, &url)?)),
None => {
let name = js["displayname"].as_str().unwrap_or("@");
Ok(draw_identicon(userid, String::from(name))?)
Ok((name.clone(), draw_identicon(userid, name)?))
},
}
},
Err(_) => {
Ok(draw_identicon(userid, String::from(&userid[1..2]))?)
Ok((String::from(userid), draw_identicon(userid, String::from(&userid[1..2]))?))
}
}
}
Expand Down

0 comments on commit 591d65a

Please sign in to comment.