Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 89 additions & 31 deletions src/Indicator.vala
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ public class Notifications.Indicator : Wingpanel.Indicator {
private const string CHILD_PATH = "/io/elementary/notifications/applications/%s/";
private const string REMEMBER_KEY = "remember";

private Gtk.Spinner? dynamic_icon = null;
private Gtk.Grid? main_box = null;
private Notifications.Session session;

private GLib.ListStore notifications;
private GLib.HashTable<string, GLib.DateTime> app_datetime;
private Gee.HashMap<string, Settings> app_settings_cache;
private GLib.Settings notify_settings;
private Gtk.Grid? main_box = null;
private Gtk.ModelButton clear_all_btn;
private Gtk.Spinner? dynamic_icon = null;
private NotificationsList nlist;

public Indicator () {
Object (
Expand All @@ -37,20 +39,28 @@ public class Notifications.Indicator : Wingpanel.Indicator {

construct {
notify_settings = new GLib.Settings ("io.elementary.notifications");

app_datetime = new GLib.HashTable<string, GLib.DateTime> (str_hash, str_equal);
app_settings_cache = new Gee.HashMap<string, Settings> ();
notifications = new GLib.ListStore (typeof (Notifications.Notification));
}

public override Gtk.Widget get_display_widget () {
if (dynamic_icon == null) {
dynamic_icon = new Gtk.Spinner ();
dynamic_icon.active = true;

nlist = new NotificationsList ();
session = new Notifications.Session ();
var previous_session = session.get_session_notifications ();
foreach (unowned Notification notification in previous_session) {
unowned GLib.DateTime? time = app_datetime[notification.desktop_id];
if (time == null || time.compare (notification.timestamp) <= 0) {
app_datetime[notification.desktop_id] = notification.timestamp;
}
}

var previous_session = Session.get_instance ().get_session_notifications ();
previous_session.foreach ((notification) => {
nlist.add_entry (notification);
});
notifications.splice (0, 0, (Object[]) previous_session);
notifications.sort ((GLib.CompareDataFunc<GLib.Object>) sort_notification);

var provider = new Gtk.CssProvider ();
provider.load_from_resource ("io/elementary/wingpanel/notifications/indicator.css");
Expand All @@ -76,8 +86,9 @@ public class Notifications.Indicator : Wingpanel.Indicator {
set_display_icon_name ();
});

nlist.add.connect (set_display_icon_name);
nlist.remove.connect (set_display_icon_name);
notifications.items_changed.connect ((position, removed, added) => {
set_display_icon_name ();
});

set_display_icon_name ();
}
Expand All @@ -87,6 +98,8 @@ public class Notifications.Indicator : Wingpanel.Indicator {

public override Gtk.Widget? get_widget () {
if (main_box == null) {
var nlist = new NotificationsList (notifications);

var not_disturb_switch = new Granite.SwitchModelButton (_("Do Not Disturb"));
not_disturb_switch.get_style_context ().add_class (Granite.STYLE_CLASS_H4_LABEL);

Expand All @@ -106,7 +119,7 @@ public class Notifications.Indicator : Wingpanel.Indicator {
margin_bottom = 3
};

clear_all_btn = new Gtk.ModelButton ();
var clear_all_btn = new Gtk.ModelButton ();
clear_all_btn.text = _("Clear All Notifications");

var settings_btn = new Gtk.ModelButton ();
Expand All @@ -125,13 +138,40 @@ public class Notifications.Indicator : Wingpanel.Indicator {

notify_settings.bind ("do-not-disturb", not_disturb_switch, "active", GLib.SettingsBindFlags.DEFAULT);

nlist.clear_app.connect ((app_id) => {
nlist.get_children ().foreach ((child) => {
if (child is NotificationEntry) {
unowned NotificationEntry entry = (NotificationEntry) child;
if (entry.notification.desktop_id == app_id) {
entry.dismiss ();
}
}
});
});

nlist.remove_notification.connect ((notification) => {
uint position;
if (notifications.find (notification, out position)) {
session.remove_notification (notification);
notifications.remove (position);
} else {
warning ("Notification not found!");
}
});

nlist.close_popover.connect (() => close ());
nlist.add.connect (update_clear_all_sensitivity);
nlist.remove.connect (update_clear_all_sensitivity);

clear_all_btn.clicked.connect (() => {
nlist.clear_all ();
Session.get_instance ().clear ();
session.clear ();
nlist.get_children ().foreach ((child) => {
if (child is NotificationEntry) {
((NotificationEntry) child).dismiss ();
}
});
});

notifications.items_changed.connect ((position, removed, added) => {
clear_all_btn.sensitive = notifications.get_n_items () > 0;
});

settings_btn.clicked.connect (show_settings);
Expand All @@ -141,7 +181,6 @@ public class Notifications.Indicator : Wingpanel.Indicator {
}

public override void opened () {
update_clear_all_sensitivity ();
}

public override void closed () {
Expand All @@ -165,23 +204,41 @@ public class Notifications.Indicator : Wingpanel.Indicator {
}

if (app_settings == null || app_settings.get_boolean (REMEMBER_KEY)) {
nlist.add_entry (notification);
}
unowned GLib.DateTime? time = app_datetime[notification.desktop_id];
if (time == null || time.compare (notification.timestamp) <= 0) {
app_datetime[notification.desktop_id] = notification.timestamp;
}

set_display_icon_name ();
notifications.insert_sorted (notification, (GLib.CompareDataFunc<GLib.Object>) sort_notification);
session.add_notification (notification);
}
}

private void update_clear_all_sensitivity () {
clear_all_btn.sensitive = nlist.app_entries.size > 0;
[CCode (instance_pos = -1)]
private int sort_notification (Notification a, Notification b) {
if (a.desktop_id == b.desktop_id) {
return Notification.compare (a, b);
} else {
unowned GLib.DateTime? time_a = app_datetime[a.desktop_id];
unowned GLib.DateTime? time_b = app_datetime[b.desktop_id];
if (time_a != null && time_b != null) {
return time_a.compare (time_b);
} else if (time_a != null) {
return -1;
} else if (time_b != null) {
return 1;
} else {
return 0;
}
}
}

private void on_notification_closed (uint32 id) {
foreach (var app_entry in nlist.app_entries.values) {
foreach (var item in app_entry.app_notifications) {
if (item.notification.id == id) {
item.notification.close ();
return;
}
for (int i = 0; i < notifications.get_n_items (); i++) {
var notification = (Notification) notifications.get_item (i);
if (notification.id == id) {
notification.close ();
return;
}
}
}
Expand All @@ -190,7 +247,7 @@ public class Notifications.Indicator : Wingpanel.Indicator {
unowned var dynamic_icon_style_context = dynamic_icon.get_style_context ();
if (notify_settings.get_boolean ("do-not-disturb")) {
dynamic_icon_style_context.add_class ("disabled");
} else if (nlist != null && nlist.app_entries.size > 0) {
} else if (notifications.get_n_items () > 0) {
dynamic_icon_style_context.remove_class ("disabled");
dynamic_icon_style_context.add_class ("new");
} else {
Expand All @@ -211,8 +268,9 @@ public class Notifications.Indicator : Wingpanel.Indicator {
}

private void update_tooltip () {
uint number_of_notifications = Session.get_instance ().get_session_notifications ().length ();
int number_of_apps = nlist.app_entries.size;
uint number_of_notifications = session.get_session_notifications ().length;
int number_of_apps = 0;
// int number_of_apps = nlist.app_entries.size;

string description;
string accel_label;
Expand Down
4 changes: 4 additions & 0 deletions src/Services/Notification.vala
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ public class Notifications.Notification : Object {
return false;
}

public static int compare (Notification self, Notification other) {
return self.timestamp.compare (other.timestamp);
}

private string get_string (Variant tuple, int column) {
var child = tuple.get_child_value (column);
return child.dup_string ();
Expand Down
19 changes: 5 additions & 14 deletions src/Services/Session.vala
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
*/
public class Notifications.Session : GLib.Object {
private const string SESSION_FILE_NAME = ".notifications.session";
private static Session? instance = null;

private File session_file = null;

Expand All @@ -39,15 +38,7 @@ public class Notifications.Session : GLib.Object {

private KeyFile key;

public static Session get_instance () {
if (instance == null) {
instance = new Session ();
}

return instance;
}

private Session () {
public Session () {
session_file = File.new_for_path (Path.build_filename (Environment.get_user_cache_dir (), SESSION_FILE_NAME));
if (!session_file.query_exists ()) {
create_session_file ();
Expand All @@ -57,8 +48,8 @@ public class Notifications.Session : GLib.Object {
key.set_list_separator (';');
}

public List<Notification> get_session_notifications () {
var list = new List<Notification> ();
public Notification[] get_session_notifications () {
Notification[] list = {};
try {
key.load_from_file (session_file.get_path (), KeyFileFlags.NONE);
foreach (unowned string group in key.get_groups ()) {
Expand All @@ -72,7 +63,7 @@ public class Notifications.Session : GLib.Object {
key.get_int64 (group, UNIX_TIME_KEY),
key.get_uint64 (group, REPLACES_ID_KEY),
key.get_string (group, SENDER_KEY));
list.append (notification);
list += notification;
}
} catch (KeyFileError e) {
warning (e.message);
Expand Down Expand Up @@ -102,7 +93,7 @@ public class Notifications.Session : GLib.Object {
try {
key.remove_group (notification.id.to_string ());
} catch (KeyFileError e) {
warning (e.message);
return;
}

write_contents ();
Expand Down
50 changes: 7 additions & 43 deletions src/Widgets/AppEntry.vala
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

public class Notifications.AppEntry : Gtk.ListBoxRow {
public class Notifications.AppEntry : Gtk.Grid {
public signal void clear ();

public string app_id { get; private set; }
public AppInfo? app_info { get; construct; default = null; }
public List<NotificationEntry> app_notifications;

public AppEntry (AppInfo? app_info) {
Object (app_info: app_info);
}

construct {
margin = 12;
margin_bottom = 3;
margin_top = 6;

app_notifications = new List<NotificationEntry> ();

unowned string name;
if (app_info != null) {
app_id = app_info.get_id ();
Expand All @@ -53,44 +46,15 @@ public class Notifications.AppEntry : Gtk.ListBoxRow {
};
clear_btn_entry.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT);

var grid = new Gtk.Grid () {
column_spacing = 6
};
grid.add (label);
grid.add (clear_btn_entry);

add (grid);
show_all ();
column_spacing = 6;
margin = 12;
margin_bottom = 3;
margin_top = 6;
add (label);
add (clear_btn_entry);

clear_btn_entry.clicked.connect (() => {
clear_all_notification_entries ();
});
}

public void add_notification_entry (NotificationEntry entry) {
app_notifications.prepend (entry);
entry.clear.connect (remove_notification_entry);
}

public void remove_notification_entry (NotificationEntry entry) {
app_notifications.remove (entry);
entry.dismiss ();

Session.get_instance ().remove_notification (entry.notification);
if (app_notifications.length () == 0) {
clear ();
}
}

public void clear_all_notification_entries () {
Notification[] to_remove = {};
app_notifications.@foreach ((entry) => {
entry.dismiss ();
to_remove += entry.notification;
});

app_notifications = new List<NotificationEntry> ();
Session.get_instance ().remove_notifications (to_remove);
clear ();
}
}
12 changes: 6 additions & 6 deletions src/Widgets/NotificationEntry.vala
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
*/

public class Notifications.NotificationEntry : Gtk.ListBoxRow {
public signal void clear ();
public signal void removed ();

public Notification notification { get; construct; }

Expand Down Expand Up @@ -185,7 +185,7 @@ public class Notifications.NotificationEntry : Gtk.ListBoxRow {
show_all ();

delete_button.clicked.connect (() => {
clear ();
dismiss ();
});

eventbox.enter_notify_event.connect ((event) => {
Expand All @@ -203,17 +203,17 @@ public class Notifications.NotificationEntry : Gtk.ListBoxRow {
return GLib.Source.CONTINUE;
});

notification.closed.connect (() => clear ());
notification.closed.connect (() => dismiss ());

deck.notify["visible-child"].connect (() => {
if (deck.transition_running == false && deck.visible_child != overlay) {
clear ();
dismiss ();
}
});

deck.notify["transition-running"].connect (() => {
if (deck.transition_running == false && deck.visible_child != overlay) {
clear ();
dismiss ();
}
});
}
Expand All @@ -223,7 +223,7 @@ public class Notifications.NotificationEntry : Gtk.ListBoxRow {

revealer.notify["child-revealed"].connect (() => {
if (!revealer.child_revealed) {
destroy ();
removed ();
}
});
revealer.reveal_child = false;
Expand Down
Loading