Commit 376df188 authored by Daniel Garcia Moreno's avatar Daniel Garcia Moreno

Merge branch 'globals' into 'master'

Move App Actions to new Location

See merge request !297
parents 57a2c094 5e4c9123
Pipeline #44641 failed with stages
in 18 minutes and 41 seconds
......@@ -33,7 +33,6 @@ fractal-gtk/res/ui/sticker_group.ui
fractal-gtk/res/ui/stickers_popover.ui
# rust files
fractal-gtk/src/app/actions.rs
fractal-gtk/src/app/appop_loop.rs
fractal-gtk/src/app/backend_loop.rs
fractal-gtk/src/app/connect/account.rs
......@@ -81,8 +80,9 @@ fractal-gtk/src/static_resources.rs
fractal-gtk/src/uibuilder.rs
fractal-gtk/src/util.rs
fractal-gtk/src/uitypes.rs
fractal-gtk/src/actions/room_history.rs
fractal-gtk/src/actions/global.rs
fractal-gtk/src/actions/mod.rs
fractal-gtk/src/actions/room_history.rs
fractal-gtk/src/widgets/address.rs
fractal-gtk/src/widgets/room_history.rs
fractal-gtk/src/widgets/autocomplete.rs
......
use std::sync::{Arc, Mutex};
use appop::AppOp;
use appop::AppState;
use gio::prelude::*;
use gio::SimpleAction;
use gtk::prelude::*;
/* This creates globale actions which are connected to the application */
/* TODO: Remove op */
pub fn new(op: Arc<Mutex<AppOp>>) {
let app = op.lock().unwrap().gtk_app.clone();
let settings = SimpleAction::new("settings", None);
let account = SimpleAction::new("account_settings", None);
let dir = SimpleAction::new("directory", None);
let chat = SimpleAction::new("start_chat", None);
let newr = SimpleAction::new("new_room", None);
let joinr = SimpleAction::new("join_room", None);
let logout = SimpleAction::new("logout", None);
let room = SimpleAction::new("room_details", None);
let inv = SimpleAction::new("room_invite", None);
let search = SimpleAction::new("search", None);
let leave = SimpleAction::new("leave_room", None);
let quit = SimpleAction::new("quit", None);
let shortcuts = SimpleAction::new("shortcuts", None);
let about = SimpleAction::new("about", None);
let open_room = SimpleAction::new("open_room", glib::VariantTy::new("s").ok());
app.add_action(&settings);
app.add_action(&account);
app.add_action(&dir);
app.add_action(&chat);
app.add_action(&newr);
app.add_action(&joinr);
app.add_action(&logout);
app.add_action(&room);
app.add_action(&inv);
app.add_action(&search);
app.add_action(&leave);
app.add_action(&quit);
app.add_action(&shortcuts);
app.add_action(&about);
app.add_action(&open_room);
quit.connect_activate(clone!(op => move |_, _| op.lock().unwrap().quit() ));
about.connect_activate(clone!(op => move |_, _| op.lock().unwrap().about_dialog() ));
settings.connect_activate(move |_, _| {
info!("SETTINGS");
});
settings.set_enabled(false);
account.connect_activate(
clone!(op => move |_, _| op.lock().unwrap().show_account_settings_dialog()),
);
dir.connect_activate(
clone!(op => move |_, _| op.lock().unwrap().set_state(AppState::Directory) ),
);
logout.connect_activate(clone!(op => move |_, _| op.lock().unwrap().logout() ));
room.connect_activate(clone!(op => move |_, _| op.lock().unwrap().show_room_settings() ));
inv.connect_activate(clone!(op => move |_, _| op.lock().unwrap().show_invite_user_dialog() ));
chat.connect_activate(clone!(op => move |_, _| op.lock().unwrap().show_direct_chat_dialog() ));
leave.connect_activate(clone!(op => move |_, _| op.lock().unwrap().leave_active_room() ));
newr.connect_activate(clone!(op => move |_, _| op.lock().unwrap().new_room_dialog() ));
joinr.connect_activate(clone!(op => move |_, _| op.lock().unwrap().join_to_room_dialog() ));
open_room.connect_activate(clone!(op => move |_, data| {
if let Some(id) = get_room_id(data) {
op.lock().unwrap().set_active_room_by_id(id.to_string());
}
}));
/* Add Keybindings to actions */
app.set_accels_for_action("app.quit", &["<Ctrl>Q"]);
}
fn get_room_id(data: &Option<glib::Variant>) -> Option<&str> {
data.as_ref()?.get_str()
}
pub mod global;
pub mod room_history;
pub use self::global as Global;
pub use self::room_history as RoomHistory;
use gio;
use gio::ActionMapExt;
use gio::SimpleActionExt;
use appop::AppState;
use app::App;
impl App {
pub fn create_actions(&self) {
let settings = gio::SimpleAction::new("settings", None);
let account = gio::SimpleAction::new("account_settings", None);
let dir = gio::SimpleAction::new("directory", None);
let chat = gio::SimpleAction::new("start_chat", None);
let newr = gio::SimpleAction::new("new_room", None);
let joinr = gio::SimpleAction::new("join_room", None);
let logout = gio::SimpleAction::new("logout", None);
let room = gio::SimpleAction::new("room_details", None);
let inv = gio::SimpleAction::new("room_invite", None);
let search = gio::SimpleAction::new("search", None);
let leave = gio::SimpleAction::new("leave_room", None);
let quit = gio::SimpleAction::new("quit", None);
let shortcuts = gio::SimpleAction::new("shortcuts", None);
let about = gio::SimpleAction::new("about", None);
let op = &self.op;
op.lock().unwrap().gtk_app.add_action(&settings);
op.lock().unwrap().gtk_app.add_action(&account);
op.lock().unwrap().gtk_app.add_action(&dir);
op.lock().unwrap().gtk_app.add_action(&chat);
op.lock().unwrap().gtk_app.add_action(&newr);
op.lock().unwrap().gtk_app.add_action(&joinr);
op.lock().unwrap().gtk_app.add_action(&logout);
op.lock().unwrap().gtk_app.add_action(&room);
op.lock().unwrap().gtk_app.add_action(&inv);
op.lock().unwrap().gtk_app.add_action(&search);
op.lock().unwrap().gtk_app.add_action(&leave);
op.lock().unwrap().gtk_app.add_action(&quit);
op.lock().unwrap().gtk_app.add_action(&shortcuts);
op.lock().unwrap().gtk_app.add_action(&about);
quit.connect_activate(clone!(op => move |_, _| op.lock().unwrap().quit() ));
about.connect_activate(clone!(op => move |_, _| op.lock().unwrap().about_dialog() ));
settings.connect_activate(move |_, _| {
info!("SETTINGS");
});
settings.set_enabled(false);
account.connect_activate(
clone!(op => move |_, _| op.lock().unwrap().show_account_settings_dialog()),
);
dir.connect_activate(
clone!(op => move |_, _| op.lock().unwrap().set_state(AppState::Directory) ),
);
logout.connect_activate(clone!(op => move |_, _| op.lock().unwrap().logout() ));
room.connect_activate(clone!(op => move |_, _| op.lock().unwrap().show_room_settings() ));
inv.connect_activate(
clone!(op => move |_, _| op.lock().unwrap().show_invite_user_dialog() ),
);
chat.connect_activate(
clone!(op => move |_, _| op.lock().unwrap().show_direct_chat_dialog() ),
);
leave.connect_activate(clone!(op => move |_, _| op.lock().unwrap().leave_active_room() ));
newr.connect_activate(clone!(op => move |_, _| op.lock().unwrap().new_room_dialog() ));
joinr.connect_activate(clone!(op => move |_, _| op.lock().unwrap().join_to_room_dialog() ));
}
}
......@@ -8,7 +8,6 @@ use std::thread;
use types::Member;
use types::Message;
use types::Room;
use types::Sticker;
use types::StickerGroup;
......@@ -16,7 +15,6 @@ use types::StickerGroup;
pub enum InternalCommand {
SetView(AppState),
NotifyClicked(Message),
SelectRoom(Room),
LoadMore,
RemoveInv(String),
AppendTmpMessages,
......@@ -47,10 +45,6 @@ pub fn appop_loop(rx: Receiver<InternalCommand>) {
Ok(InternalCommand::NotifyClicked(msg)) => {
APPOP!(notification_cliked, (msg));
}
Ok(InternalCommand::SelectRoom(r)) => {
let id = r.id;
APPOP!(set_active_room_by_id, (id));
}
Ok(InternalCommand::LoadMore) => {
APPOP!(load_more_messages);
}
......
......@@ -18,6 +18,7 @@ mod roomlist_search;
mod send;
mod stickers;
use actions;
use app::App;
impl App {
......@@ -56,8 +57,7 @@ impl App {
}
});
self.create_actions();
actions::Global::new(self.op.clone());
self.connect_headerbars();
self.connect_login_view();
......
......@@ -17,7 +17,6 @@ use backend::Backend;
use globals;
use uibuilder;
mod actions;
mod connect;
pub use self::appop_loop::InternalCommand;
......@@ -65,8 +64,6 @@ impl App {
let gtk_app = gtk::Application::new(Some(&appid[..]), gio::ApplicationFlags::empty())
.expect("Failed to initialize GtkApplication");
gtk_app.set_accels_for_action("app.quit", &["<Ctrl>Q"]);
let path = "/org/gnome/Fractal".to_string();
gtk_app.set_property_resource_base_path(Some(&path));
......
......@@ -14,7 +14,6 @@ use globals;
use widgets;
use types::Member;
use types::Room;
impl AppOp {
pub fn add_to_invite(&mut self, u: Member) {
......@@ -229,17 +228,19 @@ impl AppOp {
self.invitation_roomid = None;
}
pub fn show_inv_dialog(&mut self, r: &Room) {
/* FIXME: move to a widget */
pub fn show_inv_dialog(&self, sender: Option<&Member>, room_name: Option<&String>) {
let dialog = self
.ui
.builder
.get_object::<gtk::MessageDialog>("invite_dialog")
.expect("Can't find invite_dialog in ui file.");
let room_name = r.name.clone().unwrap_or_default();
let empty = String::from("");
let room_name = room_name.unwrap_or(&empty);
let title = i18n_k("Join {room_name}?", &[("room_name", &room_name)]);
let secondary;
if let Some(ref sender) = r.inv_sender {
if let Some(ref sender) = sender {
let sender_name = sender.get_alias();
secondary = i18n_k(
"You’ve been invited to join to <b>{room_name}</b> room by <b>{sender_name}</b>",
......@@ -256,7 +257,6 @@ impl AppOp {
dialog.set_property_secondary_use_markup(true);
dialog.set_property_secondary_text(Some(&secondary));
self.invitation_roomid = Some(r.id.clone());
dialog.present();
}
......
......@@ -37,29 +37,13 @@ impl AppOp {
/// This function is used to mark as read the last message of a room when the focus comes in,
/// so we need to force the mark_as_read because the window isn't active yet
pub fn mark_active_room_messages(&mut self) {
let mut msg: Option<Message> = None;
if let Some(ref active_room_id) = self.active_room {
if let Some(ref r) = self.rooms.get(active_room_id) {
if let Some(m) = r.messages.last() {
msg = Some(m.clone());
}
}
}
// this is done here because in the above we've a reference to self and mark as read needs
// a mutable reference to self so we can't do it inside
if let Some(m) = msg {
self.mark_as_read(&m, Force(true));
}
self.mark_last_message_as_read(Force(true));
}
pub fn add_room_message(&mut self, msg: &Message) -> Option<()> {
if &msg.room == self.active_room.as_ref()? && !msg.redacted {
if let Some(ui_msg) = self.create_new_room_message(msg) {
if let Some(ref mut history) = self.history {
history.add_new_message(ui_msg);
}
if let Some(ui_msg) = self.create_new_room_message(msg) {
if let Some(ref mut history) = self.history {
history.add_new_message(ui_msg);
}
}
None
......@@ -119,7 +103,7 @@ impl AppOp {
None
}
pub fn mark_as_read(&mut self, msg: &Message, Force(force): Force) -> Option<()> {
pub fn mark_last_message_as_read(&mut self, Force(force): Force) -> Option<()> {
let window: gtk::Window = self
.ui
.builder
......@@ -140,8 +124,8 @@ impl AppOp {
self.backend
.send(BKCommand::MarkAsRead(
msg.room.clone(),
msg.id.clone().unwrap_or_default(),
last_message.room.clone(),
last_message.id.clone()?,
))
.unwrap();
}
......@@ -397,6 +381,7 @@ impl AppOp {
}
}
let mut msg_in_active = false;
let uid = self.uid.clone()?;
for msg in msgs.iter() {
let should_notify = msg.sender != uid
......@@ -407,16 +392,16 @@ impl AppOp {
self.notify(msg);
}
self.add_room_message(&msg);
if &msg.room == self.active_room.as_ref()? && !msg.redacted {
self.add_room_message(&msg);
msg_in_active = true;
}
self.roomlist.moveup(msg.room.clone());
self.roomlist.set_bold(msg.room.clone(), true);
}
if !msgs.is_empty() {
let active_room = self.active_room.clone()?;
let fs = msgs.iter().filter(|x| x.room == active_room);
let msg = fs.last()?;
self.mark_as_read(msg, Force(false));
if msg_in_active {
self.mark_last_message_as_read(Force(false));
}
None
......
......@@ -104,10 +104,6 @@ impl AppOp {
container.add(&self.roomlist.widget());
self.roomlist.set_selected(selected_room);
let bk = self.internal.clone();
self.roomlist.connect(move |room| {
bk.send(InternalCommand::SelectRoom(room)).unwrap();
});
let bk = self.backend.clone();
self.roomlist.connect_fav(move |room, tofav| {
bk.send(BKCommand::AddToFav(room.id.clone(), tofav))
......@@ -137,23 +133,14 @@ impl AppOp {
self.set_state(AppState::Chat);
}
pub fn set_active_room_by_id(&mut self, roomid: String) {
let mut room = None;
if let Some(r) = self.rooms.get(&roomid) {
room = Some(r.clone());
}
if let Some(r) = room {
if r.inv {
self.show_inv_dialog(&r);
pub fn set_active_room_by_id(&mut self, id: String) {
if let Some(room) = self.rooms.get(&id) {
if room.inv {
self.show_inv_dialog(room.inv_sender.as_ref(), room.name.as_ref());
self.invitation_roomid = Some(room.id.clone());
return;
}
self.set_active_room(&r);
}
}
pub fn set_active_room(&mut self, room: &Room) {
self.room_panel(RoomPanel::Room);
let msg_entry = self.ui.sventry.view.clone();
......@@ -162,35 +149,55 @@ impl AppOp {
let end = buffer.get_end_iter();
if let Some(msg) = buffer.get_text(&start, &end, false) {
let active_room_id = self.active_room.clone().unwrap_or_default();
if msg.len() > 0 {
if let Some(mark) = buffer.get_insert() {
let iter = buffer.get_iter_at_mark(&mark);
let msg_position = iter.get_offset();
self.unsent_messages
.insert(active_room_id, (msg, msg_position));
if let Some(ref active_room) = self.active_room {
if msg.len() > 0 {
if let Some(mark) = buffer.get_insert() {
let iter = buffer.get_iter_at_mark(&mark);
let msg_position = iter.get_offset();
self.unsent_messages
.insert(active_room.clone(), (msg, msg_position));
}
} else {
self.unsent_messages.remove(active_room);
}
} else {
self.unsent_messages.remove(&active_room_id);
}
}
}
self.active_room = Some(room.id.clone());
self.clear_tmp_msgs();
/* Transform id into the active_room */
let active_room = id;
// getting room details
self.backend
.send(BKCommand::SetRoom(active_room.clone()))
.unwrap();
/* create the intitial list of messages to fill the new room history */
let active_room = self.active_room.clone().unwrap_or_default();
let mut messages = vec![];
for msg in room.messages.iter() {
/* Make sure the message is from this room and not redacted */
if msg.room == active_room && !msg.redacted {
let row = self.create_new_room_message(msg);
if let Some(row) = row {
messages.push(row);
if let Some(room) = self.rooms.get(&active_room) {
for msg in room.messages.iter() {
/* Make sure the message is from this room and not redacted */
if msg.room == active_room && !msg.redacted {
let row = self.create_new_room_message(msg);
if let Some(row) = row {
messages.push(row);
}
}
}
let l = room.messages.len();
if l > 0 && l < globals::INITIAL_MESSAGES {
self.internal.send(InternalCommand::LoadMore).unwrap();
}
self.internal
.send(InternalCommand::AppendTmpMessages)
.unwrap();
self.set_current_room_detail(String::from("m.room.name"), room.name.clone());
self.set_current_room_detail(String::from("m.room.topic"), room.topic.clone());
}
/* make sure we remove the old room history first, because the lazy loading could try to
......@@ -204,42 +211,9 @@ impl AppOp {
history.create(messages);
self.history = Some(history);
let l = room.messages.len();
if l > 0 && l < globals::INITIAL_MESSAGES {
self.internal.send(InternalCommand::LoadMore).unwrap();
}
self.internal
.send(InternalCommand::AppendTmpMessages)
.unwrap();
if let Some(msg) = room.messages.iter().last() {
self.mark_as_read(msg, Force(false));
}
// getting room details
self.backend.send(BKCommand::SetRoom(room.clone())).unwrap();
self.set_room_topic_label(room.topic.clone());
let name_label = self
.ui
.builder
.get_object::<gtk::Label>("room_name")
.expect("Can't find room_name in ui file.");
name_label.set_text(&room.name.clone().unwrap_or_default());
let mut size = 24;
if let Some(r) = room.topic.clone() {
if !r.is_empty() {
size = 16;
}
}
self.set_current_room_avatar(room.avatar.clone(), size);
self.set_current_room_detail(String::from("m.room.name"), room.name.clone());
self.set_current_room_detail(String::from("m.room.topic"), room.topic.clone());
self.active_room = Some(active_room);
/* Mark the new active room as read */
self.mark_last_message_as_read(Force(false));
}
pub fn really_leave_active_room(&mut self) {
......@@ -398,16 +372,6 @@ impl AppOp {
self.roomlist
.set_room_avatar(roomid.clone(), r.avatar.clone());
}
if roomid == self.active_room.clone().unwrap_or_default() {
let mut size = 24;
if let Some(r) = self.rooms.get_mut(&roomid) {
if !r.clone().topic.unwrap_or_default().is_empty() {
size = 16;
}
}
self.set_current_room_avatar(avatar, size);
}
}
pub fn set_current_room_detail(&self, key: String, value: Option<String>) {
......@@ -430,8 +394,6 @@ impl AppOp {
};
}
pub fn set_current_room_avatar(&self, _avatar: Option<String>, _size: i32) {}
pub fn filter_rooms(&self, term: Option<String>) {
self.roomlist.filter_rooms(term);
}
......
......@@ -286,14 +286,6 @@ impl RoomListGroup {
self.widget.hide();
}
pub fn connect<F: Fn(Room) + 'static>(&self, cb: F) {
let rs = self.roomvec.clone();
self.list.connect_row_activated(move |_, row| {
let idx = row.get_index();
cb(rs.lock().unwrap()[idx as usize].room.clone());
});
}
pub fn get_selected(&self) -> Option<String> {
let rv = self.roomvec.lock().unwrap();
match self.list.get_selected_row() {
......@@ -498,17 +490,6 @@ impl RoomList {
self.show_and_hide();
}
pub fn connect<F: Fn(Room) + 'static>(&self, cb: F) {
let acb = Arc::new(cb);
let cb = acb.clone();
self.inv.get().connect(move |room| cb(room));
let cb = acb.clone();
self.fav.get().connect(move |room| cb(room));
let cb = acb.clone();
self.rooms.get().connect(move |room| cb(room));
}
pub fn connect_fav<F: Fn(Room, bool) + 'static>(&self, cb: F) {
let acb = Arc::new(cb);
......
......@@ -133,7 +133,7 @@ impl RoomRow {
.circle(self.room.id.clone(), Some(name), ICON_SIZE);
}
pub fn widget(&self) -> gtk::EventBox {
pub fn widget(&self) -> gtk::ListBoxRow {
let b = gtk::Box::new(gtk::Orientation::Horizontal, 5);
for ch in self.widget.get_children() {
......@@ -159,7 +159,12 @@ impl RoomRow {
self.notifications.hide();
}
self.widget.clone()
let row = gtk::ListBoxRow::new();
row.add(&self.widget);
let data = glib::Variant::from(&self.room.id);
row.set_action_target_value(&data);
row.set_action_name("app.open_room");
row
}
pub fn connect_dnd(&self) {
......
......@@ -209,8 +209,8 @@ impl Backend {
let r = room::redact_msg(self, msg);
bkerror!(r, tx, BKResponse::SendMsgRedactionError);
}
Ok(BKCommand::SetRoom(room)) => {
let r = room::set_room(self, room);
Ok(BKCommand::SetRoom(id)) => {
let r = room::set_room(self, id);
bkerror!(r, tx, BKResponse::SetRoomError);
}
Ok(BKCommand::GetRoomAvatar(room)) => {
......
......@@ -28,10 +28,11 @@ use types::Room;
use serde_json::Value as JsonValue;
pub fn set_room(bk: &Backend, room: Room) -> Result<(), Error> {
get_room_detail(bk, room.id.clone(), String::from("m.room.topic"))?;
get_room_avatar(bk, room.id.clone())?;
get_room_members(bk, room.id.clone())?;
pub fn set_room(bk: &Backend, id: String) -> Result<(), Error> {
/* FIXME: remove clone and pass id by reference */
get_room_detail(bk, id.clone(), String::from("m.room.topic"))?;
get_room_avatar(bk, id.clone())?;
get_room_members(bk, id)?;
Ok(())
}
......
......@@ -60,7 +60,7 @@ pub enum BKCommand {
GetUserNameAsync(String, Sender<String>),
SendMsg(Message),
SendMsgRedaction(Message),
SetRoom(Room),
SetRoom(String),
ShutDown,
DirectoryProtocols,
DirectorySearch(String, String, String, bool),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment