Tooth/src/Views/Profile.vala

263 lines
7.8 KiB
Vala
Raw Normal View History

2018-04-25 13:16:57 +00:00
using Gtk;
2022-11-13 20:57:43 +00:00
public class Tooth.Views.Profile : Views.Timeline {
2019-03-07 16:16:52 +00:00
2020-09-05 08:02:42 +00:00
public API.Account profile { get; construct set; }
public API.Relationship rs { get; construct set; }
public bool include_replies { get; set; default = false; }
public bool only_media { get; set; default = false; }
public string source { get; set; default = "statuses"; }
2020-06-29 21:43:45 +00:00
2021-07-23 11:41:03 +00:00
protected Cover cover;
protected MenuButton menu_button;
2021-07-25 15:35:51 +00:00
protected Widgets.RelationshipButton rs_button;
2021-07-23 11:41:03 +00:00
protected SimpleAction media_action;
protected SimpleAction replies_action;
protected SimpleAction muting_action;
protected SimpleAction hiding_reblogs_action;
protected SimpleAction blocking_action;
protected SimpleAction domain_blocking_action;
protected SimpleAction source_action;
2020-07-10 14:22:38 +00:00
2020-09-05 08:02:42 +00:00
construct {
2021-07-23 11:41:03 +00:00
cover = build_cover ();
column_view.prepend (cover);
2020-09-05 08:02:42 +00:00
}
public Profile (API.Account acc) {
Object (
profile: acc,
rs: new API.Relationship.for_account (acc),
2021-07-23 11:41:03 +00:00
label: _("Profile"),
2020-09-05 08:02:42 +00:00
url: @"/api/v1/accounts/$(acc.id)/statuses"
);
2021-07-23 11:41:03 +00:00
cover.bind (profile);
2020-09-05 08:02:42 +00:00
}
2022-11-13 20:57:43 +00:00
[GtkTemplate (ui = "/dev/geopjr/tooth/ui/views/profile_header.ui")]
2021-07-23 11:41:03 +00:00
protected class Cover : Box {
[GtkChild] unowned Widgets.Background background;
[GtkChild] unowned ListBox info;
[GtkChild] unowned Widgets.RichLabel display_name;
[GtkChild] unowned Label handle;
[GtkChild] unowned Widgets.Avatar avatar;
[GtkChild] unowned Widgets.MarkupView note;
public void bind (API.Account account) {
display_name.label = account.display_name;
handle.label = account.handle;
avatar.account = account;
note.content = account.note;
image_cache.request_paintable (account.header, on_cache_response);
if (account.fields != null) {
foreach (API.AccountField f in account.fields) {
var row = new Adw.ActionRow ();
var val = new Widgets.RichLabel (HtmlUtils.simplify (f.val));
val.wrap = false;
2021-07-23 11:41:03 +00:00
val.xalign = 1;
row.title = f.name;
row.add_suffix (val);
info.append (row);
}
}
2021-07-23 11:41:03 +00:00
}
void on_cache_response (bool is_loaded, owned Gdk.Paintable? data) {
background.paintable = data;
}
}
protected override void build_header () {
base.build_header ();
menu_button = new MenuButton ();
var menu_builder = new Builder.from_resource (@"$(Build.RESOURCES)ui/menus.ui");
var menu = "profile-menu";
menu_button.menu_model = menu_builder.get_object (menu) as MenuModel;
menu_button.popover.width_request = 250;
menu_button.icon_name = "view-more-symbolic";
header.pack_end (menu_button);
2021-07-25 15:35:51 +00:00
rs_button = new Widgets.RelationshipButton () {
rs = this.rs
};
if (profile.id != accounts.active.id)
header.pack_end (rs_button);
2021-07-23 11:41:03 +00:00
}
protected virtual Cover build_cover () {
return new Cover ();
}
2021-07-23 11:41:03 +00:00
protected override void build_actions () {
base.build_actions ();
2020-09-05 08:02:42 +00:00
media_action = new SimpleAction.stateful ("only-media", null, false);
media_action.change_state.connect (v => {
media_action.set_state (only_media = v.get_boolean ());
invalidate_actions (true);
});
actions.add_action (media_action);
replies_action = new SimpleAction.stateful ("include-replies", null, false);
replies_action.change_state.connect (v => {
replies_action.set_state (include_replies = v.get_boolean ());
invalidate_actions (true);
});
actions.add_action (replies_action);
2021-07-23 11:41:03 +00:00
source_action = new SimpleAction.stateful ("source", VariantType.STRING, source);
2020-09-05 08:02:42 +00:00
source_action.change_state.connect (v => {
source = v.get_string ();
source_action.set_state (source);
2021-07-23 11:41:03 +00:00
accepts = (source == "statuses" ? typeof (API.Status) : typeof (API.Account));
2020-09-05 08:02:42 +00:00
url = @"/api/v1/accounts/$(profile.id)/$source";
invalidate_actions (true);
});
actions.add_action (source_action);
var mention_action = new SimpleAction ("mention", VariantType.STRING);
mention_action.activate.connect (v => {
var status = new API.Status.empty ();
2021-07-23 11:41:03 +00:00
status.visibility = v.get_string ();
2020-09-05 08:02:42 +00:00
status.content = @"$(profile.handle) ";
new Dialogs.Compose (status);
});
actions.add_action (mention_action);
2021-07-23 11:41:03 +00:00
//FIXME: Take a variant to copy "handle" and "uri"
var copy_handle_action = new SimpleAction ("copy_handle", null);
copy_handle_action.activate.connect (v => {
2021-07-23 11:41:03 +00:00
Host.copy (profile.handle);
});
actions.add_action (copy_handle_action);
2020-09-05 08:02:42 +00:00
muting_action = new SimpleAction.stateful ("muting", null, false);
muting_action.change_state.connect (v => {
var state = v.get_boolean ();
rs.modify (state ? "mute" : "unmute");
});
actions.add_action (muting_action);
hiding_reblogs_action = new SimpleAction.stateful ("hiding_reblogs", null, false);
hiding_reblogs_action.change_state.connect (v => {
2021-07-23 11:41:03 +00:00
if (!rs.following) {
warning ("Trying to hide boosts while not following an account.");
return;
}
2020-09-05 08:02:42 +00:00
var state = !v.get_boolean ();
rs.modify ("follow", "reblogs", @"$state");
});
actions.add_action (hiding_reblogs_action);
blocking_action = new SimpleAction.stateful ("blocking", null, false);
blocking_action.change_state.connect (v => {
var block = v.get_boolean ();
var q = block ? _("Block \"%s\"?") : _("Unblock \"%s\"?");
var yes = app.question (q.printf (profile.handle));
2021-07-25 15:35:51 +00:00
warning (q);
2020-09-05 08:02:42 +00:00
if (yes)
rs.modify (block ? "block" : "unblock");
});
actions.add_action (blocking_action);
domain_blocking_action = new SimpleAction.stateful ("domain_blocking", null, false);
domain_blocking_action.change_state.connect (v => {
var block = v.get_boolean ();
var q = block ? _("Block Entire \"%s\"?") : _("Unblock Entire \"%s\"?");
2021-07-25 15:35:51 +00:00
warning (q);
2020-09-05 08:02:42 +00:00
var yes = app.question (
q.printf (profile.domain),
_("Blocking a domain will:\n\n• Remove its public posts and notifications from your timelines\n• Remove its followers from your account\n• Prevent you from following its users")
);
if (yes) {
var req = new Request.POST ("/api/v1/domain_blocks")
.with_account (accounts.active)
.with_param ("domain", profile.domain)
.then (() => {
rs.request ();
});
if (!block) req.method = "DELETE";
req.exec ();
}
});
actions.add_action (domain_blocking_action);
invalidate_actions (false);
}
void invalidate_actions (bool refresh) {
replies_action.set_enabled (accepts == typeof (API.Status));
media_action.set_enabled (accepts == typeof (API.Status));
muting_action.set_state (rs.muting);
hiding_reblogs_action.set_state (!rs.showing_reblogs);
hiding_reblogs_action.set_enabled (rs.following);
blocking_action.set_state (rs.blocking);
domain_blocking_action.set_state (rs.domain_blocking);
domain_blocking_action.set_enabled (accounts.active.domain != profile.domain);
if (refresh) {
page_next = null;
on_refresh ();
}
}
2019-03-07 16:16:52 +00:00
2021-07-25 15:35:51 +00:00
// TODO: RS badges
void on_rs_updated () {
2021-07-23 11:41:03 +00:00
// var label = "";
// if (rs_button.sensitive = rs != null) {
// if (rs.requested)
// label = _("Sent follow request");
// else if (rs.followed_by && rs.following)
// label = _("Mutually follows you");
// else if (rs.followed_by)
// label = _("Follows you");
2020-05-29 12:19:35 +00:00
2021-07-23 11:41:03 +00:00
// string action_icon = "";
// string action_label = "";
// get_rs_button_state (ref action_label, ref action_icon, ref rs_button_action);
// rs_button.icon_name = action_icon;
// rs_button.label = action_label;
// }
// relationship.label = label;
// relationship.visible = label != "";
2020-09-05 08:02:42 +00:00
invalidate_actions (false);
2020-05-29 12:19:35 +00:00
}
2019-03-07 16:16:52 +00:00
2020-05-29 12:19:35 +00:00
public override Request append_params (Request req) {
2020-09-05 08:02:42 +00:00
if (page_next == null && source == "statuses") {
req.with_param ("exclude_replies", @"$(!include_replies)");
req.with_param ("only_media", @"$(only_media)");
2020-06-20 10:04:58 +00:00
return base.append_params (req);
}
2020-09-05 08:02:42 +00:00
else return req;
2020-05-29 12:19:35 +00:00
}
2020-09-05 08:02:42 +00:00
public static void open_from_id (string id) {
var msg = new Soup.Message ("GET", @"$(accounts.active.instance)/api/v1/accounts/$id");
network.queue (msg, (sess, mess) => {
var node = network.parse_node (mess);
var acc = API.Account.from (node);
2021-07-23 11:41:03 +00:00
app.main_window.open_view (new Views.Profile (acc));
},
network.on_error);
2020-06-29 21:43:45 +00:00
}
2018-04-25 13:16:57 +00:00
}