Add notifications

This commit is contained in:
bleakgrey 2018-04-17 15:01:55 +03:00
parent b2683cc56a
commit f0bf2cfcce
8 changed files with 223 additions and 4 deletions

View File

@ -27,15 +27,19 @@ executable(
'src/API/Account.vala',
'src/API/Status.vala',
'src/API/StatusVisibility.vala',
'src/API/Notification.vala',
'src/API/NotificationType.vala',
'src/Widgets/AlignedLabel.vala',
'src/Widgets/AccountsButton.vala',
'src/Widgets/StatusWidget.vala',
'src/Widgets/NotificationWidget.vala',
'src/Dialogs/DialogToot.vala',
'src/Views/AbstractView.vala',
'src/Views/AddAccountView.vala',
'src/Views/HomeView.vala',
'src/Views/LocalView.vala',
'src/Views/FederatedView.vala',
'src/Views/NotificationsView.vala',
dependencies: [
dependency('gtk+-3.0'),
dependency('glib-2.0', version: '>=2.30.0'),

View File

@ -6,6 +6,7 @@ public class Tootle.Account{
public string display_name;
public string note;
public string avatar;
public string url;
public Account(int64 id){
this.id = id;
@ -20,6 +21,7 @@ public class Tootle.Account{
account.display_name = obj.get_string_member ("display_name");
account.note = obj.get_string_member ("note");
account.avatar = obj.get_string_member ("avatar");
account.url = obj.get_string_member ("url");
return account;
}

29
src/API/Notification.vala Normal file
View File

@ -0,0 +1,29 @@
public class Tootle.Notification{
public int64 id;
public NotificationType type;
public string created_at;
public Status? status;
public Account? account;
public Notification(int64 id) {
this.id = id;
}
public static Notification parse(Json.Object obj) {
var id = int64.parse (obj.get_string_member ("id"));
var notification = new Notification (id);
notification.type = NotificationType.from_string (obj.get_string_member ("type"));
notification.created_at = obj.get_string_member ("created_at");
if (obj.has_member ("status"))
notification.status = Status.parse(obj.get_object_member ("status"));
if (obj.has_member ("account"))
notification.account = Account.parse(obj.get_object_member ("account"));
return notification;
}
}

View File

@ -0,0 +1,67 @@
public enum Tootle.NotificationType {
MENTION,
REBLOG,
FAVORITE,
FOLLOW;
public string to_string() {
switch (this) {
case MENTION:
return "mention";
case REBLOG:
return "reblog";
case FAVORITE:
return "favourite";
case FOLLOW:
return "follow";
default:
assert_not_reached();
}
}
public static NotificationType from_string (string str) {
switch (str) {
case "mention":
return MENTION;
case "reblog":
return REBLOG;
case "favourite":
return FAVORITE;
case "follow":
return FOLLOW;
default:
assert_not_reached();
}
}
public string get_desc (Account? account) {
switch (this) {
case MENTION:
return _("<a href=\"%s\"><b>%s</b></a> mentioned you").printf (account.url, account.display_name);
case REBLOG:
return _("<a href=\"%s\"><b>%s</b></a> boosted your toot").printf (account.url, account.display_name);
case FAVORITE:
return _("<a href=\"%s\"><b>%s</b></a> favorited your toot").printf (account.url, account.display_name);
case FOLLOW:
return _("<a href=\"%s\"><b>%s</b></a> now follows you").printf (account.url, account.display_name);
default:
assert_not_reached();
}
}
public string get_icon () {
switch (this) {
case MENTION:
return "user-available-symbolic";
case REBLOG:
return "edit-undo-symbolic";
case FAVORITE:
return "help-about-symbolic";
case FOLLOW:
return "contact-new-symbolic";
default:
assert_not_reached();
}
}
}

View File

@ -11,7 +11,8 @@ public class Tootle.MainWindow: Gtk.Window {
public HomeView home = new HomeView ();
public LocalView feed_local = new LocalView ();
FederatedView feed_federated = new FederatedView ();
public FederatedView feed_federated = new FederatedView ();
public NotificationsView notifications = new NotificationsView ();
public MainWindow (Gtk.Application application) {
Object (application: application,
@ -93,6 +94,7 @@ public class Tootle.MainWindow: Gtk.Window {
add_view (home);
add_view (feed_local);
add_view (feed_federated);
add_view (notifications);
mode.set_active (0);
mode.show ();
button_toot.show ();
@ -101,9 +103,10 @@ public class Tootle.MainWindow: Gtk.Window {
private void add_view (AbstractView view) {
if (view.show_in_header){
var button = new Gtk.Image.from_icon_name(view.get_icon (), Gtk.IconSize.LARGE_TOOLBAR);
button.tooltip_text = view.get_name ();
mode.append (button);
var img = new Gtk.Image.from_icon_name(view.get_icon (), Gtk.IconSize.LARGE_TOOLBAR);
img.tooltip_text = view.get_name ();
mode.append (img);
view.image = img;
stack.add_named(view, view.get_name ());
}

View File

@ -3,6 +3,7 @@ using Gtk;
public abstract class Tootle.AbstractView : Gtk.Box {
public bool show_in_header;
public Gtk.Image image;
public AbstractView (bool show_in_header) {
this.show_in_header = show_in_header;

View File

@ -0,0 +1,68 @@
using Gtk;
using Gdk;
public class Tootle.NotificationsView : Tootle.AbstractView {
Gtk.Box view;
Gtk.ScrolledWindow scroll;
construct {
view = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
view.hexpand = true;
view.valign = Gtk.Align.START;
scroll = new Gtk.ScrolledWindow (null, null);
scroll.hexpand = true;
scroll.vexpand = true;
scroll.hscrollbar_policy = Gtk.PolicyType.NEVER;
scroll.add (view);
add (scroll);
}
public NotificationsView () {
base (true);
show_all();
AccountManager.instance.changed_current.connect(on_account_changed);
}
public override string get_icon () {
return "notification-symbolic";
}
public override string get_name () {
return "Notifications";
}
public void prepend(Notification notification){
var widget = new NotificationWidget(notification);
view.pack_start(widget, false, false, 0);
image.icon_name = "notification-new-symbolic";
}
public virtual void on_account_changed (Account? account){
if(account == null)
return;
var url = Settings.instance.instance_url;
url += "/api/v1/notifications";
var msg = new Soup.Message("GET", url);
NetManager.instance.queue(msg, (sess, mess) => {
try{
NetManager.parse_array (mess).foreach_element ((array, i, node) => {
var object = node.get_object ();
if (object != null){
var notification = Notification.parse(object);
prepend (notification);
}
});
}
catch (GLib.Error e) {
warning ("Can't update feed");
warning (e.message);
}
});
}
}

View File

@ -0,0 +1,45 @@
using Gtk;
using Granite;
public class Tootle.NotificationWidget : Gtk.Grid {
public Notification notification;
private Gtk.Image image;
private Gtk.Label label;
private Gtk.Button dismiss;
private StatusWidget? status_widget;
construct {
margin = 6;
image = new Gtk.Image.from_icon_name("notification-symbolic", Gtk.IconSize.SMALL_TOOLBAR);
image.margin_start = 32;
image.margin_end = 6;
label = new Gtk.Label (_("Unknown Notification"));
label.hexpand = true;
label.halign = Gtk.Align.START;
label.use_markup = true;
dismiss = new Gtk.Button.from_icon_name ("close-symbolic", Gtk.IconSize.SMALL_TOOLBAR);
dismiss.tooltip_text = _("Dismiss");
attach(image, 0, 0, 1, 1);
attach(label, 1, 0, 1, 1);
attach(dismiss, 2, 0, 1, 1);
show_all();
}
public NotificationWidget (Notification notification) {
this.notification = notification;
image.icon_name = notification.type.get_icon ();
label.label = notification.type.get_desc (notification.account);
get_style_context ().add_class ("notification");
if (notification.status != null){
status_widget = new StatusWidget (this.notification.status);
status_widget.rebind (this.notification.status);
attach(status_widget, 0, 1, 3, 1);
}
}
}