Context menus for toots

This commit is contained in:
bleakgrey 2018-05-21 18:23:31 +03:00
parent 5309bcec9d
commit 4a1549fadf
8 changed files with 75 additions and 23 deletions

View File

@ -86,6 +86,10 @@ public class Tootle.Status {
return status;
}
public bool is_owned (){
return get_formal ().account.id == Tootle.accounts.current.id;
}
public void set_reblogged (bool rebl = true){
var action = rebl ? "reblog" : "unreblog";
var msg = new Soup.Message("POST", "%s/api/v1/statuses/%lld/%s".printf (Tootle.settings.instance_url, id, action));

View File

@ -27,7 +27,18 @@ public class Tootle.Utils{
}
public static string escape_entities (string content) {
return content.replace ("&", "&");
return content
.replace ("&", "&")
.replace ("'", "'");
}
public static void copy (string str) {
var display = Tootle.window.get_display ();
var clipboard = Gtk.Clipboard.get_for_display (display, Gdk.SELECTION_CLIPBOARD);
var normalized = str
.replace ("&", "&")
.replace ("'", "'");
clipboard.set_text (normalized, -1);
}
}

View File

@ -176,6 +176,10 @@ public class Tootle.AccountView : TimelineView {
relationship.hide ();
}
public override bool is_status_owned (ref Status status) {
return status.get_formal().account.id == account.id;
}
private Gtk.Button add_counter (string name, int? i = null, int64? val = null) {
Gtk.Button btn;
if (val != null){
@ -201,10 +205,6 @@ public class Tootle.AccountView : TimelineView {
return view.get_children ().length () <= 2;
}
public override bool is_status_owned (Status status){
return status.get_formal ().account.id == account.id;
}
public override string get_url () {
if (page_next != null)
return page_next;

View File

@ -14,14 +14,14 @@ public class Tootle.StatusView : AbstractView {
private void prepend (ref Status status, bool is_root = false){
var separator = new Gtk.Separator (Gtk.Orientation.HORIZONTAL);
separator.show ();
var widget = new StatusWidget (ref status);
if (is_root)
widget.highlight ();
widget.content_label.selectable = true;
if (widget.content_spoiler != null)
widget.content_spoiler.selectable = true;
widget.avatar.button_press_event.connect(widget.on_avatar_clicked);
var widget = new StatusWidget (ref status);
widget.avatar.button_press_event.connect(widget.open_account);
if (!is_root)
widget.button_press_event.connect(widget.open);
else
widget.highlight ();
if (!last_was_a_root) {
widget.separator = separator;
view.pack_start (separator, false, false, 0);

View File

@ -31,10 +31,6 @@ public class Tootle.TimelineView : AbstractView {
return _("Home");
}
public virtual bool is_status_owned (Status status){
return false;
}
private void on_status_added (ref Status status, string timeline) {
if (timeline != this.timeline)
return;
@ -42,6 +38,10 @@ public class Tootle.TimelineView : AbstractView {
prepend (ref status, true);
}
public virtual bool is_status_owned (ref Status status) {
return status.is_owned ();
}
public void prepend (ref Status status, bool first = false){
if (empty != null)
empty.destroy ();
@ -52,8 +52,8 @@ public class Tootle.TimelineView : AbstractView {
var widget = new StatusWidget (ref status);
widget.separator = separator;
widget.button_press_event.connect(widget.open);
if (!is_status_owned (status))
widget.avatar.button_press_event.connect(widget.on_avatar_clicked);
if (!is_status_owned (ref status))
widget.avatar.button_press_event.connect(widget.open_account);
view.pack_start(separator, false, false, 0);
view.pack_start(widget, false, false, 0);

View File

@ -12,7 +12,7 @@ public class Tootle.AccountWidget : StatusWidget {
title_acct.visible = false;
content_label.margin_bottom = 12;
button_press_event.connect(() => {
on_avatar_clicked ();
open_account ();
return true;
});
}

View File

@ -55,7 +55,7 @@ public class Tootle.NotificationWidget : Gtk.Grid {
if (notification.status != null){
status_widget = new StatusWidget (ref notification.status);
status_widget.button_press_event.connect(status_widget.open);
status_widget.avatar.button_press_event.connect(status_widget.on_avatar_clicked);
status_widget.avatar.button_press_event.connect(status_widget.open_account);
attach(status_widget, 1, 3, 3, 1);
}

View File

@ -1,4 +1,5 @@
using Gtk;
using Gdk;
using Granite;
public class Tootle.StatusWidget : Gtk.EventBox {
@ -107,6 +108,8 @@ public class Tootle.StatusWidget : Gtk.EventBox {
grid.attach (revealer, 2, 4, 1, 1);
grid.attach (counters, 2, 5, 1, 1);
show_all ();
this.button_press_event.connect (on_clicked);
}
public StatusWidget (ref Status status) {
@ -231,17 +234,51 @@ public class Tootle.StatusWidget : Gtk.EventBox {
return null;
}
public bool on_avatar_clicked () {
public bool open_account () {
var view = new AccountView (status.get_formal ().account);
Tootle.window.open_view (view);
return true;
}
public bool open () {
public bool open (EventButton ev) {
var formal = status.get_formal ();
var view = new StatusView (ref formal);
Tootle.window.open_view (view);
return false;
return true;
}
private bool on_clicked (EventButton ev) {
if (ev.button == 3)
return open_menu (ev.button, ev.time);
else
return false;
}
public bool open_menu (uint button, uint32 time) {
var menu = new Gtk.Menu ();
menu.selection_done.connect (() => {
menu.detach ();
menu.destroy ();
});
var item_open_link = new Gtk.MenuItem.with_label (_("Open in Browser"));
item_open_link.activate.connect (() => Utils.open_url (status.url));
var item_copy_link = new Gtk.MenuItem.with_label (_("Copy Link"));
item_copy_link.activate.connect (() => Utils.copy (status.url));
var item_copy = new Gtk.MenuItem.with_label (_("Copy Text"));
item_copy.activate.connect (() => {
var sanitized = Utils.escape_html (status.content);
Utils.copy (sanitized);
});
menu.add (item_open_link);
menu.add (new Gtk.SeparatorMenuItem ());
menu.add (item_copy_link);
menu.add (item_copy);
menu.show_all ();
menu.attach_widget = this;
menu.popup (null, null, null, button, time);
return true;
}
}