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 ( ) ;
2022-11-13 11:00:59 +00:00
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 ) ;
}
2020-10-15 15:55:13 +00:00
}
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 ( ) ;
2020-10-15 15:55:13 +00:00
}
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"
2020-10-15 15:55:13 +00:00
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 ) ;
2020-10-15 15:55:13 +00:00
} ) ;
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-10-15 15:55:13 +00:00
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
}