2017-03-02 14:37:32 +00:00
using Gee ;
using Gtk ;
2018-11-16 15:27:31 +00:00
using Pango ;
2017-03-02 14:37:32 +00:00
using Dino.Entities ;
2018-01-12 20:03:09 +00:00
using Xmpp ;
2017-03-02 14:37:32 +00:00
namespace Dino.Ui.ManageAccounts {
2017-12-03 18:42:15 +00:00
[ GtkTemplate ( ui = " /im/dino/Dino/manage_accounts/add_account_dialog.ui " ) ]
2017-03-02 14:37:32 +00:00
public class AddAccountDialog : Gtk . Dialog {
public signal void added ( Account account ) ;
2018-08-19 22:27:02 +00:00
[ GtkChild ] private Stack stack ;
[ GtkChild ] private Revealer notification_revealer ;
[ GtkChild ] private Label notification_label ;
2018-11-16 15:27:31 +00:00
// Sign in - JID
[ GtkChild ] private Box sign_in_jid_box ;
[ GtkChild ] private Label sign_in_jid_error_label ;
2017-03-10 17:07:28 +00:00
[ GtkChild ] private Entry jid_entry ;
2018-11-16 15:27:31 +00:00
[ GtkChild ] private Stack sign_in_jid_continue_stack ;
[ GtkChild ] private Button sign_in_jid_continue_button ;
[ GtkChild ] private Button sign_in_jid_serverlist_button ;
// Sign in - TLS error
[ GtkChild ] private Box sign_in_tls_box ;
[ GtkChild ] private Label sign_in_tls_label ;
[ GtkChild ] private Stack sign_in_password_continue_stack ;
[ GtkChild ] private Button sign_in_tls_back_button ;
// Sign in - Password
[ GtkChild ] private Box sign_in_password_box ;
[ GtkChild ] private Label sign_in_password_title ;
[ GtkChild ] private Label sign_in_password_error_label ;
2017-03-10 17:07:28 +00:00
[ GtkChild ] private Entry password_entry ;
2018-11-16 15:27:31 +00:00
[ GtkChild ] private Button sign_in_password_continue_button ;
[ GtkChild ] private Button sign_in_password_back_button ;
2018-08-19 22:27:02 +00:00
// Select Server
[ GtkChild ] private Box create_account_box ;
[ GtkChild ] private Button login_button ;
[ GtkChild ] private Stack select_server_continue_stack ;
[ GtkChild ] private Button select_server_continue ;
[ GtkChild ] private Label register_form_continue_label ;
[ GtkChild ] private ListBox server_list_box ;
[ GtkChild ] private Entry server_entry ;
// Register Form
[ GtkChild ] private Box register_box ;
[ GtkChild ] private Label register_title ;
[ GtkChild ] private Box form_box ;
[ GtkChild ] private Button register_form_back ;
[ GtkChild ] private Stack register_form_continue_stack ;
[ GtkChild ] private Button register_form_continue ;
2018-11-16 15:27:31 +00:00
// Success
[ GtkChild ] private Box success_box ;
[ GtkChild ] private Label success_description ;
[ GtkChild ] private Button success_continue_button ;
2018-08-19 22:27:02 +00:00
private static string [ ] server_list = new string [ ] {
" 5222.de " ,
" jabber.fr " ,
" movim.eu " ,
" yax.im "
} ;
2018-11-16 15:27:31 +00:00
private StreamInteractor stream_interactor ;
2019-08-23 19:19:26 +00:00
private Database db ;
2018-08-19 22:27:02 +00:00
private HashMap < ListBoxRow , string > list_box_jids = new HashMap < ListBoxRow , string > ( ) ;
private Jid ? server_jid = null ;
2019-12-22 03:10:53 +00:00
private Jid ? login_jid = null ;
2018-08-19 22:27:02 +00:00
private Xep . InBandRegistration . Form ? form = null ;
2017-03-02 14:37:32 +00:00
2019-08-23 19:19:26 +00:00
public AddAccountDialog ( StreamInteractor stream_interactor , Database db ) {
2018-11-16 15:27:31 +00:00
this . stream_interactor = stream_interactor ;
2019-08-23 19:19:26 +00:00
this . db = db ;
2017-04-07 09:09:47 +00:00
this . title = _ ( " Add Account " ) ;
2017-03-02 14:37:32 +00:00
2018-11-16 15:27:31 +00:00
// Sign in - Jid
Util . force_error_color ( sign_in_jid_error_label ) ;
2017-03-02 14:37:32 +00:00
jid_entry . changed . connect ( on_jid_entry_changed ) ;
2018-11-16 15:27:31 +00:00
sign_in_jid_continue_button . clicked . connect ( on_sign_in_jid_continue_button_clicked ) ;
sign_in_jid_serverlist_button . clicked . connect ( show_select_server ) ;
// Sign in - TLS error
sign_in_tls_back_button . clicked . connect ( show_sign_in_jid ) ;
// Sign in - Password
Util . force_error_color ( sign_in_password_error_label ) ;
password_entry . changed . connect ( ( ) = > { sign_in_password_continue_button . set_sensitive ( password_entry . text . length > 0 ) ; } ) ;
sign_in_password_continue_button . clicked . connect ( on_sign_in_password_continue_button_clicked ) ;
sign_in_password_back_button . clicked . connect ( show_sign_in_jid ) ;
2018-08-19 22:27:02 +00:00
// Select Server
server_entry . changed . connect ( ( ) = > {
2019-12-22 03:10:53 +00:00
try {
Jid jid = new Jid ( server_entry . text ) ;
select_server_continue . sensitive = jid ! = null & & jid . localpart = = null & & jid . resourcepart = = null ;
} catch ( InvalidJidError e ) {
select_server_continue . sensitive = false ;
}
2018-08-19 22:27:02 +00:00
} ) ;
select_server_continue . clicked . connect ( on_select_server_continue ) ;
2018-11-16 15:27:31 +00:00
login_button . clicked . connect ( show_sign_in_jid ) ;
2018-08-19 22:27:02 +00:00
foreach ( string server in server_list ) {
ListBoxRow list_box_row = new ListBoxRow ( ) { visible = true } ;
list_box_row . add ( new Label ( server ) { xalign = 0 , margin = 3 , margin_start = 7 , margin_end = 7 , visible = true } ) ;
list_box_jids [ list_box_row ] = server ;
server_list_box . add ( list_box_row ) ;
}
// Register Form
register_form_continue . clicked . connect ( on_register_form_continue_clicked ) ;
register_form_back . clicked . connect ( show_select_server ) ;
2018-11-16 15:27:31 +00:00
// Success
success_continue_button . clicked . connect ( ( ) = > close ( ) ) ;
show_sign_in_jid ( ) ;
2018-08-19 22:27:02 +00:00
}
2018-11-16 15:27:31 +00:00
private void show_sign_in_jid ( ) {
sign_in_jid_box . visible = true ;
2019-12-23 16:29:35 +00:00
jid_entry . grab_focus ( ) ;
2018-11-16 15:27:31 +00:00
stack . visible_child_name = " login_jid " ;
sign_in_tls_box . visible = false ;
sign_in_password_box . visible = false ;
2018-08-19 22:27:02 +00:00
create_account_box . visible = false ;
register_box . visible = false ;
2018-11-16 15:27:31 +00:00
success_box . visible = false ;
set_default ( sign_in_jid_continue_button ) ;
sign_in_jid_error_label . label = " " ;
2019-12-22 03:10:53 +00:00
jid_entry . sensitive = true ;
2018-11-16 15:27:31 +00:00
animate_window_resize ( sign_in_jid_box ) ;
}
private void show_tls_error ( ) {
sign_in_tls_box . visible = true ;
stack . visible_child_name = " tls_error " ;
sign_in_jid_box . visible = false ;
sign_in_password_box . visible = false ;
create_account_box . visible = false ;
register_box . visible = false ;
success_box . visible = false ;
}
private void show_sign_in_password ( ) {
sign_in_password_box . visible = true ;
2019-12-23 16:29:35 +00:00
password_entry . grab_focus ( ) ;
2018-11-16 15:27:31 +00:00
stack . visible_child_name = " login_password " ;
sign_in_jid_box . visible = false ;
sign_in_tls_box . visible = false ;
create_account_box . visible = false ;
register_box . visible = false ;
success_box . visible = false ;
set_default ( sign_in_password_continue_button ) ;
sign_in_password_error_label . label = " " ;
2019-12-22 03:10:53 +00:00
sign_in_password_title . label = _ ( " Sign in to %s " ) . printf ( login_jid . to_string ( ) ) ;
2018-11-16 15:27:31 +00:00
animate_window_resize ( sign_in_password_box ) ;
2018-08-19 22:27:02 +00:00
}
private void show_select_server ( ) {
server_entry . text = " " ;
server_entry . grab_focus ( ) ;
set_default ( select_server_continue ) ;
2019-12-23 16:29:35 +00:00
server_list_box . row_activated . disconnect ( on_server_list_row_activated ) ;
2018-08-19 22:27:02 +00:00
server_list_box . unselect_all ( ) ;
2019-12-23 16:29:35 +00:00
server_list_box . row_activated . connect ( on_server_list_row_activated ) ;
2018-08-19 22:27:02 +00:00
create_account_box . visible = true ;
stack . visible_child_name = " server " ;
2018-11-16 15:27:31 +00:00
sign_in_jid_box . visible = false ;
sign_in_tls_box . visible = false ;
2018-08-19 22:27:02 +00:00
register_box . visible = false ;
2018-11-16 15:27:31 +00:00
success_box . visible = false ;
2018-08-19 22:27:02 +00:00
animate_window_resize ( create_account_box ) ;
}
private void show_register_form ( ) {
register_box . visible = true ;
stack . visible_child_name = " form " ;
2018-11-16 15:27:31 +00:00
sign_in_jid_box . visible = false ;
sign_in_tls_box . visible = false ;
sign_in_password_box . visible = false ;
2018-08-19 22:27:02 +00:00
create_account_box . visible = false ;
2018-11-16 15:27:31 +00:00
success_box . visible = false ;
2018-08-19 22:27:02 +00:00
set_default ( register_form_continue ) ;
animate_window_resize ( register_box ) ;
2017-03-02 14:37:32 +00:00
}
2019-12-23 15:54:19 +00:00
private void show_success ( Account account ) {
2018-11-16 15:27:31 +00:00
success_box . visible = true ;
stack . visible_child_name = " success " ;
sign_in_jid_box . visible = false ;
sign_in_tls_box . visible = false ;
sign_in_password_box . visible = false ;
create_account_box . visible = false ;
register_box . visible = false ;
2020-04-12 19:32:18 +00:00
success_description . label = _ ( " You can now use the account %s. " ) . printf ( " <b> " + Markup . escape_text ( account . bare_jid . to_string ( ) ) + " </b> " ) ;
2018-11-16 15:27:31 +00:00
set_default ( success_continue_button ) ;
}
2017-03-02 14:37:32 +00:00
private void on_jid_entry_changed ( ) {
2019-12-22 03:10:53 +00:00
try {
login_jid = new Jid ( jid_entry . text ) ;
if ( login_jid . localpart ! = null & & login_jid . resourcepart = = null ) {
sign_in_jid_continue_button . sensitive = true ;
jid_entry . secondary_icon_name = null ;
} else {
sign_in_jid_continue_button . sensitive = false ;
}
} catch ( InvalidJidError e ) {
sign_in_jid_continue_button . sensitive = false ;
2017-03-02 14:37:32 +00:00
}
}
2018-11-16 15:27:31 +00:00
private async void on_sign_in_jid_continue_button_clicked ( ) {
2019-12-22 03:10:53 +00:00
try {
login_jid = new Jid ( jid_entry . text ) ;
jid_entry . sensitive = false ;
sign_in_tls_label . label = " " ;
sign_in_jid_error_label . label = " " ;
sign_in_jid_continue_button . sensitive = false ;
sign_in_jid_continue_stack . visible_child_name = " spinner " ;
Register . ServerAvailabilityReturn server_status = yield Register . check_server_availability ( login_jid ) ;
sign_in_jid_continue_stack . visible_child_name = " label " ;
sign_in_jid_continue_button . sensitive = true ;
if ( server_status . available ) {
show_sign_in_password ( ) ;
2018-11-16 15:27:31 +00:00
} else {
2019-12-22 03:10:53 +00:00
jid_entry . sensitive = true ;
if ( server_status . error_flags ! = null ) {
string error_desc = " The server could not prove that it is %s. " . printf ( " <b> " + login_jid . domainpart + " </b> " ) ;
if ( TlsCertificateFlags . UNKNOWN_CA in server_status . error_flags ) {
error_desc + = " " + " Its security certificate is not trusted by your computer's operating system. " ;
} else if ( TlsCertificateFlags . BAD_IDENTITY in server_status . error_flags ) {
error_desc + = " " + " Its security certificate is issued to another domain. " ;
} else if ( TlsCertificateFlags . NOT_ACTIVATED in server_status . error_flags ) {
error_desc + = " " + " Its security certificate will only become valid in the future. " ;
} else if ( TlsCertificateFlags . EXPIRED in server_status . error_flags ) {
error_desc + = " " + " Its security certificate is expired. " ;
}
sign_in_tls_label . label = error_desc ;
show_tls_error ( ) ;
} else {
sign_in_jid_error_label . label = _ ( " Could not connect to %s " ) . printf ( login_jid . domainpart ) ;
}
2018-11-16 15:27:31 +00:00
}
2019-12-22 03:10:53 +00:00
} catch ( InvalidJidError e ) {
warning ( " Invalid address from interface allowed login: %s " , e . message ) ;
sign_in_jid_error_label . label = _ ( " Invalid address " ) ;
2017-03-02 14:37:32 +00:00
}
}
2018-11-16 15:27:31 +00:00
private async void on_sign_in_password_continue_button_clicked ( ) {
2019-12-22 03:10:53 +00:00
string password = password_entry . text ;
Account account = new Account ( login_jid , null , password , null ) ;
2018-11-16 15:27:31 +00:00
sign_in_password_continue_stack . visible_child_name = " spinner " ;
ConnectionManager . ConnectionError . Source ? error = yield stream_interactor . get_module ( Register . IDENTITY ) . add_check_account ( account ) ;
sign_in_password_continue_stack . visible_child_name = " label " ;
if ( error ! = null ) {
switch ( error ) {
case ConnectionManager . ConnectionError . Source . SASL :
sign_in_password_error_label . label = _ ( " Wrong username or password " ) ;
break ;
default :
2019-12-22 03:10:53 +00:00
sign_in_password_error_label . label = _ ( " Something went wrong " ) ;
2018-11-16 15:27:31 +00:00
break ;
}
} else {
2019-08-23 19:19:26 +00:00
add_activate_account ( account ) ;
2019-12-23 15:54:19 +00:00
show_success ( account ) ;
2018-11-16 15:27:31 +00:00
}
2018-08-19 22:27:02 +00:00
}
private void on_select_server_continue ( ) {
2019-12-22 03:10:53 +00:00
try {
server_jid = new Jid ( server_entry . text ) ;
request_show_register_form . begin ( ) ;
} catch ( InvalidJidError e ) {
warning ( " Invalid address from interface allowed server: %s " , e . message ) ;
display_notification ( _ ( " Invalid address " ) ) ;
}
2018-08-19 22:27:02 +00:00
}
2019-12-23 16:29:35 +00:00
private void on_server_list_row_activated ( ListBox box , ListBoxRow row ) {
2019-12-22 03:10:53 +00:00
try {
server_jid = new Jid ( list_box_jids [ row ] ) ;
request_show_register_form . begin ( ) ;
} catch ( InvalidJidError e ) {
warning ( " Invalid address from selected server: %s " , e . message ) ;
display_notification ( _ ( " Invalid address " ) ) ;
}
2018-08-19 22:27:02 +00:00
}
private async void request_show_register_form ( ) {
select_server_continue_stack . visible_child_name = " spinner " ;
form = yield Register . get_registration_form ( server_jid ) ;
if ( select_server_continue_stack = = null ) {
return ;
}
select_server_continue_stack . visible_child_name = " label " ;
if ( form ! = null ) {
set_register_form ( server_jid , form ) ;
show_register_form ( ) ;
} else {
display_notification ( _ ( " No response from server " ) ) ;
}
}
private void set_register_form ( Jid server , Xep . InBandRegistration . Form form ) {
form_box . foreach ( ( widget ) = > { widget . destroy ( ) ; } ) ;
register_title . label = _ ( " Register on %s " ) . printf ( server . to_string ( ) ) ;
if ( form . oob ! = null ) {
2019-09-10 23:19:24 +00:00
form_box . add ( new Label ( _ ( " The server requires to sign up through a website " ) ) { visible = true } ) ;
2018-08-19 22:27:02 +00:00
form_box . add ( new Label ( @" <a href= \" $(form.oob) \" >$(form.oob)</a> " ) { use_markup = true , visible = true } ) ;
2020-03-24 20:34:10 +00:00
register_form_continue_label . label = _ ( " Open website " ) ;
2018-08-19 22:27:02 +00:00
register_form_continue . visible = true ;
register_form_continue . grab_focus ( ) ;
} else if ( form . fields . size > 0 ) {
foreach ( Xep . DataForms . DataForm . Field field in form . fields ) {
2019-12-16 00:34:28 +00:00
Widget ? field_widget = Util . get_data_form_field_widget ( field ) ;
2019-11-18 23:00:08 +00:00
if ( field . label ! = null & & field . label ! = " " & & field_widget ! = null ) {
2018-08-19 22:27:02 +00:00
form_box . add ( new Label ( field . label ) { xalign = 0 , margin_top = 7 , visible = true } ) ;
form_box . add ( field_widget ) ;
}
}
register_form_continue . visible = true ;
register_form_continue_label . label = _ ( " Register " ) ;
} else {
form_box . add ( new Label ( _ ( " Check %s for information on how to sign up " ) . printf ( @" <a href= \" http://$(server) \" >$(server)</a> " ) ) { use_markup = true , visible = true } ) ;
register_form_continue . visible = false ;
}
}
private async void on_register_form_continue_clicked ( ) {
notification_revealer . set_reveal_child ( false ) ;
// Button is opening a registration website
if ( form . oob ! = null ) {
try {
AppInfo . launch_default_for_uri ( form . oob , null ) ;
} catch ( Error e ) { }
2018-11-16 15:27:31 +00:00
show_sign_in_jid ( ) ;
2018-08-19 22:27:02 +00:00
return ;
}
register_form_continue_stack . visible_child_name = " spinner " ;
string ? error = yield Register . submit_form ( server_jid , form ) ;
if ( register_form_continue_stack = = null ) {
return ;
}
register_form_continue_stack . visible_child_name = " label " ;
if ( error = = null ) {
string ? username = null , password = null ;
foreach ( Xep . DataForms . DataForm . Field field in form . fields ) {
switch ( field . var ) {
case " username " : username = field . get_value_string ( ) ; break ;
case " password " : password = field . get_value_string ( ) ; break ;
}
}
2019-12-22 03:10:53 +00:00
try {
Account account = new Account ( new Jid . components ( username , server_jid . domainpart , null ) , null , password , null ) ;
add_activate_account ( account ) ;
show_success ( account ) ;
} catch ( InvalidJidError e ) {
warning ( " Invalid address from components of registration: %s " , e . message ) ;
display_notification ( _ ( " Invalid address " ) ) ;
}
2018-08-19 22:27:02 +00:00
} else {
display_notification ( error ) ;
}
}
private void display_notification ( string text ) {
notification_label . label = text ;
notification_revealer . set_reveal_child ( true ) ;
Timeout . add_seconds ( 5 , ( ) = > {
notification_revealer . set_reveal_child ( false ) ;
return false ;
} ) ;
}
2019-08-23 19:19:26 +00:00
private void add_activate_account ( Account account ) {
account . enabled = true ;
account . persist ( db ) ;
stream_interactor . connect_account ( account ) ;
added ( account ) ;
}
2018-08-19 22:27:02 +00:00
private void animate_window_resize ( Widget widget ) { // TODO code duplication
int def_height , curr_width , curr_height ;
get_size ( out curr_width , out curr_height ) ;
widget . get_preferred_height ( null , out def_height ) ;
def_height + = 5 ;
int difference = def_height - curr_height ;
Timer timer = new Timer ( ) ;
Timeout . add ( ( int ) ( stack . transition_duration / 30 ) ,
( ) = > {
ulong microsec ;
timer . elapsed ( out microsec ) ;
ulong millisec = microsec / 1000 ;
double partial = double . min ( 1 , ( double ) millisec / stack . transition_duration ) ;
resize ( curr_width , ( int ) ( curr_height + difference * partial ) ) ;
return millisec < stack . transition_duration ;
} ) ;
2017-03-02 14:37:32 +00:00
}
}
2017-03-10 17:07:28 +00:00
2017-03-02 14:37:32 +00:00
}