diff --git a/frontend_tests/node_tests/dispatch.js b/frontend_tests/node_tests/dispatch.js index 639c988f27..dacc3cee16 100644 --- a/frontend_tests/node_tests/dispatch.js +++ b/frontend_tests/node_tests/dispatch.js @@ -692,20 +692,30 @@ with_overrides(function (override) { $("body").fadeIn = (secs) => { assert_same(secs, 300); }; global.with_stub(function (stub) { - event = event_fixtures.update_display_settings__night_mode; - page_params.night_mode = false; + event = event_fixtures.update_display_settings__color_scheme_dark; + page_params.color_scheme = 1; override('night_mode.enable', stub.f); // automatically checks if called override('realm_logo.rerender', noop); dispatch(event); - assert_same(page_params.night_mode, true); + assert(page_params.color_scheme, 2); }); global.with_stub(function (stub) { - event = event_fixtures.update_display_settings__night_mode_false; - page_params.night_mode = true; + event = event_fixtures.update_display_settings__color_scheme_light; + page_params.color_scheme = 1; override('night_mode.disable', stub.f); // automatically checks if called + override('realm_logo.rerender', noop); dispatch(event); - assert(!page_params.night_mode); + assert(page_params.color_scheme, 3); + }); + + global.with_stub(function (stub) { + event = event_fixtures.update_display_settings__color_scheme_automatic; + page_params.color_scheme = 2; + override('night_mode.default_preference_checker', stub.f); // automatically checks if called + override('realm_logo.rerender', noop); + dispatch(event); + assert(page_params.color_scheme, 1); }); global.with_stub(function (stub) { diff --git a/frontend_tests/node_tests/lib/events.js b/frontend_tests/node_tests/lib/events.js index 58cba6964b..78c761ad1e 100644 --- a/frontend_tests/node_tests/lib/events.js +++ b/frontend_tests/node_tests/lib/events.js @@ -478,16 +478,22 @@ exports.fixtures = { setting: true, }, - update_display_settings__night_mode: { + update_display_settings__color_scheme_automatic: { type: 'update_display_settings', - setting_name: 'night_mode', - setting: true, + setting_name: 'color_scheme', + setting: 1, }, - update_display_settings__night_mode_false: { + update_display_settings__color_scheme_dark: { type: 'update_display_settings', - setting_name: 'night_mode', - setting: false, + setting_name: 'color_scheme', + setting: 2, + }, + + update_display_settings__color_scheme_light: { + type: 'update_display_settings', + setting_name: 'color_scheme', + setting: 3, }, update_display_settings__starred_message_counts: { diff --git a/static/js/night_mode.js b/static/js/night_mode.js index 2dec1fd6ba..3b32690ec1 100644 --- a/static/js/night_mode.js +++ b/static/js/night_mode.js @@ -1,9 +1,13 @@ exports.enable = function () { - $("body").addClass("night-mode"); + $("body").removeClass("color-scheme-automatic").addClass("night-mode"); }; exports.disable = function () { - $("body").removeClass("night-mode"); + $("body").removeClass("color-scheme-automatic").removeClass("night-mode"); +}; + +exports.default_preference_checker = function () { + $("body").removeClass("night-mode").addClass("color-scheme-automatic"); }; window.night_mode = exports; diff --git a/static/js/realm_logo.js b/static/js/realm_logo.js index f067ba15b7..479573d9cf 100644 --- a/static/js/realm_logo.js +++ b/static/js/realm_logo.js @@ -1,3 +1,5 @@ +const settings_config = require("./settings_config"); + exports.build_realm_logo_widget = function (upload_function, is_night) { let logo_section_id = '#realm-day-logo-upload-widget'; let logo_source = page_params.realm_logo_source; @@ -73,7 +75,11 @@ exports.rerender = function () { $("#realm-night-logo-upload-widget .image-block").attr("src", page_params.realm_night_logo_url); } - if (page_params.night_mode && page_params.realm_night_logo_source !== 'D') { + if (page_params.color_scheme === settings_config.color_scheme_values.night.code && + page_params.realm_night_logo_source !== 'D' || + page_params.color_scheme === settings_config.color_scheme_values.automatic.code && + page_params.realm_night_logo_source !== 'D' && + (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches)) { $("#realm-logo").attr("src", page_params.realm_night_logo_url); } else { $("#realm-logo").attr("src", page_params.realm_logo_url); diff --git a/static/js/server_events_dispatch.js b/static/js/server_events_dispatch.js index 6272f5e6d9..164e9cb149 100644 --- a/static/js/server_events_dispatch.js +++ b/static/js/server_events_dispatch.js @@ -1,3 +1,5 @@ +const settings_config = require("./settings_config"); + exports.dispatch_normal_event = function dispatch_normal_event(event) { const noop = function () {}; switch (event.type) { @@ -395,13 +397,13 @@ exports.dispatch_normal_event = function dispatch_normal_event(event) { case 'update_display_settings': { const user_display_settings = [ + 'color_scheme', 'default_language', 'demote_inactive_streams', 'dense_mode', 'emojiset', 'fluid_layout_width', 'high_contrast_mode', - 'night_mode', 'left_side_userlist', 'timezone', 'twenty_four_hour_time', @@ -433,15 +435,18 @@ exports.dispatch_normal_event = function dispatch_normal_event(event) { $("body").toggleClass("less_dense_mode"); $("body").toggleClass("more_dense_mode"); } - if (event.setting_name === 'night_mode') { + if (event.setting_name === 'color_scheme') { $("body").fadeOut(300); setTimeout(function () { - if (event.setting === true) { + if (event.setting === settings_config.color_scheme_values.night.code) { night_mode.enable(); realm_logo.rerender(); - } else { + } else if (event.setting === settings_config.color_scheme_values.day.code) { night_mode.disable(); realm_logo.rerender(); + } else { + night_mode.default_preference_checker(); + realm_logo.rerender(); } $("body").fadeIn(300); }, 300); diff --git a/static/js/settings.js b/static/js/settings.js index fbbf5c9b0e..883f45ea04 100644 --- a/static/js/settings.js +++ b/static/js/settings.js @@ -37,7 +37,6 @@ function setup_settings_label() { fluid_layout_width: i18n.t("Use full width on wide screens"), high_contrast_mode: i18n.t("High contrast mode"), left_side_userlist: i18n.t("Show user list on left sidebar in narrow windows"), - night_mode: i18n.t("Night mode"), starred_message_counts: i18n.t("Show counts for starred messages"), twenty_four_hour_time: i18n.t("Time format"), translate_emoticons: i18n.t("Convert emoticons before sending (:) becomes 😃)"), @@ -58,6 +57,7 @@ exports.build_page = function () { can_create_new_bots: settings_bots.can_create_new_bots(), settings_label: exports.settings_label, demote_inactive_streams_values: settings_config.demote_inactive_streams_values, + color_scheme_values: settings_config.color_scheme_values, twenty_four_hour_time_values: settings_config.twenty_four_hour_time_values, general_settings: settings_config.all_notifications().general_settings, notification_settings: settings_config.all_notifications().settings, diff --git a/static/js/settings_config.js b/static/js/settings_config.js index 25a4854f97..3ecc1e99ad 100644 --- a/static/js/settings_config.js +++ b/static/js/settings_config.js @@ -27,6 +27,21 @@ exports.demote_inactive_streams_values = { }, }; +exports.color_scheme_values = { + automatic: { + code: 1, + description: i18n.t("Automatic"), + }, + night: { + code: 2, + description: i18n.t("Night mode"), + }, + day: { + code: 3, + description: i18n.t("Day mode"), + }, +}; + exports.twenty_four_hour_time_values = { twenty_four_hour_clock: { value: true, @@ -42,7 +57,6 @@ exports.get_all_display_settings = () => ({ settings: { user_display_settings: [ "dense_mode", - "night_mode", "high_contrast_mode", "left_side_userlist", "starred_message_counts", diff --git a/static/js/settings_display.js b/static/js/settings_display.js index 28667d5f06..1bb5d6c759 100644 --- a/static/js/settings_display.js +++ b/static/js/settings_display.js @@ -29,6 +29,8 @@ exports.set_up = function () { $("#demote_inactive_streams").val(page_params.demote_inactive_streams); + $("#color_scheme").val(page_params.color_scheme); + $("#twenty_four_hour_time").val(JSON.stringify(page_params.twenty_four_hour_time)); $(".emojiset_choice[value=" + page_params.emojiset + "]").prop("checked", true); @@ -82,6 +84,11 @@ exports.set_up = function () { change_display_setting(data, '#display-settings-status'); }); + $('#color_scheme').change(function () { + const data = {color_scheme: this.value}; + change_display_setting(data, '#display-settings-status'); + }); + $('body').on('click', '.reload_link', function () { window.location.reload(); }); @@ -146,8 +153,8 @@ exports.update_page = function () { $("#left_side_userlist").prop('checked', page_params.left_side_userlist); $("#default_language_name").text(page_params.default_language_name); $("#translate_emoticons").prop('checked', page_params.translate_emoticons); - $("#night_mode").prop('checked', page_params.night_mode); $("#twenty_four_hour_time").val(JSON.stringify(page_params.twenty_four_hour_time)); + $("#color_scheme").val(JSON.stringify(page_params.color_scheme)); // TODO: Set emojiset selector here. // Longer term, we'll want to automate this function diff --git a/static/styles/night_mode.scss b/static/styles/night_mode.scss index 90a2440258..885d0271dd 100644 --- a/static/styles/night_mode.scss +++ b/static/styles/night_mode.scss @@ -786,3 +786,9 @@ on a dark background, and don't change the dark labels dark either. */ background-color: hsla(0, 0%, 0%, 0.2); } } + +@media (prefers-color-scheme: dark) { + .color-scheme-automatic { + @extend body.night-mode; + } +} diff --git a/static/templates/settings/display_settings.hbs b/static/templates/settings/display_settings.hbs index f9e9478943..2cca09ebef 100644 --- a/static/templates/settings/display_settings.hbs +++ b/static/templates/settings/display_settings.hbs @@ -21,6 +21,14 @@

{{t "Display settings" }}

+
+ + +
+ {{#each display_settings.settings.user_display_settings}} {{> settings_checkbox setting_name=this diff --git a/templates/zerver/api/changelog.md b/templates/zerver/api/changelog.md index 84843f0637..b99d94f825 100644 --- a/templates/zerver/api/changelog.md +++ b/templates/zerver/api/changelog.md @@ -10,6 +10,11 @@ below features are supported. ## Changes in Zulip 2.2 +**Feature level 21** + +* `PATCH /settings/display`: Replaced the `night_mode` boolean with + `color_scheme` as part of supporting automatic night theme detection. + **Feature level 20** * Added support for inviting users as organization owners to the diff --git a/templates/zerver/base.html b/templates/zerver/base.html index 6958ff7c2c..d043093720 100644 --- a/templates/zerver/base.html +++ b/templates/zerver/base.html @@ -29,7 +29,7 @@ {% endblock %} - + {% block content %} {% endblock %} diff --git a/templates/zerver/help/night-mode.md b/templates/zerver/help/night-mode.md index f6de1bff80..7001568929 100644 --- a/templates/zerver/help/night-mode.md +++ b/templates/zerver/help/night-mode.md @@ -1,15 +1,21 @@ # Night mode -By default, Zulip has a white background. Zulip also provides a -"night mode", which is great for working in a dark space. +Zulip provides both a light theme and a night theme, which is great +for working in a dark space. -### Enable night mode +## Manage color theme {start_tabs} {settings_tab|display-settings} -2. Under **Display settings**, select **Night mode**. +2. Under **Display settings**, configure **Color scheme**. {end_tabs} -. + +The default is **Automatic**, which detects which theme to use based +on the color scheme used by your operating system. + +You can also specifc **Night mode** or **Day mode** if you'd like +Zulip to use the same color scheme regardless of your operating system +configuration. diff --git a/version.py b/version.py index cab5abf5d8..a6b6dd7e51 100644 --- a/version.py +++ b/version.py @@ -29,7 +29,7 @@ DESKTOP_WARNING_VERSION = "5.2.0" # # Changes should be accompanied by documentation explaining what the # new level means in templates/zerver/api/changelog.md. -API_FEATURE_LEVEL = 20 +API_FEATURE_LEVEL = 21 # Bump the minor PROVISION_VERSION to indicate that folks should provision # only when going from an old version of the code to a newer version. Bump diff --git a/zerver/lib/zcommand.py b/zerver/lib/zcommand.py index 16beb63894..14ed4b9179 100644 --- a/zerver/lib/zcommand.py +++ b/zerver/lib/zcommand.py @@ -9,7 +9,7 @@ from zerver.models import UserProfile def process_zcommands(content: str, user_profile: UserProfile) -> Dict[str, Any]: def change_mode_setting(command: str, switch_command: str, - setting: str, setting_value: bool) -> str: + setting: str, setting_value: int) -> str: msg = 'Changed to {command} mode! To revert ' \ '{command} mode, type `/{switch_command}`.'.format( command=command, @@ -27,19 +27,19 @@ def process_zcommands(content: str, user_profile: UserProfile) -> Dict[str, Any] if command == 'ping': return dict() elif command == 'night': - if user_profile.night_mode: + if user_profile.color_scheme == UserProfile.COLOR_SCHEME_NIGHT: return dict(msg='You are still in night mode.') return dict(msg=change_mode_setting(command=command, switch_command='day', - setting='night_mode', - setting_value=True)) + setting='color_scheme', + setting_value=UserProfile.COLOR_SCHEME_NIGHT)) elif command == 'day': - if not user_profile.night_mode: + if user_profile.color_scheme == UserProfile.COLOR_SCHEME_LIGHT: return dict(msg='You are still in day mode.') return dict(msg=change_mode_setting(command=command, switch_command='night', - setting='night_mode', - setting_value=False)) + setting='color_scheme', + setting_value=UserProfile.COLOR_SCHEME_LIGHT)) elif command == 'fluid-width': if user_profile.fluid_layout_width: return dict(msg='You are still in fluid width mode.') diff --git a/zerver/migrations/0290_remove_night_mode_add_color_scheme.py b/zerver/migrations/0290_remove_night_mode_add_color_scheme.py new file mode 100644 index 0000000000..644cd02485 --- /dev/null +++ b/zerver/migrations/0290_remove_night_mode_add_color_scheme.py @@ -0,0 +1,35 @@ +# Generated by Django 2.2.13 on 2020-06-20 15:22 + +from django.db import migrations, models +from django.db.backends.postgresql.schema import DatabaseSchemaEditor +from django.db.migrations.state import StateApps + +COLOR_SCHEME_AUTOMATIC = 1 +COLOR_SCHEME_NIGHT = 2 + +# Set color_scheme to night mode, if night_mode is True. +def set_color_scheme_to_night_mode(apps: StateApps, schema_editor: DatabaseSchemaEditor) -> None: + UserProfile = apps.get_model("zerver", "UserProfile") + UserProfile.objects.filter(night_mode=True).update(color_scheme=COLOR_SCHEME_NIGHT) + +class Migration(migrations.Migration): + + dependencies = [ + ('zerver', '0289_tighten_attachment_size'), + ] + + operations = [ + migrations.AddField( + model_name='userprofile', + name='color_scheme', + field=models.PositiveSmallIntegerField(default=COLOR_SCHEME_AUTOMATIC), + ), + migrations.RunPython( + set_color_scheme_to_night_mode, + reverse_code=migrations.RunPython.noop, + elidable=True), + migrations.RemoveField( + model_name='userprofile', + name='night_mode', + ), + ] diff --git a/zerver/models.py b/zerver/models.py index ba1682f7b7..2898184b47 100644 --- a/zerver/models.py +++ b/zerver/models.py @@ -999,10 +999,18 @@ class UserProfile(AbstractBaseUser, PermissionsMixin): dense_mode: bool = models.BooleanField(default=True) fluid_layout_width: bool = models.BooleanField(default=False) high_contrast_mode: bool = models.BooleanField(default=False) - night_mode: bool = models.BooleanField(default=False) translate_emoticons: bool = models.BooleanField(default=False) twenty_four_hour_time: bool = models.BooleanField(default=False) starred_message_counts: bool = models.BooleanField(default=False) + COLOR_SCHEME_AUTOMATIC = 1 + COLOR_SCHEME_NIGHT = 2 + COLOR_SCHEME_LIGHT = 3 + COLOR_SCHEME_CHOICES = [ + COLOR_SCHEME_AUTOMATIC, + COLOR_SCHEME_NIGHT, + COLOR_SCHEME_LIGHT + ] + color_scheme = models.PositiveSmallIntegerField(default=COLOR_SCHEME_AUTOMATIC) # UI setting controlling Zulip's behavior of demoting in the sort # order and graying out streams with no recent traffic. The @@ -1069,6 +1077,7 @@ class UserProfile(AbstractBaseUser, PermissionsMixin): # Define the types of the various automatically managed properties property_types = dict( + color_scheme=int, default_language=str, demote_inactive_streams=int, dense_mode=bool, @@ -1076,7 +1085,6 @@ class UserProfile(AbstractBaseUser, PermissionsMixin): fluid_layout_width=bool, high_contrast_mode=bool, left_side_userlist=bool, - night_mode=bool, starred_message_counts=bool, timezone=str, translate_emoticons=bool, diff --git a/zerver/tests/test_events.py b/zerver/tests/test_events.py index 6242765a88..d9a2756a22 100644 --- a/zerver/tests/test_events.py +++ b/zerver/tests/test_events.py @@ -1852,6 +1852,7 @@ class EventsRegisterTest(ZulipTestCase): default_language = ['es', 'de', 'en'], timezone = ['US/Mountain', 'US/Samoa', 'Pacific/Galapogos', ''], demote_inactive_streams = [2, 3, 1], + color_scheme = [2, 3, 1] ) property_type = UserProfile.property_types[setting_name] diff --git a/zerver/tests/test_home.py b/zerver/tests/test_home.py index cd9b0b3985..ad8b148a63 100644 --- a/zerver/tests/test_home.py +++ b/zerver/tests/test_home.py @@ -61,6 +61,7 @@ class HomeTest(ZulipTestCase): "bot_types", "can_create_streams", "can_subscribe_other_users", + "color_scheme", "cross_realm_bots", "custom_profile_field_types", "custom_profile_fields", @@ -117,7 +118,6 @@ class HomeTest(ZulipTestCase): "narrow_stream", "needs_tutorial", "never_subscribed", - "night_mode", "notification_sound", "password_min_guesses", "password_min_length", @@ -761,34 +761,34 @@ class HomeTest(ZulipTestCase): def test_compute_navbar_logo_url(self) -> None: user_profile = self.example_user("hamlet") - page_params = {"night_mode": True} + page_params = {"color_scheme": user_profile.COLOR_SCHEME_NIGHT} add_realm_logo_fields(page_params, user_profile.realm) self.assertEqual(compute_navbar_logo_url(page_params), "/static/images/logo/zulip-org-logo.png?version=0") - page_params = {"night_mode": False} + page_params = {"color_scheme": user_profile.COLOR_SCHEME_LIGHT} add_realm_logo_fields(page_params, user_profile.realm) self.assertEqual(compute_navbar_logo_url(page_params), "/static/images/logo/zulip-org-logo.png?version=0") do_change_logo_source(user_profile.realm, Realm.LOGO_UPLOADED, night=False) - page_params = {"night_mode": True} + page_params = {"color_scheme": user_profile.COLOR_SCHEME_NIGHT} add_realm_logo_fields(page_params, user_profile.realm) self.assertEqual(compute_navbar_logo_url(page_params), f"/user_avatars/{user_profile.realm_id}/realm/logo.png?version=2") - page_params = {"night_mode": False} + page_params = {"color_scheme": user_profile.COLOR_SCHEME_LIGHT} add_realm_logo_fields(page_params, user_profile.realm) self.assertEqual(compute_navbar_logo_url(page_params), f"/user_avatars/{user_profile.realm_id}/realm/logo.png?version=2") do_change_logo_source(user_profile.realm, Realm.LOGO_UPLOADED, night=True) - page_params = {"night_mode": True} + page_params = {"color_scheme": user_profile.COLOR_SCHEME_NIGHT} add_realm_logo_fields(page_params, user_profile.realm) self.assertEqual(compute_navbar_logo_url(page_params), f"/user_avatars/{user_profile.realm_id}/realm/night_logo.png?version=2") - page_params = {"night_mode": False} + page_params = {"color_scheme": user_profile.COLOR_SCHEME_LIGHT} add_realm_logo_fields(page_params, user_profile.realm) self.assertEqual(compute_navbar_logo_url(page_params), f"/user_avatars/{user_profile.realm_id}/realm/logo.png?version=2") @@ -796,12 +796,12 @@ class HomeTest(ZulipTestCase): # This configuration isn't super supported in the UI and is a # weird choice, but we have a test for it anyway. do_change_logo_source(user_profile.realm, Realm.LOGO_DEFAULT, night=False) - page_params = {"night_mode": True} + page_params = {"color_scheme": user_profile.COLOR_SCHEME_NIGHT} add_realm_logo_fields(page_params, user_profile.realm) self.assertEqual(compute_navbar_logo_url(page_params), f"/user_avatars/{user_profile.realm_id}/realm/night_logo.png?version=2") - page_params = {"night_mode": False} + page_params = {"color_scheme": user_profile.COLOR_SCHEME_LIGHT} add_realm_logo_fields(page_params, user_profile.realm) self.assertEqual(compute_navbar_logo_url(page_params), "/static/images/logo/zulip-org-logo.png?version=0") diff --git a/zerver/tests/test_middleware.py b/zerver/tests/test_middleware.py index 6506b73f04..694d064d71 100644 --- a/zerver/tests/test_middleware.py +++ b/zerver/tests/test_middleware.py @@ -83,9 +83,8 @@ class OpenGraphTest(ZulipTestCase): self.check_title_and_description( '/help/night-mode', "Night mode (Zulip Help Center)", - ['By default, Zulip has a white background. ', - 'Zulip also provides a "night mode", which is great for working in a dark space.'], - [], + ['Zulip provides both a white background and a "night mode", which is great for working in a dark space.'], + [] ) def test_settings_tab(self) -> None: diff --git a/zerver/tests/test_settings.py b/zerver/tests/test_settings.py index 246ae6f687..9626c5104f 100644 --- a/zerver/tests/test_settings.py +++ b/zerver/tests/test_settings.py @@ -322,6 +322,7 @@ class ChangeSettingsTest(ZulipTestCase): emojiset = 'google', timezone = 'US/Mountain', demote_inactive_streams = 2, + color_scheme = 2, ) self.login('hamlet') diff --git a/zerver/tests/test_users.py b/zerver/tests/test_users.py index f2d2f6ec8b..58df104385 100644 --- a/zerver/tests/test_users.py +++ b/zerver/tests/test_users.py @@ -1020,11 +1020,12 @@ class UserProfileTest(ZulipTestCase): iago = self.example_user("iago") cordelia = self.example_user("cordelia") hamlet = self.example_user("hamlet") + hamlet.color_scheme = UserProfile.COLOR_SCHEME_LIGHT cordelia.default_language = "de" cordelia.emojiset = "twitter" cordelia.timezone = "America/Phoenix" - cordelia.night_mode = True + cordelia.color_scheme = UserProfile.COLOR_SCHEME_NIGHT cordelia.enable_offline_email_notifications = False cordelia.enable_stream_push_notifications = True cordelia.enter_sends = False @@ -1055,9 +1056,9 @@ class UserProfileTest(ZulipTestCase): self.assertEqual(cordelia.timezone, "America/Phoenix") self.assertEqual(hamlet.timezone, "") - self.assertEqual(iago.night_mode, True) - self.assertEqual(cordelia.night_mode, True) - self.assertEqual(hamlet.night_mode, False) + self.assertEqual(iago.color_scheme, UserProfile.COLOR_SCHEME_NIGHT) + self.assertEqual(cordelia.color_scheme, UserProfile.COLOR_SCHEME_NIGHT) + self.assertEqual(hamlet.color_scheme, UserProfile.COLOR_SCHEME_LIGHT) self.assertEqual(iago.enable_offline_email_notifications, False) self.assertEqual(cordelia.enable_offline_email_notifications, False) diff --git a/zerver/tests/test_zcommand.py b/zerver/tests/test_zcommand.py index 08c1ca7d16..abf2afc134 100644 --- a/zerver/tests/test_zcommand.py +++ b/zerver/tests/test_zcommand.py @@ -1,4 +1,5 @@ from zerver.lib.test_classes import ZulipTestCase +from zerver.models import UserProfile class ZcommandTest(ZulipTestCase): @@ -24,7 +25,7 @@ class ZcommandTest(ZulipTestCase): def test_night_zcommand(self) -> None: self.login('hamlet') user = self.example_user('hamlet') - user.night_mode = False + user.color_scheme = UserProfile.COLOR_SCHEME_LIGHT user.save() payload = dict(command="/night") @@ -39,7 +40,7 @@ class ZcommandTest(ZulipTestCase): def test_day_zcommand(self) -> None: self.login('hamlet') user = self.example_user('hamlet') - user.night_mode = True + user.color_scheme = UserProfile.COLOR_SCHEME_NIGHT user.save() payload = dict(command="/day") diff --git a/zerver/views/home.py b/zerver/views/home.py index 3976b15073..04d4174a79 100644 --- a/zerver/views/home.py +++ b/zerver/views/home.py @@ -129,7 +129,7 @@ def get_bot_types(user_profile: Optional[UserProfile]) -> List[Dict[str, object] return bot_types def compute_navbar_logo_url(page_params: Dict[str, Any]) -> str: - if page_params["night_mode"] and page_params["realm_night_logo_source"] != Realm.LOGO_DEFAULT: + if page_params["color_scheme"] == 2 and page_params["realm_night_logo_source"] != Realm.LOGO_DEFAULT: navbar_logo_url = page_params["realm_night_logo_url"] else: navbar_logo_url = page_params["realm_logo_url"] @@ -315,13 +315,13 @@ def home_real(request: HttpRequest) -> HttpResponse: csp_nonce = generate_random_token(48) if user_profile is not None: - night_mode = user_profile.night_mode + color_scheme = user_profile.color_scheme is_guest = user_profile.is_guest is_realm_owner = user_profile.is_realm_owner is_realm_admin = user_profile.is_realm_admin show_webathena = user_profile.realm.webathena_enabled else: # nocoverage - night_mode = False + color_scheme = UserProfile.COLOR_SCHEME_AUTOMATIC is_guest = False is_realm_admin = False is_realm_owner = False @@ -342,7 +342,7 @@ def home_real(request: HttpRequest) -> HttpResponse: 'is_owner': is_realm_owner, 'is_admin': is_realm_admin, 'is_guest': is_guest, - 'night_mode': night_mode, + 'color_scheme': color_scheme, 'navbar_logo_url': navbar_logo_url, 'show_webathena': show_webathena, 'embedded': narrow_stream is not None, diff --git a/zerver/views/user_settings.py b/zerver/views/user_settings.py index 8575bf8e82..db10ab4376 100644 --- a/zerver/views/user_settings.py +++ b/zerver/views/user_settings.py @@ -165,7 +165,8 @@ def update_display_settings_backend( 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), + color_scheme: Optional[int]=REQ(validator=check_int_in( + UserProfile.COLOR_SCHEME_CHOICES), default=None), translate_emoticons: Optional[bool]=REQ(validator=check_bool, default=None), default_language: Optional[str]=REQ(validator=check_string, default=None), left_side_userlist: Optional[bool]=REQ(validator=check_bool, default=None),