Introduce Widgetizable interface
This commit is contained in:
parent
d24e10ace2
commit
82e2f93bc8
|
@ -58,6 +58,8 @@ executable(
|
|||
'src/API/Notification.vala',
|
||||
'src/API/NotificationType.vala',
|
||||
'src/API/Attachment.vala',
|
||||
'src/API/Conversation.vala',
|
||||
'src/Widgets/Widgetizable.vala',
|
||||
'src/Widgets/Avatar.vala',
|
||||
'src/Widgets/AccountsButton.vala',
|
||||
'src/Widgets/RichLabel.vala',
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
public class Tootle.API.Conversation : GLib.Object, Json.Serializable, Widgetizable {
|
||||
|
||||
public string id { get; construct set; }
|
||||
public bool unread { get; set; default = false; }
|
||||
|
||||
public Conversation () {
|
||||
GLib.Object ();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
public class Tootle.API.Notification : GLib.Object {
|
||||
public class Tootle.API.Notification : GLib.Object, Widgetizable {
|
||||
|
||||
public int64 id { get; construct set; }
|
||||
public Account account { get; construct set; }
|
||||
|
@ -27,6 +27,10 @@ public class Tootle.API.Notification : GLib.Object {
|
|||
);
|
||||
}
|
||||
|
||||
public override Gtk.Widget to_widget () {
|
||||
return new Widgets.Notification (this);
|
||||
}
|
||||
|
||||
public Json.Node? serialize () {
|
||||
var builder = new Json.Builder ();
|
||||
builder.begin_object ();
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using Gee;
|
||||
|
||||
public class Tootle.API.Status : GLib.Object {
|
||||
|
||||
public class Tootle.API.Status : GLib.Object, Widgetizable {
|
||||
|
||||
public int64 id { get; construct set; } //TODO: IDs are no longer guaranteed to be numbers. Replace with strings.
|
||||
public API.Account account { get; construct set; }
|
||||
|
@ -115,6 +114,13 @@ public class Tootle.API.Status : GLib.Object {
|
|||
content = Html.remove_tags (account.note);
|
||||
}
|
||||
|
||||
public override Gtk.Widget to_widget () {
|
||||
var w = new Widgets.Status (this);
|
||||
w.button_press_event.connect (w.open);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
public Json.Node? serialize () {
|
||||
var builder = new Json.Builder ();
|
||||
builder.begin_object ();
|
||||
|
|
|
@ -6,7 +6,8 @@ namespace Tootle {
|
|||
public errordomain Oopsie {
|
||||
USER,
|
||||
PARSING,
|
||||
INSTANCE
|
||||
INSTANCE,
|
||||
INTERNAL
|
||||
}
|
||||
|
||||
public static Application app;
|
||||
|
|
|
@ -4,7 +4,8 @@ public class Tootle.Views.Conversations : Views.Timeline {
|
|||
Object (
|
||||
url: "/api/v1/conversations",
|
||||
label: _("Conversations"),
|
||||
icon: "mail-send-symbolic"
|
||||
icon: API.Visibility.DIRECT.get_icon (),
|
||||
accepts: typeof (API.Conversation)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ public class Tootle.Views.Notifications : Views.Timeline, IAccountListener, IStr
|
|||
label: _("Notifications"),
|
||||
icon: Desktop.fallback_icon ("notification-symbolic", "preferences-system-notifications-symbolic", "user-invisible-symbolic")
|
||||
);
|
||||
accepts = typeof (API.Notification);
|
||||
on_notification.connect (add_notification);
|
||||
on_status_added.disconnect (add_status);
|
||||
}
|
||||
|
@ -41,20 +42,15 @@ public class Tootle.Views.Notifications : Views.Timeline, IAccountListener, IStr
|
|||
accounts.save ();
|
||||
}
|
||||
|
||||
public override GLib.Object? to_entity (Json.Object? json) {
|
||||
if (json != null)
|
||||
return new API.Notification (json);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
public override GLib.Object to_entity (Json.Node node) throws Oopsie {
|
||||
if (node == null)
|
||||
throw new Oopsie.PARSING ("Received null Json.Node");
|
||||
|
||||
public override Widget? widgetize (GLib.Object? entity) {
|
||||
var n = entity as API.Notification;
|
||||
if (n == null)
|
||||
return null;
|
||||
var obj = node.get_object ();
|
||||
if (obj == null)
|
||||
throw new Oopsie.PARSING ("Received Json.Node is not a Json.Object!");
|
||||
|
||||
var w = new Widgets.Notification (n);
|
||||
return w;
|
||||
return new API.Notification (obj);
|
||||
}
|
||||
|
||||
public override void on_account_changed (InstanceAccount? acc) {
|
||||
|
@ -72,7 +68,7 @@ public class Tootle.Views.Notifications : Views.Timeline, IAccountListener, IStr
|
|||
public override bool request () {
|
||||
if (account != null) {
|
||||
account.cached_notifications.@foreach (n => {
|
||||
append (widgetize (n));
|
||||
append (n.to_widget ());
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
@ -86,7 +82,7 @@ public class Tootle.Views.Notifications : Views.Timeline, IAccountListener, IStr
|
|||
}
|
||||
|
||||
void add_notification (API.Notification n) {
|
||||
prepend (widgetize (n));
|
||||
prepend (n.to_widget ());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -156,11 +156,12 @@ public class Tootle.Views.Profile : Views.Timeline {
|
|||
return base.append_params (req);
|
||||
}
|
||||
|
||||
public override GLib.Object? to_entity (Json.Object? json) {
|
||||
public override GLib.Object to_entity (Json.Node node) {
|
||||
var obj = node.get_object ();
|
||||
if (posts_tab.active)
|
||||
return new API.Status (json);
|
||||
return new API.Status (obj);
|
||||
else {
|
||||
var account = new API.Account (json);
|
||||
var account = new API.Account (obj);
|
||||
return new API.Status.from_account (account);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ public class Tootle.Views.Timeline : IAccountListener, IStreamListener, Views.Ba
|
|||
|
||||
public string url { get; construct set; }
|
||||
public bool is_public { get; construct set; default = false; }
|
||||
public Type accepts { get; set; default = typeof (API.Status); }
|
||||
|
||||
protected InstanceAccount? account = null;
|
||||
|
||||
|
@ -29,21 +30,15 @@ public class Tootle.Views.Timeline : IAccountListener, IStreamListener, Views.Ba
|
|||
return status.is_owned ();
|
||||
}
|
||||
|
||||
public virtual GLib.Object? to_entity (Json.Object? json) {
|
||||
return new API.Status (json);
|
||||
}
|
||||
public virtual GLib.Object to_entity (Json.Node node) throws Oopsie {
|
||||
if (node == null)
|
||||
throw new Oopsie.PARSING ("Received null Json.Node");
|
||||
|
||||
public virtual Widget? widgetize (GLib.Object? entity) {
|
||||
var status = entity as API.Status;
|
||||
if (status == null)
|
||||
return null;
|
||||
var obj = node.get_object ();
|
||||
if (obj == null)
|
||||
throw new Oopsie.PARSING ("Received Json.Node is not a Json.Object!");
|
||||
|
||||
var w = new Widgets.Status (status);
|
||||
w.button_press_event.connect (w.open);
|
||||
if (!is_status_owned (status))
|
||||
w.avatar.button_press_event.connect (w.on_avatar_clicked);
|
||||
|
||||
return w;
|
||||
return new API.Status (obj);
|
||||
}
|
||||
|
||||
public void prepend (Widget? w) {
|
||||
|
@ -51,8 +46,10 @@ public class Tootle.Views.Timeline : IAccountListener, IStreamListener, Views.Ba
|
|||
}
|
||||
|
||||
public virtual void append (Widget? w, bool first = false) {
|
||||
if (w == null)
|
||||
if (w == null) {
|
||||
warning ("Attempted to add an empty widget");
|
||||
return;
|
||||
}
|
||||
|
||||
if (first)
|
||||
content_list.prepend (w);
|
||||
|
@ -105,15 +102,13 @@ public class Tootle.Views.Timeline : IAccountListener, IStreamListener, Views.Ba
|
|||
append_params (new Request.GET (get_req_url ()))
|
||||
.with_account (account)
|
||||
.then_parse_array ((node, msg) => {
|
||||
var obj = node.get_object ();
|
||||
if (obj == null)
|
||||
warning ("Received invalid Json.Object");
|
||||
else {
|
||||
var entity = to_entity (obj);
|
||||
if (entity == null)
|
||||
warning ("Can't convert Json.Object to required entity");
|
||||
else
|
||||
append (widgetize (entity));
|
||||
try {
|
||||
var e = to_entity (node);
|
||||
var w = e as Widgetizable;
|
||||
append (w.to_widget ());
|
||||
}
|
||||
catch (Error e) {
|
||||
warning (@"Timeline item parse error: $(e.message)");
|
||||
}
|
||||
get_pages (msg.response_headers.get_one ("Link"));
|
||||
})
|
||||
|
@ -154,7 +149,7 @@ public class Tootle.Views.Timeline : IAccountListener, IStreamListener, Views.Ba
|
|||
allow_update = settings.public_live_updates;
|
||||
|
||||
if (settings.live_updates && allow_update)
|
||||
prepend (widgetize (status));
|
||||
prepend (status.to_widget ());
|
||||
}
|
||||
|
||||
protected virtual void remove_status (int64 id) {
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
using Gdk;
|
||||
|
||||
public class Tootle.Widgets.Account : Widgets.Status {
|
||||
|
||||
public Account (API.Account account) {
|
||||
var status = new API.Status (-1);
|
||||
status.account = account;
|
||||
//status.url = account.url;
|
||||
//status.content = "<a href=\"%s\">@%s</a>".printf (account.url, account.acct);
|
||||
//status.created_at = account.created_at;
|
||||
|
||||
base (status);
|
||||
|
||||
//counters.visible = false;
|
||||
//title_acct.visible = false;
|
||||
//content_label.margin_bottom = 12;
|
||||
}
|
||||
|
||||
protected override bool on_clicked (EventButton ev) {
|
||||
if (ev.button == 1)
|
||||
return on_avatar_clicked (ev);
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool open_menu (uint button, uint32 time) {
|
||||
var menu = new Gtk.Menu ();
|
||||
|
||||
var item_open_link = new Gtk.MenuItem.with_label (_("Open in Browser"));
|
||||
item_open_link.activate.connect (() => Desktop.open_uri (status.url));
|
||||
var item_copy_link = new Gtk.MenuItem.with_label (_("Copy Link"));
|
||||
item_copy_link.activate.connect (() => Desktop.copy (status.url));
|
||||
menu.add (item_open_link);
|
||||
menu.add (item_copy_link);
|
||||
|
||||
menu.show_all ();
|
||||
menu.popup_at_pointer ();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -135,6 +135,7 @@ public class Tootle.Widgets.Status : EventBox {
|
|||
}
|
||||
|
||||
menu_button.clicked.connect (open_menu);
|
||||
avatar.button_press_event.connect (on_avatar_clicked);
|
||||
}
|
||||
|
||||
public Status (API.Status status, API.NotificationType? _kind = null) {
|
||||
|
@ -166,7 +167,7 @@ public class Tootle.Widgets.Status : EventBox {
|
|||
var view = new Views.Profile (status.formal.account);
|
||||
return window.open_view (view);
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool open (EventButton ev) {
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
public interface Tootle.Widgetizable : GLib.Object {
|
||||
|
||||
public virtual Gtk.Widget to_widget () throws Oopsie {
|
||||
throw new Tootle.Oopsie.INTERNAL ("Widgetizable didn't provide a Widget!");
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue