Skip to content

Commit

Permalink
feat(gui): add dynamic icon redefinition and reply functionality
Browse files Browse the repository at this point in the history
- Introduced a `reply_revealer` widget to manage visibility of the reply entry.
- Updated `update_from_details` method to accept `runtime_data` for dynamic icon redefinition.
- Modified `from_details` method to handle `runtime_data` and pass it to `update_from_details`.
- Added click event handling for the "inline-reply" action to toggle the reply entry or activate it.
- Introduced `icon_redefines` in `_RuntimeData` to manage icon overrides dynamically.
  • Loading branch information
bzglve committed Sep 2, 2024
1 parent aaf0b5c commit a29c9ee
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 39 deletions.
89 changes: 53 additions & 36 deletions src/gui/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub struct Window {
app_icon: gtk::Image,
body: gtk::Label,
reply_entry: gtk::Entry,
reply_revealer: gtk::Revealer,
actions_box: gtk::Box,
expire_timeout: Duration,
thandle: Rc<RefCell<Option<JoinHandle<()>>>>,
Expand Down Expand Up @@ -73,7 +74,7 @@ impl Window {
runtime_data: RuntimeData,
) -> Self {
info!("Building window from details: {:?}", details);
let window = Window::from_details(details.clone(), iface.clone());
let window = Window::from_details(details.clone(), iface.clone(), runtime_data.clone());

init_layer_shell(&window.inner);
window.inner.set_application(Some(&application));
Expand Down Expand Up @@ -119,7 +120,12 @@ impl Window {
window
}

pub fn update_from_details(&mut self, value: &Details, iface: Rc<IFaceRef>) {
pub fn update_from_details(
&mut self,
value: &Details,
iface: Rc<IFaceRef>,
runtime_data: RuntimeData,
) {
debug!("Updating window from details: {:?}", value);
if self.thandle.borrow().is_some() {
self.stop_timeout();
Expand Down Expand Up @@ -197,39 +203,47 @@ impl Window {
if !value.hints.action_icons {
btn.set_label(&action.text);
} else {
// TODO if icons is used need to have fallback or some override map
// e.g. `inline-reply`
btn.set_icon_name(&action.key);
let runtime_data = runtime_data.borrow();
let redef = runtime_data.icon_redefines.get(&action.key).unwrap_or(&action.key);
btn.set_icon_name(redef);
}
btn.set_tooltip_text(Some(&action.text));

btn.connect_clicked(clone!(
#[strong]
iface,
#[strong]
action,
#[strong(rename_to=entry)]
self.reply_entry,
move |_| {
if action.key == "inline-reply" {
entry.emit_activate();
if action.key == "inline-reply" {
btn.connect_clicked(clone!(
#[strong(rename_to=s)]
self,
move |_| {
if s.reply_entry.text().is_empty() {
s.reply_revealer.set_reveal_child(!s.reply_revealer.reveals_child());
} else {
s.reply_entry.emit_activate();
}
}

glib::spawn_future_local(clone!(
#[strong]
iface,
#[strong]
action,
async move {
if let Err(e) = IFace::action_invoked(iface.signal_context(), value.id, action.clone()).await {
error!("Failed to invoke action: {} for window id: {}. Error: {:?}", action.key, value.id, e);
} else {
info!("Action invoked: {} for window id: {}", action.key, value.id);
));
} else {
btn.connect_clicked(clone!(
#[strong]
iface,
#[strong]
action,
move |_| {
glib::spawn_future_local(clone!(
#[strong]
iface,
#[strong]
action,
async move {
if let Err(e) = IFace::action_invoked(iface.signal_context(), value.id, action.clone()).await {
error!("Failed to invoke action: {} for window id: {}. Error: {:?}", action.key, value.id, e);
} else {
info!("Action invoked: {} for window id: {}", action.key, value.id);
}
}
}
));
}
));
));
}
));
}

btn
});
Expand Down Expand Up @@ -291,9 +305,11 @@ impl Window {
.use_markup(true)
.build();

let reply_entry = gtk::Entry::builder()
.visible(false)
.placeholder_text("Reply")
let reply_entry = gtk::Entry::builder().placeholder_text("Reply").build();

let reply_revealer = gtk::Revealer::builder()
.reveal_child(false)
.child(&reply_entry)
.build();

let app_icon = gtk::Image::builder()
Expand Down Expand Up @@ -376,7 +392,7 @@ impl Window {
// main_box.append(&app_name);
main_box.append(&summary_box);
main_box.append(&body);
main_box.append(&reply_entry);
main_box.append(&reply_revealer);

let outer_box = gtk::Box::builder()
.orientation(Orientation::Horizontal)
Expand Down Expand Up @@ -414,14 +430,15 @@ impl Window {
app_icon,
body,
reply_entry,
reply_revealer,
actions_box,
expire_timeout: value.expire_timeout,
thandle: Default::default(),
inner,
}
}

pub fn from_details(value: Details, iface: Rc<IFaceRef>) -> Self {
pub fn from_details(value: Details, iface: Rc<IFaceRef>, runtime_data: RuntimeData) -> Self {
info!("Creating window from details for id: {}", value.id);
let mut _self = Self::build_widgets_tree(&value);

Expand All @@ -437,7 +454,7 @@ impl Window {
}
));

_self.update_from_details(&value, iface);
_self.update_from_details(&value, iface, runtime_data);
_self
}

Expand Down
6 changes: 5 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,11 @@ fn main() -> Result<(), Box<dyn Error>> {
"Updating existing notification window with id: {}",
details.id
);
window.update_from_details(&details, iface.clone());
window.update_from_details(
&details,
iface.clone(),
runtime_data.clone(),
);

window.start_timeout();
}
Expand Down
21 changes: 19 additions & 2 deletions src/types.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,27 @@
use std::{cell::RefCell, collections::BTreeMap, rc::Rc};
use std::{
cell::RefCell,
collections::{BTreeMap, HashMap},
rc::Rc,
};

use crate::gui::window::Window;

pub type RuntimeData = Rc<RefCell<_RuntimeData>>;

#[derive(Default)]
pub struct _RuntimeData {
pub windows: BTreeMap<u32, Window>,
pub icon_redefines: HashMap<String, String>, // TODO it has to be in config
}

impl Default for _RuntimeData {
fn default() -> Self {
let mut icon_redefines = HashMap::new();
icon_redefines.insert("inline-reply".to_owned(), "mail-reply".to_owned());
icon_redefines.insert("dismiss".to_owned(), "window-close".to_owned());

Self {
windows: Default::default(),
icon_redefines,
}
}
}

0 comments on commit a29c9ee

Please sign in to comment.