diff --git a/frontend_tests/node_tests/dispatch.js b/frontend_tests/node_tests/dispatch.js index 32f7e163ed..161dc82ef7 100644 --- a/frontend_tests/node_tests/dispatch.js +++ b/frontend_tests/node_tests/dispatch.js @@ -601,6 +601,12 @@ var event_fixtures = { setting: true, }, + update_display_settings__fluid_layout_width: { + type: 'update_display_settings', + setting_name: 'fluid_layout_width', + setting: true, + }, + update_display_settings__translate_emoticons: { type: 'update_display_settings', setting_name: 'translate_emoticons', @@ -1377,6 +1383,12 @@ with_overrides(function (override) { page_params.starred_message_counts = false; dispatch(event); assert_same(page_params.starred_message_counts, true); + + override('scroll_bar.set_layout_width', noop); + event = event_fixtures.update_display_settings__fluid_layout_width; + page_params.fluid_layout_width = false; + dispatch(event); + assert_same(page_params.fluid_layout_width, true); }); with_overrides(function (override) { diff --git a/static/js/scroll_bar.js b/static/js/scroll_bar.js index 4e8ae50eef..f373b41067 100644 --- a/static/js/scroll_bar.js +++ b/static/js/scroll_bar.js @@ -36,11 +36,9 @@ exports.initialize = function () { if (sbWidth > 0) { $(".header").css("left", "-" + sbWidth + "px"); $(".header-main").css("left", sbWidth + "px"); - $(".header-main").css("max-width", 1400 + sbWidth + "px"); $(".header-main .column-middle").css("margin-right", 250 + sbWidth + "px"); $(".fixed-app").css("left", "-" + sbWidth + "px"); - $(".fixed-app .app-main").css("max-width", 1400 + sbWidth + "px"); $(".fixed-app .column-middle").css("margin-left", 250 + sbWidth + "px"); $(".column-right").css("right", sbWidth + "px"); @@ -50,17 +48,30 @@ exports.initialize = function () { $("#compose").css("left", "-" + sbWidth + "px"); $(".compose-content").css({left: sbWidth + "px", "margin-right": 250 + sbWidth + "px"}); - $("#compose-container").css("max-width", 1400 + sbWidth + "px"); $('#keyboard-icon').css({right: sbWidth + 13 + "px"}); $("head").append(""); - } + exports.set_layout_width(); + } ui.set_up_scrollbar($("#stream-filters-container")); }; +exports.set_layout_width = function () { + var sbWidth = getScrollbarWidth(); + if (page_params.fluid_layout_width) { + $(".header-main").css("max-width", "inherit"); + $(".app-main").css("max-width", "inherit"); + $("#compose-container").css("max-width", "inherit"); + } else { + $(".header-main").css("max-width", 1400 + sbWidth + "px"); + $(".app-main").css("max-width", 1400 + sbWidth + "px"); + $("#compose-container").css("max-width", 1400 + sbWidth + "px"); + } +}; + return exports; }()); if (typeof module !== 'undefined') { diff --git a/static/js/server_events_dispatch.js b/static/js/server_events_dispatch.js index d9a6dc89ab..e9c875ff56 100644 --- a/static/js/server_events_dispatch.js +++ b/static/js/server_events_dispatch.js @@ -385,6 +385,7 @@ exports.dispatch_normal_event = function dispatch_normal_event(event) { 'twenty_four_hour_time', 'translate_emoticons', 'starred_message_counts', + 'fluid_layout_width', ]; if (_.contains(user_display_settings, event.setting_name)) { page_params[event.setting_name] = event.setting; @@ -423,6 +424,9 @@ exports.dispatch_normal_event = function dispatch_normal_event(event) { if (event.setting_name === 'starred_message_counts') { starred_messages.rerender_ui(); } + if (event.setting_name === 'fluid_layout_width') { + scroll_bar.set_layout_width(); + } if (event.setting_name === 'left_side_userlist') { // TODO: Make this change the view immediately rather // than requiring a reload or page resize. diff --git a/static/js/settings.js b/static/js/settings.js index 6494760691..d071245cbe 100644 --- a/static/js/settings.js +++ b/static/js/settings.js @@ -112,6 +112,7 @@ function setup_settings_label() { left_side_userlist: i18n.t("User list on left sidebar in narrow windows"), night_mode: i18n.t("Night mode"), starred_message_counts: i18n.t("Show counts for starred messages"), + fluid_layout_width: i18n.t("Use full width on wide screens"), twenty_four_hour_time: i18n.t("24-hour time (17:00 instead of 5:00 PM)"), translate_emoticons: i18n.t("Convert emoticons before sending (:) becomes 😃)"), }; diff --git a/static/js/settings_display.js b/static/js/settings_display.js index 4447f4744e..c4a1360e66 100644 --- a/static/js/settings_display.js +++ b/static/js/settings_display.js @@ -78,6 +78,11 @@ exports.set_up = function () { change_display_setting(data, '#display-settings-status'); }); + $('#fluid_layout_width').change(function () { + var data = {fluid_layout_width: JSON.stringify(this.checked)}; + change_display_setting(data, '#display-settings-status'); + }); + $("#night_mode").change(function () { exports.set_night_mode(this.checked); }); diff --git a/static/templates/settings/display-settings.handlebars b/static/templates/settings/display-settings.handlebars index 788d3bcd6c..3cdff15f52 100644 --- a/static/templates/settings/display-settings.handlebars +++ b/static/templates/settings/display-settings.handlebars @@ -51,6 +51,11 @@ "setting_name" "starred_message_counts" "is_checked" page_params.starred_message_counts "label" settings_label.starred_message_counts}} + + {{partial "settings_checkbox" + "setting_name" "fluid_layout_width" + "is_checked" page_params.fluid_layout_width + "label" settings_label.fluid_layout_width}}
diff --git a/zerver/migrations/0222_userprofile_fluid_layout_width.py b/zerver/migrations/0222_userprofile_fluid_layout_width.py new file mode 100644 index 0000000000..0acbbd866f --- /dev/null +++ b/zerver/migrations/0222_userprofile_fluid_layout_width.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.20 on 2019-04-15 17:10 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('zerver', '0221_subscription_notifications_data_migration'), + ] + + operations = [ + migrations.AddField( + model_name='userprofile', + name='fluid_layout_width', + field=models.BooleanField(default=False), + ), + ] diff --git a/zerver/models.py b/zerver/models.py index 97b84e963f..60506f90f6 100644 --- a/zerver/models.py +++ b/zerver/models.py @@ -861,6 +861,7 @@ class UserProfile(AbstractBaseUser, PermissionsMixin): translate_emoticons = models.BooleanField(default=False) # type: bool dense_mode = models.BooleanField(default=True) # type: bool starred_message_counts = models.BooleanField(default=False) # type: bool + fluid_layout_width = models.BooleanField(default=False) # type: bool # A timezone name from the `tzdata` database, as found in pytz.all_timezones. # @@ -920,6 +921,7 @@ class UserProfile(AbstractBaseUser, PermissionsMixin): night_mode=bool, translate_emoticons=bool, starred_message_counts=bool, + fluid_layout_width=bool, ) notification_setting_types = dict( diff --git a/zerver/tests/test_home.py b/zerver/tests/test_home.py index b6deef3206..3ae9681870 100644 --- a/zerver/tests/test_home.py +++ b/zerver/tests/test_home.py @@ -78,6 +78,7 @@ class HomeTest(ZulipTestCase): "enable_stream_sounds", "enter_sends", "first_in_realm", + "fluid_layout_width", "full_name", "furthest_read_time", "has_mobile_devices", diff --git a/zerver/views/user_settings.py b/zerver/views/user_settings.py index 6412d313f1..3998e0aa29 100644 --- a/zerver/views/user_settings.py +++ b/zerver/views/user_settings.py @@ -119,6 +119,7 @@ def update_display_settings_backend( twenty_four_hour_time: Optional[bool]=REQ(validator=check_bool, default=None), dense_mode: Optional[bool]=REQ(validator=check_bool, default=None), starred_message_counts: Optional[bool]=REQ(validator=check_bool, default=None), + fluid_layout_width: Optional[bool]=REQ(validator=check_bool, default=None), high_contrast_mode: Optional[bool]=REQ(validator=check_bool, default=None), night_mode: Optional[bool]=REQ(validator=check_bool, default=None), translate_emoticons: Optional[bool]=REQ(validator=check_bool, default=None),