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

213 lines
7.3 KiB
Vala
Raw Normal View History

2018-04-14 14:09:06 +02:00
using Gtk;
using Granite;
2018-04-25 13:45:50 +02:00
public class Tootle.StatusWidget : Gtk.EventBox {
2018-04-14 14:09:06 +02:00
2018-04-16 20:22:42 +02:00
public Status status;
public int64? date_utc;
2018-04-16 20:22:42 +02:00
2018-04-22 13:35:25 +02:00
public int avatar_size;
2018-05-03 10:11:31 +02:00
public Gtk.Separator? separator;
2018-04-14 14:09:06 +02:00
public Granite.Widgets.Avatar avatar;
public Gtk.Label title_user;
public Gtk.Label title_date;
public Gtk.Label title_acct;
2018-04-23 19:02:21 +02:00
public Gtk.Revealer revealer;
2018-04-28 18:27:10 +02:00
public Tootle.RichLabel content;
2018-04-24 12:11:10 +02:00
public Gtk.Label? spoiler_content;
Gtk.Box title_box;
2018-04-25 13:45:50 +02:00
Gtk.Grid grid;
2018-04-14 14:09:06 +02:00
Gtk.Box counters;
Gtk.Label reblogs;
Gtk.Label favorites;
2018-04-16 20:22:42 +02:00
Gtk.ToggleButton reblog;
Gtk.ToggleButton favorite;
2018-04-24 16:50:38 +02:00
Gtk.ToggleButton reply;
2018-04-23 18:43:29 +02:00
Gtk.Button? spoiler_button;
2018-04-14 14:09:06 +02:00
construct {
2018-04-25 13:45:50 +02:00
grid = new Gtk.Grid ();
2018-04-14 19:18:42 +02:00
2018-04-22 13:35:25 +02:00
avatar_size = 32;
avatar = new Granite.Widgets.Avatar.with_default_icon (avatar_size);
2018-04-14 14:09:06 +02:00
avatar.valign = Gtk.Align.START;
2018-05-01 18:37:45 +02:00
avatar.margin_top = 6;
avatar.margin_start = 6;
2018-04-14 14:09:06 +02:00
avatar.margin_end = 6;
title_box = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6);
title_box.hexpand = true;
title_box.margin_end = 12;
title_box.margin_top = 6;
title_user = new Gtk.Label ("");
title_user.use_markup = true;
title_box.pack_start (title_user, false, false, 0);
title_acct = new Gtk.Label ("");
title_acct.opacity = 0.5;
title_box.pack_start (title_acct, false, false, 0);
title_date = new Gtk.Label ("");
title_date.ellipsize = Pango.EllipsizeMode.END;
title_box.pack_end (title_date, false, false, 0);
title_box.show_all ();
2018-04-23 19:02:21 +02:00
2018-04-28 18:27:10 +02:00
content = new RichLabel ("");
2018-04-14 14:09:06 +02:00
content.halign = Gtk.Align.START;
content.single_line_mode = false;
content.set_line_wrap (true);
2018-04-30 18:04:22 +02:00
content.wrap_mode = Pango.WrapMode.WORD_CHAR;
2018-04-14 14:09:06 +02:00
content.justify = Gtk.Justification.LEFT;
2018-05-01 18:37:45 +02:00
content.margin_end = 12;
2018-04-14 14:09:06 +02:00
content.xalign = 0;
2018-04-23 19:02:21 +02:00
revealer = new Revealer ();
revealer.reveal_child = true;
revealer.add (content);
2018-04-14 14:09:06 +02:00
reblogs = new Gtk.Label ("0");
favorites = new Gtk.Label ("0");
2018-04-16 20:22:42 +02:00
2018-04-24 16:50:38 +02:00
reblog = get_action_button ("go-up-symbolic");
2018-04-30 18:04:22 +02:00
reblog.tooltip_text = _("Boost");
2018-04-16 20:22:42 +02:00
reblog.toggled.connect (() => {
if (reblog.sensitive)
2018-05-01 15:53:46 +02:00
status.set_reblogged (reblog.get_active ());
2018-04-16 20:22:42 +02:00
});
2018-04-24 16:50:38 +02:00
favorite = get_action_button ("help-about-symbolic");
2018-04-30 18:04:22 +02:00
favorite.tooltip_text = _("Favorite");
2018-04-16 20:22:42 +02:00
favorite.toggled.connect (() => {
if (favorite.sensitive)
2018-05-01 15:53:46 +02:00
status.set_favorited (favorite.get_active ());
2018-04-16 20:22:42 +02:00
});
2018-04-24 16:50:38 +02:00
reply = get_action_button ("edit-undo-symbolic");
2018-04-30 18:04:22 +02:00
reply.tooltip_text = _("Reply");
2018-04-24 16:50:38 +02:00
reply.toggled.connect (() => {
reply.set_active (false);
PostDialog.open_reply (Tootle.window, this.status);
});
2018-04-16 20:22:42 +02:00
2018-04-14 19:18:42 +02:00
counters = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6); //TODO: currently useless
2018-04-14 14:09:06 +02:00
counters.margin_top = 6;
2018-05-01 18:37:45 +02:00
counters.margin_bottom = 6;
2018-04-24 12:11:10 +02:00
counters.add (reblog);
counters.add (reblogs);
counters.add (favorite);
counters.add (favorites);
2018-04-24 16:50:38 +02:00
counters.add (reply);
2018-04-14 14:09:06 +02:00
counters.show_all ();
2018-04-25 13:45:50 +02:00
grid.attach (avatar, 1, 1, 1, 4);
grid.attach (title_box, 2, 2, 1, 1);
2018-04-25 13:45:50 +02:00
grid.attach (revealer, 2, 4, 1, 1);
grid.attach (counters, 2, 5, 1, 1);
add (grid);
2018-04-24 12:11:10 +02:00
show_all (); //TODO: display conversations
2018-04-14 14:09:06 +02:00
}
2018-04-16 20:22:42 +02:00
public StatusWidget (Status status) {
this.status = status;
2018-05-01 15:53:46 +02:00
status.updated.connect (rebind);
2018-04-14 14:09:06 +02:00
get_style_context ().add_class ("status");
2018-04-18 11:13:22 +02:00
2018-04-21 11:21:03 +02:00
if (status.reblog != null){
2018-04-24 16:50:38 +02:00
var image = new Gtk.Image.from_icon_name("go-up-symbolic", Gtk.IconSize.SMALL_TOOLBAR);
2018-04-21 11:21:03 +02:00
image.halign = Gtk.Align.END;
2018-05-01 18:37:45 +02:00
image.margin_end = 6;
image.margin_top = 6;
2018-04-21 11:21:03 +02:00
image.show ();
2018-04-21 11:27:00 +02:00
var label_text = _("<a href=\"%s\"><b>%s</b></a> boosted").printf (status.account.url, status.account.display_name);
2018-04-28 18:27:10 +02:00
var label = new RichLabel (label_text);
2018-04-21 11:21:03 +02:00
label.halign = Gtk.Align.START;
2018-05-01 18:37:45 +02:00
label.margin_top = 6;
2018-04-21 11:21:03 +02:00
label.show ();
2018-04-25 13:45:50 +02:00
grid.attach (image, 1, 0, 1, 1);
grid.attach (label, 2, 0, 2, 1);
2018-04-21 11:21:03 +02:00
}
2018-04-23 18:43:29 +02:00
if (status.spoiler_text != null){
2018-04-23 19:02:21 +02:00
revealer.reveal_child = false;
2018-04-30 18:04:22 +02:00
spoiler_button = new Button.with_label (_("Toggle content"));
2018-04-28 18:27:10 +02:00
spoiler_content = new RichLabel (status.spoiler_text);
2018-04-23 19:02:21 +02:00
var spoiler_box = new Box (Gtk.Orientation.HORIZONTAL, 6);
2018-04-23 18:43:29 +02:00
spoiler_box.add (spoiler_content);
spoiler_box.add (spoiler_button);
spoiler_box.show_all ();
2018-04-23 19:02:21 +02:00
spoiler_button.clicked.connect (() => revealer.set_reveal_child (!revealer.child_revealed));
2018-04-25 13:45:50 +02:00
grid.attach (spoiler_box, 2, 3, 1, 1);
2018-04-23 18:43:29 +02:00
}
2018-04-18 11:13:22 +02:00
destroy.connect (() => {
if(separator != null)
separator.destroy ();
});
2018-05-01 15:53:46 +02:00
rebind ();
2018-04-14 14:09:06 +02:00
}
2018-04-22 13:35:25 +02:00
public void highlight (){
2018-05-01 18:37:45 +02:00
grid.get_style_context ().add_class ("card");
grid.margin_bottom = 6;
2018-04-22 13:35:25 +02:00
}
2018-05-01 15:53:46 +02:00
public void rebind (){
title_user.label = "<b>%s</b>".printf (status.get_formal ().account.display_name);
title_acct.label = "@" + status.account.acct;
2018-04-14 14:09:06 +02:00
content.label = status.content;
2018-04-28 18:27:10 +02:00
content.mentions = status.mentions;
parse_date_iso8601 (status.created_at);
2018-04-14 14:09:06 +02:00
reblogs.label = status.reblogs_count.to_string ();
favorites.label = status.favourites_count.to_string ();
2018-04-30 18:04:22 +02:00
reblog.sensitive = false;
2018-04-16 20:22:42 +02:00
reblog.active = status.reblogged;
reblog.sensitive = true;
2018-04-30 18:04:22 +02:00
favorite.sensitive = false;
2018-04-16 20:22:42 +02:00
favorite.active = status.favorited;
favorite.sensitive = true;
Tootle.cache.load_avatar (status.get_formal ().account.avatar, this.avatar, this.avatar_size);
2018-04-25 15:16:57 +02:00
}
// elementary OS has old GLib, so I have to improvise
// Version >=2.56 provides DateTime.from_iso8601
public void parse_date_iso8601 (string date){
2018-05-02 14:28:46 +02:00
var cmd = "date -d " + date + " +%s";
2018-05-03 10:11:31 +02:00
var runner = new CmdRunner ("/bin/", cmd); //Workaround for Granite SimpleCommand pipes bug
runner.done.connect (exit => {
date_utc = int64.parse (runner.standard_output_str);
var date_obj = new GLib.DateTime.from_unix_local (date_utc);
title_date.label = Granite.DateTime.get_relative_datetime (date_obj);
});
runner.run ();
}
2018-04-26 16:05:03 +02:00
public bool on_avatar_clicked (){
var view = new AccountView (status.get_formal ().account);
2018-04-25 15:16:57 +02:00
Tootle.window.open_secondary_view (view);
return true;
2018-04-14 14:09:06 +02:00
}
2018-04-16 20:22:42 +02:00
2018-04-26 16:05:03 +02:00
public bool open (){
var view = new StatusView (status.get_formal ());
2018-04-26 16:05:03 +02:00
Tootle.window.open_secondary_view (view);
return false;
}
2018-04-24 16:50:38 +02:00
private Gtk.ToggleButton get_action_button (string icon_path){
var icon = new Gtk.Image.from_icon_name (icon_path, Gtk.IconSize.SMALL_TOOLBAR);
2018-04-16 20:22:42 +02:00
var button = new Gtk.ToggleButton ();
2018-04-19 20:17:20 +02:00
button.can_default = false;
2018-04-30 19:56:02 +02:00
button.set_focus_on_click (false);
2018-04-19 20:17:20 +02:00
button.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT);
2018-04-16 20:22:42 +02:00
button.add (icon);
return button;
}
2018-04-14 14:09:06 +02:00
}