Add RichLabel class

This commit is contained in:
bleakgrey 2018-04-28 19:27:10 +03:00
parent ece9abb1b2
commit 52d34f5343
8 changed files with 138 additions and 14 deletions

View File

@ -26,12 +26,15 @@ executable(
'src/CacheManager.vala',
'src/Utils.vala',
'src/API/Account.vala',
'src/API/Mention.vala',
'src/API/Tag.vala',
'src/API/Status.vala',
'src/API/StatusVisibility.vala',
'src/API/Notification.vala',
'src/API/NotificationType.vala',
'src/Widgets/HeaderBar.vala',
'src/Widgets/AlignedLabel.vala',
'src/Widgets/RichLabel.vala',
'src/Widgets/AccountsButton.vala',
'src/Widgets/StatusWidget.vala',
'src/Widgets/NotificationWidget.vala',

29
src/API/Mention.vala Normal file
View File

@ -0,0 +1,29 @@
public class Tootle.Mention{
public int64 id;
public string username;
public string acct;
public string url;
public Mention(int64 id){
this.id = id;
}
public Mention.from_account(Account account){
this.id = account.id;
this.username = account.username;
this.acct = account.acct;
this.url = account.url;
}
public static Mention parse (Json.Object obj){
var id = int64.parse (obj.get_string_member ("id"));
var mention = new Mention (id);
mention.username = obj.get_string_member ("username");
mention.acct = obj.get_string_member ("acct");
mention.url = obj.get_string_member ("url");
return mention;
}
}

View File

@ -10,6 +10,8 @@ public class Tootle.Status{
public int64 favourites_count;
public string avatar;
public string acct;
public Mention[]? mentions;
public Tag[]? tags;
public bool reblogged;
public bool favorited;
@ -31,6 +33,25 @@ public class Tootle.Status{
status.reblogs_count = obj.get_int_member ("reblogs_count");
status.favourites_count = obj.get_int_member ("favourites_count");
status.content = Utils.escape_html ( obj.get_string_member ("content"));
Mention[]? _mentions = {};
obj.get_array_member ("mentions").foreach_element ((array, i, node) => {
var object = node.get_object ();
if (object != null)
_mentions += Mention.parse (object);
});
if (_mentions.length > 0)
status.mentions = _mentions;
Tag[]? _tags = {};
obj.get_array_member ("tags").foreach_element ((array, i, node) => {
var object = node.get_object ();
if (object != null)
_tags += Tag.parse (object);
});
if (_tags.length > 0)
status.tags = _tags;
var spoiler = obj.get_string_member ("spoiler_text");
if (spoiler != "")
status.spoiler_text = Utils.escape_html (spoiler);

17
src/API/Tag.vala Normal file
View File

@ -0,0 +1,17 @@
public class Tootle.Tag{
public string name;
public string url;
public Tag(string name, string url){
this.name = name;
this.url = url;
}
public static Tag parse (Json.Object obj){
var name = obj.get_string_member ("name");
var url = obj.get_string_member ("url");
return new Tag (name, url);
}
}

View File

@ -10,7 +10,7 @@ public class Tootle.AccountView : Tootle.HomeView {
Granite.Widgets.Avatar avatar;
Gtk.Label display_name;
Gtk.Label username;
Gtk.Label note;
Tootle.RichLabel note;
Gtk.Grid counters;
public override void pre_construct () {
@ -22,7 +22,7 @@ public class Tootle.AccountView : Tootle.HomeView {
avatar.margin_bottom = 16;
header.attach (avatar, 0, 1, 1, 1);
display_name = new Gtk.Label ("");
display_name = new RichLabel ("");
display_name.get_style_context ().add_class (Granite.STYLE_CLASS_H2_LABEL);
header.attach (display_name, 0, 2, 1, 1);
@ -30,8 +30,7 @@ public class Tootle.AccountView : Tootle.HomeView {
username.get_style_context ().add_class (Granite.STYLE_CLASS_H3_LABEL);
header.attach (username, 0, 3, 1, 1);
note = new Gtk.Label ("");
note.set_use_markup (true);
note = new RichLabel ("");
note.set_line_wrap (true);
note.get_style_context ().add_class (Granite.STYLE_CLASS_H3_LABEL);
note.justify = Gtk.Justification.CENTER;
@ -55,7 +54,7 @@ public class Tootle.AccountView : Tootle.HomeView {
base ("account_"+acc.id.to_string ());
account = acc;
display_name.label = account.display_name;
display_name.label = "<b>%s</b>".printf (account.display_name);
username.label = "@" + account.acct;
note.label = Utils.escape_html (account.note);
Tootle.cache.load_avatar (account.avatar, avatar, 128);
@ -93,4 +92,20 @@ public class Tootle.AccountView : Tootle.HomeView {
return url;
}
public static void open_from_id (int64 id){
var url = "%s/api/v1/accounts/%lld".printf (Tootle.settings.instance_url, id);
var msg = new Soup.Message("GET", url);
Tootle.network.queue(msg, (sess, mess) => {
try{
var root = Tootle.network.parse (mess);
var acc = Account.parse (root);
Tootle.window.open_secondary_view (new AccountView (acc));
}
catch (GLib.Error e) {
warning ("Can't update feed");
warning (e.message);
}
});
}
}

View File

@ -7,7 +7,7 @@ public class Tootle.NotificationWidget : Gtk.Grid {
public Gtk.Separator? separator;
private Gtk.Image image;
private Gtk.Label label;
private Tootle.RichLabel label;
private Gtk.Button dismiss_button;
private StatusWidget? status_widget;
@ -17,10 +17,9 @@ public class Tootle.NotificationWidget : Gtk.Grid {
image = new Gtk.Image.from_icon_name("notification-symbolic", Gtk.IconSize.SMALL_TOOLBAR);
image.margin_start = 32;
image.margin_end = 6;
label = new Gtk.Label (_("Unknown Notification"));
label = new RichLabel (_("Unknown Notification"));
label.hexpand = true;
label.halign = Gtk.Align.START;
label.use_markup = true;
dismiss_button = new Gtk.Button.from_icon_name ("close-symbolic", Gtk.IconSize.SMALL_TOOLBAR);
dismiss_button.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT);
dismiss_button.tooltip_text = _("Dismiss");

View File

@ -0,0 +1,41 @@
using Gtk;
public class Tootle.RichLabel : Gtk.Label {
public weak Mention[]? mentions;
public RichLabel (string text, bool override_links = true) {
label = text;
set_use_markup (true);
if (override_links)
activate_link.connect (open_link);
}
public bool open_link (string url){
if (mentions != null){
foreach (Mention mention in mentions){
if (url == mention.url){
AccountView.open_from_id (mention.id);
return true;
}
}
}
if ("/tags/" in url){
var hashtag = url.split("/tags/")[1];
//TODO: search hashtags
return true;
}
if ("/@" in url){
var profile = url.split("/@")[1];
//TODO: search profiles
return true;
}
Gtk.show_uri (null, url, Gdk.CURRENT_TIME);
return true;
}
}

View File

@ -9,7 +9,7 @@ public class Tootle.StatusWidget : Gtk.EventBox {
public Granite.Widgets.Avatar avatar;
public Gtk.Label user;
public Gtk.Revealer revealer;
public Gtk.Label content;
public Tootle.RichLabel content;
public Gtk.Separator? separator;
public Gtk.Label? spoiler_content;
Gtk.Grid grid;
@ -34,9 +34,8 @@ public class Tootle.StatusWidget : Gtk.EventBox {
user.halign = Gtk.Align.START;
user.use_markup = true;
content = new Gtk.Label ("");
content = new RichLabel ("");
content.halign = Gtk.Align.START;
content.use_markup = true;
content.single_line_mode = false;
content.set_line_wrap (true);
content.justify = Gtk.Justification.LEFT;
@ -93,9 +92,8 @@ public class Tootle.StatusWidget : Gtk.EventBox {
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);
var label = new RichLabel (label_text);
label.halign = Gtk.Align.START;
label.use_markup = true;
label.margin_bottom = 8;
label.show ();
@ -106,7 +104,7 @@ public class Tootle.StatusWidget : Gtk.EventBox {
if (status.spoiler_text != null){
revealer.reveal_child = false;
spoiler_button = new Button.with_label (_("Show content"));
spoiler_content = new Label (status.spoiler_text);
spoiler_content = new RichLabel (status.spoiler_text);
var spoiler_box = new Box (Gtk.Orientation.HORIZONTAL, 6);
spoiler_box.add (spoiler_content);
@ -135,6 +133,7 @@ public class Tootle.StatusWidget : Gtk.EventBox {
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;
content.mentions = status.mentions;
reblogs.label = status.reblogs_count.to_string ();
favorites.label = status.favourites_count.to_string ();