2013-05-03 00:29:52 +02:00
var settings = ( function ( ) {
var exports = { } ;
2016-06-14 23:56:38 +02:00
var _streams _deferred = $ . Deferred ( ) ;
var streams = _streams _deferred . promise ( ) ; // promise to the full stream list
2013-05-03 00:29:52 +02:00
2014-02-24 16:50:03 +01:00
function build _stream _list ( $select , extra _names ) {
if ( extra _names === undefined ) {
extra _names = [ ] ;
2014-02-19 16:07:28 +01:00
}
2014-02-24 16:50:03 +01:00
streams . done ( function ( stream _items ) {
var build _option = function ( value _name ) {
return $ ( '<option>' )
. attr ( 'value' , value _name [ 0 ] )
. text ( value _name [ 1 ] ) ;
} ;
var public _names = _ . chain ( stream _items )
2016-12-03 03:08:47 +01:00
. where ( { invite _only : false } )
2014-02-24 16:50:03 +01:00
. pluck ( 'name' )
. map ( function ( x ) { return [ x , x ] ; } )
. value ( ) ;
var public _options = _ . chain ( extra _names . concat ( public _names ) )
. map ( build _option )
. reduce (
function ( $optgroup , option ) { return $optgroup . append ( option ) ; } ,
$ ( '<optgroup label="Public"/>' )
)
. value ( ) ;
var private _options = _ . chain ( stream _items )
2016-12-03 03:08:47 +01:00
. where ( { invite _only : true } )
2014-02-24 16:50:03 +01:00
. pluck ( 'name' )
. map ( function ( x ) { return [ x , x ] ; } )
. map ( build _option )
. reduce (
function ( $optgroup , option ) { return $optgroup . append ( option ) ; } ,
$ ( '<optgroup label="Private"/>' )
)
. value ( ) ;
2014-02-11 19:53:55 +01:00
2014-02-19 16:07:28 +01:00
$select . empty ( ) ;
2014-02-24 16:50:03 +01:00
$select . append ( public _options ) ;
$select . append ( private _options ) ;
2014-02-19 16:07:28 +01:00
} ) ;
}
2013-06-14 20:03:54 +02:00
2014-02-19 16:07:28 +01:00
function add _bot _row ( info ) {
info . id _suffix = _ . uniqueId ( '_bot_' ) ;
2013-07-05 21:52:38 +02:00
var row = $ ( templates . render ( 'bot_avatar_row' , info ) ) ;
2014-02-19 16:07:28 +01:00
var default _sending _stream _select = row . find ( 'select[name=bot_default_sending_stream]' ) ;
var default _events _register _stream _select = row . find ( 'select[name=bot_default_events_register_stream]' ) ;
if ( ! feature _flags . new _bot _ui ) {
row . find ( '.new-bot-ui' ) . hide ( ) ;
}
var to _extra _options = [ ] ;
if ( info . default _sending _stream === null ) {
to _extra _options . push ( [ '' , 'No default selected' ] ) ;
}
build _stream _list (
default _sending _stream _select ,
to _extra _options
) ;
default _sending _stream _select . val (
info . default _sending _stream ,
to _extra _options
) ;
var events _extra _options = [ [ '__all_public__' , 'All public streams' ] ] ;
if ( info . default _events _register _stream === null && ! info . default _all _public _streams ) {
events _extra _options . unshift ( [ '' , 'No default selected' ] ) ;
}
build _stream _list (
default _events _register _stream _select ,
events _extra _options
) ;
if ( info . default _all _public _streams ) {
default _events _register _stream _select . val ( '__all_public__' ) ;
} else {
default _events _register _stream _select . val ( info . default _events _register _stream ) ;
}
2013-07-05 20:59:25 +02:00
$ ( '#bots_list' ) . append ( row ) ;
$ ( '#bots_list' ) . show ( ) ;
2013-05-03 00:29:52 +02:00
}
2016-12-02 15:16:33 +01:00
function add _bot _default _streams _to _form ( formData , default _sending _stream ,
default _events _register _stream ) {
2014-02-19 16:08:18 +01:00
if ( ! feature _flags . new _bot _ui ) { return ; }
if ( default _sending _stream !== '' ) {
formData . append ( 'default_sending_stream' , default _sending _stream ) ;
}
if ( default _events _register _stream === '__all_public__' ) {
formData . append ( 'default_all_public_streams' , JSON . stringify ( true ) ) ;
formData . append ( 'default_events_register_stream' , null ) ;
} else if ( default _events _register _stream !== '' ) {
formData . append ( 'default_all_public_streams' , JSON . stringify ( false ) ) ;
formData . append ( 'default_events_register_stream' , default _events _register _stream ) ;
}
}
2013-05-03 00:29:52 +02:00
function is _local _part ( value , element ) {
// Adapted from Django's EmailValidator
return this . optional ( element ) || /^[\-!#$%&'*+\/=?\^_`{}|~0-9A-Z]+(\.[\-!#$%&'*+\/=?\^_`{}|~0-9A-Z]+)*$/i . test ( value ) ;
}
2014-02-27 18:27:58 +01:00
function render _bots ( ) {
$ ( '#bots_list' ) . empty ( ) ;
_ . each ( bot _data . get _editable ( ) , function ( elem ) {
add _bot _row ( {
name : elem . full _name ,
email : elem . email ,
avatar _url : elem . avatar _url ,
api _key : elem . api _key ,
2016-12-07 18:38:59 +01:00
zuliprc : 'zuliprc' , // Most browsers do not allow filename starting with `.`
2014-02-27 18:27:58 +01:00
default _sending _stream : elem . default _sending _stream ,
default _events _register _stream : elem . default _events _register _stream ,
default _all _public _streams : elem . default _all _public _streams
} ) ;
} ) ;
}
2016-12-07 18:38:59 +01:00
exports . generate _zuliprc _uri = function ( email , api _key ) {
var data = settings . generate _zuliprc _content ( email , api _key ) ;
return "data:application/octet-stream;charset=utf-8," + encodeURIComponent ( data ) ;
} ;
exports . generate _zuliprc _content = function ( email , api _key ) {
return "[api]" +
"\nemail=" + email +
"\nkey=" + api _key +
"\nsite=" + page _params . realm _uri +
// Some tools would not work in files without a trailing new line.
"\n" ;
} ;
2013-11-19 17:15:48 +01:00
// Choose avatar stamp fairly randomly, to help get old avatars out of cache.
exports . avatar _stamp = Math . floor ( Math . random ( ) * 100 ) ;
2016-06-10 09:03:36 +02:00
function _setup _page ( ) {
2014-02-19 16:07:28 +01:00
// To build the edit bot streams dropdown we need both the bot and stream
// API results. To prevent a race streams will be initialized to a promise
// at page load. This promise will be resolved with a list of streams after
// the first settings page load. build_stream_list then adds a callback to
// the promise, which in most cases will already be resolved.
2016-06-14 23:56:38 +02:00
if ( _streams _deferred . state ( ) !== "resolved" ) {
2014-02-19 16:07:28 +01:00
channel . get ( {
url : '/json/streams' ,
success : function ( data ) {
2016-06-14 23:56:38 +02:00
_streams _deferred . resolve ( data . streams ) ;
2014-02-19 16:07:28 +01:00
build _stream _list ( $ ( '#create_bot_default_sending_stream' ) ) ;
build _stream _list (
$ ( '#create_bot_default_events_register_stream' ) ,
[ [ '__all_public__' , 'All public streams' ] ]
) ;
}
} ) ;
}
2016-12-07 18:38:59 +01:00
// Most browsers do not allow filenames to start with `.` without the user manually changing it.
var settings _tab = templates . render ( 'settings_tab' , { page _params : page _params , zuliprc : 'zuliprc' } ) ;
2014-02-13 23:47:57 +01:00
$ ( "#settings" ) . html ( settings _tab ) ;
$ ( "#settings-status" ) . hide ( ) ;
$ ( "#notify-settings-status" ) . hide ( ) ;
2015-08-19 22:35:46 +02:00
$ ( "#display-settings-status" ) . hide ( ) ;
2014-02-13 23:47:57 +01:00
$ ( "#ui-settings-status" ) . hide ( ) ;
2014-03-04 23:37:29 +01:00
alert _words _ui . set _up _alert _words ( ) ;
2014-02-13 23:47:57 +01:00
$ ( "#api_key_value" ) . text ( "" ) ;
$ ( "#get_api_key_box" ) . hide ( ) ;
$ ( "#show_api_key_box" ) . hide ( ) ;
$ ( "#api_key_button_box" ) . show ( ) ;
function clear _password _change ( ) {
// Clear the password boxes so that passwords don't linger in the DOM
// for an XSS attacker to find.
$ ( '#old_password, #new_password, #confirm_password' ) . val ( '' ) ;
}
clear _password _change ( ) ;
$ ( '#api_key_button' ) . click ( function ( e ) {
if ( page _params . password _auth _enabled !== false ) {
$ ( "#get_api_key_box" ) . show ( ) ;
} else {
// Skip the password prompt step
$ ( "#get_api_key_box form" ) . submit ( ) ;
}
$ ( "#api_key_button_box" ) . hide ( ) ;
} ) ;
$ ( '#pw_change_link' ) . on ( 'click' , function ( e ) {
e . preventDefault ( ) ;
$ ( '#pw_change_link' ) . hide ( ) ;
$ ( '#pw_change_controls' ) . show ( ) ;
2016-06-04 02:19:07 +02:00
if ( page _params . password _auth _enabled !== false ) {
// zxcvbn.js is pretty big, and is only needed on password
// change, so load it asynchronously.
2016-12-06 17:22:06 +01:00
$ . getScript ( '/static/node_modules/zxcvbn/dist/zxcvbn.js' , function ( ) {
2016-06-04 02:19:07 +02:00
$ ( '#pw_strength .bar' ) . removeClass ( "fade" ) ;
} ) ;
}
2014-02-13 23:47:57 +01:00
} ) ;
$ ( '#new_password' ) . on ( 'change keyup' , function ( ) {
password _quality ( $ ( '#new_password' ) . val ( ) , $ ( '#pw_strength .bar' ) ) ;
} ) ;
2013-10-28 15:49:38 +01:00
2015-08-20 09:11:11 +02:00
if ( ! page _params . show _digest _email ) {
$ ( "#other_notifications" ) . hide ( ) ;
2013-12-02 03:01:09 +01:00
}
2014-02-11 19:53:55 +01:00
if ( ! feature _flags . new _bot _ui ) {
$ ( '.new-bot-ui' ) . hide ( ) ;
}
2013-10-28 15:49:38 +01:00
2015-08-21 01:23:53 +02:00
function settings _change _error ( message , xhr ) {
// Scroll to the top so the error message is visible.
// We would scroll anyway if we end up submitting the form.
viewport . scrollTop ( 0 ) ;
ui . report _error ( message , xhr , $ ( '#settings-status' ) . expectOne ( ) ) ;
}
2014-02-13 23:47:57 +01:00
2015-08-21 01:23:53 +02:00
function settings _change _success ( message ) {
2014-02-13 23:47:57 +01:00
// Scroll to the top so the error message is visible.
// We would scroll anyway if we end up submitting the form.
viewport . scrollTop ( 0 ) ;
2015-08-21 01:23:53 +02:00
ui . report _success ( message , $ ( '#settings-status' ) . expectOne ( ) ) ;
2014-02-13 23:47:57 +01:00
}
$ ( "form.your-account-settings" ) . ajaxForm ( {
dataType : 'json' , // This seems to be ignored. We still get back an xhr.
beforeSubmit : function ( arr , form , options ) {
if ( page _params . password _auth _enabled !== false ) {
// FIXME: Check that the two password fields match
// FIXME: Use the same jQuery validation plugin as the signup form?
var new _pw = $ ( '#new_password' ) . val ( ) ;
if ( new _pw !== '' ) {
var password _ok = password _quality ( new _pw ) ;
if ( password _ok === undefined ) {
// zxcvbn.js didn't load, for whatever reason.
settings _change _error (
'An internal error occurred; try reloading the page. ' +
'Sorry for the trouble!' ) ;
return false ;
} else if ( ! password _ok ) {
settings _change _error ( 'New password is too weak' ) ;
return false ;
}
}
}
return true ;
} ,
success : function ( resp , statusText , xhr , form ) {
2015-08-21 01:23:53 +02:00
settings _change _success ( "Updated settings!" ) ;
2014-02-13 23:47:57 +01:00
} ,
error : function ( xhr , error _type , xhn ) {
2015-08-21 01:23:53 +02:00
settings _change _error ( "Error changing settings" , xhr ) ;
2014-02-13 23:47:57 +01:00
} ,
complete : function ( xhr , statusText ) {
// Whether successful or not, clear the password boxes.
// TODO: Clear these earlier, while the request is still pending.
clear _password _change ( ) ;
}
} ) ;
function update _notification _settings _success ( resp , statusText , xhr , form ) {
var message = "Updated notification settings!" ;
2016-08-24 23:56:23 +02:00
var result = JSON . parse ( xhr . responseText ) ;
2014-02-13 23:47:57 +01:00
var notify _settings _status = $ ( '#notify-settings-status' ) . expectOne ( ) ;
// Stream notification settings.
if ( result . enable _stream _desktop _notifications !== undefined ) {
2016-12-02 15:16:33 +01:00
page _params . stream _desktop _notifications _enabled =
result . enable _stream _desktop _notifications ;
2014-02-13 23:47:57 +01:00
}
if ( result . enable _stream _sounds !== undefined ) {
page _params . stream _sounds _enabled = result . enable _stream _sounds ;
}
// PM and @-mention notification settings.
if ( result . enable _desktop _notifications !== undefined ) {
page _params . desktop _notifications _enabled = result . enable _desktop _notifications ;
}
if ( result . enable _sounds !== undefined ) {
page _params . sounds _enabled = result . enable _sounds ;
}
if ( result . enable _offline _email _notifications !== undefined ) {
2016-12-02 15:16:33 +01:00
page _params . enable _offline _email _notifications =
result . enable _offline _email _notifications ;
2014-02-13 23:47:57 +01:00
}
if ( result . enable _offline _push _notifications !== undefined ) {
2016-12-02 15:16:33 +01:00
page _params . enable _offline _push _notifications =
result . enable _offline _push _notifications ;
2014-02-13 23:47:57 +01:00
}
2016-09-19 22:55:18 +02:00
if ( result . enable _online _push _notifications !== undefined ) {
page _params . enable _online _push _notifications = result . enable _online _push _notifications ;
}
2014-02-13 23:47:57 +01:00
// Other notification settings.
if ( result . enable _digest _emails !== undefined ) {
page _params . enable _digest _emails = result . enable _digest _emails ;
}
2016-06-23 12:56:00 +02:00
ui . report _success ( i18n . t ( "Updated notification settings!" ) , notify _settings _status ) ;
2014-02-13 23:47:57 +01:00
}
function update _notification _settings _error ( xhr , error _type , xhn ) {
2016-06-23 13:05:17 +02:00
ui . report _error ( i18n . t ( "Error changing settings" ) , xhr , $ ( '#notify-settings-status' ) . expectOne ( ) ) ;
2014-02-13 23:47:57 +01:00
}
function post _notify _settings _changes ( notification _changes , success _func ,
error _func ) {
return channel . post ( {
url : "/json/notify_settings/change" ,
data : notification _changes ,
success : success _func ,
error : error _func
} ) ;
}
$ ( "#change_notification_settings" ) . on ( "click" , function ( e ) {
var updated _settings = { } ;
_ . each ( [ "enable_stream_desktop_notifications" , "enable_stream_sounds" ,
"enable_desktop_notifications" , "enable_sounds" ,
"enable_offline_email_notifications" ,
2016-09-19 22:55:18 +02:00
"enable_offline_push_notifications" , "enable_online_push_notifications" ,
"enable_digest_emails" ] ,
2014-02-13 23:47:57 +01:00
function ( setting ) {
updated _settings [ setting ] = $ ( "#" + setting ) . is ( ":checked" ) ;
} ) ;
post _notify _settings _changes ( updated _settings ,
update _notification _settings _success ,
update _notification _settings _error ) ;
} ) ;
function update _global _stream _setting ( notification _type , new _setting ) {
var data = { } ;
data [ notification _type ] = new _setting ;
channel . post ( {
url : "/json/notify_settings/change" ,
data : data ,
success : update _notification _settings _success ,
error : update _notification _settings _error
} ) ;
}
function update _desktop _notification _setting ( new _setting ) {
update _global _stream _setting ( "enable_stream_desktop_notifications" , new _setting ) ;
subs . set _all _stream _desktop _notifications _to ( new _setting ) ;
}
function update _audible _notification _setting ( new _setting ) {
update _global _stream _setting ( "enable_stream_sounds" , new _setting ) ;
subs . set _all _stream _audible _notifications _to ( new _setting ) ;
}
function maybe _bulk _update _stream _notification _setting ( notification _checkbox ,
propagate _setting _function ) {
var html = templates . render ( "propagate_notification_change" ) ;
var control _group = notification _checkbox . closest ( ".control-group" ) ;
var checkbox _status = notification _checkbox . is ( ":checked" ) ;
control _group . find ( ".propagate_stream_notifications_change" ) . html ( html ) ;
control _group . find ( ".yes_propagate_notifications" ) . on ( "click" , function ( e ) {
propagate _setting _function ( checkbox _status ) ;
control _group . find ( ".propagate_stream_notifications_change" ) . empty ( ) ;
} ) ;
control _group . find ( ".no_propagate_notifications" ) . on ( "click" , function ( e ) {
control _group . find ( ".propagate_stream_notifications_change" ) . empty ( ) ;
} ) ;
}
$ ( "#enable_stream_desktop_notifications" ) . on ( "click" , function ( e ) {
var notification _checkbox = $ ( "#enable_stream_desktop_notifications" ) ;
maybe _bulk _update _stream _notification _setting ( notification _checkbox ,
update _desktop _notification _setting ) ;
} ) ;
$ ( "#enable_stream_sounds" ) . on ( "click" , function ( e ) {
var notification _checkbox = $ ( "#enable_stream_sounds" ) ;
maybe _bulk _update _stream _notification _setting ( notification _checkbox ,
update _audible _notification _setting ) ;
} ) ;
2015-08-20 23:59:44 +02:00
$ ( "#left_side_userlist" ) . change ( function ( ) {
var left _side _userlist = this . checked ;
var data = { } ;
data . left _side _userlist = JSON . stringify ( left _side _userlist ) ;
2016-07-01 11:55:23 +02:00
var context = { } ;
if ( data . left _side _userlist === "true" ) {
2016-10-10 06:46:09 +02:00
context . side = i18n . t ( 'left' ) ;
2016-07-01 11:55:23 +02:00
} else {
2016-10-10 06:46:09 +02:00
context . side = i18n . t ( 'right' ) ;
2016-07-01 11:55:23 +02:00
}
2015-08-20 23:59:44 +02:00
channel . patch ( {
url : '/json/left_side_userlist' ,
data : data ,
success : function ( resp , statusText , xhr , form ) {
2016-07-01 11:55:23 +02:00
ui . report _success ( i18n . t ( "User list will appear on the __side__ hand side! You will need to reload the window for your changes to take effect." , context ) ,
2015-08-20 23:59:44 +02:00
$ ( '#display-settings-status' ) . expectOne ( ) ) ;
} ,
error : function ( xhr , error _type , xhn ) {
2016-07-01 11:55:23 +02:00
ui . report _error ( i18n . t ( "Error updating user list placement setting" ) , xhr , $ ( '#display-settings-status' ) . expectOne ( ) ) ;
2015-08-20 23:59:44 +02:00
}
} ) ;
} ) ;
2015-08-19 22:35:46 +02:00
$ ( "#twenty_four_hour_time" ) . change ( function ( ) {
var data = { } ;
2015-09-20 08:17:36 +02:00
var setting _value = $ ( "#twenty_four_hour_time" ) . is ( ":checked" ) ;
data . twenty _four _hour _time = JSON . stringify ( setting _value ) ;
2016-07-01 11:55:23 +02:00
var context = { } ;
if ( data . twenty _four _hour _time === "true" ) {
context . format = '24' ;
} else {
context . format = '12' ;
}
2015-08-19 22:35:46 +02:00
channel . patch ( {
url : '/json/time_setting' ,
data : data ,
success : function ( resp , statusText , xhr , form ) {
2016-07-01 11:55:23 +02:00
ui . report _success ( i18n . t ( "Time will be displayed in the __format__-hour format! You will need to reload the window for your changes to take effect" , context ) ,
2015-08-21 01:23:53 +02:00
$ ( '#display-settings-status' ) . expectOne ( ) ) ;
2015-09-20 08:17:36 +02:00
} ,
2015-08-19 22:35:46 +02:00
error : function ( xhr , error _type , xhn ) {
2016-07-01 11:55:23 +02:00
ui . report _error ( i18n . t ( "Error updating time format setting" ) , xhr , $ ( '#display-settings-status' ) . expectOne ( ) ) ;
2016-06-23 11:32:45 +02:00
}
} ) ;
} ) ;
2016-08-02 15:03:42 +02:00
$ ( "#default_language_modal .language" ) . click ( function ( e ) {
e . preventDefault ( ) ;
e . stopPropagation ( ) ;
$ ( '#default_language_modal' ) . modal ( 'hide' ) ;
2016-06-23 11:32:45 +02:00
var data = { } ;
2016-10-19 22:20:21 +02:00
var $link = $ ( e . target ) . closest ( "a[data-code]" ) ;
var setting _value = $link . attr ( 'data-code' ) ;
2016-06-23 11:32:45 +02:00
data . default _language = JSON . stringify ( setting _value ) ;
2016-08-02 15:03:42 +02:00
2016-10-19 22:20:21 +02:00
var new _language = $link . attr ( 'data-name' ) ;
2016-08-02 15:03:42 +02:00
$ ( '#default_language_name' ) . text ( new _language ) ;
2016-07-01 11:55:23 +02:00
var context = { } ;
2016-08-02 15:03:42 +02:00
context . lang = new _language ;
2016-06-23 11:32:45 +02:00
channel . patch ( {
url : '/json/language_setting' ,
data : data ,
success : function ( resp , statusText , xhr , form ) {
2016-07-01 11:55:23 +02:00
ui . report _success ( i18n . t ( "__lang__ is now the default language! You will need to reload the window for your changes to take effect" , context ) ,
2016-06-23 11:32:45 +02:00
$ ( '#display-settings-status' ) . expectOne ( ) ) ;
} ,
error : function ( xhr , error _type , xhn ) {
2016-07-01 11:55:23 +02:00
ui . report _error ( i18n . t ( "Error updating default language setting" ) , xhr , $ ( '#display-settings-status' ) . expectOne ( ) ) ;
2015-08-19 22:35:46 +02:00
}
} ) ;
} ) ;
2016-08-02 15:03:42 +02:00
$ ( '#default_language' ) . on ( 'click' , function ( e ) {
e . preventDefault ( ) ;
e . stopPropagation ( ) ;
$ ( '#default_language_modal' ) . modal ( 'show' ) ;
} ) ;
2015-08-19 22:35:46 +02:00
2016-10-13 20:09:32 +02:00
$ ( "#user_deactivate_account_button" ) . on ( 'click' , function ( e ) {
e . preventDefault ( ) ;
e . stopPropagation ( ) ;
$ ( "#deactivate_self_modal" ) . modal ( "show" ) ;
} ) ;
$ ( "#do_deactivate_self_button" ) . on ( 'click' , function ( e ) {
$ ( "#deactivate_self_modal" ) . modal ( "hide" ) ;
channel . del ( {
url : '/json/users/me' ,
success : function ( ) {
window . location . href = "/login" ;
} ,
error : function ( xhr , error _type ) {
ui . report _error ( i18n . t ( "Error deactivating account" ) , xhr , $ ( '#settings-status' ) . expectOne ( ) ) ;
}
} ) ;
} ) ;
2014-02-13 23:47:57 +01:00
$ ( "#get_api_key_box" ) . hide ( ) ;
$ ( "#show_api_key_box" ) . hide ( ) ;
$ ( "#get_api_key_box form" ) . ajaxForm ( {
dataType : 'json' , // This seems to be ignored. We still get back an xhr.
success : function ( resp , statusText , xhr , form ) {
var message = "Updated settings!" ;
2016-08-24 23:56:23 +02:00
var result = JSON . parse ( xhr . responseText ) ;
2014-02-13 23:47:57 +01:00
var settings _status = $ ( '#settings-status' ) . expectOne ( ) ;
$ ( "#get_api_key_password" ) . val ( "" ) ;
$ ( "#api_key_value" ) . text ( result . api _key ) ;
$ ( "#show_api_key_box" ) . show ( ) ;
$ ( "#get_api_key_box" ) . hide ( ) ;
settings _status . hide ( ) ;
} ,
error : function ( xhr , error _type , xhn ) {
2016-06-23 13:05:17 +02:00
ui . report _error ( i18n . t ( "Error getting API key" ) , xhr , $ ( '#settings-status' ) . expectOne ( ) ) ;
2014-02-13 23:47:57 +01:00
$ ( "#show_api_key_box" ) . hide ( ) ;
$ ( "#get_api_key_box" ) . show ( ) ;
}
} ) ;
2013-10-28 15:49:38 +01:00
function upload _avatar ( file _input ) {
var form _data = new FormData ( ) ;
form _data . append ( 'csrfmiddlewaretoken' , csrf _token ) ;
jQuery . each ( file _input [ 0 ] . files , function ( i , file ) {
form _data . append ( 'file-' + i , file ) ;
} ) ;
var spinner = $ ( "#upload_avatar_spinner" ) . expectOne ( ) ;
2014-03-13 15:03:01 +01:00
loading . make _indicator ( spinner , { text : 'Uploading avatar.' } ) ;
2013-10-28 15:49:38 +01:00
2013-12-18 19:55:18 +01:00
channel . post ( {
2013-10-28 15:49:38 +01:00
url : '/json/set_avatar' ,
data : form _data ,
cache : false ,
processData : false ,
contentType : false ,
success : function ( data ) {
2014-03-13 15:03:01 +01:00
loading . destroy _indicator ( $ ( "#upload_avatar_spinner" ) ) ;
2013-11-19 17:15:48 +01:00
var url = data . avatar _url + '&stamp=' + exports . avatar _stamp ;
2013-10-28 15:49:38 +01:00
$ ( "#user-settings-avatar" ) . expectOne ( ) . attr ( "src" , url ) ;
2013-11-19 17:15:48 +01:00
exports . avatar _stamp += 1 ;
2013-10-28 15:49:38 +01:00
}
} ) ;
}
avatar . build _user _avatar _widget ( upload _avatar ) ;
2014-03-27 23:50:37 +01:00
if ( page _params . name _changes _disabled ) {
2013-08-05 02:29:01 +02:00
$ ( "#name_change_container" ) . hide ( ) ;
}
2013-05-03 00:29:52 +02:00
2014-02-27 18:27:58 +01:00
// TODO: render bots xxxx
render _bots ( ) ;
$ ( document ) . on ( 'zulip.bot_data_changed' , render _bots ) ;
2013-05-03 00:29:52 +02:00
$ . validator . addMethod ( "bot_local_part" ,
function ( value , element ) {
return is _local _part . call ( this , value + "-bot" , element ) ;
} ,
"Please only use characters that are valid in an email address" ) ;
2013-06-28 17:41:18 +02:00
2013-08-01 15:43:48 +02:00
var create _avatar _widget = avatar . build _bot _create _widget ( ) ;
2013-06-28 17:41:18 +02:00
2013-05-03 00:29:52 +02:00
$ ( '#create_bot_form' ) . validate ( {
errorClass : 'text-error' ,
success : function ( ) {
$ ( '#bot_table_error' ) . hide ( ) ;
} ,
submitHandler : function ( ) {
2013-06-14 20:03:54 +02:00
var full _name = $ ( '#create_bot_name' ) . val ( ) ;
2016-09-14 02:20:13 +02:00
var short _name = $ ( '#create_bot_short_name' ) . val ( ) || $ ( '#create_bot_short_name' ) . text ( ) ;
2014-02-11 19:53:55 +01:00
var default _sending _stream = $ ( '#create_bot_default_sending_stream' ) . val ( ) ;
2014-02-12 23:35:15 +01:00
var default _events _register _stream = $ ( '#create_bot_default_events_register_stream' ) . val ( ) ;
2013-06-14 20:03:54 +02:00
var formData = new FormData ( ) ;
2014-02-13 00:06:34 +01:00
2013-06-14 20:03:54 +02:00
formData . append ( 'csrfmiddlewaretoken' , csrf _token ) ;
formData . append ( 'full_name' , full _name ) ;
formData . append ( 'short_name' , short _name ) ;
2016-12-02 15:16:33 +01:00
add _bot _default _streams _to _form ( formData , default _sending _stream ,
default _events _register _stream ) ;
2013-07-05 17:43:56 +02:00
jQuery . each ( $ ( '#bot_avatar_file_input' ) [ 0 ] . files , function ( i , file ) {
2013-06-14 20:03:54 +02:00
formData . append ( 'file-' + i , file ) ;
} ) ;
2013-11-16 20:03:56 +01:00
$ ( '#create_bot_button' ) . val ( 'Adding bot...' ) . prop ( 'disabled' , true ) ;
2013-12-18 19:55:18 +01:00
channel . post ( {
2014-02-11 16:42:19 +01:00
url : '/json/bots' ,
2013-06-14 20:03:54 +02:00
data : formData ,
cache : false ,
processData : false ,
contentType : false ,
2013-05-03 00:29:52 +02:00
success : function ( data ) {
$ ( '#bot_table_error' ) . hide ( ) ;
$ ( '#create_bot_name' ) . val ( '' ) ;
$ ( '#create_bot_short_name' ) . val ( '' ) ;
2013-06-14 20:03:54 +02:00
$ ( '#create_bot_button' ) . show ( ) ;
2013-08-01 15:43:48 +02:00
create _avatar _widget . clear ( ) ;
2013-05-03 00:29:52 +02:00
} ,
error : function ( xhr , error _type , exn ) {
$ ( '#bot_table_error' ) . text ( JSON . parse ( xhr . responseText ) . msg ) . show ( ) ;
2013-11-16 20:03:56 +01:00
} ,
complete : function ( xhr , status ) {
$ ( '#create_bot_button' ) . val ( 'Create bot' ) . prop ( 'disabled' , false ) ;
2013-05-03 00:29:52 +02:00
}
} ) ;
}
} ) ;
2013-07-10 17:26:30 +02:00
$ ( "#bots_list" ) . on ( "click" , "button.delete_bot" , function ( e ) {
2013-10-21 01:04:25 +02:00
var email = $ ( e . currentTarget ) . data ( 'email' ) ;
2013-12-18 19:55:18 +01:00
channel . del ( {
2014-02-11 17:14:33 +01:00
url : '/json/bots/' + encodeURIComponent ( email ) ,
2013-07-10 17:26:30 +02:00
success : function ( ) {
2013-10-21 01:04:25 +02:00
var row = $ ( e . currentTarget ) . closest ( "li" ) ;
2013-07-10 21:40:01 +02:00
row . hide ( 'slow' , function ( ) { row . remove ( ) ; } ) ;
2013-07-10 22:30:03 +02:00
} ,
error : function ( xhr ) {
$ ( '#bot_delete_error' ) . text ( JSON . parse ( xhr . responseText ) . msg ) . show ( ) ;
2013-07-10 17:26:30 +02:00
}
} ) ;
} ) ;
2013-07-22 17:12:35 +02:00
2013-07-26 05:07:59 +02:00
$ ( "#bots_list" ) . on ( "click" , "button.regenerate_bot_api_key" , function ( e ) {
2013-10-21 01:04:25 +02:00
var email = $ ( e . currentTarget ) . data ( 'email' ) ;
2013-12-18 19:55:18 +01:00
channel . post ( {
2013-07-22 17:12:35 +02:00
url : '/json/bots/' + encodeURIComponent ( email ) + '/api_key/regenerate' ,
2014-01-07 23:40:31 +01:00
idempotent : true ,
2013-07-22 17:12:35 +02:00
success : function ( data ) {
2013-10-21 01:04:25 +02:00
var row = $ ( e . currentTarget ) . closest ( "li" ) ;
2013-07-22 17:12:35 +02:00
row . find ( ".api_key" ) . find ( ".value" ) . text ( data . api _key ) ;
row . find ( "api_key_error" ) . hide ( ) ;
} ,
error : function ( xhr ) {
2013-10-21 01:04:25 +02:00
var row = $ ( e . currentTarget ) . closest ( "li" ) ;
2013-07-22 17:12:35 +02:00
row . find ( ".api_key_error" ) . text ( JSON . parse ( xhr . responseText ) . msg ) . show ( ) ;
}
} ) ;
} ) ;
2013-07-22 20:09:34 +02:00
2013-07-29 16:27:18 +02:00
var image _version = 0 ;
2013-07-22 20:09:34 +02:00
$ ( "#bots_list" ) . on ( "click" , "button.open_edit_bot_form" , function ( e ) {
2013-10-21 01:04:25 +02:00
var li = $ ( e . currentTarget ) . closest ( 'li' ) ;
2013-07-22 20:09:34 +02:00
var edit _div = li . find ( 'div.edit_bot' ) ;
var form = li . find ( '.edit_bot_form' ) ;
var image = li . find ( ".image" ) ;
var bot _info = li . find ( ".bot_info" ) ;
var reset _edit _bot = li . find ( ".reset_edit_bot" ) ;
var old _full _name = bot _info . find ( ".name" ) . text ( ) ;
form . find ( ".edit_bot_name" ) . attr ( 'value' , old _full _name ) ;
image . hide ( ) ;
bot _info . hide ( ) ;
edit _div . show ( ) ;
2013-08-01 15:43:48 +02:00
var avatar _widget = avatar . build _bot _edit _widget ( li ) ;
2013-07-29 16:27:18 +02:00
2013-07-22 20:09:34 +02:00
function show _row _again ( ) {
image . show ( ) ;
bot _info . show ( ) ;
edit _div . hide ( ) ;
2013-08-01 15:43:48 +02:00
avatar _widget . close ( ) ;
2013-07-22 20:09:34 +02:00
}
reset _edit _bot . click ( function ( event ) {
show _row _again ( ) ;
$ ( this ) . off ( event ) ;
} ) ;
var errors = form . find ( '.bot_edit_errors' ) ;
form . validate ( {
errorClass : 'text-error' ,
success : function ( label ) {
errors . hide ( ) ;
} ,
submitHandler : function ( ) {
var email = form . data ( 'email' ) ;
var full _name = form . find ( '.edit_bot_name' ) . val ( ) ;
2013-07-29 16:27:18 +02:00
var file _input = li . find ( '.edit_bot_avatar_file_input' ) ;
2014-02-19 16:08:18 +01:00
var default _sending _stream = form . find ( '.edit_bot_default_sending_stream' ) . val ( ) ;
var default _events _register _stream = form . find ( '.edit_bot_default_events_register_stream' ) . val ( ) ;
2013-07-22 20:09:34 +02:00
var spinner = form . find ( '.edit_bot_spinner' ) ;
var edit _button = form . find ( '.edit_bot_button' ) ;
var formData = new FormData ( ) ;
2014-02-19 16:08:18 +01:00
2013-07-22 20:09:34 +02:00
formData . append ( 'csrfmiddlewaretoken' , csrf _token ) ;
2014-02-19 16:08:18 +01:00
formData . append ( 'full_name' , full _name ) ;
2016-12-02 15:16:33 +01:00
add _bot _default _streams _to _form ( formData , default _sending _stream ,
default _events _register _stream ) ;
2013-07-29 16:27:18 +02:00
jQuery . each ( file _input [ 0 ] . files , function ( i , file ) {
formData . append ( 'file-' + i , file ) ;
} ) ;
2014-03-13 15:03:01 +01:00
loading . make _indicator ( spinner , { text : 'Editing bot' } ) ;
2013-07-22 20:09:34 +02:00
edit _button . hide ( ) ;
2013-12-18 19:55:18 +01:00
channel . patch ( {
2013-07-22 20:09:34 +02:00
url : '/json/bots/' + encodeURIComponent ( email ) ,
data : formData ,
cache : false ,
processData : false ,
contentType : false ,
success : function ( data ) {
2014-03-13 15:03:01 +01:00
loading . destroy _indicator ( spinner ) ;
2013-07-22 20:09:34 +02:00
errors . hide ( ) ;
edit _button . show ( ) ;
show _row _again ( ) ;
bot _info . find ( '.name' ) . text ( full _name ) ;
2013-07-29 16:27:18 +02:00
if ( data . avatar _url ) {
// Note that the avatar_url won't actually change on the back end
// when the user had a previous uploaded avatar. Only the content
// changes, so we version it to get an uncached copy.
image _version += 1 ;
image . find ( 'img' ) . attr ( 'src' , data . avatar _url + '&v=' + image _version . toString ( ) ) ;
}
2013-07-22 20:09:34 +02:00
} ,
error : function ( xhr , error _type , exn ) {
2014-03-13 15:03:01 +01:00
loading . destroy _indicator ( spinner ) ;
2013-07-22 20:09:34 +02:00
edit _button . show ( ) ;
errors . text ( JSON . parse ( xhr . responseText ) . msg ) . show ( ) ;
}
} ) ;
}
} ) ;
} ) ;
2016-12-07 18:38:59 +01:00
$ ( "#bots_list" ) . on ( "click" , "a.download_bot_zuliprc" , function ( e ) {
var bot _info = $ ( this ) . parent ( ) . parent ( ) ;
var email = bot _info . find ( ".email .value" ) . text ( ) ;
var api _key = bot _info . find ( ".api_key .api-key-value-and-button .value" ) . text ( ) ;
$ ( this ) . attr ( "href" , settings . generate _zuliprc _uri (
$ . trim ( email ) , $ . trim ( api _key )
) ) ;
} ) ;
$ ( "#download_zuliprc" ) . on ( "click" , function ( e ) {
$ ( this ) . attr ( "href" , settings . generate _zuliprc _uri (
page _params . email ,
$ ( "#api_key_value" ) . text ( )
) ) ;
} ) ;
2013-08-08 18:08:30 +02:00
$ ( "#show_api_key_box" ) . on ( "click" , "button.regenerate_api_key" , function ( e ) {
2013-12-18 19:55:18 +01:00
channel . post ( {
2013-08-08 18:08:30 +02:00
url : '/json/users/me/api_key/regenerate' ,
2014-01-07 23:40:31 +01:00
idempotent : true ,
2013-08-08 18:08:30 +02:00
success : function ( data ) {
$ ( '#api_key_value' ) . text ( data . api _key ) ;
} ,
error : function ( xhr ) {
$ ( '#user_api_key_error' ) . text ( JSON . parse ( xhr . responseText ) . msg ) . show ( ) ;
}
} ) ;
} ) ;
2013-07-22 20:09:34 +02:00
2014-02-13 23:47:57 +01:00
$ ( "#ui-settings" ) . on ( "click" , "input[name='change_settings']" , function ( e ) {
var labs _updates = { } ;
_ . each ( [ "autoscroll_forever" , "default_desktop_notifications" ] ,
function ( setting ) {
labs _updates [ setting ] = $ ( "#" + setting ) . is ( ":checked" ) ;
} ) ;
channel . post ( {
url : '/json/ui_settings/change' ,
data : labs _updates ,
success : function ( resp , statusText , xhr , form ) {
2016-06-23 12:56:00 +02:00
var message = i18n . t ( "Updated __product_name__ Labs settings!" , page _params ) ;
2016-08-24 23:56:23 +02:00
var result = JSON . parse ( xhr . responseText ) ;
2015-08-20 08:50:35 +02:00
var ui _settings _status = $ ( '#ui-settings-status' ) . expectOne ( ) ;
2014-02-13 23:47:57 +01:00
if ( result . autoscroll _forever !== undefined ) {
page _params . autoscroll _forever = result . autoscroll _forever ;
2014-03-13 19:03:31 +01:00
resize . resize _page _components ( ) ;
2014-02-13 23:47:57 +01:00
}
2015-08-21 01:23:53 +02:00
ui . report _success ( message , ui _settings _status ) ;
2014-02-13 23:47:57 +01:00
} ,
error : function ( xhr , error _type , xhn ) {
2016-06-23 13:05:17 +02:00
ui . report _error ( i18n . t ( "Error changing settings" ) , xhr , $ ( '#ui-settings-status' ) . expectOne ( ) ) ;
2014-02-13 23:47:57 +01:00
}
} ) ;
} ) ;
2016-06-10 09:03:36 +02:00
}
exports . setup _page = function ( ) {
i18n . ensure _i18n ( _setup _page ) ;
2014-02-13 23:47:57 +01:00
} ;
2013-05-03 00:29:52 +02:00
2013-11-19 17:15:48 +01:00
return exports ;
2013-06-27 23:05:36 +02:00
} ( ) ) ;
2016-12-04 08:59:56 +01:00
if ( typeof module !== 'undefined' ) {
module . exports = settings ;
}