Make spoiler text selectable
This commit is contained in:
parent
00205e5847
commit
9de1095e08
|
@ -37,6 +37,8 @@ public class Tootle.StatusView : Tootle.AbstractView {
|
|||
|
||||
widget.rebind (status);
|
||||
widget.content.selectable = true;
|
||||
if (widget.spoiler_content != null)
|
||||
widget.spoiler_content.selectable = true;
|
||||
view.pack_start (widget, false, false, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
using Gtk;
|
||||
|
||||
public class Tootle.StatusView : Tootle.AbstractView {
|
||||
|
||||
Status root_status;
|
||||
Gtk.Box view;
|
||||
Gtk.ScrolledWindow scroll;
|
||||
|
||||
construct {
|
||||
view = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
|
||||
view.hexpand = true;
|
||||
view.valign = Gtk.Align.START;
|
||||
|
||||
scroll = new Gtk.ScrolledWindow (null, null);
|
||||
scroll.hexpand = true;
|
||||
scroll.vexpand = true;
|
||||
scroll.hscrollbar_policy = Gtk.PolicyType.NEVER;
|
||||
scroll.add (view);
|
||||
add (scroll);
|
||||
|
||||
show_all ();
|
||||
}
|
||||
|
||||
public StatusView (Status status) {
|
||||
base (false);
|
||||
root_status = status;
|
||||
request_context ();
|
||||
}
|
||||
|
||||
private void prepend (Status status, bool is_root = false){
|
||||
var widget = new StatusWidget(status);
|
||||
|
||||
if (is_root)
|
||||
widget.highlight ();
|
||||
else
|
||||
widget.margin_start = 24;
|
||||
|
||||
widget.rebind (status);
|
||||
widget.content.selectable = true;
|
||||
view.pack_start (widget, false, false, 0);
|
||||
}
|
||||
|
||||
public Soup.Message request_context (){
|
||||
var url = "%s/api/v1/statuses/%lld/context".printf (Settings.instance.instance_url, root_status.id);
|
||||
var msg = new Soup.Message("GET", url);
|
||||
NetManager.instance.queue(msg, (sess, mess) => {
|
||||
try{
|
||||
var root = NetManager.parse (mess);
|
||||
|
||||
var ancestors = root.get_array_member ("ancestors");
|
||||
ancestors.foreach_element ((array, i, node) => {
|
||||
var object = node.get_object ();
|
||||
if (object != null)
|
||||
prepend (Status.parse(object));
|
||||
});
|
||||
|
||||
prepend (root_status, true);
|
||||
|
||||
var descendants = root.get_array_member ("descendants");
|
||||
descendants.foreach_element ((array, i, node) => {
|
||||
var object = node.get_object ();
|
||||
if (object != null)
|
||||
prepend (Status.parse(object));
|
||||
});
|
||||
}
|
||||
catch (GLib.Error e) {
|
||||
warning ("Can't get context for a status");
|
||||
warning (e.message);
|
||||
}
|
||||
});
|
||||
return msg;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -11,14 +11,12 @@ public class Tootle.StatusWidget : Gtk.Grid {
|
|||
public Gtk.Revealer revealer;
|
||||
public Gtk.Label content;
|
||||
public Gtk.Separator? separator;
|
||||
|
||||
public Gtk.Label? spoiler_content;
|
||||
Gtk.Box counters;
|
||||
Gtk.Label reblogs;
|
||||
Gtk.Label favorites;
|
||||
Gtk.ToggleButton reblog;
|
||||
Gtk.ToggleButton favorite;
|
||||
|
||||
Gtk.Label? spoiler_content;
|
||||
Gtk.Button? spoiler_button;
|
||||
|
||||
construct {
|
||||
|
@ -61,17 +59,17 @@ public class Tootle.StatusWidget : Gtk.Grid {
|
|||
|
||||
counters = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6); //TODO: currently useless
|
||||
counters.margin_top = 6;
|
||||
counters.add(reblog);
|
||||
counters.add(reblogs);
|
||||
counters.add(favorite);
|
||||
counters.add(favorites);
|
||||
counters.add (reblog);
|
||||
counters.add (reblogs);
|
||||
counters.add (favorite);
|
||||
counters.add (favorites);
|
||||
counters.show_all ();
|
||||
|
||||
attach(avatar, 1, 1, 1, 4);
|
||||
attach(user, 2, 2, 1, 1);
|
||||
attach(revealer, 2, 4, 1, 1);
|
||||
attach(counters, 2, 5, 1, 1);
|
||||
show_all(); //TODO: display conversations
|
||||
attach (avatar, 1, 1, 1, 4);
|
||||
attach (user, 2, 2, 1, 1);
|
||||
attach (revealer, 2, 4, 1, 1);
|
||||
attach (counters, 2, 5, 1, 1);
|
||||
show_all (); //TODO: display conversations
|
||||
}
|
||||
|
||||
public StatusWidget (Status status) {
|
||||
|
@ -106,7 +104,7 @@ public class Tootle.StatusWidget : Gtk.Grid {
|
|||
spoiler_box.show_all ();
|
||||
|
||||
spoiler_button.clicked.connect (() => revealer.set_reveal_child (!revealer.child_revealed));
|
||||
attach(spoiler_box, 2, 3, 1, 1);
|
||||
attach (spoiler_box, 2, 3, 1, 1);
|
||||
}
|
||||
|
||||
destroy.connect (() => {
|
||||
|
@ -153,46 +151,46 @@ public class Tootle.StatusWidget : Gtk.Grid {
|
|||
return button;
|
||||
}
|
||||
|
||||
public void toggle_reblog(){
|
||||
public void toggle_reblog (){
|
||||
var state = reblog.get_active ();
|
||||
var action = "reblog";
|
||||
if (!state)
|
||||
action = "unreblog";
|
||||
|
||||
var msg = new Soup.Message("POST", Settings.instance.instance_url + "/api/v1/statuses/" + status.id.to_string () + "/" + action);
|
||||
msg.finished.connect(() => {
|
||||
msg.finished.connect (() => {
|
||||
status.reblogged = state;
|
||||
reblog.sensitive = false;
|
||||
favorite.sensitive = false;
|
||||
if(state)
|
||||
if (state)
|
||||
status.reblogs_count += 1;
|
||||
else
|
||||
status.reblogs_count -= 1;
|
||||
rebind ();
|
||||
});
|
||||
NetManager.instance.queue(msg, (sess, mess) => {
|
||||
NetManager.instance.queue (msg, (sess, mess) => {
|
||||
//NetManager.parse (msg);
|
||||
});
|
||||
}
|
||||
|
||||
public void toggle_fav(){
|
||||
public void toggle_fav (){
|
||||
var state = favorite.get_active ();
|
||||
var action = "favourite";
|
||||
if (!state)
|
||||
action = "unfavourite";
|
||||
|
||||
var msg = new Soup.Message("POST", Settings.instance.instance_url + "/api/v1/statuses/" + status.id.to_string () + "/" + action);
|
||||
msg.finished.connect(() => {
|
||||
var msg = new Soup.Message ("POST", Settings.instance.instance_url + "/api/v1/statuses/" + status.id.to_string () + "/" + action);
|
||||
msg.finished.connect (() => {
|
||||
status.favorited = state;
|
||||
reblog.sensitive = false;
|
||||
favorite.sensitive = false;
|
||||
if(state)
|
||||
if (state)
|
||||
status.favourites_count += 1;
|
||||
else
|
||||
status.favourites_count -= 1;
|
||||
rebind ();
|
||||
});
|
||||
NetManager.instance.queue(msg, (sess, mess) => {
|
||||
NetManager.instance.queue (msg, (sess, mess) => {
|
||||
//NetManager.parse (msg);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -0,0 +1,200 @@
|
|||
using Gtk;
|
||||
using Granite;
|
||||
|
||||
public class Tootle.StatusWidget : Gtk.Grid {
|
||||
|
||||
public Status status;
|
||||
|
||||
public int avatar_size;
|
||||
public Granite.Widgets.Avatar avatar;
|
||||
public Gtk.Label user;
|
||||
public Gtk.Revealer revealer;
|
||||
public Gtk.Label content;
|
||||
public Gtk.Separator? separator;
|
||||
|
||||
Gtk.Box counters;
|
||||
Gtk.Label reblogs;
|
||||
Gtk.Label favorites;
|
||||
Gtk.ToggleButton reblog;
|
||||
Gtk.ToggleButton favorite;
|
||||
|
||||
Gtk.Label? spoiler_content;
|
||||
Gtk.Button? spoiler_button;
|
||||
|
||||
construct {
|
||||
margin = 6;
|
||||
|
||||
avatar_size = 32;
|
||||
avatar = new Granite.Widgets.Avatar.with_default_icon (avatar_size);
|
||||
avatar.valign = Gtk.Align.START;
|
||||
avatar.margin_end = 6;
|
||||
user = new Gtk.Label (_("Anonymous"));
|
||||
user.hexpand = true;
|
||||
user.halign = Gtk.Align.START;
|
||||
user.use_markup = true;
|
||||
|
||||
content = new Gtk.Label (_("Error parsing text :c"));
|
||||
content.halign = Gtk.Align.START;
|
||||
content.use_markup = true;
|
||||
content.single_line_mode = false;
|
||||
content.set_line_wrap (true);
|
||||
content.justify = Gtk.Justification.LEFT;
|
||||
content.margin_end = 6;
|
||||
content.xalign = 0;
|
||||
revealer = new Revealer ();
|
||||
revealer.reveal_child = true;
|
||||
revealer.add (content);
|
||||
|
||||
reblogs = new Gtk.Label ("0");
|
||||
favorites = new Gtk.Label ("0");
|
||||
|
||||
reblog = get_action_button ();
|
||||
reblog.toggled.connect (() => {
|
||||
if (reblog.sensitive)
|
||||
toggle_reblog ();
|
||||
});
|
||||
favorite = get_action_button (false);
|
||||
favorite.toggled.connect (() => {
|
||||
if (favorite.sensitive)
|
||||
toggle_fav ();
|
||||
});
|
||||
|
||||
counters = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6); //TODO: currently useless
|
||||
counters.margin_top = 6;
|
||||
counters.add(reblog);
|
||||
counters.add(reblogs);
|
||||
counters.add(favorite);
|
||||
counters.add(favorites);
|
||||
counters.show_all ();
|
||||
|
||||
attach(avatar, 1, 1, 1, 4);
|
||||
attach(user, 2, 2, 1, 1);
|
||||
attach(revealer, 2, 4, 1, 1);
|
||||
attach(counters, 2, 5, 1, 1);
|
||||
show_all(); //TODO: display conversations
|
||||
}
|
||||
|
||||
public StatusWidget (Status status) {
|
||||
this.status = status;
|
||||
get_style_context ().add_class ("status");
|
||||
|
||||
if (status.reblog != null){
|
||||
var image = new Gtk.Image.from_icon_name("edit-undo-symbolic", Gtk.IconSize.SMALL_TOOLBAR);
|
||||
image.halign = Gtk.Align.END;
|
||||
image.margin_end = 8;
|
||||
image.show ();
|
||||
|
||||
var label_text = _("<a href=\"%s\"><b>%s</b></a> boosted").printf (status.account.url, status.account.display_name);
|
||||
var label = new Gtk.Label (label_text);
|
||||
label.halign = Gtk.Align.START;
|
||||
label.use_markup = true;
|
||||
label.margin_bottom = 8;
|
||||
label.show ();
|
||||
|
||||
attach (image, 1, 0, 1, 1);
|
||||
attach (label, 2, 0, 2, 1);
|
||||
}
|
||||
|
||||
if (status.spoiler_text != null){
|
||||
revealer.reveal_child = false;
|
||||
spoiler_button = new Button.with_label (_("Show content"));
|
||||
spoiler_content = new Label (status.spoiler_text);
|
||||
|
||||
var spoiler_box = new Box (Gtk.Orientation.HORIZONTAL, 6);
|
||||
spoiler_box.add (spoiler_content);
|
||||
spoiler_box.add (spoiler_button);
|
||||
spoiler_box.show_all ();
|
||||
|
||||
spoiler_button.clicked.connect (() => revealer.set_reveal_child (!revealer.child_revealed));
|
||||
attach(spoiler_box, 2, 3, 1, 1);
|
||||
}
|
||||
|
||||
destroy.connect (() => {
|
||||
if(separator != null)
|
||||
separator.destroy ();
|
||||
});
|
||||
}
|
||||
|
||||
public void highlight (){
|
||||
content.get_style_context ().add_class (Granite.STYLE_CLASS_H3_LABEL);
|
||||
if (spoiler_content != null)
|
||||
spoiler_content.get_style_context ().add_class (Granite.STYLE_CLASS_H3_LABEL);
|
||||
avatar_size = 48;
|
||||
avatar.show_default (avatar_size);
|
||||
}
|
||||
|
||||
public void rebind (Status status = this.status){
|
||||
var user_label = status.reblog != null ? status.reblog.account.display_name : status.account.display_name;
|
||||
user.label = "<b>%s</b>".printf (user_label);
|
||||
content.label = status.content;
|
||||
|
||||
reblogs.label = status.reblogs_count.to_string ();
|
||||
favorites.label = status.favourites_count.to_string ();
|
||||
|
||||
reblog.active = status.reblogged;
|
||||
reblog.sensitive = true;
|
||||
favorite.active = status.favorited;
|
||||
favorite.sensitive = true;
|
||||
|
||||
var avatar_url = status.reblog != null ? status.reblog.account.avatar : status.account.avatar;
|
||||
CacheManager.instance.load_avatar (avatar_url, this.avatar, this.avatar_size);
|
||||
}
|
||||
|
||||
private Gtk.ToggleButton get_action_button (bool reblog = true){
|
||||
var path = "edit-undo-symbolic";
|
||||
if (!reblog)
|
||||
path = "help-about-symbolic";
|
||||
var icon = new Gtk.Image.from_icon_name (path, Gtk.IconSize.SMALL_TOOLBAR);
|
||||
|
||||
var button = new Gtk.ToggleButton ();
|
||||
button.can_default = false;
|
||||
button.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT);
|
||||
button.add (icon);
|
||||
return button;
|
||||
}
|
||||
|
||||
public void toggle_reblog(){
|
||||
var state = reblog.get_active ();
|
||||
var action = "reblog";
|
||||
if (!state)
|
||||
action = "unreblog";
|
||||
|
||||
var msg = new Soup.Message("POST", Settings.instance.instance_url + "/api/v1/statuses/" + status.id.to_string () + "/" + action);
|
||||
msg.finished.connect(() => {
|
||||
status.reblogged = state;
|
||||
reblog.sensitive = false;
|
||||
favorite.sensitive = false;
|
||||
if(state)
|
||||
status.reblogs_count += 1;
|
||||
else
|
||||
status.reblogs_count -= 1;
|
||||
rebind ();
|
||||
});
|
||||
NetManager.instance.queue(msg, (sess, mess) => {
|
||||
//NetManager.parse (msg);
|
||||
});
|
||||
}
|
||||
|
||||
public void toggle_fav(){
|
||||
var state = favorite.get_active ();
|
||||
var action = "favourite";
|
||||
if (!state)
|
||||
action = "unfavourite";
|
||||
|
||||
var msg = new Soup.Message("POST", Settings.instance.instance_url + "/api/v1/statuses/" + status.id.to_string () + "/" + action);
|
||||
msg.finished.connect(() => {
|
||||
status.favorited = state;
|
||||
reblog.sensitive = false;
|
||||
favorite.sensitive = false;
|
||||
if(state)
|
||||
status.favourites_count += 1;
|
||||
else
|
||||
status.favourites_count -= 1;
|
||||
rebind ();
|
||||
});
|
||||
NetManager.instance.queue(msg, (sess, mess) => {
|
||||
//NetManager.parse (msg);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue