mirror of https://github.com/zulip/zulip.git
Convert settings from static HTML to a template.
This will make life much easier for handling update events. (imported from commit 66b101eb5fae89b4eec6fc797fee8be26ac99bfb)
This commit is contained in:
parent
c96ceeaea4
commit
87635b9e32
|
@ -23,12 +23,270 @@ function is_local_part(value, element) {
|
|||
// Choose avatar stamp fairly randomly, to help get old avatars out of cache.
|
||||
exports.avatar_stamp = Math.floor(Math.random()*100);
|
||||
|
||||
$(function () {
|
||||
exports.setup_page = function () {
|
||||
var settings_tab = templates.render('settings_tab', {page_params: page_params});
|
||||
$("#settings").html(settings_tab);
|
||||
$("#settings-status").hide();
|
||||
$("#notify-settings-status").hide();
|
||||
$("#ui-settings-status").hide();
|
||||
|
||||
$("#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();
|
||||
});
|
||||
|
||||
$('#new_password').on('change keyup', function () {
|
||||
password_quality($('#new_password').val(), $('#pw_strength .bar'));
|
||||
});
|
||||
|
||||
if (feature_flags.dont_show_digest_email_setting) {
|
||||
$("#digest_container").hide();
|
||||
}
|
||||
|
||||
|
||||
function settings_change_error(message) {
|
||||
// Scroll to the top so the error message is visible.
|
||||
// We would scroll anyway if we end up submitting the form.
|
||||
viewport.scrollTop(0);
|
||||
var settings_status = $('#settings-status').expectOne();
|
||||
settings_status.removeClass(status_classes)
|
||||
.addClass('alert-error')
|
||||
.text(message).stop(true).fadeTo(0,1);
|
||||
}
|
||||
|
||||
$("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) {
|
||||
var message = "Updated settings!";
|
||||
var result = $.parseJSON(xhr.responseText);
|
||||
var settings_status = $('#settings-status').expectOne();
|
||||
|
||||
settings_status.removeClass(status_classes)
|
||||
.addClass('alert-success')
|
||||
.text(message).stop(true).fadeTo(0,1);
|
||||
},
|
||||
error: function (xhr, error_type, xhn) {
|
||||
var response = "Error changing settings";
|
||||
if (xhr.status.toString().charAt(0) === "4") {
|
||||
// Only display the error response for 4XX, where we've crafted
|
||||
// a nice response.
|
||||
response += ": " + $.parseJSON(xhr.responseText).msg;
|
||||
}
|
||||
settings_change_error(response);
|
||||
},
|
||||
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!";
|
||||
var result = $.parseJSON(xhr.responseText);
|
||||
var notify_settings_status = $('#notify-settings-status').expectOne();
|
||||
|
||||
// Stream notification settings.
|
||||
|
||||
if (result.enable_stream_desktop_notifications !== undefined) {
|
||||
page_params.stream_desktop_notifications_enabled = result.enable_stream_desktop_notifications;
|
||||
}
|
||||
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) {
|
||||
page_params.enable_offline_email_notifications = result.enable_offline_email_notifications;
|
||||
}
|
||||
|
||||
if (result.enable_offline_push_notifications !== undefined) {
|
||||
page_params.enable_offline_push_notifications = result.enable_offline_push_notifications;
|
||||
}
|
||||
|
||||
// Other notification settings.
|
||||
|
||||
if (result.enable_digest_emails !== undefined) {
|
||||
page_params.enable_digest_emails = result.enable_digest_emails;
|
||||
}
|
||||
|
||||
notify_settings_status.removeClass(status_classes)
|
||||
.addClass('alert-success')
|
||||
.text(message).stop(true).fadeTo(0,1);
|
||||
}
|
||||
|
||||
function update_notification_settings_error(xhr, error_type, xhn) {
|
||||
var response = "Error changing settings";
|
||||
var notify_settings_status = $('#notify-settings-status').expectOne();
|
||||
|
||||
if (xhr.status.toString().charAt(0) === "4") {
|
||||
// Only display the error response for 4XX, where we've crafted
|
||||
// a nice response.
|
||||
response += ": " + $.parseJSON(xhr.responseText).msg;
|
||||
}
|
||||
|
||||
notify_settings_status.removeClass(status_classes)
|
||||
.addClass('alert-error')
|
||||
.text(response).stop(true).fadeTo(0,1);
|
||||
}
|
||||
|
||||
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",
|
||||
"enable_offline_push_notifications", "enable_digest_emails"],
|
||||
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);
|
||||
});
|
||||
|
||||
$("#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!";
|
||||
var result = $.parseJSON(xhr.responseText);
|
||||
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) {
|
||||
var response = "Error getting API key";
|
||||
var settings_status = $('#settings-status').expectOne();
|
||||
|
||||
if (xhr.status.toString().charAt(0) === "4") {
|
||||
// Only display the error response for 4XX, where we've crafted
|
||||
// a nice response.
|
||||
response += ": " + $.parseJSON(xhr.responseText).msg;
|
||||
}
|
||||
settings_status.removeClass(status_classes)
|
||||
.addClass('alert-error')
|
||||
.text(response).stop(true).fadeTo(0,1);
|
||||
$("#show_api_key_box").hide();
|
||||
$("#get_api_key_box").show();
|
||||
}
|
||||
});
|
||||
|
||||
function upload_avatar(file_input) {
|
||||
var form_data = new FormData();
|
||||
|
||||
|
@ -269,7 +527,49 @@ $(function () {
|
|||
});
|
||||
});
|
||||
|
||||
$("#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) {
|
||||
var message = "Updated Zulip Labs settings!";
|
||||
var result = $.parseJSON(xhr.responseText);
|
||||
var ui_settings_status = feature_flags.show_autoscroll_forever_option &&
|
||||
$('#ui-settings-status').expectOne();
|
||||
|
||||
if (result.autoscroll_forever !== undefined) {
|
||||
page_params.autoscroll_forever = result.autoscroll_forever;
|
||||
ui.resize_page_components();
|
||||
}
|
||||
|
||||
ui_settings_status.removeClass(status_classes)
|
||||
.addClass('alert-success')
|
||||
.text(message).stop(true).fadeTo(0,1);
|
||||
},
|
||||
error: function (xhr, error_type, xhn) {
|
||||
var response = "Error changing settings";
|
||||
var ui_settings_status = feature_flags.show_autoscroll_forever_option &&
|
||||
$('#ui-settings-status').expectOne();
|
||||
|
||||
if (xhr.status.toString().charAt(0) === "4") {
|
||||
// Only display the error response for 4XX, where we've crafted
|
||||
// a nice response.
|
||||
response += ": " + $.parseJSON(xhr.responseText).msg;
|
||||
}
|
||||
|
||||
ui_settings_status.removeClass(status_classes)
|
||||
.addClass('alert-error')
|
||||
.text(response).stop(true).fadeTo(0,1);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return exports;
|
||||
}());
|
||||
|
|
284
static/js/ui.js
284
static/js/ui.js
|
@ -940,12 +940,6 @@ $(function () {
|
|||
e.preventDefault();
|
||||
});
|
||||
|
||||
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('');
|
||||
}
|
||||
|
||||
admin.show_or_hide_menu_item();
|
||||
|
||||
$('#gear-menu a[data-toggle="tab"]').on('show', function (e) {
|
||||
|
@ -962,13 +956,6 @@ $(function () {
|
|||
$('.alert-info').hide();
|
||||
$('.alert').hide();
|
||||
|
||||
$("#api_key_value").text("");
|
||||
$("#get_api_key_box").hide();
|
||||
$("#show_api_key_box").hide();
|
||||
$("#api_key_button_box").show();
|
||||
|
||||
clear_password_change();
|
||||
|
||||
// Set the URL bar title to show the sub-page you're currently on.
|
||||
var browser_url = target_tab;
|
||||
if (browser_url === "#home") {
|
||||
|
@ -1003,265 +990,14 @@ $(function () {
|
|||
// Whenever the streams page comes up (from anywhere), populate it.
|
||||
subs_link.on('shown', subs.setup_page);
|
||||
|
||||
// The admin and settings pages are generated client-side through
|
||||
// templates.
|
||||
|
||||
var admin_link = $('#gear-menu a[href="#administration"]');
|
||||
admin_link.on('shown', admin.setup_page);
|
||||
|
||||
$('#pw_change_link').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
$('#pw_change_link').hide();
|
||||
$('#pw_change_controls').show();
|
||||
});
|
||||
|
||||
$('#new_password').on('change keyup', function () {
|
||||
password_quality($('#new_password').val(), $('#pw_strength .bar'));
|
||||
});
|
||||
|
||||
var settings_status = $('#settings-status').expectOne();
|
||||
var notify_settings_status = $('#notify-settings-status').expectOne();
|
||||
// does this make me a bad person?
|
||||
var ui_settings_status = feature_flags.show_autoscroll_forever_option && $('#ui-settings-status').expectOne();
|
||||
|
||||
function settings_change_error(message) {
|
||||
// Scroll to the top so the error message is visible.
|
||||
// We would scroll anyway if we end up submitting the form.
|
||||
viewport.scrollTop(0);
|
||||
settings_status.removeClass(status_classes)
|
||||
.addClass('alert-error')
|
||||
.text(message).stop(true).fadeTo(0,1);
|
||||
}
|
||||
|
||||
$("form.your-account-settings").expectOne().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) {
|
||||
var message = "Updated settings!";
|
||||
var result = $.parseJSON(xhr.responseText);
|
||||
|
||||
settings_status.removeClass(status_classes)
|
||||
.addClass('alert-success')
|
||||
.text(message).stop(true).fadeTo(0,1);
|
||||
},
|
||||
error: function (xhr, error_type, xhn) {
|
||||
var response = "Error changing settings";
|
||||
if (xhr.status.toString().charAt(0) === "4") {
|
||||
// Only display the error response for 4XX, where we've crafted
|
||||
// a nice response.
|
||||
response += ": " + $.parseJSON(xhr.responseText).msg;
|
||||
}
|
||||
settings_change_error(response);
|
||||
},
|
||||
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!";
|
||||
var result = $.parseJSON(xhr.responseText);
|
||||
|
||||
// Stream notification settings.
|
||||
|
||||
if (result.enable_stream_desktop_notifications !== undefined) {
|
||||
page_params.stream_desktop_notifications_enabled = result.enable_stream_desktop_notifications;
|
||||
}
|
||||
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) {
|
||||
page_params.enable_offline_email_notifications = result.enable_offline_email_notifications;
|
||||
}
|
||||
|
||||
if (result.enable_offline_push_notifications !== undefined) {
|
||||
page_params.enable_offline_push_notifications = result.enable_offline_push_notifications;
|
||||
}
|
||||
|
||||
// Other notification settings.
|
||||
|
||||
if (result.enable_digest_emails !== undefined) {
|
||||
page_params.enable_digest_emails = result.enable_digest_emails;
|
||||
}
|
||||
|
||||
notify_settings_status.removeClass(status_classes)
|
||||
.addClass('alert-success')
|
||||
.text(message).stop(true).fadeTo(0,1);
|
||||
}
|
||||
|
||||
function update_notification_settings_error(xhr, error_type, xhn) {
|
||||
var response = "Error changing settings";
|
||||
if (xhr.status.toString().charAt(0) === "4") {
|
||||
// Only display the error response for 4XX, where we've crafted
|
||||
// a nice response.
|
||||
response += ": " + $.parseJSON(xhr.responseText).msg;
|
||||
}
|
||||
|
||||
notify_settings_status.removeClass(status_classes)
|
||||
.addClass('alert-error')
|
||||
.text(response).stop(true).fadeTo(0,1);
|
||||
}
|
||||
|
||||
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",
|
||||
"enable_offline_push_notifications", "enable_digest_emails"],
|
||||
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);
|
||||
});
|
||||
|
||||
if (feature_flags.show_autoscroll_forever_option) {
|
||||
$("form.ui-settings").expectOne().ajaxForm({
|
||||
dataType: 'json',
|
||||
|
||||
success: function (resp, statusText, xhr, form) {
|
||||
var message = "Updated Zulip Labs settings!";
|
||||
var result = $.parseJSON(xhr.responseText);
|
||||
|
||||
if (result.autoscroll_forever !== undefined) {
|
||||
page_params.autoscroll_forever = result.autoscroll_forever;
|
||||
exports.resize_page_components();
|
||||
}
|
||||
|
||||
ui_settings_status.removeClass(status_classes)
|
||||
.addClass('alert-success')
|
||||
.text(message).stop(true).fadeTo(0,1);
|
||||
},
|
||||
error: function (xhr, error_type, xhn) {
|
||||
var response = "Error changing settings";
|
||||
if (xhr.status.toString().charAt(0) === "4") {
|
||||
// Only display the error response for 4XX, where we've crafted
|
||||
// a nice response.
|
||||
response += ": " + $.parseJSON(xhr.responseText).msg;
|
||||
}
|
||||
|
||||
ui_settings_status.removeClass(status_classes)
|
||||
.addClass('alert-error')
|
||||
.text(response).stop(true).fadeTo(0,1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$("#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!";
|
||||
var result = $.parseJSON(xhr.responseText);
|
||||
$("#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) {
|
||||
var response = "Error getting API key";
|
||||
if (xhr.status.toString().charAt(0) === "4") {
|
||||
// Only display the error response for 4XX, where we've crafted
|
||||
// a nice response.
|
||||
response += ": " + $.parseJSON(xhr.responseText).msg;
|
||||
}
|
||||
settings_status.removeClass(status_classes)
|
||||
.addClass('alert-error')
|
||||
.text(response).stop(true).fadeTo(0,1);
|
||||
$("#show_api_key_box").hide();
|
||||
$("#get_api_key_box").show();
|
||||
}
|
||||
});
|
||||
var settings_link = $('#gear-menu a[href="#settings"]');
|
||||
settings_link.on('shown', settings.setup_page);
|
||||
|
||||
// A little hackish, because it doesn't seem to totally get us the
|
||||
// exact right width for the floating_recipient_bar and compose
|
||||
|
@ -1589,16 +1325,6 @@ $(function () {
|
|||
server_events.restart_get_events({dont_block: true});
|
||||
});
|
||||
|
||||
$('#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();
|
||||
});
|
||||
|
||||
$('body').on('click', '.edit_content_button', function (e) {
|
||||
var row = current_msg_list.get_row(rows.id($(this).closest(".message_row")));
|
||||
message_edit.start(row);
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
{# Settings tab of the app. #}
|
||||
|
||||
<h1><i class="icon-vector-wrench settings-icon"></i>Settings</h1>
|
||||
|
||||
<div id="settings-change-box">
|
||||
|
@ -10,16 +8,16 @@
|
|||
<div class="settings-section-title"><i class="icon-vector-user settings-section-icon"></i>Your Account</div>
|
||||
<div class="account-settings-form">
|
||||
<form action="/json/settings/change" method="post"
|
||||
class="form-horizontal your-account-settings">{% csrf_token %}
|
||||
class="form-horizontal your-account-settings">
|
||||
<div class="control-group" id="name_change_container">
|
||||
<label for="full_name" class="control-label">Full name</label>
|
||||
<div class="controls">
|
||||
<input type="text" name="full_name" id="full_name"
|
||||
value="{{ user_profile.full_name }}" />
|
||||
value="{{ page_params.fullname }}" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if password_auth_enabled %}
|
||||
{{#if page_params.password_auth_enabled}}
|
||||
<div class="control-group" id="pw_change_link">
|
||||
<label for="change_password_button" class="control-label">Password</label>
|
||||
<div class="controls">
|
||||
|
@ -63,7 +61,7 @@
|
|||
</div>
|
||||
|
||||
</div>
|
||||
{% endif %}
|
||||
{{/if}}
|
||||
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
|
@ -74,7 +72,7 @@
|
|||
|
||||
<div class="user-avatar-section">
|
||||
<p>
|
||||
<img id="user-settings-avatar" src="{{ avatar_url }}" />
|
||||
<img id="user-settings-avatar" src="{{ page_params.avatar_url }}" />
|
||||
</p>
|
||||
<div id="user_avatar_file_input_error" class="text-error"></div>
|
||||
<div id="user_avatar_file"></div>
|
||||
|
@ -102,9 +100,9 @@
|
|||
<div class="controls">
|
||||
<input type="checkbox" name="enable_stream_desktop_notifications"
|
||||
id="enable_stream_desktop_notifications"
|
||||
{% if user_profile.enable_stream_desktop_notifications %}
|
||||
{{#if page_params.stream_desktop_notifications_enabled}}
|
||||
checked="yes"
|
||||
{% endif %} />
|
||||
{{/if}} />
|
||||
</div>
|
||||
<label for="enable_stream_desktop_notifications" class="control-label">
|
||||
Desktop notifications
|
||||
|
@ -115,9 +113,9 @@
|
|||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<input type="checkbox" name="enable_stream_sounds" id="enable_stream_sounds"
|
||||
{% if user_profile.enable_stream_sounds %}
|
||||
{{#if page_params.stream_sounds_enabled}}
|
||||
checked="yes"
|
||||
{% endif %} />
|
||||
{{/if}} />
|
||||
</div>
|
||||
<label for="enable_stream_sounds" class="control-label">
|
||||
Audible notifications
|
||||
|
@ -125,9 +123,10 @@
|
|||
<div class="propagate_stream_notifications_change"></div>
|
||||
</div>
|
||||
|
||||
<p class="notification-settings-note">Change notification settings for
|
||||
individual streams on your <a href="/#subscriptions">Streams
|
||||
page</a>.</p>
|
||||
<p class="notification-settings-note">
|
||||
Change notification settings for individual streams on your <a
|
||||
href="/#subscriptions">Streams page</a>.
|
||||
</p>
|
||||
|
||||
<h4>Private messages and @-mentions</h4>
|
||||
|
||||
|
@ -136,9 +135,9 @@
|
|||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<input type="checkbox" name="enable_desktop_notifications" id="enable_desktop_notifications"
|
||||
{% if user_profile.enable_desktop_notifications %}
|
||||
{{#if page_params.desktop_notifications_enabled}}
|
||||
checked="yes"
|
||||
{% endif %} />
|
||||
{{/if}} />
|
||||
</div>
|
||||
<label for="enable_desktop_notifications" class="control-label">
|
||||
Desktop notifications
|
||||
|
@ -148,9 +147,9 @@
|
|||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<input type="checkbox" name="enable_sounds" id="enable_sounds"
|
||||
{% if user_profile.enable_sounds %}
|
||||
{{#if page_params.sounds_enabled}}
|
||||
checked="yes"
|
||||
{% endif %} />
|
||||
{{/if}} />
|
||||
</div>
|
||||
<label for="enable_sounds" class="control-label">
|
||||
Audible notifications
|
||||
|
@ -160,9 +159,9 @@
|
|||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<input type="checkbox" name="enable_offline_email_notifications" id="enable_offline_email_notifications"
|
||||
{% if user_profile.enable_offline_email_notifications %}
|
||||
{{#if page_params.enable_offline_email_notifications}}
|
||||
checked="yes"
|
||||
{% endif %} />
|
||||
{{/if}} />
|
||||
</div>
|
||||
<label for="enable_offline_email_notifications" class="control-label">
|
||||
Email notifications when offline
|
||||
|
@ -172,9 +171,9 @@
|
|||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<input type="checkbox" name="enable_offline_push_notifications" id="enable_offline_push_notifications"
|
||||
{% if user_profile.enable_offline_push_notifications %}
|
||||
{{#if page_params.enable_offline_push_notifications}}
|
||||
checked="yes"
|
||||
{% endif %} />
|
||||
{{/if}} />
|
||||
</div>
|
||||
<label for="enable_offline_push_notifications" class="control-label">
|
||||
Mobile push notifications when offline
|
||||
|
@ -188,9 +187,9 @@
|
|||
<div class="control-group" id="digest_container">
|
||||
<div class="controls">
|
||||
<input type="checkbox" name="enable_digest_emails" id="enable_digest_emails"
|
||||
{% if user_profile.enable_digest_emails %}
|
||||
{{#if page_params.enable_digest_emails}}
|
||||
checked="yes"
|
||||
{% endif %} />
|
||||
{{/if}} />
|
||||
</div>
|
||||
<label for="enable_digest_emails" class="control-label">
|
||||
Digest emails when I'm away
|
||||
|
@ -235,7 +234,7 @@
|
|||
<div class="control-group">
|
||||
<label for="bot_short_name" class="control-label">Username</label>
|
||||
<input type="text" name="bot_short_name" id="create_bot_short_name" class="required bot_local_part"
|
||||
placeholder="bot_user_name" value="" />-bot@{{ user_profile.realm.domain }}
|
||||
placeholder="bot_user_name" value="" />-bot@{{ page_params.domain }}
|
||||
<div><label for="create_bot_short_name" generated="true" class="text-error"></label></div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
|
@ -273,7 +272,7 @@
|
|||
<div id="get_api_key_box">
|
||||
<p>Please re-enter your password to confirm your identity.
|
||||
(<a href="/accounts/password/reset/" target="_blank">Forgotten it?</a>)</p>
|
||||
<form action="/json/fetch_api_key" method="post" class="form-horizontal">{% csrf_token %}
|
||||
<form action="/json/fetch_api_key" method="post" class="form-horizontal">
|
||||
<div class="control-group">
|
||||
<label for="password" class="control-label">Current password</label>
|
||||
<input type="password" autocomplete="off"
|
||||
|
@ -304,9 +303,8 @@
|
|||
</ul>
|
||||
</div>
|
||||
|
||||
{% if show_autoscroll_forever_option or show_default_desktop_notifications_option%}
|
||||
<form action="/json/ui_settings/change" method="post"
|
||||
class="form-horizontal ui-settings">{% csrf_token %}
|
||||
{{#if_or page_params.show_autoscroll_forever_option page_params.show_default_desktop_notifications_option}}
|
||||
<div class="ui-settings">
|
||||
<div id="ui-settings" class="settings-section">
|
||||
<div class="settings-section-title"><i class="icon-vector-beaker settings-section-icon"></i>Zulip Labs</div>
|
||||
<div class="alert" id="ui-settings-status"></div>
|
||||
|
@ -316,29 +314,29 @@
|
|||
features we're working on. Let us know what you think!
|
||||
</p>
|
||||
<div class="control-group">
|
||||
{% if show_autoscroll_forever_option %}
|
||||
{{#if page_params.show_autoscroll_forever_option}}
|
||||
<div class="controls">
|
||||
<input type="checkbox" name="autoscroll_forever" id="autoscroll_forever"
|
||||
{% if user_profile.autoscroll_forever %}
|
||||
{{#if page_params.autoscroll_forever}}
|
||||
checked="yes"
|
||||
{% endif %} />
|
||||
{{/if}} />
|
||||
</div>
|
||||
<label for="autoscroll_forever" class="control-label">
|
||||
Always auto-scroll to new messages
|
||||
</label>
|
||||
{% endif %}
|
||||
{{/if}}
|
||||
|
||||
{% if show_default_desktop_notifications_option %}
|
||||
{{#if page_params.show_default_desktop_notifications_option}}
|
||||
<div class="controls">
|
||||
<input type="checkbox" name="default_desktop_notifications" id="default_desktop_notifications"
|
||||
{% if user_profile.default_desktop_notifications %}
|
||||
{{#if page_params.default_desktop_notifications}}
|
||||
checked="yes"
|
||||
{% endif %} />
|
||||
{{/if}} />
|
||||
</div>
|
||||
<label for="default_desktop_notifications" class="control-label">
|
||||
Enable desktop notifications for new streams
|
||||
</label>
|
||||
{% endif %}
|
||||
{{/if}}
|
||||
|
||||
</div>
|
||||
<div class="control-group">
|
||||
|
@ -348,5 +346,5 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
{{/if_or}}
|
|
@ -104,7 +104,6 @@ var page_params = {{ page_params }};
|
|||
<div class="tab-pane" id="administration">
|
||||
</div>
|
||||
<div class="tab-pane" id="settings">
|
||||
{% include "zerver/settings.html" %}
|
||||
</div>
|
||||
|
||||
{% if show_debug %}
|
||||
|
|
|
@ -537,22 +537,26 @@ class ChangeSettingsTest(AuthedTestCase):
|
|||
def test_ui_settings(self):
|
||||
self.login("hamlet@zulip.com")
|
||||
|
||||
json_result = self.client.post("/json/ui_settings/change", {"autoscroll_forever": "on"})
|
||||
json_result = self.client.post("/json/ui_settings/change",
|
||||
{"autoscroll_forever": ujson.dumps(True)})
|
||||
self.assert_json_success(json_result)
|
||||
self.assertEqual(get_user_profile_by_email("hamlet@zulip.com").
|
||||
enable_desktop_notifications, True)
|
||||
|
||||
json_result = self.client.post("/json/ui_settings/change", {})
|
||||
json_result = self.client.post("/json/ui_settings/change",
|
||||
{"autoscroll_forever": ujson.dumps(False)})
|
||||
self.assert_json_success(json_result)
|
||||
self.assertEqual(get_user_profile_by_email("hamlet@zulip.com").
|
||||
autoscroll_forever, False)
|
||||
|
||||
json_result = self.client.post("/json/ui_settings/change", {"default_desktop_notifications": "on"})
|
||||
json_result = self.client.post("/json/ui_settings/change",
|
||||
{"default_desktop_notifications": ujson.dumps(True)})
|
||||
self.assert_json_success(json_result)
|
||||
self.assertEqual(get_user_profile_by_email("hamlet@zulip.com").
|
||||
default_desktop_notifications, True)
|
||||
|
||||
json_result = self.client.post("/json/ui_settings/change", {})
|
||||
json_result = self.client.post("/json/ui_settings/change",
|
||||
{"default_desktop_notifications": ujson.dumps(False)})
|
||||
self.assert_json_success(json_result)
|
||||
self.assertEqual(get_user_profile_by_email("hamlet@zulip.com").
|
||||
default_desktop_notifications, False)
|
||||
|
|
|
@ -672,6 +672,50 @@ function render(template_name, args) {
|
|||
assert.equal(button_area.find(".no_propagate_notifications").text().trim(), 'No');
|
||||
}());
|
||||
|
||||
(function settings_tab() {
|
||||
var page_param_checkbox_options = {
|
||||
stream_desktop_notifications_enabled: true,
|
||||
stream_sounds_enabled: true, desktop_notifications_enabled: true,
|
||||
sounds_enabled: true, enable_offline_email_notifications: true,
|
||||
enable_offline_push_notifications: true, enable_digest_emails: true,
|
||||
autoscroll_forever: true, default_desktop_notifications: true
|
||||
};
|
||||
var page_params = $.extend(page_param_checkbox_options, {
|
||||
fullname: "Alyssa P. Hacker", password_auth_enabled: true,
|
||||
avatar_url: "https://google.com",
|
||||
domain: "zulip.com", show_autoscroll_forever_option: true,
|
||||
show_default_desktop_notifications_option: true
|
||||
});
|
||||
|
||||
var checkbox_ids = ["enable_stream_desktop_notifications",
|
||||
"enable_stream_sounds", "enable_desktop_notifications",
|
||||
"enable_sounds", "enable_offline_push_notifications",
|
||||
"enable_digest_emails", "autoscroll_forever",
|
||||
"default_desktop_notifications"];
|
||||
|
||||
// Render with all booleans set to true.
|
||||
var html = render('settings_tab', {page_params: page_params});
|
||||
global.write_test_output("settings_tab.handlebars", html);
|
||||
|
||||
// All checkboxes should be checked.
|
||||
_.each(checkbox_ids, function (checkbox) {
|
||||
assert.equal($(html).find("#" + checkbox).is(":checked"), true);
|
||||
});
|
||||
|
||||
// Re-render with checkbox booleans set to false.
|
||||
_.each(page_param_checkbox_options, function (value, option) {
|
||||
page_params[option] = false;
|
||||
});
|
||||
|
||||
html = render('settings_tab', {page_params: page_params});
|
||||
|
||||
// All checkboxes should be unchecked.
|
||||
_.each(checkbox_ids, function (checkbox) {
|
||||
assert.equal($(html).find("#" + checkbox).is(":checked"), false);
|
||||
});
|
||||
|
||||
}());
|
||||
|
||||
// By the end of this test, we should have compiled all our templates. Ideally,
|
||||
// we will also have exercised them to some degree, but that's a little trickier
|
||||
// to enforce.
|
||||
|
|
|
@ -55,8 +55,7 @@ from zerver.lib.validator import check_string, check_list, check_dict, check_int
|
|||
|
||||
from zerver.decorator import require_post, \
|
||||
authenticated_api_view, authenticated_json_post_view, \
|
||||
has_request_variables, authenticated_json_view, \
|
||||
to_non_negative_int, json_to_bool, \
|
||||
has_request_variables, authenticated_json_view, to_non_negative_int, \
|
||||
JsonableError, get_user_profile_by_email, REQ, require_realm_admin, \
|
||||
RequestVariableConversionError
|
||||
from zerver.lib.avatar import avatar_url, get_avatar_url
|
||||
|
@ -913,6 +912,8 @@ def home(request):
|
|||
has_mobile_devices = num_push_devices_for_user(user_profile) > 0,
|
||||
autoscroll_forever = user_profile.autoscroll_forever,
|
||||
show_autoscroll_forever_option = user_profile.realm.domain in ("customer28.invalid", "zulip.com", "customer31.invalid"),
|
||||
default_desktop_notifications = user_profile.default_desktop_notifications,
|
||||
show_default_desktop_notifications_option = user_profile.realm.domain in ("customer13.invalid", "zulip.com",),
|
||||
avatar_url = avatar_url(user_profile)
|
||||
)
|
||||
if narrow_stream is not None:
|
||||
|
@ -952,8 +953,6 @@ def home(request):
|
|||
'show_webathena': user_profile.realm.domain == "mit.edu",
|
||||
'enable_feedback': settings.ENABLE_FEEDBACK,
|
||||
'embedded': narrow_stream is not None,
|
||||
'show_default_desktop_notifications_option': user_profile.realm.domain in ("customer13.invalid", "zulip.com",),
|
||||
'show_autoscroll_forever_option': page_params["show_autoscroll_forever_option"],
|
||||
},
|
||||
context_instance=RequestContext(request))
|
||||
patch_cache_control(response, no_cache=True, no_store=True, must_revalidate=True)
|
||||
|
@ -1561,18 +1560,20 @@ def create_user_backend(request, user_profile, email=REQ, password=REQ,
|
|||
@authenticated_json_post_view
|
||||
@has_request_variables
|
||||
def json_change_ui_settings(request, user_profile,
|
||||
autoscroll_forever=REQ(converter=lambda x: x == "on",
|
||||
default=False),
|
||||
default_desktop_notifications=REQ(converter=lambda x: x == "on",
|
||||
default=False)):
|
||||
autoscroll_forever=REQ(validator=check_bool,
|
||||
default=None),
|
||||
default_desktop_notifications=REQ(validator=check_bool,
|
||||
default=None)):
|
||||
|
||||
result = {}
|
||||
|
||||
if user_profile.autoscroll_forever != autoscroll_forever:
|
||||
if autoscroll_forever is not None and \
|
||||
user_profile.autoscroll_forever != autoscroll_forever:
|
||||
do_change_autoscroll_forever(user_profile, autoscroll_forever)
|
||||
result['autoscroll_forever'] = autoscroll_forever
|
||||
|
||||
if user_profile.default_desktop_notifications != default_desktop_notifications:
|
||||
if default_desktop_notifications is not None and \
|
||||
user_profile.default_desktop_notifications != default_desktop_notifications:
|
||||
do_change_default_desktop_notifications(user_profile, default_desktop_notifications)
|
||||
result['default_desktop_notifications'] = default_desktop_notifications
|
||||
|
||||
|
|
Loading…
Reference in New Issue