Tooth/src/Widgets/Status.vala

267 lines
7.4 KiB
Vala
Raw Normal View History

2018-04-14 12:09:06 +00:00
using Gtk;
2018-05-21 15:23:31 +00:00
using Gdk;
2018-04-14 12:09:06 +00:00
2020-05-29 12:19:35 +00:00
[GtkTemplate (ui = "/com/github/bleakgrey/tootle/ui/widgets/status.ui")]
public class Tootle.Widgets.Status : ListBoxRow {
2019-03-07 16:16:52 +00:00
2020-07-30 19:02:03 +00:00
public API.Status status { get; construct set; }
public API.NotificationType? kind { get; construct set; }
[GtkChild]
protected Grid grid;
[GtkChild]
protected Image header_icon;
[GtkChild]
protected Widgets.RichLabel header_label;
[GtkChild]
public Widgets.Avatar avatar;
[GtkChild]
protected Widgets.RichLabel name_label;
[GtkChild]
protected Widgets.RichLabel handle_label;
[GtkChild]
2020-08-01 21:47:22 +00:00
protected Box indicators;
[GtkChild]
2020-07-30 19:02:03 +00:00
protected Widgets.RichLabel date_label;
[GtkChild]
protected Image pin_indicator;
[GtkChild]
2020-08-01 21:47:22 +00:00
protected Image indicator;
[GtkChild]
protected Box content_column;
2020-08-01 21:47:22 +00:00
[GtkChild]
protected Stack spoiler_stack;
2020-07-30 19:02:03 +00:00
[GtkChild]
protected Box content_box;
2020-07-30 19:02:03 +00:00
[GtkChild]
protected Widgets.RichLabel content;
2020-07-30 19:02:03 +00:00
[GtkChild]
protected Widgets.Attachment.Box attachments;
[GtkChild]
protected Button spoiler_button;
[GtkChild]
protected Widgets.RichLabel spoiler_label;
2020-07-30 19:02:03 +00:00
[GtkChild]
protected Box actions;
[GtkChild]
protected Button reply_button;
[GtkChild]
protected ToggleButton reblog_button;
[GtkChild]
protected Image reblog_icon;
[GtkChild]
protected ToggleButton favorite_button;
[GtkChild]
protected ToggleButton bookmark_button;
[GtkChild]
protected Button menu_button;
protected string spoiler_text {
2020-07-30 19:02:03 +00:00
owned get {
var text = status.formal.spoiler_text;
if (text == null || text == "")
return _("Click to show sensitive content");
2020-07-30 19:02:03 +00:00
else
return text;
2020-07-30 19:02:03 +00:00
}
}
public bool reveal_spoiler { get; set; default = false; }
2020-07-30 19:02:03 +00:00
2020-08-01 21:47:22 +00:00
protected string date {
owned get {
2020-09-05 08:02:42 +00:00
var date = status.formal.created_at;
return @"<small>$(DateTime.humanize (date))</small>";
2020-08-01 21:47:22 +00:00
}
}
public string title_text {
2020-05-29 12:19:35 +00:00
owned get {
var name = Html.simplify (status.formal.account.display_name);
2020-06-29 21:43:45 +00:00
return @"<b>$name</b>";
2020-05-29 12:19:35 +00:00
}
}
2020-08-01 21:47:22 +00:00
public string subtitle_text {
2020-05-29 12:19:35 +00:00
owned get {
2020-08-01 21:47:22 +00:00
return @"<small>$(status.formal.account.handle)</small>";
2020-07-12 08:27:11 +00:00
}
}
2020-08-01 21:47:22 +00:00
public string? avatar_url {
2020-07-12 08:27:11 +00:00
owned get {
2020-08-01 21:47:22 +00:00
return status.formal.account.avatar;
2020-05-29 12:19:35 +00:00
}
}
2019-03-07 16:16:52 +00:00
2020-08-01 21:47:22 +00:00
public signal void open ();
public virtual void on_open () {
2020-07-31 23:42:14 +00:00
if (status.id == "")
on_avatar_clicked ();
2020-08-01 15:40:56 +00:00
else
status.open ();
2020-07-30 19:02:03 +00:00
}
construct {
notify["kind"].connect (on_kind_changed);
2020-08-01 21:47:22 +00:00
open.connect (on_open);
2020-07-30 19:02:03 +00:00
if (kind == null) {
if (status.reblog != null)
kind = API.NotificationType.REBLOG_REMOTE_USER;
}
status.formal.bind_property ("favourited", favorite_button, "active", BindingFlags.SYNC_CREATE);
favorite_button.clicked.connect (() => {
status.action (status.formal.favourited ? "unfavourite" : "favourite");
});
status.formal.bind_property ("reblogged", reblog_button, "active", BindingFlags.SYNC_CREATE);
reblog_button.clicked.connect (() => {
status.action (status.formal.reblogged ? "unreblog" : "reblog");
});
status.formal.bind_property ("bookmarked", bookmark_button, "active", BindingFlags.SYNC_CREATE);
bookmark_button.clicked.connect (() => {
status.action (status.formal.bookmarked ? "unbookmark" : "bookmark");
});
reply_button.clicked.connect (() => new Dialogs.Compose.reply (status));
bind_property ("spoiler-text", spoiler_label, "text", BindingFlags.SYNC_CREATE);
status.formal.bind_property ("content", content, "text", BindingFlags.SYNC_CREATE);
2020-08-01 21:47:22 +00:00
bind_property ("title_text", name_label, "text", BindingFlags.SYNC_CREATE);
bind_property ("subtitle_text", handle_label, "text", BindingFlags.SYNC_CREATE);
2020-05-29 12:19:35 +00:00
bind_property ("date", date_label, "label", BindingFlags.SYNC_CREATE);
status.formal.bind_property ("pinned", pin_indicator, "visible", BindingFlags.SYNC_CREATE);
2020-10-18 20:35:59 +00:00
status.formal.bind_property ("account", avatar, "account", BindingFlags.SYNC_CREATE);
2020-05-29 12:19:35 +00:00
status.formal.bind_property ("has-spoiler", this, "reveal-spoiler", BindingFlags.SYNC_CREATE, (b, src, ref target) => {
target.set_boolean (!src.get_boolean ());
return true;
});
bind_property ("reveal-spoiler", spoiler_stack, "visible-child-name", BindingFlags.SYNC_CREATE, (b, src, ref target) => {
var name = reveal_spoiler ? "content" : "spoiler";
target.set_string (name);
return true;
});
2020-07-30 19:02:03 +00:00
if (status.formal.visibility == API.Visibility.DIRECT) {
reblog_icon.icon_name = status.formal.visibility.get_icon ();
reblog_button.sensitive = false;
reblog_button.tooltip_text = _("This post can't be boosted");
}
if (status.id == "") {
actions.destroy ();
date_label.destroy ();
content.single_line_mode = true;
content.lines = 2;
content.ellipsize = Pango.EllipsizeMode.END;
}
if (!attachments.populate (status.formal.media_attachments) || status.id == "") {
attachments.destroy ();
}
menu_button.clicked.connect (open_menu);
}
public Status (API.Status status, API.NotificationType? kind = null) {
Object (
status: status,
kind: kind
);
2020-07-30 19:02:03 +00:00
}
~Status () {
notify["kind"].disconnect (on_kind_changed);
}
[GtkCallback]
public void toggle_spoiler () {
reveal_spoiler = !reveal_spoiler;
2020-07-30 19:02:03 +00:00
}
protected virtual void on_kind_changed () {
header_icon.visible = header_label.visible = (kind != null);
if (kind == null)
return;
header_icon.icon_name = kind.get_icon ();
header_label.label = kind.get_desc (status.account);
}
2020-07-31 23:42:14 +00:00
[GtkCallback]
public void on_avatar_clicked () {
2020-08-01 15:40:56 +00:00
status.formal.account.open ();
2020-07-30 19:02:03 +00:00
}
protected void open_menu () {
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.formal.url));
var item_copy_link = new Gtk.MenuItem.with_label (_("Copy Link"));
item_copy_link.activate.connect (() => Desktop.copy (status.formal.url));
var item_copy = new Gtk.MenuItem.with_label (_("Copy Text"));
item_copy.activate.connect (() => {
var sanitized = Html.remove_tags (status.formal.content);
Desktop.copy (sanitized);
});
// if (is_notification) {
// var item_muting = new Gtk.MenuItem.with_label (status.muted ? _("Unmute Conversation") : _("Mute Conversation"));
// item_muting.activate.connect (() => status.update_muted (!is_muted) );
// menu.add (item_muting);
// }
menu.add (item_open_link);
menu.add (new SeparatorMenuItem ());
menu.add (item_copy_link);
menu.add (item_copy);
if (status.is_owned ()) {
menu.add (new SeparatorMenuItem ());
var item_pin = new Gtk.MenuItem.with_label (status.pinned ? _("Unpin from Profile") : _("Pin on Profile"));
item_pin.activate.connect (() => {
status.action (status.formal.pinned ? "unpin" : "pin");
});
menu.add (item_pin);
var item_delete = new Gtk.MenuItem.with_label (_("Delete"));
item_delete.activate.connect (() => {
status.annihilate ()
.then ((sess, mess) => {
streams.force_delete (status.id);
})
.exec ();
});
menu.add (item_delete);
var item_redraft = new Gtk.MenuItem.with_label (_("Redraft"));
item_redraft.activate.connect (() => new Dialogs.Compose.redraft (status.formal));
menu.add (item_redraft);
}
menu.show_all ();
menu.popup_at_widget (menu_button, Gravity.SOUTH_EAST, Gravity.SOUTH_EAST);
}
2018-04-14 12:09:06 +00:00
public void expand_root () {
activatable = false;
content.selectable = true;
var parent = content_column.get_parent () as Container;
var left_attach = parent.find_child_property ("left-attach");
var width = parent.find_child_property ("width");
parent.set_child_property (content_column, 1, 0, left_attach);
parent.set_child_property (content_column, 3, 2, width);
}
2018-04-14 12:09:06 +00:00
}