tootle-linux-client/src/Widgets/Status.vala

231 lines
7.7 KiB
Vala
Raw Normal View History

2018-04-14 14:09:06 +02:00
using Gtk;
2018-05-21 17:23:31 +02:00
using Gdk;
2018-04-14 14:09:06 +02:00
2020-05-29 14:19:35 +02:00
[GtkTemplate (ui = "/com/github/bleakgrey/tootle/ui/widgets/status.ui")]
2019-03-11 15:14:37 +01:00
public class Tootle.Widgets.Status : EventBox {
2019-03-07 17:16:52 +01:00
2020-05-29 14:19:35 +02:00
public API.Status status { get; construct set; }
public API.NotificationType? kind { get; construct set; }
2019-03-07 17:16:52 +01:00
2020-05-29 14:19:35 +02:00
[GtkChild]
2018-10-24 12:50:40 +02:00
protected Grid grid;
2019-03-07 17:16:52 +01:00
2020-05-29 14:19:35 +02:00
[GtkChild]
protected Image header_icon;
[GtkChild]
protected Widgets.RichLabel header_label;
[GtkChild]
public Widgets.Avatar avatar;
[GtkChild]
2020-06-29 23:43:45 +02:00
protected Widgets.RichLabel name_label;
[GtkChild]
2020-05-29 14:19:35 +02:00
protected Widgets.RichLabel handle_label;
[GtkChild]
2020-06-29 23:43:45 +02:00
protected Widgets.RichLabel date_label;
2020-05-29 14:19:35 +02:00
[GtkChild]
protected Image pin_indicator;
[GtkChild]
public Revealer revealer;
[GtkChild]
protected Widgets.RichLabel content;
[GtkChild]
protected Widgets.RichLabel revealer_content;
[GtkChild]
protected Widgets.Attachment.Box attachments;
[GtkChild]
protected Box actions;
[GtkChild]
protected Button reply_button;
[GtkChild]
protected ToggleButton reblog_button;
[GtkChild]
protected Image reblog_icon;
[GtkChild]
protected ToggleButton favorite_button;
2020-06-03 14:41:21 +02:00
[GtkChild]
protected ToggleButton bookmark_button;
[GtkChild]
protected Button menu_button;
2020-05-29 14:19:35 +02:00
protected string escaped_spoiler {
owned get {
if (status.formal.has_spoiler) {
2020-06-29 23:43:45 +02:00
var text = status.formal.spoiler_text ?? "";
2020-05-29 14:19:35 +02:00
var label = _("[ Toggle content ]");
2020-06-29 23:43:45 +02:00
text += @" <a href=\"tootle://toggle\">$label</a>";
2020-05-29 14:19:35 +02:00
return text;
}
else
2020-06-29 23:43:45 +02:00
return status.formal.content;
2020-05-29 14:19:35 +02:00
}
}
2018-04-14 14:09:06 +02:00
2020-05-29 14:19:35 +02:00
protected string escaped_content {
owned get {
2020-06-29 23:43:45 +02:00
return status.formal.has_spoiler ? status.formal.content : "";
2020-05-29 14:19:35 +02:00
}
}
2019-03-07 17:16:52 +01:00
2020-06-29 23:43:45 +02:00
protected string display_name {
2020-05-29 14:19:35 +02:00
owned get {
var name = Html.simplify (status.formal.account.display_name);
2020-06-29 23:43:45 +02:00
return @"<b>$name</b>";
2020-05-29 14:19:35 +02:00
}
}
protected string date {
owned get {
2020-05-30 18:48:20 +02:00
var date = new GLib.DateTime.from_iso8601 (status.formal.created_at, null);
2020-05-29 14:19:35 +02:00
return Granite.DateTime.get_relative_datetime (date);
}
}
2019-03-07 17:16:52 +01:00
2020-05-29 14:19:35 +02:00
construct {
content.activate_link.connect (on_toggle_spoiler);
notify["kind"].connect (on_kind_changed);
2018-04-14 14:09:06 +02:00
2020-05-29 14:19:35 +02:00
if (kind == null) {
if (status.reblog != null)
kind = API.NotificationType.REBLOG_REMOTE_USER;
2018-04-21 11:21:03 +02:00
}
2019-03-07 17:16:52 +01:00
2020-06-20 12:04:58 +02:00
status.formal.bind_property ("favourited", favorite_button, "active", BindingFlags.SYNC_CREATE);
2020-05-29 14:19:35 +02:00
favorite_button.clicked.connect (() => {
2020-06-20 12:04:58 +02:00
status.action (status.formal.favourited ? "unfavourite" : "favourite");
2018-04-18 11:13:22 +02:00
});
2019-03-07 17:16:52 +01:00
2020-05-29 14:19:35 +02:00
status.formal.bind_property ("reblogged", reblog_button, "active", BindingFlags.SYNC_CREATE);
reblog_button.clicked.connect (() => {
status.action (status.formal.reblogged ? "unreblog" : "reblog");
2018-05-16 13:23:48 +02:00
});
2019-03-07 17:16:52 +01:00
2020-05-29 14:19:35 +02:00
reply_button.clicked.connect (() => new Dialogs.Compose.reply (status));
2020-06-29 23:43:45 +02:00
bind_property ("escaped-spoiler", content, "text", BindingFlags.SYNC_CREATE);
bind_property ("escaped-content", revealer_content, "text", BindingFlags.SYNC_CREATE);
2020-05-29 14:19:35 +02:00
status.formal.account.bind_property ("avatar", avatar, "url", BindingFlags.SYNC_CREATE);
2020-06-29 23:43:45 +02:00
status.account.bind_property ("handle", handle_label, "label", BindingFlags.SYNC_CREATE);
bind_property ("display_name", name_label, "text", BindingFlags.SYNC_CREATE);
2020-05-29 14:19:35 +02:00
bind_property ("date", date_label, "label", BindingFlags.SYNC_CREATE);
status.formal.bind_property ("pinned", pin_indicator, "visible", BindingFlags.SYNC_CREATE);
status.formal.bind_property ("has_spoiler", revealer_content, "visible", BindingFlags.SYNC_CREATE);
revealer.reveal_child = !status.formal.has_spoiler;
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");
}
2020-06-20 12:04:58 +02:00
if (status.id == "") {
2020-05-29 14:19:35 +02:00
actions.destroy ();
date_label.destroy ();
content.single_line_mode = true;
content.lines = 2;
content.ellipsize = Pango.EllipsizeMode.END;
button_press_event.connect (on_avatar_clicked);
}
else {
button_press_event.connect (open);
}
2020-06-20 12:04:58 +02:00
if (!attachments.populate (status.formal.media_attachments) || status.id == "") {
2020-05-29 14:19:35 +02:00
attachments.destroy ();
}
2020-06-03 14:41:21 +02:00
menu_button.clicked.connect (open_menu);
2020-06-03 17:06:11 +02:00
avatar.button_press_event.connect (on_avatar_clicked);
2018-04-14 14:09:06 +02:00
}
2019-03-07 17:16:52 +01:00
2020-05-29 14:19:35 +02:00
public Status (API.Status status, API.NotificationType? _kind = null) {
Object (status: status, kind: _kind);
2018-04-22 13:35:25 +02:00
}
2020-05-29 14:19:35 +02:00
~Status () {
notify["kind"].disconnect (on_kind_changed);
}
2019-03-07 17:16:52 +01:00
2020-05-29 14:19:35 +02:00
protected bool on_toggle_spoiler (string uri) {
if (uri == "tootle://toggle") {
revealer.reveal_child = !revealer.reveal_child;
return true;
}
return false;
2018-04-25 15:16:57 +02:00
}
2018-05-04 22:57:31 +02:00
2020-05-29 14:19:35 +02:00
protected virtual void on_kind_changed () {
header_icon.visible = header_label.visible = (kind != null);
if (kind == null)
return;
2019-03-07 17:16:52 +01:00
2020-05-29 14:19:35 +02:00
header_icon.icon_name = kind.get_icon ();
header_label.label = kind.get_desc (status.account);
}
2019-03-07 17:16:52 +01:00
2019-03-11 13:28:51 +01:00
public bool on_avatar_clicked (EventButton ev) {
if (ev.button == 1) {
2020-05-29 14:19:35 +02:00
var view = new Views.Profile (status.formal.account);
2019-03-11 13:28:51 +01:00
return window.open_view (view);
}
2020-06-03 17:06:11 +02:00
return true;
2018-04-14 14:09:06 +02:00
}
2019-03-07 17:16:52 +01:00
2018-05-21 17:23:31 +02:00
public bool open (EventButton ev) {
2019-03-11 13:28:51 +01:00
if (ev.button == 1) {
2020-05-29 14:19:35 +02:00
var formal = status.formal;
2019-03-11 15:14:37 +01:00
var view = new Views.ExpandedStatus (formal);
2019-03-11 13:28:51 +01:00
return window.open_view (view);
}
return false;
2018-05-21 17:23:31 +02:00
}
2019-03-07 17:16:52 +01:00
2020-06-03 14:41:21 +02:00
protected void open_menu () {
2018-05-21 17:23:31 +02:00
var menu = new Gtk.Menu ();
2019-03-07 17:16:52 +01:00
2018-05-21 17:23:31 +02:00
var item_open_link = new Gtk.MenuItem.with_label (_("Open in Browser"));
2020-05-29 14:19:35 +02:00
item_open_link.activate.connect (() => Desktop.open_uri (status.formal.url));
2018-05-21 17:23:31 +02:00
var item_copy_link = new Gtk.MenuItem.with_label (_("Copy Link"));
2020-05-29 14:19:35 +02:00
item_copy_link.activate.connect (() => Desktop.copy (status.formal.url));
2018-05-21 17:23:31 +02:00
var item_copy = new Gtk.MenuItem.with_label (_("Copy Text"));
item_copy.activate.connect (() => {
2020-05-29 14:19:35 +02:00
var sanitized = Html.remove_tags (status.formal.content);
Desktop.copy (sanitized);
2018-05-21 17:23:31 +02:00
});
2019-03-07 17:16:52 +01:00
2020-06-03 14:41:21 +02:00
// 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);
2019-03-14 12:55:27 +01:00
if (status.is_owned ()) {
2020-06-03 14:41:21 +02:00
menu.add (new SeparatorMenuItem ());
2020-05-29 14:19:35 +02:00
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);
2019-03-07 17:16:52 +01:00
2018-10-24 14:01:32 +02:00
var item_delete = new Gtk.MenuItem.with_label (_("Delete"));
item_delete.activate.connect (() => status.poof ());
2018-05-22 14:47:25 +02:00
menu.add (item_delete);
2019-03-07 17:16:52 +01:00
2018-10-24 14:01:32 +02:00
var item_redraft = new Gtk.MenuItem.with_label (_("Redraft"));
2020-05-29 14:19:35 +02:00
item_redraft.activate.connect (() => new Dialogs.Compose.redraft (status.formal));
2018-10-24 14:01:32 +02:00
menu.add (item_redraft);
2018-05-22 14:47:25 +02:00
}
2019-03-07 17:16:52 +01:00
2018-05-21 17:23:31 +02:00
menu.show_all ();
2020-06-03 14:41:21 +02:00
menu.popup_at_widget (menu_button, Gravity.SOUTH_EAST, Gravity.SOUTH_EAST);
2018-04-26 16:05:03 +02:00
}
2018-04-14 14:09:06 +02:00
}