1
0
mirror of https://gitlab.gnome.org/World/tootle synced 2025-02-17 03:51:11 +01:00

Implement search

This commit is contained in:
bleakgrey 2018-05-14 17:43:10 +03:00
parent 0858cd88a8
commit ea790423dd
9 changed files with 170 additions and 31 deletions

View File

@ -54,6 +54,7 @@ executable(
'src/Views/StatusView.vala',
'src/Views/AccountView.vala',
'src/Views/FavoritesView.vala',
'src/Views/SearchView.vala',
dependencies: [
dependency('gtk+-3.0'),
dependency('glib-2.0', version: '>=2.30.0'),

View File

@ -10,6 +10,7 @@ public class Tootle.Account{
public string header;
public string avatar;
public string url;
public string created_at;
public int64 followers_count;
public int64 following_count;
public int64 statuses_count;
@ -33,6 +34,7 @@ public class Tootle.Account{
account.avatar = obj.get_string_member ("avatar");
account.header = obj.get_string_member ("header");
account.url = obj.get_string_member ("url");
account.created_at = obj.get_string_member ("created_at");
account.followers_count = obj.get_int_member ("followers_count");
account.following_count = obj.get_int_member ("following_count");
@ -121,7 +123,7 @@ public class Tootle.Account{
}
public Soup.Message get_stream () {
var url = "%sapi/v1/streaming/?stream=user&access_token=%s".printf (Tootle.settings.instance_url, Tootle.settings.access_token);
var url = "%s/api/v1/streaming/?stream=user&access_token=%s".printf (Tootle.settings.instance_url, Tootle.settings.access_token);
var msg = new Soup.Message("GET", url);
msg.priority = Soup.MessagePriority.VERY_HIGH;
return msg;

View File

@ -24,8 +24,8 @@ public class Tootle.AddAccountView : Tootle.AbstractView {
image.margin_bottom = 24;
entry = new Entry ();
entry.text = "https://myinstance.com/";
entry.set_placeholder_text ("https://myinstance.com/");
entry.text = "https://myinstance.com";
entry.set_placeholder_text ("https://myinstance.com");
entry.width_chars = 30;
button_next = new Button.with_label ("Next");

View File

@ -53,11 +53,7 @@ public class Tootle.HomeView : Tootle.AbstractView {
}
public virtual string get_url () {
var url = Tootle.settings.instance_url;
url += "api/v1/timelines/";
url += this.timeline;
url += "?limit=25";
var url = "%s/api/v1/timelines/%s?limit=25".printf (Tootle.settings.instance_url, this.timeline);
if (max_id > 0)
url += "&max_id=" + max_id.to_string ();

130
src/Views/SearchView.vala Normal file
View File

@ -0,0 +1,130 @@
using Gtk;
public class Tootle.SearchView : AbstractView {
Gtk.Entry entry;
construct {
view.margin_bottom = 6;
entry = new Gtk.Entry ();
entry.placeholder_text = _("Search");
entry.secondary_icon_name = "system-search-symbolic";
entry.width_chars = 25;
entry.show ();
Tootle.window.header.pack_start (entry);
destroy.connect (() => entry.destroy ());
entry.activate.connect (() => request ());
entry.icon_press.connect (() => request ());
}
public SearchView () {
entry.grab_focus_without_selecting ();
}
private void append_account (Account acc) {
var _status = new Status (-1);
_status.account = acc;
_status.content = "<a href=\"%s\">@%s</a>".printf (acc.url, acc.acct);
_status.created_at = acc.created_at;
var widget = new StatusWidget (_status);
widget.counters.visible = false;
widget.title_acct.visible = false;
widget.button_press_event.connect(() => {
widget.on_avatar_clicked ();
return true;
});
view.pack_start (widget, false, false, 0);
}
private void append_status (Status status) {
var widget = new StatusWidget (status);
widget.button_press_event.connect(widget.open);
view.pack_start (widget, false, false, 0);
}
private void append_header (string name) {
var widget = new Gtk.Label (name);
widget.get_style_context ().add_class ("h4");
widget.halign = Gtk.Align.START;
widget.margin = 6;
widget.margin_bottom = 0;
widget.show ();
view.pack_start (widget, false, false, 0);
}
private void append_empty_state (){
var empty_state = new Gtk.Label (_("No Results"));
empty_state.get_style_context ().add_class ("h2");
view.pack_start (empty_state, false, false, 6);
}
private void append_hashtag (string name) {
var text = "<a href=\"%s/tags/%s\">#%s</a>".printf (Tootle.settings.instance_url, Soup.URI.encode (name, null), name);
var widget = new RichLabel (text);
widget.use_markup = true;
widget.halign = Gtk.Align.START;
widget.margin = 6;
widget.margin_bottom = 0;
widget.show ();
view.pack_start (widget, false, false, 0);
}
private void request () {
if (entry.text == "") {
clear ();
return;
}
var query = Soup.URI.encode (entry.text, null);
var url = "%s/api/v1/search?q=%s".printf (Tootle.settings.instance_url, query);
var msg = new Soup.Message("GET", url);
Tootle.network.queue(msg, (sess, mess) => {
try{
var root = Tootle.network.parse (mess);
var accounts = root.get_array_member ("accounts");
var statuses = root.get_array_member ("statuses");
var hashtags = root.get_array_member ("hashtags");
clear ();
if (accounts.get_length () == 0 && statuses.get_length () == 0 && hashtags.get_length () == 0) {
append_empty_state ();
return;
}
if (accounts.get_length () > 0) {
append_header (_("Accounts"));
accounts.foreach_element ((array, i, node) => {
var obj = node.get_object ();
var acc = Account.parse (obj);
append_account (acc);
});
}
if (statuses.get_length () > 0) {
append_header (_("Statuses"));
statuses.foreach_element ((array, i, node) => {
var obj = node.get_object ();
var status = Status.parse (obj);
append_status (status);
});
}
if (hashtags.get_length () > 0) {
append_header (_("Hashtags"));
hashtags.foreach_element ((array, i, node) => {
append_hashtag (node.get_string ());
});
}
}
catch (GLib.Error e) {
warning ("Can't update feed");
warning (e.message);
}
});
}
}

View File

@ -8,6 +8,7 @@ public class Tootle.AccountsButton : Gtk.MenuButton{
AccountView default_account;
Gtk.ModelButton item_settings;
Gtk.ModelButton item_refresh;
Gtk.ModelButton item_search;
Gtk.ModelButton item_favs;
private class AccountView : Gtk.Grid{
@ -60,6 +61,10 @@ public class Tootle.AccountsButton : Gtk.MenuButton{
item_favs.text = _("Favorites");
item_favs.clicked.connect (() => Tootle.window.open_view (new FavoritesView ()));
item_search = new Gtk.ModelButton ();
item_search.text = _("Search");
item_search.clicked.connect (() => Tootle.window.open_view (new SearchView ()));
item_settings = new Gtk.ModelButton ();
item_settings.text = _("Settings");
@ -68,10 +73,11 @@ public class Tootle.AccountsButton : Gtk.MenuButton{
grid.width_request = 200;
grid.attach(default_account, 0, 1, 1, 1);
grid.attach(item_separator, 0, 2, 1, 1);
grid.attach(item_favs, 0, 4, 1, 1);
grid.attach(new Gtk.Separator (Gtk.Orientation.HORIZONTAL), 0, 5, 1, 1);
grid.attach(item_refresh, 0, 6, 1, 1);
grid.attach(item_settings, 0, 7, 1, 1);
grid.attach(item_favs, 0, 3, 1, 1);
grid.attach(new Gtk.Separator (Gtk.Orientation.HORIZONTAL), 0, 4, 1, 1);
grid.attach(item_refresh, 0, 5, 1, 1);
grid.attach(item_search, 0, 6, 1, 1);
//grid.attach(item_settings, 0, 8, 1, 1);
grid.show_all ();
menu = new Gtk.Popover (null);

View File

@ -63,15 +63,17 @@ public class Tootle.HeaderBar : Gtk.HeaderBar{
public void update (bool primary_mode, bool hide_all = false){
button_mode.set_active (last_tab);
if (hide_all){
button_mode.opacity = 0;
button_mode.sensitive = false;
//button_mode.opacity = 0;
//button_mode.sensitive = false;
button_mode.hide ();
button_toot.hide ();
button_back.hide ();
button_accounts.hide ();
return;
}
button_mode.opacity = primary_mode ? 1 : 0;
button_mode.sensitive = primary_mode ? true : false;
//button_mode.opacity = primary_mode ? 1 : 0;
//button_mode.sensitive = primary_mode ? true : false;
button_mode.set_visible (primary_mode);
button_toot.set_visible (primary_mode);
button_back.set_visible (!primary_mode);
button_accounts.set_visible (true);

View File

@ -31,11 +31,13 @@ public class Tootle.RichLabel : Gtk.Label {
}
}
// if ("/tags/" in url){
// var hashtag = url.split("/tags/")[1];
// //TODO: search hashtags
// return true;
// }
if ("/tags/" in url){
var encoded = url.split("/tags/")[1];
var hashtag = Soup.URI.decode (encoded);
var feed = new HomeView ("tag/" + hashtag);
Tootle.window.open_view (feed);
return true;
}
if ("/@" in url){
var profile = url.split("/@")[1];

View File

@ -15,16 +15,16 @@ public class Tootle.StatusWidget : Gtk.EventBox {
public Gtk.Revealer revealer;
public Tootle.RichLabel content_label;
public Tootle.RichLabel? content_spoiler;
Gtk.Button? spoiler_button;
Gtk.Box title_box;
AttachmentBox attachments;
Gtk.Grid grid;
Gtk.Box counters;
Gtk.Label reblogs;
Gtk.Label favorites;
ImageToggleButton reblog;
ImageToggleButton favorite;
ImageToggleButton reply;
public Gtk.Button? spoiler_button;
public Gtk.Box title_box;
public AttachmentBox attachments;
public Gtk.Grid grid;
public Gtk.Box counters;
public Gtk.Label reblogs;
public Gtk.Label favorites;
public ImageToggleButton reblog;
public ImageToggleButton favorite;
public ImageToggleButton reply;
construct {
grid = new Gtk.Grid ();