Rework notifications

This commit is contained in:
Jesse van den Kieboom 2015-08-13 08:07:36 +02:00
parent 6015438b0e
commit bf2edae624
11 changed files with 157 additions and 72 deletions

View file

@ -77,6 +77,7 @@ gitg_gitg_VALASOURCES = \
gitg/gitg-ref-action-fetch.vala \
gitg/gitg-ref-action-rename.vala \
gitg/gitg-remote-manager.vala \
gitg/gitg-remote-notification.vala \
gitg/gitg-resource.vala \
gitg/gitg-ui-elements.vala \
gitg/gitg-window.vala \

View file

@ -25,11 +25,13 @@ public class Notifications : Object, GitgExt.Notifications
private Gtk.Overlay d_overlay;
private Gee.HashSet<uint> d_delay_handles;
private Gtk.Box d_box;
private Gee.HashMap<GitgExt.Notification, ulong> d_handles;
public Notifications(Gtk.Overlay overlay)
{
d_overlay = overlay;
d_delay_handles = new Gee.HashSet<uint>();
d_handles = new Gee.HashMap<GitgExt.Notification, ulong>();
d_box = new Gtk.Box(Gtk.Orientation.VERTICAL, 3);
d_box.get_style_context().add_class("notifications");
@ -48,49 +50,57 @@ public class Notifications : Object, GitgExt.Notifications
d_delay_handles.clear();
foreach (var notification in d_handles.keys)
{
notification.disconnect(d_handles[notification]);
}
d_handles.clear();
base.dispose();
}
public void add(Gtk.Widget widget)
public new void add(GitgExt.Notification notification)
{
var revealer = new Gtk.Revealer();
revealer.margin_top = 1;
revealer.set_transition_duration(500);
revealer.set_transition_type(Gtk.RevealerTransitionType.SLIDE_UP);
revealer.add(widget);
revealer.add(notification.widget);
widget.show();
notification.widget.show();
revealer.show();
d_box.add(revealer);
revealer.reveal_child = true;
d_handles[notification] = notification.close.connect((delay) => {
remove(notification, delay);
});
}
private void remove_now(Gtk.Widget widget)
private void remove_now(GitgExt.Notification notification)
{
var revealer = widget.get_parent() as Gtk.Revealer;
var revealer = notification.widget.get_parent() as Gtk.Revealer;
notification.disconnect(d_handles[notification]);
revealer.notify["child-revealed"].connect(() => {
revealer.remove(widget);
revealer.remove(notification.widget);
revealer.destroy();
});
revealer.reveal_child = false;
}
public void remove(Gtk.Widget widget, uint delay)
public void remove(GitgExt.Notification notification, uint delay)
{
if (delay == 0)
{
remove_now(widget);
}
uint id = 0;
id = Timeout.add(delay, () => {
d_delay_handles.remove(id);
remove_now(widget);
remove_now(notification);
return false;
});

View file

@ -90,7 +90,7 @@ class RefActionFetch : GitgExt.UIElement, GitgExt.Action, GitgExt.RefAction, Obj
get { return d_remote != null; }
}
public void activate()
public async bool fetch()
{
var notification = new RemoteNotification(d_remote);
application.notifications.add(notification);
@ -99,7 +99,7 @@ class RefActionFetch : GitgExt.UIElement, GitgExt.Action, GitgExt.RefAction, Obj
var updates = new Gee.ArrayList<string>();
var tip_updated_id = d_remote.tip_updated.connect((remote, name, a, b) => {
var tip_updated_id = d_remote.tip_updated.connect((d_remote, name, a, b) => {
if (a.is_zero())
{
/* Translators: new refers to a new remote reference having been fetched, */
@ -112,35 +112,41 @@ class RefActionFetch : GitgExt.UIElement, GitgExt.Action, GitgExt.RefAction, Obj
}
});
d_remote.fetch.begin(null, null, (obj, res) =>{
try
{
d_remote.fetch.end(res);
}
catch (Error e)
{
notification.error(_("Failed to fetch from %s: %s").printf(d_remote.get_url(), e.message));
stderr.printf("Failed to fetch: %s\n", e.message);
return;
}
finally
{
(d_remote as Object).disconnect(tip_updated_id);
}
try
{
yield d_remote.fetch(null, null);
}
catch (Error e)
{
notification.error(_("Failed to fetch from %s: %s").printf(d_remote.get_url(), e.message));
stderr.printf("Failed to fetch: %s\n", e.message);
if (updates.size == 0)
{
/* Translators: the %s will get replaced with the remote url, */
notification.success(_("Fetched from %s: everything is up to date").printf(d_remote.get_url()));
}
else
{
/* Translators: the first %s is the remote url to fetch from,
* the second is a list of references that got updated. */
notification.success(_("Fetched from %s: %s").printf(d_remote.get_url(), string.joinv(", ", updates.to_array())));
}
return false;
}
finally
{
((Object)d_remote).disconnect(tip_updated_id);
}
application.notifications.remove(notification, 3000);
if (updates.size == 0)
{
/* Translators: the %s will get replaced with the remote url, */
notification.success(_("Fetched from %s: everything is up to date").printf(d_remote.get_url()));
}
else
{
/* Translators: the first %s is the remote url to fetch from,
* the second is a list of references that got updated. */
notification.success(_("Fetched from %s: %s").printf(d_remote.get_url(), string.joinv(", ", updates.to_array())));
}
return true;
}
public void activate()
{
fetch.begin((obj, res) => {
fetch.end(res);
});
}
}

View file

@ -21,8 +21,11 @@ namespace Gitg
{
[GtkTemplate (ui = "/org/gnome/gitg/ui/gitg-remote-notification.ui")]
public class RemoteNotification : ProgressBin
public class RemoteNotification : ProgressBin, GitgExt.Notification
{
// Do this to pull in config.h before glib.h (for gettext...)
private const string version = Gitg.Config.VERSION;
private Remote? d_remote;
[GtkChild ( name = "image_icon" )]
@ -37,7 +40,8 @@ public class RemoteNotification : ProgressBin
private bool d_finished;
public signal void cancel();
public signal void close();
private string d_text;
public RemoteNotification(Remote remote)
{
@ -47,53 +51,85 @@ public class RemoteNotification : ProgressBin
d_remote.bind_property("transfer-progress", this, "fraction");
}
public Gtk.Widget? widget
{
owned get { return this; }
}
public void success(string text)
{
d_image_icon.icon_name = "emblem-ok-symbolic";
this.text = text;
Idle.add(() => {
d_image_icon.icon_name = "emblem-ok-symbolic";
this.text = text;
get_style_context().add_class("success");
get_style_context().add_class("success");
finish();
finish();
return false;
});
}
public void error(string text)
{
d_image_icon.icon_name = "network-error-symbolic";
this.text = text;
Idle.add(() => {
d_image_icon.icon_name = "network-error-symbolic";
this.text = text;
get_style_context().add_class("error");
finish();
get_style_context().add_class("error");
finish();
return false;
});
}
private void finish()
{
d_finished = true;
d_button_cancel.label = _("Close");
Idle.add(() => {
d_finished = true;
d_button_cancel.label = _("Close");
close(3000);
return false;
});
}
public string text
{
get { return d_label_text.label; }
set { d_label_text.label = value; }
get
{
return d_text;
}
set
{
Idle.add(() => {
d_label_text.label = value;
return false;
});
}
}
public RemoteState remote_state
{
set
{
switch (value)
{
case Gitg.RemoteState.CONNECTING:
d_image_icon.icon_name = "network-wireless-acquiring-symbolic";
break;
case Gitg.RemoteState.CONNECTED:
d_image_icon.icon_name = "network-idle-symbolic";
break;
case Gitg.RemoteState.TRANSFERRING:
d_image_icon.icon_name = "network-transmit-receive-symbolic";
break;
}
Idle.add(() => {
switch (value)
{
case Gitg.RemoteState.CONNECTING:
d_image_icon.icon_name = "network-wireless-acquiring-symbolic";
break;
case Gitg.RemoteState.CONNECTED:
d_image_icon.icon_name = "network-idle-symbolic";
break;
case Gitg.RemoteState.TRANSFERRING:
d_image_icon.icon_name = "network-transmit-receive-symbolic";
break;
}
return false;
});
}
}

View file

@ -21,6 +21,8 @@
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-create-branch-dialog.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-create-tag-dialog.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-dash-view.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-remote-notification.ui</file>
<file compressed="true">ui/style.css</file>
</gresource>
</gresources>

View file

@ -54,6 +54,7 @@ libgitg_ext_libgitg_ext_1_0_la_VALASOURCES = \
libgitg-ext/gitg-ext-message-bus.vala \
libgitg-ext/gitg-ext-message-id.vala \
libgitg-ext/gitg-ext-message.vala \
libgitg-ext/gitg-ext-notification.vala \
libgitg-ext/gitg-ext-notifications.vala \
libgitg-ext/gitg-ext-preferences.vala \
libgitg-ext/gitg-ext-ref-action-interface.vala \

View file

@ -0,0 +1,31 @@
/*
* This file is part of gitg
*
* Copyright (C) 2015 - Jesse van den Kieboom
*
* gitg is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* gitg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with gitg. If not, see <http://www.gnu.org/licenses/>.
*/
namespace GitgExt
{
public interface Notification : Object
{
public signal void close(uint delay = 0);
public abstract Gtk.Widget? widget { owned get; }
}
}
// ex:set ts=4 noet:

View file

@ -22,8 +22,8 @@ namespace GitgExt
public interface Notifications : Object
{
public abstract void add(Gtk.Widget widget);
public abstract void remove(Gtk.Widget widget, uint delay);
public abstract void add(Notification notification);
public abstract void remove(Notification notification, uint delay);
}
}

View file

@ -81,7 +81,6 @@ libgitg_libgitg_1_0_la_VALASOURCES = \
libgitg/gitg-ref-base.vala \
libgitg/gitg-ref.vala \
libgitg/gitg-remote.vala \
libgitg/gitg-remote-notification.vala \
libgitg/gitg-repository-list-box.vala \
libgitg/gitg-repository.vala \
libgitg/gitg-sidebar.vala \

View file

@ -11,7 +11,6 @@
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-repository-list-box-row.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-authentication-dialog.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-sidebar.ui</file>
<file compressed="true" preprocess="xml-stripblanks">ui/gitg-remote-notification.ui</file>
</gresource>
</gresources>